mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-29 02:30:12 +00:00
allow ORS/OFS/OPS to be multi-char
This commit is contained in:
parent
008d4adabf
commit
fc64c7510b
8 changed files with 97 additions and 70 deletions
|
|
@ -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")) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue