Merge pull request #218 from saper/build-fixes
[envytools.git] / rnn / headergen.c
blob676f3dfb43e83d3dbb9435b5bcfebbcc3290a869
1 /*
2 * Copyright (C) 2010-2011 Marcelina Koƛcielnicka <mwk@0x04.net>
3 * Copyright (C) 2010 Luca Barbieri <luca@luca-barbieri.com>
4 * Copyright (C) 2010 Marcin Slusarz <marcin.slusarz@gmail.com>
5 * All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
27 #include "rnn.h"
28 #include "util.h"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <inttypes.h>
32 #include <time.h>
33 #include <ctype.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <sys/stat.h>
37 #include <sys/wait.h>
39 uint64_t *strides = 0;
40 int stridesnum = 0;
41 int stridesmax = 0;
43 int startcol = 64;
45 struct fout {
46 char *name;
47 FILE *file;
48 char *guard;
51 struct fout *fouts = 0;
52 int foutsnum = 0;
53 int foutsmax = 0;
55 void seekcol (FILE *f, int src, int dst) {
56 if (dst <= src)
57 fprintf (f, "\t");
58 else {
59 int n = dst/8 - src/8;
60 if (n) {
61 while (n--)
62 fprintf (f, "\t");
63 n = dst&7;
64 } else
65 n = dst-src;
66 while (n--)
67 fprintf (f, " ");
71 FILE *findfout (char *file) {
72 int i;
73 for (i = 0; i < foutsnum; i++)
74 if (!strcmp(fouts[i].name, file))
75 break;
76 if (i == foutsnum) {
77 fprintf (stderr, "AIII, didn't open file %s.\n", file);
78 exit(1);
80 return fouts[i].file;
83 void printdef (char *name, char *suf, int type, uint64_t val, char *file) {
84 FILE *dst = findfout(file);
85 int len;
86 if (suf)
87 fprintf (dst, "#define %s__%s%n", name, suf, &len);
88 else
89 fprintf (dst, "#define %s%n", name, &len);
90 if (type == 0 && val > 0xffffffffull)
91 seekcol (dst, len, startcol-8);
92 else
93 seekcol (dst, len, startcol);
94 switch (type) {
95 case 0:
96 if (val > 0xffffffffull)
97 fprintf (dst, "0x%016"PRIx64"ULL\n", val);
98 else
99 fprintf (dst, "0x%08"PRIx64"\n", val);
100 break;
101 case 1:
102 fprintf (dst, "%"PRIu64"\n", val);
103 break;
107 void printvalue (struct rnnvalue *val, int shift) {
108 if (val->varinfo.dead)
109 return;
110 if (val->valvalid)
111 printdef (val->fullname, 0, 0, val->value << shift, val->file);
114 void printbitfield (struct rnnbitfield *bf, int shift);
116 void printtypeinfo (struct rnntypeinfo *ti, char *prefix, int shift, char *file) {
117 if (ti->shr)
118 printdef (prefix, "SHR", 1, ti->shr, file);
119 if (ti->minvalid)
120 printdef (prefix, "MIN", 0, ti->min, file);
121 if (ti->maxvalid)
122 printdef (prefix, "MAX", 0, ti->max, file);
123 if (ti->alignvalid)
124 printdef (prefix, "ALIGN", 0, ti->align, file);
125 if (ti->radixvalid)
126 printdef (prefix, "RADIX", 0, ti->radix, file);
127 int i;
128 for (i = 0; i < ti->valsnum; i++)
129 printvalue(ti->vals[i], shift);
130 for (i = 0; i < ti->bitfieldsnum; i++)
131 printbitfield(ti->bitfields[i], shift);
134 void printbitfield (struct rnnbitfield *bf, int shift) {
135 if (bf->varinfo.dead)
136 return;
137 if (bf->typeinfo.type == RNN_TTYPE_BOOLEAN) {
138 printdef (bf->fullname, 0, 0, bf->mask << shift, bf->file);
139 } else {
140 printdef (bf->fullname, "MASK", 0, bf->mask << shift, bf->file);
141 printdef (bf->fullname, "SHIFT", 1, bf->low + shift, bf->file);
143 printtypeinfo (&bf->typeinfo, bf->fullname, bf->low + shift, bf->file);
146 void printdelem (struct rnndelem *elem, uint64_t offset) {
147 if (elem->varinfo.dead)
148 return;
149 if (elem->length != 1)
150 ADDARRAY(strides, elem->stride);
151 if (elem->name) {
152 if (stridesnum) {
153 int len, total;
154 FILE *dst = findfout(elem->file);
155 fprintf (dst, "#define %s(%n", elem->fullname, &total);
156 int i;
157 for (i = 0; i < stridesnum; i++) {
158 if (i) {
159 fprintf(dst, ", ");
160 total += 2;
162 fprintf (dst, "i%d%n", i, &len);
163 total += len;
165 fprintf (dst, ")");
166 total++;
167 seekcol (dst, total, startcol-1);
168 fprintf (dst, "(0x%08"PRIx64"", offset + elem->offset);
169 for (i = 0; i < stridesnum; i++)
170 fprintf (dst, " + %#" PRIx64 "*(i%d)", strides[i], i);
171 fprintf (dst, ")\n");
172 } else
173 printdef (elem->fullname, 0, 0, offset + elem->offset, elem->file);
174 if (elem->stride)
175 printdef (elem->fullname, "ESIZE", 0, elem->stride, elem->file);
176 if (elem->length != 1)
177 printdef (elem->fullname, "LEN", 0, elem->length, elem->file);
178 printtypeinfo (&elem->typeinfo, elem->fullname, 0, elem->file);
180 fprintf (findfout(elem->file), "\n");
181 int j;
182 for (j = 0; j < elem->subelemsnum; j++) {
183 printdelem(elem->subelems[j], offset + elem->offset);
185 if (elem->length != 1) stridesnum--;
188 void print_file_info_(FILE *dst, struct stat* sb, struct tm* tm)
190 char timestr[64];
191 strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm);
192 fprintf(dst, "(%7Lu bytes, from %s)\n", (unsigned long long)sb->st_size, timestr);
195 void print_file_info(FILE *dst, const char* file)
197 struct stat sb;
198 struct tm tm;
199 stat(file, &sb);
200 gmtime_r(&sb.st_mtime, &tm);
201 print_file_info_(dst, &sb, &tm);
204 void printhead(struct fout f, struct rnndb *db) {
205 int i, j;
206 struct stat sb;
207 struct tm tm;
208 stat(f.name, &sb);
209 gmtime_r(&sb.st_mtime, &tm);
210 fprintf (f.file, "#ifndef %s\n", f.guard);
211 fprintf (f.file, "#define %s\n", f.guard);
212 fprintf (f.file, "\n");
213 fprintf(f.file,
214 "/* Autogenerated file, DO NOT EDIT manually!\n"
215 "\n"
216 "This file was generated by the rules-ng-ng headergen tool in this git repository:\n"
217 "https://github.com/envytools/envytools/\n"
218 "git clone https://github.com/envytools/envytools.git\n"
219 "\n"
220 "The rules-ng-ng source files this header was generated from are:\n");
221 unsigned maxlen = 0;
222 for(i = 0; i < db->filesnum; ++i) {
223 unsigned len = strlen(db->files[i]);
224 if(len > maxlen)
225 maxlen = len;
227 for(i = 0; i < db->filesnum; ++i) {
228 unsigned len = strlen(db->files[i]);
229 fprintf(f.file, "- %s%*s ", db->files[i], maxlen - len, "");
230 print_file_info(f.file, db->files[i]);
232 fprintf(f.file,
233 "\n"
234 "Copyright (C) ");
235 if(db->copyright.firstyear && db->copyright.firstyear < (1900 + tm.tm_year))
236 fprintf(f.file, "%u-", db->copyright.firstyear);
237 fprintf(f.file, "%u", 1900 + tm.tm_year);
238 if(db->copyright.authorsnum) {
239 fprintf(f.file, " by the following authors:");
240 for(i = 0; i < db->copyright.authorsnum; ++i) {
241 fprintf(f.file, "\n- ");
242 if(db->copyright.authors[i]->name)
243 fprintf(f.file, "%s", db->copyright.authors[i]->name);
244 if(db->copyright.authors[i]->email)
245 fprintf(f.file, " <%s>", db->copyright.authors[i]->email);
246 if(db->copyright.authors[i]->nicknamesnum) {
247 for(j = 0; j < db->copyright.authors[i]->nicknamesnum; ++j) {
248 fprintf(f.file, "%s%s", (j ? ", " : " ("), db->copyright.authors[i]->nicknames[j]);
250 fprintf(f.file, ")");
254 fprintf(f.file, "\n");
255 if(db->copyright.license)
256 fprintf(f.file, "\n%s\n", db->copyright.license);
257 fprintf(f.file, "*/\n\n\n");
260 int main(int argc, char **argv) {
261 struct rnndb *db;
262 int i, j, ret;
264 if (argc < 2) {
265 fprintf(stderr, "Usage:\n\theadergen database-file\n");
266 exit(1);
269 rnn_init();
270 db = rnn_newdb();
271 rnn_parsefile (db, argv[1]);
272 rnn_prepdb (db);
273 for(i = 0; i < db->filesnum; ++i) {
274 char *dstname = malloc(strlen(db->files[i]) + 3);
275 char *pretty;
276 strcpy(dstname, db->files[i]);
277 strcat(dstname, ".h");
278 struct fout f = { db->files[i], fopen(dstname, "w") };
279 if (!f.file) {
280 perror(dstname);
281 exit(1);
283 free(dstname);
284 pretty = strrchr(f.name, '/');
285 if (pretty)
286 pretty += 1;
287 else
288 pretty = f.name;
289 f.guard = strdup(pretty);
290 for (j = 0; j < strlen(f.guard); j++)
291 if (isalnum(f.guard[j]))
292 f.guard[j] = toupper(f.guard[j]);
293 else
294 f.guard[j] = '_';
295 ADDARRAY(fouts, f);
296 printhead(f, db);
299 for (i = 0; i < db->enumsnum; i++) {
300 if (db->enums[i]->isinline)
301 continue;
302 int j;
303 for (j = 0; j < db->enums[i]->valsnum; j++)
304 printvalue (db->enums[i]->vals[j], 0);
306 for (i = 0; i < db->bitsetsnum; i++) {
307 if (db->bitsets[i]->isinline)
308 continue;
309 int j;
310 for (j = 0; j < db->bitsets[i]->bitfieldsnum; j++)
311 printbitfield (db->bitsets[i]->bitfields[j], 0);
313 for (i = 0; i < db->domainsnum; i++) {
314 if (db->domains[i]->size)
315 printdef (db->domains[i]->fullname, "SIZE", 0, db->domains[i]->size, db->domains[i]->file);
316 int j;
317 for (j = 0; j < db->domains[i]->subelemsnum; j++) {
318 printdelem(db->domains[i]->subelems[j], 0);
321 for(i = 0; i < foutsnum; ++i) {
322 fprintf (fouts[i].file, "\n#endif /* %s */\n", fouts[i].guard);
324 ret = db->estatus;
326 rnn_freedb(db);
327 rnn_fini();
329 return ret;