Exemplo n.º 1
0
/*
 * T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN
 */
void
for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3)
{

	/*
	 * If there is no initialisation expression it is possible that
	 * it is intended not to enter the loop at top.
	 */
	if (tn1 != NULL && !reached) {
		/* loop not entered at top */
		warning(207);
		reached = 1;
	}

	pushctrl(T_FOR);
	cstk->c_loop = 1;

	/*
	 * Store the tree memory for the reinitialisation expression.
	 * Also remember this expression itself. We must check it at
	 * the end of the loop to get "used but not set" warnings correct.
	 */
	cstk->c_fexprm = tsave();
	cstk->c_f3expr = tn3;
	STRUCT_ASSIGN(cstk->c_fpos, curr_pos);
	STRUCT_ASSIGN(cstk->c_cfpos, csrc_pos);

	if (tn1 != NULL)
		expr(tn1, 0, 0);

	if (tn2 != NULL)
		tn2 = cconv(tn2);
	if (tn2 != NULL)
		tn2 = promote(NOOP, 0, tn2);
	if (tn2 != NULL && !issclt(tn2->tn_type->t_tspec)) {
		/* controlling expressions must have scalar type */
		error(204);
		tn2 = NULL;
	}
	if (tn2 != NULL)
		expr(tn2, 0, 1);

	if (tn2 == NULL) {
		cstk->c_infinite = 1;
	} else if (tn2->tn_op == CON) {
		if (isityp(tn2->tn_type->t_tspec)) {
			cstk->c_infinite = tn2->tn_val->v_quad != 0;
		} else {
			cstk->c_infinite = tn2->tn_val->v_ldbl != 0.0;
		}
	}

	/* Checking the reinitialisation expression is done in for2() */

	reached = 1;
}
Exemplo n.º 2
0
/*
 * Read an u-record (emitted by lint1 if a symbol was used).
 */
static void
usedsym(pos_t *posp, const char *cp)
{
	usym_t	*usym;
	hte_t	*hte;
	const char *name;

	usym = xalloc(sizeof (usym_t));
	STRUCT_ASSIGN(usym->u_pos, *posp);

	/* needed as delimiter between two numbers */
	if (*cp++ != 'x')
		inperr();

	name = inpname(cp, &cp);
	hte = _hsearch(renametab, name, 0);
	if (hte != NULL)
		hte = hte->h_hte;
	else
		hte = hsearch(name, 1);
	hte->h_used = 1;

	*hte->h_lusym = usym;
	hte->h_lusym = &usym->u_nxt;
}
Exemplo n.º 3
0
/*
 * SCANFLIKE comment
 *
 * Check all arguments until the (n-1)-th as usual. The n-th argument is
 * used the check the types of remaining arguments.
 */
void
scanflike(int n)
{

	if (n == -1)
		n = 0;

	if (dcs->d_ctx != EXTERN) {
		/* must be outside function: ** %s ** */
		warning(280, "SCANFLIKE");
		return;
	}
	if (scflstrg != -1) {
		/* duplicate use of ** %s ** */
		warning(281, "SCANFLIKE");
	}
	scflstrg = n;
	STRUCT_ASSIGN(scflpos, curr_pos);
}
Exemplo n.º 4
0
/*
 * VARARGS comment
 *
 * Makes that lint2 checks only the first n arguments for compatibility
 * to the function definition. A missing argument is taken to be 0.
 */
void
varargs(int n)
{

	if (n == -1)
		n = 0;

	if (dcs->d_ctx != EXTERN) {
		/* must be outside function: ** %s ** */
		warning(280, "VARARGS");
		return;
	}
	if (nvararg != -1) {
		/* duplicate use of  ** %s ** */
		warning(281, "VARARGS");
	}
	nvararg = n;
	STRUCT_ASSIGN(vapos, curr_pos);
}
Exemplo n.º 5
0
/*
 * ARGSUSED comment
 *
 * Only the first n arguments of the following function are checked
 * for usage. A missing argument is taken to be 0.
 */
void
argsused(int n)
{

	if (n == -1)
		n = 0;

	if (dcs->d_ctx != EXTERN) {
		/* must be outside function: ** %s ** */
		warning(280, "ARGSUSED");
		return;
	}
	if (nargusg != -1) {
		/* duplicate use of ** %s ** */
		warning(281, "ARGSUSED");
	}
	nargusg = n;
	STRUCT_ASSIGN(aupos, curr_pos);
}
Exemplo n.º 6
0
/*
 * Do some cleanup after a global declaration or definition.
 * Especially remove informations about unused lint comments.
 */
