static void Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const struct token *t_port) { const char *ipv4, *ipv4a, *ipv6, *ipv6a, *pa; char buf[256]; AN(t_host->dec); if (t_port != NULL) bprintf(buf, "%s %s", t_host->dec, t_port->dec); else bprintf(buf, "%s", t_host->dec); Resolve_Sockaddr(tl, buf, "80", &ipv4, &ipv4a, &ipv6, &ipv6a, &pa, 2, t_host, "Backend host"); ERRCHK(tl); if (ipv4 != NULL) { Fb(tl, 0, "\t.ipv4_suckaddr = (const struct suckaddr *)%s,\n", ipv4); Fb(tl, 0, "\t.ipv4_addr = \"%s\",\n", ipv4a); } if (ipv6 != NULL) { Fb(tl, 0, "\t.ipv6_suckaddr = (const struct suckaddr *)%s,\n", ipv6); Fb(tl, 0, "\t.ipv6_addr = \"%s\",\n", ipv6a); } Fb(tl, 0, "\t.port = \"%s\",\n", pa); Fb(tl, 0, "\t.path = (void *) 0,\n"); }
static void vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) { struct expr *e1, *e2; const char *ip; const struct symbol *sym; double d; *e = NULL; if (tl->t->tok == '(') { SkipToken(tl, '('); vcc_expr0(tl, &e2, fmt); ERRCHK(tl); SkipToken(tl, ')'); *e = vcc_expr_edit(e2->fmt, "(\v1)", e2, NULL); return; } switch(tl->t->tok) { case ID: /* * XXX: what if var and func/proc had same name ? * XXX: look for SYM_VAR first for consistency ? */ sym = VCC_FindSymbol(tl, tl->t, SYM_NONE); if (sym == NULL || sym->eval == NULL) { VSB_printf(tl->sb, "Symbol not found: "); vcc_ErrToken(tl, tl->t); VSB_printf(tl->sb, " (expected type %s):\n", vcc_Type(fmt)); vcc_ErrWhere(tl, tl->t); return; } AN(sym); switch(sym->kind) { case SYM_VAR: case SYM_FUNC: case SYM_BACKEND: AN(sym->eval); AZ(*e); sym->eval(tl, e, sym); return; default: break; } VSB_printf(tl->sb, "Symbol type (%s) can not be used in expression.\n", VCC_SymKind(tl, sym)); vcc_ErrWhere(tl, tl->t); return; case CSTR: assert(fmt != VOID); if (fmt == IP) { Resolve_Sockaddr(tl, tl->t->dec, "80", &ip, NULL, &ip, NULL, NULL, 1, tl->t, "IP constant"); ERRCHK(tl); e1 = vcc_mk_expr(IP, "%s", ip); ERRCHK(tl); } else { e1 = vcc_new_expr(); EncToken(e1->vsb, tl->t); e1->fmt = STRING; AZ(VSB_finish(e1->vsb)); } e1->t1 = tl->t; e1->constant = EXPR_CONST; vcc_NextToken(tl); *e = e1; break; case CNUM: /* * XXX: %g may not have enough decimals by default * XXX: but %a is ugly, isn't it ? */ assert(fmt != VOID); if (fmt == DURATION) { vcc_Duration(tl, &d); ERRCHK(tl); e1 = vcc_mk_expr(DURATION, "%g", d); } else if (fmt == BYTES) { vcc_ByteVal(tl, &d); ERRCHK(tl); e1 = vcc_mk_expr(BYTES, "%.1f", d); ERRCHK(tl); } else if (fmt == REAL) { e1 = vcc_mk_expr(REAL, "%g", vcc_DoubleVal(tl)); ERRCHK(tl); } else { e1 = vcc_mk_expr(INT, "%.*s", PF(tl->t)); vcc_NextToken(tl); } e1->constant = EXPR_CONST; *e = e1; break; default: VSB_printf(tl->sb, "Unknown token "); vcc_ErrToken(tl, tl->t); VSB_printf(tl->sb, " when looking for %s\n\n", vcc_Type(fmt)); vcc_ErrWhere(tl, tl->t); break; } }