leading-zero-decimal JSON-compliant output

This commit is contained in:
John Kerl 2016-02-11 11:20:58 -05:00
parent 0da8ae84d7
commit eec8cc732c
6 changed files with 40 additions and 23 deletions

View file

@ -37,6 +37,8 @@ static void mlhmmv_level_print_stacked(mlhmmv_level_t* plevel, int depth,
static void mlhmmv_level_print_single_line(mlhmmv_level_t* plevel, int depth,
int do_final_comma, int quote_values_always);
static void json_decimal_print(char* s);
static int mlhmmv_hash_func(mv_t* plevel_key);
// ----------------------------------------------------------------
@ -355,7 +357,7 @@ static void mlhmmv_level_enlarge(mlhmmv_level_t* plevel) {
// xxx rename to have 'json' in the method name
void mlhmmv_print_stacked(mlhmmv_t* pmap, int quote_values_always) {
void mlhmmv_print_json_stacked(mlhmmv_t* pmap, int quote_values_always) {
mlhmmv_level_print_stacked(pmap->proot_level, 0, FALSE, quote_values_always);
}
@ -380,9 +382,8 @@ static void mlhmmv_level_print_stacked(mlhmmv_level_t* plevel, int depth,
printf("\"%s\"", level_value_string);
} else if (pentry->level_value.u.mlrval.type == MT_STRING) {
double unused;
// xxx insert leading '0' if starts with '.'; insert leading '-0' if starts with '-.'.
if (mlr_try_float_from_string(level_value_string, &unused))
printf("%s", level_value_string);
json_decimal_print(level_value_string);
else if (streq(level_value_string, "true") || streq(level_value_string, "false"))
printf("%s", level_value_string);
else
@ -411,7 +412,7 @@ static void mlhmmv_level_print_stacked(mlhmmv_level_t* plevel, int depth,
}
// ----------------------------------------------------------------
void mlhmmv_print_single_line(mlhmmv_t* pmap, int quote_values_always) {
void mlhmmv_print_json_single_line(mlhmmv_t* pmap, int quote_values_always) {
mlhmmv_level_print_single_line(pmap->proot_level, 0, FALSE, quote_values_always);
printf("\n");
}
@ -435,7 +436,7 @@ static void mlhmmv_level_print_single_line(mlhmmv_level_t* plevel, int depth,
} else if (pentry->level_value.u.mlrval.type == MT_STRING) {
double unused;
if (mlr_try_float_from_string(level_value_string, &unused))
printf("%s", level_value_string);
json_decimal_print(level_value_string);
else if (streq(level_value_string, "true") || streq(level_value_string, "false"))
printf("%s", level_value_string);
else
@ -459,6 +460,21 @@ static void mlhmmv_level_print_single_line(mlhmmv_level_t* plevel, int depth,
printf(" }");
}
// ----------------------------------------------------------------
// 0.123 is valid JSON; .123 is not. Meanwhile is a format-converter tool so if there is
// perfectly legitimate CSV/DKVP/etc. data to be JSON-formatted, we make it JSON-compliant.
//
// Precondition: the caller has already checked that the string represents a number.
static void json_decimal_print(char* s) {
if (s[0] == '.') {
printf("0%s", s);
} else if (s[0] == '-' && s[1] == '.') {
printf("-0.%s", &s[2]);
} else {
printf("%s", s);
}
}
// ----------------------------------------------------------------
typedef int mlhmmv_typed_hash_func(mv_t* pa);

View file

@ -76,7 +76,7 @@ void mlhmmv_put(mlhmmv_t* pmap, sllmv_t* pmvkeys, mv_t* pterminal_value);
// The caller shouldn't free it, or modify it.
mv_t* mlhmmv_get(mlhmmv_t* pmap, sllmv_t* pmvkeys, int* perror);
void mlhmmv_print_stacked(mlhmmv_t* pmap, int quote_values_always);
void mlhmmv_print_single_line(mlhmmv_t* pmap, int quote_values_always);
void mlhmmv_print_json_stacked(mlhmmv_t* pmap, int quote_values_always);
void mlhmmv_print_json_single_line(mlhmmv_t* pmap, int quote_values_always);
#endif // MLHMMV_H

View file

@ -347,7 +347,7 @@ static void evaluate_statements(
sllv_append(poutrecs, prec_to_emit);
} else if (node_type == MD_AST_NODE_TYPE_DUMP) {
mlhmmv_print_stacked(pstate->poosvars, FALSE);
mlhmmv_print_json_stacked(pstate->poosvars, FALSE);
} else if (node_type == MD_AST_NODE_TYPE_FILTER) {
mlr_dsl_cst_statement_item_t* pitem = pstatement->pitems->phead->pvvalue;

View file

@ -77,9 +77,9 @@ static void lrec_writer_json_process(FILE* output_stream, lrec_t* prec, void* pv
}
if (pstate->stack_vertically)
mlhmmv_print_stacked(pmap, pstate->quote_json_values_always);
mlhmmv_print_json_stacked(pmap, pstate->quote_json_values_always);
else
mlhmmv_print_single_line(pmap, pstate->quote_json_values_always);
mlhmmv_print_json_single_line(pmap, pstate->quote_json_values_always);
mlhmmv_free(pmap);

View file

@ -10,6 +10,7 @@ TOP-OF-LIST SUMMARY
! rh/fedora/centos mlr-3.3.2: after patch-file for manpage
* parameterized emit: needs spec & impl
* pattern-action: note that breaks the simple LHS/RHS partition I've enjoyed up until now
* valgrinds
* explode & any other komosas from feature-request task

View file

@ -27,7 +27,7 @@ static char* test_no_overlap() {
printf("----------------------------------------------------------------\n");
printf("empty map:\n");
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
sllmv_t* pmvkeys1 = sllmv_single(imv(3));
mv_t value1 = mv_from_int(4LL);
@ -37,7 +37,7 @@ static char* test_no_overlap() {
printf("value1: %s\n", mv_alloc_format_val(&value1));
mlhmmv_put(pmap, pmvkeys1, &value1);
printf("map:\n");
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys1, &error), &value1));
sllmv_t* pmvkeys2 = sllmv_double(smv("abcde"), imv(-6));
@ -48,7 +48,7 @@ static char* test_no_overlap() {
printf("value2: %s\n", mv_alloc_format_val(&value2));
mlhmmv_put(pmap, pmvkeys2, &value2);
printf("map:\n");
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys2, &error), &value2));
sllmv_t* pmvkeys3 = sllmv_triple(imv(0), smv("fghij"), imv(0));
@ -59,7 +59,7 @@ static char* test_no_overlap() {
printf("value3: %s\n", mv_alloc_format_val(&value3));
mlhmmv_put(pmap, pmvkeys3, &value3);
printf("map:\n");
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys3, &error), &value3));
sllmv_free(pmvkeys1);
@ -76,35 +76,35 @@ static char* test_overlap() {
sllmv_t* pmvkeys = sllmv_single(imv(3));
mv_t* ptermval = imv(4);
mlhmmv_put(pmap, pmvkeys, ptermval);
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys, &error), ptermval));
ptermval = imv(5);
mlhmmv_put(pmap, pmvkeys, ptermval);
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys, &error), ptermval));
pmvkeys = sllmv_double(imv(3), smv("x"));
ptermval = imv(6);
mlhmmv_put(pmap, pmvkeys, ptermval);
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys, &error), ptermval));
ptermval = imv(7);
mlhmmv_put(pmap, pmvkeys, ptermval);
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys, &error), ptermval));
pmvkeys = sllmv_triple(imv(3), imv(9), smv("y"));
ptermval = smv("z");
mlhmmv_put(pmap, pmvkeys, ptermval);
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys, &error), ptermval));
pmvkeys = sllmv_triple(imv(3), imv(9), smv("z"));
ptermval = smv("y");
mlhmmv_put(pmap, pmvkeys, ptermval);
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
mu_assert_lf(mv_equals_si(mlhmmv_get(pmap, pmvkeys, &error), ptermval));
mlhmmv_free(pmap);
@ -119,17 +119,17 @@ static char* test_resize() {
printf("----------------------------------------------------------------\n");
for (int i = 0; i < 2*MLHMMV_INITIAL_ARRAY_LENGTH; i++)
mlhmmv_put(pmap, sllmv_single(imv(i)), imv(-i));
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
printf("\n");
for (int i = 0; i < 2*MLHMMV_INITIAL_ARRAY_LENGTH; i++)
mlhmmv_put(pmap, sllmv_double(smv("a"), imv(i)), imv(-i));
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
printf("\n");
for (int i = 0; i < 2*MLHMMV_INITIAL_ARRAY_LENGTH; i++)
mlhmmv_put(pmap, sllmv_triple(imv(i*100), imv(i % 4), smv("b")), smv("term"));
mlhmmv_print_stacked(pmap, FALSE);
mlhmmv_print_json_stacked(pmap, FALSE);
sllmv_t* pmvkeys = sllmv_single(imv(2));
mv_t* ptermval = imv(-2);