Fix copyright comments and file comments.
[deliverable/binutils-gdb.git] / binutils / dllwrap.c
index 574611b3dd97b009f3ca3fcb0113fe37def10120..637fa52fc17ff76002085b3cefed1421a6a1e220 100644 (file)
@@ -1,5 +1,5 @@
 /* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    Contributed by Mumit Khan (khan@xraylith.wisc.edu).
 
    This file is part of GNU Binutils.
 #endif
 #endif
 
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #include "bfd.h"
 #include "libiberty.h"
 #include "bucomm.h"
 
 #include <ctype.h>
 #include <time.h>
+#include <sys/stat.h>
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
 
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
@@ -82,8 +78,7 @@
 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
 #endif /* ! HAVE_SYS_WAIT_H */
 
-static char *program_version = "0.2.4";
-static char *driver_name = "gcc";
+static char *driver_name = NULL;
 static char *cygwin_driver_flags = 
   "-Wl,--dll -nostartfiles";
 static char *mingw32_driver_flags = "-mdll";
@@ -91,14 +86,14 @@ static char *generic_driver_flags = "-Wl,--dll";
 
 static char *entry_point;
 
-static char *dlltool_name = "dlltool";
+static char *dlltool_name = NULL;
 
 static char *target = TARGET;
 
 typedef enum {
   UNKNOWN_TARGET, 
   CYGWIN_TARGET, 
-  MINGW32_TARGET
+  MINGW_TARGET
 } 
 target_type;
 
@@ -122,20 +117,225 @@ static int delete_def_file = 1;
 
 static int run PARAMS ((const char *, char *));
 static void usage PARAMS ((FILE *, int));
+static void display PARAMS ((const char *, va_list));
+static void inform PARAMS ((const char *, ...));
+static void warn PARAMS ((const char *format, ...));
+static char *look_for_prog PARAMS ((const char *, const char *, int));
+static char *deduce_name PARAMS ((const char *));
 static void delete_temp_files PARAMS ((void));
 static void cleanup_and_exit PARAMS ((int status));
 
 /**********************************************************************/
 
