static enum ParserResult parsePipeline(struct Parser* parser, struct Pipeline* pipeline) { pipeline->commands = NULL; pipeline->numCommands = 0; pipeline->bang = false; enum ParserResult result; struct Token* token = getToken(parser); if (!token) return PARSER_SYNTAX; while (token->type == TOKEN && strcmp(token->text, "!") == 0) { pipeline->bang = !pipeline->bang; parser->offset++; token = getToken(parser); if (!token) return PARSER_SYNTAX; } while (true) { struct SimpleCommand command; result = parseSimpleCommand(parser, &command); if (result != PARSER_MATCH) goto fail; if (!addToArray((void**) &pipeline->commands, &pipeline->numCommands, &command, sizeof(command))) { result = PARSER_ERROR; goto fail; } token = getToken(parser); if (!token) return PARSER_MATCH; if (token->type != OPERATOR || strcmp(token->text, "|") != 0) { return PARSER_MATCH; } parser->offset++; token = getToken(parser); if (!token) { result = PARSER_SYNTAX; goto fail; } while (token->type == OPERATOR && strcmp(token->text, "\n") == 0) { parser->offset++; token = getToken(parser); if (!token) { result = PARSER_NEWLINE; goto fail; } } } return PARSER_MATCH; fail: freePipeline(pipeline); return result; }
bool AbstractParser::parseUserCommands(const QString &input) { if (tryParseGenericDoorCommand(input)) return false; if (input.startsWith(prefixChar)) { auto view = StringView{input}.trim(); if (view.isEmpty() || view.takeFirstLetter() != prefixChar) sendToUser("Internal error. Sorry.\r\n"); else parseSpecialCommand(view); sendPromptToUser(); return false; } return parseSimpleCommand(input); }