home *** CD-ROM | disk | FTP | other *** search
- From: brennan@ssc-vax.UUCP (Mike Brennan)
- Newsgroups: alt.sources
- Subject: mawk0.97.shar 3 of 6
- Message-ID: <3965@ssc-bee.ssc-vax.UUCP>
- Date: 11 May 91 14:52:40 GMT
-
-
- ------------------cut here----------------
- register FCALL_REC *q = &dummy ; /* trails p */
-
- q->link = p ;
- while ( p )
- {
- if ( ! p->callee->code )
- { /* callee never defined */
- errmsg(0, "line %u: function %s never defined" ,
- p->line_no, p->callee->name) ;
- if ( ++compile_error_count == MAX_COMPILE_ERRORS )
- mawk_exit(1) ;
- /* delete p from list */
- q->link = p->link ;
- /* don't worry about freeing memory, we'll exit soon */
- }
- else /* note p->arg_list starts with last argument */
- if ( ! p->arg_list /* nothing to do */ ||
- ! p->arg_cnt_checked &&
- ! arg_cnt_ok(p->callee, p->arg_list, p->line_no) )
- { q->link = p->link ; /* delete p */
- /* the ! arg_list case is not an error so free memory */
- zfree(p, sizeof(FCALL_REC)) ;
- }
- else
- { /* keep p and set call_start */
- q = p ;
- switch ( p->call_scope )
- {
- case SCOPE_MAIN :
- p->call_start = main_start ;
- break ;
-
- case SCOPE_BEGIN :
- p->call_start = begin_start ;
- break ;
-
- case SCOPE_END :
- p->call_start = end_start ;
- break ;
-
- case SCOPE_FUNCT :
- p->call_start = p->call->code ;
- break ;
- }
- }
- p = q->link ;
- }
- return dummy.link ;
- }
-
- /* continuously walk the resolve_list making type deductions
- until this list goes empty or no more progress can be made
- (An example where no more progress can be made is at end of file
- */
-
- void resolve_fcalls()
- { register FCALL_REC *p, *old_list , *new_list ;
- int progress ; /* a flag */
-
- old_list = first_pass(resolve_list) ;
- new_list = (FCALL_REC *) 0 ;
- progress = 0 ;
-
- while ( 1 )
- {
- if ( !(p = old_list) )
- { /* flop the lists */
- if ( !(p = old_list = new_list) /* nothing left */
- || ! progress /* can't do any more */ ) return ;
-
- /* reset after flop */
- new_list = (FCALL_REC *) 0 ; progress = 0 ;
- }
-
- old_list = p->link ;
-
- if ( p->arg_list = call_arg_check(p->callee, p->arg_list ,
- p->call_start, p->line_no) )
- {
- /* still have work to do , put on new_list */
- progress |= check_progress ;
- p->link = new_list ; new_list = p ;
- }
- else /* done with p */
- { progress = 1 ; zfree(p, sizeof(FCALL_REC)) ; }
- }
- }
-
- /* the parser has just reduced a function call ;
- the info needed to type check is passed in. If type checking
- can not be done yet (most common reason -- function referenced
- but not defined), a node is added to the resolve list.
- */
- void check_fcall( callee, call_scope, call, arg_list, line_no )
- FBLOCK *callee ;
- int call_scope ;
- FBLOCK *call ;
- CA_REC *arg_list ;
- unsigned line_no ;
- {
- FCALL_REC *p ;
- INST *call_start ;
-
- if ( ! callee->code )
- { /* forward reference to a function to be defined later */
- p = (FCALL_REC *) zmalloc(sizeof(FCALL_REC)) ;
- p->callee = callee ;
- p->call_scope = call_scope ;
- p->call = call ;
- p->arg_list = arg_list ;
- p->arg_cnt_checked = 0 ;
- p->line_no = line_no ;
- /* add to resolve list */
- p->link = resolve_list ; resolve_list = p ;
- }
- else
- if ( arg_list && arg_cnt_ok( callee, arg_list, line_no ) )
- {
- switch ( call_scope )
- {
- case SCOPE_MAIN :
- call_start = main_start ;
- break ;
-
- case SCOPE_BEGIN :
- call_start = begin_start ;
- break ;
-
- case SCOPE_END :
- call_start = end_start ;
- break ;
-
- case SCOPE_FUNCT :
- call_start = call->code ;
- break ;
- }
-
- /* usually arg_list disappears here and all is well
- otherwise add to resolve list */
-
- if ( arg_list = call_arg_check(callee, arg_list,
- call_start, line_no) )
- {
- p = (FCALL_REC *) zmalloc(sizeof(FCALL_REC)) ;
- p->callee = callee ;
- p->call_scope = call_scope ;
- p->call = call ;
- p->arg_list = arg_list ;
- p->arg_cnt_checked = 1 ;
- p->line_no = line_no ;
- /* add to resolve list */
- p->link = resolve_list ; resolve_list = p ;
- }
- }
- }
-
-
-
- /* example where typing cannot progress
-
- { f(z) }
-
- function f(x) { print NR }
-
- # this is legal, does something useful, but absurdly written
- # We have to design so this works
- */
-
- @//E*O*F mawk0.97/fcall.c//
- chmod u=rw,g=r,o=r mawk0.97/fcall.c
-
- echo x - mawk0.97/field.c
- sed 's/^@//' > "mawk0.97/field.c" <<'@//E*O*F mawk0.97/field.c//'
-
- /********************************************
- field.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /* $Log: field.c,v $
- * Revision 2.2 91/04/09 12:39:00 brennan
- * added static to funct decls to satisfy STARDENT compiler
- *
- * Revision 2.1 91/04/08 08:23:01 brennan
- * VERSION 0.97
- *
- */
-
-
- /* field.c */
-
- #include "mawk.h"
- #include "field.h"
- #include "init.h"
- #include "memory.h"
- #include "scan.h"
- #include "bi_vars.h"
- #include "repl.h"
- #include "regexp.h"
-
- CELL field[NUM_FIELDS] ;
-
- /* statics */
- static void PROTO( build_field0, (void) ) ;
- static void PROTO( xcast, (CELL *) ) ;
- static void PROTO( set_rs_shadow, (void) ) ;
-
- /* the order is important here, must be the same as
- postion after field[MAX_FIELD] */
-
- static char *biv_field_names[] = {
- "NF" , "RS" , "FS", "OFMT" } ;
-
- /* a description of how to split based on RS.
- If RS is changed, so is rs_shadow */
- SEPARATOR rs_shadow = {SEP_CHAR, '\n'} ;
- /* a splitting CELL version of FS */
- CELL fs_shadow = {C_SPACE} ;
- int nf ;
- /* nf holds the true value of NF. If nf < 0 , then
- NF has not been computed, i.e., $0 has not been split
- */
-
- static void set_rs_shadow()
- { CELL c ;
- STRING *sval ;
- char *s ;
- unsigned len ;
-
- if ( rs_shadow.type == SEP_STR ) free_STRING((STRING*) rs_shadow.ptr) ;
-
- cast_for_split( cellcpy(&c, field+RS) ) ;
- switch( c.type )
- {
- case C_RE :
- if ( s = is_string_split(c.ptr, &len) )
- if ( len == 1 )
- { rs_shadow.type = SEP_CHAR ;
- rs_shadow.c = s[0] ;
- }
- else
- { rs_shadow.type = SEP_STR ;
- rs_shadow.ptr = (PTR) new_STRING(s) ;
- }
- else
- { rs_shadow.type = SEP_RE ;
- rs_shadow.ptr = c.ptr ;
- }
- break ;
-
- case C_SPACE :
- rs_shadow.type = SEP_CHAR ;
- rs_shadow.c = ' ' ;
- break ;
-
- case C_SNULL : /* RS becomes one or more blank lines */
- rs_shadow.type = SEP_RE ;
- sval = new_STRING( "\n([ \t]*\n)+" ) ;
- rs_shadow.ptr = re_compile(sval) ;
- free_STRING(sval) ;
- break ;
-
- default : bozo("bad cell in set_rs_shadow") ;
- }
- }
-
- void field_init()
- { char **p = biv_field_names ;
- SYMTAB *st_p ;
- int i ;
-
- for(i = NF ; i < NUM_FIELDS ; p++ , i++ )
- {
- st_p = insert( *p ) ;
- st_p->type = ST_FIELD ;
- st_p->stval.cp = &field[i] ;
- }
-
- field[NF].type = C_DOUBLE ;
- field[NF].dval = 0.0 ;
- field[0].type = C_STRING ;
- field[0].ptr = (PTR) & null_str ;
- null_str.ref_cnt++ ;
-
- field[RS].type = C_STRING ;
- field[RS].ptr = (PTR) new_STRING( "\n" ) ;
- /* rs_shadow already set */
-
- field[FS].type = C_STRING ;
- field[FS].ptr = (PTR) new_STRING( " " ) ;
- /* fs_shadow is already set */
-
- field[OFMT].type = C_STRING ;
- field[OFMT].ptr = (PTR) new_STRING( "%.6g" ) ;
- }
-
-
-
- void set_field0( s, len)
- char *s ;
- unsigned len ;
- {
- cell_destroy( & field[0] ) ;
- nf = -1 ;
-
- if ( len )
- {
- field[0].type = C_MBSTRN ;
- field[0].ptr = (PTR) new_STRING( (char *) 0, len) ;
- (void) memcpy( string(&field[0])->str, s, len ) ;
- }
- else
- {
- field[0].type = C_STRING ;
- field[0].ptr = (PTR) &null_str ;
- null_str.ref_cnt++ ;
- }
- }
-
-
-
- /* split field[0] into $1, $2 ... and set NF */
-
- void split_field0()
- { register int i ;
- CELL c ;
- int cast_flag ; /* we had to cast field[0] */
- char *s ;
- unsigned len ;
-
- if ( fs_shadow.type == C_SNULL ) /* FS == "" */
- { cell_destroy(field+1) ;
- (void) cellcpy(field+1, field+0) ;
- cell_destroy(field+NF) ;
- field[NF].type = C_DOUBLE ; field[NF].dval = 1.0 ;
- return ;
- }
-
- if ( field[0].type < C_STRING )
- { cast1_to_s(cellcpy(&c, field+0)) ;
- s = string(&c)->str ;
- len = string(&c)->len ;
- cast_flag = 1 ;
- }
- else
- { s = string(field)->str ;
- len = string(field)->len ;
- cast_flag = 0 ;
- }
-
- nf = len == 0 ? 0 :
- fs_shadow.type == C_SPACE
- ? space_split(s) : re_split(s, fs_shadow.ptr) ;
-
- cell_destroy(field+NF) ;
- field[NF].type = C_DOUBLE ;
- field[NF].dval = (double) nf ;
-
- for( i = 1 ; i <= nf ; i++ )
- {
- cell_destroy(field+i) ;
- field[i].ptr = temp_buff.ptr_buff[i-1] ;
- field[i].type = C_MBSTRN ;
- }
-
- if ( cast_flag ) free_STRING( string(&c) ) ;
- }
-
- /*
- assign CELL *cp to field[i]
- and take care of all side effects
- */
-
- void field_assign( i, cp)
- register int i ;
- CELL *cp ;
- { register int j ;
- CELL c ;
-
- /* update fields not up to date */
- if ( nf < 0 ) split_field0() ;
-
- switch( i )
- {
- case 0 :
- cell_destroy(field) ;
- nf = -1 ;
- (void) cellcpy(field, cp) ;
- break ; ;
-
- case NF :
- cell_destroy(field+NF) ;
- (void) cellcpy(field+NF, cellcpy(&c,cp) ) ;
- if ( c.type != C_DOUBLE ) cast1_to_d(&c) ;
-
- if ( (j = (int) c.dval) < 0 )
- rt_error("negative value assigned to NF") ;
- if ( j > MAX_FIELD )
- rt_overflow("MAX_FIELD", MAX_FIELD) ;
-
- if ( j > nf )
- for ( i = nf+1 ; i <= j ; i++ )
- { cell_destroy(field+i) ;
- field[i].type = C_STRING ;
- field[i].ptr = (PTR) &null_str ;
- null_str.ref_cnt++ ;
- }
-
- nf = j ;
- build_field0() ;
- break ;
-
- case RS :
- cell_destroy(field+RS) ;
- (void) cellcpy(field+RS, cp) ;
- set_rs_shadow() ;
- break ;
-
- case FS :
- cell_destroy(field+FS) ;
- cast_for_split( cellcpy(&fs_shadow, cellcpy(field+FS, cp)) ) ;
- break ;
-
- case OFMT :
- /* If the user does something stupid with OFMT, we could crash.
- We'll make an attempt to protect ourselves here. This is
- why OFMT is made a field.
-
- The ptr of OFMT always has a valid STRING, even if assigned
- a DOUBLE or NOINIT
- */
-
- free_STRING( string(field+OFMT) ) ;
- (void) cellcpy(field+OFMT, cp) ;
- if ( field[OFMT].type < C_STRING ) /* !! */
- field[OFMT].ptr = (PTR) new_STRING( "%.6g" ) ;
- else
- {
- /* It's a string, but if it's really goofy it could still
- damage us. Test it . */
- temp_buff.string_buff[256] = 0 ;
- (void) sprintf(temp_buff.string_buff,
- string(field+OFMT)->str, 3.1459) ;
- if ( temp_buff.string_buff[256] )
- rt_error("OFMT assigned unusable value") ;
- }
- break ;
-
-
- default:
-
- #ifdef DEBUG
- if ( i < 0 )
- bozo("negative field index in field_assign") ;
- if ( i > MAX_FIELD )
- bozo("large field index in field_assign") ;
- #endif
-
- cell_destroy(field+i) ;
- (void) cellcpy(field+i, cp) ;
- if ( i > nf )
- { for ( j = nf+1 ; j < i ; j++ )
- { cell_destroy(field+j) ;
- field[j].type = C_STRING ;
- field[j].ptr = (PTR) &null_str ;
- null_str.ref_cnt++ ;
- }
- nf = i ;
- cell_destroy(field+NF) ;
- field[NF].type = C_DOUBLE ;
- field[NF].dval = (double) i ;
- }
-
- build_field0() ;
-
- }
- }
-
-
- /* get the string rep of a double without changing its
- type */
-
- static void xcast( cp )
- register CELL *cp ;
- {
- switch ( cp->type )
- {
- case C_NOINIT :
- cp->ptr = (PTR) &null_str ;
- null_str.ref_cnt++ ;
- break ;
-
- case C_DOUBLE :
- (void) sprintf(temp_buff.string_buff,
- string(field+OFMT)->str, cp->dval) ;
- cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
- break ;
- }
- }
-
-
- /* construct field[0] from the other fields */
-
- static void build_field0()
- {
-
-
- #ifdef DEBUG
- if ( nf < 0 )
- bozo("nf <0 in build_field0") ;
- #endif
-
- cell_destroy( field+0 ) ;
-
- if ( nf == 0 )
- { field[0].type = C_STRING ;
- field[0].ptr = (PTR) &null_str ;
- null_str.ref_cnt++ ;
- }
- else
- if ( nf == 1 ) (void) cellcpy(field, field+1) ;
-
- else
- { CELL ofs ;
- char *ofs_str ;
- unsigned ofs_len , len0 = 0 ;
- register int i ;
- register char *p, *q ;
-
-
- (void) cellcpy(& ofs , bi_vars + OFS) ;
- if ( ofs.type < C_STRING ) cast1_to_s(&ofs) ;
- ofs_str = string(&ofs)->str ;
- ofs_len = string(&ofs)->len ;
-
-
- for( i = 1 ; i <= nf ; i++ )
- {
- if ( field[i].type < C_STRING ) xcast(field+i) ;
- len0 += string(field+i)->len + ofs_len ;
- }
- len0 -= ofs_len ;
-
- field[0].type = C_STRING ;
- field[0].ptr = (PTR) new_STRING((char *) 0, len0) ;
-
- p = string(field)->str ;
- for( i = 1 ; i < nf ; i++ )
- {
- (void) memcpy(p, string(field+i)->str, string(field+i)->len) ;
- p += string(field+i)->len ;
-
- /* add the separator */
- q = ofs_str ;
- while ( *p++ = *q++ ) ; p-- ;
-
- /* if not really string undo the xcast */
- if ( field[i].type < C_STRING )
- free_STRING( string(field+i) ) ;
- }
- /* do the last piece */
- (void) memcpy(p, string(field+i)->str, string(field+i)->len) ;
- if ( field[i].type < C_STRING )
- free_STRING( string(field+i) ) ;
-
- free_STRING( string(&ofs) ) ;
- }
- }
- @//E*O*F mawk0.97/field.c//
- chmod u=rw,g=r,o=r mawk0.97/field.c
-
- echo x - mawk0.97/field.h
- sed 's/^@//' > "mawk0.97/field.h" <<'@//E*O*F mawk0.97/field.h//'
-
- /********************************************
- field.h
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /* $Log: field.h,v $
- * Revision 2.1 91/04/08 08:23:03 brennan
- * VERSION 0.97
- *
- */
-
- /* field.h */
-
-
- #ifndef FIELD_H
- #define FIELD_H 1
-
- void PROTO( set_field0, (char *, unsigned) ) ;
- void PROTO( split_field0, (void) ) ;
- int PROTO( is_strnum, (char *, unsigned, double *) ) ;
- void PROTO( field_assign, (int, CELL *) ) ;
- char *PROTO( is_string_split, (PTR , unsigned *) ) ;
-
- #define NF (MAX_FIELD+1)
- #define RS (MAX_FIELD+2)
- #define FS (MAX_FIELD+3)
- #define OFMT (MAX_FIELD+4)
- #define NUM_FIELDS (MAX_FIELD+5)
-
-
- extern CELL field[NUM_FIELDS] ;
-
- extern int nf ; /* shadows NF */
-
- /* a shadow type for RS and FS */
- #define SEP_SPACE 0
- #define SEP_CHAR 1
- #define SEP_STR 2
- #define SEP_RE 3
-
- typedef struct {
- char type ;
- char c ;
- PTR ptr ; /* STRING* or RE machine* */
- } SEPARATOR ;
-
- extern SEPARATOR rs_shadow ;
- extern CELL fs_shadow ;
-
-
-
-
-
-
- #endif /* FIELD_H */
- @//E*O*F mawk0.97/field.h//
- chmod u=rw,g=r,o=r mawk0.97/field.h
-
- echo x - mawk0.97/files.c
- sed 's/^@//' > "mawk0.97/files.c" <<'@//E*O*F mawk0.97/files.c//'
-
- /********************************************
- files.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /*$Log: files.c,v $
- * Revision 2.1 91/04/08 08:23:05 brennan
- * VERSION 0.97
- *
- */
-
- /* files.c */
-
- #include "mawk.h"
- #include "files.h"
- #include "memory.h"
- #include <stdio.h>
- #include "fin.h"
-
- #if ! DOS
- #include <fcntl.h>
- #endif
-
- /* We store dynamically created files on a linked linear
- list with move to the front (big surprise) */
-
- typedef struct file {
- struct file *link ;
- STRING *name ;
- short type ;
- #if ! DOS
- int pid ; /* we need to wait() when we close an out pipe */
- #endif
- PTR ptr ; /* FIN* or FILE* */
- } FILE_NODE ;
-
- static FILE_NODE *file_list ;
-
- PTR file_find( sval, type )
- STRING *sval ;
- int type ;
- { register FILE_NODE *p = file_list ;
- FILE_NODE *q = (FILE_NODE *) 0 ;
- char *name = sval->str ;
-
- while (1)
- {
- if ( !p ) /* open a new one */
- {
- p = (FILE_NODE*) zmalloc(sizeof(FILE_NODE)) ;
- switch( p->type = type )
- {
- case F_TRUNC :
- if ( !(p->ptr = (PTR) fopen(name, "w")) )
- goto out_failure ;
- break ;
-
- case F_APPEND :
- if ( !(p->ptr = (PTR) fopen(name, "a")) )
- goto out_failure ;
- break ;
-
- case F_IN :
- if ( !(p->ptr = (PTR) FINopen(name, 0)) )
- { zfree(p, sizeof(FILE_NODE)) ; return (PTR) 0 ; }
- break ;
-
- case PIPE_OUT :
- case PIPE_IN :
- #if DOS
- rt_error("pipes not supported under MsDOS") ;
- #else
- if ( !(p->ptr = get_pipe(name, type, &p->pid)) )
- if ( type == PIPE_OUT ) goto out_failure ;
- else
- { zfree(p, sizeof(FILE_NODE) ) ;
- return (PTR) 0 ;
- }
- #endif
- break ;
-
- #ifdef DEBUG
- default :
- bozo("bad file type") ;
- #endif
- }
- /* successful open */
- p->name = sval ;
- sval->ref_cnt++ ;
- break ;
- }
-
- if ( strcmp(name, p->name->str) == 0 )
- {
- if ( p->type != type ) goto type_failure ;
- if ( !q ) /*at front of list */
- return p->ptr ;
- /* delete from list for move to front */
- q->link = p->link ;
- break ;
- }
- q = p ; p = p->link ;
- }
-
- /* put p at the front of the list */
- p->link = file_list ;
- return (PTR) (file_list = p)->ptr ;
-
- out_failure:
- errmsg(errno, "cannot open \"%s\" for output", name) ;
- mawk_exit(1) ;
-
- type_failure :
- rt_error("use of file \"%s\"\n\tis inconsistent with previous use",
- name) ;
- }
-
-
- /* close a file and delete it's node from the file_list */
-
- int file_close( sval )
- STRING *sval ;
- { register FILE_NODE *p = file_list ;
- FILE_NODE *q = (FILE_NODE *) 0 ; /* trails p */
- char *name = sval->str ;
-
- while ( p )
- if ( strcmp(name,p->name->str) == 0 ) /* found */
- {
- switch( p->type )
- {
- case F_TRUNC :
- case F_APPEND :
- (void) fclose((FILE *) p->ptr) ;
- break ;
-
- case PIPE_OUT :
- (void) fclose((FILE *) p->ptr) ;
- #if ! DOS
- (void) wait_for(p->pid) ;
- #endif
- break ;
-
- case F_IN :
- case PIPE_IN :
- FINclose((FIN *) p->ptr) ;
- break ;
- }
-
- free_STRING(p->name) ;
- if ( q ) q->link = p->link ;
- else file_list = p->link ;
-
- zfree(p, sizeof(FILE_NODE)) ;
- return 0 ;
- }
- else { q = p ; p = p->link ; }
-
- /* its not on the list */
- return -1 ;
- }
-
- /* When we exit, we need to close and wait for all output pipes */
-
- #if !DOS
- void close_out_pipes()
- { register FILE_NODE *p = file_list ;
-
- while ( p )
- { if ( p->type == PIPE_OUT )
- { (void) fclose((FILE *) p->ptr) ; (void) wait_for(p->pid) ; }
- p = p->link ;
- }
- }
- #endif
-
-
- char *shell ;
-
- #if ! DOS
- PTR get_pipe( name, type, pid_ptr)
- char *name ;
- int type ;
- int *pid_ptr ;
- { int the_pipe[2], local_fd, remote_fd ;
-
- if ( ! shell ) shell = (shell = getenv("SHELL")) ? shell :"/bin/sh" ;
-
- if ( pipe(the_pipe) == -1 ) return (PTR) 0 ;
- local_fd = the_pipe[type == PIPE_OUT] ;
- remote_fd = the_pipe[type == PIPE_IN ] ;
-
- switch( *pid_ptr = fork() )
- { case -1 :
- (void) close(local_fd) ;
- (void) close(remote_fd) ;
- return (PTR) 0 ;
-
- case 0 :
- (void) close(local_fd) ;
- (void) close(type == PIPE_IN) ;
- (void) dup( remote_fd ) ;
- (void) close( remote_fd ) ;
- (void) execl(shell, shell, "-c", name, (char *) 0 ) ;
- errmsg(errno, "failed to exec %s -c %s" , shell, name) ;
- fflush(stderr) ;
- _exit(128) ;
-
- default :
- (void) close(remote_fd) ;
- /* we could deadlock if future child inherit the local fd ,
- set close on exec flag */
- (void) fcntl(local_fd, F_SETFD, 1) ;
- break ;
- }
-
- return type == PIPE_IN ? (PTR) FINdopen(local_fd, 0) :
- (PTR) fdopen(local_fd, "w") ;
- }
-
-
-
- /*------------ children ------------------*/
-
- /* we need to wait for children at the end of output pipes to
- complete so we know any files they have created are complete */
-
- /* dead children are kept on this list */
-
- static struct child {
- int pid ;
- int exit_status ;
- struct child *link ;
- } *child_list ;
-
- static void add_to_child_list(pid, exit_status)
- int pid, exit_status ;
- { register struct child *p =
- (struct child *) zmalloc(sizeof(struct child)) ;
-
- p->pid = pid ; p->exit_status = exit_status ;
- p->link = child_list ; child_list = p ;
- }
-
- static struct child *remove_from_child_list(pid)
- int pid ;
- { register struct child *p = child_list ;
- struct child *q = (struct child *) 0 ;
-
- while ( p )
- if ( p->pid == pid )
- {
- if ( q ) q->link = p->link ;
- else child_list = p->link ;
- break ;
- }
- else { q = p ; p = p->link ; }
-
- return p ; /* null return if not in the list */
- }
-
-
- /* wait for a specific child to complete and return its
- exit status */
-
- int wait_for(pid)
- int pid ;
- { int exit_status ;
- struct child *p ;
- int id ;
-
- /* see if an earlier wait() caught our child */
- if ( p = remove_from_child_list(pid) )
- { exit_status = p->exit_status ;
- zfree(p, sizeof(struct child)) ;
- }
- else /* need to really wait */
- while ( (id = wait(&exit_status)) != pid )
- if ( id == -1 ) /* can't happen */ bozo("wait_for") ;
- else
- { /* we got the exit status of another child
- put it on the child list and try again */
- add_to_child_list(id, exit_status ) ;
- }
-
- return exit_status ;
- }
-
- #endif
- @//E*O*F mawk0.97/files.c//
- chmod u=rw,g=r,o=r mawk0.97/files.c
-
- echo x - mawk0.97/files.h
- sed 's/^@//' > "mawk0.97/files.h" <<'@//E*O*F mawk0.97/files.h//'
-
- /********************************************
- files.h
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /*$Log: files.h,v $
- * Revision 2.1 91/04/08 08:23:07 brennan
- * VERSION 0.97
- *
- */
-
- #ifndef FILES_H
- #define FILES_H
-
- /* IO redirection types */
- #define F_IN (-5)
- #define PIPE_IN (-4)
- #define PIPE_OUT (-3)
- #define F_APPEND (-2)
- #define F_TRUNC (-1)
-
- extern char *shell ; /* for pipes and system() */
-
- PTR PROTO(file_find, (STRING *, int)) ;
- int PROTO(file_close, (STRING *)) ;
- PTR PROTO(get_pipe, (char *, int) ) ;
- int PROTO(wait_for, (int) ) ;
- void PROTO( close_out_pipes, (void) ) ;
-
-
- #endif
- @//E*O*F mawk0.97/files.h//
- chmod u=rw,g=r,o=r mawk0.97/files.h
-
- echo x - mawk0.97/fin.c
- sed 's/^@//' > "mawk0.97/fin.c" <<'@//E*O*F mawk0.97/fin.c//'
-
- /********************************************
- fin.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /*$Log: fin.c,v $
- * Revision 2.1 91/04/08 08:23:09 brennan
- * VERSION 0.97
- *
- */
-
- /* fin.c */
-
- #include "mawk.h"
- #include "fin.h"
- #include "memory.h"
- #include "bi_vars.h"
- #include "field.h"
- #include "symtype.h"
- #include "scan.h"
- #include <fcntl.h>
-
- extern int errno ;
- int PROTO(isatty, (int) ) ;
- FILE *PROTO(fdopen, (int, char*) ) ;
-
- /* statics */
- int PROTO( next_main, (void) ) ;
- int PROTO( is_cmdline_assign, (char *) ) ;
-
- FIN *FINdopen( fd, main_flag )
- int fd , main_flag ;
- { register FIN *fin = (FIN *) zmalloc( sizeof(FIN) ) ;
-
- fin->fd = fd ;
-
- if ( main_flag )
- { fin->flags = MAIN_FLAG ;
- fin->buffp = fin->buff = main_buff ;
- }
- else
- {
- fin->flags = 0 ;
- fin->buffp = fin->buff = (char *) zmalloc(BUFFSZ+1) ;
- }
- *fin->buffp = 0 ;
-
- if ( isatty(fd) && rs_shadow.type == SEP_CHAR
- && rs_shadow.c == '\n' )
- {
- /* interactive, i.e., line buffer this file */
- if ( fd == 0 ) fin->fp = stdin ;
- else
- if ( !(fin->fp = fdopen(fd, "r")) )
- { errmsg(errno, "fdopen failed") ; exit(1) ; }
- }
- else fin->fp = (FILE *) 0 ;
-
- return fin ;
- }
-
- FIN *FINopen( filename, main_flag )
- char *filename ;
- int main_flag ;
- { int fd ;
-
- if ( (fd = open( filename , O_RDONLY, 0 )) == -1 )
- { errmsg( errno, "cannot open %s" , filename ) ;
- return (FIN *) 0 ; }
-
- else return FINdopen( fd, main_flag ) ;
- }
-
- void FINclose( fin )
- register FIN *fin ;
- {
- if ( ! (fin->flags & MAIN_FLAG) )
- zfree(fin->buff, BUFFSZ+1) ;
-
- if ( fin->fd )
- if ( fin->fp ) (void) fclose(fin->fp) ;
- else (void) close(fin->fd) ;
-
- zfree( fin , sizeof(FIN) ) ;
- }
-
- /* return one input record as determined by RS,
- from input file (FIN) fin
- */
-
- char *FINgets( fin, len_p )
- FIN *fin ;
- unsigned *len_p ;
- { register char *p, *q ;
- unsigned match_len ;
- unsigned r ;
-
- restart :
-
- if ( ! (p = fin->buffp)[0] ) /* need a refill */
- {
- if ( fin->flags & EOF_FLAG )
- if ( (fin->flags & MAIN_FLAG) && next_main() ) goto restart ;
- else
- { *len_p = 0 ; return (char *) 0 ; }
-
- if ( fin->fp ) /* line buffering */
- if ( ! fgets(fin->buff, BUFFSZ+1, fin->fp) )
- {
- fin->flags |= EOF_FLAG ;
- fin->buff[0] = 0 ;
- fin->buffp = fin->buff ;
- goto restart ; /* might be main_fin */
- }
- else /* return this line */
- {
- if ( !(p = strchr(fin->buff, '\n')) )
- p = fin->buff + BUFFSZ + 1 ; /* unlikely to occur */
-
- *p = 0 ; *len_p = p - fin->buff ;
- fin->buffp = p ;
- return fin->buff ;
- }
- else /* block buffering */
- {
- if ( (r = fillbuff(fin->fd, fin->buff, BUFFSZ)) == 0 )
- {
- fin->flags |= EOF_FLAG ;
- fin->buffp = fin->buff ;
- goto restart ; /* might be main */
- }
- else
- if ( r < BUFFSZ ) fin->flags |= EOF_FLAG ;
-
- p = fin->buffp = fin->buff ;
- }
- }
-
- retry:
-
- switch( rs_shadow.type )
- {
- case SEP_CHAR :
- q = strchr(p, rs_shadow.c) ;
- match_len = 1 ;
- break ;
-
- case SEP_STR :
- q = str_str(p, ((STRING *) rs_shadow.ptr)->str,
- match_len = ((STRING *) rs_shadow.ptr)->len ) ;
- break ;
-
- case SEP_RE :
- q = re_pos_match(p, rs_shadow.ptr, &match_len) ;
- /* if the match is at the end, there might be more
- still to be read */
- if ( q && q[match_len] == 0 &&
- p != fin->buff ) q = (char *) 0 ;
- break ;
-
- default :
- bozo("type of rs_shadow") ;
- }
- if ( q )
- { /* the easy and normal case */
- *q = 0 ; *len_p = q - p ;
- fin->buffp = q + match_len ;
- return p ;
- }
-
- if ( p == fin->buff ) /* last line or one huge (truncated) line */
- { *len_p = r = strlen(p) ; fin->buffp = p + r ;
- /* treat truncated case as overflow */
- if ( r == BUFFSZ )
- { /* overflow, update NR and FNR */
- cast2_to_d(bi_vars+NR) ;
- bi_vars[NR].dval += 1.0 ;
- bi_vars[FNR].dval += 1.0 ;
- rt_overflow("maximum record length" , BUFFSZ) ;
- }
- return p ;
- }
-
- /* move a partial line to front of buffer and try again */
- p = (char *) memcpy( fin->buff, p, r = strlen(p) ) ;
- q = p+r ;
- if ( fin->flags & EOF_FLAG ) *q = 0 ;
- else
- { unsigned rr = BUFFSZ - r ;
-
- if ( (r = fillbuff(fin->fd, q, rr)) < rr ) fin->flags |= EOF_FLAG ;
- }
- goto retry ;
- }
-
- /*--------
- target is big enough to hold size + 1 chars
- on exit the back of the target is zero terminated
- *--------------*/
- unsigned fillbuff(fd, target, size)
- int fd ;
- register char *target ;
- unsigned size ;
- { register int r ;
- unsigned entry_size = size ;
-
- while ( size )
- switch( r = read(fd, target, size) )
- { case -1 :
- errmsg(errno, "read error on file") ;
- exit(1) ;
-
- case 0 :
- goto out ;
-
- default :
- target += r ; size -= r ;
- break ;
- }
-
- out :
- *target = 0 ;
- return entry_size - size ;
- }
-
- /* main_fin is a handle to the main input stream
- == -1 if never tried to open
- == 0 if end of stream
- otherwise active */
- FIN *main_fin = (FIN *) -1 ;
- ARRAY Argv ; /* to the user this is ARGV */
- static int argi = 1 ; /* index of next ARGV[argi] to try to open */
-
- int open_main() /* boolean return, true if main is open */
- {
- if ( bi_vars[ARGC].type == C_DOUBLE && bi_vars[ARGC].dval == 1.0 )
- { cell_destroy( bi_vars + FILENAME ) ;
- bi_vars[FILENAME].type = C_STRING ;
- bi_vars[FILENAME].ptr = (PTR) new_STRING( "-") ;
- main_fin = FINdopen(0, 1) ;
- return 1 ;
- }
- else return next_main() ;
- }
-
- static int next_main()
- { char xbuff[16] ;
- register CELL *cp ;
- STRING *sval ;
- CELL argc ; /* temp copy of ARGC */
- CELL tc ; /* copy of ARGV[argi] */
- double d_argi ;
-
- #ifdef DEBUG
- if ( ! main_fin ) bozo("call to next_main with dead main") ;
- #endif
-
- tc.type = C_NOINIT ;
-
- if ( main_fin != (FIN *)-1 ) FINclose(main_fin) ;
- cell_destroy( bi_vars + FILENAME ) ;
- cell_destroy( bi_vars + FNR ) ;
- bi_vars[FNR].type = C_DOUBLE ;
- bi_vars[FNR].dval = 0.0 ;
-
- if ( cellcpy(&argc, &bi_vars[ARGC])->type != C_DOUBLE )
- cast1_to_d(&argc) ;
- xbuff[1] = 0 ;
- d_argi = (double) argi ;
-
- while ( d_argi < argc.dval )
- {
- if ( argi < 10 ) xbuff[0] = argi + '0' ;
- else (void) sprintf(xbuff, "%u", argi) ;
-
- argi++ ; d_argi += 1.0 ;
- sval = new_STRING(xbuff) ;
-
- /* the user might have changed ARGC or deleted
- ARGV[argi] -- test for existence without side effects */
-
- if ( ! array_test(Argv, sval) )
- { free_STRING(sval) ; continue ; }
-
- cp = array_find( Argv, sval, 0) ;
- free_STRING(sval) ;
-
- /* make a copy so we can cast w/o side effect */
- cell_destroy(&tc) ;
- cp = cellcpy(&tc, cp) ;
- if ( cp->type < C_STRING ) cast1_to_s(cp) ;
- if ( string(cp)->len == 0 ) continue ;
-
- if ( string(cp)->len == 1 && string(cp)->str[0] == '-' )
- { /* input from stdin */
- main_fin = FINdopen(0,1) ;
- }
- else /* it might be a command line assignment */
- if ( is_cmdline_assign(string(cp)->str) ) continue ;
-
- else /* try to open it */
- if ( ! (main_fin = FINopen( string(cp)->str, 1 )) ) continue ;
-
- /* success */
- (void) cellcpy( &bi_vars[FILENAME] , cp ) ;
- free_STRING( string(cp) ) ;
- return 1 ;
- }
- /* failure */
- bi_vars[FILENAME].type = C_STRING ;
- bi_vars[FILENAME].ptr = (PTR) new_STRING( "" ) ;
- main_fin = (FIN *) 0 ;
- cell_destroy(&tc) ;
- return 0 ;
- }
-
-
- static int is_cmdline_assign(s)
- char *s ;
- { char *q;
- unsigned char *p ;
- int c ;
- SYMTAB *stp ;
- CELL *cp ;
-
- if ( scan_code[*(unsigned char *)s] != SC_IDCHAR
- || !(q = strchr(s,'=')) ) return 0 ;
-
- p = (unsigned char *)s+1 ;
- while ( (c = scan_code[*p]) == SC_IDCHAR || c == SC_DIGIT ) p++ ;
-
- if ( (char *)p < q ) return 0 ;
-
- *q = 0 ;
- stp = find(s) ;
-
- switch( stp->type )
- {
- case ST_NONE :
- stp->type = ST_VAR ;
- stp->stval.cp = cp = new_CELL() ;
- break ;
-
- case ST_VAR :
- cp = stp->stval.cp ;
- break ;
-
- default :
- rt_error(
- "cannot command line assign to %s\n\t- type clash or keyword"
- , s ) ;
- }
-
- *q++ = '=' ;
- cp->ptr = (PTR) new_STRING(q) ;
- check_strnum(cp) ;
- return 1 ;
- }
- @//E*O*F mawk0.97/fin.c//
- chmod u=rw,g=r,o=r mawk0.97/fin.c
-
- echo x - mawk0.97/fin.h
- sed 's/^@//' > "mawk0.97/fin.h" <<'@//E*O*F mawk0.97/fin.h//'
-
- /********************************************
- fin.h
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /*$Log: fin.h,v $
- * Revision 2.1 91/04/08 08:23:11 brennan
- * VERSION 0.97
- *
- */
-
- /* fin.h */
-
- #ifndef FIN_H
- #define FIN_H
- /* structure to control input files */
-
- typedef struct {
- int fd ;
- FILE *fp ; /* NULL unless interactive */
- char *buff ;
- char *buffp ;
- short flags ;
- } FIN ;
-
- #define MAIN_FLAG 1 /* part of main input stream if on */
- #define EOF_FLAG 2
-
- FIN * PROTO (FINdopen, (int, int) );
- FIN * PROTO (FINopen, (char *, int) );
- void PROTO (FINclose, (FIN *) ) ;
- char* PROTO (FINgets, (FIN *, unsigned *) ) ;
- unsigned PROTO ( fillbuff, (int, char *, unsigned) ) ;
-
-
- extern FIN *main_fin ; /* for the main input stream */
- int PROTO( open_main, (void) ) ;
- #endif /* FIN_H */
- @//E*O*F mawk0.97/fin.h//
- chmod u=rw,g=r,o=r mawk0.97/fin.h
-
- echo x - mawk0.97/hash.c
- sed 's/^@//' > "mawk0.97/hash.c" <<'@//E*O*F mawk0.97/hash.c//'
-
- /********************************************
- hash.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: hash.c,v $
- * Revision 2.1 91/04/08 08:23:13 brennan
- * VERSION 0.97
- *
- */
-
-
- /* hash.c */
-
- #include "mawk.h"
- #include "memory.h"
- #include "symtype.h"
- #include <string.h>
-
-
- unsigned hash(s)
- register char *s ;
- { register unsigned h = 0 ;
-
- while ( *s ) h += h + *s++ ;
- return h ;
- }
-
- typedef struct hash {
- struct hash *link ;
- SYMTAB symtab ;
- } HASHNODE ;
-
- static HASHNODE *PROTO( delete, (char *) ) ;
-
- #define new_HASHNODE() (HASHNODE *) zmalloc(sizeof(HASHNODE))
-
- static HASHNODE *hash_table[HASH_PRIME] ;
-
- /*
- * insert -- s is not there and need not be duplicated
- * -- used during initialization
- */
-
- SYMTAB *insert(s)
- char *s ;
- { register HASHNODE *p = new_HASHNODE();
- register unsigned h ;
-
- p->link = hash_table[h = hash(s) % HASH_PRIME ] ;
- p->symtab.name = s ;
- hash_table[h] = p ;
- return &p->symtab ;
- }
-
- /*
- * find -- s might be there, find it else insert and dup
- * s
- */
-
- SYMTAB *find(s)
- char *s ;
- { register HASHNODE *p ;
- HASHNODE *q ;
- unsigned h ;
-
- p = hash_table[h = hash(s) % HASH_PRIME ] ;
- q = (HASHNODE *) 0 ;
- while ( 1 )
- { if ( !p )
- { p = new_HASHNODE() ;
- p->symtab.type = ST_NONE ;
- p->symtab.name = strcpy(zmalloc( strlen(s)+1 ), s) ;
- break ;
- }
-
- if ( strcmp(p->symtab.name, s) == 0 ) /* found */
- if ( !q ) /* already at the front */
- return &p->symtab ;
- else /* delete from the list */
- { q->link = p->link ; break ; }
-
- q = p ; p = p->link ;
- }
- /* put p on front of the list */
- p->link = hash_table[h] ;
- hash_table[h] = p ;
- return & p->symtab ;
- }
-
-
- /* remove a node from the hash table
- return a ptr to the node */
-
- static unsigned last_hash ;
-
- static HASHNODE *delete( s )
- char *s ;
- { register HASHNODE *p ;
- HASHNODE *q = (HASHNODE *) 0 ;
- unsigned h ;
-
- p = hash_table[ last_hash = h = hash(s) % HASH_PRIME ] ;
- while ( p )
- if ( strcmp(p->symtab.name, s) == 0 ) /* found */
- {
- if ( q ) q->link = p->link ;
- else hash_table[h] = p->link ;
- return p ;
- }
- else { q = p ; p = p->link ; }
-
- #ifdef DEBUG /* we should not ever get here */
- bozo("delete") ;
- #endif
- return (HASHNODE *) 0 ;
- }
-
- /* when processing user functions, global ids which are
- replaced by local ids are saved on this list */
-
- static HASHNODE *save_list ;
-
- /* store a global id on the save list,
- return a ptr to the local symtab */
- SYMTAB *save_id( s )
- char *s ;
- { HASHNODE *p, *q ;
- unsigned h ;
-
- p = delete(s) ;
- q = new_HASHNODE() ;
- q->symtab.type = ST_LOCAL_NONE ;
- q->symtab.name = p->symtab.name ;
- /* put q in the hash table */
- q->link = hash_table[ h = last_hash ] ;
- hash_table[h] = q ;
-
- /* save p */
- p->link = save_list ; save_list = p ;
-
- return & q->symtab ;
- }
-
- /* restore all global indentifiers */
- void restore_ids()
- { register HASHNODE *p, *q ;
- register unsigned h ;
-
- q = save_list ; save_list = (HASHNODE *) 0 ;
- while ( q )
- {
- p = q ; q = q->link ;
- zfree( delete(p->symtab.name) , sizeof(HASHNODE) ) ;
- p->link = hash_table[h = last_hash ] ;
- hash_table[h] = p ;
- }
- }
- @//E*O*F mawk0.97/hash.c//
- chmod u=rw,g=r,o=r mawk0.97/hash.c
-
- echo x - mawk0.97/init.c
- sed 's/^@//' > "mawk0.97/init.c" <<'@//E*O*F mawk0.97/init.c//'
-
- /********************************************
- init.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: init.c,v $
- * Revision 2.2 91/04/09 12:39:08 brennan
- * added static to funct decls to satisfy STARDENT compiler
- *
- * Revision 2.1 91/04/08 08:23:15 brennan
- * VERSION 0.97
- *
- */
-
-
- /* init.c */
- #include "mawk.h"
- #include "code.h"
- #include "init.h"
- #include "memory.h"
- #include "symtype.h"
- #include "bi_vars.h"
- #include "field.h"
-
- #define PROGRAM_FROM_CMDLINE 1
-
- /* static protos */
- static void PROTO( no_program, (void) ) ;
- static void PROTO( process_cmdline , (int, char **) ) ;
- static void PROTO( set_FS, (char *) ) ;
- static void PROTO( set_dump, (char *) ) ;
-
- #if DOS && ! HAVE_REARGV
- #include <fcntl.h>
- static void PROTO(emit_prompt, (void) ) ;
- #endif
-
- union tbuff temp_buff ;
- char *main_buff = temp_buff.string_buff + TEMP_BUFF_SZ ;
-
- void initialize(argc, argv)
- int argc ; char **argv ;
- {
- bi_vars_init() ; /* load the builtin variables */
- bi_funct_init() ; /* load the builtin functions */
- kw_init() ; /* load the keywords */
- field_init() ;
- process_cmdline(argc, argv) ;
-
- jmp_stacks_init() ;
- code_init() ;
- fpe_init() ;
-
- #if NO_STRTOD
- strtod_init() ;
- #endif
-
- }
-
- void compile_cleanup()
- /* program has parsed OK, free some memory
- we don't need anymore */
- {
- scan_cleanup() ;
- jmp_stacks_cleanup() ;
- code_cleanup() ;
- }
-
-
- static void no_program()
- { errmsg( 0, "no program") ; mawk_exit(1) ; }
-
- int dump_code ; /* if on dump internal code */
- #ifdef DEBUG
- int dump_RE ; /* if on dump compiled REs */
- #endif
-
- static void set_FS(s)
- char *s ;
- {
- cell_destroy(field+FS) ;
- field[FS].type = C_STRING ;
- field[FS].ptr = (PTR) new_STRING(s) ;
- cast_for_split( cellcpy(&fs_shadow, field+FS) ) ;
- }
-
-
- #ifdef DEBUG
- static void set_dump(s)
- char *s ;
- {
- while ( 1 )
- { switch ( *s )
- { case 'p' :
- case 'P' : yydebug = 1 ; break ;
-
- case 'c' :
- case 'C' : dump_code = 1 ; break ;
-
- case 'r' :
- case 'R' : dump_RE = 1 ; break ;
-
- case 0 :
- if ( s[-1] == 'D' ) dump_code = 1 ;
- return ;
-
- default : break ;
- }
- s++ ;
- }
- }
- #else
- static void set_dump(s)
- char *s ;
- { dump_code = 1 ; }
- #endif
-
- static void process_cmdline(argc, argv)
- int argc ; char **argv ;
- { extern int program_fd ;
- int i ; /* index to walk command line */
- char *p ;
- CELL *cp ;
- SYMTAB *st_p ;
- char xbuff[20] ;
-
-
- for( i = 1 ; i < argc && argv[i][0] == '-' ; i++ )
- { p = & argv[i][1] ;
- if ( *p == 'F' ) set_FS(p+1) ;
-
- else if ( *p == 'D' ) set_dump(p+1) ;
- else if ( *p == 'f' )
- { if ( i == argc - 1 ) no_program() ;
- scan_init(! PROGRAM_FROM_CMDLINE, argv[i+1] ) ;
- i += 2 ;
- goto set_ARGV ;
- }
- }
-
- #if DOS && ! HAVE_REARGV
- /* allows short programs to be typed in without mucking stdin */
- emit_prompt() ;
- scan_init(! PROGRAM_FROM_CMDLINE, "CON") ;
- #else /* the real world */
-
- if ( i == argc ) no_program() ;
- scan_init(PROGRAM_FROM_CMDLINE, argv[i]) ;
- i++ ;
- #endif
-
- set_ARGV:
-
- /* now set up ARGC and ARGV */
- st_p = insert( "ARGV" ) ;
- st_p->type = ST_ARRAY ;
- Argv = st_p->stval.array = new_ARRAY() ;
- xbuff[0] = '0' ; xbuff[1] = 0 ;
- cp = array_find( st_p->stval.array, xbuff, 1) ;
- 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 */
- { int arg_count = 1 ;
-
- for( ; i < argc ; i++, arg_count++ )
- {
- if ( arg_count < 10 ) xbuff[0] = arg_count + '0' ;
- else (void) sprintf(xbuff, "%u" , arg_count ) ;
- cp = array_find( st_p->stval.array, xbuff, 1) ;
- cp->type = C_MBSTRN ;
- cp->ptr = (PTR) new_STRING( argv[i] ) ;
- }
- bi_vars[ARGC].type = C_DOUBLE ;
- bi_vars[ARGC].dval = (double) arg_count ;
- }
- }
-
- #if DOS && ! HAVE_REARGV
-
- static void emit_prompt()
- { static char prompt[] = DOS_PROMPT ;
- int fd = open("CON", O_WRONLY, 0) ;
-
- (void) write(fd, prompt, strlen(prompt)) ;
- (void) close(fd) ;
- }
- #endif
-
- @//E*O*F mawk0.97/init.c//
- chmod u=rw,g=r,o=r mawk0.97/init.c
-
- echo x - mawk0.97/init.h
- sed 's/^@//' > "mawk0.97/init.h" <<'@//E*O*F mawk0.97/init.h//'
-
- /********************************************
- init.h
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /* $Log: init.h,v $
- * Revision 2.1 91/04/08 08:23:17 brennan
- * VERSION 0.97
- *
- */
-
- /* init.h */
-
-
- #ifndef INIT_H
- #define INIT_H
-
-
- void PROTO( initialize, (int, char **) ) ;
- void PROTO( code_init, (void) ) ;
- void PROTO( code_cleanup, (void) ) ;
- void PROTO( compile_cleanup, (void) ) ;
- void PROTO(scan_init, (int, char *) ) ;
- void PROTO(scan_cleanup, (void) ) ;
- void PROTO(bi_vars_init, (void) ) ;
- void PROTO(bi_funct_init, (void) ) ;
- void PROTO(print_init, (void) ) ;
- void PROTO(kw_init, (void) ) ;
- void PROTO(jmp_stacks_init, (void) ) ;
- void PROTO(jmp_stacks_cleanup, (void) ) ;
- void PROTO( field_init, (void) ) ;
- void PROTO( fpe_init, (void) ) ;
-
- #endif /* INIT_H */
- @//E*O*F mawk0.97/init.h//
- chmod u=rw,g=r,o=r mawk0.97/init.h
-
- echo x - mawk0.97/jmp.c
- sed 's/^@//' > "mawk0.97/jmp.c" <<'@//E*O*F mawk0.97/jmp.c//'
-
- /********************************************
- jmp.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /* $Log: jmp.c,v $
- * Revision 2.1 91/04/08 08:23:19 brennan
- * VERSION 0.97
- *
- */
-
- /* this module deals with back patching jumps, breaks and continues,
- and with save and restoring code when we move code.
- There are three stacks. If we encounter a compile error, the
- stacks are frozen, i.e., we do not attempt error recovery
- on the stacks
- */
-
-
- #include "mawk.h"
- #include "jmp.h"
- #include "code.h"
- #include "sizes.h"
- #include "init.h"
- #include "memory.h"
-
- extern unsigned compile_error_count ;
- #define error_state (compile_error_count>0)
-
-
- /* a stack to hold jumps that need to be patched */
-
- #define JMP_STK_SZ (2*MAX_LOOP_DEPTH)
-
- static INST **jmp_stack ;
- static INST **jmp_sp ;
-
- /*-------------------------------------*/
- /* a stack to hold break or continue that need to be
- patched (which is all of them) */
-
- #define BC_SZ MAX_LOOP_DEPTH
-
- /* the stack holds a linked list of these */
-
- struct BC_node { /* struct for the break/continue list */
- char type ; /* 'B' or 'C' */
- INST *jmp ; /* the jump to patch */
- struct BC_node *link ;
- } ;
-
- static struct BC_node **BC_stack ;
- static struct BC_node **BC_sp ;
-
- /*---------------------------------------*/
- /* a stack to hold some pieces of code while
- reorganizing loops */
-
- #define LOOP_CODE_SZ (2*MAX_LOOP_DEPTH)
-
- static struct loop_code {
- INST *code ;
- unsigned short len ;
- } *loop_code_stack , *lc_sp ;
-
- /*--------------------------------------*/
- void jmp_stacks_init()
- { jmp_stack = (INST **) zmalloc(JMP_STK_SZ*sizeof(INST*)) ;
- jmp_sp = jmp_stack-1 ;
-
- BC_stack = (struct BC_node **)
- zmalloc(BC_SZ*sizeof(struct BC_node*)) ;
- BC_sp = BC_stack-1 ;
-
- loop_code_stack = (struct loop_code *)
- zmalloc(LOOP_CODE_SZ*sizeof(struct loop_code)) ;
- lc_sp = loop_code_stack - 1 ;
- }
-
- void jmp_stacks_cleanup()
- { zfree(jmp_stack, JMP_STK_SZ*sizeof(INST*)) ;
- zfree(BC_stack, BC_SZ*sizeof(struct BC_node*)) ;
- zfree(loop_code_stack, LOOP_CODE_SZ*sizeof(struct loop_code)) ;
- }
- /*--------------------------------------*/
- /* operations on the jmp_stack */
-
- void code_jmp( jtype, target)
- int jtype ; INST *target ;
- {
- if (error_state) return ;
-
- /* check if a constant expression will be at top of stack,
- if so replace conditional jump with jump */
-
- if ( code_ptr[-2].op == _PUSHC && jtype != _JMP )
- { int t = test( (CELL *) code_ptr[-1].ptr ) ;
- if ( jtype == _JZ && ! t ||
- jtype == _JNZ && t )
- { code_ptr -= 2 ; jtype = _JMP ; }
- }
-
- if ( ! target ) /* jump will have to be patched later ,
- put it on the jmp_stack */
- { if ( ++jmp_sp == jmp_stack + JMP_STK_SZ )
- overflow("jmp stack" , JMP_STK_SZ ) ;
- *jmp_sp = code_ptr ;
- code2(jtype, 0) ;
- }
- else
- { INST *source = code_ptr ;
-
- code_ptr++->op = jtype ;
- code_ptr++->op = target - source ;
- }
- }
-
- void patch_jmp(target) /* patch a jump on the jmp_stack */
- INST *target ;
- { register INST *source ;
-
- if ( ! error_state )
- {
- if ( jmp_sp <= jmp_stack-1 ) bozo("jmp stack underflow") ;
- source = *jmp_sp-- ;
- source[1].op = target - source ;
- }
- }
-
-
- /*---------------------------*/
-
- /* a stack of linked lists of BC_nodes for patching
- break and continue statements. */
-
-
- void BC_new() /* push an empty list on the stack */
- {
- if ( ! error_state )
- { if ( ++BC_sp == BC_stack + BC_SZ ) overflow("BC stack", BC_SZ) ;
- * BC_sp = (struct BC_node *) 0 ;
- }
- }
-
- void BC_insert(type, address)
- int type ; INST *address ;
- { register struct BC_node *p ;
-
- if ( error_state ) return ;
- if ( BC_sp <= BC_stack - 1 )
- { compile_error( type == 'B' ?
- "break statement outside of loop" :
- "continue statement outside of loop" ) ;
- return ;
- }
-
- p = (struct BC_node *) zmalloc( sizeof(struct BC_node) ) ;
- p->type = type ; p->jmp = address ;
- p->link = *BC_sp ; *BC_sp = p ;
- }
-
- void BC_clear(B_address, C_address)
- /* patch all break and continues on list */
- INST *B_address, *C_address ;
- { register struct BC_node *p , *q ;
-
- if (error_state) return ;
- if ( BC_sp <= BC_stack-1) bozo("underflow on BC stack") ;
- p = *BC_sp-- ;
- while ( p )
- { p->jmp[1].op = (p->type=='B' ? B_address : C_address) - p->jmp ;
- q = p ; p = p->link ; zfree(q, sizeof(struct BC_node)) ;
- }
- }
-
- /*---------------------------------------------*/
- /* save and restore some code for reorganizing
- loops on a stack */
-
-
- void code_push( p, len)
- INST *p ; unsigned len ;
- {
- if (error_state) return ;
- if ( ++lc_sp == loop_code_stack + LOOP_CODE_SZ )
- overflow("loop_code_stack" , LOOP_CODE_SZ) ;
-
- if ( len )
- { lc_sp->code = (INST *) zmalloc(sizeof(INST) * len) ;
- (void) memcpy(lc_sp->code, p, sizeof(INST) * len) ; }
- else lc_sp->code = (INST *) 0 ;
- lc_sp->len = (unsigned short) len ;
- }
-
- /* copy the code at the top of the loop code stack to target.
- return the number of bytes moved */
-
- unsigned code_pop(target)
- INST *target ;
- {
- if (error_state) return 0 ;
- if ( lc_sp <= loop_code_stack-1 ) bozo("loop code stack underflow") ;
- if ( lc_sp->len )
- { (void) memcpy(target, lc_sp->code, lc_sp->len * sizeof(INST)) ;
- zfree(lc_sp->code, sizeof(INST)*lc_sp->len) ; }
- return lc_sp-- -> len ;
- }
- @//E*O*F mawk0.97/jmp.c//
- chmod u=rw,g=r,o=r mawk0.97/jmp.c
-
- echo x - mawk0.97/jmp.h
- sed 's/^@//' > "mawk0.97/jmp.h" <<'@//E*O*F mawk0.97/jmp.h//'
-
- /********************************************
- jmp.h
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /* $Log: jmp.h,v $
- * Revision 2.1 91/04/08 08:23:21 brennan
- * VERSION 0.97
- *
- */
-
- #ifndef JMP_H
- #define JMP_H
-
- void PROTO(BC_new, (void) ) ;
- void PROTO(BC_insert, (int, INST*) ) ;
- void PROTO(BC_clear, (INST *, INST *) ) ;
- void PROTO(code_push, (INST *, unsigned) ) ;
- unsigned PROTO(code_pop, (INST *) ) ;
- void PROTO(code_jmp, (int, INST *) ) ;
- void PROTO(patch_jmp, (INST *) ) ;
-
-
- #endif /* JMP_H */
-
- @//E*O*F mawk0.97/jmp.h//
- chmod u=rw,g=r,o=r mawk0.97/jmp.h
-
- echo x - mawk0.97/kw.c
- sed 's/^@//' > "mawk0.97/kw.c" <<'@//E*O*F mawk0.97/kw.c//'
-
- /********************************************
- kw.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: kw.c,v $
- * Revision 2.1 91/04/08 08:23:23 brennan
- * VERSION 0.97
- *
- */
-
-
- /* kw.c */
-
-
- #include "mawk.h"
- #include "symtype.h"
- #include "parse.h"
- #include "init.h"
-
-
- static struct kw {
- char *text ;
- short kw ;
- } keywords[] = {
-
- "print", PRINT,
- "printf", PRINTF,
- "do" , DO ,
- "while" , WHILE ,
- "for" , FOR ,
- "break" , BREAK ,
- "continue" , CONTINUE ,
- "if" , IF ,
- "else", ELSE ,
- "in" , IN ,
- "delete", DELETE ,
- "split" , SPLIT ,
- "match" , MATCH_FUNC ,
- "BEGIN" , BEGIN,
- "END" , END ,
- "exit" , EXIT ,
- "next" , NEXT ,
- "return", RETURN,
- "getline", GETLINE,
- "sub" , SUB,
- "gsub", GSUB,
- "function", FUNCTION,
- (char *) 0 , 0 } ;
-
- /* put keywords in the symbol table */
- void kw_init()
- { register struct kw *p = keywords ;
- register SYMTAB *q ;
-
- while ( p->text )
- { q = insert( p->text ) ;
- q->type = ST_KEYWORD ;
- q->stval.kw = p++ -> kw ;
- }
- }
-
- /* find a keyword to emit an error message */
- char *find_kw_str( kw_token )
- int kw_token ;
- { struct kw *p = keywords ;
-
- for( p = keywords ; p->text ; p++ )
- if ( p->kw == kw_token ) return p->text ;
- /* search failed */
- return (char *) 0 ;
- }
- @//E*O*F mawk0.97/kw.c//
- chmod u=rw,g=r,o=r mawk0.97/kw.c
-
- echo x - mawk0.97/machine.h
- sed 's/^@//' > "mawk0.97/machine.h" <<'@//E*O*F mawk0.97/machine.h//'
-
- /********************************************
- machine.h
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
- /*$Log: machine.h,v $
- * Revision 2.2 91/04/09 12:39:14 brennan
- * added static to funct decls to satisfy STARDENT compiler
- *
- * Revision 2.1 91/04/08 08:23:25 brennan
- * VERSION 0.97
- *
- */
-
-
- /* I've attempted to isolate machine/system dependencies here.
-
- Floating point exceptions are the biggest hassle.
- If you have IEEE754 floating point, turn off floating point
- traps and let the INFs and NANs go berserk. This should be
- the default (see page 14 of IEEE754), but ANSI C seems to imply
- they should be on (i.e., one standards committee does not talk to
- the other). Anyway, define a macro TURNOFF_FPE_TRAPS() which will
- probably be a 1 liner.
-
- If you cannot turn off floating exceptions, check out
- fpe_catch() in matherr.c and modify as needed for your machine.
- Also you may need to define FPE_ZERODIVIDE and FPE_OVERFLOW.
-
- If you have SysV like matherr(), use it.
- If you have SysV compatible math lib , use it.
- You might need to supply a macro to replace drand48(), otherwise.
- (See BSD43 for no IEEE754, no matherr(), no fmod(),
- no strtod(), no drand48())
-
- If you have to be conservative with memory (e.g., small model
- MsDos), a small evaluation stack (16-32) is plenty.
- Recursive functions calls are the only reason you need a big
- stack. The default for MsDos uses 64 which allows some
- recursion without killing too many memory CELLs.
- */
-
- /* MsDOS --
- If you use command.com as the shell, entering programs on the
- command line is hopeless. Command.com will always glom onto
- | or < or > as redirection.
-
- If you use a Unix style shell under DOS, then you need to
- write
-
- void reargv(int *argc, char ***argv)
-
- which gets the arguments from your shell, and then
-
- #define HAVE_REARGV 1
-
- See README in dos directory
- and MsDos section of manual.
- */
-
- #ifndef MACHINE_H
- #define MACHINE_H
-
-
- #ifdef sun /* sun3 or sun4 with SUNOS 4.0.3 */
- #define FPE_TRAPS 0
- #define TURNOFF_FPE_TRAPS() /* empty, default is off */
- #define HAVE_MATHERR 1
- #endif
-
- #ifdef __TURBOC__
- #define DOS 1
- #define SMALL_EVAL_STACK 1
- #define FPE_TRAPS 0
- #define TURNOFF_FPE_TRAPS() _control87(0x3f,0x3f)
- #define HAVE_MATHERR 1
- #endif
-
- #ifdef ULTRIX /* V4.1 on a vax 3600 */
- #define HAVE_VOID_PTR 1
- #define HAVE_MATHERR 1
- #define FPE_ZERODIVIDE FPE_FLTDIV_FAULT
- #define FPE_OVERFLOW FPE_FLTOVF_FAULT
- #endif
-
- #ifdef BSD43 /* on a vax */
- #define NO_STRTOD 1
- #define NO_FMOD 1
- #define srand48(x) srandom(x)
- #define drand48() (((double)random())/((double)(unsigned)0x80000000))
- #define vfprintf(s,f,a) _doprnt(f,a,s)
- #define FPE_ZERODIVIDE FPE_FLTDIV_FAULT
- #define FPE_OVERFLOW FPE_FLTOVF_FAULT
- #endif
-
- #ifdef STARDENT /* Stardent 3000, SysV R3.0 */
- #define HAVE_MATHERR 1
- #define FPE_TRAPS 0
- #define TURNOFF_FPE_TRAPS() /* nothing */
- #define HAVE_VOID_PTR 1
- #endif
-
- /* the defaults */
- #ifndef HAVE_VOID_PTR
- #define HAVE_VOID_PTR 0 /* no void * */
- #endif
-
- #ifndef FPE_TRAPS
- #define FPE_TRAPS 1
- /* floating point errors generate exceptions */
- #endif
-
- #ifndef HAVE_MATHERR
- #define HAVE_MATHERR 0
- /* SysV style matherr() is not available */
- #endif
-
- #ifndef NO_STRTOD
- #define NO_STRTOD 0 /* default is have */
- #endif
-
- #ifndef SMALL_EVAL_STACK
- #define SMALL_EVAL_STACK 0
- #endif
-
- #ifndef NO_FMOD
- #define NO_FMOD 0 /* default is to have fmod() */
- #endif
-
- #define STDC_MATHERR (FPE_TRAPS && ! HAVE_MATHERR)
-
- #ifndef DOS
- #define DOS 0
- #endif
-
- #if DOS
-
- #ifndef HAVE_REARGV
- #define HAVE_REARGV 0
- #endif
-
- #define DOS_PROMPT "mawk> "
- /* change to "mawk \01 " on a good day */
- #endif
-
-
-
-
-
- #endif /* MACHINE_H */
- @//E*O*F mawk0.97/machine.h//
- chmod u=rw,g=r,o=r mawk0.97/machine.h
-
- echo x - mawk0.97/main.c
- sed 's/^@//' > "mawk0.97/main.c" <<'@//E*O*F mawk0.97/main.c//'
-
- /********************************************
- main.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
- /* $Log: main.c,v $
- * Revision 2.2 91/04/22 08:08:58 brennan
- * cannot close(3) or close(4) because of bug in TurboC++ 1.0
- *
- * Revision 2.1 91/04/08 08:23:27 brennan
- * VERSION 0.97
- *
- */
-
-
-
- /* main.c */
-
- #include "mawk.h"
- #include "code.h"
- #include "init.h"
- #include "fin.h"
- #include "bi_vars.h"
- #include "field.h"
- #include "files.h"
- #include <stdio.h>
-
- #if DOS
- void reargv(int *, char ***) ;
- #endif
-
-
- void PROTO( process, (void) ) ;
- void PROTO( main_loop, (void) ) ;
-
- extern int program_fd ;
- char *progname ;
-
- jmp_buf exit_jump, next_jump ;
- int exit_code ;
-
-
- main(argc , argv )
- int argc ; char **argv ;
- {
-
- #if DOS
- progname = "mawk" ;
- #if HAVE_REARGV
- reargv(&argc, &argv) ;
- #endif
- #else
- { char *strrchr() ;
- char *p = strrchr(argv[0], '/') ;
- progname = p ? p+1 : argv[0] ; }
- #endif
-
- initialize(argc, argv) ;
-
- if ( parse() || compile_error_count ) exit(1) ;
-
- compile_cleanup() ;
- process() ;
-
- mawk_exit( exit_code ) ;
- return 0 ;
- }
-
-
- static void process()
- {
-
- if ( setjmp(exit_jump) )
- { if ( begin_start ) zfree(begin_start, begin_size) ;
- goto the_exit ;
- }
-
- if ( begin_start )
- { (void) execute(begin_start, eval_stack-1, 0) ;
- zfree( begin_start , begin_size ) ;
- begin_start = (INST *) 0 ;
- }
-
- if ( main_start || end_start ) main_loop() ;
-
- the_exit:
-
- if ( setjmp(exit_jump) ) mawk_exit(exit_code) ;
-
- if ( main_start ) zfree(main_start, main_size) ;
- if ( end_start ) (void) execute(end_start, eval_stack-1, 0) ;
- }
-
-
- static void main_loop()
- { register char *p ;
- unsigned len ;
-
- /* the main file stream might already be open by a call of
- getline in the BEGIN block */
-
- if ( main_fin == (FIN *) -1 && ! open_main()
- || ! main_fin ) return ;
-
- if ( main_start )
- {
- (void) setjmp(next_jump) ;
-
- while ( p = FINgets( main_fin, &len ) )
- {
- if ( TEST2(bi_vars + NR) != TWO_DOUBLES )
- cast2_to_d(bi_vars + NR) ;
-
- bi_vars[NR].dval += 1.0 ;
- bi_vars[FNR].dval += 1.0 ;
-
- set_field0(p, len) ;
- (void) execute( main_start, eval_stack-1, 0) ;
- }
- }
- else /* eat main to set NR and FNR before executing END */
- { long nr ;
-
- if ( TEST2(bi_vars+NR) != TWO_DOUBLES ) cast2_to_d(bi_vars+NR) ;
- nr = (long) bi_vars[NR].dval ;
- while ( FINgets( main_fin, &len ) )
- { nr++ ; bi_vars[FNR].dval += 1.0 ; }
- bi_vars[NR].dval = (double) nr ;
- }
- }
-
-
- void mawk_exit(x)
- int x ;
- {
- #if ! DOS
- close_out_pipes() ; /* no effect, if no out pipes */
- #endif
- exit(x) ;
- }
- @//E*O*F mawk0.97/main.c//
- chmod u=rw,g=r,o=r mawk0.97/main.c
-
- echo x - mawk0.97/makescan.c
- sed 's/^@//' > "mawk0.97/makescan.c" <<'@//E*O*F mawk0.97/makescan.c//'
-
- /********************************************
- makescan.c
- copyright 1991, Michael D. Brennan
-
- This is a source file for mawk, an implementation of
- the Awk programming language as defined in
- Aho, Kernighan and Weinberger, The AWK Programming Language,
- Addison-Wesley, 1988.
-
- See the accompaning file, LIMITATIONS, for restrictions
- regarding modification and redistribution of this
- program in source or binary form.
- ********************************************/
-
-
-
- /*$Log: makescan.c,v $
- * Revision 2.1 91/04/08 08:23:29 brennan
- * VERSION 0.97
- *
- */
-
- /* source for makescan.exe which builds the scancode[]
- via: makescan.exe > scancode.c
- */
-
- #define MAKESCAN
-
- #include "scan.h"
-
- char scan_code[256] ;
-
- void scan_init()
- {
- register char *p ;
-
- (void) memset(scan_code, SC_UNEXPECTED, sizeof(scan_code)) ;
- for( p = scan_code + '0' ; p <= scan_code + '9' ; p++ )
- *p = SC_DIGIT ;
- scan_code[0] = 0 ;
- scan_code[ ' ' ] = scan_code['\t'] = scan_code['\f'] = SC_SPACE ;
- scan_code[ '\r'] = scan_code['\013'] = SC_SPACE ;
-
- scan_code[';'] = SC_SEMI_COLON ;
- scan_code['\n'] = SC_NL ;
- scan_code['{'] = SC_LBRACE ;
- scan_code[ '}'] = SC_RBRACE ;
- scan_code['+'] = SC_PLUS ;
- scan_code['-'] = SC_MINUS ;
- scan_code['*'] = SC_MUL ;
- scan_code['/'] = SC_DIV ;
- scan_code['%'] = SC_MOD ;
- scan_code['^'] = SC_POW ;
- scan_code['('] = SC_LPAREN ;
- scan_code[')'] = SC_RPAREN ;
- scan_code['_'] = SC_IDCHAR ;
- scan_code['='] = SC_EQUAL ;
- scan_code['#'] = SC_COMMENT ;
- scan_code['\"'] = SC_DQUOTE ;
- scan_code[','] = SC_COMMA ;
- scan_code['!'] = SC_NOT ;
- scan_code['<'] = SC_LT ;
- scan_code['>'] = SC_GT ;
- scan_code['|'] = SC_OR ;
-