[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

libquran on WIN32



Salam 3alikom,

i made some minor changes to run libquran on win32, i have
successfully compiled the library on MINGW as a DLL and linked against
it. The patch is Attached for the maintainers review.

Here is a brief description of the changes:
-added implementation for functions that are not available on WIN32
and not provided by mingw :
scandir, alphasort, strndup, strnlen, strtok_r, le_short (speex version)

-added proxy functions for free, malloc, coz on win32 when compiled
the library will be linked against a specific version of MS provided
CRT, using a newer (also MS provided) version for the program calling
the library will result in heap corruption and exception when trying
to free memory allocated by libquran. this stupid/annoying desgin by
Microsoft e.g. VC8 program calling VC7 program can't free/allocate
memory coz of different. so programs calling libquran will need to
call libquran's version of free to avoid heap corruption.

-use newer version of obsolete functions not available on win32,
strchr instead of index

-added function decoration ifdefs for dll import/export

-increased memory allocated in audio/quran open_index by one to
accommodate the '\0', was causing heap corruption errors on win32
(write past allocated memory)

Things todo:
-Create C# bindings and java bindings
-remove hardcoded windows path, and use dynamic %SYSTEMPATH% and %USER_DATA_DIR%

Need help with:
add "-Wl,--output-def,libquran-0.def" conditionally to the Makefile.am
i.e. only when building on win32

Wa Jazakom Allah 3ana Khayran

Ahmed Ghoneim
diff -B -b libquran.cvs/configure.in libquran/configure.in
10a11
> AC_LIBTOOL_WIN32_DLL
12d12
< AC_PROG_RANLIB
Common subdirectories: libquran.cvs/data and libquran/data
diff -B -b libquran.cvs/globals.c libquran/globals.c
24a25,30
> #ifdef _WIN32
> #include<dirent.h>
> #include<stdlib.h>
> #include<sys/types.h>
> #endif
> 
116a123,220
> 
> #ifdef _WIN32
> 
> int scandir(const char *dir, struct dirent ***namelist,
>             int (*select)(const struct dirent *),
>             int (*compar)(const struct dirent **, const struct dirent **)) {
>   DIR *d;
>   struct dirent *entry;
>   register int i=0;
>   size_t entrysize;
> 
>   if ((d=opendir(dir)) == NULL)
>      return(-1);
> 
>   *namelist=NULL;
>   while ((entry=readdir(d)) != NULL)
>   {
>     if (select == NULL || (select != NULL && (*select)(entry)))
>     {
>       *namelist=(struct dirent **)realloc((void *)(*namelist),
>                  (size_t)((i+1)*sizeof(struct dirent *)));
> 	if (*namelist == NULL) return(-1);
> 	entrysize=sizeof(struct dirent)-sizeof(entry->d_name)+strlen(entry->d_name)+1;
> 	(*namelist)[i]=(struct dirent *)malloc(entrysize);
> 	if ((*namelist)[i] == NULL) return(-1);
> 	memcpy((*namelist)[i], entry, entrysize);
> 	i++;
>     }
>   }
>   if (closedir(d)) return(-1);
>   if (i == 0) return(-1);
>   if (compar != NULL)
>     qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), compar);
>     
>   return(i);
> }
> 
> int alphasort(const struct dirent **a, const struct dirent **b) {
>   return(strcmp((*a)->d_name, (*b)->d_name));
> }
> 
> 
> char * strndup (const char *s, size_t n) {
>   size_t len = strnlen (s, n);
>   char *new = malloc (len + 1);
> 
>   if (new == NULL)
>     return NULL;
> 
>   new[len] = '\0';
>   return (char *) memcpy (new, s, len);
> }
> 
> size_t strnlen (const char *string, size_t maxlen) {
>   const char *end = memchr (string, '\0', maxlen);
>   return end ? (size_t) (end - string) : maxlen;
> }
> 
> 
> unsigned short le_short(unsigned short s)
> {
>   unsigned short ret=s;
> #ifdef WORDS_BIGENDIAN
>   ret =  s>>8;
>   ret += s<<8;
> #endif
>   return ret;
> }
> 
> 
> char *strtok_r(char *str, const char *delim, char **saveptr)
> {
>     char *token;
>     if (str)
>         *saveptr = str;
>     token = *saveptr;
> 
>     if (!token)
>         return NULL;
> 
>     token += strspn(token, delim);
>     *saveptr = strpbrk(token, delim);
>     if (*saveptr)
>         *(*saveptr)++ = '\0';
> 
>     return *token ? token : NULL;
> } 
> 
> LIBQURAN_SCOPE void free_q(void* memblock) {
> 	free(memblock);
> }
> 
> LIBQURAN_SCOPE void *malloc_q(size_t size) {
> 	return malloc(size);
> }
> 
> #endif
> 
diff -B -b libquran.cvs/globals.h libquran/globals.h
43a44,52
> #ifdef _WIN32
> int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
> int alphasort(const struct dirent **, const struct dirent **);
> char * strndup (const char *, size_t);
> size_t strnlen (const char *, size_t);
> unsigned short le_short(unsigned short);
> char *strtok_r(char *, const char *, char **);
> #endif
> 
diff -B -b libquran.cvs/init.c libquran/init.c
54c54
< int quran_init(libquran_ctx * ctx) {
---
> LIBQURAN_SCOPE int quran_init(libquran_ctx * ctx) {
108c108
< void quran_free(libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE void quran_free(libquran_ctx *ctx) {
187c187
< #ifdef _MINGW
---
> #ifdef _WIN32
192c192
< #endif // _MINGW
---
> #endif // _WIN32
197a198,199
> 	
> #ifndef _WIN32	
198a201,207
> #else
> #ifdef _WIN32
> 	temp = (char *)malloc(1000);
> 	fgets(temp, 1000, file_handle);
> #endif // _WIN32
> #endif // _!WIN32
> 
207c216
< 			if (index (whitespace, trimmed [n]) != NULL) {
---
> 			if (strchr (whitespace, trimmed [n]) != NULL) {
220c229
< 			if (index (whitespace, trimmed [n]) != NULL) {
---
> 			if (strchr (whitespace, trimmed [n]) != NULL) {
488c497
< #if defined(_WIN32) && defined (_MINGW)
---
> #if defined(_WIN32)
514c523
< #if defined(_WIN32) && defined(_MINGW)
---
> #if defined(_WIN32)
608c617
< #if defined(_WIN32) && defined(_MINGW)
---
> #if defined(_WIN32)
diff -B -b libquran.cvs/Makefile.am libquran/Makefile.am
5a6,9
> #if _WIN32
> libquran_la_LDFLAGS = -no-undefined
> #endif
> libquran_la_LIBADD = -L at SPEEX@ -lexpat -lspeex -logg
diff -B -b libquran.cvs/quranaudio.c libquran/quranaudio.c
54c54
< quran_audio *quran_audio_open(const char *lang, const char *package, const int sura_no, const int aya_no, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE quran_audio *quran_audio_open(const char *lang, const char *package, const int sura_no, const int aya_no, libquran_ctx *ctx) {
99c99
< quran_audio *quran_audio_open_index(const int lang, const int audio, const int sura_no, const int aya_no, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE quran_audio *quran_audio_open_index(const int lang, const int audio, const int sura_no, const int aya_no, libquran_ctx *ctx) {
129c129,131
< 						strlen(ctx->libquran.avail_langs[lang].avail_audio_packages[audio].filename));
---
> 						strlen(ctx->libquran.avail_langs[lang].avail_audio_packages[audio].filename) +
> 						1 /* '\0' */
> 						);
132c134
< #if defined(_WIN32) && defined(_MINGW)
---
> #if defined(_WIN32)
185c187
< int quran_audio_play(quran_audio *qa, int (*callback)(quran_audio *)) {
---
> LIBQURAN_SCOPE int quran_audio_play(quran_audio *qa, int (*callback)(quran_audio *)) {
214c216
< void quran_audio_stop(quran_audio *qa) {
---
> LIBQURAN_SCOPE void quran_audio_stop(quran_audio *qa) {
230c232
< void quran_audio_close(quran_audio *qa, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE void quran_audio_close(quran_audio *qa, libquran_ctx *ctx) {
diff -B -b libquran.cvs/qurandata.c libquran/qurandata.c
100c100
< quran *quran_open(const char * lang, const char * text_file, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE quran *quran_open(const char * lang, const char * text_file, libquran_ctx *ctx) {
142c142
< quran * quran_open_index(const int lang, const int text, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE quran * quran_open_index(const int lang, const int text, libquran_ctx *ctx) {
172c172,173
< 				  2  /* 2 slashes */
---
> 				  2 +  /* 2 slashes */
> 				  1   /* '\0' */
185c186
< #if defined(_WIN32) && defined(_MINGW)
---
> #if defined(_WIN32)
229c230
< char *quran_read_verse(const quran *q, int sura_no, int aya_no, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE char *quran_read_verse(const quran *q, int sura_no, int aya_no, libquran_ctx *ctx) {
281c282
< void quran_close(quran *q, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE void quran_close(quran *q, libquran_ctx *ctx) {
329c330
< sura_info *quran_sura_info(int sura_no) {
---
> LIBQURAN_SCOPE sura_info *quran_sura_info(int sura_no) {
360c361
< ayainfo * quran_verse_info(int sura_no, int aya_no) {
---
> LIBQURAN_SCOPE ayainfo * quran_verse_info(int sura_no, int aya_no) {
diff -B -b libquran.cvs/quran.h libquran/quran.h
39a40,55
> 
> #ifdef _WIN32
> #ifdef DLL_EXPORT
> #define LIBQURAN_SCOPE __declspec(dllexport)
> #else
> #ifdef LIBQURAN_DLL_IMPORT
> #define LIBQURAN_SCOPE extern __declspec(dllimport)
> #endif
> #endif
> #endif
> 
> #ifndef LIBQURAN_SCOPE
> #define LIBQURAN_SCOPE extern
> #endif
> 
> 
207,227c223,245
< int quran_init(libquran_ctx *);
< void quran_free();
< quran *quran_open(const char *, const char *, libquran_ctx *);
< quran *quran_open_index(int, int, libquran_ctx *);
< char *quran_read_verse(const quran *, int, int, libquran_ctx *); 
< void quran_close(quran *, libquran_ctx *);
< ayainfo * quran_verse_info (int , int );
< sura_info * quran_sura_info(int);
< char * quran_recitor_name(const char *, const char *);
< quran_audio * quran_audio_open(const char *, const char *, const int, const int, libquran_ctx *);
< quran_audio * quran_audio_open_index(int, int, const int, const int, libquran_ctx *);
< int quran_audio_play(quran_audio *, int (*)(quran_audio *));
< void quran_audio_stop(quran_audio *);
< void quran_audio_close(quran_audio *, libquran_ctx *);
< int quran_search_quran(quran *, const char *, int, int, libquran_ctx *);
< int quran_search_sura(quran *, const char *, int, int, int, libquran_ctx *);
< int quran_search_hezb(quran *, const char *, int, int, int, libquran_ctx *);
< int quran_search_juzz(quran *, const char *, int, int, int, libquran_ctx *);
< int quran_search_part(quran *, const char *, int, int, int, int, int, int, libquran_ctx *);
< results_struct **quran_get_search_results(libquran_ctx *);
< void quran_free_search_results(libquran_ctx *);
---
> LIBQURAN_SCOPE int              quran_init(libquran_ctx *);
> LIBQURAN_SCOPE void             quran_free();
> LIBQURAN_SCOPE quran*           quran_open(const char *, const char *, libquran_ctx *);
> LIBQURAN_SCOPE quran*           quran_open_index(int, int, libquran_ctx *);
> LIBQURAN_SCOPE char*            quran_read_verse(const quran *, int, int, libquran_ctx *); 
> LIBQURAN_SCOPE void             quran_close(quran *, libquran_ctx *);
> LIBQURAN_SCOPE ayainfo*         quran_verse_info (int , int );
> LIBQURAN_SCOPE sura_info*       quran_sura_info(int);
> LIBQURAN_SCOPE quran_audio*     quran_audio_open(const char *, const char *, const int, const int, libquran_ctx *);
> LIBQURAN_SCOPE quran_audio*     quran_audio_open_index(int, int, const int, const int, libquran_ctx *);
> LIBQURAN_SCOPE int              quran_audio_play(quran_audio *, int (*)(quran_audio *));
> LIBQURAN_SCOPE void             quran_audio_stop(quran_audio *);
> LIBQURAN_SCOPE void             quran_audio_close(quran_audio *, libquran_ctx *);
> LIBQURAN_SCOPE int              quran_search_quran(quran *, const char *, int, int, libquran_ctx *);
> LIBQURAN_SCOPE int              quran_search_sura(quran *, const char *, int, int, int, libquran_ctx *);
> LIBQURAN_SCOPE int              quran_search_hezb(quran *, const char *, int, int, int, libquran_ctx *);
> LIBQURAN_SCOPE int              quran_search_juzz(quran *, const char *, int, int, int, libquran_ctx *);
> LIBQURAN_SCOPE int              quran_search_part(quran *, const char *, int, int, int, int, int, int, libquran_ctx *);
> LIBQURAN_SCOPE results_struct** quran_get_search_results(libquran_ctx *);
> LIBQURAN_SCOPE void             quran_free_search_results(libquran_ctx *);
> LIBQURAN_SCOPE void             free_q(void*);
> LIBQURAN_SCOPE void*            malloc_q(size_t);
> //LIBQURAN_SCOPE char*            quran_recitor_name(const char *, const char *);
diff -B -b libquran.cvs/quran_install_component.c libquran/quran_install_component.c
38c38
< 
---
> #ifndef _WIN32
370a371,380
> 
> #endif //!_WIN32
> 
> #ifdef _WIN32
> 
> int main(int argc, char * argv[]) {
> 	return 0;	
> }
> 
> #endif
diff -B -b libquran.cvs/search.c libquran/search.c
55c55
< int quran_search_quran(quran *q, const char *search_string, int type, int similarity, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE int quran_search_quran(quran *q, const char *search_string, int type, int similarity, libquran_ctx *ctx) {
85c85
< int quran_search_sura(quran *q, const char *search_string, int sura_no, int type, int similarity, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE int quran_search_sura(quran *q, const char *search_string, int sura_no, int type, int similarity, libquran_ctx *ctx) {
120c120
< int quran_search_juzz(quran *q, const char *search_string, int juzz_no, int type, int similarity, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE int quran_search_juzz(quran *q, const char *search_string, int juzz_no, int type, int similarity, libquran_ctx *ctx) {
160c160
< int quran_search_hezb(quran *q, const char *search_string, int hezb_no, int type, int similarity, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE int quran_search_hezb(quran *q, const char *search_string, int hezb_no, int type, int similarity, libquran_ctx *ctx) {
203c203
< int quran_search_part(quran *q, const char *search_string, int begin_sura, int begin_aya, int end_sura, int end_aya, int type, int similarity, libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE int quran_search_part(quran *q, const char *search_string, int begin_sura, int begin_aya, int end_sura, int end_aya, int type, int similarity, libquran_ctx *ctx) {
311c311
< results_struct **quran_get_search_results(libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE results_struct **quran_get_search_results(libquran_ctx *ctx) {
324c324
< void quran_free_search_results(libquran_ctx *ctx) {
---
> LIBQURAN_SCOPE void quran_free_search_results(libquran_ctx *ctx) {
diff -B -b libquran.cvs/testquran.c libquran/testquran.c
0a1,4
> #ifdef _WIN32
> #define LIBQURAN_DLL_IMPORT
> #endif
> 
30c34
< 	quran_free();
---
> 	quran_free(&ctx);