Merge winewrap into winegcc. Many cleanups.
diff --git a/tools/winegcc/utils.c b/tools/winegcc/utils.c
index 61d4857..d1541e0 100644
--- a/tools/winegcc/utils.c
+++ b/tools/winegcc/utils.c
@@ -36,7 +36,7 @@
int verbose = 0;
-void error(const char *s, ...)
+void error(const char* s, ...)
{
va_list ap;
@@ -48,9 +48,10 @@
exit(2);
}
-void *xmalloc(size_t size)
+void* xmalloc(size_t size)
{
- void *p;
+ void* p;
+
if ((p = malloc (size)) == NULL)
error("Can not malloc %d bytes.", size);
@@ -66,14 +67,22 @@
return p2;
}
-char *strmake(const char *fmt, ...)
+int strendswith(const char* str, const char* end)
+{
+ int l = strlen(str);
+ int m = strlen(end);
+
+ return l >= m && strcmp(str + l - m, end) == 0;
+}
+
+char* strmake(const char* fmt, ...)
{
int n;
size_t size = 100;
- char *p;
+ char* p;
va_list ap;
- p = xmalloc (size);
+ p = xmalloc (size);
while (1)
{
va_start(ap, fmt);
@@ -85,9 +94,9 @@
}
}
-strarray *strarray_alloc(void)
+strarray* strarray_alloc(void)
{
- strarray *arr = xmalloc(sizeof(*arr));
+ strarray* arr = xmalloc(sizeof(*arr));
arr->maximum = arr->size = 0;
arr->base = NULL;
return arr;
@@ -109,19 +118,137 @@
arr->base[arr->size++] = str;
}
-void spawn(const strarray* arr)
+strarray* strarray_dup(const strarray* arr)
+{
+ strarray* dup = strarray_alloc();
+ int i;
+
+ for (i = 0; i < arr->size; i++)
+ strarray_add(dup, arr->base[i]);
+
+ return dup;
+}
+
+char* get_basename(const char* file)
+{
+ const char* name;
+ char *base_name, *p;
+
+ if ((name = strrchr(file, '/'))) name++;
+ else name = file;
+
+ base_name = strdup(name);
+ if ((p = strrchr(base_name, '.'))) *p = 0;
+
+ return base_name;
+}
+
+void create_file(const char* name, const char* fmt, ...)
+{
+ va_list ap;
+ FILE *file;
+
+ if (verbose) printf("Creating file %s\n", name);
+ va_start(ap, fmt);
+ if ( !(file = fopen(name, "w")) )
+ error ("Can not create %s.", name);
+ vfprintf(file, fmt, ap);
+ va_end(ap);
+ fclose(file);
+}
+
+file_type get_file_type(const char* dir, const char* filename)
+{
+ /* 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 };
+ char buf[sizeof(res_sig)];
+ char *fullname;
+ int fd, cnt;
+
+ fullname = strmake("%s/%s", dir, filename);
+ fd = open( fullname, O_RDONLY );
+ cnt = read(fd, buf, sizeof(buf));
+ if (cnt == -1) error("Can't read file: %s/%s", dir, filename);
+ free( fullname );
+ close( fd );
+
+ if (fd == -1) return file_na;
+
+ if (cnt == sizeof(res_sig) && !memcmp(buf, res_sig, sizeof(res_sig))) return file_res;
+ if (strendswith(filename, ".o")) return file_obj;
+ if (strendswith(filename, ".a")) return file_arh;
+ if (strendswith(filename, ".res")) return file_res;
+ if (strendswith(filename, ".so")) return file_so;
+ if (strendswith(filename, ".def")) return file_dll;
+ if (strendswith(filename, ".rc")) return file_rc;
+
+ return file_other;
+}
+
+static file_type try_lib_path(const char* dir, const char* pre,
+ const char* library, const char* ext)
+{
+ char *fullname;
+ file_type type;
+
+ fullname = strmake("%s%s%s", pre, library, ext);
+ if (verbose > 1) fprintf(stderr, "Try %s/%s...", dir, fullname);
+ type = get_file_type(dir, fullname);
+ free( fullname );
+ if (verbose > 1) fprintf(stderr, type == file_na ? "no\n" : "FOUND!\n");
+ return type;
+}
+
+static file_type guess_lib_type(const char* dir, const char* library)
+{
+ /* Unix shared object */
+ if (try_lib_path(dir, "lib", library, ".so") == file_so)
+ return file_so;
+
+ /* Windows DLL */
+ if (try_lib_path(dir, "lib", library, ".def") == file_dll)
+ return file_dll;
+ if (try_lib_path(dir, "", library, ".def") == file_dll)
+ return file_dll;
+
+ /* Unix static archives */
+ if (try_lib_path(dir, "lib", library, ".a") == file_arh)
+ return file_arh;
+
+ return file_na;
+}
+
+file_type get_lib_type(strarray* path, const char* library)
+{
+ int i;
+
+ for (i = 0; i < path->size; i++)
+ {
+ file_type type = guess_lib_type(path->base[i], library);
+ if (type != file_na) return type;
+ }
+ return file_na;
+}
+
+void spawn(const strarray* args)
{
int i, status;
+ strarray* arr = strarray_dup(args);
const char **argv = arr->base;
+ strarray_add(arr, NULL);
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);
+ if ((status = spawnvp( _P_WAIT, argv[0], argv)))
+ {
+ if (status > 0) error("%s failed.", argv[0]);
+ else perror("Error:");
+ exit(3);
+ }
+
+ strarray_free(arr);
}