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