#define USE_HCONFIG
#include "proj.h"
#include "malloc.h"
#undef MAXNAMELEN
#define MAXNAMELEN 100
typedef struct _name_ *name;
struct _name_
{
name next;
name previous;
name next_alpha;
name previous_alpha;
int namelen;
int kwlen;
char kwname[MAXNAMELEN];
char name_uc[MAXNAMELEN];
char name_lc[MAXNAMELEN];
char name_ic[MAXNAMELEN];
};
struct _name_root_
{
name first;
name last;
};
struct _name_alpha_
{
name ign1;
name ign2;
name first;
name last;
};
static FILE *in;
static FILE *out;
static char prefix[32];
static char postfix[32];
static char storage[32];
static const char *const xspaces[]
=
{
"",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
"\t",
"\t ",
"\t ",
"\t ",
"\t ",
"\t ",
"\t ",
"\t ",
"\t\t",
"\t\t ",
"\t\t ",
"\t\t ",
"\t\t ",
"\t\t ",
"\t\t ",
"\t\t ",
"\t\t\t",
"\t\t\t ",
"\t\t\t ",
"\t\t\t ",
"\t\t\t ",
"\t\t\t ",
"\t\t\t ",
"\t\t\t ",
"\t\t\t\t",
"\t\t\t\t ",
"\t\t\t\t ",
"\t\t\t\t ",
"\t\t\t\t ",
"\t\t\t\t ",
"\t\t\t\t ",
"\t\t\t\t ",
"\t\t\t\t\t",
"\t\t\t\t\t ",
"\t\t\t\t\t ",
"\t\t\t\t\t ",
"\t\t\t\t\t ",
"\t\t\t\t\t ",
"\t\t\t\t\t ",
"\t\t\t\t\t ",
"\t\t\t\t\t\t",
"\t\t\t\t\t\t ",
"\t\t\t\t\t\t ",
"\t\t\t\t\t\t ",
"\t\t\t\t\t\t ",
"\t\t\t\t\t\t ",
"\t\t\t\t\t\t ",
"\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ",
};
void testname (bool nested, int indent, name first, name last);
void testnames (bool nested, int indent, int len, name first, name last);
int
main (int argc, char **argv)
{
char buf[MAXNAMELEN];
char last_buf[MAXNAMELEN];
char kwname[MAXNAMELEN];
char routine[32];
char type[32];
int i;
int count;
int len;
struct _name_root_ names[200];
struct _name_alpha_ names_alpha;
name n;
name newname;
char *input_name;
char *output_name;
char *include_name;
FILE *incl;
int fixlengths;
int total_length;
int do_name;
int do_names;
int cc;
bool do_exit = FALSE;
last_buf[0] = '\0';
for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i)
{
names[i].first = (name) &names[i];
names[i].last = (name) &names[i];
}
names_alpha.first = (name) &names_alpha;
names_alpha.last = (name) &names_alpha;
if (argc != 4)
{
fprintf (stderr, "Command form: fini input output-code output-include\n");
return (1);
}
input_name = argv[1];
output_name = argv[2];
include_name = argv[3];
in = fopen (input_name, "r");
if (in == NULL)
{
fprintf (stderr, "Cannot open \"%s\"\n", input_name);
return (1);
}
out = fopen (output_name, "w");
if (out == NULL)
{
fclose (in);
fprintf (stderr, "Cannot open \"%s\"\n", output_name);
return (1);
}
incl = fopen (include_name, "w");
if (incl == NULL)
{
fclose (in);
fprintf (stderr, "Cannot open \"%s\"\n", include_name);
return (1);
}
for (;;)
{
cc = getc (in);
if (cc == '{')
{
while (((cc = getc (in)) != '}') && (cc != EOF))
;
}
else if (cc != EOF)
{
while (((cc = getc (in)) != EOF) && (! ISALNUM (cc)))
;
ungetc (cc, in);
break;
}
else
{
assert ("EOF too soon!" == NULL);
return (1);
}
}
fscanf (in, "%s %s %s %s %s %d %d", prefix, postfix, storage, type, routine,
&do_name, &do_names);
if (storage[0] == '\0')
storage[1] = '\0';
else
{
if (storage[2] == '\0')
storage[1] = '\0';
else
storage[strlen (storage) - 1] = ' ';
}
if (postfix[0] == '\0')
postfix[1] = '\0';
else
postfix[strlen (postfix) - 1] = '\0';
for (i = 1; storage[i] != '\0'; ++i)
storage[i - 1] = storage[i];
storage[i - 1] = '\0';
for (i = 1; postfix[i] != '\0'; ++i)
postfix[i - 1] = postfix[i];
postfix[i - 1] = '\0';
fixlengths = strlen (prefix) + strlen (postfix);
while (TRUE)
{
count = fscanf (in, "%s %s", buf, kwname);
if (count == EOF)
break;
len = strlen (buf);
if (len == 0)
continue;
if (buf[0] == ';')
continue;
for (i = strlen (buf) - 1; i > 0; --i)
cc = buf[i];
newname = (name) xmalloc (sizeof (*newname));
newname->namelen = strlen (buf);
newname->kwlen = strlen (kwname);
total_length = newname->kwlen + fixlengths;
if (total_length >= 32)
{
fprintf (stderr, "%s: %s%s%s is 31+%d chars long\n", input_name,
prefix, kwname, postfix, total_length - 31);
do_exit = TRUE;
}
strcpy (newname->kwname, kwname);
for (i = 0; i < newname->namelen; ++i)
{
cc = buf[i];
newname->name_uc[i] = TOUPPER (cc);
newname->name_lc[i] = TOLOWER (cc);
newname->name_ic[i] = cc;
}
newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i] = '\0';
if ((last_buf[0] != '\0')
&& (strcmp (last_buf, newname->name_uc) >= 0))
{
fprintf (stderr, "%s: \"%s\" precedes \"%s\"\n", input_name,
last_buf, newname->name_uc);
do_exit = TRUE;
}
strcpy (last_buf, newname->name_uc);
n = names_alpha.last;
newname->next_alpha = n->next_alpha;
newname->previous_alpha = n;
n->next_alpha->previous_alpha = newname;
n->next_alpha = newname;
n = (name) &names[len];
while ((n->next != (name) &names[len])
&& (strcmp (buf, n->next->name_uc) > 0))
n = n->next;
if (strcmp (buf, n->next->name_uc) == 0)
{
fprintf (stderr, "%s: extraneous \"%s\"\n", input_name, buf);
do_exit = TRUE;
}
newname->next = n->next;
newname->previous = n;
n->next->previous = newname;
n->next = newname;
}
#if 0
for (len = 0; len < ARRAY_SIZE (name); ++len)
{
if (names[len].first == (name) &names[len])
continue;
printf ("Length %d:\n", len);
for (n = names[len].first; n != (name) &names[len]; n = n->next)
printf (" %s %s %s\n", n->name_uc, n->name_lc, n->name_ic);
}
#endif
if (do_exit)
return (1);
for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
{
fprintf (incl, "#define %sl%s%s %d\n", prefix, n->kwname, postfix,
n->namelen);
}
fprintf (incl,
"\
\n\
enum %s_\n\
{\n\
%sNone%s,\n\
",
type, prefix, postfix);
for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha)
{
fprintf (incl,
"\
%s%s%s,\n\
",
prefix, n->kwname, postfix);
}
fprintf (incl,
"\
%s%s\n\
};\n\
typedef enum %s_ %s;\n\
",
prefix, postfix, type, type);
fprintf (out,
"\
%s%s\n\
%s (ffelexToken t)\n\
%c\n\
char *p;\n\
int c;\n\
\n\
p = ffelex_token_text (t);\n\
\n\
",
storage, type, routine, '{');
if (do_name)
{
if (do_names)
fprintf (out,
"\
if (ffelex_token_type (t) == FFELEX_typeNAME)\n\
{\n\
switch (ffelex_token_length (t))\n\
\t{\n\
"
);
else
fprintf (out,
"\
assert (ffelex_token_type (t) == FFELEX_typeNAME);\n\
\n\
switch (ffelex_token_length (t))\n\
{\n\
"
);
for (len = 0; ((size_t) len) < ARRAY_SIZE (names); ++len)
{
if (names[len].first != (name) &names[len])
{
if (do_names)
fprintf (out,
"\
\tcase %d:\n\
",
len);
else
fprintf (out,
"\
case %d:\n\
",
len);
testname (FALSE, do_names ? 10 : 6, names[len].first, names[len].last);
if (do_names)
fprintf (out,
"\
\t break;\n\
"
);
else
fprintf (out,
"\
break;\n\
"
);
}
}
if (do_names)
fprintf (out,
"\
\t}\n\
return %sNone%s;\n\
}\n\
\n\
",
prefix, postfix);
else
fprintf (out,
"\
}\n\
\n\
return %sNone%s;\n\
}\n\
",
prefix, postfix);
}
if (do_names)
{
fputs ("\
assert (ffelex_token_type (t) == FFELEX_typeNAMES);\n\
\n\
switch (ffelex_token_length (t))\n\
{\n\
default:\n\
",
out);
for (len = ARRAY_SIZE (names) - 1;
names[len].first == (name) &names[len];
--len)
;
if (len > 0)
{
for (; len != 0; --len)
{
fprintf (out,
"\
case %d:\n\
",
len);
if (names[len].first != (name) &names[len])
testnames (FALSE, 6, len, names[len].first, names[len].last);
}
if (names[1].first == (name) &names[1])
fprintf (out,
"\
;\n\
"
);
}
fprintf (out,
"\
}\n\
\n\
return %sNone%s;\n\
}\n\
",
prefix, postfix);
}
if (out != stdout)
fclose (out);
if (incl != stdout)
fclose (incl);
if (in != stdin)
fclose (in);
return (0);
}
void
testname (bool nested, int indent, name first, name last)
{
name n;
name nhalf;
int num;
int numhalf;
assert (!nested || indent >= 2);
assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
num = 0;
numhalf = 0;
for (n = first, nhalf = first; n != last->next; n = n->next)
{
if ((++num & 1) == 0)
{
nhalf = nhalf->next;
++numhalf;
}
}
if (nested)
fprintf (out,
"\
%s{\n\
",
xspaces[indent - 2]);
fprintf (out,
"\
%sif ((c = ffesrc_strcmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\")) == 0)\n\
%sreturn %s%s%s;\n\
",
xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
xspaces[indent + 2], prefix, nhalf->kwname, postfix);
if (num != 1)
{
fprintf (out,
"\
%selse if (c < 0)\n\
",
xspaces[indent]);
if (numhalf == 0)
fprintf (out,
"\
%s;\n\
",
xspaces[indent + 2]);
else
testname (TRUE, indent + 4, first, nhalf->previous);
if (num - numhalf > 1)
{
fprintf (out,
"\
%selse\n\
",
xspaces[indent]);
testname (TRUE, indent + 4, nhalf->next, last);
}
}
if (nested)
fprintf (out,
"\
%s}\n\
",
xspaces[indent - 2]);
}
void
testnames (bool nested, int indent, int len, name first, name last)
{
name n;
name nhalf;
int num;
int numhalf;
assert (!nested || indent >= 2);
assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
num = 0;
numhalf = 0;
for (n = first, nhalf = first; n != last->next; n = n->next)
{
if ((++num & 1) == 0)
{
nhalf = nhalf->next;
++numhalf;
}
}
if (nested)
fprintf (out,
"\
%s{\n\
",
xspaces[indent - 2]);
fprintf (out,
"\
%sif ((c = ffesrc_strncmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\", %d)) == 0)\n\
%sreturn %s%s%s;\n\
",
xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
len, xspaces[indent + 2], prefix, nhalf->kwname, postfix);
if (num != 1)
{
fprintf (out,
"\
%selse if (c < 0)\n\
",
xspaces[indent]);
if (numhalf == 0)
fprintf (out,
"\
%s;\n\
",
xspaces[indent + 2]);
else
testnames (TRUE, indent + 4, len, first, nhalf->previous);
if (num - numhalf > 1)
{
fprintf (out,
"\
%selse\n\
",
xspaces[indent]);
testnames (TRUE, indent + 4, len, nhalf->next, last);
}
}
if (nested)
fprintf (out,
"\
%s}\n\
",
xspaces[indent - 2]);
}