lwip-1.4.1 (partial)
http-server/cparser.c@1:119c4f7144c8, 2018-07-24 (annotated)
- Committer:
- ua1arn
- Date:
- Tue Jul 24 17:36:01 2018 +0000
- Revision:
- 1:119c4f7144c8
lwip 1.4.1 with necessary servers
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ua1arn | 1:119c4f7144c8 | 1 | /* |
ua1arn | 1:119c4f7144c8 | 2 | * The MIT License (MIT) |
ua1arn | 1:119c4f7144c8 | 3 | * |
ua1arn | 1:119c4f7144c8 | 4 | * Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com> |
ua1arn | 1:119c4f7144c8 | 5 | * |
ua1arn | 1:119c4f7144c8 | 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
ua1arn | 1:119c4f7144c8 | 7 | * of this software and associated documentation files (the "Software"), to deal |
ua1arn | 1:119c4f7144c8 | 8 | * in the Software without restriction, including without limitation the rights |
ua1arn | 1:119c4f7144c8 | 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
ua1arn | 1:119c4f7144c8 | 10 | * copies of the Software, and to permit persons to whom the Software is |
ua1arn | 1:119c4f7144c8 | 11 | * furnished to do so, subject to the following conditions: |
ua1arn | 1:119c4f7144c8 | 12 | * |
ua1arn | 1:119c4f7144c8 | 13 | * The above copyright notice and this permission notice shall be included in all |
ua1arn | 1:119c4f7144c8 | 14 | * copies or substantial portions of the Software. |
ua1arn | 1:119c4f7144c8 | 15 | * |
ua1arn | 1:119c4f7144c8 | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
ua1arn | 1:119c4f7144c8 | 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
ua1arn | 1:119c4f7144c8 | 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
ua1arn | 1:119c4f7144c8 | 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
ua1arn | 1:119c4f7144c8 | 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
ua1arn | 1:119c4f7144c8 | 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
ua1arn | 1:119c4f7144c8 | 22 | * SOFTWARE. |
ua1arn | 1:119c4f7144c8 | 23 | */ |
ua1arn | 1:119c4f7144c8 | 24 | |
ua1arn | 1:119c4f7144c8 | 25 | /* |
ua1arn | 1:119c4f7144c8 | 26 | * version: 1.0 demo (7.02.2015) |
ua1arn | 1:119c4f7144c8 | 27 | */ |
ua1arn | 1:119c4f7144c8 | 28 | |
ua1arn | 1:119c4f7144c8 | 29 | #include "cparser.h" |
ua1arn | 1:119c4f7144c8 | 30 | |
ua1arn | 1:119c4f7144c8 | 31 | void parser_init(parser_t *p, const char *str, int len) |
ua1arn | 1:119c4f7144c8 | 32 | { |
ua1arn | 1:119c4f7144c8 | 33 | p->buff = NULL; |
ua1arn | 1:119c4f7144c8 | 34 | p->buff_size = 0; |
ua1arn | 1:119c4f7144c8 | 35 | p->user_data = NULL; |
ua1arn | 1:119c4f7144c8 | 36 | p->read_cb = NULL; |
ua1arn | 1:119c4f7144c8 | 37 | p->total = 0; |
ua1arn | 1:119c4f7144c8 | 38 | p->line = 0; |
ua1arn | 1:119c4f7144c8 | 39 | p->col = 0; |
ua1arn | 1:119c4f7144c8 | 40 | p->priv.curr = str; |
ua1arn | 1:119c4f7144c8 | 41 | p->priv.stop = str + len; |
ua1arn | 1:119c4f7144c8 | 42 | } |
ua1arn | 1:119c4f7144c8 | 43 | |
ua1arn | 1:119c4f7144c8 | 44 | void parser_init_s(parser_t *p, char *stream_buff, size_t size, parser_read_t cb) |
ua1arn | 1:119c4f7144c8 | 45 | { |
ua1arn | 1:119c4f7144c8 | 46 | p->buff = stream_buff; |
ua1arn | 1:119c4f7144c8 | 47 | p->buff_size = size; |
ua1arn | 1:119c4f7144c8 | 48 | p->user_data = NULL; |
ua1arn | 1:119c4f7144c8 | 49 | p->read_cb = cb; |
ua1arn | 1:119c4f7144c8 | 50 | p->total = 0; |
ua1arn | 1:119c4f7144c8 | 51 | p->line = 0; |
ua1arn | 1:119c4f7144c8 | 52 | p->col = 0; |
ua1arn | 1:119c4f7144c8 | 53 | p->priv.curr = NULL; |
ua1arn | 1:119c4f7144c8 | 54 | p->priv.stop = NULL; |
ua1arn | 1:119c4f7144c8 | 55 | } |
ua1arn | 1:119c4f7144c8 | 56 | |
ua1arn | 1:119c4f7144c8 | 57 | bool parser_provide_space(parser_t *p, int size) |
ua1arn | 1:119c4f7144c8 | 58 | { |
ua1arn | 1:119c4f7144c8 | 59 | int allow; |
ua1arn | 1:119c4f7144c8 | 60 | allow = p->priv.stop - p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 61 | if (allow >= size) return true; |
ua1arn | 1:119c4f7144c8 | 62 | if (p->buff == NULL || p->buff_size < size) return false; |
ua1arn | 1:119c4f7144c8 | 63 | memmove(p->buff, p->priv.stop - allow, allow); |
ua1arn | 1:119c4f7144c8 | 64 | size = p->read_cb(p, p->buff + allow, p->buff_size - allow); |
ua1arn | 1:119c4f7144c8 | 65 | p->priv.curr = p->buff; |
ua1arn | 1:119c4f7144c8 | 66 | p->priv.stop = p->buff + allow + size; |
ua1arn | 1:119c4f7144c8 | 67 | return true; |
ua1arn | 1:119c4f7144c8 | 68 | } |
ua1arn | 1:119c4f7144c8 | 69 | |
ua1arn | 1:119c4f7144c8 | 70 | bool parser_is_next(parser_t *p, const char *str, int len) |
ua1arn | 1:119c4f7144c8 | 71 | { |
ua1arn | 1:119c4f7144c8 | 72 | if (!parser_provide_space(p, len)) return false; |
ua1arn | 1:119c4f7144c8 | 73 | return memcmp(p->priv.curr, str, len) == 0; |
ua1arn | 1:119c4f7144c8 | 74 | } |
ua1arn | 1:119c4f7144c8 | 75 | |
ua1arn | 1:119c4f7144c8 | 76 | static bool query_data(parser_t *p) |
ua1arn | 1:119c4f7144c8 | 77 | { |
ua1arn | 1:119c4f7144c8 | 78 | size_t size = p->read_cb(p, p->buff, p->buff_size); |
ua1arn | 1:119c4f7144c8 | 79 | p->priv.curr = p->buff; |
ua1arn | 1:119c4f7144c8 | 80 | p->priv.stop = p->buff + size; |
ua1arn | 1:119c4f7144c8 | 81 | return size > 0; |
ua1arn | 1:119c4f7144c8 | 82 | } |
ua1arn | 1:119c4f7144c8 | 83 | |
ua1arn | 1:119c4f7144c8 | 84 | #define INC_POS \ |
ua1arn | 1:119c4f7144c8 | 85 | p->total++; \ |
ua1arn | 1:119c4f7144c8 | 86 | p->col++; \ |
ua1arn | 1:119c4f7144c8 | 87 | if (*p->priv.curr == '\n') \ |
ua1arn | 1:119c4f7144c8 | 88 | { \ |
ua1arn | 1:119c4f7144c8 | 89 | p->line++; \ |
ua1arn | 1:119c4f7144c8 | 90 | p->col = 0; \ |
ua1arn | 1:119c4f7144c8 | 91 | } \ |
ua1arn | 1:119c4f7144c8 | 92 | p->priv.curr++; |
ua1arn | 1:119c4f7144c8 | 93 | |
ua1arn | 1:119c4f7144c8 | 94 | #define CHECK_STATE() \ |
ua1arn | 1:119c4f7144c8 | 95 | eof = false; \ |
ua1arn | 1:119c4f7144c8 | 96 | if (p->priv.curr == p->priv.stop) \ |
ua1arn | 1:119c4f7144c8 | 97 | eof = p->buff == NULL ? true : !query_data(p); |
ua1arn | 1:119c4f7144c8 | 98 | |
ua1arn | 1:119c4f7144c8 | 99 | char parser_curr(parser_t *p) |
ua1arn | 1:119c4f7144c8 | 100 | { |
ua1arn | 1:119c4f7144c8 | 101 | bool eof; |
ua1arn | 1:119c4f7144c8 | 102 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 103 | return eof ? 0 : *p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 104 | } |
ua1arn | 1:119c4f7144c8 | 105 | |
ua1arn | 1:119c4f7144c8 | 106 | bool parser_eof(parser_t *p) |
ua1arn | 1:119c4f7144c8 | 107 | { |
ua1arn | 1:119c4f7144c8 | 108 | bool eof; |
ua1arn | 1:119c4f7144c8 | 109 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 110 | return eof; |
ua1arn | 1:119c4f7144c8 | 111 | } |
ua1arn | 1:119c4f7144c8 | 112 | |
ua1arn | 1:119c4f7144c8 | 113 | int parser_read(parser_t *p, const chatset_t chatset, char *dest, int dest_size) |
ua1arn | 1:119c4f7144c8 | 114 | { |
ua1arn | 1:119c4f7144c8 | 115 | bool eof; |
ua1arn | 1:119c4f7144c8 | 116 | register int c; |
ua1arn | 1:119c4f7144c8 | 117 | int res = 0; |
ua1arn | 1:119c4f7144c8 | 118 | while (true) |
ua1arn | 1:119c4f7144c8 | 119 | { |
ua1arn | 1:119c4f7144c8 | 120 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 121 | if (eof) break; |
ua1arn | 1:119c4f7144c8 | 122 | c = (unsigned)*p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 123 | if (!chatset[c]) break; |
ua1arn | 1:119c4f7144c8 | 124 | if (res < dest_size - 1) |
ua1arn | 1:119c4f7144c8 | 125 | dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 126 | res++; |
ua1arn | 1:119c4f7144c8 | 127 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 128 | } |
ua1arn | 1:119c4f7144c8 | 129 | if (res >= dest_size) |
ua1arn | 1:119c4f7144c8 | 130 | dest[dest_size - 1] = 0; else |
ua1arn | 1:119c4f7144c8 | 131 | dest[res] = 0; |
ua1arn | 1:119c4f7144c8 | 132 | return res; |
ua1arn | 1:119c4f7144c8 | 133 | } |
ua1arn | 1:119c4f7144c8 | 134 | |
ua1arn | 1:119c4f7144c8 | 135 | int parser_read_before2(parser_t *p, char *dest, int dest_size, char c1, char c2) |
ua1arn | 1:119c4f7144c8 | 136 | { |
ua1arn | 1:119c4f7144c8 | 137 | bool eof; |
ua1arn | 1:119c4f7144c8 | 138 | register int cc; |
ua1arn | 1:119c4f7144c8 | 139 | int res = 0; |
ua1arn | 1:119c4f7144c8 | 140 | while (true) |
ua1arn | 1:119c4f7144c8 | 141 | { |
ua1arn | 1:119c4f7144c8 | 142 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 143 | if (eof) break; |
ua1arn | 1:119c4f7144c8 | 144 | cc = *p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 145 | if (cc == c1 || cc == c2) break; |
ua1arn | 1:119c4f7144c8 | 146 | if (res < dest_size) |
ua1arn | 1:119c4f7144c8 | 147 | dest[res] = cc; |
ua1arn | 1:119c4f7144c8 | 148 | res++; |
ua1arn | 1:119c4f7144c8 | 149 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 150 | } |
ua1arn | 1:119c4f7144c8 | 151 | if (res >= dest_size) |
ua1arn | 1:119c4f7144c8 | 152 | dest[dest_size - 1] = 0; else |
ua1arn | 1:119c4f7144c8 | 153 | dest[res] = 0; |
ua1arn | 1:119c4f7144c8 | 154 | return res; |
ua1arn | 1:119c4f7144c8 | 155 | } |
ua1arn | 1:119c4f7144c8 | 156 | |
ua1arn | 1:119c4f7144c8 | 157 | int parser_read_digits(parser_t *p, char *dest, int dest_size, bool hex) |
ua1arn | 1:119c4f7144c8 | 158 | { |
ua1arn | 1:119c4f7144c8 | 159 | bool eof; |
ua1arn | 1:119c4f7144c8 | 160 | register int c; |
ua1arn | 1:119c4f7144c8 | 161 | int res = 0; |
ua1arn | 1:119c4f7144c8 | 162 | while (true) |
ua1arn | 1:119c4f7144c8 | 163 | { |
ua1arn | 1:119c4f7144c8 | 164 | bool done; |
ua1arn | 1:119c4f7144c8 | 165 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 166 | if (eof) break; |
ua1arn | 1:119c4f7144c8 | 167 | c = (unsigned)*p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 168 | done = false; |
ua1arn | 1:119c4f7144c8 | 169 | done |= c >= '0' && c <= '9'; |
ua1arn | 1:119c4f7144c8 | 170 | done |= hex && (c >= 'a' && c <= 'f'); |
ua1arn | 1:119c4f7144c8 | 171 | done |= hex && (c >= 'A' && c <= 'F'); |
ua1arn | 1:119c4f7144c8 | 172 | if (!done) break; |
ua1arn | 1:119c4f7144c8 | 173 | if (res < dest_size - 1) |
ua1arn | 1:119c4f7144c8 | 174 | dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 175 | res++; |
ua1arn | 1:119c4f7144c8 | 176 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 177 | } |
ua1arn | 1:119c4f7144c8 | 178 | if (res >= dest_size) |
ua1arn | 1:119c4f7144c8 | 179 | dest[dest_size - 1] = 0; else |
ua1arn | 1:119c4f7144c8 | 180 | dest[res] = 0; |
ua1arn | 1:119c4f7144c8 | 181 | return res; |
ua1arn | 1:119c4f7144c8 | 182 | } |
ua1arn | 1:119c4f7144c8 | 183 | |
ua1arn | 1:119c4f7144c8 | 184 | int parser_read_value(parser_t *p, char *dest, int dest_size, int fmt) |
ua1arn | 1:119c4f7144c8 | 185 | { |
ua1arn | 1:119c4f7144c8 | 186 | // state: 0 1 2 3 4 5 6 7 |
ua1arn | 1:119c4f7144c8 | 187 | // 1234567 |
ua1arn | 1:119c4f7144c8 | 188 | // 1234567 e 2 |
ua1arn | 1:119c4f7144c8 | 189 | // 1234567 e - 2 |
ua1arn | 1:119c4f7144c8 | 190 | // 345 . 1234 e + 4 |
ua1arn | 1:119c4f7144c8 | 191 | // 0 . 1234 e + 4 |
ua1arn | 1:119c4f7144c8 | 192 | // 0 x ABCD |
ua1arn | 1:119c4f7144c8 | 193 | // 0 h ABCD |
ua1arn | 1:119c4f7144c8 | 194 | // 0 b 0110 |
ua1arn | 1:119c4f7144c8 | 195 | |
ua1arn | 1:119c4f7144c8 | 196 | bool eof; |
ua1arn | 1:119c4f7144c8 | 197 | register int c; |
ua1arn | 1:119c4f7144c8 | 198 | int res; |
ua1arn | 1:119c4f7144c8 | 199 | int state; |
ua1arn | 1:119c4f7144c8 | 200 | char last; |
ua1arn | 1:119c4f7144c8 | 201 | |
ua1arn | 1:119c4f7144c8 | 202 | res = 0; |
ua1arn | 1:119c4f7144c8 | 203 | state = 0; |
ua1arn | 1:119c4f7144c8 | 204 | |
ua1arn | 1:119c4f7144c8 | 205 | while (true) |
ua1arn | 1:119c4f7144c8 | 206 | { |
ua1arn | 1:119c4f7144c8 | 207 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 208 | if (eof) break; |
ua1arn | 1:119c4f7144c8 | 209 | c = *p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 210 | |
ua1arn | 1:119c4f7144c8 | 211 | if (state == 0 || state == 2 || state == 5) |
ua1arn | 1:119c4f7144c8 | 212 | { |
ua1arn | 1:119c4f7144c8 | 213 | if (c >= '0' && c <= '9') |
ua1arn | 1:119c4f7144c8 | 214 | { |
ua1arn | 1:119c4f7144c8 | 215 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 216 | last = c; |
ua1arn | 1:119c4f7144c8 | 217 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 218 | res++; |
ua1arn | 1:119c4f7144c8 | 219 | continue; |
ua1arn | 1:119c4f7144c8 | 220 | } |
ua1arn | 1:119c4f7144c8 | 221 | if (state == 0 && c == '.' && (fmt & VAL_FMT_FLOAT)) |
ua1arn | 1:119c4f7144c8 | 222 | { |
ua1arn | 1:119c4f7144c8 | 223 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 224 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 225 | res++; |
ua1arn | 1:119c4f7144c8 | 226 | state = 2; |
ua1arn | 1:119c4f7144c8 | 227 | continue; |
ua1arn | 1:119c4f7144c8 | 228 | } |
ua1arn | 1:119c4f7144c8 | 229 | if ((state == 0 || state == 2) && (c == 'e' || c == 'E') && (fmt & VAL_FMT_FLOAT)) |
ua1arn | 1:119c4f7144c8 | 230 | { |
ua1arn | 1:119c4f7144c8 | 231 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 232 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 233 | res++; |
ua1arn | 1:119c4f7144c8 | 234 | state = 4; |
ua1arn | 1:119c4f7144c8 | 235 | continue; |
ua1arn | 1:119c4f7144c8 | 236 | } |
ua1arn | 1:119c4f7144c8 | 237 | if (state == 0 && last == '0' && res == 1) |
ua1arn | 1:119c4f7144c8 | 238 | { |
ua1arn | 1:119c4f7144c8 | 239 | if (((fmt & VAL_FMT_0H) && (c == 'H' || c == 'h')) || ((c == 'x' || c == 'X') && (fmt & VAL_FMT_0X))) |
ua1arn | 1:119c4f7144c8 | 240 | { |
ua1arn | 1:119c4f7144c8 | 241 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 242 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 243 | res++; |
ua1arn | 1:119c4f7144c8 | 244 | state = 6; |
ua1arn | 1:119c4f7144c8 | 245 | continue; |
ua1arn | 1:119c4f7144c8 | 246 | } |
ua1arn | 1:119c4f7144c8 | 247 | if ((fmt & VAL_FMT_0B) && (c == 'b' || c == 'B')) |
ua1arn | 1:119c4f7144c8 | 248 | { |
ua1arn | 1:119c4f7144c8 | 249 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 250 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 251 | res++; |
ua1arn | 1:119c4f7144c8 | 252 | state = 7; |
ua1arn | 1:119c4f7144c8 | 253 | continue; |
ua1arn | 1:119c4f7144c8 | 254 | } |
ua1arn | 1:119c4f7144c8 | 255 | } |
ua1arn | 1:119c4f7144c8 | 256 | if ((fmt & VAL_FMT_SIGN) && res == 0 && (c == '+' || c == '-')) |
ua1arn | 1:119c4f7144c8 | 257 | { |
ua1arn | 1:119c4f7144c8 | 258 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 259 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 260 | res++; |
ua1arn | 1:119c4f7144c8 | 261 | continue; |
ua1arn | 1:119c4f7144c8 | 262 | } |
ua1arn | 1:119c4f7144c8 | 263 | } |
ua1arn | 1:119c4f7144c8 | 264 | if (state == 4) |
ua1arn | 1:119c4f7144c8 | 265 | { |
ua1arn | 1:119c4f7144c8 | 266 | if (c == '+' || c == '-') |
ua1arn | 1:119c4f7144c8 | 267 | { |
ua1arn | 1:119c4f7144c8 | 268 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 269 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 270 | res++; |
ua1arn | 1:119c4f7144c8 | 271 | } |
ua1arn | 1:119c4f7144c8 | 272 | state = 5; |
ua1arn | 1:119c4f7144c8 | 273 | continue; |
ua1arn | 1:119c4f7144c8 | 274 | } |
ua1arn | 1:119c4f7144c8 | 275 | if (state == 6) |
ua1arn | 1:119c4f7144c8 | 276 | { |
ua1arn | 1:119c4f7144c8 | 277 | if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) |
ua1arn | 1:119c4f7144c8 | 278 | { |
ua1arn | 1:119c4f7144c8 | 279 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 280 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 281 | res++; |
ua1arn | 1:119c4f7144c8 | 282 | continue; |
ua1arn | 1:119c4f7144c8 | 283 | } |
ua1arn | 1:119c4f7144c8 | 284 | } |
ua1arn | 1:119c4f7144c8 | 285 | if (state == 7) |
ua1arn | 1:119c4f7144c8 | 286 | { |
ua1arn | 1:119c4f7144c8 | 287 | if (c == '0' || c == '1') |
ua1arn | 1:119c4f7144c8 | 288 | { |
ua1arn | 1:119c4f7144c8 | 289 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 290 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 291 | res++; |
ua1arn | 1:119c4f7144c8 | 292 | continue; |
ua1arn | 1:119c4f7144c8 | 293 | } |
ua1arn | 1:119c4f7144c8 | 294 | } |
ua1arn | 1:119c4f7144c8 | 295 | break; |
ua1arn | 1:119c4f7144c8 | 296 | } |
ua1arn | 1:119c4f7144c8 | 297 | if (res >= dest_size) |
ua1arn | 1:119c4f7144c8 | 298 | dest[dest_size - 1] = 0; else |
ua1arn | 1:119c4f7144c8 | 299 | dest[res] = 0; |
ua1arn | 1:119c4f7144c8 | 300 | return res; |
ua1arn | 1:119c4f7144c8 | 301 | } |
ua1arn | 1:119c4f7144c8 | 302 | |
ua1arn | 1:119c4f7144c8 | 303 | #define is_ident_char(c) \ |
ua1arn | 1:119c4f7144c8 | 304 | (c == '_' || \ |
ua1arn | 1:119c4f7144c8 | 305 | (c >= '0' && c <= '9') || \ |
ua1arn | 1:119c4f7144c8 | 306 | (c >= 'a' && c <= 'z') || \ |
ua1arn | 1:119c4f7144c8 | 307 | (c >= 'a' && c <= 'z')) |
ua1arn | 1:119c4f7144c8 | 308 | |
ua1arn | 1:119c4f7144c8 | 309 | int parser_read_string(parser_t *p, char *dest, int dest_size, int fmt) |
ua1arn | 1:119c4f7144c8 | 310 | { |
ua1arn | 1:119c4f7144c8 | 311 | // state: 0 1 2 3 4 5 |
ua1arn | 1:119c4f7144c8 | 312 | // string |
ua1arn | 1:119c4f7144c8 | 313 | // ' string ' |
ua1arn | 1:119c4f7144c8 | 314 | // " string " |
ua1arn | 1:119c4f7144c8 | 315 | // ' str \ ' |
ua1arn | 1:119c4f7144c8 | 316 | // ' str \ rntbf\/" ' |
ua1arn | 1:119c4f7144c8 | 317 | // ' str \ u ' |
ua1arn | 1:119c4f7144c8 | 318 | // ' str \ u ' |
ua1arn | 1:119c4f7144c8 | 319 | // ' str \ u 12AB ' |
ua1arn | 1:119c4f7144c8 | 320 | bool eof; |
ua1arn | 1:119c4f7144c8 | 321 | register int c; |
ua1arn | 1:119c4f7144c8 | 322 | int res; |
ua1arn | 1:119c4f7144c8 | 323 | int state; |
ua1arn | 1:119c4f7144c8 | 324 | char first; |
ua1arn | 1:119c4f7144c8 | 325 | |
ua1arn | 1:119c4f7144c8 | 326 | res = 0; |
ua1arn | 1:119c4f7144c8 | 327 | state = 0; |
ua1arn | 1:119c4f7144c8 | 328 | first = 0; |
ua1arn | 1:119c4f7144c8 | 329 | |
ua1arn | 1:119c4f7144c8 | 330 | while (true) |
ua1arn | 1:119c4f7144c8 | 331 | { |
ua1arn | 1:119c4f7144c8 | 332 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 333 | if (eof) break; |
ua1arn | 1:119c4f7144c8 | 334 | c = *p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 335 | |
ua1arn | 1:119c4f7144c8 | 336 | if (state == 0 && (((fmt & STR_FMT_QUOTE) && c == '"') || ((fmt & STR_FMT_APOST) && c == '\''))) |
ua1arn | 1:119c4f7144c8 | 337 | { |
ua1arn | 1:119c4f7144c8 | 338 | first = c; |
ua1arn | 1:119c4f7144c8 | 339 | state = 1; |
ua1arn | 1:119c4f7144c8 | 340 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 341 | continue; |
ua1arn | 1:119c4f7144c8 | 342 | } |
ua1arn | 1:119c4f7144c8 | 343 | |
ua1arn | 1:119c4f7144c8 | 344 | if (state == 0 && (fmt & STR_FMT_NAKED)) |
ua1arn | 1:119c4f7144c8 | 345 | { |
ua1arn | 1:119c4f7144c8 | 346 | state = 1; |
ua1arn | 1:119c4f7144c8 | 347 | continue; |
ua1arn | 1:119c4f7144c8 | 348 | } |
ua1arn | 1:119c4f7144c8 | 349 | |
ua1arn | 1:119c4f7144c8 | 350 | if (state == 1 && c == first) |
ua1arn | 1:119c4f7144c8 | 351 | { |
ua1arn | 1:119c4f7144c8 | 352 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 353 | break; |
ua1arn | 1:119c4f7144c8 | 354 | } |
ua1arn | 1:119c4f7144c8 | 355 | |
ua1arn | 1:119c4f7144c8 | 356 | if (state == 1 && first == 0 && is_ident_char(c)) // reading naked |
ua1arn | 1:119c4f7144c8 | 357 | { |
ua1arn | 1:119c4f7144c8 | 358 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 359 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 360 | res++; |
ua1arn | 1:119c4f7144c8 | 361 | continue; |
ua1arn | 1:119c4f7144c8 | 362 | } |
ua1arn | 1:119c4f7144c8 | 363 | |
ua1arn | 1:119c4f7144c8 | 364 | if (state == 1 && (fmt & STR_FMT_ESC) && c == '\\') |
ua1arn | 1:119c4f7144c8 | 365 | { |
ua1arn | 1:119c4f7144c8 | 366 | state = 3; |
ua1arn | 1:119c4f7144c8 | 367 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 368 | continue; |
ua1arn | 1:119c4f7144c8 | 369 | } |
ua1arn | 1:119c4f7144c8 | 370 | |
ua1arn | 1:119c4f7144c8 | 371 | if (state == 1 && first != 0) |
ua1arn | 1:119c4f7144c8 | 372 | { |
ua1arn | 1:119c4f7144c8 | 373 | if (res < dest_size) dest[res] = c; |
ua1arn | 1:119c4f7144c8 | 374 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 375 | res++; |
ua1arn | 1:119c4f7144c8 | 376 | continue; |
ua1arn | 1:119c4f7144c8 | 377 | } |
ua1arn | 1:119c4f7144c8 | 378 | |
ua1arn | 1:119c4f7144c8 | 379 | if (state == 3 && (fmt & STR_FMT_ESCU) && c == 'u') |
ua1arn | 1:119c4f7144c8 | 380 | { |
ua1arn | 1:119c4f7144c8 | 381 | state = 4; |
ua1arn | 1:119c4f7144c8 | 382 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 383 | continue; |
ua1arn | 1:119c4f7144c8 | 384 | } |
ua1arn | 1:119c4f7144c8 | 385 | |
ua1arn | 1:119c4f7144c8 | 386 | if (state == 3) |
ua1arn | 1:119c4f7144c8 | 387 | { |
ua1arn | 1:119c4f7144c8 | 388 | char e; |
ua1arn | 1:119c4f7144c8 | 389 | switch (c) |
ua1arn | 1:119c4f7144c8 | 390 | { |
ua1arn | 1:119c4f7144c8 | 391 | case 'r': e = '\r'; break; |
ua1arn | 1:119c4f7144c8 | 392 | case 'n': e = '\n'; break; |
ua1arn | 1:119c4f7144c8 | 393 | case 't': e = '\t'; break; |
ua1arn | 1:119c4f7144c8 | 394 | case 'b': e = '\b'; break; |
ua1arn | 1:119c4f7144c8 | 395 | case 'f': e = '\f'; break; |
ua1arn | 1:119c4f7144c8 | 396 | case '\\': e = '\\'; break; |
ua1arn | 1:119c4f7144c8 | 397 | case '/': e = '/'; break; |
ua1arn | 1:119c4f7144c8 | 398 | case '"': e = '"'; break; |
ua1arn | 1:119c4f7144c8 | 399 | default: |
ua1arn | 1:119c4f7144c8 | 400 | if (res < dest_size) dest[res] = '\\'; |
ua1arn | 1:119c4f7144c8 | 401 | res++; |
ua1arn | 1:119c4f7144c8 | 402 | e = c; |
ua1arn | 1:119c4f7144c8 | 403 | break; |
ua1arn | 1:119c4f7144c8 | 404 | } |
ua1arn | 1:119c4f7144c8 | 405 | state = 1; |
ua1arn | 1:119c4f7144c8 | 406 | if (res < dest_size) dest[res] = e; |
ua1arn | 1:119c4f7144c8 | 407 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 408 | res++; |
ua1arn | 1:119c4f7144c8 | 409 | continue; |
ua1arn | 1:119c4f7144c8 | 410 | } |
ua1arn | 1:119c4f7144c8 | 411 | |
ua1arn | 1:119c4f7144c8 | 412 | if (state == 4) |
ua1arn | 1:119c4f7144c8 | 413 | { |
ua1arn | 1:119c4f7144c8 | 414 | } |
ua1arn | 1:119c4f7144c8 | 415 | |
ua1arn | 1:119c4f7144c8 | 416 | break; |
ua1arn | 1:119c4f7144c8 | 417 | } |
ua1arn | 1:119c4f7144c8 | 418 | if (res >= dest_size) |
ua1arn | 1:119c4f7144c8 | 419 | dest[dest_size - 1] = 0; else |
ua1arn | 1:119c4f7144c8 | 420 | dest[res] = 0; |
ua1arn | 1:119c4f7144c8 | 421 | return res; |
ua1arn | 1:119c4f7144c8 | 422 | } |
ua1arn | 1:119c4f7144c8 | 423 | |
ua1arn | 1:119c4f7144c8 | 424 | int parser_skip(parser_t *p, const chatset_t chatset) |
ua1arn | 1:119c4f7144c8 | 425 | { |
ua1arn | 1:119c4f7144c8 | 426 | bool eof; |
ua1arn | 1:119c4f7144c8 | 427 | register int c; |
ua1arn | 1:119c4f7144c8 | 428 | int res = 0; |
ua1arn | 1:119c4f7144c8 | 429 | while (true) |
ua1arn | 1:119c4f7144c8 | 430 | { |
ua1arn | 1:119c4f7144c8 | 431 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 432 | if (eof) break; |
ua1arn | 1:119c4f7144c8 | 433 | c = (unsigned)*p->priv.curr; |
ua1arn | 1:119c4f7144c8 | 434 | if (!chatset[(uint8_t)c]) break; |
ua1arn | 1:119c4f7144c8 | 435 | res++; |
ua1arn | 1:119c4f7144c8 | 436 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 437 | } |
ua1arn | 1:119c4f7144c8 | 438 | return res; |
ua1arn | 1:119c4f7144c8 | 439 | } |
ua1arn | 1:119c4f7144c8 | 440 | |
ua1arn | 1:119c4f7144c8 | 441 | int parser_skip_n(parser_t *p, int n) |
ua1arn | 1:119c4f7144c8 | 442 | { |
ua1arn | 1:119c4f7144c8 | 443 | bool eof; |
ua1arn | 1:119c4f7144c8 | 444 | int i; |
ua1arn | 1:119c4f7144c8 | 445 | for (i = 0; i < n; i++) |
ua1arn | 1:119c4f7144c8 | 446 | { |
ua1arn | 1:119c4f7144c8 | 447 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 448 | if (eof) return i; |
ua1arn | 1:119c4f7144c8 | 449 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 450 | } |
ua1arn | 1:119c4f7144c8 | 451 | return n; |
ua1arn | 1:119c4f7144c8 | 452 | } |
ua1arn | 1:119c4f7144c8 | 453 | |
ua1arn | 1:119c4f7144c8 | 454 | bool parser_skip_char(parser_t *p, char c) |
ua1arn | 1:119c4f7144c8 | 455 | { |
ua1arn | 1:119c4f7144c8 | 456 | bool eof; |
ua1arn | 1:119c4f7144c8 | 457 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 458 | if (*p->priv.curr != c || eof) return false; |
ua1arn | 1:119c4f7144c8 | 459 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 460 | return true; |
ua1arn | 1:119c4f7144c8 | 461 | } |
ua1arn | 1:119c4f7144c8 | 462 | |
ua1arn | 1:119c4f7144c8 | 463 | bool parser_skip_ws(parser_t *p) |
ua1arn | 1:119c4f7144c8 | 464 | { |
ua1arn | 1:119c4f7144c8 | 465 | bool eof; |
ua1arn | 1:119c4f7144c8 | 466 | bool res = false; |
ua1arn | 1:119c4f7144c8 | 467 | while (true) |
ua1arn | 1:119c4f7144c8 | 468 | { |
ua1arn | 1:119c4f7144c8 | 469 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 470 | if (eof) return res; |
ua1arn | 1:119c4f7144c8 | 471 | if (*p->priv.curr > 0x20) return res; |
ua1arn | 1:119c4f7144c8 | 472 | res = true; |
ua1arn | 1:119c4f7144c8 | 473 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 474 | } |
ua1arn | 1:119c4f7144c8 | 475 | } |
ua1arn | 1:119c4f7144c8 | 476 | |
ua1arn | 1:119c4f7144c8 | 477 | bool parser_skip_ws_in_line(parser_t *p) |
ua1arn | 1:119c4f7144c8 | 478 | { |
ua1arn | 1:119c4f7144c8 | 479 | bool eof; |
ua1arn | 1:119c4f7144c8 | 480 | bool res = false; |
ua1arn | 1:119c4f7144c8 | 481 | while (true) |
ua1arn | 1:119c4f7144c8 | 482 | { |
ua1arn | 1:119c4f7144c8 | 483 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 484 | if (eof) return res; |
ua1arn | 1:119c4f7144c8 | 485 | if (*p->priv.curr > 0x20 || *p->priv.curr == '\r' || *p->priv.curr == '\n') |
ua1arn | 1:119c4f7144c8 | 486 | return res; |
ua1arn | 1:119c4f7144c8 | 487 | res = true; |
ua1arn | 1:119c4f7144c8 | 488 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 489 | } |
ua1arn | 1:119c4f7144c8 | 490 | } |
ua1arn | 1:119c4f7144c8 | 491 | |
ua1arn | 1:119c4f7144c8 | 492 | bool parser_skip_line(parser_t *p) |
ua1arn | 1:119c4f7144c8 | 493 | { |
ua1arn | 1:119c4f7144c8 | 494 | bool eof; |
ua1arn | 1:119c4f7144c8 | 495 | while (true) |
ua1arn | 1:119c4f7144c8 | 496 | { |
ua1arn | 1:119c4f7144c8 | 497 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 498 | if (eof) return false; |
ua1arn | 1:119c4f7144c8 | 499 | if (*p->priv.curr == '\n') |
ua1arn | 1:119c4f7144c8 | 500 | { |
ua1arn | 1:119c4f7144c8 | 501 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 502 | return true; |
ua1arn | 1:119c4f7144c8 | 503 | } |
ua1arn | 1:119c4f7144c8 | 504 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 505 | } |
ua1arn | 1:119c4f7144c8 | 506 | } |
ua1arn | 1:119c4f7144c8 | 507 | |
ua1arn | 1:119c4f7144c8 | 508 | bool parser_skip_before(parser_t *p, char c) |
ua1arn | 1:119c4f7144c8 | 509 | { |
ua1arn | 1:119c4f7144c8 | 510 | bool eof; |
ua1arn | 1:119c4f7144c8 | 511 | while (true) |
ua1arn | 1:119c4f7144c8 | 512 | { |
ua1arn | 1:119c4f7144c8 | 513 | CHECK_STATE(); |
ua1arn | 1:119c4f7144c8 | 514 | if (eof) return false; |
ua1arn | 1:119c4f7144c8 | 515 | if (*p->priv.curr == c) return true; |
ua1arn | 1:119c4f7144c8 | 516 | INC_POS; |
ua1arn | 1:119c4f7144c8 | 517 | } |
ua1arn | 1:119c4f7144c8 | 518 | } |
ua1arn | 1:119c4f7144c8 | 519 |