Fix the case of product and company names.
[wine] / tools / bin2res.c
1 /************************************************
2  *
3  * Converting binary resources from/to *.rc files
4  *
5  * Copyright 1999 Juergen Schmied
6  *
7  * 11/99 first release
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "config.h"
25
26 #ifdef HAVE_SYS_PARAM_H
27 # include <sys/param.h>
28 #endif
29 #include <sys/types.h>
30 #include <sys/stat.h>
31
32 #include <ctype.h>
33 #include <string.h>
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38
39 #include <fcntl.h>
40 #ifdef HAVE_UNISTD_H
41 # include <unistd.h>
42 #endif
43 #ifdef HAVE_SYS_MMAN_H
44 # include <sys/mman.h>
45 #endif
46
47 #include "windef.h"
48 #include "winbase.h"
49 #include "wingdi.h"
50 #include "winuser.h"
51
52 extern char*   g_lpstrFileName;
53
54 /* global options */
55
56 char*   g_lpstrFileName = NULL;
57 char*   g_lpstrInputFile = NULL;
58 int     b_to_binary = 0;
59 int     b_force_overwrite = 0;
60
61 static char*    errorOpenFile = "Unable to open file.\n";
62 static char*    errorRCFormat = "Unexpexted syntax in rc file line %i\n";
63
64 void usage(void)
65 {
66     printf("Usage: bin2res [-d bin] [input file]\n");
67     printf("  -d bin convert a *.res back to a binary\n");
68     printf("  -f force overwriting newer files\n");
69     exit(-1);
70 }
71
72 void parse_options(int argc, char **argv)
73 {
74   int i;
75
76   switch( argc )
77   {
78     case 2:
79          g_lpstrInputFile = argv[1];
80          break;
81
82     case 3:
83     case 4:
84     case 5:
85          for( i = 1; i < argc - 1; i++ )
86          {
87            if( argv[i][0] != '-' ||
88                strlen(argv[i]) != 2 ) break;
89
90            if( argv[i][1] == 'd')
91            {
92              if (strcmp ("bin", argv[i+1])==0)
93              {
94                b_to_binary =1;
95                i++;
96              }
97              else
98              {
99                usage();
100              }
101
102            }
103            else if ( argv[i][1] == 'f')
104            {
105              b_force_overwrite = 1;
106            }
107            else
108            {
109              usage();
110            }
111          }
112          if( i == argc - 1 )
113          {
114            g_lpstrInputFile = argv[i];
115            break;
116          }
117     default: usage();
118   }
119 }
120
121 int insert_hex (char * infile, FILE * outfile)
122 {
123 #ifdef  HAVE_MMAP
124         unsigned int i;
125         int             fd;
126         struct stat     st;
127         LPBYTE p_in_file = NULL;
128
129         if( (fd = open( infile, O_RDONLY))==-1 )
130         {
131           fprintf(stderr, errorOpenFile );
132           exit(1);
133         }
134         if ((fstat(fd, &st) == -1) || (p_in_file = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
135         {
136           fprintf(stderr, errorOpenFile );
137           close(fd);
138           exit(1);
139         }
140
141         fprintf (outfile, "{\n '");
142         i = 0;
143         while (1)
144         {
145           fprintf(outfile, "%02X", p_in_file[i]);
146           if (++i >= st.st_size) break;
147           fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
148         }
149         fprintf (outfile, "'\n}");
150         munmap(p_in_file, st.st_size);
151         close(fd);
152         return 1;
153 #else   /* HAVE_MMAP */
154         FILE*   fp;
155         struct stat     st;
156         unsigned int    i;
157         int             c;
158
159         fp = fopen( infile, "r" );
160         if ( fp == NULL )
161         {
162           fprintf(stderr, errorOpenFile );
163           exit(1);
164         }
165         if (fstat(fileno(fp), &st) == -1)
166         {
167           fprintf(stderr, errorOpenFile );
168           fclose(fp);
169           exit(1);
170         }
171
172         fprintf (outfile, "{\n '");
173         i = 0;
174         while (1)
175         {
176           c = fgetc(fp);
177           if ( c == EOF )
178           {
179             fprintf(stderr, errorOpenFile );
180             fclose(fp);
181             exit(1);
182           }
183           fprintf(outfile, "%02X", c);
184           if (++i >= st.st_size) break;
185           fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
186         }
187         fprintf (outfile, "'\n}");
188
189         fclose(fp);
190         return 1;
191 #endif  /* HAVE_MMAP */
192 }
193
194 int convert_to_res ()
195 {
196         FILE    *fin, *ftemp;
197         char    buffer[255];
198         char    infile[255];
199         char    tmpfile[255];
200         char    *pos;
201         int     c, len;
202         struct stat     st;
203         int line = 0;
204         time_t  tinput;
205         long startpos, endpos;
206
207         strcpy( tmpfile, g_lpstrInputFile );
208         strcat( tmpfile, "-tmp" );
209         /* FIXME: should use better tmp name and create with O_EXCL */
210         if( (ftemp = fopen( tmpfile, "w")) == NULL ) goto error_open_file;
211
212         if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
213         tinput = st.st_ctime;
214
215         while ( NULL != fgets(buffer, 255, fin))
216         {
217           fputs(buffer, ftemp);
218           line++;
219           if ( (pos = strstr(buffer, "BINRES")) != NULL)
220           {
221             /* get the out-file name */
222             len = 0; pos += 6; startpos=0; endpos=0;
223             while ( *pos == ' ') pos++;
224             while ( pos[len] != ' ') len++;
225             strncpy(infile, pos, len);
226             infile[len]=0;
227
228             if ( (!stat(infile, &st) && st.st_ctime > tinput) || b_force_overwrite)
229             {
230               /* write a output file */
231               printf("[%s:c]", infile);
232               while((c = fgetc(fin))!='{' && c != EOF) fputc(c, ftemp);
233               if (c == EOF ) goto error_rc_format;
234               while((c = fgetc(fin))!='}' && c != EOF);
235               if (c == EOF ) goto error_rc_format;
236
237               insert_hex(infile, ftemp);
238             }
239             else
240             {
241               printf("[%s:s]", infile);
242             }
243           }
244         }
245
246         fclose(fin);
247         fclose(ftemp);
248
249         if (unlink(g_lpstrInputFile) == -1)
250         {
251             perror("unlink");
252             unlink(tmpfile);
253             return 0;
254         }
255         if (rename(tmpfile, g_lpstrInputFile) == -1)
256         {
257             perror("rename");
258             unlink(tmpfile);
259             return 0;
260         }
261         return 1;
262
263 error_open_file:
264         fprintf(stderr, errorOpenFile );
265         return 0;
266
267 error_rc_format:
268         fprintf(stderr, errorRCFormat, line);
269         return 0;
270 }
271
272 int convert_to_bin()
273 {
274         FILE    *fin, *fout;
275         char    buffer[255];
276         char    outfile[255];
277         char    *pos;
278         int     len, index, in_resource;
279         unsigned int    byte;
280         struct stat     st;
281         int line = 0;
282         time_t  tinput;
283
284         if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
285         tinput = st.st_ctime;
286
287         while ( NULL != fgets(buffer, 255, fin))
288         {
289           line++;
290           if ( (pos = strstr(buffer, "BINRES")) != NULL)
291           {
292             /* get the out-file name */
293             len = 0; pos += 6;
294             while ( *pos == ' ') pos++;
295             while ( pos[len] != ' ') len++;
296             strncpy(outfile, pos, len);
297             outfile[len]=0;
298
299             if ( stat(outfile, &st) || st.st_ctime < tinput || b_force_overwrite)
300             {
301               /* write a output file */
302               printf("[%s:c]", outfile);
303               if ( (fout = fopen( outfile, "w")) == NULL) goto error_open_file;
304
305               in_resource = 0;
306               while (1)
307               {
308                 if ( NULL == fgets(buffer, 255, fin)) goto error_rc_format;
309                 line++;
310
311                 /* parse a line */
312                 for ( index = 0; buffer[index] != 0; index++ )
313                 {
314                   if ( ! in_resource )
315                   {
316                     if ( buffer[index] == '{' ) in_resource = 1;
317                     continue;
318                   }
319
320                   if ( buffer[index] == ' ' || buffer[index] == '\''|| buffer[index] == '\n' ) continue;
321                   if ( buffer[index] == '}' ) goto end_of_resource;
322                   if ( ! isxdigit(buffer[index])) goto error_rc_format;
323                   index += sscanf(&buffer[index], "%02x", &byte);
324                   fputc(byte, fout);
325                 }
326               }
327               fclose(fout);
328             }
329             else
330             {
331               printf("[%s:s]", outfile);
332             }
333 end_of_resource: ;
334           }
335         }
336
337         fclose(fin);
338         return 1;
339
340 error_open_file:
341         fprintf(stderr, errorOpenFile );
342         return 0;
343
344 error_rc_format:
345         fprintf(stderr, errorRCFormat, line);
346         return 0;
347 }
348
349 int main(int argc, char **argv)
350 {
351         parse_options( argc, argv);
352
353         if (b_to_binary == 0)
354         {
355           convert_to_res();
356         }
357         else
358         {
359           convert_to_bin();
360         }
361         printf("\n");
362         return 0;
363 }