Skip to content

Commit

Permalink
add serialize option -p/--position (#82)
Browse files Browse the repository at this point in the history
  • Loading branch information
liquidaty authored Nov 22, 2022
1 parent 6f75955 commit 05c00f7
Show file tree
Hide file tree
Showing 3 changed files with 88,113 additions and 10 deletions.
45 changes: 36 additions & 9 deletions app/serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ struct serialize_data {
size_t len;
unsigned char case_insensitive:1;
unsigned char entire:1;
unsigned dummy:6;
unsigned _:6;
} filter;
unsigned char use_column_position:1;
unsigned char _:7;
};

struct output_header_name *get_output_header_name(struct serialize_data *data,
Expand All @@ -76,9 +78,14 @@ static void serialize_cell(void *hook, unsigned char *utf8_value, size_t len) {
if(!h)
asprintf(&data->err_msg, "Out of memory!");
else {
if((h->str = malloc(1 + len))) {
memcpy(h->str, utf8_value, len);
h->str[len] = '\0';
// save the column header name
if(data->use_column_position)
asprintf((char **)&h->str, "%u", data->current_col_index);
else {
if((h->str = malloc(1 + len))) {
memcpy(h->str, utf8_value, len);
h->str[len] = '\0';
}
}
h->next = data->temp_header_names;
data->temp_header_names = h;
Expand Down Expand Up @@ -166,13 +173,28 @@ static void serialize_row(void *hook) {
for(struct serialize_header_name *hn = data->temp_header_names; hn; hn = hn->next, i++, j--) {
if((data->header_names[j-1].str = hn->str)) {
if((data->header_names[j-1].output_str =
zsv_writer_str_to_csv(hn->str, strlen((char *)hn->str))))
zsv_writer_str_to_csv(hn->str, strlen((char *)hn->str))))
data->header_names[j-1].output_len =
strlen((char *)data->header_names[j-1].output_str);
}
hn->str = NULL;
}
}

if(data->use_column_position) {
// process the header row as if it was a data row
data->current_col_index = 0;
for(unsigned int i = 0; i < data->col_count; i++) {
struct zsv_cell cell = zsv_get_cell(data->parser, i);
// write row ID
zsv_writer_cell_s(data->csv_writer, 1, (const unsigned char *)"Header", 0);
// write column name
zsv_writer_cell(data->csv_writer, 0, data->header_names[i].str,
data->header_names[i].output_len, 0);
// write cell value
zsv_writer_cell(data->csv_writer, 0, cell.str, cell.len, cell.quoted);
}
}
}

if(data->row_id) {
Expand All @@ -192,10 +214,13 @@ const char *serialize_usage_msg[] =
"Serializes a CSV file",
"",
"Options:",
" -b: output with BOM",
" -f <value>, --filter <value>: only output cells with text that contains the given value",
" -i, --case-insensitive: use case-insensitive match for the filter value",
" -e, --entire: match the entire cell's content",
" -b : output with BOM",
" -f,--filter <value> : only output cells with text that contains the given value",
" -e,--entire : match the entire cell's content (only applicable with -f)",
" -i,--case-insensitive : use case-insensitive match for the filter value",
" -p,--position : output column position instead of name; the second column",
" will be position 1, and the first row will be treated as a",
" normal data row",
NULL
};

Expand Down Expand Up @@ -249,6 +274,8 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
}
} else if(!strcmp(arg, "-i") || !strcmp(arg, "--case-insensitive"))
data.filter.case_insensitive = 1;
else if(!strcmp(arg, "-p") || !strcmp(arg, "--position"))
data.use_column_position = 1;
else if(!strcmp(arg, "-e") || !strcmp(arg, "--entire"))
data.filter.entire = 1;
else if(!strcmp(argv[arg_i], "-b"))
Expand Down
12 changes: 11 additions & 1 deletion app/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,23 @@ test-stack2: ${BUILD_DIR}/bin/zsv_stack${EXE}
@${PREFIX} $< ${TEST_DATA_DIR}/stack2-[12].csv ${REDIRECT} ${TMP_DIR}/$@.out
@${CMP} ${TMP_DIR}/$@.out expected/$@.out && ${TEST_PASS} || ${TEST_FAIL}

test-2tsv test-sql test-serialize test-flatten test-pretty : test-%: ${BUILD_DIR}/bin/zsv_%${EXE}
test-2tsv test-sql test-flatten test-pretty : test-%: ${BUILD_DIR}/bin/zsv_%${EXE}
@${TEST_INIT}
@( ( ! [ -s "${TEST_DATA_DIR}/test/$*.csv" ] ) && echo "No test input for $*") || \
(${PREFIX} $< ${ARGS-$*} < ${TEST_DATA_DIR}/test/$*.csv ${REDIRECT1} ${TMP_DIR}/$@.out && \
${CMP} ${TMP_DIR}/$@.out expected/$@.out && ${TEST_PASS} || ${TEST_FAIL})
# @if [ "$@" = "test-2tsv" ] ; then echo "TO DO: update 2tsv to output Excel format-- see data/Excel.tsv"; fi

test-serialize : test-%: ${BUILD_DIR}/bin/zsv_%${EXE}
@${TEST_INIT}
@( ( ! [ -s "${TEST_DATA_DIR}/test/$*.csv" ] ) && echo "No test input for $*") || \
(${PREFIX} $< < ${TEST_DATA_DIR}/test/$*.csv ${REDIRECT1} ${TMP_DIR}/$@.out && \
${CMP} ${TMP_DIR}/$@.out expected/$@.out && ${TEST_PASS} || ${TEST_FAIL})

(${PREFIX} $< -p < ${TEST_DATA_DIR}/test/$*.csv ${REDIRECT1} ${TMP_DIR}/$@-2.out && \
${CMP} ${TMP_DIR}/$@-2.out expected/$@-2.out && ${TEST_PASS} || ${TEST_FAIL})


test-sql: test-sql2 test-sql3 test-sql4
test-sql2: ${BUILD_DIR}/bin/zsv_sql${EXE}
@${TEST_INIT}
Expand Down
Loading

0 comments on commit 05c00f7

Please sign in to comment.