+/* Please keep the following 4 routines in sync with dlltool.c:
+     display ()
+     inform ()
+     look_for_prog ()
+     deduce_name ()
+   It's not worth the hassle to break these out since dllwrap will
+   (hopefully) soon be retired in favor of `ld --shared.  */
+
+static void
+display (message, args)
+     const char * message;
+     va_list      args;
+{
+  if (program_name != NULL)
+    fprintf (stderr, "%s: ", program_name);
+
+  vfprintf (stderr, message, args);
+  fputc ('\n', stderr);
+}
+
+
+#ifdef __STDC__
+static void
+inform (const char * message, ...)
+{
+  va_list args;
+
+  if (!verbose)
+    return;
+
+  va_start (args, message);
+  display (message, args);
+  va_end (args);
+}
+
+static void
+warn (const char *format, ...)
+{
+  va_list args;
+
+  va_start (args, format);
+  display (format, args);
+  va_end (args);
+}
+#else
+
+static void
+inform (message, va_alist)
+     const char * message;
+     va_dcl
+{
+  va_list args;
+
+  if (!verbose)
+    return;
+
+  va_start (args);
+  display (message, args);
+  va_end (args);
+}
+
+static void
+warn (format, va_alist)
+     const char *format;
+     va_dcl
+{
+  va_list args;
+
+  va_start (args);
+  display (format, args);
+  va_end (args);
+}
+#endif
+
+/* Look for the program formed by concatenating PROG_NAME and the
+   string running from PREFIX to END_PREFIX.  If the concatenated
+   string contains a '/', try appending EXECUTABLE_SUFFIX if it is
+   appropriate.  */
+
+static char *
+look_for_prog (prog_name, prefix, end_prefix)
+     const char *prog_name;
+     const char *prefix;
+     int end_prefix;
+{
+  struct stat s;
+  char *cmd;
+
+  cmd = xmalloc (strlen (prefix) 
+                 + strlen (prog_name) 
+#ifdef HAVE_EXECUTABLE_SUFFIX
+                 + strlen (EXECUTABLE_SUFFIX) 
+#endif
+                + 10);
+  strcpy (cmd, prefix);
+
+  sprintf (cmd + end_prefix, "%s", prog_name);
+
+  if (strchr (cmd, '/') != NULL)
+    {
+      int found;
+
+      found = (stat (cmd, &s) == 0
+#ifdef HAVE_EXECUTABLE_SUFFIX
+               || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
+#endif
+              );
+
+      if (! found)
+        {
+         /* xgettext:c-format */
+         inform (_("Tried file: %s"), cmd);
+         free (cmd);
+         return NULL;
+       }
+    }
+
+  /* xgettext:c-format */
+  inform (_("Using file: %s"), cmd);
+
+  return cmd;
+}
+
+/* Deduce the name of the program we are want to invoke.
+   PROG_NAME is the basic name of the program we want to run,
+   eg "as" or "ld".  The catch is that we might want actually
+   run "i386-pe-as" or "ppc-pe-ld".  
+
+   If argv[0] contains the full path, then try to find the program
+   in the same place, with and then without a target-like prefix.
+
+   Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
+   deduce_name("as") uses the following search order: 
+
+     /usr/local/bin/i586-cygwin32-as
+     /usr/local/bin/as
+     as
+   
+   If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
+   name, it'll try without and then with EXECUTABLE_SUFFIX.
+
+   Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
+   as the fallback, but rather return i586-cygwin32-as.
+     
+   Oh, and given, argv[0] = dlltool, it'll return "as".
+
+   Returns a dynamically allocated string.  */
+
+static char *
+deduce_name (prog_name)
+     const char *prog_name;
+{
+  char *cmd;
+  char *dash, *slash, *cp;
+
+  dash = NULL;
+  slash = NULL;
+  for (cp = program_name; *cp != '\0'; ++cp)
+    {
+      if (*cp == '-')
+       dash = cp;
+      if (
+#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
+         *cp == ':' || *cp == '\\' ||
+#endif
+         *cp == '/')
+       {
+         slash = cp;
+         dash = NULL;
+       }
+    }
+
+  cmd = NULL;
+
+  if (dash != NULL)
+    {
+      /* First, try looking for a prefixed PROG_NAME in the
+         PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME.  */
+      cmd = look_for_prog (prog_name, program_name, dash - program_name + 1);
+    }
+
+  if (slash != NULL && cmd == NULL)
+    {
+      /* Next, try looking for a PROG_NAME in the same directory as
+         that of this program.  */
+      cmd = look_for_prog (prog_name, program_name, slash - program_name + 1);
+    }
+
+  if (cmd == NULL)
+    {
+      /* Just return PROG_NAME as is.  */
+      cmd = xstrdup (prog_name);
+    }
+
+  return cmd;
+}
+
 static void
 delete_temp_files ()
 {
   if (delete_base_file && base_file_name)
     {
       if (verbose)
-       fprintf (stderr, "%s temporary base file %s\n",
-                dontdeltemps ? "Keeping" : "Deleting",
-                base_file_name);
+       {
+         if (dontdeltemps)
+           warn (_("Keeping temporary base file %s"), base_file_name);
+         else
+           warn (_("Deleting temporary base file %s"), base_file_name);
+       }
       if (! dontdeltemps)
         {
           unlink (base_file_name);
@@ -146,9 +346,12 @@ delete_temp_files ()
   if (delete_exp_file && exp_file_name)
     {
       if (verbose)
-       fprintf (stderr, "%s temporary exp file %s\n",
-                dontdeltemps ? "Keeping" : "Deleting",
-                exp_file_name);
+       {
+         if (dontdeltemps)
+           warn (_("Keeping temporary exp file %s"), exp_file_name);
+         else
+           warn (_("Deleting temporary exp file %s"), exp_file_name);
+       }
       if (! dontdeltemps)
         {
           unlink (exp_file_name);
@@ -158,9 +361,12 @@ delete_temp_files ()
   if (delete_def_file && def_file_name)
     {
       if (verbose)
-       fprintf (stderr, "%s temporary def file %s\n",
-                dontdeltemps ? "Keeping" : "Deleting",
-                def_file_name);
+       {
+         if (dontdeltemps)
+           warn (_("Keeping temporary def file %s"), def_file_name);
+         else
+           warn (_("Deleting temporary def file %s"), def_file_name);
+       }
       if (! dontdeltemps)
         {
           unlink (def_file_name);
@@ -242,21 +448,19 @@ run (what, args)
   pid = pwait (pid, &wait_status, 0);
   if (pid == -1)
     {
-      fprintf (stderr, "%s: wait: %s\n", program_name, strerror (errno));
+      warn ("wait: %s", strerror (errno));
       retcode = 1;
     }
   else if (WIFSIGNALED (wait_status))
     {
-      fprintf (stderr, "%s: subprocess got fatal signal %d\n",
-              program_name, WTERMSIG (wait_status));
+      warn (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
       retcode = 1;
     }
   else if (WIFEXITED (wait_status))
     {
       if (WEXITSTATUS (wait_status) != 0)
        {
-         fprintf (stderr, "%s: %s exited with status %d\n",
-                  program_name, what, WEXITSTATUS (wait_status));
+         warn (_("%s exited with status %d"), what, WEXITSTATUS (wait_status));
          retcode = 1;
        }
     }
@@ -308,60 +512,47 @@ strhash (const char *str)
 
 /**********************************************************************/
 
-void
-print_version (name)
-     const char *name;
-{
-  /* This output is intended to follow the GNU standards document.  */
-  /* xgettext:c-format */
-  printf ("GNU %s %s\n", name, program_version);
-  printf ("Copyright 1998 Free Software Foundation, Inc.\n");
-  printf ("\
-This program is free software; you may redistribute it under the terms of\n\
-the GNU General Public License.  This program has absolutely no warranty.\n");
-  exit (0);
-}
-
 static void
 usage (file, status)
      FILE *file;
      int status;
 {
-  fprintf (file, "Usage %s <options> <object-files>\n", program_name);
-  fprintf (file, "  Generic options:\n");
-  fprintf (file, "   --quiet, -q            Work quietly\n");
-  fprintf (file, "   --verbose, -v          Verbose\n");
-  fprintf (file, "   --version              Print dllwrap version\n");
-  fprintf (file, "   --implib <outname>     Synonym for --output-lib\n");
-  fprintf (file, "  Options for %s:\n", program_name);
-  fprintf (file, "   --driver-name <driver> Defaults to \"gcc\"\n");
-  fprintf (file, "   --driver-flags <flags> Override default ld flags\n");
-  fprintf (file, "   --dlltool-name <dlltool> Defaults to \"dlltool\"\n");
-  fprintf (file, "   --entry <entry>        Specify alternate DLL entry point\n");
-  fprintf (file, "   --image-base <base>    Specify image base address\n");
-  fprintf (file, "   --target <machine>     i386-cygwin32 or i386-mingw32\n");
-  fprintf (file, "   --dry-run              Show what needs to be run\n");
-  fprintf (file, "  Options passed to DLLTOOL:\n");
-  fprintf (file, "   --machine <machine>\n");
-  fprintf (file, "   --output-exp <outname> Generate export file.\n");
-  fprintf (file, "   --output-lib <outname> Generate input library.\n");
-  fprintf (file, "   --add-indirect         Add dll indirects to export file.\n");
-  fprintf (file, "   --dllname <name>       Name of input dll to put into output lib.\n");
-  fprintf (file, "   --def <deffile>        Name input .def file\n");
-  fprintf (file, "   --output-def <deffile> Name output .def file\n");
-  fprintf (file, "   --export-all-symbols     Export all symbols to .def\n");
-  fprintf (file, "   --no-export-all-symbols  Only export .drectve symbols\n");
-  fprintf (file, "   --exclude-symbols <list> Exclude <list> from .def\n");
-  fprintf (file, "   --no-default-excludes    Zap default exclude symbols\n");
-  fprintf (file, "   --base-file <basefile> Read linker generated base file\n");
-  fprintf (file, "   --no-idata4           Don't generate idata$4 section\n");
-  fprintf (file, "   --no-idata5           Don't generate idata$5 section\n");
-  fprintf (file, "   -U                     Add underscores to .lib\n");
-  fprintf (file, "   -k                     Kill @<n> from exported names\n");
-  fprintf (file, "   --add-stdcall-alias    Add aliases without @<n>\n");
-  fprintf (file, "   --as <name>            Use <name> for assembler\n");
-  fprintf (file, "   --nodelete             Keep temp files.\n");
-  fprintf (file, "  Rest are passed unmodified to the language driver\n");
+  fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
+  fprintf (file, _("  Generic options:\n"));
+  fprintf (file, _("   --quiet, -q            Work quietly\n"));
+  fprintf (file, _("   --verbose, -v          Verbose\n"));
+  fprintf (file, _("   --version              Print dllwrap version\n"));
+  fprintf (file, _("   --implib <outname>     Synonym for --output-lib\n"));
+  fprintf (file, _("  Options for %s:\n"), program_name);
+  fprintf (file, _("   --driver-name <driver> Defaults to \"gcc\"\n"));
+  fprintf (file, _("   --driver-flags <flags> Override default ld flags\n"));
+  fprintf (file, _("   --dlltool-name <dlltool> Defaults to \"dlltool\"\n"));
+  fprintf (file, _("   --entry <entry>        Specify alternate DLL entry point\n"));
+  fprintf (file, _("   --image-base <base>    Specify image base address\n"));
+  fprintf (file, _("   --target <machine>     i386-cygwin32 or i386-mingw32\n"));
+  fprintf (file, _("   --dry-run              Show what needs to be run\n"));
+  fprintf (file, _("   --mno-cygwin           Create Mingw DLL\n"));
+  fprintf (file, _("  Options passed to DLLTOOL:\n"));
+  fprintf (file, _("   --machine <machine>\n"));
+  fprintf (file, _("   --output-exp <outname> Generate export file.\n"));
+  fprintf (file, _("   --output-lib <outname> Generate input library.\n"));
+  fprintf (file, _("   --add-indirect         Add dll indirects to export file.\n"));
+  fprintf (file, _("   --dllname <name>       Name of input dll to put into output lib.\n"));
+  fprintf (file, _("   --def <deffile>        Name input .def file\n"));
+  fprintf (file, _("   --output-def <deffile> Name output .def file\n"));
+  fprintf (file, _("   --export-all-symbols     Export all symbols to .def\n"));
+  fprintf (file, _("   --no-export-all-symbols  Only export .drectve symbols\n"));
+  fprintf (file, _("   --exclude-symbols <list> Exclude <list> from .def\n"));
+  fprintf (file, _("   --no-default-excludes    Zap default exclude symbols\n"));
+  fprintf (file, _("   --base-file <basefile> Read linker generated base file\n"));
+  fprintf (file, _("   --no-idata4           Don't generate idata$4 section\n"));
+  fprintf (file, _("   --no-idata5           Don't generate idata$5 section\n"));
+  fprintf (file, _("   -U                     Add underscores to .lib\n"));
+  fprintf (file, _("   -k                     Kill @<n> from exported names\n"));
+  fprintf (file, _("   --add-stdcall-alias    Add aliases without @<n>\n"));
+  fprintf (file, _("   --as <name>            Use <name> for assembler\n"));
+  fprintf (file, _("   --nodelete             Keep temp files.\n"));
+  fprintf (file, _("  Rest are passed unmodified to the language driver\n"));
   fprintf (file, "\n\n");
   exit (status);
 }
@@ -381,9 +572,10 @@ usage (file, status)
 #define OPTION_ENTRY           (OPTION_DLLTOOL_NAME + 1)
 #define OPTION_IMAGE_BASE      (OPTION_ENTRY + 1)
 #define OPTION_TARGET          (OPTION_IMAGE_BASE + 1)
+#define OPTION_MNO_CYGWIN      (OPTION_TARGET + 1)
 
 /* DLLTOOL options. */
-#define OPTION_NODELETE                (OPTION_TARGET + 1)
+#define OPTION_NODELETE                (OPTION_MNO_CYGWIN + 1)
 #define OPTION_DLLNAME         (OPTION_NODELETE + 1)
 #define OPTION_NO_IDATA4       (OPTION_DLLNAME + 1)
 #define OPTION_NO_IDATA5       (OPTION_NO_IDATA4 + 1)
@@ -441,7 +633,7 @@ static const struct option long_options[] =
   {"add-indirect", no_argument, NULL, OPTION_ADD_INDIRECT},
   {"base-file", required_argument, NULL, OPTION_BASE_FILE},
   {"as", required_argument, NULL, OPTION_AS},
-  {0}
+  {0, 0, 0, 0}
 };
 
 int
@@ -568,6 +760,9 @@ main (argc, argv)
        case OPTION_TARGET:
          target = optarg;
          break;
+       case OPTION_MNO_CYGWIN:
+         target = "i386-mingw32";
+         break;
        case OPTION_BASE_FILE:
          base_file_name = optarg;
          delete_base_file = 0;
@@ -614,13 +809,11 @@ main (argc, argv)
            } 
        }
     }
-  
+
   /* sanity checks. */
   if (! dll_name && ! dll_file_name)
     {
-      fprintf (stderr,
-               "%s: Must provide at least one of -o or --dllname options\n",
-               program_name);
+      warn (_("Must provide at least one of -o or --dllname options"));
       exit (1);
     }
   else if (! dll_name)
@@ -631,7 +824,14 @@ main (argc, argv)
     {
       dll_file_name = xstrdup (dll_name);
     }
-  
+
+  /* Deduce driver-name and dlltool-name from our own. */
+  if (driver_name == NULL)
+    driver_name = deduce_name ("gcc");
+
+  if (dlltool_name == NULL)
+    dlltool_name = deduce_name ("dlltool");
+
   if (! def_file_seen)
     {
       char *fileprefix = choose_temp_base ();
@@ -641,16 +841,15 @@ main (argc, argv)
       delete_def_file = 1;
       free (fileprefix);
       delete_def_file = 1;
-      fprintf (stderr, "Warning: no export definition file provided\n");
-      fprintf (stderr, 
-               "dllwrap will create one, but may not be what you want\n");
+      warn (_("no export definition file provided"));
+      warn (_("creating one, but that may not be what you want"));
     }
   
   /* set the target platform. */
-  if (strstr (target, "cygwin32"))
+  if (strstr (target, "cygwin"))
     which_target = CYGWIN_TARGET;
-  else if (strstr (target, "mingw32"))
-    which_target = MINGW32_TARGET;
+  else if (strstr (target, "mingw"))
+    which_target = MINGW_TARGET;
   else 
     which_target = UNKNOWN_TARGET;
 
@@ -686,7 +885,7 @@ main (argc, argv)
           driver_flags = cygwin_driver_flags;
          break;
        
-       case MINGW32_TARGET:
+       case MINGW_TARGET:
           driver_flags = mingw32_driver_flags;
          break;
        
@@ -707,7 +906,7 @@ main (argc, argv)
          entry_point = "__cygwin_dll_entry@12";
          break;
        
-       case MINGW32_TARGET:
+       case MINGW_TARGET:
          entry_point = "_DllMainCRTStartup@12";
          break;
        
@@ -804,10 +1003,10 @@ main (argc, argv)
 
   if (verbose)
     {
-      fprintf (stderr, "DLLTOOL name    : %s\n", dlltool_name);
-      fprintf (stderr, "DLLTOOL options : %s\n", dlltool_cmdline->s);
-      fprintf (stderr, "DRIVER name     : %s\n", driver_name);
-      fprintf (stderr, "DRIVER options  : %s\n", driver_cmdline->s);
+      fprintf (stderr, _("DLLTOOL name    : %s\n"), dlltool_name);
+      fprintf (stderr, _("DLLTOOL options : %s\n"), dlltool_cmdline->s);
+      fprintf (stderr, _("DRIVER name     : %s\n"), driver_name);
+      fprintf (stderr, _("DRIVER options  : %s\n"), driver_cmdline->s);
     }
  
   /*
This page took 0.030552 seconds and 4 git commands to generate.