Ejemplo n.º 1
0
/*
 * add the special macros to the macro table
 */
static void add_special_macros(void)
{
	struct macro *m;

	HTT_put(&macros, new_macro(), "__LINE__");
	HTT_put(&macros, new_macro(), "__FILE__");
	HTT_put(&macros, new_macro(), "__DATE__");
	HTT_put(&macros, new_macro(), "__TIME__");
	HTT_put(&macros, new_macro(), "__STDC__");
	m = new_macro(); m->narg = 1;
	m->arg = getmem(sizeof(char *)); m->arg[0] = sdup("foo");
	HTT_put(&macros, m, "_Pragma");
	if (c99_compliant) {

		m = new_macro();
		m->cval.t = getmem(9);
		m->cval.t[0] = NUMBER;
		mmv(m->cval.t + 1, "199901L", 8);
		m->cval.length = 9;
		HTT_put(&macros, m, "__STDC_VERSION__");
	}
	if (c99_hosted) {
		m = new_macro();
		m->cval.t = getmem(3);
		m->cval.t[0] = NUMBER;
		mmv(m->cval.t + 1, "1", 2);
		m->cval.length = 3;
	}
}
    /*!
      \brief Apply the preconditoner.

      \copydoc Preconditioner::apply(X&,const Y&)
    */
    virtual void apply (Domain& v, const Range& d)
    {
        Range& md = const_cast<Range&>(d);
        comm_.copyOwnerToAll(md,md);
        auto endrow=ilu_.end();
        for ( auto row = ilu_.begin(); row != endrow; ++row )
        {
            auto rhs(d[row.index()]);
            for ( auto col = row->begin(); col.index() < row.index(); ++col )
            {
                col->mmv(v[col.index()],rhs);
            }
            v[row.index()] = rhs;
        }
        comm_.copyOwnerToAll(v, v);
        auto rendrow = ilu_.beforeBegin();
        for( auto row = ilu_.beforeEnd(); row != rendrow; --row)
        {
            auto rhs(v[row.index()]);
            auto col = row->beforeEnd();
            for( ; col.index() > row.index(); --col)
            {
                col->mmv(v[col.index()], rhs);
            }
            v[row.index()] = 0;
            col->umv(rhs, v[row.index()]);
        }
        comm_.copyOwnerToAll(v, v);
        v *= w_;
    }
Ejemplo n.º 3
0
void *incmem_debug(void *x, size_t ol, size_t nl, char *file, int line)
{
	void *y = getmem_debug(nl, file, line);
	mmv(y, x, ol < nl ? ol : nl);
	freemem_debug(x, file, line);
	return y;
}
Ejemplo n.º 4
0
char *sdup_debug(const char *src, char *file, int line)
{
	size_t n = 1 + strlen(src);
	char *x = getmem_debug(n, file, line);

	mmv(x, src, n);
	return x;
}
Ejemplo n.º 5
0
/*
 * This function creates a new char * and fills it with a copy of src
 */
char *(sdup)(const char *src)
{
	size_t n = 1 + strlen(src);
	char *x = getmem(n);

	mmv(x, src, n);
	return x;
}
Ejemplo n.º 6
0
static void *true_incmem(void *x, size_t old_size, size_t new_size)
{
	void * y = realloc(x, new_size);

	if (y == 0) {
		y = malloc(new_size);
		if (y == 0) {
			fprintf(stderr, "ouch: malloc() failed\n");
			die();
		}
		mmv(y, x, old_size < new_size ? old_size : new_size);
		free(x);
	}
	return y;
}
Ejemplo n.º 7
0
/*
 * This function duplicates a given hash table; the data is not copied
 */
struct HT *copyHT(struct HT *ht)
{
	struct HT *nht = newHT(ht->nb_lists, ht->cmpdata, ht->hash,
		ht->deldata);
	struct hash_item *t;
	int i, j;

	for (i = 0; i < nht->nb_lists; i ++) {
		j = 0;
		t = ht->lists[i];
		while (t) {
			t = t->next;
			j ++;
		}
		if (j != 0) {
			nht->lists[i] = getmem(j * sizeof(struct hash_item));
			mmv(nht->lists[i], ht->lists[i],
				j * sizeof(struct hash_item));
		}
	}
	return nht;
}
Ejemplo n.º 8
0
/*
 * We found a #define directive; parse the end of the line, perform
 * sanity checks, store the new macro into the "macros" hash table.
 *
 * In case of a redefinition of a macro: we enforce the rule that a
 * macro should be redefined identically, including the spelling of
 * parameters. We emit an error on offending code; dura lex, sed lex.
 * After all, it is easy to avoid such problems, with a #undef directive.
 */
