| 766 | // |
| 767 | template <class Data, class MatchResult> |
| 768 | int |
| 769 | ControlMatcher<Data, MatchResult>::BuildTableFromString(char *file_buf) |
| 770 | { |
| 771 | // Table build locals |
| 772 | Tokenizer bufTok("\n"); |
| 773 | tok_iter_state i_state; |
| 774 | const char *tmp; |
| 775 | matcher_line *first = nullptr; |
| 776 | matcher_line *current; |
| 777 | matcher_line *last = nullptr; |
| 778 | int line_num = 0; |
| 779 | int second_pass = 0; |
| 780 | int numEntries = 0; |
| 781 | |
| 782 | // type counts |
| 783 | int hostDomain = 0; |
| 784 | int regex = 0; |
| 785 | int url = 0; |
| 786 | int ip = 0; |
| 787 | int hostregex = 0; |
| 788 | |
| 789 | if (bufTok.Initialize(file_buf, SHARE_TOKS | ALLOW_EMPTY_TOKS) == 0) { |
| 790 | // We have an empty file |
| 791 | return 0; |
| 792 | } |
| 793 | |
| 794 | // First get the number of entries |
| 795 | tmp = bufTok.iterFirst(&i_state); |
| 796 | while (tmp != nullptr) { |
| 797 | line_num++; |
| 798 | |
| 799 | // skip all blank spaces at beginning of line |
| 800 | while (*tmp && isspace(*tmp)) { |
| 801 | tmp++; |
| 802 | } |
| 803 | |
| 804 | if (*tmp != '#' && *tmp != '\0') { |
| 805 | const char *errptr; |
| 806 | |
| 807 | current = static_cast<matcher_line *>(ats_malloc(sizeof(matcher_line))); |
| 808 | errptr = parseConfigLine(const_cast<char *>(tmp), current, config_tags); |
| 809 | |
| 810 | if (errptr != nullptr) { |
| 811 | if (config_tags != &socks_server_tags) { |
| 812 | Result error = |
| 813 | Result::failure("%s discarding %s entry at line %d : %s", matcher_name, config_file_path, line_num, errptr); |
| 814 | Error("%s", error.message()); |
| 815 | } |
| 816 | ats_free(current); |
| 817 | } else { |
| 818 | // Line parsed ok. Figure out what the destination |
| 819 | // type is and link it into our list |
| 820 | numEntries++; |
| 821 | current->line_num = line_num; |
| 822 | |
| 823 | switch (current->type) { |
| 824 | case MATCH_HOST: |
| 825 | case MATCH_DOMAIN: |
nothing calls this directly
no test coverage detected