NetBSD/gnu/usr.bin/awk/init.c

362 lines
7.4 KiB
C

/********************************************
init.c
copyright 1991, Michael D. Brennan
This is a source file for mawk, an implementation of
the AWK programming language.
Mawk is distributed without warranty under the terms of
the GNU General Public License, version 2, 1991.
********************************************/
/* $Log: init.c,v $
/* Revision 1.2 1993/07/02 23:57:29 jtc
/* Updated to mawk 1.1.4
/*
* Revision 5.4 1992/12/24 01:58:19 mike
* 1.1.2d changes for MsDOS
*
* Revision 5.3 1992/07/10 16:17:10 brennan
* MsDOS: remove NO_BINMODE macro
*
* Revision 5.2 1992/01/09 08:46:14 brennan
* small change for MSC
*
* Revision 5.1 91/12/05 07:56:07 brennan
* 1.1 pre-release
*
*/
/* init.c */
#include "mawk.h"
#include "code.h"
#include "memory.h"
#include "symtype.h"
#include "init.h"
#include "bi_vars.h"
#include "field.h"
#ifdef THINK_C
#include <console.h>
#endif
#if MSDOS
#include <fcntl.h>
#endif
static void PROTO( process_cmdline , (int, char **) ) ;
static void PROTO( set_ARGV, (int, char **, int)) ;
static void PROTO( bad_option, (char *)) ;
extern void PROTO( print_version, (void) ) ;
extern int PROTO( is_cmdline_assign, (char*)) ;
#if MSDOS
void PROTO(stdout_init,(void)) ;
#if HAVE_REARGV
void PROTO(reargv, (int*,char***)) ;
#endif
#endif
char *progname ;
void initialize(argc, argv)
int argc ; char **argv ;
{
SET_PROGNAME() ;
bi_vars_init() ; /* load the builtin variables */
bi_funct_init() ; /* load the builtin functions */
kw_init() ; /* load the keywords */
field_init() ;
#ifdef THINK_C
fputc('\n',stderr); /* (causes Think C console window to appear) */
SetWTitle( FrontWindow(), "\pMacMAWK" );
argc = ccommand(&argv);
#endif
#if MSDOS
{ char *p = getenv("MAWKBINMODE") ;
if ( p ) set_binmode( atoi(p) ) ;
}
#endif
process_cmdline(argc, argv) ;
code_init() ;
fpe_init() ;
set_stderr() ;
#if MSDOS
stdout_init() ;
#endif
}
void compile_cleanup()
/* program has parsed OK, free some memory
we don't need anymore */
{
scan_cleanup() ;
code_cleanup() ;
}
int dump_code ; /* if on dump internal code */
int posix_space_flag ;
#ifdef DEBUG
int dump_RE ; /* if on dump compiled REs */
#endif
static void bad_option(s)
char *s ;
{ errmsg(0, "not an option: %s", s) ; mawk_exit(1) ; }
static void process_cmdline(argc, argv)
int argc ;
char **argv ;
{
int i , nextarg ;
char *optarg ;
PFILE dummy ; /* starts linked list of filenames */
PFILE *tail = &dummy ;
for( i = 1 ; i < argc && argv[i][0] == '-' ; i = nextarg )
{
if ( argv[i][1] == 0 ) /* - alone */
{
if ( ! pfile_name )
{ errmsg(0, "no program") ; exit(1) ; }
break ; /* the for loop */
}
/* safe to look at argv[i][2] */
if ( argv[i][2] == 0 )
{
if ( i == argc-1 && argv[i][1] != '-' )
{
if ( strchr("WFvf", argv[i][1]) )
{ errmsg(0, "option %s lacks argument", argv[i]) ;
mawk_exit(1) ;
}
bad_option(argv[i]) ;
}
optarg = argv[i+1] ;
nextarg = i+2 ;
}
else /* argument glued to option */
{
optarg = &argv[i][2] ;
nextarg = i+1 ;
}
switch( argv[i][1] )
{
case 'W' :
if ( optarg[0] >= 'a' && optarg[0] <= 'z')
optarg[0] += 'A' - 'a' ;
if ( optarg[0] == 'V' ) print_version() ;
else
if ( optarg[0] == 'D' )
{ dump_code = 1 ;
#if SM_DOS
errmsg(0, "-W dump option unavailable in small model") ;
dump_code=0 ;
#endif
}
else
if ( optarg[0] == 'S' )
{
char *p = strchr(optarg,'=') ;
int x = p ? atoi(p+1) : 0 ;
if ( x > SPRINTF_SZ )
{
sprintf_buff = (char *) zmalloc(x) ;
sprintf_limit = sprintf_buff + x ;
}
}
#if MSDOS
else
if ( optarg[0] == 'B' )
{
char *p = strchr(optarg,'=') ;
int x = p ? atoi(p+1) : 0 ;
set_binmode(x) ;
}
#endif
else
if ( optarg[0] == 'P' )
{
posix_space_flag = 1 ;
}
else
errmsg(0,"vacuous option: -W %s", optarg) ;
break ;
case 'v' :
if ( ! is_cmdline_assign(optarg) )
{ errmsg(0 , "improper assignment: -v %s" , optarg) ;
exit(1) ;
}
break ;
case 'F' :
rm_escape(optarg) ; /* recognize escape sequences */
cell_destroy(FS) ;
FS->type = C_STRING ;
FS->ptr = (PTR) new_STRING(optarg) ;
cast_for_split( cellcpy(&fs_shadow, FS) ) ;
break ;
case '-' :
if ( argv[i][2] != 0 ) bad_option(argv[i]) ;
i++ ;
goto no_more_opts ;
case 'f' :
/* first file goes in pfile_name ; any more go
on a list */
if ( ! pfile_name ) pfile_name = optarg ;
else
{ tail = tail->link = ZMALLOC(PFILE) ;
tail->fname = optarg ;
}
break ;
default : bad_option(argv[i]) ;
}
i = nextarg ;
}
no_more_opts:
tail->link = (PFILE*) 0 ;
pfile_list = dummy.link ;
if ( pfile_name )
{
set_ARGV(argc, argv, i) ;
scan_init( (char *) 0 ) ;
}
else /* program on command line */
{
#if 0
#if MSDOS && ! HAVE_REARGV /* prompt for program */
set_ARGV(argc, argv, i) ;
emit_prompt() ;
pfile_name = "CON" ;
scan_init( (char *) 0 ) ;
#else /* the real world */
#endif
#endif /* 0 */
if ( i == argc )
{ errmsg(0, "no program") ; mawk_exit(1) ; }
set_ARGV(argc, argv, i+1) ;
#if MSDOS && ! HAVE_REARGV /* reversed quotes */
{ char *p ;
for( p = argv[i] ; *p ; p++ )
if ( *p == '\'' ) *p = '\"' ;
}
#endif
scan_init( argv[i]) ;
/* #endif */
}
}
static void set_ARGV(argc, argv, i)
int argc ; char **argv ;
int i ; /* argv[i] = ARGV[1] */
{
SYMTAB *st_p ;
CELL argi ;
register CELL *cp ;
st_p = insert( "ARGV" ) ;
st_p->type = ST_ARRAY ;
Argv = st_p->stval.array = new_ARRAY() ;
argi.type = C_DOUBLE ;
argi.dval = 0.0 ;
cp = array_find( st_p->stval.array, &argi, CREATE) ;
cp->type = C_STRING ;
cp->ptr = (PTR) new_STRING( progname ) ;
/* ARGV[0] is set, do the rest
The type of ARGV[1] ... should be C_MBSTRN
because the user might enter numbers from the command line */
for( argi.dval = 1.0 ; i < argc ; i++, argi.dval += 1.0 )
{
cp = array_find( st_p->stval.array, &argi, CREATE) ;
cp->type = C_MBSTRN ;
cp->ptr = (PTR) new_STRING( argv[i] ) ;
}
ARGC->type = C_DOUBLE ;
ARGC->dval = argi.dval ;
}
#if 0
#if MSDOS && ! HAVE_REARGV
static void emit_prompt()
{ static char prompt[] = "mawk> " ;
int fd = open("CON", O_WRONLY, 0) ;
(void) write(fd, prompt, strlen(prompt)) ;
(void) close(fd) ;
}
#endif
#endif
/*----- ENVIRON ----------*/
void load_environ( ENV )
ARRAY ENV ;
{
CELL c ;
#ifndef MSDOS_MSC /* MSC declares it near */
extern char **environ ;
#endif
register char **p = environ ; /* walks environ */
char *s ; /* looks for the '=' */
CELL *cp ; /* pts at ENV[&c] */
c.type = C_STRING ;
while ( *p )
{
if ( s = strchr(*p, '=') ) /* shouldn't fail */
{
*s = 0 ;
c.ptr = (PTR) new_STRING(*p) ;
*s++ = '=' ;
cp = array_find(ENV, &c, CREATE) ;
cp->type = C_MBSTRN ;
cp->ptr = (PTR) new_STRING(s) ;
free_STRING(string(&c)) ;
}
p++ ;
}
}