コード例 #1
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * deal with comments in the fast scanner.
 */
static void
fastcmnt2(int ch)
{

	int lastline = ifiles->lineno;

	incmnt = 1;
	if (ch == '/') { /* C++ comment */
		while ((ch = qcchar()) != '\n')
			;
		unch(ch);
	} else if (ch == '*') {
		for (;;) {
			if ((ch = qcchar()) == 0)
				break;
			if (ch == '*') {
				if ((ch = qcchar()) == '/') {
					break;
				} else
					unch(ch);
			} else if (ch == '\n') {
				putch('\n');
				ifiles->lineno++;
			}
		}
	} else
		error("fastcmnt2");
	if (ch == 0)
		error("comment at line %d never ends", lastline);
	incmnt = 0;
}
コード例 #2
0
ファイル: token.c プロジェクト: pauley/pcc
/*
 * Check for (and convert) trigraphs.
 */
int
chktg()
{
	int c;

	if ((c = inpch()) != '?') {
		unch(c);
		return 0;
	}
	switch (c = inpch()) {
	case '=': c = '#'; break;
	case '(': c = '['; break;
	case ')': c = ']'; break;
	case '<': c = '{'; break;
	case '>': c = '}'; break;
	case '/': c = '\\'; break;
	case '\'': c = '^'; break;
	case '!': c = '|'; break;
	case '-': c = '~'; break;
	default:
		unch(c);
		unch('?');
		c = 0;
	}
	return c;
}
コード例 #3
0
ファイル: token.c プロジェクト: Sciumo/pcc
/*
 * Check for (and convert) trigraphs.
 */
static int
chktg(void)
{
	int ch;

	if ((ch = inpch()) != '?') {
		unch(ch);
		return 0;
	}

	switch (ch = inpch()) {
	case '=':  return '#';
	case '(':  return '[';
	case ')':  return ']';
	case '<':  return '{';
	case '>':  return '}';
	case '/':  return '\\';
	case '\'': return '^';
	case '!':  return '|';
	case '-':  return '~';
	}

	unch(ch);
	unch('?');
	return 0;
}
コード例 #4
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * deal with comments when -C is active.
 * Save comments in expanded macros???
 */
void
Ccmnt2(struct iobuf *ob, int ch)
{

	if (skpows)
		cntline();

	if (ch == '/') { /* C++ comment */
		putob(ob, ch);
		do {
			putob(ob, ch);
		} while ((ch = qcchar()) && ch != '\n');
		unch(ch);
	} else if (ch == '*') {
		strtobuf((usch *)"/*", ob);
		for (;;) {
			ch = qcchar();
			putob(ob, ch);
			if (ch == '*') {
				if ((ch = qcchar()) == '/') {
					putob(ob, ch);
					break;
				} else
					unch(ch);
			} else if (ch == '\n') {
				ifiles->lineno++;
			}
		}
	}
}
コード例 #5
0
ファイル: token.c プロジェクト: sambuc/netbsd
/*
 * Handle a preprocessor directive.
 */
void
ppdir(void)
{
	char bp[20];
	int ch, i;

redo:	while ((ch = inch()) == ' ' || ch == '\t')
		;
	if (ch == '/') {
		if ((ch = inch()) == '/') {
			skpln();
			return;
		}
		if (ch == '*') {
			while ((ch = inch()) != -1) {
				if (ch == '*') {
					if ((ch = inch()) == '/')
						goto redo;
					unch(ch);
				} else if (ch == '\n') {
					putch('\n');
					ifiles->lineno++;
				}
			}
		}
	}
	if (ch == '\n') { /* empty directive */
		unch(ch);
		return;
	}
	if (ch < 'a' || ch > 'z')
		goto out; /* something else, ignore */
	i = 0;
	do {
		bp[i++] = (usch)ch;
		if (i == sizeof(bp)-1)
			goto out; /* too long */
		ch = inch();
	} while ((ch >= 'a' && ch <= 'z') || (ch == '_'));
	unch(ch);
	bp[i++] = 0;

	/* got keyword */
	for (i = 0; i < NPPD; i++) {
		if (bp[0] == ppd[i].name[0] && strcmp(bp, ppd[i].name) == 0) {
			(*ppd[i].fun)();
			return;
		}
	}

out:
	if (flslvl == 0 && Aflag == 0)
		error("invalid preprocessor directive");

	unch(ch);
	skpln();
}
コード例 #6
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * Handle a preprocessor directive.
 * # is already found.
 */
