3 * Copyright (c) 1997-2000 Markku Rossi.
5 * Author: Markku Rossi <mtr@iki.fi>
9 * This file is part of GNU enscript.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
31 * Types and definitions.
34 #define STDIN_NAME "(stdin)"
44 StringHashPtr ns_prims = NULL;
45 StringHashPtr ns_vars = NULL;
46 StringHashPtr ns_subs = NULL;
47 StringHashPtr ns_states = NULL;
50 * Global expressions which are evaluated after config file has been
53 List *global_stmts = NULL;
55 /* Statements from the start{} block. */
56 List *start_stmts = NULL;
58 /* Start and name rules. */
59 List *startrules = NULL;
60 List *namerules = NULL;
66 unsigned int data_in_buffer;
70 unsigned int current_linenum;
72 struct re_registers *current_match = NULL;
73 char *current_match_buf = NULL;
78 * -D VAR=VAL, --define=VAR=VAL
80 * Define variable VAR to have value VAL.
83 VariableDef *vardefs = NULL;
84 VariableDef *vardefs_tail = NULL;
87 * -f NAME, --file=NAME
89 * Read state definitions from file NAME. The default is "states.st" in
90 * the current working directory.
93 char *defs_file = "states.st";
94 unsigned int linenum = 1;
98 * -o FILE, --output=FILE
100 * Save output to file FILE, the default is stdout.
106 * -p PATH, --path=PATH
108 * Set the load path to PATH.
114 * -s NAME, --state=NAME
116 * Start from state NAME. As a default, start date is resolved during
117 * the program startup by using start, namerules and startrules rules.
119 char *start_state_arg = NULL;
125 * Increase the program verbosity.
127 unsigned int verbose = 0;
132 * Print the program version number.
136 * -W LEVEL, --warning=LEVEL
138 * Set the warning level to LEVEL.
140 WarningLevel warning_level = WARN_LIGHT;
147 static struct option long_options[] =
149 {"define", required_argument, 0, 'D'},
150 {"file", required_argument, 0, 'f'},
151 {"help", no_argument, 0, 'h'},
152 {"output", required_argument, 0, 'o'},
153 {"path", required_argument, 0, 'p'},
154 {"state", required_argument, 0, 's'},
155 {"verbose", no_argument, 0, 'v'},
156 {"version", no_argument, 0, 'V'},
157 {"warning", required_argument, 0, 'W'},
162 /* Version string. */
167 * Prototypes for static functions.
170 static void usage ___P ((void));
185 /* Set defaults for options. */
188 /* Get program's name. */
189 program = strrchr (argv[0], '/');
195 /* Make getopt_long() to use our modified program name. */
198 /* Format version string. */
199 sprintf (version, _("states for GNU %s %s"), PACKAGE, VERSION);
201 /* Internationalization. */
204 setlocale (LC_MESSAGES, "");
208 bindtextdomain (PACKAGE, LOCALEDIR);
209 textdomain (PACKAGE);
212 /* Init namespaces. */
213 ns_prims = strhash_init ();
214 ns_vars = strhash_init ();
215 ns_subs = strhash_init ();
216 ns_states = strhash_init ();
218 global_stmts = list ();
219 start_stmts = list ();
220 startrules = list ();
223 nvoid = node_alloc (nVOID);
224 inbuf = (char *) xmalloc (INBUFSIZE);
228 re_set_syntax (RE_SYNTAX_GNU_AWK | RE_INTERVALS);
230 /* Enter some system variables. */
231 enter_system_variable ("program", program);
232 enter_system_variable ("version", version);
234 /* Parse arguments. */
237 int option_index = 0;
239 c = getopt_long (argc, argv, "D:f:ho:p:s:vVW:", long_options,
246 case 'D': /* define variable */
247 vardef = (VariableDef *) xcalloc (1, sizeof (*vardef));
248 vardef->sym = (char *) xmalloc (strlen (optarg) + 1);
249 strcpy (vardef->sym, optarg);
251 vardef->val = strchr (vardef->sym, '=');
252 if (vardef->val == NULL)
254 fprintf (stderr, _("%s: malformed variable definition \"%s\"\n"),
255 program, vardef->sym);
262 vardefs_tail->next = vardef;
265 vardefs_tail = vardef;
268 case 'f': /* definitions file */
277 case 'o': /* output file */
278 ofp = fopen (optarg, "w");
282 _("%s: couldn't create output file \"%s\": %s\n"),
283 program, optarg, strerror (errno));
292 case 's': /* start state */
293 start_state_arg = optarg;
296 case 'v': /* verbose */
300 case 'V': /* version */
301 printf ("%s\n", version);
305 case 'W': /* warning level */
306 if (strcmp (optarg, "light") == 0)
307 warning_level = WARN_LIGHT;
308 else if (strcmp (optarg, "all") == 0)
309 warning_level = WARN_ALL;
313 _("%s: unknown warning level `%s'\n"),
319 case '?': /* Errors found during getopt_long(). */
320 fprintf (stderr, _("Try `%s --help' for more information.\n"),
326 printf ("Hey! main() didn't handle option \"%c\" (%d)", c, c);
328 printf (" with arg %s", optarg);
335 /* Pass all remaining arguments to States through `argv' array. */
340 v = node_alloc (nARRAY);
341 v->u.array.allocated = argc - optind + 1;
342 v->u.array.len = argc - optind;
343 v->u.array.array = (Node **) xcalloc (v->u.array.allocated,
345 for (i = optind; i < argc; i++)
349 n = node_alloc (nSTRING);
350 if (strcmp (argv[i], "-") == 0)
355 n->u.str.len = strlen (data);
356 n->u.str.data = xstrdup (data);
357 v->u.array.array[i - optind] = n;
360 if (!strhash_put (ns_vars, "argv", 4, v, (void **) &n))
362 fprintf (stderr, _("%s: out of memory\n"), program);
368 /* Set some defaults if the user didn't give them. */
372 cp = strrchr (defs_file, '/');
375 path = xmalloc (cp - defs_file + 3);
376 sprintf (path, ".%c%.*s", PATH_SEPARATOR, cp - defs_file, defs_file);
382 /* Parse config file. */
383 load_states_file (defs_file);
385 /* Define variables given at the command line. */
386 for (vardef = vardefs; vardef; vardef = vardef->next)
391 val = node_alloc (nSTRING);
392 val->u.str.len = strlen (vardef->val);
393 val->u.str.data = xstrdup (vardef->val);
395 if (!strhash_put (ns_vars, vardef->sym, strlen (vardef->sym),
396 val, (void **) &old_val))
398 fprintf (stderr, _("%s: out of memory\n"), program);
408 process_file (STDIN_NAME);
411 for (; optind < argc; optind++)
413 if (strcmp (argv[optind], "-") == 0)
416 process_file (STDIN_NAME);
420 ifp = fopen (argv[optind], "r");
423 fprintf (stderr, _("%s: couldn't open input file `%s': %s\n"),
424 program, argv[optind], strerror (errno));
427 process_file (argv[optind]);
432 /* Close output file. */
448 Usage: %s [OPTION]... [FILE]...\n\
449 Mandatory arguments to long options are mandatory for short options too.\n"),
452 -D, --define=VAR=VAL define variable VAR to have value VAR\n\
453 -f, --file=NAME read state definitions from file NAME\n\
454 -h, --help print this help and exit\n\
455 -o, --output=NAME save output to file NAME\n\
456 -p, --path=PATH set the load path to PATH\n\
457 -s, --state=NAME start from state NAME\n\
458 -v, --verbose increase the program verbosity\n\
459 -V, --version print version number\n\
460 -W, --warning=LEVEL set the warning level to LEVEL\n"));