From 8e25fb13d15b9b63ea73093cf292b6b455a941ad Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 18 Jun 2023 17:20:38 +0900 Subject: [PATCH] [cexpr] Add string and voidptr types The string type is useful for passing around strings (the only thing that they can do, currently), particularly as arguments to functions. The voidptr type is (currently) never generated by the core cexpr system, but is useful for storing pointers via cexpr (probably a bit of a hack, but it seems to work well in my current use). --- include/QF/cexpr.h | 3 +++ libs/util/cexpr-lex.l | 16 ++++++++++++++++ libs/util/cexpr-type.c | 10 ++++++++++ 3 files changed, 29 insertions(+) diff --git a/include/QF/cexpr.h b/include/QF/cexpr.h index 5935e37bb..b035275c7 100644 --- a/include/QF/cexpr.h +++ b/include/QF/cexpr.h @@ -151,6 +151,9 @@ extern exprtype_t cexpr_exprval; extern exprtype_t cexpr_field; extern exprtype_t cexpr_function; extern exprtype_t cexpr_plitem; +extern exprtype_t cexpr_string; +// generic pointer holder, never generated directly by cexpr +extern exprtype_t cexpr_voidptr; extern binop_t cexpr_array_binops[]; extern binop_t cexpr_struct_binops[]; diff --git a/libs/util/cexpr-lex.l b/libs/util/cexpr-lex.l index 88dced412..ef91d414d 100644 --- a/libs/util/cexpr-lex.l +++ b/libs/util/cexpr-lex.l @@ -76,6 +76,7 @@ static exprval_t *parse_uint (const char *str, exprctx_t *context); static exprval_t *parse_size_t (const char *str, exprctx_t *context); static exprval_t *parse_float (const char *str, exprctx_t *context); static exprval_t *parse_double (const char *str, exprctx_t *context); +static exprval_t *parse_string (const char *str, exprctx_t *context); static exprsym_t *parse_name (const char *str, exprctx_t *context); static exprval_t *parse_variable (const char *str, exprctx_t *context); @@ -174,6 +175,8 @@ STRING \"(\\.|[^"\\])*\" } {STRING} { + yylval->value = parse_string (yytext, context); + return VALUE; } @ return '@'; @@ -292,6 +295,19 @@ static exprval_t *parse_double (const char *str, exprctx_t *context) return val; } +static exprval_t *parse_string (const char *str, exprctx_t *context) +{ + exprval_t *val = cexpr_value (&cexpr_string, context); + // str includes the quotes, which add 2 to the length of the string, but + // only one byte is needed for the terminating nul + size_t size = strlen (str) - 1; + char *dup = cmemalloc (context->memsuper, size); + strncpy (dup, str + 1, size - 1); + dup[size - 1] = 0; + *(char **) val->value = dup; + return val; +} + static exprsym_t * parse_name (const char *name, exprctx_t *context) { diff --git a/libs/util/cexpr-type.c b/libs/util/cexpr-type.c index 369195d05..656a36da7 100644 --- a/libs/util/cexpr-type.c +++ b/libs/util/cexpr-type.c @@ -774,6 +774,16 @@ exprtype_t cexpr_plitem = { .unops = 0, }; +exprtype_t cexpr_string = { + .name = "string", + .size = sizeof (char *), +}; + +exprtype_t cexpr_voidptr = { + .name = "voidptr", + .size = sizeof (void *), +}; + VISIBLE binop_t * cexpr_find_cast (exprtype_t *dst_type, exprtype_t *src_type) {