aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-25 19:38:27 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-25 19:38:27 +0200
commit8c5da0323bf2da02c40c587c5694b22e3ec623fb (patch)
tree67aaf4a97d20d3e3ad0c235beaf4b83b36aba2ea
parent53a7a9cd8c15d64fcc2278cf8981ba526dfbe0d2 (diff)
downloadbusybox-w32-8c5da0323bf2da02c40c587c5694b22e3ec623fb.tar.gz
busybox-w32-8c5da0323bf2da02c40c587c5694b22e3ec623fb.tar.bz2
busybox-w32-8c5da0323bf2da02c40c587c5694b22e3ec623fb.zip
awk: more efficient -f FILE, document what "some trick in next_token" is
function old new delta awk_main 890 898 +8 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/awk.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/editors/awk.c b/editors/awk.c
index 5f1d670a4..1b23c17d2 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -1217,6 +1217,8 @@ static uint32_t next_token(uint32_t expected)
1217 if (!isalnum_(*p)) 1217 if (!isalnum_(*p))
1218 syntax_error(EMSG_UNEXP_TOKEN); /* no */ 1218 syntax_error(EMSG_UNEXP_TOKEN); /* no */
1219 /* yes */ 1219 /* yes */
1220/* "move name one char back" trick: we need a byte for NUL terminator */
1221/* NB: this results in argv[i][-1] being used (!!!) in e.g. "awk -e 'NAME'" case */
1220 t_string = --p; 1222 t_string = --p;
1221 while (isalnum_(*++p)) { 1223 while (isalnum_(*++p)) {
1222 p[-1] = *p; 1224 p[-1] = *p;
@@ -3345,7 +3347,7 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
3345#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS 3347#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
3346 llist_t *list_e = NULL; 3348 llist_t *list_e = NULL;
3347#endif 3349#endif
3348 int i, j; 3350 int i;
3349 var *v; 3351 var *v;
3350 var tv; 3352 var tv;
3351 char **envp; 3353 char **envp;
@@ -3417,30 +3419,43 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
3417 bb_show_usage(); 3419 bb_show_usage();
3418 } 3420 }
3419 while (list_f) { 3421 while (list_f) {
3420 char *s = NULL; 3422 int fd;
3421 FILE *from_file; 3423 char *s;
3422 3424
3423 g_progname = llist_pop(&list_f); 3425 g_progname = llist_pop(&list_f);
3424 from_file = xfopen_stdin(g_progname); 3426 fd = xopen_stdin(g_progname);
3425 /* one byte is reserved for some trick in next_token */ 3427 /* 1st byte is reserved for "move name one char back" trick in next_token */
3426 for (i = j = 1; j > 0; i += j) { 3428 i = 1;
3427 s = xrealloc(s, i + 4096); 3429 s = NULL;
3428 j = fread(s + i, 1, 4094, from_file); 3430 for (;;) {
3431 int sz;
3432 s = xrealloc(s, i + 1000);
3433 sz = safe_read(fd, s + i, 1000);
3434 if (sz <= 0)
3435 break;
3436 i += sz;
3429 } 3437 }
3438 s = xrealloc(s, i + 1); /* trim unused 999 bytes */
3430 s[i] = '\0'; 3439 s[i] = '\0';
3431 fclose(from_file); 3440 close(fd);
3432 parse_program(s + 1); 3441 parse_program(s + 1);
3433 free(s); 3442 free(s);
3434 } 3443 }
3435 g_progname = "cmd. line"; 3444 g_progname = "cmd. line";
3436#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS 3445#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
3437 while (list_e) { 3446 while (list_e) {
3447 /* NB: "move name one char back" trick in next_token
3448 * can use argv[i][-1] here.
3449 */
3438 parse_program(llist_pop(&list_e)); 3450 parse_program(llist_pop(&list_e));
3439 } 3451 }
3440#endif 3452#endif
3441 if (!(opt & (OPT_f | OPT_e))) { 3453 if (!(opt & (OPT_f | OPT_e))) {
3442 if (!*argv) 3454 if (!*argv)
3443 bb_show_usage(); 3455 bb_show_usage();
3456 /* NB: "move name one char back" trick in next_token
3457 * can use argv[i][-1] here.
3458 */
3444 parse_program(*argv++); 3459 parse_program(*argv++);
3445 } 3460 }
3446 3461