summaryrefslogtreecommitdiffstats
path: root/libnetdata/line_splitter/line_splitter.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:20:02 +0000
commit58daab21cd043e1dc37024a7f99b396788372918 (patch)
tree96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /libnetdata/line_splitter/line_splitter.h
parentReleasing debian version 1.43.2-1. (diff)
downloadnetdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz
netdata-58daab21cd043e1dc37024a7f99b396788372918.zip
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--libnetdata/line_splitter/line_splitter.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/libnetdata/line_splitter/line_splitter.h b/libnetdata/line_splitter/line_splitter.h
new file mode 100644
index 000000000..b5a59ad3a
--- /dev/null
+++ b/libnetdata/line_splitter/line_splitter.h
@@ -0,0 +1,120 @@
+// 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);
+
+extern bool isspace_map_pluginsd[256];
+extern bool isspace_map_config[256];
+extern bool isspace_map_group_by_label[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)
+
+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