1
/* main.c: The main program for bc. */
3
/* This file is part of GNU bc.
4
Copyright (C) 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License , or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; see the file COPYING. If not, write to
18
The Free Software Foundation, Inc.
19
59 Temple Place, Suite 330
22
You may contact the author by:
23
e-mail: philnelson@acm.org
24
us-mail: Philip A. Nelson
25
Computer Science Department, 9062
26
Western Washington University
27
Bellingham, WA 98226-9062
29
*************************************************************************/
38
/* Variables for processing multiple files. */
39
static char first_file;
41
/* Points to the last node in the file name list for easy adding. */
42
static file_node *last = NULL;
44
/* long option support */
45
static struct option long_options[] =
47
{"compile", 0, &compile_only, TRUE},
49
{"interactive", 0, 0, 'i'},
50
{"mathlib", 0, &use_math, TRUE},
51
{"quiet", 0, &quiet, TRUE},
52
{"standard", 0, &std_only, TRUE},
53
{"version", 0, 0, 'v'},
54
{"warn", 0, &warn_not_std, TRUE},
61
usage (char *progname)
63
printf ("usage: %s [options] [file ...]\n%s%s%s%s%s%s%s", progname,
64
" -h --help print this usage and exit\n",
65
" -i --interactive force interactive mode\n",
66
" -l --mathlib use the predefine math routnes\n",
67
" -q --quiet don't print initial banner\n",
68
" -s --standard non-standard bc constructs are errors\n",
69
" -w --warn warn about non-standard bc constructs\n",
70
" -v --version print version information and exit\n");
75
parse_args (argc, argv)
83
/* Force getopt to initialize. Depends on GNU getopt. */
86
/* Parse the command line */
89
optch = getopt_long (argc, argv, "chilqswv", long_options, &long_index);
91
if (optch == EOF) /* End of arguments. */
96
case 'c': /* compile only */
105
case 'i': /* force interactive */
109
case 'l': /* math lib */
113
case 'q': /* quiet mode */
117
case 's': /* Non standard features give errors. */
121
case 'v': /* Print the version. */
126
case 'w': /* Non standard features give warnings. */
136
/* Add file names to a list of files to process. */
137
while (optind < argc)
139
temp = (file_node *) bc_malloc(sizeof(file_node));
140
temp->name = argv[optind];
151
/* The main program for bc. */
161
/* Initialize many variables. */
162
compile_only = FALSE;
164
warn_not_std = FALSE;
166
if (isatty(0) && isatty(1))
174
/* attempt to simplify interaction with applications such as emacs */
175
(void) setvbuf(stdout, NULL, _IOLBF, 0);
178
/* Environment arguments. */
179
env_value = getenv ("BC_ENV_ARGS");
180
if (env_value != NULL)
183
env_argv[0] = "BC_ENV_ARGS";
184
while (*env_value != 0)
186
if (*env_value != ' ')
188
env_argv[env_argc++] = env_value;
189
while (*env_value != ' ' && *env_value != 0)
200
parse_args (env_argc, env_argv);
203
/* Command line arguments. */
204
parse_args (argc, argv);
206
/* Other environment processing. */
207
if (getenv ("POSIXLY_CORRECT") != NULL)
210
env_value = getenv ("BC_LINE_LENGTH");
211
if (env_value != NULL)
213
line_size = atoi (env_value);
220
/* Initialize the machine. */
224
/* Set up interrupts to print a message. */
226
signal (SIGINT, use_quit);
228
/* Initialize the front end. */
233
if (!open_new_file ())
238
/* Enable libedit support. */
239
edit = el_init ("bc", stdin, stdout, stderr);
240
hist = history_init();
241
el_set (edit, EL_EDITOR, "emacs");
242
el_set (edit, EL_HIST, history, hist);
243
el_set (edit, EL_PROMPT, null_prompt);
244
el_source (edit, NULL);
245
history (hist, &histev, H_SETSIZE, INT_MAX);
249
#if defined(READLINE)
251
/* Readline support. Set both application name and input file. */
252
rl_readline_name = "bc";
261
/* End the compile only output with a newline. */
269
/* This is the function that opens all the files.
270
It returns TRUE if the file was opened, otherwise
279
/* Set the line number. */
282
/* Check to see if we are done. */
283
if (is_std_in) return (FALSE);
285
/* Open the other files. */
286
if (use_math && first_file)
288
/* Load the code from a precompiled version of the math libarary. */
289
extern char *libmath[];
292
/* These MUST be in the order of first mention of each function.
293
That is why "a" comes before "c" even though "a" is defined after
294
after "c". "a" is used in "s"! */
295
tmp = lookup ("e", FUNCT);
296
tmp = lookup ("l", FUNCT);
297
tmp = lookup ("s", FUNCT);
298
tmp = lookup ("a", FUNCT);
299
tmp = lookup ("c", FUNCT);
300
tmp = lookup ("j", FUNCT);
308
/* One of the argv values. */
309
if (file_names != NULL)
311
new_file = fopen (file_names->name, "r");
312
if (new_file != NULL)
314
new_yy_file (new_file);
316
file_name = temp->name;
317
file_names = temp->next;
321
fprintf (stderr, "File %s is unavailable.\n", file_names->name);
325
/* If we fall through to here, we should return stdin. */
332
/* Set yyin to the new file. */
338
if (!first_file) fclose (yyin);
344
/* Message to use quit. */
350
printf ("\n(interrupt) use quit to exit.\n");
351
signal (SIGINT, use_quit);