| 674 | namespace values { |
| 675 | |
| 676 | Try<Value> parse(const string& text) |
| 677 | { |
| 678 | Value value; |
| 679 | |
| 680 | // Remove all spaces. |
| 681 | string temp = strings::replace(text, " ", ""); |
| 682 | |
| 683 | if (temp.length() == 0) { |
| 684 | return Error("Expecting non-empty string"); |
| 685 | } |
| 686 | |
| 687 | // TODO(ynie): Find a better way to check brackets. |
| 688 | if (!strings::checkBracketsMatching(temp, '{', '}') || |
| 689 | !strings::checkBracketsMatching(temp, '[', ']') || |
| 690 | !strings::checkBracketsMatching(temp, '(', ')')) { |
| 691 | return Error("Mismatched brackets"); |
| 692 | } |
| 693 | |
| 694 | size_t index = temp.find('['); |
| 695 | if (index == 0) { |
| 696 | // This is a Value::Ranges. |
| 697 | value.set_type(Value::RANGES); |
| 698 | Value::Ranges* ranges = value.mutable_ranges(); |
| 699 | const vector<string> tokens = strings::tokenize(temp, "[]-,\n"); |
| 700 | if (tokens.size() % 2 != 0) { |
| 701 | return Error("Expecting one or more \"ranges\""); |
| 702 | } else { |
| 703 | for (size_t i = 0; i < tokens.size(); i += 2) { |
| 704 | Value::Range* range = ranges->add_range(); |
| 705 | |
| 706 | Try<uint64_t> begin = numify<uint64_t>(tokens[i]); |
| 707 | Try<uint64_t> end = numify<uint64_t>(tokens[i + 1]); |
| 708 | if (begin.isError() || end.isError()) { |
| 709 | return Error( |
| 710 | "Expecting non-negative integers in '" + tokens[i] + "'"); |
| 711 | } |
| 712 | |
| 713 | range->set_begin(begin.get()); |
| 714 | range->set_end(end.get()); |
| 715 | } |
| 716 | |
| 717 | coalesce(ranges); |
| 718 | |
| 719 | return value; |
| 720 | } |
| 721 | } else if (index == string::npos) { |
| 722 | size_t index = temp.find('{'); |
| 723 | if (index == 0) { |
| 724 | // This is a set. |
| 725 | value.set_type(Value::SET); |
| 726 | Value::Set* set = value.mutable_set(); |
| 727 | const vector<string> tokens = strings::tokenize(temp, "{},\n"); |
| 728 | for (size_t i = 0; i < tokens.size(); i++) { |
| 729 | set->add_item(tokens[i]); |
| 730 | } |
| 731 | return value; |
| 732 | } else if (index == string::npos) { |
| 733 | Try<double> value_ = numify<double>(temp); |
nothing calls this directly
no test coverage detected