+/* 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 (const char * message, va_list args)
+{
+ if (prog_name != NULL)
+ fprintf (stderr, "%s: ", prog_name);
+
+ vfprintf (stderr, message, args);
+ fputc ('\n', stderr);
+}
+
+
+static void
+inform VPARAMS ((const char *message, ...))
+{
+ VA_OPEN (args, message);
+ VA_FIXEDARG (args, const char *, message);
+
+ if (!verbose)
+ return;
+
+ display (message, args);
+
+ VA_CLOSE (args);
+}
+
+static void
+warn VPARAMS ((const char *format, ...))
+{
+ VA_OPEN (args, format);
+ VA_FIXEDARG (args, const char *, format);
+
+ display (format, args);
+
+ VA_CLOSE (args);
+}
+
+/* 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 (const char *progname, const char *prefix, int end_prefix)
+{
+ struct stat s;
+ char *cmd;
+
+ cmd = xmalloc (strlen (prefix)
+ + strlen (progname)
+#ifdef HAVE_EXECUTABLE_SUFFIX
+ + strlen (EXECUTABLE_SUFFIX)
+#endif
+ + 10);
+ strcpy (cmd, prefix);
+
+ sprintf (cmd + end_prefix, "%s", progname);
+
+ 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 (const char * name)
+{
+ char *cmd;
+ const char *dash;
+ const char *slash;
+ const char *cp;
+
+ dash = NULL;
+ slash = NULL;
+ for (cp = prog_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 NAME in the
+ PROG_NAME directory, with the same prefix as PROG_NAME. */
+ cmd = look_for_prog (name, prog_name, dash - prog_name + 1);
+
+ if (slash != NULL && cmd == NULL)
+ /* Next, try looking for a NAME in the same directory as
+ that of this program. */
+ cmd = look_for_prog (name, prog_name, slash - prog_name + 1);
+
+ if (cmd == NULL)
+ /* Just return NAME as is. */
+ cmd = xstrdup (name);
+
+ return cmd;
+}
+