regexp engine now undestands some character classes (like :space:) and non-greedy ops
[k8jam.git] / src / mkjambase.c
blob4a8576e3e6a26f1f725117fd21423de3b4373406
1 /*
2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
7 /*
8 * mkjambase.c - turn Jambase into a big C structure
10 * Usage: mkjambase jambase.c Jambase ...
12 * Results look like this:
14 * char *jambase[] = {
15 * "...\n",
16 * ...
17 * 0 };
19 * Handles \'s and "'s specially; knows how to delete blank and comment lines.
21 * 11/04/02 (seiwald) - const-ing for string literals
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
28 //#define MKJAMBASE_COMPACT
31 static void fatal (const char *msg) {
32 fprintf(stdout, "FATAL: %s\n", msg);
33 exit(1);
37 #define EMIT(ch) {if (outp-outbuf>2046) fatal("output line too big\n"); *(outp++) = (ch); }
40 int main (int argc, char **argv, char **envp) {
41 char buf[1024], outbuf[2048];
42 FILE *fin;
43 FILE *fout;
44 char *p, *e, quoteCh, *outp;
45 int doDotC = 0, wasScreen, dontStrip = 0, dropSpaces;
47 if (argc < 3) {
48 fprintf(stderr, "usage: %s jambase.c Jambase ...\n", argv[0]);
49 return -1;
52 if (!(fout = fopen(argv[1], "w"))) {
53 perror(argv[1]);
54 return -1;
57 /* if the file ends in .c generate a C source file */
58 if ((p = strrchr(argv[1], '.')) && !strcmp(p, ".c")) ++doDotC;
60 /* now process the files */
61 argc -= 2, argv += 2;
63 if (doDotC) {
64 fprintf(fout, "/* Generated by mkjambase from Jambase */\n");
65 fprintf(fout, "const char *jambase[] = {\n");
68 for (; argc--; ++argv) {
69 if (!(fin = fopen(*argv, "r"))) {
70 perror(*argv);
71 return -1;
73 if (doDotC) fprintf(fout, "/* %s */\n", *argv); else fprintf(fout, "### %s ###\n", *argv);
75 while (fgets(buf, sizeof(buf), fin)) {
76 if (doDotC) {
77 #ifdef MKJAMBASE_COMPACT
78 if (!strncmp(buf, "#DONT_TOUCH", 11)) {
79 dontStrip = !dontStrip;
80 continue;
82 #else
83 dontStrip = 1;
84 #endif
85 char *p = buf;
86 /* strip leading whitespace */
87 if (!dontStrip) {
88 while (*p && *((unsigned char *)p) <= ' ') ++p;
89 /* drop comments and empty lines */
90 if (*p == '#' || !*p) continue;
92 /* copy; drop comments if # is not in quotes */
93 outp = outbuf; quoteCh = 0; wasScreen = 0;
94 EMIT('"');
95 dropSpaces = 0;
96 for (; *p && *p != '\n' && *p != '\r'; p++) {
97 if (!dontStrip) {
98 if (!quoteCh && !wasScreen && *p == '#') break; /* comment follows; drop it */
100 switch (*p) {
101 case '\\':
102 EMIT('\\'); EMIT('\\');
103 wasScreen = !wasScreen;
104 dropSpaces = 0;
105 break;
106 case '"':
107 EMIT('\\'); EMIT('"');
108 if (!wasScreen) quoteCh = (quoteCh==*p)?0:*p;
109 dropSpaces = 0;
110 break;
111 case '\x27': /* ' */
112 EMIT('\x27');
113 if (!wasScreen) quoteCh = (quoteCh==*p)?0:*p;
114 dropSpaces = 0;
115 break;
116 default:
117 if (!dontStrip && *((unsigned char *)p) <= ' ') {
118 if (wasScreen || !dropSpaces) EMIT(*p);
119 dropSpaces = !wasScreen;
120 } else {
121 EMIT(*p);
122 dropSpaces = 0;
124 wasScreen = 0;
125 break;
128 /* terminate output */
129 *outp = '\0';
130 if (!dontStrip) {
131 /* strip ending whitespace */
132 e = outp-1;
133 while (e >= outbuf && *((unsigned char *)e) <= ' ') --e;
134 *(++e) = '\0';
135 /* drop empty line */
136 if (!outbuf[0]) continue;
138 fprintf(fout, "%s\\n\",\n", outbuf);
139 } else {
140 fprintf(fout, "%s", buf);
143 fclose(fin);
145 if (doDotC) fprintf(fout, "0};\n");
146 fclose(fout);
148 return 0;