void
glclup(int silent)
{
	pos_t	cpos;

	STRUCT_ASSIGN(cpos, curr_pos);

	if (nargusg != -1) {
		if (!silent) {
			STRUCT_ASSIGN(curr_pos, aupos);
			/* must precede function definition: %s */
			warning(282, "ARGSUSED");
		}
		nargusg = -1;
	}
	if (nvararg != -1) {
		if (!silent) {
			STRUCT_ASSIGN(curr_pos, vapos);
			/* must precede function definition: %s */
			warning(282, "VARARGS");
		}
		nvararg = -1;
	}
	if (prflstrg != -1) {
		if (!silent) {
			STRUCT_ASSIGN(curr_pos, prflpos);
			/* must precede function definition: %s */
			warning(282, "PRINTFLIKE");
		}
		prflstrg = -1;
	}
	if (scflstrg != -1) {
		if (!silent) {
			STRUCT_ASSIGN(curr_pos, scflpos);
			/* must precede function definition: %s */
			warning(282, "SCANFLIKE");
		}
		scflstrg = -1;
	}

	STRUCT_ASSIGN(curr_pos, cpos);

	dcs->d_asm = 0;
}
Exemplo n.º 7
0
/*
 * for_exprs stmnt
 * for_exprs error
 */
void
for2(void)
{
	pos_t	cpos, cspos;
	tnode_t	*tn3;

	if (cstk->c_cont)
		reached = 1;

	STRUCT_ASSIGN(cpos, curr_pos);
	STRUCT_ASSIGN(cspos, csrc_pos);

	/* Restore the tree memory for the reinitialisation expression */
	trestor(cstk->c_fexprm);
	tn3 = cstk->c_f3expr;
	STRUCT_ASSIGN(curr_pos, cstk->c_fpos);
	STRUCT_ASSIGN(csrc_pos, cstk->c_cfpos);

	/* simply "statement not reached" would be confusing */
	if (!reached && !rchflg) {
		/* end-of-loop code not reached */
		warning(223);
		reached = 1;
	}

	if (tn3 != NULL) {
		expr(tn3, 0, 0);
	} else {
		tfreeblk();
	}

	STRUCT_ASSIGN(curr_pos, cpos);
	STRUCT_ASSIGN(csrc_pos, cspos);

	/* An endless loop without break will never terminate */
	reached = cstk->c_break || !cstk->c_infinite;
	rchflg = 0;

	popctrl(T_FOR);
}
Exemplo n.º 8
0
void
inittyp(void)
{
	size_t	i;
	static const struct {
		tspec_t	it_tspec;
		ttab_t	it_ttab;
	} ittab[NTSPEC] = {
		{ SIGNED,   { 0, 0,
				      SIGNED, UNSIGN,
				      0, 0, 0, 0, 0, 0, "signed" } },
		{ UNSIGN,   { 0, 0,
				      SIGNED, UNSIGN,
				      0, 0, 0, 0, 0, 0, "unsigned" } },
		{ BOOL,	    { CHAR_SIZE, 1,
				      BOOL, BOOL,
				      1, 1, 0, 1, 1, 0, "_Bool" } },
		{ CHAR,	    { CHAR_SIZE, CHAR_BIT,
				      SCHAR, UCHAR,
				      1, 0, 0, 1, 1, 0, "char" } },
		{ SCHAR,    { CHAR_SIZE, CHAR_BIT,
				      SCHAR, UCHAR,
				      1, 0, 0, 1, 1, 0, "signed char" } },
		{ UCHAR,    { CHAR_SIZE, CHAR_BIT,
				      SCHAR, UCHAR,
				      1, 1, 0, 1, 1, 0, "unsigned char" } },
		{ SHORT,    { SHORT_SIZE, 2 * CHAR_BIT,
				      SHORT, USHORT,
				      1, 0, 0, 1, 1, 0, "short" } },
		{ USHORT,   { SHORT_SIZE, 2 * CHAR_BIT,
				      SHORT, USHORT,
				      1, 1, 0, 1, 1, 0, "unsigned short" } },
		{ INT,      { INT_SIZE, INT_RSIZE * CHAR_BIT,
				      INT, UINT,
				      1, 0, 0, 1, 1, 0, "int" } },
		{ UINT,     { INT_SIZE, INT_RSIZE * CHAR_BIT,
				      INT, UINT,
				      1, 1, 0, 1, 1, 0, "unsigned int" } },
		{ LONG,     { LONG_SIZE, 4 * CHAR_BIT,
				      LONG, ULONG,
				      1, 0, 0, 1, 1, 0, "long" } },
		{ ULONG,    { LONG_SIZE, 4 * CHAR_BIT,
				      LONG, ULONG,
				      1, 1, 0, 1, 1, 0, "unsigned long" } },
		{ QUAD,     { QUAD_SIZE, 8 * CHAR_BIT,
				      QUAD, UQUAD,
				      1, 0, 0, 1, 1, 0, "long long" } },
		{ UQUAD,    { QUAD_SIZE, 8 * CHAR_BIT,
				      QUAD, UQUAD,
				      1, 1, 0, 1, 1, 0, "unsigned long long" } },
		{ FLOAT,    { FLOAT_SIZE, 4 * CHAR_BIT,
				      FLOAT, FLOAT,
				      0, 0, 1, 1, 1, 0, "float" } },
		{ DOUBLE,   { DOUBLE_SIZE, 8 * CHAR_BIT,
				      DOUBLE, DOUBLE,
				      0, 0, 1, 1, 1, 0, "double" } },
		{ LDOUBLE,  { LDOUBLE_SIZE, 10 * CHAR_BIT,
				      LDOUBLE, LDOUBLE,
				      0, 0, 1, 1, 1, 0, "long double" } },
		{ FCOMPLEX,   { FLOAT_SIZE * 2, 4 * CHAR_BIT * 2,
				      FCOMPLEX, FCOMPLEX,
				      0, 0, 1, 1, 1, 1, "float _Complex" } },
		{ DCOMPLEX,   { DOUBLE_SIZE * 2, 8 * CHAR_BIT * 2,
				      DCOMPLEX, DCOMPLEX,
				      0, 0, 1, 1, 1, 1, "double _Complex" } },
		{ LCOMPLEX,   { LDOUBLE_SIZE * 2, 8 * CHAR_BIT * 2,
				      LCOMPLEX, LCOMPLEX,
				      0, 0, 1, 1, 1, 1, "long double _Complex" } },
		{ VOID,     { -1, -1,
				      VOID, VOID,
				      0, 0, 0, 0, 0, 0, "void" } },
		{ STRUCT,   { -1, -1,
				      STRUCT, STRUCT,
				      0, 0, 0, 0, 0, 0, "struct" } },
		{ UNION,    { -1, -1,
				      UNION, UNION,
				      0, 0, 0, 0, 0, 0, "union" } },
		{ ENUM,     { ENUM_SIZE, 3 * CHAR_BIT,
				      ENUM, ENUM,
				      1, 0, 0, 1, 1, 0, "enum" } },
		{ PTR,      { PTR_SIZE, 4 * CHAR_BIT,
				      PTR, PTR,
				      0, 1, 0, 0, 1, 0, "pointer" } },
		{ ARRAY,    { -1, -1,
				      ARRAY, ARRAY,
				      0, 0, 0, 0, 0, 0, "array" } },
		{ FUNC,     { -1, -1,
				      FUNC, FUNC,
				      0, 0, 0, 0, 0, 0, "function" } },
	};

	for (i = 0; i < sizeof (ittab) / sizeof (ittab[0]); i++)
		STRUCT_ASSIGN(ttab[ittab[i].it_tspec], ittab[i].it_ttab);
	if (!pflag) {
		for (i = 0; i < NTSPEC; i++)
			ttab[i].tt_psz = ttab[i].tt_sz;
	}
}
Exemplo n.º 9
0
/*
 * Process a label.
 *
 * typ		type of the label (T_NAME, T_DEFAULT or T_CASE).
 * sym		symbol table entry of label if typ == T_NAME
 * tn		expression if typ == T_CASE
 */
