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 $FreeBSD: src/contrib/bc/bc/main.c,v 1.4.2.1 2001/03/04 09:34:54 kris Exp $
30 $DragonFly: src/contrib/bc/bc/Attic/main.c,v 1.2 2003/06/17 04:23:58 dillon Exp $
32 *************************************************************************/
41 /* Variables for processing multiple files. */
42 static char first_file;
44 /* Points to the last node in the file name list for easy adding. */
45 static file_node *last = NULL;
47 /* long option support */
48 static struct option long_options[] =
50 {"compile", 0, &compile_only, TRUE},
52 {"interactive", 0, 0, 'i'},
53 {"mathlib", 0, &use_math, TRUE},
54 {"quiet", 0, &quiet, TRUE},
55 {"standard", 0, &std_only, TRUE},
56 {"version", 0, 0, 'v'},
57 {"warn", 0, &warn_not_std, TRUE},
64 usage (char *progname)
66 printf ("usage: %s [options] [file ...]\n%s%s%s%s%s%s%s", progname,
67 " -h --help print this usage and exit\n",
68 " -i --interactive force interactive mode\n",
69 " -l --mathlib use the predefine math routnes\n",
70 " -q --quiet don't print initial banner\n",
71 " -s --standard non-standard bc constructs are errors\n",
72 " -w --warn warn about non-standard bc constructs\n",
73 " -v --version print version information and exit\n");
78 parse_args (argc, argv)
86 /* Force getopt to initialize. Depends on GNU getopt. */
89 /* Parse the command line */
92 optch = getopt_long (argc, argv, "chilqswv", long_options, &long_index);
94 if (optch == EOF) /* End of arguments. */
99 case 'c': /* compile only */
108 case 'i': /* force interactive */
112 case 'l': /* math lib */
116 case 'q': /* quiet mode */
120 case 's': /* Non standard features give errors. */
124 case 'v': /* Print the version. */
129 case 'w': /* Non standard features give warnings. */
139 /* Add file names to a list of files to process. */
140 while (optind < argc)
142 temp = (file_node *) bc_malloc(sizeof(file_node));
143 temp->name = argv[optind];
154 /* The main program for bc. */
164 /* Initialize many variables. */
165 compile_only = FALSE;
167 warn_not_std = FALSE;
169 if (isatty(0) && isatty(1))
177 /* attempt to simplify interaction with applications such as emacs */
178 (void) setvbuf(stdout, NULL, _IOLBF, 0);
181 /* Environment arguments. */
182 env_value = getenv ("BC_ENV_ARGS");
183 if (env_value != NULL)
186 env_argv[0] = "BC_ENV_ARGS";
187 while (*env_value != 0)
189 if (*env_value != ' ')
191 env_argv[env_argc++] = env_value;
192 while (*env_value != ' ' && *env_value != 0)
203 parse_args (env_argc, env_argv);
206 /* Command line arguments. */
207 parse_args (argc, argv);
209 /* Other environment processing. */
210 if (getenv ("POSIXLY_CORRECT") != NULL)
213 env_value = getenv ("BC_LINE_LENGTH");
214 if (env_value != NULL)
216 line_size = atoi (env_value);
223 /* Initialize the machine. */
227 /* Set up interrupts to print a message. */
229 signal (SIGINT, use_quit);
231 /* Initialize the front end. */
236 if (!open_new_file ())
241 /* Enable libedit support. */
242 edit = el_init ("bc", stdin, stdout, stderr);
243 hist = history_init();
244 el_set (edit, EL_EDITOR, "emacs");
245 el_set (edit, EL_HIST, history, hist);
246 el_set (edit, EL_PROMPT, null_prompt);
247 el_source (edit, NULL);
248 history (hist, &histev, H_SETSIZE, INT_MAX);
252 #if defined(READLINE)
254 /* Readline support. Set both application name and input file. */
255 rl_readline_name = "bc";
264 /* End the compile only output with a newline. */
272 /* This is the function that opens all the files.
273 It returns TRUE if the file was opened, otherwise
282 /* Set the line number. */
285 /* Check to see if we are done. */
286 if (is_std_in) return (FALSE);
288 /* Open the other files. */
289 if (use_math && first_file)
291 /* Load the code from a precompiled version of the math libarary. */
292 extern char *libmath[];
295 /* These MUST be in the order of first mention of each function.
296 That is why "a" comes before "c" even though "a" is defined after
297 after "c". "a" is used in "s"! */
298 tmp = lookup ("e", FUNCT);
299 tmp = lookup ("l", FUNCT);
300 tmp = lookup ("s", FUNCT);
301 tmp = lookup ("a", FUNCT);
302 tmp = lookup ("c", FUNCT);
303 tmp = lookup ("j", FUNCT);
311 /* One of the argv values. */
312 if (file_names != NULL)
314 new_file = fopen (file_names->name, "r");
315 if (new_file != NULL)
317 new_yy_file (new_file);
319 file_name = temp->name;
320 file_names = temp->next;
324 fprintf (stderr, "File %s is unavailable.\n", file_names->name);
328 /* If we fall through to here, we should return stdin. */
335 /* Set yyin to the new file. */
341 if (!first_file) fclose (yyin);
347 /* Message to use quit. */
353 printf ("\n(interrupt) use quit to exit.\n");
354 signal (SIGINT, use_quit);