|
7 | 7 | %{ |
8 | 8 |
|
9 | 9 | #include <cmetrics/cmt_decode_prometheus.h> |
| 10 | +#include <stdio.h> |
10 | 11 |
|
11 | 12 | #define STRBUF_RET \ |
12 | 13 | yylval->str = context->strbuf; \ |
13 | 14 | context->strbuf = NULL |
14 | 15 |
|
| 16 | +static void set_allocation_error(struct cmt_decode_prometheus_context *context) |
| 17 | +{ |
| 18 | + context->errcode = CMT_DECODE_PROMETHEUS_ALLOCATION_ERROR; |
| 19 | + |
| 20 | + if (context->opts.errbuf != NULL && context->opts.errbuf_size > 0) { |
| 21 | + snprintf(context->opts.errbuf, |
| 22 | + context->opts.errbuf_size - 1, |
| 23 | + "memory allocation failed"); |
| 24 | + } |
| 25 | +} |
| 26 | + |
| 27 | +static int reset_strbuf(struct cmt_decode_prometheus_context *context) |
| 28 | +{ |
| 29 | + if (context->strbuf != NULL) { |
| 30 | + cfl_sds_destroy(context->strbuf); |
| 31 | + } |
| 32 | + |
| 33 | + context->strbuf = cfl_sds_create_size(256); |
| 34 | + if (context->strbuf == NULL) { |
| 35 | + set_allocation_error(context); |
| 36 | + |
| 37 | + return -1; |
| 38 | + } |
| 39 | + |
| 40 | + return 0; |
| 41 | +} |
| 42 | + |
| 43 | +static int append_strbuf(struct cmt_decode_prometheus_context *context, |
| 44 | + const char *text, int length) |
| 45 | +{ |
| 46 | + cfl_sds_t result; |
| 47 | + |
| 48 | + result = cfl_sds_cat(context->strbuf, text, length); |
| 49 | + if (result == NULL) { |
| 50 | + set_allocation_error(context); |
| 51 | + |
| 52 | + return -1; |
| 53 | + } |
| 54 | + |
| 55 | + context->strbuf = result; |
| 56 | + |
| 57 | + return 0; |
| 58 | +} |
| 59 | + |
| 60 | +#define STRBUF_CREATE() \ |
| 61 | + do { \ |
| 62 | + if (reset_strbuf(context) != 0) { \ |
| 63 | + return 0; \ |
| 64 | + } \ |
| 65 | + } while (0) |
| 66 | + |
| 67 | +#define STRBUF_APPEND(text, length) \ |
| 68 | + do { \ |
| 69 | + if (append_strbuf(context, (text), (length)) != 0) { \ |
| 70 | + return 0; \ |
| 71 | + } \ |
| 72 | + } while (0) |
| 73 | + |
| 74 | +#define SET_STR_TOKEN() \ |
| 75 | + do { \ |
| 76 | + yylval->str = cfl_sds_create(yytext); \ |
| 77 | + if (yylval->str == NULL) { \ |
| 78 | + set_allocation_error(context); \ |
| 79 | + return 0; \ |
| 80 | + } \ |
| 81 | + } while (0) |
| 82 | + |
15 | 83 | %} |
16 | 84 |
|
17 | 85 | /* here we define some states that allow us to create rules only |
|
74 | 142 |
|
75 | 143 | <HELPTAG,TYPETAG>[^ \t]+ { |
76 | 144 | // The next token will be the metric name |
77 | | - yylval->str = cfl_sds_create(yytext); |
| 145 | + SET_STR_TOKEN(); |
78 | 146 | return YYSTATE == HELPTAG ? HELP : TYPE; |
79 | 147 | } |
80 | 148 |
|
|
86 | 154 | // separate start condition for this to handle "\\" and "\n" escapes |
87 | 155 | // more easily. |
88 | 156 | BEGIN(INHELPTAG); |
89 | | - context->strbuf = cfl_sds_create_size(256); |
| 157 | + STRBUF_CREATE(); |
90 | 158 | } |
91 | 159 | else { |
92 | 160 | // For TYPETAG we enter INTYPETAG start condition to check only valid |
|
107 | 175 |
|
108 | 176 | <INHELPTAG>\\n { |
109 | 177 | // Process linefeed escape sequence |
110 | | - context->strbuf = cfl_sds_cat(context->strbuf, "\n", 1); |
| 178 | + STRBUF_APPEND("\n", 1); |
111 | 179 | } |
112 | 180 |
|
113 | 181 | <INHELPTAG>\\\\ { |
114 | 182 | // Process backslack escape sequence |
115 | | - context->strbuf = cfl_sds_cat(context->strbuf, "\\", 1); |
| 183 | + STRBUF_APPEND("\\", 1); |
116 | 184 | } |
117 | 185 |
|
118 | 186 | <INHELPTAG>[^\r\n\\]+ { |
119 | 187 | // Put everything that is not a backslash or a line feed into strbuf |
120 | | - context->strbuf = cfl_sds_cat(context->strbuf, yytext, yyleng); |
| 188 | + STRBUF_APPEND(yytext, yyleng); |
121 | 189 | } |
122 | 190 |
|
123 | 191 | <INTYPETAG>counter { |
|
146 | 214 |
|
147 | 215 | ["] { |
148 | 216 | BEGIN(INQUOTE); |
149 | | - if (context->strbuf != NULL) { |
150 | | - cfl_sds_destroy(context->strbuf); |
151 | | - } |
152 | | - context->strbuf = cfl_sds_create_size(256); |
| 217 | + STRBUF_CREATE(); |
153 | 218 | } |
154 | 219 |
|
155 | 220 | <INQUOTE>[\\]["] { |
156 | | - context->strbuf = cfl_sds_cat(context->strbuf, "\"", 1); |
| 221 | + STRBUF_APPEND("\"", 1); |
157 | 222 | } |
158 | 223 |
|
159 | 224 | <INQUOTE>\\n { |
160 | | - context->strbuf = cfl_sds_cat(context->strbuf, "\n", 1); |
| 225 | + STRBUF_APPEND("\n", 1); |
161 | 226 | } |
162 | 227 |
|
163 | 228 | <INQUOTE>\\\\ { |
164 | | - context->strbuf = cfl_sds_cat(context->strbuf, "\\", 1); |
| 229 | + STRBUF_APPEND("\\", 1); |
165 | 230 | } |
166 | 231 |
|
167 | 232 | <INQUOTE>[^\r\n\\"]+ { |
168 | | - context->strbuf = cfl_sds_cat(context->strbuf, yytext, yyleng); |
| 233 | + STRBUF_APPEND(yytext, yyleng); |
169 | 234 | } |
170 | 235 |
|
171 | 236 | <INQUOTE>["] { |
|
180 | 245 | } |
181 | 246 |
|
182 | 247 | [a-zA-Z_][a-zA-Z_0-9]* { |
183 | | - yylval->str = cfl_sds_create(yytext); |
| 248 | + SET_STR_TOKEN(); |
184 | 249 | return IDENTIFIER; |
185 | 250 | } |
186 | 251 |
|
|
0 commit comments