void
label(int typ, sym_t *sym, tnode_t *tn)
{
	cstk_t	*ci;
	clst_t	*cl;
	val_t	*v;
	val_t	nv;
	tspec_t	t;

	switch (typ) {

	case T_NAME:
		if (sym->s_set) {
			/* label %s redefined */
			error(194, sym->s_name);
		} else {
			setsflg(sym);
		}
		break;

	case T_CASE:

		/* find the stack entry for the innermost switch statement */
		for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt)
			continue;

		if (ci == NULL) {
			/* case not in switch */
			error(195);
			tn = NULL;
		} else if (tn != NULL && tn->tn_op != CON) {
			/* non-constant case expression */
			error(197);
			tn = NULL;
		} else if (tn != NULL && !isityp(tn->tn_type->t_tspec)) {
			/* non-integral case expression */
			error(198);
			tn = NULL;
		}

		if (tn != NULL) {

			if (ci->c_swtype == NULL)
				lerror("label() 1");

			if (reached && !ftflg) {
				if (hflag)
					/* fallthrough on case statement */
					warning(220);
			}

			t = tn->tn_type->t_tspec;
			if (t == LONG || t == ULONG ||
			    t == QUAD || t == UQUAD) {
				if (tflag)
					/* case label must be of type ... */
					warning(203);
			}

			/*
			 * get the value of the expression and convert it
			 * to the type of the switch expression
			 */
			v = constant(tn);
			(void) memset(&nv, 0, sizeof nv);
			cvtcon(CASE, 0, ci->c_swtype, &nv, v);
			free(v);

			/* look if we had this value already */
			for (cl = ci->c_clst; cl != NULL; cl = cl->cl_nxt) {
				if (cl->cl_val.v_quad == nv.v_quad)
					break;
			}
			if (cl != NULL && isutyp(nv.v_tspec)) {
				/* duplicate case in switch, %lu */
				error(200, (u_long)nv.v_quad);
			} else if (cl != NULL) {
				/* duplicate case in switch, %ld */
				error(199, (long)nv.v_quad);
			} else {
				/*
				 * append the value to the list of
				 * case values
				 */
				cl = xcalloc(1, sizeof (clst_t));
				STRUCT_ASSIGN(cl->cl_val, nv);
				cl->cl_nxt = ci->c_clst;
				ci->c_clst = cl;
			}
		}
		tfreeblk();
		break;

	case T_DEFAULT:

		/* find the stack entry for the innermost switch statement */
		for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt)
			continue;

		if (ci == NULL) {
			/* default outside switch */
			error(201);
		} else if (ci->c_default) {
			/* duplicate default in switch */
			error(202);
		} else {
			if (reached && !ftflg) {
				if (hflag)
					/* fallthrough on default statement */
					warning(284);
			}
			ci->c_default = 1;
		}
		break;
	};
	reached = 1;
}
Exemplo n.º 10
0
/*
 * Called after a function declaration which introduces a function definition
 * and before an (optional) old style argument declaration list.
 *
 * Puts all symbols declared in the Prototype or in an old style argument
 * list back to the symbol table.
 *
 * Does the usual checking of storage class, type (return value),
 * redeclaration etc..
 */
