* readelf.c (process_file_header): Handle e_phnum extension.
[deliverable/binutils-gdb.git] / binutils / resrc.c
index 24b423d93e98f82056ba1912073c89d712dad74f..a72a23f631739b418018c9a8926fc7f34af90c1c 100644 (file)
@@ -1,5 +1,5 @@
 /* resrc.c -- read and write Windows rc files.
-   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
+   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008
    Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
    Rewritten by Kai Tietz, Onevision.
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -351,7 +351,33 @@ open_input_stream (char *cmd)
   return cpp_pipe;
 }
 
-/* look for the preprocessor program */
+/* Determine if FILENAME contains special characters that
+   can cause problems unless the entire filename is quoted.  */
+
+static int
+filename_need_quotes (const char *filename)
+{
+  if (filename == NULL || (filename[0] == '-' && filename[1] == 0))
+    return 0;
+
+  while (*filename != 0)
+    {
+      switch (*filename)
+        {
+        case '&':
+        case ' ':
+        case '<':
+        case '>':
+        case '|':
+        case '%':
+          return 1;
+        }
+      ++filename;
+    }
+  return 0;
+}
+
+/* Look for the preprocessor program.  */
 
 static FILE *
 look_for_default (char *cmd, const char *prefix, int end_prefix,
@@ -360,6 +386,7 @@ look_for_default (char *cmd, const char *prefix, int end_prefix,
   char *space;
   int found;
   struct stat s;
+  const char *fnquotes = (filename_need_quotes (filename) ? "\"" : "");
 
   strcpy (cmd, prefix);
 
@@ -390,8 +417,8 @@ look_for_default (char *cmd, const char *prefix, int end_prefix,
 
   strcpy (cmd, prefix);
 
-  sprintf (cmd + end_prefix, "%s %s %s",
-          DEFAULT_PREPROCESSOR, preprocargs, filename);
+  sprintf (cmd + end_prefix, "%s %s %s%s%s",
+          DEFAULT_PREPROCESSOR, preprocargs, fnquotes, filename, fnquotes);
 
   if (verbose)
     fprintf (stderr, _("Using `%s'\n"), cmd);
@@ -407,21 +434,60 @@ read_rc_file (const char *filename, const char *preprocessor,
              const char *preprocargs, int language, int use_temp_file)
 {
   char *cmd;
+  const char *fnquotes = (filename_need_quotes (filename) ? "\"" : "");
+
+  if (filename == NULL)
+    filename = "-";
+  /* Setup the default resource import path taken from input file.  */
+  else if (strchr (filename, '/') != NULL || strchr (filename, '\\') != NULL)
+    {
+      char *edit, *dir;
+
+      if (filename[0] == '/'
+         || filename[0] == '\\'
+         || filename[1] == ':')
+        /* Absolute path.  */
+       edit = dir = xstrdup (filename);
+      else
+       {
+         /* Relative path.  */
+         edit = dir = xmalloc (strlen (filename) + 3);
+         sprintf (dir, "./%s", filename);
+       }
+
+      /* Walk dir backwards stopping at the first directory separator.  */
+      edit += strlen (dir);
+      while (edit > dir && (edit[-1] != '\\' && edit[-1] != '/'))
+       {
+         --edit;
+         edit[0] = 0;
+       }
+
+      /* Cut off trailing slash.  */
+      --edit;
+      edit[0] = 0;
+
+      /* Convert all back slashes to forward slashes.  */
+      while ((edit = strchr (dir, '\\')) != NULL)
+       *edit = '/';
+
+      windres_add_include_dir (dir);
+    }
 
   istream_type = (use_temp_file) ? ISTREAM_FILE : ISTREAM_PIPE;
 
   if (preprocargs == NULL)
     preprocargs = "";
-  if (filename == NULL)
-    filename = "-";
 
   if (preprocessor)
     {
       cmd = xmalloc (strlen (preprocessor)
                     + strlen (preprocargs)
                     + strlen (filename)
+                    + strlen (fnquotes) * 2
                     + 10);
-      sprintf (cmd, "%s %s %s", preprocessor, preprocargs, filename);
+      sprintf (cmd, "%s %s %s%s%s", preprocessor, preprocargs,
+              fnquotes, filename, fnquotes);
 
       cpp_pipe = open_input_stream (cmd);
     }
@@ -435,6 +501,7 @@ read_rc_file (const char *filename, const char *preprocessor,
                     + strlen (preprocessor)
                     + strlen (preprocargs)
                     + strlen (filename)
+                    + strlen (fnquotes) * 2
 #ifdef HAVE_EXECUTABLE_SUFFIX
                     + strlen (EXECUTABLE_SUFFIX)
 #endif
@@ -528,7 +595,19 @@ close_input_stream (void)
   else
     {
       if (cpp_pipe != NULL)
-       pclose (cpp_pipe);
+        {
+         int err;
+         err = pclose (cpp_pipe);
+         /* We are reading from a pipe, therefore we don't
+             know if cpp failed or succeeded until pclose.  */
+         if (err != 0 || errno == ECHILD)
+           {
+             /* Since this is also run via xatexit, safeguard.  */
+             cpp_pipe = NULL;
+             cpp_temp_file = NULL;
+             fatal (_("preprocessing failed."));
+           }
+        }
     }
 
   /* Since this is also run via xatexit, safeguard.  */
@@ -606,7 +685,8 @@ get_data (FILE *e, bfd_byte *p, rc_uint_type c, const char *msg)
   if (got == c)
     return;
 
-  fatal (_("%s: read of %lu returned %lu"), msg, (long) c, (long) got);
+  fatal (_("%s: read of %lu returned %lu"),
+        msg, (unsigned long) c, (unsigned long) got);
 }
 \f
 /* Define an accelerator resource.  */
@@ -1846,7 +1926,7 @@ indent (FILE *e, int c)
    without the need to store it somewhere externally.  */
 
 void
-write_rc_file (const char *filename, const rc_res_directory *resources)
+write_rc_file (const char *filename, const rc_res_directory *res_dir)
 {
   FILE *e;
   rc_uint_type language;
@@ -1861,7 +1941,7 @@ write_rc_file (const char *filename, const rc_res_directory *resources)
     }
 
   language = (rc_uint_type) ((bfd_signed_vma) -1);
-  write_rc_directory (e, resources, (const rc_res_id *) NULL,
+  write_rc_directory (e, res_dir, (const rc_res_id *) NULL,
                      (const rc_res_id *) NULL, &language, 1);
 }
 
@@ -2982,10 +3062,10 @@ write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_
                      {
              if (k == 0)
                plen  = fprintf (e, "0x%lxL",
-                                (long) windres_get_32 (&wrtarget, data + i, length - i));
+                                (unsigned long) windres_get_32 (&wrtarget, data + i, length - i));
                        else
                plen = fprintf (e, " 0x%lxL",
-                               (long) windres_get_32 (&wrtarget, data + i, length - i)) - 1;
+                               (unsigned long) windres_get_32 (&wrtarget, data + i, length - i)) - 1;
              if (has_next || (i + 4) < length)
                          {
                  if (plen>0 && plen < 11)
@@ -3131,7 +3211,7 @@ write_rc_stringtable (FILE *e, const rc_res_id *name,
     {
       if (stringtable->strings[i].length != 0)
        {
-         fprintf (e, "  %lu, ", (long) offset + i);
+         fprintf (e, "  %lu, ", (unsigned long) offset + i);
          unicode_print_quoted (e, stringtable->strings[i].string,
                         stringtable->strings[i].length);
          fprintf (e, "\n");
This page took 0.025784 seconds and 4 git commands to generate.