Example #1
0
awkfloat
getfval(CELL *vp)
{


	if (vp->sval == record && donerec == 0)
		recbld();
	dprintf("getfval: %o", vp, NULL, NULL);
	if (vp->tval & ARR)
		error(FATAL, "illegal reference to array %ws", vp->nval);
	if ((vp->tval & (NUM | STR)) == 0)
		error(FATAL, "funny variable %o: %ws %ws %g %o", vp, vp->nval,
			vp->sval, vp->fval, vp->tval);
	if ((vp->tval & NUM) == 0) {
		/* the problem is to make non-numeric things */
		/* have unlikely numeric variables, so that */
		/* $1 == $2 comparisons sort of make sense when */
		/* one or the other is numeric */
		if (isanumber(vp->sval)) {
			vp->fval = watof(vp->sval);
			if (!(vp->tval & CON))
				/* don't change type of a constant */
				vp->tval |= NUM;
		}
		else
			vp->fval = 0.0;	/* not a very good idea */
	}
	dprintf("  %g\n", vp->fval, NULL, NULL);
	return (vp->fval);
}
Example #2
0
awkfloat getfval(register cell *vp)
{

	if (vp->sval == record && donerec == 0)
		recbld();
	dprintf("getfval: %lo", (long)vp);
	checkval(vp);
	if ((vp->tval & NUM) == 0) {
		/* the problem is to make non-numeric things */
		/* have unlikely numeric variables, so that */
		/* $1 == $2 comparisons sort of make sense when */
		/* one or the other is numeric */
		if (isanumber(vp->sval)) {
			vp->fval = atof(vp->sval);
			if (!(vp->tval & CON))	/* don't change type of a constant */
				vp->tval |= NUM;
		}
		else
			vp->fval = 0.0;	/* not a very good idea */
	}
	dprintf("  %g\n", vp->fval);
	return(vp->fval);
}
Example #3
0
File: parse.c Project: Reen/gnuplot
/* add action table entries for primary expressions, i.e. either a
 * parenthesized expression, a variable name, a numeric constant, a
 * function evaluation, a power operator or postfix '!' (factorial)
 * expression */
