Removed trailing whitespace.
[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
38 #include <fcntl.h>
39 #include <unistd.h>
40 #ifdef HAVE_SYS_MMAN_H
41 # include <sys/mman.h>
42 #endif
43
44 #include "windef.h"
45 #include "winbase.h"
46 #include "wingdi.h"
47 #include "winuser.h"
48
49 extern char*   g_lpstrFileName;
50
51 /* global options */
52
53 char*   g_lpstrFileName = NULL;
54 char*   g_lpstrInputFile = NULL;
55 int     b_to_binary = 0;
56 int     b_force_overwrite = 0;
57
58 static char*    errorOpenFile = "Unable to open file.\n";
59 static char*    errorRCFormat = "Unexpexted syntax in rc file line %i\n";
60
61 void usage(void)
62 {
63     printf("Usage: bin2res [-d bin] [input file]\n");
64     printf("  -d bin convert a *.res back to a binary\n");
65     printf("  -f force overwriting newer files\n");
66     exit(-1);
67 }
68
69 void parse_options(int argc, char **argv)
70 {
71   int i;
72
73   switch( argc )
74   {
75     case 2:
76          g_lpstrInputFile = argv[1];
77          break;
78
79     case 3:
80     case 4:
81     case 5:
82          for( i = 1; i < argc - 1; i++ )
83          {
84            if( argv[i][0] != '-' ||
85                strlen(argv[i]) != 2 ) break;
86
87            if( argv[i][1] == 'd')
88            {
89              if (strcmp ("bin", argv[i+1])==0)
90              {
91                b_to_binary =1;
92                i++;
93              }
94              else
95              {
96                usage();
97              }
98
99            }
100            else if ( argv[i][1] == 'f')
101            {
102              b_force_overwrite = 1;
103            }
104            else
105            {
106              usage();
107            }
108          }
109          if( i == argc - 1 )
110          {
111            g_lpstrInputFile = argv[i];
112            break;
113          }
114     default: usage();
115   }
116 }
117
118 int insert_hex (char * infile, FILE * outfile)
119 {
120 #ifdef  HAVE_MMAP
121         unsigned int i;
122         int             fd;
123         struct stat     st;
124         LPBYTE p_in_file = NULL;
125
126         if( (fd = open( infile, O_RDONLY))==-1 )
127         {
128           fprintf(stderr, errorOpenFile );
129           exit(1);
130         }
131         if ((fstat(fd, &st) == -1) || (p_in_file = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
132         {
133           fprintf(stderr, errorOpenFile );
134           close(fd);
135           exit(1);
136         }
137
138         fprintf (outfile, "{\n '");
139         i = 0;
140         while (1)
141         {
142           fprintf(outfile, "%02X", p_in_file[i]);
143           if (++i >= st.st_size) break;
144           fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
145         }
146         fprintf (outfile, "'\n}");
147         munmap(p_in_file, st.st_size);
148         close(fd);
149         return 1;
150 #else   /* HAVE_MMAP */
151         FILE*   fp;
152         struct stat     st;
153         unsigned int    i;
154         int             c;
155
156         fp = fopen( infile, "r" );
157         if ( fp == NULL )
158         {
159           fprintf(stderr, errorOpenFile );
160           exit(1);
161         }
162         if (fstat(fileno(fp), &st) == -1)
163         {
164           fprintf(stderr, errorOpenFile );
165           fclose(fp);
166           exit(1);
167         }
168
169         fprintf (outfile, "{\n '");
170         i = 0;
171         while (1)
172         {
173           c = fgetc(fp);
174           if ( c == EOF )
175           {
176             fprintf(stderr, errorOpenFile );
177             fclose(fp);
178             exit(1);
179           }
180           fprintf(outfile, "%02X", c);
181           if (++i >= st.st_size) break;
182           fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
183         }
184         fprintf (outfile, "'\n}");
185
186         fclose(fp);
187         return 1;
188 #endif  /* HAVE_MMAP */
189 }
190
191 int convert_to_res ()
192 {
193         FILE    *fin, *ftemp;
194         char    buffer[255];
195         char    infile[255];
196         char    tmpfile[255];
197         char    *pos;
198         int     c, len;
199         struct stat     st;
200         int line = 0;
201         time_t  tinput;
202         long startpos, endpos;
203
204         strcpy( tmpfile, g_lpstrInputFile );
205         strcat( tmpfile, "-tmp" );
206         /* FIXME: should use better tmp name and create with O_EXCL */
207         if( (ftemp = fopen( tmpfile, "w")) == NULL ) goto error_open_file;
208
209         if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
210         tinput = st.st_ctime;
211
212         while ( NULL != fgets(buffer, 255, fin))
213         {
214           fputs(buffer, ftemp);
215           line++;
216           if ( (pos = strstr(buffer, "BINRES")) != NULL)
217           {
218             /* get the out-file name */
219             len = 0; pos += 6; startpos=0; endpos=0;
220             while ( *pos == ' ') pos++;
221             while ( pos[len] != ' ') len++;
222             strncpy(infile, pos, len);
223             infile[len]=0;
224
225             if ( (!stat(infile, &st) && st.st_ctime > tinput) || b_force_overwrite)
226             {
227               /* write a output file */
228               printf("[%s:c]", infile);
229               while((c = fgetc(fin))!='{' && c != EOF) fputc(c, ftemp);
230               if (c == EOF ) goto error_rc_format;
231               while((c = fgetc(fin))!='}' && c != EOF);
232               if (c == EOF ) goto error_rc_format;
233
234               insert_hex(infile, ftemp);
235             }
236             else
237             {
238               printf("[%s:s]", infile);
239             }
240           }
241         }
242
243         fclose(fin);
244         fclose(ftemp);
245         if (rename(tmpfile, g_lpstrInputFile) == -1)
246         {
247             perror("rename");
248             unlink(tmpfile);
249             return 0;
250         }
251         return 1;
252
253 error_open_file:
254         fprintf(stderr, errorOpenFile );
255         return 0;
256
257 error_rc_format:
258         fprintf(stderr, errorRCFormat, line);
259         return 0;
260 }
261
262 int convert_to_bin()
263 {
264         FILE    *fin, *fout;
265         char    buffer[255];
266         char    outfile[255];
267         char    *pos;
268         int     len, index, in_resource;
269         unsigned int    byte;
270         struct stat     st;
271         int line = 0;
272         time_t  tinput;
273
274         if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
275         tinput = st.st_ctime;
276
277         while ( NULL != fgets(buffer, 255, fin))
278         {
279           line++;
280           if ( (pos = strstr(buffer, "BINRES")) != NULL)
281           {
282             /* get the out-file name */
283             len = 0; pos += 6;
284             while ( *pos == ' ') pos++;
285             while ( pos[len] != ' ') len++;
286             strncpy(outfile, pos, len);
287             outfile[len]=0;
288
289             if ( stat(outfile, &st) || st.st_ctime < tinput || b_force_overwrite)
290             {
291               /* write a output file */
292               printf("[%s:c]", outfile);
293               if ( (fout = fopen( outfile, "w")) == NULL) goto error_open_file;
294
295               in_resource = 0;
296               while (1)
297               {
298                 if ( NULL == fgets(buffer, 255, fin)) goto error_rc_format;
299                 line++;
300
301                 /* parse a line */
302                 for ( index = 0; buffer[index] != 0; index++ )
303                 {
304                   if ( ! in_resource )
305                   {
306                     if ( buffer[index] == '{' ) in_resource = 1;
307                     continue;
308                   }
309
310                   if ( buffer[index] == ' ' || buffer[index] == '\''|| buffer[index] == '\n' ) continue;
311                   if ( buffer[index] == '}' ) goto end_of_resource;
312                   if ( ! isxdigit(buffer[index])) goto error_rc_format;
313                   index += sscanf(&buffer[index], "%02x", &byte);
314                   fputc(byte, fout);
315                 }
316               }
317               fclose(fout);
318             }
319             else
320             {
321               printf("[%s:s]", outfile);
322             }
323 end_of_resource: ;
324           }
325         }
326
327         fclose(fin);
328         return 1;
329
330 error_open_file:
331         fprintf(stderr, errorOpenFile );
332         return 0;
333
334 error_rc_format:
335         fprintf(stderr, errorRCFormat, line);
336         return 0;
337 }
338
339 int main(int argc, char **argv)
340 {
341         parse_options( argc, argv);
342
343         if (b_to_binary == 0)
344         {
345           convert_to_res();
346         }
347         else
348         {
349           convert_to_bin();
350         }
351         printf("\n");
352         return 0;
353 }