void
funcdef(sym_t *fsym)
{
	int	n, warn;
	sym_t	*arg, *sym, *rdsym;

	funcsym = fsym;

	/*
	 * Put all symbols declared in the argument list back to the
	 * symbol table.
	 */
	for (sym = dcs->d_fpsyms; sym != NULL; sym = sym->s_dlnxt) {
		if (sym->s_blklev != -1) {
			if (sym->s_blklev != 1)
				lerror("funcdef() 1");
			inssym(1, sym);
		}
	}

	/*
	 * In osfunc() we did not know whether it is an old style function
	 * definition or only an old style declaration, if there are no
	 * arguments inside the argument list ("f()").
	 */
	if (!fsym->s_type->t_proto && fsym->s_args == NULL)
		fsym->s_osdef = 1;

	chktyp(fsym);

	/*
	 * chktyp() checks for almost all possible errors, but not for
	 * incomplete return values (these are allowed in declarations)
	 */
	if (fsym->s_type->t_subt->t_tspec != VOID &&
	    incompl(fsym->s_type->t_subt)) {
		/* cannot return incomplete type */
		error(67);
	}

	fsym->s_def = DEF;

	if (fsym->s_scl == TYPEDEF) {
		fsym->s_scl = EXTERN;
		/* illegal storage class */
		error(8);
	}

	if (dcs->d_inline)
		fsym->s_inline = 1;

	/*
	 * Arguments in new style function declarations need a name.
	 * (void is already removed from the list of arguments)
	 */
	n = 1;
	for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_nxt) {
		if (arg->s_scl == ABSTRACT) {
			if (arg->s_name != unnamed)
				lerror("funcdef() 2");
			/* formal parameter lacks name: param #%d */
			error(59, n);
		} else {
			if (arg->s_name == unnamed)
				lerror("funcdef() 3");
		}
		n++;
	}

	/*
	 * We must also remember the position. s_dpos is overwritten
	 * if this is an old style definition and we had already a
	 * prototype.
	 */
	STRUCT_ASSIGN(dcs->d_fdpos, fsym->s_dpos);

	if ((rdsym = dcs->d_rdcsym) != NULL) {

		if (!isredec(fsym, (warn = 0, &warn))) {

			/*
			 * Print nothing if the newly defined function
			 * is defined in old style. A better warning will
			 * be printed in cluparg().
			 */
			if (warn && !fsym->s_osdef) {
				/* redeclaration of %s */
				(*(sflag ? error : warning))(27, fsym->s_name);
				prevdecl(-1, rdsym);
			}

			/* copy usage information */
			cpuinfo(fsym, rdsym);

			/*
			 * If the old symbol was a prototype and the new
			 * one is none, overtake the position of the
			 * declaration of the prototype.
			 */
			if (fsym->s_osdef && rdsym->s_type->t_proto)
				STRUCT_ASSIGN(fsym->s_dpos, rdsym->s_dpos);

			/* complete the type */
			compltyp(fsym, rdsym);

			/* once a function is inline it remains inline */
			if (rdsym->s_inline)
				fsym->s_inline = 1;

		}

		/* remove the old symbol from the symbol table */
		rmsym(rdsym);

	}

	if (fsym->s_osdef && !fsym->s_type->t_proto) {
		if (sflag && hflag && strcmp(fsym->s_name, "main") != 0)
			/* function definition is not a prototype */
			warning(286);
	}

	if (dcs->d_notyp)
		/* return value is implicitly declared to be int */
		fsym->s_rimpl = 1;

	reached = 1;
}
Exemplo n.º 11
0
/*
 * Process a declaration or definition (d-record).
 */
