String getword() { String s=EmptyString; int i=0; char c; wor++; while (i==0) { wpos=pos;wrow=row;wcol=col; c=(char)fgetc(f); pos++; col++; if (c=='\n') { row++; col=0; } if (c==EOF) break; while (alphanum(c)) { s[i]=c; i++; c=(char)fgetc(f); pos++; col++; if (c=='\n') { row++; col=0; } if (c==EOF) break; } } s[i]='\0'; return s; }
void setname ( /* does parameter assignments */ unsigned char *argi, int xp ) { register unsigned char *argscan = argi; register struct namnod *n; if (letter(*argscan)) { while (alphanum(*argscan)) argscan++; if (*argscan == '=') { *argscan = 0; /* make name a cohesive string */ n = lookup(argi); *argscan++ = '='; attrib(n, xp); if (xp & N_ENVNAM) { n->namenv = n->namval = argscan; if (n == &pathnod) set_builtins_path(); } else assign(n, argscan); dolocale(n->namid); return; } } }
BOOL chkid(unsigned char *nam) { register unsigned char *cp = nam; if (!letter(*cp)) return(FALSE); else { while (*++cp) { if (!alphanum(*cp)) return(FALSE); } } return(TRUE); }
static int matchsequence(char *start,char *end,char *pattern, char symbols[MAX_OPT_VARS][MAX_ALIAS+1], int *match_length) { int var,i; char str[MAX_ALIAS+1]; char *start_org=start; cell value; char *ptr; *match_length=0; for (var=0; var<MAX_OPT_VARS; var++) symbols[var][0]='\0'; while (*start=='\t' || *start==' ') start++; while (*pattern) { if (start>=end) return FALSE; switch (*pattern) { case '%': /* new "symbol" */ pattern++; assert(isdigit(*pattern)); var=atoi(pattern) - 1; assert(var>=0 && var<MAX_OPT_VARS); assert(*start=='-' || alphanum(*start)); for (i=0; start<end && (*start=='-' || *start=='+' || alphanum(*start)); i++,start++) { assert(i<=MAX_ALIAS); str[i]=*start; } /* for */ str[i]='\0'; if (symbols[var][0]!='\0') { if (strcmp(symbols[var],str)!=0) return FALSE; /* symbols should be identical */ } else { strcpy(symbols[var],str); } /* if */ break; case '-': value=-strtol(pattern+1,&pattern,16); ptr=itoh((ucell)value); while (*ptr!='\0') { if (tolower(*start) != tolower(*ptr)) return FALSE; start++; ptr++; } /* while */ pattern--; /* there is an increment following at the end of the loop */ break; case ' ': if (*start!='\t' && *start!=' ') return FALSE; while ((start<end && *start=='\t') || *start==' ') start++; break; case '!': while ((start<end && *start=='\t') || *start==' ') start++; /* skip trailing white space */ if (*start!='\n') return FALSE; assert(*(start+1)=='\0'); start+=2; /* skip '\n' and '\0' */ if (*(pattern+1)!='\0') while ((start<end && *start=='\t') || *start==' ') start++; /* skip leading white space of next instruction */ break; default: if (tolower(*start) != tolower(*pattern)) return FALSE; start++; } /* switch */ pattern++; } /* while */ *match_length=(int)(start-start_org); return TRUE; }
static int matchsequence(char *start, char *end, char *pattern, char symbols[_maxoptvars][_aliasmax + 1], int *match_length) { int var, i; char str[_aliasmax + 1]; char *start_org = start; *match_length = 0; for (var = 0; var < _maxoptvars; var++) symbols[var][0] = '\0'; while (*start == '\t' || *start == ' ') start++; while (*pattern) { if (start >= end) return FALSE; switch (*pattern) { case '%': /* new "symbol" */ pattern++; assert(isdigit(*pattern)); var = atoi(pattern) - 1; assert(var >= 0 && var < _maxoptvars); assert(alphanum(*start)); for (i = 0; start < end && alphanum(*start); i++, start++) { assert(i <= _aliasmax); str[i] = *start; } /* for */ str[i] = '\0'; if (symbols[var][0] != '\0') { if (strcmp(symbols[var], str) != 0) return FALSE; /* symbols should be identical */ } else { strcpy(symbols[var], str); } /* if */ break; case ' ': if (*start != '\t' && *start != ' ') return FALSE; while ((start < end && *start == '\t') || *start == ' ') start++; break; case '!': while ((start < end && *start == '\t') || *start == ' ') start++; /* skip trailing white space */ if (*start != '\n') return FALSE; assert(*(start + 1) == '\0'); start += 2; /* skip '\n' and '\0' */ if (*(pattern + 1) != '\0') while ((start < end && *start == '\t') || *start == ' ') start++; /* skip leading white space of next instruction */ break; default: if (tolower(*start) != tolower(*pattern)) return FALSE; start++; break; } /* switch */ pattern++; } /* while */ *match_length = (int) (start - start_org); return TRUE; }
int word(void) { register unsigned int c, d, cc; struct argnod *arg = (struct argnod *)locstak(); register unsigned char *argp = arg->argval; unsigned char *oldargp; int alpha = 1; unsigned char *pc; wdnum = 0; wdset = 0; while (1) { while (c = nextwc(), space(c)) /* skipc() */ ; if (c == COMCHAR) { while ((c = readwc()) != NL && c != EOF); peekc = c; } else { break; /* out of comment - white space loop */ } } if (!eofmeta(c)) { do { if (c == LITERAL) { oldargp = argp; while ((c = readwc()) && c != LITERAL){ /* * quote each character within * single quotes */ pc = readw(c); if (argp >= brkend) growstak(argp); *argp++='\\'; /* Pick up rest of multibyte character */ if (c == NL) chkpr(); while (c = *pc++) { if (argp >= brkend) growstak(argp); *argp++ = (unsigned char)c; } } if (argp == oldargp) { /* null argument - '' */ /* * Word will be represented by quoted null * in macro.c if necessary */ if (argp >= brkend) growstak(argp); *argp++ = '"'; if (argp >= brkend) growstak(argp); *argp++ = '"'; } } else { if (c == 0) { if (argp >= brkend) growstak(argp); *argp++ = 0; } else { pc = readw(c); while (*pc) { if (argp >= brkend) growstak(argp); *argp++ = *pc++; } } if (c == '\\') { if ((cc = readwc()) == 0) { if (argp >= brkend) growstak(argp); *argp++ = 0; } else { pc = readw(cc); while (*pc) { if (argp >= brkend) growstak(argp); *argp++ = *pc++; } } } if (c == '=') wdset |= alpha; if (!alphanum(c)) alpha = 0; if (qotchar(c)) { d = c; for (;;) { if ((c = nextwc()) == 0) { if (argp >= brkend) growstak(argp); *argp++ = 0; } else { pc = readw(c); while (*pc) { if (argp >= brkend) growstak(argp); *argp++ = *pc++; } } if (c == 0 || c == d) break; if (c == NL) chkpr(); /* * don't interpret quoted * characters */ if (c == '\\') { if ((cc = readwc()) == 0) { if (argp >= brkend) growstak(argp); *argp++ = 0; } else { pc = readw(cc); while (*pc) { if (argp >= brkend) growstak(argp); *argp++ = *pc++; } } } } } } } while ((c = nextwc(), !eofmeta(c))); argp = endstak(argp); if (!letter(arg->argval[0])) wdset = 0; peekn = c | MARK; if (arg->argval[1] == 0 && (d = arg->argval[0], digit(d)) && (c == '>' || c == '<')) { word(); wdnum = d - '0'; }else{ /* check for reserved words */ if (reserv == FALSE || (wdval = syslook(arg->argval, reserved, no_reserved)) == 0) { wdval = 0; } /* set arg for reserved words too */ wdarg = arg; } }else if (dipchar(c)){ if ((d = nextwc()) == c) { wdval = c | SYMREP; if (c == '<') { if ((d = nextwc()) == '-') wdnum |= IOSTRIP; else peekn = d | MARK; } } else { peekn = d | MARK; wdval = c; } } else { if ((wdval = c) == EOF) wdval = EOFSYM; if (iopend && eolchar(c)) { struct ionod *tmp_iopend; tmp_iopend = iopend; iopend = 0; copy(tmp_iopend); } } reserv = FALSE; return (wdval); }
static char *replacesequence(const char *pattern,char symbols[MAX_OPT_VARS+1][MAX_ALIAS+1],int *repl_length) { char *lptr; int var,optsym; char *buffer; /* calculate the length of the new buffer * this is the length of the pattern plus the length of all symbols (note * that the same symbol may occur multiple times in the pattern) plus * line endings and startings ('\t' to start a line and '\n\0' to end one) */ assert(repl_length!=NULL); *repl_length=0; optsym=FALSE; lptr=(char*)pattern; while (*lptr) { switch (*lptr) { case '%': lptr++; /* skip '%' */ assert(isdigit(*lptr)); var=atoi(lptr); assert(var>=0 && var<=MAX_OPT_VARS); assert(symbols[var][0]!='\0' || optsym); /* variable should be defined */ assert(var!=0 || strlen(symbols[var])==pc_cellsize || (symbols[var][0]=='-' && strlen(symbols[var])==pc_cellsize+1) || atoi(symbols[var])==0); *repl_length+=(int)strlen(symbols[var]); optsym=FALSE; break; case '~': /* optional space followed by optional symbol */ assert(lptr[1]=='%'); assert(isdigit(lptr[2])); var=atoi(lptr+2); assert(var>=0 && var<=MAX_OPT_VARS); if (symbols[var][0]!='\0') *repl_length+=1; /* copy space if following symbol is valid */ else optsym=TRUE; /* don't copy space, and symbol is optional */ break; case '#': lptr++; /* skip '#' */ assert(alphanum(*lptr)); while (alphanum(lptr[1])) lptr++; *repl_length+=pc_cellsize*2; break; case '!': *repl_length+=3; /* '\t', '\n' & '\0' */ break; default: *repl_length+=1; } /* switch */ lptr++; } /* while */ /* allocate a buffer to replace the sequence in */ if ((buffer=(char*)malloc(*repl_length))==NULL) { error(103); return NULL; } /* if */ /* replace the pattern into this temporary buffer */ optsym=FALSE; lptr=buffer; *lptr++='\t'; /* the "replace" patterns do not have tabs */ while (*pattern) { assert((int)(lptr-buffer)<*repl_length); switch (*pattern) { case '%': /* write out the symbol */ pattern++; assert(isdigit(*pattern)); var=atoi(pattern); assert(var>=0 && var<=MAX_OPT_VARS); assert(symbols[var][0]!='\0' || optsym); /* variable should be defined */ assert(symbols[var][0]=='\0' || !optsym); /* but optional variable should be undefined */ strcpy(lptr,symbols[var]); lptr+=strlen(symbols[var]); optsym=FALSE; break; case '~': assert(pattern[1]=='%'); assert(isdigit(pattern[2])); var=atoi(pattern+2); assert(var>=0 && var<=MAX_OPT_VARS); if (symbols[var][0]!='\0') *lptr++=' '; /* replace ~ by a space */ else optsym=TRUE; /* don't copy space, and symbol is optional */ break; case '#': { ucell v=hex2ucell(pattern+1,NULL); char *ptr=itoh(v); strcpy(lptr,ptr); lptr+=strlen(ptr); assert(alphanum(pattern[1])); while (alphanum(pattern[1])) pattern++; break; } /* case */ case '!': /* finish the line, optionally start the next line with an indent */ *lptr++='\n'; *lptr++='\0'; if (*(pattern+1)!='\0') *lptr++='\t'; break; default: *lptr++=*pattern; } /* switch */ pattern++; } /* while */ assert((int)(lptr-buffer)==*repl_length); return buffer; }
static int matchsequence(char *start,char *end,const char *pattern, char symbols[MAX_OPT_VARS+1][MAX_ALIAS+1], int *match_length) { int var,i,optsym; char str[MAX_ALIAS+1]; char *start_org=start; cell value; char *ptr; *match_length=0; optsym=FALSE; for (var=0; var<=MAX_OPT_VARS; var++) symbols[var][0]='\0'; while (*start=='\t' || *start==' ') start++; while (*pattern) { if (start>=end) return FALSE; switch (*pattern) { case '%': /* new "symbol" */ pattern++; assert(isdigit(*pattern)); var=atoi(pattern); assert(var>=0 && var<=MAX_OPT_VARS); assert(*start=='-' || alphanum(*start) || optsym); for (i=0; start<end && (*start=='-' || *start=='+' || alphanum(*start)); i++,start++) { assert(i<=MAX_ALIAS); str[i]=*start; } /* for */ str[i]='\0'; if (var==0) { /* match only if the parameter is numeric and in the range of a half cell */ const char *ptr; /* getparamvalue() resolves leading '-' on values and adds multiple * values (the peephole optimizer may create such variants) */ ucell v=getparamvalue(str,&ptr); if (*ptr>' ' || v>=((ucell)1<<((pc_cellsize*4)-1)) && v<=~((ucell)1<<((pc_cellsize*4)-1))) return FALSE; /* reconvert the value to a string (without signs or expressions) */ ptr=itoh(v); #if !defined NDEBUG assert(strlen(ptr)==2*pc_cellsize); assert((ptr[0]=='0' || ptr[0]=='f') && (ptr[1]=='0' || ptr[1]=='f')); if (pc_cellsize>=32) assert((ptr[2]=='0' || ptr[2]=='f') && (ptr[3]=='0' || ptr[3]=='f')); if (pc_cellsize>=64) { assert((ptr[4]=='0' || ptr[4]=='f') && (ptr[5]=='0' || ptr[5]=='f')); assert((ptr[6]=='0' || ptr[6]=='f') && (ptr[7]=='0' || ptr[7]=='f')); } /* if */ #endif if (v==0) { str[0]='0'; /* make zero transform to '0' rather than '0000' */ str[1]='\0'; } else { memmove(str,ptr+pc_cellsize,pc_cellsize+1); } /* if */ } /* if */ if (symbols[var][0]!='\0') { if (strcmp(symbols[var],str)!=0) return FALSE; /* symbols should be identical */ } else { strcpy(symbols[var],str); } /* if */ optsym=FALSE; break; case '-': value=-hex2cell(pattern+1,&pattern); ptr=itoh((ucell)value); while (*ptr!='\0') { if (tolower(*start) != tolower(*ptr)) return FALSE; start++; ptr++; } /* while */ pattern--; /* there is an increment following at the end of the loop */ break; case '+': value=hex2cell(pattern+1,&pattern); ptr=itoh((ucell)value); while (*ptr!='\0') { if (tolower(*start) != tolower(*ptr)) return FALSE; start++; ptr++; } /* while */ pattern--; /* there is an increment following at the end of the loop */ break; case ' ': /* required whitespace */ if (*start!='\t' && *start!=' ') return FALSE; while (start<end && (*start=='\t' || *start==' ')) start++; break; case '~': /* optional whitespace (followed by optional symbol) */ while (start<end && (*start=='\t' || *start==' ')) start++; optsym= (pattern[1]=='%'); break; case '!': while (start<end && (*start=='\t' || *start==' ')) start++; /* skip trailing white space */ if (*start==';') while (start<end && *start!='\n') start++; /* skip trailing comment */ if (*start!='\n') return FALSE; assert(*(start+1)=='\0'); start+=2; /* skip '\n' and '\0' */ if (*(pattern+1)!='\0') while (start<end && *start=='\t' || *start==' ') start++; /* skip leading white space of next instruction */ break; default: if (tolower(*start) != tolower(*pattern)) return FALSE; start++; } /* switch */ pattern++; } /* while */ *match_length=(int)(start-start_org); return TRUE; }
int word(void) { register char c, d; register char *argp = locstak() + BYTESPERWORD; int alpha = 1; wdnum = 0; wdset = 0; while (1) { while (c = nextc(0), space(c)) /* skipc() */ ; if (c == COMCHAR) { while ((c = readc()) != NL && c != EOF); peekc = c; } else { break; /* out of comment - white space loop */ } } if (!eofmeta(c)) { do { if (c == LITERAL) { *argp++ = (DQUOTE); while ((c = readc()) && c != LITERAL) { *argp++ = (c | QUOTE); chkpr(c); } *argp++ = (DQUOTE); } else { *argp++ = (c); if (c == '=') wdset |= alpha; if (!alphanum(c)) alpha = 0; if (qotchar(c)) { d = c; while ((*argp++ = (c = nextc(d))) && c != d) chkpr(c); } } } while ((c = nextc(0), !eofmeta(c))); argp = endstak(argp); if (!letter(((ARGPTR) argp)->argval[0])) wdset = 0; peekc = c | MARK; if (((ARGPTR) argp)->argval[1] == 0 && (d = ((ARGPTR) argp)->argval[0], digit(d)) && (c == '>' || c == '<')) { word(); wdnum = d - '0'; } else { /*check for reserved words */ if (reserv == FALSE || (wdval = syslook(((ARGPTR) argp)->argval, reserved)) == 0) { wdarg = (ARGPTR) argp; wdval = 0; } } } else if (dipchar(c)) { if ((d = nextc(0)) == c) wdval = c | SYMREP; else { peekc = d | MARK; wdval = c; } } else { if ((wdval = c) == EOF) wdval = EOFSYM; if (iopend && eolchar(c)) { copy(iopend); iopend = 0; } } reserv = FALSE; return wdval; }
static int getch(char endch) { register char d; retry: d = readc(); if (!subchar(d)) return (d); if (d == DOLLAR) { register int c; if ((c = readc(), dolchar(c))) { NAMPTR n = (NAMPTR) NIL; int dolg = 0; BOOL bra; register const char *argp; register const char *v; CHAR idb[2]; char *id = idb; if (bra = (c == BRACE)) c = readc(); if (letter(c)) { argp = (STRING) relstak(); while (alphanum(c)) { pushstak(c); c = readc(); } zerostak(); n = lookup(absstak(argp)); setstak(argp); v = n->namval; id = (char *)n->namid; peekc = c | MARK;; } else if (digchar(c)) { *id = c; idb[1] = 0; if (astchar(c)) { dolg = 1; c = '1'; } c -= '0'; v = ((c == 0) ? (const char *)cmdadr : (c <= dolc) ? dolv[c] : (dolg = 0, NULL)); } else if (c == '$') { v = pidadr; } else if (c == '!') { v = pcsadr; } else if (c == '#') { v = dolladr; } else if (c == '?') { v = exitadr; } else if (c == '-') { v = flagadr; } else if (bra) { error(badsub); } else { goto retry; } c = readc(); if (!defchar(c) && bra) error(badsub); argp = 0; if (bra) { if (c != '}') { argp = (STRING) relstak(); if ((v == 0) ^ (setchar(c))) copyto('}'); else skipto('}'); argp = absstak(argp); } } else { peekc = c | MARK; c = 0; } if (v) { if (c != '+') { for (;;) { while (c = *v++) pushstak(c | quote); if (dolg == 0 || (++dolg > dolc)) break; else { v = dolv[dolg]; pushstak(SP | (*id == '*' ? quote : 0)); } } } } else if (argp) { if (c == '?') { failed(id, *argp ? argp : badparam); } else if (c == '=') { if (n) assign(n, argp); else error(badsub); } } else if (flags & setflg) { failed(id, badparam); } goto retry; } else { peekc = c | MARK; } } else if (d == endch) { return (d); } else if (d == SQUOTE) { comsubst(); goto retry; } else if (d == DQUOTE) { quoted++; quote ^= QUOTE; goto retry; } return d; }
int main(int argc, char** argv) { // between ok(between('a','z','c'), "c is between a and z"); fail(between('a','z','C'), "C is not between a and z"); // num ok(num('0'), "0 is a number"); ok(num('9'), "9 is a number"); fail(num('/'), "/ is not a number"); fail(num(':'), "0 is not a number"); // alpha ok(alpha('a'), "a is a letter"); ok(alpha('z'), "z is a letter"); ok(alpha('A'), "A is a letter"); ok(alpha('Z'), "Z is a letter"); fail(alpha('@'), "@ is not a letter"); fail(alpha('['), "[ is not a letter"); fail(alpha('`'), "` is not a letter"); fail(alpha('{'), "{ is not a letter"); // alphanum ok(alphanum('a'), "a is alphanum"); ok(alphanum('z'), "z is alphanum"); ok(alphanum('A'), "A is alphanum"); ok(alphanum('Z'), "Z is alphanum"); ok(alphanum('0'), "0 is alphanum"); ok(alphanum('9'), "9 is alphanum"); fail(alpha('@'), "@ is not alphanum "); fail(alpha('['), "[ is not alphanum"); fail(alpha('`'), "` is not alphanum"); fail(alpha('{'), "{ is not alphanum"); // space ok(space(' '), "space is space"); fail(space('\n'), "new line is not space"); fail(space('\r'), "cr is not space"); fail(space('\t'), "tab is not space"); // tab ok(tab('\t'), "tab is tab"); fail(tab(' '), "space is not tab"); fail(tab('\n'), "new line is not tab"); fail(tab('\r'), "cr is not tab"); // nl ok(nl('\n'), "new line is new line"); fail(nl('\t'), "tab is not new line"); fail(nl(' '), "space is not new line"); fail(nl('\r'), "cr is not new line"); // cr fail(cr('\n'), "new line is not cr"); fail(cr('\t'), "tab is not cr"); fail(cr(' '), "space is not cr"); ok(cr('\r'), "cr is cr"); // whitespace ok(whitespace('\n'), "new line is whitespace"); ok(whitespace('\t'), "tab is whitespace"); ok(whitespace(' '), "space is whitespace"); ok(whitespace('\r'), "cr is whitespace"); fail(whitespace('\b'), "backspace is not whitespace"); // colon ok(colon(':'), "colon is colon"); fail(colon(';'), "semicolon is not colon"); // semi fail(semi(':'), "colon is not semicolon"); ok(semi(';'), "semicolon is semicolon"); // slash fail(slash('\\'), "\\ is not /"); ok(slash('/'), "/ is /"); // dot fail(dot('*'), "* is not ."); ok(dot('.'), ". is ."); // star ok(star('*'), "* is *"); fail(star('.'), ". is not *"); // question ok(question('?'), "? is ?"); // hex ok(hex('a'), "a is hex"); ok(hex('f'), "f is hex"); ok(hex('A'), "A is hex"); ok(hex('F'), "F is hex"); ok(hex('0'), "0 is hex"); ok(hex('9'), "9 is hex"); fail(hex('g'), "g is not hex"); fail(hex('G'), "G is not hex"); // decimal ok(decimal('0'), "0 is decimal"); ok(decimal('9'), "9 is decimal"); ok(decimal('.'), ". is decimal"); fail(decimal('a'), "a is not decimal"); // ctrl ok(ctrl('\b'), "Backspace is ctrl"); ok(ctrl('\a'), "Bell is ctrl"); ok(ctrl(127), "Del is ctrl"); fail(ctrl('a'), "a is not ctrl"); // any value(3,any(alpha,"abc123"), "three letters at abc123"); value(0,any(num,"abc123"), "no numbers at abc123"); value(6,any(alphanum,"abc123"), "six alphanum in abc123"); // until value(5,until(space,"hello world!"), "5 letters until space"); value(11,until(question,"hello world?"), "11 letters until question"); value(12,until(ctrl,"hello world?"), "12 chacters till end"); // crlf, eol, and upto value(6, upto(eol, "line 1\r\nline 1\r\n"), "6 chars upto crlf"); value(0, upto(eol, "\r\n\r\n"), "0 characters to end of line"); value(12, upto(eol, "hello world!"), "12 characters to eol"); // all test value(5, all(dot, ".....\r\n"), "there are 5 dots"); return done("test_parse"); }