1 /********************************************************************************
2 *                                                                               *
3 *                R e s o u r c e   W r a p p i n g   U t i l i t y              *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1997,2005 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This program is free software; you can redistribute it and/or modify          *
9 * it under the terms of the GNU General Public License as published by          *
10 * the Free Software Foundation; either version 2 of the License, or             *
11 * (at your option) any later version.                                           *
12 *                                                                               *
13 * This program is distributed in the hope that it will be useful,               *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 *
16 * GNU General Public License for more details.                                  *
17 *                                                                               *
18 * You should have received a copy of the GNU General Public License             *
19 * along with this program; if not, write to the Free Software                   *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
21 *********************************************************************************
22 * $Id: reswrap.cpp,v 1.15 2005/02/04 04:33:19 fox Exp $                         *
23 ********************************************************************************/
24 #include "stdio.h"
25 #include "stdlib.h"
26 #include "string.h"
27 #include "ctype.h"
28 
29 
30 
31 /*
32 
33   Notes:
34   - Updated to version 3.2.
35   - Can now also generate output as a text string.
36   - When ASCII option is used with text string option, it prints human
37     readable C-style string, with non-ASCII characters escaped as appropriate.
38   - Removed PPM feature as that was never really used in FOX.
39   - License changed to GPL from LGPL because this is a standalone program
40     that does not need to be linked to anything.
41   - Added MSDOS mode, useful for wrapping ASCII text.
42   - Added option to keep extension (separated by '_').
43   - Need option to place #include "icons.h" or something into icons.cpp
44   - Always prepend prefix in front of resource name, even if name was overrided
45     because prefix may be namespace name.
46 */
47 
48 /*******************************************************************************/
49 
50 #define MODE_DECIMAL  0
51 #define MODE_HEX      1
52 #define MODE_TEXT     2
53 
54 
55 const char version[]="3.2.0";
56 
57 
58 /* Print some help */
printusage()59 void printusage(){
60   fprintf(stderr,"Usage: reswrap [options] [-o[a] outfile] files...\n");
61   fprintf(stderr,"Convert files containing images, text, or binary data into C/C++ data arrays.\n");
62   fprintf(stderr,"\n");
63   fprintf(stderr,"Options:\n");
64   fprintf(stderr,"  -o[a] outfile  Output [append] to outfile instead of stdout\n");
65   fprintf(stderr,"  -h             Print help\n");
66   fprintf(stderr,"  -v             Print version number\n");
67   fprintf(stderr,"  -d             Output as decimal\n");
68   fprintf(stderr,"  -m             Read files with MS-DOS mode (default is binary)\n");
69   fprintf(stderr,"  -x             Output as hex (default)\n");
70   fprintf(stderr,"  -t[a]          Output as [ascii] text string\n");
71   fprintf(stderr,"  -e             Generate external reference declaration\n");
72   fprintf(stderr,"  -i             Build an include file\n");
73   fprintf(stderr,"  -k             Keep extension, separated by underscore\n");
74   fprintf(stderr,"  -s             Suppress header in output file\n");
75   fprintf(stderr,"  -p prefix      Place prefix in front of names of declarations and definitions\n");
76   fprintf(stderr,"  -n namespace   Place declarations and definitions inside given namespace\n");
77   fprintf(stderr,"  -c cols        Change number of columns in output to cols\n");
78   fprintf(stderr,"  -u             Force unsigned char even for text mode\n");
79   fprintf(stderr,"\n");
80   fprintf(stderr,"Each file may be preceded by the following extra option:\n");
81   fprintf(stderr,"  -r name        Override resource name of following resource file\n");
82   fprintf(stderr,"\n");
83   }
84 
85 
86 /* Print version information */
printversion()87 void printversion(){
88   fprintf(stderr,"Reswrap %s %s.\n",version,__DATE__);
89   fprintf(stderr,"Copyright (C) 1997,2005 Jeroen van der Zijp. All Rights Reserved.\n");
90   fprintf(stderr,"Please visit: http://www.fox-toolkit.org for further information.\n");
91   fprintf(stderr,"\n");
92   fprintf(stderr,"This program is free software; you can redistribute it and/or modify\n");
93   fprintf(stderr,"it under the terms of the GNU General Public License as published by\n");
94   fprintf(stderr,"the Free Software Foundation; either version 2 of the License, or\n");
95   fprintf(stderr,"(at your option) any later version.\n");
96   fprintf(stderr,"\n");
97   fprintf(stderr,"This program is distributed in the hope that it will be useful,\n");
98   fprintf(stderr,"but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
99   fprintf(stderr,"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
100   fprintf(stderr,"GNU General Public License for more details.\n");
101   fprintf(stderr,"\n");
102   fprintf(stderr,"You should have received a copy of the GNU General Public License\n");
103   fprintf(stderr,"along with this program; if not, write to the Free Software\n");
104   fprintf(stderr,"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.\n");
105   }
106 
107 
108 /* Build resource name */
resourcename(char * name,const char * prefix,const char * filename,int keepdot)109 void resourcename(char *name,const char* prefix,const char* filename,int keepdot){
110   const char* begin=name;
111   const char* ptr;
112 
113   /* Copy prefix */
114   while(*prefix){
115     *name++=*prefix++;
116     }
117 
118   /* Get name only; take care of mixed path separator characters on mswindows */
119   if((ptr=strrchr(filename,'/'))!=0) filename=ptr;
120   if((ptr=strrchr(filename,'\\'))!=0) filename=ptr;
121 
122   /* Copy filename */
123   while(*filename){
124 
125     /* C++ identifier may contain _, alpha, digit (if not first), or namespace separator : */
126     if(*filename==':' || *filename=='_' || isalpha(*filename) || (isdigit(*filename) && (begin!=name))){
127       *name++=*filename;
128       }
129 
130     /* We can squash dot extension to _ */
131     else if(*filename=='.'){
132       if(!keepdot) break;
133       *name++='_';
134       }
135 
136     filename++;
137     }
138   *name=0;
139   }
140 
141 
142 /* Main */
main(int argc,char ** argv)143 int main(int argc,char **argv){
144   char *outfilename,*resfilename;
145   FILE *resfile,*outfile;
146   int i,b,first,col,append,maxcols,external,header,include,mode,colsset,ascii,msdos,keepext,hex,forceunsigned;
147   const char *thenamespace,*theprefix;
148   char resname[1000];
149 
150   /* Initialize */
151   outfilename=0;
152   outfile=stdout;
153   maxcols=16;
154   colsset=0;
155   external=0;
156   header=1;
157   include=0;
158   ascii=0;
159   mode=MODE_HEX;
160   msdos=0;
161   keepext=0;
162   thenamespace=0;
163   theprefix="";
164   append=0;
165   forceunsigned=0;
166 
167   /* Check arguments */
168   if(argc<2){
169     printusage();
170     exit(1);
171     }
172 
173   /* Process all options first, except for the -r option */
174   for(i=1; i<argc && argv[i][0]=='-' && argv[i][1]!='r'; i++){
175 
176     /* Change output file */
177     if(argv[i][1]=='o'){
178       if(argv[i][2]=='a') append=1;
179       i++;
180       if(i>=argc){
181         fprintf(stderr,"reswrap: missing argument for -o option\n");
182         exit(1);
183         }
184       outfilename=argv[i];
185       }
186 
187     /* Print help */
188     else if(argv[i][1]=='h'){
189       printusage();
190       exit(0);
191       }
192 
193     /* Print version */
194     else if(argv[i][1]=='v'){
195       printversion();
196       exit(0);
197       }
198 
199     /* Switch to decimal */
200     else if(argv[i][1]=='d'){
201       mode=MODE_DECIMAL;
202       if(!colsset) maxcols=10;
203       }
204 
205     /* Switch to hex */
206     else if(argv[i][1]=='x'){
207       mode=MODE_HEX;
208       if(!colsset) maxcols=16;
209       }
210 
211     /* Switch to text */
212     else if(argv[i][1]=='t'){
213       if(argv[i][2]=='a') ascii=1;
214       mode=MODE_TEXT;
215       if(!colsset) maxcols=80;
216       }
217 
218     /* Suppress header */
219     else if(argv[i][1]=='s'){
220       header=0;
221       }
222 
223     /* Force unsigned */
224     else if(argv[i][1]=='u'){
225       forceunsigned=1;
226       }
227 
228     /* Generate as external reference */
229     else if(argv[i][1]=='e'){
230       external=1;
231       }
232 
233     /* Building include file implies also extern */
234     else if(argv[i][1]=='i'){
235       include=1;
236       external=1;
237       }
238 
239     /* Read resource with MS-DOS mode */
240     else if(argv[i][1]=='m'){
241       msdos=1;
242       }
243 
244     /* Keep extension */
245     else if(argv[i][1]=='k'){
246       keepext=1;
247       }
248 
249     /* Change number of columns */
250     else if(argv[i][1]=='c'){
251       i++;
252       if(i>=argc){
253         fprintf(stderr,"reswrap: missing argument for -c option\n");
254         exit(1);
255         }
256       if(sscanf(argv[i],"%d",&maxcols)==1 && maxcols<1){
257         fprintf(stderr,"reswrap: illegal argument for number of columns\n");
258         exit(1);
259         }
260       colsset=1;
261       }
262 
263     /* Embed in namespace */
264     else if(argv[i][1]=='n'){
265       i++;
266       if(i>=argc){
267         fprintf(stderr,"reswrap: missing argument for -n option\n");
268         exit(1);
269         }
270       thenamespace=argv[i];
271       }
272 
273     /* Prefix in front of declarations */
274     else if(argv[i][1]=='p'){
275       i++;
276       if(i>=argc){
277         fprintf(stderr,"reswrap: missing argument for -p option\n");
278         exit(1);
279         }
280       theprefix=argv[i];
281       }
282     }
283 
284   /* To file instead out stdout */
285   if(outfilename){
286     outfile=fopen(outfilename,append?"a":"w");
287     if(!outfile){
288       fprintf(stderr,"reswrap: unable to open output file %s\n",outfilename);
289       exit(1);
290       }
291     }
292 
293   /* Output header */
294   if(header){
295     fprintf(outfile,"/* Generated by reswrap version %s */\n\n",version);
296     }
297 
298   /* Output namespace begin */
299   if(thenamespace){
300     fprintf(outfile,"namespace %s {\n\n",thenamespace);
301     }
302 
303   /* Process resource files next */
304   for(; i<argc; i++){
305 
306     /* Resource name override */
307     if(argv[i][0]=='-' && argv[i][1]=='r'){
308 
309       /* Must have extra argument */
310       if(++i>=argc){
311         fprintf(stderr,"reswrap: missing name argument for -r option\n");
312         exit(1);
313         }
314 
315       /* Get resource name */
316       resourcename(resname,theprefix,argv[i],keepext);
317 
318       /* Must have following file name */
319       if(++i>=argc){
320         fprintf(stderr,"reswrap: missing resource file name\n");
321         exit(1);
322         }
323 
324       /* Get resource file name */
325       resfilename=argv[i];
326       }
327 
328     else{
329 
330       /* Get resource file name */
331       resfilename=argv[i];
332 
333       /* Get resource name */
334       resourcename(resname,theprefix,resfilename,keepext);
335       }
336 
337 
338     /* Check resource name not empty */
339     if(*resname==0){
340       fprintf(stderr,"reswrap: empty resource name for %s\n",resfilename);
341       exit(1);
342       }
343 
344     /* Open resource file; always open as binary */
345     resfile=fopen(resfilename,"rb");
346     if(!resfile){
347       fprintf(stderr,"reswrap: unable to open input file %s\n",resfilename);
348       exit(1);
349       }
350 
351     /* Output header */
352     if(header){
353       fprintf(outfile,"/* created by reswrap from file %s */\n",resfilename);
354       }
355 
356     /* Generate external reference for #include's */
357     if(external){ fprintf(outfile,"extern "); }
358 
359     /* In text mode, output a 'char' declaration */
360     if((mode==MODE_TEXT) && !forceunsigned){
361       fprintf(outfile,"const char %s[]",resname);
362       }
363 
364     /* In binary mode, output a 'unsigned char' declaration */
365     else{
366       fprintf(outfile,"const unsigned char %s[]",resname);
367       }
368 
369     /* Generate resource array */
370     if(!include){
371       if(mode==MODE_TEXT){
372         col=0;
373         hex=0;
374         fprintf(outfile,"=\n  \"");
375         while((b=fgetc(resfile))!=EOF){
376           if(msdos && (b=='\r')) continue;
377           if(col>=maxcols){
378             fprintf(outfile,"\"\n  \"");
379             col=0;
380             }
381           if(ascii){
382             if(b=='\\'){ fprintf(outfile,"\\\\"); col+=2; hex=0; }
383             else if(b=='\a'){ fprintf(outfile,"\\a"); col+=2; hex=0; }
384             else if(b=='\t'){ fprintf(outfile,"\\t"); col+=2; hex=0; }
385             else if(b=='\r'){ fprintf(outfile,"\\r"); col+=2; hex=0; }
386             else if(b=='\f'){ fprintf(outfile,"\\f"); col+=2; hex=0; }
387             else if(b=='\v'){ fprintf(outfile,"\\v"); col+=2; hex=0; }
388             else if(b=='\"'){ fprintf(outfile,"\\\""); col+=2; hex=0; }
389             else if(b=='\n'){ fprintf(outfile,"\\n\"\n  \""); col=0; hex=0; }
390             else if(b<32 || b>=127){ fprintf(outfile,"\\x%02x",b); col+=4; hex=1; }
391             else if(hex && isxdigit(b)){ fprintf(outfile,"\\x%02x",b); col+=4; hex=1; }
392             else{ fprintf(outfile,"%c",b); col+=1; hex=0; }
393             }
394           else{
395             fprintf(outfile,"\\x%02x",b); col+=4;
396             }
397           }
398         fprintf(outfile,"\"\n  ");
399         }
400       else{
401         col=0;
402         first=1;
403         fprintf(outfile,"={\n  ");
404         while((b=fgetc(resfile))!=EOF){
405           if(msdos && (b=='\r')) continue;
406           if(!first){
407             fprintf(outfile,",");
408             }
409           if(col>=maxcols){
410             fprintf(outfile,"\n  ");
411             col=0;
412             }
413           if(mode==MODE_HEX)
414             fprintf(outfile,"0x%02x",b);
415           else
416             fprintf(outfile,"%3d",b);
417           first=0;
418           col++;
419           }
420         fprintf(outfile,"\n  }");
421         }
422       }
423 
424     fprintf(outfile,";\n\n");
425 
426     /* Close resource file */
427     fclose(resfile);
428     }
429 
430   /* Output namespace end */
431   if(thenamespace){
432     fprintf(outfile,"}\n");
433     }
434 
435   /* To file instead out stdout */
436   if(outfilename){
437     fclose(outfile);
438     }
439 
440   return 0;
441   }
442 
443 
444 
445