void
ppdir(void)
{
	int ch, i, oldC;
	usch *bp;

	oldC = Cflag;
redo:	Cflag = 0;
	if ((ch = fastspc()) == '\n') { /* empty directive */
		unch(ch);
		Cflag = oldC;
		return;
	}
	Cflag = oldC;
	if ((spechr[ch] & C_ID0) == 0)
		goto out;
	bp = readid(ch);

	/* got some keyword */
	for (i = 0; i < NPPD; i++) {
		if (bp[0] == ppd[i].name[0] &&
		    strcmp((char *)bp, ppd[i].name) == 0) {
			if (flslvl == 0) {
				(*ppd[i].fun)();
				if (flslvl == 0)
					return;
			} else {
				if (ppd[i].flags & DIR_FLSLVL) {
					(*ppd[i].fun)();
					if (flslvl == 0)
						return;
				} else if (ppd[i].flags & DIR_FLSINC)
					flslvl++;
			}
			flscan();
			goto redo;
		}
	}
	if (flslvl == 0) {
		if (Aflag)
			skpln();
		return;
	}
	flscan();
	goto redo;

out:
	if (flslvl == 0 && Aflag == 0)
		error("invalid preprocessor directive");

	unch(ch);
	skpln();
}
コード例 #7
0
ファイル: token.c プロジェクト: enukane/netbsd-src
static int
eatcmnt(void)
{
	int ch;

	if (Cflag) { PUTCH('/'); PUTCH('*'); }
	for (;;) {
		ch = inch();
		if (ch == '\n') {
			ifiles->lineno++;
			PUTCH('\n');
		}
		if (ch == -1)
			return -1;
		if (ch == '*') {
			ch = inch();
			if (ch == '/') {
				if (Cflag) {
					PUTCH('*');
					PUTCH('/');
				} else
					PUTCH(' ');
				break;
			}
			unch(ch);
			ch = '*';
		}
		if (Cflag) PUTCH(ch);
	}
	return 0;
}
コード例 #8
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * get a preprocessing number and save it as given by ob.
 * returns first non-pp-number char.
 * We know that this is a valid number already.
 *
 *	pp-number:	digit
 *			. digit
 *			pp-number digit
 *			pp-number identifier-nondigit
 *			pp-number e sign
 *			pp-number E sign
 *			pp-number p sign
 *			pp-number P sign
 *			pp-number .
 */
