aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
Diffstat (limited to 'editors')
-rw-r--r--editors/awk.c115
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:"
82enum { 82enum {
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)
3695int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 3699int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
3696int awk_main(int argc UNUSED_PARAM, char **argv) 3700int 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