static void
parse_primary_expression()
{
    if (equals(c_token, "(")) {
	c_token++;
	parse_expression();

	/* Expressions may be separated by a comma */
	while (equals(c_token,",")) {
	    c_token++;
	    (void) add_action(POP);
	    parse_expression();
	}

	if (!equals(c_token, ")"))
	    int_error(c_token, "')' expected");
	c_token++;
    } else if (equals(c_token, "$")) {
	struct value a;

	c_token++;
	if (equals(c_token,"N")) {	/* $N == pseudocolumn -3 means "last column" */
	    c_token++;
	    Ginteger(&a, -3);
	    at_highest_column_used = -3;
	} else if (!isanumber(c_token)) {
	    int_error(c_token, "Column number expected");
	} else {
	    convert(&a, c_token++);
	    if (a.type != INTGR || a.v.int_val < 0)
		int_error(c_token, "Positive integer expected");
	    if (at_highest_column_used < a.v.int_val)
		at_highest_column_used = a.v.int_val;
	}
	add_action(DOLLARS)->v_arg = a;
    } else if (isanumber(c_token)) {
	/* work around HP 9000S/300 HP-UX 9.10 cc limitation ... */
	/* HBB 20010724: use this code for all platforms, then */
	union argument *foo = add_action(PUSHC);

	convert(&(foo->v_arg), c_token);
	c_token++;
    } else if (isletter(c_token)) {
	/* Found an identifier --- check whether its a function or a
	 * variable by looking for the parentheses of a function
	 * argument list */
	if (equals(c_token + 1, "(")) {
	    enum operators whichfunc = is_builtin_function(c_token);
	    struct value num_params;
	    num_params.type = INTGR;

#if (1)	    /* DEPRECATED */
	    if (whichfunc && (strcmp(ft[whichfunc].f_name,"defined")==0)) {
		/* Deprecated syntax:   if (defined(foo)) ...  */
		/* New syntax:          if (exists("foo")) ... */
		struct udvt_entry *udv = add_udv(c_token+2);
		union argument *foo = add_action(PUSHC);
		foo->v_arg.type = INTGR;
		foo->v_arg.v.int_val = udv->udv_undef ? 0 : 1;
		c_token += 4;  /* skip past "defined ( <foo> ) " */
		return;
	    }
#endif

	    if (whichfunc) {
		c_token += 2;	/* skip fnc name and '(' */
		parse_expression(); /* parse fnc argument */
		num_params.v.int_val = 1;
		while (equals(c_token, ",")) {
		    c_token++;
		    num_params.v.int_val++;
		    parse_expression();
		}

		if (!equals(c_token, ")"))
		    int_error(c_token, "')' expected");
		c_token++;

		/* So far sprintf is the only built-in function */
		/* with a variable number of arguments.         */
		if (!strcmp(ft[whichfunc].f_name,"sprintf"))
		    add_action(PUSHC)->v_arg = num_params;

		/* The column() function has side effects requiring special handling */
		if (!strcmp(ft[whichfunc].f_name,"column")) {
		    set_up_columnheader_parsing( &(at->actions[at->a_count-1]) );
		}

		(void) add_action(whichfunc);

	    } else {
		/* it's a call to a user-defined function */
		enum operators call_type = (int) CALL;
		int tok = c_token;

		c_token += 2;	/* skip func name and '(' */
		parse_expression();
		if (equals(c_token, ",")) { /* more than 1 argument? */
		    num_params.v.int_val = 1;
		    while (equals(c_token, ",")) {
			num_params.v.int_val += 1;
			c_token += 1;
			parse_expression();
		    }
		    add_action(PUSHC)->v_arg = num_params;
		    call_type = (int) CALLN;
		}
		if (!equals(c_token, ")"))
		    int_error(c_token, "')' expected");
		c_token++;
		add_action(call_type)->udf_arg = add_udf(tok);
	    }
	} else if (equals(c_token, "sum") && equals(c_token+1, "[")) {
            parse_sum_expression();
	/* dummy_func==NULL is a flag to say no dummy variables active */
	} else if (dummy_func) {
	    if (equals(c_token, c_dummy_var[0])) {
		c_token++;
		add_action(PUSHD1)->udf_arg = dummy_func;
		fit_dummy_var[0]++;
	    } else if (equals(c_token, c_dummy_var[1])) {
		c_token++;
		add_action(PUSHD2)->udf_arg = dummy_func;
		fit_dummy_var[1]++;
	    } else {
		int i, param = 0;

		for (i = 2; i < MAX_NUM_VAR; i++) {
		    if (equals(c_token, c_dummy_var[i])) {
			struct value num_params;
			num_params.type = INTGR;
			num_params.v.int_val = i;
			param = 1;
			c_token++;
			add_action(PUSHC)->v_arg = num_params;
			add_action(PUSHD)->udf_arg = dummy_func;
			fit_dummy_var[i]++;
			break;
		    }
		}
		if (!param) {	/* defined variable */
		    add_action(PUSH)->udv_arg = add_udv(c_token);
		    c_token++;
		}
	    }
	    /* its a variable, with no dummies active - div */
	} else {
	    add_action(PUSH)->udv_arg = add_udv(c_token);
	    c_token++;
	}
    }
    /* end if letter */

    /* Maybe it's a string constant */
    else if (isstring(c_token)) {
	union argument *foo = add_action(PUSHC);
	foo->v_arg.type = STRING;
	foo->v_arg.v.string_val = NULL;
	/* this dynamically allocated string will be freed by free_at() */
	m_quote_capture(&(foo->v_arg.v.string_val), c_token, c_token);
	c_token++;
    } else
	int_error(c_token, "invalid expression ");

    /* add action code for ! (factorial) operator */
    while (equals(c_token, "!")) {
	c_token++;
	(void) add_action(FACTORIAL);
    }
    /* add action code for ** operator */
    if (equals(c_token, "**")) {
	c_token++;
	parse_unary_expression();
	(void) add_action(POWER);
    }

    /* Parse and add actions for range specifier applying to previous entity.
     * Currently only used to generate substrings, but could also be used to
     * extract vector slices.
     */
    if (equals(c_token, "[") && !isanumber(c_token-1)) {
	/* handle '*' or empty start of range */
	if (equals(++c_token,"*") || equals(c_token,":")) {
	    union argument *empty = add_action(PUSHC);
	    empty->v_arg.type = INTGR;
	    empty->v_arg.v.int_val = 1;
	    if (equals(c_token,"*"))
		c_token++;
	} else
	    parse_expression();
	if (!equals(c_token, ":"))
	    int_error(c_token, "':' expected");
	/* handle '*' or empty end of range */
	if (equals(++c_token,"*") || equals(c_token,"]")) {
	    union argument *empty = add_action(PUSHC);
	    empty->v_arg.type = INTGR;
	    empty->v_arg.v.int_val = 65535; /* should be INT_MAX */
	    if (equals(c_token,"*"))
		c_token++;
	} else
	    parse_expression();
	if (!equals(c_token, "]"))
	    int_error(c_token, "']' expected");
	c_token++;
	(void) add_action(RANGE);
    }
}
Example #4
0
/* <fillstyle> = {empty | solid {<density>} | pattern {<n>}} {noborder | border {<lt>}} */
void
parse_fillstyle(struct fill_style_type *fs, int def_style, int def_density, int def_pattern, 
		t_colorspec def_bordertype)
{
    TBOOLEAN set_fill = FALSE;
    TBOOLEAN set_param = FALSE;
    TBOOLEAN transparent = FALSE;

    /* Set defaults */
    fs->fillstyle = def_style;
    fs->filldensity = def_density;
    fs->fillpattern = def_pattern;
    fs->border_color = def_bordertype;

    if (END_OF_COMMAND)
	return;
    if (!equals(c_token, "fs") && !almost_equals(c_token, "fill$style"))
	return;
    c_token++;

    while (!END_OF_COMMAND) {
	if (almost_equals(c_token, "trans$parent")) {
	    transparent = TRUE;
	    c_token++;
	}

	if (almost_equals(c_token, "e$mpty")) {
	    fs->fillstyle = FS_EMPTY;
	    c_token++;
	} else if (almost_equals(c_token, "s$olid")) {
	    fs->fillstyle = transparent ? FS_TRANSPARENT_SOLID : FS_SOLID;
	    set_fill = TRUE;
	    c_token++;
	} else if (almost_equals(c_token, "p$attern")) {
	    fs->fillstyle = transparent ? FS_TRANSPARENT_PATTERN : FS_PATTERN;
	    set_fill = TRUE;
	    c_token++;
	}

	if (END_OF_COMMAND)
	    continue;
	else if (almost_equals(c_token, "bo$rder")) {
	    fs->border_color.type = TC_DEFAULT;
	    c_token++;
	    if (equals(c_token,"-") || isanumber(c_token)) {
		fs->border_color.type = TC_LT;
		fs->border_color.lt = int_expression() - 1;
	    } else if (equals(c_token,"lc") || almost_equals(c_token,"linec$olor")) {
		parse_colorspec(&fs->border_color, TC_Z);
	    } else if (equals(c_token,"rgb")
		   ||  equals(c_token,"lt") || almost_equals(c_token,"linet$ype")) {
		c_token--;
		parse_colorspec(&fs->border_color, TC_Z);
	    }
	    continue;
	} else if (almost_equals(c_token, "nobo$rder")) {
	    fs->border_color.type = TC_LT;
	    fs->border_color.lt = LT_NODRAW;
	    c_token++;
	    continue;
	}

	/* We hit something unexpected */
	if (!set_fill || set_param)
	    break;
	if (!(isanumber(c_token) || type_udv(c_token) == INTGR || type_udv(c_token) == CMPLX))
	    break;

	if (fs->fillstyle == FS_SOLID || fs->fillstyle == FS_TRANSPARENT_SOLID) {
	    /* user sets 0...1, but is stored as an integer 0..100 */
	    fs->filldensity = 100.0 * real_expression() + 0.5;
	    if (fs->filldensity < 0)
		fs->filldensity = 0;
	    if (fs->filldensity > 100)
		fs->filldensity = 100;
	    set_param = TRUE;
	} else if (fs->fillstyle == FS_PATTERN || fs->fillstyle == FS_TRANSPARENT_PATTERN) {
	    fs->fillpattern = int_expression();
	    if (fs->fillpattern < 0)
		fs->fillpattern = 0;
	    set_param = TRUE;
	}
    }
}
Example #5
0
void
fldbld(void)
{
	register char *r, *fr;
	wchar_t wc, sep;
	int i, j, n;

	r = record;
	fr = fields;
	i = 0;	/* number of fields accumulated here */
	next(sep, *FS, n);
	if (sep == ' ')
		for (i = 0; ; ) {
			while (*r == ' ' || *r == '\t' || *r == '\n')
				r++;
			if (*r == 0)
				break;
			i++;
			if (i >= MAXFLD)
				morefields();
			if (!(fldtab[i]->tval&FLD))
				strfree(fldtab[i]->sval);
			fldtab[i]->sval = fr;
			fldtab[i]->tval = FLD | STR;
			next(wc, r, n);
			do {
				do
					*fr++ = *r++;
				while (--n);
				next(wc, r, n);
			} while (wc != ' ' && wc != '\t' && wc != '\n' &&
					wc != '\0');
			*fr++ = 0;
		}
	else if (*r != 0)	/* if 0, it's a null field */
		for (;;) {
			i++;
			if (i >= MAXFLD)
				morefields();
			if (!(fldtab[i]->tval&FLD))
				strfree(fldtab[i]->sval);
			fldtab[i]->sval = fr;
			fldtab[i]->tval = FLD | STR;
			while (next(wc, r, n),
					wc != sep && wc != '\n' && wc != '\0') {
					/* \n always a separator */
				do
					*fr++ = *r++;
				while (--n);
			}
			*fr++ = '\0';
			if (wc == '\0')
				break;
			r += n;
		}
	*fr = 0;
	for (j=MAXFLD-1; j>i; j--) {	/* clean out junk from previous record */
		if (!(fldtab[j]->tval&FLD))
			strfree(fldtab[j]->sval);
		fldtab[j]->tval = STR | FLD;
		fldtab[j]->sval = EMPTY;
	}
	maxfld = i;
	donefld = 1;
	for(i=1; i<=maxfld; i++)
		if(isanumber(fldtab[i]->sval)) {
			fldtab[i]->fval = atof(fldtab[i]->sval);
			fldtab[i]->tval |= NUM;
		}
	setfval(lookup("NF", symtab, 0), (awkfloat) maxfld);
	if (dbg)
		for (i = 0; i <= maxfld; i++)
			printf("field %d: |%s|\n", i, fldtab[i]->sval);
}
Example #6
0
void
parse_fillstyle(struct fill_style_type *fs, int def_style, int def_density, int def_pattern, 
		t_colorspec def_bordertype)
{
    TBOOLEAN set_fill = FALSE;
    TBOOLEAN set_border = FALSE;
    TBOOLEAN transparent = FALSE;

    /* Set defaults */
    fs->fillstyle = def_style;
    fs->filldensity = def_density;
    fs->fillpattern = def_pattern;
    fs->border_color = def_bordertype;

    if (END_OF_COMMAND)
	return;
    if (!equals(c_token, "fs") && !almost_equals(c_token, "fill$style"))
	return;
    c_token++;

    while (!END_OF_COMMAND) {
	int i;

	if (almost_equals(c_token, "trans$parent")) {
	    transparent = TRUE;
	    c_token++;
	    continue;
	}

	i = lookup_table(fs_opt_tbl, c_token);
	switch (i) {
	    default:
		 break;

	    case FS_EMPTY:
	    case FS_SOLID:
	    case FS_PATTERN:

		if (set_fill && fs->fillstyle != i)
		    int_error(c_token, "conflicting option");
		fs->fillstyle = i;
		set_fill = TRUE;
		c_token++;
		
		if (isanumber(c_token) || type_udv(c_token) == INTGR || type_udv(c_token) == CMPLX) {
		    if (fs->fillstyle == FS_SOLID) {
			/* user sets 0...1, but is stored as an integer 0..100 */
			fs->filldensity = 100.0 * real_expression() + 0.5;
			if (fs->filldensity < 0)
			    fs->filldensity = 0;
			if (fs->filldensity > 100)
			    fs->filldensity = 100;
		    } else if (fs->fillstyle == FS_PATTERN) {
			fs->fillpattern = int_expression();
			if (fs->fillpattern < 0)
			    fs->fillpattern = 0;
		    } else
			int_error(c_token, "this fill style does not have a parameter");
		}
		continue;
	}

	if (almost_equals(c_token, "bo$rder")) {
	    if (set_border && fs->border_color.lt == LT_NODRAW)
		int_error(c_token, "conflicting option");
	    fs->border_color.type = TC_DEFAULT;
	    set_border = TRUE;
	    c_token++;
	    if (END_OF_COMMAND)
		continue;
	    if (equals(c_token,"-") || isanumber(c_token)) {
		fs->border_color.type = TC_LT;
		fs->border_color.lt = int_expression() - 1;
	    } else if (equals(c_token,"lc") || almost_equals(c_token,"linec$olor")) {
		parse_colorspec(&fs->border_color, TC_Z);
	    } else if (equals(c_token,"rgb")
		   ||  equals(c_token,"lt") || almost_equals(c_token,"linet$ype")) {
		c_token--;
		parse_colorspec(&fs->border_color, TC_Z);
	    }
	    continue;
	} else if (almost_equals(c_token, "nobo$rder")) {
	    if (set_border && fs->border_color.lt != LT_NODRAW)
		int_error(c_token, "conflicting option");
	    fs->border_color.type = TC_LT;
	    fs->border_color.lt = LT_NODRAW;
	    set_border = TRUE;
	    c_token++;
	    continue;
	}

	/* Keyword must belong to someone else */
	break;
    }
    if (transparent) {
	if (fs->fillstyle == FS_SOLID)
	    fs->fillstyle = FS_TRANSPARENT_SOLID;
        else if (fs->fillstyle == FS_PATTERN)
	    fs->fillstyle = FS_TRANSPARENT_PATTERN;
    }
}
Example #7
0
asm86_t *ack_get_instruction(void)
{
	asm86_t *a= nil;
	expression_t *e;
	token_t *t;

	while ((t= get_token(0))->symbol == ';')
		skip_token(1);

	if (t->type == T_EOF) return nil;

	if (t->symbol == '#') {
		/* Preprocessor line and file change. */

		if ((t= get_token(1))->type != T_WORD || !isanumber(t->name)
			|| get_token(2)->type != T_STRING
		) {
			parse_err(1, t, "file not preprocessed?\n");
			zap();
		} else {
			set_file(get_token(2)->name,
				strtol(get_token(1)->name, nil, 0) - 1);

			/* GNU CPP adds extra cruft, simply zap the line. */
			zap();
		}
		a= ack_get_instruction();
	} else
	if (t->type == T_WORD && get_token(1)->symbol == ':') {
		/* A label definition. */
		a= new_asm86();
		a->line= t->line;
		a->opcode= DOT_LABEL;
		a->optype= PSEUDO;
		a->args= e= new_expr();
		e->operator= ':';
		e->name= copystr(t->name);
		skip_token(2);
	} else
	if (t->type == T_WORD && get_token(1)->symbol == '=') {
		int n= 2;

		if ((e= ack_get_C_expression(&n)) == nil) {
			zap();
			a= ack_get_instruction();
		} else
		if (get_token(n)->symbol != ';') {
			parse_err(1, t, "garbage after assignment\n");
			zap();
			a= ack_get_instruction();
		} else {
			a= new_asm86();
			a->line= t->line;
			a->opcode= DOT_EQU;
			a->optype= PSEUDO;
			a->args= new_expr();
			a->args->operator= '=';
			a->args->name= copystr(t->name);
			a->args->middle= e;
			skip_token(n+1);
		}
	} else
	if (t->type == T_WORD) {
		if ((a= ack_get_statement()) == nil) {
			zap();
			a= ack_get_instruction();
		}
	} else {
		parse_err(1, t, "syntax error\n");
		zap();
		a= ack_get_instruction();
	}
	return a;
}
Example #8
0
static asm86_t *ack_get_statement(void)
/* Get a pseudo op or machine instruction with arguments. */
{
	token_t *t= get_token(0);
	asm86_t *a;
	mnemonic_t *m;
	int n;
	int prefix_seen;
	int oaz_prefix;
	int deref;

	assert(t->type == T_WORD);

	if (strcmp(t->name, ".sect") == 0) {
		/* .sect .text etc.  Accept only four segment names. */
		skip_token(1);
		t= get_token(0);
		if (t->type != T_WORD || (
			strcmp(t->name, ".text") != 0
			&& strcmp(t->name, ".rom") != 0
			&& strcmp(t->name, ".data") != 0
			&& strcmp(t->name, ".bss") != 0
			&& strcmp(t->name, ".end") != 0
		)) {
			parse_err(1, t, "weird section name to .sect\n");
			return nil;
		}
	}
	a= new_asm86();

	/* Process instruction prefixes. */
	oaz_prefix= 0;
	for (prefix_seen= 0;; prefix_seen= 1) {
		if (strcmp(t->name, "o16") == 0) {
			if (use16()) {
				parse_err(1, t, "o16 in an 8086 section\n");
			}
			oaz_prefix|= OPZ;
		} else
		if (strcmp(t->name, "o32") == 0) {
			if (use32()) {
				parse_err(1, t, "o32 in an 80386 section\n");
			}
			oaz_prefix|= OPZ;
		} else
		if (strcmp(t->name, "a16") == 0) {
			if (use16()) {
				parse_err(1, t, "a16 in an 8086 section\n");
			}
			oaz_prefix|= ADZ;
		} else
		if (strcmp(t->name, "a32") == 0) {
			if (use32()) {
				parse_err(1, t, "a32 in an 80386 section\n");
			}
			oaz_prefix|= ADZ;
		} else
		if (strcmp(t->name, "rep") == 0
			|| strcmp(t->name, "repe") == 0
			|| strcmp(t->name, "repne") == 0
			|| strcmp(t->name, "repz") == 0
			|| strcmp(t->name, "repnz") == 0
		) {
			if (a->rep != ONCE) {
				parse_err(1, t,
					"can't have more than one rep\n");
			}
			switch (t->name[3]) {
			case 0:		a->rep= REP;	break;
			case 'e':
			case 'z':	a->rep= REPE;	break;
			case 'n':	a->rep= REPNE;	break;
			}
		} else
		if (strchr("cdefgs", t->name[0]) != nil
					&& strcmp(t->name+1, "seg") == 0) {
			if (a->seg != DEFSEG) {
				parse_err(1, t,
				"can't have more than one segment prefix\n");
			}
			switch (t->name[0]) {
			case 'c':	a->seg= CSEG;	break;
			case 'd':	a->seg= DSEG;	break;
			case 'e':	a->seg= ESEG;	break;
			case 'f':	a->seg= FSEG;	break;
			case 'g':	a->seg= GSEG;	break;
			case 's':	a->seg= SSEG;	break;
			}
		} else
		if (!prefix_seen) {
			/* No prefix here, get out! */
			break;
		} else {
			/* No more prefixes, next must be an instruction. */
			if (t->type != T_WORD
				|| (m= search_mnem(t->name)) == nil
				|| m->optype == PSEUDO
			) {
				parse_err(1, t,
		"machine instruction expected after instruction prefix\n");
				del_asm86(a);
				return nil;
			}
			if (oaz_prefix != 0 && m->optype != JUMP
						&& m->optype != WORD) {
				parse_err(1, t,
			"'%s' can't have an operand size prefix\n", m->name);
			}
			break;
		}

		/* Skip the prefix and extra newlines. */
		do {
			skip_token(1);
		} while ((t= get_token(0))->symbol == ';');
	}

	/* All the readahead being done upsets the line counter. */
	a->line= t->line;

	/* Read a machine instruction or pseudo op. */
	if ((m= search_mnem(t->name)) == nil) {
		parse_err(1, t, "unknown instruction '%s'\n", t->name);
		del_asm86(a);
		return nil;
	}
	a->opcode= m->opcode;
	a->optype= m->optype;
	a->oaz= oaz_prefix;

	switch (a->opcode) {
	case IN:
	case OUT:
	case INT:
		deref= 0;
		break;
	default:
		deref= (a->optype >= BYTE);
	}
	n= 1;
	if (get_token(1)->symbol != ';'
			&& (a->args= ack_get_oplist(&n, deref)) == nil) {
		del_asm86(a);
		return nil;
	}
	if (get_token(n)->symbol != ';') {
		parse_err(1, t, "garbage at end of instruction\n");
		del_asm86(a);
		return nil;
	}
	switch (a->opcode) {
	case DOT_ALIGN:
		/* Restrict .align to have a single numeric argument, some
		 * assemblers think of the argument as a power of two, so
		 * we need to be able to change the value.
		 */
		if (a->args == nil || a->args->operator != 'W'
					|| !isanumber(a->args->name)) {
			parse_err(1, t,
			  ".align is restricted to one numeric argument\n");
			del_asm86(a);
			return nil;
		}
		break;
	case JMPF:
	case CALLF:
		/* NCC jmpf off,seg  ->  ACK jmpf seg:off */
		if (dialect == NCC && a->args != nil
						&& a->args->operator == ',') {
			expression_t *t;

			t= a->args->left;
			a->args->left= a->args->right;
			a->args->right= t;
			break;
		}
		/*FALL THROUGH*/
	case JMP:
	case CALL:
		/* NCC jmp @(reg)  ->  ACK jmp (reg) */
		if (dialect == NCC && a->args != nil && (
			(a->args->operator == '('
				&& a->args->middle != nil
				&& a->args->middle->operator == 'O')
			|| (a->args->operator == 'O'
				&& a->args->left == nil
				&& a->args->middle != nil
				&& a->args->right == nil)
		)) {
			expression_t *t;

			t= a->args;
			a->args= a->args->middle;
			t->middle= nil;
			del_expr(t);
			if (a->args->operator == 'B') a->args->operator= 'W';
		}
		break;
	default:;
	}
	skip_token(n+1);
	return a;
}
Example #9
0
int main(int argc,char *argv[]) 

	/* argc: Number of arguments */
	/* argv: argument vector */

