ok() does not support '%S'. Store the Ansi version, convert to Unicode
[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 #ifdef WORDS_BIGENDIAN
81 #define ENDIAN  "big"
82 #else
83 #define ENDIAN  "little"
84 #endif
85
86 static char usage[] =
87         "Usage: wrc [options...] [infile[.rc|.res]] [outfile]\n"
88         "   -a n        Alignment of resource (win16 only, default is 4)\n"
89         "   -A          Auto register resources (only with gcc 2.7 and better)\n"
90         "   -b          Create an assembly array from a binary .res file\n"
91         "   -B x        Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
92         "               (win32 only; default is " ENDIAN "-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          Prints this summary.\n"
102         "   -i file     The name of the input file.\n"
103         "   -I path     Set include search dir to path (multiple -I allowed)\n"
104         "   -J          Do not search the standard include path\n"
105         "   -l lan      Set default language to lan (default is neutral {0, 0})\n"
106         "   -m          Do not remap numerical resource IDs\n"
107         "   -N          Do not preprocess input\n"
108         "   -o file     Output to file (default is infile.[res|s|h]\n"
109         "   -O format   The output format: one of `res', 'asm', 'hdr'.\n"
110         "   -p prefix   Give a prefix for the generated names\n"
111         "   -s          Add structure with win32/16 (PE/NE) resource directory\n"
112         "   -t          Generate indirect loadable resource tables\n"
113         "   -T          Generate only indirect loadable resources tables\n"
114         "   -v          Enable verbose mode.\n"
115         "   -V          Print version and exit\n"
116         "   -w 16|32    Select win16 or win32 output (default is win32)\n"
117         "   -W          Enable pedantic warnings\n"
118 #ifdef HAVE_GETOPT_LONG
119         "The following long options are supported:\n"
120         "   --input             Synonym for -i.\n"
121         "   --output            Synonym for -o.\n"
122         "   --target            Synonym for -F.\n"
123         "   --format            Synonym for -O.\n"
124         "   --include-dir       Synonym for -I.\n"
125         "   --nostdinc          Synonym for -J.\n"
126         "   --define            Synonym for -D.\n"
127         "   --language          Synonym for -l.\n"
128         "   --use-temp-file     Ignored for compatibility with windres.\n"
129         "   --no-use-temp-file  Ignored for compatibility with windres.\n"
130         "   --preprocessor      Specify the preprocessor to use, including arguments.\n"
131         "   --help              Synonym for -h.\n"
132         "   --version           Synonym for -V.\n"
133 #endif
134         "Input is taken from stdin if no sourcefile specified.\n"
135         "Debug level 'n' is a bitmask with following meaning:\n"
136         "    * 0x01 Tell which resource is parsed (verbose mode)\n"
137         "    * 0x02 Dump internal structures\n"
138         "    * 0x04 Create a parser trace (yydebug=1)\n"
139         "    * 0x08 Preprocessor messages\n"
140         "    * 0x10 Preprocessor lex messages\n"
141         "    * 0x20 Preprocessor yacc trace\n"
142         "If no input filename is given and the output name is not overridden\n"
143         "with -o, then the output is written to \"wrc.tab.[sh]\"\n"
144         ;
145
146 char version_string[] = "Wine Resource Compiler Version " WRC_FULLVERSION "\n"
147                         "Copyright 1998-2000 Bertho A. Stultiens\n"
148                         "          1994 Martin von Loewis\n";
149
150 /*
151  * Default prefix for resource names used in the C array.
152  * Option '-p name' sets it to 'name'
153  */
154 char *prefix = __ASM_NAME("_Resource");
155
156 /*
157  * Set if compiling in 32bit mode (default).
158  */
159 int win32 = 1;
160
161 /*
162  * Set when generated C variables should be prefixed with 'const'
163  */
164 int constant = 0;
165
166 /*
167  * Output type (default res)
168  */
169 enum output_t { output_def, output_res, output_asm, output_hdr } output_type = output_def;
170
171 /*
172  * debuglevel == DEBUGLEVEL_NONE        Don't bother
173  * debuglevel & DEBUGLEVEL_CHAT         Say whats done
174  * debuglevel & DEBUGLEVEL_DUMP         Dump internal structures
175  * debuglevel & DEBUGLEVEL_TRACE        Create parser trace
176  * debuglevel & DEBUGLEVEL_PPMSG        Preprocessor messages
177  * debuglevel & DEBUGLEVEL_PPLEX        Preprocessor lex trace
178  * debuglevel & DEBUGLEVEL_PPTRACE      Preprocessor yacc trace
179  */
180 int debuglevel = DEBUGLEVEL_NONE;
181
182 /*
183  * Recognize win32 keywords if set (-w 32 enforces this),
184  * otherwise set with -e option.
185  */
186 int extensions = 1;
187
188 /*
189  * Set when creating C array from .res file (-b option).
190  */
191 int binary = 0;
192
193 /*
194  * Set when the NE/PE resource directory should be dumped into
195  * the output file.
196  */
197 int create_dir = 0;
198
199 /*
200  * Set when all symbols should be added to the global namespace (-g option)
201  */
202 int global = 0;
203
204 /*
205  * Set when indirect loadable resource tables should be created (-t)
206  */
207 int indirect = 0;
208
209 /*
210  * Set when _only_ indirect loadable resource tables should be created (-T)
211  */
212 int indirect_only = 0;
213
214 /*
215  * NE segment resource aligment (-a option)
216  */
217 int alignment = 4;
218 int alignment_pwr;
219
220 /*
221  * Language setting for resources (-l option)
222  */
223 language_t *currentlanguage = NULL;
224
225 /*
226  * The codepage to write in win32 PE resource segment (-C option)
227  */
228 DWORD codepage = 0;
229
230 /*
231  * Set when extra warnings should be generated (-W option)
232  */
233 int pedantic = 0;
234
235 /*
236  * Set when autoregister code must be added to the output (-A option)
237  */
238 int auto_register = 0;
239
240 /*
241  * The output byte-order of resources (set with -B)
242  */
243 int byteorder = WRC_BO_NATIVE;
244
245 /*
246  * Set when _only_ to run the preprocessor (-E option)
247  */
248 int preprocess_only = 0;
249
250 /*
251  * Set when _not_ to run the preprocessor (-N option)
252  */
253 int no_preprocess = 0;
254
255 /*
256  * Cleared when _not_ to remap resource types (-m option)
257  */
258 int remap = 1;
259
260 char *output_name;              /* The name given by the -o option */
261 char *input_name;               /* The name given on the command-line */
262 char *temp_name;                /* Temporary file for preprocess pipe */
263
264 int line_number = 1;            /* The current line */
265 int char_number = 1;            /* The current char pos within the line */
266
267 char *cmdline;                  /* The entire commandline */
268 time_t now;                     /* The time of start of wrc */
269
270 resource_t *resource_top;       /* The top of the parsed resources */
271
272 int getopt (int argc, char *const *argv, const char *optstring);
273 static void rm_tempfile(void);
274 static void segvhandler(int sig);
275
276 static const char* short_options = 
277         "a:AbB:cC:d:D:eEF:ghH:i:I:Jl:LmnNo:O:p:rstTvVw:W";
278 #ifdef HAVE_GETOPT_LONG
279 static struct option long_options[] = {
280         { "input", 1, 0, 'i' },
281         { "output", 1, 0, 'o' },
282         { "target", 1, 0, 'F' },
283         { "format", 1, 0, 'O' },
284         { "include-dir", 1, 0, 'I' },
285         { "nostdinc", 0, 0, 'J' },
286         { "define", 1, 0, 'D' },
287         { "language", 1, 0, 'l' },
288         { "version", 0, 0, 'V' },
289         { "help", 0, 0, 'h' },
290         { "preprocessor", 1, 0, 1 },
291         { "use-temp-file", 0, 0, 2 },
292         { "no-use-temp-file", 0, 0, 3 },
293         { 0, 0, 0, 0 }
294 };
295 #endif
296
297 int main(int argc,char *argv[])
298 {
299         extern char* optarg;
300         extern int   optind;
301         int optc, opti = 0;
302         int stdinc = 1;
303         int lose = 0;
304         int ret;
305         int a;
306         int i;
307         int cmdlen;
308
309         signal(SIGSEGV, segvhandler);
310
311         now = time(NULL);
312
313         /* First rebuild the commandline to put in destination */
314         /* Could be done through env[], but not all OS-es support it */
315         cmdlen = 4; /* for "wrc " */
316         for(i = 1; i < argc; i++)
317                 cmdlen += strlen(argv[i]) + 1;
318         cmdline = (char *)xmalloc(cmdlen);
319         strcpy(cmdline, "wrc ");
320         for(i = 1; i < argc; i++)
321         {
322                 strcat(cmdline, argv[i]);
323                 if(i < argc-1)
324                         strcat(cmdline, " ");
325         }
326
327 #ifdef HAVE_GETOPT_LONG
328         while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF)
329 #else
330         while((optc = getopt(argc, argv, short_options)) != EOF)
331 #endif
332         {
333                 switch(optc)
334                 {
335                 case 1:
336                         fprintf(stderr, "--preprocessor option not yet supported, ignored.\n");
337                         break;
338                 case 2:
339                         fprintf(stderr, "--use-temp-file option not yet supported, ignored.\n");
340                         break;
341                 case 3:
342                         fprintf(stderr, "--no-use-temp-file option not yet supported, ignored.\n");
343                         break;
344                 case 'a':
345                         alignment = atoi(optarg);
346                         break;
347                 case 'A':
348                         auto_register = 1;
349                         break;
350                 case 'b':
351                         binary = 1;
352                         break;
353                 case 'B':
354                         switch(optarg[0])
355                         {
356                         case 'n':
357                         case 'N':
358                                 byteorder = WRC_BO_NATIVE;
359                                 break;
360                         case 'l':
361                         case 'L':
362                                 byteorder = WRC_BO_LITTLE;
363                                 break;
364                         case 'b':
365                         case 'B':
366                                 byteorder = WRC_BO_BIG;
367                                 break;
368                         default:
369                                 fprintf(stderr, "Byte ordering must be n[ative], l[ittle] or b[ig]\n");
370                                 lose++;
371                         }
372                         break;
373                 case 'c':
374                         constant = 1;
375                         break;
376                 case 'C':
377                         codepage = strtol(optarg, NULL, 0);
378                         break;
379                 case 'd':
380                         debuglevel = strtol(optarg, NULL, 0);
381                         break;
382                 case 'D':
383                         wpp_add_cmdline_define(optarg);
384                         break;
385                 case 'e':
386                         extensions = 0;
387                         break;
388                 case 'E':
389                         preprocess_only = 1;
390                         break;
391                 case 'F':
392                         /* ignored for compatibility with windres */
393                         break;
394                 case 'g':
395                         global = 1;
396                         break;
397                 case 'h':
398                         printf(usage);
399                         exit(0);
400                 case 'i':
401                         if (!input_name) input_name = strdup(optarg);
402                         else error("Too many input files.\n");
403                         break;
404                 case 'I':
405                         wpp_add_include_path(optarg);
406                         break;
407                 case 'J':
408                         stdinc = 0;
409                         break;
410                 case 'l':
411                         {
412                                 int lan;
413                                 lan = strtol(optarg, NULL, 0);
414                                 if (get_language_codepage(PRIMARYLANGID(lan), SUBLANGID(lan)) == -1)
415                                         error("Language %04x is not supported",lan);
416                                 currentlanguage = new_language(PRIMARYLANGID(lan), SUBLANGID(lan));
417                         }
418                         break;
419                 case 'm':
420                         remap = 0;
421                         break;
422                 case 'N':
423                         no_preprocess = 1;
424                         break;
425                 case 'o':
426                         if (!output_name) output_name = strdup(optarg);
427                         else error("Too many output files.\n");
428                         break;
429                 case 'O':
430                         if (strcmp(optarg, "res") == 0) output_type = output_res;
431                         else if (strcmp(optarg, "asm") == 0) output_type = output_asm;
432                         else if (strcmp(optarg, "hdr") == 0) output_type = output_hdr;
433                         else error("Output format %s not supported.", optarg);
434                         break;
435                 case 'p':
436                         prefix = xstrdup(optarg);
437                         break;
438                 case 's':
439                         create_dir = 1;
440                         break;
441                 case 'T':
442                         indirect_only = 1;
443                         /* Fall through */
444                 case 't':
445                         indirect = 1;
446                         break;
447                 case 'v':
448                         debuglevel = DEBUGLEVEL_CHAT;
449                         break;
450                 case 'V':
451                         printf(version_string);
452                         exit(0);
453                         break;
454                 case 'w':
455                         if(!strcmp(optarg, "16"))
456                                 win32 = 0;
457                         else if(!strcmp(optarg, "32"))
458                                 win32 = 1;
459                         else
460                                 lose++;
461                         break;
462                 case 'W':
463                         pedantic = 1;
464                         wpp_set_pedantic(1);
465                         break;
466                 default:
467                         lose++;
468                         break;
469                 }
470         }
471
472         if(lose)
473         {
474                 fprintf(stderr, usage);
475                 return 1;
476         }
477
478         /* If we do need to search standard includes, add them to the path */
479         if (stdinc)
480         {
481                 wpp_add_include_path(INCLUDEDIR"/msvcrt");
482                 wpp_add_include_path(INCLUDEDIR"/windows");
483         }
484         
485         /* Check for input file on command-line */
486         if(optind < argc)
487         {
488                 if (!input_name) input_name = argv[optind++];
489                 else error("Too many input files.\n");
490         }
491
492         /* Check for output file on command-line */
493         if(optind < argc)
494         {
495                 if (!output_name) output_name = argv[optind++];
496                 else error("Too many output files.\n");
497         }
498
499         /* Try to guess the output format based on output name */
500         if (output_type == output_def)
501         {
502                 char *dotstr = output_name ? strrchr(output_name, '.') : 0;
503                 
504                 output_type = output_res; /* by default generate .res files */
505                 if (dotstr)
506                 {
507                         if (strcmp(dotstr+1, "s") == 0) output_type = output_asm;
508                         else if(strcmp(dotstr+1, "h") == 0) output_type = output_hdr;
509                 }
510         }
511
512
513         /* Check the command line options for invalid combinations */
514         if(win32)
515         {
516                 if(!extensions)
517                 {
518                         warning("Option -e ignored with 32bit compile\n");
519                         extensions = 1;
520                 }
521         }
522
523         if(output_type == output_res)
524         {
525                 if(constant)
526                 {
527                         warning("Option -c ignored with compile to .res\n");
528                         constant = 0;
529                 }
530
531                 if(indirect)
532                 {
533                         warning("Option -t ignored with compile to .res\n");
534                         indirect = 0;
535                 }
536
537                 if(indirect_only)
538                 {
539                         warning("Option -T ignored with compile to .res\n");
540                         indirect_only = 0;
541                 }
542
543                 if(global)
544                 {
545                         warning("Option -g ignored with compile to .res\n");
546                         global = 0;
547                 }
548
549                 if(create_dir)
550                 {
551                         error("Option -r and -s cannot be used together\n");
552                 }
553
554                 if(binary)
555                 {
556                         error("Option -r and -b cannot be used together\n");
557                 }
558         }
559
560         if(byteorder != WRC_BO_NATIVE)
561         {
562                 if(binary)
563                         error("Forced byteordering not supported for binary resources\n");
564         }
565
566         if(preprocess_only)
567         {
568                 if(constant)
569                 {
570                         warning("Option -c ignored with preprocess only\n");
571                         constant = 0;
572                 }
573
574                 if(indirect)
575                 {
576                         warning("Option -t ignored with preprocess only\n");
577                         indirect = 0;
578                 }
579
580                 if(indirect_only)
581                 {
582                         error("Option -E and -T cannot be used together\n");
583                 }
584
585                 if(global)
586                 {
587                         warning("Option -g ignored with preprocess only\n");
588                         global = 0;
589                 }
590
591                 if(create_dir)
592                 {
593                         warning("Option -s ignored with preprocess only\n");
594                         create_dir = 0;
595                 }
596
597                 if(binary)
598                 {
599                         error("Option -E and -b cannot be used together\n");
600                 }
601
602                 if(no_preprocess)
603                 {
604                         error("Option -E and -N cannot be used together\n");
605                 }
606         }
607
608 #if !defined(HAVE_WINE_CONSTRUCTOR)
609         if(auto_register)
610         {
611                 warning("Autoregister code non-operable (HAVE_WINE_CONSTRUCTOR not defined)");
612                 auto_register = 0;
613         }
614 #endif
615
616         /* Set alignment power */
617         a = alignment;
618         for(alignment_pwr = 0; alignment_pwr < 10 && a > 1; alignment_pwr++)
619         {
620                 a >>= 1;
621         }
622         if(a != 1)
623         {
624                 error("Alignment must be between 1 and 1024");
625         }
626         if((1 << alignment_pwr) != alignment)
627         {
628                 error("Alignment must be a power of 2");
629         }
630
631         /* Kill io buffering when some kind of debuglevel is enabled */
632         if(debuglevel)
633         {
634                 setbuf(stdout,0);
635                 setbuf(stderr,0);
636         }
637
638         yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
639         yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
640
641         wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0,
642                        (debuglevel & DEBUGLEVEL_PPTRACE) != 0,
643                        (debuglevel & DEBUGLEVEL_PPMSG) != 0 );
644
645         /* Set the default defined stuff */
646         wpp_add_cmdline_define("__WRC__=" WRC_EXP_STRINGIZE(WRC_MAJOR_VERSION));
647         wpp_add_cmdline_define("__WRC_MINOR__=" WRC_EXP_STRINGIZE(WRC_MINOR_VERSION));
648         wpp_add_cmdline_define("__WRC_MICRO__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION));
649         wpp_add_cmdline_define("__WRC_PATCH__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION));
650
651         wpp_add_cmdline_define("RC_INVOKED=1");
652
653         if(win32)
654         {
655                 wpp_add_cmdline_define("__WIN32__=1");
656                 wpp_add_cmdline_define("__FLAT__=1");
657         }
658
659         /* Check if the user set a language, else set default */
660         if(!currentlanguage)
661                 currentlanguage = new_language(0, 0);
662
663         if(binary && !input_name)
664         {
665                 error("Binary mode requires .res file as input\n");
666         }
667
668         /* Generate appropriate outfile names */
669         if(!output_name && !preprocess_only)
670         {
671                 output_name = dup_basename(input_name, binary ? ".res" : ".rc");
672                 if (output_type == output_res) strcat(output_name, ".res");
673                 else if (output_type == output_asm) strcat(output_name, ".s");
674                 else if (output_type == output_hdr) strcat(output_name, ".h");
675         }
676
677         /* Run the preprocessor on the input */
678         if(!no_preprocess && !binary)
679         {
680                 /*
681                  * Preprocess the input to a temp-file, or stdout if
682                  * no output was given.
683                  */
684
685                 chat("Starting preprocess");
686
687                 if (!preprocess_only)
688                 {
689                     atexit(rm_tempfile);
690                     ret = wpp_parse_temp( input_name, output_name, &temp_name );
691                 }
692                 else if (output_name)
693                 {
694                     FILE *output;
695
696                     if (!(output = fopen( output_name, "w" )))
697                         error( "Could not open %s for writing\n", output_name );
698                     ret = wpp_parse( input_name, output );
699                     fclose( output );
700                 }
701                 else
702                 {
703                     ret = wpp_parse( input_name, stdout );
704                 }
705
706                 if(ret)
707                         exit(1);        /* Error during preprocess */
708
709                 if(preprocess_only)
710                         exit(0);
711
712                 input_name = temp_name;
713         }
714
715         if(!binary)
716         {
717                 /* Go from .rc to .res or .s */
718                 chat("Starting parse");
719
720                 if(!(yyin = fopen(input_name, "rb")))
721                         error("Could not open %s for input\n", input_name);
722
723                 ret = yyparse();
724
725                 if(input_name)
726                         fclose(yyin);
727
728                 if(ret)
729                 {
730                         /* Error during parse */
731                         exit(1);
732                 }
733
734                 if(debuglevel & DEBUGLEVEL_DUMP)
735                         dump_resources(resource_top);
736
737                 /* Convert the internal lists to binary data */
738                 resources2res(resource_top);
739
740                 if(output_type == output_res)
741                 {
742                         chat("Writing .res-file");
743                         write_resfile(output_name, resource_top);
744                 }
745                 else if(output_type == output_asm)
746                 {
747                         chat("Writing .s-file");
748                         write_s_file(output_name, resource_top);
749                 }
750                 else if(output_type == output_hdr)
751                 {
752                         chat("Writing .h-file");
753                         write_h_file(output_name, resource_top);
754                 }
755
756         }
757         else
758         {
759                 /* Go from .res to .s */
760                 chat("Reading .res-file");
761                 resource_top = read_resfile(input_name);
762                 if(output_type == output_asm)
763                 {
764                         chat("Writing .s-file");
765                         write_s_file(output_name, resource_top);
766                 }
767                 else if(output_type == output_hdr)
768                 {
769                         chat("Writing .h-file");
770                         write_h_file(output_name, resource_top);
771                 }
772         }
773
774         return 0;
775 }
776
777
778 static void rm_tempfile(void)
779 {
780         if(temp_name)
781                 unlink(temp_name);
782 }
783
784 static void segvhandler(int sig)
785 {
786         fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
787         fflush(stdout);
788         fflush(stderr);
789         abort();
790 }