diff options
Diffstat (limited to 'src/libnetdata/line_splitter/line_splitter.h')
-rw-r--r-- | src/libnetdata/line_splitter/line_splitter.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/libnetdata/line_splitter/line_splitter.h b/src/libnetdata/line_splitter/line_splitter.h new file mode 100644 index 000000000..968930410 --- /dev/null +++ b/src/libnetdata/line_splitter/line_splitter.h @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../libnetdata.h" + +#ifndef NETDATA_LINE_SPLITTER_H +#define NETDATA_LINE_SPLITTER_H + +#define PLUGINSD_MAX_WORDS 30 + +struct line_splitter { + size_t count; // counts number of lines + char *words[PLUGINSD_MAX_WORDS]; // an array of pointers for the words in this line + size_t num_words; // the number of pointers used in this line +}; + +bool line_splitter_reconstruct_line(BUFFER *wb, void *ptr); + +static inline void line_splitter_reset(struct line_splitter *line) { + line->num_words = 0; +} + +int pluginsd_isspace(char c); +int config_isspace(char c); +int group_by_label_isspace(char c); +int dyncfg_id_isspace(char c); + +extern bool isspace_map_pluginsd[256]; +extern bool isspace_map_config[256]; +extern bool isspace_map_group_by_label[256]; +extern bool isspace_dyncfg_id_map[256]; + +static inline size_t quoted_strings_splitter(char *str, char **words, size_t max_words, bool *isspace_map) { + char *s = str, quote = 0; + size_t i = 0; + + // skip all white space + while (unlikely(isspace_map[(uint8_t)*s])) + s++; + + if(unlikely(!*s)) { + words[i] = NULL; + return 0; + } + + // check for quote + if (unlikely(*s == '\'' || *s == '"')) { + quote = *s; // remember the quote + s++; // skip the quote + } + + // store the first word + words[i++] = s; + + // while we have something + while (likely(*s)) { + // if it is an escape + if (unlikely(*s == '\\' && s[1])) { + s += 2; + continue; + } + + // if it is a quote + else if (unlikely(*s == quote)) { + quote = 0; + *s = ' '; + continue; + } + + // if it is a space + else if (unlikely(quote == 0 && isspace_map[(uint8_t)*s])) { + // terminate the word + *s++ = '\0'; + + // skip all white space + while (likely(isspace_map[(uint8_t)*s])) + s++; + + // check for a quote + if (unlikely(*s == '\'' || *s == '"')) { + quote = *s; // remember the quote + s++; // skip the quote + } + + // if we reached the end, stop + if (unlikely(!*s)) + break; + + // store the next word + if (likely(i < max_words)) + words[i++] = s; + else + break; + } + + // anything else + else + s++; + } + + if (likely(i < max_words)) + words[i] = NULL; + + return i; +} + +#define quoted_strings_splitter_query_group_by_label(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_map_group_by_label) + +#define quoted_strings_splitter_config(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_map_config) + +#define quoted_strings_splitter_pluginsd(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_map_pluginsd) + +#define quoted_strings_splitter_dyncfg_id(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_dyncfg_id_map) + +static inline char *get_word(char **words, size_t num_words, size_t index) { + if (unlikely(index >= num_words)) + return NULL; + + return words[index]; +} + +#endif //NETDATA_LINE_SPLITTER_H |