int
fastnum(int ch, struct iobuf *ob)
{
	int c2;

	if ((spechr[ch] & C_DIGIT) == 0) {
		/* not digit, dot */
		putob(ob, ch);
		ch = qcchar();
	}
	for (;;) {
		putob(ob, ch);
		if ((ch = qcchar()) == 0)
			return 0;
		if ((c2 = (ch & 0337)) == 'E' || c2 == 'P') {
			if ((c2 = qcchar()) != '-' && c2 != '+') {
				if (c2 > 0)
					unch(c2);
				break;
			}
			putob(ob, ch);
			ch = c2;
		} else if (ch == '.' || (spechr[ch] & C_ID)) {
			continue;
		} else
			break;
	}
	return ch;
}
コード例 #9
0
ファイル: token.c プロジェクト: pauley/pcc
static void
cppwarning(void)
{
	usch *cp;
	int c;

	if (flslvl)
		return;
	c = sloscan();
	if (c != WSPACE && c != '\n')
		error("bad warning");

	/* svinp() add an unwanted \n */
	cp = stringbuf;
	while ((c = inch()) && c != '\n')
		savch(c);
	savch(0);

	if (flslvl)
		stringbuf = cp;
	else
		warning("#warning %s", cp);

	unch('\n');
}
コード例 #10
0
ファイル: token.c プロジェクト: Sciumo/pcc
static void
eatcmnt(void)
{
	int ch;

	if (Cflag) { PUTCH('/'); PUTCH('*'); }
	for (;;) {
		ch = inch();
		if (ch == '\n') {
			ifiles->lineno++;
			putch('\n');
			continue;
		}
		if (ch == -1)
			break;
		if (ch == '*') {
			ch = inch();
			if (ch == '/') {
				if (Cflag) {
					PUTCH('*');
					PUTCH('/');
				} else
					PUTCH(' ');
				break;
			}
			unch(ch);
			ch = '*';
		}
		if (Cflag) PUTCH(ch);
	}
}
コード例 #11
0
ファイル: token.c プロジェクト: Sciumo/pcc
void
cunput(int c)
{
#ifdef PCC_DEBUG
//	if (dflag)printf(": '%c'(%d)\n", c > 31 ? c : ' ', c);
#endif
	unch(c);
}
コード例 #12
0
ファイル: token.c プロジェクト: sambuc/netbsd
/*
 * check for universal-character-name on input, and
 * unput to the pushback buffer encoded as UTF-8.
 */
static int
chkucn(void)
{
	unsigned long cp, m;
	int ch, n;

	if ((ch = inch()) == -1)
		return 0;
	if (ch == 'u')
		n = 4;
	else if (ch == 'U')
		n = 8;
	else {
		unch(ch);
		return 0;
	}

	cp = 0;
	while (n-- > 0) {
		if ((ch = inch()) == -1 || (spechr[ch] & C_HEX) == 0) {
			warning("invalid universal character name");
			// XXX should actually unput the chars and return 0
			unch(ch); // XXX eof
			break;
		}
		cp = cp * 16 + dig2num(ch);
	}

	if ((cp < 0xa0 && cp != 0x24 && cp != 0x40 && cp != 0x60)
	    || (cp >= 0xd800 && cp <= 0xdfff))	/* 6.4.3.2 */
		error("universal character name cannot be used");

	if (cp > 0x7fffffff)
		error("universal character name out of range");

	n = 0;
	m = 0x7f;
	while (cp > m) {
		unch(0x80 | (cp & 0x3f));
		cp >>= 6;
		m >>= (n++ ? 1 : 2);
	}
	unch(((m << 1) ^ 0xfe) | cp);
	return 1;
}
コード例 #13
0
ファイル: token.c プロジェクト: pauley/pcc
static void
skpln(void)
{
	/* just ignore the rest of the line */
	while (inch() != '\n')
		;
	unch('\n');
	flslvl++;
}
コード例 #14
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * do an even faster scan than fastscan while at flslvl.
 * just search for a new directive.
 */
static void
flscan(void)
{
	int ch;

	for (;;) {
		ch = qcchar();
again:		switch (ch) {
		case 0:
			return;
		case '\n':
			putch('\n');
			ifiles->lineno++;
			while ((ch = qcchar()) == ' ' || ch == '\t')
				;
			if (ch == '#')
				return;
			if (ch == '%' && (ch = qcchar()) == ':')
				return;
			goto again;
		case '\'':
			while ((ch = qcchar()) != '\'') {
				if (ch == '\\')
					qcchar();
				if (ch == '\n')
					return;
			}
			break;
		case '\"':
			instr = 1;
			while ((ch = qcchar()) != '\"') {
				switch (ch) {
				case '\\':
					incmnt = 1;
					qcchar();
					incmnt = 0;
					break;
				case '\n':
					unch(ch);
					/* FALLTHROUGH */
				case 0:
					instr = 0;
					return;
				}
			}
			instr = 0;
			break;
		case '/':
			ch = qcchar();
			if (ch == '/' || ch == '*')
				fastcmnt2(ch);
			goto again;
		}
        }
}
コード例 #15
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
static void
pragmastmt(void)
{
	int ch;

	putstr((const usch *)"\n#pragma");
	while ((ch = qcchar()) != '\n' && ch > 0)
		putch(ch);
	unch(ch);
	prtline(1);
}
コード例 #16
0
ファイル: token.c プロジェクト: Sciumo/pcc
/*
 * check for (and eat) end-of-line
 */