{
	struct arguments   args;   /* place to store the parsed arguments*/
	nl_catd	catdmsg;           /* catalog descriptor for message catalog */
	char 	*message;	   /* place to store message */
	char 	*p;		   /* pointer to current pos within message */
	int 	idx, 		   /* current argument to be printed */
		reorder = NOT_SET; /* Reordering  (TRUE, FALSE, NOT_SET) */
	int	n;		   /* # bytes in a character */

	setlocale (LC_ALL,"");
	catderr = catopen(MF_MSGFAC, 0);
	if (argc < 3) {
		die(catgets(catderr,MS_DSPMSG,M_DSPMSG, "Usage: dtdspmsg [-s setno] <catname> <msgno> ['default' arg ... ]"));
	}

/*______________________________________________________________________
	Parse the input arguments int the args structure.
  ______________________________________________________________________*/

	parse_args(argc,argv,&args);

/*______________________________________________________________________
	get the message out of the catalog.
  ______________________________________________________________________*/

	catdmsg = catopen(args.catname, 0);
	message = catgets(catdmsg,args.set,args.msg,args.def);

/*______________________________________________________________________

	print out the message making the appropriate sub's for
	the parameters.  Reorder the parameters if necessary.
	Do not use mixed reordering!!!
  ______________________________________________________________________*/

	for (p = message , idx = 0 ; *p ; p++ )  {

		/* quoted escape characters */
		if (*p == '\\' && message == args.def) {
			switch (*++p) {
				case 'n':
					putc('\n',stdout);
					break;

				case 't':
					putc('\t',stdout);
					break;

				case 'b':
					putc('\b',stdout);
					break;

				case 'r':
					putc('\r',stdout);
					break;

				case 'v':
					putc('\v',stdout);
					break;

				case 'f':
					putc('\f',stdout);
					break;

				case 'x':
					{
					char *pesc = p;
					int hex, hexlen = 0;

					while (isxdigit(*++pesc))
						hexlen++;
					if (hexlen == 2)
						sscanf (p+1, "%2x", &hex);
					else if (hexlen == 4)
						sscanf (p+1, "%4x", &hex);
					else {
						putc('x',stdout);
						break;
					}
					putc(hex,stdout);
					p += hexlen;
					break;
					}

				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
					{
					int c = 0;
					char *pesc = p;

					do
						c = c * 8 + *pesc++ - '0';
					while (isaoctal(*pesc) && pesc < p+3);
					if (c <= 0377) {
						putc(c,stdout);
						p = pesc - 1;
					} else
						putc(*p,stdout);
					break;
					}

				default: 
					putc(*p,stdout);
					break;
			}
		}

                /* printf % style substitution */
		else if (*p == '%') {

			/* %% prints one % */
			if (*++p == '%')  {
				putc(*p,stdout);
				continue;
			}

			/* %n$ reorders the argument list and uses variable n next */
			/* once this is used, all arguments must use it */
			if (isanumber(*p)) {

				/* do not allow mixing of reorder types */
				if (reorder == FALSE) {
					die(catgets(catderr,MS_DSPMSG,M_REORDER,"\nNone or all arguments must use %n$ format"));
				}
				for (idx = 0 ; isanumber(*p) ; p++)
					idx += idx * 10 + toanumber(*p);
				idx--;
				if (*p++ != '$') {
					die(catgets(catderr,MS_DSPMSG,M_INVRE,"\n% missing from %n$ format"));
				}
				reorder = TRUE;
			}
			else {
				/* do not allow mixing of reorder types */
				if (reorder == TRUE) {
					die(catgets(catderr,MS_DSPMSG,M_REORDER,"\nNone or all arguments must use %n$ format"));
				}
				reorder = FALSE;	
			}
			/* report invalid printf argument number */
			if (idx < 0 || idx >= args.argmax) {
				die(catgets(catderr,MS_DSPMSG,M_REINDEX,"\nInvalid argument index"));
			}
			/* report unsupported % type */
			if (*p == 's')
				;
			else if (*p == 'l' && p[1] == 'd')
				p++;
			else {
				exit(1);
			}
			fwrite(args.args[idx],strlen(args.args[idx]),1,stdout);
			idx++;				
		}

		/* just print the next character */
		else {
			n = mblen(p, MB_CUR_MAX);
			if (n < 0)
				n = 1;
			do
				putc(*p++,stdout);
			while (--n > 0);
			p--;
		}
	}
	exit(0);
}
Example #10
0
asm86_t *gnu_get_instruction(void)
{
	asm86_t *a= nil;
	expression_t *e;
	token_t *t;

	while ((t= get_token(0))->symbol == ';' || t->symbol == '/') {
		zap();		/* if a comment started by a '/' */
		skip_token(1);
	}

	if (t->type == T_EOF) return nil;

	if (t->type == T_COMMENT || t->type == T_C_PREPROCESSOR) {

		a = new_asm86();
		if (t->type == T_COMMENT)
			a->opcode = COMMENT;
		else
			a->opcode = C_PREPROCESSOR;

		a->raw_string = malloc(t->len + 1);
		if (!a->raw_string)
			return NULL;

		strcpy(a->raw_string, t->name);
		skip_token(1);
		return a;
	}

	if (t->symbol == '#') {
		/* Preprocessor line and file change. */

		if ((t= get_token(1))->type != T_WORD || !isanumber(t->name)
			|| get_token(2)->type != T_STRING
		) {
			parse_err(1, t, "file not preprocessed?\n");
			zap();
		} else {
			set_file(get_token(2)->name,
				strtol(get_token(1)->name, nil, 0) - 1);

			/* GNU CPP adds extra cruft, simply zap the line. */
			zap();
		}
		a= gnu_get_instruction();
	} else
	if (t->type == T_WORD && get_token(1)->symbol == ':') {
		/* A label definition. */

		a= new_asm86();
		a->line= t->line;
		a->opcode= DOT_LABEL;
		a->optype= PSEUDO;
		a->args= e= new_expr();
		e->operator= ':';
		e->name= copystr(t->name);
		syms_add(t->name);
		skip_token(2);
	} else
	if (t->type == T_WORD && get_token(1)->symbol == '=') {
		int n= 2;

		if ((e= gnu_get_C_expression(&n)) == nil) {
			zap();
			a= gnu_get_instruction();
		} else
		if (get_token(n)->type != T_COMMENT && get_token(n)->symbol != ';') {
			parse_err(1, t, "garbage after assignment\n");
			zap();
			a= gnu_get_instruction();
		} else {
			a= new_asm86();
			if (get_token(n)->type == T_COMMENT) {
				token_t *c = get_token(n);

				a->raw_string = malloc(c->len + 1);
				if (!a->raw_string)
					return NULL;

				strcpy(a->raw_string, c->name);
			}
			a->line= t->line;
			a->opcode= DOT_EQU;
			a->optype= PSEUDO;
			a->args= new_expr();
			a->args->operator= '=';
			a->args->name= copystr(t->name);
			syms_add(t->name);
			a->args->middle= e;
			skip_token(n+1);
		}
	} else
	if (t->type == T_WORD) {
		if ((a= gnu_get_statement()) == nil) {
			zap();
			a= gnu_get_instruction();
		}
	} else {
		parse_err(1, t, "syntax error\n");
		zap();
		a= gnu_get_instruction();
	}
	return a;
}
Example #11
0
static asm86_t *gnu_get_statement(void)
/* Get a pseudo op or machine instruction with arguments. */
{
	token_t *t= get_token(0);
	token_t *tn;
	asm86_t *a;
	mnemonic_t *m;
	int n;
	int prefix_seen;
	int deref;

	assert(t->type == T_WORD);

	a= new_asm86();

	/* Process instruction prefixes. */
	for (prefix_seen= 0;; prefix_seen= 1) {
		if (strcmp(t->name, "rep") == 0
			|| strcmp(t->name, "repe") == 0
			|| strcmp(t->name, "repne") == 0
			|| strcmp(t->name, "repz") == 0
			|| strcmp(t->name, "repnz") == 0
		) {
			if (a->rep != ONCE) {
				parse_err(1, t,
					"can't have more than one rep\n");
			}
			switch (t->name[3]) {
			case 0:		a->rep= REP;	break;
			case 'e':
			case 'z':	a->rep= REPE;	break;
			case 'n':	a->rep= REPNE;	break;
			}
		} else
		if (!prefix_seen) {
			/* No prefix here, get out! */
			break;
		} else {
			/* No more prefixes, next must be an instruction. */
			if (t->type != T_WORD
				|| (m= search_mnem(t->name)) == nil
				|| m->optype == PSEUDO
			) {
				parse_err(1, t,
		"machine instruction expected after instruction prefix\n");
				del_asm86(a);
				return nil;
			}
			break;
		}

		/* Skip the prefix and extra newlines. */
		do {
			skip_token(1);
		} while ((t= get_token(0))->symbol == ';');
	}

	/* All the readahead being done upsets the line counter. */
	a->line= t->line;

	/* Read a machine instruction or pseudo op. */
	if ((m= search_mnem(t->name)) == nil) {
		/* we assume that unknown stuff is part of unresolved macro */
		a->opcode = UNKNOWN;
		if (zap_unknown(a)) {
			parse_err(1, t, "unknown instruction '%s'\n", t->name);
			del_asm86(a);
			return nil;
		}
		return a;
	}
	a->opcode= m->opcode;
	a->optype= m->optype;
	a->oaz= 0;
	if (a->optype == OWORD) {
		a->oaz|= OPZ;
		a->optype= WORD;
	}
	else if (a->optype == JUMP16) {
		a->oaz|= OPZ;
		a->optype= JUMP;
	}

	switch (a->opcode) {
	case IN:
	case OUT:
	case INT:
		deref= 0;
		break;
	default:
		deref= (a->optype >= BYTE);
	}
	n= 1;
	if (get_token(1)->type != T_COMMENT && get_token(1)->symbol != ';'
			&& (a->args= gnu_get_oplist(a, &n, deref)) == nil) {
		del_asm86(a);
		return nil;
	}
	tn = get_token(n);
	if (tn->type == T_COMMENT) {
		a->raw_string = malloc(tn->len + 1);
		if (!a->raw_string)
			return NULL;

		strcpy(a->raw_string, tn->name);
	} else
	if (get_token(n)->symbol != ';') {
		parse_err(1, t, "garbage at end of instruction\n");
		del_asm86(a);
		return nil;
	}
	if (!is_pseudo(a->opcode)) {
		/* GNU operand order is the other way around. */
		expression_t *e, *t;

		e= a->args;
		while (e != nil && e->operator == ',') {
			t= e->right; e->right= e->left; e->left= t;
			e= e->left;
		}
	}
	switch (a->opcode) {
	case DOT_ALIGN:
		/* Delete two argument .align, because ACK can't do it.
		 */
		if (a->args == nil || a->args->operator != 'W') {	
			del_asm86(a);
			return nil;
		}
		if (a->args != nil && a->args->operator == 'W'
			&& isanumber(a->args->name)
		) {	
			unsigned n;
			char num[sizeof(int) * CHAR_BIT / 3 + 1];

			n= strtoul(a->args->name, nil, 0);
			sprintf(num, "%u", n);
			deallocate(a->args->name);
			a->args->name= copystr(num);
		}
		break;
	case DOT_DEFINE:
	case DOT_EXTERN:
		syms_add_global_csl(a->args);
		break;
	case DOT_COMM:
		syms_add_global(a->args->left->name);
		break;
	case DOT_LCOMM:
		syms_add(a->args->left->name);
		break;
	case JMPF:
	case CALLF:
		/*FALL THROUGH*/
	case JMP:
	case CALL:
		break;
	default:;
	}
	skip_token(n+1);
	return a;
}