aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-09-08 09:52:04 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-09-08 09:52:04 +0200
commit48cb983b136fb74c61db594a30e18bdc42b7264c (patch)
treedfd043047bec76c4f09e9ff535e47bd449d1140a /shell
parent8c68ae8416c8b54222eb3cd1d4908a570147e134 (diff)
downloadbusybox-w32-48cb983b136fb74c61db594a30e18bdc42b7264c.tar.gz
busybox-w32-48cb983b136fb74c61db594a30e18bdc42b7264c.tar.bz2
busybox-w32-48cb983b136fb74c61db594a30e18bdc42b7264c.zip
ash: parser: Get rid of PEOA
Upstream commit: Date: Wed, 27 May 2020 12:19:13 +1000 parser: Get rid of PEOA PEOA is a special character used to mark an alias as being finished so that we don't enter an infinite loop with nested aliases. It complicates the parser because we have to ensure that it is skipped where necessary and not copied to the resulting token text. This patch removes it and instead delays the marking of aliases until the second pgetc. This has the same effect as the current PEOA code while keeping the complexities within the input code. This adds ~32 bytes of global data: function old new delta __pgetc - 512 +512 freestrings - 95 +95 popfile 86 110 +24 pushstring 141 160 +19 basepf 76 84 +8 syntax_index_table 258 257 -1 S_I_T 30 28 -2 .rodata 104255 104247 -8 pgetc_without_PEOA 13 - -13 xxreadtoken 230 215 -15 popstring 158 120 -38 readtoken1 3110 3045 -65 pgetc 547 22 -525 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 3/7 up/down: 658/-667) Total: -9 bytes text data bss dec hex filename 1043102 559 5020 1048681 100069 busybox_old 1043085 559 5052 1048696 100078 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c239
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
3030static const uint16_t S_I_T[] ALIGN2 = { 3036static 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 */
3053enum { 3056enum {
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
10739static void 10722static void popstring(void)
10740popstring(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)
10856static int pgetc(void); 10833static int __pgetc(void);
10857static int 10834static int
10858preadbuffer(void) 10835preadbuffer(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
10969static int 10936static void freestrings(struct strpush *sp)
10970pgetc(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
10960static 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/*
10993static int 10983 * Read a character from the script, returning PEOF on end of file.
10994pgetc_without_PEOA(void) 10984 * Nul characters in the input are silently discarded.
10985 */
10986static 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
12390readtoken1(int c, int syntax, char *eofmark, int striptabs) 12381readtoken1(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)