static int
chkeol(void)
{
	int ch;

	ch = inpch();
	if (ch == '\r') {
		ch = inpch();
		if (ch == '\n')
			return '\n';

		unch(ch);
		unch('\r');
		return 0;
	}
	if (ch == '\n')
		return '\n';

	unch(ch);
	return 0;
}
コード例 #17
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * check for universal-character-name on input, and
 * unput to the pushback buffer encoded as UTF-8.
 */
static void
ucn(int n)
{
	unsigned long cp, m;
	int ch;

	if (incmnt) {
		struct iobuf *ib = ifiles->ib;
		ib->cptr--; /* [uU] */
		ib->buf[--ib->cptr] = '\\';
		return;
	}

	cp = 0;
	while (n-- > 0) {
		if ((ch = qcchar()) == 0 || (spechr[ch] & C_HEX) == 0) {
			warning("invalid universal character name");
			// XXX should actually unput the chars and return 0
			unch(ch); // XXX eof
			break;
		}
		cp = cp * 16 + dig2num(ch);
	}

	if ((cp < 0xa0 && cp != 0x24 && cp != 0x40 && cp != 0x60)
	    || (cp >= 0xd800 && cp <= 0xdfff))	/* 6.4.3.2 */
		error("universal character name cannot be used");

	if (cp > 0x7fffffff)
		error("universal character name out of range");

	n = 0;
	m = 0x7f;
	while (cp > m) {
		unch(0x80 | (cp & 0x3f));
		cp >>= 6;
		m >>= (n++ ? 1 : 2);
	}
	unch(((m << 1) ^ 0xfe) | cp);
}
コード例 #18
0
ファイル: token.c プロジェクト: pauley/pcc
/*
 * Handle a preprocessor directive.
 */
void
ppdir(void)
{
	char bp[20];
	int ch, i;

	while ((ch = inch()) == ' ' || ch == '\t')
		;
	if (ch == '\n') { /* empty directive */
		unch(ch);
		return;
	}
	if (ch < 'a' || ch > 'z')
		goto out; /* something else, ignore */
	i = 0;
	do {
		bp[i++] = (usch)ch;
		if (i == sizeof(bp)-1)
			goto out; /* too long */
		ch = inch();
	} while ((ch >= 'a' && ch <= 'z') || (ch == '_'));
	unch(ch);
	bp[i++] = 0;

	/* got keyword */
#define	SZ (int)(sizeof(ppd)/sizeof(ppd[0]))
	for (i = 0; i < SZ; i++)
		if (bp[0] == ppd[i].name[0] && strcmp(bp, ppd[i].name) == 0)
			break;
	if (i == SZ)
		goto out;

	/* Found matching keyword */
	(*ppd[i].fun)();
	return;

out:	while ((ch = inch()) != '\n' && ch != -1)
		;
	unch('\n');
}
コード例 #19
0
ファイル: token.c プロジェクト: Sciumo/pcc
static void
skpln(void)
{
	int ch;

	/* just ignore the rest of the line */
	while ((ch = inch()) != -1) {
		if (ch == '\n') {
			unch('\n');
			break;
		}
	}
}
コード例 #20
0
ファイル: token.c プロジェクト: pauley/pcc
void
cunput(int c)
{
#ifdef CPP_DEBUG
	extern int dflag;
	if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
#endif
#if 0
if (c == 10) {
	printf("c == 10!!!\n");
}
#endif
	unch(c);
}
コード例 #21
0
ファイル: token.c プロジェクト: pauley/pcc
static int
inch(void)
{
	int c;

again:	switch (c = inpch()) {
	case '\\': /* continued lines */
msdos:		if ((c = inpch()) == '\n') {
			ifiles->lineno++;
			goto again;
		} else if (c == '\r')
			goto msdos;
		unch(c);
		return '\\';
	case '?': /* trigraphs */
		if ((c = chktg())) {
			unch(c);
			goto again;
		}
		return '?';
	default:
		return c;
	}
}
コード例 #22
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * readin chars and store in buf. Warn about too long names.
 */
