#include "bcdefs.h"
#include <signal.h>
#include "global.h"
#include "proto.h"
#include "getopt.h"
static char first_file;
static file_node *last = NULL;
static struct option long_options[] =
{
{"compile", 0, &compile_only, TRUE},
{"help", 0, 0, 'h'},
{"interactive", 0, 0, 'i'},
{"mathlib", 0, &use_math, TRUE},
{"quiet", 0, &quiet, TRUE},
{"standard", 0, &std_only, TRUE},
{"version", 0, 0, 'v'},
{"warn", 0, &warn_not_std, TRUE},
{0, 0, 0, 0}
};
void
usage (char *progname)
{
printf ("usage: %s [options] [file ...]\n%s%s%s%s%s%s%s", progname,
" -h --help print this usage and exit\n",
" -i --interactive force interactive mode\n",
" -l --mathlib use the predefine math routnes\n",
" -q --quiet don't print initial banner\n",
" -s --standard non-standard bc constructs are errors\n",
" -w --warn warn about non-standard bc constructs\n",
" -v --version print version information and exit\n");
}
void
parse_args (argc, argv)
int argc;
char **argv;
{
int optch;
int long_index;
file_node *temp;
optind = 0;
while (1)
{
optch = getopt_long (argc, argv, "chilqswv", long_options, &long_index);
if (optch == EOF)
break;
switch (optch)
{
case 'c':
compile_only = TRUE;
break;
case 'h':
usage(argv[0]);
exit (0);
break;
case 'i':
interactive = TRUE;
break;
case 'l':
use_math = TRUE;
break;
case 'q':
quiet = TRUE;
break;
case 's':
std_only = TRUE;
break;
case 'v':
show_bc_version ();
exit (0);
break;
case 'w':
warn_not_std = TRUE;
break;
case 0:
break;
default:
usage(argv[0]);
exit (1);
}
}
while (optind < argc)
{
temp = (file_node *) bc_malloc(sizeof(file_node));
temp->name = argv[optind];
temp->next = NULL;
if (last == NULL)
file_names = temp;
else
last->next = temp;
last = temp;
optind++;
}
}
int
main (argc, argv)
int argc;
char *argv[];
{
char *env_value;
char *env_argv[30];
int env_argc;
compile_only = FALSE;
use_math = FALSE;
warn_not_std = FALSE;
std_only = FALSE;
if (isatty(0) && isatty(1))
interactive = TRUE;
else
interactive = FALSE;
quiet = FALSE;
file_names = NULL;
#ifdef HAVE_SETVBUF
(void) setvbuf(stdout, NULL, _IOLBF, 0);
#endif
env_value = getenv ("BC_ENV_ARGS");
if (env_value != NULL)
{
env_argc = 1;
env_argv[0] = "BC_ENV_ARGS";
while (*env_value != 0)
{
if (*env_value != ' ')
{
env_argv[env_argc++] = env_value;
while (*env_value != ' ' && *env_value != 0)
env_value++;
if (*env_value != 0)
{
*env_value = 0;
env_value++;
}
}
else
env_value++;
}
parse_args (env_argc, env_argv);
}
parse_args (argc, argv);
if (getenv ("POSIXLY_CORRECT") != NULL)
std_only = TRUE;
env_value = getenv ("BC_LINE_LENGTH");
if (env_value != NULL)
{
line_size = atoi (env_value);
if (line_size < 2)
line_size = 70;
}
else
line_size = 70;
init_storage();
init_load();
if (interactive)
signal (SIGINT, use_quit);
init_tree();
init_gen ();
is_std_in = FALSE;
first_file = TRUE;
if (!open_new_file ())
exit (1);
#if defined(LIBEDIT)
if (interactive) {
edit = el_init ("bc", stdin, stdout, stderr);
hist = history_init();
el_set (edit, EL_EDITOR, "emacs");
el_set (edit, EL_HIST, history, hist);
el_set (edit, EL_PROMPT, null_prompt);
el_source (edit, NULL);
history (hist, &histev, H_SETSIZE, INT_MAX);
}
#endif
#if defined(READLINE)
if (interactive) {
rl_readline_name = "bc";
rl_instream = stdin;
using_history ();
}
#endif
yyparse ();
if (compile_only)
printf ("\n");
exit (0);
}
int
open_new_file ()
{
FILE *new_file;
file_node *temp;
line_no = 1;
if (is_std_in) return (FALSE);
if (use_math && first_file)
{
extern char *libmath[];
char **mstr;
char tmp;
tmp = lookup ("e", FUNCT);
tmp = lookup ("l", FUNCT);
tmp = lookup ("s", FUNCT);
tmp = lookup ("a", FUNCT);
tmp = lookup ("c", FUNCT);
tmp = lookup ("j", FUNCT);
mstr = libmath;
while (*mstr) {
load_code (*mstr);
mstr++;
}
}
if (file_names != NULL)
{
new_file = fopen (file_names->name, "r");
if (new_file != NULL)
{
new_yy_file (new_file);
temp = file_names;
file_name = temp->name;
file_names = temp->next;
free (temp);
return TRUE;
}
fprintf (stderr, "File %s is unavailable.\n", file_names->name);
exit (1);
}
new_yy_file (stdin);
is_std_in = TRUE;
return TRUE;
}
void
new_yy_file (file)
FILE *file;
{
if (!first_file) fclose (yyin);
yyin = file;
first_file = FALSE;
}
void
use_quit (sig)
int sig;
{
printf ("\n(interrupt) use quit to exit.\n");
signal (SIGINT, use_quit);
}