void TBValue::SetFromStringAuto(const char *str, SET set) { if (!str) SetNull(); else if (is_number_only(str)) { if (is_number_float(str)) SetFloat((float)atof(str)); else SetInt(atoi(str)); } else if (is_start_of_number(str) && contains_non_trailing_space(str)) { // If the number has nontrailing space, we'll assume a list of numbers (example: "10 -4 3.5") SetNull(); if (TBValueArray *arr = new TBValueArray) { TBStr tmpstr; char *s3; if (tmpstr.Set(str)) { char * pch = strtok_r(tmpstr, ", ", &s3); while (pch) { if (TBValue *new_val = arr->AddValue()) new_val->SetFromStringAuto(pch, SET_NEW_COPY); pch = strtok_r(NULL, ", ", &s3); } } SetArray(arr, SET_TAKE_OWNERSHIP); } } else if (*str == '[') { SetNull(); if (TBValueArray *arr = new TBValueArray) { assert(!"not implemented! Split out the tokenizer code above!"); SetArray(arr, SET_TAKE_OWNERSHIP); } } else { SetString(str, set); return; } // We didn't set as string, so we might need to deal with the passed in string data. if (set == SET_TAKE_OWNERSHIP) { // Delete the passed in data TBValue tmp; tmp.SetString(str, SET_TAKE_OWNERSHIP); } }
void TBParser::ConsumeValue(TBValue &dst_value, char *&line) { // Find value (As quoted string, or as auto) char *value = line; if (*line == '\"' || *line == '\'') { const char quote_type = *line; // Consume starting quote line++; value++; // Find ending quote or end while (!IsEndQuote(value, line, quote_type) && *line != 0) line++; // Terminate away the quote if (*line == quote_type) *line++ = 0; // consume any whitespace while (is_white_space(line)) line++; // consume any comma if (*line == ',') line++; UnescapeString(value); dst_value.SetString(value, TBValue::SET_AS_STATIC); } else { // Find next comma or end while (*line != ',' && *line != 0) line++; // Terminate away the comma if (*line == ',') *line++ = 0; UnescapeString(value); dst_value.SetFromStringAuto(value, TBValue::SET_AS_STATIC); } // Check if we still have pending value data on the following line and set pending_multiline. bool continuing_multiline = pending_multiline; pending_multiline = is_pending_multiline(line); // Append the multi line value to the buffer. if (continuing_multiline || pending_multiline) multi_line_value.AppendString(dst_value.GetString()); }
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; } }