dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / common / ficl / softcore / makesoftcore.c
blobd24006261c379464c5699b4e2114d9889612373c
1 /*
2 * Ficl softcore generator.
3 * Generates both uncompressed and Lempel-Ziv compressed versions.
4 * Strips blank lines, strips full-line comments, collapses whitespace.
5 * Chops, blends, dices, makes julienne fries.
7 * Contributed by Larry Hastings, larry@hastings.org
8 */
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <time.h>
14 #include "ficl.h"
16 #ifndef SOFTCORE_OUT
17 #define SOFTCORE_OUT "softcore.c"
18 #endif
20 extern size_t
21 lz4_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n);
23 void
24 fprintDataAsHex(FILE *f, unsigned char *data, int length)
26 int i;
27 while (length) {
28 fprintf(f, "\t");
29 for (i = 0; (i < 8) && length; i++) {
30 char buf[16];
32 * if you don't do this little stuff, you get ugly
33 * sign-extended 0xFFFFFF6b crap.
35 sprintf(buf, "%08x", (unsigned int)*data++);
36 fprintf(f, "0x%s, ", buf + 6);
37 length--;
39 fprintf(f, "\n");
43 void
44 fprintDataAsQuotedString(FILE *f, char *data)
46 int lineIsBlank = 1; /* true */
48 while (*data) {
49 if (*data == '\n') {
50 if (!lineIsBlank)
51 fprintf(f, "\\n\"\n");
52 lineIsBlank = 1; /* true */
53 } else {
54 if (lineIsBlank) {
55 fputc('\t', f);
56 fputc('"', f);
57 lineIsBlank = 0; /* false */
60 if (*data == '"')
61 fprintf(f, "\\\"");
62 else if (*data == '\\')
63 fprintf(f, "\\\\");
64 else
65 fputc(*data, f);
67 data++;
69 if (!lineIsBlank)
70 fprintf(f, "\"");
73 int
74 main(int argc, char *argv[])
76 char *uncompressed = (char *)malloc(128 * 1024);
77 unsigned char *compressed = malloc(128 * 1024);
78 char *trace = uncompressed;
79 int i;
80 size_t compressedSize = 128 * 1024;
81 size_t uncompressedSize;
82 char *src, *dst;
83 FILE *f;
84 time_t currentTimeT;
85 struct tm *currentTime;
86 char cleverTime[32];
88 time(&currentTimeT);
89 currentTime = localtime(&currentTimeT);
90 strftime(cleverTime, sizeof (cleverTime),
91 "%Y/%m/%d %H:%M:%S", currentTime);
93 *trace++ = ' ';
95 for (i = 1; i < argc; i++) {
96 int size;
98 * This ensures there's always whitespace space between files.
99 * It *also* ensures that src[-1] is always safe in comment
100 * detection code below. (Any leading whitespace will be
101 * thrown away in a later pass.)
102 * --lch
104 *trace++ = ' ';
106 f = fopen(argv[i], "rb");
107 fseek(f, 0, SEEK_END);
108 size = ftell(f);
109 fseek(f, 0, SEEK_SET);
110 fread(trace, 1, size, f);
111 fclose(f);
112 trace += size;
114 *trace = 0;
116 #define IS_EOL(x) ((*x == '\n') || (*x == '\r'))
117 #define IS_EOL_COMMENT(x) \
118 (((x[0] == '\\') && isspace(x[1])) || \
119 ((x[0] == '/') && (x[1] == '/') && isspace(x[2])))
120 #define IS_BLOCK_COMMENT(x) \
121 ((x[0] == '(') && isspace(x[1]) && isspace(x[-1]))
123 src = dst = uncompressed;
124 while (*src) {
125 /* ignore leading whitespace, or entirely blank lines */
126 while (isspace(*src))
127 src++;
128 /* if the line is commented out */
129 if (IS_EOL_COMMENT(src)) {
130 /* throw away this entire line */
131 while (*src && !IS_EOL(src))
132 src++;
133 continue;
136 * This is where we'd throw away mid-line comments, but
137 * that's simply unsafe. Things like
138 * start-prefixes
139 * : \ postpone \ ;
140 * : ( postpone ( ;
141 * get broken that way.
142 * --lch
144 while (*src && !IS_EOL(src)) {
145 *dst++ = *src++;
148 /* strip trailing whitespace */
149 dst--;
150 while (isspace(*dst))
151 dst--;
152 dst++;
154 /* and end the line */
155 *dst++ = '\n';
158 *dst = 0;
161 * now make a second pass to collapse all contiguous whitespace
162 * to a single space.
164 src = dst = uncompressed;
165 while (*src) {
166 *dst++ = *src;
167 if (!isspace(*src))
168 src++;
169 else {
170 while (isspace(*src))
171 src++;
174 *dst = 0;
176 f = fopen(SOFTCORE_OUT, "wt");
177 if (f == NULL) {
178 printf("couldn't open " SOFTCORE_OUT
179 " for writing! giving up.\n");
180 exit(-1);
183 fprintf(f,
184 "/*\n"
185 "** Ficl softcore\n"
186 "** both uncompressed and LZ4 compressed versions.\n"
187 "**\n"
188 "** Generated %s\n"
189 "**/\n"
190 "\n"
191 "#include \"ficl.h\"\n"
192 "\n"
193 "\n", cleverTime);
195 uncompressedSize = dst - uncompressed;
196 compressedSize = lz4_compress(uncompressed, compressed,
197 uncompressedSize, compressedSize, 0);
199 fprintf(f, "static size_t ficlSoftcoreUncompressedSize = %d; "
200 "/* not including trailing null */\n", uncompressedSize);
201 fprintf(f, "\n");
202 fprintf(f, "#if !FICL_WANT_LZ4_SOFTCORE\n");
203 fprintf(f, "\n");
204 fprintf(f, "static char ficlSoftcoreUncompressed[] =\n");
205 fprintDataAsQuotedString(f, uncompressed);
206 fprintf(f, ";\n");
207 fprintf(f, "\n");
208 fprintf(f, "#else /* !FICL_WANT_LZ4_SOFTCORE */\n");
209 fprintf(f, "\n");
210 fprintf(f, "extern int lz4_decompress(void *, void *, size_t, "
211 "size_t, int);\n\n");
212 fprintf(f, "static unsigned char ficlSoftcoreCompressed[%d] = "
213 "{\n", compressedSize);
214 fprintDataAsHex(f, compressed, compressedSize);
215 fprintf(f, "\t};\n");
216 fprintf(f, "\n");
217 fprintf(f, "#endif /* !FICL_WANT_LZ4_SOFTCORE */\n");
218 fprintf(f,
219 "\n"
220 "\n"
221 "void ficlSystemCompileSoftCore(ficlSystem *system)\n"
222 "{\n"
223 " ficlVm *vm = system->vmList;\n"
224 " int returnValue;\n"
225 " ficlCell oldSourceID = vm->sourceId;\n"
226 " ficlString s;\n"
227 "#if FICL_WANT_LZ4_SOFTCORE\n"
228 " char *ficlSoftcoreUncompressed = malloc(ficlSoftcoreUncompressedSize+1);\n"
229 " returnValue = lz4_decompress(ficlSoftcoreCompressed, "
230 "ficlSoftcoreUncompressed, sizeof(ficlSoftcoreCompressed), "
231 "ficlSoftcoreUncompressedSize+1, 0);\n"
232 " FICL_VM_ASSERT(vm, returnValue == 0);\n"
233 "#endif /* FICL_WANT_LZ4_SOFTCORE */\n"
234 " vm->sourceId.i = -1;\n"
235 " FICL_STRING_SET_POINTER(s, (char *)(ficlSoftcoreUncompressed));\n"
236 " FICL_STRING_SET_LENGTH(s, ficlSoftcoreUncompressedSize);\n"
237 " returnValue = ficlVmExecuteString(vm, s);\n"
238 " vm->sourceId = oldSourceID;\n"
239 "#if FICL_WANT_LZ4_SOFTCORE\n"
240 " free(ficlSoftcoreUncompressed);\n"
241 "#endif /* FICL_WANT_LZ4_SOFTCORE */\n"
242 " FICL_VM_ASSERT(vm, returnValue != FICL_VM_STATUS_ERROR_EXIT);\n"
243 " return;\n"
244 "}\n\n"
245 "/* end-of-file */\n");
246 free(uncompressed);
247 free(compressed);
248 return (0);