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>
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
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.
39 uint64_t *strides
= 0;
51 struct fout
*fouts
= 0;
55 void seekcol (FILE *f
, int src
, int dst
) {
59 int n
= dst
/8 - src
/8;
71 FILE *findfout (char *file
) {
73 for (i
= 0; i
< foutsnum
; i
++)
74 if (!strcmp(fouts
[i
].name
, file
))
77 fprintf (stderr
, "AIII, didn't open file %s.\n", file
);
83 void printdef (char *name
, char *suf
, int type
, uint64_t val
, char *file
) {
84 FILE *dst
= findfout(file
);
87 fprintf (dst
, "#define %s__%s%n", name
, suf
, &len
);
89 fprintf (dst
, "#define %s%n", name
, &len
);
90 if (type
== 0 && val
> 0xffffffffull
)
91 seekcol (dst
, len
, startcol
-8);
93 seekcol (dst
, len
, startcol
);
96 if (val
> 0xffffffffull
)
97 fprintf (dst
, "0x%016"PRIx64
"ULL\n", val
);
99 fprintf (dst
, "0x%08"PRIx64
"\n", val
);
102 fprintf (dst
, "%"PRIu64
"\n", val
);
107 void printvalue (struct rnnvalue
*val
, int shift
) {
108 if (val
->varinfo
.dead
)
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
) {
118 printdef (prefix
, "SHR", 1, ti
->shr
, file
);
120 printdef (prefix
, "MIN", 0, ti
->min
, file
);
122 printdef (prefix
, "MAX", 0, ti
->max
, file
);
124 printdef (prefix
, "ALIGN", 0, ti
->align
, file
);
126 printdef (prefix
, "RADIX", 0, ti
->radix
, file
);
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
)
137 if (bf
->typeinfo
.type
== RNN_TTYPE_BOOLEAN
) {
138 printdef (bf
->fullname
, 0, 0, bf
->mask
<< shift
, bf
->file
);
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
)
149 if (elem
->length
!= 1)
150 ADDARRAY(strides
, elem
->stride
);
154 FILE *dst
= findfout(elem
->file
);
155 fprintf (dst
, "#define %s(%n", elem
->fullname
, &total
);
157 for (i
= 0; i
< stridesnum
; i
++) {
162 fprintf (dst
, "i%d%n", i
, &len
);
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");
173 printdef (elem
->fullname
, 0, 0, offset
+ elem
->offset
, elem
->file
);
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");
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
)
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
)
200 gmtime_r(&sb
.st_mtime
, &tm
);
201 print_file_info_(dst
, &sb
, &tm
);
204 void printhead(struct fout f
, struct rnndb
*db
) {
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");
214 "/* Autogenerated file, DO NOT EDIT manually!\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"
220 "The rules-ng-ng source files this header was generated from are:\n");
222 for(i
= 0; i
< db
->filesnum
; ++i
) {
223 unsigned len
= strlen(db
->files
[i
]);
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
]);
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
) {
265 fprintf(stderr
, "Usage:\n\theadergen database-file\n");
271 rnn_parsefile (db
, argv
[1]);
273 for(i
= 0; i
< db
->filesnum
; ++i
) {
274 char *dstname
= malloc(strlen(db
->files
[i
]) + 3);
276 strcpy(dstname
, db
->files
[i
]);
277 strcat(dstname
, ".h");
278 struct fout f
= { db
->files
[i
], fopen(dstname
, "w") };
284 pretty
= strrchr(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
]);
299 for (i
= 0; i
< db
->enumsnum
; i
++) {
300 if (db
->enums
[i
]->isinline
)
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
)
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
);
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
);