bool AbstractParser::parseField(StringView words) { #define PARSE_FIELD(X) \ for (const auto x : DEFINED_ROOM_##X##_TYPES) { \ if (getParserCommandName(x).matches(firstWord)) { \ setRoomFieldCommand(x, RoomField::X##_TYPE); \ return true; \ } \ } if (words.isEmpty()) return false; // REVISIT: support "set room field XXX" ? const auto firstWord = words.takeFirstWord(); if (!words.isEmpty()) return false; PARSE_FIELD(LIGHT); PARSE_FIELD(SUNDEATH); PARSE_FIELD(PORTABLE); PARSE_FIELD(RIDABLE); PARSE_FIELD(ALIGN); return false; #undef PARSE }
static char* parse(ag_t *ag, char *buf, int sz) { char *c; char *plugin_start = NULL, *plugin_inst_start = NULL, *type_inst_start = NULL, *val_start = NULL; char *parsed = NULL; int str_len; char plugin[MAX_STR_SIZE]; char plugin_inst[MAX_STR_SIZE]; char type_inst[MAX_STR_SIZE]; double vals[MAX_VALS]; int n_vals = 0; state_t state = AG_START; for (c = buf; c < buf+sz; c++) { switch (state) { case AG_START: plugin_start = c; state = AG_PLUGIN; break; case AG_PLUGIN: PARSE_FIELD(plugin_start, plugin, plugin_inst_start, AG_PLUGIN_INST); break; case AG_PLUGIN_INST: PARSE_FIELD(plugin_inst_start, plugin_inst, type_inst_start, AG_TYPE_INST); break; case AG_TYPE_INST: PARSE_FIELD(type_inst_start, type_inst, val_start, AG_VALUES); break; case AG_VALUES: switch (*c) { case ':': if (n_vals < MAX_VALS) { vals[n_vals++] = strtod(val_start, NULL); } else { WARNING("aggregator plugin: more than 64 values " "in this packet. Dropping the extra."); } val_start = c+1; break; case '\n': if (n_vals < MAX_VALS) { vals[n_vals++] = strtod(val_start, NULL); } else { WARNING("aggregator plugin: more than 64 values " "in this packet. Dropping the extra."); } /* read a complete line, process these values */ handle_vals(ag, plugin, plugin_inst, type_inst, vals, n_vals); /* reset everything */ state = AG_START; parsed = c+1; n_vals = 0; break; } break; } } return parsed; }