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