| 39 | } |
| 40 | |
| 41 | void CFGParser::Parse(){ |
| 42 | if(!cfgFile || !cfgData.size()) return; |
| 43 | |
| 44 | int state = ParserStateName; |
| 45 | |
| 46 | std::string headingName; |
| 47 | std::string name; |
| 48 | std::string value; |
| 49 | |
| 50 | std::vector<CFGItem> values; |
| 51 | for(auto it = cfgData.begin(); it != cfgData.end(); it++){ |
| 52 | char c = *it; |
| 53 | switch(c){ |
| 54 | case '=': |
| 55 | if(state == ParserStateName){ |
| 56 | state = ParserStateValue; |
| 57 | break; |
| 58 | } else { |
| 59 | value += c; |
| 60 | break; |
| 61 | } |
| 62 | case '#': |
| 63 | while(it != cfgData.end() && (c = *it++) != '\n'); |
| 64 | [[fallthrough]]; |
| 65 | case '\n': |
| 66 | if(state == ParserStateValue){ |
| 67 | CFGItem item; |
| 68 | |
| 69 | item.name = name; |
| 70 | item.value = value; |
| 71 | |
| 72 | // Trim whitespaces, tabs and carriage returns |
| 73 | item.name.erase(0, name.find_first_not_of(" \t\r")); |
| 74 | item.name.erase(name.find_last_not_of(" \t\r") + 1); |
| 75 | item.value.erase(0, value.find_first_not_of(" \t\r")); |
| 76 | item.value.erase(value.find_last_not_of(" \t\r") + 1); |
| 77 | |
| 78 | values.push_back(item); |
| 79 | } else if(state == ParserStateName) { |
| 80 | if(!name.length()){ |
| 81 | break; // Empty line? |
| 82 | } |
| 83 | |
| 84 | CFGItem item; |
| 85 | item.name = ""; |
| 86 | item.value = name; |
| 87 | } else if(state == ParserStateHeading){ |
| 88 | printf("CFGParser: Potentially malformed heading [%s\n", headingName.c_str()); |
| 89 | headingName.clear(); |
| 90 | } |
| 91 | |
| 92 | name.clear(); |
| 93 | value.clear(); |
| 94 | |
| 95 | state = ParserStateName; |
| 96 | break; |
| 97 | case ']': |
| 98 | case '[': |