int handle_define(struct lexer_state *ls)
{
	struct macro *m = 0, *n;
	struct token_fifo mv;
	int ltwws = 1, redef = 0;
	char *mname = 0;
	int narg;
	size_t nt;
	long l = ls->line;

	mv.art = mv.nt = 0;
	mv.t = NULL;
	/* find the next non-white token on the line, this should be
	   the macro name */
	while (!next_token(ls) && ls->ctok->type != NEWLINE) {
		if (ttMWS(ls->ctok->type)) continue;
		if (ls->ctok->type == NAME) mname = sdup(ls->ctok->name);
		break;
	}
	if (mname == 0) {
		error(l, "missing macro name");
		return 1;
	}
	if (check_special_macro(mname)) {
		error(l, "trying to redefine the special macro %s", mname);
		goto warp_error;
	}
	/*
	 * If a macro with this name was already defined: the K&R
	 * states that the new macro should be identical to the old one
	 * (with some arcane rule of equivalence of whitespace); otherwise,
	 * redefining the macro is an error. Most preprocessors would
	 * only emit a warning (or nothing at all) on an unidentical
	 * redefinition.
	 *
	 * Since it is easy to avoid this error (with a #undef directive),
	 * we choose to enforce the rule and emit an error.
	 */
	if ((n = HTT_get(&macros, mname)) != 0) {
		/* redefinition of a macro: we must check that we define
		   it identical */
		redef = 1;
		n->cval.rp = 0;
		freemem(mname);
		mname = 0;
	}
	if (!redef) {
		m = new_macro();
		m->narg = -1;
#define mval	mv
	}
	if (next_token(ls)) goto define_end;
	/*
	 * Check if the token immediately following the macro name is
	 * a left parenthesis; if so, then this is a macro with arguments.
	 * Collect their names and try to match the next parenthesis.
	 */
	if (ls->ctok->type == LPAR) {
		int i, j;
		int need_comma = 0, saw_mdots = 0;

		narg = 0;
		while (!next_token(ls)) {
			if (ls->ctok->type == NEWLINE) {
				error(l, "truncated macro definition");
				goto define_error;
			}
			if (ls->ctok->type == COMMA) {
				if (saw_mdots) {
					error(l, "'...' must end the macro "
						"argument list");
					goto warp_error;
				}
				if (!need_comma) {
					error(l, "void macro argument");
					goto warp_error;
				}
				need_comma = 0;
				continue;
			} else if (ls->ctok->type == NAME) {
				if (saw_mdots) {
					error(l, "'...' must end the macro "
						"argument list");
					goto warp_error;
				}
				if (need_comma) {
					error(l, "missing comma in "
						"macro argument list");
					goto warp_error;
				}
				if (!redef) {
					aol(m->arg, narg,
						sdup(ls->ctok->name), 8);
					/* we must keep track of m->narg
					   so that cleanup in case of
					   error works. */
					m->narg = narg;
					if (narg == 128
						&& (ls->flags & WARN_STANDARD))
						warning(l, "more arguments to "
							"macro than the ISO "
							"limit (127)");
					if (narg == 32767) {
						error(l, "too many arguments "
							"in macro definition "
							"(max 32766)");
						goto warp_error;
					}
				} else {
					/* this is a redefinition of the
					   macro; check equality between
					   old and new definitions */
					if (narg >= n->narg) goto redef_error;
					if (strcmp(ls->ctok->name,
						n->arg[narg ++]))
						goto redef_error;
				}
				need_comma = 1;
				continue;
			} else if ((ls->flags & MACRO_VAARG)
				&& ls->ctok->type == MDOTS) {
				if (need_comma) {
					error(l, "missing comma before '...'");
					goto warp_error;
				}
				if (redef && !n->vaarg) goto redef_error;
				if (!redef) m->vaarg = 1;
				saw_mdots = 1;
				need_comma = 1;
				continue;
			} else if (ls->ctok->type == RPAR) {
				if (narg > 0 && !need_comma) {
					error(l, "void macro argument");
					goto warp_error;
				}
				if (redef && n->vaarg && !saw_mdots)
					goto redef_error;
				break;
			} else if (ttMWS(ls->ctok->type)) {
				continue;
			}
			error(l, "invalid macro argument");
			goto warp_error;
		}
		if (!redef) {
			for (i = 1; i < narg; i ++) for (j = 0; j < i; j ++)
				if (!strcmp(m->arg[i], m->arg[j])) {
					error(l, "duplicate macro "
						"argument");
					goto warp_error;
				}
		}
		if (!redef) m->narg = narg;
	} else {
		if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD))
			warning(ls->line, "identifier not followed by "
				"whitespace in #define");
		ls->flags |= READ_AGAIN;
		narg = 0;
	}
	if (redef) nt = 0;

	/* now, we have the arguments. Let's get the macro contents. */
	while (!next_token(ls) && ls->ctok->type != NEWLINE) {
		struct token t;

		t.type = ls->ctok->type;
		if (ltwws && ttMWS(t.type)) continue;
		t.line = 0;
		if (t.type == NAME) {
			int i;

			if ((ls->flags & MACRO_VAARG)
				&& !strcmp(ls->ctok->name, "__VA_ARGS__")) {
				if (redef) {
					if (!n->vaarg) goto redef_error;
				} else if (!m->vaarg) {
					error(l, "'__VA_ARGS__' is forbidden "
						"in macros with a fixed "
						"number of arguments");
					goto warp_error;
				}
				t.type = MACROARG;
				t.line = redef ? n->narg : m->narg;
			}
			for (i = 0; i < narg; i ++)
				if (!strcmp(redef ? n->arg[i] : m->arg[i],
					ls->ctok->name)) {
					t.type = MACROARG;
					/* this is a hack: we store the
					   argument number in the line field */
					t.line = i;
					break;
				}
		}
		if (!redef && S_TOKEN(t.type)) t.name = sdup(ls->ctok->name);
		if (ttMWS(t.type)) {
			if (ltwws) continue;
#ifdef SEMPER_FIDELIS
			t.type = OPT_NONE;
#else
			t.type = NONE;
#endif
			ltwws = 1;
		} else ltwws = 0;
		if (!redef) {
			/* we ensure that each macro token has a correct
			   line number */
			if (t.type != MACROARG) t.line = 1;
			aol(mval.t, mval.nt, t, TOKEN_LIST_MEMG);
		} else {
			int tt;

			if (n->cval.rp >= n->cval.length) {
#ifdef SEMPER_FIDELIS
				if (t.type != OPT_NONE) goto redef_error;
#else
				if (t.type != NONE) goto redef_error;
#endif
			} else if (t.type != n->cval.t[n->cval.rp]) {
				goto redef_error;
			} else if (t.type == MACROARG) {
				unsigned anum = n->cval.t[n->cval.rp + 1];

				if (anum >= 128U) anum = ((anum & 127U) << 8)
					| m->cval.t[n->cval.rp + 2];
				if (anum != (unsigned)t.line) goto redef_error;
			} else if (S_TOKEN(t.type) && strcmp(ls->ctok->name,
				   (char *)(n->cval.t + n->cval.rp + 1))) {
				goto redef_error;
			}
			tt = n->cval.t[n->cval.rp ++];
			if (S_TOKEN(tt)) n->cval.rp += 1
				+ strlen((char *)(n->cval.t + n->cval.rp));
			else if (tt == MACROARG) {
				if (n->cval.t[++ n->cval.rp] >= 128)
					n->cval.rp ++;
			}
			nt ++;
		}
	}

	if (redef) {
		if (n->cval.rp < n->cval.length) goto redef_error_2;
		return 0;
	}

	/* now we have the complete macro; perform some checks about
	   the operators # and ##, and, if everything is ok,
	   store the macro into the hash table */
