Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/editors/awk.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 114  typedef struct nvblock_s { Line 114  typedef struct nvblock_s {
114   var *pos;   var *pos;
115   struct nvblock_s *prev;   struct nvblock_s *prev;
116   struct nvblock_s *next;   struct nvblock_s *next;
117   var nv[0];   var nv[];
118  } nvblock;  } nvblock;
119    
120  typedef struct tsplitter_s {  typedef struct tsplitter_s {
# Line 250  enum { Line 250  enum {
250    
251  /* builtins */  /* builtins */
252  enum {  enum {
253   B_a2, B_ix, B_ma, B_sp, B_ss, B_ti, B_lo, B_up,   B_a2, B_ix, B_ma, B_sp, B_ss, B_ti,   B_mt, B_lo, B_up,
254   B_ge, B_gs, B_su,   B_ge, B_gs, B_su,
255   B_an, B_co, B_ls, B_or, B_rs, B_xo,   B_an, B_co, B_ls, B_or, B_rs, B_xo,
256  };  };
# Line 299  static const char tokenlist[] ALIGN1 = Line 299  static const char tokenlist[] ALIGN1 =
299   "\4rand"    "\3sin"     "\4sqrt"    "\5srand"   "\4rand"    "\3sin"     "\4sqrt"    "\5srand"
300   "\6gensub"  "\4gsub"    "\5index"   "\6length"   "\6gensub"  "\4gsub"    "\5index"   "\6length"
301   "\5match"   "\5split"   "\7sprintf" "\3sub"   "\5match"   "\5split"   "\7sprintf" "\3sub"
302   "\6substr"  "\7systime" "\10strftime"   "\6substr"  "\7systime" "\10strftime" "\6mktime"
303   "\7tolower" "\7toupper" NTC   "\7tolower" "\7toupper" NTC
304   "\7getline" NTC   "\7getline" NTC
305   "\4func"    "\10function"   NTC   "\4func"    "\10function"   NTC
# Line 353  static const uint32_t tokeninfo[] = { Line 353  static const uint32_t tokeninfo[] = {
353   OC_FBLTIN|F_rn,    OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr,   OC_FBLTIN|F_rn,    OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr,
354   OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), OC_FBLTIN|Sx|F_le,   OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), OC_FBLTIN|Sx|F_le,
355   OC_B|B_ma|P(0x89), OC_B|B_sp|P(0x8b), OC_SPRINTF,        OC_B|B_su|P(0xb6),   OC_B|B_ma|P(0x89), OC_B|B_sp|P(0x8b), OC_SPRINTF,        OC_B|B_su|P(0xb6),
356   OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti,    OC_B|B_ti|P(0x0b),   OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti,    OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b),
357   OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49),   OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49),
358   OC_GETLINE|SV|P(0),   OC_GETLINE|SV|P(0),
359   0, 0,   0, 0,
# Line 366  static const uint32_t tokeninfo[] = { Line 366  static const uint32_t tokeninfo[] = {
366  enum {  enum {
367   CONVFMT,    OFMT,       FS,         OFS,   CONVFMT,    OFMT,       FS,         OFS,
368   ORS,        RS,         RT,         FILENAME,   ORS,        RS,         RT,         FILENAME,
369   SUBSEP,     ARGIND,     ARGC,       ARGV,   SUBSEP,     F0,         ARGIND,     ARGC,
370   ERRNO,      FNR,   ARGV,       ERRNO,      FNR,        NR,
371   NR,         NF,         IGNORECASE,   NF,         IGNORECASE, ENVIRON,    NUM_INTERNAL_VARS
  ENVIRON,    F0,         NUM_INTERNAL_VARS  
372  };  };
373    
374  static const char vNames[] ALIGN1 =  static const char vNames[] ALIGN1 =
375   "CONVFMT\0" "OFMT\0"    "FS\0*"     "OFS\0"   "CONVFMT\0" "OFMT\0"    "FS\0*"     "OFS\0"
376   "ORS\0"     "RS\0*"     "RT\0"      "FILENAME\0"   "ORS\0"     "RS\0*"     "RT\0"      "FILENAME\0"
377   "SUBSEP\0"  "ARGIND\0"  "ARGC\0"    "ARGV\0"   "SUBSEP\0"  "$\0*"      "ARGIND\0"  "ARGC\0"
378   "ERRNO\0"   "FNR\0"   "ARGV\0"    "ERRNO\0"   "FNR\0"     "NR\0"
379   "NR\0"      "NF\0*"     "IGNORECASE\0*"   "NF\0*"     "IGNORECASE\0*" "ENVIRON\0" "\0";
  "ENVIRON\0" "$\0*"      "\0";  
