single-quoting faqent

This commit is contained in:
John Kerl 2017-03-15 20:32:36 -04:00
parent f493593699
commit a528350849
5 changed files with 163 additions and 8 deletions

View file

@ -3,7 +3,8 @@
#include "input/mlr_json_adapter.h"
static lrec_t* validate_millerable_object(json_value_t* pjson_object, char* flatten_sep, int json_skip_arrays_on_input);
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep);
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep,
int json_skip_arrays_on_input);
// ----------------------------------------------------------------
int reference_json_objects_as_lrecs(sllv_t* precords, json_value_t* ptop_level_json, char* flatten_sep,
@ -65,7 +66,7 @@ lrec_t* validate_millerable_object(json_value_t* pjson, char* flatten_sep, int j
case JSON_OBJECT:
// This could be made more efficient ... the string length is in the json_value_t.
prefix = mlr_paste_2_strings(key, flatten_sep);
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep);
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep, json_skip_arrays_on_input);
free(prefix);
break;
case JSON_ARRAY:
@ -104,7 +105,10 @@ lrec_t* validate_millerable_object(json_value_t* pjson, char* flatten_sep, int j
// Example: the JSON object has { "a": { "b" : 1, "c" : 2 } }. Then we add "a:b" => "1" and "a:c" => "2"
// to the lrec.
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep) {
// xxx retval
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep,
int json_skip_arrays_on_input)
{
int n = pjson_object->u.object.length;
for (int i = 0; i < n; i++) {
json_object_entry_t* pobject_entry = &pjson_object->u.object.p.values[i];
@ -128,14 +132,69 @@ static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object
break;
case JSON_OBJECT:
prefix = mlr_paste_2_strings(lrec_key, flatten_sep);
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep);
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep, json_skip_arrays_on_input);
free(prefix);
free(lrec_key);
break;
case JSON_ARRAY:
fprintf(stderr,
"%s: found array item within JSON object. This is valid but unmillerable JSON.\n",
MLR_GLOBALS.bargv0);
if (!json_skip_arrays_on_input) {
fprintf(stderr,
"%s: found array item within JSON object. This is valid but unmillerable JSON.\n",
MLR_GLOBALS.bargv0);
}
break;
case JSON_INTEGER:
lrec_put(prec, lrec_key, pjson_value->u.integer.sval, FREE_ENTRY_KEY);
break;
case JSON_DOUBLE:
lrec_put(prec, lrec_key, pjson_value->u.dbl.sval, FREE_ENTRY_KEY);
break;
default:
MLR_INTERNAL_CODING_ERROR();
break;
}
}
}
// xxx retval
/*xxx temp static*/
void populate_from_nested_array(lrec_t* prec, json_value_t* pjson_array, char* prefix, char* flatten_sep,
int json_skip_arrays_on_input)
{
int n = pjson_array->u.array.length;
for (int i = 0; i < n; i++) {
json_value_t* pjson_value = &pjson_array->u.array.p.values[i];
// xxx char* json_key = (char*)pobject_entry->name;
char* json_key = "temp"; // xxx temp
char* lrec_key = mlr_paste_2_strings(prefix, json_key);
char* prefix = NULL;
switch (pjson_value->type) {
case JSON_NONE:
lrec_put(prec, lrec_key, "", FREE_ENTRY_KEY);
break;
case JSON_NULL:
lrec_put(prec, lrec_key, "", FREE_ENTRY_KEY);
break;
case JSON_STRING:
lrec_put(prec, lrec_key, pjson_value->u.string.ptr, FREE_ENTRY_KEY);
break;
case JSON_BOOLEAN:
lrec_put(prec, lrec_key, pjson_value->u.boolean.sval, FREE_ENTRY_KEY);
break;
case JSON_OBJECT:
prefix = mlr_paste_2_strings(lrec_key, flatten_sep);
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep, json_skip_arrays_on_input);
free(prefix);
free(lrec_key);
break;
case JSON_ARRAY:
if (!json_skip_arrays_on_input) {
fprintf(stderr,
"%s: found array item within JSON object. This is valid but unmillerable JSON.\n",
MLR_GLOBALS.bargv0);
}
break;
case JSON_INTEGER:
lrec_put(prec, lrec_key, pjson_value->u.integer.sval, FREE_ENTRY_KEY);

View file

@ -8,7 +8,7 @@ BUGFIXES
! windows port
! eddelbuettel ac error <-> smith aclocal-1.15?
* eddelbuettel ac error <-> smith aclocal-1.15?
* --mmap / --no-mmap double-regression loop
o also "." the setup funcs

View file

@ -85,6 +85,43 @@ POKI_RUN_COMMAND{{echo x,y,z | mlr --dkvp rename 2,999}}HERE
POKI_RUN_COMMAND{{echo x,y,z | mlr --dkvp rename 2,newname}}HERE
POKI_RUN_COMMAND{{echo x,y,z | mlr --csv --implicit-csv-header reorder -f 3,1,2}}HERE
</div>
<h1>How can I put single-quotes into strings?</h1>
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_single_quotes_in_strings');" href="javascript:;">Toggle section visibility</button>
<div id="section_toggle_single_quotes_in_strings" style="display: block">
<p/> This is a little tricky due to the shell&rsquo;s handling of quotes. For simplicity, let&rsquo;s first put
an update script into a file:
POKI_INCLUDE_ESCAPED(data/single-quote-example.mlr)HERE
POKI_RUN_COMMAND{{echo a=bcd | mlr put -f data/single-quote-example.mlr}}HERE
<p/>So, it&rsuoq;s simple: Miller&rsquo;s DSL uses double quotes for strings,
and you can put single quotes (or backslash-escaped double-quotes) inside
strings, no problem.
<p/> Without putting the update expression in a file, it&rsquo;s messier:
POKI_RUN_COMMAND{{echo a=bcd | mlr put '$a="It'\''s OK, I said, '\''for now'\''."'}}HERE
<p/> The idea is that the outermost single-quotes are to protect the
<tt>put</tt> expression from the shell, and the double quotes within them are
for Miller. To get a single quote in the middle there, you need to actually put it <i>outside</i> the single-quoting
for the shell. The pieces are
<ul>
<li/> <tt>$a="It</tt>
<li/> <tt>\'</tt>
<li/> <tt>s OK, I said,</tt>
<li/> <tt>\'</tt>
<li/> <tt>for now</tt>
<li/> <tt>\'</tt>
<li/> <tt>.</tt>
</ul>
all concatenated together.
</div>
<h1>Why doesn&rsquo;t mlr cut put fields in the order I want?</h1>
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_cut_out_of_order');" href="javascript:;">Toggle section visibility</button>

View file

@ -0,0 +1 @@
$a = "It's OK, I said, then 'for now'."

View file

@ -192,6 +192,7 @@ Miller commands were run with pretty-print-tabular output format.
&bull;&nbsp;<a href="#Diagnosing_delimiter_specifications">Diagnosing delimiter specifications</a><br/>
&bull;&nbsp;<a href="#How_do_I_examine_then-chaining?">How do I examine then-chaining?</a><br/>
&bull;&nbsp;<a href="#I_assigned_$9_and_it&rsquo;s_not_9th">I assigned $9 and it&rsquo;s not 9th</a><br/>
&bull;&nbsp;<a href="#How_can_I_put_single-quotes_into_strings?">How can I put single-quotes into strings?</a><br/>
&bull;&nbsp;<a href="#Why_doesn&rsquo;t_mlr_cut_put_fields_in_the_order_I_want?">Why doesn&rsquo;t mlr cut put fields in the order I want?</a><br/>
&bull;&nbsp;<a href="#NR_is_not_consecutive_after_then-chaining">NR is not consecutive after then-chaining</a><br/>
&bull;&nbsp;<a href="#Why_am_I_not_seeing_all_possible_joins_occur?">Why am I not seeing all possible joins occur?</a><br/>
@ -442,6 +443,63 @@ z,x,y
</div>
<p/>
</div>
<a id="How_can_I_put_single-quotes_into_strings?"/><h1>How can I put single-quotes into strings?</h1>
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_single_quotes_in_strings');" href="javascript:;">Toggle section visibility</button>
<div id="section_toggle_single_quotes_in_strings" style="display: block">
<p/> This is a little tricky due to the shell&rsquo;s handling of quotes. For simplicity, let&rsquo;s first put
an update script into a file:
<p/>
<div class="pokipanel">
<pre>
$a = "It's OK, I said, then 'for now'."
</pre>
</div>
<p/>
<p/>
<div class="pokipanel">
<pre>
$ echo a=bcd | mlr put -f data/single-quote-example.mlr
a=It's OK, I said, then 'for now'.
</pre>
</div>
<p/>
<p/>So, it&rsuoq;s simple: Miller&rsquo;s DSL uses double quotes for strings,
and you can put single quotes (or backslash-escaped double-quotes) inside
strings, no problem.
<p/> Without putting the update expression in a file, it&rsquo;s messier:
<p/>
<div class="pokipanel">
<pre>
$ echo a=bcd | mlr put '$a="It'\''s OK, I said, '\''for now'\''."'
a=It's OK, I said, 'for now'.
</pre>
</div>
<p/>
<p/> The idea is that the outermost single-quotes are to protect the
<tt>put</tt> expression from the shell, and the double quotes within them are
for Miller. To get a single quote in the middle there, you need to actually put it <i>outside</i> the single-quoting
for the shell. The pieces are
<ul>
<li/> <tt>$a="It</tt>
<li/> <tt>\'</tt>
<li/> <tt>s OK, I said,</tt>
<li/> <tt>\'</tt>
<li/> <tt>for now</tt>
<li/> <tt>\'</tt>
<li/> <tt>.</tt>
</ul>
all concatenated together.
</div>
<a id="Why_doesn&rsquo;t_mlr_cut_put_fields_in_the_order_I_want?"/><h1>Why doesn&rsquo;t mlr cut put fields in the order I want?</h1>
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_cut_out_of_order');" href="javascript:;">Toggle section visibility</button>