master
h 133 lines 3.7 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "../libnetdata.h"
4
5 #ifndef NETDATA_LINE_SPLITTER_H
6 #define NETDATA_LINE_SPLITTER_H
7
8 #define PLUGINSD_MAX_WORDS 30
9
10 struct line_splitter {
11 size_t count; // counts number of lines
12 char *words[PLUGINSD_MAX_WORDS]; // an array of pointers for the words in this line
13 size_t num_words; // the number of pointers used in this line
14 };
15
16 bool line_splitter_reconstruct_line(BUFFER *wb, void *ptr);
17
18 static inline void line_splitter_reset(struct line_splitter *line) {
19 line->num_words = 0;
20 }
21
22 int isspace_pluginsd(char c);
23 int isspace_config(char c);
24 int isspace_group_by_label(char c);
25 int isspace_dyncfg_id(char c);
26 int isspace_whitespace(char c);
27
28 extern bool isspace_map_whitespace[256];
29 extern bool isspace_map_pluginsd[256];
30 extern bool isspace_map_config[256];
31 extern bool isspace_map_group_by_label[256];
32 extern bool isspace_dyncfg_id_map[256];
33
34 static ALWAYS_INLINE size_t quoted_strings_splitter(char *str, char **words, size_t max_words, bool *isspace_map) {
35 char *s = str, quote = 0;
36 size_t i = 0;
37
38 // skip all white space
39 while (unlikely(isspace_map[(uint8_t)*s]))
40 s++;
41
42 if(unlikely(!*s)) {
43 words[i] = NULL;
44 return 0;
45 }
46
47 // check for quote
48 if (unlikely(*s == '\'' || *s == '"')) {
49 quote = *s; // remember the quote
50 s++; // skip the quote
51 }
52
53 // store the first word
54 words[i++] = s;
55
56 // while we have something
57 while (likely(*s)) {
58 // if it is an escape
59 if (unlikely(*s == '\\' && s[1])) {
60 // IMPORTANT: support for escaping is incomplete!
61 // The backslash character needs to be removed
62 // from the parsed string.
63 s += 2;
64 continue;
65 }
66
67 // if it is a quote
68 else if (unlikely(*s == quote)) {
69 quote = 0;
70 *s = ' ';
71 continue;
72 }
73
74 // if it is a space
75 else if (unlikely(quote == 0 && isspace_map[(uint8_t)*s])) {
76 // terminate the word
77 *s++ = '\0';
78
79 // skip all white space
80 while (likely(isspace_map[(uint8_t)*s]))
81 s++;
82
83 // check for a quote
84 if (unlikely(*s == '\'' || *s == '"')) {
85 quote = *s; // remember the quote
86 s++; // skip the quote
87 }
88
89 // if we reached the end, stop
90 if (unlikely(!*s))
91 break;
92
93 // store the next word
94 if (likely(i < max_words))
95 words[i++] = s;
96 else
97 break;
98 }
99
100 // anything else
101 else
102 s++;
103 }
104
105 if (likely(i < max_words))
106 words[i] = NULL;
107
108 return i;
109 }
110
111 #define quoted_strings_splitter_whitespace(str, words, max_words) \
112 quoted_strings_splitter(str, words, max_words, isspace_map_whitespace)
113
114 #define quoted_strings_splitter_query_group_by_label(str, words, max_words) \
115 quoted_strings_splitter(str, words, max_words, isspace_map_group_by_label)
116
117 #define quoted_strings_splitter_config(str, words, max_words) \
118 quoted_strings_splitter(str, words, max_words, isspace_map_config)
119
120 #define quoted_strings_splitter_pluginsd(str, words, max_words) \
121 quoted_strings_splitter(str, words, max_words, isspace_map_pluginsd)
122
123 #define quoted_strings_splitter_dyncfg_id(str, words, max_words) \
124 quoted_strings_splitter(str, words, max_words, isspace_dyncfg_id_map)
125
126 static ALWAYS_INLINE char *get_word(char **words, size_t num_words, size_t index) {
127 if (unlikely(index >= num_words))
128 return NULL;
129
130 return words[index];
131 }
132
133 #endif //NETDATA_LINE_SPLITTER_H