+/* 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;
+}
+