Code Search for Developers
 
 
  

init.c from Nxabega at Krugle


Show init.c syntax highlighted

#include "c.h"


static int curseg;		/* current segment */

/* defpointer - initialize a pointer to p or to 0 if p==0 */
void defpointer(Symbol p) {
	if (p) {
		(*IR->defaddress)(p);
		p->ref++;
	} else {
		static Value v;
		(*IR->defconst)(P, voidptype->size, v);
	}
}

/* genconst - generate/check constant expression e; return size */
static int genconst(Tree e, int def) {
	for (;;)
		switch (generic(e->op)) {
		case ADDRG:
			if (def)
				(*IR->defaddress)(e->u.sym);
			return e->type->size;
		case CNST:
			if (e->op == CNST+P && isarray(e->type)) {
				e = cvtconst(e);
				continue;
			}
			if (def)
				(*IR->defconst)(e->type->op, e->type->size, e->u.v);
			return e->type->size;
		case RIGHT:
			assert(e->kids[0] || e->kids[1]);
			if (e->kids[1] && e->kids[0])
				error("initializer must be constant\n");
			e = e->kids[1] ? e->kids[1] : e->kids[0];
			continue;
		case CVP:
			if (isarith(e->type))
				error("cast from `%t' to `%t' is illegal in constant expressions\n",
					e->kids[0]->type, e->type);
			/* fall thru */
		case CVI: case CVU: case CVF:
			e = e->kids[0];
			continue;
		default:
			error("initializer must be constant\n");
			if (def)
				genconst(consttree(0, inttype), def);
			return inttype->size;
		}
}

/* initvalue - evaluate a constant expression for a value of integer type ty */
static Tree initvalue(Type ty) {
	Type aty;
	Tree e;

	needconst++;
	e = expr1(0);
	if ((aty = assign(ty, e)) != NULL)
		e = cast(e, aty);
	else {
		error("invalid initialization type; found `%t' expected `%t'\n",
			e->type,  ty);
		e = retype(consttree(0, inttype), ty);
	}
	needconst--;
	if (generic(e->op) != CNST) {
		error("initializer must be constant\n");
		e = retype(consttree(0, inttype), ty);
	}
	return e;
}

/* initarray - initialize array of ty of <= len bytes; if len == 0, go to } */
static int initarray(int len, Type ty, int lev) {
	int n = 0;

	do {
		initializer(ty, lev);
		n += ty->size;
		if (len > 0 && n >= len || t != ',')
			break;
		t = gettok();
	} while (t != '}');
	return n;
}

/* initchar - initialize array of <= len ty characters; if len == 0, go to } */
static int initchar(int len, Type ty) {
	int n = 0;
	char buf[16], *s = buf;

	do {
		*s++ = initvalue(ty)->u.v.i;
		if (++n%inttype->size == 0) {
			(*IR->defstring)(inttype->size, buf);
			s = buf;
		}
		if (len > 0 && n >= len || t != ',')
			break;
		t = gettok();
	} while (t != '}');
	if (s > buf)
		(*IR->defstring)(s - buf, buf);
	return n;
}

/* initend - finish off an initialization at level lev; accepts trailing comma */
static void initend(int lev, char follow[]) {
	if (lev == 0 && t == ',')
		t = gettok();
	test('}', follow);
}

/* initfields - initialize <= an unsigned's worth of bit fields in fields p to q */
static int initfields(Field p, Field q) {
	unsigned int bits = 0;
	int i, n = 0;

	do {
		i = initvalue(inttype)->u.v.i;
		if (fieldsize(p) < 8*p->type->size) {
			if (p->type == inttype &&
			   (i < -(int)(fieldmask(p)>>1)-1 || i > (int)(fieldmask(p)>>1))
			||  p->type == unsignedtype && (i&~fieldmask(p)) !=  0)
				warning("initializer exceeds bit-field width\n");
			i &= fieldmask(p);
		}
		bits |= i<<fieldright(p);
		if (IR->little_endian) {
			if (fieldsize(p) + fieldright(p) > n)
				n = fieldsize(p) + fieldright(p);
		} else {
			if (fieldsize(p) + fieldleft(p) > n)
				n = fieldsize(p) + fieldleft(p);
		}
		if (p->link == q)
			break;
		p = p->link;
	} while (t == ',' && (t = gettok()) != 0);
	n = (n + 7)/8;
	for (i = 0; i < n; i++) {
		Value v;
		if (IR->little_endian) {
			v.u = (unsigned char)bits;
			bits >>= 8;
		} else {	/* a big endian */
			v.u = (unsigned char)(bits>>(8*(unsignedtype->size - 1)));
			bits <<= 8;
		}
		(*IR->defconst)(U, unsignedchar->size, v);
	}
	return n;
}

/* initstruct - initialize a struct ty of <= len bytes; if len == 0, go to } */
static int initstruct(int len, Type ty, int lev) {
	int a, n = 0;
	Field p = ty->u.sym->u.s.flist;

	do {
		if (p->offset > n) {
			(*IR->space)(p->offset - n);
			n += p->offset - n;
		}
		if (p->lsb) {
			Field q = p;
			while (q->link && q->link->offset == p->offset)
				q = q->link;
			n += initfields(p, q->link);
			p = q;
		} else {
			initializer(p->type, lev);
			n += p->type->size;
		}
		if (p->link) {
			p = p->link;
			a = p->type->align;
		} else
			a = ty->align;
		if (a && n%a) {
			(*IR->space)(a - n%a);
			n = roundup(n, a);
		}
		if (len > 0 && n >= len || t != ',')
			break;
		t = gettok();
	} while (t != '}');
	return n;
}

