1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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
|