| 1091 | typedef RString (*OnValueFunction)(RString name, const EditorParams& params, void* context); |
| 1092 | typedef RString (*OnExpressionFunction)(RString name, const EditorParams& params, void* context); |
| 1093 | |
| 1094 | static RString ParseLine(RString format, const EditorParams& params, OnRequiredFunction onRequired, |
| 1095 | OnValueFunction onValue, OnExpressionFunction onExpression, void* context) |
| 1096 | { |
| 1097 | static const int len = 1024; |
| 1098 | char dst[len]; |
| 1099 | int i = 0; |
| 1100 | for (const char* ptr = format; *ptr; ptr++) |
| 1101 | { |
| 1102 | if (*ptr == '%') |
| 1103 | { |
| 1104 | ptr++; |
| 1105 | if (!*ptr) |
| 1106 | { |
| 1107 | Fail("Syntax error"); |
| 1108 | break; |
| 1109 | } |
| 1110 | else if (*ptr == '%') |
| 1111 | { |
| 1112 | dst[i++] = *ptr; |
| 1113 | if (i >= len - 1) |
| 1114 | { |
| 1115 | Fail("Buffer overflow"); |
| 1116 | break; |
| 1117 | } |
| 1118 | } |
| 1119 | else if (*ptr == '!') |
| 1120 | { |
| 1121 | onRequired(context); |
| 1122 | } |
| 1123 | else if (*ptr == '(') |
| 1124 | { |
| 1125 | ptr++; |
| 1126 | const char* begin = ptr; |
| 1127 | while (*ptr && *ptr != ')') |
| 1128 | ptr++; |
| 1129 | RString name(begin, ptr - begin); |
| 1130 | if (!*ptr) |
| 1131 | ptr--; |
| 1132 | |
| 1133 | // expression |
| 1134 | RString value = onExpression(name, params, context); |
| 1135 | int n = value.GetLength(); |
| 1136 | if (i + n >= len - 1) |
| 1137 | { |
| 1138 | Fail("Buffer overflow"); |
| 1139 | break; |
| 1140 | } |
| 1141 | strcpy(dst + i, value); |
| 1142 | i += n; |
| 1143 | } |
| 1144 | else |
| 1145 | { |
| 1146 | const char* begin = ptr; |
| 1147 | while (*ptr && __iscsym(*ptr)) |
| 1148 | ptr++; |
| 1149 | RString name(begin, ptr - begin); |
| 1150 | ptr--; |
no test coverage detected