MCPcopy Create free account
hub / github.com/HailToDodongo/pyrite64 / parseDataStruct

Method parseDataStruct

src/utils/codeParser.cpp:112–184  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

110}
111
112Utils::CPP::Struct Utils::CPP::parseDataStruct(const std::string &sourceCode, const std::string &structName)
113{
114 // remove line and multi-line comments
115 auto code = std::regex_replace(sourceCode, std::regex(R"(//[^\n]*)"), "");
116 code = std::regex_replace(code, std::regex(R"(/\*[\s\S]*?\*/)"), "");
117
118 std::vector<Struct> structs{};
119
120 // match all structs to get the body of it
121 std::regex structRegex(R"(P64_DATA\(([\s\S]*?)\);)");
122
123 std::smatch structMatch;
124 auto structBegin = code.cbegin();
125
126 while (std::regex_search(structBegin, code.cend(), structMatch, structRegex))
127 {
128 Struct s{.name = "Data"};
129 if (s.name != structName)continue;
130
131 std::string body = structMatch[1];
132
133 // Regex for attributes + field lines
134 std::regex fieldRegex(
135 R"((\[\[\s*([^\]]+)\s*\]\]\s*)?([\w:<>]+)\s+(\w+)(\[[0-9]+\])?(?:\s*\=(.*))?\s*;)"
136 );
137
138 std::smatch fieldMatch;
139 auto fieldBegin = body.cbegin();
140
141 while (std::regex_search(fieldBegin, body.cend(), fieldMatch, fieldRegex))
142 {
143 Field field{
144 .type = fromString(fieldMatch[3]),
145 .dataSize = getTypeSize(fromString(fieldMatch[3])),
146 .name = fieldMatch[4],
147 .attr = parseAttributes(fieldMatch[2]),
148 .defaultValue = fieldMatch[6],
149 };
150
151 // Pre-parse the bitmask attribute for unsigned int fields, so the editor doesn't re-parse each frame.
152 if (field.type == DataType::u8 || field.type == DataType::u16 || field.type == DataType::u32) {
153 auto bitmaskAttr = field.attr.find("P64::Bitmask");
154 if (bitmaskAttr != field.attr.end()) {
155 field.bitmask = parseBitmask(bitmaskAttr->second);
156 }
157 }
158
159 if(field.type == DataType::string) {
160 try
161 {
162 auto strSize = fieldMatch[5].str(); // -> [42]
163 field.dataSize = std::stoul(strSize.substr(1, strSize.size() - 2)); // parse without brackets
164 } catch(...) {
165 Logger::log(
166 "Failed to parse size for string field: " + field.name + ", defaulting to 4 bytes.",
167 Logger::LEVEL_ERROR
168 );
169 field.dataSize = 4;

Callers

nothing calls this directly

Calls 7

fromStringFunction · 0.85
getTypeSizeFunction · 0.85
parseAttributesFunction · 0.85
parseBitmaskFunction · 0.85
logFunction · 0.85
endMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected