MCPcopy Create free account
hub / github.com/ZDoom/Raze / FStringFormat

Function FStringFormat

source/common/scripting/interface/stringformat.cpp:46–244  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

44
45
46FString FStringFormat(VM_ARGS, int offset)
47{
48 PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array
49 assert(va_reginfo[offset] == REGT_STRING);
50
51 FString fmtstring = param[offset].s().GetChars();
52
53 param += offset;
54 numparam -= offset;
55 va_reginfo += offset;
56
57 // note: we don't need a real printf format parser.
58 // enough to simply find the subtitution tokens and feed them to the real printf after checking types.
59 // https://en.wikipedia.org/wiki/Printf_format_string#Format_placeholder_specification
60 FString output;
61 bool in_fmt = false;
62 FString fmt_current;
63 int argnum = 1;
64 int argauto = 1;
65 // % = starts
66 // [0-9], -, +, \s, 0, #, . continue
67 // %, s, d, i, u, fF, eE, gG, xX, o, c, p, aA terminate
68 // various type flags are not supported. not like stuff like 'hh' modifier is to be used in the VM.
69 // the only combination that is parsed locally is %n$...
70 bool haveargnums = false;
71 for (size_t i = 0; i < fmtstring.Len(); i++)
72 {
73 char c = fmtstring[i];
74 if (in_fmt)
75 {
76 if (c == '*' && (fmt_current.Len() == 1 || (fmt_current.Len() == 2 && fmt_current[1] == '0')))
77 {
78 fmt_current += c;
79 }
80 else if ((c >= '0' && c <= '9') ||
81 c == '-' || c == '+' || (c == ' ' && fmt_current.Back() != ' ') || c == '#' || c == '.')
82 {
83 fmt_current += c;
84 }
85 else if (c == '$') // %number$format
86 {
87 if (!haveargnums && argauto > 1)
88 ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
89 FString argnumstr = fmt_current.Mid(1);
90 if (!argnumstr.IsInt()) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for argument number, got '%s'.", argnumstr.GetChars());
91 auto argnum64 = argnumstr.ToLong();
92 if (argnum64 < 1 || argnum64 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format (tried to access argument %d, %d total).", argnum64, numparam);
93 fmt_current = "%";
94 haveargnums = true;
95 argnum = int(argnum64);
96 }
97 else
98 {
99 fmt_current += c;
100
101 switch (c)
102 {
103 // string

Callers 3

DEFINE_ACTION_FUNCTIONFunction · 0.85
DEFINE_ACTION_FUNCTIONFunction · 0.85
DEFINE_ACTION_FUNCTIONFunction · 0.85

Calls 10

ThrowAbortExceptionFunction · 0.85
LenMethod · 0.80
MidMethod · 0.80
IsIntMethod · 0.80
ToLongMethod · 0.80
AppendFormatMethod · 0.80
GetCharsMethod · 0.45
BackMethod · 0.45
ToIntMethod · 0.45
ToDoubleMethod · 0.45

Tested by

no test coverage detected