380    
381  static const char vValues[] ALIGN1 =  static const char vValues[] ALIGN1 =
382   "%.6g\0"    "%.6g\0"    " \0"       " \0"   "%.6g\0"    "%.6g\0"    " \0"       " \0"
383   "\n\0"      "\n\0"      "\0"        "\0"   "\n\0"      "\n\0"      "\0"        "\0"
384   "\034\0"   "\034\0"    "\0"        "\377";
  "\377";  
385    
386  /* hash size may grow to these values */  /* hash size may grow to these values */
387  #define FIRST_PRIME 61  #define FIRST_PRIME 61
# Line 489  struct globals2 { Line 486  struct globals2 {
486  #define fsplitter    (G.fsplitter   )  #define fsplitter    (G.fsplitter   )
487  #define rsplitter    (G.rsplitter   )  #define rsplitter    (G.rsplitter   )
488  #define INIT_G() do { \  #define INIT_G() do { \
489   SET_PTR_TO_GLOBALS(xzalloc(sizeof(G1) + sizeof(G)) + sizeof(G1)); \   SET_PTR_TO_GLOBALS((char*)xzalloc(sizeof(G1)+sizeof(G)) + sizeof(G1)); \
490   G.next_token__ltclass = TC_OPTERM; \   G.next_token__ltclass = TC_OPTERM; \
491   G.evaluate__seed = 1; \   G.evaluate__seed = 1; \
492  } while (0)  } while (0)
# Line 519  static const char EMSG_UNDEF_FUNC[] ALIG Line 516  static const char EMSG_UNDEF_FUNC[] ALIG
516  static const char EMSG_NO_MATH[] ALIGN1 = "Math support is not compiled in";  static const char EMSG_NO_MATH[] ALIGN1 = "Math support is not compiled in";
517  #endif  #endif
518    
519  static void zero_out_var(var * vp)  static void zero_out_var(var *vp)
520  {  {
521   memset(vp, 0, sizeof(*vp));   memset(vp, 0, sizeof(*vp));
522  }  }
523    
524  static void syntax_error(const char *const message) NORETURN;  static void syntax_error(const char *message) NORETURN;
525  static void syntax_error(const char *const message)  static void syntax_error(const char *message)
526  {  {
527   bb_error_msg_and_die("%s:%i: %s", g_progname, g_lineno, message);   bb_error_msg_and_die("%s:%i: %s", g_progname, g_lineno, message);
528  }  }
# Line 536  static unsigned hashidx(const char *name Line 533  static unsigned hashidx(const char *name
533  {  {
534   unsigned idx = 0;   unsigned idx = 0;
535    
536   while (*name) idx = *name++ + (idx << 6) - idx;   while (*name)
537     idx = *name++ + (idx << 6) - idx;
538   return idx;   return idx;
539  }  }
540    
# Line 545  static xhash *hash_init(void) Line 543  static xhash *hash_init(void)
543  {  {
544   xhash *newhash;   xhash *newhash;
545    
546   newhash = xzalloc(sizeof(xhash));   newhash = xzalloc(sizeof(*newhash));
547   newhash->csize = FIRST_PRIME;   newhash->csize = FIRST_PRIME;
548   newhash->items = xzalloc(newhash->csize * sizeof(hash_item *));   newhash->items = xzalloc(FIRST_PRIME * sizeof(newhash->items[0]));
549    
550   return newhash;   return newhash;
551  }  }
# Line 557  static void *hash_search(xhash *hash, co Line 555  static void *hash_search(xhash *hash, co
555  {  {
556   hash_item *hi;   hash_item *hi;
557    
558   hi = hash->items [ hashidx(name) % hash->csize ];   hi = hash->items[hashidx(name) % hash->csize];
559   while (hi) {   while (hi) {
560   if (strcmp(hi->name, name) == 0)   if (strcmp(hi->name, name) == 0)
561   return &(hi->data);   return &(hi->data);
# Line 576  static void hash_rebuild(xhash *hash) Line 574  static void hash_rebuild(xhash *hash)
574   return;   return;
575    
576   newsize = PRIMES[hash->nprime++];   newsize = PRIMES[hash->nprime++];
577   newitems = xzalloc(newsize * sizeof(hash_item *));   newitems = xzalloc(newsize * sizeof(newitems[0]));
578    
579   for (i = 0; i < hash->csize; i++) {   for (i = 0; i < hash->csize; i++) {
580   hi = hash->items[i];   hi = hash->items[i];
# Line 607  static void *hash_find(xhash *hash, cons Line 605  static void *hash_find(xhash *hash, cons
605   hash_rebuild(hash);   hash_rebuild(hash);
606    
607   l = strlen(name) + 1;   l = strlen(name) + 1;
608   hi = xzalloc(sizeof(hash_item) + l);   hi = xzalloc(sizeof(*hi) + l);
609   memcpy(hi->name, name, l);   strcpy(hi->name, name);
610    
611   idx = hashidx(name) % hash->csize;   idx = hashidx(name) % hash->csize;
612   hi->next = hash->items[idx];   hi->next = hash->items[idx];
# Line 662  static void skip_spaces(char **s) Line 660  static void skip_spaces(char **s)
660  static char *nextword(char **s)  static char *nextword(char **s)
661  {  {
662   char *p = *s;   char *p = *s;
663     while (*(*s)++)
664   while (*(*s)++) /* */;   continue;
   
665   return p;   return p;
666  }  }
667    
# Line 674  static char nextchar(char **s) Line 671  static char nextchar(char **s)
671    
672   c = *((*s)++);   c = *((*s)++);
673   pps = *s;   pps = *s;
674   if (c == '\\') c = bb_process_escape_sequence((const char**)s);   if (c == '\\')
675   if (c == '\\' && *s == pps) c = *((*s)++);   c = bb_process_escape_sequence((const char**)s);
676     if (c == '\\' && *s == pps)
677     c = *((*s)++);
678   return c;   return c;
679  }  }
680    
# Line 757  static var *setvar_s(var *v, const char Line 756  static var *setvar_s(var *v, const char
756   return setvar_p(v, (value && *value) ? xstrdup(value) : NULL);   return setvar_p(v, (value && *value) ? xstrdup(value) : NULL);
757  }  }
758    
759  /* same as setvar_s but set USER flag */  /* same as setvar_s but sets USER flag */
760  static var *setvar_u(var *v, const char *value)  static var *setvar_u(var *v, const char *value)
761  {  {
762   setvar_s(v, value);   v = setvar_s(v, value);
763   v->type |= VF_USER;   v->type |= VF_USER;
764   return v;   return v;
765  }  }
# Line 768  static var *setvar_u(var *v, const char Line 767  static var *setvar_u(var *v, const char
767  /* set array element to user string */  /* set array element to user string */
768  static void setari_u(var *a, int idx, const char *s)  static void setari_u(var *a, int idx, const char *s)
769  {  {
  char sidx[sizeof(int)*3 + 1];  
770   var *v;   var *v;
771    
772   sprintf(sidx, "%d", idx);   v = findvar(iamarray(a), itoa(idx));
  v = findvar(iamarray(a), sidx);  
773   setvar_u(v, s);   setvar_u(v, s);
774  }  }
775    
# Line 847  static var *copyvar(var *dest, const var Line 844  static var *copyvar(var *dest, const var
844    
845  static var *incvar(var *v)  static var *incvar(var *v)
846  {  {
847   return setvar_i(v, getvar_i(v) + 1.);   return setvar_i(v, getvar_i(v) + 1.0);
848  }  }
849    
850  /* return true if v is number or numeric string */  /* return true if v is number or numeric string */
# Line 861  static int is_numeric(var *v) Line 858  static int is_numeric(var *v)
858  static int istrue(var *v)  static int istrue(var *v)
859  {  {
860   if (is_numeric(v))   if (is_numeric(v))
861   return (v->number == 0) ? 0 : 1;   return (v->number != 0);
862   return (v->string && *(v->string)) ? 1 : 0;   return (v->string && v->string[0]);
863  }  }
864    
865  /* temporary variables allocator. Last allocated should be first freed */  /* temporary variables allocator. Last allocated should be first freed */
# Line 874  static var *nvalloc(int n) Line 871  static var *nvalloc(int n)
871    
872   while (g_cb) {   while (g_cb) {
873   pb = g_cb;   pb = g_cb;
874   if ((g_cb->pos - g_cb->nv) + n <= g_cb->size) break;   if ((g_cb->pos - g_cb->nv) + n <= g_cb->size)
875     break;
876   g_cb = g_cb->next;   g_cb = g_cb->next;
877   }   }
878    
# Line 885  static var *nvalloc(int n) Line 883  static var *nvalloc(int n)
883   g_cb->pos = g_cb->nv;   g_cb->pos = g_cb->nv;
884   g_cb->prev = pb;   g_cb->prev = pb;
885   /*g_cb->next = NULL; - xzalloc did it */   /*g_cb->next = NULL; - xzalloc did it */
886   if (pb) pb->next = g_cb;   if (pb)
887     pb->next = g_cb;
888   }   }
889    
890   v = r = g_cb->pos;   v = r = g_cb->pos;
# Line 1148  static node *parse_expr(uint32_t iexp) Line 1147  static node *parse_expr(uint32_t iexp)
1147   /* for binary and postfix-unary operators, jump back over   /* for binary and postfix-unary operators, jump back over
1148   * previous operators with higher priority */   * previous operators with higher priority */
1149   vn = cn;   vn = cn;
1150   while ( ((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2))   while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2))
1151   || ((t_info == vn->info) && ((t_info & OPCLSMASK) == OC_COLON)) )      || ((t_info == vn->info) && ((t_info & OPCLSMASK) == OC_COLON))
1152     ) {
1153   vn = vn->a.n;   vn = vn->a.n;
1154     }
1155   if ((t_info & OPCLSMASK) == OC_TERNARY)   if ((t_info & OPCLSMASK) == OC_TERNARY)
1156   t_info += P(6);   t_info += P(6);
1157   cn = vn->a.n->r.n = new_node(t_info);   cn = vn->a.n->r.n = new_node(t_info);
# Line 1485  static node *mk_splitter(const char *s, Line 1486  static node *mk_splitter(const char *s,
1486   */   */
1487  static regex_t *as_regex(node *op, regex_t *preg)  static regex_t *as_regex(node *op, regex_t *preg)
1488  {  {
1489     int cflags;
1490   var *v;   var *v;
1491   const char *s;   const char *s;
1492    
# Line 1493  static regex_t *as_regex(node *op, regex Line 1495  static regex_t *as_regex(node *op, regex
1495   }   }
1496   v = nvalloc(1);   v = nvalloc(1);
1497   s = getvar_s(evaluate(op, v));   s = getvar_s(evaluate(op, v));
1498   xregcomp(preg, s, icase ? REG_EXTENDED | REG_ICASE : REG_EXTENDED);  
1499     cflags = icase ? REG_EXTENDED | REG_ICASE : REG_EXTENDED;
1500     /* Testcase where REG_EXTENDED fails (unpaired '{'):
1501     * echo Hi | awk 'gsub("@(samp|code|file)\{","");'
1502     * gawk 3.1.5 eats this. We revert to ~REG_EXTENDED
1503     * (maybe gsub is not supposed to use REG_EXTENDED?).
1504     */
1505     if (regcomp(preg, s, cflags)) {
1506     cflags &= ~REG_EXTENDED;
1507     xregcomp(preg, s, cflags);
1508     }
1509   nvfree(v);   nvfree(v);
1510   return preg;   return preg;
1511  }  }
# Line 1563  static int awk_split(const char *s, node Line 1575  static int awk_split(const char *s, node
1575   n++; /* we saw yet another delimiter */   n++; /* we saw yet another delimiter */
1576   } else {   } else {
1577   pmatch[0].rm_eo = l;   pmatch[0].rm_eo = l;
1578   if (s[l]) pmatch[0].rm_eo++;   if (s[l])
1579     pmatch[0].rm_eo++;
1580   }   }
1581   memcpy(s1, s, l);   memcpy(s1, s, l);
1582   s1[l] = '\0';   /* make sure we remove *all* of the separator chars */
1583     do {
1584     s1[l] = '\0';
1585     } while (++l < pmatch[0].rm_eo);
1586   nextword(&s1);   nextword(&s1);
1587   s += pmatch[0].rm_eo;   s += pmatch[0].rm_eo;
1588   } while (*s);   } while (*s);
# Line 1859  static int fmt_num(char *b, int size, co Line 1875  static int fmt_num(char *b, int size, co
1875   return r;   return r;
1876  }  }
1877    
   
