[util] Auto-cast plist string items

The casting uses a recursive call to the expression parser, so the
expressions are type-checked automatically.
This commit is contained in:
Bill Currie 2021-02-04 22:37:20 +09:00
parent a54de63fee
commit e929dca300
4 changed files with 35 additions and 1 deletions

View file

@ -118,6 +118,9 @@ void cexpr_struct_pointer_getfield (const exprval_t *a, const exprval_t *b,
exprval_t *cexpr_cvar (const char *name, exprctx_t *ctx);
exprval_t *cexpr_cvar_struct (exprctx_t *ctx);
void cexpr_cast_plitem (const exprval_t *val1, const exprval_t *src,
exprval_t *result, exprctx_t *ctx);
void cexpr_init_symtab (exprtab_t *symtab, exprctx_t *ctx);
char *cexpr_yyget_text (void *scanner);

View file

@ -100,6 +100,7 @@ binop_t int_binops[] = {
{ '^', &cexpr_int, &cexpr_int, int_xor },
{ '%', &cexpr_int, &cexpr_int, int_rem },
{ MOD, &cexpr_int, &cexpr_int, int_mod },
{ '=', &cexpr_plitem, &cexpr_int, cexpr_cast_plitem },
{}
};
@ -154,6 +155,7 @@ binop_t uint_binops[] = {
{ '%', &cexpr_uint, &cexpr_uint, uint_rem },
{ MOD, &cexpr_uint, &cexpr_uint, uint_rem },
{ '=', &cexpr_int, &cexpr_uint, uint_cast_int },
{ '=', &cexpr_plitem, &cexpr_uint, cexpr_cast_plitem },
{}
};
@ -222,6 +224,7 @@ binop_t size_t_binops[] = {
{ MOD, &cexpr_size_t, &cexpr_size_t, size_t_rem },
{ '=', &cexpr_int, &cexpr_size_t, size_t_cast_int },
{ '=', &cexpr_uint, &cexpr_size_t, size_t_cast_uint },
{ '=', &cexpr_plitem, &cexpr_size_t, cexpr_cast_plitem },
{}
};
@ -310,6 +313,7 @@ binop_t float_binops[] = {
{ '%', &cexpr_float, &cexpr_float, float_rem },
{ MOD, &cexpr_float, &cexpr_float, float_mod },
{ '=', &cexpr_int, &cexpr_float, float_cast_int },
{ '=', &cexpr_plitem, &cexpr_float, cexpr_cast_plitem },
{}
};
@ -366,6 +370,7 @@ binop_t double_binops[] = {
{ '/', &cexpr_double, &cexpr_double, double_div },
{ '%', &cexpr_double, &cexpr_double, double_rem },
{ MOD, &cexpr_double, &cexpr_double, double_mod },
{ '=', &cexpr_plitem, &cexpr_double, cexpr_cast_plitem },
{}
};
@ -595,6 +600,26 @@ exprtype_t cexpr_function = {
0,
};
void
cexpr_cast_plitem (const exprval_t *val1, const exprval_t *src,
exprval_t *result, exprctx_t *ctx)
{
plitem_t *item = *(plitem_t **) src->value;
const char *str = PL_String (item);
if (!str) {
cexpr_error (ctx, "not a string object: %d", PL_Line (item));
return;
}
exprctx_t ectx = *ctx;
ectx.result = result;
cexpr_eval_string (str, &ectx);
ctx->errors += ectx.errors;
if (ectx.errors) {
cexpr_error (ctx, "could not convert: %d", PL_Line (item));
}
}
static void
plitem_field (const exprval_t *a, const exprval_t *b, exprval_t *c,
exprctx_t *ctx)

View file

@ -79,7 +79,7 @@ skip_value(string name)
fprintf (output_file, "\tflag_binops,\n");
fprintf (output_file, "\tflag_unops,\n");
} else {
fprintf (output_file, "\t0,\n");
fprintf (output_file, "\tenum_binops,\n");
fprintf (output_file, "\t0,\n");
}
fprintf (output_file, "};\n");

View file

@ -103,6 +103,12 @@ binop_t flag_binops[] = {
{ '|', 0, 0, flag_or },
{ '&', 0, 0, flag_and },
{ '=', &cexpr_int, 0, flag_cast_int },
{ '=', &cexpr_plitem, 0, cexpr_cast_plitem },
{}
};
binop_t enum_binops[] = {
{ '=', &cexpr_plitem, 0, cexpr_cast_plitem },
{}
};