Static void zgettok()

in MultiSource/Benchmarks/MallocBench/p2c/lex.c [2544:3358]


Static void zgettok()
#else
void gettok()
#endif
{
    register char ch;
    register char *cp;
    char ch2;
    char *startcp;
    int i;

    debughook();
    for (;;) {
        switch ((ch = *inbufptr++)) {

            case 0:
	        if (commenting_flag)
		    saveinputcomment(inbufptr-1);
                p2c_getline();
		cp = curtokbuf;
		for (;;) {
		    inbufindent = 0;
		    for (;;) {
			if (*inbufptr == '\t') {
			    inbufindent++;
			    if (intabsize)
				inbufindent = (inbufindent / intabsize + 1) * intabsize;
			} else if (*inbufptr == ' ')
			    inbufindent++;
			else if (*inbufptr != 26)
			    break;
			inbufptr++;
		    }
		    if (!*inbufptr && !commenting_flag) {   /* blank line */
			*cp++ = '\001';
			p2c_getline();
		    } else
			break;
		}
		if (cp > curtokbuf) {
		    *cp = 0;
		    commentline(CMT_POST);
		}
                break;

            case '\t':
            case ' ':
            case 26:    /* ignore ^Z's in Turbo files */
                while (*inbufptr++ == ch) ;
                inbufptr--;
                break;

            case '$':
		if (dollar_idents)
		    goto ident;
                if (dollar_flag) {
                    dollar_flag = 0;
                    curtok = TOK_DOLLAR;
                    return;
		}
		startcp = inbufptr-1;
		while (isspace(*inbufptr))
		    inbufptr++;
		cp = inbufptr;
		while (isxdigit(*cp))
		    cp++;
		if (cp > inbufptr && cp <= inbufptr+8 && !isalnum(*cp)) {
		    while (isspace(*cp))
			cp++;
		    if (!isdigit(*cp) && *cp != '\'') {
			cp = curtokbuf;    /* Turbo hex constant */
			while (isxdigit(*inbufptr))
			    *cp++ = *inbufptr++;
			*cp = 0;
			curtok = TOK_HEXLIT;
			curtokint = my_strtol(curtokbuf, NULL, 16);
			return;
		    }
                }
		dollar_flag++;     /* HP Pascal compiler directive */
		do {
		    gettok();
		    if (curtok == TOK_IF) {             /* $IF expr$ */
			Expr *ex;
			Value val;
			if (!skipping_module) {
			    if (!setup_complete)
				error("$IF$ not allowed at top of program");

			    /* Even though HP Pascal doesn't let these nest,
			       there's no harm in supporting it. */
			    if (if_flag) {
				skiptotoken(TOK_DOLLAR);
				if_flag++;
				break;
			    }
			    gettok();
			    ex = p_expr(tp_boolean);
			    val = eval_expr_consts(ex);
			    freeexpr(ex);
			    i = (val.type == tp_boolean && val.i);
			    free_value(&val);
			    if (!i) {
				if (curtok != TOK_DOLLAR) {
				    warning("Syntax error in $IF$ expression [240]");
				    skiptotoken(TOK_DOLLAR);
				}
				begincommenting(startcp);
				if_flag++;
				while (if_flag > 0)
				    gettok();
				endcommenting(inbufptr);
			    }
			} else {
			    skiptotoken(TOK_DOLLAR);
			}
		    } else if (curtok == TOK_END) {     /* $END$ */
			if (if_flag) {
			    gettok();
			    if (!wexpecttok(TOK_DOLLAR))
				skiptotoken(TOK_DOLLAR);
			    curtok = TOK_ENDIF;
			    if_flag--;
			    return;
			} else {
			    gettok();
			    if (!wexpecttok(TOK_DOLLAR))
				skiptotoken(TOK_DOLLAR);
			}
		    } else if (curtok == TOK_IDENT) {
			if (!strcmp(curtokbuf, "INCLUDE") &&
			     !if_flag && !skipping_module) {
			    char *fn;
			    gettok();
			    if (curtok == TOK_IDENT) {
				fn = stralloc(curtokcase);
				gettok();
			    } else if (wexpecttok(TOK_STRLIT)) {
				fn = stralloc(curtokbuf);
				gettok();
			    } else
				fn = "";
			    if (!wexpecttok(TOK_DOLLAR)) {
				skiptotoken(TOK_DOLLAR);
			    } else {
				if (handle_include(fn))
				    return;
			    }
			} else if (ignore_directives ||
				   if_flag ||
				   !strcmp(curtokbuf, "SEARCH") ||
				   !strcmp(curtokbuf, "REF") ||
				   !strcmp(curtokbuf, "DEF")) {
			    skiptotoken(TOK_DOLLAR);
			} else if (!strcmp(curtokbuf, "SWITCH_STRPOS")) {
			    switch_strpos = getflag();
			} else if (!strcmp(curtokbuf, "SYSPROG")) {
			    if (getflag())
				sysprog_flag |= 1;
			    else
				sysprog_flag &= ~1;
			} else if (!strcmp(curtokbuf, "MODCAL")) {
			    if (getflag())
				sysprog_flag |= 2;
			    else
				sysprog_flag &= ~2;
			} else if (!strcmp(curtokbuf, "PARTIAL_EVAL")) {
			    if (shortcircuit < 0)
				partial_eval_flag = getflag();
			} else if (!strcmp(curtokbuf, "IOCHECK")) {
			    iocheck_flag = getflag();
			} else if (!strcmp(curtokbuf, "RANGE")) {
			    if (getflag()) {
				if (!range_flag)
				    note("Range checking is ON [216]");
				range_flag = 1;
			    } else {
				if (range_flag)
				    note("Range checking is OFF [216]");
				range_flag = 0;
			    }
			} else if (!strcmp(curtokbuf, "OVFLCHECK")) {
			    if (getflag()) {
				if (!ovflcheck_flag)
				    note("Overflow checking is ON [219]");
				ovflcheck_flag = 1;
			    } else {
				if (ovflcheck_flag)
				    note("Overflow checking is OFF [219]");
				ovflcheck_flag = 0;
			    }
			} else if (!strcmp(curtokbuf, "STACKCHECK")) {
			    if (getflag()) {
				if (!stackcheck_flag)
				    note("Stack checking is ON [217]");
				stackcheck_flag = 1;
			    } else {
				if (stackcheck_flag)
				    note("Stack checking is OFF [217]");
				stackcheck_flag = 0;
			    }
			}
			skiptotoken2(TOK_DOLLAR, TOK_COMMA);
		    } else {
			warning("Mismatched '$' signs [241]");
			dollar_flag = 0;    /* got out of sync */
			return;
		    }
		} while (curtok == TOK_COMMA);
                break;

            case '"':
		if (C_lex) {
		    get_C_string(ch);
		    curtok = TOK_STRLIT;
		    return;
		}
		goto stringLiteral;

            case '#':
		if (modula2) {
		    curtok = TOK_NE;
		    return;
		}
		cp = inbufptr;
		while (isspace(*cp)) cp++;
		if (!strcincmp(cp, "INCLUDE", 7)) {
		    char *cp2, *cp3;
		    cp += 7;
		    while (isspace(*cp)) cp++;
		    cp2 = cp + strlen(cp) - 1;
		    while (isspace(*cp2)) cp2--;
		    if ((*cp == '"' && *cp2 == '"' && cp2 > cp) ||
			(*cp == '<' && *cp2 == '>')) {
			inbufptr = cp2 + 1;
			cp3 = stralloc(cp + 1);
			cp3[cp2 - cp - 1] = 0;
			if (handle_include(cp3))
			    return;
			else
			    break;
		    }
		}
		/* fall through */

            case '\'':
                if (C_lex && ch == '\'') {
                    get_C_string(ch);
                    if (curtokint != 1)
                        warning("Character constant has length != 1 [242]");
                    curtokint = *curtokbuf;
                    curtok = TOK_CHARLIT;
                    return;
                }
	      stringLiteral:
                cp = curtokbuf;
		ch2 = (ch == '"') ? '"' : '\'';
                do {
                    if (ch == ch2) {
                        while ((ch = *inbufptr++) != '\n' &&
                               ch != EOF) {
                            if (ch == ch2) {
                                if (*inbufptr != ch2 || modula2)
                                    break;
                                else
                                    inbufptr++;
                            }
                            *cp++ = ch;
                        }
                        if (ch != ch2)
                            warning("Error in string literal [243]");
                    } else {
                        ch = *inbufptr++;
                        if (isdigit(ch)) {
                            i = 0;
                            while (isdigit(ch)) {
                                i = i*10 + ch - '0';
                                ch = *inbufptr++;
                            }
                            inbufptr--;
                            *cp++ = i;
                        } else {
                            *cp++ = ch & 0x1f;
                        }
                    }
                    while (*inbufptr == ' ' || *inbufptr == '\t')
                        inbufptr++;
                } while ((ch = *inbufptr++) == ch2 || ch == '#');
                inbufptr--;
                *cp = 0;
                curtokint = cp - curtokbuf;
                curtok = TOK_STRLIT;
                return;

            case '(':
                if (*inbufptr == '*' && !C_lex) {
                    inbufptr++;
		    switch (commenting_flag ? 0 : parsecomment(0, 1)) {
		        case 0:
                            comment(1);
			    break;
		        case 2:
			    return;
		    }
                    break;
                } else if (*inbufptr == '.') {
                    curtok = TOK_LBR;
                    inbufptr++;
                } else {
                    curtok = TOK_LPAR;
                }
                return;

            case '{':
                if (C_lex || modula2) {
                    curtok = TOK_LBRACE;
                    return;
                }
                switch (commenting_flag ? 0 : parsecomment(0, 0)) {
                    case 0:
                        comment(0);
                        break;
                    case 2:
                        return;
                }
                break;

            case '}':
                if (C_lex || modula2) {
                    curtok = TOK_RBRACE;
                    return;
                }
		if (skipflag > 0) {
		    skipflag = 0;
		} else
		    warning("Unmatched '}' in input file [244]");
                break;

            case ')':
                curtok = TOK_RPAR;
                return;

            case '*':
		if (*inbufptr == (C_lex ? '/' : ')')) {
		    inbufptr++;
		    if (skipflag > 0) {
			skipflag = 0;
		    } else
			warning("Unmatched '*)' in input file [245]");
		    break;
		} else if (*inbufptr == '*' && !C_lex) {
		    curtok = TOK_STARSTAR;
		    inbufptr++;
		} else
		    curtok = TOK_STAR;
                return;

            case '+':
                if (C_lex && *inbufptr == '+') {
                    curtok = TOK_PLPL;
                    inbufptr++;
                } else
                    curtok = TOK_PLUS;
                return;

            case ',':
                curtok = TOK_COMMA;
                return;

            case '-':
                if (C_lex && *inbufptr == '-') {
                    curtok = TOK_MIMI;
                    inbufptr++;
                } else if (*inbufptr == '>') {
                    curtok = TOK_ARROW;
                    inbufptr++;
                } else
                    curtok = TOK_MINUS;
                return;

            case '.':
                if (*inbufptr == '.') {
                    curtok = TOK_DOTS;
                    inbufptr++;
                } else if (*inbufptr == ')') {
                    curtok = TOK_RBR;
                    inbufptr++;
                } else
                    curtok = TOK_DOT;
                return;

            case '/':
		if (C_lex && *inbufptr == '*') {
		    inbufptr++;
		    comment(2);
		    break;
		}
                curtok = TOK_SLASH;
                return;

            case ':':
                if (*inbufptr == '=') {
                    curtok = TOK_ASSIGN;
                    inbufptr++;
		} else if (*inbufptr == ':') {
                    curtok = TOK_COLONCOLON;
                    inbufptr++;
                } else
                    curtok = TOK_COLON;
                return;

            case ';':
                curtok = TOK_SEMI;
                return;

            case '<':
                if (*inbufptr == '=') {
                    curtok = TOK_LE;
                    inbufptr++;
                } else if (*inbufptr == '>') {
                    curtok = TOK_NE;
                    inbufptr++;
                } else if (*inbufptr == '<') {
                    curtok = TOK_LTLT;
                    inbufptr++;
                } else
                    curtok = TOK_LT;
                return;

            case '>':
                if (*inbufptr == '=') {
                    curtok = TOK_GE;
                    inbufptr++;
                } else if (*inbufptr == '>') {
                    curtok = TOK_GTGT;
                    inbufptr++;
                } else
                    curtok = TOK_GT;
                return;

            case '=':
		if (*inbufptr == '=') {
		    curtok = TOK_EQEQ;
		    inbufptr++;
		} else
		    curtok = TOK_EQ;
                return;

            case '[':
                curtok = TOK_LBR;
                return;

            case ']':
                curtok = TOK_RBR;
                return;

            case '^':
                curtok = TOK_HAT;
                return;

            case '&':
                if (*inbufptr == '&') {
                    curtok = TOK_ANDAND;
                    inbufptr++;
                } else
                    curtok = TOK_AMP;
                return;

            case '|':
                if (*inbufptr == '|') {
                    curtok = TOK_OROR;
                    inbufptr++;
                } else
                    curtok = TOK_VBAR;
                return;

            case '~':
                curtok = TOK_TWIDDLE;
                return;

            case '!':
                if (*inbufptr == '=') {
                    curtok = TOK_BANGEQ;
                    inbufptr++;
                } else
                    curtok = TOK_BANG;
                return;

            case '%':
		if (C_lex) {
		    curtok = TOK_PERC;
		    return;
		}
		goto ident;

            case '?':
                curtok = TOK_QM;
                return;

            case '@':
		curtok = TOK_ADDR;
                return;

            case EOFMARK:
                if (curtok == TOK_EOF) {
                    if (inputkind == INP_STRLIST)
                        error("Unexpected end of macro");
                    else
                        error("Unexpected end of file");
                }
                curtok = TOK_EOF;
                return;

            default:
                if (isdigit(ch)) {
		    cp = inbufptr;
		    while (isxdigit(*cp))
			cp++;
		    if (*cp == '#' && isxdigit(cp[1])) {
			i = atoi(inbufptr-1);
			inbufptr = cp+1;
		    } else if (toupper(cp[-1]) == 'B' ||
			       toupper(cp[-1]) == 'C') {
                        inbufptr--;
			i = 8;
		    } else if (toupper(*cp) == 'H') {
                        inbufptr--;
			i = 16;
		    } else if ((ch == '0' && toupper(*inbufptr) == 'X' &&
				isxdigit(inbufptr[1]))) {
			inbufptr++;
			i = 16;
		    } else {
			i = 10;
		    }
		    if (i != 10) {
                        curtokint = 0;
                        while (isdigit(*inbufptr) ||
			       (i > 10 && isxdigit(*inbufptr))) {
                            ch = toupper(*inbufptr++);
                            curtokint *= i;
                            if (ch <= '9')
                                curtokint += ch - '0';
                            else
                                curtokint += ch - 'A' + 10;
                        }
                        sprintf(curtokbuf, "%ld", curtokint);
			if ((toupper(*inbufptr) == 'B' && i == 8) ||
			    (toupper(*inbufptr) == 'H' && i == 16))
			    inbufptr++;
			if (toupper(*inbufptr) == 'C' && i == 8) {
			    inbufptr++;
			    curtok = TOK_STRLIT;
			    curtokbuf[0] = curtokint;
			    curtokbuf[1] = 0;
			    curtokint = 1;
			    return;
			}
                        if (toupper(*inbufptr) == 'L') {
                            strcat(curtokbuf, "L");
                            inbufptr++;
                        }
                        curtok = (i == 8) ? TOK_OCTLIT : TOK_HEXLIT;
                        return;
                    }
                    cp = curtokbuf;
                    i = 0;
                    while (ch == '0')
                        ch = *inbufptr++;
                    if (isdigit(ch)) {
                        while (isdigit(ch)) {
                            *cp++ = ch;
                            ch = *inbufptr++;
                        }
                    } else
                        *cp++ = '0';
                    if (ch == '.') {
                        if (isdigit(*inbufptr)) {
                            *cp++ = ch;
                            ch = *inbufptr++;
                            i = 1;
                            while (isdigit(ch)) {
                                *cp++ = ch;
                                ch = *inbufptr++;
                            }
                        }
                    }
                    if (ch == 'e' || ch == 'E' ||
			ch == 'd' || ch == 'D' ||
			ch == 'q' || ch == 'Q') {
                        ch = *inbufptr;
                        if (isdigit(ch) || ch == '+' || ch == '-') {
                            *cp++ = 'e';
                            inbufptr++;
                            i = 1;
                            do {
                                *cp++ = ch;
                                ch = *inbufptr++;
                            } while (isdigit(ch));
                        }
                    }
                    inbufptr--;
                    *cp = 0;
                    if (i) {
                        curtok = TOK_REALLIT;
                        curtokint = cp - curtokbuf;
                    } else {
                        if (cp >= curtokbuf+10) {
                            i = strcmp(curtokbuf, "2147483648");
                            if (cp > curtokbuf+10 || i > 0) {
				curtok = TOK_REALLIT;
				curtokint = cp - curtokbuf + 2;
				strcat(curtokbuf, ".0");
				return;
			    }
                            if (i == 0) {
                                curtok = TOK_MININT;
                                curtokint = -2147483648;
                                return;
                            }
                        }
                        curtok = TOK_INTLIT;
                        curtokint = atol(curtokbuf);
                        if (toupper(*inbufptr) == 'L') {
                            strcat(curtokbuf, "L");
                            inbufptr++;
                        }
                    }
                    return;
                } else if (isalpha(ch) || ch == '_') {
ident:
                    {
                        register char *cp2;
                        curtoksym = NULL;
                        cp = curtokbuf;
                        cp2 = curtokcase;
			*cp2++ = symcase ? ch : tolower(ch);
			*cp++ = pascalcasesens ? ch : toupper(ch);
			while (isalnum((ch = *inbufptr++)) ||
			       ch == '_' ||
			       (ch == '%' && !C_lex) ||
			       (ch == '$' && dollar_idents)) {
			    *cp2++ = symcase ? ch : tolower(ch);
			    if (!ignorenonalpha || isalnum(ch))
				*cp++ = pascalcasesens ? ch : toupper(ch);
			}
                        inbufptr--;
                        *cp2 = 0;
                        *cp = 0;
			if (pascalsignif > 0)
			    curtokbuf[pascalsignif] = 0;
                    }
		    if (*curtokbuf == '%') {
			if (!strcicmp(curtokbuf, "%INCLUDE")) {
			    char *cp2 = inbufptr;
			    while (isspace(*cp2)) cp2++;
			    if (*cp2 == '\'')
				cp2++;
			    cp = curtokbuf;
			    while (*cp2 && *cp2 != '\'' &&
				   *cp2 != ';' && !isspace(*cp2)) {
				*cp++ = *cp2++;
			    }
			    *cp = 0;
			    cp = my_strrchr(curtokbuf, '/');
			    if (cp && (!strcicmp(cp, "/LIST") ||
				       !strcicmp(cp, "/NOLIST")))
				*cp = 0;
			    if (*cp2 == '\'')
				cp2++;
			    while (isspace(*cp2)) cp2++;
			    if (*cp2 == ';')
				cp2++;
			    while (isspace(*cp2)) cp2++;
			    if (!*cp2) {
				inbufptr = cp2;
				(void) handle_include(stralloc(curtokbuf));
				return;
			    }
			} else if (!strcicmp(curtokbuf, "%TITLE") ||
				   !strcicmp(curtokbuf, "%SUBTITLE")) {
			    gettok();   /* string literal */
			    break;
			} else if (!strcicmp(curtokbuf, "%PAGE")) {
			    /* should store a special page-break comment? */
			    break;   /* ignore token */
			} else if ((i = 2, !strcicmp(curtokbuf, "%B")) ||
				   (i = 8, !strcicmp(curtokbuf, "%O")) ||
				   (i = 16, !strcicmp(curtokbuf, "%X"))) {
			    while (isspace(*inbufptr)) inbufptr++;
			    if (*inbufptr == '\'') {
				inbufptr++;
				curtokint = 0;
				while (*inbufptr && *inbufptr != '\'') {
				    ch = toupper(*inbufptr++);
				    if (isxdigit(ch)) {
					curtokint *= i;
					if (ch <= '9')
					    curtokint += ch - '0';
					else
					    curtokint += ch - 'A' + 10;
				    } else if (!isspace(ch))
					warning("Bad digit in literal [246]");
				}
				if (*inbufptr)
				    inbufptr++;
				sprintf(curtokbuf, "%ld", curtokint);
				curtok = (i == 8) ? TOK_OCTLIT : TOK_HEXLIT;
				return;
			    }
                        }
		    }
                    {
                        register unsigned int hash;
                        register Symbol *sp;

                        hash = 0;
                        for (cp = curtokbuf; *cp; cp++)
                            hash = hash*3 + *cp;
                        sp = symtab[hash % SYMHASHSIZE];
                        while (sp && (i = strcmp(sp->name, curtokbuf)) != 0) {
                            if (i < 0)
                                sp = sp->left;
                            else
                                sp = sp->right;
                        }
                        if (!sp)
                            sp = findsymbol(curtokbuf);
			if (sp->flags & SSYNONYM) {
			    i = 100;
			    while (--i > 0 && sp && (sp->flags & SSYNONYM)) {
				Strlist *sl;
				sl = strlist_find(sp->symbolnames, "===");
				if (sl)
				    sp = (Symbol *)sl->value;
				else
				    sp = NULL;
			    }
			    if (!sp)
				break;    /* ignore token */
			}
			if (sp->kwtok && !(sp->flags & KWPOSS) &&
			    (pascalcasesens != 2 || !islower(*curtokbuf)) &&
			    (pascalcasesens != 3 || !isupper(*curtokbuf))) {
			    curtok = sp->kwtok;
			    return;
			}
			curtok = TOK_IDENT;
                        curtoksym = sp;
                        if ((i = withlevel) != 0 && sp->fbase) {
                            while (--i >= 0) {
                                curtokmeaning = sp->fbase;
                                while (curtokmeaning) {
                                    if (curtokmeaning->rectype == withlist[i]) {
                                        curtokint = i;
                                        return;
                                    }
                                    curtokmeaning = curtokmeaning->snext;
                                }
                            }
                        }
                        curtokmeaning = sp->mbase;
                        while (curtokmeaning && !curtokmeaning->isactive)
                            curtokmeaning = curtokmeaning->snext;
			if (!curtokmeaning)
			    return;
			while (curtokmeaning->kind == MK_SYNONYM)
			    curtokmeaning = curtokmeaning->xnext;
			/* look for unit.ident notation */
                        if (curtokmeaning->kind == MK_MODULE ||
			    curtokmeaning->kind == MK_FUNCTION) {
                            for (cp = inbufptr; isspace(*cp); cp++) ;
                            if (*cp == '.') {
                                for (cp++; isspace(*cp); cp++) ;
                                if (isalpha(*cp)) {
                                    Meaning *mp = curtokmeaning;
                                    Symbol *sym = curtoksym;
                                    char *saveinbufptr = inbufptr;
                                    gettok();
                                    if (curtok == TOK_DOT)
					gettok();
				    else
					curtok = TOK_END;
                                    if (curtok == TOK_IDENT) {
					curtokmeaning = curtoksym->mbase;
					while (curtokmeaning &&
					       curtokmeaning->ctx != mp)
					    curtokmeaning = curtokmeaning->snext;
					if (!curtokmeaning &&
					    !strcmp(sym->name, "SYSTEM")) {
					    curtokmeaning = curtoksym->mbase;
					    while (curtokmeaning &&
						   curtokmeaning->ctx != nullctx)
						curtokmeaning = curtokmeaning->snext;
					}
				    } else
					curtokmeaning = NULL;
                                    if (!curtokmeaning) {
                                        /* oops, was probably funcname.field */
                                        inbufptr = saveinbufptr;
                                        curtokmeaning = mp;
                                        curtoksym = sym;
                                    }
                                }
                            }
                        }
                        return;
                    }
                } else {
                    warning(format_d("Unrecognized character 0%o in file [247]",
				     ch));
                }
        }
    }
}