lrec_t* lrec_parse_stdio_dkvp_multi_sep(char* line, char* ifs, char* ips, int ifslen, int ipslen, int allow_repeat_ifs) { lrec_t* prec = lrec_dkvp_alloc(line); // It would be easier to split the line on field separator (e.g. ","), then // split each key-value pair on pair separator (e.g. "="). But, that // requires two passes through the data. Here we do it in one pass. int idx = 0; char* p = line; if (allow_repeat_ifs) { // xxx memneq while (strncmp(p, ifs, ifslen) == 0) p += ifslen; } char* key = p; char* value = p; int saw_ps = FALSE; for ( ; *p; ) { if (strncmp(p, ifs, ifslen) == 0) { saw_ps = FALSE; *p = 0; if (*key == 0) { // xxx to do: get file-name/line-number context in here. fprintf(stderr, "Empty key disallowed.\n"); exit(1); } idx++; if (value <= key) { // E.g the pair has no equals sign: "a" rather than "a=1" or // "a=". Here we use the positional index as the key. This way // DKVP is a generalization of NIDX. char free_flags = 0; lrec_put(prec, make_nidx_key(idx, &free_flags), value, free_flags); } else { lrec_put_no_free(prec, key, value); } p += ifslen; if (allow_repeat_ifs) { while (strncmp(p, ifs, ifslen) == 0) p += ifslen; } key = p; value = p; } else if (!strncmp(p, ips, ipslen) && !saw_ps) { *p = 0; p += ipslen; value = p; saw_ps = TRUE; } else { p++; } } idx++; if (allow_repeat_ifs && *key == 0 && *value == 0) { ; // OK } else { if (*key == 0) { // xxx to do: get file-name/line-number context in here. fprintf(stderr, "Empty key disallowed.\n"); exit(1); } if (value <= key) { char free_flags = 0; lrec_put(prec, make_nidx_key(idx, &free_flags), value, free_flags); } else { lrec_put_no_free(prec, key, value); } } return prec; }
lrec_t* lrec_parse_stdio_dkvp_single_sep(char* line, char ifs, char ips, int allow_repeat_ifs, context_t* pctx) { lrec_t* prec = lrec_dkvp_alloc(line); // It would be easier to split the line on field separator (e.g. ","), then // split each key-value pair on pair separator (e.g. "="). But, that // requires two passes through the data. Here we do it in one pass. int idx = 0; char* p = line; if (allow_repeat_ifs) { while (*p == ifs) p++; } char* key = p; char* value = p; int saw_ps = FALSE; for ( ; *p; ) { if (*p == ifs) { saw_ps = FALSE; *p = 0; idx++; if (*key == 0 || value <= key) { // E.g the pair has no equals sign: "a" rather than "a=1" or // "a=". Here we use the positional index as the key. This way // DKVP is a generalization of NIDX. char free_flags = 0; lrec_put(prec, make_nidx_key(idx, &free_flags), value, free_flags); } else { lrec_put(prec, key, value, NO_FREE); } p++; if (allow_repeat_ifs) { while (*p == ifs) p++; } key = p; value = p; } else if (*p == ips && !saw_ps) { *p = 0; p++; value = p; saw_ps = TRUE; } else { p++; } } idx++; if (allow_repeat_ifs && *key == 0 && *value == 0) { ; // OK } else { if (*key == 0 || value <= key) { char free_flags = 0; lrec_put(prec, make_nidx_key(idx, &free_flags), value, free_flags); } else { lrec_put(prec, key, value, NO_FREE); } } return prec; }