define_end:
#ifdef SEMPER_FIDELIS
	if (mval.nt && mval.t[mval.nt - 1].type == OPT_NONE) {
#else
	if (mval.nt && mval.t[mval.nt - 1].type == NONE) {
#endif
		mval.nt --;
		if (mval.nt == 0) freemem(mval.t);
	}
	if (mval.nt != 0) {
		/* some checks about the macro */
		if (mval.t[0].type == DSHARP
			|| mval.t[0].type == DIG_DSHARP
			|| mval.t[mval.nt - 1].type == DSHARP
			|| mval.t[mval.nt - 1].type == DIG_DSHARP) {
			error(l, "operator '##' may neither begin "
				"nor end a macro");
			goto define_error;
		}
		if (m->narg >= 0) {
			size_t i;
			for (i = 0; i < mval.nt; i ++)
				if ((mval.t[i].type == SHARP
					|| mval.t[i].type == DIG_SHARP) &&
					(i == (mval.nt - 1)
					|| (ttMWS(mval.t[i + 1].type) &&
					    (i == mval.nt - 2
					     || mval.t[i + 2].type != MACROARG))
					|| (!ttMWS(mval.t[i + 1].type)
					     && mval.t[i + 1].type != MACROARG))) {
					error(l, "operator '#' not followed "
						"by a macro argument");
					goto define_error;
				}
		}
	}
	{
		size_t i, l;

		for (i = 0, l = 0; i < mval.nt; i ++) {
			l ++;
			if (S_TOKEN(mval.t[i].type))
				l += 1 + strlen(mval.t[i].name);
			else if (mval.t[i].type == MACROARG) {
				l ++;
				if (mval.t[i].line >= 128) l ++;
			}
		}
		m->cval.length = l;
		if (l) m->cval.t = getmem(l);
		for (i = 0, l = 0; i < mval.nt; i ++) {
			m->cval.t[l ++] = mval.t[i].type;
			if (S_TOKEN(mval.t[i].type)) {
				size_t x = 1 + strlen(mval.t[i].name);

				mmv(m->cval.t + l, mval.t[i].name, x);
				l += x;
				freemem(mval.t[i].name);
			}
			else if (mval.t[i].type == MACROARG) {
				unsigned anum = mval.t[i].line;

				if (anum >= 128) {
					m->cval.t[l ++] = 128 | (anum >> 8);
					m->cval.t[l ++] = anum & 0xFF;
				} else {
					m->cval.t[l ++] = anum;
				}
			}
		}