/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */
Type initializer(Type ty, int lev) {
	int n = 0;
	Tree e;
	Type aty = NULL;
	static char follow[] = { IF, CHAR, STATIC, 0 };

	ty = unqual(ty);
	if (isscalar(ty)) {
		needconst++;
		if (t == '{') {
			t = gettok();
			e = expr1(0);
			initend(lev, follow);
		} else
			e = expr1(0);
		e = pointer(e);
		if ((aty = assign(ty, e)) != NULL)
			e = cast(e, aty);
		else
			error("invalid initialization type; found `%t' expected `%t'\n",
				e->type, ty);
		n = genconst(e, 1);
		deallocate(STMT);
		needconst--;
	}
	if ((isunion(ty) || isstruct(ty)) && ty->size == 0) {
		static char follow[] = { CHAR, STATIC, 0 };
		error("cannot initialize undefined `%t'\n", ty);
		skipto(';', follow);
		return ty;
	} else if (isunion(ty)) {
		if (t == '{') {
			t = gettok();
			n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
			initend(lev, follow);
		} else {
			if (lev == 0)
				error("missing { in initialization of `%t'\n", ty);
			n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
		}
	} else if (isstruct(ty)) {
		if (t == '{') {
			t = gettok();
			n = initstruct(0, ty, lev + 1);
			test('}', follow);
		} else if (lev > 0)
			n = initstruct(ty->size, ty, lev + 1);
		else {
			error("missing { in initialization of `%t'\n", ty);
			n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
		}
	}
	if (isarray(ty))
		aty = unqual(ty->type);
	if (isarray(ty) && ischar(aty)) {
		if (t == SCON) {
			if (ty->size > 0 && ty->size == tsym->type->size - 1)
				tsym->type = array(chartype, ty->size, 0);
			n = tsym->type->size;
			(*IR->defstring)(tsym->type->size, tsym->u.c.v.p);
			t = gettok();
		} else if (t == '{') {
			t = gettok();
			if (t == SCON) {
				ty = initializer(ty, lev + 1);
				initend(lev, follow);
				return ty;
			}
			n = initchar(0, aty);
			test('}', follow);
		} else if (lev > 0 && ty->size > 0)
			n = initchar(ty->size, aty);
		else {	/* eg, char c[] = 0; */
			error("missing { in initialization of `%t'\n", ty);
			n = initchar(1, aty);
		}
	} else if (isarray(ty)) {
		if (t == SCON && aty == widechar) {
			int i;
			unsigned int *s = tsym->u.c.v.p;
			if (ty->size > 0 && ty->size == tsym->type->size - widechar->size)
				tsym->type = array(widechar, ty->size/widechar->size, 0);
			n = tsym->type->size;
			for (i = 0; i < n; i += widechar->size) {
				Value v;
				v.u = *s++;
				(*IR->defconst)(widechar->op, widechar->size, v);
			}
			t = gettok();
		} else if (t == '{') {
			t = gettok();
			if (t == SCON && aty == widechar) {
				ty = initializer(ty, lev + 1);
				initend(lev, follow);
				return ty;
			}
			n = initarray(0, aty, lev + 1);
			test('}', follow);
		} else if (lev > 0 && ty->size > 0)
			n = initarray(ty->size, aty, lev + 1);
		else {
			error("missing { in initialization of `%t'\n", ty);
			n = initarray(aty->size, aty, lev + 1);
		}
	}	
	if (ty->size) {
		if (n > ty->size)
			error("too many initializers\n");
		else if (n < ty->size)
			(*IR->space)(ty->size - n);
	} else if (isarray(ty) && ty->type->size > 0)
		ty = array(ty->type, n/ty->type->size, 0);
	else
		ty->size = n;
	return ty;
}

/* swtoseg - switch to segment seg, if necessary */
void swtoseg(int seg) {
	if (curseg != seg)
		(*IR->segment)(seg);
	curseg = seg;
}




See more files for this project here

Nxabega

Nxabega is a First Person Shooter (FPS) based upon the open sourced Quake 3 engine and game code. The final intention is to provide a rich single player game.

Project homepage: http://sourceforge.net/projects/nxabega
Programming language(s): C,C++
License: other

  2html.c
  alloc.c
  alpha.md
  asdl.c
  bind.c
  bytecode.c
  c.h
  config.h
  dag.c
  dagcheck.md
  decl.c
  enode.c
  error.c
  event.c
  expr.c
  gen.c
  init.c
  inits.c
  input.c
  lex.c
  list.c
  main.c
  mips.md
  null.c
  output.c
  pass2.c
  prof.c
  profio.c
  rcc.asdl
  run.sh
  simp.c
  sparc.md
  stab.c
  stab.h
  stmt.c
  string.c
  sym.c
  symbolic.c
  token.h
  trace.c
  tree.c
  types.c
  x86.md
  x86linux.md