diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 239 |
1 files changed, 108 insertions, 131 deletions
diff --git a/shell/ash.c b/shell/ash.c index 5a001b004..ba116d83a 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -295,6 +295,10 @@ typedef long arith_t; | |||
295 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | 295 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ |
296 | #endif | 296 | #endif |
297 | 297 | ||
298 | #ifndef unlikely | ||
299 | # define unlikely(cond) (cond) | ||
300 | #endif | ||
301 | |||
298 | #if !BB_MMU | 302 | #if !BB_MMU |
299 | # error "Do not even bother, ash will not run on NOMMU machine" | 303 | # error "Do not even bother, ash will not run on NOMMU machine" |
300 | #endif | 304 | #endif |
@@ -583,6 +587,9 @@ struct strpush { | |||
583 | #endif | 587 | #endif |
584 | char *string; /* remember the string since it may change */ | 588 | char *string; /* remember the string since it may change */ |
585 | 589 | ||
590 | /* Delay freeing so we can stop nested aliases. */ | ||
591 | struct strpush *spfree; | ||
592 | |||
586 | /* Remember last two characters for pungetc. */ | 593 | /* Remember last two characters for pungetc. */ |
587 | int lastc[2]; | 594 | int lastc[2]; |
588 | 595 | ||
@@ -605,6 +612,9 @@ struct parsefile { | |||
605 | struct strpush *strpush; /* for pushing strings at this level */ | 612 | struct strpush *strpush; /* for pushing strings at this level */ |
606 | struct strpush basestrpush; /* so pushing one is fast */ | 613 | struct strpush basestrpush; /* so pushing one is fast */ |
607 | 614 | ||
615 | /* Delay freeing so we can stop nested aliases. */ | ||
616 | struct strpush *spfree; | ||
617 | |||
608 | /* Remember last two characters for pungetc. */ | 618 | /* Remember last two characters for pungetc. */ |
609 | int lastc[2]; | 619 | int lastc[2]; |
610 | 620 | ||
@@ -3013,12 +3023,8 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3013 | #define CENDFILE 11 /* end of file */ | 3023 | #define CENDFILE 11 /* end of file */ |
3014 | #define CCTL 12 /* like CWORD, except it must be escaped */ | 3024 | #define CCTL 12 /* like CWORD, except it must be escaped */ |
3015 | #define CSPCL 13 /* these terminate a word */ | 3025 | #define CSPCL 13 /* these terminate a word */ |
3016 | #define CIGN 14 /* character should be ignored */ | ||
3017 | 3026 | ||
3018 | #define PEOF 256 | 3027 | #define PEOF 256 |
3019 | #if ENABLE_ASH_ALIAS | ||
3020 | # define PEOA 257 | ||
3021 | #endif | ||
3022 | 3028 | ||
3023 | #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE | 3029 | #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE |
3024 | 3030 | ||
@@ -3028,49 +3034,43 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3028 | # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8)) | 3034 | # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8)) |
3029 | #endif | 3035 | #endif |
3030 | static const uint16_t S_I_T[] ALIGN2 = { | 3036 | static const uint16_t S_I_T[] ALIGN2 = { |
3031 | #if ENABLE_ASH_ALIAS | 3037 | SIT_ITEM(CSPCL , CWORD , CWORD, CWORD ), /* 0, ' ' */ |
3032 | SIT_ITEM(CSPCL , CIGN , CIGN , CIGN ), /* 0, PEOA */ | 3038 | SIT_ITEM(CNL , CNL , CNL , CNL ), /* 1, \n */ |
3033 | #endif | 3039 | SIT_ITEM(CWORD , CCTL , CCTL , CWORD ), /* 2, !*-/:=?[]~ */ |
3034 | SIT_ITEM(CSPCL , CWORD , CWORD, CWORD ), /* 1, ' ' */ | 3040 | SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD ), /* 3, '"' */ |
3035 | SIT_ITEM(CNL , CNL , CNL , CNL ), /* 2, \n */ | 3041 | SIT_ITEM(CVAR , CVAR , CWORD, CVAR ), /* 4, $ */ |
3036 | SIT_ITEM(CWORD , CCTL , CCTL , CWORD ), /* 3, !*-/:=?[]~ */ | 3042 | SIT_ITEM(CSQUOTE , CWORD , CENDQUOTE, CWORD), /* 5, "'" */ |
3037 | SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD ), /* 4, '"' */ | 3043 | SIT_ITEM(CSPCL , CWORD , CWORD, CLP ), /* 6, ( */ |
3038 | SIT_ITEM(CVAR , CVAR , CWORD, CVAR ), /* 5, $ */ | 3044 | SIT_ITEM(CSPCL , CWORD , CWORD, CRP ), /* 7, ) */ |
3039 | SIT_ITEM(CSQUOTE , CWORD , CENDQUOTE, CWORD), /* 6, "'" */ | 3045 | SIT_ITEM(CBACK , CBACK , CCTL , CBACK ), /* 8, \ */ |
3040 | SIT_ITEM(CSPCL , CWORD , CWORD, CLP ), /* 7, ( */ | 3046 | SIT_ITEM(CBQUOTE , CBQUOTE , CWORD, CBQUOTE), /* 9, ` */ |
3041 | SIT_ITEM(CSPCL , CWORD , CWORD, CRP ), /* 8, ) */ | 3047 | SIT_ITEM(CENDVAR , CENDVAR , CWORD, CENDVAR), /* 10, } */ |
3042 | SIT_ITEM(CBACK , CBACK , CCTL , CBACK ), /* 9, \ */ | ||
3043 | SIT_ITEM(CBQUOTE , CBQUOTE , CWORD, CBQUOTE), /* 10, ` */ | ||
3044 | SIT_ITEM(CENDVAR , CENDVAR , CWORD, CENDVAR), /* 11, } */ | ||
3045 | #if !USE_SIT_FUNCTION | 3048 | #if !USE_SIT_FUNCTION |
3046 | SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 12, PEOF */ | 3049 | SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 11, PEOF */ |
3047 | SIT_ITEM(CWORD , CWORD , CWORD, CWORD ), /* 13, 0-9A-Za-z */ | 3050 | SIT_ITEM(CWORD , CWORD , CWORD, CWORD ), /* 12, 0-9A-Za-z */ |
3048 | SIT_ITEM(CCTL , CCTL , CCTL , CCTL ) /* 14, CTLESC ... */ | 3051 | SIT_ITEM(CCTL , CCTL , CCTL , CCTL ) /* 13, CTLESC ... */ |
3049 | #endif | 3052 | #endif |
3050 | #undef SIT_ITEM | 3053 | #undef SIT_ITEM |
3051 | }; | 3054 | }; |
3052 | /* Constants below must match table above */ | 3055 | /* Constants below must match table above */ |
3053 | enum { | 3056 | enum { |
3054 | #if ENABLE_ASH_ALIAS | 3057 | CSPCL_CWORD_CWORD_CWORD , /* 0 */ |
3055 | CSPCL_CIGN_CIGN_CIGN , /* 0 */ | 3058 | CNL_CNL_CNL_CNL , /* 1 */ |
3056 | #endif | 3059 | CWORD_CCTL_CCTL_CWORD , /* 2 */ |
3057 | CSPCL_CWORD_CWORD_CWORD , /* 1 */ | 3060 | CDQUOTE_CENDQUOTE_CWORD_CWORD , /* 3 */ |
3058 | CNL_CNL_CNL_CNL , /* 2 */ | 3061 | CVAR_CVAR_CWORD_CVAR , /* 4 */ |
3059 | CWORD_CCTL_CCTL_CWORD , /* 3 */ | 3062 | CSQUOTE_CWORD_CENDQUOTE_CWORD , /* 5 */ |
3060 | CDQUOTE_CENDQUOTE_CWORD_CWORD , /* 4 */ | 3063 | CSPCL_CWORD_CWORD_CLP , /* 6 */ |
3061 | CVAR_CVAR_CWORD_CVAR , /* 5 */ | 3064 | CSPCL_CWORD_CWORD_CRP , /* 7 */ |
3062 | CSQUOTE_CWORD_CENDQUOTE_CWORD , /* 6 */ | 3065 | CBACK_CBACK_CCTL_CBACK , /* 8 */ |
3063 | CSPCL_CWORD_CWORD_CLP , /* 7 */ | 3066 | CBQUOTE_CBQUOTE_CWORD_CBQUOTE , /* 9 */ |
3064 | CSPCL_CWORD_CWORD_CRP , /* 8 */ | 3067 | CENDVAR_CENDVAR_CWORD_CENDVAR , /* 10 */ |
3065 | CBACK_CBACK_CCTL_CBACK , /* 9 */ | 3068 | CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 11 */ |
3066 | CBQUOTE_CBQUOTE_CWORD_CBQUOTE , /* 10 */ | 3069 | CWORD_CWORD_CWORD_CWORD , /* 12 */ |
3067 | CENDVAR_CENDVAR_CWORD_CENDVAR , /* 11 */ | 3070 | CCTL_CCTL_CCTL_CCTL , /* 13 */ |
3068 | CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 12 */ | ||
3069 | CWORD_CWORD_CWORD_CWORD , /* 13 */ | ||
3070 | CCTL_CCTL_CCTL_CCTL , /* 14 */ | ||
3071 | }; | 3071 | }; |
3072 | 3072 | ||
3073 | /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF, | 3073 | /* c in SIT(c, syntax) must be an *unsigned char* or PEOF, |
3074 | * caller must ensure proper cast on it if c is *char_ptr! | 3074 | * caller must ensure proper cast on it if c is *char_ptr! |
3075 | */ | 3075 | */ |
3076 | #if USE_SIT_FUNCTION | 3076 | #if USE_SIT_FUNCTION |
@@ -3088,44 +3088,28 @@ SIT(int c, int syntax) | |||
3088 | * but glibc one isn't. With '/' always treated as CWORD, | 3088 | * but glibc one isn't. With '/' always treated as CWORD, |
3089 | * both work fine. | 3089 | * both work fine. |
3090 | */ | 3090 | */ |
3091 | # if ENABLE_ASH_ALIAS | ||
3092 | static const uint8_t syntax_index_table[] ALIGN1 = { | ||
3093 | 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */ | ||
3094 | 7, 8, 3, 3,/*3,*/3, 1, 1, /* "()*-/:;<" */ | ||
3095 | 3, 1, 3, 3, 9, 3, 10, 1, /* "=>?[\\]`|" */ | ||
3096 | 11, 3 /* "}~" */ | ||
3097 | }; | ||
3098 | # else | ||
3099 | static const uint8_t syntax_index_table[] ALIGN1 = { | 3091 | static const uint8_t syntax_index_table[] ALIGN1 = { |
3100 | 0, 1, 0, 2, 3, 4, 0, 5, /* "\t\n !\"$&'" */ | 3092 | 0, 1, 0, 2, 3, 4, 0, 5, /* "\t\n !\"$&'" */ |
3101 | 6, 7, 2, 2,/*2,*/2, 0, 0, /* "()*-/:;<" */ | 3093 | 6, 7, 2, 2,/*2,*/2, 0, 0, /* "()*-/:;<" */ |
3102 | 2, 0, 2, 2, 8, 2, 9, 0, /* "=>?[\\]`|" */ | 3094 | 2, 0, 2, 2, 8, 2, 9, 0, /* "=>?[\\]`|" */ |
3103 | 10, 2 /* "}~" */ | 3095 | 10, 2 /* "}~" */ |
3104 | }; | 3096 | }; |
3105 | # endif | ||
3106 | const char *s; | 3097 | const char *s; |
3107 | int indx; | 3098 | int indx; |
3108 | 3099 | ||
3109 | if (c == PEOF) | 3100 | if (c == PEOF) |
3110 | return CENDFILE; | 3101 | return CENDFILE; |
3111 | # if ENABLE_ASH_ALIAS | 3102 | /* Cast is purely for paranoia here, |
3112 | if (c == PEOA) | 3103 | * just in case someone passed signed char to us */ |
3113 | indx = 0; | 3104 | if ((unsigned char)c >= CTL_FIRST |
3114 | else | 3105 | && (unsigned char)c <= CTL_LAST |
3115 | # endif | 3106 | ) { |
3116 | { | 3107 | return CCTL; |
3117 | /* Cast is purely for paranoia here, | ||
3118 | * just in case someone passed signed char to us */ | ||
3119 | if ((unsigned char)c >= CTL_FIRST | ||
3120 | && (unsigned char)c <= CTL_LAST | ||
3121 | ) { | ||
3122 | return CCTL; | ||
3123 | } | ||
3124 | s = strchrnul(spec_symbls, c); | ||
3125 | if (*s == '\0') | ||
3126 | return CWORD; | ||
3127 | indx = syntax_index_table[s - spec_symbls]; | ||
3128 | } | 3108 | } |
3109 | s = strchrnul(spec_symbls, c); | ||
3110 | if (*s == '\0') | ||
3111 | return CWORD; | ||
3112 | indx = syntax_index_table[s - spec_symbls]; | ||
3129 | return (S_I_T[indx] >> (syntax*4)) & 0xf; | 3113 | return (S_I_T[indx] >> (syntax*4)) & 0xf; |
3130 | } | 3114 | } |
3131 | 3115 | ||
@@ -3396,9 +3380,6 @@ static const uint8_t syntax_index_table[] ALIGN1 = { | |||
3396 | /* 254 */ CWORD_CWORD_CWORD_CWORD, | 3380 | /* 254 */ CWORD_CWORD_CWORD_CWORD, |
3397 | /* 255 */ CWORD_CWORD_CWORD_CWORD, | 3381 | /* 255 */ CWORD_CWORD_CWORD_CWORD, |
3398 | /* PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE, | 3382 | /* PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE, |
3399 | # if ENABLE_ASH_ALIAS | ||
3400 | /* PEOA */ CSPCL_CIGN_CIGN_CIGN, | ||
3401 | # endif | ||
3402 | }; | 3383 | }; |
3403 | 3384 | ||
3404 | #if 1 | 3385 | #if 1 |
@@ -10712,7 +10693,7 @@ pushstring(char *s, struct alias *ap) | |||
10712 | 10693 | ||
10713 | len = strlen(s); | 10694 | len = strlen(s); |
10714 | INT_OFF; | 10695 | INT_OFF; |
10715 | if (g_parsefile->strpush) { | 10696 | if (g_parsefile->strpush || g_parsefile->spfree) { |
10716 | sp = ckzalloc(sizeof(*sp)); | 10697 | sp = ckzalloc(sizeof(*sp)); |
10717 | sp->prev = g_parsefile->strpush; | 10698 | sp->prev = g_parsefile->strpush; |
10718 | } else { | 10699 | } else { |
@@ -10722,6 +10703,7 @@ pushstring(char *s, struct alias *ap) | |||
10722 | sp->prev_string = g_parsefile->next_to_pgetc; | 10703 | sp->prev_string = g_parsefile->next_to_pgetc; |
10723 | sp->prev_left_in_line = g_parsefile->left_in_line; | 10704 | sp->prev_left_in_line = g_parsefile->left_in_line; |
10724 | sp->unget = g_parsefile->unget; | 10705 | sp->unget = g_parsefile->unget; |
10706 | sp->spfree = g_parsefile->spfree; | ||
10725 | memcpy(sp->lastc, g_parsefile->lastc, sizeof(sp->lastc)); | 10707 | memcpy(sp->lastc, g_parsefile->lastc, sizeof(sp->lastc)); |
10726 | #if ENABLE_ASH_ALIAS | 10708 | #if ENABLE_ASH_ALIAS |
10727 | sp->ap = ap; | 10709 | sp->ap = ap; |
@@ -10733,11 +10715,11 @@ pushstring(char *s, struct alias *ap) | |||
10733 | g_parsefile->next_to_pgetc = s; | 10715 | g_parsefile->next_to_pgetc = s; |
10734 | g_parsefile->left_in_line = len; | 10716 | g_parsefile->left_in_line = len; |
10735 | g_parsefile->unget = 0; | 10717 | g_parsefile->unget = 0; |
10718 | g_parsefile->spfree = NULL; | ||
10736 | INT_ON; | 10719 | INT_ON; |
10737 | } | 10720 | } |
10738 | 10721 | ||
10739 | static void | 10722 | static void popstring(void) |
10740 | popstring(void) | ||
10741 | { | 10723 | { |
10742 | struct strpush *sp = g_parsefile->strpush; | 10724 | struct strpush *sp = g_parsefile->strpush; |
10743 | 10725 | ||
@@ -10752,10 +10734,6 @@ popstring(void) | |||
10752 | if (sp->string != sp->ap->val) { | 10734 | if (sp->string != sp->ap->val) { |
10753 | free(sp->string); | 10735 | free(sp->string); |
10754 | } | 10736 | } |
10755 | sp->ap->flag &= ~ALIASINUSE; | ||
10756 | if (sp->ap->flag & ALIASDEAD) { | ||
10757 | unalias(sp->ap->name); | ||
10758 | } | ||
10759 | } | 10737 | } |
10760 | #endif | 10738 | #endif |
10761 | g_parsefile->next_to_pgetc = sp->prev_string; | 10739 | g_parsefile->next_to_pgetc = sp->prev_string; |
@@ -10763,8 +10741,7 @@ popstring(void) | |||
10763 | g_parsefile->unget = sp->unget; | 10741 | g_parsefile->unget = sp->unget; |
10764 | memcpy(g_parsefile->lastc, sp->lastc, sizeof(sp->lastc)); | 10742 | memcpy(g_parsefile->lastc, sp->lastc, sizeof(sp->lastc)); |
10765 | g_parsefile->strpush = sp->prev; | 10743 | g_parsefile->strpush = sp->prev; |
10766 | if (sp != &(g_parsefile->basestrpush)) | 10744 | g_parsefile->spfree = sp; |
10767 | free(sp); | ||
10768 | INT_ON; | 10745 | INT_ON; |
10769 | } | 10746 | } |
10770 | 10747 | ||
@@ -10853,26 +10830,16 @@ preadfd(void) | |||
10853 | */ | 10830 | */ |
10854 | //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__) | 10831 | //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__) |
10855 | #define pgetc_debug(...) ((void)0) | 10832 | #define pgetc_debug(...) ((void)0) |
10856 | static int pgetc(void); | 10833 | static int __pgetc(void); |
10857 | static int | 10834 | static int |
10858 | preadbuffer(void) | 10835 | preadbuffer(void) |
10859 | { | 10836 | { |
10860 | char *q; | 10837 | char *q; |
10861 | int more; | 10838 | int more; |
10862 | 10839 | ||
10863 | if (g_parsefile->strpush) { | 10840 | if (unlikely(g_parsefile->strpush)) { |
10864 | #if ENABLE_ASH_ALIAS | ||
10865 | if (g_parsefile->left_in_line == -1 | ||
10866 | && g_parsefile->strpush->ap | ||
10867 | && g_parsefile->next_to_pgetc[-1] != ' ' | ||
10868 | && g_parsefile->next_to_pgetc[-1] != '\t' | ||
10869 | ) { | ||
10870 | pgetc_debug("preadbuffer PEOA"); | ||
10871 | return PEOA; | ||
10872 | } | ||
10873 | #endif | ||
10874 | popstring(); | 10841 | popstring(); |
10875 | return pgetc(); | 10842 | return __pgetc(); |
10876 | } | 10843 | } |
10877 | /* on both branches above g_parsefile->left_in_line < 0. | 10844 | /* on both branches above g_parsefile->left_in_line < 0. |
10878 | * "pgetc" needs refilling. | 10845 | * "pgetc" needs refilling. |
@@ -10966,8 +10933,31 @@ nlnoprompt(void) | |||
10966 | needprompt = doprompt; | 10933 | needprompt = doprompt; |
10967 | } | 10934 | } |
10968 | 10935 | ||
10969 | static int | 10936 | static void freestrings(struct strpush *sp) |
10970 | pgetc(void) | 10937 | { |
10938 | INT_OFF; | ||
10939 | do { | ||
10940 | struct strpush *psp; | ||
10941 | |||
10942 | if (sp->ap) { | ||
10943 | sp->ap->flag &= ~ALIASINUSE; | ||
10944 | if (sp->ap->flag & ALIASDEAD) { | ||
10945 | unalias(sp->ap->name); | ||
10946 | } | ||
10947 | } | ||
10948 | |||
10949 | psp = sp; | ||
10950 | sp = sp->spfree; | ||
10951 | |||
10952 | if (psp != &(g_parsefile->basestrpush)) | ||
10953 | free(psp); | ||
10954 | } while (sp); | ||
10955 | |||
10956 | g_parsefile->spfree = NULL; | ||
10957 | INT_ON; | ||
10958 | } | ||
10959 | |||
10960 | static int __pgetc(void) | ||
10971 | { | 10961 | { |
10972 | int c; | 10962 | int c; |
10973 | 10963 | ||
@@ -10989,23 +10979,19 @@ pgetc(void) | |||
10989 | return c; | 10979 | return c; |
10990 | } | 10980 | } |
10991 | 10981 | ||
10992 | #if ENABLE_ASH_ALIAS | 10982 | /* |
10993 | static int | 10983 | * Read a character from the script, returning PEOF on end of file. |
10994 | pgetc_without_PEOA(void) | 10984 | * Nul characters in the input are silently discarded. |
10985 | */ | ||
10986 | static int pgetc(void) | ||
10995 | { | 10987 | { |
10996 | int c; | 10988 | struct strpush *sp = g_parsefile->spfree; |
10997 | do { | 10989 | |
10998 | pgetc_debug("pgetc at %d:%p'%s'", | 10990 | if (unlikely(sp)) |
10999 | g_parsefile->left_in_line, | 10991 | freestrings(sp); |
11000 | g_parsefile->next_to_pgetc, | 10992 | |
11001 | g_parsefile->next_to_pgetc); | 10993 | return __pgetc(); |
11002 | c = pgetc(); | ||
11003 | } while (c == PEOA); | ||
11004 | return c; | ||
11005 | } | 10994 | } |
11006 | #else | ||
11007 | # define pgetc_without_PEOA() pgetc() | ||
11008 | #endif | ||
11009 | 10995 | ||
11010 | /* | 10996 | /* |
11011 | * Undo a call to pgetc. Only two characters may be pushed back. | 10997 | * Undo a call to pgetc. Only two characters may be pushed back. |
@@ -11082,6 +11068,7 @@ pushfile(void) | |||
11082 | pf->prev = g_parsefile; | 11068 | pf->prev = g_parsefile; |
11083 | pf->pf_fd = -1; | 11069 | pf->pf_fd = -1; |
11084 | /*pf->strpush = NULL; - ckzalloc did it */ | 11070 | /*pf->strpush = NULL; - ckzalloc did it */ |
11071 | /*pf->spfree = NULL;*/ | ||
11085 | /*pf->basestrpush.prev = NULL;*/ | 11072 | /*pf->basestrpush.prev = NULL;*/ |
11086 | /*pf->unget = 0;*/ | 11073 | /*pf->unget = 0;*/ |
11087 | g_parsefile = pf; | 11074 | g_parsefile = pf; |
@@ -11099,8 +11086,12 @@ popfile(void) | |||
11099 | if (pf->pf_fd >= 0) | 11086 | if (pf->pf_fd >= 0) |
11100 | close(pf->pf_fd); | 11087 | close(pf->pf_fd); |
11101 | free(pf->buf); | 11088 | free(pf->buf); |
11102 | while (pf->strpush) | 11089 | if (g_parsefile->spfree) |
11090 | freestrings(g_parsefile->spfree); | ||
11091 | while (pf->strpush) { | ||
11103 | popstring(); | 11092 | popstring(); |
11093 | freestrings(g_parsefile->spfree); | ||
11094 | } | ||
11104 | g_parsefile = pf->prev; | 11095 | g_parsefile = pf->prev; |
11105 | free(pf); | 11096 | free(pf); |
11106 | INT_ON; | 11097 | INT_ON; |
@@ -12390,7 +12381,7 @@ static int | |||
12390 | readtoken1(int c, int syntax, char *eofmark, int striptabs) | 12381 | readtoken1(int c, int syntax, char *eofmark, int striptabs) |
12391 | { | 12382 | { |
12392 | /* NB: syntax parameter fits into smallint */ | 12383 | /* NB: syntax parameter fits into smallint */ |
12393 | /* c parameter is an unsigned char or PEOF or PEOA */ | 12384 | /* c parameter is an unsigned char or PEOF */ |
12394 | char *out; | 12385 | char *out; |
12395 | size_t len; | 12386 | size_t len; |
12396 | struct nodelist *bqlist; | 12387 | struct nodelist *bqlist; |
@@ -12460,7 +12451,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
12460 | USTPUTC(c, out); | 12451 | USTPUTC(c, out); |
12461 | break; | 12452 | break; |
12462 | case CBACK: /* backslash */ | 12453 | case CBACK: /* backslash */ |
12463 | c = pgetc_without_PEOA(); | 12454 | c = pgetc(); |
12464 | if (c == PEOF) { | 12455 | if (c == PEOF) { |
12465 | USTPUTC(CTLESC, out); | 12456 | USTPUTC(CTLESC, out); |
12466 | USTPUTC('\\', out); | 12457 | USTPUTC('\\', out); |
@@ -12567,8 +12558,6 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
12567 | break; | 12558 | break; |
12568 | case CENDFILE: | 12559 | case CENDFILE: |
12569 | goto endword; /* exit outer loop */ | 12560 | goto endword; /* exit outer loop */ |
12570 | case CIGN: | ||
12571 | break; | ||
12572 | default: | 12561 | default: |
12573 | if (synstack->varnest == 0) { | 12562 | if (synstack->varnest == 0) { |
12574 | #if BASH_REDIR_OUTPUT | 12563 | #if BASH_REDIR_OUTPUT |
@@ -12590,8 +12579,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
12590 | #endif | 12579 | #endif |
12591 | goto endword; /* exit outer loop */ | 12580 | goto endword; /* exit outer loop */ |
12592 | } | 12581 | } |
12593 | IF_ASH_ALIAS(if (c != PEOA)) | 12582 | USTPUTC(c, out); |
12594 | USTPUTC(c, out); | ||
12595 | } | 12583 | } |
12596 | c = pgetc_top(synstack); | 12584 | c = pgetc_top(synstack); |
12597 | } /* for (;;) */ | 12585 | } /* for (;;) */ |
@@ -12642,14 +12630,9 @@ checkend: { | |||
12642 | int markloc; | 12630 | int markloc; |
12643 | char *p; | 12631 | char *p; |
12644 | 12632 | ||
12645 | #if ENABLE_ASH_ALIAS | ||
12646 | if (c == PEOA) | ||
12647 | c = pgetc_without_PEOA(); | ||
12648 | #endif | ||
12649 | if (striptabs) { | 12633 | if (striptabs) { |
12650 | while (c == '\t') { | 12634 | while (c == '\t') |
12651 | c = pgetc_without_PEOA(); | 12635 | c = pgetc(); |
12652 | } | ||
12653 | } | 12636 | } |
12654 | 12637 | ||
12655 | markloc = out - (char *)stackblock(); | 12638 | markloc = out - (char *)stackblock(); |
@@ -12663,7 +12646,7 @@ checkend: { | |||
12663 | * F | 12646 | * F |
12664 | * (see heredoc_bkslash_newline2.tests) | 12647 | * (see heredoc_bkslash_newline2.tests) |
12665 | */ | 12648 | */ |
12666 | c = pgetc_without_PEOA(); | 12649 | c = pgetc(); |
12667 | } | 12650 | } |
12668 | 12651 | ||
12669 | if (c == '\n' || c == PEOF) { | 12652 | if (c == '\n' || c == PEOF) { |
@@ -12788,7 +12771,6 @@ parsesub: { | |||
12788 | 12771 | ||
12789 | c = pgetc_eatbnl(); | 12772 | c = pgetc_eatbnl(); |
12790 | if ((checkkwd & CHKEOFMARK) | 12773 | if ((checkkwd & CHKEOFMARK) |
12791 | || c > 255 /* PEOA or PEOF */ | ||
12792 | || (c != '(' && c != '{' && !is_name(c) && !is_special(c)) | 12774 | || (c != '(' && c != '{' && !is_name(c) && !is_special(c)) |
12793 | ) { | 12775 | ) { |
12794 | #if BASH_DOLLAR_SQUOTE | 12776 | #if BASH_DOLLAR_SQUOTE |
@@ -12811,7 +12793,7 @@ parsesub: { | |||
12811 | PARSEBACKQNEW(); | 12793 | PARSEBACKQNEW(); |
12812 | } | 12794 | } |
12813 | } else { | 12795 | } else { |
12814 | /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */ | 12796 | /* $VAR, $<specialchar>, ${...}, or PEOF */ |
12815 | smalluint newsyn = synstack->syntax; | 12797 | smalluint newsyn = synstack->syntax; |
12816 | 12798 | ||
12817 | USTPUTC(CTLVAR, out); | 12799 | USTPUTC(CTLVAR, out); |
@@ -13006,13 +12988,9 @@ parsebackq: { | |||
13006 | ) { | 12988 | ) { |
13007 | STPUTC('\\', pout); | 12989 | STPUTC('\\', pout); |
13008 | } | 12990 | } |
13009 | if (pc <= 255 /* not PEOA or PEOF */) { | 12991 | break; |
13010 | break; | ||
13011 | } | ||
13012 | /* fall through */ | ||
13013 | 12992 | ||
13014 | case PEOF: | 12993 | case PEOF: |
13015 | IF_ASH_ALIAS(case PEOA:) | ||
13016 | raise_error_syntax("EOF in backquote substitution"); | 12994 | raise_error_syntax("EOF in backquote substitution"); |
13017 | 12995 | ||
13018 | case '\n': | 12996 | case '\n': |
@@ -13147,7 +13125,7 @@ xxreadtoken(void) | |||
13147 | setprompt_if(needprompt, 2); | 13125 | setprompt_if(needprompt, 2); |
13148 | for (;;) { /* until token or start of word found */ | 13126 | for (;;) { /* until token or start of word found */ |
13149 | c = pgetc_eatbnl(); | 13127 | c = pgetc_eatbnl(); |
13150 | if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA)) | 13128 | if (c == ' ' || c == '\t') |
13151 | continue; | 13129 | continue; |
13152 | 13130 | ||
13153 | if (c == '#') { | 13131 | if (c == '#') { |
@@ -13205,7 +13183,6 @@ xxreadtoken(void) | |||
13205 | c = pgetc_eatbnl(); | 13183 | c = pgetc_eatbnl(); |
13206 | switch (c) { | 13184 | switch (c) { |
13207 | case ' ': case '\t': | 13185 | case ' ': case '\t': |
13208 | IF_ASH_ALIAS(case PEOA:) | ||
13209 | continue; | 13186 | continue; |
13210 | case '#': | 13187 | case '#': |
13211 | while ((c = pgetc()) != '\n' && c != PEOF) | 13188 | while ((c = pgetc()) != '\n' && c != PEOF) |