Skip to content

Commit

Permalink
Fcin: make the fcgetc() macro less ugly
Browse files Browse the repository at this point in the history
The fcgetc() macro of the Fcin interface (fast I/O library used by
the lexer and parser) is written in an annoying and confusing way:

 #define fcgetc(c) (((c=fcget()) || (c=fcfill())), c)
 #define fcget()   ((int)(*_Fcin.fcptr++))

...where fcfill() is a function that reads more data from the input
file after the buffer runs out.

The fcgetc() macro modifies the variable passed to it, and also
returns that variable's value. This is quite redundant, and makes
the macro usage in the code misleading and confusing. It also
requires a scratch variable to simply skip a character.

To fix this awfulness, we don't need to go as far as ksh2020 did[*]
and convert the macro to a library function, slightly impacting
performance. Instead, we can rewrite it into a simple function-like
macro that doesn't take any arguments:

 #define fcgetc() (*_Fcin.fcptr++ ? (int)_Fcin.fcptr[-1] : fcfill())

which means that, e.g., fcgetc(c) is now changed to c = fcgetc(),
and we can eliminate variables where the stored value isn't used.

[*] att@86f38e4c
  • Loading branch information
McDutchie committed Dec 5, 2024
1 parent 6b55697 commit 6cada38
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 52 deletions.
4 changes: 2 additions & 2 deletions src/cmd/ksh93/include/fcin.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1982-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
Expand Down Expand Up @@ -46,7 +46,7 @@ typedef struct _fcin
# define fcmbget(x) (fcget())
#endif
#define fcfile() (_Fcin._fcfile)
#define fcgetc(c) (((c=fcget()) || (c=fcfill())), c)
#define fcgetc() (*_Fcin.fcptr++ ? (int)_Fcin.fcptr[-1] : fcfill())
#define fcget() ((int)(*_Fcin.fcptr++))
#define fcpeek(n) ((int)_Fcin.fcptr[n])
#define fcseek(n) ((char*)(_Fcin.fcptr+=(n)))
Expand Down
66 changes: 33 additions & 33 deletions src/cmd/ksh93/sh/lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ int sh_lex(Lex_t* lp)
if(lp->noreserv)
{
lp->lex.reservok = 0;
while((fcgetc(c)) && (c==' ' || c== '\t' || c=='\n'))
while((c = fcgetc()) && (c==' ' || c== '\t' || c=='\n'))
if(c=='\n')
sh.inlineno++;
fcseek(-LEN);
Expand All @@ -286,7 +286,7 @@ int sh_lex(Lex_t* lp)
}
else if(lp->lexd.docword)
{
if(fcgetc(c)=='-' || c=='#')
if((c = fcgetc())=='-' || c=='#')
{
lp->lexd.docword++;
lp->digits=(c=='#'?3:1);
Expand Down Expand Up @@ -388,7 +388,7 @@ int sh_lex(Lex_t* lp)
lp->lexd.nocopy--;
do
{
while(fcgetc(c)>0 && c!='\n');
while((c = fcgetc()) > 0 && c!='\n');
if(c<=0 || lp->heredoc)
{
sh.inlineno++;
Expand Down Expand Up @@ -476,7 +476,7 @@ int sh_lex(Lex_t* lp)
}
lp->lex.testop1 = lp->lex.intest;
}
if(fcgetc(n)>0)
if((n = fcgetc()) > 0)
fcseek(-LEN);
if(state[n]==S_OP || n=='#')
{
Expand Down Expand Up @@ -546,8 +546,8 @@ int sh_lex(Lex_t* lp)
{
lp->digits = sh_isoption(SH_POSIX) ? 0 : 1;
c = IORDWRSYM;
fcgetc(n);
if(fcgetc(n)==';')
fcgetc();
if((n = fcgetc())==';')
{
lp->token = c = IORDWRSYMT;
if(lp->inexec)
Expand Down Expand Up @@ -588,12 +588,12 @@ int sh_lex(Lex_t* lp)
return lp->token=c;
case S_ESC:
/* check for \<new-line> */
fcgetc(n);
n = fcgetc();
c=2;
#if SHOPT_CRNL
if(n=='\r')
{
if(fcgetc(n)=='\n')
if((n = fcgetc())=='\n')
c=3;
else
{
Expand Down Expand Up @@ -665,7 +665,7 @@ int sh_lex(Lex_t* lp)
if(n!=S_TILDE)
continue;
tilde:
fcgetc(n);
n = fcgetc();
if(n>0)
{
if(c=='~' && n==LPAREN)
Expand Down Expand Up @@ -754,7 +754,7 @@ int sh_lex(Lex_t* lp)
/* \ inside '' */
if(endchar(lp)=='$')
{
fcgetc(n);
n = fcgetc();
if(n=='\n')
sh.inlineno++;
}
Expand Down Expand Up @@ -857,10 +857,10 @@ int sh_lex(Lex_t* lp)
if(varnamelength && fcpeek(-LEN - 1)==']')
varnamelength = 0;
/* make sure next character is alpha */
if(fcgetc(n)>0)
if((n = fcgetc()) > 0)
{
if(n=='.')
fcgetc(n);
n = fcgetc();
if(n>0)
fcseek(-LEN);
}
Expand Down Expand Up @@ -922,7 +922,7 @@ int sh_lex(Lex_t* lp)
}
else
{
if(fcgetc(c)>0)
if((c = fcgetc()) > 0)
fcseek(-LEN);
if(state[c]==S_ALP)
goto err;
Expand Down Expand Up @@ -964,11 +964,11 @@ int sh_lex(Lex_t* lp)
if(kia.file)
refvar(lp,1);
#endif /* SHOPT_KIA */
if(c!=':' && fcgetc(n)>0)
if(c!=':' && (n = fcgetc()) > 0)
{
if(n!=c)
c = 0;
if(!c || (fcgetc(n)>0))
if(!c || (n = fcgetc()) > 0)
{
fcseek(-LEN);
if(n==LPAREN)
Expand All @@ -989,7 +989,7 @@ int sh_lex(Lex_t* lp)
case S_LBRA:
if((c=endchar(lp)) == '$')
{
if(fcgetc(c)>0)
if((c = fcgetc()) > 0)
fcseek(-LEN);
setchar(lp,RBRACE);
if(state[c]!=S_ERR && c!=RBRACE)
Expand Down Expand Up @@ -1025,7 +1025,7 @@ int sh_lex(Lex_t* lp)
errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,sh.inlineno,c);
continue;
case S_PUSH:
fcgetc(n);
n = fcgetc();
if(n==RPAREN)
continue;
else
Expand All @@ -1052,7 +1052,7 @@ int sh_lex(Lex_t* lp)
continue;
if((c==RBRACE||c==RPAREN) && n==RPAREN)
{
if(fcgetc(n)==LPAREN)
if((n = fcgetc())==LPAREN)
{
if(c!=RPAREN)
fcseek(-LEN);
Expand Down Expand Up @@ -1086,7 +1086,7 @@ int sh_lex(Lex_t* lp)
/* check for ((...)) */
if(n==1 && c==RPAREN)
{
if(fcgetc(n)==RPAREN)
if((n = fcgetc())==RPAREN)
{
if(mode==ST_NONE && !lp->lexd.dolparen)
goto breakloop;
Expand Down Expand Up @@ -1131,7 +1131,7 @@ int sh_lex(Lex_t* lp)
case S_COLON:
if(assignment)
{
if(fcgetc(c)=='~')
if((c = fcgetc())=='~')
wordflags |= ARG_MAC;
else if(c!=LPAREN && assignment==SH_COMPASSIGN)
assignment = 0;
Expand All @@ -1148,7 +1148,7 @@ int sh_lex(Lex_t* lp)
(oldmode(lp)==ST_NONE) ||
(mode==ST_NAME && (lp->assignok||lp->lexd.level)))
{
fcgetc(n);
n = fcgetc();
if(n>0 && n==']')
{
if(mode==ST_NAME)
Expand All @@ -1174,7 +1174,7 @@ int sh_lex(Lex_t* lp)
{
if(lp->comsub)
return lp->token=c;
fcgetc(n);
n = fcgetc();
if(n>0)
fcseek(-LEN);
else
Expand All @@ -1196,7 +1196,7 @@ int sh_lex(Lex_t* lp)
goto do_reg;
}
isfirst = (lp->lexd.first&&fcseek(0)==lp->lexd.first+1);
if(fcgetc(n)<=0)
if((n = fcgetc()) <= 0)
break;
/* check for {} */
if(c==LBRACE && n==RBRACE)
Expand All @@ -1222,7 +1222,7 @@ int sh_lex(Lex_t* lp)
/* FALLTHROUGH */
case S_EPAT:
epat:
if(fcgetc(n)==LPAREN && c!='[')
if((n = fcgetc())==LPAREN && c!='[')
{
epatchar = c;
if(lp->lex.incase==TEST_RE)
Expand Down Expand Up @@ -1488,7 +1488,7 @@ int sh_lex(Lex_t* lp)
else if(c==TIMESYM)
{
/* POSIX requires time -p */
while(fcgetc(n)==' ' || n=='\t');
while((n = fcgetc())==' ' || n=='\t');
if(n>0)
fcseek(-LEN);
if(n=='-')
Expand Down Expand Up @@ -1582,15 +1582,15 @@ static int comsub(Lex_t *lp, int endtok)
}
count++;
lp->lexd.paren = 0;
fcgetc(c);
fcgetc();
}
while(1)
{
/* look for case and esac */
n=0;
while(1)
{
fcgetc(c);
c = fcgetc();
/* skip leading white space */
if(n==0 && !sh_lexstates[ST_BEGIN][c])
continue;
Expand Down Expand Up @@ -1659,7 +1659,7 @@ static int comsub(Lex_t *lp, int endtok)
sh_syntax(lp,0);
/* UNREACHABLE */
case IOSEEKSYM:
if(fcgetc(c)!='#' && c>0)
if((c = fcgetc())!='#' && c>0)
fcseek(-LEN);
break;
case IODOCSYM:
Expand All @@ -1672,7 +1672,7 @@ static int comsub(Lex_t *lp, int endtok)
break;
case ';':
do
fcgetc(c);
c = fcgetc();
while(!sh_lexstates[ST_BEGIN][c]);
if(c==RBRACE && endtok==LBRACE)
goto rbrace;
Expand Down Expand Up @@ -1822,7 +1822,7 @@ static int here_copy(Lex_t *lp,struct ionod *iop)
if(iop->iofile&IOLSEEK)
{
iop->iofile &= ~IOLSEEK;
while(fcgetc(c)=='\t' || c==' ')
while((c = fcgetc())=='\t' || c==' ')
{
if(c==' ')
stripcol++;
Expand All @@ -1831,7 +1831,7 @@ static int here_copy(Lex_t *lp,struct ionod *iop)
}
}
else
while(fcgetc(c)=='\t');
while((c = fcgetc())=='\t');
if(c>0)
fcseek(-LEN);
}
Expand Down Expand Up @@ -1921,7 +1921,7 @@ static int here_copy(Lex_t *lp,struct ionod *iop)
int col=0;
do
{
fcgetc(c);
c = fcgetc();
if(c==' ')
col++;
else
Expand All @@ -1932,7 +1932,7 @@ static int here_copy(Lex_t *lp,struct ionod *iop)
while (c==' ' || c=='\t');
}
else while(c=='\t')
fcgetc(c);
c = fcgetc();
if(c<=0)
goto done;
bufp = fcseek(-LEN);
Expand Down
12 changes: 6 additions & 6 deletions src/cmd/ksh93/sh/macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ void sh_machere(Sfio_t *infile, Sfio_t *outfile, char *string)
cp = fcseek(-1);
continue;
case S_ESC:
fcgetc(c);
c = fcgetc();
cp=fcseek(-1);
if(c>0)
cp++;
Expand Down Expand Up @@ -365,7 +365,7 @@ void sh_machere(Sfio_t *infile, Sfio_t *outfile, char *string)
}
else if(n==S_ALP)
{
while(fcgetc(c),isaname(c))
while(c = fcgetc(), isaname(c))
sfputc(stkp,c);
fcseek(-1);
}
Expand Down Expand Up @@ -2202,11 +2202,11 @@ static void comsubst(Mac_t *mp,Shnode_t* t, int type)
}
else
{
while(fcgetc(c)!='`' && c)
while((c = fcgetc()) && c != '`')
{
if(c==ESCAPE)
{
fcgetc(c);
c = fcgetc();
if(!(isescchar(sh_lexstates[ST_QUOTE][c]) ||
(c=='"' && mp->quote)))
sfputc(stkp,ESCAPE);
Expand Down Expand Up @@ -2775,7 +2775,7 @@ static char *sh_tilde(const char *string)
return cp;
}
#if _WINIX
if(fcgetc(c)=='/')
if((c = fcgetc())=='/')
{
char *str;
int n=0,offset=stktell(sh.stk);
Expand All @@ -2785,7 +2785,7 @@ static char *sh_tilde(const char *string)
sfputc(sh.stk,c);
n++;
}
while (fcgetc(c) && c!='/');
while ((c = fcgetc()) && c!='/');
sfputc(sh.stk,0);
if(c)
fcseek(-1);
Expand Down
Loading

0 comments on commit 6cada38

Please sign in to comment.