#include "defs.h"
#include "getopt.h"
#define STDIN_NAME "(stdin)"
char *program;
StringHashPtr ns_prims = NULL;
StringHashPtr ns_vars = NULL;
StringHashPtr ns_subs = NULL;
StringHashPtr ns_states = NULL;
List *global_stmts = NULL;
List *start_stmts = NULL;
List *startrules = NULL;
List *namerules = NULL;
Node *nvoid = NULL;
FILE *ifp = NULL;
char *inbuf = NULL;
unsigned int data_in_buffer;
unsigned int bufpos;
int eof_seen;
char *current_fname;
unsigned int current_linenum;
struct re_registers *current_match = NULL;
char *current_match_buf = NULL;
VariableDef *vardefs = NULL;
VariableDef *vardefs_tail = NULL;
char *defs_file = "states.st";
unsigned int linenum = 1;
char *yyin_name;
FILE *ofp = NULL;
char *path = NULL;
char *start_state_arg = NULL;
char *start_state;
unsigned int verbose = 0;
WarningLevel warning_level = WARN_LIGHT;
static struct option long_options[] =
{
{"define", required_argument, 0, 'D'},
{"file", required_argument, 0, 'f'},
{"help", no_argument, 0, 'h'},
{"output", required_argument, 0, 'o'},
{"path", required_argument, 0, 'p'},
{"state", required_argument, 0, 's'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"warning", required_argument, 0, 'W'},
{NULL, 0, 0, 0},
};
char version[256];
static void usage ___P ((void));
int
main (argc, argv)
int argc;
char *argv[];
{
int c;
VariableDef *vardef;
ofp = stdout;
program = strrchr (argv[0], '/');
if (program == NULL)
program = argv[0];
else
program++;
argv[0] = program;
sprintf (version, _("states for GNU %s %s"), PACKAGE, VERSION);
#if HAVE_SETLOCALE
#if HAVE_LC_MESSAGES
setlocale (LC_MESSAGES, "");
#endif
#endif
#if ENABLE_NLS
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif
ns_prims = strhash_init ();
ns_vars = strhash_init ();
ns_subs = strhash_init ();
ns_states = strhash_init ();
global_stmts = list ();
start_stmts = list ();
startrules = list ();
namerules = list ();
nvoid = node_alloc (nVOID);
inbuf = (char *) xmalloc (INBUFSIZE);
init_primitives ();
re_set_syntax (RE_SYNTAX_GNU_AWK | RE_INTERVALS);
enter_system_variable ("program", program);
enter_system_variable ("version", version);
while (1)
{
int option_index = 0;
c = getopt_long (argc, argv, "D:f:ho:p:s:vVW:", long_options,
&option_index);
if (c == -1)
break;
switch (c)
{
case 'D':
vardef = (VariableDef *) xcalloc (1, sizeof (*vardef));
vardef->sym = (char *) xmalloc (strlen (optarg) + 1);
strcpy (vardef->sym, optarg);
vardef->val = strchr (vardef->sym, '=');
if (vardef->val == NULL)
{
fprintf (stderr, _("%s: malformed variable definition \"%s\"\n"),
program, vardef->sym);
exit (1);
}
*vardef->val = '\0';
vardef->val++;
if (vardefs)
vardefs_tail->next = vardef;
else
vardefs = vardef;
vardefs_tail = vardef;
break;
case 'f':
defs_file = optarg;
break;
case 'h':
usage ();
exit (0);
break;
case 'o':
ofp = fopen (optarg, "w");
if (ofp == NULL)
{
fprintf (stderr,
_("%s: couldn't create output file \"%s\": %s\n"),
program, optarg, strerror (errno));
exit (1);
}
break;
case 'p':
path = optarg;
break;
case 's':
start_state_arg = optarg;
break;
case 'v':
verbose++;
break;
case 'V':
printf ("%s\n", version);
exit (0);
break;
case 'W':
if (strcmp (optarg, "light") == 0)
warning_level = WARN_LIGHT;
else if (strcmp (optarg, "all") == 0)
warning_level = WARN_ALL;
else
{
fprintf (stderr,
_("%s: unknown warning level `%s'\n"),
program, optarg);
exit (1);
}
break;
case '?':
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program);
exit (1);
break;
default:
printf ("Hey! main() didn't handle option \"%c\" (%d)", c, c);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
abort ();
break;
}
}
{
Node *v, *n;
int i;
v = node_alloc (nARRAY);
v->u.array.allocated = argc - optind + 1;
v->u.array.len = argc - optind;
v->u.array.array = (Node **) xcalloc (v->u.array.allocated,
sizeof (Node *));
for (i = optind; i < argc; i++)
{
char *data;
n = node_alloc (nSTRING);
if (strcmp (argv[i], "-") == 0)
data = STDIN_NAME;
else
data = argv[i];
n->u.str.len = strlen (data);
n->u.str.data = xstrdup (data);
v->u.array.array[i - optind] = n;
}
if (!strhash_put (ns_vars, "argv", 4, v, (void **) &n))
{
fprintf (stderr, _("%s: out of memory\n"), program);
exit (1);
}
node_free (n);
}
if (path == NULL)
{
char *cp;
cp = strrchr (defs_file, '/');
if (cp)
{
path = xmalloc (cp - defs_file + 3);
sprintf (path, ".%c%.*s", PATH_SEPARATOR, cp - defs_file, defs_file);
}
else
path = ".";
}
load_states_file (defs_file);
for (vardef = vardefs; vardef; vardef = vardef->next)
{
Node *val;
Node *old_val;
val = node_alloc (nSTRING);
val->u.str.len = strlen (vardef->val);
val->u.str.data = xstrdup (vardef->val);
if (!strhash_put (ns_vars, vardef->sym, strlen (vardef->sym),
val, (void **) &old_val))
{
fprintf (stderr, _("%s: out of memory\n"), program);
exit (1);
}
node_free (old_val);
}
if (optind == argc)
{
ifp = stdin;
process_file (STDIN_NAME);
}
else
for (; optind < argc; optind++)
{
if (strcmp (argv[optind], "-") == 0)
{
ifp = stdin;
process_file (STDIN_NAME);
}
else
{
ifp = fopen (argv[optind], "r");
if (ifp == NULL)
{
fprintf (stderr, _("%s: couldn't open input file `%s': %s\n"),
program, argv[optind], strerror (errno));
exit (1);
}
process_file (argv[optind]);
fclose (ifp);
}
}
if (ofp != stdout)
fclose (ofp);
return 0;
}
static void
usage ()
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
Mandatory arguments to long options are mandatory for short options too.\n"),
program);
printf (_("\
-D, --define=VAR=VAL define variable VAR to have value VAR\n\
-f, --file=NAME read state definitions from file NAME\n\
-h, --help print this help and exit\n\
-o, --output=NAME save output to file NAME\n\
-p, --path=PATH set the load path to PATH\n\
-s, --state=NAME start from state NAME\n\
-v, --verbose increase the program verbosity\n\
-V, --version print version number\n\
-W, --warning=LEVEL set the warning level to LEVEL\n"));
}