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));
182 int option_index = 0;
184 /* Set defaults for options. */
187 /* Get program's name. */
188 program = strrchr (argv[0], '/');
194 /* Make getopt_long() to use our modified program name. */
197 /* Format version string. */
198 sprintf (version, _("states for %s"), PACKAGE_STRING);
200 /* Internationalization. */
203 setlocale (LC_MESSAGES, "");
207 bindtextdomain (PACKAGE, LOCALEDIR);
208 textdomain (PACKAGE);
211 /* Init namespaces. */
212 ns_prims = strhash_init ();
213 ns_vars = strhash_init ();
214 ns_subs = strhash_init ();
215 ns_states = strhash_init ();
217 global_stmts = list ();
218 start_stmts = list ();
219 startrules = list ();
222 nvoid = node_alloc (nVOID);
223 inbuf = (char *) xmalloc (INBUFSIZE);
227 re_set_syntax (RE_SYNTAX_GNU_AWK | RE_INTERVALS);
229 /* Enter some system variables. */
230 enter_system_variable ("program", program);
231 enter_system_variable ("version", version);
233 /* Parse arguments. */
234 while ((c = getopt_long (argc, argv, "D:f:ho:p:s:vVW:", long_options,
235 &option_index)) != -1) {
238 case 'D': /* define variable */
239 vardef = (VariableDef *) xcalloc (1, sizeof (*vardef));
240 vardef->sym = (char *) xmalloc (strlen (optarg) + 1);
241 strcpy (vardef->sym, optarg);
243 vardef->val = strchr (vardef->sym, '=');
244 if (vardef->val == NULL)
246 fprintf (stderr, _("%s: malformed variable definition \"%s\"\n"),
247 program, vardef->sym);
254 vardefs_tail->next = vardef;
257 vardefs_tail = vardef;
260 case 'f': /* definitions file */
269 case 'o': /* output file */
270 ofp = fopen (optarg, "w");
274 _("%s: couldn't create output file \"%s\": %s\n"),
275 program, optarg, strerror (errno));
284 case 's': /* start state */
285 start_state_arg = optarg;
288 case 'v': /* verbose */
292 case 'V': /* version */
293 printf ("%s\n", version);
297 case 'W': /* warning level */
298 if (strcmp (optarg, "light") == 0)
299 warning_level = WARN_LIGHT;
300 else if (strcmp (optarg, "all") == 0)
301 warning_level = WARN_ALL;
305 _("%s: unknown warning level `%s'\n"),
311 case '?': /* Errors found during getopt_long(). */
312 fprintf (stderr, _("Try `%s --help' for more information.\n"),
318 printf ("Hey! main() didn't handle option \"%c\" (%d)", c, c);
320 printf (" with arg %s", optarg);
327 /* Pass all remaining arguments to States through `argv' array. */
332 v = node_alloc (nARRAY);
333 v->u.array.allocated = argc - optind + 1;
334 v->u.array.len = argc - optind;
335 v->u.array.array = (Node **) xcalloc (v->u.array.allocated,
337 for (i = optind; i < argc; i++)
341 n = node_alloc (nSTRING);
342 if (strcmp (argv[i], "-") == 0)
347 n->u.str.len = strlen (data);
348 n->u.str.data = xstrdup (data);
349 v->u.array.array[i - optind] = n;
352 if (!strhash_put (ns_vars, "argv", 4, v, (void **) &n))
354 fprintf (stderr, _("%s: out of memory\n"), program);
360 /* Set some defaults if the user didn't give them. */
364 cp = strrchr (defs_file, '/');
367 path = xmalloc (cp - defs_file + 3);
368 sprintf (path, ".%c%.*s", PATH_SEPARATOR, cp - defs_file, defs_file);
374 /* Parse config file. */
375 load_states_file (defs_file);
377 /* Define variables given at the command line. */
378 for (vardef = vardefs; vardef; vardef = vardef->next)
383 val = node_alloc (nSTRING);
384 val->u.str.len = strlen (vardef->val);
385 val->u.str.data = xstrdup (vardef->val);
387 if (!strhash_put (ns_vars, vardef->sym, strlen (vardef->sym),
388 val, (void **) &old_val))
390 fprintf (stderr, _("%s: out of memory\n"), program);
400 process_file (STDIN_NAME);
403 for (; optind < argc; optind++)
405 if (strcmp (argv[optind], "-") == 0)
408 process_file (STDIN_NAME);
412 ifp = fopen (argv[optind], "r");
415 fprintf (stderr, _("%s: couldn't open input file `%s': %s\n"),
416 program, argv[optind], strerror (errno));
419 process_file (argv[optind]);
424 /* Close output file. */
440 Usage: %s [OPTION]... [FILE]...\n\
441 Mandatory arguments to long options are mandatory for short options too.\n"),
444 -D, --define=VAR=VAL define variable VAR to have value VAR\n\
445 -f, --file=NAME read state definitions from file NAME\n\
446 -h, --help print this help and exit\n\
447 -o, --output=NAME save output to file NAME\n\
448 -p, --path=PATH set the load path to PATH\n\
449 -s, --state=NAME start from state NAME\n\
450 -v, --verbose increase the program verbosity\n\
451 -V, --version print version number\n\
452 -W, --warning=LEVEL set the warning level to LEVEL\n"));