For static libs (.a) we need to pass the actual filename to winebuild,
not a -l switch. Do not remove the file extension to get to the base
name if it's not .exe or .exe.so. Link shell32 by default for GUI
programs. Fix parsing of options with arguments.

diff --git a/tools/winegcc/utils.c b/tools/winegcc/utils.c
index d1541e0..d9d716d 100644
--- a/tools/winegcc/utils.c
+++ b/tools/winegcc/utils.c
@@ -157,22 +157,18 @@
     fclose(file);
 }
 
-file_type get_file_type(const char* dir, const char* filename)
+file_type get_file_type(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 );
-
+    fd = open( filename, O_RDONLY );
     if (fd == -1) return file_na;
+    cnt = read(fd, buf, sizeof(buf));
+    close( fd );
+    if (cnt == -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;
@@ -185,46 +181,48 @@
     return file_other;
 }
 
-static file_type try_lib_path(const char* dir, const char* pre, 
-			      const char* library, const char* ext)
+static char* try_lib_path(const char* dir, const char* pre, 
+			  const char* library, const char* ext,
+			  file_type expected_type)
 {
     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);
+    fullname = strmake("%s/%s%s%s", dir, pre, library, ext);
+    if (verbose > 1) fprintf(stderr, "Try %s...", fullname);
+    type = get_file_type(fullname);
+    if (verbose > 1) fprintf(stderr, type == expected_type ? "FOUND!\n" : "no\n");
+    if (type == expected_type) return fullname;
     free( fullname );
-    if (verbose > 1) fprintf(stderr, type == file_na ? "no\n" : "FOUND!\n");
-    return type;
+    return 0; 
 }
 
