From a04128015b07bc0f37cc45bf8960432ae1025812 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Tue, 13 Oct 2015 21:44:47 -0400 Subject: [PATCH] sub/gsub capture-group iterate --- c/experimental/getlines.c | 27 ++++++++------------------- c/input/lrec_reader_csv.c | 6 ++---- c/lib/string_builder.c | 15 +++++++++++++++ c/lib/string_builder.h | 2 ++ c/mapping/lrec_evaluators.c | 7 ++----- c/mapping/mlr_val.c | 20 ++++++++++---------- c/mapping/mlr_val.h | 2 ++ c/unit_test/test_string_builder.c | 3 +-- 8 files changed, 42 insertions(+), 40 deletions(-) diff --git a/c/experimental/getlines.c b/c/experimental/getlines.c index f461e529f..99463966a 100644 --- a/c/experimental/getlines.c +++ b/c/experimental/getlines.c @@ -194,14 +194,10 @@ static char* read_line_getc_unlocked_psb(FILE* fp, string_builder_t* psb, char* static int read_file_getc_unlocked_psb(char* filename, int do_write) { FILE* fp = fopen_or_die(filename); + string_builder_t* psb = sb_alloc(STRING_BUILDER_INIT_SIZE); char* irs = "\n"; - int bc = 0; - string_builder_t sb; - string_builder_t* psb = &sb; - sb_init(&sb, STRING_BUILDER_INIT_SIZE); - while (TRUE) { char* line = read_line_getc_unlocked_psb(fp, psb, irs); if (line == NULL) @@ -213,6 +209,7 @@ static int read_file_getc_unlocked_psb(char* filename, int do_write) { bc += strlen(line); free(line); } + sb_free(psb); fclose(fp); return bc; } @@ -236,12 +233,8 @@ static char* read_line_fgetc_psb(FILE* fp, string_builder_t* psb, char* irs) { static int read_file_fgetc_psb(char* filename, int do_write) { FILE* fp = fopen_or_die(filename); + string_builder_t* psb = sb_alloc(STRING_BUILDER_INIT_SIZE); char* irs = "\n"; - - string_builder_t sb; - string_builder_t* psb = &sb; - sb_init(&sb, STRING_BUILDER_INIT_SIZE); - int bc = 0; while (TRUE) { @@ -255,6 +248,7 @@ static int read_file_fgetc_psb(char* filename, int do_write) { bc += strlen(line); free(line); } + sb_free(psb); fclose(fp); return bc; } @@ -281,12 +275,8 @@ static char* read_line_mmap_psb(file_reader_mmap_state_t* ph, string_builder_t* static int read_file_mmap_psb(char* filename, int do_write) { file_reader_mmap_state_t* ph = file_reader_mmap_open(filename); + string_builder_t* psb = sb_alloc(STRING_BUILDER_INIT_SIZE); char* irs = "\n"; - - string_builder_t sb; - string_builder_t* psb = &sb; - sb_init(&sb, STRING_BUILDER_INIT_SIZE); - int bc = 0; while (TRUE) { @@ -299,6 +289,7 @@ static int read_file_mmap_psb(char* filename, int do_write) { } bc += strlen(line); } + sb_free(psb); file_reader_mmap_close(ph); return bc; } @@ -335,6 +326,7 @@ static char* read_line_pfr_psb(peek_file_reader_t* pfr, string_builder_t* psb, p static int read_file_pfr_psb(char* filename, int do_write) { byte_reader_t* pbr = stdio_byte_reader_alloc(); + string_builder_t* psb = sb_alloc(STRING_BUILDER_INIT_SIZE); pbr->popen_func(pbr, filename); peek_file_reader_t* pfr = pfr_alloc(pbr, PEEK_BUF_LEN); @@ -344,10 +336,6 @@ static int read_file_pfr_psb(char* filename, int do_write) { parse_trie_add_string(ptrie, "\xff", EOF_STRIDX); parse_trie_add_string(ptrie, "\n\xff", IRSEOF_STRIDX); - string_builder_t sb; - string_builder_t* psb = &sb; - sb_init(&sb, STRING_BUILDER_INIT_SIZE); - int bc = 0; while (TRUE) { @@ -361,6 +349,7 @@ static int read_file_pfr_psb(char* filename, int do_write) { bc += strlen(line); free(line); } + sb_free(psb); pbr->pclose_func(pbr); return bc; } diff --git a/c/input/lrec_reader_csv.c b/c/input/lrec_reader_csv.c index 238f27430..e376903c8 100644 --- a/c/input/lrec_reader_csv.c +++ b/c/input/lrec_reader_csv.c @@ -54,7 +54,6 @@ typedef struct _lrec_reader_csv_state_t { int dquotelen; - string_builder_t sb; string_builder_t* psb; byte_reader_t* pbr; peek_file_reader_t* pfr; @@ -110,8 +109,7 @@ lrec_reader_t* lrec_reader_csv_alloc(byte_reader_t* pbr, char* irs, char* ifs) { parse_trie_add_string(pstate->pdquote_parse_trie, pstate->dquote_eof, DQUOTE_EOF_STRIDX); parse_trie_add_string(pstate->pdquote_parse_trie, pstate->dquote_dquote, DQUOTE_DQUOTE_STRIDX); - pstate->psb = &pstate->sb; - sb_init(pstate->psb, STRING_BUILDER_INIT_SIZE); + pstate->psb = sb_alloc(STRING_BUILDER_INIT_SIZE); pstate->pbr = pbr; pstate->pfr = pfr_alloc(pstate->pbr, mlr_imax2(pstate->pno_dquote_parse_trie->maxlen, pstate->pdquote_parse_trie->maxlen)); @@ -140,7 +138,7 @@ static void lrec_reader_csv_free(void* pvstate) { pfr_free(pstate->pfr); parse_trie_free(pstate->pno_dquote_parse_trie); parse_trie_free(pstate->pdquote_parse_trie); - // write & use sb_free after the refactor + sb_free(pstate->psb); } // ---------------------------------------------------------------- diff --git a/c/lib/string_builder.c b/c/lib/string_builder.c index 26ae285b4..98ad08603 100644 --- a/c/lib/string_builder.c +++ b/c/lib/string_builder.c @@ -4,6 +4,21 @@ #include "lib/mlrutil.h" #include "lib/mlr_globals.h" +// ---------------------------------------------------------------- +string_builder_t* sb_alloc(int alloc_length) { + string_builder_t* psb = mlr_malloc_or_die(sizeof(string_builder_t)); + sb_init(psb, alloc_length); + return psb; +} + +// ---------------------------------------------------------------- +void sb_free(string_builder_t* psb) { + if (psb == NULL) + return; + free(psb->buffer); + free(psb); +} + // ---------------------------------------------------------------- void sb_init(string_builder_t* psb, int alloc_length) { if (alloc_length < 1) { diff --git a/c/lib/string_builder.h b/c/lib/string_builder.h index f4f967ea8..508282b18 100644 --- a/c/lib/string_builder.h +++ b/c/lib/string_builder.h @@ -7,6 +7,8 @@ typedef struct _string_builder_t { char* buffer; } string_builder_t; +string_builder_t* sb_alloc(int alloc_length); +void sb_free(string_builder_t* psb); void sb_init(string_builder_t* psb, int alloc_length); void _sb_enlarge(string_builder_t* psb); // private method diff --git a/c/mapping/lrec_evaluators.c b/c/mapping/lrec_evaluators.c index fbb5032c6..9da1669df 100644 --- a/c/mapping/lrec_evaluators.c +++ b/c/mapping/lrec_evaluators.c @@ -29,7 +29,6 @@ // lrec_evaluators.c to invoke functions here with mlr_vals of the correct // type(s). // ================================================================ -#define STRING_BUILDER_ALLOC_LENGTH 32 // ---------------------------------------------------------------- typedef struct _lrec_evaluator_b_b_state_t { @@ -499,8 +498,7 @@ lrec_evaluator_t* lrec_evaluator_alloc_from_x_sr_func(mv_binary_arg2_regex_func_ int cflags = ignore_case ? REG_ICASE : 0; regcomp_or_die(&pstate->regex, regex_string, cflags); - pstate->psb = mlr_malloc_or_die(sizeof(string_builder_t)); - sb_init(pstate->psb, STRING_BUILDER_ALLOC_LENGTH); + pstate->psb = sb_alloc(MV_SB_ALLOC_LENGTH); lrec_evaluator_t* pevaluator = mlr_malloc_or_die(sizeof(lrec_evaluator_t)); pevaluator->pvstate = pstate; @@ -622,8 +620,7 @@ lrec_evaluator_t* lrec_evaluator_alloc_from_x_srs_func(mv_ternary_arg2_regex_fun int cflags = ignore_case ? REG_ICASE : 0; regcomp_or_die(&pstate->regex, regex_string, cflags); - pstate->psb = mlr_malloc_or_die(sizeof(string_builder_t)); - sb_init(pstate->psb, STRING_BUILDER_ALLOC_LENGTH); + pstate->psb = sb_alloc(MV_SB_ALLOC_LENGTH); pstate->parg3 = parg3; diff --git a/c/mapping/mlr_val.c b/c/mapping/mlr_val.c index 453ac14ca..ea97eb546 100644 --- a/c/mapping/mlr_val.c +++ b/c/mapping/mlr_val.c @@ -183,10 +183,9 @@ mv_t s_ss_dot_func(mv_t* pval1, mv_t* pval2) { // ---------------------------------------------------------------- mv_t sub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) { regex_t regex; - string_builder_t sb; - sb_init(&sb, 32); - mv_t rv = sub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), &sb, pval3); - free(sb_finish(&sb)); + string_builder_t *psb = sb_alloc(MV_SB_ALLOC_LENGTH); + mv_t rv = sub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), psb, pval3); + sb_free(psb); regfree(®ex); return rv; } @@ -204,14 +203,14 @@ mv_t sub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) { // * len4 = 6 = 2+3+1 mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* pval3) { - const size_t nmatch = 1; // xxx temp: parameterize after adding capture-group support + const size_t nmatch = 10; // Capture-groups \1 through \9 supported, along with entire-string match regmatch_t pmatch[nmatch]; int eflags = 0; int matched = regmatch_or_die(pregex, pval1->u.strv, nmatch, pmatch, eflags); if (!matched) { return *pval1; - } else { + } else if (pmatch[1].rm_so == -1) { // No capture groups: only a replacement string int so = pmatch[0].rm_so; int eo = pmatch[0].rm_eo; @@ -234,6 +233,8 @@ mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* mv_t rv = {.type = MT_STRING, .u.strv = string4}; return rv; + } else { + return *pval1; // xxx temp stub } } @@ -251,10 +252,9 @@ mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* mv_t gsub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) { regex_t regex; - string_builder_t sb; - sb_init(&sb, 32); - mv_t rv = gsub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), &sb, pval3); - free(sb_finish(&sb)); + string_builder_t *psb = sb_alloc(MV_SB_ALLOC_LENGTH); + mv_t rv = gsub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), psb, pval3); + sb_free(psb); regfree(®ex); return rv; } diff --git a/c/mapping/mlr_val.h b/c/mapping/mlr_val.h index 0b711d8b5..a84b5d91d 100644 --- a/c/mapping/mlr_val.h +++ b/c/mapping/mlr_val.h @@ -25,6 +25,8 @@ #define MT_STRING 5 #define MT_MAX 6 +#define MV_SB_ALLOC_LENGTH 32 + typedef struct _mlr_val_t { union { int boolv; diff --git a/c/unit_test/test_string_builder.c b/c/unit_test/test_string_builder.c index ee050b13e..c4b55d56a 100644 --- a/c/unit_test/test_string_builder.c +++ b/c/unit_test/test_string_builder.c @@ -11,8 +11,7 @@ int assertions_failed = 0; // ---------------------------------------------------------------- static char * test_simple() { - string_builder_t sb; - string_builder_t* psb = &sb; + string_builder_t* psb = sb_alloc(1); sb_init(psb, 1); mu_assert("error: case 0", streq("", sb_finish(psb)));