home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / gawk2.0.t.Z / gawk2.0.t / awk1.c < prev    next >
C/C++ Source or Header  |  1988-12-31  |  20KB  |  881 lines

  1.  
  2. /*
  3.  * awk1 -- Expression tree constructors and main program for gawk. 
  4.  *
  5.  * Copyright (C) 1986 Free Software Foundation Written by Paul Rubin, August
  6.  * 1986 
  7.  *
  8.  * $Log:    awk1.c,v $
  9.  * Revision 1.29  88/12/08  15:57:41  david
  10.  * *** empty log message ***
  11.  * 
  12.  * Revision 1.28  88/12/07  20:00:15  david
  13.  * changes for incorporating source filename into error messages
  14.  * 
  15.  * Revision 1.27  88/12/01  15:05:26  david
  16.  * changes to allow source line number printing in error messages
  17.  * 
  18.  * Revision 1.26  88/11/28  20:12:30  david
  19.  * unbuffer stdout if compiled with DEBUG
  20.  * 
  21.  * Revision 1.25  88/11/23  21:39:57  david
  22.  * Arnold: set strict if invoked as "awk"
  23.  * 
  24.  * Revision 1.24  88/11/22  13:47:40  david
  25.  * Arnold: changes for case-insensitive matching
  26.  * 
  27.  * Revision 1.23  88/11/15  10:18:57  david
  28.  * Arnold: cleanup; allow multiple -f options; if invoked as awk disable
  29.  * -v option for compatability
  30.  * 
  31.  * Revision 1.22  88/11/14  21:54:27  david
  32.  * Arnold: cleanup
  33.  * 
  34.  * Revision 1.21  88/11/03  15:22:22  david
  35.  * revised flags
  36.  * 
  37.  * Revision 1.20  88/11/01  11:47:24  david
  38.  * mostly cleanup and code movement
  39.  * 
  40.  * Revision 1.19  88/10/19  21:56:00  david
  41.  * replace malloc with emalloc
  42.  * 
  43.  * Revision 1.18  88/10/17  20:57:19  david
  44.  * Arnold: purge FAST
  45.  * 
  46.  * Revision 1.17  88/10/14  22:11:24  david
  47.  * pathc from Hack to get gcc to work
  48.  * 
  49.  * Revision 1.16  88/10/13  21:55:08  david
  50.  * purge FAST; clean up error messages
  51.  * 
  52.  * Revision 1.15  88/10/06  21:55:20  david
  53.  * be more careful about I/O errors on exit
  54.  * Arnold's fixes for command line processing
  55.  * 
  56.  * Revision 1.14  88/10/06  15:52:24  david
  57.  * changes from Arnold: use getopt; ifdef -v option; change semantics of = args.
  58.  * 
  59.  * Revision 1.13  88/09/26  10:16:35  david
  60.  * cleanup from Arnold
  61.  * 
  62.  * Revision 1.12  88/09/19  20:38:29  david
  63.  * added -v option
  64.  * set FILENAME to "-" if stdin
  65.  * 
  66.  * Revision 1.11  88/08/09  14:49:23  david
  67.  * reorganized handling of command-line arguments and files
  68.  * 
  69.  * Revision 1.10  88/06/13  18:08:25  david
  70.  * delete \a and -R options
  71.  * separate exit value from flag indicating that exit has been called
  72.  * [from Arnold]
  73.  * 
  74.  * Revision 1.9  88/06/05  22:19:41  david
  75.  * func_level goes away; param_counter is used to count order of local vars.
  76.  * 
  77.  * Revision 1.8  88/05/31  09:21:56  david
  78.  * Arnold's portability changes (vprintf)
  79.  * fixed handling of function parameter use inside function
  80.  * 
  81.  * Revision 1.7  88/05/30  09:51:17  david
  82.  * exit after yyparse() if any errors were encountered
  83.  * mk_re_parse() parses C escapes in regexps.
  84.  * do panic() properly with varargs
  85.  * clean up and simplify pop_var()
  86.  * 
  87.  * Revision 1.6  88/05/26  22:46:19  david
  88.  * minor changes: break out separate case for making regular expressions
  89.  *   from parser vs. from strings
  90.  * 
  91.  * Revision 1.5  88/05/13  22:02:31  david
  92.  * moved BEGIN and END block merging into parse-phase (sorry Arnold)
  93.  * if there is only a BEGIN block and nothing else, don't read any files
  94.  * cleaned up func_install a bit
  95.  * 
  96.  * Revision 1.4  88/05/04  12:18:28  david
  97.  * make_for_loop() now returns a NODE *
  98.  * pop_var() now returns the value of the node being popped, to be used
  99.  * in func_call() if the variable is an array (call by reference)
  100.  * 
  101.  * Revision 1.3  88/04/15  13:12:19  david
  102.  * small fix to arg reading code
  103.  * 
  104.  * Revision 1.2  88/04/14  14:40:25  david
  105.  * Arnold's changes to read program from a file
  106.  * 
  107.  * Revision 1.1  88/04/08  15:14:52  david
  108.  * Initial revision
  109.  *  Revision 1.6  88/04/08  14:48:30  david changes from
  110.  * Arnold Robbins 
  111.  *
  112.  * Revision 1.5  88/03/28  14:13:33  david *** empty log message *** 
  113.  *
  114.  * Revision 1.4  88/03/23  22:17:33  david mostly delinting -- a couple of bug
  115.  * fixes 
  116.  *
  117.  * Revision 1.3  88/03/18  21:00:09  david Baseline -- hoefully all the
  118.  * functionality of the new awk added. Just debugging and tuning to do. 
  119.  *
  120.  * Revision 1.2  87/11/19  14:40:17  david added support for user-defined
  121.  * functions 
  122.  *
  123.  * Revision 1.1  87/10/27  15:23:26  david Initial revision 
  124.  *
  125.  */
  126.  
  127. /*
  128.  * GAWK is distributed in the hope that it will be useful, but WITHOUT ANY
  129.  * WARRANTY.  No author or distributor accepts responsibility to anyone for
  130.  * the consequences of using it or for whether it serves any particular
  131.  * purpose or works at all, unless he says so in writing. Refer to the GAWK
  132.  * General Public License for full details. 
  133.  *
  134.  * Everyone is granted permission to copy, modify and redistribute GAWK, but
  135.  * only under the conditions described in the GAWK General Public License.  A
  136.  * copy of this license is supposed to have been given to you along with GAWK
  137.  * so you can know your rights and responsibilities.  It should be in a file
  138.  * named COPYING.  Among other things, the copyright notice and this notice
  139.  * must be preserved on all copies. 
  140.  *
  141.  * In other words, go ahead and share GAWK, but don't try to stop anyone else
  142.  * from sharing it farther.  Help stamp out software hoarding! 
  143.  */
  144.  
  145. #include "awk.h"
  146.  
  147. NODE *expression_value;
  148.  
  149. struct hashnode *variables[HASHSIZE];
  150.  
  151. /*
  152.  * Temporary nodes are stored here.  ob_dummy is a dummy object used to keep
  153.  * the obstack library from free()ing up the entire stack.  
  154.  */
  155. struct obstack temp_strings;
  156. char *ob_dummy;
  157.  
  158. /*
  159.  * The parse tree and field nodes are stored here.  Parse_end is a dummy item
  160.  * used to free up unneeded fields without freeing the program being run 
  161.  */
  162. struct obstack other_stack;
  163. struct obstack var_stack;
  164. char *parse_end;
  165. int errcount = 0;    /* error counter, used by yyerror() */
  166. int param_counter;
  167.  
  168. /* The global null string */
  169. NODE *Nnull_string;
  170.  
  171. /* The special variable that contains the name of the current input file */
  172. extern NODE *FILENAME_node;
  173. extern NODE *ARGC_node;
  174. extern NODE *ARGV_node;
  175.  
  176. /* The name the program was invoked under, for error messages */
  177. char *myname;
  178.  
  179. /* A block of AWK code to be run before running the program */
  180. NODE *begin_block = 0;
  181.  
  182. /* A block of AWK code to be run after the last input file */
  183. NODE *end_block = 0;
  184.  
  185. FILE *input_file;        /* Where to read from */
  186.  
  187. int exiting = 0;        /* Was an "exit" statement executed? */
  188. int exit_val = 0;        /* optional exit value */
  189.  
  190. #ifdef DEBUG
  191. /* non-zero means in debugging is enabled.  Probably not very useful */
  192. int debugging = 0;
  193.  
  194. #endif
  195.  
  196. int tempsource = 0;        /* source is in a temp file */
  197. char **sourcefile = NULL;    /* source file name(s) */
  198. int numfiles = -1;        /* how many source files */
  199.  
  200. int ignorecase = 0;        /* global flag for ignoring case */
  201.  
  202. int strict = 0;            /* turn off gnu extensions */
  203.  
  204. main(argc, argv)
  205. int argc;
  206. char **argv;
  207. {
  208. #ifdef DEBUG
  209.     /* Print out the parse tree.   For debugging */
  210.     register int dotree = 0;
  211.     extern int yydebug;
  212.  
  213. #endif
  214.     extern char *lexptr;
  215.     extern char *lexptr_begin;
  216.     extern char *version_string;
  217.     extern FILE *nextfile();
  218.     extern char *alloca();
  219.     FILE *fp, *fopen();
  220. #ifndef OSK
  221.     static char template[] = "/tmp/gawk.XXXXX";
  222. #else
  223.     static char template[] = "/dd/tmp/gawk.XXXXX";
  224. #endif
  225.      char *mktemp ();
  226.     int c;
  227.     extern int opterr, optind, getopt();
  228.     extern char *optarg;
  229.     char *cp, *rindex();
  230.     /*
  231.      * for strict to work, legal options must be first
  232.      */
  233. #define EXTENSIONS    4    /* where to clear */
  234. #ifdef DEBUG
  235.     char *awk_opts = "F:f:ivdD";
  236. #else
  237.     char *awk_opts = "F:f:iv";
  238. #endif
  239.  
  240. #ifdef DEBUG
  241.     /*malloc_debug(2);*/
  242. #endif
  243.     myname = argv[0];
  244.     if (argc < 2)
  245.         usage();
  246.  
  247.     /* Tell the regex routines how they should work. . . */
  248.     (void) re_set_syntax(RE_SYNTAX_AWK);
  249.  
  250.     /* Set up the stack for temporary strings */
  251.     obstack_init(&temp_strings);
  252.     ob_dummy = obstack_alloc(&temp_strings, 0);
  253.  
  254.     /* Set up the other stack for other things */
  255.     obstack_init(&other_stack);
  256.     obstack_init(&var_stack);
  257.     /* initialize the null string */
  258.     Nnull_string = make_string("", 0);
  259.     Nnull_string->numbr = 0.0;
  260.     Nnull_string->type = Node_val;
  261.     Nnull_string->flags = (PERM|STR|NUM);
  262.  
  263.     /* Set up the special variables */
  264.  
  265.     /*
  266.      * Note that this must be done BEFORE arg parsing else -F
  267.      * breaks horribly 
  268.      */
  269.     init_vars();
  270.  
  271.     sourcefile = (char **) alloca(argc * sizeof(char *));    /* worst case */
  272.  
  273.  
  274. #ifdef STRICT    /* strict Unix awk compatibility */
  275.     strict = 1;
  276. #else
  277.     /* if invoked as 'awk', also behave strictly */
  278.     if ((cp = rindex(myname, '/')) != NULL)
  279.         cp++;
  280.     else
  281.         cp = myname;
  282.     if (strcmp (cp, "awk") == 0)
  283.         strict = 1;
  284. #endif
  285.  
  286.     if (strict)
  287.         awk_opts[EXTENSIONS] = '\0';
  288.  
  289.     while ((c = getopt (argc, argv, awk_opts)) != EOF) {
  290.         switch (c) {
  291. #ifdef DEBUG
  292.         case 'd':
  293.             debugging++;
  294.             dotree++;
  295.             break;
  296.  
  297.         case 'D':
  298.             debugging++;
  299.             yydebug = 2;
  300.             break;
  301. #endif
  302.  
  303.         case 'F':
  304.             set_fs(optarg);
  305.             break;
  306.  
  307.         case 'f':
  308.             /*
  309.              * a la MKS awk, allow multiple -f options.
  310.              * this makes function libraries real easy.
  311.              * most of the magic is in the scanner.
  312.              */
  313.             sourcefile[++numfiles] = optarg;
  314.             break;
  315.  
  316.         case 'i':
  317.             ignorecase = 1;
  318.             break;
  319.  
  320.         case 'v':
  321.             fprintf(stderr, "%s", version_string);
  322.             break;
  323.  
  324.         case '?':
  325.         default:
  326.             /* getopt will print a message for us */
  327.             /* S5R4 awk ignores bad options and keeps going */
  328.             break;
  329.         }
  330.     }
  331. #ifdef DEBUG
  332.     setbuf(stdout, (char *) NULL);    /* make debugging easier */
  333. #endif
  334.     /* No -f option, use next arg */
  335.     /* write to temp file and save sourcefile name */
  336.     if (numfiles == -1) {
  337.         int i;
  338.  
  339.         if (optind > argc - 1)    /* no args left */
  340.             usage();
  341.         numfiles++;
  342.         sourcefile[0] = mktemp (template);
  343.         i = strlen (argv[optind]);
  344.         if ((fp = fopen (sourcefile[0], "w")) == NULL)
  345.             fatal("could not save source prog in temp file (%s)",
  346.             sys_errlist[errno]);
  347.         if (fwrite (argv[optind], 1, i, fp) == 0)
  348.             fatal(
  349.             "could not write source program to temp file (%s)",
  350.             sys_errlist[errno]);
  351.         if (argv[optind][i-1] != '\n')
  352.             putc ('\n', fp);
  353.         (void) fclose (fp);
  354.         tempsource++;
  355.         optind++;
  356.     }
  357.     init_args(optind, argc, myname, argv);
  358.  
  359.     /* Read in the program */
  360.     lexptr_begin = lexptr;
  361.     if (yyparse() || errcount)
  362.         exit(1);
  363.  
  364.     /*
  365.      * Anything allocated on the other_stack after here will be freed
  366.      * when the next input line is read. 
  367.      */
  368.     parse_end = obstack_alloc(&other_stack, 0);
  369.  
  370. #ifdef DEBUG
  371.     if (dotree)
  372.         print_parse_tree(expression_value);
  373. #endif
  374.     /* Set up the field variables */
  375.     init_fields();
  376.  
  377.     if (begin_block)
  378.         (void) interpret(begin_block);
  379.     if (!exiting && (expression_value || end_block)) {
  380.         if(input_file)
  381.             do_file(input_file);
  382.         while ((fp = nextfile()) != NULL) {
  383.             do_file(fp);
  384.             if (exiting)
  385.                 break;
  386.         }
  387.     }
  388.     if (end_block)
  389.         (void) interpret(end_block);
  390.     if (flush_io() != 0 && exit_val == 0)
  391.         exit_val = 1;
  392.     if (close_io() != 0 && exit_val == 0)
  393.         exit_val = 1;
  394.     exit(exit_val);
  395. }
  396.  
  397. do_file(fp)
  398. FILE *fp;
  399. {
  400.     input_file = fp;
  401.     /* This is where it spends all its time.  The infamous MAIN LOOP */
  402.     if (inrec() == 0) {
  403.         do {
  404.             /*obstack_free(&temp_strings, ob_dummy);*/
  405.             /*obstack_free(&other_stack, parse_end);*/
  406.         } while (interpret(expression_value) && inrec() == 0);
  407.     }
  408.     if (fp != stdin)
  409.         (void) fclose(fp);
  410. }
  411.  
  412. usage()
  413. {
  414. #ifdef STRICT
  415.     char *opt1 = "[ -Ffs ] -f progfile [ -- ]";
  416.     char *opt2 = "[ -Ffs ] [ -- ] 'program'";
  417. #else
  418.     char *opt1 = "[ -v ] [ -Ffs ] -f progfile [ -- ]";
  419.     char *opt2 = "[ -v ] [ -Ffs ] [ -- ] 'program'";
  420. #endif
  421.  
  422.     fprintf(stderr, "usage: %s %s file ...\n       %s %s file ...\n",
  423.         myname, opt1, myname, opt2);
  424. #ifdef OSK
  425.     exit(1);
  426. #else
  427.     exit(11);
  428. #endif
  429. }
  430.  
  431. NODE *
  432. node_common(op)
  433. NODETYPE op;
  434. {
  435.     register NODE *r;
  436.     extern int lineno;
  437.     extern int numfiles;
  438.     extern int tempsource;
  439.     extern char **sourcefile;
  440.     extern int curinfile;
  441.  
  442.     r = (NODE *) obstack_alloc(&other_stack, sizeof(NODE));
  443.     r->type = op;
  444.     r->source_line = lineno;
  445.     if (numfiles > 1 && !tempsource)
  446.         r->source_file = sourcefile[curinfile];
  447.     else
  448.         r->source_file = NULL;
  449.     return r;
  450. }
  451.  
  452. /*
  453.  * This allocates a node with defined lnode and rnode. 
  454.  * This should only be used by yyparse+co while reading in the program 
  455.  */
  456. NODE *
  457. node(left, op, right)
  458. NODE *left, *right;
  459. NODETYPE op;
  460. {
  461.     register NODE *r;
  462.  
  463.     r = node_common(op);
  464.     r->lnode = left;
  465.     r->rnode = right;
  466.     return r;
  467. }
  468.  
  469. /*
  470.  * This allocates a node with defined subnode and proc
  471.  * Otherwise like node()
  472.  */
  473. NODE *
  474. snode(subn, op, procp)
  475. NODETYPE op;
  476. NODE *(*procp) ();
  477. NODE *subn;
  478. {
  479.     register NODE *r;
  480.  
  481.     r = node_common(op);
  482.     r->subnode = subn;
  483.     r->proc = procp;
  484.     return r;
  485. }
  486.  
  487. /*
  488.  * This allocates a Node_line_range node with defined condpair and
  489.  * zeroes the trigger word to avoid the temptation of assuming that calling
  490.  * 'node( foo, Node_line_range, 0)' will properly initialize 'triggered'. 
  491.  */
  492. /* Otherwise like node() */
  493. NODE *
  494. mkrangenode(cpair)
  495. NODE *cpair;
  496. {
  497.     register NODE *r;
  498.  
  499.     r = (NODE *) obstack_alloc(&other_stack, sizeof(NODE));
  500.     r->type = Node_line_range;
  501.     r->condpair = cpair;
  502.     r->triggered = 0;
  503.     return r;
  504. }
  505.  
  506. struct re_pattern_buffer *
  507. mk_re_parse(s)
  508. char *s;
  509. {
  510.     register char *src, *dest;
  511.     int c;
  512.  
  513.     for (dest = src = s; *src != '\0'; src++) {
  514.         if (*src == '\\') {
  515.             c = *++src;
  516.             switch (c) {
  517.             case 'b':
  518.                 *dest++ = '\b';
  519.                 break;
  520.             case 'f':
  521.                 *dest++ = '\f';
  522.                 break;
  523.             case 'n':
  524.                 *dest++ = '\n';
  525.                 break;
  526.             case 'r':
  527.                 *dest++ = '\r';
  528.                 break;
  529.             case 't':
  530.                 *dest++ = '\t';
  531.                 break;
  532.             case 'v':
  533.                 *dest++ = '\v';
  534.                 break;
  535.             case '0':
  536.             case '1':
  537.             case '2':
  538.             case '3':
  539.             case '4':
  540.             case '5':
  541.             case '6':
  542.             case '7':
  543.                 {
  544.                 register int i = c - '0';
  545.                 register int count = 0;
  546.     
  547.                 while (++count < 3) {
  548.                     if ((c = *++src) >= '0' && c <= '7') {
  549.                         i *= 8;
  550.                         i += c - '0';
  551.                     } else
  552.                         break;
  553.                 }
  554.                 *dest++ = i;
  555.                 }
  556.                 break;
  557.             default:
  558.                 *dest++ = '\\';
  559.                 *dest++ = c;
  560.                 break;
  561.             }
  562.         } else if (*src == '/')
  563.             break;
  564.         else
  565.             *dest++ = *src;
  566.     }
  567.     return make_regexp(tmp_string(s, dest-s));
  568. }
  569.  
  570. /* Generate compiled regular expressions */
  571. struct re_pattern_buffer *
  572. make_regexp(s)
  573. NODE *s;
  574. {
  575.     struct re_pattern_buffer *rp;
  576.     char *err;
  577.  
  578.     emalloc(rp, struct re_pattern_buffer *, sizeof(*rp), "make_regexp");
  579.     bzero((char *) rp, sizeof(*rp));
  580.     emalloc(rp->buffer, char *, 8, "make_regexp");
  581.     /*
  582.      * This could be obstack allocated, except the regex routines
  583.      * try to realloc() it, which fails.
  584.      * Note that this means it may never be freed.  Someone fix, please?
  585.      */
  586.  
  587.     rp->allocated = 8;
  588.     emalloc(rp->fastmap, char *, 256, "make_regexp");
  589.  
  590.     if ((err = re_compile_pattern(s->stptr, s->stlen, rp)) != NULL)
  591.         fatal("%s: /%s/", err, s->stptr);
  592.     return rp;
  593. }
  594.  
  595. /* Build a for loop */
  596. NODE *
  597. make_for_loop(init, cond, incr)
  598. NODE *init, *cond, *incr;
  599. {
  600.     register FOR_LOOP_HEADER *r;
  601.     NODE *n;
  602.  
  603.     r = (FOR_LOOP_HEADER *) obstack_alloc(&other_stack, sizeof(FOR_LOOP_HEADER));
  604.     n = (NODE *) obstack_alloc(&other_stack, sizeof(NODE));
  605.     r->init = init;
  606.     r->cond = cond;
  607.     r->incr = incr;
  608.     n->type = Node_illegal;
  609.     n->sub.nodep.r.hd = r;
  610.     return n;
  611. }
  612.  
  613. /* Name points to a variable name.  Make sure its in the symbol table */
  614. NODE *
  615. variable(name)
  616. char *name;
  617. {
  618.     register NODE *r;
  619.     NODE *lookup(), *install(), *make_name();
  620.  
  621.     if ((r = lookup(variables, name)) == NULL)
  622.         r = install(variables, name,
  623.             node(Nnull_string, Node_var, (NODE *) NULL));
  624.     return r;
  625. }
  626.  
  627. /* Create a special variable */
  628. NODE *
  629. spc_var(name, value)
  630. char *name;
  631. NODE *value;
  632. {
  633.     register NODE *r;
  634.     NODE *lookup(), *install();
  635.  
  636.     if ((r = lookup(variables, name)) == NULL)
  637.         r = install(variables, name, node(value, Node_var, (NODE *) NULL));
  638.     return r;
  639. }
  640.  
  641.  
  642.  
  643. /*
  644.  * Install a name in the hash table specified, even if it is already there.
  645.  * Name stops with first non alphanumeric. Caller must check against
  646.  * redefinition if that is desired. 
  647.  */
  648. NODE *
  649. install(table, name, value)
  650. HASHNODE **table;
  651. char *name;
  652. NODE *value;
  653. {
  654.     register HASHNODE *hp;
  655.     register int i, len, bucket;
  656.     register char *p;
  657.  
  658.     len = 0;
  659.     p = name;
  660.     while (is_identchar(*p))
  661.         p++;
  662.     len = p - name;
  663.  
  664.     i = sizeof(HASHNODE) + len + 1;
  665.     hp = (HASHNODE *) obstack_alloc(&var_stack, i);
  666.     bucket = hashf(name, len, HASHSIZE);
  667.     hp->next = table[bucket];
  668.     table[bucket] = hp;
  669.     hp->length = len;
  670.     hp->value = value;
  671.     hp->name = ((char *) hp) + sizeof(HASHNODE);
  672.     hp->length = len;
  673.     bcopy(name, hp->name, len);
  674.     hp->name[len] = '\0';
  675.     hp->value->varname = hp->name;
  676.     return hp->value;
  677. }
  678.  
  679. /*
  680.  * find the most recent hash node for name name (ending with first
  681.  * non-identifier char) installed by install 
  682.  */
  683. NODE *
  684. lookup(table, name)
  685. HASHNODE **table;
  686. char *name;
  687. {
  688.     register char *bp;
  689.     register HASHNODE *bucket;
  690.     register int len;
  691.  
  692.     for (bp = name; is_identchar(*bp); bp++)
  693.         ;
  694.     len = bp - name;
  695.     bucket = table[hashf(name, len, HASHSIZE)];
  696.     while (bucket) {
  697.         if (bucket->length == len && strncmp(bucket->name, name, len) == 0)
  698.             return bucket->value;
  699.         bucket = bucket->next;
  700.     }
  701.     return NULL;
  702. }
  703.  
  704. #define HASHSTEP(old, c) ((old << 1) + c)
  705. #define MAKE_POS(v) (v & ~0x80000000)    /* make number positive */
  706.  
  707. /*
  708.  * return hash function on name.
  709.  */
  710. int
  711. hashf(name, len, hashsize)
  712. register char *name;
  713. register int len;
  714. int hashsize;
  715. {
  716.     register int r = 0;
  717.  
  718.     while (len--)
  719.         r = HASHSTEP(r, *name++);
  720.  
  721.     r = MAKE_POS(r) % hashsize;
  722.     return r;
  723. }
  724.  
  725. /*
  726.  * Add new to the rightmost branch of LIST.  This uses n^2 time, but doesn't
  727.  * get used enough to make optimizing worth it. . . 
  728.  */
  729. /* You don't believe me?  Profile it yourself! */
  730.  
  731. NODE *
  732. append_right(list, new)
  733. NODE *list, *new;
  734. {
  735.     register NODE *oldlist;
  736.  
  737.     oldlist = list;
  738.     while (list->rnode != NULL)
  739.         list = list->rnode;
  740.     list->rnode = new;
  741.     return oldlist;
  742. }
  743.  
  744. /*
  745.  * check if name is already installed;  if so, it had better have Null value,
  746.  * in which case def is added as the value. Otherwise, install name with def
  747.  * as value. 
  748.  */
  749. func_install(params, def)
  750. NODE *params;
  751. NODE *def;
  752. {
  753.     NODE *r;
  754.     NODE *lookup();
  755.  
  756.     pop_params(params);
  757.     r = lookup(variables, params->param);
  758.     if (r != NULL) {
  759.         fatal("function name `%s' previously defined", params->param);
  760.     } else
  761.         (void) install(variables, params->param,
  762.             node(params, Node_func, def));
  763. }
  764.  
  765. NODE *
  766. pop_var(name)
  767. char *name;
  768. {
  769.     register char *bp;
  770.     register HASHNODE *bucket, **save;
  771.     register int len;
  772.  
  773.     for (bp = name; is_identchar(*bp); bp++)
  774.         ;
  775.     len = bp - name;
  776.     save = &(variables[hashf(name, len, HASHSIZE)]);
  777.     bucket = *save;
  778.     while (bucket) {
  779.         if (strncmp(bucket->name, name, len) == 0) {
  780.             *save = bucket->next;
  781.             return bucket->value;
  782.         }
  783.         save = &(bucket->next);
  784.         bucket = bucket->next;
  785.     }
  786.     return NULL;
  787. }
  788.  
  789. pop_params(params)
  790. NODE *params;
  791. {
  792.     register NODE *np;
  793.  
  794.     for (np = params; np != NULL; np = np->rnode)
  795.         pop_var(np->param);
  796. }
  797.  
  798. NODE *
  799. make_name(name, type)
  800. char *name;
  801. NODETYPE type;
  802. {
  803.     register char *p;
  804.     register NODE *r;
  805.     register int len;
  806.  
  807.     p = name;
  808.     while (is_identchar(*p))
  809.         p++;
  810.     len = p - name;
  811.     r = (NODE *) obstack_alloc(&other_stack, sizeof(NODE));
  812.     r->param = (char *) obstack_alloc(&other_stack, len + 1);
  813.     if (r->param == NULL)
  814.         abort();
  815.     bcopy(name, r->param, len);
  816.     r->param[len] = '\0';
  817.     r->rnode = NULL;
  818.     r->type = type;
  819.     return (install(variables, name, r));
  820. }
  821.  
  822. NODE *make_param(name)
  823. char *name;
  824. {
  825.     NODE *r;
  826.  
  827.     r = make_name(name, Node_param_list);
  828.     r->param_cnt = param_counter++;
  829.     return r;
  830. }
  831.  
  832. FILE *
  833. nextfile()
  834. {
  835.     static int i = 1;
  836.     static int files = 0;
  837.     char *arg;
  838.     char *cp;
  839.     FILE *fp;
  840.     extern NODE **assoc_lookup();
  841.  
  842.     for (; i < (int) (ARGC_node->lnode->numbr); i++) {
  843.         arg = (*assoc_lookup(ARGV_node, tmp_number((AWKNUM) i)))->stptr;
  844.         if (*arg == '\0')
  845.             continue;
  846.         cp = index(arg, '=');
  847.         if (cp != NULL) {
  848.             *cp++ = '\0';
  849.             variable(arg)->var_value = make_string(cp, strlen(cp));
  850.         } else {
  851.             extern NODE *deref;
  852.  
  853.             files++;
  854.             if (strcmp(arg, "-") == 0)
  855.                 fp = stdin;
  856.             else
  857.                 fp = fopen(arg, "r");
  858.             if (fp == NULL)
  859.                 fatal("cannot open file `%s' for reading (%s)",
  860.                     arg, sys_errlist[errno]);
  861.                 /* NOTREACHED */
  862.             /* This is a kludge.  */
  863.             deref = FILENAME_node->var_value;
  864.             do_deref();
  865.             FILENAME_node->var_value =
  866.                 make_string(arg, strlen(arg));
  867.             FNR_node->var_value->numbr = 0.0;
  868.             i++;
  869.             return fp;
  870.         }
  871.     }
  872.     if (files == 0) {
  873.         files++;
  874.         /* no args. -- use stdin */
  875.         /* FILENAME is init'ed to "-" */
  876.         /* FNR is init'ed to 0 */
  877.         return stdin;
  878.     }
  879.     return NULL;
  880. }
  881.