libdb/lang/sql/odbc/mkopc3.c
2011-09-13 13:44:24 -04:00

217 lines
4.8 KiB
C

/*
* Make opcodes.[ch] from standard input and parse.h.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct tk {
struct tk *next, *other;
char *name;
int val;
int nopush;
};
static int
opsort(const void *a, const void *b)
{
struct tk *ta = (struct tk *) a;
struct tk *tb = (struct tk *) b;
return ta->val - tb->val;
}
static void
append(struct tk **head, struct tk *tk)
{
struct tk *h = *head;
tk->next = NULL;
if (h != NULL) {
while (h->next != NULL) {
h = h->next;
}
h->next = tk;
} else {
*head = tk;
}
}
static int nopush[10];
int
main(int argc, char **argv)
{
FILE *c_file, *h_file, *p_file, *a_file;
char line[512];
char used[1024];
int count = 0, last_val, max_val = -1, nop = 0;
struct tk *tk = NULL;
struct tk *op = NULL, *opa = NULL;
memset(used, 0, sizeof (used));
p_file = fopen("parse.h", "r");
c_file = fopen("opcodes.c", "w");
h_file = fopen("opcodes.h", "w");
if (p_file == NULL) {
fprintf(stderr, "unable to open parse.h\n");
exit(1);
}
if (c_file == NULL || h_file == NULL) {
fprintf(stderr, "unable to open output file(s)\n");
exit(1);
}
while (fgets(line, sizeof (line), p_file) != NULL) {
if (strncmp(line, "#define TK_", 11) == 0) {
char name[64];
int val;
if (sscanf(line, "#define %s%d", name, &val) == 2) {
struct tk *tkn = malloc(sizeof (struct tk) + strlen(name) + 1);
tkn->next = tk;
tkn->other = NULL;
tkn->name = (char *) (tkn + 1);
tkn->val = val;
tkn->nopush = 0;
strcpy(tkn->name, name);
tk = tkn;
if (val > max_val) {
max_val = val;
}
}
}
}
fclose(p_file);
a_file = fopen("addopcodes.awk", "r");
if (a_file) {
p_file = fopen("parse.h", "a");
while (fgets(line, sizeof (line), a_file) != NULL) {
if (strstr(line, "printf") && strstr(line, "#define TK_")) {
char *name = NULL, *p;
for (p = line, count = 0; p != NULL && count < 3; count++) {
p = strchr(p, '"');
if (p) {
++p;
}
}
if (p != NULL) {
char *q = strchr(p, '"');
if (q != NULL) {
name = p;
*q = '\0';
}
}
if (name != NULL) {
struct tk *tkn = malloc(sizeof (struct tk) +
strlen(name) + 3 + 1);
fprintf(p_file, "#define TK_%-27s %3d\n", name, ++max_val);
tkn->next = tk;
tkn->other = NULL;
tkn->name = (char *) (tkn + 1);
tkn->val = max_val;
tkn->nopush = 0;
strcpy(tkn->name, "TK_");
strcat(tkn->name, name);
tk = tkn;
}
}
}
fclose(a_file);
fclose(p_file);
}
while (fgets(line, sizeof (line), stdin) != NULL) {
if (strncmp(line, "case OP_", 7) == 0) {
char *p, *q, *qq;
struct tk *opn;
p = line + 5;
q = strchr(p, ':');
if (q == NULL) {
continue;
}
*q = '\0';
opn = malloc(sizeof (struct tk) + strlen(p) + 1);
opn->next = opn->other = NULL;
opn->name = (char *) (opn + 1);
opn->val = -1;
opn->nopush = 0;
strcpy(opn->name, p);
append(&op, opn);
qq = strstr(q + 1, "same as TK_");
if (qq != NULL) {
qq = strstr(qq, "TK_");
q = qq + 3;
}
if (qq != NULL) {
struct tk *tkp;
for (tkp = tk; tkp != NULL; tkp = tkp->next) {
if (memcmp(qq, tkp->name, strlen(tkp->name)) == 0) {
opn->other = tkp;
opn->val = tkp->val;
used[opn->val] = 1;
break;
}
}
}
qq = strstr(q + 1, "no-push");
if (qq != NULL) {
opn->nopush = 1;
}
}
}
if (op != NULL) {
struct tk *opp;
for (opp = op; opp != NULL; opp = opp->next) {
if (opp->val < 0) {
++count;
while (used[count]) {
count++;
}
opp->val = count;
}
++nop;
}
opa = malloc(sizeof (struct tk) * nop);
nop = 0;
for (opp = op; opp != NULL; opp = opp->next) {
opa[nop++] = *opp;
}
qsort(opa, nop, sizeof (struct tk), opsort);
}
fprintf(c_file, "/* Automatically generated file. Do not edit */\n");
fprintf(c_file, "char *sqliteOpcodeNames[] = {\n");
fprintf(h_file, "/* Automatically generated file. Do not edit */\n");
for (count = 0, last_val = -1; count < nop; count++) {
while (++last_val < opa[count].val) {
fprintf(c_file, " \"???\",\n");
}
fprintf(c_file, " \"%s\",\n", opa[count].name + 3);
fprintf(h_file, "#define %-30s %3d",
opa[count].name, opa[count].val);
if (opa[count].other != NULL) {
fprintf(h_file, " /* same as %s */", opa[count].other->name);
}
fprintf(h_file, "\n");
}
fprintf(c_file, "};\n");
for (count = 0; count < nop; count++) {
if (opa[count].nopush) {
int bit = opa[count].val % 16;
int off = opa[count].val / 16;
nopush[off] |= 1 << bit;
}
}
for (count = 0; count < 10; count++) {
fprintf(h_file, "#define NOPUSH_MASK_%d %d\n", count, nopush[count]);
}
fclose(h_file);
fclose(c_file);
return 0;
}