* addr2line.c (usage): Document @file.
[external/binutils.git] / binutils / windres.c
1 /* windres.c -- a program to manipulate Windows resources
2    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4    Written by Ian Lance Taylor, Cygnus Support.
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 2 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@ixos-leipzig.de>.
34
35    * The res2coff program, written by Pedro A. Aranda <paag@tid.es>.  */
36
37 #include "config.h"
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41 #include <assert.h>
42 #include <time.h>
43 #include "bfd.h"
44 #include "getopt.h"
45 #include "bucomm.h"
46 #include "libiberty.h"
47 #include "safe-ctype.h"
48 #include "obstack.h"
49 #include "windres.h"
50
51 /* Used by resrc.c at least.  */
52
53 int verbose = 0;
54
55 /* An enumeration of format types.  */
56
57 enum res_format
58 {
59   /* Unknown format.  */
60   RES_FORMAT_UNKNOWN,
61   /* Textual RC file.  */
62   RES_FORMAT_RC,
63   /* Binary RES file.  */
64   RES_FORMAT_RES,
65   /* COFF file.  */
66   RES_FORMAT_COFF
67 };
68
69 /* A structure used to map between format types and strings.  */
70
71 struct format_map
72 {
73   const char *name;
74   enum res_format format;
75 };
76
77 /* A mapping between names and format types.  */
78
79 static const struct format_map format_names[] =
80 {
81   { "rc", RES_FORMAT_RC },
82   { "res", RES_FORMAT_RES },
83   { "coff", RES_FORMAT_COFF },
84   { NULL, RES_FORMAT_UNKNOWN }
85 };
86
87 /* A mapping from file extensions to format types.  */
88
89 static const struct format_map format_fileexts[] =
90 {
91   { "rc", RES_FORMAT_RC },
92   { "res", RES_FORMAT_RES },
93   { "exe", RES_FORMAT_COFF },
94   { "obj", RES_FORMAT_COFF },
95   { "o", RES_FORMAT_COFF },
96   { NULL, RES_FORMAT_UNKNOWN }
97 };
98
99 /* A list of include directories.  */
100
101 struct include_dir
102 {
103   struct include_dir *next;
104   char *dir;
105 };
106
107 static struct include_dir *include_dirs;
108
109 /* Static functions.  */
110
111 static void res_init (void);
112 static int extended_menuitems (const struct menuitem *);
113 static enum res_format format_from_name (const char *, int);
114 static enum res_format format_from_filename (const char *, int);
115 static void usage (FILE *, int);
116 static int cmp_res_entry (const void *, const void *);
117 static struct res_directory *sort_resources (struct res_directory *);
118 static void reswr_init (void);
119 static const char * quot (const char *);
120 \f
121 /* When we are building a resource tree, we allocate everything onto
122    an obstack, so that we can free it all at once if we want.  */
123
124 #define obstack_chunk_alloc xmalloc
125 #define obstack_chunk_free free
126
127 /* The resource building obstack.  */
128
129 static struct obstack res_obstack;
130
131 /* Initialize the resource building obstack.  */
132
133 static void
134 res_init (void)
135 {
136   obstack_init (&res_obstack);
137 }
138
139 /* Allocate space on the resource building obstack.  */
140
141 void *
142 res_alloc (size_t bytes)
143 {
144   return (void *) obstack_alloc (&res_obstack, bytes);
145 }
146
147 /* We also use an obstack to save memory used while writing out a set
148    of resources.  */
149
150 static struct obstack reswr_obstack;
151
152 /* Initialize the resource writing obstack.  */
153
154 static void
155 reswr_init (void)
156 {
157   obstack_init (&reswr_obstack);
158 }
159
160 /* Allocate space on the resource writing obstack.  */
161
162 void *
163 reswr_alloc (size_t bytes)
164 {
165   return (void *) obstack_alloc (&reswr_obstack, bytes);
166 }
167 \f
168 /* Open a file using the include directory search list.  */
169
170 FILE *
171 open_file_search (const char *filename, const char *mode, const char *errmsg,
172                   char **real_filename)
173 {
174   FILE *e;
175   struct include_dir *d;
176
177   e = fopen (filename, mode);
178   if (e != NULL)
179     {
180       *real_filename = xstrdup (filename);
181       return e;
182     }
183
184   if (errno == ENOENT)
185     {
186       for (d = include_dirs; d != NULL; d = d->next)
187         {
188           char *n;
189
190           n = (char *) xmalloc (strlen (d->dir) + strlen (filename) + 2);
191           sprintf (n, "%s/%s", d->dir, filename);
192           e = fopen (n, mode);
193           if (e != NULL)
194             {
195               *real_filename = n;
196               return e;
197             }
198
199           if (errno != ENOENT)
200             break;
201         }
202     }
203
204   fatal (_("can't open %s `%s': %s"), errmsg, filename, strerror (errno));
205
206   /* Return a value to avoid a compiler warning.  */
207   return NULL;
208 }
209 \f
210 /* Compare two resource ID's.  We consider name entries to come before
211    numeric entries, because that is how they appear in the COFF .rsrc
212    section.  */
213
214 int
215 res_id_cmp (struct res_id a, struct res_id b)
216 {
217   if (! a.named)
218     {
219       if (b.named)
220         return 1;
221       if (a.u.id > b.u.id)
222         return 1;
223       else if (a.u.id < b.u.id)
224         return -1;
225       else
226         return 0;
227     }
228   else
229     {
230       unichar *as, *ase, *bs, *bse;
231
232       if (! b.named)
233         return -1;
234
235       as = a.u.n.name;
236       ase = as + a.u.n.length;
237       bs = b.u.n.name;
238       bse = bs + b.u.n.length;
239
240       while (as < ase)
241         {
242           int i;
243
244           if (bs >= bse)
245             return 1;
246           i = (int) *as - (int) *bs;
247           if (i != 0)
248             return i;
249           ++as;
250           ++bs;
251         }
252
253       if (bs < bse)
254         return -1;
255
256       return 0;
257     }
258 }
259
260 /* Print a resource ID.  */
261
262 void
263 res_id_print (FILE *stream, struct res_id id, int quote)
264 {
265   if (! id.named)
266     fprintf (stream, "%lu", id.u.id);
267   else
268     {
269       if (quote)
270         putc ('"', stream);
271       unicode_print (stream, id.u.n.name, id.u.n.length);
272       if (quote)
273         putc ('"', stream);
274     }
275 }
276
277 /* Print a list of resource ID's.  */
278
279 void
280 res_ids_print (FILE *stream, int cids, const struct res_id *ids)
281 {
282   int i;
283
284   for (i = 0; i < cids; i++)
285     {
286       res_id_print (stream, ids[i], 1);
287       if (i + 1 < cids)
288         fprintf (stream, ": ");
289     }
290 }
291
292 /* Convert an ASCII string to a resource ID.  */
293
294 void
295 res_string_to_id (struct res_id *res_id, const char *string)
296 {
297   res_id->named = 1;
298   unicode_from_ascii (&res_id->u.n.length, &res_id->u.n.name, string);
299 }
300
301 /* Define a resource.  The arguments are the resource tree, RESOURCES,
302    and the location at which to put it in the tree, CIDS and IDS.
303    This returns a newly allocated res_resource structure, which the
304    caller is expected to initialize.  If DUPOK is non-zero, then if a
305    resource with this ID exists, it is returned.  Otherwise, a warning
306    is issued, and a new resource is created replacing the existing
307    one.  */
308
309 struct res_resource *
310 define_resource (struct res_directory **resources, int cids,
311                  const struct res_id *ids, int dupok)
312 {
313   struct res_entry *re = NULL;
314   int i;
315
316   assert (cids > 0);
317   for (i = 0; i < cids; i++)
318     {
319       struct res_entry **pp;
320
321       if (*resources == NULL)
322         {
323           static unsigned long timeval;
324
325           /* Use the same timestamp for every resource created in a
326              single run.  */
327           if (timeval == 0)
328             timeval = time (NULL);
329
330           *resources = ((struct res_directory *)
331                         res_alloc (sizeof **resources));
332           (*resources)->characteristics = 0;
333           (*resources)->time = timeval;
334           (*resources)->major = 0;
335           (*resources)->minor = 0;
336           (*resources)->entries = NULL;
337         }
338
339       for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
340         if (res_id_cmp ((*pp)->id, ids[i]) == 0)
341           break;
342
343       if (*pp != NULL)
344         re = *pp;
345       else
346         {
347           re = (struct res_entry *) res_alloc (sizeof *re);
348           re->next = NULL;
349           re->id = ids[i];
350           if ((i + 1) < cids)
351             {
352               re->subdir = 1;
353               re->u.dir = NULL;
354             }
355           else
356             {
357               re->subdir = 0;
358               re->u.res = NULL;
359             }
360
361           *pp = re;
362         }
363
364       if ((i + 1) < cids)
365         {
366           if (! re->subdir)
367             {
368               fprintf (stderr, "%s: ", program_name);
369               res_ids_print (stderr, i, ids);
370               fprintf (stderr, _(": expected to be a directory\n"));
371               xexit (1);
372             }
373
374           resources = &re->u.dir;
375         }
376     }
377
378   if (re->subdir)
379     {
380       fprintf (stderr, "%s: ", program_name);
381       res_ids_print (stderr, cids, ids);
382       fprintf (stderr, _(": expected to be a leaf\n"));
383       xexit (1);
384     }
385
386   if (re->u.res != NULL)
387     {
388       if (dupok)
389         return re->u.res;
390
391       fprintf (stderr, _("%s: warning: "), program_name);
392       res_ids_print (stderr, cids, ids);
393       fprintf (stderr, _(": duplicate value\n"));
394     }
395
396   re->u.res = ((struct res_resource *)
397                res_alloc (sizeof (struct res_resource)));
398   memset (re->u.res, 0, sizeof (struct res_resource));
399
400   re->u.res->type = RES_TYPE_UNINITIALIZED;
401   return re->u.res;
402 }
403
404 /* Define a standard resource.  This is a version of define_resource
405    that just takes type, name, and language arguments.  */
406
407 struct res_resource *
408 define_standard_resource (struct res_directory **resources, int type,
409                           struct res_id name, int language, int dupok)
410 {
411   struct res_id a[3];
412
413   a[0].named = 0;
414   a[0].u.id = type;
415   a[1] = name;
416   a[2].named = 0;
417   a[2].u.id = language;
418   return define_resource (resources, 3, a, dupok);
419 }
420
421 /* Comparison routine for resource sorting.  */
422
423 static int
424 cmp_res_entry (const void *p1, const void *p2)
425 {
426   const struct res_entry **re1, **re2;
427
428   re1 = (const struct res_entry **) p1;
429   re2 = (const struct res_entry **) p2;
430   return res_id_cmp ((*re1)->id, (*re2)->id);
431 }
432
433 /* Sort the resources.  */
434
435 static struct res_directory *
436 sort_resources (struct res_directory *resdir)
437 {
438   int c, i;
439   struct res_entry *re;
440   struct res_entry **a;
441
442   if (resdir->entries == NULL)
443     return resdir;
444
445   c = 0;
446   for (re = resdir->entries; re != NULL; re = re->next)
447     ++c;
448
449   /* This is a recursive routine, so using xmalloc is probably better
450      than alloca.  */
451   a = (struct res_entry **) xmalloc (c * sizeof (struct res_entry *));
452
453   for (i = 0, re = resdir->entries; re != NULL; re = re->next, i++)
454     a[i] = re;
455
456   qsort (a, c, sizeof (struct res_entry *), cmp_res_entry);
457
458   resdir->entries = a[0];
459   for (i = 0; i < c - 1; i++)
460     a[i]->next = a[i + 1];
461   a[i]->next = NULL;
462
463   free (a);
464
465   /* Now sort the subdirectories.  */
466
467   for (re = resdir->entries; re != NULL; re = re->next)
468     if (re->subdir)
469       re->u.dir = sort_resources (re->u.dir);
470
471   return resdir;
472 }
473 \f
474 /* Return whether the dialog resource DIALOG is a DIALOG or a
475    DIALOGEX.  */
476
477 int
478 extended_dialog (const struct dialog *dialog)
479 {
480   const struct dialog_control *c;
481
482   if (dialog->ex != NULL)
483     return 1;
484
485   for (c = dialog->controls; c != NULL; c = c->next)
486     if (c->data != NULL || c->help != 0)
487       return 1;
488
489   return 0;
490 }
491
492 /* Return whether MENUITEMS are a MENU or a MENUEX.  */
493
494 int
495 extended_menu (const struct menu *menu)
496 {
497   return extended_menuitems (menu->items);
498 }
499
500 static int
501 extended_menuitems (const struct menuitem *menuitems)
502 {
503   const struct menuitem *mi;
504
505   for (mi = menuitems; mi != NULL; mi = mi->next)
506     {
507       if (mi->help != 0 || mi->state != 0)
508         return 1;
509       if (mi->popup != NULL && mi->id != 0)
510         return 1;
511       if ((mi->type
512            & ~ (MENUITEM_CHECKED
513                 | MENUITEM_GRAYED
514                 | MENUITEM_HELP
515                 | MENUITEM_INACTIVE
516                 | MENUITEM_MENUBARBREAK
517                 | MENUITEM_MENUBREAK))
518           != 0)
519         return 1;
520       if (mi->popup != NULL)
521         {
522           if (extended_menuitems (mi->popup))
523             return 1;
524         }
525     }
526
527   return 0;
528 }
529 \f
530 /* Convert a string to a format type, or exit if it can't be done.  */
531
532 static enum res_format
533 format_from_name (const char *name, int exit_on_error)
534 {
535   const struct format_map *m;
536
537   for (m = format_names; m->name != NULL; m++)
538     if (strcasecmp (m->name, name) == 0)
539       break;
540
541   if (m->name == NULL && exit_on_error)
542     {
543       non_fatal (_("unknown format type `%s'"), name);
544       fprintf (stderr, _("%s: supported formats:"), program_name);
545       for (m = format_names; m->name != NULL; m++)
546         fprintf (stderr, " %s", m->name);
547       fprintf (stderr, "\n");
548       xexit (1);
549     }
550
551   return m->format;
552 }
553
554 /* Work out a format type given a file name.  If INPUT is non-zero,
555    it's OK to look at the file itself.  */
556
557 static enum res_format
558 format_from_filename (const char *filename, int input)
559 {
560   const char *ext;
561   FILE *e;
562   unsigned char b1, b2, b3, b4, b5;
563   int magic;
564
565   /* If we have an extension, see if we recognize it as implying a
566      particular format.  */
567   ext = strrchr (filename, '.');
568   if (ext != NULL)
569     {
570       const struct format_map *m;
571
572       ++ext;
573       for (m = format_fileexts; m->name != NULL; m++)
574         if (strcasecmp (m->name, ext) == 0)
575           return m->format;
576     }
577
578   /* If we don't recognize the name of an output file, assume it's a
579      COFF file.  */
580   if (! input)
581     return RES_FORMAT_COFF;
582
583   /* Read the first few bytes of the file to see if we can guess what
584      it is.  */
585   e = fopen (filename, FOPEN_RB);
586   if (e == NULL)
587     fatal ("%s: %s", filename, strerror (errno));
588
589   b1 = getc (e);
590   b2 = getc (e);
591   b3 = getc (e);
592   b4 = getc (e);
593   b5 = getc (e);
594
595   fclose (e);
596
597   /* A PE executable starts with 0x4d 0x5a.  */
598   if (b1 == 0x4d && b2 == 0x5a)
599     return RES_FORMAT_COFF;
600
601   /* A COFF .o file starts with a COFF magic number.  */
602   magic = (b2 << 8) | b1;
603   switch (magic)
604     {
605     case 0x14c: /* i386 */
606     case 0x166: /* MIPS */
607     case 0x184: /* Alpha */
608     case 0x268: /* 68k */
609     case 0x1f0: /* PowerPC */
610     case 0x290: /* PA */
611       return RES_FORMAT_COFF;
612     }
613
614   /* A RES file starts with 0x0 0x0 0x0 0x0 0x20 0x0 0x0 0x0.  */
615   if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0 && b5 == 0x20)
616     return RES_FORMAT_RES;
617
618   /* If every character is printable or space, assume it's an RC file.  */
619   if ((ISPRINT (b1) || ISSPACE (b1))
620       && (ISPRINT (b2) || ISSPACE (b2))
621       && (ISPRINT (b3) || ISSPACE (b3))
622       && (ISPRINT (b4) || ISSPACE (b4))
623       && (ISPRINT (b5) || ISSPACE (b5)))
624     return RES_FORMAT_RC;
625
626   /* Otherwise, we give up.  */
627   fatal (_("can not determine type of file `%s'; use the -J option"),
628          filename);
629
630   /* Return something to silence the compiler warning.  */
631   return RES_FORMAT_UNKNOWN;
632 }
633
634 /* Print a usage message and exit.  */
635
636 static void
637 usage (FILE *stream, int status)
638 {
639   fprintf (stream, _("Usage: %s [option(s)] [input-file] [output-file]\n"),
640            program_name);
641   fprintf (stream, _(" The options are:\n\
642   -i --input=<file>            Name input file\n\
643   -o --output=<file>           Name output file\n\
644   -J --input-format=<format>   Specify input format\n\
645   -O --output-format=<format>  Specify output format\n\
646   -F --target=<target>         Specify COFF target\n\
647      --preprocessor=<program>  Program to use to preprocess rc file\n\
648   -I --include-dir=<dir>       Include directory when preprocessing rc file\n\
649   -D --define <sym>[=<val>]    Define SYM when preprocessing rc file\n\
650   -U --undefine <sym>          Undefine SYM when preprocessing rc file\n\
651   -v --verbose                 Verbose - tells you what it's doing\n\
652   -l --language=<val>          Set language when reading rc file\n\
653      --use-temp-file           Use a temporary file instead of popen to read\n\
654                                the preprocessor output\n\
655      --no-use-temp-file        Use popen (default)\n"));
656 #ifdef YYDEBUG
657   fprintf (stream, _("\
658      --yydebug                 Turn on parser debugging\n"));
659 #endif
660   fprintf (stream, _("\
661   -r                           Ignored for compatibility with rc\n\
662   @<file>                      Read options from <file>\n\
663   -h --help                    Print this help message\n\
664   -V --version                 Print version information\n"));
665   fprintf (stream, _("\
666 FORMAT is one of rc, res, or coff, and is deduced from the file name\n\
667 extension if not specified.  A single file name is an input file.\n\
668 No input-file is stdin, default rc.  No output-file is stdout, default rc.\n"));
669
670   list_supported_targets (program_name, stream);
671
672   if (status == 0)
673     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
674
675   exit (status);
676 }
677
678 /* Quote characters that will confuse the shell when we run the preprocessor.  */
679
680 static const char *
681 quot (const char *string)
682 {
683   static char *buf = 0;
684   static int buflen = 0;
685   int slen = strlen (string);
686   const char *src;
687   char *dest;
688
689   if ((buflen < slen * 2 + 2) || !buf)
690     {
691       buflen = slen * 2 + 2;
692       if (buf)
693         free (buf);
694       buf = (char *) xmalloc (buflen);
695     }
696
697   for (src=string, dest=buf; *src; src++, dest++)
698     {
699       if (*src == '(' || *src == ')' || *src == ' ')
700         *dest++ = '\\';
701       *dest = *src;
702     }
703   *dest = 0;
704   return buf;
705 }
706
707 /* Long options.  */
708
709 /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
710
711 #define OPTION_PREPROCESSOR     150
712 #define OPTION_USE_TEMP_FILE    (OPTION_PREPROCESSOR + 1)
713 #define OPTION_NO_USE_TEMP_FILE (OPTION_USE_TEMP_FILE + 1)
714 #define OPTION_YYDEBUG          (OPTION_NO_USE_TEMP_FILE + 1)
715
716 static const struct option long_options[] =
717 {
718   {"input", required_argument, 0, 'i'},
719   {"output", required_argument, 0, 'o'},
720   {"input-format", required_argument, 0, 'J'},
721   {"output-format", required_argument, 0, 'O'},
722   {"target", required_argument, 0, 'F'},
723   {"preprocessor", required_argument, 0, OPTION_PREPROCESSOR},
724   {"include-dir", required_argument, 0, 'I'},
725   {"define", required_argument, 0, 'D'},
726   {"undefine", required_argument, 0, 'U'},
727   {"verbose", no_argument, 0, 'v'},
728   {"language", required_argument, 0, 'l'},
729   {"use-temp-file", no_argument, 0, OPTION_USE_TEMP_FILE},
730   {"no-use-temp-file", no_argument, 0, OPTION_NO_USE_TEMP_FILE},
731   {"yydebug", no_argument, 0, OPTION_YYDEBUG},
732   {"version", no_argument, 0, 'V'},
733   {"help", no_argument, 0, 'h'},
734   {0, no_argument, 0, 0}
735 };
736
737 /* This keeps gcc happy when using -Wmissing-prototypes -Wstrict-prototypes.  */
738 int main (int, char **);
739
740 /* The main function.  */
741
742 int
743 main (int argc, char **argv)
744 {
745   int c;
746   char *input_filename;
747   char *output_filename;
748   enum res_format input_format;
749   enum res_format input_format_tmp;
750   enum res_format output_format;
751   char *target;
752   char *preprocessor;
753   char *preprocargs;
754   const char *quotedarg;
755   int language;
756   struct res_directory *resources;
757   int use_temp_file;
758
759 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
760   setlocale (LC_MESSAGES, "");
761 #endif
762 #if defined (HAVE_SETLOCALE)
763   setlocale (LC_CTYPE, "");
764 #endif
765   bindtextdomain (PACKAGE, LOCALEDIR);
766   textdomain (PACKAGE);
767
768   program_name = argv[0];
769   xmalloc_set_program_name (program_name);
770
771   expandargv (&argc, &argv);
772
773   bfd_init ();
774   set_default_bfd_target ();
775
776   res_init ();
777
778   input_filename = NULL;
779   output_filename = NULL;
780   input_format = RES_FORMAT_UNKNOWN;
781   output_format = RES_FORMAT_UNKNOWN;
782   target = NULL;
783   preprocessor = NULL;
784   preprocargs = NULL;
785   language = 0x409;   /* LANG_ENGLISH, SUBLANG_ENGLISH_US.  */
786   use_temp_file = 0;
787
788   while ((c = getopt_long (argc, argv, "f:i:l:o:I:J:O:F:D:U:rhHvV", long_options,
789                            (int *) 0)) != EOF)
790     {
791       switch (c)
792         {
793         case 'i':
794           input_filename = optarg;
795           break;
796
797         case 'f':
798           /* For compatibility with rc we accept "-fo <name>" as being the
799              equivalent of "-o <name>".  We do not advertise this fact
800              though, as we do not want users to use non-GNU like command
801              line switches.  */
802           if (*optarg != 'o')
803             fatal (_("invalid option -f\n"));
804           optarg++;
805           if (* optarg == 0)
806             {
807               if (optind == argc)
808                 fatal (_("No filename following the -fo option.\n"));
809               optarg = argv [optind++];
810             }
811           /* Fall through.  */
812
813         case 'o':
814           output_filename = optarg;
815           break;
816
817         case 'J':
818           input_format = format_from_name (optarg, 1);
819           break;
820
821         case 'O':
822           output_format = format_from_name (optarg, 1);
823           break;
824
825         case 'F':
826           target = optarg;
827           break;
828
829         case OPTION_PREPROCESSOR:
830           preprocessor = optarg;
831           break;
832
833         case 'D':
834         case 'U':
835           if (preprocargs == NULL)
836             {
837               quotedarg = quot (optarg);
838               preprocargs = xmalloc (strlen (quotedarg) + 3);
839               sprintf (preprocargs, "-%c%s", c, quotedarg);
840             }
841           else
842             {
843               char *n;
844
845               quotedarg = quot (optarg);
846               n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
847               sprintf (n, "%s -%c%s", preprocargs, c, quotedarg);
848               free (preprocargs);
849               preprocargs = n;
850             }
851           break;
852
853         case 'r':
854           /* Ignored for compatibility with rc.  */
855           break;
856
857         case 'v':
858           verbose ++;
859           break;
860
861         case 'I':
862           /* For backward compatibility, should be removed in the future.  */
863           input_format_tmp = format_from_name (optarg, 0);
864           if (input_format_tmp != RES_FORMAT_UNKNOWN)
865             {
866               fprintf (stderr, _("Option -I is deprecated for setting the input format, please use -J instead.\n"));
867               input_format = input_format_tmp;
868               break;
869             }
870
871           if (preprocargs == NULL)
872             {
873               quotedarg = quot (optarg);
874               preprocargs = xmalloc (strlen (quotedarg) + 3);
875               sprintf (preprocargs, "-I%s", quotedarg);
876             }
877           else
878             {
879               char *n;
880
881               quotedarg = quot (optarg);
882               n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
883               sprintf (n, "%s -I%s", preprocargs, quotedarg);
884               free (preprocargs);
885               preprocargs = n;
886             }
887
888           {
889             struct include_dir *n, **pp;
890
891             n = (struct include_dir *) xmalloc (sizeof *n);
892             n->next = NULL;
893             n->dir = optarg;
894
895             for (pp = &include_dirs; *pp != NULL; pp = &(*pp)->next)
896               ;
897             *pp = n;
898           }
899
900           break;
901
902         case 'l':
903           language = strtol (optarg, (char **) NULL, 16);
904           break;
905
906         case OPTION_USE_TEMP_FILE:
907           use_temp_file = 1;
908           break;
909
910         case OPTION_NO_USE_TEMP_FILE:
911           use_temp_file = 0;
912           break;
913
914 #ifdef YYDEBUG
915         case OPTION_YYDEBUG:
916           yydebug = 1;
917           break;
918 #endif
919
920         case 'h':
921         case 'H':
922           usage (stdout, 0);
923           break;
924
925         case 'V':
926           print_version ("windres");
927           break;
928
929         default:
930           usage (stderr, 1);
931           break;
932         }
933     }
934
935   if (input_filename == NULL && optind < argc)
936     {
937       input_filename = argv[optind];
938       ++optind;
939     }
940
941   if (output_filename == NULL && optind < argc)
942     {
943       output_filename = argv[optind];
944       ++optind;
945     }
946
947   if (argc != optind)
948     usage (stderr, 1);
949
950   if (input_format == RES_FORMAT_UNKNOWN)
951     {
952       if (input_filename == NULL)
953         input_format = RES_FORMAT_RC;
954       else
955         input_format = format_from_filename (input_filename, 1);
956     }
957
958   if (output_format == RES_FORMAT_UNKNOWN)
959     {
960       if (output_filename == NULL)
961         output_format = RES_FORMAT_RC;
962       else
963         output_format = format_from_filename (output_filename, 0);
964     }
965
966   /* Read the input file.  */
967   switch (input_format)
968     {
969     default:
970       abort ();
971     case RES_FORMAT_RC:
972       resources = read_rc_file (input_filename, preprocessor, preprocargs,
973                                 language, use_temp_file);
974       break;
975     case RES_FORMAT_RES:
976       resources = read_res_file (input_filename);
977       break;
978     case RES_FORMAT_COFF:
979       resources = read_coff_rsrc (input_filename, target);
980       break;
981     }
982
983   if (resources == NULL)
984     fatal (_("no resources"));
985
986   /* Sort the resources.  This is required for COFF, convenient for
987      rc, and unimportant for res.  */
988   resources = sort_resources (resources);
989
990   /* Write the output file.  */
991   reswr_init ();
992
993   switch (output_format)
994     {
995     default:
996       abort ();
997     case RES_FORMAT_RC:
998       write_rc_file (output_filename, resources);
999       break;
1000     case RES_FORMAT_RES:
1001       write_res_file (output_filename, resources);
1002       break;
1003     case RES_FORMAT_COFF:
1004       write_coff_file (output_filename, target, resources);
1005       break;
1006     }
1007
1008   xexit (0);
1009   return 0;
1010 }