⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncpp.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;
		case OR:
			rv1 |= rv2;
			break;
		case CIRC:
			rv1 ^= rv2;
			break;
		case TILDE:
			rv1 = ~rv1;
			break;
		case NOT:
			rv1 = !rv1;
			if (rtype != UND)
				rtype = SGN;
			break;
		case SLASH:
			if (rv2 == 0) {
				rtype = UND;
				break;
			}
			if (rtype == UNS)
				rv1 /= (unsigned long) rv2;
			else
				rv1 /= rv2;
			break;
		case PCT:
			if (rv2 == 0) {
				rtype = UND;
				break;
			}
			if (rtype == UNS)
				rv1 %= (unsigned long) rv2;
			else
				rv1 %= rv2;
			break;
		case COLON:
			if (op[-1] != QUEST)
				error(CPPERROR, StrTab[128]);   // <Bad ?: in #if/endif>
			else {
				op--;
				if ((--vp)->val == 0)
					v1 = v2;
				rtype = v1.type;
				rv1 = v1.val;
			}
			break;
		case DEFINED:
			break;
		default:
			error(CPPERROR, StrTab[129]);   // <Eval botch (unknown operator)>
			return 1;
		}
/*lint +e574 +e644 */
		v1.val = rv1;
		v1.type = rtype;
		*vp++ = v1;
	}
	return 0;
}
static struct value tokval(Token * tp)
{
	struct value v;
	Nlist *np;
	int i, base, c;
	unsigned long n;
	uchar *p;
	v.type = SGN;
	v.val = 0;
	switch (tp->type) {
	case NAME:
		v.val = 0;
		break;
	case NAME1:
		if ((np = cpplookup(tp)) != NULL && np->flag & ISDEFINED)
			v.val = 1;
		break;
	case NUMBER:
		n = 0;
		base = 10;
		p = tp->t;
		c = p[tp->len];
		p[tp->len] = '\0';
		if (*p == '0') {
			base = 8;
			if (p[1] == 'x' || p[1] == 'X') {
				base = 16;
				p++;
			}
			p++;
		}
		for (;; p++) {
			if ((i = digit(*p)) < 0)
				break;
			if (i >= base)
				error(CPPWARNING,
					StrTab[130], tp); // <Bad digit in number %t>
			n *= base;
			n += i;
		}
		if (n >= 0x80000000 && base != 10)
			v.type = UNS;
		for (; *p; p++) {
			if (*p == 'u' || *p == 'U')
				v.type = UNS;
			else if (*p == 'l' || *p == 'L');
			else {
				error(CPPERROR,
					StrTab[131], tp); // <Bad number %t in #if/#elsif>
				break;
			}
		}
		v.val = n;
		tp->t[tp->len] = (unsigned char) c;
		break;
	case CCON:
		n = 0;
		p = tp->t;
		if (*p == 'L') {
			p += 1;
			error(CPPWARNING, StrTab[132]); // <Wide char constant value undefined>
		}
		p += 1;
		if (*p == '\\') {
			p += 1;
			if ((i = digit(*p)) >= 0 && i <= 7) {
				n = i;
				p += 1;
				if ((i = digit(*p)) >= 0 && i <= 7) {
					p += 1;
					n <<= 3;
					n += i;
					if ((i = digit(*p)) >= 0 && i <= 7) {
						p += 1;
						n <<= 3;
						n += i;
					}
				}
			}
			else if (*p == 'x') {
				p += 1;
				while ((i = digit(*p)) >= 0 && i <= 15) {
					p += 1;
					n <<= 4;
					n += i;
				}
			}
			else {
				static char cvcon[]
				= "a\ab\bf\fn\nr\rt\tv\v''\"\"??\\\\";
				for (i = 0; i < sizeof(cvcon); i += 2) {
					if (*p == cvcon[i]) {
						n = cvcon[i + 1];
						break;
					}
				}
				p += 1;
				if (i >= sizeof(cvcon))
					error(CPPWARNING,
						StrTab[133]); // <Undefined escape in character constant>
			}
		}
		else if (*p == '\'')
			error(CPPERROR, StrTab[134]);   // <Empty character constant>
		else
			n = *p++;
		if (*p != '\'')
			error(CPPWARNING, StrTab[135]); // <Multibyte character constant undefined>
		else if (n > 127)
			error(CPPWARNING, StrTab[136]); // <Character constant taken as not signed>
		v.val = n;
		break;
	case STRING:
		error(CPPERROR, StrTab[137]);   // <String in #if/#elsif>
		break;
	}
	return v;
}
static int digit(int i)
{
	if ('0' <= i && i <= '9')
		i -= '0';
	else if ('a' <= i && i <= 'f')
		i -= 'a' - 10;
	else if ('A' <= i && i <= 'F')
		i -= 'A' - 10;
	else
		i = -1;
	return i;
}
/*
 * A hideset is a null-terminated array of Nlist pointers.
 * They are referred to by indices in the hidesets array.
 * Hideset 0 is empty.
 */