static void
decldef(pos_t *posp, const char *cp)
{
	sym_t	*symp, sym;
	char	c, *ep, *pos1;
	int	used, renamed;
	hte_t	*hte, *renamehte = NULL;
	const char *name, *rename;

	(void)memset(&sym, 0, sizeof (sym));
	STRUCT_ASSIGN(sym.s_pos, *posp);
	sym.s_def = NODECL;

	used = 0;

	while (strchr("tdeurosvPS", (c = *cp)) != NULL) {
		cp++;
		switch (c) {
		case 't':
			if (sym.s_def != NODECL)
				inperr();
			sym.s_def = TDEF;
			break;
		case 'd':
			if (sym.s_def != NODECL)
				inperr();
			sym.s_def = DEF;
			break;
		case 'e':
			if (sym.s_def != NODECL)
				inperr();
			sym.s_def = DECL;
			break;
		case 'u':
			if (used)
				inperr();
			used = 1;
			break;
		case 'r':
			if (sym.s_rval)
				inperr();
			sym.s_rval = 1;
			break;
		case 'o':
			if (sym.s_osdef)
				inperr();
			sym.s_osdef = 1;
			break;
		case 's':
			if (sym.s_static)
				inperr();
			sym.s_static = 1;
			break;
		case 'v':
			if (sym.s_va)
				inperr();
			sym.s_va = 1;
			sym.s_nva = (short)strtol(cp, &ep, 10);
			if (cp == ep)
				inperr();
			cp = ep;
			break;
		case 'P':
			if (sym.s_prfl)
				inperr();
			sym.s_prfl = 1;
			sym.s_nprfl = (short)strtol(cp, &ep, 10);
			if (cp == ep)
				inperr();
			cp = ep;
			break;
		case 'S':
			if (sym.s_scfl)
				inperr();
			sym.s_scfl = 1;
			sym.s_nscfl = (short)strtol(cp, &ep, 10);
			if (cp == ep)
				inperr();
			cp = ep;
			break;
		}
	}

	/* read symbol name, doing renaming if necessary */
	name = inpname(cp, &cp);
	renamed = 0;
	if (*cp == 'r') {
		cp++;
		name = xstrdup(name);
		rename = inpname(cp, &cp);

		/* enter it and see if it's already been renamed */
		renamehte = _hsearch(renametab, name, 1);
		if (renamehte->h_hte == NULL) {
			hte = hsearch(rename, 1);
			renamehte->h_hte = hte;
			renamed = 1;
		} else if (strcmp((hte = renamehte->h_hte)->h_name, rename)) {
			pos1 = xstrdup(mkpos(&renamehte->h_syms->s_pos));
			/* %s renamed multiple times\t%s  ::  %s */
			msg(18, name, pos1, mkpos(&sym.s_pos));
			free(pos1);
		}
		free((char *)name);
	} else {
		/* it might be a previously-done rename */
		hte = _hsearch(renametab, name, 0);
		if (hte != NULL)
			hte = hte->h_hte;
		else
			hte = hsearch(name, 1);
	}
	hte->h_used |= used;
	if (sym.s_def == DEF || sym.s_def == TDEF)
		hte->h_def = 1;

	sym.s_type = inptype(cp, &cp);

	/*
	 * Allocate memory for this symbol only if it was not already
	 * declared or tentatively defined at the same location with
	 * the same type. Works only for symbols with external linkage,
	 * because static symbols, tentatively defined at the same location
	 * but in different translation units are really different symbols.
	 */
	for (symp = hte->h_syms; symp != NULL; symp = symp->s_nxt) {
		if (symp->s_pos.p_isrc == sym.s_pos.p_isrc &&
		    symp->s_pos.p_iline == sym.s_pos.p_iline &&
		    symp->s_type == sym.s_type &&
		    ((symp->s_def == DECL && sym.s_def == DECL) ||
		     (!sflag && symp->s_def == TDEF && sym.s_def == TDEF)) &&
		    !symp->s_static && !sym.s_static) {
			break;
		}
	}

	if (symp == NULL) {
		/* allocsym reserviert keinen Platz fuer s_nva */
		if (sym.s_va || sym.s_prfl || sym.s_scfl) {
			symp = xalloc(sizeof (sym_t));
			STRUCT_ASSIGN(*symp, sym);
		} else {
			symp = xalloc(sizeof (symp->s_s));
			STRUCT_ASSIGN(symp->s_s, sym.s_s);
		}
		*hte->h_lsym = symp;
		hte->h_lsym = &symp->s_nxt;

		/* XXX hack so we can remember where a symbol was renamed */
		if (renamed)
			renamehte->h_syms = symp;
	}

	if (*cp != '\0')
		inperr();
}
Exemplo n.º 12
0
/*
 * Process a function call record (c-record).
 */
