void TBParser::OnCompactLine(char *line, TBParserTarget *target) { target->Enter(); while (*line) { // consume any whitespace while (is_white_space(line)) line++; // Find token char *token = line; while (*line != ':' && *line != 0) line++; if (!*line) break; // Syntax error, expected token *line++ = 0; // consume any whitespace while (is_white_space(line)) line++; TBValue v; ConsumeValue(v, line); if (pending_multiline) { // The value wrapped to the next line, so we should remember the token and continue. multi_line_token.Set(token); // Since we need to call target->Leave when the multiline is ready, set multi_line_sub_level. multi_line_sub_level = 1; return; } // Ready target->OnToken(current_line_nr, token, v); } target->Leave(); }
void TBParser::OnMultiline(char *line, TBParserTarget *target) { // consume any whitespace while (is_white_space(line)) line++; TBValue value; ConsumeValue(value, line); if (!pending_multiline) { // Ready with all lines value.SetString(multi_line_value.GetData(), TBValue::SET_AS_STATIC); target->OnToken(current_line_nr, multi_line_token, value); if (multi_line_sub_level) target->Leave(); // Reset multi_line_value.SetAppendPos(0); multi_line_sub_level = 0; } }
/** Check if current item is a "value" tag with the given name and if so consumes that item and returns the value. Throws an exception if current item is not a value tag with the given name. \param[in] name Name of value tag to check for. \returns value of the value tag. \throws InternalErrorException if current item is not a value tag with the given name. */ std::wstring SCXFilePersistDataReader::ConsumeValue(const std::wstring& name) { std::wstring retval = L""; ConsumeValue(name, retval, true); return retval; }
void TBParser::OnLine(char *line, TBParserTarget *target) { if (is_space_or_comment(line)) { if (*line == '#') target->OnComment(current_line_nr, line + 1); return; } if (pending_multiline) { OnMultiline(line, target); return; } // Check indent int indent = 0; while (line[indent] == '\t' && line[indent] != 0) indent++; line += indent; if (indent - current_indent > 1) { target->OnError(current_line_nr, "Indentation error. (Line skipped)"); return; } if (indent > current_indent) { // FIX: Report indentation error if more than 1 higher! assert(indent - current_indent == 1); target->Enter(); current_indent++; } else if (indent < current_indent) { while (indent < current_indent) { target->Leave(); current_indent--; } } if (*line == 0) return; else { char *token = line; // Read line while consuming it and copy over to token buf while (!is_white_space(line) && *line != 0) line++; int token_len = line - token; // Consume any white space after the token while (is_white_space(line)) line++; bool is_compact_line = token_len && token[token_len - 1] == ':'; TBValue value; if (is_compact_line) { token_len--; token[token_len] = 0; // Check if the first argument is not a child but the value for this token if (*line == '[' || *line == '\"' || *line == '\'' || is_start_of_number(line) || is_start_of_color(line) || is_start_of_reference(line)) { ConsumeValue(value, line); if (pending_multiline) { // The value wrapped to the next line, so we should remember the token and continue. multi_line_token.Set(token); return; } } } else if (token[token_len]) { token[token_len] = 0; UnescapeString(line); value.SetFromStringAuto(line, TBValue::SET_AS_STATIC); } target->OnToken(current_line_nr, token, value); if (is_compact_line) OnCompactLine(line, target); } }