2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * mkjambase.c - turn Jambase into a big C structure
10 * Usage: mkjambase jambase.c Jambase ...
12 * Results look like this:
19 * Handles \'s and "'s specially; knows how to delete blank and comment lines.
21 * 11/04/02 (seiwald) - const-ing for string literals
29 //#define MKJAMBASE_COMPACT
32 static void fatal (const char *msg
) {
33 fprintf(stdout
, "FATAL: %s\n", msg
);
38 #define EMIT(ch) do { \
39 if (outp-outbuf >= sizeof(outbuf)) fatal("output line too big\n");\
44 static inline void normSlashes (char *s
) {
45 for (; *s
; ++s
) if (*s
== '\\') *s
= '/';
49 static int doDotC
= 0, wasScreen
, dontStrip
= 0, dropSpaces
;
51 static int lineno
= 0;
52 static int inclevel
= 0;
53 static const char *srcfname
= "<cli>";
55 static void processFile (FILE *fout
, const char *fname
) {
57 char *p
, *e
, quoteCh
, *outp
;
58 static char buf
[32768], outbuf
[32768];
60 const char *ofn
= srcfname
;
65 if (++inclevel
> 64) {
67 fprintf(stderr
, "FATAL: too many nested includes, failed in file '%s', line %d\n", ofn
, olno
);
71 printf(": %s\n", fname
);
72 if (!(fin
= fopen(fname
, "r"))) {
74 fprintf(stderr
, "FATAL: can't open file '%s', failed in file '%s', line %d\n", fname
, ofn
, olno
);
77 if (doDotC
) fprintf(fout
, "/* %s */\n", fname
); else fprintf(fout
, "### %s ###\n", fname
);
79 while (fgets(buf
, sizeof(buf
), fin
)) {
87 while (*p
&& *((unsigned char *)p
) <= ' ') ++p
;
88 if ((t
= strchr(p
, '#')) != NULL
) *t
= '\0';
89 for (t
= p
+strlen(p
); t
> p
; --t
) if (!isspace(t
[-1])) break;
93 fprintf(stderr
, "FATAL: invalid '.' in file '%s', line %d\n", fname
, lineno
);
96 fn
= malloc(strlen(p
)+strlen(fname
)+64);
99 fprintf(stderr
, "FATAL: out of memory in file '%s', line %d\n", fname
, lineno
);
104 if ((t
= strrchr(fn
, '/')) != NULL
) t
[1] = '\0'; else fn
[0] = '\0';
106 processFile(fout
, fn
);
112 #ifdef MKJAMBASE_COMPACT
113 if (!strncmp(buf
, "#DONT_TOUCH", 11)) {
114 dontStrip
= !dontStrip
;
121 /* strip leading whitespace */
123 while (*p
&& *((unsigned char *)p
) <= ' ') ++p
;
124 /* drop comments and empty lines */
125 if (*p
== '#' || !*p
) continue;
127 /* copy; drop comments if # is not in quotes */
128 outp
= outbuf
; quoteCh
= 0; wasScreen
= 0;
131 for (; *p
&& *p
!= '\n' && *p
!= '\r'; p
++) {
133 if (!quoteCh
&& !wasScreen
&& *p
== '#') break; /* comment follows; drop it */
137 EMIT('\\'); EMIT('\\');
138 wasScreen
= !wasScreen
;
142 EMIT('\\'); EMIT('"');
143 if (!wasScreen
) quoteCh
= (quoteCh
==*p
)?0:*p
;
148 if (!wasScreen
) quoteCh
= (quoteCh
==*p
)?0:*p
;
152 if (!dontStrip
&& *((unsigned char *)p
) <= ' ') {
153 if (wasScreen
|| !dropSpaces
|| quoteCh
) EMIT(*p
);
154 dropSpaces
= !quoteCh
;
163 /* terminate output */
166 /* strip ending whitespace */
168 while (e
>= outbuf
&& *((unsigned char *)e
) <= ' ') --e
;
170 /* drop empty line */
171 if (!outbuf
[0]) continue;
173 fprintf(fout
, "%s\\n\",\n", outbuf
);
175 fprintf(fout
, "%s", buf
);
185 int main (int argc
, char *argv
[]) {
190 fprintf(stderr
, "usage: %s jambase.c Jambase ...\n", argv
[0]);
194 if (!(fout
= fopen(argv
[1], "w"))) {
199 /* if the file ends in .c generate a C source file */
200 if ((p
= strrchr(argv
[1], '.')) && !strcmp(p
, ".c")) ++doDotC
;
202 /* now process the files */
203 argc
-= 2, argv
+= 2;
206 fprintf(fout
, "/* Generated by mkjambase from Jambase */\n");
207 fprintf(fout
, "const char *jambase[] = {\n");
210 for (; argc
--; ++argv
) processFile(fout
, *argv
);
212 if (doDotC
) fprintf(fout
, "0};\n");