mirror of https://github.com/mirror/busybox.git
awk: implement -E; do not reorder -f and -e
function old new delta awk_main 843 891 +48 next_input_file 243 261 +18 packed_usage 34631 34638 +7 .rodata 105391 105390 -1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/1 up/down: 73/-1) Total: 72 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>master
parent
6d22c9abc2
commit
92ab29fcf0
113
editors/awk.c
113
editors/awk.c
|
@ -40,7 +40,7 @@
|
|||
//usage:#define awk_full_usage "\n\n"
|
||||
//usage: " -v VAR=VAL Set variable"
|
||||
//usage: "\n -F SEP Use SEP as field separator"
|
||||
//usage: "\n -f FILE Read program from FILE"
|
||||
//usage: "\n -f/-E FILE Read program from FILE"
|
||||
//usage: IF_FEATURE_AWK_GNU_EXTENSIONS(
|
||||
//usage: "\n -e AWK_PROGRAM"
|
||||
//usage: )
|
||||
|
@ -76,8 +76,8 @@
|
|||
* 1: -argz
|
||||
*/
|
||||
#define OPTSTR_AWK "+" \
|
||||
"F:v:*f:*" \
|
||||
IF_FEATURE_AWK_GNU_EXTENSIONS("e:*") \
|
||||
"F:v:f:" \
|
||||
IF_FEATURE_AWK_GNU_EXTENSIONS("e:E:") \
|
||||
"W:"
|
||||
enum {
|
||||
OPTBIT_F, /* define field separator */
|
||||
|
@ -560,6 +560,7 @@ struct globals {
|
|||
var *Fields;
|
||||
char *g_pos;
|
||||
char g_saved_ch;
|
||||
smallint got_program;
|
||||
smallint icase;
|
||||
smallint exiting;
|
||||
smallint nextrec;
|
||||
|
@ -635,6 +636,7 @@ struct globals2 {
|
|||
#define Fields (G1.Fields )
|
||||
#define g_pos (G1.g_pos )
|
||||
#define g_saved_ch (G1.g_saved_ch )
|
||||
#define got_program (G1.got_program )
|
||||
#define icase (G1.icase )
|
||||
#define exiting (G1.exiting )
|
||||
#define nextrec (G1.nextrec )
|
||||
|
@ -2899,11 +2901,13 @@ static int next_input_file(void)
|
|||
}
|
||||
fname = getvar_s(findvar(iamarray(intvar[ARGV]), utoa(argind)));
|
||||
if (fname && *fname) {
|
||||
/* "If a filename on the command line has the form
|
||||
* var=val it is treated as a variable assignment"
|
||||
*/
|
||||
if (try_to_assign(fname))
|
||||
continue;
|
||||
if (got_program != 2) { /* there was no -E option */
|
||||
/* "If a filename on the command line has the form
|
||||
* var=val it is treated as a variable assignment"
|
||||
*/
|
||||
if (try_to_assign(fname))
|
||||
continue;
|
||||
}
|
||||
iF.F = xfopen_stdin(fname);
|
||||
setvar_i(intvar[ARGIND], argind);
|
||||
break;
|
||||
|
@ -3659,13 +3663,7 @@ static int awk_exit(void)
|
|||
int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int awk_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
unsigned opt;
|
||||
char *opt_F;
|
||||
llist_t *list_v = NULL;
|
||||
llist_t *list_f = NULL;
|
||||
#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
|
||||
llist_t *list_e = NULL;
|
||||
#endif
|
||||
int ch;
|
||||
int i;
|
||||
|
||||
INIT_G();
|
||||
|
@ -3714,49 +3712,68 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
|
|||
}
|
||||
}
|
||||
}
|
||||
opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL);
|
||||
argv += optind;
|
||||
//argc -= optind;
|
||||
if (opt & OPT_W)
|
||||
bb_simple_error_msg("warning: option -W is ignored");
|
||||
if (opt & OPT_F) {
|
||||
unescape_string_in_place(opt_F);
|
||||
setvar_s(intvar[FS], opt_F);
|
||||
}
|
||||
while (list_v) {
|
||||
if (!try_to_assign(llist_pop(&list_v)))
|
||||
bb_show_usage();
|
||||
}
|
||||
|
||||
/* Parse all supplied programs */
|
||||
fnhash = hash_init();
|
||||
ahash = hash_init();
|
||||
while (list_f) {
|
||||
int fd;
|
||||
char *s;
|
||||
|
||||
g_progname = llist_pop(&list_f);
|
||||
fd = xopen_stdin(g_progname);
|
||||
s = xmalloc_read(fd, NULL); /* it's NUL-terminated */
|
||||
if (!s)
|
||||
bb_perror_msg_and_die("read error from '%s'", g_progname);
|
||||
close(fd);
|
||||
parse_program(s);
|
||||
free(s);
|
||||
}
|
||||
g_progname = "cmd. line";
|
||||
/* Cannot use getopt32: need to preserve order of -e / -f / -E / -i */
|
||||
while ((ch = getopt(argc, argv, OPTSTR_AWK)) >= 0) {
|
||||
switch (ch) {
|
||||
case 'F':
|
||||
unescape_string_in_place(optarg);
|
||||
setvar_s(intvar[FS], optarg);
|
||||
break;
|
||||
case 'v':
|
||||
if (!try_to_assign(optarg))
|
||||
bb_show_usage();
|
||||
break;
|
||||
//TODO: implement -i LIBRARY, it is easy-ish
|
||||
case 'E':
|
||||
case 'f': {
|
||||
int fd;
|
||||
char *s;
|
||||
g_progname = optarg;
|
||||
fd = xopen_stdin(g_progname);
|
||||
s = xmalloc_read(fd, NULL); /* it's NUL-terminated */
|
||||
if (!s)
|
||||
bb_perror_msg_and_die("read error from '%s'", g_progname);
|
||||
close(fd);
|
||||
parse_program(s);
|
||||
free(s);
|
||||
got_program = 1;
|
||||
if (ch == 'E') {
|
||||
got_program = 2;
|
||||
goto stop_option_parsing;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
|
||||
while (list_e) {
|
||||
parse_program(llist_pop(&list_e));
|
||||
}
|
||||
case 'e':
|
||||
g_progname = "cmd. line";
|
||||
parse_program(optarg);
|
||||
got_program = 1;
|
||||
break;
|
||||
#endif
|
||||
//FIXME: preserve order of -e and -f
|
||||
//TODO: implement -i LIBRARY and -E FILE too, they are easy-ish
|
||||
if (!(opt & (OPT_f | OPT_e))) {
|
||||
case 'W':
|
||||
bb_simple_error_msg("warning: option -W is ignored");
|
||||
break;
|
||||
default:
|
||||
//bb_error_msg("ch:%d", ch);
|
||||
bb_show_usage();
|
||||
}
|
||||
}
|
||||
stop_option_parsing:
|
||||
|
||||
argv += optind;
|
||||
//argc -= optind;
|
||||
|
||||
if (!got_program) {
|
||||
if (!*argv)
|
||||
bb_show_usage();
|
||||
g_progname = "cmd. line";
|
||||
parse_program(*argv++);
|
||||
}
|
||||
|
||||
/* Free unused parse structures */
|
||||
//hash_free(fnhash); // ~250 bytes when empty, used only for function names
|
||||
//^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs
|
||||
|
|
Loading…
Reference in New Issue