xref: /386bsd/usr/src/usr.bin/bc/main.c (revision a2142627)
1 /* main.c: The main program for bc.  */
2 
3 /*  This file is part of bc written for MINIX.
4     Copyright (C) 1991, 1992 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 
34 /* Variables for processing multiple files. */
35 char   first_file;
36 extern FILE *yyin;
37 
38 
39 /* The main program for bc. */
40 int
main(argc,argv)41 main (argc, argv)
42      int argc;
43      char *argv[];
44 {
45   int  ch;
46 
47   /* Initialize many variables. */
48   compile_only = FALSE;
49   use_math = FALSE;
50   warn_not_std = FALSE;
51   std_only = FALSE;
52   if (isatty(0) && isatty(1))
53     interactive = TRUE;
54   else
55     interactive = FALSE;
56 
57   /* Parse the command line */
58   ch = getopt (argc, argv, "lcisvw");
59   while (ch != EOF)
60     {
61       switch (ch)
62 	{
63 	case 'c':  /* compile only */
64 	  compile_only = TRUE;
65 	  break;
66 	case 'l':  /* math lib */
67 	  use_math = TRUE;
68 	  break;
69 	case 'i':  /* force interactive */
70 	  interactive = TRUE;
71 	  break;
72 	case 'w':  /* Non standard features give warnings. */
73 	  warn_not_std = TRUE;
74 	  break;
75 	case 's':  /* Non standard features give errors. */
76 	  std_only = TRUE;
77 	  break;
78 	case 'v':  /* Print the version. */
79 	  printf ("%s\n", BC_VERSION);
80 	  break;
81 	}
82       ch = getopt (argc, argv, "lcisvw");
83     }
84 
85   /* Initialize the machine.  */
86   init_storage();
87   init_load();
88 
89   /* Set up interrupts to print a message. */
90   if (interactive)
91     signal (SIGINT, use_quit);
92 
93   /* Initialize the front end. */
94   init_tree();
95   init_gen ();
96   g_argv = argv;
97   g_argc = argc;
98   is_std_in = FALSE;
99   first_file = TRUE;
100   if (!open_new_file ())
101     exit (1);
102 
103   /* Do the parse. */
104   yyparse ();
105 
106   /* End the compile only output with a newline. */
107   if (compile_only)
108     printf ("\n");
109 
110   exit (0);
111 }
112 
113 
114 /* This is the function that opens all the files.
115    It returns TRUE if the file was opened, otherwise
116    it returns FALSE. */
117 
118 int
open_new_file()119 open_new_file ()
120 {
121   FILE *new_file;
122 
123   /* Set the line number. */
124   line_no = 1;
125 
126   /* Check to see if we are done. */
127   if (is_std_in) return (FALSE);
128 
129   /* Open the other files. */
130   if (use_math && first_file)
131     {
132 #ifdef BC_MATH_FILE
133       /* Make the first file be the math library. */
134       new_file = fopen (BC_MATH_FILE, "r");
135       use_math = FALSE;
136       if (new_file != NULL)
137 	{
138 	  new_yy_file (new_file);
139 	  return TRUE;
140 	}
141       else
142 	{
143 	  fprintf (stderr, "Math Library unavailable.\n");
144 	  exit (1);
145 	}
146 #else
147       /* Load the code from a precompiled version of the math libarary. */
148       extern char libmath[];
149       char tmp;
150       /* These MUST be in the order of first mention of each function.
151 	 That is why "a" comes before "c" even though "a" is defined after
152 	 after "c".  "a" is used in "s"! */
153       tmp = lookup ("e", FUNCT);
154       tmp = lookup ("l", FUNCT);
155       tmp = lookup ("s", FUNCT);
156       tmp = lookup ("a", FUNCT);
157       tmp = lookup ("c", FUNCT);
158       tmp = lookup ("j", FUNCT);
159       load_code (libmath);
160 #endif
161     }
162 
163   /* One of the argv values. */
164   while (optind < g_argc)
165     {
166       new_file = fopen (g_argv[optind], "r");
167       if (new_file != NULL)
168 	{
169 	  new_yy_file (new_file);
170 	  optind++;
171 	  return TRUE;
172 	}
173       fprintf (stderr, "File %s is unavailable.\n", g_argv[optind++]);
174       exit (1);
175     }
176 
177   /* If we fall through to here, we should return stdin. */
178   new_yy_file (stdin);
179   is_std_in = TRUE;
180   return TRUE;
181 }
182 
183 
184 /* Set yyin to the new file. */
185 
186 void
new_yy_file(file)187 new_yy_file (file)
188      FILE *file;
189 {
190   if (!first_file) fclose (yyin);
191   yyin = file;
192   first_file = FALSE;
193 }
194 
195 
196 /* Message to use quit.  */
197 
198 void
use_quit(sig)199 use_quit (sig)
200      int sig;
201 {
202   printf ("\n(interrupt) use quit to exit.\n");
203   signal (SIGINT, use_quit);
204 }
205