Use std::variant for STRFMT arguments

This commit is contained in:
Rangi42
2024-02-27 23:20:06 -05:00
committed by Sylvie
parent beb1997378
commit 7daa8759c9
2 changed files with 15 additions and 26 deletions

View File

@@ -4,6 +4,7 @@
#define RGBDS_FORMAT_SPEC_H #define RGBDS_FORMAT_SPEC_H
#include <stdint.h> #include <stdint.h>
#include <variant>
#include <vector> #include <vector>
enum FormatState { enum FormatState {
@@ -29,17 +30,9 @@ struct FormatSpec {
bool valid; bool valid;
}; };
struct StrFmtArg {
union {
uint32_t number;
char *string;
};
bool isNumeric;
};
struct StrFmtArgList { struct StrFmtArgList {
char *format; char *format;
std::vector<struct StrFmtArg> *args; std::vector<std::variant<uint32_t, char *>> *args;
}; };
struct FormatSpec fmt_NewSpec(void); struct FormatSpec fmt_NewSpec(void);

View File

@@ -257,7 +257,7 @@ static void strrpl(char *dest, size_t destLen, char const *src, char const *old,
static void initStrFmtArgList(struct StrFmtArgList *args) static void initStrFmtArgList(struct StrFmtArgList *args)
{ {
args->args = new(std::nothrow) std::vector<struct StrFmtArg>(); args->args = new(std::nothrow) std::vector<std::variant<uint32_t, char *>>();
if (!args->args) if (!args->args)
fatalerror("Failed to allocate memory for STRFMT arg list: %s\n", fatalerror("Failed to allocate memory for STRFMT arg list: %s\n",
strerror(errno)); strerror(errno));
@@ -266,13 +266,15 @@ static void initStrFmtArgList(struct StrFmtArgList *args)
static void freeStrFmtArgList(struct StrFmtArgList *args) static void freeStrFmtArgList(struct StrFmtArgList *args)
{ {
free(args->format); free(args->format);
for (struct StrFmtArg &arg : *args->args) for (std::variant<uint32_t, char *> &arg : *args->args) {
if (!arg.isNumeric) if (char **str = std::get_if<char *>(&arg); str)
free(arg.string); free(*str);
}
delete args->args; delete args->args;
} }
static void strfmt(char *dest, size_t destLen, char const *fmt, std::vector<struct StrFmtArg> &args) static void strfmt(char *dest, size_t destLen, char const *fmt,
std::vector<std::variant<uint32_t, char *>> &args)
{ {
size_t a = 0; size_t a = 0;
size_t i = 0; size_t i = 0;
@@ -319,13 +321,13 @@ static void strfmt(char *dest, size_t destLen, char const *fmt, std::vector<stru
continue; continue;
} }
struct StrFmtArg &arg = args[a++]; std::variant<uint32_t, char *> &arg = args[a++];
static char buf[MAXSTRLEN + 1]; static char buf[MAXSTRLEN + 1];
if (arg.isNumeric) if (std::holds_alternative<uint32_t>(arg))
fmt_PrintNumber(buf, sizeof(buf), &spec, arg.number); fmt_PrintNumber(buf, sizeof(buf), &spec, std::get<uint32_t>(arg));
else else
fmt_PrintString(buf, sizeof(buf), &spec, arg.string); fmt_PrintString(buf, sizeof(buf), &spec, std::get<char *>(arg));
i += snprintf(&dest[i], destLen - i, "%s", buf); i += snprintf(&dest[i], destLen - i, "%s", buf);
} }
@@ -1682,17 +1684,11 @@ strfmt_va_args : %empty {
initStrFmtArgList(&$$); initStrFmtArgList(&$$);
} }
| strfmt_va_args T_COMMA const_no_str { | strfmt_va_args T_COMMA const_no_str {
struct StrFmtArg &arg = $1.args->emplace_back(); $1.args->push_back((uint32_t)$3);
arg.number = $3;
arg.isNumeric = true;
$$ = $1; $$ = $1;
} }
| strfmt_va_args T_COMMA string { | strfmt_va_args T_COMMA string {
struct StrFmtArg &arg = $1.args->emplace_back(); $1.args->push_back(strdup($3));
arg.string = strdup($3);
arg.isNumeric = false;
$$ = $1; $$ = $1;
} }
; ;