-static file_type guess_lib_type(const char* dir, const char* library)
+static file_type guess_lib_type(const char* dir, const char* library, char** file)
 {
     /* Unix shared object */
-    if (try_lib_path(dir, "lib", library, ".so") == file_so)
+    if ((*file = try_lib_path(dir, "lib", library, ".so", file_so)))
 	return file_so;
 
     /* Windows DLL */
-    if (try_lib_path(dir, "lib", library, ".def") == file_dll)
+    if ((*file = try_lib_path(dir, "lib", library, ".def", file_dll)))
 	return file_dll;
-    if (try_lib_path(dir, "", library, ".def") == file_dll)
+    if ((*file = try_lib_path(dir, "", library, ".def", file_dll)))
 	return file_dll;
 
     /* Unix static archives */
-    if (try_lib_path(dir, "lib", library, ".a") == file_arh)
+    if ((*file = 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)
+file_type get_lib_type(strarray* path, const char* library, char** file)
 {
     int i;
 
     for (i = 0; i < path->size; i++)
     {
-        file_type type = guess_lib_type(path->base[i], library);
+        file_type type = guess_lib_type(path->base[i], library, file);
 	if (type != file_na) return type;
     }
     return file_na;
diff --git a/tools/winegcc/utils.h b/tools/winegcc/utils.h
index c0c0b4f..cf35c31 100644
--- a/tools/winegcc/utils.h
+++ b/tools/winegcc/utils.h
@@ -46,8 +46,8 @@
 
 char* get_basename(const char* file);
 void create_file(const char* name, const char* fmt, ...);
-file_type get_file_type(const char* dir, const char* filename);
-file_type get_lib_type(strarray* path, const char* library);
+file_type get_file_type(const char* filename);
+file_type get_lib_type(strarray* path, const char* library, char** file);
 void spawn(const strarray* arr);
 
 extern int verbose;
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c
index 5786a23..cfd0ffa 100644
--- a/tools/winegcc/winegcc.c
+++ b/tools/winegcc/winegcc.c
@@ -274,7 +274,10 @@
     if (opts->compile_only)
 	strarray_add(comp_args, "-c");
     if (opts->output_name)
-	strarray_add(comp_args, strmake("-o%s", opts->output_name));
+    {
+	strarray_add(comp_args, "-o");
+	strarray_add(comp_args, opts->output_name);
+    }
 
     /* the rest of the pass-through parameters */
     for ( j = 0 ; j < opts->compiler_args->size ; j++ ) 
@@ -324,12 +327,14 @@
     res_files = strarray_alloc();
     lib_paths = strarray_alloc();
 
-    output_name = opts->output_name ? opts->output_name : "a.out.exe";
+    output_name = opts->output_name ? opts->output_name : "a.out";
 
     /* get base filename by removing the .exe extension, if present */
     base_file = strdup(output_name);
-    if (strendswith(base_file, ".exe")) base_file[strlen(base_file) - 4] = 0;
-    base_name = get_basename(output_name);
+    if (strendswith(base_file, ".exe.so")) base_file[strlen(base_file) - 7] = 0;
+    else if (strendswith(base_file, ".exe")) base_file[strlen(base_file) - 4] = 0;
+    if ((base_name = strrchr(base_file, '/'))) base_name++;
+    else base_name = base_file;
 
     /* prepare the linking path */
     lib_dirs = strarray_dup(opts->lib_dirs);
@@ -343,21 +348,22 @@
     for ( j = 0; j < opts->lib_names->size; j++ )
     {
 	const char* name = opts->lib_names->base[j];
-	const char* lib = strmake("-l%s", name);
-	switch(get_lib_type(lib_dirs, name))
+	char* fullname;
+	switch(get_lib_type(lib_dirs, name, &fullname))
 	{
 	    case file_arh:
-		strarray_add(arh_libs, lib);
+		strarray_add(arh_libs, strdup(fullname));
 		break;
 	    case file_dll:
-		strarray_add(dll_libs, lib);
+		strarray_add(dll_libs, strmake("-l%s", name));
 		break;
 	    case file_so:
-		strarray_add(so_libs, lib);
+		strarray_add(so_libs, strmake("-l%s", name));
 		break;
 	    default:
-		fprintf(stderr, "Can't find library %s, ignoring\n", name);
+		fprintf(stderr, "Can't find library '%s', ignoring\n", name);
 	}
+	free(fullname);
     }
 
     if (!opts->nostdlib) 
@@ -369,10 +375,10 @@
     {
         if (opts->gui_app) 
 	{
+            strarray_add(dll_libs, "-lshell32");
 	    strarray_add(dll_libs, "-lcomdlg32");
 	    strarray_add(dll_libs, "-lgdi32");
 	}
-        strarray_add(dll_libs, "-lshell32");
         strarray_add(dll_libs, "-ladvapi32");
         strarray_add(dll_libs, "-luser32");
         strarray_add(dll_libs, "-lkernel32");
@@ -382,7 +388,7 @@
     for ( j = 0; j < opts->files->size; j++ )
     {
 	const char* file = opts->files->base[j];
-	switch(get_file_type(".", file))
+	switch(get_file_type(file))
 	{
 	    case file_rc:
 		/* FIXME: invoke wrc to build it */
@@ -452,7 +458,8 @@
     strarray_add(link_args, "-Wl,-Bsymbolic,-z,defs");
 #endif
 
-    strarray_add(link_args, strmake("-o%s.exe.so", base_file));
+    strarray_add(link_args, "-o");
+    strarray_add(link_args, strmake("%s.exe.so", base_file));
 
     for ( j = 0 ; j < opts->linker_args->size ; j++ ) 
         strarray_add(link_args, opts->linker_args->base[j]);
@@ -595,13 +602,14 @@
         if (argv[i][0] == '-')  /* option */
 	{
 	    /* determine if tihs switch is followed by a separate argument */
+	    next_is_arg = 0;
 	    option_arg = 0;
 	    switch(argv[i][1])
 	    {
 		case 'x': case 'o': case 'D': case 'U':
 		case 'I': case 'A': case 'l': case 'u':
 		case 'b': case 'V': case 'G':
-		    if (argv[i][2]) option_arg = argv[i] + 2;
+		    if (argv[i][2]) option_arg = &argv[i][2];
 		    else next_is_arg = 1;
 		    break;
 		case 'i':
@@ -619,7 +627,7 @@
 		    c = argv[i][2];
 		    if (c == 'F' || c == 'T' || c == 'Q')
 		    {
-			if (argv[i][3]) option_arg = argv[i] + 3;
+			if (argv[i][3]) option_arg = &argv[i][3];
 			else next_is_arg = 1;
 		    }
 		    break;
@@ -706,7 +714,7 @@
 			keep_generated = 1;
                     break;
                 case 'v':
-                    if (argv[i][2] == 0) verbose = 1;
+                    if (argv[i][2] == 0) verbose++;
                     break;
                 case 'W':
                     if (strncmp("-Wl,", argv[i], 4) == 0)