Expand description
The JSON string decoder a .db JSON-brace value goes through — C’s yajl.
A .db field value has two escape regimes, and they are NOT the same
function:
- a QUOTED value (
field(VAL,"a\tb")) —dbLexRoutines.c:1398strips the quotes and runscrate::runtime::epics_string::raw_from_escaped(CdbTranslateEscape→epicsStrnRawFromEscaped); - a JSON-BRACE value (
field(INP,{const:"a\tb"})) —dbLexRoutines.c:1398deliberately leaves it alone (theiftests for a leading quote), because the text is handed todbParseLink→dbJLinkInit→dbJLinkParse, which feeds it to yajl; yajl’s lexer flags a string with escapes andyajl_parser.c:273-281decodes it throughyajl_string_decode(yajl_encode.c:136-215) before the jlifstringcallback ever sees it (lnkConst.c:199).
The port carried the brace text verbatim all the way into the record, so
every JSON link carrying an escaped string — {const:"…"} seeds,
{pva:{pv:"…"}} targets — reached the record with its backslashes intact.
Measured, softIoc 7.0.10 (linux-x86_64), dbgf (which re-escapes for
display, so a stored backslash prints DOUBLED):
record(stringin,"J1"){field(DTYP,"Soft Channel") field(INP,{const:"a\tb"})}
dbgf J1.VAL -> "a\tb" i.e. stored a, TAB, b
record(stringin,"J2"){field(DTYP,"Soft Channel") field(INP,{const:"x\\ny"})}
dbgf J2.VAL -> "x\\ny" i.e. stored x, BACKSLASH, n, y(caget/caget-rs are NOT oracles here: both print a DBF_STRING through
epicsStrnEscapedFromRaw — tool_lib.c:135, cli.rs:834 — so a stored TAB
comes back on screen as \t and reads exactly like an untranslated escape.)
Functions§
- decode_
json_ string - C
yajl_string_decode(yajl_encode.c:136-215): decode the CONTENT of a JSON string (no surrounding quotes). - decode_
json_ string_ token - A JSON string TOKEN — quotes included — decoded.
Nonewhentokis not a quoted string (a number,true, an object, …): C’s jlifstringcallback is simply not the one yajl calls for those.