//#define HSSIZ   32
#define HSSIZ	512
typedef Nlist **Hideset;
static Hideset *hidesets;
static int nhidesets = 0;
static int maxhidesets = 3;
static int inserths(Hideset, Hideset, Nlist *);
/*
 * Test for membership in a hideset
 */
static int checkhideset(int hs, Nlist * np)
{
	Hideset hsp;
	if (hs >= nhidesets)
		abort();
	for (hsp = hidesets[hs]; *hsp; hsp++) {
		if (*hsp == np)
			return 1;
	}
	return 0;
}
/*
 * Return the (possibly new) hideset obtained by adding np to hs.
 */
static int newhideset(int hs, Nlist * np)
{
	int i, len;
	Nlist *nhs[HSSIZ + 3];
	Hideset hs1, hs2;
	len = inserths(nhs, hidesets[hs], np);
	for (i = 0; i < nhidesets; i++) {
		for (hs1 = nhs, hs2 = hidesets[i]; *hs1 == *hs2; hs1++, hs2++)
			if (*hs1 == NULL)
				return i;
	}
	if (len >= HSSIZ)
		return hs;
	if (nhidesets >= maxhidesets) {
		maxhidesets = 3 * maxhidesets / 2 + 1;
		hidesets = (Hideset *) realloc(hidesets, (sizeof(Hideset *)) * maxhidesets);
	}
	hs1 = (Hideset) domalloc(len * sizeof(Hideset));
	memmove(hs1, nhs, len * sizeof(Hideset));
	hidesets[nhidesets] = hs1;
	return nhidesets++;
}
static int inserths(Hideset dhs, Hideset shs, Nlist * np)
{
	Hideset odhs = dhs;
	while (*shs && *shs < np)
		*dhs++ = *shs++;
	if (*shs != np)
		*dhs++ = np;
	do {
		*dhs++ = *shs;
	} while (*shs++);
	return dhs - odhs;
}
/*
 * Hideset union
 */
static int unionhideset(int hs1, int hs2)
{
	Hideset hp;
	for (hp = hidesets[hs2]; *hp; hp++)
		hs1 = newhideset(hs1, *hp);
	return hs1;
}
static void iniths(void)
{
	hidesets = (Hideset *) domalloc(maxhidesets * sizeof(Hideset *));
	hidesets[0] = (Hideset) domalloc(sizeof(Hideset));
	*hidesets[0] = NULL;
	nhidesets++;
}
static Includelist includelist[NINCLUDE];
static unsigned char *objname;
int IsAbsolutePath(unsigned char *fname)
{
	int drive = *fname;
	if (drive >= 'a' && drive <= 'z')
		drive -= ' ';
	if (fname[1] == ':' && (drive >= 'A' && drive <= 'Z'))
		return (1);
	if (drive == '\\')
		return 1;
	return (0);
}
typedef struct tagSourceFilesList {
	struct tagSourceFilesList *Next;
	char *Name;
} SourceFilesList;

static SourceFilesList *LoadedSources = NULL;

static int NewSourceFile(char *name)
{
	SourceFilesList *rvp,*last;
	if (LoadedSources == NULL) {
		LoadedSources = domalloc(sizeof(SourceFilesList));
		LoadedSources->Name = domalloc(strlen(name)+1);
		strcpy(LoadedSources->Name,name);
		return 1;
	}
	rvp = LoadedSources;
	last = NULL;
	while (rvp) {
		if (!stricmp(name,rvp->Name))
			return 0;
		last = rvp;
		rvp = rvp->Next;
	}
	last->Next = domalloc(sizeof(SourceFilesList));
	last = last->Next;
	last->Name = domalloc(strlen(name)+1);
	strcpy(last->Name,name);
	return 1;
}

