2 * Copyright 1993, 1995 Christopher Seiwald.
3 * This file is part of Jam - see jam.c for Copyright information.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * mkjambase.c - turn Jambase into a big C structure
21 * Usage: mkjambase jambase.c Jambase ...
23 * Results look like this:
30 * Handles \'s and "'s specially; knows how to delete blank and comment lines.
41 //#define MKJAMBASE_COMPACT
44 ////////////////////////////////////////////////////////////////////////////////
45 static void fatal (const char *msg
) {
46 fprintf(stdout
, "FATAL: %s\n", msg
);
51 static char outdata
[1024*1024];
52 static int outdatalen
= 0;
55 static void outStr (const char *str
) {
56 memmove(outdata
+outdatalen
, str
, strlen(str
));
57 outdatalen
+= strlen(str
);
61 #define EMIT(ch) do { \
62 if (outp-outbuf >= sizeof(outbuf)) fatal("output line too big\n");\
67 static inline void normSlashes (char *s
) {
68 for (; *s
; ++s
) if (*s
== '\\') *s
= '/';
72 static int doDotC
= 0, wasScreen
, dontStrip
= 0, dropSpaces
, doCompress
= 1;
74 static int lineno
= 0;
75 static int inclevel
= 0;
76 static const char *srcfname
= "<cli>";
78 static void processFile (FILE *fout
, const char *fname
) {
80 char *p
, *e
, quoteCh
, *outp
;
81 static char buf
[32768], outbuf
[32768];
83 const char *ofn
= srcfname
;
88 if (++inclevel
> 64) {
90 fprintf(stderr
, "FATAL: too many nested includes, failed in file '%s', line %d\n", ofn
, olno
);
94 printf(": %s\n", fname
);
95 if (!(fin
= fopen(fname
, "r"))) {
97 fprintf(stderr
, "FATAL: can't open file '%s', failed in file '%s', line %d\n", fname
, ofn
, olno
);
101 if (!doCompress
) fprintf(fout
, "/* %s */\n", fname
);
108 while (fgets(buf
, sizeof(buf
), fin
)) {
116 while (*p
&& *((unsigned char *)p
) <= ' ') ++p
;
117 if ((t
= strchr(p
, '#')) != NULL
) *t
= '\0';
118 for (t
= p
+strlen(p
); t
> p
; --t
) if (!isspace(t
[-1])) break;
122 fprintf(stderr
, "FATAL: invalid '.' in file '%s', line %d\n", fname
, lineno
);
125 fn
= malloc(strlen(p
)+strlen(fname
)+64);
128 fprintf(stderr
, "FATAL: out of memory in file '%s', line %d\n", fname
, lineno
);
133 if ((t
= strrchr(fn
, '/')) != NULL
) t
[1] = '\0'; else fn
[0] = '\0';
135 processFile(fout
, fn
);
141 #ifdef MKJAMBASE_COMPACT
142 if (!strncmp(buf
, "#DONT_TOUCH", 11)) {
143 dontStrip
= !dontStrip
;
150 /* strip leading whitespace */
152 while (*p
&& *((unsigned char *)p
) <= ' ') ++p
;
153 /* drop comments and empty lines */
154 if (*p
== '#' || !*p
) continue;
156 /* copy; drop comments if # is not in quotes */
157 outp
= outbuf
; quoteCh
= 0; wasScreen
= 0;
158 if (!doCompress
) EMIT('"');
160 for (; *p
&& *p
!= '\n' && *p
!= '\r'; p
++) {
162 if (!quoteCh
&& !wasScreen
&& *p
== '#') break; /* comment follows; drop it */
166 if (!doCompress
) EMIT('\\');
168 wasScreen
= !wasScreen
;
172 if (!doCompress
) EMIT('\\');
174 if (!wasScreen
) quoteCh
= (quoteCh
==*p
)?0:*p
;
179 if (!wasScreen
) quoteCh
= (quoteCh
==*p
)?0:*p
;
183 if (!dontStrip
&& *((unsigned char *)p
) <= ' ') {
184 if (wasScreen
|| !dropSpaces
|| quoteCh
) EMIT(*p
);
185 dropSpaces
= !quoteCh
;
194 /* terminate output */
197 /* strip ending whitespace */
199 while (e
>= outbuf
&& *((unsigned char *)e
) <= ' ') --e
;
201 /* drop empty line */
202 if (!outbuf
[0]) continue;
208 fprintf(fout
, "%s\\n\",\n", outbuf
);
211 fprintf(fout
, "%s", buf
);
222 int main (int argc
, char *argv
[]) {
227 fprintf(stderr
, "usage: %s jambase.c Jambase ...\n", argv
[0]);
231 if (!(fout
= fopen(argv
[1], "wb"))) {
236 /* if the file ends in .c generate a C source file */
237 if ((p
= strrchr(argv
[1], '.')) && !strcmp(p
, ".c")) ++doDotC
;
239 /* now process the files */
240 argc
-= 2, argv
+= 2;
243 fprintf(fout
, "/* Generated by mkjambase from Jambase */\n");
244 fprintf(fout
, "#include \"jam.h\"\n");
246 fprintf(fout
, "char **jambase = 0;\n");
247 fprintf(fout
, "unsigned char jambasepk[] = {");
249 fprintf(fout
, "const char *jambase[] = {\n");
253 for (; argc
--; ++argv
) processFile(fout
, *argv
);
255 if (outdatalen
> 0) {
261 if (lzCompress(outdata
, outdatalen
, &dest
, &destlen
) != 0) {
262 perror("compression error!");
265 printf("%d bytes packed to %u bytes (%u%%)\n", outdatalen
, (unsigned int)destlen
, (unsigned int)(100*destlen
/outdatalen
));
266 //fwrite(dest, destlen, 1, fout);
267 for (int f
= 0; f
< destlen
; ++f
) {
273 fprintf(fout
, "0x%02x,", dest
[f
]);
275 if (cnt
> 0) fputc('\n', fout
);
279 //fwrite(outdata, outdatalen, 1, fout);
284 if (!doCompress
) fputc('0', fout
);
285 fprintf(fout
, "};\n");
286 if (doCompress
) fprintf(fout
, "\nJAMFA_CONST int jbpksize (void) { return sizeof(jambasepk); }\n");