mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use std::variant for STRFMT arguments
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user