diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/awk.c | 266 |
1 files changed, 139 insertions, 127 deletions
diff --git a/editors/awk.c b/editors/awk.c index 2245cad03..8bc56756c 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -283,88 +283,80 @@ enum { | |||
283 | #define OC_B OC_BUILTIN | 283 | #define OC_B OC_BUILTIN |
284 | 284 | ||
285 | static const char tokenlist[] ALIGN1 = | 285 | static const char tokenlist[] ALIGN1 = |
286 | "\1(" NTC | 286 | "\1(" NTC |
287 | "\1)" NTC | 287 | "\1)" NTC |
288 | "\1/" NTC /* REGEXP */ | 288 | "\1/" NTC /* REGEXP */ |
289 | "\2>>" "\1>" "\1|" NTC /* OUTRDR */ | 289 | "\2>>" "\1>" "\1|" NTC /* OUTRDR */ |
290 | "\2++" "\2--" NTC /* UOPPOST */ | 290 | "\2++" "\2--" NTC /* UOPPOST */ |
291 | "\2++" "\2--" "\1$" NTC /* UOPPRE1 */ | 291 | "\2++" "\2--" "\1$" NTC /* UOPPRE1 */ |
292 | "\2==" "\1=" "\2+=" "\2-=" /* BINOPX */ | 292 | "\2==" "\1=" "\2+=" "\2-=" /* BINOPX */ |
293 | "\2*=" "\2/=" "\2%=" "\2^=" | 293 | "\2*=" "\2/=" "\2%=" "\2^=" |
294 | "\1+" "\1-" "\3**=" "\2**" | 294 | "\1+" "\1-" "\3**=" "\2**" |
295 | "\1/" "\1%" "\1^" "\1*" | 295 | "\1/" "\1%" "\1^" "\1*" |
296 | "\2!=" "\2>=" "\2<=" "\1>" | 296 | "\2!=" "\2>=" "\2<=" "\1>" |
297 | "\1<" "\2!~" "\1~" "\2&&" | 297 | "\1<" "\2!~" "\1~" "\2&&" |
298 | "\2||" "\1?" "\1:" NTC | 298 | "\2||" "\1?" "\1:" NTC |
299 | "\2in" NTC | 299 | "\2in" NTC |
300 | "\1," NTC | 300 | "\1," NTC |
301 | "\1|" NTC | 301 | "\1|" NTC |
302 | "\1+" "\1-" "\1!" NTC /* UOPPRE2 */ | 302 | "\1+" "\1-" "\1!" NTC /* UOPPRE2 */ |
303 | "\1]" NTC | 303 | "\1]" NTC |
304 | "\1{" NTC | 304 | "\1{" NTC |
305 | "\1}" NTC | 305 | "\1}" NTC |
306 | "\1;" NTC | 306 | "\1;" NTC |
307 | "\1\n" NTC | 307 | "\1\n" NTC |
308 | "\2if" "\2do" "\3for" "\5break" /* STATX */ | 308 | "\2if" "\2do" "\3for" "\5break" /* STATX */ |
309 | "\10continue" "\6delete" "\5print" | 309 | "\10continue" "\6delete" "\5print" |
310 | "\6printf" "\4next" "\10nextfile" | 310 | "\6printf" "\4next" "\10nextfile" |
311 | "\6return" "\4exit" NTC | 311 | "\6return" "\4exit" NTC |
312 | "\5while" NTC | 312 | "\5while" NTC |
313 | "\4else" NTC | 313 | "\4else" NTC |
314 | 314 | ||
315 | "\3and" "\5compl" "\6lshift" "\2or" | 315 | "\3and" "\5compl" "\6lshift" "\2or" |
316 | "\6rshift" "\3xor" | 316 | "\6rshift" "\3xor" |
317 | "\5close" "\6system" "\6fflush" "\5atan2" /* BUILTIN */ | 317 | "\5close" "\6system" "\6fflush" "\5atan2" /* BUILTIN */ |
318 | "\3cos" "\3exp" "\3int" "\3log" | 318 | "\3cos" "\3exp" "\3int" "\3log" |
319 | "\4rand" "\3sin" "\4sqrt" "\5srand" | 319 | "\4rand" "\3sin" "\4sqrt" "\5srand" |
320 | "\6gensub" "\4gsub" "\5index" "\6length" | 320 | "\6gensub" "\4gsub" "\5index" "\6length" |
321 | "\5match" "\5split" "\7sprintf" "\3sub" | 321 | "\5match" "\5split" "\7sprintf" "\3sub" |
322 | "\6substr" "\7systime" "\10strftime" "\6mktime" | 322 | "\6substr" "\7systime" "\10strftime" "\6mktime" |
323 | "\7tolower" "\7toupper" NTC | 323 | "\7tolower" "\7toupper" NTC |
324 | "\7getline" NTC | 324 | "\7getline" NTC |
325 | "\4func" "\10function" NTC | 325 | "\4func" "\10function" NTC |
326 | "\5BEGIN" NTC | 326 | "\5BEGIN" NTC |
327 | "\3END" "\0" | 327 | "\3END" |
328 | /* compiler adds trailing "\0" */ | ||
328 | ; | 329 | ; |
329 | 330 | ||
330 | static const uint32_t tokeninfo[] = { | 331 | static const uint32_t tokeninfo[] = { |
331 | 0, | 332 | 0, |
332 | 0, | 333 | 0, |
333 | OC_REGEXP, | 334 | OC_REGEXP, |
334 | xS|'a', xS|'w', xS|'|', | 335 | xS|'a', xS|'w', xS|'|', |
335 | OC_UNARY|xV|P(9)|'p', OC_UNARY|xV|P(9)|'m', | 336 | OC_UNARY|xV|P(9)|'p', OC_UNARY|xV|P(9)|'m', |
336 | OC_UNARY|xV|P(9)|'P', OC_UNARY|xV|P(9)|'M', | 337 | OC_UNARY|xV|P(9)|'P', OC_UNARY|xV|P(9)|'M', OC_FIELD|xV|P(5), |
337 | OC_FIELD|xV|P(5), | 338 | OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(74), OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-', |
338 | OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(74), | 339 | OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&', |
339 | OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-', | 340 | OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&', |
340 | OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', | 341 | OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*', |
341 | OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&', | 342 | OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, |
342 | OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', | 343 | OC_COMPARE|VV|P(39)|2, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), |
343 | OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&', | 344 | OC_LOR|Vx|P(59), OC_TERNARY|Vx|P(64)|'?', OC_COLON|xx|P(67)|':', |
344 | OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', | 345 | OC_IN|SV|P(49), /* in */ |
345 | OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*', | ||
346 | OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, | ||
347 | OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, | ||
348 | OC_COMPARE|VV|P(39)|2, OC_MATCH|Sx|P(45)|'!', | ||
349 | OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), | ||
350 | OC_LOR|Vx|P(59), OC_TERNARY|Vx|P(64)|'?', | ||
351 | OC_COLON|xx|P(67)|':', | ||
352 | OC_IN|SV|P(49), | ||
353 | OC_COMMA|SS|P(80), | 346 | OC_COMMA|SS|P(80), |
354 | OC_PGETLINE|SV|P(37), | 347 | OC_PGETLINE|SV|P(37), |
355 | OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', | 348 | OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!', |
356 | OC_UNARY|xV|P(19)|'!', | 349 | 0, /* ] */ |
357 | 0, | 350 | 0, |
358 | 0, | 351 | 0, |
359 | 0, | 352 | 0, |
360 | 0, | 353 | 0, /* \n */ |
361 | 0, | 354 | ST_IF, ST_DO, ST_FOR, OC_BREAK, |
362 | ST_IF, ST_DO, ST_FOR, OC_BREAK, | 355 | OC_CONTINUE, OC_DELETE|Vx, OC_PRINT, |
363 | OC_CONTINUE, OC_DELETE|Vx, OC_PRINT, | 356 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, |
364 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, | 357 | OC_RETURN|Vx, OC_EXIT|Nx, |
365 | OC_RETURN|Vx, OC_EXIT|Nx, | ||
366 | ST_WHILE, | 358 | ST_WHILE, |
367 | 0, | 359 | 0, /* else */ |
368 | 360 | ||
369 | OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83), | 361 | OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83), |
370 | OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83), | 362 | OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83), |
@@ -376,9 +368,9 @@ static const uint32_t tokeninfo[] = { | |||
376 | OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti, OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b), | 368 | OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti, OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b), |
377 | OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49), | 369 | OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49), |
378 | OC_GETLINE|SV|P(0), | 370 | OC_GETLINE|SV|P(0), |
379 | 0, 0, | 371 | 0, 0, |
380 | 0, | 372 | 0, |
381 | 0 | 373 | 0 /* END */ |
382 | }; | 374 | }; |
383 | 375 | ||
384 | /* internal variable names and their initial values */ | 376 | /* internal variable names and their initial values */ |
@@ -532,9 +524,7 @@ static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments for builtin"; | |||
532 | static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; | 524 | static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; |
533 | static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; | 525 | static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; |
534 | static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; | 526 | static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; |
535 | #if !ENABLE_FEATURE_AWK_LIBM | ||
536 | static const char EMSG_NO_MATH[] ALIGN1 = "Math support is not compiled in"; | 527 | static const char EMSG_NO_MATH[] ALIGN1 = "Math support is not compiled in"; |
537 | #endif | ||
538 | 528 | ||
539 | static void zero_out_var(var *vp) | 529 | static void zero_out_var(var *vp) |
540 | { | 530 | { |
@@ -692,8 +682,11 @@ static char nextchar(char **s) | |||
692 | pps = *s; | 682 | pps = *s; |
693 | if (c == '\\') | 683 | if (c == '\\') |
694 | c = bb_process_escape_sequence((const char**)s); | 684 | c = bb_process_escape_sequence((const char**)s); |
695 | if (c == '\\' && *s == pps) | 685 | if (c == '\\' && *s == pps) { /* unrecognized \z? */ |
696 | c = *(*s)++; | 686 | c = *(*s); /* yes, fetch z */ |
687 | if (c) | ||
688 | (*s)++; /* advance unless z = NUL */ | ||
689 | } | ||
697 | return c; | 690 | return c; |
698 | } | 691 | } |
699 | 692 | ||
@@ -705,8 +698,7 @@ static ALWAYS_INLINE int isalnum_(int c) | |||
705 | static double my_strtod(char **pp) | 698 | static double my_strtod(char **pp) |
706 | { | 699 | { |
707 | char *cp = *pp; | 700 | char *cp = *pp; |
708 | #if ENABLE_DESKTOP | 701 | if (ENABLE_DESKTOP && cp[0] == '0') { |
709 | if (cp[0] == '0') { | ||
710 | /* Might be hex or octal integer: 0x123abc or 07777 */ | 702 | /* Might be hex or octal integer: 0x123abc or 07777 */ |
711 | char c = (cp[1] | 0x20); | 703 | char c = (cp[1] | 0x20); |
712 | if (c == 'x' || isdigit(cp[1])) { | 704 | if (c == 'x' || isdigit(cp[1])) { |
@@ -723,7 +715,6 @@ static double my_strtod(char **pp) | |||
723 | */ | 715 | */ |
724 | } | 716 | } |
725 | } | 717 | } |
726 | #endif | ||
727 | return strtod(cp, pp); | 718 | return strtod(cp, pp); |
728 | } | 719 | } |
729 | 720 | ||
@@ -1015,9 +1006,10 @@ static uint32_t next_token(uint32_t expected) | |||
1015 | /* it's a string */ | 1006 | /* it's a string */ |
1016 | t_string = s = ++p; | 1007 | t_string = s = ++p; |
1017 | while (*p != '\"') { | 1008 | while (*p != '\"') { |
1018 | char *pp = p; | 1009 | char *pp; |
1019 | if (*p == '\0' || *p == '\n') | 1010 | if (*p == '\0' || *p == '\n') |
1020 | syntax_error(EMSG_UNEXP_EOS); | 1011 | syntax_error(EMSG_UNEXP_EOS); |
1012 | pp = p; | ||
1021 | *s++ = nextchar(&pp); | 1013 | *s++ = nextchar(&pp); |
1022 | p = pp; | 1014 | p = pp; |
1023 | } | 1015 | } |
@@ -1836,6 +1828,8 @@ static int awk_getline(rstream *rsm, var *v) | |||
1836 | int fd, so, eo, r, rp; | 1828 | int fd, so, eo, r, rp; |
1837 | char c, *m, *s; | 1829 | char c, *m, *s; |
1838 | 1830 | ||
1831 | debug_printf_eval("entered %s()\n", __func__); | ||
1832 | |||
1839 | /* we're using our own buffer since we need access to accumulating | 1833 | /* we're using our own buffer since we need access to accumulating |
1840 | * characters | 1834 | * characters |
1841 | */ | 1835 | */ |
@@ -1922,6 +1916,8 @@ static int awk_getline(rstream *rsm, var *v) | |||
1922 | rsm->pos = p - eo; | 1916 | rsm->pos = p - eo; |
1923 | rsm->size = size; | 1917 | rsm->size = size; |
1924 | 1918 | ||
1919 | debug_printf_eval("returning from %s(): %d\n", __func__, r); | ||
1920 | |||
1925 | return r; | 1921 | return r; |
1926 | } | 1922 | } |
1927 | 1923 | ||
@@ -2168,11 +2164,10 @@ static NOINLINE var *exec_builtin(node *op, var *res) | |||
2168 | switch (info) { | 2164 | switch (info) { |
2169 | 2165 | ||
2170 | case B_a2: | 2166 | case B_a2: |
2171 | #if ENABLE_FEATURE_AWK_LIBM | 2167 | if (ENABLE_FEATURE_AWK_LIBM) |
2172 | setvar_i(res, atan2(getvar_i(av[0]), getvar_i(av[1]))); | 2168 | setvar_i(res, atan2(getvar_i(av[0]), getvar_i(av[1]))); |
2173 | #else | 2169 | else |
2174 | syntax_error(EMSG_NO_MATH); | 2170 | syntax_error(EMSG_NO_MATH); |
2175 | #endif | ||
2176 | break; | 2171 | break; |
2177 | 2172 | ||
2178 | case B_sp: { | 2173 | case B_sp: { |
@@ -2347,6 +2342,8 @@ static var *evaluate(node *op, var *res) | |||
2347 | if (!op) | 2342 | if (!op) |
2348 | return setvar_s(res, NULL); | 2343 | return setvar_s(res, NULL); |
2349 | 2344 | ||
2345 | debug_printf_eval("entered %s()\n", __func__); | ||
2346 | |||
2350 | v1 = nvalloc(2); | 2347 | v1 = nvalloc(2); |
2351 | 2348 | ||
2352 | while (op) { | 2349 | while (op) { |
@@ -2367,7 +2364,7 @@ static var *evaluate(node *op, var *res) | |||
2367 | opn = (opinfo & OPNMASK); | 2364 | opn = (opinfo & OPNMASK); |
2368 | g_lineno = op->lineno; | 2365 | g_lineno = op->lineno; |
2369 | op1 = op->l.n; | 2366 | op1 = op->l.n; |
2370 | debug_printf_eval("opinfo:%08x opn:%08x XC:%x\n", opinfo, opn, XC(opinfo & OPCLSMASK)); | 2367 | debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); |
2371 | 2368 | ||
2372 | /* execute inevitable things */ | 2369 | /* execute inevitable things */ |
2373 | if (opinfo & OF_RES1) | 2370 | if (opinfo & OF_RES1) |
@@ -2387,6 +2384,7 @@ static var *evaluate(node *op, var *res) | |||
2387 | debug_printf_eval("L_d:%f\n", L_d); | 2384 | debug_printf_eval("L_d:%f\n", L_d); |
2388 | } | 2385 | } |
2389 | 2386 | ||
2387 | debug_printf_eval("switch(0x%x)\n", XC(opinfo & OPCLSMASK)); | ||
2390 | switch (XC(opinfo & OPCLSMASK)) { | 2388 | switch (XC(opinfo & OPCLSMASK)) { |
2391 | 2389 | ||
2392 | /* -- iterative node type -- */ | 2390 | /* -- iterative node type -- */ |
@@ -2642,8 +2640,6 @@ static var *evaluate(node *op, var *res) | |||
2642 | 2640 | ||
2643 | /* simple builtins */ | 2641 | /* simple builtins */ |
2644 | case XC( OC_FBLTIN ): { | 2642 | case XC( OC_FBLTIN ): { |
2645 | int i; | ||
2646 | rstream *rsm; | ||
2647 | double R_d = R_d; /* for compiler */ | 2643 | double R_d = R_d; /* for compiler */ |
2648 | 2644 | ||
2649 | switch (opn) { | 2645 | switch (opn) { |
@@ -2654,35 +2650,40 @@ static var *evaluate(node *op, var *res) | |||
2654 | case F_rn: | 2650 | case F_rn: |
2655 | R_d = (double)rand() / (double)RAND_MAX; | 2651 | R_d = (double)rand() / (double)RAND_MAX; |
2656 | break; | 2652 | break; |
2657 | #if ENABLE_FEATURE_AWK_LIBM | 2653 | |
2658 | case F_co: | 2654 | case F_co: |
2659 | R_d = cos(L_d); | 2655 | if (ENABLE_FEATURE_AWK_LIBM) { |
2660 | break; | 2656 | R_d = cos(L_d); |
2657 | break; | ||
2658 | } | ||
2661 | 2659 | ||
2662 | case F_ex: | 2660 | case F_ex: |
2663 | R_d = exp(L_d); | 2661 | if (ENABLE_FEATURE_AWK_LIBM) { |
2664 | break; | 2662 | R_d = exp(L_d); |
2663 | break; | ||
2664 | } | ||
2665 | 2665 | ||
2666 | case F_lg: | 2666 | case F_lg: |
2667 | R_d = log(L_d); | 2667 | if (ENABLE_FEATURE_AWK_LIBM) { |
2668 | break; | 2668 | R_d = log(L_d); |
2669 | break; | ||
2670 | } | ||
2669 | 2671 | ||
2670 | case F_si: | 2672 | case F_si: |
2671 | R_d = sin(L_d); | 2673 | if (ENABLE_FEATURE_AWK_LIBM) { |
2672 | break; | 2674 | R_d = sin(L_d); |
2675 | break; | ||
2676 | } | ||
2673 | 2677 | ||
2674 | case F_sq: | 2678 | case F_sq: |
2675 | R_d = sqrt(L_d); | 2679 | if (ENABLE_FEATURE_AWK_LIBM) { |
2676 | break; | 2680 | R_d = sqrt(L_d); |
2677 | #else | 2681 | break; |
2678 | case F_co: | 2682 | } |
2679 | case F_ex: | 2683 | |
2680 | case F_lg: | ||
2681 | case F_si: | ||
2682 | case F_sq: | ||
2683 | syntax_error(EMSG_NO_MATH); | 2684 | syntax_error(EMSG_NO_MATH); |
2684 | break; | 2685 | break; |
2685 | #endif | 2686 | |
2686 | case F_sr: | 2687 | case F_sr: |
2687 | R_d = (double)seed; | 2688 | R_d = (double)seed; |
2688 | seed = op1 ? (unsigned)L_d : (unsigned)time(NULL); | 2689 | seed = op1 ? (unsigned)L_d : (unsigned)time(NULL); |
@@ -2709,26 +2710,37 @@ static var *evaluate(node *op, var *res) | |||
2709 | if (!op1) { | 2710 | if (!op1) { |
2710 | fflush(stdout); | 2711 | fflush(stdout); |
2711 | } else if (L.s && *L.s) { | 2712 | } else if (L.s && *L.s) { |
2712 | rsm = newfile(L.s); | 2713 | rstream *rsm = newfile(L.s); |
2713 | fflush(rsm->F); | 2714 | fflush(rsm->F); |
2714 | } else { | 2715 | } else { |
2715 | fflush_all(); | 2716 | fflush_all(); |
2716 | } | 2717 | } |
2717 | break; | 2718 | break; |
2718 | 2719 | ||
2719 | case F_cl: | 2720 | case F_cl: { |
2720 | i = 0; | 2721 | rstream *rsm; |
2722 | int err = 0; | ||
2721 | rsm = (rstream *)hash_search(fdhash, L.s); | 2723 | rsm = (rstream *)hash_search(fdhash, L.s); |
2724 | debug_printf_eval("OC_FBLTIN F_cl rsm:%p\n", rsm); | ||
2722 | if (rsm) { | 2725 | if (rsm) { |
2723 | i = rsm->is_pipe ? pclose(rsm->F) : fclose(rsm->F); | 2726 | debug_printf_eval("OC_FBLTIN F_cl " |
2727 | "rsm->is_pipe:%d, ->F:%p\n", | ||
2728 | rsm->is_pipe, rsm->F); | ||
2729 | /* Can be NULL if open failed. Example: | ||
2730 | * getline line <"doesnt_exist"; | ||
2731 | * close("doesnt_exist"); <--- here rsm->F is NULL | ||
2732 | */ | ||
2733 | if (rsm->F) | ||
2734 | err = rsm->is_pipe ? pclose(rsm->F) : fclose(rsm->F); | ||
2724 | free(rsm->buffer); | 2735 | free(rsm->buffer); |
2725 | hash_remove(fdhash, L.s); | 2736 | hash_remove(fdhash, L.s); |
2726 | } | 2737 | } |
2727 | if (i != 0) | 2738 | if (err) |
2728 | setvar_i(intvar[ERRNO], errno); | 2739 | setvar_i(intvar[ERRNO], errno); |
2729 | R_d = (double)i; | 2740 | R_d = (double)err; |
2730 | break; | 2741 | break; |
2731 | } | 2742 | } |
2743 | } /* switch */ | ||
2732 | setvar_i(res, R_d); | 2744 | setvar_i(res, R_d); |
2733 | break; | 2745 | break; |
2734 | } | 2746 | } |
@@ -2822,11 +2834,10 @@ static var *evaluate(node *op, var *res) | |||
2822 | L_d /= R_d; | 2834 | L_d /= R_d; |
2823 | break; | 2835 | break; |
2824 | case '&': | 2836 | case '&': |
2825 | #if ENABLE_FEATURE_AWK_LIBM | 2837 | if (ENABLE_FEATURE_AWK_LIBM) |
2826 | L_d = pow(L_d, R_d); | 2838 | L_d = pow(L_d, R_d); |
2827 | #else | 2839 | else |
2828 | syntax_error(EMSG_NO_MATH); | 2840 | syntax_error(EMSG_NO_MATH); |
2829 | #endif | ||
2830 | break; | 2841 | break; |
2831 | case '%': | 2842 | case '%': |
2832 | if (R_d == 0) | 2843 | if (R_d == 0) |
@@ -2877,6 +2888,7 @@ static var *evaluate(node *op, var *res) | |||
2877 | } /* while (op) */ | 2888 | } /* while (op) */ |
2878 | 2889 | ||
2879 | nvfree(v1); | 2890 | nvfree(v1); |
2891 | debug_printf_eval("returning from %s(): %p\n", __func__, res); | ||
2880 | return res; | 2892 | return res; |
2881 | #undef fnargs | 2893 | #undef fnargs |
2882 | #undef seed | 2894 | #undef seed |
@@ -2917,21 +2929,21 @@ static int awk_exit(int r) | |||
2917 | * otherwise return 0 */ | 2929 | * otherwise return 0 */ |
2918 | static int is_assignment(const char *expr) | 2930 | static int is_assignment(const char *expr) |
2919 | { | 2931 | { |
2920 | char *exprc, *s, *s0, *s1; | 2932 | char *exprc, *val, *s, *s1; |
2921 | 2933 | ||
2922 | exprc = xstrdup(expr); | 2934 | if (!isalnum_(*expr) || (val = strchr(expr, '=')) == NULL) { |
2923 | if (!isalnum_(*exprc) || (s = strchr(exprc, '=')) == NULL) { | ||
2924 | free(exprc); | ||
2925 | return FALSE; | 2935 | return FALSE; |
2926 | } | 2936 | } |
2927 | 2937 | ||
2928 | *s++ = '\0'; | 2938 | exprc = xstrdup(expr); |
2929 | s0 = s1 = s; | 2939 | val = exprc + (val - expr); |
2930 | while (*s) | 2940 | *val++ = '\0'; |
2931 | *s1++ = nextchar(&s); | 2941 | |
2942 | s = s1 = val; | ||
2943 | while ((*s1 = nextchar(&s)) != '\0') | ||
2944 | s1++; | ||
2932 | 2945 | ||
2933 | *s1 = '\0'; | 2946 | setvar_u(newvar(exprc), val); |
2934 | setvar_u(newvar(exprc), s0); | ||
2935 | free(exprc); | 2947 | free(exprc); |
2936 | return TRUE; | 2948 | return TRUE; |
2937 | } | 2949 | } |