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