/* * Copyright 2023 Oleg Borodin */ #include #include #include #include #include #include #include #define INIT_BSIZE 64 static char* strcopy(char* src) { size_t srcsize = strlen(src) + 1; char* dst = malloc(srcsize); memset(dst, '\0', srcsize); strcpy(dst, src); return dst; } #if 0 static char* strconcat(char** str, int num) { size_t tsize = 0; size_t size[num]; for (int i = 0; i < num; i++) { size[i] = 0; if (str[i] != NULL) { size[i] = strlen(str[i]); tsize += size[i]; } } tsize++; char* dst = malloc(tsize); memset(dst, '\0', tsize); int pos = 0; for (int i = 0; i < num; i++) { if (str[i] != NULL) { strcpy(&dst[pos], str[i]); pos += size[i]; } } return dst; } #endif void cfparser_init(cfparser_t * parser, cflexer_t * lexer) { parser->lexer = lexer; parser->kvalarr = malloc(sizeof(cfkval_t) * INIT_BSIZE); parser->kvalcapa = INIT_BSIZE; parser->kvalsize = 0; } int cfparser_bind(cfparser_t * parser, int type, char* key, void* ref) { for (int i = 0; i < parser->kvalsize; i++) { if (strcmp(key, parser->kvalarr[i].key) == 0) { char* key = parser->kvalarr[i].key; char* val = parser->kvalarr[i].val; switch (type) { case CFVALTYPE_STR: { *(char**)(ref) = strcopy(val); break; } case CFVALTYPE_INT: { for (size_t i = 0; i < strlen(val); i++) { if (isdigit(val[i]) == 0 && val[i] != '-' ) { log_error("wrong integer value: %s = %s", key, val); return -1; } } char* eptr = NULL; *(int64_t*)(ref) = (int64_t)strtol(val, &eptr, 10); break; } case CFVALTYPE_BOOL:{ *(bool*)(ref) = false; if (strcmp(val, "true") == 0) { *(bool*)(ref) = true; } else if (strcmp(val, "false") == 0) { *(bool*)(ref) = false; } else { log_error("wrong boolean key value: %s = %s", key, val); } break; } } } } return 0; } #define MAX_TOKEN_SIZE 1024 int cfparser_parse(cfparser_t * parser) { cflexer_t* lex = parser->lexer; char token[MAX_TOKEN_SIZE]; int type = 0; int pos = 0; char* key; //char* val; while ((type = cflexer_gettoken(lex, token)) != CFLEXTOK_END) { switch (pos) { // POS 0 case 0:{ if (type == CFLEXTOK_SPACE) continue; if (type == CFLEXTOK_COMM) continue; if (type == CFLEXTOK_NEXT) continue; if (type == CFLEXTOK_WORD) { key = strcopy(token); pos++; } else { return -1; } break; } // POS 1 case 1:{ if (type == CFLEXTOK_SPACE) continue; if (type == CFLEXTOK_SEPAR) { pos++; } else { return -1; } break; } // POS 2 case 2:{ if (type == CFLEXTOK_SPACE) continue; if (type == CFLEXTOK_WORD) { char* val = strcopy(token); if (parser->kvalsize >= parser->kvalcapa) { // TODO } parser->kvalarr[parser->kvalsize].key = key; parser->kvalarr[parser->kvalsize].val = val; parser->kvalsize++; pos++; } else { return -1; } break; } case 3:{ if (type == CFLEXTOK_SPACE) continue; if (type == CFLEXTOK_COMM) continue; if (type == CFLEXTOK_NEXT) { pos = 0; } else { return -1; } break; } default:{ return -1; } } } return 0; } void cfparser_destroy(cfparser_t * parser) { if (parser == NULL) return; if (parser->kvalarr != NULL) { for (int i = 0; i < parser->kvalsize; i++) { free(parser->kvalarr[i].key); free(parser->kvalarr[i].val); } free(parser->kvalarr); } }