1878  /* formatted output into an allocated buffer, return ptr to buffer */  /* formatted output into an allocated buffer, return ptr to buffer */
1879  static char *awk_printf(node *n)  static char *awk_printf(node *n)
1880  {  {
# Line 1976  static int awk_sub(node *rn, const char Line 1991  static int awk_sub(node *rn, const char
1991   }   }
1992    
1993   sp += eo;   sp += eo;
1994   if (i == nm) break;   if (i == nm)
1995     break;
1996   if (eo == so) {   if (eo == so) {
1997   ds[di] = *sp++;   ds[di] = *sp++;
1998   if (!ds[di++]) break;   if (!ds[di++])
1999     break;
2000   }   }
2001   }   }
2002    
2003   qrealloc(&ds, di + strlen(sp), &dssize);   qrealloc(&ds, di + strlen(sp), &dssize);
2004   strcpy(ds + di, sp);   strcpy(ds + di, sp);
2005   setvar_p(dest, ds);   setvar_p(dest, ds);
2006   if (re == &sreg) regfree(re);   if (re == &sreg)
2007     regfree(re);
2008   return i;   return i;
2009  }  }
2010    
2011  static var *exec_builtin(node *op, var *res)  static NOINLINE int do_mktime(const char *ds)
2012    {
2013     struct tm then;
2014     int count;
2015    
2016     /*memset(&then, 0, sizeof(then)); - not needed */
2017     then.tm_isdst = -1; /* default is unknown */
2018    
2019     /* manpage of mktime says these fields are ints,
2020     * so we can sscanf stuff directly into them */
2021     count = sscanf(ds, "%u %u %u %u %u %u %d",
2022     &then.tm_year, &then.tm_mon, &then.tm_mday,
2023     &then.tm_hour, &then.tm_min, &then.tm_sec,
2024     &then.tm_isdst);
2025    
2026     if (count < 6
2027     || (unsigned)then.tm_mon < 1
2028     || (unsigned)then.tm_year < 1900
2029     ) {
2030     return -1;
2031     }
2032    
2033     then.tm_mon -= 1;
2034     then.tm_year -= 1900;
2035    
2036     return mktime(&then);
2037    }
2038    
2039    static NOINLINE var *exec_builtin(node *op, var *res)
2040  {  {
2041  #define tspl (G.exec_builtin__tspl)  #define tspl (G.exec_builtin__tspl)
2042    
  int (*to_xxx)(int);  
2043   var *tv;   var *tv;
2044   node *an[4];   node *an[4];
2045   var *av[4];   var *av[4];
# Line 2024  static var *exec_builtin(node *op, var * Line 2069  static var *exec_builtin(node *op, var *
2069   if ((uint32_t)nargs < (info >> 30))   if ((uint32_t)nargs < (info >> 30))
2070   syntax_error(EMSG_TOO_FEW_ARGS);   syntax_error(EMSG_TOO_FEW_ARGS);
2071    
2072   switch (info & OPNMASK) {   info &= OPNMASK;
2073     switch (info) {
2074    
2075   case B_a2:   case B_a2:
2076  #if ENABLE_FEATURE_AWK_LIBM  #if ENABLE_FEATURE_AWK_LIBM
# Line 2089  static var *exec_builtin(node *op, var * Line 2135  static var *exec_builtin(node *op, var *
2135   break;   break;
2136    
2137   case B_lo:   case B_lo:
  to_xxx = tolower;  
  goto lo_cont;  
   
2138   case B_up:   case B_up:
  to_xxx = toupper;  
  lo_cont:  
2139   s1 = s = xstrdup(as[0]);   s1 = s = xstrdup(as[0]);
2140   while (*s1) {   while (*s1) {
2141   *s1 = (*to_xxx)(*s1);   //*s1 = (info == B_up) ? toupper(*s1) : tolower(*s1);
2142     if ((unsigned char)((*s1 | 0x20) - 'a') <= ('z' - 'a'))
2143     *s1 = (info == B_up) ? (*s1 & 0xdf) : (*s1 | 0x20);
2144   s1++;   s1++;
2145   }   }
2146   setvar_p(res, s);   setvar_p(res, s);
# Line 2139  static var *exec_builtin(node *op, var * Line 2182  static var *exec_builtin(node *op, var *
2182   setvar_s(res, g_buf);   setvar_s(res, g_buf);
2183   break;   break;
2184    
2185     case B_mt:
2186     setvar_i(res, do_mktime(as[0]));
2187     break;
2188    
2189   case B_ma:   case B_ma:
2190   re = as_regex(an[1], &sreg);   re = as_regex(an[1], &sreg);
2191   n = regexec(re, as[0], 1, pmatch, 0);   n = regexec(re, as[0], 1, pmatch, 0);
# Line 2377  static var *evaluate(node *op, var *res) Line 2424  static var *evaluate(node *op, var *res)
2424   X.re = as_regex(op1, &sreg);   X.re = as_regex(op1, &sreg);
2425   R.i = regexec(X.re, L.s, 0, NULL, 0);   R.i = regexec(X.re, L.s, 0, NULL, 0);
2426   if (X.re == &sreg) regfree(X.re);   if (X.re == &sreg) regfree(X.re);
2427   setvar_i(res, (R.i == 0 ? 1 : 0) ^ (opn == '!' ? 1 : 0));   setvar_i(res, (R.i == 0) ^ (opn == '!'));
2428   break;   break;
2429    
2430   case XC( OC_MOVE ):   case XC( OC_MOVE ):
2431   /* if source is a temporary string, jusk relink it to dest */   /* if source is a temporary string, jusk relink it to dest */
2432   if (R.v == v1+1 && R.v->string) {  //Disabled: if R.v is numeric but happens to have cached R.v->string,
2433   res = setvar_p(L.v, R.v->string);  //then L.v ends up being a string, which is wrong
2434   R.v->string = NULL;  // if (R.v == v1+1 && R.v->string) {
2435   } else {  // res = setvar_p(L.v, R.v->string);
2436    // R.v->string = NULL;
2437    // } else {
2438   res = copyvar(L.v, R.v);   res = copyvar(L.v, R.v);
2439   }  // }
2440   break;   break;
2441    
2442   case XC( OC_TERNARY ):   case XC( OC_TERNARY ):
# Line 2400  static var *evaluate(node *op, var *res) Line 2449  static var *evaluate(node *op, var *res)
2449   if (!op->r.f->body.first)   if (!op->r.f->body.first)
2450   syntax_error(EMSG_UNDEF_FUNC);   syntax_error(EMSG_UNDEF_FUNC);
2451    
2452   X.v = R.v = nvalloc(op->r.f->nargs+1);   X.v = R.v = nvalloc(op->r.f->nargs + 1);
2453   while (op1) {   while (op1) {
2454   L.v = evaluate(nextarg(&op1), v1);   L.v = evaluate(nextarg(&op1), v1);
2455   copyvar(R.v, L.v);   copyvar(R.v, L.v);
# Line 2514  static var *evaluate(node *op, var *res) Line 2563  static var *evaluate(node *op, var *res)
2563   break;   break;
2564    
2565   case F_sy:   case F_sy:
2566   fflush(NULL);   fflush_all();
2567   R.d = (ENABLE_FEATURE_ALLOW_EXEC && L.s && *L.s)   R.d = (ENABLE_FEATURE_ALLOW_EXEC && L.s && *L.s)
2568   ? (system(L.s) >> 8) : 0;   ? (system(L.s) >> 8) : 0;
2569   break;   break;
# Line 2527  static var *evaluate(node *op, var *res) Line 2576  static var *evaluate(node *op, var *res)
2576   X.rsm = newfile(L.s);   X.rsm = newfile(L.s);
2577   fflush(X.rsm->F);   fflush(X.rsm->F);
2578   } else {   } else {
2579   fflush(NULL);   fflush_all();
2580   }   }
2581   }   }
2582   break;   break;
# Line 2572  static var *evaluate(node *op, var *res) Line 2621  static var *evaluate(node *op, var *res)
2621   R.d--;   R.d--;
2622   goto r_op_change;   goto r_op_change;
2623   case '!':   case '!':
2624   L.d = istrue(X.v) ? 0 : 1;   L.d = !istrue(X.v);
2625   break;   break;
2626   case '-':   case '-':
2627   L.d = -R.d;   L.d = -R.d;
# Line 2632  static var *evaluate(node *op, var *res) Line 2681  static var *evaluate(node *op, var *res)
2681   L.d *= R.d;   L.d *= R.d;
2682   break;   break;
2683   case '/':   case '/':
2684   if (R.d == 0) syntax_error(EMSG_DIV_BY_ZERO);   if (R.d == 0)
2685     syntax_error(EMSG_DIV_BY_ZERO);
2686   L.d /= R.d;   L.d /= R.d;
2687   break;   break;
2688   case '&':   case '&':
# Line 2643  static var *evaluate(node *op, var *res) Line 2693  static var *evaluate(node *op, var *res)
2693  #endif  #endif
2694   break;   break;
2695   case '%':   case '%':
2696   if (R.d == 0) syntax_error(EMSG_DIV_BY_ZERO);   if (R.d == 0)
2697     syntax_error(EMSG_DIV_BY_ZERO);
2698   L.d -= (int)(L.d / R.d) * R.d;   L.d -= (int)(L.d / R.d) * R.d;
2699   break;   break;
2700   }   }
# Line 2669  static var *evaluate(node *op, var *res) Line 2720  static var *evaluate(node *op, var *res)
2720   R.i = (L.d == 0);   R.i = (L.d == 0);
2721   break;   break;
2722   }   }
2723   setvar_i(res, (opn & 0x1 ? R.i : !R.i) ? 1 : 0);   setvar_i(res, (opn & 1 ? R.i : !R.i) ? 1 : 0);
2724   break;   break;
2725    
2726   default:   default:
# Line 2751  static rstream *next_input_file(void) Line 2802  static rstream *next_input_file(void)
2802   FILE *F = NULL;   FILE *F = NULL;
2803   const char *fname, *ind;   const char *fname, *ind;
2804    
2805   if (rsm.F) fclose(rsm.F);   if (rsm.F)
2806     fclose(rsm.F);
2807   rsm.F = NULL;   rsm.F = NULL;
2808   rsm.pos = rsm.adv = 0;   rsm.pos = rsm.adv = 0;
2809    
# Line 2869  int awk_main(int argc, char **argv) Line 2921  int awk_main(int argc, char **argv)
2921   parse_program(s + 1);   parse_program(s + 1);
2922   free(s);   free(s);
2923   } while (list_f);   } while (list_f);
2924     argc++;
2925   } else { // no -f: take program from 1st parameter   } else { // no -f: take program from 1st parameter
2926   if (!argc)   if (!argc)
2927   bb_show_usage();   bb_show_usage();
2928   g_progname = "cmd. line";   g_progname = "cmd. line";
2929   parse_program(*argv++);   parse_program(*argv++);
  argc--;  
2930   }   }
2931   if (opt & 0x8) // -W   if (opt & 0x8) // -W
2932   bb_error_msg("warning: unrecognized option '-W %s' ignored", opt_W);   bb_error_msg("warning: unrecognized option '-W %s' ignored", opt_W);
2933    
2934   /* fill in ARGV array */   /* fill in ARGV array */
2935   setvar_i(intvar[ARGC], argc + 1);   setvar_i(intvar[ARGC], argc);
2936   setari_u(intvar[ARGV], 0, "awk");   setari_u(intvar[ARGV], 0, "awk");
2937   i = 0;   i = 0;
2938   while (*argv)   while (*argv)
# Line 2891  int awk_main(int argc, char **argv) Line 2943  int awk_main(int argc, char **argv)
2943   awk_exit(EXIT_SUCCESS);   awk_exit(EXIT_SUCCESS);
2944    
2945   /* input file could already be opened in BEGIN block */   /* input file could already be opened in BEGIN block */
2946   if (!iF) iF = next_input_file();   if (!iF)
2947     iF = next_input_file();
2948    
2949   /* passing through input files */   /* passing through input files */
2950   while (iF) {   while (iF) {

Legend:
Removed from v.983  
changed lines
  Added in v.984