Use an extendable array to store the lists of strings. Only make wrapper argument lists if we're going to use them.
diff --git a/tools/winegcc/Makefile.in b/tools/winegcc/Makefile.in index 21c00fc..4aedb58 100644 --- a/tools/winegcc/Makefile.in +++ b/tools/winegcc/Makefile.in
@@ -10,6 +10,7 @@ winewrap C_SRCS = \ + utils.c \ winegcc.c \ winewrap.c @@ -17,11 +18,11 @@ @MAKE_RULES@ -winegcc: winegcc.o - $(CC) $(CFLAGS) -o $@ winegcc.o $(LIBPORT) +winegcc: winegcc.o utils.o + $(CC) $(CFLAGS) -o $@ winegcc.o utils.o $(LIBPORT) -winewrap: winewrap.o - $(CC) $(CFLAGS) -o $@ winewrap.o $(LIBPORT) +winewrap: winewrap.o utils.o + $(CC) $(CFLAGS) -o $@ winewrap.o utils.o $(LIBPORT) install:: $(PROGRAMS) $(MKINSTALLDIRS) $(bindir)
diff --git a/tools/winegcc/utils.c b/tools/winegcc/utils.c new file mode 100644 index 0000000..bd7d7a5 --- /dev/null +++ b/tools/winegcc/utils.c
@@ -0,0 +1,127 @@ +/* + * Useful functions for winegcc/winewrap + * + * Copyright 2000 Francois Gouget + * Copyright 2002 Dimitrie O. Paun + * Copyright 2003 Richard Cohen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "config.h" +#include "wine/port.h" + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> +#include <errno.h> + +#include "utils.h" + +#if !defined(min) +# define min(x,y) (((x) < (y)) ? (x) : (y)) +#endif + +int verbose = 0; + +void error(const char *s, ...) +{ + va_list ap; + + va_start(ap, s); + fprintf(stderr, "Error: "); + vfprintf(stderr, s, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(2); +} + +void *xmalloc(size_t size) +{ + void *p; + if ((p = malloc (size)) == NULL) + error("Can not malloc %d bytes.", size); + + return p; +} + +void *xrealloc(void* p, size_t size) +{ + void* p2; + if ((p2 = realloc (p, size)) == NULL) + error("Can not realloc %d bytes.", size); + + return p2; +} + +char *strmake(const char *fmt, ...) +{ + int n; + size_t size = 100; + char *p; + va_list ap; + p = xmalloc (size); + + while (1) + { + va_start(ap, fmt); + n = vsnprintf (p, size, fmt, ap); + va_end(ap); + if (n > -1 && n < size) return p; + size = min( size*2, n+1 ); + p = xrealloc (p, size); + } +} + +strarray *strarray_alloc(void) +{ + strarray *arr = xmalloc(sizeof(*arr)); + arr->maximum = arr->size = 0; + arr->base = NULL; + return arr; +} + +void strarray_free(strarray* arr) +{ + free(arr->base); + free(arr); +} + +void strarray_add(strarray* arr, char* str) +{ + if (arr->size == arr->maximum) + { + arr->maximum += 10; + arr->base = xrealloc(arr->base, sizeof(*(arr->base)) * arr->maximum); + } + arr->base[arr->size++] = str; +} + +void spawn(strarray* arr) +{ + int i, status; + char **argv = arr->base; + + if (verbose) + { + for(i = 0; argv[i]; i++) printf("%s ", argv[i]); + printf("\n"); + } + if (!(status = spawnvp( _P_WAIT, argv[0], argv))) return; + + if (status > 0) error("%s failed.", argv[0]); + else perror("Error:"); + exit(3); +}
diff --git a/tools/winegcc/utils.h b/tools/winegcc/utils.h new file mode 100644 index 0000000..c01c57f --- /dev/null +++ b/tools/winegcc/utils.h
@@ -0,0 +1,42 @@ +/* + * Useful functions for winegcc/winewrap + * + * Copyright 2000 Francois Gouget + * Copyright 2002 Dimitrie O. Paun + * Copyright 2003 Richard Cohen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +void error(const char *s, ...); + +void *xmalloc(size_t size); +void *xrealloc(void* p, size_t size); +char *strmake(const char *fmt, ...); + +typedef struct { + size_t maximum; + size_t size; + char** base; +} strarray; + +strarray *strarray_alloc(void); +void strarray_free(strarray* arr); +void strarray_add(strarray* arr, char* str); + +void spawn(strarray* arr); + +extern int verbose;
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index e5a143d..b5c17f4 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c
@@ -27,63 +27,13 @@ #include <stdarg.h> #include <string.h> #include <errno.h> -#include <sys/stat.h> -static char **tmp_files; -static int nb_tmp_files; -static int verbose = 0; +#include "utils.h" + static int keep_generated = 0; +static strarray *tmp_files; -void error(const char *s, ...) -{ - va_list ap; - - va_start(ap, s); - fprintf(stderr, "Error: "); - vfprintf(stderr, s, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(2); -} - -char *strmake(const char *fmt, ...) -{ - int n, size = 100; - char *p; - va_list ap; - - if ((p = malloc (size)) == NULL) - error("Can not malloc %d bytes.", size); - - while (1) - { - va_start(ap, fmt); - n = vsnprintf (p, size, fmt, ap); - va_end(ap); - if (n > -1 && n < size) return p; - size *= 2; - if ((p = realloc (p, size)) == NULL) - error("Can not realloc %d bytes.", size); - } -} - -void spawn(char *const argv[]) -{ - int i, status; - - if (verbose) - { - for(i = 0; argv[i]; i++) printf("%s ", argv[i]); - printf("\n"); - } - if (!(status = spawnvp( _P_WAIT, argv[0], argv))) return; - - if (status > 0) error("%s failed.", argv[0]); - else perror("Error:"); - exit(3); -} - -int strendswith(const char *str, const char *end) +static int strendswith(const char *str, const char *end) { int l = strlen(str); int m = strlen(end); @@ -91,17 +41,18 @@ return l >= m && strcmp(str + l - m, end) == 0; } -void clean_temp_files() +static void clean_temp_files() { - int i; - - if (keep_generated) return; - - for (i = 0; i < nb_tmp_files; i++) - unlink(tmp_files[i]); + if (!keep_generated) + { + int i; + for (i = 0; i < tmp_files->size; i++) + unlink(tmp_files->base[i]); + } + strarray_free(tmp_files); } -char *get_temp_file(const char *suffix) +static char *get_temp_file(const char *suffix) { char *tmp = strmake("wgcc.XXXXXX%s", suffix); int fd = mkstemps( tmp, strlen(suffix) ); @@ -114,33 +65,34 @@ if (fd == -1) error( "could not create temp file" ); } close( fd ); - tmp_files = realloc( tmp_files, (nb_tmp_files+1) * sizeof(*tmp_files) ); - tmp_files[nb_tmp_files++] = tmp; + strarray_add(tmp_files, tmp); return tmp; } -char *get_obj_file(char **argv, int n) +static char *get_obj_file(char **argv, int n) { - char *tmpobj, **compargv; - int i, j; + char *tmpobj; + strarray* compargv; + int j; if (strendswith(argv[n], ".o")) return argv[n]; if (strendswith(argv[n], ".a")) return argv[n]; if (strendswith(argv[n], ".res")) return argv[n]; tmpobj = get_temp_file(".o"); - compargv = malloc(sizeof(char*) * (n + 10)); - i = 0; - compargv[i++] = "winegcc"; - compargv[i++] = "-c"; - compargv[i++] = "-o"; - compargv[i++] = tmpobj; + + compargv = strarray_alloc(); + strarray_add(compargv,"winegcc"); + strarray_add(compargv, "-c"); + strarray_add(compargv, "-o"); + strarray_add(compargv, tmpobj); for (j = 1; j <= n; j++) - if (argv[j]) compargv[i++] = argv[j]; - compargv[i] = 0; + if (argv[j]) strarray_add(compargv, argv[j]); + strarray_add(compargv, NULL); spawn(compargv); + strarray_free(compargv); return tmpobj; } @@ -148,11 +100,12 @@ int main(int argc, char **argv) { - char **gcc_argv; + strarray *gcc_argv; int i, j; int linking = 1, cpp = 0, use_static_linking = 0; int use_stdinc = 1, use_stdlib = 1, use_msvcrt = 0, gui_app = 0; + tmp_files = strarray_alloc(); atexit(clean_temp_files); if (strendswith(argv[0], "++")) cpp = 1; @@ -210,23 +163,29 @@ if (use_static_linking) error("Static linking is not supported."); - gcc_argv = malloc(sizeof(char*) * (argc + 20)); + gcc_argv = strarray_alloc(); i = 0; if (linking) { int has_output_name = 0; int has_input_files = 0; - char **temp_argv; - /* we need this to erase some of the parameters as we go along */ - temp_argv = malloc(sizeof(char*) * argc); - memcpy(temp_argv, argv, sizeof(char*) * argc); + strarray *copy_argv; - gcc_argv[i++] = "winewrap"; - if (gui_app) gcc_argv[i++] = "-mgui"; + /* we need a copy in case we decide to pass args straight to gcc + * and we erase some of the original parameters as we go along + */ + copy_argv = strarray_alloc(); + strarray_add(copy_argv, cpp ? "g++" : "gcc"); + for( j = 1; j < argc ; j++ ) + strarray_add(copy_argv, argv[j]); - if (cpp) gcc_argv[i++] = "-C"; + strarray_add(gcc_argv, "winewrap"); + if (gui_app) strarray_add(gcc_argv, "-mgui"); + + if (cpp) strarray_add(gcc_argv, "-C"); + for ( j = 1 ; j < argc ; j++ ) { if ( argv[j][0] == '-' ) @@ -235,18 +194,18 @@ { case 'L': case 'o': - gcc_argv[i++] = argv[j]; - temp_argv[j] = 0; - if (!gcc_argv[i-1][2] && j + 1 < argc) + strarray_add(gcc_argv, argv[j]); + if (!argv[j][2] && j + 1 < argc) { - gcc_argv[i++] = argv[++j]; - temp_argv[j] = 0; + argv[j] = 0; + strarray_add(gcc_argv, argv[++j]); } has_output_name = 1; + argv[j] = 0; break; case 'l': - gcc_argv[i++] = strcmp(argv[j], "-luuid") ? argv[j] : "-lwine_uuid"; - temp_argv[j] = 0; + strarray_add(gcc_argv, strcmp(argv[j], "-luuid") ? argv[j] : "-lwine_uuid"); + argv[j] = 0; break; default: ; /* ignore the rest */ @@ -254,8 +213,8 @@ } else { - gcc_argv[i++] = get_obj_file(temp_argv, j); - temp_argv[j] = 0; + strarray_add(gcc_argv, get_obj_file(argv, j)); + argv[j] = 0; has_input_files = 1; } } @@ -265,71 +224,70 @@ /* Support the a.out default name, to appease configure */ if (!has_output_name) { - gcc_argv[i++] = "-o"; - gcc_argv[i++] = "a.out"; + strarray_add(gcc_argv, "-o"); + strarray_add(gcc_argv, "a.out"); } - if (use_stdlib && use_msvcrt) gcc_argv[i++] = "-lmsvcrt"; - if (gui_app) gcc_argv[i++] = "-lcomdlg32"; - gcc_argv[i++] = "-ladvapi32"; - gcc_argv[i++] = "-lshell32"; + if (use_stdlib && use_msvcrt) strarray_add(gcc_argv, "-lmsvcrt"); + if (gui_app) strarray_add(gcc_argv, "-lcomdlg32"); + strarray_add(gcc_argv, "-ladvapi32"); + strarray_add(gcc_argv, "-lshell32"); } else { /* if we have nothing to process, just forward stuff to gcc */ - memcpy(gcc_argv, argv, sizeof(char*) * argc); - gcc_argv[0] = cpp ? "g++" : "gcc"; - i = argc; + strarray_free(gcc_argv); + gcc_argv = copy_argv; } } else { - gcc_argv[i++] = cpp ? "g++" : "gcc"; + strarray_add(gcc_argv, cpp ? "g++" : "gcc"); - gcc_argv[i++] = "-fshort-wchar"; - gcc_argv[i++] = "-fPIC"; - if (use_stdinc) - { - if (use_msvcrt) - { - gcc_argv[i++] = "-I" INCLUDEDIR "/msvcrt"; - gcc_argv[i++] = "-D__MSVCRT__"; - } - gcc_argv[i++] = "-I" INCLUDEDIR "/windows"; - } - gcc_argv[i++] = "-DWIN32"; - gcc_argv[i++] = "-D_WIN32"; - gcc_argv[i++] = "-D__WIN32"; - gcc_argv[i++] = "-D__WIN32__"; - gcc_argv[i++] = "-D__WINNT"; - gcc_argv[i++] = "-D__WINNT__"; + strarray_add(gcc_argv, "-fshort-wchar"); + strarray_add(gcc_argv, "-fPIC"); + if (use_stdinc) + { + if (use_msvcrt) + { + strarray_add(gcc_argv, "-I" INCLUDEDIR "/msvcrt"); + strarray_add(gcc_argv, "-D__MSVCRT__"); + } + strarray_add(gcc_argv, "-I" INCLUDEDIR "/windows"); + } + strarray_add(gcc_argv, "-DWIN32"); + strarray_add(gcc_argv, "-D_WIN32"); + strarray_add(gcc_argv, "-D__WIN32"); + strarray_add(gcc_argv, "-D__WIN32__"); + strarray_add(gcc_argv, "-D__WINNT"); + strarray_add(gcc_argv, "-D__WINNT__"); - gcc_argv[i++] = "-D__stdcall=__attribute__((__stdcall__))"; - gcc_argv[i++] = "-D__cdecl=__attribute__((__cdecl__))"; - gcc_argv[i++] = "-D__fastcall=__attribute__((__fastcall__))"; - gcc_argv[i++] = "-D_stdcall=__attribute__((__stdcall__))"; - gcc_argv[i++] = "-D_cdecl=__attribute__((__cdecl__))"; - gcc_argv[i++] = "-D_fastcall=__attribute__((__fastcall__))"; - gcc_argv[i++] = "-D__declspec(x)=__declspec_##x"; - gcc_argv[i++] = "-D__declspec_align(x)=__attribute__((aligned(x)))"; - gcc_argv[i++] = "-D__declspec_allocate(x)=__attribute__((section(x)))"; - gcc_argv[i++] = "-D__declspec_deprecated=__attribute__((deprecated))"; - gcc_argv[i++] = "-D__declspec_dllimport=__attribute__((dllimport))"; - gcc_argv[i++] = "-D__declspec_dllexport=__attribute__((dllexport))"; - gcc_argv[i++] = "-D__declspec_naked=__attribute__((naked))"; - gcc_argv[i++] = "-D__declspec_noinline=__attribute__((noinline))"; - gcc_argv[i++] = "-D__declspec_noreturn=__attribute__((noreturn))"; - gcc_argv[i++] = "-D__declspec_nothrow=__attribute__((nothrow))"; - gcc_argv[i++] = "-D__declspec_novtable=__attribute__(())"; /* ignore it */ - gcc_argv[i++] = "-D__declspec_selectany=__attribute__((weak))"; - gcc_argv[i++] = "-D__declspec_thread=__thread"; - - /* Wine specific defines */ - gcc_argv[i++] = "-D__WINE__"; - gcc_argv[i++] = "-DWINE_UNICODE_NATIVE"; - gcc_argv[i++] = "-D__int8=char"; - gcc_argv[i++] = "-D__int16=short"; - gcc_argv[i++] = "-D__int32=int"; - gcc_argv[i++] = "-D__int64=long long"; + strarray_add(gcc_argv, "-D__stdcall=__attribute__((__stdcall__))"); + strarray_add(gcc_argv, "-D__cdecl=__attribute__((__cdecl__))"); + strarray_add(gcc_argv, "-D__fastcall=__attribute__((__fastcall__))"); + strarray_add(gcc_argv, "-D_stdcall=__attribute__((__stdcall__))"); + strarray_add(gcc_argv, "-D_cdecl=__attribute__((__cdecl__))"); + strarray_add(gcc_argv, "-D_fastcall=__attribute__((__fastcall__))"); + strarray_add(gcc_argv, "-D__declspec(x)=__declspec_##x"); + strarray_add(gcc_argv, "-D__declspec_align(x)=__attribute__((aligned(x)))"); + strarray_add(gcc_argv, "-D__declspec_allocate(x)=__attribute__((section(x)))"); + strarray_add(gcc_argv, "-D__declspec_deprecated=__attribute__((deprecated))"); + strarray_add(gcc_argv, "-D__declspec_dllimport=__attribute__((dllimport))"); + strarray_add(gcc_argv, "-D__declspec_dllexport=__attribute__((dllexport))"); + strarray_add(gcc_argv, "-D__declspec_naked=__attribute__((naked))"); + strarray_add(gcc_argv, "-D__declspec_noinline=__attribute__((noinline))"); + strarray_add(gcc_argv, "-D__declspec_noreturn=__attribute__((noreturn))"); + strarray_add(gcc_argv, "-D__declspec_nothrow=__attribute__((nothrow))"); + strarray_add(gcc_argv, "-D__declspec_novtable=__attribute__(())"); /* ignore it */ + strarray_add(gcc_argv, "-D__declspec_selectany=__attribute__((weak))"); + strarray_add(gcc_argv, "-D__declspec_thread=__thread"); + + /* Wine specific defines */ + strarray_add(gcc_argv, "-D__WINE__"); + strarray_add(gcc_argv, "-DWINE_UNICODE_NATIVE"); + strarray_add(gcc_argv, "-D__int8=char"); + strarray_add(gcc_argv, "-D__int16=short"); + strarray_add(gcc_argv, "-D__int32=int"); + strarray_add(gcc_argv, "-D__int64=long long"); for ( j = 1 ; j < argc ; j++ ) { @@ -346,13 +304,15 @@ else if (strcmp("-s", argv[j]) == 0) ; /* ignore this option */ else - gcc_argv[i++] = argv[j]; + strarray_add(gcc_argv, argv[j]); } } - gcc_argv[i] = NULL; + strarray_add(gcc_argv, NULL); spawn(gcc_argv); + strarray_free(gcc_argv); + return 0; }
diff --git a/tools/winegcc/winewrap.c b/tools/winegcc/winewrap.c index 8f92853..6f3ca9d 100644 --- a/tools/winegcc/winewrap.c +++ b/tools/winegcc/winewrap.c
@@ -29,6 +29,8 @@ #include <errno.h> #include <sys/stat.h> +#include "utils.h" + #ifndef WINEDLLS #define WINEDLLS "/usr/local/lib/wine" #endif @@ -213,50 +215,15 @@ ; static char *output_name; -static char **arh_files, **dll_files, **lib_files, **lib_paths, **obj_files; -static int nb_arh_files, nb_dll_files, nb_lib_files, nb_lib_paths, nb_obj_files; -static int verbose = 0; +static strarray *arh_files, *dll_files, *lib_files, *lib_paths, *obj_files; static int keep_generated = 0; -void error(const char *s, ...) -{ - va_list ap; - - va_start(ap, s); - fprintf(stderr, "Error: "); - vfprintf(stderr, s, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(2); -} - -char *strmake(const char *fmt, ...) -{ - int n, size = 100; - char *p; - va_list ap; - - if ((p = malloc (size)) == NULL) - error("Can not malloc %d bytes.", size); - - while (1) - { - va_start(ap, fmt); - n = vsnprintf (p, size, fmt, ap); - va_end(ap); - if (n > -1 && n < size) return p; - size *= 2; - if ((p = realloc (p, size)) == NULL) - error("Can not realloc %d bytes.", size); - } -} - -void rm_temp_file(const char *file) +static void rm_temp_file(const char *file) { if (!keep_generated) unlink(file); } -void create_file(const char *name, const char *fmt, ...) +static void create_file(const char *name, const char *fmt, ...) { va_list ap; FILE *file; @@ -270,23 +237,7 @@ fclose(file); } -void spawn(char *const argv[]) -{ - int i, status; - - if (verbose) - { - for(i = 0; argv[i]; i++) printf("%s ", argv[i]); - printf("\n"); - } - if (!(status = spawnvp( _P_WAIT, argv[0], argv))) return; - - if (status > 0) error("%s failed.", argv[0]); - else perror("Error:"); - exit(3); -} - -int is_resource(const char* file) +static int is_resource(const char* file) { /* see tools/winebuild/res32.c: check_header for details */ static const char res_sig[] = { 0,0,0,0, 32,0,0,0, 0xff,0xff, 0,0, 0xff,0xff, 0,0, 0,0,0,0, 0,0, 0,0, 0,0,0,0, 0,0,0,0 }; @@ -334,14 +285,14 @@ } /* open the .def library for a given dll */ -static char *open_dll(const char *name) +static char *find_dll(const char *name) { char *fullname; int i; - for (i = 0; i < nb_lib_paths; i++) + for (i = 0; i < lib_paths->size; i++) { - if ((fullname = try_dll_path( lib_paths[i], name ))) return fullname; + if ((fullname = try_dll_path( lib_paths->base[i], name ))) return fullname; } return try_dll_path( ".", name ); } @@ -353,9 +304,9 @@ char *fullname; int i; - for (i = 0; i < nb_lib_paths; i++) + for (i = 0; i < lib_paths->size; i++) { - if ((fullname = try_lib_path( lib_paths[i], name ))) return fullname; + if ((fullname = try_lib_path( lib_paths->base[i], name ))) return fullname; } for (i = 0; i < sizeof(std_paths)/sizeof(std_paths[0]); i++) @@ -366,48 +317,127 @@ return 0; } -void add_lib_path(const char* path) +static void add_lib_path(const char* path) { - lib_paths = realloc( lib_paths, (nb_lib_paths+1) * sizeof(*lib_paths) ); - lib_paths[nb_lib_paths++] = strdup(path); - dll_files = realloc( dll_files, (nb_dll_files+1) * sizeof(*dll_files) ); - dll_files[nb_dll_files++] = strmake("-L%s", path); - lib_files = realloc( lib_files, (nb_lib_files+1) * sizeof(*lib_files) ); - lib_files[nb_lib_files++] = strmake("-L%s", path); + strarray_add(lib_paths, strdup(path)); + strarray_add(dll_files, strmake("-L%s", path)); + strarray_add(lib_files, strmake("-L%s", path)); } -void add_lib_file(const char* library) +static void add_lib_file(const char* library) { char *lib; - if (open_dll(library)) + if (find_dll(library)) { - dll_files = realloc( dll_files, (nb_dll_files+1) * sizeof(*dll_files) ); - dll_files[nb_dll_files++] = strmake("-l%s", library); + strarray_add(dll_files, strmake("-l%s", library)); } else if ((lib = find_lib(library))) { - arh_files = realloc( arh_files, (nb_arh_files+1) * sizeof(*arh_files) ); - arh_files[nb_arh_files++] = lib; + strarray_add(arh_files, lib); } else { - lib_files = realloc( lib_files, (nb_lib_files+1) * sizeof(*lib_files) ); - lib_files[nb_lib_files++] = strmake("-l%s", library); + strarray_add(lib_files, strmake("-l%s", library)); } } +static void create_the_wrapper(char* base_file, char* base_name, int gui_mode, int cpp) +{ + char *wrp_temp_name, *wspec_name, *wspec_c_name, *wspec_o_name; + char *wrap_c_name, *wrap_o_name; + strarray *wwrap_args, *wspec_args, *wcomp_args, *wlink_args; + int i; + + wrp_temp_name = tempnam(0, "wwrp"); + wspec_name = strmake("%s.spec", wrp_temp_name); + wspec_c_name = strmake("%s.c", wspec_name); + wspec_o_name = strmake("%s.o", wspec_name); + + wrap_c_name = strmake("%s.c", wrp_temp_name); + wrap_o_name = strmake("%s.o", wrp_temp_name); + + /* build wrapper compile argument list */ + wwrap_args = strarray_alloc(); + strarray_add(wwrap_args, "gcc"); + strarray_add(wwrap_args, "-fPIC"); + strarray_add(wwrap_args, "-I" INCLUDEDIR "/windows"); + strarray_add(wwrap_args, "-o"); + strarray_add(wwrap_args, wrap_o_name); + strarray_add(wwrap_args, "-c"); + strarray_add(wwrap_args, wrap_c_name); + strarray_add(wwrap_args, NULL); + + create_file(wrap_c_name, wrapper_code, base_name, gui_mode); + spawn(wwrap_args); + strarray_free(wwrap_args); + rm_temp_file(wrap_c_name); + + /* build wrapper winebuild's argument list */ + wspec_args = strarray_alloc(); + strarray_add(wspec_args, "winebuild"); + strarray_add(wspec_args, "-o"); + strarray_add(wspec_args, wspec_c_name); + strarray_add(wspec_args, "--exe"); + strarray_add(wspec_args, strmake("%s.exe", base_name)); + strarray_add(wspec_args, gui_mode ? "-mgui" : "-mcui"); + strarray_add(wspec_args, wrap_o_name); + for (i = 0; i < lib_files->size; i++) + strarray_add(wspec_args, lib_files->base[i]); + for (i = 0; i < dll_files->size; i++) + strarray_add(wspec_args, dll_files->base[i]); + strarray_add(wspec_args, NULL); + + spawn(wspec_args); + strarray_free(wspec_args); + + /* build wrapper gcc's argument list */ + wcomp_args = strarray_alloc(); + strarray_add(wcomp_args, "gcc"); + strarray_add(wcomp_args, "-fPIC"); + strarray_add(wcomp_args, "-o"); + strarray_add(wcomp_args, wspec_o_name); + strarray_add(wcomp_args, "-c"); + strarray_add(wcomp_args, wspec_c_name); + strarray_add(wcomp_args, NULL); + + spawn(wcomp_args); + strarray_free(wcomp_args); + rm_temp_file(wspec_c_name); + + /* build wrapper ld's argument list */ + wlink_args = strarray_alloc(); + strarray_add(wlink_args, cpp ? "g++" : "gcc"); + strarray_add(wlink_args, "-shared"); + strarray_add(wlink_args, "-Wl,-Bsymbolic,-z,defs"); + strarray_add(wlink_args, "-lwine"); + strarray_add(wlink_args, "-ldl"); + strarray_add(wlink_args, "-o"); + strarray_add(wlink_args, strmake("%s.exe.so", base_file)); + strarray_add(wlink_args, wspec_o_name); + strarray_add(wlink_args, wrap_o_name); + strarray_add(wlink_args, NULL); + + spawn(wlink_args); + strarray_free(wlink_args); + rm_temp_file(wspec_o_name); + rm_temp_file(wrap_o_name); +} + int main(int argc, char **argv) { char *library = 0, *path = 0; - int i, j, len, cpp = 0, no_opt = 0, gui_mode = 0, create_wrapper = -1; - char *base_name, *base_file, *app_temp_name, *wrp_temp_name; + int i, len, cpp = 0, no_opt = 0, gui_mode = 0, create_wrapper = -1; + char *base_name, *base_file, *app_temp_name; char *spec_name, *spec_c_name, *spec_o_name; - char *wspec_name, *wspec_c_name, *wspec_o_name; - char *wrap_c_name, *wrap_o_name; - char **spec_args, **comp_args, **link_args; - char **wwrap_args, **wspec_args, **wcomp_args, **wlink_args; - + strarray *spec_args, *comp_args, *link_args; + + arh_files = strarray_alloc(); + dll_files = strarray_alloc(); + lib_files = strarray_alloc(); + lib_paths = strarray_alloc(); + obj_files = strarray_alloc(); + /* include the standard DLL path first */ add_lib_path(WINEDLLS); @@ -468,8 +498,7 @@ } /* it's a filename, add it to its list */ - obj_files = realloc( obj_files, (nb_obj_files+1) * sizeof(*obj_files) ); - obj_files[nb_obj_files++] = strdup(argv[i]); + strarray_add(obj_files, strdup(argv[i])); } /* create wrapper only in C++ by default */ @@ -481,8 +510,6 @@ add_lib_file("kernel32"); app_temp_name = tempnam(0, "wapp"); - wrp_temp_name = tempnam(0, "wwrp"); - /* get base filename by removing the .exe extension, if present */ base_file = strdup(output_name); len = strlen(base_file); @@ -497,151 +524,83 @@ spec_c_name = strmake("%s.c", spec_name); spec_o_name = strmake("%s.o", spec_name); - wspec_name = strmake("%s.spec", wrp_temp_name); - wspec_c_name = strmake("%s.c", wspec_name); - wspec_o_name = strmake("%s.o", wspec_name); - - wrap_c_name = strmake("%s.c", wrp_temp_name); - wrap_o_name = strmake("%s.o", wrp_temp_name); - /* build winebuild's argument list */ - spec_args = malloc( (nb_arh_files + nb_dll_files + nb_obj_files + 20) * sizeof (char *) ); - j = 0; - spec_args[j++] = "winebuild"; - spec_args[j++] = "-o"; - spec_args[j++] = spec_c_name; - if (create_wrapper) - { - spec_args[j++] = "-F"; - spec_args[j++] = strmake("%s-wrap.dll", base_name); - spec_args[j++] = "--spec"; - spec_args[j++] = spec_name; - } - else - { - spec_args[j++] = "--exe"; - spec_args[j++] = strmake("%s.exe", base_name); - spec_args[j++] = gui_mode ? "-mgui" : "-mcui"; - } - for (i = 0; i < nb_dll_files; i++) - spec_args[j++] = dll_files[i]; - for (i = 0; i < nb_obj_files; i++) - spec_args[j++] = obj_files[i]; - for (i = 0; i < nb_arh_files; i++) - spec_args[j++] = arh_files[i]; - spec_args[j] = 0; - - /* build gcc's argument list */ - comp_args = malloc ( 20 * sizeof (char *) ); - j = 0; - comp_args[j++] = "gcc"; - comp_args[j++] = "-fPIC"; - comp_args[j++] = "-o"; - comp_args[j++] = spec_o_name; - comp_args[j++] = "-c"; - comp_args[j++] = spec_c_name; - comp_args[j] = 0; - - /* build ld's argument list */ - link_args = malloc( (nb_arh_files + nb_obj_files + nb_lib_files + 20) * sizeof (char *) ); - j = 0; - link_args[j++] = cpp ? "g++" : "gcc"; - link_args[j++] = "-shared"; - link_args[j++] = "-Wl,-Bsymbolic,-z,defs"; - link_args[j++] = "-lwine"; - link_args[j++] = "-lm"; - for (i = 0; i < nb_lib_files; i++) - link_args[j++] = lib_files[i]; - link_args[j++] = "-o"; - if (create_wrapper) link_args[j++] = strmake("%s-wrap.dll.so", base_file); - else link_args[j++] = strmake("%s.exe.so", base_file); - link_args[j++] = spec_o_name; - for (i = 0; i < nb_obj_files; i++) - if (!is_resource(obj_files[i])) link_args[j++] = obj_files[i]; - for (i = 0; i < nb_arh_files; i++) - link_args[j++] = arh_files[i]; - link_args[j] = 0; - - /* build wrapper compile argument list */ - wwrap_args = malloc ( 20 * sizeof (char *) ); - j = 0; - wwrap_args[j++] = "gcc"; - wwrap_args[j++] = "-fPIC"; - wwrap_args[j++] = "-I" INCLUDEDIR "/windows"; - wwrap_args[j++] = "-o"; - wwrap_args[j++] = wrap_o_name; - wwrap_args[j++] = "-c"; - wwrap_args[j++] = wrap_c_name; - wwrap_args[j] = 0; - - /* build wrapper winebuild's argument list */ - wspec_args = malloc( (nb_dll_files + 20) * sizeof (char *) ); - j = 0; - wspec_args[j++] = "winebuild"; - wspec_args[j++] = "-o"; - wspec_args[j++] = wspec_c_name; - wspec_args[j++] = "--exe"; - wspec_args[j++] = strmake("%s.exe", base_name); - wspec_args[j++] = gui_mode ? "-mgui" : "-mcui"; - wspec_args[j++] = wrap_o_name; - for (i = 0; i < nb_dll_files; i++) - wspec_args[j++] = dll_files[i]; - wspec_args[j] = 0; - - /* build wrapper gcc's argument list */ - wcomp_args = malloc ( 20 * sizeof (char *) ); - j = 0; - wcomp_args[j++] = "gcc"; - wcomp_args[j++] = "-fPIC"; - wcomp_args[j++] = "-o"; - wcomp_args[j++] = wspec_o_name; - wcomp_args[j++] = "-c"; - wcomp_args[j++] = wspec_c_name; - wcomp_args[j] = 0; - - /* build wrapper ld's argument list */ - wlink_args = malloc( 20 * sizeof (char *) ); - j = 0; - wlink_args[j++] = cpp ? "g++" : "gcc"; - wlink_args[j++] = "-shared"; - wlink_args[j++] = "-Wl,-Bsymbolic,-z,defs"; - wlink_args[j++] = "-lwine"; - wlink_args[j++] = "-ldl"; - wlink_args[j++] = "-o"; - wlink_args[j++] = strmake("%s.exe.so", base_file); - wlink_args[j++] = wspec_o_name; - wlink_args[j++] = wrap_o_name; - wlink_args[j] = 0; - - /* run winebuild to get the .spec.c file */ + spec_args = strarray_alloc(); + strarray_add(spec_args, "winebuild"); + strarray_add(spec_args, "-o"); + strarray_add(spec_args, spec_c_name); if (create_wrapper) { create_file(spec_name, gui_mode ? app_gui_spec : app_cui_spec); - spawn(spec_args); - rm_temp_file(spec_name); - spawn(comp_args); - rm_temp_file(spec_c_name); - spawn(link_args); - rm_temp_file(spec_o_name); - - create_file(wrap_c_name, wrapper_code, base_name, gui_mode); - spawn(wwrap_args); - rm_temp_file(wrap_c_name); - spawn(wspec_args); - spawn(wcomp_args); - rm_temp_file(wspec_c_name); - spawn(wlink_args); - rm_temp_file(wspec_o_name); - rm_temp_file(wrap_o_name); + strarray_add(spec_args, "-F"); + strarray_add(spec_args, strmake("%s-wrap.dll", base_name)); + strarray_add(spec_args, "--spec"); + strarray_add(spec_args, spec_name); } else { - spawn(spec_args); - spawn(comp_args); - rm_temp_file(spec_c_name); - spawn(link_args); - rm_temp_file(spec_o_name); + strarray_add(spec_args, "--exe"); + strarray_add(spec_args, strmake("%s.exe", base_name)); + strarray_add(spec_args, gui_mode ? "-mgui" : "-mcui"); } + for (i = 0; i < dll_files->size; i++) + strarray_add(spec_args, dll_files->base[i]); + for (i = 0; i < obj_files->size; i++) + strarray_add(spec_args, obj_files->base[i]); + for (i = 0; i < arh_files->size; i++) + strarray_add(spec_args, arh_files->base[i]); + strarray_add(spec_args, NULL); + + /* run winebuild to get the .spec.c file */ + spawn(spec_args); + strarray_free(spec_args); + + if (create_wrapper) + rm_temp_file(spec_name); + + /* build gcc's argument list */ + comp_args = strarray_alloc(); + strarray_add(comp_args, "gcc"); + strarray_add(comp_args, "-fPIC"); + strarray_add(comp_args, "-o"); + strarray_add(comp_args, spec_o_name); + strarray_add(comp_args, "-c"); + strarray_add(comp_args, spec_c_name); + strarray_add(comp_args, NULL); + + spawn(comp_args); + strarray_free(comp_args); + rm_temp_file(spec_c_name); + + /* build ld's argument list */ + link_args = strarray_alloc(); + strarray_add(link_args, cpp ? "g++" : "gcc"); + strarray_add(link_args, "-shared"); + strarray_add(link_args, "-Wl,-Bsymbolic,-z,defs"); + strarray_add(link_args, "-lwine"); + strarray_add(link_args, "-lm"); + for (i = 0; i < lib_files->size; i++) + strarray_add(link_args, lib_files->base[i]); + strarray_add(link_args, "-o"); + if (create_wrapper) + strarray_add(link_args, strmake("%s-wrap.dll.so", base_file)); + else + strarray_add(link_args, strmake("%s.exe.so", base_file)); + strarray_add(link_args, spec_o_name); + + for (i = 0; i < obj_files->size; i++) + if (!is_resource(obj_files->base[i])) + strarray_add(link_args, obj_files->base[i]); + for (i = 0; i < arh_files->size; i++) + strarray_add(link_args, arh_files->base[i]); + strarray_add(link_args, NULL); + + spawn(link_args); + strarray_free(link_args); + rm_temp_file(spec_o_name); + + if (create_wrapper) + create_the_wrapper(base_file, base_name, gui_mode, cpp); /* create the loader script */ create_file(base_file, app_loader_script, base_name);