static void doinclude(Tokenrow * trp,int importflag)
{
	unsigned char fname[256], iname[256], *p;
	Includelist *ip;
	int angled, len, fd, i;

	if (Mflag)
		importflag = 1;
	trp->tp += 1;
	if (trp->tp >= trp->lp)
		goto syntax;
	if (trp->tp->type != STRING && trp->tp->type != LT) {
		len = trp->tp - trp->bp;
		expandrow(trp, (unsigned char *) "<include>");
		trp->tp = trp->bp + len;
	}
	if (trp->tp->type == STRING) {
		len = trp->tp->len - 2;
		if (len > sizeof(fname) - 1)
			len = sizeof(fname) - 1;
		strncpy(fname, trp->tp->t + 1, len);
		angled = 0;
	}
	else {
		len = 0;
		trp->tp++;
		while (trp->tp->type != GT) {
			if (trp->tp > trp->lp || len + trp->tp->len + 2 >= sizeof(fname))
				goto syntax;
			strncpy(fname + len, trp->tp->t, trp->tp->len);
			len += trp->tp->len;
			trp->tp++;
		}
		angled = 1;
	}
	trp->tp += 2;
	if (trp->tp < trp->lp || len == 0)
		goto syntax;
	fname[len] = '\0';
	p = fname;
	while (*p) {
		if (*p == '/')
			*p = '\\';
		p++;
	}
	if (IsAbsolutePath(fname)) {
		if (!NewSourceFile(fname) && importflag) {
			return;
		}
		fd = DoOpen(fname);
		strcpy(iname, fname);
	}
	else
		for (fd = -1, i = NINCLUDE - 1; i >= 0; i--) {
			ip = &includelist[i];
			if (ip->file == NULL || ip->deleted || (angled && ip->always == 0))
				continue;
			if (strlen(fname) + strlen(ip->file) + 2 > sizeof(iname))
				continue;
			sprintf(iname, "%s%c%s", ip->file, PATH_SEPARATOR, fname);
			if ((fd = DoOpen(iname)) >= 0) {
				if (!NewSourceFile(iname) && importflag) {
					DoClose(fd);
					return;
				}
				break;
			}
		}
#ifndef LRC
	if (Mflag) {
		if (Mflag > 1)
			PrintIncludeTree(iname);
		else if (IncPath && strncmp(IncPath,iname,strlen(IncPath))) {
			fprintf(TraceIncludesFile,"%s\n",iname);
		}
	}
#endif
	if (fd >= 0) {
		if (++incdepth > 10)
			error(CPPFATAL, StrTab[138]);   // <#include too deeply nested>
		setsource((char *) newstring((uchar *) iname, strlen(iname), 0), fd, NULL);
		genline();
	}
	else {
		trp->tp = trp->bp + 2;
		error(CPPERROR, StrTab[139], trp);  // <Could not find include file %r>
	}
	return;
syntax:
	error(CPPERROR, StrTab[140]);   // <Syntax error in #include>
	return;
}
/*
 * Generate a line directive for cursource
 */
extern int DoLineDirective;
static int genline(void)
{
	static Token ta = {UNCLASS, 0, 0, 0};
	static Tokenrow tr = {&ta, &ta, &ta + 1, 1};
	uchar *p;
	ta.t = p = (uchar *) OutputPtr;
	if (DoLineDirective) {
		if (outputLine) {
			strcpy((char *) p, "#line ");
			p += sizeof("#line ") - 1;
		}
		else {
			strcpy((char *) p, "# ");
			p += sizeof("# ") - 1;
		}
		p = (uchar *) outnum((char *) p, cursource->line);
		*p++ = ' ';
		*p++ = '"';
		if (cursource->filename[0] != PATH_SEPARATOR && wd[0]) {
			strcpy((char *) p, wd);
			p += strlen(wd);
			*p++ = PATH_SEPARATOR;
		}
		strcpy((char *) p, cursource->filename);
		p += strlen((char *) p);
		*p++ = '"';
		*p++ = '\n';
	}
	ta.len = (char *) p - OutputPtr;
	OutputPtr = (char *) p;
	tr.tp = tr.bp;
	return (puttokens(&tr));
}
static void setobjname(unsigned char *f)
{
	if (objname == NULL) {
		objname = (char *) domalloc(255);
	}
	strcpy(objname, f);
}
/*
 * lexical FSM encoding
 *   when in state state, and one of the characters
 *   in ch arrives, enter nextstate.
 *   States >= S_SELF are either final, or at least require special action.
 *   In 'fsm' there is a line for each state X charset X nextstate.
 *   List chars that overwrite previous entries later (e.g. C_ALPH
 *   can be overridden by '_' by a later entry; and C_XX is the
 *   the universal set, and should always be first.
 *   States above S_SELF are represented in the big table as negative values.
 *   S_SELF and S_SELFB encode the resulting token type in the upper bits.
 *   These actions differ in that S_SELF doesn't have a lookahead char,
 *   S_SELFB does.
 *
 *   The encoding is blown out into a big table for time-efficiency.
 *   Entries have
 *      nextstate: 6 bits; ?\ marker: 1 bit; tokentype: 9 bits.
 */
