Do not display the long options in the usage message if we don't
[wine] / tools / wrc / wrc.c
1 /*
2  * Copyright  Martin von Loewis, 1994
3  * Copyrignt 1998 Bertho A. Stultiens (BS)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * History:
20  * 30-Apr-2000 BS       - Integrated a new preprocessor (-E and -N)
21  * 20-Jun-1998 BS       - Added -L option to prevent case conversion
22  *                        of embedded filenames.
23  *
24  * 08-Jun-1998 BS       - Added -A option to generate autoregister code
25  *                        for winelib operation.
26  *
27  * 21-May-1998 BS       - Removed the CPP option. Its internal now.
28  *                      - Added implementations for defines and includes
29  *                        on the commandline.
30  *
31  * 30-Apr-1998 BS       - The options now contain nearly the entire alphabet.
32  *                        Seems to be a sign for too much freedom. I implemeted
33  *                        most of them as a user choice possibility for things
34  *                        that I do not know what to put there by default.
35  *                      - -l and -L options are now known as -t and -T.
36  *
37  * 23-Apr-1998 BS       - Finally gave up on backward compatibility on the
38  *                        commandline (after a blessing from the newsgroup).
39  *                        So, I changed the lot.
40  *
41  * 17-Apr-1998 BS       - Added many new command-line options but took care
42  *                        that it would not break old scripts (sigh).
43  *
44  * 16-Apr-1998 BS       - There is not much left of the original source...
45  *                        I had to rewrite most of it because the parser
46  *                        changed completely with all the types etc..
47  *
48  */
49
50 #include "config.h"
51 #include "wine/port.h"
52
53 #include <stdio.h>
54 #include <stdlib.h>
55 #ifdef HAVE_UNISTD_H
56 # include <unistd.h>
57 #endif
58 #include <string.h>
59 #include <assert.h>
60 #include <ctype.h>
61 #include <signal.h>
62 #ifdef HAVE_GETOPT_H
63 # include <getopt.h>
64 #endif
65
66 #include "wrc.h"
67 #include "utils.h"
68 #include "writeres.h"
69 #include "readres.h"
70 #include "dumpres.h"
71 #include "genres.h"
72 #include "newstruc.h"
73 #include "parser.h"
74 #include "../wpp/wpp.h"
75
76 #ifndef INCLUDEDIR
77 #define INCLUDEDIR "/usr/local/include/wine"
78 #endif
79
80 static char usage[] =
81         "Usage: wrc [options...] [infile[.rc|.res]] [outfile]\n"
82         "   -a n        Alignment of resource (win16 only, default is 4)\n"
83         "   -A          Auto register resources (only with gcc 2.7 and better)\n"
84         "   -b          Create an assembly array from a binary .res file\n"
85         "   -B x        Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
86         "               (win32 only; default is n[ative] which equals "
87 #ifdef WORDS_BIGENDIAN
88         "big"
89 #else
90         "little"
91 #endif
92         "-endian)\n"
93         "   -c          Add 'const' prefix to C constants\n"
94         "   -C cp       Set the resource's codepage to cp (default is 0)\n"
95         "   -d n        Set debug level to 'n'\n"
96         "   -D id[=val] Define preprocessor identifier id=val\n"
97         "   -e          Disable recognition of win32 keywords in 16bit compile\n"
98         "   -E          Preprocess only\n"
99         "   -F target   Ignored for compatibility with windres\n"
100         "   -g          Add symbols to the global c namespace\n"
101         "   -h          Also generate a .h file\n"
102         "   -H file     Same as -h but written to file\n"
103         "   -i file     The name of the input file.\n"
104         "   -I path     Set include search dir to path (multiple -I allowed)\n"
105         "   -J          Do not search the standard include path\n"
106         "   -l lan      Set default language to lan (default is neutral {0, 0})\n"
107         "   -L          Leave case of embedded filenames as is\n"
108         "   -m          Do not remap numerical resource IDs\n"
109         "   -n          Do not generate .s file\n"
110         "   -N          Do not preprocess input\n"
111         "   -o file     Output to file (default is infile.[res|s|h]\n"
112         "   -O format   The output format to generate. format may be `res' only.\n"
113         "   -p prefix   Give a prefix for the generated names\n"
114         "   -r          Create binary .res file (compile only)\n"
115         "   -s          Add structure with win32/16 (PE/NE) resource directory\n"
116         "   -t          Generate indirect loadable resource tables\n"
117         "   -T          Generate only indirect loadable resources tables\n"
118         "   -V          Print version and exit\n"
119         "   -w 16|32    Select win16 or win32 output (default is win32)\n"
120         "   -W          Enable pedantic warnings\n"
121 #ifdef HAVE_GETOPT_LONG
122         "The following long options are supported:\n"
123         "   --input             Synonym for -i.\n"
124         "   --output            Synonym for -o.\n"
125         "   --target            Synonym for -F.\n"
126         "   --format            Synonym for -O.\n"
127         "   --include-dir       Synonym for -I.\n"
128         "   --nostdinc          Synonym for -J.\n"
129         "   --define            Synonym for -D.\n"
130         "   --language          Synonym for -l.\n"
131         "   --preprocessor      Specify the preprocessor to use, including arguments.\n"
132         "   --help              Prints a usage summary.\n"
133         "   --version           Synonym for -V.\n"
134 #endif
135         "Input is taken from stdin if no sourcefile specified.\n"
136         "Debug level 'n' is a bitmask with following meaning:\n"
137         "    * 0x01 Tell which resource is parsed (verbose mode)\n"
138         "    * 0x02 Dump internal structures\n"
139         "    * 0x04 Create a parser trace (yydebug=1)\n"
140         "    * 0x08 Preprocessor messages\n"
141         "    * 0x10 Preprocessor lex messages\n"
142         "    * 0x20 Preprocessor yacc trace\n"
143         "The -o option only applies to the final destination file, which is\n"
144         "in case of normal compile a .s file. You must use the '-H header.h'\n"
145         "option to override the header-filename.\n"
146         "If no input filename is given and the output name is not overridden\n"
147         "with -o and/or -H, then the output is written to \"wrc.tab.[sh]\"\n"
148         ;
149
150 char version_string[] = "Wine Resource Compiler Version " WRC_FULLVERSION "\n"
151                         "Copyright 1998-2000 Bertho A. Stultiens\n"
152                         "          1994 Martin von Loewis\n";
153
154 /*
155  * Default prefix for resource names used in the C array.
156  * Option '-p name' sets it to 'name'
157  */
158 char *prefix = __ASM_NAME("_Resource");
159
160 /*
161  * Set if compiling in 32bit mode (default).
162  */
163 int win32 = 1;
164
165 /*
166  * Set when generated C variables should be prefixed with 'const'
167  */
168 int constant = 0;
169
170 /*
171  * Create a .res file from the source and exit (-r option).
172  */
173 int create_res = 0;
174
175 /*
176  * debuglevel == DEBUGLEVEL_NONE        Don't bother
177  * debuglevel & DEBUGLEVEL_CHAT         Say whats done
178  * debuglevel & DEBUGLEVEL_DUMP         Dump internal structures
179  * debuglevel & DEBUGLEVEL_TRACE        Create parser trace
180  * debuglevel & DEBUGLEVEL_PPMSG        Preprocessor messages
181  * debuglevel & DEBUGLEVEL_PPLEX        Preprocessor lex trace
182  * debuglevel & DEBUGLEVEL_PPTRACE      Preprocessor yacc trace
183  */
184 int debuglevel = DEBUGLEVEL_NONE;
185
186 /*
187  * Recognize win32 keywords if set (-w 32 enforces this),
188  * otherwise set with -e option.
189  */
190 int extensions = 1;
191
192 /*
193  * Set when creating C array from .res file (-b option).
194  */
195 int binary = 0;
196
197 /*
198  * Set when an additional C-header is to be created in compile (-h option).
199  */
200 int create_header = 0;
201
202 /*
203  * Set when the NE/PE resource directory should be dumped into
204  * the output file.
205  */
206 int create_dir = 0;
207
208 /*
209  * Set when all symbols should be added to the global namespace (-g option)
210  */
211 int global = 0;
212
213 /*
214  * Set when indirect loadable resource tables should be created (-t)
215  */
216 int indirect = 0;
217
218 /*
219  * Set when _only_ indirect loadable resource tables should be created (-T)
220  */
221 int indirect_only = 0;
222
223 /*
224  * NE segment resource aligment (-a option)
225  */
226 int alignment = 4;
227 int alignment_pwr;
228
229 /*
230  * Cleared when the assembly file must be suppressed (-n option)
231  */
232 int create_s = 1;
233
234 /*
235  * Language setting for resources (-l option)
236  */
237 language_t *currentlanguage = NULL;
238
239 /*
240  * The codepage to write in win32 PE resource segment (-C option)
241  */
242 DWORD codepage = 0;
243
244 /*
245  * Set when extra warnings should be generated (-W option)
246  */
247 int pedantic = 0;
248
249 /*
250  * Set when autoregister code must be added to the output (-A option)
251  */
252 int auto_register = 0;
253
254 /*
255  * Set when the case of embedded filenames should not be converted
256  * to lower case (-L option)
257  */
258 int leave_case = 0;
259
260 /*
261  * The output byte-order of resources (set with -B)
262  */
263 int byteorder = WRC_BO_NATIVE;
264
265 /*
266  * Set when _only_ to run the preprocessor (-E option)
267  */
268 int preprocess_only = 0;
269
270 /*
271  * Set when _not_ to run the preprocessor (-N option)
272  */
273 int no_preprocess = 0;
274
275 /*
276  * Cleared when _not_ to remap resource types (-m option)
277  */
278 int remap = 1;
279
280 char *output_name;              /* The name given by the -o option */
281 char *input_name;               /* The name given on the command-line */
282 char *header_name;              /* The name given by the -H option */
283 char *temp_name;                /* Temporary file for preprocess pipe */
284
285 int line_number = 1;            /* The current line */
286 int char_number = 1;            /* The current char pos within the line */
287
288 char *cmdline;                  /* The entire commandline */
289 time_t now;                     /* The time of start of wrc */
290
291 resource_t *resource_top;       /* The top of the parsed resources */
292
293 int getopt (int argc, char *const *argv, const char *optstring);
294 static void rm_tempfile(void);
295 static void segvhandler(int sig);
296
297 #ifdef HAVE_GETOPT_LONG
298 static struct option long_options[] = {
299         { "input", 1, 0, 'i' },
300         { "output", 1, 0, 'o' },
301         { "target", 1, 0, 'F' },
302         { "format", 1, 0, 'O' },
303         { "include-dir", 1, 0, 'I' },
304         { "nostdinc", 0, 0, 'J' },
305         { "define", 1, 0, 'D' },
306         { "language", 1, 0, 'l' },
307         { "preprocessor", 1, 0, 1 },
308         { "help", 0, 0, 2 },
309         { "version", 0, 0, 'V' },
310         { 0, 0, 0, 0 }
311 };
312 #endif
313
314 int main(int argc,char *argv[])
315 {
316         extern char* optarg;
317         extern int   optind;
318         int optc, opti = 0;
319         int stdinc = 1;
320         int lose = 0;
321         int ret;
322         int a;
323         int i;
324         int cmdlen;
325
326         signal(SIGSEGV, segvhandler);
327
328         now = time(NULL);
329
330         /* First rebuild the commandline to put in destination */
331         /* Could be done through env[], but not all OS-es support it */
332         cmdlen = 4; /* for "wrc " */
333         for(i = 1; i < argc; i++)
334                 cmdlen += strlen(argv[i]) + 1;
335         cmdline = (char *)xmalloc(cmdlen);
336         strcpy(cmdline, "wrc ");
337         for(i = 1; i < argc; i++)
338         {
339                 strcat(cmdline, argv[i]);
340                 if(i < argc-1)
341                         strcat(cmdline, " ");
342         }
343
344 #ifdef HAVE_GETOPT_LONG
345         while((optc = getopt_long(argc, argv, "a:AbB:cC:d:D:eEF:ghH:i:I:Jl:LmnNo:O:p:rstTVw:W", long_options, &opti)) != EOF)
346 #else
347         while((optc = getopt(argc, argv, "a:AbB:cC:d:D:eEF:ghH:i:I:Jl:LmnNo:O:p:rstTVw:W")) != EOF)
348 #endif
349         {
350                 switch(optc)
351                 {
352                 case 1:
353                         fprintf(stderr, "--preprocessor option not yet supported, ignored.\n");
354                         break;
355                 case 2:
356                         printf(usage);
357                         exit(0);
358                         break;
359                 case 'a':
360                         alignment = atoi(optarg);
361                         break;
362                 case 'A':
363                         auto_register = 1;
364                         break;
365                 case 'b':
366                         binary = 1;
367                         break;
368                 case 'B':
369                         switch(optarg[0])
370                         {
371                         case 'n':
372                         case 'N':
373                                 byteorder = WRC_BO_NATIVE;
374                                 break;
375                         case 'l':
376                         case 'L':
377                                 byteorder = WRC_BO_LITTLE;
378                                 break;
379                         case 'b':
380                         case 'B':
381                                 byteorder = WRC_BO_BIG;
382                                 break;
383                         default:
384                                 fprintf(stderr, "Byte ordering must be n[ative], l[ittle] or b[ig]\n");
385                                 lose++;
386                         }
387                         break;
388                 case 'c':
389                         constant = 1;
390                         break;
391                 case 'C':
392                         codepage = strtol(optarg, NULL, 0);
393                         break;
394                 case 'd':
395                         debuglevel = strtol(optarg, NULL, 0);
396                         break;
397                 case 'D':
398                         wpp_add_cmdline_define(optarg);
399                         break;
400                 case 'e':
401                         extensions = 0;
402                         break;
403                 case 'E':
404                         preprocess_only = 1;
405                         break;
406                 case 'F':
407                         /* ignored for compatibility with windres */
408                         break;
409                 case 'g':
410                         global = 1;
411                         break;
412                 case 'H':
413                         header_name = strdup(optarg);
414                         /* Fall through */
415                 case 'h':
416                         create_header = 1;
417                         break;
418                 case 'i':
419                         if (!input_name) input_name = strdup(optarg);
420                         else error("Too many input files.\n");
421                         break;
422                 case 'I':
423                         wpp_add_include_path(optarg);
424                         break;
425                 case 'J':
426                         stdinc = 0;
427                         break;
428                 case 'l':
429                         {
430                                 int lan;
431                                 lan = strtol(optarg, NULL, 0);
432                                 if (get_language_codepage(PRIMARYLANGID(lan), SUBLANGID(lan)) == -1)
433                                         error("Language %04x is not supported",lan);
434                                 currentlanguage = new_language(PRIMARYLANGID(lan), SUBLANGID(lan));
435                         }
436                         break;
437                 case 'L':
438                         leave_case = 1;
439                         break;
440                 case 'm':
441                         remap = 0;
442                         break;
443                 case 'n':
444                         create_s = 0;
445                         break;
446                 case 'N':
447                         no_preprocess = 1;
448                         break;
449                 case 'o':
450                         if (!output_name) output_name = strdup(optarg);
451                         else error("Too many output files.\n");
452                         break;
453                 case 'O':
454                         if (strcmp(optarg, "res"))
455                                 error("Output format %s not supported.", optarg);
456                         break;
457                 case 'p':
458                         prefix = xstrdup(optarg);
459                         break;
460                 case 'r':
461                         create_res = 1;
462                         break;
463                 case 's':
464                         create_dir = 1;
465                         break;
466                 case 'T':
467                         indirect_only = 1;
468                         /* Fall through */
469                 case 't':
470                         indirect = 1;
471                         break;
472                 case 'V':
473                         printf(version_string);
474                         exit(0);
475                         break;
476                 case 'w':
477                         if(!strcmp(optarg, "16"))
478                                 win32 = 0;
479                         else if(!strcmp(optarg, "32"))
480                                 win32 = 1;
481                         else
482                                 lose++;
483                         break;
484                 case 'W':
485                         pedantic = 1;
486                         wpp_set_pedantic(1);
487                         break;
488                 default:
489                         lose++;
490                         break;
491                 }
492         }
493
494         if(lose)
495         {
496                 fprintf(stderr, usage);
497                 return 1;
498         }
499
500         /* If we do need to search standard includes, add them to the path */
501         if (stdinc)
502         {
503                 wpp_add_include_path(INCLUDEDIR"/msvcrt");
504                 wpp_add_include_path(INCLUDEDIR"/windows");
505         }
506         
507         /* Check for input file on command-line */
508         if(optind < argc)
509         {
510                 if (!input_name) input_name = argv[optind++];
511                 else error("Too many input files.\n");
512         }
513
514         /* Check for output file on command-line */
515         if(optind < argc)
516         {
517                 if (!output_name) output_name = argv[optind++];
518                 else error("Too many output files.\n");
519         }
520
521         /* Try to guess the output format based on output name */
522         if (output_name)
523         {
524                 char *dotstr = strrchr(output_name, '.');
525                 if (dotstr && (strcmp(dotstr+1, "res") == 0 ||
526                                strcmp(dotstr+1, "o") == 0))
527                         create_res = 1;
528         }
529
530
531         /* Check the command line options for invalid combinations */
532         if(win32)
533         {
534                 if(!extensions)
535                 {
536                         warning("Option -e ignored with 32bit compile\n");
537                         extensions = 1;
538                 }
539         }
540
541         if(create_res)
542         {
543                 if(constant)
544                 {
545                         warning("Option -c ignored with compile to .res\n");
546                         constant = 0;
547                 }
548
549                 if(create_header)
550                 {
551                         warning("Option -[h|H] ignored with compile to .res\n");
552                         create_header = 0;
553                 }
554
555                 if(indirect)
556                 {
557                         warning("Option -t ignored with compile to .res\n");
558                         indirect = 0;
559                 }
560
561                 if(indirect_only)
562                 {
563                         warning("Option -T ignored with compile to .res\n");
564                         indirect_only = 0;
565                 }
566
567                 if(global)
568                 {
569                         warning("Option -g ignored with compile to .res\n");
570                         global = 0;
571                 }
572
573                 if(create_dir)
574                 {
575                         error("Option -r and -s cannot be used together\n");
576                 }
577
578                 if(binary)
579                 {
580                         error("Option -r and -b cannot be used together\n");
581                 }
582         }
583
584         if(byteorder != WRC_BO_NATIVE)
585         {
586                 if(binary)
587                         error("Forced byteordering not supported for binary resources\n");
588         }
589
590         if(preprocess_only)
591         {
592                 if(constant)
593                 {
594                         warning("Option -c ignored with preprocess only\n");
595                         constant = 0;
596                 }
597
598                 if(create_header)
599                 {
600                         warning("Option -[h|H] ignored with preprocess only\n");
601                         create_header = 0;
602                 }
603
604                 if(indirect)
605                 {
606                         warning("Option -t ignored with preprocess only\n");
607                         indirect = 0;
608                 }
609
610                 if(indirect_only)
611                 {
612                         error("Option -E and -T cannot be used together\n");
613                 }
614
615                 if(global)
616                 {
617                         warning("Option -g ignored with preprocess only\n");
618                         global = 0;
619                 }
620
621                 if(create_dir)
622                 {
623                         warning("Option -s ignored with preprocess only\n");
624                         create_dir = 0;
625                 }
626
627                 if(binary)
628                 {
629                         error("Option -E and -b cannot be used together\n");
630                 }
631
632                 if(no_preprocess)
633                 {
634                         error("Option -E and -N cannot be used together\n");
635                 }
636         }
637
638 #if !defined(HAVE_WINE_CONSTRUCTOR)
639         if(auto_register)
640         {
641                 warning("Autoregister code non-operable (HAVE_WINE_CONSTRUCTOR not defined)");
642                 auto_register = 0;
643         }
644 #endif
645
646         /* Set alignment power */
647         a = alignment;
648         for(alignment_pwr = 0; alignment_pwr < 10 && a > 1; alignment_pwr++)
649         {
650                 a >>= 1;
651         }
652         if(a != 1)
653         {
654                 error("Alignment must be between 1 and 1024");
655         }
656         if((1 << alignment_pwr) != alignment)
657         {
658                 error("Alignment must be a power of 2");
659         }
660
661         /* Kill io buffering when some kind of debuglevel is enabled */
662         if(debuglevel)
663         {
664                 setbuf(stdout,0);
665                 setbuf(stderr,0);
666         }
667
668         yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
669         yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
670
671         wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0,
672                        (debuglevel & DEBUGLEVEL_PPTRACE) != 0,
673                        (debuglevel & DEBUGLEVEL_PPMSG) != 0 );
674
675         /* Set the default defined stuff */
676         wpp_add_cmdline_define("__WRC__=" WRC_EXP_STRINGIZE(WRC_MAJOR_VERSION));
677         wpp_add_cmdline_define("__WRC_MINOR__=" WRC_EXP_STRINGIZE(WRC_MINOR_VERSION));
678         wpp_add_cmdline_define("__WRC_MICRO__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION));
679         wpp_add_cmdline_define("__WRC_PATCH__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION));
680
681         wpp_add_cmdline_define("RC_INVOKED=1");
682
683         if(win32)
684         {
685                 wpp_add_cmdline_define("__WIN32__=1");
686                 wpp_add_cmdline_define("__FLAT__=1");
687         }
688
689         /* Check if the user set a language, else set default */
690         if(!currentlanguage)
691                 currentlanguage = new_language(0, 0);
692
693         if(binary && !input_name)
694         {
695                 error("Binary mode requires .res file as input\n");
696         }
697
698         /* Generate appropriate outfile names */
699         if(!output_name && !preprocess_only)
700         {
701                 output_name = dup_basename(input_name, binary ? ".res" : ".rc");
702                 strcat(output_name, create_res ? ".res" : ".s");
703         }
704
705         if(!header_name && !create_res)
706         {
707                 header_name = dup_basename(input_name, binary ? ".res" : ".rc");
708                 strcat(header_name, ".h");
709         }
710
711         /* Run the preprocessor on the input */
712         if(!no_preprocess && !binary)
713         {
714                 /*
715                  * Preprocess the input to a temp-file, or stdout if
716                  * no output was given.
717                  */
718
719                 chat("Starting preprocess");
720
721                 if (!preprocess_only)
722                 {
723                     atexit(rm_tempfile);
724                     ret = wpp_parse_temp( input_name, output_name, &temp_name );
725                 }
726                 else if (output_name)
727                 {
728                     FILE *output;
729
730                     if (!(output = fopen( output_name, "w" )))
731                         error( "Could not open %s for writing\n", output_name );
732                     ret = wpp_parse( input_name, output );
733                     fclose( output );
734                 }
735                 else
736                 {
737                     ret = wpp_parse( input_name, stdout );
738                 }
739
740                 if(ret)
741                         exit(1);        /* Error during preprocess */
742
743                 if(preprocess_only)
744                         exit(0);
745
746                 input_name = temp_name;
747         }
748
749         if(!binary)
750         {
751                 /* Go from .rc to .res or .s */
752                 chat("Starting parse");
753
754                 if(!(yyin = fopen(input_name, "rb")))
755                         error("Could not open %s for input\n", input_name);
756
757                 ret = yyparse();
758
759                 if(input_name)
760                         fclose(yyin);
761
762                 if(ret)
763                 {
764                         /* Error during parse */
765                         exit(1);
766                 }
767
768                 if(debuglevel & DEBUGLEVEL_DUMP)
769                         dump_resources(resource_top);
770
771                 /* Convert the internal lists to binary data */
772                 resources2res(resource_top);
773
774                 if(create_res)
775                 {
776                         chat("Writing .res-file");
777                         write_resfile(output_name, resource_top);
778                 }
779                 else
780                 {
781                         if(create_s)
782                         {
783                                 chat("Writing .s-file");
784                                 write_s_file(output_name, resource_top);
785                         }
786                         if(create_header)
787                         {
788                                 chat("Writing .h-file");
789                                 write_h_file(header_name, resource_top);
790                         }
791                 }
792
793         }
794         else
795         {
796                 /* Go from .res to .s */
797                 chat("Reading .res-file");
798                 resource_top = read_resfile(input_name);
799                 if(create_s)
800                 {
801                         chat("Writing .s-file");
802                         write_s_file(output_name, resource_top);
803                 }
804                 if(create_header)
805                 {
806                         chat("Writing .h-file");
807                         write_h_file(header_name, resource_top);
808                 }
809         }
810
811         return 0;
812 }
813
814
815 static void rm_tempfile(void)
816 {
817         if(temp_name)
818                 unlink(temp_name);
819 }
820
821 static void segvhandler(int sig)
822 {
823         fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
824         fflush(stdout);
825         fflush(stderr);
826         abort();
827 }