Example #1
0
static void
vcc_expr_string_add(struct vcc *tl, struct expr **e)
{
	struct expr  *e2;
	enum var_type f2;

	f2 = (*e)->fmt;

	while (tl->t->tok == '+') {
		vcc_NextToken(tl);
		vcc_expr_mul(tl, &e2, STRING);
		ERRCHK(tl);
		if (e2->fmt != STRING && e2->fmt != STRING_LIST) {
			vcc_expr_tostring(tl, &e2, f2);
			ERRCHK(tl);
		}
		ERRCHK(tl);
		assert(e2->fmt == STRING || e2->fmt == STRING_LIST);

		if (vcc_isconst(*e) && vcc_isconst(e2)) {
			assert((*e)->fmt == STRING);
			assert(e2->fmt == STRING);
			*e = vcc_expr_edit(STRING, "\v1\n\v2", *e, e2);
			(*e)->constant = EXPR_CONST;
		} else if (((*e)->constant & EXPR_STR_CONST) &&
		    vcc_isconst(e2)) {
			assert((*e)->fmt == STRING_LIST);
			assert(e2->fmt == STRING);
			*e = vcc_expr_edit(STRING_LIST, "\v1\n\v2", *e, e2);
			(*e)->constant = EXPR_VAR | EXPR_STR_CONST;
		} else if (e2->fmt == STRING && vcc_isconst(e2)) {
			*e = vcc_expr_edit(STRING_LIST, "\v1,\n\v2", *e, e2);
			(*e)->constant = EXPR_VAR | EXPR_STR_CONST;
		} else {
			*e = vcc_expr_edit(STRING_LIST, "\v1,\n\v2", *e, e2);
			(*e)->constant = EXPR_VAR;
		}
	}
}
Example #2
0
static void
vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
{
	struct expr  *e2;
	enum var_type f2;
	struct token *tk;

	*e = NULL;
	vcc_expr_mul(tl, e, fmt);
	ERRCHK(tl);
	f2 = (*e)->fmt;

	if ((f2 == STRING_LIST || f2 == STRING) && tl->t->tok == '+') {
		while (tl->t->tok == '+') {
			vcc_NextToken(tl);
			vcc_expr_mul(tl, &e2, STRING);
			ERRCHK(tl);
			if (e2->fmt != STRING && e2->fmt != STRING_LIST)
				vcc_expr_tostring(&e2, f2);
			ERRCHK(tl);
			assert(e2->fmt == STRING || e2->fmt == STRING_LIST);
			if ((*e)->constant &&  e2->constant) {
				assert((*e)->fmt == STRING);
				assert(e2->fmt == STRING);
				*e = vcc_expr_edit(STRING, "\v1\n\v2", *e, e2);
			} else {
				*e = vcc_expr_edit(STRING_LIST,
				    "\v1,\n\v2", *e, e2);
			}
		}
	}
	if (fmt != STRING_LIST && (*e)->fmt == STRING_LIST)
		*e = vcc_expr_edit(STRING,
		    "\v+VRT_WrkString(sp,\n\v1,\nvrt_magic_string_end)",
		    *e, NULL);
	if (fmt == STRING_LIST && (*e)->fmt == STRING)
		(*e)->fmt = STRING_LIST;

	switch(f2) {
	case INT:	break;
	case TIME:	break;
	case DURATION:	break;
	case BYTES:	break;
	default:
		if (tl->t->tok != '+' && tl->t->tok != '-')
			return;
		VSB_printf(tl->sb, "Operator %.*s not possible on type %s.\n",
		    PF(tl->t), vcc_Type(f2));
		vcc_ErrWhere(tl, tl->t);
		return;
	}

	while (tl->t->tok == '+' || tl->t->tok == '-') {
		if (f2 == TIME)
			f2 = DURATION;
		tk = tl->t;
		vcc_NextToken(tl);
		vcc_expr_mul(tl, &e2, f2);
		ERRCHK(tl);
		if (tk->tok == '-' && (*e)->fmt == TIME && e2->fmt == TIME) {
			/* OK */
		} else if (tk->tok == '-' &&
		    (*e)->fmt == BYTES && e2->fmt == BYTES) {
			/* OK */
		} else if (e2->fmt != f2) {
			VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
			    vcc_Type((*e)->fmt), PF(tk), vcc_Type(e2->fmt));
			vcc_ErrWhere2(tl, tk, tl->t);
			return;
		}
		if (tk->tok == '+')
			*e = vcc_expr_edit(f2, "(\v1+\v2)", *e, e2);
		else if (f2 == TIME && e2->fmt == TIME)
			*e = vcc_expr_edit(DURATION, "(\v1-\v2)", *e, e2);
		else
			*e = vcc_expr_edit(f2, "(\v1-\v2)", *e, e2);
	}
}
Example #3
0
static void
vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
{
	struct expr  *e2;
	enum var_type f2;
	struct token *tk;

	*e = NULL;
	vcc_expr_mul(tl, e, fmt);
	ERRCHK(tl);
	f2 = (*e)->fmt;

	/* Unless we specifically ask for a HEADER, fold them to string here */
	if (fmt != HEADER && f2 == HEADER) {
		vcc_expr_tostring(tl, e, STRING);
		ERRCHK(tl);
		f2 = (*e)->fmt;
		assert(f2 == STRING);
	}

	if (tl->t->tok != '+' && tl->t->tok != '-')
		return;

	switch(f2) {
	case STRING:
	case STRING_LIST:
		vcc_expr_string_add(tl, e);
		return;
	case INT:		break;
	case TIME:		break;
	case DURATION:		break;
	case BYTES:		break;
	default:
		VSB_printf(tl->sb, "Operator %.*s not possible on type %s.\n",
		    PF(tl->t), vcc_Type(f2));
		vcc_ErrWhere(tl, tl->t);
		return;
	}

	while (tl->t->tok == '+' || tl->t->tok == '-') {
		if (f2 == TIME)
			f2 = DURATION;
		tk = tl->t;
		vcc_NextToken(tl);
		vcc_expr_mul(tl, &e2, f2);
		ERRCHK(tl);
		if (tk->tok == '-' && (*e)->fmt == TIME && e2->fmt == TIME) {
			/* OK */
		} else if ((*e)->fmt == TIME && e2->fmt == DURATION) {
			f2 = TIME;
			/* OK */
		} else if (tk->tok == '-' &&
		    (*e)->fmt == BYTES && e2->fmt == BYTES) {
			/* OK */
		} else if (e2->fmt != f2) {
			VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
			    vcc_Type((*e)->fmt), PF(tk), vcc_Type(e2->fmt));
			vcc_ErrWhere2(tl, tk, tl->t);
			return;
		}
		if (tk->tok == '+')
			*e = vcc_expr_edit(f2, "(\v1+\v2)", *e, e2);
		else if (f2 == TIME && e2->fmt == TIME)
			*e = vcc_expr_edit(DURATION, "(\v1-\v2)", *e, e2);
		else
			*e = vcc_expr_edit(f2, "(\v1-\v2)", *e, e2);
	}
}