usch *
readid(int ch)
{
	int p = 0;

	do {
		if (p == MAXIDSZ)
			warning("identifier exceeds C99 5.2.4.1, truncating");
		if (p < MAXIDSZ)
			idbuf[p] = ch;
		p++;
	} while (spechr[ch = qcchar()] & C_ID);
	idbuf[p] = 0;
	unch(ch);
	return idbuf;
}
コード例 #23
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * readin chars and store in buf. Warn about too long names.
 */
usch *
bufid(int ch, struct iobuf *ob)
{
	int n = ob->cptr;

	do {
		if (ob->cptr - n == MAXIDSZ)
			warning("identifier exceeds C99 5.2.4.1");
		if (ob->cptr < ob->bsz)
			ob->buf[ob->cptr++] = ch;
		else
			putob(ob, ch);
	} while (spechr[ch = qcchar()] & C_ID);
	ob->buf[ob->cptr] = 0; /* legal */
	unch(ch);
	return ob->buf+n;
}
コード例 #24
0
ファイル: token.c プロジェクト: Sciumo/pcc
/* save line into stringbuf */
static usch *
savln(void)
{
	int c;
	usch *cp = stringbuf;

	while ((c = inch()) != -1) {
		if (c == '\n') {
			unch(c);
			break;
		}
		savch(c);
	}
	savch(0);

	return cp;
}
コード例 #25
0
ファイル: token.c プロジェクト: pauley/pcc
static void
pragmastmt(void)
{
	int c;

	if (sloscan() != WSPACE)
		error("bad pragma");
	if (!flslvl)
		putstr((const usch *)"#pragma ");
	do {
		c = inch();
		if (!flslvl)
			putch(c);	/* Do arg expansion instead? */
	} while (c && c != '\n');
	if (c == '\n')
		unch(c);
	prtline();
}
コード例 #26
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
static void
chknl(int ignore)
{
	void (*f)(const char *, ...);
	int t;

	f = ignore ? warning : error;
	if ((t = fastspc()) != '\n') {
		if (t) {
			f("newline expected");
			/* ignore rest of line */
			while ((t = qcchar()) > 0 && t != '\n')
				;
		} else
			f("no newline at end of file");
	}
	unch(t);
}
コード例 #27
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/* save line into iobuf */
struct iobuf *
savln(void)
{
	struct iobuf *ob = getobuf(BNORMAL);
	int c;

	while ((c = qcchar()) != 0) {
		if (c == '\n') {
			unch(c);
			break;
		}
		if (c == '\'' || c == '\"')
			faststr(c, ob);
		else
			putob(ob, c);
	}
	ob->buf[ob->cptr] = 0;
	return ob;
}
コード例 #28
0
ファイル: token.c プロジェクト: arnoldrobbins/pcc-revived
/*
 * get a string or character constant and save it as given by d.
 */
