diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/awk.c | 115 |
1 files changed, 66 insertions, 49 deletions
diff --git a/editors/awk.c b/editors/awk.c index 5045297cd..7fb629273 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -40,7 +40,7 @@ | |||
40 | //usage:#define awk_full_usage "\n\n" | 40 | //usage:#define awk_full_usage "\n\n" |
41 | //usage: " -v VAR=VAL Set variable" | 41 | //usage: " -v VAR=VAL Set variable" |
42 | //usage: "\n -F SEP Use SEP as field separator" | 42 | //usage: "\n -F SEP Use SEP as field separator" |
43 | //usage: "\n -f FILE Read program from FILE" | 43 | //usage: "\n -f/-E FILE Read program from FILE" |
44 | //usage: IF_FEATURE_AWK_GNU_EXTENSIONS( | 44 | //usage: IF_FEATURE_AWK_GNU_EXTENSIONS( |
45 | //usage: "\n -e AWK_PROGRAM" | 45 | //usage: "\n -e AWK_PROGRAM" |
46 | //usage: ) | 46 | //usage: ) |
@@ -76,8 +76,8 @@ | |||
76 | * 1: -argz | 76 | * 1: -argz |
77 | */ | 77 | */ |
78 | #define OPTSTR_AWK "+" \ | 78 | #define OPTSTR_AWK "+" \ |
79 | "F:v:*f:*" \ | 79 | "F:v:f:" \ |
80 | IF_FEATURE_AWK_GNU_EXTENSIONS("e:*") \ | 80 | IF_FEATURE_AWK_GNU_EXTENSIONS("e:E:") \ |
81 | "W:" | 81 | "W:" |
82 | enum { | 82 | enum { |
83 | OPTBIT_F, /* define field separator */ | 83 | OPTBIT_F, /* define field separator */ |
@@ -560,6 +560,7 @@ struct globals { | |||
560 | var *Fields; | 560 | var *Fields; |
561 | char *g_pos; | 561 | char *g_pos; |
562 | char g_saved_ch; | 562 | char g_saved_ch; |
563 | smallint got_program; | ||
563 | smallint icase; | 564 | smallint icase; |
564 | smallint exiting; | 565 | smallint exiting; |
565 | smallint nextrec; | 566 | smallint nextrec; |
@@ -635,6 +636,7 @@ struct globals2 { | |||
635 | #define Fields (G1.Fields ) | 636 | #define Fields (G1.Fields ) |
636 | #define g_pos (G1.g_pos ) | 637 | #define g_pos (G1.g_pos ) |
637 | #define g_saved_ch (G1.g_saved_ch ) | 638 | #define g_saved_ch (G1.g_saved_ch ) |
639 | #define got_program (G1.got_program ) | ||
638 | #define icase (G1.icase ) | 640 | #define icase (G1.icase ) |
639 | #define exiting (G1.exiting ) | 641 | #define exiting (G1.exiting ) |
640 | #define nextrec (G1.nextrec ) | 642 | #define nextrec (G1.nextrec ) |
@@ -2908,11 +2910,13 @@ static int next_input_file(void) | |||
2908 | } | 2910 | } |
2909 | fname = getvar_s(findvar(iamarray(intvar[ARGV]), utoa(argind))); | 2911 | fname = getvar_s(findvar(iamarray(intvar[ARGV]), utoa(argind))); |
2910 | if (fname && *fname) { | 2912 | if (fname && *fname) { |
2911 | /* "If a filename on the command line has the form | 2913 | if (got_program != 2) { /* there was no -E option */ |
2912 | * var=val it is treated as a variable assignment" | 2914 | /* "If a filename on the command line has the form |
2913 | */ | 2915 | * var=val it is treated as a variable assignment" |
2914 | if (try_to_assign(fname)) | 2916 | */ |
2915 | continue; | 2917 | if (try_to_assign(fname)) |
2918 | continue; | ||
2919 | } | ||
2916 | iF.F = xfopen_stdin(fname); | 2920 | iF.F = xfopen_stdin(fname); |
2917 | setvar_i(intvar[ARGIND], argind); | 2921 | setvar_i(intvar[ARGIND], argind); |
2918 | break; | 2922 | break; |
@@ -3695,13 +3699,7 @@ static int awk_exit(void) | |||
3695 | int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 3699 | int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
3696 | int awk_main(int argc UNUSED_PARAM, char **argv) | 3700 | int awk_main(int argc UNUSED_PARAM, char **argv) |
3697 | { | 3701 | { |
3698 | unsigned opt; | 3702 | int ch; |
3699 | char *opt_F; | ||
3700 | llist_t *list_v = NULL; | ||
3701 | llist_t *list_f = NULL; | ||
3702 | #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS | ||
3703 | llist_t *list_e = NULL; | ||
3704 | #endif | ||
3705 | int i; | 3703 | int i; |
3706 | 3704 | ||
3707 | INIT_G(); | 3705 | INIT_G(); |
@@ -3750,52 +3748,71 @@ int awk_main(int argc UNUSED_PARAM, char **argv) | |||
3750 | } | 3748 | } |
3751 | } | 3749 | } |
3752 | } | 3750 | } |
3753 | opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL); | ||
3754 | argv += optind; | ||
3755 | //argc -= optind; | ||
3756 | if (opt & OPT_W) | ||
3757 | bb_simple_error_msg("warning: option -W is ignored"); | ||
3758 | if (opt & OPT_F) { | ||
3759 | unescape_string_in_place(opt_F); | ||
3760 | setvar_s(intvar[FS], opt_F); | ||
3761 | } | ||
3762 | while (list_v) { | ||
3763 | if (!try_to_assign(llist_pop(&list_v))) | ||
3764 | bb_show_usage(); | ||
3765 | } | ||
3766 | 3751 | ||
3767 | /* Parse all supplied programs */ | ||
3768 | fnhash = hash_init(); | 3752 | fnhash = hash_init(); |
3769 | ahash = hash_init(); | 3753 | ahash = hash_init(); |
3770 | while (list_f) { | ||
3771 | int fd; | ||
3772 | char *s; | ||
3773 | 3754 | ||
3774 | g_progname = llist_pop(&list_f); | 3755 | /* Cannot use getopt32: need to preserve order of -e / -f / -E / -i */ |
3775 | fd = xopen_stdin(g_progname); | 3756 | while ((ch = getopt(argc, argv, OPTSTR_AWK)) >= 0) { |
3757 | switch (ch) { | ||
3758 | case 'F': | ||
3759 | unescape_string_in_place(optarg); | ||
3760 | setvar_s(intvar[FS], optarg); | ||
3761 | break; | ||
3762 | case 'v': | ||
3763 | if (!try_to_assign(optarg)) | ||
3764 | bb_show_usage(); | ||
3765 | break; | ||
3766 | //TODO: implement -i LIBRARY, it is easy-ish | ||
3767 | case 'E': | ||
3768 | case 'f': { | ||
3769 | int fd; | ||
3770 | char *s; | ||
3771 | g_progname = optarg; | ||
3772 | fd = xopen_stdin(g_progname); | ||
3776 | #if ENABLE_PLATFORM_MINGW32 | 3773 | #if ENABLE_PLATFORM_MINGW32 |
3777 | _setmode(fd, _O_TEXT); | 3774 | _setmode(fd, _O_TEXT); |
3778 | #endif | 3775 | #endif |
3779 | s = xmalloc_read(fd, NULL); /* it's NUL-terminated */ | 3776 | s = xmalloc_read(fd, NULL); /* it's NUL-terminated */ |
3780 | if (!s) | 3777 | if (!s) |
3781 | bb_perror_msg_and_die("read error from '%s'", g_progname); | 3778 | bb_perror_msg_and_die("read error from '%s'", g_progname); |
3782 | close(fd); | 3779 | close(fd); |
3783 | parse_program(s); | 3780 | parse_program(s); |
3784 | free(s); | 3781 | free(s); |
3785 | } | 3782 | got_program = 1; |
3786 | g_progname = "cmd. line"; | 3783 | if (ch == 'E') { |
3784 | got_program = 2; | ||
3785 | goto stop_option_parsing; | ||
3786 | } | ||
3787 | break; | ||
3788 | } | ||
3787 | #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS | 3789 | #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS |
3788 | while (list_e) { | 3790 | case 'e': |
3789 | parse_program(llist_pop(&list_e)); | 3791 | g_progname = "cmd. line"; |
3790 | } | 3792 | parse_program(optarg); |
3793 | got_program = 1; | ||
3794 | break; | ||
3791 | #endif | 3795 | #endif |
3792 | //FIXME: preserve order of -e and -f | 3796 | case 'W': |
3793 | //TODO: implement -i LIBRARY and -E FILE too, they are easy-ish | 3797 | bb_simple_error_msg("warning: option -W is ignored"); |
3794 | if (!(opt & (OPT_f | OPT_e))) { | 3798 | break; |
3799 | default: | ||
3800 | //bb_error_msg("ch:%d", ch); | ||
3801 | bb_show_usage(); | ||
3802 | } | ||
3803 | } | ||
3804 | stop_option_parsing: | ||
3805 | |||
3806 | argv += optind; | ||
3807 | //argc -= optind; | ||
3808 | |||
3809 | if (!got_program) { | ||
3795 | if (!*argv) | 3810 | if (!*argv) |
3796 | bb_show_usage(); | 3811 | bb_show_usage(); |
3812 | g_progname = "cmd. line"; | ||
3797 | parse_program(*argv++); | 3813 | parse_program(*argv++); |
3798 | } | 3814 | } |
3815 | |||
3799 | /* Free unused parse structures */ | 3816 | /* Free unused parse structures */ |
3800 | //hash_free(fnhash); // ~250 bytes when empty, used only for function names | 3817 | //hash_free(fnhash); // ~250 bytes when empty, used only for function names |
3801 | //^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs | 3818 | //^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs |