From fc64c7510bdda9d99bc453424a2384759aefb318 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Fri, 11 Sep 2015 20:07:22 -0400 Subject: [PATCH] allow ORS/OFS/OPS to be multi-char --- c/cli/mlrcli.c | 82 ++++++++++++++++++++++------------ c/cli/mlrcli.h | 6 +-- c/output/lrec_writer_csv.c | 10 ++--- c/output/lrec_writer_csvlite.c | 22 ++++----- c/output/lrec_writer_dkvp.c | 20 ++++----- c/output/lrec_writer_nidx.c | 18 ++++---- c/output/lrec_writer_pprint.c | 1 + c/output/lrec_writers.h | 8 ++-- 8 files changed, 97 insertions(+), 70 deletions(-) diff --git a/c/cli/mlrcli.c b/c/cli/mlrcli.c index f9df7c4aa..1dbd78d37 100644 --- a/c/cli/mlrcli.c +++ b/c/cli/mlrcli.c @@ -43,9 +43,9 @@ static mapper_setup_t* mapper_lookup_table[] = { static int mapper_lookup_table_length = sizeof(mapper_lookup_table) / sizeof(mapper_lookup_table[0]); // ---------------------------------------------------------------- -#define DEFAULT_RS '\n' -#define DEFAULT_FS ',' -#define DEFAULT_PS '=' +#define DEFAULT_RS "\n" +#define DEFAULT_FS "," +#define DEFAULT_PS "=" #define DEFAULT_OFMT "%lf" @@ -89,8 +89,8 @@ static void main_usage(char* argv0, int exit_code) { fprintf(o, " -p is a keystroke-saver for --nidx --fs space --repifs\n"); fprintf(o, "Separator options, for input, output, or both:\n"); fprintf(o, " --rs --irs --ors Record separators, defaulting to newline\n"); - fprintf(o, " --fs --ifs --ofs --repifs Field separators, defaulting to \"%c\"\n", DEFAULT_FS); - fprintf(o, " --ps --ips --ops Pair separators, defaulting to \"%c\"\n", DEFAULT_PS); + fprintf(o, " --fs --ifs --ofs --repifs Field separators, defaulting to \"%s\"\n", DEFAULT_FS); + fprintf(o, " --ps --ips --ops Pair separators, defaulting to \"%s\"\n", DEFAULT_PS); fprintf(o, " Notes (as of Miller v2.0.0):\n"); fprintf(o, " * RS/FS/PS are used for DKVP, NIDX, and CSVLITE formats where they must be single-character.\n"); fprintf(o, " * For CSV, PPRINT, and XTAB formats, RS/FS/PS command-line options are ignored.\n"); @@ -119,6 +119,14 @@ static void main_usage(char* argv0, int exit_code) { exit(exit_code); } +static char xxx_temp_check_single_char_separator(char* sep, char* argv0) { + if (strlen(sep) != 1) { + main_usage(argv0, 1); + } + return sep[0]; +} + + static void usage_all_verbs(char* argv0) { char* separator = "================================================================"; @@ -143,28 +151,38 @@ static void check_arg_count(char** argv, int argi, int argc, int n) { } } -static char sep_from_arg(char* arg, char* argv0) { +static char* sep_from_arg(char* arg, char* argv0) { + if (streq(arg, "cr")) + return "\r"; + if (streq(arg, "lf")) + return "\n"; + if (streq(arg, "lflf")) + return "\n\n"; + if (streq(arg, "crlf")) + return "\r\n"; + if (streq(arg, "crlfcrlf")) + return "\r\n\r\n"; if (streq(arg, "tab")) - return '\t'; + return "\t"; + if (streq(arg, "tab")) + return "\t"; if (streq(arg, "space")) - return ' '; + return " "; if (streq(arg, "comma")) - return ','; + return ","; if (streq(arg, "newline")) - return '\n'; + return "\n"; if (streq(arg, "pipe")) - return '|'; + return "|"; if (streq(arg, "slash")) - return '/'; + return "/"; if (streq(arg, "colon")) - return ':'; + return ":"; if (streq(arg, "semicolon")) - return '|'; + return "|"; if (streq(arg, "equals")) - return '='; - if (strlen(arg) != 1) - main_usage(argv0, 1); - return arg[0]; + return "="; + return arg; } static mapper_setup_t* look_up_mapper_setup(char* verb) { @@ -182,9 +200,9 @@ cli_opts_t* parse_command_line(int argc, char** argv) { cli_opts_t* popts = mlr_malloc_or_die(sizeof(cli_opts_t)); memset(popts, 0, sizeof(*popts)); - popts->irs = DEFAULT_RS; - popts->ifs = DEFAULT_FS; - popts->ips = DEFAULT_PS; + popts->irs = DEFAULT_RS[0]; // xxx temp + popts->ifs = DEFAULT_FS[0]; + popts->ips = DEFAULT_PS[0]; popts->allow_repeat_ifs = FALSE; popts->allow_repeat_ips = FALSE; @@ -231,12 +249,14 @@ cli_opts_t* parse_command_line(int argc, char** argv) { else if (streq(argv[argi], "--rs")) { check_arg_count(argv, argi, argc, 2); - popts->ors = popts->irs = sep_from_arg(argv[argi+1], argv[0]); + //popts->ors = popts->irs = sep_from_arg(argv[argi+1], argv[0]); // xxx temp + popts->ors = sep_from_arg(argv[argi+1], argv[0]); + popts->irs = xxx_temp_check_single_char_separator(sep_from_arg(argv[argi+1], argv[0]), argv[0]); argi++; } else if (streq(argv[argi], "--irs")) { check_arg_count(argv, argi, argc, 2); - popts->irs = sep_from_arg(argv[argi+1], argv[0]); + popts->irs = xxx_temp_check_single_char_separator(sep_from_arg(argv[argi+1], argv[0]), argv[0]); argi++; } else if (streq(argv[argi], "--ors")) { @@ -247,12 +267,15 @@ cli_opts_t* parse_command_line(int argc, char** argv) { else if (streq(argv[argi], "--fs")) { check_arg_count(argv, argi, argc, 2); - popts->ofs = popts->ifs = sep_from_arg(argv[argi+1], argv[0]); + // xxx temp + //popts->ofs = popts->ifs[0] = sep_from_arg(argv[argi+1], argv[0]); + popts->ofs = sep_from_arg(argv[argi+1], argv[0]); + popts->ifs = xxx_temp_check_single_char_separator(sep_from_arg(argv[argi+1], argv[0]), argv[0]); argi++; } else if (streq(argv[argi], "--ifs")) { check_arg_count(argv, argi, argc, 2); - popts->ifs = sep_from_arg(argv[argi+1], argv[0]); + popts->ifs = xxx_temp_check_single_char_separator(sep_from_arg(argv[argi+1], argv[0]), argv[0]); argi++; } else if (streq(argv[argi], "--ofs")) { @@ -268,18 +291,21 @@ cli_opts_t* parse_command_line(int argc, char** argv) { popts->ifmt = "nidx"; ofmt = "nidx"; popts->ifs = ' '; - popts->ofs = ' '; + popts->ofs = " "; popts->allow_repeat_ifs = TRUE; } else if (streq(argv[argi], "--ps")) { check_arg_count(argv, argi, argc, 2); - popts->ops = popts->ips = sep_from_arg(argv[argi+1], argv[0]); + // xxx temp + // popts->ops = popts->ips[0] = sep_from_arg(argv[argi+1], argv[0]); + popts->ops = sep_from_arg(argv[argi+1], argv[0]); + popts->ips = xxx_temp_check_single_char_separator(sep_from_arg(argv[argi+1], argv[0]), argv[0]); argi++; } else if (streq(argv[argi], "--ips")) { check_arg_count(argv, argi, argc, 2); - popts->ips = sep_from_arg(argv[argi+1], argv[0]); + popts->ips = xxx_temp_check_single_char_separator(sep_from_arg(argv[argi+1], argv[0]), argv[0]); argi++; } else if (streq(argv[argi], "--ops")) { diff --git a/c/cli/mlrcli.h b/c/cli/mlrcli.h index 63477d3a6..3d9209799 100644 --- a/c/cli/mlrcli.h +++ b/c/cli/mlrcli.h @@ -25,9 +25,9 @@ typedef struct _cli_opts_t { int use_mmap_for_read; char* ifmt; - char ors; - char ofs; - char ops; + char* ors; + char* ofs; + char* ops; char* ofmt; int oquoting; diff --git a/c/output/lrec_writer_csv.c b/c/output/lrec_writer_csv.c index c89abe9fc..c805907fb 100644 --- a/c/output/lrec_writer_csv.c +++ b/c/output/lrec_writer_csv.c @@ -13,8 +13,8 @@ static void quote_numeric_output_func(FILE* fp, char* string, char* ors, char* o typedef struct _lrec_writer_csv_state_t { int onr; - char *ors; // xxx char -> char* - char *ofs; // xxx char -> char* + char *ors; + char *ofs; int orslen; int ofslen; quoted_output_func_t* pquoted_output_func; @@ -78,13 +78,13 @@ static void lrec_writer_csv_free(void* pvstate) { } } -lrec_writer_t* lrec_writer_csv_alloc(char ors, char ofs, int oquoting) { +lrec_writer_t* lrec_writer_csv_alloc(char* ors, char* ofs, int oquoting) { lrec_writer_t* plrec_writer = mlr_malloc_or_die(sizeof(lrec_writer_t)); lrec_writer_csv_state_t* pstate = mlr_malloc_or_die(sizeof(lrec_writer_csv_state_t)); pstate->onr = 0; - //pstate->ors = ors; - //pstate->ofs = ofs; + //pstate->ors = ors; + //pstate->ofs = ofs; pstate->ors = "\r\n"; // xxx temp pstate->ofs = ","; // xxx temp pstate->orslen = strlen(pstate->ors); diff --git a/c/output/lrec_writer_csvlite.c b/c/output/lrec_writer_csvlite.c index c608ffce1..cdf5538dd 100644 --- a/c/output/lrec_writer_csvlite.c +++ b/c/output/lrec_writer_csvlite.c @@ -4,9 +4,9 @@ #include "output/lrec_writers.h" typedef struct _lrec_writer_csvlite_state_t { - int onr; - char ors; - char ofs; + int onr; + char* ors; + char* ofs; long long num_header_lines_output; slls_t* plast_header_output; } lrec_writer_csvlite_state_t; @@ -18,8 +18,8 @@ static void lrec_writer_csvlite_process(FILE* output_stream, lrec_t* prec, void* if (prec == NULL) return; lrec_writer_csvlite_state_t* pstate = pvstate; - char ors = pstate->ors; - char ofs = pstate->ofs; + char* ors = pstate->ors; + char* ofs = pstate->ofs; if (pstate->plast_header_output != NULL) { // xxx make a fcn to compare these w/o copy: put it in mixutil. @@ -27,7 +27,7 @@ static void lrec_writer_csvlite_process(FILE* output_stream, lrec_t* prec, void* slls_free(pstate->plast_header_output); pstate->plast_header_output = NULL; if (pstate->num_header_lines_output > 0LL) - fputc(ors, output_stream); + fputs(ors, output_stream); } } @@ -35,11 +35,11 @@ static void lrec_writer_csvlite_process(FILE* output_stream, lrec_t* prec, void* int nf = 0; for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) { if (nf > 0) - fputc(ofs, output_stream); + fputs(ofs, output_stream); fputs(pe->key, output_stream); nf++; } - fputc(ors, output_stream); + fputs(ors, output_stream); pstate->plast_header_output = mlr_copy_keys_from_record(prec); pstate->num_header_lines_output++; } @@ -47,11 +47,11 @@ static void lrec_writer_csvlite_process(FILE* output_stream, lrec_t* prec, void* int nf = 0; for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) { if (nf > 0) - fputc(ofs, output_stream); + fputs(ofs, output_stream); fputs(pe->value, output_stream); nf++; } - fputc(ors, output_stream); + fputs(ors, output_stream); pstate->onr++; lrec_free(prec); // xxx cmt mem-mgmt @@ -65,7 +65,7 @@ static void lrec_writer_csvlite_free(void* pvstate) { } } -lrec_writer_t* lrec_writer_csvlite_alloc(char ors, char ofs) { +lrec_writer_t* lrec_writer_csvlite_alloc(char* ors, char* ofs) { lrec_writer_t* plrec_writer = mlr_malloc_or_die(sizeof(lrec_writer_t)); lrec_writer_csvlite_state_t* pstate = mlr_malloc_or_die(sizeof(lrec_writer_csvlite_state_t)); diff --git a/c/output/lrec_writer_dkvp.c b/c/output/lrec_writer_dkvp.c index f49d85d2f..3e3f8cc82 100644 --- a/c/output/lrec_writer_dkvp.c +++ b/c/output/lrec_writer_dkvp.c @@ -3,9 +3,9 @@ #include "output/lrec_writers.h" typedef struct _lrec_writer_dkvp_state_t { - char rs; - char fs; - char ps; + char* rs; + char* fs; + char* ps; } lrec_writer_dkvp_state_t; // ---------------------------------------------------------------- @@ -13,27 +13,27 @@ static void lrec_writer_dkvp_process(FILE* output_stream, lrec_t* prec, void* pv if (prec == NULL) return; lrec_writer_dkvp_state_t* pstate = pvstate; - char rs = pstate->rs; - char fs = pstate->fs; - char ps = pstate->ps; + char* rs = pstate->rs; + char* fs = pstate->fs; + char* ps = pstate->ps; int nf = 0; for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) { if (nf > 0) - fputc(fs, output_stream); + fputs(fs, output_stream); fputs(pe->key, output_stream); - fputc(ps, output_stream); + fputs(ps, output_stream); fputs(pe->value, output_stream); nf++; } - fputc(rs, output_stream); + fputs(rs, output_stream); lrec_free(prec); // xxx cmt mem-mgmt } static void lrec_writer_dkvp_free(void* pvstate) { } -lrec_writer_t* lrec_writer_dkvp_alloc(char rs, char fs, char ps) { +lrec_writer_t* lrec_writer_dkvp_alloc(char* rs, char* fs, char* ps) { lrec_writer_t* plrec_writer = mlr_malloc_or_die(sizeof(lrec_writer_t)); lrec_writer_dkvp_state_t* pstate = mlr_malloc_or_die(sizeof(lrec_writer_dkvp_state_t)); diff --git a/c/output/lrec_writer_nidx.c b/c/output/lrec_writer_nidx.c index 85b476193..1ea8e6e74 100644 --- a/c/output/lrec_writer_nidx.c +++ b/c/output/lrec_writer_nidx.c @@ -3,8 +3,8 @@ #include "output/lrec_writers.h" typedef struct _lrec_writer_nidx_state_t { - char rs; - char fs; + char* ors; + char* ofs; } lrec_writer_nidx_state_t; // ---------------------------------------------------------------- @@ -12,29 +12,29 @@ static void lrec_writer_nidx_process(FILE* output_stream, lrec_t* prec, void* pv if (prec == NULL) return; lrec_writer_nidx_state_t* pstate = pvstate; - char rs = pstate->rs; - char fs = pstate->fs; + char* ors = pstate->ors; + char* ofs = pstate->ofs; int nf = 0; for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) { if (nf > 0) - fputc(fs, output_stream); + fputs(ofs, output_stream); fputs(pe->value, output_stream); nf++; } - fputc(rs, output_stream); + fputs(ors, output_stream); lrec_free(prec); // xxx cmt mem-mgmt } static void lrec_writer_nidx_free(void* pvstate) { } -lrec_writer_t* lrec_writer_nidx_alloc(char rs, char fs) { +lrec_writer_t* lrec_writer_nidx_alloc(char* ors, char* ofs) { lrec_writer_t* plrec_writer = mlr_malloc_or_die(sizeof(lrec_writer_t)); lrec_writer_nidx_state_t* pstate = mlr_malloc_or_die(sizeof(lrec_writer_nidx_state_t)); - pstate->rs = rs; - pstate->fs = fs; + pstate->ors = ors; + pstate->ofs = ofs; plrec_writer->pvstate = (void*)pstate; plrec_writer->pprocess_func = &lrec_writer_nidx_process; diff --git a/c/output/lrec_writer_pprint.c b/c/output/lrec_writer_pprint.c index 2b8a7fd2c..2fff373c6 100644 --- a/c/output/lrec_writer_pprint.c +++ b/c/output/lrec_writer_pprint.c @@ -16,6 +16,7 @@ typedef struct _lrec_writer_pprint_state_t { static void print_and_free_record_list(sllv_t* precords, FILE* output_stream, int left_align); // ---------------------------------------------------------------- +// xxx use ORS here static void lrec_writer_pprint_process(FILE* output_stream, lrec_t* prec, void* pvstate) { lrec_writer_pprint_state_t* pstate = pvstate; diff --git a/c/output/lrec_writers.h b/c/output/lrec_writers.h index 737cfaf0e..8fc4c1653 100644 --- a/c/output/lrec_writers.h +++ b/c/output/lrec_writers.h @@ -2,10 +2,10 @@ #define LREC_WRITERS_H #include "output/lrec_writer.h" -lrec_writer_t* lrec_writer_csv_alloc(char rs, char fs, int oquoting); -lrec_writer_t* lrec_writer_csvlite_alloc(char rs, char fs); -lrec_writer_t* lrec_writer_dkvp_alloc(char rs, char fs, char ps); -lrec_writer_t* lrec_writer_nidx_alloc(char rs, char fs); +lrec_writer_t* lrec_writer_csv_alloc(char* rs, char* fs, int oquoting); +lrec_writer_t* lrec_writer_csvlite_alloc(char* rs, char* fs); +lrec_writer_t* lrec_writer_dkvp_alloc(char* rs, char* fs, char* ps); +lrec_writer_t* lrec_writer_nidx_alloc(char* rs, char* fs); lrec_writer_t* lrec_writer_pprint_alloc(int left_align); lrec_writer_t* lrec_writer_xtab_alloc();