// This is a personal academic project. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include #include #include #include "parser_utils.h" const char * parser_utils_strcmpi_event(const enum string_cmp_event_types type) { const char *ret; switch (type) { case STRING_CMP_MAYEQ: ret = "wait(c)"; break; case STRING_CMP_EQ: ret = "eq(c)"; break; case STRING_CMP_NEQ: ret = "neq(c)"; break; } return ret; } static void may_eq(struct parser_event *ret, const uint8_t c) { ret->type = STRING_CMP_MAYEQ; ret->n = 1; ret->data[0] = c; } static void eq(struct parser_event *ret, const uint8_t c) { ret->type = STRING_CMP_EQ; ret->n = 1; ret->data[0] = c; } static void neq(struct parser_event *ret, const uint8_t c) { ret->type = STRING_CMP_NEQ; ret->n = 1; ret->data[0] = c; } struct parser_definition * parser_utils_strcmpi(const char *s) { const size_t n = strlen(s); struct parser_state_transition **states = calloc(n + 2, sizeof(*states)); size_t *nstates = calloc(n + 2, sizeof(*nstates)); struct parser_state_transition *transitions = calloc(3 * (n + 2), sizeof(*transitions)); if (states == NULL || nstates == NULL || transitions == NULL) { free(states); free(nstates); free(transitions); struct parser_definition * def = calloc(1, sizeof(struct parser_definition)); return def; } // Estados fijos const size_t st_eq = n; const size_t st_neq = n + 1; for(size_t i = 0; i < n; i++) { const size_t dest = (i + 1 == n) ? st_eq : i + 1; transitions[i * 3 + 0].when = tolower(s[i]); transitions[i * 3 + 0].dest = dest; transitions[i * 3 + 0].act1 = i + 1 == n ? eq : may_eq; transitions[i * 3 + 1].when = toupper(s[i]); transitions[i * 3 + 1].dest = dest; transitions[i * 3 + 1].act1 = i + 1 == n ? eq : may_eq; transitions[i * 3 + 2].when = ANY; transitions[i * 3 + 2].dest = st_neq; transitions[i * 3 + 2].act1 = neq; states[i] = transitions + (i * 3 + 0); nstates[i] = 3; } // EQ transitions[(n + 0) * 3].when = ANY; transitions[(n + 0) * 3].dest = st_neq; transitions[(n + 0) * 3].act1 = neq; states[(n + 0)] = transitions + ((n + 0) * 3 + 0); nstates[(n + 0)] = 1; // NEQ transitions[(n + 1) * 3].when = ANY; transitions[(n + 1) * 3].dest = st_neq; transitions[(n + 1) * 3].act1 = neq; states[(n + 1)] = transitions + ((n + 1) * 3 + 0); nstates[(n + 1)] = 1; struct parser_definition * def = malloc(sizeof(*def)); def->start_state = 0; def->states_count = n + 2; def->states = (struct parser_state_transition **) states; def->states_n = (size_t *) nstates; return def; } void parser_utils_strcmpi_destroy(struct parser_definition *p) { free((void *)p->states[0]); free((void *)p->states); free((void *)p->states_n); free(p); }