#define MAXSTATE 32
#define ACT(tok,act)    ((tok<<7)+act)
#define QBSBIT  0100
#define GETACT(st)  (st>>7)&0x1ff
/* character classes */
#define C_WS    1
#define C_ALPH  2
#define C_NUM   3
#define C_EOF   4
#define C_XX    5
enum state {
	START = 0, NUM1, NUM2, NUM3, ID1, ST1, ST2, ST3, COM1, COM2, COM3, COM4,
	CC1, CC2, WS1, PLUS1, MINUS1, STAR1, SLASH1, PCT1, SHARP1,
	CIRC1, GT1, GT2, LT1, LT2, OR1, AND1, ASG1, NOT1, DOTS1,
	S_SELF = MAXSTATE, S_SELFB, S_EOF, S_NL, S_EOFSTR,
	S_STNL, S_COMNL, S_EOFCOM, S_COMMENT, S_EOB, S_WS, S_NAME
};
struct fsm {
	int state;                  /* if in this state */
	uchar ch[4];                /* and see one of these characters */
	int nextstate;              /* enter this state if +ve */
};
static struct fsm fsm[] = {
	/* start state */
	START, {C_XX}, ACT(UNCLASS, S_SELF),
	START, {' ', '\t', '\v'}, WS1,
	START, {C_NUM}, NUM1,
	START, {'.'}, NUM3,
	START, {C_ALPH}, ID1,
	START, {'L'}, ST1,
	START, {'"'}, ST2,
	START, {'\''}, CC1,
	START, {'/'}, COM1,
	START, {EOFC}, S_EOF,
	START, {'\n'}, S_NL,
	START, {'\r'}, S_NL,
	START, {'-'}, MINUS1,
	START, {'+'}, PLUS1,
	START, {'<'}, LT1,
	START, {'>'}, GT1,
	START, {'='}, ASG1,
	START, {'!'}, NOT1,
	START, {'&'}, AND1,
	START, {'|'}, OR1,
	START, {'#'}, SHARP1,
	START, {'%'}, PCT1,
	START, {'['}, ACT(SBRA, S_SELF),
	START, {']'}, ACT(SKET, S_SELF),
	START, {'('}, ACT(LP, S_SELF),
	START, {')'}, ACT(RP, S_SELF),
	START, {'*'}, STAR1,
	START, {','}, ACT(COMMA, S_SELF),
	START, {'?'}, ACT(QUEST, S_SELF),
	START, {':'}, ACT(COLON, S_SELF),
	START, {';'}, ACT(SEMIC, S_SELF),
	START, {'{'}, ACT(CBRA, S_SELF),
	START, {'}'}, ACT(CKET, S_SELF),
	START, {'~'}, ACT(TILDE, S_SELF),
	START, {'^'}, CIRC1,
	/* saw a digit */
	NUM1, {C_XX}, ACT(NUMBER, S_SELFB),
	NUM1, {C_NUM, C_ALPH, '.'}, NUM1,
	NUM1, {'E', 'e'}, NUM2,
	NUM1, {'_'}, ACT(NUMBER, S_SELFB),
	/* saw possible start of exponent, digits-e */
	NUM2, {C_XX}, ACT(NUMBER, S_SELFB),
	NUM2, {'+', '-'}, NUM1,
	NUM2, {C_NUM, C_ALPH}, NUM1,
	NUM2, {'_'}, ACT(NUMBER, S_SELFB),
	/* saw a '.', which could be a number or an operator */
	NUM3, {C_XX}, ACT(DOT, S_SELFB),
	NUM3, {'.'}, DOTS1,
	NUM3, {C_NUM}, NUM1,
	DOTS1, {C_XX}, ACT(UNCLASS, S_SELFB),
	DOTS1, {C_NUM}, NUM1,
	DOTS1, {'.'}, ACT(ELLIPS, S_SELF),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -