5761885 [rkeene@sledge /home/rkeene/devel/old/bc-dos/bc]$ cat -n main.c
  1 /* main.c: The main program for bc.  */
  2 
  3 /*  This file is part of GNU bc.
  4     Copyright (C) 1991, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
  5 
  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.
 10 
 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.
 15 
 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, 675 Mass Ave, Cambridge, MA 02139, USA.
 19 
 20     You may contact the author by:
 21        e-mail:  phil@cs.wwu.edu
 22       us-mail:  Philip A. Nelson
 23                 Computer Science Department, 9062
 24                 Western Washington University
 25                 Bellingham, WA 98226-9062
 26        
 27 *************************************************************************/
 28 
 29 #include "bcdefs.h"
 30 #include <signal.h>
 31 #include "global.h"
 32 #include "proto.h"
 33 #include "getopt.h"
 34 
 35 
 36 /* Variables for processing multiple files. */
 37 char   first_file;
 38 extern FILE *yyin;
 39 
 40 /* Points to the last node in the file name list for easy adding. */
 41 static file_node *last = NULL;
 42 
 43 #ifdef READLINE
 44 /* Readline support. */
 45 extern char *rl_readline_name;
 46 extern FILE *rl_instream;
 47 #endif
 48 
 49 /* long option support */
 50 static struct option long_options[] =
 51 {
 52   {"compile",  0, &compile_only, TRUE},
 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},
 58 
 59   {0, 0, 0, 0}
 60 };
 61 
 62 
 63 void
 64 parse_args (argc, argv)
 65      int argc;
 66      char **argv;
 67 {
 68   int optch;
 69   int long_index;
 70   file_node *temp;
 71 
 72   /* Force getopt to initialize.  Depends on GNU getopt. */
 73   optind = 0;
 74 
 75   /* Parse the command line */
 76   while (1)
 77     {
 78       optch = getopt_long (argc, argv, "lciqsvw", long_options, &long_index);
 79 
 80       if (optch == EOF)  /* End of arguments. */
 81     break;
 82 
 83       switch (optch)
 84     {
 85     case 'c':  /* compile only */
 86       compile_only = TRUE;
 87       break;
 88 
 89     case 'l':  /* math lib */
 90       use_math = TRUE;
 91       break;
 92 
 93     case 'i':  /* force interactive */
 94       interactive = TRUE;
 95       break;
 96 
 97     case 'q':  /* quiet mode */
 98       quiet = TRUE;
 99       break;
100 
101     case 's':  /* Non standard features give errors. */
102       std_only = TRUE;
103       break;
104 
105     case 'v':  /* Print the version. */
106       printf ("%s\n", BC_VERSION);
107       exit (0);
108       break;
109 
110     case 'w':  /* Non standard features give warnings. */
111       warn_not_std = TRUE;
112       break;
113     }
114     }
115 
116   /* Add file names to a list of files to process. */
117   while (optind < argc)
118     {
119       temp = (file_node *) bc_malloc(sizeof(file_node));
120       temp->name = argv[optind];
121       temp->next = NULL;
122       if (last == NULL)
123     file_names = temp;
124       else
125     last->next = temp;
126       last = temp;
127       optind++;
128     }
129 }
130 
131 /* The main program for bc. */
132 int
133 main (argc, argv)
134      int argc;
135      char *argv[];
136 {
137   char *env_value;
138   char *env_argv[30];
139   int   env_argc;
140   
141   /* Initialize many variables. */
142   compile_only = FALSE;
143   use_math = FALSE;
144   warn_not_std = FALSE;
145   std_only = FALSE;
146   if (isatty(0) && isatty(1)) 
147     interactive = TRUE;
148   else
149     interactive = FALSE;
150   quiet = FALSE;
151   file_names = NULL;
152 
153 #ifdef HAVE_SETVBUF
154   /* attempt to simplify interaction with applications such as emacs */
155   (void) setvbuf(stdout, NULL, _IOLBF, 0);
156 #endif
157 
158   /* Environment arguments. */
159   env_value = getenv ("BC_ENV_ARGS");
160   if (env_value != NULL)
161     {
162       env_argc = 1;
163       env_argv[0] = "BC_ENV_ARGS";
164       while (*env_value != 0)
165     {
166       if (*env_value != ' ')
167         {
168           env_argv[env_argc++] = env_value;
169           while (*env_value != ' ' && *env_value != 0)
170         env_value++;
171           if (*env_value != 0)
172         {
173           *env_value = 0;
174           env_value++;
175         }
176         }
177       else
178         env_value++;
179     }
180       parse_args (env_argc, env_argv);
181     }
182 
183   /* Command line arguments. */
184   parse_args (argc, argv);
185 
186   /* Other environment processing. */
187   if (getenv ("POSIXLY_CORRECT") != NULL)
188     std_only = TRUE;
189 
190   env_value = getenv ("BC_LINE_LENGTH");
191   if (env_value != NULL)
192     {
193       line_size = atoi (env_value);
194       if (line_size < 2)
195     line_size = 70;
196     }
197   else
198     line_size = 70;
199 
200   /* Initialize the machine.  */
201   init_storage();
202   init_load();
203 
204   /* Set up interrupts to print a message. */
205   if (interactive)
206     signal (SIGINT, use_quit);
207 
208   /* Initialize the front end. */
209   init_tree();
210   init_gen ();
211   is_std_in = FALSE;
212   first_file = TRUE;
213   if (!open_new_file ())
214     exit (1);
215 
216 #ifdef READLINE
217   if (interactive) {
218     /* Readline support.  Set both application name and input file. */
219     rl_readline_name = "bc";
220     rl_instream = stdin;
221     using_history ();
222   }
223 #endif
224 
225   /* Do the parse. */
226   yyparse ();
227 
228   /* End the compile only output with a newline. */
229   if (compile_only)
230     printf ("\n");
231 
232   exit (0);
233 }
234 
235 
236 /* This is the function that opens all the files. 
237    It returns TRUE if the file was opened, otherwise
238    it returns FALSE. */
239 
240 int
241 open_new_file ()
242 {
243   FILE *new_file;
244   file_node *temp;
245 
246   /* Set the line number. */
247   line_no = 1;
248 
249   /* Check to see if we are done. */
250   if (is_std_in) return (FALSE);
251 
252   /* Open the other files. */
253   if (use_math && first_file)
254     {
255 #ifdef BC_MATH_FILE
256       /* Make the first file be the math library. */
257       new_file = fopen (BC_MATH_FILE, "r");
258       use_math = FALSE;
259       if (new_file != NULL)
260     {
261       new_yy_file (new_file);
262       return TRUE;
263     }   
264       else
265     {
266       fprintf (stderr, "Math Library unavailable.\n");
267       exit (1);
268     }
269 #else
270       /* Load the code from a precompiled version of the math libarary. */
271       extern char libmath[];
272       char tmp;
273       /* These MUST be in the order of first mention of each function.
274      That is why "a" comes before "c" even though "a" is defined after
275      after "c".  "a" is used in "s"! */
276       tmp = lookup ("e", FUNCT);
277       tmp = lookup ("l", FUNCT);
278       tmp = lookup ("s", FUNCT);
279       tmp = lookup ("a", FUNCT);
280       tmp = lookup ("c", FUNCT);
281       tmp = lookup ("j", FUNCT);
282       load_code (libmath);
283 #endif
284     }
285   
286   /* One of the argv values. */
287   if (file_names != NULL)
288     {
289       new_file = fopen (file_names->name, "r");
290       if (new_file != NULL)
291     {
292       new_yy_file (new_file);
293       temp = file_names;
294       file_name  = temp->name;
295       file_names = temp->next;
296       free (temp);
297       return TRUE;
298     }
299       fprintf (stderr, "File %s is unavailable.\n", file_names->name);
300       exit (1);
301     }
302   
303   /* If we fall through to here, we should return stdin. */
304   new_yy_file (stdin);
305   is_std_in = TRUE;
306   return TRUE;
307 }
308 
309 
310 /* Set yyin to the new file. */
311 
312 void
313 new_yy_file (file)
314      FILE *file;
315 {
316   if (!first_file) fclose (yyin);
317   yyin = file;
318   first_file = FALSE;
319 }
320 
321 
322 /* Message to use quit.  */
323 
324 void
325 use_quit (sig)
326      int sig;
327 {
328   printf ("\n(interrupt) use quit to exit.\n");
329   signal (SIGINT, use_quit);
330 }
5761886 [rkeene@sledge /home/rkeene/devel/old/bc-dos/bc]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 1998-04-17 17:39:14