3 * Copyright (c) 1997-2000 Markku Rossi.
5 * Author: Markku Rossi <mtr@iki.fi>
9 * This file is part of GNU Enscript.
11 * Enscript 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 3 of the License, or
14 * (at your option) any later version.
16 * Enscript 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 Enscript. If not, see <http://www.gnu.org/licenses/>.
29 * Types and definitions.
32 #define STDIN_NAME "(stdin)"
42 StringHashPtr ns_prims = NULL;
43 StringHashPtr ns_vars = NULL;
44 StringHashPtr ns_subs = NULL;
45 StringHashPtr ns_states = NULL;
48 * Global expressions which are evaluated after config file has been
51 List *global_stmts = NULL;
53 /* Statements from the start{} block. */
54 List *start_stmts = NULL;
56 /* Start and name rules. */
57 List *startrules = NULL;
58 List *namerules = NULL;
64 unsigned int data_in_buffer;
68 unsigned int current_linenum;
70 struct re_registers *current_match = NULL;
71 char *current_match_buf = NULL;
76 * -D VAR=VAL, --define=VAR=VAL
78 * Define variable VAR to have value VAL.
81 VariableDef *vardefs = NULL;
82 VariableDef *vardefs_tail = NULL;
85 * -f NAME, --file=NAME
87 * Read state definitions from file NAME. The default is "states.st" in
88 * the current working directory.
91 char *defs_file = "states.st";
92 unsigned int linenum = 1;
96 * -o FILE, --output=FILE
98 * Save output to file FILE, the default is stdout.
104 * -p PATH, --path=PATH
106 * Set the load path to PATH.
112 * -s NAME, --state=NAME
114 * Start from state NAME. As a default, start date is resolved during
115 * the program startup by using start, namerules and startrules rules.
117 char *start_state_arg = NULL;
123 * Increase the program verbosity.
125 unsigned int verbose = 0;
130 * Print the program version number.
134 * -W LEVEL, --warning=LEVEL
136 * Set the warning level to LEVEL.
138 WarningLevel warning_level = WARN_LIGHT;
145 static struct option long_options[] =
147 {"define", required_argument, 0, 'D'},
148 {"file", required_argument, 0, 'f'},
149 {"help", no_argument, 0, 'h'},
150 {"output", required_argument, 0, 'o'},
151 {"path", required_argument, 0, 'p'},
152 {"state", required_argument, 0, 's'},
153 {"verbose", no_argument, 0, 'v'},
154 {"version", no_argument, 0, 'V'},
155 {"warning", required_argument, 0, 'W'},
160 /* Version string. */
165 * Prototypes for static functions.
168 static void usage ___P ((void));
183 /* Set defaults for options. */
186 /* Get program's name. */
187 program = strrchr (argv[0], '/');
193 /* Make getopt_long() to use our modified program name. */
196 /* Format version string. */
197 sprintf (version, _("states for %s"), PACKAGE_STRING);
199 /* Internationalization. */
202 setlocale (LC_MESSAGES, "");
206 bindtextdomain (PACKAGE, LOCALEDIR);
207 textdomain (PACKAGE);
210 /* Init namespaces. */
211 ns_prims = strhash_init ();
212 ns_vars = strhash_init ();
213 ns_subs = strhash_init ();
214 ns_states = strhash_init ();
216 global_stmts = list ();
217 start_stmts = list ();
218 startrules = list ();
221 nvoid = node_alloc (nVOID);
222 inbuf = (char *) xmalloc (INBUFSIZE);
226 re_set_syntax (RE_SYNTAX_GNU_AWK | RE_INTERVALS);
228 /* Enter some system variables. */
229 enter_system_variable ("program", program);
230 enter_system_variable ("version", version);
232 /* Parse arguments. */
235 int option_index = 0;
237 c = getopt_long (argc, argv, "D:f:ho:p:s:vVW:", long_options,
244 case 'D': /* define variable */
245 vardef = (VariableDef *) xcalloc (1, sizeof (*vardef));
246 vardef->sym = (char *) xmalloc (strlen (optarg) + 1);
247 strcpy (vardef->sym, optarg);
249 vardef->val = strchr (vardef->sym, '=');
250 if (vardef->val == NULL)
252 fprintf (stderr, _("%s: malformed variable definition \"%s\"\n"),
253 program, vardef->sym);
260 vardefs_tail->next = vardef;
263 vardefs_tail = vardef;
266 case 'f': /* definitions file */
275 case 'o': /* output file */
276 ofp = fopen (optarg, "w");
280 _("%s: couldn't create output file \"%s\": %s\n"),
281 program, optarg, strerror (errno));
290 case 's': /* start state */
291 start_state_arg = optarg;
294 case 'v': /* verbose */
298 case 'V': /* version */
299 printf ("%s\n", version);
303 case 'W': /* warning level */
304 if (strcmp (optarg, "light") == 0)
305 warning_level = WARN_LIGHT;
306 else if (strcmp (optarg, "all") == 0)
307 warning_level = WARN_ALL;
311 _("%s: unknown warning level `%s'\n"),
317 case '?': /* Errors found during getopt_long(). */
318 fprintf (stderr, _("Try `%s --help' for more information.\n"),
324 printf ("Hey! main() didn't handle option \"%c\" (%d)", c, c);
326 printf (" with arg %s", optarg);
333 /* Pass all remaining arguments to States through `argv' array. */
338 v = node_alloc (nARRAY);
339 v->u.array.allocated = argc - optind + 1;
340 v->u.array.len = argc - optind;
341 v->u.array.array = (Node **) xcalloc (v->u.array.allocated,
343 for (i = optind; i < argc; i++)
347 n = node_alloc (nSTRING);
348 if (strcmp (argv[i], "-") == 0)
353 n->u.str.len = strlen (data);
354 n->u.str.data = xstrdup (data);
355 v->u.array.array[i - optind] = n;
358 if (!strhash_put (ns_vars, "argv", 4, v, (void **) &n))
360 fprintf (stderr, _("%s: out of memory\n"), program);
366 /* Set some defaults if the user didn't give them. */
370 cp = strrchr (defs_file, '/');
373 path = xmalloc (cp - defs_file + 3);
374 sprintf (path, ".%c%.*s", PATH_SEPARATOR, cp - defs_file, defs_file);
380 /* Parse config file. */
381 load_states_file (defs_file);
383 /* Define variables given at the command line. */
384 for (vardef = vardefs; vardef; vardef = vardef->next)
389 val = node_alloc (nSTRING);
390 val->u.str.len = strlen (vardef->val);
391 val->u.str.data = xstrdup (vardef->val);
393 if (!strhash_put (ns_vars, vardef->sym, strlen (vardef->sym),
394 val, (void **) &old_val))
396 fprintf (stderr, _("%s: out of memory\n"), program);
406 process_file (STDIN_NAME);
409 for (; optind < argc; optind++)
411 if (strcmp (argv[optind], "-") == 0)
414 process_file (STDIN_NAME);
418 ifp = fopen (argv[optind], "r");
421 fprintf (stderr, _("%s: couldn't open input file `%s': %s\n"),
422 program, argv[optind], strerror (errno));
425 process_file (argv[optind]);
430 /* Close output file. */
446 Usage: %s [OPTION]... [FILE]...\n\
447 Mandatory arguments to long options are mandatory for short options too.\n"),
450 -D, --define=VAR=VAL define variable VAR to have value VAL\n\
451 -f, --file=NAME read state definitions from file NAME\n\
452 -h, --help print this help and exit\n\
453 -o, --output=NAME save output to file NAME\n\
454 -p, --path=PATH set the load path to PATH\n\
455 -s, --state=NAME start from state NAME\n\
456 -v, --verbose increase the program verbosity\n\
457 -V, --version print version number\n\
458 -W, --warning=LEVEL set the warning level to LEVEL\n"));