| 3297 | } |
| 3298 | |
| 3299 | bool cypherComplete(const char* z) { |
| 3300 | enum TokenType { tkSEMI = 0, tkWS, tkOTHER }; |
| 3301 | |
| 3302 | unsigned char state = 0; /* Current state, using numbers defined in header comment */ |
| 3303 | unsigned char token; /* Value of the next token */ |
| 3304 | |
| 3305 | /* If triggers are not supported by this compile then the statement machine |
| 3306 | ** used to detect the end of a statement is much simpler |
| 3307 | */ |
| 3308 | static const unsigned char trans[3][3] = { |
| 3309 | /* Token: */ |
| 3310 | /* State: ** SEMI WS OTHER */ |
| 3311 | /* 0 INVALID: */ { |
| 3312 | 2, |
| 3313 | 0, |
| 3314 | 2, |
| 3315 | }, |
| 3316 | /* 1 START: */ |
| 3317 | { |
| 3318 | 1, |
| 3319 | 1, |
| 3320 | 2, |
| 3321 | }, |
| 3322 | /* 2 NORMAL: */ |
| 3323 | { |
| 3324 | 1, |
| 3325 | 2, |
| 3326 | 2, |
| 3327 | }, |
| 3328 | }; |
| 3329 | |
| 3330 | while (*z) { |
| 3331 | switch (*z) { |
| 3332 | case ';': { /* A semicolon */ |
| 3333 | token = tkSEMI; |
| 3334 | break; |
| 3335 | } |
| 3336 | case ' ': |
| 3337 | case '\r': |
| 3338 | case '\t': |
| 3339 | case '\n': |
| 3340 | case '\f': { /* White space is ignored */ |
| 3341 | token = tkWS; |
| 3342 | break; |
| 3343 | } |
| 3344 | case '/': { /* C-style comments */ |
| 3345 | if (z[1] == '*') { |
| 3346 | z += 2; |
| 3347 | while (z[0] && (z[0] != '*' || z[1] != '/')) { |
| 3348 | z++; |
| 3349 | } |
| 3350 | if (z[0] == 0) |
| 3351 | return 0; |
| 3352 | z++; |
| 3353 | token = tkWS; |
| 3354 | break; |
| 3355 | } else if (z[1] == '/') { |
| 3356 | while (*z && *z != '\n') { |
no outgoing calls
no test coverage detected