Home | History | Annotate | Download | only in binutils
      1 /* windres.c -- a program to manipulate Windows resources
      2    Copyright (C) 1997-2016 Free Software Foundation, Inc.
      3    Written by Ian Lance Taylor, Cygnus Support.
      4    Rewritten by Kai Tietz, Onevision.
      5 
      6    This file is part of GNU Binutils.
      7 
      8    This program is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3 of the License, or
     11    (at your option) any later version.
     12 
     13    This program is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program; if not, write to the Free Software
     20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
     21    02110-1301, USA.  */
     22 
     23 /* This program can read and write Windows resources in various
     24    formats.  In particular, it can act like the rc resource compiler
     25    program, and it can act like the cvtres res to COFF conversion
     26    program.
     27 
     28    It is based on information taken from the following sources:
     29 
     30    * Microsoft documentation.
     31 
     32    * The rcl program, written by Gunther Ebert
     33      <gunther.ebert (at) ixos-leipzig.de>.
     34 
     35    * The res2coff program, written by Pedro A. Aranda <paag (at) tid.es>.  */
     36 
     37 #include "sysdep.h"
     38 #include <assert.h>
     39 #include "bfd.h"
     40 #include "getopt.h"
     41 #include "bucomm.h"
     42 #include "libiberty.h"
     43 #include "safe-ctype.h"
     44 #include "obstack.h"
     45 #include "windres.h"
     46 
     47 /* Used by resrc.c at least.  */
     48 
     49 int verbose = 0;
     50 
     51 int target_is_bigendian = 0;
     52 const char *def_target_arch;
     53 
     54 static void set_endianness (bfd *, const char *);
     55 
     56 /* An enumeration of format types.  */
     57 
     58 enum res_format
     59 {
     60   /* Unknown format.  */
     61   RES_FORMAT_UNKNOWN,
     62   /* Textual RC file.  */
     63   RES_FORMAT_RC,
     64   /* Binary RES file.  */
     65   RES_FORMAT_RES,
     66   /* COFF file.  */
     67   RES_FORMAT_COFF
     68 };
     69 
     70 /* A structure used to map between format types and strings.  */
     71 
     72 struct format_map
     73 {
     74   const char *name;
     75   enum res_format format;
     76 };
     77 
     78 /* A mapping between names and format types.  */
     79 
     80 static const struct format_map format_names[] =
     81 {
     82   { "rc", RES_FORMAT_RC },
     83   { "res", RES_FORMAT_RES },
     84   { "coff", RES_FORMAT_COFF },
     85   { NULL, RES_FORMAT_UNKNOWN }
     86 };
     87 
     88 /* A mapping from file extensions to format types.  */
     89 
     90 static const struct format_map format_fileexts[] =
     91 {
     92   { "rc", RES_FORMAT_RC },
     93   { "res", RES_FORMAT_RES },
     94   { "exe", RES_FORMAT_COFF },
     95   { "obj", RES_FORMAT_COFF },
     96   { "o", RES_FORMAT_COFF },
     97   { NULL, RES_FORMAT_UNKNOWN }
     98 };
     99 
    100 /* A list of include directories.  */
    101 
    102 struct include_dir
    103 {
    104   struct include_dir *next;
    105   char *dir;
    106 };
    107 
    108 static struct include_dir *include_dirs;
    109 
    110 /* Static functions.  */
    111 
    112 static void res_init (void);
    113 static int extended_menuitems (const rc_menuitem *);
    114 static enum res_format format_from_name (const char *, int);
    115 static enum res_format format_from_filename (const char *, int);
    116 static void usage (FILE *, int);
    117 static int cmp_res_entry (const void *, const void *);
    118 static rc_res_directory *sort_resources (rc_res_directory *);
    119 static void reswr_init (void);
    120 static const char * quot (const char *);
    121 
    122 static rc_uint_type target_get_8 (const void *, rc_uint_type);
    124 static void target_put_8 (void *, rc_uint_type);
    125 static rc_uint_type target_get_16 (const void *, rc_uint_type);
    126 static void target_put_16 (void *, rc_uint_type);
    127 static rc_uint_type target_get_32 (const void *, rc_uint_type);
    128 static void target_put_32 (void *, rc_uint_type);
    129 
    130 
    131 /* When we are building a resource tree, we allocate everything onto
    133    an obstack, so that we can free it all at once if we want.  */
    134 
    135 #define obstack_chunk_alloc xmalloc
    136 #define obstack_chunk_free free
    137 
    138 /* The resource building obstack.  */
    139 
    140 static struct obstack res_obstack;
    141 
    142 /* Initialize the resource building obstack.  */
    143 
    144 static void
    145 res_init (void)
    146 {
    147   obstack_init (&res_obstack);
    148 }
    149 
    150 /* Allocate space on the resource building obstack.  */
    151 
    152 void *
    153 res_alloc (rc_uint_type bytes)
    154 {
    155   return obstack_alloc (&res_obstack, (size_t) bytes);
    156 }
    157 
    158 /* We also use an obstack to save memory used while writing out a set
    159    of resources.  */
    160 
    161 static struct obstack reswr_obstack;
    162 
    163 /* Initialize the resource writing obstack.  */
    164 
    165 static void
    166 reswr_init (void)
    167 {
    168   obstack_init (&reswr_obstack);
    169 }
    170 
    171 /* Allocate space on the resource writing obstack.  */
    172 
    173 void *
    174 reswr_alloc (rc_uint_type bytes)
    175 {
    176   return obstack_alloc (&reswr_obstack, (size_t) bytes);
    177 }
    178 
    179 /* Open a file using the include directory search list.  */
    181 
    182 FILE *
    183 open_file_search (const char *filename, const char *mode, const char *errmsg,
    184 		  char **real_filename)
    185 {
    186   FILE *e;
    187   struct include_dir *d;
    188 
    189   e = fopen (filename, mode);
    190   if (e != NULL)
    191     {
    192       *real_filename = xstrdup (filename);
    193       return e;
    194     }
    195 
    196   if (errno == ENOENT)
    197     {
    198       for (d = include_dirs; d != NULL; d = d->next)
    199 	{
    200 	  char *n;
    201 
    202 	  n = (char *) xmalloc (strlen (d->dir) + strlen (filename) + 2);
    203 	  sprintf (n, "%s/%s", d->dir, filename);
    204 	  e = fopen (n, mode);
    205 	  if (e != NULL)
    206 	    {
    207 	      *real_filename = n;
    208 	      return e;
    209 	    }
    210 	  free (n);
    211 
    212 	  if (errno != ENOENT)
    213 	    break;
    214 	}
    215     }
    216 
    217   fatal (_("can't open %s `%s': %s"), errmsg, filename, strerror (errno));
    218 
    219   /* Return a value to avoid a compiler warning.  */
    220   return NULL;
    221 }
    222 
    223 /* Compare two resource ID's.  We consider name entries to come before
    225    numeric entries, because that is how they appear in the COFF .rsrc
    226    section.  */
    227 
    228 int
    229 res_id_cmp (rc_res_id a, rc_res_id b)
    230 {
    231   if (! a.named)
    232     {
    233       if (b.named)
    234 	return 1;
    235       if (a.u.id > b.u.id)
    236 	return 1;
    237       else if (a.u.id < b.u.id)
    238 	return -1;
    239       else
    240 	return 0;
    241     }
    242   else
    243     {
    244       unichar *as, *ase, *bs, *bse;
    245 
    246       if (! b.named)
    247 	return -1;
    248 
    249       as = a.u.n.name;
    250       ase = as + a.u.n.length;
    251       bs = b.u.n.name;
    252       bse = bs + b.u.n.length;
    253 
    254       while (as < ase)
    255 	{
    256 	  int i;
    257 
    258 	  if (bs >= bse)
    259 	    return 1;
    260 	  i = (int) *as - (int) *bs;
    261 	  if (i != 0)
    262 	    return i;
    263 	  ++as;
    264 	  ++bs;
    265 	}
    266 
    267       if (bs < bse)
    268 	return -1;
    269 
    270       return 0;
    271     }
    272 }
    273 
    274 /* Print a resource ID.  */
    275 
    276 void
    277 res_id_print (FILE *stream, rc_res_id id, int quote)
    278 {
    279   if (! id.named)
    280     fprintf (stream, "%u", (int) id.u.id);
    281   else
    282     {
    283       if (quote)
    284 	unicode_print_quoted (stream, id.u.n.name, id.u.n.length);
    285       else
    286       unicode_print (stream, id.u.n.name, id.u.n.length);
    287     }
    288 }
    289 
    290 /* Print a list of resource ID's.  */
    291 
    292 void
    293 res_ids_print (FILE *stream, int cids, const rc_res_id *ids)
    294 {
    295   int i;
    296 
    297   for (i = 0; i < cids; i++)
    298     {
    299       res_id_print (stream, ids[i], 1);
    300       if (i + 1 < cids)
    301 	fprintf (stream, ": ");
    302     }
    303 }
    304 
    305 /* Convert an ASCII string to a resource ID.  */
    306 
    307 void
    308 res_string_to_id (rc_res_id *res_id, const char *string)
    309 {
    310   res_id->named = 1;
    311   unicode_from_ascii (&res_id->u.n.length, &res_id->u.n.name, string);
    312 }
    313 
    314 /* Convert an unicode string to a resource ID.  */
    315 void
    316 res_unistring_to_id (rc_res_id *res_id, const unichar *u)
    317 {
    318   res_id->named = 1;
    319   res_id->u.n.length = unichar_len (u);
    320   res_id->u.n.name = unichar_dup_uppercase (u);
    321 }
    322 
    323 /* Define a resource.  The arguments are the resource tree, RESOURCES,
    324    and the location at which to put it in the tree, CIDS and IDS.
    325    This returns a newly allocated rc_res_resource structure, which the
    326    caller is expected to initialize.  If DUPOK is non-zero, then if a
    327    resource with this ID exists, it is returned.  Otherwise, a warning
    328    is issued, and a new resource is created replacing the existing
    329    one.  */
    330 
    331 rc_res_resource *
    332 define_resource (rc_res_directory **resources, int cids,
    333 		 const rc_res_id *ids, int dupok)
    334 {
    335   rc_res_entry *re = NULL;
    336   int i;
    337 
    338   assert (cids > 0);
    339   for (i = 0; i < cids; i++)
    340     {
    341       rc_res_entry **pp;
    342 
    343       if (*resources == NULL)
    344 	{
    345 	  *resources = ((rc_res_directory *)
    346 			res_alloc (sizeof (rc_res_directory)));
    347 	  (*resources)->characteristics = 0;
    348 	  /* Using a real timestamp only serves to create non-deterministic
    349 	     results.  Use zero instead.  */
    350 	  (*resources)->time = 0;
    351 	  (*resources)->major = 0;
    352 	  (*resources)->minor = 0;
    353 	  (*resources)->entries = NULL;
    354 	}
    355 
    356       for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
    357 	if (res_id_cmp ((*pp)->id, ids[i]) == 0)
    358 	  break;
    359 
    360       if (*pp != NULL)
    361 	re = *pp;
    362       else
    363 	{
    364 	  re = (rc_res_entry *) res_alloc (sizeof (rc_res_entry));
    365 	  re->next = NULL;
    366 	  re->id = ids[i];
    367 	  if ((i + 1) < cids)
    368 	    {
    369 	      re->subdir = 1;
    370 	      re->u.dir = NULL;
    371 	    }
    372 	  else
    373 	    {
    374 	      re->subdir = 0;
    375 	      re->u.res = NULL;
    376 	    }
    377 
    378 	  *pp = re;
    379 	}
    380 
    381       if ((i + 1) < cids)
    382 	{
    383 	  if (! re->subdir)
    384 	    {
    385 	      fprintf (stderr, "%s: ", program_name);
    386 	      res_ids_print (stderr, i, ids);
    387 	      fprintf (stderr, _(": expected to be a directory\n"));
    388 	      xexit (1);
    389 	    }
    390 
    391 	  resources = &re->u.dir;
    392 	}
    393     }
    394 
    395   if (re->subdir)
    396     {
    397       fprintf (stderr, "%s: ", program_name);
    398       res_ids_print (stderr, cids, ids);
    399       fprintf (stderr, _(": expected to be a leaf\n"));
    400       xexit (1);
    401     }
    402 
    403   if (re->u.res != NULL)
    404     {
    405       if (dupok)
    406 	return re->u.res;
    407 
    408       fprintf (stderr, _("%s: warning: "), program_name);
    409       res_ids_print (stderr, cids, ids);
    410       fprintf (stderr, _(": duplicate value\n"));
    411     }
    412 
    413   re->u.res = ((rc_res_resource *)
    414 	       res_alloc (sizeof (rc_res_resource)));
    415   memset (re->u.res, 0, sizeof (rc_res_resource));
    416 
    417   re->u.res->type = RES_TYPE_UNINITIALIZED;
    418   return re->u.res;
    419 }
    420 
    421 /* Define a standard resource.  This is a version of define_resource
    422    that just takes type, name, and language arguments.  */
    423 
    424 rc_res_resource *
    425 define_standard_resource (rc_res_directory **resources, int type,
    426 			  rc_res_id name, rc_uint_type language, int dupok)
    427 {
    428   rc_res_id a[3];
    429 
    430   a[0].named = 0;
    431   a[0].u.id = type;
    432   a[1] = name;
    433   a[2].named = 0;
    434   a[2].u.id = language;
    435   return define_resource (resources, 3, a, dupok);
    436 }
    437 
    438 /* Comparison routine for resource sorting.  */
    439 
    440 static int
    441 cmp_res_entry (const void *p1, const void *p2)
    442 {
    443   const rc_res_entry **re1, **re2;
    444 
    445   re1 = (const rc_res_entry **) p1;
    446   re2 = (const rc_res_entry **) p2;
    447   return res_id_cmp ((*re1)->id, (*re2)->id);
    448 }
    449 
    450 /* Sort the resources.  */
    451 
    452 static rc_res_directory *
    453 sort_resources (rc_res_directory *resdir)
    454 {
    455   int c, i;
    456   rc_res_entry *re;
    457   rc_res_entry **a;
    458 
    459   if (resdir->entries == NULL)
    460     return resdir;
    461 
    462   c = 0;
    463   for (re = resdir->entries; re != NULL; re = re->next)
    464     ++c;
    465 
    466   /* This is a recursive routine, so using xmalloc is probably better
    467      than alloca.  */
    468   a = (rc_res_entry **) xmalloc (c * sizeof (rc_res_entry *));
    469 
    470   for (i = 0, re = resdir->entries; re != NULL; re = re->next, i++)
    471     a[i] = re;
    472 
    473   qsort (a, c, sizeof (rc_res_entry *), cmp_res_entry);
    474 
    475   resdir->entries = a[0];
    476   for (i = 0; i < c - 1; i++)
    477     a[i]->next = a[i + 1];
    478   a[i]->next = NULL;
    479 
    480   free (a);
    481 
    482   /* Now sort the subdirectories.  */
    483 
    484   for (re = resdir->entries; re != NULL; re = re->next)
    485     if (re->subdir)
    486       re->u.dir = sort_resources (re->u.dir);
    487 
    488   return resdir;
    489 }
    490 
    491 /* Return whether the dialog resource DIALOG is a DIALOG or a
    493    DIALOGEX.  */
    494 
    495 int
    496 extended_dialog (const rc_dialog *dialog)
    497 {
    498   const rc_dialog_control *c;
    499 
    500   if (dialog->ex != NULL)
    501     return 1;
    502 
    503   for (c = dialog->controls; c != NULL; c = c->next)
    504     if (c->data != NULL || c->help != 0)
    505       return 1;
    506 
    507   return 0;
    508 }
    509 
    510 /* Return whether MENUITEMS are a MENU or a MENUEX.  */
    511 
    512 int
    513 extended_menu (const rc_menu *menu)
    514 {
    515   return extended_menuitems (menu->items);
    516 }
    517 
    518 static int
    519 extended_menuitems (const rc_menuitem *menuitems)
    520 {
    521   const rc_menuitem *mi;
    522 
    523   for (mi = menuitems; mi != NULL; mi = mi->next)
    524     {
    525       if (mi->help != 0 || mi->state != 0)
    526 	return 1;
    527       if (mi->popup != NULL && mi->id != 0)
    528 	return 1;
    529       if ((mi->type
    530 	   & ~ (MENUITEM_CHECKED
    531 		| MENUITEM_GRAYED
    532 		| MENUITEM_HELP
    533 		| MENUITEM_INACTIVE
    534 		| MENUITEM_MENUBARBREAK
    535 		| MENUITEM_MENUBREAK))
    536 	  != 0)
    537 	return 1;
    538       if (mi->popup != NULL)
    539 	{
    540 	  if (extended_menuitems (mi->popup))
    541 	    return 1;
    542 	}
    543     }
    544 
    545   return 0;
    546 }
    547 
    548 /* Convert a string to a format type, or exit if it can't be done.  */
    550 
    551 static enum res_format
    552 format_from_name (const char *name, int exit_on_error)
    553 {
    554   const struct format_map *m;
    555 
    556   for (m = format_names; m->name != NULL; m++)
    557     if (strcasecmp (m->name, name) == 0)
    558       break;
    559 
    560   if (m->name == NULL && exit_on_error)
    561     {
    562       non_fatal (_("unknown format type `%s'"), name);
    563       fprintf (stderr, _("%s: supported formats:"), program_name);
    564       for (m = format_names; m->name != NULL; m++)
    565 	fprintf (stderr, " %s", m->name);
    566       fprintf (stderr, "\n");
    567       xexit (1);
    568     }
    569 
    570   return m->format;
    571 }
    572 
    573 /* Work out a format type given a file name.  If INPUT is non-zero,
    574    it's OK to look at the file itself.  */
    575 
    576 static enum res_format
    577 format_from_filename (const char *filename, int input)
    578 {
    579   const char *ext;
    580   FILE *e;
    581   bfd_byte b1, b2, b3, b4, b5;
    582   int magic;
    583 
    584   /* If we have an extension, see if we recognize it as implying a
    585      particular format.  */
    586   ext = strrchr (filename, '.');
    587   if (ext != NULL)
    588     {
    589       const struct format_map *m;
    590 
    591       ++ext;
    592       for (m = format_fileexts; m->name != NULL; m++)
    593 	if (strcasecmp (m->name, ext) == 0)
    594 	  return m->format;
    595     }
    596 
    597   /* If we don't recognize the name of an output file, assume it's a
    598      COFF file.  */
    599   if (! input)
    600     return RES_FORMAT_COFF;
    601 
    602   /* Read the first few bytes of the file to see if we can guess what
    603      it is.  */
    604   e = fopen (filename, FOPEN_RB);
    605   if (e == NULL)
    606     fatal ("%s: %s", filename, strerror (errno));
    607 
    608   b1 = getc (e);
    609   b2 = getc (e);
    610   b3 = getc (e);
    611   b4 = getc (e);
    612   b5 = getc (e);
    613 
    614   fclose (e);
    615 
    616   /* A PE executable starts with 0x4d 0x5a.  */
    617   if (b1 == 0x4d && b2 == 0x5a)
    618     return RES_FORMAT_COFF;
    619 
    620   /* A COFF .o file starts with a COFF magic number.  */
    621   magic = (b2 << 8) | b1;
    622   switch (magic)
    623     {
    624     case 0x14c: /* i386 */
    625     case 0x166: /* MIPS */
    626     case 0x184: /* Alpha */
    627     case 0x268: /* 68k */
    628     case 0x1f0: /* PowerPC */
    629     case 0x290: /* PA */
    630       return RES_FORMAT_COFF;
    631     }
    632 
    633   /* A RES file starts with 0x0 0x0 0x0 0x0 0x20 0x0 0x0 0x0.  */
    634   if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0 && b5 == 0x20)
    635     return RES_FORMAT_RES;
    636 
    637   /* If every character is printable or space, assume it's an RC file.  */
    638   if ((ISPRINT (b1) || ISSPACE (b1))
    639       && (ISPRINT (b2) || ISSPACE (b2))
    640       && (ISPRINT (b3) || ISSPACE (b3))
    641       && (ISPRINT (b4) || ISSPACE (b4))
    642       && (ISPRINT (b5) || ISSPACE (b5)))
    643     return RES_FORMAT_RC;
    644 
    645   /* Otherwise, we give up.  */
    646   fatal (_("can not determine type of file `%s'; use the -J option"),
    647 	 filename);
    648 
    649   /* Return something to silence the compiler warning.  */
    650   return RES_FORMAT_UNKNOWN;
    651 }
    652 
    653 /* Print a usage message and exit.  */
    654 
    655 static void
    656 usage (FILE *stream, int status)
    657 {
    658   fprintf (stream, _("Usage: %s [option(s)] [input-file] [output-file]\n"),
    659 	   program_name);
    660   fprintf (stream, _(" The options are:\n\
    661   -i --input=<file>            Name input file\n\
    662   -o --output=<file>           Name output file\n\
    663   -J --input-format=<format>   Specify input format\n\
    664   -O --output-format=<format>  Specify output format\n\
    665   -F --target=<target>         Specify COFF target\n\
    666      --preprocessor=<program>  Program to use to preprocess rc file\n\
    667      --preprocessor-arg=<arg>  Additional preprocessor argument\n\
    668   -I --include-dir=<dir>       Include directory when preprocessing rc file\n\
    669   -D --define <sym>[=<val>]    Define SYM when preprocessing rc file\n\
    670   -U --undefine <sym>          Undefine SYM when preprocessing rc file\n\
    671   -v --verbose                 Verbose - tells you what it's doing\n\
    672   -c --codepage=<codepage>     Specify default codepage\n\
    673   -l --language=<val>          Set language when reading rc file\n\
    674      --use-temp-file           Use a temporary file instead of popen to read\n\
    675                                the preprocessor output\n\
    676      --no-use-temp-file        Use popen (default)\n"));
    677 #ifdef YYDEBUG
    678   fprintf (stream, _("\
    679      --yydebug                 Turn on parser debugging\n"));
    680 #endif
    681   fprintf (stream, _("\
    682   -r                           Ignored for compatibility with rc\n\
    683   @<file>                      Read options from <file>\n\
    684   -h --help                    Print this help message\n\
    685   -V --version                 Print version information\n"));
    686   fprintf (stream, _("\
    687 FORMAT is one of rc, res, or coff, and is deduced from the file name\n\
    688 extension if not specified.  A single file name is an input file.\n\
    689 No input-file is stdin, default rc.  No output-file is stdout, default rc.\n"));
    690 
    691   list_supported_targets (program_name, stream);
    692 
    693   if (REPORT_BUGS_TO[0] && status == 0)
    694     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
    695 
    696   exit (status);
    697 }
    698 
    699 /* Quote characters that will confuse the shell when we run the preprocessor.  */
    700 
    701 static const char *
    702 quot (const char *string)
    703 {
    704   static char *buf = 0;
    705   static int buflen = 0;
    706   int slen = strlen (string);
    707   const char *src;
    708   char *dest;
    709 
    710   if ((buflen < slen * 2 + 2) || ! buf)
    711     {
    712       buflen = slen * 2 + 2;
    713       if (buf)
    714 	free (buf);
    715       buf = (char *) xmalloc (buflen);
    716     }
    717 
    718   for (src=string, dest=buf; *src; src++, dest++)
    719     {
    720       if (*src == '(' || *src == ')' || *src == ' ')
    721 	*dest++ = '\\';
    722       *dest = *src;
    723     }
    724   *dest = 0;
    725   return buf;
    726 }
    727 
    728 /* Long options.  */
    729 
    730 enum option_values
    731 {
    732   /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
    733   OPTION_PREPROCESSOR	= 150,
    734   OPTION_USE_TEMP_FILE,
    735   OPTION_NO_USE_TEMP_FILE,
    736   OPTION_YYDEBUG,
    737   OPTION_INCLUDE_DIR,
    738   OPTION_PREPROCESSOR_ARG
    739 };
    740 
    741 static const struct option long_options[] =
    742 {
    743   {"input", required_argument, 0, 'i'},
    744   {"output", required_argument, 0, 'o'},
    745   {"input-format", required_argument, 0, 'J'},
    746   {"output-format", required_argument, 0, 'O'},
    747   {"target", required_argument, 0, 'F'},
    748   {"preprocessor", required_argument, 0, OPTION_PREPROCESSOR},
    749   {"preprocessor-arg", required_argument, 0, OPTION_PREPROCESSOR_ARG},
    750   {"include-dir", required_argument, 0, OPTION_INCLUDE_DIR},
    751   {"define", required_argument, 0, 'D'},
    752   {"undefine", required_argument, 0, 'U'},
    753   {"verbose", no_argument, 0, 'v'},
    754   {"codepage", required_argument, 0, 'c'},
    755   {"language", required_argument, 0, 'l'},
    756   {"use-temp-file", no_argument, 0, OPTION_USE_TEMP_FILE},
    757   {"no-use-temp-file", no_argument, 0, OPTION_NO_USE_TEMP_FILE},
    758   {"yydebug", no_argument, 0, OPTION_YYDEBUG},
    759   {"version", no_argument, 0, 'V'},
    760   {"help", no_argument, 0, 'h'},
    761   {0, no_argument, 0, 0}
    762 };
    763 
    764 void
    765 windres_add_include_dir (const char *p)
    766 {
    767   struct include_dir *n, **pp;
    768 
    769   /* Computing paths is often complicated and error prone.
    770      The easiest way to check for mistakes is at the time
    771      we add them to include_dirs.  */
    772   assert (p != NULL);
    773   assert (*p != '\0');
    774 
    775   n = xmalloc (sizeof *n);
    776   n->next = NULL;
    777   n->dir = (char * ) p;
    778 
    779   for (pp = &include_dirs; *pp != NULL; pp = &(*pp)->next)
    780     ;
    781   *pp = n;
    782 }
    783 
    784 /* This keeps gcc happy when using -Wmissing-prototypes -Wstrict-prototypes.  */
    785 int main (int, char **);
    786 
    787 /* The main function.  */
    788 
    789 int
    790 main (int argc, char **argv)
    791 {
    792   int c;
    793   char *input_filename;
    794   char *output_filename;
    795   enum res_format input_format;
    796   enum res_format input_format_tmp;
    797   enum res_format output_format;
    798   char *target;
    799   char *preprocessor;
    800   char *preprocargs;
    801   const char *quotedarg;
    802   int language;
    803   rc_res_directory *resources;
    804   int use_temp_file;
    805 
    806 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
    807   setlocale (LC_MESSAGES, "");
    808 #endif
    809 #if defined (HAVE_SETLOCALE)
    810   setlocale (LC_CTYPE, "");
    811 #endif
    812   bindtextdomain (PACKAGE, LOCALEDIR);
    813   textdomain (PACKAGE);
    814 
    815   program_name = argv[0];
    816   xmalloc_set_program_name (program_name);
    817   bfd_set_error_program_name (program_name);
    818 
    819   expandargv (&argc, &argv);
    820 
    821   bfd_init ();
    822   set_default_bfd_target ();
    823 
    824   res_init ();
    825 
    826   input_filename = NULL;
    827   output_filename = NULL;
    828   input_format = RES_FORMAT_UNKNOWN;
    829   output_format = RES_FORMAT_UNKNOWN;
    830   target = NULL;
    831   preprocessor = NULL;
    832   preprocargs = NULL;
    833   language = 0x409;   /* LANG_ENGLISH, SUBLANG_ENGLISH_US.  */
    834   use_temp_file = 0;
    835 
    836   while ((c = getopt_long (argc, argv, "c:f:i:l:o:I:J:O:F:D:U:rhHvV", long_options,
    837 			   (int *) 0)) != EOF)
    838     {
    839       switch (c)
    840 	{
    841 	case 'c':
    842 	  {
    843 	    rc_uint_type ncp;
    844 
    845 	    if (optarg[0] == '0' && (optarg[1] == 'x' || optarg[1] == 'X'))
    846 	      ncp = (rc_uint_type) strtol (optarg + 2, NULL, 16);
    847 	    else
    848 	      ncp = (rc_uint_type) strtol (optarg, NULL, 10);
    849 	    if (ncp == CP_UTF16 || ! unicode_is_valid_codepage (ncp))
    850 	      fatal (_("invalid codepage specified.\n"));
    851 	    wind_default_codepage = wind_current_codepage = ncp;
    852 	  }
    853 	  break;
    854 
    855 	case 'i':
    856 	  input_filename = optarg;
    857 	  break;
    858 
    859 	case 'f':
    860 	  /* For compatibility with rc we accept "-fo <name>" as being the
    861 	     equivalent of "-o <name>".  We do not advertise this fact
    862 	     though, as we do not want users to use non-GNU like command
    863 	     line switches.  */
    864 	  if (*optarg != 'o')
    865 	    fatal (_("invalid option -f\n"));
    866 	  optarg++;
    867 	  if (* optarg == 0)
    868 	    {
    869 	      if (optind == argc)
    870 		fatal (_("No filename following the -fo option.\n"));
    871 	      optarg = argv [optind++];
    872 	    }
    873 	  /* Fall through.  */
    874 
    875 	case 'o':
    876 	  output_filename = optarg;
    877 	  break;
    878 
    879 	case 'J':
    880 	  input_format = format_from_name (optarg, 1);
    881 	  break;
    882 
    883 	case 'O':
    884 	  output_format = format_from_name (optarg, 1);
    885 	  break;
    886 
    887 	case 'F':
    888 	  target = optarg;
    889 	  break;
    890 
    891 	case OPTION_PREPROCESSOR:
    892 	  preprocessor = optarg;
    893 	  break;
    894 
    895 	case OPTION_PREPROCESSOR_ARG:
    896 	  if (preprocargs == NULL)
    897 	    {
    898 	      quotedarg = quot (optarg);
    899 	      preprocargs = xstrdup (quotedarg);
    900 	    }
    901 	  else
    902 	    {
    903 	      char *n;
    904 
    905 	      quotedarg = quot (optarg);
    906 	      n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 2);
    907 	      sprintf (n, "%s %s", preprocargs, quotedarg);
    908 	      free (preprocargs);
    909 	      preprocargs = n;
    910 	    }
    911 	  break;
    912 
    913 	case 'D':
    914 	case 'U':
    915 	  if (preprocargs == NULL)
    916 	    {
    917 	      quotedarg = quot (optarg);
    918 	      preprocargs = xmalloc (strlen (quotedarg) + 3);
    919 	      sprintf (preprocargs, "-%c%s", c, quotedarg);
    920 	    }
    921 	  else
    922 	    {
    923 	      char *n;
    924 
    925 	      quotedarg = quot (optarg);
    926 	      n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
    927 	      sprintf (n, "%s -%c%s", preprocargs, c, quotedarg);
    928 	      free (preprocargs);
    929 	      preprocargs = n;
    930 	    }
    931 	  break;
    932 
    933 	case 'r':
    934 	  /* Ignored for compatibility with rc.  */
    935 	  break;
    936 
    937 	case 'v':
    938 	  verbose ++;
    939 	  break;
    940 
    941 	case 'I':
    942 	  /* For backward compatibility, should be removed in the future.  */
    943 	  input_format_tmp = format_from_name (optarg, 0);
    944 	  if (input_format_tmp != RES_FORMAT_UNKNOWN)
    945 	    {
    946 	      struct stat statbuf;
    947 	      char modebuf[11];
    948 
    949 	      if (stat (optarg, & statbuf) == 0
    950 		  /* Coded this way to avoid importing knowledge of S_ISDIR into this file.  */
    951 		  && (mode_string (statbuf.st_mode, modebuf), modebuf[0] == 'd'))
    952 		/* We have a -I option with a directory name that just happens
    953 		   to match a format name as well.  eg: -I res  Assume that the
    954 		   user knows what they are doing and do not complain.  */
    955 		;
    956 	      else
    957 		{
    958 		  fprintf (stderr,
    959 			   _("Option -I is deprecated for setting the input format, please use -J instead.\n"));
    960 		  input_format = input_format_tmp;
    961 		  break;
    962 		}
    963 	    }
    964 	  /* Fall through.  */
    965 
    966 	case OPTION_INCLUDE_DIR:
    967 	  if (preprocargs == NULL)
    968 	    {
    969 	      quotedarg = quot (optarg);
    970 	      preprocargs = xmalloc (strlen (quotedarg) + 3);
    971 	      sprintf (preprocargs, "-I%s", quotedarg);
    972 	    }
    973 	  else
    974 	    {
    975 	      char *n;
    976 
    977 	      quotedarg = quot (optarg);
    978 	      n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
    979 	      sprintf (n, "%s -I%s", preprocargs, quotedarg);
    980 	      free (preprocargs);
    981 	      preprocargs = n;
    982 	    }
    983 
    984 	  windres_add_include_dir (optarg);
    985 
    986 	  break;
    987 
    988 	case 'l':
    989 	  language = strtol (optarg, (char **) NULL, 16);
    990 	  break;
    991 
    992 	case OPTION_USE_TEMP_FILE:
    993 	  use_temp_file = 1;
    994 	  break;
    995 
    996 	case OPTION_NO_USE_TEMP_FILE:
    997 	  use_temp_file = 0;
    998 	  break;
    999 
   1000 #ifdef YYDEBUG
   1001 	case OPTION_YYDEBUG:
   1002 	  yydebug = 1;
   1003 	  break;
   1004 #endif
   1005 
   1006 	case 'h':
   1007 	case 'H':
   1008 	  usage (stdout, 0);
   1009 	  break;
   1010 
   1011 	case 'V':
   1012 	  print_version ("windres");
   1013 	  break;
   1014 
   1015 	default:
   1016 	  usage (stderr, 1);
   1017 	  break;
   1018 	}
   1019     }
   1020 
   1021   if (input_filename == NULL && optind < argc)
   1022     {
   1023       input_filename = argv[optind];
   1024       ++optind;
   1025     }
   1026 
   1027   if (output_filename == NULL && optind < argc)
   1028     {
   1029       output_filename = argv[optind];
   1030       ++optind;
   1031     }
   1032 
   1033   if (argc != optind)
   1034     usage (stderr, 1);
   1035 
   1036   if (input_format == RES_FORMAT_UNKNOWN)
   1037     {
   1038       if (input_filename == NULL)
   1039 	input_format = RES_FORMAT_RC;
   1040       else
   1041 	input_format = format_from_filename (input_filename, 1);
   1042     }
   1043 
   1044   if (output_format == RES_FORMAT_UNKNOWN)
   1045     {
   1046       if (output_filename == NULL)
   1047 	output_format = RES_FORMAT_RC;
   1048       else
   1049 	output_format = format_from_filename (output_filename, 0);
   1050     }
   1051 
   1052   set_endianness (NULL, target);
   1053 
   1054   /* Read the input file.  */
   1055   switch (input_format)
   1056     {
   1057     default:
   1058       abort ();
   1059     case RES_FORMAT_RC:
   1060       resources = read_rc_file (input_filename, preprocessor, preprocargs,
   1061 				language, use_temp_file);
   1062       break;
   1063     case RES_FORMAT_RES:
   1064       resources = read_res_file (input_filename);
   1065       break;
   1066     case RES_FORMAT_COFF:
   1067       resources = read_coff_rsrc (input_filename, target);
   1068       break;
   1069     }
   1070 
   1071   if (resources == NULL)
   1072     fatal (_("no resources"));
   1073 
   1074   /* Sort the resources.  This is required for COFF, convenient for
   1075      rc, and unimportant for res.  */
   1076   resources = sort_resources (resources);
   1077 
   1078   /* Write the output file.  */
   1079   reswr_init ();
   1080 
   1081   switch (output_format)
   1082     {
   1083     default:
   1084       abort ();
   1085     case RES_FORMAT_RC:
   1086       write_rc_file (output_filename, resources);
   1087       break;
   1088     case RES_FORMAT_RES:
   1089       write_res_file (output_filename, resources);
   1090       break;
   1091     case RES_FORMAT_COFF:
   1092       write_coff_file (output_filename, target, resources);
   1093       break;
   1094     }
   1095 
   1096   xexit (0);
   1097   return 0;
   1098 }
   1099 
   1100 static void
   1101 set_endianness (bfd *abfd, const char *target)
   1102 {
   1103   const bfd_target *target_vec;
   1104 
   1105   def_target_arch = NULL;
   1106   target_vec = bfd_get_target_info (target, abfd, &target_is_bigendian, NULL,
   1107                                    &def_target_arch);
   1108   if (! target_vec)
   1109     fatal ("Can't detect target endianness and architecture.");
   1110   if (! def_target_arch)
   1111     fatal ("Can't detect architecture.");
   1112 }
   1113 
   1114 bfd *
   1115 windres_open_as_binary (const char *filename, int rdmode)
   1116 {
   1117   bfd *abfd;
   1118 
   1119   abfd = (rdmode ? bfd_openr (filename, "binary") : bfd_openw (filename, "binary"));
   1120   if (! abfd)
   1121     fatal ("can't open `%s' for %s", filename, (rdmode ? "input" : "output"));
   1122 
   1123   if (rdmode && ! bfd_check_format (abfd, bfd_object))
   1124     fatal ("can't open `%s' for input.", filename);
   1125 
   1126   return abfd;
   1127 }
   1128 
   1129 void
   1130 set_windres_bfd_endianness (windres_bfd *wrbfd, int is_bigendian)
   1131 {
   1132   assert (!! wrbfd);
   1133   switch (WR_KIND(wrbfd))
   1134   {
   1135   case WR_KIND_BFD_BIN_L:
   1136     if (is_bigendian)
   1137       WR_KIND(wrbfd) = WR_KIND_BFD_BIN_B;
   1138     break;
   1139   case WR_KIND_BFD_BIN_B:
   1140     if (! is_bigendian)
   1141       WR_KIND(wrbfd) = WR_KIND_BFD_BIN_L;
   1142     break;
   1143   default:
   1144     /* only binary bfd can be overriden. */
   1145     abort ();
   1146   }
   1147 }
   1148 
   1149 void
   1150 set_windres_bfd (windres_bfd *wrbfd, bfd *abfd, asection *sec, rc_uint_type kind)
   1151 {
   1152   assert (!! wrbfd);
   1153   switch (kind)
   1154   {
   1155   case WR_KIND_TARGET:
   1156     abfd = NULL;
   1157     sec = NULL;
   1158     break;
   1159   case WR_KIND_BFD:
   1160   case WR_KIND_BFD_BIN_L:
   1161   case WR_KIND_BFD_BIN_B:
   1162     assert (!! abfd);
   1163     assert (!!sec);
   1164     break;
   1165   default:
   1166     abort ();
   1167   }
   1168   WR_KIND(wrbfd) = kind;
   1169   WR_BFD(wrbfd) = abfd;
   1170   WR_SECTION(wrbfd) = sec;
   1171 }
   1172 
   1173 void
   1174 set_windres_bfd_content (windres_bfd *wrbfd, const void *data, rc_uint_type off,
   1175 			 rc_uint_type length)
   1176 {
   1177   if (WR_KIND(wrbfd) != WR_KIND_TARGET)
   1178     {
   1179       if (! bfd_set_section_contents (WR_BFD(wrbfd), WR_SECTION(wrbfd), data, off, length))
   1180 	bfd_fatal ("bfd_set_section_contents");
   1181     }
   1182   else
   1183     abort ();
   1184 }
   1185 
   1186 void
   1187 get_windres_bfd_content (windres_bfd *wrbfd, void *data, rc_uint_type off,
   1188 			 rc_uint_type length)
   1189 {
   1190   if (WR_KIND(wrbfd) != WR_KIND_TARGET)
   1191     {
   1192       if (! bfd_get_section_contents (WR_BFD(wrbfd), WR_SECTION(wrbfd), data, off, length))
   1193 	bfd_fatal ("bfd_get_section_contents");
   1194     }
   1195   else
   1196     abort ();
   1197 }
   1198 
   1199 void
   1200 windres_put_8 (windres_bfd *wrbfd, void *p, rc_uint_type value)
   1201 {
   1202   switch (WR_KIND(wrbfd))
   1203     {
   1204     case WR_KIND_TARGET:
   1205       target_put_8 (p, value);
   1206       break;
   1207     case WR_KIND_BFD:
   1208     case WR_KIND_BFD_BIN_L:
   1209     case WR_KIND_BFD_BIN_B:
   1210       bfd_put_8 (WR_BFD(wrbfd), value, p);
   1211       break;
   1212     default:
   1213       abort ();
   1214     }
   1215 }
   1216 
   1217 void
   1218 windres_put_16 (windres_bfd *wrbfd, void *data, rc_uint_type value)
   1219 {
   1220   switch (WR_KIND(wrbfd))
   1221     {
   1222     case WR_KIND_TARGET:
   1223       target_put_16 (data, value);
   1224       break;
   1225     case WR_KIND_BFD:
   1226     case WR_KIND_BFD_BIN_B:
   1227       bfd_put_16 (WR_BFD(wrbfd), value, data);
   1228       break;
   1229     case WR_KIND_BFD_BIN_L:
   1230       bfd_putl16 (value, data);
   1231       break;
   1232     default:
   1233       abort ();
   1234     }
   1235 }
   1236 
   1237 void
   1238 windres_put_32 (windres_bfd *wrbfd, void *data, rc_uint_type value)
   1239 {
   1240   switch (WR_KIND(wrbfd))
   1241     {
   1242     case WR_KIND_TARGET:
   1243       target_put_32 (data, value);
   1244       break;
   1245     case WR_KIND_BFD:
   1246     case WR_KIND_BFD_BIN_B:
   1247       bfd_put_32 (WR_BFD(wrbfd), value, data);
   1248       break;
   1249     case WR_KIND_BFD_BIN_L:
   1250       bfd_putl32 (value, data);
   1251       break;
   1252     default:
   1253       abort ();
   1254     }
   1255 }
   1256 
   1257 rc_uint_type
   1258 windres_get_8 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
   1259 {
   1260   if (length < 1)
   1261     fatal ("windres_get_8: unexpected eob.");
   1262   switch (WR_KIND(wrbfd))
   1263     {
   1264     case WR_KIND_TARGET:
   1265       return target_get_8 (data, length);
   1266     case WR_KIND_BFD:
   1267     case WR_KIND_BFD_BIN_B:
   1268     case WR_KIND_BFD_BIN_L:
   1269       return bfd_get_8 (WR_BFD(wrbfd), data);
   1270     default:
   1271       abort ();
   1272     }
   1273   return 0;
   1274 }
   1275 
   1276 rc_uint_type
   1277 windres_get_16 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
   1278 {
   1279   if (length < 2)
   1280     fatal ("windres_get_16: unexpected eob.");
   1281   switch (WR_KIND(wrbfd))
   1282     {
   1283     case WR_KIND_TARGET:
   1284       return target_get_16 (data, length);
   1285     case WR_KIND_BFD:
   1286     case WR_KIND_BFD_BIN_B:
   1287       return bfd_get_16 (WR_BFD(wrbfd), data);
   1288     case WR_KIND_BFD_BIN_L:
   1289       return bfd_getl16 (data);
   1290     default:
   1291       abort ();
   1292     }
   1293   return 0;
   1294 }
   1295 
   1296 rc_uint_type
   1297 windres_get_32 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
   1298 {
   1299   if (length < 4)
   1300     fatal ("windres_get_32: unexpected eob.");
   1301   switch (WR_KIND(wrbfd))
   1302     {
   1303     case WR_KIND_TARGET:
   1304       return target_get_32 (data, length);
   1305     case WR_KIND_BFD:
   1306     case WR_KIND_BFD_BIN_B:
   1307       return bfd_get_32 (WR_BFD(wrbfd), data);
   1308     case WR_KIND_BFD_BIN_L:
   1309       return bfd_getl32 (data);
   1310     default:
   1311       abort ();
   1312     }
   1313   return 0;
   1314 }
   1315 
   1316 static rc_uint_type
   1317 target_get_8 (const void *p, rc_uint_type length)
   1318 {
   1319   rc_uint_type ret;
   1320 
   1321   if (length < 1)
   1322     fatal ("Resource too small for getting 8-bit value.");
   1323 
   1324   ret = (rc_uint_type) *((const bfd_byte *) p);
   1325   return ret & 0xff;
   1326 }
   1327 
   1328 static rc_uint_type
   1329 target_get_16 (const void *p, rc_uint_type length)
   1330 {
   1331   if (length < 2)
   1332     fatal ("Resource too small for getting 16-bit value.");
   1333 
   1334   if (target_is_bigendian)
   1335     return bfd_getb16 (p);
   1336   else
   1337     return bfd_getl16 (p);
   1338 }
   1339 
   1340 static rc_uint_type
   1341 target_get_32 (const void *p, rc_uint_type length)
   1342 {
   1343   if (length < 4)
   1344     fatal ("Resource too small for getting 32-bit value.");
   1345 
   1346   if (target_is_bigendian)
   1347     return bfd_getb32 (p);
   1348   else
   1349     return bfd_getl32 (p);
   1350 }
   1351 
   1352 static void
   1353 target_put_8 (void *p, rc_uint_type value)
   1354 {
   1355   assert (!! p);
   1356   *((bfd_byte *) p)=(bfd_byte) value;
   1357 }
   1358 
   1359 static void
   1360 target_put_16 (void *p, rc_uint_type value)
   1361 {
   1362   assert (!! p);
   1363 
   1364   if (target_is_bigendian)
   1365     bfd_putb16 (value, p);
   1366   else
   1367     bfd_putl16 (value, p);
   1368 }
   1369 
   1370 static void
   1371 target_put_32 (void *p, rc_uint_type value)
   1372 {
   1373   assert (!! p);
   1374 
   1375   if (target_is_bigendian)
   1376     bfd_putb32 (value, p);
   1377   else
   1378     bfd_putl32 (value, p);
   1379 }
   1380 
   1381 static int isInComment = 0;
   1382 
   1383 int wr_printcomment (FILE *e, const char *fmt, ...)
   1384 {
   1385   va_list arg;
   1386   int r = 0;
   1387 
   1388   if (isInComment)
   1389     r += fprintf (e, "\n   ");
   1390   else
   1391     fprintf (e, "/* ");
   1392   isInComment = 1;
   1393   if (fmt == NULL)
   1394     return r;
   1395   va_start (arg, fmt);
   1396   r += vfprintf (e, fmt, arg);
   1397   va_end (arg);
   1398   return r;
   1399 }
   1400 
   1401 int wr_print (FILE *e, const char *fmt, ...)
   1402 {
   1403   va_list arg;
   1404   int r = 0;
   1405   if (isInComment)
   1406     r += fprintf (e, ".  */\n");
   1407   isInComment = 0;
   1408   if (! fmt)
   1409     return r;
   1410   va_start (arg, fmt);
   1411   r += vfprintf (e, fmt, arg);
   1412   va_end (arg);
   1413   return r;
   1414 }
   1415