static void
funccall(pos_t *posp, const char *cp)
{
	arginf_t *ai, **lai;
	char	c, *eptr;
	int	rused, rdisc;
	hte_t	*hte;
	fcall_t	*fcall;
	const char *name;

	fcall = xalloc(sizeof (fcall_t));
	STRUCT_ASSIGN(fcall->f_pos, *posp);

	/* read flags */
	rused = rdisc = 0;
	lai = &fcall->f_args;
	while ((c = *cp) == 'u' || c == 'i' || c == 'd' ||
	       c == 'z' || c == 'p' || c == 'n' || c == 's') {
		cp++;
		switch (c) {
		case 'u':
			if (rused || rdisc)
				inperr();
			rused = 1;
			break;
		case 'i':
			if (rused || rdisc)
				inperr();
			break;
		case 'd':
			if (rused || rdisc)
				inperr();
			rdisc = 1;
			break;
		case 'z':
		case 'p':
		case 'n':
		case 's':
			ai = xalloc(sizeof (arginf_t));
			ai->a_num = (int)strtol(cp, &eptr, 10);
			if (cp == eptr)
				inperr();
			cp = eptr;
			if (c == 'z') {
				ai->a_pcon = ai->a_zero = 1;
			} else if (c == 'p') {
				ai->a_pcon = 1;
			} else if (c == 'n') {
				ai->a_ncon = 1;
			} else {
				ai->a_fmt = 1;
				ai->a_fstrg = inpqstrg(cp, &cp);
			}
			*lai = ai;
			lai = &ai->a_nxt;
			break;
		}
	}
	fcall->f_rused = rused;
	fcall->f_rdisc = rdisc;

	/* read name of function */
	name = inpname(cp, &cp);

	/* first look it up in the renaming table, then in the normal table */
	hte = _hsearch(renametab, name, 0);
	if (hte != NULL)
		hte = hte->h_hte;
	else
		hte = hsearch(name, 1);
	hte->h_used = 1;

	fcall->f_type = inptype(cp, &cp);

	*hte->h_lcall = fcall;
	hte->h_lcall = &fcall->f_nxt;

	if (*cp != '\0')
		inperr();
}