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);
 }