struct iobuf *
faststr(int bc, struct iobuf *ob)
{
	struct iobuf *ib = ifiles->ib;
	int ch;

	if (ob == NULL)
		ob = getobuf(BNORMAL);

	instr = 1;
	putob(ob, bc);
	for (;;) {
		if (ib->bsz == ib->cptr)
			ch = qcchar();
		else if (ISCQ(ch = ib->buf[ib->cptr]))
			ch = qcchar();
		else
			ib->cptr++;
		switch (ch) {
		case '\\':
			putob(ob, ch);
			if (ib->cptr == ib->bsz)
				inpbuf(0);
			incmnt = 1;
			putob(ob, qcchar());
			incmnt = 0;
			continue;
		case '\n':
			warning("unterminated literal");
			instr = 0;
			unch(ch);
			return ob;
		}
		putob(ob, ch);
		if (ch == bc)
			break;
	}
	putob(ob, 0);
	ob->cptr--;
	instr = 0;
	return ob;
}
コード例 #29
0
ファイル: token.c プロジェクト: Sciumo/pcc
int
yylex(void)
{
	static int ifdef, noex;
	struct symtab *nl;
	int ch, c2;

	while ((ch = sloscan()) == WSPACE)
		;
	if (ch < 128 && (spechr[ch] & C_2))
		c2 = inch();
	else
		c2 = 0;

	switch (ch) {
	case '=':
		if (c2 == '=') return EQ;
		break;
	case '!':
		if (c2 == '=') return NE;
		break;
	case '|':
		if (c2 == '|') return OROR;
		break;
	case '&':
		if (c2 == '&') return ANDAND;
		break;
	case '<':
		if (c2 == '<') return LS;
		if (c2 == '=') return LE;
		break;
	case '>':
		if (c2 == '>') return RS;
		if (c2 == '=') return GE;
		break;
	case '+':
	case '-':
		if (ch == c2)
			error("invalid preprocessor operator %c%c", ch, c2);
		break;

	case '/':
		if (Cflag == 0 || c2 != '*')
			break;
		/* Found comment that need to be skipped */
		for (;;) {
			ch = inch();
		c1:	if (ch != '*')
				continue;
			if ((ch = inch()) == '/')
				break;
			goto c1;
		}
		return yylex();

	case NUMBER:
		if (yytext[0] == '\'') {
			yylval.node.op = NUMBER;
			yylval.node.nd_val = charcon(yytext);
		} else
			cvtdig(yytext[0] != '0' ? 10 :
			    yytext[1] == 'x' || yytext[1] == 'X' ? 16 : 8);
		return NUMBER;

	case IDENT:
		if (strcmp((char *)yytext, "defined") == 0) {
			ifdef = 1;
			return DEFINED;
		}
		nl = lookup(yytext, FIND);
		if (ifdef) {
			yylval.node.nd_val = nl != NULL;
			ifdef = 0;
		} else if (nl && noex == 0) {
			usch *och = stringbuf;
			int i;

			i = kfind(nl);
			unch(WARN);
			if (i)
				unpstr(stringbuf);
			else
				unpstr(nl->namep);
			stringbuf = och;
			noex = 1;
			return yylex();
		} else {
			yylval.node.nd_val = 0;
		}
		yylval.node.op = NUMBER;
		return NUMBER;
	case WARN:
		noex = 0;
		/* FALLTHROUGH */
	case PHOLD:
		return yylex();
	default:
		return ch;
	}
	unch(c2);
	return ch;
}
コード例 #30
0
ファイル: token.c プロジェクト: Sciumo/pcc
int
sloscan(void)
{
	int ch;
	int yyp;

zagain:
	yyp = 0;
 	ch = inch();
	yytext[yyp++] = (usch)ch;
	switch (ch) {
	case -1:
		return 0;
	case '\n':
		/* sloscan() never passes \n, that's up to fastscan() */
		unch(ch);
		yytext[yyp] = 0;
		return ch;

	case '\r': /* Ignore CR's */
		yyp = 0;
		break;

	case '0': case '1': case '2': case '3': case '4': case '5': 
	case '6': case '7': case '8': case '9':
		/* readin a "pp-number" */
ppnum:		for (;;) {
			ch = inch();
			if (ch == -1)
				break;
			if (spechr[ch] & C_EP) {
				yytext[yyp++] = (usch)ch;
				ch = inch();
				if (ch == '-' || ch == '+') {
					yytext[yyp++] = (usch)ch;
				} else
					unch(ch);
				continue;
			}
			if ((spechr[ch] & C_ID) || ch == '.') {
				yytext[yyp++] = (usch)ch;
				continue;
			} 
			break;
		}
		unch(ch);
		yytext[yyp] = 0;

		return NUMBER;

	case '\'':
chlit:		
		for (;;) {
			if ((ch = inch()) == '\\') {
				yytext[yyp++] = (usch)ch;
				yytext[yyp++] = (usch)inch();
				continue;
			} else if (ch == -1 || ch == '\n') {
				/* not a constant */
				while (yyp > 1)
					unch(yytext[--yyp]);
				ch = '\'';
				goto any;
			} else
				yytext[yyp++] = (usch)ch;
			if (ch == '\'')
				break;
		}
		yytext[yyp] = 0;

		return NUMBER;

	case ' ':
	case '\t':
		while ((ch = inch()) == ' ' || ch == '\t')
			yytext[yyp++] = (usch)ch;
		unch(ch);
		yytext[yyp] = 0;
		return WSPACE;

	case '/':
		if ((ch = inch()) == '/') {
			do {
				yytext[yyp++] = (usch)ch;
				ch = inch();
			} while (ch != -1 && ch != '\n');
			yytext[yyp] = 0;
			unch(ch);
			goto zagain;
		} else if (ch == '*') {
			int c, wrn;
			extern int readmac;

			if (Cflag && !flslvl && readmac) {
				unch(ch);
				yytext[yyp] = 0;
				return CMNT;
			}

			wrn = 0;
		more:	while ((c = inch()) != '*') {
				if (c == -1)
					return 0;	
				if (c == '\n')
					putch(c), ifiles->lineno++;
				else if (c == EBLOCK) {
					(void)inch();
					(void)inch();
				} else if (c == WARN)
					wrn = 1;
			}
			if ((c = inch()) == -1)
				return 0;
			if (c != '/') {
				unch(c);
				goto more;
			}
			if (!tflag && !Cflag && !flslvl)
				unch(' ');
			if (wrn)
				unch(WARN);
			goto zagain;
		}
		unch(ch);
		ch = '/';
		goto any;

	case '.':
		if ((ch = inch()) == -1)
			return 0;
		if ((spechr[ch] & C_DIGIT)) {
			yytext[yyp++] = (usch)ch;
			goto ppnum;
		} else {
			unch(ch);
			ch = '.';
		}
		goto any;

	case '\"':
		if (tflag && defining)
			goto any;
	strng:
		for (;;) {
			if ((ch = inch()) == '\\') {
				yytext[yyp++] = (usch)ch;
				yytext[yyp++] = (usch)inch();
				continue;
			} else if (ch == -1) {
				break;
			} else 
				yytext[yyp++] = (usch)ch;
			if (ch == '\"')
				break;
		}
		yytext[yyp] = 0;
		return STRING;

	case 'L':
		if ((ch = inch()) == '\"' && !tflag) {
			yytext[yyp++] = (usch)ch;
			goto strng;
		} else if (ch == '\'' && !tflag) {
			yytext[yyp++] = (usch)ch;
			goto chlit;
		}
		unch(ch);
		/* FALLTHROUGH */

	/* Yetch, all identifiers */
	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 
	case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': 
	case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': 
	case 's': case 't': case 'u': case 'v': case 'w': case 'x': 
	case 'y': case 'z':
	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 
	case 'G': case 'H': case 'I': case 'J': case 'K':
	case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 
	case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 
	case 'Y': case 'Z':
	case '_': /* {L}({L}|{D})* */

		/* Special hacks */
		for (;;) { /* get chars */
			if ((ch = inch()) == -1)
				break;
			if ((spechr[ch] & C_ID)) {
				yytext[yyp++] = (usch)ch;
			} else {
				unch(ch);
				break;
			}
		}
		yytext[yyp] = 0; /* need already string */
		/* end special hacks */

		return IDENT;
	default:
	any:
		yytext[yyp] = 0;
		return yytext[0];

	} /* endcase */
	goto zagain;
}