LLVMFuzzerTestOneInput:
   27|  2.93k|{//gpsd/tests//test_json.c
   28|       |
   29|  2.93k|    if (Size < kMinInputLength || Size > kMaxInputLength){
  ------------------
  |  |   21|  5.86k|#define kMinInputLength 10
  ------------------
                  if (Size < kMinInputLength || Size > kMaxInputLength){
  ------------------
  |  |   22|  2.92k|#define kMaxInputLength 5120
  ------------------
  |  Branch (29:9): [True: 6, False: 2.92k]
  |  Branch (29:35): [True: 19, False: 2.90k]
  ------------------
   30|     25|        return 0;
   31|     25|    }
   32|       |
   33|  2.90k|    uint8_t *DataFx;
   34|  2.90k|    size_t SizeFx = Size+1;
   35|  2.90k|    DataFx = (uint8_t *)calloc(SizeFx,sizeof(uint8_t));
   36|       |
   37|  2.90k|    memcpy((void *)DataFx,(void *)Data,Size);
   38|       |
   39|  2.90k|    char AddCB[] ={0x7b}; //{
   40|  2.90k|    memcpy((void *)DataFx,(void *)AddCB,sizeof(AddCB));
   41|       |//calloc already added 0x00 at the end of DataFx.
   42|       |
   43|  2.90k|    int status;
   44|  2.90k|    {
   45|  2.90k|        memset((void *)&gpsdata, 0, sizeof(gpsdata));
   46|  2.90k|        status = libgps_json_unpack((char *)DataFx, &gpsdata, NULL);
   47|  2.90k|    }
   48|  2.90k|    {
   49|  2.90k|        memset((void *)&gpsdata, 0, sizeof(gpsdata));
   50|  2.90k|        status = json_toff_read((char *)DataFx, &gpsdata, NULL);
   51|  2.90k|    }
   52|       |
   53|  2.90k|    free(DataFx);
   54|       |
   55|  2.90k|    return status;
   56|  2.93k|}

libgps_json.c:str_starts_with:
   18|  19.6k|{
   19|  19.6k|    return 0 == strncmp(str, prefix, strlen(prefix));
   20|  19.6k|}

json_ais_read:
   42|    323|{
   43|       |    // collected but not actually used yet
   44|    323|    bool scaled;
   45|       |
   46|    323|#define AIS_HEADER \
   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
   49|    323|        {"device",         t_string,   .addr.string = path, \
   50|    323|                                          .len = pathlen}, \
   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
   53|    323|                                          .dflt.boolean = false}, \
   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
   55|       |
   56|    323|#define AIS_TYPE6 \
   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
   58|    323|                                       .dflt.uinteger = 0},\
   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
   60|    323|                                       .dflt.uinteger = 0},\
   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
   62|    323|                                       .dflt.boolean = false},\
   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
   64|    323|                                       .dflt.uinteger = 0},\
   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
   66|    323|                                       .dflt.uinteger = 0},
   67|    323|#define AIS_TYPE8 \
   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
   69|    323|                                       .dflt.uinteger = 0},\
   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
   71|    323|                                       .dflt.uinteger = 0},
   72|       |
   73|    323|    int status;
   74|       |
   75|    323|#include "ais_json.i"           // JSON parser template structures
  ------------------
  |  |    1|       |/*
  |  |    2|       | * This is code generated by jsongen.py. Do not hand-hack it!
  |  |    3|       | */
  |  |    4|    323| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |    5|       |
  |  |    6|       |
  |  |    7|    323|    const struct json_attr_t json_ais1[] = {
  |  |    8|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |    9|    323|	{"status",        t_uinteger,  .addr.uinteger = &ais->type1.status,
  |  |   10|    323|                                       .dflt.uinteger = 0},
  |  |   11|    323|	{"status_text",   t_ignore},
  |  |   12|    323|	{"turn",          t_integer,   .addr.integer = &ais->type1.turn,
  |  |   13|    323|                                       .dflt.integer = AIS_TURN_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1548|    323|#define AIS_TURN_NOT_AVAILABLE  128
  |  |  ------------------
  |  |   14|    323|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type1.speed,
  |  |   15|    323|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1550|    323|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |   16|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type1.accuracy,
  |  |   17|    323|                                       .dflt.boolean = false},
  |  |   18|    323|	{"lon",           t_integer,   .addr.integer = &ais->type1.lon,
  |  |   19|    323|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1555|    323|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |   20|    323|	{"lat",           t_integer,   .addr.integer = &ais->type1.lat,
  |  |   21|    323|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1557|    323|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |   22|    323|	{"course",        t_uinteger,  .addr.uinteger = &ais->type1.course,
  |  |   23|    323|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1559|    323|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |   24|    323|	{"heading",       t_uinteger,  .addr.uinteger = &ais->type1.heading,
  |  |   25|    323|                                       .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1561|    323|#define AIS_HEADING_NOT_AVAILABLE       511
  |  |  ------------------
  |  |   26|    323|	{"second",        t_uinteger,  .addr.uinteger = &ais->type1.second,
  |  |   27|    323|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1566|    323|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |   28|    323|	{"maneuver",      t_uinteger,  .addr.uinteger = &ais->type1.maneuver,
  |  |   29|    323|                                       .dflt.uinteger = AIS_SEC_INOPERATIVE},
  |  |  ------------------
  |  |  |  | 1569|    323|#define AIS_SEC_INOPERATIVE     63
  |  |  ------------------
  |  |   30|    323|	{"raim",          t_boolean,   .addr.boolean = &ais->type1.raim,
  |  |   31|    323|                                       .dflt.boolean = false},
  |  |   32|    323|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type1.radio,
  |  |   33|    323|                                       .dflt.uinteger = 0},
  |  |   34|    323|        {NULL}
  |  |   35|    323|    };
  |  |   36|       |
  |  |   37|    323|    char timestamp[JSON_VAL_MAX+1];
  |  |   38|    323|    const struct json_attr_t json_ais4[] = {
  |  |   39|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |   40|    323|	{"timestamp",     t_string,    .addr.string = timestamp,
  |  |   41|    323|                                       .len = sizeof(timestamp)},
  |  |   42|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type4.accuracy,
  |  |   43|    323|                                       .dflt.boolean = true},
  |  |   44|    323|	{"lon",           t_integer,   .addr.integer = &ais->type4.lon,
  |  |   45|    323|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1555|    323|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |   46|    323|	{"lat",           t_integer,   .addr.integer = &ais->type4.lat,
  |  |   47|    323|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1557|    323|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |   48|    323|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type4.epfd,
  |  |   49|    323|                                       .dflt.uinteger = 0},
  |  |   50|    323|	{"epfd_text",   t_ignore},
  |  |   51|    323|	{"raim",          t_boolean,   .addr.boolean = &ais->type4.raim,
  |  |   52|    323|                                       .dflt.boolean = false},
  |  |   53|    323|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type4.radio,
  |  |   54|    323|                                       .dflt.uinteger = 0},
  |  |   55|    323|        {NULL}
  |  |   56|    323|    };
  |  |   57|       |
  |  |   58|    323|    char eta[JSON_VAL_MAX+1];
  |  |   59|    323|    const struct json_attr_t json_ais5[] = {
  |  |   60|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |   61|    323|	{"imo",           t_uinteger,  .addr.uinteger = &ais->type5.imo,
  |  |   62|    323|                                       .dflt.uinteger = 0},
  |  |   63|    323|	{"ais_version",   t_uinteger,  .addr.uinteger = &ais->type5.ais_version,
  |  |   64|    323|                                       .dflt.uinteger = 0},
  |  |   65|    323|	{"callsign",      t_string,    .addr.string = ais->type5.callsign,
  |  |   66|    323|                                       .len = sizeof(ais->type5.callsign)},
  |  |   67|    323|	{"shipname",      t_string,    .addr.string = ais->type5.shipname,
  |  |   68|    323|                                       .len = sizeof(ais->type5.shipname)},
  |  |   69|    323|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type5.shiptype,
  |  |   70|    323|                                       .dflt.uinteger = 0},
  |  |   71|    323|	{"shiptype_text",   t_ignore},
  |  |   72|    323|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type5.to_bow,
  |  |   73|    323|                                       .dflt.uinteger = 0},
  |  |   74|    323|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type5.to_stern,
  |  |   75|    323|                                       .dflt.uinteger = 0},
  |  |   76|    323|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type5.to_port,
  |  |   77|    323|                                       .dflt.uinteger = 0},
  |  |   78|    323|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type5.to_starboard,
  |  |   79|    323|                                       .dflt.uinteger = 0},
  |  |   80|    323|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type5.epfd,
  |  |   81|    323|                                       .dflt.uinteger = 0},
  |  |   82|    323|	{"epfd_text",   t_ignore},
  |  |   83|    323|	{"eta",           t_string,    .addr.string = eta,
  |  |   84|    323|                                       .len = sizeof(eta)},
  |  |   85|    323|	{"draught",       t_uinteger,  .addr.uinteger = &ais->type5.draught,
  |  |   86|    323|                                       .dflt.uinteger = 0},
  |  |   87|    323|	{"destination",   t_string,    .addr.string = ais->type5.destination,
  |  |   88|    323|                                       .len = sizeof(ais->type5.destination)},
  |  |   89|    323|	{"dte",           t_uinteger,  .addr.uinteger = &ais->type5.dte,
  |  |   90|    323|                                       .dflt.uinteger = 1},
  |  |   91|    323|        {NULL}
  |  |   92|    323|    };
  |  |   93|       |
  |  |   94|    323|    char data[JSON_VAL_MAX+1];
  |  |   95|    323|    const struct json_attr_t json_ais6[] = {
  |  |   96|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |   97|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |   98|    323|	{"data",          t_string,    .addr.string = data,
  |  |   99|    323|                                       .len = sizeof(data)},
  |  |  100|    323|        {NULL}
  |  |  101|    323|    };
  |  |  102|       |
  |  |  103|    323|    const struct json_attr_t json_ais6_fid10[] = {
  |  |  104|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  105|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  106|    323|	{"ana_int",       t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.ana_int,
  |  |  107|    323|                                       .dflt.uinteger = 0},
  |  |  108|    323|	{"ana_ext1",      t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.ana_ext1,
  |  |  109|    323|                                       .dflt.uinteger = 0},
  |  |  110|    323|	{"ana_ext2",      t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.ana_ext2,
  |  |  111|    323|                                       .dflt.uinteger = 0},
  |  |  112|    323|	{"racon",         t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.racon,
  |  |  113|    323|                                       .dflt.uinteger = 0},
  |  |  114|    323|	{"racon_text",   t_ignore},
  |  |  115|    323|	{"light",         t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.light,
  |  |  116|    323|                                       .dflt.uinteger = 0},
  |  |  117|    323|	{"light_text",   t_ignore},
  |  |  118|    323|	{"alarm",         t_boolean,   .addr.boolean = &ais->type6.dac235fid10.alarm,
  |  |  119|    323|                                       .dflt.boolean = false},
  |  |  120|    323|	{"stat_ext",      t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.stat_ext,
  |  |  121|    323|                                       .dflt.uinteger = 0},
  |  |  122|    323|	{"off_pos",       t_boolean,   .addr.boolean = &ais->type6.dac235fid10.off_pos,
  |  |  123|    323|                                       .dflt.boolean = false},
  |  |  124|    323|        {NULL}
  |  |  125|    323|    };
  |  |  126|       |
  |  |  127|    323|    char departure[JSON_VAL_MAX+1];
  |  |  128|    323|    const struct json_attr_t json_ais6_fid12[] = {
  |  |  129|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  130|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  131|    323|	{"lastport",      t_string,    .addr.string = ais->type6.dac1fid12.lastport,
  |  |  132|    323|                                       .len = sizeof(ais->type6.dac1fid12.lastport)},
  |  |  133|    323|	{"departure",     t_string,    .addr.string = departure,
  |  |  134|    323|                                       .len = sizeof(departure)},
  |  |  135|    323|	{"nextport",      t_string,    .addr.string = ais->type6.dac1fid12.nextport,
  |  |  136|    323|                                       .len = sizeof(ais->type6.dac1fid12.nextport)},
  |  |  137|    323|	{"eta",           t_string,    .addr.string = eta,
  |  |  138|    323|                                       .len = sizeof(eta)},
  |  |  139|    323|	{"dangerous",     t_string,    .addr.string = ais->type6.dac1fid12.dangerous,
  |  |  140|    323|                                       .len = sizeof(ais->type6.dac1fid12.dangerous)},
  |  |  141|    323|	{"imdcat",        t_string,    .addr.string = ais->type6.dac1fid12.imdcat,
  |  |  142|    323|                                       .len = sizeof(ais->type6.dac1fid12.imdcat)},
  |  |  143|    323|	{"unid",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid12.unid,
  |  |  144|    323|                                       .dflt.uinteger = 0},
  |  |  145|    323|	{"amount",        t_uinteger,  .addr.uinteger = &ais->type6.dac1fid12.amount,
  |  |  146|    323|                                       .dflt.uinteger = 0},
  |  |  147|    323|	{"unit",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid12.unit,
  |  |  148|    323|                                       .dflt.uinteger = 0},
  |  |  149|    323|        {NULL}
  |  |  150|    323|    };
  |  |  151|       |
  |  |  152|    323|    const struct json_attr_t json_ais6_fid15[] = {
  |  |  153|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  154|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  155|    323|	{"airdraught",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid15.airdraught,
  |  |  156|    323|                                       .dflt.uinteger = 0},
  |  |  157|    323|        {NULL}
  |  |  158|    323|    };
  |  |  159|       |
  |  |  160|    323|    const struct json_attr_t json_ais6_fid16[] = {
  |  |  161|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  162|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  163|    323|	{"persons",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid16.persons,
  |  |  164|    323|                                       .dflt.uinteger = 0},
  |  |  165|    323|        {NULL}
  |  |  166|    323|    };
  |  |  167|       |
  |  |  168|    323|    char arrival[JSON_VAL_MAX+1];
  |  |  169|    323|    const struct json_attr_t json_ais6_fid18[] = {
  |  |  170|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  171|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  172|    323|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid18.linkage,
  |  |  173|    323|                                       .dflt.uinteger = 0},
  |  |  174|    323|	{"arrival",       t_string,    .addr.string = arrival,
  |  |  175|    323|                                       .len = sizeof(arrival)},
  |  |  176|    323|	{"portname",      t_string,    .addr.string = ais->type6.dac1fid18.portname,
  |  |  177|    323|                                       .len = sizeof(ais->type6.dac1fid18.portname)},
  |  |  178|    323|	{"destination",   t_string,    .addr.string = ais->type6.dac1fid18.destination,
  |  |  179|    323|                                       .len = sizeof(ais->type6.dac1fid18.destination)},
  |  |  180|    323|	{"lon",           t_integer,   .addr.integer = &ais->type6.dac1fid18.lon,
  |  |  181|    323|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1511|    323|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  182|    323|	{"lat",           t_integer,   .addr.integer = &ais->type6.dac1fid18.lat,
  |  |  183|    323|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    323|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  184|    323|        {NULL}
  |  |  185|    323|    };
  |  |  186|       |
  |  |  187|    323|    char berth_name[JSON_VAL_MAX+1];
  |  |  188|    323|    const struct json_attr_t json_ais6_fid20[] = {
  |  |  189|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  190|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  191|    323|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.linkage,
  |  |  192|    323|                                       .dflt.uinteger = 0},
  |  |  193|    323|	{"berth_length",  t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.berth_length,
  |  |  194|    323|                                       .dflt.uinteger = 0},
  |  |  195|    323|	{"berth_depth",   t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.berth_depth,
  |  |  196|    323|                                       .dflt.uinteger = 0},
  |  |  197|    323|	{"position",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.position,
  |  |  198|    323|                                       .dflt.uinteger = 0},
  |  |  199|    323|	{"position_text",   t_ignore},
  |  |  200|    323|	{"arrival",       t_string,    .addr.string = arrival,
  |  |  201|    323|                                       .len = sizeof(arrival)},
  |  |  202|    323|	{"availability",  t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.availability,
  |  |  203|    323|                                       .dflt.uinteger = 0},
  |  |  204|    323|	{"agent",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.agent,
  |  |  205|    323|                                       .dflt.uinteger = 0},
  |  |  206|    323|	{"fuel",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.fuel,
  |  |  207|    323|                                       .dflt.uinteger = 0},
  |  |  208|    323|	{"chandler",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.chandler,
  |  |  209|    323|                                       .dflt.uinteger = 0},
  |  |  210|    323|	{"stevedore",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.stevedore,
  |  |  211|    323|                                       .dflt.uinteger = 0},
  |  |  212|    323|	{"electrical",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.electrical,
  |  |  213|    323|                                       .dflt.uinteger = 0},
  |  |  214|    323|	{"water",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.water,
  |  |  215|    323|                                       .dflt.uinteger = 0},
  |  |  216|    323|	{"customs",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.customs,
  |  |  217|    323|                                       .dflt.uinteger = 0},
  |  |  218|    323|	{"cartage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.cartage,
  |  |  219|    323|                                       .dflt.uinteger = 0},
  |  |  220|    323|	{"crane",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.crane,
  |  |  221|    323|                                       .dflt.uinteger = 0},
  |  |  222|    323|	{"lift",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.lift,
  |  |  223|    323|                                       .dflt.uinteger = 0},
  |  |  224|    323|	{"medical",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.medical,
  |  |  225|    323|                                       .dflt.uinteger = 0},
  |  |  226|    323|	{"navrepair",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.navrepair,
  |  |  227|    323|                                       .dflt.uinteger = 0},
  |  |  228|    323|	{"provisions",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.provisions,
  |  |  229|    323|                                       .dflt.uinteger = 0},
  |  |  230|    323|	{"shiprepair",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.shiprepair,
  |  |  231|    323|                                       .dflt.uinteger = 0},
  |  |  232|    323|	{"surveyor",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.surveyor,
  |  |  233|    323|                                       .dflt.uinteger = 0},
  |  |  234|    323|	{"steam",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.steam,
  |  |  235|    323|                                       .dflt.uinteger = 0},
  |  |  236|    323|	{"tugs",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.tugs,
  |  |  237|    323|                                       .dflt.uinteger = 0},
  |  |  238|    323|	{"solidwaste",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.solidwaste,
  |  |  239|    323|                                       .dflt.uinteger = 0},
  |  |  240|    323|	{"liquidwaste",   t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.liquidwaste,
  |  |  241|    323|                                       .dflt.uinteger = 0},
  |  |  242|    323|	{"hazardouswaste",t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.hazardouswaste,
  |  |  243|    323|                                       .dflt.uinteger = 0},
  |  |  244|    323|	{"ballast",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.ballast,
  |  |  245|    323|                                       .dflt.uinteger = 0},
  |  |  246|    323|	{"additional",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.additional,
  |  |  247|    323|                                       .dflt.uinteger = 0},
  |  |  248|    323|	{"regional1",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.regional1,
  |  |  249|    323|                                       .dflt.uinteger = 0},
  |  |  250|    323|	{"regional2",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.regional2,
  |  |  251|    323|                                       .dflt.uinteger = 0},
  |  |  252|    323|	{"future1",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.future1,
  |  |  253|    323|                                       .dflt.uinteger = 0},
  |  |  254|    323|	{"future2",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.future2,
  |  |  255|    323|                                       .dflt.uinteger = 0},
  |  |  256|    323|	{"berth_name",    t_string,    .addr.string = berth_name,
  |  |  257|    323|                                       .len = sizeof(berth_name)},
  |  |  258|    323|	{"berth_lon",     t_integer,   .addr.integer = &ais->type6.dac1fid20.berth_lon,
  |  |  259|    323|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1511|    323|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  260|    323|	{"berth_lat",     t_integer,   .addr.integer = &ais->type6.dac1fid20.berth_lat,
  |  |  261|    323|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    323|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  262|    323|        {NULL}
  |  |  263|    323|    };
  |  |  264|       |
  |  |  265|    323|    const struct json_attr_t json_ais6_fid21[] = {
  |  |  266|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  267|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  268|    323|	{"country",       t_string,    .addr.string = ais->type6.dac200fid21.country,
  |  |  269|    323|                                       .len = sizeof(ais->type6.dac200fid21.country)},
  |  |  270|    323|	{"locode",        t_string,    .addr.string = ais->type6.dac200fid21.locode,
  |  |  271|    323|                                       .len = sizeof(ais->type6.dac200fid21.locode)},
  |  |  272|    323|	{"section",       t_string,    .addr.string = ais->type6.dac200fid21.section,
  |  |  273|    323|                                       .len = sizeof(ais->type6.dac200fid21.section)},
  |  |  274|    323|	{"terminal",      t_string,    .addr.string = ais->type6.dac200fid21.terminal,
  |  |  275|    323|                                       .len = sizeof(ais->type6.dac200fid21.terminal)},
  |  |  276|    323|	{"hectometre",    t_string,    .addr.string = ais->type6.dac200fid21.hectometre,
  |  |  277|    323|                                       .len = sizeof(ais->type6.dac200fid21.hectometre)},
  |  |  278|    323|	{"eta",           t_string,    .addr.string = eta,
  |  |  279|    323|                                       .len = sizeof(eta)},
  |  |  280|    323|	{"tugs",          t_uinteger,  .addr.uinteger = &ais->type6.dac200fid21.tugs,
  |  |  281|    323|                                       .dflt.uinteger = 0},
  |  |  282|    323|	{"airdraught",    t_uinteger,  .addr.uinteger = &ais->type6.dac200fid21.airdraught,
  |  |  283|    323|                                       .dflt.uinteger = 0},
  |  |  284|    323|        {NULL}
  |  |  285|    323|    };
  |  |  286|       |
  |  |  287|    323|    char rta[JSON_VAL_MAX+1];
  |  |  288|    323|    const struct json_attr_t json_ais6_fid22[] = {
  |  |  289|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  290|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  291|    323|	{"country",       t_string,    .addr.string = ais->type6.dac200fid22.country,
  |  |  292|    323|                                       .len = sizeof(ais->type6.dac200fid22.country)},
  |  |  293|    323|	{"locode",        t_string,    .addr.string = ais->type6.dac200fid22.locode,
  |  |  294|    323|                                       .len = sizeof(ais->type6.dac200fid22.locode)},
  |  |  295|    323|	{"section",       t_string,    .addr.string = ais->type6.dac200fid22.section,
  |  |  296|    323|                                       .len = sizeof(ais->type6.dac200fid22.section)},
  |  |  297|    323|	{"terminal",      t_string,    .addr.string = ais->type6.dac200fid22.terminal,
  |  |  298|    323|                                       .len = sizeof(ais->type6.dac200fid22.terminal)},
  |  |  299|    323|	{"hectometre",    t_string,    .addr.string = ais->type6.dac200fid22.hectometre,
  |  |  300|    323|                                       .len = sizeof(ais->type6.dac200fid22.hectometre)},
  |  |  301|    323|	{"rta",           t_string,    .addr.string = rta,
  |  |  302|    323|                                       .len = sizeof(rta)},
  |  |  303|    323|	{"status",        t_uinteger,  .addr.uinteger = &ais->type6.dac200fid22.status,
  |  |  304|    323|                                       .dflt.uinteger = DAC200FID22_STATUS_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1663|    323|#define DAC200FID22_STATUS_NOT_AVAILABLE        0
  |  |  ------------------
  |  |  305|    323|        {NULL}
  |  |  306|    323|    };
  |  |  307|       |
  |  |  308|    323|    const struct json_attr_t json_ais6_fid25_cargos_subtype[] = {
  |  |  309|    323|	{"code",          t_uinteger,STRUCTOBJECT(struct cargo_t, code),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  310|    323|                                       .dflt.uinteger = 0},
  |  |  311|    323|	{"subtype",       t_uinteger,STRUCTOBJECT(struct cargo_t, subtype),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  312|    323|                                       .dflt.uinteger = 0},
  |  |  313|    323|        {NULL}
  |  |  314|    323|    };
  |  |  315|    323|    const struct json_attr_t json_ais6_fid25[] = {
  |  |  316|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  317|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  318|    323|	{"unit",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid25.unit,
  |  |  319|    323|                                       .dflt.uinteger = 0},
  |  |  320|    323|	{"amount",        t_uinteger,  .addr.uinteger = &ais->type6.dac1fid25.amount,
  |  |  321|    323|                                       .dflt.uinteger = 0},
  |  |  322|    323|	{"cargos",        t_array,     STRUCTARRAY(ais->type6.dac1fid25.cargos, json_ais6_fid25_cargos_subtype, &ais->type6.dac1fid25.ncargos)},
  |  |  ------------------
  |  |  |  |  190|    323|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    323|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    323|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    323|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    323|        .addr.array.count = n, \
  |  |  |  |  195|    323|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    323| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  323|    323|        {NULL}
  |  |  324|    323|    };
  |  |  325|       |
  |  |  326|    323|    char start[JSON_VAL_MAX+1];
  |  |  327|    323|    const struct json_attr_t json_ais6_fid28_waypoints_subtype[] = {
  |  |  328|    323|	{"lon",           t_integer, STRUCTOBJECT(struct waypoint_t, lon),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  329|    323|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    323|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  330|    323|	{"lat",           t_integer, STRUCTOBJECT(struct waypoint_t, lat),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  331|    323|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1517|    323|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  332|    323|        {NULL}
  |  |  333|    323|    };
  |  |  334|    323|    const struct json_attr_t json_ais6_fid28[] = {
  |  |  335|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  336|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  337|    323|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.linkage,
  |  |  338|    323|                                       .dflt.uinteger = 0},
  |  |  339|    323|	{"sender",        t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.sender,
  |  |  340|    323|                                       .dflt.uinteger = 0},
  |  |  341|    323|	{"rtype",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.rtype,
  |  |  342|    323|                                       .dflt.uinteger = 0},
  |  |  343|    323|	{"rtype_text",   t_ignore},
  |  |  344|    323|	{"start",         t_string,    .addr.string = start,
  |  |  345|    323|                                       .len = sizeof(start)},
  |  |  346|    323|	{"duration",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.duration,
  |  |  347|    323|                                       .dflt.uinteger = 0},
  |  |  348|    323|	{"waypoints",     t_array,     STRUCTARRAY(ais->type6.dac1fid28.waypoints, json_ais6_fid28_waypoints_subtype, &ais->type6.dac1fid28.waycount)},
  |  |  ------------------
  |  |  |  |  190|    323|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    323|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    323|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    323|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    323|        .addr.array.count = n, \
  |  |  |  |  195|    323|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    323| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  349|    323|        {NULL}
  |  |  350|    323|    };
  |  |  351|       |
  |  |  352|    323|    const struct json_attr_t json_ais6_fid30[] = {
  |  |  353|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  354|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  355|    323|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid30.linkage,
  |  |  356|    323|                                       .dflt.uinteger = 0},
  |  |  357|    323|	{"text",          t_string,    .addr.string = ais->type6.dac1fid30.text,
  |  |  358|    323|                                       .len = sizeof(ais->type6.dac1fid30.text)},
  |  |  359|    323|        {NULL}
  |  |  360|    323|    };
  |  |  361|       |
  |  |  362|    323|    const struct json_attr_t json_ais6_fid32_tidals_subtype[] = {
  |  |  363|    323|	{"lon",           t_integer, STRUCTOBJECT(struct tidal_t, lon),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  364|    323|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1511|    323|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  365|    323|	{"lat",           t_integer, STRUCTOBJECT(struct tidal_t, lat),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  366|    323|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    323|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  367|    323|	{"from_hour",     t_uinteger,STRUCTOBJECT(struct tidal_t, from_hour),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  368|    323|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1580|    323|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  369|    323|	{"from_min",      t_uinteger,STRUCTOBJECT(struct tidal_t, from_min),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  370|    323|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1586|    323|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  371|    323|	{"to_hour",       t_uinteger,STRUCTOBJECT(struct tidal_t, to_hour),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  372|    323|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1584|    323|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  373|    323|	{"to_min",        t_uinteger,STRUCTOBJECT(struct tidal_t, to_min),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  374|    323|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1586|    323|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  375|    323|	{"cdir",          t_uinteger,STRUCTOBJECT(struct tidal_t, cdir),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  376|    323|                                       .dflt.uinteger = DAC1FID32_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1879|    323|#define DAC1FID32_CDIR_NOT_AVAILABLE     360
  |  |  ------------------
  |  |  377|    323|	{"cspeed",        t_uinteger,STRUCTOBJECT(struct tidal_t, cspeed),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  378|    323|                                       .dflt.uinteger = DAC1FID32_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1881|    323|#define DAC1FID32_CSPEED_NOT_AVAILABLE   127
  |  |  ------------------
  |  |  379|    323|        {NULL}
  |  |  380|    323|    };
  |  |  381|    323|    const struct json_attr_t json_ais6_fid32[] = {
  |  |  382|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  383|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  384|    323|	{"month",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid32.month,
  |  |  385|    323|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1580|    323|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  386|    323|	{"day",           t_uinteger,  .addr.uinteger = &ais->type6.dac1fid32.day,
  |  |  387|    323|                                       .dflt.uinteger = AIS_DAY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1582|    323|#define AIS_DAY_NOT_AVAILABLE   0
  |  |  ------------------
  |  |  388|    323|	{"tidals",        t_array,     STRUCTARRAY(ais->type6.dac1fid32.tidals, json_ais6_fid32_tidals_subtype, &ais->type6.dac1fid32.ntidals)},
  |  |  ------------------
  |  |  |  |  190|    323|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    323|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    323|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    323|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    323|        .addr.array.count = n, \
  |  |  |  |  195|    323|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    323| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  389|    323|        {NULL}
  |  |  390|    323|    };
  |  |  391|       |
  |  |  392|    323|    const struct json_attr_t json_ais6_fid55[] = {
  |  |  393|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  394|    323|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   57|    323|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   58|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   59|    323|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   60|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   61|    323|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   62|    323|                                       .dflt.boolean = false},\
  |  |  |  |   63|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   64|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   65|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   66|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  395|    323|	{"crew",          t_uinteger,  .addr.uinteger = &ais->type6.dac200fid55.crew,
  |  |  396|    323|                                       .dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1670|    323|#define DAC200FID55_COUNT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  397|    323|	{"passengers",    t_uinteger,  .addr.uinteger = &ais->type6.dac200fid55.passengers,
  |  |  398|    323|                                       .dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1670|    323|#define DAC200FID55_COUNT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  399|    323|	{"personnel",     t_uinteger,  .addr.uinteger = &ais->type6.dac200fid55.personnel,
  |  |  400|    323|                                       .dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1670|    323|#define DAC200FID55_COUNT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  401|    323|        {NULL}
  |  |  402|    323|    };
  |  |  403|       |
  |  |  404|    323|    const struct json_attr_t json_ais7[] = {
  |  |  405|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  406|    323|	{"mmsi1",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi1,
  |  |  407|    323|                                       .dflt.uinteger = 0},
  |  |  408|    323|	{"mmsi2",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi2,
  |  |  409|    323|                                       .dflt.uinteger = 0},
  |  |  410|    323|	{"mmsi3",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi3,
  |  |  411|    323|                                       .dflt.uinteger = 0},
  |  |  412|    323|	{"mmsi4",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi4,
  |  |  413|    323|                                       .dflt.uinteger = 0},
  |  |  414|    323|	{"seqno1",        t_uinteger,  .addr.uinteger = &ais->type7.seqno1,
  |  |  415|    323|                                       .dflt.uinteger = 0},
  |  |  416|    323|	{"seqno2",        t_uinteger,  .addr.uinteger = &ais->type7.seqno2,
  |  |  417|    323|                                       .dflt.uinteger = 0},
  |  |  418|    323|	{"seqno3",        t_uinteger,  .addr.uinteger = &ais->type7.seqno3,
  |  |  419|    323|                                       .dflt.uinteger = 0},
  |  |  420|    323|	{"seqno4",        t_uinteger,  .addr.uinteger = &ais->type7.seqno4,
  |  |  421|    323|                                       .dflt.uinteger = 0},
  |  |  422|    323|        {NULL}
  |  |  423|    323|    };
  |  |  424|       |
  |  |  425|    323|    const struct json_attr_t json_ais8[] = {
  |  |  426|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  427|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  428|    323|	{"data",          t_string,    .addr.string = data,
  |  |  429|    323|                                       .len = sizeof(data)},
  |  |  430|    323|        {NULL}
  |  |  431|    323|    };
  |  |  432|       |
  |  |  433|    323|    const struct json_attr_t json_ais8_fid10[] = {
  |  |  434|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  435|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  436|    323|	{"vin",           t_string,    .addr.string = ais->type8.dac200fid10.vin,
  |  |  437|    323|                                       .len = sizeof(ais->type8.dac200fid10.vin)},
  |  |  438|    323|	{"length",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.length,
  |  |  439|    323|                                       .dflt.uinteger = 0},
  |  |  440|    323|	{"beam",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.beam,
  |  |  441|    323|                                       .dflt.uinteger = 0},
  |  |  442|    323|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.shiptype,
  |  |  443|    323|                                       .dflt.uinteger = 0},
  |  |  444|    323|	{"shiptype_text",   t_ignore},
  |  |  445|    323|	{"hazard",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.hazard,
  |  |  446|    323|                                       .dflt.uinteger = 0},
  |  |  447|    323|	{"hazard_text",   t_ignore},
  |  |  448|    323|	{"draught",       t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.draught,
  |  |  449|    323|                                       .dflt.uinteger = 0},
  |  |  450|    323|	{"loaded",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.loaded,
  |  |  451|    323|                                       .dflt.uinteger = 0},
  |  |  452|    323|	{"loaded_text",   t_ignore},
  |  |  453|    323|	{"speed_q",       t_boolean,   .addr.boolean = &ais->type8.dac200fid10.speed_q,
  |  |  454|    323|                                       .dflt.boolean = false},
  |  |  455|    323|	{"course_q",      t_boolean,   .addr.boolean = &ais->type8.dac200fid10.course_q,
  |  |  456|    323|                                       .dflt.boolean = false},
  |  |  457|    323|	{"heading_q",     t_boolean,   .addr.boolean = &ais->type8.dac200fid10.heading_q,
  |  |  458|    323|                                       .dflt.boolean = false},
  |  |  459|    323|        {NULL}
  |  |  460|    323|    };
  |  |  461|       |
  |  |  462|    323|    const struct json_attr_t json_ais8_fid11[] = {
  |  |  463|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  464|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  465|    323|	{"lat",           t_integer,   .addr.integer = &ais->type8.dac1fid11.lat,
  |  |  466|    323|                                       .dflt.integer = DAC1FID11_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1981|    323|#define DAC1FID11_LAT_NOT_AVAILABLE     0x7FFFFF
  |  |  ------------------
  |  |  467|    323|	{"lon",           t_integer,   .addr.integer = &ais->type8.dac1fid11.lon,
  |  |  468|    323|                                       .dflt.integer = DAC1FID11_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1979|    323|#define DAC1FID11_LON_NOT_AVAILABLE     0xFFFFFF
  |  |  ------------------
  |  |  469|    323|	{"timestamp",     t_string,    .addr.string = timestamp,
  |  |  470|    323|                                       .len = sizeof(timestamp)},
  |  |  471|    323|	{"wspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wspeed,
  |  |  472|    323|                                       .dflt.uinteger = DAC1FID11_WSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1987|    323|#define DAC1FID11_WSPEED_NOT_AVAILABLE  127
  |  |  ------------------
  |  |  473|    323|	{"wgust",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wgust,
  |  |  474|    323|                                       .dflt.uinteger = DAC1FID11_WSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1987|    323|#define DAC1FID11_WSPEED_NOT_AVAILABLE  127
  |  |  ------------------
  |  |  475|    323|	{"wdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wdir,
  |  |  476|    323|                                       .dflt.uinteger = DAC1FID11_WDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1990|    323|#define DAC1FID11_WDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  477|    323|	{"wgustdir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wgustdir,
  |  |  478|    323|                                       .dflt.uinteger = DAC1FID11_WDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1990|    323|#define DAC1FID11_WDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  479|    323|	{"airtemp",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.airtemp,
  |  |  480|    323|                                       .dflt.uinteger = DAC1FID11_AIRTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1992|    323|#define DAC1FID11_AIRTEMP_NOT_AVAILABLE 2047
  |  |  ------------------
  |  |  481|    323|	{"humidity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.humidity,
  |  |  482|    323|                                       .dflt.uinteger = DAC1FID11_HUMIDITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1996|    323|#define DAC1FID11_HUMIDITY_NOT_AVAILABLE 127
  |  |  ------------------
  |  |  483|    323|	{"dewpoint",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.dewpoint,
  |  |  484|    323|                                       .dflt.uinteger = DAC1FID11_DEWPOINT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1998|    323|#define DAC1FID11_DEWPOINT_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  485|    323|	{"pressure",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.pressure,
  |  |  486|    323|                                       .dflt.uinteger = DAC1FID11_PRESSURE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2002|    323|#define DAC1FID11_PRESSURE_NOT_AVAILABLE 511
  |  |  ------------------
  |  |  487|    323|	{"pressuretend",  t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.pressuretend,
  |  |  488|    323|                                       .dflt.uinteger = DAC1FID11_PRESSURETREND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2005|    323|#define DAC1FID11_PRESSURETREND_NOT_AVAILABLE 3
  |  |  ------------------
  |  |  489|    323|	{"visibility",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.visibility,
  |  |  490|    323|                                       .dflt.uinteger = DAC1FID11_VISIBILITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2007|    323|#define DAC1FID11_VISIBILITY_NOT_AVAILABLE  255
  |  |  ------------------
  |  |  491|    323|	{"waterlevel",    t_integer,   .addr.integer = &ais->type8.dac1fid11.waterlevel,
  |  |  492|    323|                                       .dflt.integer = DAC1FID11_WATERLEVEL_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2010|    323|#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE  511
  |  |  ------------------
  |  |  493|    323|	{"leveltrend",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.leveltrend,
  |  |  494|    323|                                       .dflt.uinteger = DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2014|    323|#define DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE 3
  |  |  ------------------
  |  |  495|    323|	{"cspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cspeed,
  |  |  496|    323|                                       .dflt.uinteger = DAC1FID11_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2016|    323|#define DAC1FID11_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  497|    323|	{"cdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdir,
  |  |  498|    323|                                       .dflt.uinteger = DAC1FID11_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2019|    323|#define DAC1FID11_CDIR_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  499|    323|	{"cspeed2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cspeed2,
  |  |  500|    323|                                       .dflt.uinteger = DAC1FID11_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2016|    323|#define DAC1FID11_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  501|    323|	{"cdir2",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdir2,
  |  |  502|    323|                                       .dflt.uinteger = DAC1FID11_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2019|    323|#define DAC1FID11_CDIR_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  503|    323|	{"cdepth2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdepth2,
  |  |  504|    323|                                       .dflt.uinteger = DAC1FID11_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2023|    323|#define DAC1FID11_CDEPTH_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  505|    323|	{"cspeed3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cspeed3,
  |  |  506|    323|                                       .dflt.uinteger = DAC1FID11_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2016|    323|#define DAC1FID11_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  507|    323|	{"cdir3",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdir3,
  |  |  508|    323|                                       .dflt.uinteger = DAC1FID11_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2019|    323|#define DAC1FID11_CDIR_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  509|    323|	{"cdepth3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdepth3,
  |  |  510|    323|                                       .dflt.uinteger = DAC1FID11_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2023|    323|#define DAC1FID11_CDEPTH_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  511|    323|	{"waveheight",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.waveheight,
  |  |  512|    323|                                       .dflt.uinteger = DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2028|    323|#define DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  513|    323|	{"waveperiod",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.waveperiod,
  |  |  514|    323|                                       .dflt.uinteger = DAC1FID11_WAVEPERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2031|    323|#define DAC1FID11_WAVEPERIOD_NOT_AVAILABLE 63
  |  |  ------------------
  |  |  515|    323|	{"wavedir",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wavedir,
  |  |  516|    323|                                       .dflt.uinteger = DAC1FID11_WAVEDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2033|    323|#define DAC1FID11_WAVEDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  517|    323|	{"swellheight",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.swellheight,
  |  |  518|    323|                                       .dflt.uinteger = DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2028|    323|#define DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  519|    323|	{"swellperiod",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.swellperiod,
  |  |  520|    323|                                       .dflt.uinteger = DAC1FID11_WAVEPERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2031|    323|#define DAC1FID11_WAVEPERIOD_NOT_AVAILABLE 63
  |  |  ------------------
  |  |  521|    323|	{"swelldir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.swelldir,
  |  |  522|    323|                                       .dflt.uinteger = DAC1FID11_WAVEDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2033|    323|#define DAC1FID11_WAVEDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  523|    323|	{"seastate",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.seastate,
  |  |  524|    323|                                       .dflt.uinteger = DAC1FID11_SEASTATE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2038|    323|#define DAC1FID11_SEASTATE_NOT_AVAILABLE   15
  |  |  ------------------
  |  |  525|    323|	{"watertemp",     t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.watertemp,
  |  |  526|    323|                                       .dflt.uinteger = DAC1FID11_WATERTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2040|    323|#define DAC1FID11_WATERTEMP_NOT_AVAILABLE  1023
  |  |  ------------------
  |  |  527|    323|	{"preciptype",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.preciptype,
  |  |  528|    323|                                       .dflt.uinteger = DAC1FID11_PRECIPTYPE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2044|    323|#define DAC1FID11_PRECIPTYPE_NOT_AVAILABLE  7
  |  |  ------------------
  |  |  529|    323|	{"preciptype_text",   t_ignore},
  |  |  530|    323|	{"salinity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.salinity,
  |  |  531|    323|                                       .dflt.uinteger = DAC1FID11_SALINITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2046|    323|#define DAC1FID11_SALINITY_NOT_AVAILABLE   511
  |  |  ------------------
  |  |  532|    323|	{"ice",           t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.ice,
  |  |  533|    323|                                       .dflt.uinteger = DAC1FID11_ICE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2049|    323|#define DAC1FID11_ICE_NOT_AVAILABLE        3
  |  |  ------------------
  |  |  534|    323|	{"ice_text",   t_ignore},
  |  |  535|    323|        {NULL}
  |  |  536|    323|    };
  |  |  537|       |
  |  |  538|    323|    char closefrom[JSON_VAL_MAX+1];
  |  |  539|    323|    char closeto[JSON_VAL_MAX+1];
  |  |  540|    323|    const struct json_attr_t json_ais8_fid13[] = {
  |  |  541|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  542|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  543|    323|	{"reason",        t_string,    .addr.string = ais->type8.dac1fid13.reason,
  |  |  544|    323|                                       .len = sizeof(ais->type8.dac1fid13.reason)},
  |  |  545|    323|	{"closefrom",     t_string,    .addr.string = closefrom,
  |  |  546|    323|                                       .len = sizeof(closefrom)},
  |  |  547|    323|	{"closeto",       t_string,    .addr.string = closeto,
  |  |  548|    323|                                       .len = sizeof(closeto)},
  |  |  549|    323|	{"radius",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.radius,
  |  |  550|    323|                                       .dflt.uinteger = AIS_DAC1FID13_RADIUS_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2057|    323|#define AIS_DAC1FID13_RADIUS_NOT_AVAILABLE 10001
  |  |  ------------------
  |  |  551|    323|	{"extunit",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.extunit,
  |  |  552|    323|                                       .dflt.uinteger = AIS_DAC1FID13_EXTUNIT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2059|    323|#define AIS_DAC1FID13_EXTUNIT_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  553|    323|	{"fday",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fday,
  |  |  554|    323|                                       .dflt.uinteger = AIS_DAY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1582|    323|#define AIS_DAY_NOT_AVAILABLE   0
  |  |  ------------------
  |  |  555|    323|	{"fmonth",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fmonth,
  |  |  556|    323|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1580|    323|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  557|    323|	{"fhour",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fhour,
  |  |  558|    323|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1584|    323|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  559|    323|	{"fminute",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fminute,
  |  |  560|    323|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1586|    323|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  561|    323|	{"tday",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.tday,
  |  |  562|    323|                                       .dflt.uinteger = AIS_DAY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1582|    323|#define AIS_DAY_NOT_AVAILABLE   0
  |  |  ------------------
  |  |  563|    323|	{"tmonth",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.tmonth,
  |  |  564|    323|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1580|    323|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  565|    323|	{"thour",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.thour,
  |  |  566|    323|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1584|    323|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  567|    323|	{"tminute",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.tminute,
  |  |  568|    323|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1586|    323|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  569|    323|        {NULL}
  |  |  570|    323|    };
  |  |  571|       |
  |  |  572|    323|    const struct json_attr_t json_ais8_fid15[] = {
  |  |  573|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  574|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  575|    323|	{"airdraught",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid15.airdraught,
  |  |  576|    323|                                       .dflt.uinteger = 0},
  |  |  577|    323|        {NULL}
  |  |  578|    323|    };
  |  |  579|       |
  |  |  580|    323|    const struct json_attr_t json_ais8_fid16[] = {
  |  |  581|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  582|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  583|    323|	{"persons",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid16.persons,
  |  |  584|    323|                                       .dflt.uinteger = 0},
  |  |  585|    323|        {NULL}
  |  |  586|    323|    };
  |  |  587|       |
  |  |  588|    323|    const struct json_attr_t json_ais8_fid17_targets_subtype[] = {
  |  |  589|    323|	{"idtype",        t_uinteger,STRUCTOBJECT(struct target_t, idtype),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  590|    323|                                       .dflt.uinteger = DAC1FID17_IDTYPE_OTHER},
  |  |  ------------------
  |  |  |  | 2084|    323|#define DAC1FID17_IDTYPE_OTHER          3
  |  |  ------------------
  |  |  591|    323|	{"id.mmsi",       t_uinteger,STRUCTOBJECT(struct target_t, id.mmsi),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  592|    323|                                       .dflt.uinteger = 0},
  |  |  593|    323|	{"id.imo",        t_uinteger,STRUCTOBJECT(struct target_t, id.imo),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  594|    323|                                       .dflt.uinteger = 0},
  |  |  595|    323|	{"id.callsign",   t_string,  STRUCTOBJECT(struct target_t, id.callsign),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  596|    323|                                       .len = DAC1FID17_ID_LENGTH},
  |  |  ------------------
  |  |  |  | 2089|    323|#define DAC1FID17_ID_LENGTH             7
  |  |  ------------------
  |  |  597|    323|	{"id.other",      t_string,  STRUCTOBJECT(struct target_t, id.other),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  598|    323|                                       .len = DAC1FID17_ID_LENGTH},
  |  |  ------------------
  |  |  |  | 2089|    323|#define DAC1FID17_ID_LENGTH             7
  |  |  ------------------
  |  |  599|    323|	{"lat",           t_integer, STRUCTOBJECT(struct target_t, lat),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  600|    323|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    323|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  601|    323|	{"lon",           t_integer, STRUCTOBJECT(struct target_t, lon),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  602|    323|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1511|    323|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  603|    323|	{"course",        t_uinteger,STRUCTOBJECT(struct target_t, course),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  604|    323|                                       .dflt.uinteger = DAC1FID17_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2096|    323|#define DAC1FID17_COURSE_NOT_AVAILABLE  360
  |  |  ------------------
  |  |  605|    323|	{"second",        t_uinteger,STRUCTOBJECT(struct target_t, second),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  606|    323|                                       .dflt.uinteger = AIS_SECOND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1588|    323|#define AIS_SECOND_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  607|    323|	{"speed",         t_uinteger,STRUCTOBJECT(struct target_t, speed),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  608|    323|                                       .dflt.uinteger = DAC1FID17_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2099|    323|#define DAC1FID17_SPEED_NOT_AVAILABLE   255
  |  |  ------------------
  |  |  609|    323|        {NULL}
  |  |  610|    323|    };
  |  |  611|    323|    const struct json_attr_t json_ais8_fid17[] = {
  |  |  612|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  613|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  614|    323|	{"targets",       t_array,     STRUCTARRAY(ais->type8.dac1fid17.targets, json_ais8_fid17_targets_subtype, &ais->type8.dac1fid17.ntargets)},
  |  |  ------------------
  |  |  |  |  190|    323|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    323|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    323|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    323|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    323|        .addr.array.count = n, \
  |  |  |  |  195|    323|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    323| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  615|    323|        {NULL}
  |  |  616|    323|    };
  |  |  617|       |
  |  |  618|    323|    const struct json_attr_t json_ais8_fid19[] = {
  |  |  619|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  620|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  621|    323|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.linkage,
  |  |  622|    323|                                       .dflt.uinteger = 0},
  |  |  623|    323|	{"station",       t_string,    .addr.string = ais->type8.dac1fid19.station,
  |  |  624|    323|                                       .len = sizeof(ais->type8.dac1fid19.station)},
  |  |  625|    323|	{"lon",           t_integer,   .addr.integer = &ais->type8.dac1fid19.lon,
  |  |  626|    323|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1511|    323|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  627|    323|	{"lat",           t_integer,   .addr.integer = &ais->type8.dac1fid19.lat,
  |  |  628|    323|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    323|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  629|    323|	{"status",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.status,
  |  |  630|    323|                                       .dflt.uinteger = 0},
  |  |  631|    323|	{"signal",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.signal,
  |  |  632|    323|                                       .dflt.uinteger = 0},
  |  |  633|    323|	{"signal_text",   t_ignore},
  |  |  634|    323|	{"hour",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.hour,
  |  |  635|    323|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1584|    323|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  636|    323|	{"minute",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.minute,
  |  |  637|    323|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1586|    323|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  638|    323|	{"nextsignal",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.nextsignal,
  |  |  639|    323|                                       .dflt.uinteger = 0},
  |  |  640|    323|	{"nextsignal_type",   t_ignore},
  |  |  641|    323|        {NULL}
  |  |  642|    323|    };
  |  |  643|       |
  |  |  644|    323|    char end[JSON_VAL_MAX+1];
  |  |  645|    323|    const struct json_attr_t json_ais8_fid23[] = {
  |  |  646|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  647|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  648|    323|	{"start",         t_string,    .addr.string = start,
  |  |  649|    323|                                       .len = sizeof(start)},
  |  |  650|    323|	{"end",           t_string,    .addr.string = end,
  |  |  651|    323|                                       .len = sizeof(end)},
  |  |  652|    323|	{"start_lon",     t_integer,   .addr.integer = &ais->type8.dac200fid23.start_lon,
  |  |  653|    323|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    323|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  654|    323|	{"start_lat",     t_integer,   .addr.integer = &ais->type8.dac200fid23.start_lat,
  |  |  655|    323|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1517|    323|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  656|    323|	{"end_lon",       t_integer,   .addr.integer = &ais->type8.dac200fid23.end_lon,
  |  |  657|    323|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    323|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  658|    323|	{"end_lat",       t_integer,   .addr.integer = &ais->type8.dac200fid23.end_lat,
  |  |  659|    323|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1517|    323|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  660|    323|	{"type",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid23.type,
  |  |  661|    323|                                       .dflt.uinteger = DAC200FID23_TYPE_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1940|    323|#define DAC200FID23_TYPE_UNKNOWN        0
  |  |  ------------------
  |  |  662|    323|	{"type_text",   t_ignore},
  |  |  663|    323|	{"min",           t_integer,   .addr.integer = &ais->type8.dac200fid23.min,
  |  |  664|    323|                                       .dflt.integer = DAC200FID23_MIN_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1942|    323|#define DAC200FID23_MIN_UNKNOWN         255
  |  |  ------------------
  |  |  665|    323|	{"max",           t_integer,   .addr.integer = &ais->type8.dac200fid23.max,
  |  |  666|    323|                                       .dflt.integer = DAC200FID23_MAX_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1944|    323|#define DAC200FID23_MAX_UNKNOWN         255
  |  |  ------------------
  |  |  667|    323|	{"intensity",     t_uinteger,  .addr.uinteger = &ais->type8.dac200fid23.intensity,
  |  |  668|    323|                                       .dflt.uinteger = DAC200FID23_CLASS_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1946|    323|#define DAC200FID23_CLASS_UNKNOWN       0
  |  |  ------------------
  |  |  669|    323|	{"intensity_text",   t_ignore},
  |  |  670|    323|	{"wind",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid23.wind,
  |  |  671|    323|                                       .dflt.uinteger = DAC200FID23_WIND_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1948|    323|#define DAC200FID23_WIND_UNKNOWN        0
  |  |  ------------------
  |  |  672|    323|	{"wind_text",   t_ignore},
  |  |  673|    323|        {NULL}
  |  |  674|    323|    };
  |  |  675|       |
  |  |  676|    323|    const struct json_attr_t json_ais8_fid24_gauges_subtype[] = {
  |  |  677|    323|	{"id",            t_uinteger,STRUCTOBJECT(struct gauge_t, id),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  678|    323|                                       .dflt.uinteger = DAC200FID24_GAUGE_ID_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1955|    323|#define DAC200FID24_GAUGE_ID_UNKNOWN    0
  |  |  ------------------
  |  |  679|    323|	{"level",         t_integer, STRUCTOBJECT(struct gauge_t, level),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  680|    323|                                       .dflt.integer = DAC200FID24_GAUGE_LEVEL_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1957|    323|#define DAC200FID24_GAUGE_LEVEL_UNKNOWN 0
  |  |  ------------------
  |  |  681|    323|        {NULL}
  |  |  682|    323|    };
  |  |  683|    323|    const struct json_attr_t json_ais8_fid24[] = {
  |  |  684|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  685|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  686|    323|	{"country",       t_string,    .addr.string = ais->type8.dac200fid24.country,
  |  |  687|    323|                                       .len = sizeof(ais->type8.dac200fid24.country)},
  |  |  688|    323|	{"gauges",        t_array,     STRUCTARRAY(ais->type8.dac200fid24.gauges, json_ais8_fid24_gauges_subtype, &ais->type8.dac200fid24.ngauges)},
  |  |  ------------------
  |  |  |  |  190|    323|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    323|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    323|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    323|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    323|        .addr.array.count = n, \
  |  |  |  |  195|    323|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    323| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  689|    323|        {NULL}
  |  |  690|    323|    };
  |  |  691|       |
  |  |  692|    323|    const struct json_attr_t json_ais8_fid27_waypoints_subtype[] = {
  |  |  693|    323|	{"lon",           t_integer, STRUCTOBJECT(struct waypoint_t, lon),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  694|    323|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    323|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  695|    323|	{"lat",           t_integer, STRUCTOBJECT(struct waypoint_t, lat),
  |  |  ------------------
  |  |  |  |  188|    323|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  696|    323|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1517|    323|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  697|    323|        {NULL}
  |  |  698|    323|    };
  |  |  699|    323|    const struct json_attr_t json_ais8_fid27[] = {
  |  |  700|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  701|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  702|    323|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.linkage,
  |  |  703|    323|                                       .dflt.uinteger = 0},
  |  |  704|    323|	{"sender",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.sender,
  |  |  705|    323|                                       .dflt.uinteger = 0},
  |  |  706|    323|	{"rtype",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.rtype,
  |  |  707|    323|                                       .dflt.uinteger = 0},
  |  |  708|    323|	{"rtype_text",   t_ignore},
  |  |  709|    323|	{"start",         t_string,    .addr.string = start,
  |  |  710|    323|                                       .len = sizeof(start)},
  |  |  711|    323|	{"duration",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.duration,
  |  |  712|    323|                                       .dflt.uinteger = 0},
  |  |  713|    323|	{"waypoints",     t_array,     STRUCTARRAY(ais->type8.dac1fid27.waypoints, json_ais8_fid27_waypoints_subtype, &ais->type8.dac1fid27.waycount)},
  |  |  ------------------
  |  |  |  |  190|    323|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    323|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    323|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    323|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    323|        .addr.array.count = n, \
  |  |  |  |  195|    323|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    323| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  714|    323|        {NULL}
  |  |  715|    323|    };
  |  |  716|       |
  |  |  717|    323|    const struct json_attr_t json_ais8_fid29[] = {
  |  |  718|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  719|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  720|    323|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid29.linkage,
  |  |  721|    323|                                       .dflt.uinteger = 0},
  |  |  722|    323|	{"text",          t_string,    .addr.string = ais->type8.dac1fid29.text,
  |  |  723|    323|                                       .len = sizeof(ais->type8.dac1fid29.text)},
  |  |  724|    323|        {NULL}
  |  |  725|    323|    };
  |  |  726|       |
  |  |  727|    323|    const struct json_attr_t json_ais8_fid31[] = {
  |  |  728|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  729|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  730|    323|	{"lon",           t_integer,   .addr.integer = &ais->type8.dac1fid31.lon,
  |  |  731|    323|                                       .dflt.integer = DAC1FID31_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2128|    323|#define DAC1FID31_LON_NOT_AVAILABLE     (181*60*DAC1FID31_LATLON_SCALE)
  |  |  |  |  ------------------
  |  |  |  |  |  | 2126|    323|#define DAC1FID31_LATLON_SCALE  1000
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  732|    323|	{"lat",           t_integer,   .addr.integer = &ais->type8.dac1fid31.lat,
  |  |  733|    323|                                       .dflt.integer = DAC1FID31_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2130|    323|#define DAC1FID31_LAT_NOT_AVAILABLE     (91*60*DAC1FID31_LATLON_SCALE)
  |  |  |  |  ------------------
  |  |  |  |  |  | 2126|    323|#define DAC1FID31_LATLON_SCALE  1000
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  734|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type8.dac1fid31.accuracy,
  |  |  735|    323|                                       .dflt.boolean = false},
  |  |  736|    323|	{"timestamp",     t_string,    .addr.string = timestamp,
  |  |  737|    323|                                       .len = sizeof(timestamp)},
  |  |  738|    323|	{"wspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wspeed,
  |  |  739|    323|                                       .dflt.uinteger = DAC1FID31_WIND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2137|    323|#define DAC1FID31_WIND_NOT_AVAILABLE     127
  |  |  ------------------
  |  |  740|    323|	{"wgust",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wgust,
  |  |  741|    323|                                       .dflt.uinteger = DAC1FID31_WIND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2137|    323|#define DAC1FID31_WIND_NOT_AVAILABLE     127
  |  |  ------------------
  |  |  742|    323|	{"wdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wdir,
  |  |  743|    323|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2140|    323|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  744|    323|	{"wgustdir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wgustdir,
  |  |  745|    323|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2140|    323|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  746|    323|	{"airtemp",       t_integer,   .addr.integer = &ais->type8.dac1fid31.airtemp,
  |  |  747|    323|                                       .dflt.integer = DAC1FID31_AIRTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2142|    323|#define DAC1FID31_AIRTEMP_NOT_AVAILABLE  -1024
  |  |  ------------------
  |  |  748|    323|	{"humidity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.humidity,
  |  |  749|    323|                                       .dflt.uinteger = DAC1FID31_HUMIDITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2145|    323|#define DAC1FID31_HUMIDITY_NOT_AVAILABLE 101
  |  |  ------------------
  |  |  750|    323|	{"dewpoint",      t_integer,   .addr.integer = &ais->type8.dac1fid31.dewpoint,
  |  |  751|    323|                                       .dflt.integer = DAC1FID31_DEWPOINT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2147|    323|#define DAC1FID31_DEWPOINT_NOT_AVAILABLE 501
  |  |  ------------------
  |  |  752|    323|	{"pressure",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.pressure,
  |  |  753|    323|                                       .dflt.uinteger = DAC1FID31_PRESSURE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2150|    323|#define DAC1FID31_PRESSURE_NOT_AVAILABLE 511
  |  |  ------------------
  |  |  754|    323|	{"pressuretend",  t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.pressuretend,
  |  |  755|    323|                                       .dflt.uinteger = DAC1FID31_PRESSURETEND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2154|    323|#define DAC1FID31_PRESSURETEND_NOT_AVAILABLE  3
  |  |  ------------------
  |  |  756|    323|	{"visgreater",    t_boolean,   .addr.boolean = &ais->type8.dac1fid31.visgreater,
  |  |  757|    323|                                       .dflt.boolean = false},
  |  |  758|    323|	{"visibility",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.visibility,
  |  |  759|    323|                                       .dflt.uinteger = DAC1FID31_VISIBILITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2157|    323|#define DAC1FID31_VISIBILITY_NOT_AVAILABLE  127
  |  |  ------------------
  |  |  760|    323|	{"waterlevel",    t_integer,   .addr.integer = &ais->type8.dac1fid31.waterlevel,
  |  |  761|    323|                                       .dflt.integer = DAC1FID31_WATERLEVEL_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2160|    323|#define DAC1FID31_WATERLEVEL_NOT_AVAILABLE 4001
  |  |  ------------------
  |  |  762|    323|	{"leveltrend",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.leveltrend,
  |  |  763|    323|                                       .dflt.uinteger = DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2164|    323|#define DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE 3
  |  |  ------------------
  |  |  764|    323|	{"cspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cspeed,
  |  |  765|    323|                                       .dflt.uinteger = DAC1FID31_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2166|    323|#define DAC1FID31_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  766|    323|	{"cdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdir,
  |  |  767|    323|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2140|    323|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  768|    323|	{"cspeed2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cspeed2,
  |  |  769|    323|                                       .dflt.uinteger = DAC1FID31_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2166|    323|#define DAC1FID31_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  770|    323|	{"cdir2",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdir2,
  |  |  771|    323|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2140|    323|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  772|    323|	{"cdepth2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdepth2,
  |  |  773|    323|                                       .dflt.uinteger = DAC1FID31_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2172|    323|#define DAC1FID31_CDEPTH_NOT_AVAILABLE     301
  |  |  ------------------
  |  |  774|    323|	{"cspeed3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cspeed3,
  |  |  775|    323|                                       .dflt.uinteger = DAC1FID31_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2166|    323|#define DAC1FID31_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  776|    323|	{"cdir3",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdir3,
  |  |  777|    323|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2140|    323|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  778|    323|	{"cdepth3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdepth3,
  |  |  779|    323|                                       .dflt.uinteger = DAC1FID31_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2172|    323|#define DAC1FID31_CDEPTH_NOT_AVAILABLE     301
  |  |  ------------------
  |  |  780|    323|	{"waveheight",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.waveheight,
  |  |  781|    323|                                       .dflt.uinteger = DAC1FID31_HEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2178|    323|#define DAC1FID31_HEIGHT_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  782|    323|	{"waveperiod",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.waveperiod,
  |  |  783|    323|                                       .dflt.uinteger = DAC1FID31_PERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2181|    323|#define DAC1FID31_PERIOD_NOT_AVAILABLE     63
  |  |  ------------------
  |  |  784|    323|	{"wavedir",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wavedir,
  |  |  785|    323|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2140|    323|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  786|    323|	{"swellheight",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.swellheight,
  |  |  787|    323|                                       .dflt.uinteger = DAC1FID31_HEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2178|    323|#define DAC1FID31_HEIGHT_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  788|    323|	{"swellperiod",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.swellperiod,
  |  |  789|    323|                                       .dflt.uinteger = DAC1FID31_PERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2181|    323|#define DAC1FID31_PERIOD_NOT_AVAILABLE     63
  |  |  ------------------
  |  |  790|    323|	{"swelldir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.swelldir,
  |  |  791|    323|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2140|    323|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  792|    323|	{"seastate",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.seastate,
  |  |  793|    323|                                       .dflt.uinteger = DAC1FID31_SEASTATE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2187|    323|#define DAC1FID31_SEASTATE_NOT_AVAILABLE   15
  |  |  ------------------
  |  |  794|    323|	{"watertemp",     t_integer,   .addr.integer = &ais->type8.dac1fid31.watertemp,
  |  |  795|    323|                                       .dflt.integer = DAC1FID31_WATERTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2189|    323|#define DAC1FID31_WATERTEMP_NOT_AVAILABLE  601
  |  |  ------------------
  |  |  796|    323|	{"preciptype",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.preciptype,
  |  |  797|    323|                                       .dflt.uinteger = DAC1FID31_PRECIPTYPE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2192|    323|#define DAC1FID31_PRECIPTYPE_NOT_AVAILABLE 7
  |  |  ------------------
  |  |  798|    323|	{"preciptype_text",   t_ignore},
  |  |  799|    323|	{"salinity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.salinity,
  |  |  800|    323|                                       .dflt.uinteger = DAC1FID31_SALINITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2194|    323|#define DAC1FID31_SALINITY_NOT_AVAILABLE   510
  |  |  ------------------
  |  |  801|    323|	{"ice",           t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.ice,
  |  |  802|    323|                                       .dflt.uinteger = DAC1FID31_ICE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2197|    323|#define DAC1FID31_ICE_NOT_AVAILABLE       3
  |  |  ------------------
  |  |  803|    323|        {NULL}
  |  |  804|    323|    };
  |  |  805|       |
  |  |  806|    323|    const struct json_attr_t json_ais8_fid40[] = {
  |  |  807|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  808|    323|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   68|    323|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   69|    323|                                       .dflt.uinteger = 0},\
  |  |  |  |   70|    323|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   71|    323|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  809|    323|	{"form",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.form,
  |  |  810|    323|                                       .dflt.uinteger = DAC200FID40_FORM_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1964|    323|#define DAC200FID40_FORM_UNKNOWN        0
  |  |  ------------------
  |  |  811|    323|	{"facing",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.facing,
  |  |  812|    323|                                       .dflt.uinteger = DAC200FID40_FACING_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1966|    323|#define DAC200FID40_FACING_UNKNOWN      0
  |  |  ------------------
  |  |  813|    323|	{"direction",     t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.direction,
  |  |  814|    323|                                       .dflt.uinteger = DAC200FID40_DIRECTION_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1968|    323|#define DAC200FID40_DIRECTION_UNKNOWN   0
  |  |  ------------------
  |  |  815|    323|	{"direction_text",   t_ignore},
  |  |  816|    323|	{"status",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.status,
  |  |  817|    323|                                       .dflt.uinteger = DAC200FID40_STATUS_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1970|    323|#define DAC200FID40_STATUS_UNKNOWN      0
  |  |  ------------------
  |  |  818|    323|	{"status_text",   t_ignore},
  |  |  819|    323|        {NULL}
  |  |  820|    323|    };
  |  |  821|       |
  |  |  822|    323|    const struct json_attr_t json_ais9[] = {
  |  |  823|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  824|    323|	{"alt",           t_uinteger,  .addr.uinteger = &ais->type9.alt,
  |  |  825|    323|                                       .dflt.uinteger = AIS_ALT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2204|    323|#define AIS_ALT_NOT_AVAILABLE   4095
  |  |  ------------------
  |  |  826|    323|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type9.speed,
  |  |  827|    323|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1550|    323|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  828|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type9.accuracy,
  |  |  829|    323|                                       .dflt.boolean = false},
  |  |  830|    323|	{"lon",           t_integer,   .addr.integer = &ais->type9.lon,
  |  |  831|    323|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1555|    323|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |  832|    323|	{"lat",           t_integer,   .addr.integer = &ais->type9.lat,
  |  |  833|    323|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1557|    323|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |  834|    323|	{"course",        t_uinteger,  .addr.uinteger = &ais->type9.course,
  |  |  835|    323|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1559|    323|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |  836|    323|	{"second",        t_uinteger,  .addr.uinteger = &ais->type9.second,
  |  |  837|    323|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1566|    323|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |  838|    323|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type9.regional,
  |  |  839|    323|                                       .dflt.uinteger = 0},
  |  |  840|    323|	{"dte",           t_uinteger,  .addr.uinteger = &ais->type9.dte,
  |  |  841|    323|                                       .dflt.uinteger = 1},
  |  |  842|    323|	{"raim",          t_boolean,   .addr.boolean = &ais->type9.raim,
  |  |  843|    323|                                       .dflt.boolean = false},
  |  |  844|    323|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type9.radio,
  |  |  845|    323|                                       .dflt.uinteger = 0},
  |  |  846|    323|        {NULL}
  |  |  847|    323|    };
  |  |  848|       |
  |  |  849|    323|    const struct json_attr_t json_ais10[] = {
  |  |  850|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  851|    323|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type10.dest_mmsi,
  |  |  852|    323|                                       .dflt.uinteger = 0},
  |  |  853|    323|        {NULL}
  |  |  854|    323|    };
  |  |  855|       |
  |  |  856|    323|    const struct json_attr_t json_ais12[] = {
  |  |  857|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  858|    323|	{"seqno",         t_uinteger,  .addr.uinteger = &ais->type12.seqno,
  |  |  859|    323|                                       .dflt.uinteger = 0},
  |  |  860|    323|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type12.dest_mmsi,
  |  |  861|    323|                                       .dflt.uinteger = 0},
  |  |  862|    323|	{"retransmit",    t_boolean,   .addr.boolean = &ais->type12.retransmit,
  |  |  863|    323|                                       .dflt.boolean = 0},
  |  |  864|    323|	{"text",          t_string,    .addr.string = ais->type12.text,
  |  |  865|    323|                                       .len = sizeof(ais->type12.text)},
  |  |  866|    323|        {NULL}
  |  |  867|    323|    };
  |  |  868|       |
  |  |  869|    323|    const struct json_attr_t json_ais14[] = {
  |  |  870|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  871|    323|	{"text",          t_string,    .addr.string = ais->type14.text,
  |  |  872|    323|                                       .len = sizeof(ais->type14.text)},
  |  |  873|    323|        {NULL}
  |  |  874|    323|    };
  |  |  875|       |
  |  |  876|    323|    const struct json_attr_t json_ais15[] = {
  |  |  877|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  878|    323|	{"mmsi1",         t_uinteger,  .addr.uinteger = &ais->type15.mmsi1,
  |  |  879|    323|                                       .dflt.uinteger = 0},
  |  |  880|    323|	{"type1_1",       t_uinteger,  .addr.uinteger = &ais->type15.type1_1,
  |  |  881|    323|                                       .dflt.uinteger = 0},
  |  |  882|    323|	{"offset1_1",     t_uinteger,  .addr.uinteger = &ais->type15.offset1_1,
  |  |  883|    323|                                       .dflt.uinteger = 0},
  |  |  884|    323|	{"type1_2",       t_uinteger,  .addr.uinteger = &ais->type15.type1_2,
  |  |  885|    323|                                       .dflt.uinteger = 0},
  |  |  886|    323|	{"offset1_2",     t_uinteger,  .addr.uinteger = &ais->type15.offset1_2,
  |  |  887|    323|                                       .dflt.uinteger = 0},
  |  |  888|    323|	{"mmsi2",         t_uinteger,  .addr.uinteger = &ais->type15.mmsi2,
  |  |  889|    323|                                       .dflt.uinteger = 0},
  |  |  890|    323|	{"type2_1",       t_uinteger,  .addr.uinteger = &ais->type15.type2_1,
  |  |  891|    323|                                       .dflt.uinteger = 0},
  |  |  892|    323|	{"offset2_1",     t_uinteger,  .addr.uinteger = &ais->type15.offset2_1,
  |  |  893|    323|                                       .dflt.uinteger = 0},
  |  |  894|    323|        {NULL}
  |  |  895|    323|    };
  |  |  896|       |
  |  |  897|    323|    const struct json_attr_t json_ais16[] = {
  |  |  898|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  899|    323|	{"mmsi1",         t_uinteger,  .addr.uinteger = &ais->type16.mmsi1,
  |  |  900|    323|                                       .dflt.uinteger = 0},
  |  |  901|    323|	{"offset1",       t_uinteger,  .addr.uinteger = &ais->type16.offset1,
  |  |  902|    323|                                       .dflt.uinteger = 0},
  |  |  903|    323|	{"increment1",    t_uinteger,  .addr.uinteger = &ais->type16.increment1,
  |  |  904|    323|                                       .dflt.uinteger = 0},
  |  |  905|    323|	{"mmsi2",         t_uinteger,  .addr.uinteger = &ais->type16.mmsi2,
  |  |  906|    323|                                       .dflt.uinteger = 0},
  |  |  907|    323|	{"offset2",       t_uinteger,  .addr.uinteger = &ais->type16.offset2,
  |  |  908|    323|                                       .dflt.uinteger = 0},
  |  |  909|    323|	{"increment2",    t_uinteger,  .addr.uinteger = &ais->type16.increment2,
  |  |  910|    323|                                       .dflt.uinteger = 0},
  |  |  911|    323|        {NULL}
  |  |  912|    323|    };
  |  |  913|       |
  |  |  914|    323|    const struct json_attr_t json_ais17[] = {
  |  |  915|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  916|    323|	{"lon",           t_integer,   .addr.integer = &ais->type17.lon,
  |  |  917|    323|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2287|    323|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  |  918|    323|	{"lat",           t_integer,   .addr.integer = &ais->type17.lat,
  |  |  919|    323|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2289|    323|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  |  920|    323|	{"data",          t_string,    .addr.string = data,
  |  |  921|    323|                                       .len = sizeof(data)},
  |  |  922|    323|        {NULL}
  |  |  923|    323|    };
  |  |  924|       |
  |  |  925|    323|    const struct json_attr_t json_ais18[] = {
  |  |  926|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  927|    323|	{"reserved",      t_uinteger,  .addr.uinteger = &ais->type18.reserved,
  |  |  928|    323|                                       .dflt.uinteger = 0},
  |  |  929|    323|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type18.speed,
  |  |  930|    323|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1550|    323|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  931|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type18.accuracy,
  |  |  932|    323|                                       .dflt.boolean = false},
  |  |  933|    323|	{"lon",           t_integer,   .addr.integer = &ais->type18.lon,
  |  |  934|    323|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1555|    323|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |  935|    323|	{"lat",           t_integer,   .addr.integer = &ais->type18.lat,
  |  |  936|    323|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1557|    323|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |  937|    323|	{"course",        t_uinteger,  .addr.uinteger = &ais->type18.course,
  |  |  938|    323|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1559|    323|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |  939|    323|	{"heading",       t_uinteger,  .addr.uinteger = &ais->type18.heading,
  |  |  940|    323|                                       .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1561|    323|#define AIS_HEADING_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  941|    323|	{"second",        t_uinteger,  .addr.uinteger = &ais->type18.second,
  |  |  942|    323|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1566|    323|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |  943|    323|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type18.regional,
  |  |  944|    323|                                       .dflt.uinteger = 0},
  |  |  945|    323|	{"cs",            t_boolean,   .addr.boolean = &ais->type18.cs,
  |  |  946|    323|                                       .dflt.boolean = false},
  |  |  947|    323|	{"display",       t_boolean,   .addr.boolean = &ais->type18.display,
  |  |  948|    323|                                       .dflt.boolean = false},
  |  |  949|    323|	{"dsc",           t_boolean,   .addr.boolean = &ais->type18.dsc,
  |  |  950|    323|                                       .dflt.boolean = false},
  |  |  951|    323|	{"band",          t_boolean,   .addr.boolean = &ais->type18.band,
  |  |  952|    323|                                       .dflt.boolean = false},
  |  |  953|    323|	{"msg22",         t_boolean,   .addr.boolean = &ais->type18.msg22,
  |  |  954|    323|                                       .dflt.boolean = false},
  |  |  955|    323|	{"raim",          t_boolean,   .addr.boolean = &ais->type18.raim,
  |  |  956|    323|                                       .dflt.boolean = false},
  |  |  957|    323|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type18.radio,
  |  |  958|    323|                                       .dflt.uinteger = 0},
  |  |  959|    323|        {NULL}
  |  |  960|    323|    };
  |  |  961|       |
  |  |  962|    323|    const struct json_attr_t json_ais19[] = {
  |  |  963|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  964|    323|	{"reserved",      t_uinteger,  .addr.uinteger = &ais->type19.reserved,
  |  |  965|    323|                                       .dflt.uinteger = 0},
  |  |  966|    323|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type19.speed,
  |  |  967|    323|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1550|    323|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  968|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type19.accuracy,
  |  |  969|    323|                                       .dflt.boolean = false},
  |  |  970|    323|	{"lon",           t_integer,   .addr.integer = &ais->type19.lon,
  |  |  971|    323|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1555|    323|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |  972|    323|	{"lat",           t_integer,   .addr.integer = &ais->type19.lat,
  |  |  973|    323|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1557|    323|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |  974|    323|	{"course",        t_uinteger,  .addr.uinteger = &ais->type19.course,
  |  |  975|    323|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1559|    323|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |  976|    323|	{"heading",       t_uinteger,  .addr.uinteger = &ais->type19.heading,
  |  |  977|    323|                                       .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1561|    323|#define AIS_HEADING_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  978|    323|	{"second",        t_uinteger,  .addr.uinteger = &ais->type19.second,
  |  |  979|    323|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1566|    323|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |  980|    323|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type19.regional,
  |  |  981|    323|                                       .dflt.uinteger = 0},
  |  |  982|    323|	{"shipname",      t_string,    .addr.string = ais->type19.shipname,
  |  |  983|    323|                                       .len = sizeof(ais->type19.shipname)},
  |  |  984|    323|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type19.shiptype,
  |  |  985|    323|                                       .dflt.uinteger = 0},
  |  |  986|    323|	{"shiptype_text",   t_ignore},
  |  |  987|    323|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type19.to_bow,
  |  |  988|    323|                                       .dflt.uinteger = 0},
  |  |  989|    323|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type19.to_stern,
  |  |  990|    323|                                       .dflt.uinteger = 0},
  |  |  991|    323|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type19.to_port,
  |  |  992|    323|                                       .dflt.uinteger = 0},
  |  |  993|    323|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type19.to_starboard,
  |  |  994|    323|                                       .dflt.uinteger = 0},
  |  |  995|    323|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type19.epfd,
  |  |  996|    323|                                       .dflt.uinteger = 0},
  |  |  997|    323|	{"epfd_text",   t_ignore},
  |  |  998|    323|	{"raim",          t_boolean,   .addr.boolean = &ais->type19.raim,
  |  |  999|    323|                                       .dflt.boolean = false},
  |  | 1000|    323|	{"dte",           t_uinteger,  .addr.uinteger = &ais->type19.dte,
  |  | 1001|    323|                                       .dflt.uinteger = 1},
  |  | 1002|    323|	{"assigned",      t_boolean,   .addr.boolean = &ais->type19.assigned,
  |  | 1003|    323|                                       .dflt.boolean = false},
  |  | 1004|    323|        {NULL}
  |  | 1005|    323|    };
  |  | 1006|       |
  |  | 1007|    323|    const struct json_attr_t json_ais20[] = {
  |  | 1008|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1009|    323|	{"offset1",       t_uinteger,  .addr.uinteger = &ais->type20.offset1,
  |  | 1010|    323|                                       .dflt.uinteger = 0},
  |  | 1011|    323|	{"number1",       t_uinteger,  .addr.uinteger = &ais->type20.number1,
  |  | 1012|    323|                                       .dflt.uinteger = 0},
  |  | 1013|    323|	{"timeout1",      t_uinteger,  .addr.uinteger = &ais->type20.timeout1,
  |  | 1014|    323|                                       .dflt.uinteger = 0},
  |  | 1015|    323|	{"increment1",    t_uinteger,  .addr.uinteger = &ais->type20.increment1,
  |  | 1016|    323|                                       .dflt.uinteger = 0},
  |  | 1017|    323|	{"offset2",       t_uinteger,  .addr.uinteger = &ais->type20.offset2,
  |  | 1018|    323|                                       .dflt.uinteger = 0},
  |  | 1019|    323|	{"number2",       t_uinteger,  .addr.uinteger = &ais->type20.number2,
  |  | 1020|    323|                                       .dflt.uinteger = 0},
  |  | 1021|    323|	{"timeout2",      t_uinteger,  .addr.uinteger = &ais->type20.timeout2,
  |  | 1022|    323|                                       .dflt.uinteger = 0},
  |  | 1023|    323|	{"increment2",    t_uinteger,  .addr.uinteger = &ais->type20.increment2,
  |  | 1024|    323|                                       .dflt.uinteger = 0},
  |  | 1025|    323|	{"offset3",       t_uinteger,  .addr.uinteger = &ais->type20.offset3,
  |  | 1026|    323|                                       .dflt.uinteger = 0},
  |  | 1027|    323|	{"number3",       t_uinteger,  .addr.uinteger = &ais->type20.number3,
  |  | 1028|    323|                                       .dflt.uinteger = 0},
  |  | 1029|    323|	{"timeout3",      t_uinteger,  .addr.uinteger = &ais->type20.timeout3,
  |  | 1030|    323|                                       .dflt.uinteger = 0},
  |  | 1031|    323|	{"increment3",    t_uinteger,  .addr.uinteger = &ais->type20.increment3,
  |  | 1032|    323|                                       .dflt.uinteger = 0},
  |  | 1033|    323|	{"offset4",       t_uinteger,  .addr.uinteger = &ais->type20.offset4,
  |  | 1034|    323|                                       .dflt.uinteger = 0},
  |  | 1035|    323|	{"number4",       t_uinteger,  .addr.uinteger = &ais->type20.number4,
  |  | 1036|    323|                                       .dflt.uinteger = 0},
  |  | 1037|    323|	{"timeout4",      t_uinteger,  .addr.uinteger = &ais->type20.timeout4,
  |  | 1038|    323|                                       .dflt.uinteger = 0},
  |  | 1039|    323|	{"increment4",    t_uinteger,  .addr.uinteger = &ais->type20.increment4,
  |  | 1040|    323|                                       .dflt.uinteger = 0},
  |  | 1041|    323|        {NULL}
  |  | 1042|    323|    };
  |  | 1043|       |
  |  | 1044|    323|    const struct json_attr_t json_ais21[] = {
  |  | 1045|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1046|    323|	{"aid_type",      t_uinteger,  .addr.uinteger = &ais->type21.aid_type,
  |  | 1047|    323|                                       .dflt.uinteger = 0},
  |  | 1048|    323|	{"aid_type_text",   t_ignore},
  |  | 1049|    323|	{"name",          t_string,    .addr.string = ais->type21.name,
  |  | 1050|    323|                                       .len = sizeof(ais->type21.name)},
  |  | 1051|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type21.accuracy,
  |  | 1052|    323|                                       .dflt.boolean = false},
  |  | 1053|    323|	{"lon",           t_integer,   .addr.integer = &ais->type21.lon,
  |  | 1054|    323|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1555|    323|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  | 1055|    323|	{"lat",           t_integer,   .addr.integer = &ais->type21.lat,
  |  | 1056|    323|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1557|    323|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  | 1057|    323|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type21.to_bow,
  |  | 1058|    323|                                       .dflt.uinteger = 0},
  |  | 1059|    323|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type21.to_stern,
  |  | 1060|    323|                                       .dflt.uinteger = 0},
  |  | 1061|    323|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type21.to_port,
  |  | 1062|    323|                                       .dflt.uinteger = 0},
  |  | 1063|    323|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type21.to_starboard,
  |  | 1064|    323|                                       .dflt.uinteger = 0},
  |  | 1065|    323|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type21.epfd,
  |  | 1066|    323|                                       .dflt.uinteger = 0},
  |  | 1067|    323|	{"epfd_text",   t_ignore},
  |  | 1068|    323|	{"second",        t_uinteger,  .addr.uinteger = &ais->type21.second,
  |  | 1069|    323|                                       .dflt.uinteger = 0},
  |  | 1070|    323|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type21.regional,
  |  | 1071|    323|                                       .dflt.uinteger = 0},
  |  | 1072|    323|	{"off_position",  t_boolean,   .addr.boolean = &ais->type21.off_position,
  |  | 1073|    323|                                       .dflt.boolean = false},
  |  | 1074|    323|	{"raim",          t_boolean,   .addr.boolean = &ais->type21.raim,
  |  | 1075|    323|                                       .dflt.boolean = false},
  |  | 1076|    323|	{"virtual_aid",   t_boolean,   .addr.boolean = &ais->type21.virtual_aid,
  |  | 1077|    323|                                       .dflt.boolean = false},
  |  | 1078|    323|        {NULL}
  |  | 1079|    323|    };
  |  | 1080|       |
  |  | 1081|    323|    const struct json_attr_t json_ais22[] = {
  |  | 1082|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1083|    323|	{"channel_a",     t_uinteger,  .addr.uinteger = &ais->type22.channel_a,
  |  | 1084|    323|                                       .dflt.uinteger = 0},
  |  | 1085|    323|	{"channel_b",     t_uinteger,  .addr.uinteger = &ais->type22.channel_b,
  |  | 1086|    323|                                       .dflt.uinteger = 0},
  |  | 1087|    323|	{"txrx",          t_uinteger,  .addr.uinteger = &ais->type22.txrx,
  |  | 1088|    323|                                       .dflt.uinteger = 0},
  |  | 1089|    323|	{"power",         t_boolean,   .addr.boolean = &ais->type22.power,
  |  | 1090|    323|                                       .dflt.boolean = false},
  |  | 1091|    323|	{"ne_lon",        t_integer,   .addr.integer = &ais->type22.area.ne_lon,
  |  | 1092|    323|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2287|    323|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1093|    323|	{"ne_lat",        t_integer,   .addr.integer = &ais->type22.area.ne_lat,
  |  | 1094|    323|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2289|    323|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1095|    323|	{"sw_lon",        t_integer,   .addr.integer = &ais->type22.area.sw_lon,
  |  | 1096|    323|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2287|    323|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1097|    323|	{"sw_lat",        t_integer,   .addr.integer = &ais->type22.area.sw_lat,
  |  | 1098|    323|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2289|    323|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1099|    323|	{"dest1",         t_uinteger,  .addr.uinteger = &ais->type22.mmsi.dest1,
  |  | 1100|    323|                                       .dflt.uinteger = 0},
  |  | 1101|    323|	{"dest2",         t_uinteger,  .addr.uinteger = &ais->type22.mmsi.dest2,
  |  | 1102|    323|                                       .dflt.uinteger = 0},
  |  | 1103|    323|	{"addressed",     t_boolean,   .addr.boolean = &ais->type22.addressed,
  |  | 1104|    323|                                       .dflt.boolean = false},
  |  | 1105|    323|	{"band_a",        t_boolean,   .addr.boolean = &ais->type22.band_a,
  |  | 1106|    323|                                       .dflt.boolean = false},
  |  | 1107|    323|	{"band_b",        t_boolean,   .addr.boolean = &ais->type22.band_b,
  |  | 1108|    323|                                       .dflt.boolean = false},
  |  | 1109|    323|	{"zonesize",      t_uinteger,  .addr.uinteger = &ais->type22.zonesize,
  |  | 1110|    323|                                       .dflt.uinteger = 0},
  |  | 1111|    323|        {NULL}
  |  | 1112|    323|    };
  |  | 1113|       |
  |  | 1114|    323|    const struct json_attr_t json_ais23[] = {
  |  | 1115|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1116|    323|	{"ne_lon",        t_integer,   .addr.integer = &ais->type23.ne_lon,
  |  | 1117|    323|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2287|    323|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1118|    323|	{"ne_lat",        t_integer,   .addr.integer = &ais->type23.ne_lat,
  |  | 1119|    323|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2289|    323|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1120|    323|	{"sw_lon",        t_integer,   .addr.integer = &ais->type23.sw_lon,
  |  | 1121|    323|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2287|    323|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1122|    323|	{"sw_lat",        t_integer,   .addr.integer = &ais->type23.sw_lat,
  |  | 1123|    323|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2289|    323|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1124|    323|	{"stationtype",   t_uinteger,  .addr.uinteger = &ais->type23.stationtype,
  |  | 1125|    323|                                       .dflt.uinteger = 0},
  |  | 1126|    323|	{"stationtype_text",   t_ignore},
  |  | 1127|    323|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type23.shiptype,
  |  | 1128|    323|                                       .dflt.uinteger = 0},
  |  | 1129|    323|	{"shiptype_text",   t_ignore},
  |  | 1130|    323|	{"txrx",          t_uinteger,  .addr.uinteger = &ais->type23.txrx,
  |  | 1131|    323|                                       .dflt.uinteger = 0},
  |  | 1132|    323|	{"interval",      t_uinteger,  .addr.uinteger = &ais->type23.interval,
  |  | 1133|    323|                                       .dflt.uinteger = 0},
  |  | 1134|    323|	{"quiet",         t_uinteger,  .addr.uinteger = &ais->type23.quiet,
  |  | 1135|    323|                                       .dflt.uinteger = 0},
  |  | 1136|    323|        {NULL}
  |  | 1137|    323|    };
  |  | 1138|       |
  |  | 1139|    323|    const struct json_attr_t json_ais24[] = {
  |  | 1140|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1141|    323|	{"shipname",      t_string,    .addr.string = ais->type24.shipname,
  |  | 1142|    323|                                       .len = sizeof(ais->type24.shipname)},
  |  | 1143|    323|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type24.shiptype,
  |  | 1144|    323|                                       .dflt.uinteger = 0},
  |  | 1145|    323|	{"shiptype_text",   t_ignore},
  |  | 1146|    323|	{"vendorid",      t_string,    .addr.string = ais->type24.vendorid,
  |  | 1147|    323|                                       .len = sizeof(ais->type24.vendorid)},
  |  | 1148|    323|	{"model",         t_uinteger,  .addr.uinteger = &ais->type24.model,
  |  | 1149|    323|                                       .dflt.uinteger = 0},
  |  | 1150|    323|	{"serial",        t_uinteger,  .addr.uinteger = &ais->type24.serial,
  |  | 1151|    323|                                       .dflt.uinteger = 0},
  |  | 1152|    323|	{"callsign",      t_string,    .addr.string = ais->type24.callsign,
  |  | 1153|    323|                                       .len = sizeof(ais->type24.callsign)},
  |  | 1154|    323|	{"mothership_mmsi",t_uinteger,  .addr.uinteger = &ais->type24.mothership_mmsi,
  |  | 1155|    323|                                       .dflt.uinteger = 0},
  |  | 1156|    323|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type24.dim.to_bow,
  |  | 1157|    323|                                       .dflt.uinteger = 0},
  |  | 1158|    323|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type24.dim.to_stern,
  |  | 1159|    323|                                       .dflt.uinteger = 0},
  |  | 1160|    323|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type24.dim.to_port,
  |  | 1161|    323|                                       .dflt.uinteger = 0},
  |  | 1162|    323|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type24.dim.to_starboard,
  |  | 1163|    323|                                       .dflt.uinteger = 0},
  |  | 1164|    323|        {NULL}
  |  | 1165|    323|    };
  |  | 1166|       |
  |  | 1167|    323|    const struct json_attr_t json_ais25[] = {
  |  | 1168|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1169|    323|	{"addressed",     t_boolean,   .addr.boolean = &ais->type25.addressed,
  |  | 1170|    323|                                       .dflt.boolean = false},
  |  | 1171|    323|	{"structured",    t_boolean,   .addr.boolean = &ais->type25.structured,
  |  | 1172|    323|                                       .dflt.boolean = false},
  |  | 1173|    323|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type25.dest_mmsi,
  |  | 1174|    323|                                       .dflt.uinteger = 0},
  |  | 1175|    323|	{"app_id",        t_uinteger,  .addr.uinteger = &ais->type25.app_id,
  |  | 1176|    323|                                       .dflt.uinteger = 0},
  |  | 1177|    323|	{"data",          t_string,    .addr.string = data,
  |  | 1178|    323|                                       .len = sizeof(data)},
  |  | 1179|    323|        {NULL}
  |  | 1180|    323|    };
  |  | 1181|       |
  |  | 1182|    323|    const struct json_attr_t json_ais26[] = {
  |  | 1183|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1184|    323|	{"addressed",     t_boolean,   .addr.boolean = &ais->type26.addressed,
  |  | 1185|    323|                                       .dflt.boolean = false},
  |  | 1186|    323|	{"structured",    t_boolean,   .addr.boolean = &ais->type26.structured,
  |  | 1187|    323|                                       .dflt.boolean = false},
  |  | 1188|    323|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type26.dest_mmsi,
  |  | 1189|    323|                                       .dflt.uinteger = 0},
  |  | 1190|    323|	{"app_id",        t_uinteger,  .addr.uinteger = &ais->type26.app_id,
  |  | 1191|    323|                                       .dflt.uinteger = 0},
  |  | 1192|    323|	{"data",          t_string,    .addr.string = data,
  |  | 1193|    323|                                       .len = sizeof(data)},
  |  | 1194|    323|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type26.radio,
  |  | 1195|    323|                                       .dflt.uinteger = 0},
  |  | 1196|    323|        {NULL}
  |  | 1197|    323|    };
  |  | 1198|       |
  |  | 1199|    323|    const struct json_attr_t json_ais27[] = {
  |  | 1200|    323|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   47|    323|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   48|    323|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   49|    323|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   50|    323|                                          .len = pathlen}, \
  |  |  |  |   51|    323|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   52|    323|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   53|    323|                                          .dflt.boolean = false}, \
  |  |  |  |   54|    323|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1201|    323|	{"status",        t_uinteger,  .addr.uinteger = &ais->type27.status,
  |  | 1202|    323|                                       .dflt.uinteger = 0},
  |  | 1203|    323|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type27.speed,
  |  | 1204|    323|                                       .dflt.uinteger = AIS_LONGRANGE_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2473|    323|#define AIS_LONGRANGE_SPEED_NOT_AVAILABLE 63
  |  |  ------------------
  |  | 1205|    323|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type27.accuracy,
  |  | 1206|    323|                                       .dflt.boolean = false},
  |  | 1207|    323|	{"lon",           t_integer,   .addr.integer = &ais->type27.lon,
  |  | 1208|    323|                                       .dflt.integer = AIS_LONGRANGE_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2469|    323|#define AIS_LONGRANGE_LON_NOT_AVAILABLE 0x1a838
  |  |  ------------------
  |  | 1209|    323|	{"lat",           t_integer,   .addr.integer = &ais->type27.lat,
  |  | 1210|    323|                                       .dflt.integer = AIS_LONGRANGE_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2471|    323|#define AIS_LONGRANGE_LAT_NOT_AVAILABLE 0xd548
  |  |  ------------------
  |  | 1211|    323|	{"course",        t_uinteger,  .addr.uinteger = &ais->type27.course,
  |  | 1212|    323|                                       .dflt.uinteger = AIS_LONGRANGE_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2475|    323|#define AIS_LONGRANGE_COURSE_NOT_AVAILABLE 511
  |  |  ------------------
  |  | 1213|    323|	{"raim",          t_boolean,   .addr.boolean = &ais->type27.raim,
  |  | 1214|    323|                                       .dflt.boolean = false},
  |  | 1215|    323|	{"gnss",          t_boolean,   .addr.boolean = &ais->type27.gnss,
  |  | 1216|    323|                                       .dflt.boolean = true},
  |  | 1217|    323|        {NULL}
  |  | 1218|    323|    };
  |  | 1219|       |
  |  | 1220|       |
  |  | 1221|       |
  |  | 1222|       |/* Generated code ends. */
  |  | 1223|       |
  ------------------
   76|       |
   77|    323|#undef AIS_HEADER
   78|       |
   79|    323|    memset(ais, '\0', sizeof(struct ais_t));
   80|       |
   81|    323|    if (NULL != strstr(buf, "\"type\":1,") ||
  ------------------
  |  Branch (81:9): [True: 1, False: 322]
  ------------------
   82|    323|        NULL != strstr(buf, "\"type\":2,") ||
  ------------------
  |  Branch (82:9): [True: 2, False: 320]
  ------------------
   83|    323|        NULL != strstr(buf, "\"type\":3,")) {
  ------------------
  |  Branch (83:9): [True: 1, False: 319]
  ------------------
   84|      4|        status = json_read_object(buf, json_ais1, endptr);
   85|    319|    } else if (NULL != strstr(buf, "\"type\":4,") ||
  ------------------
  |  Branch (85:16): [True: 5, False: 314]
  ------------------
   86|    319|               NULL != strstr(buf, "\"type\":11,")) {
  ------------------
  |  Branch (86:16): [True: 1, False: 313]
  ------------------
   87|      6|        status = json_read_object(buf, json_ais4, endptr);
   88|      6|        if (0 == status) {
  ------------------
  |  Branch (88:13): [True: 1, False: 5]
  ------------------
   89|       |            // no need to set zeros, again.
   90|       |            // ais->type4.year = AIS_YEAR_NOT_AVAILABLE;
   91|       |            // ais->type4.month = AIS_MONTH_NOT_AVAILABLE;
   92|       |            // ais->type4.day = AIS_DAY_NOT_AVAILABLE;
   93|      1|            ais->type4.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
   94|      1|            ais->type4.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
   95|      1|            ais->type4.second = AIS_SECOND_NOT_AVAILABLE;
  ------------------
  |  | 1588|      1|#define AIS_SECOND_NOT_AVAILABLE        60
  ------------------
   96|       |            /* We use %09u for the date to allow for dodgy years (>9999)
   97|       |             * to go through. */
   98|      1|            (void)sscanf(timestamp, "%09u-%02u-%02uT%02u:%02u:%02uZ",
   99|      1|                         &ais->type4.year,
  100|      1|                         &ais->type4.month,
  101|      1|                         &ais->type4.day,
  102|      1|                         &ais->type4.hour,
  103|      1|                         &ais->type4.minute,
  104|      1|                         &ais->type4.second);
  105|      1|        }
  106|    313|    } else if (strstr(buf, "\"type\":5,") != NULL) {
  ------------------
  |  Branch (106:16): [True: 13, False: 300]
  ------------------
  107|     13|        status = json_read_object(buf, json_ais5, endptr);
  108|     13|        if (status == 0) {
  ------------------
  |  Branch (108:13): [True: 2, False: 11]
  ------------------
  109|       |            // no need to set zeros, again.
  110|       |            // ais->type5.month = AIS_MONTH_NOT_AVAILABLE;
  111|       |            // ais->type5.day = AIS_DAY_NOT_AVAILABLE;
  112|      2|            ais->type5.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      2|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  113|      2|            ais->type5.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      2|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  114|      2|            (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
  115|      2|                         &ais->type5.month,
  116|      2|                         &ais->type5.day,
  117|      2|                         &ais->type5.hour,
  118|      2|                         &ais->type5.minute);
  119|      2|        }
  120|    300|    } else if (strstr(buf, "\"type\":6,") != NULL) {
  ------------------
  |  Branch (120:16): [True: 114, False: 186]
  ------------------
  121|    114|        bool structured = false;
  122|    114|        if (strstr(buf, "\"dac\":1,") != NULL) {
  ------------------
  |  Branch (122:13): [True: 31, False: 83]
  ------------------
  123|     31|            if (strstr(buf, "\"fid\":12,") != NULL) {
  ------------------
  |  Branch (123:17): [True: 5, False: 26]
  ------------------
  124|      5|                status = json_read_object(buf, json_ais6_fid12, endptr);
  125|      5|                if (status == 0) {
  ------------------
  |  Branch (125:21): [True: 1, False: 4]
  ------------------
  126|       |                    // no need to set zeros, again.
  127|       |                    // ais->type6.dac1fid12.lmonth = AIS_MONTH_NOT_AVAILABLE;
  128|       |                    // ais->type6.dac1fid12.lday = AIS_DAY_NOT_AVAILABLE;
  129|      1|                    ais->type6.dac1fid12.lhour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  130|      1|                    ais->type6.dac1fid12.lminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  131|       |                    // ais->type6.dac1fid12.nmonth = AIS_MONTH_NOT_AVAILABLE;
  132|       |                    // ais->type6.dac1fid12.nday = AIS_DAY_NOT_AVAILABLE;
  133|      1|                    ais->type6.dac1fid12.nhour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  134|      1|                    ais->type6.dac1fid12.nminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  135|      1|                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
  136|      1|                                 &ais->type6.dac1fid12.lmonth,
  137|      1|                                 &ais->type6.dac1fid12.lday,
  138|      1|                                 &ais->type6.dac1fid12.lhour,
  139|      1|                                 &ais->type6.dac1fid12.lminute);
  140|      1|                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
  141|      1|                                 &ais->type6.dac1fid12.nmonth,
  142|      1|                                 &ais->type6.dac1fid12.nday,
  143|      1|                                 &ais->type6.dac1fid12.nhour,
  144|      1|                                 &ais->type6.dac1fid12.nminute);
  145|      1|                }
  146|      5|                structured = true;
  147|      5|            }
  148|     26|            else if (strstr(buf, "\"fid\":15,") != NULL) {
  ------------------
  |  Branch (148:22): [True: 1, False: 25]
  ------------------
  149|      1|                status = json_read_object(buf, json_ais6_fid15, endptr);
  150|      1|                structured = true;
  151|      1|            }
  152|     25|            else if (strstr(buf, "\"fid\":16,") != NULL) {
  ------------------
  |  Branch (152:22): [True: 1, False: 24]
  ------------------
  153|      1|                status = json_read_object(buf, json_ais6_fid16, endptr);
  154|      1|                structured = true;
  155|      1|            }
  156|     24|            else if (strstr(buf, "\"fid\":18,") != NULL) {
  ------------------
  |  Branch (156:22): [True: 5, False: 19]
  ------------------
  157|      5|                status = json_read_object(buf, json_ais6_fid18, endptr);
  158|      5|                if (status == 0) {
  ------------------
  |  Branch (158:21): [True: 1, False: 4]
  ------------------
  159|       |                    // no need to set zeros, again.
  160|       |                    // ais->type6.dac1fid18.month = AIS_MONTH_NOT_AVAILABLE;
  161|       |                    // ais->type6.dac1fid18.day = AIS_DAY_NOT_AVAILABLE;
  162|      1|                    ais->type6.dac1fid18.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  163|      1|                    ais->type6.dac1fid18.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  164|      1|                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
  165|      1|                                 &ais->type6.dac1fid18.month,
  166|      1|                                 &ais->type6.dac1fid18.day,
  167|      1|                                 &ais->type6.dac1fid18.hour,
  168|      1|                                 &ais->type6.dac1fid18.minute);
  169|      1|                }
  170|      5|                structured = true;
  171|      5|            }
  172|     19|            else if (strstr(buf, "\"fid\":20,") != NULL) {
  ------------------
  |  Branch (172:22): [True: 7, False: 12]
  ------------------
  173|      7|                status = json_read_object(buf, json_ais6_fid20, endptr);
  174|      7|                if (status == 0) {
  ------------------
  |  Branch (174:21): [True: 2, False: 5]
  ------------------
  175|       |                    // no need to set zeros, again.
  176|       |                    // ais->type6.dac1fid20.month = AIS_MONTH_NOT_AVAILABLE;
  177|       |                    // ais->type6.dac1fid20.day = AIS_DAY_NOT_AVAILABLE;
  178|      2|                    ais->type6.dac1fid20.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      2|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  179|      2|                    ais->type6.dac1fid20.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      2|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  180|      2|                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
  181|      2|                                 &ais->type6.dac1fid20.month,
  182|      2|                                 &ais->type6.dac1fid20.day,
  183|      2|                                 &ais->type6.dac1fid20.hour,
  184|      2|                                 &ais->type6.dac1fid20.minute);
  185|      2|                }
  186|      7|                structured = true;
  187|      7|            }
  188|     12|            else if (strstr(buf, "\"fid\":25,") != NULL) {
  ------------------
  |  Branch (188:22): [True: 3, False: 9]
  ------------------
  189|      3|                status = json_read_object(buf, json_ais6_fid25, endptr);
  190|      3|                structured = true;
  191|      3|            }
  192|      9|            else if (strstr(buf, "\"fid\":28,") != NULL) {
  ------------------
  |  Branch (192:22): [True: 5, False: 4]
  ------------------
  193|      5|                status = json_read_object(buf, json_ais6_fid28, endptr);
  194|      5|                if (status == 0) {
  ------------------
  |  Branch (194:21): [True: 1, False: 4]
  ------------------
  195|       |                    // no need to set zeros, again.
  196|       |                    // ais->type6.dac1fid28.month = AIS_MONTH_NOT_AVAILABLE;
  197|       |                    // ais->type6.dac1fid28.day = AIS_DAY_NOT_AVAILABLE;
  198|      1|                    ais->type6.dac1fid28.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  199|      1|                    ais->type6.dac1fid28.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  200|      1|                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
  201|      1|                                 &ais->type6.dac1fid28.month,
  202|      1|                                 &ais->type6.dac1fid28.day,
  203|      1|                                 &ais->type6.dac1fid28.hour,
  204|      1|                                 &ais->type6.dac1fid28.minute);
  205|      1|                }
  206|      5|                structured = true;
  207|      5|            }
  208|      4|            else if (strstr(buf, "\"fid\":30,") != NULL) {
  ------------------
  |  Branch (208:22): [True: 1, False: 3]
  ------------------
  209|      1|                status = json_read_object(buf, json_ais6_fid30, endptr);
  210|      1|                structured = true;
  211|      1|            }
  212|      3|            else if (strstr(buf, "\"fid\":32,") != NULL ||
  ------------------
  |  Branch (212:22): [True: 1, False: 2]
  ------------------
  213|      2|                     strstr(buf, "\"fid\":14,") != NULL) {
  ------------------
  |  Branch (213:22): [True: 1, False: 1]
  ------------------
  214|      2|                status = json_read_object(buf, json_ais6_fid32, endptr);
  215|      2|                structured = true;
  216|      2|            }
  217|     31|        }
  218|     83|        else if (strstr(buf, "\"dac\":235,") != NULL ||
  ------------------
  |  Branch (218:18): [True: 2, False: 81]
  ------------------
  219|     81|                 strstr(buf, "\"dac\":250,") != NULL) {
  ------------------
  |  Branch (219:18): [True: 2, False: 79]
  ------------------
  220|      4|            if (strstr(buf, "\"fid\":10,") != NULL) {
  ------------------
  |  Branch (220:17): [True: 2, False: 2]
  ------------------
  221|      2|                status = json_read_object(buf, json_ais6_fid10, endptr);
  222|      2|                structured = true;
  223|      2|            }
  224|      4|        }
  225|     79|        else if (strstr(buf, "\"dac\":200,") != NULL) {
  ------------------
  |  Branch (225:18): [True: 11, False: 68]
  ------------------
  226|     11|            if (strstr(buf, "\"fid\":21,") != NULL) {
  ------------------
  |  Branch (226:17): [True: 5, False: 6]
  ------------------
  227|      5|                status = json_read_object(buf, json_ais6_fid21, endptr);
  228|      5|                structured = true;
  229|      5|                if (status == 0) {
  ------------------
  |  Branch (229:21): [True: 1, False: 4]
  ------------------
  230|       |                    // no need to set zeros, again.
  231|       |                    // ais->type6.dac200fid21.month = AIS_MONTH_NOT_AVAILABLE;
  232|       |                    // ais->type6.dac200fid21.day = AIS_DAY_NOT_AVAILABLE;
  233|      1|                    ais->type6.dac200fid21.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  234|      1|                    ais->type6.dac200fid21.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  235|      1|                    (void)sscanf(eta, "%02u-%02uT%02u:%02u",
  236|      1|                                 &ais->type6.dac200fid21.month,
  237|      1|                                 &ais->type6.dac200fid21.day,
  238|      1|                                 &ais->type6.dac200fid21.hour,
  239|      1|                                 &ais->type6.dac200fid21.minute);
  240|      1|                }
  241|      5|            }
  242|      6|            else if (strstr(buf, "\"fid\":22,") != NULL) {
  ------------------
  |  Branch (242:22): [True: 4, False: 2]
  ------------------
  243|      4|                status = json_read_object(buf, json_ais6_fid22, endptr);
  244|      4|                structured = true;
  245|      4|                if (status == 0) {
  ------------------
  |  Branch (245:21): [True: 1, False: 3]
  ------------------
  246|       |                    // no need to set zeros, again.
  247|       |                    // ais->type6.dac200fid22.month = AIS_MONTH_NOT_AVAILABLE;
  248|       |                    // ais->type6.dac200fid22.day = AIS_DAY_NOT_AVAILABLE;
  249|      1|                    ais->type6.dac200fid22.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  250|      1|                    ais->type6.dac200fid22.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  251|      1|                    (void)sscanf(rta, "%02u-%02uT%02u:%02u",
  252|      1|                                 &ais->type6.dac200fid22.month,
  253|      1|                                 &ais->type6.dac200fid22.day,
  254|      1|                                 &ais->type6.dac200fid22.hour,
  255|      1|                                 &ais->type6.dac200fid22.minute);
  256|      1|                }
  257|      4|            }
  258|      2|            else if (strstr(buf, "\"fid\":55,") != NULL) {
  ------------------
  |  Branch (258:22): [True: 1, False: 1]
  ------------------
  259|      1|                status = json_read_object(buf, json_ais6_fid55, endptr);
  260|      1|                structured = true;
  261|      1|            }
  262|     11|        }
  263|    114|        if (!structured) {
  ------------------
  |  Branch (263:13): [True: 72, False: 42]
  ------------------
  264|     72|            status = json_read_object(buf, json_ais6, endptr);
  265|     72|            if (status == 0)
  ------------------
  |  Branch (265:17): [True: 67, False: 5]
  ------------------
  266|     67|                lenhex_unpack(data, &ais->type6.bitcount,
  267|     67|                              ais->type6.bitdata, sizeof(ais->type6.bitdata));
  268|     72|        }
  269|    114|        ais->type6.structured = structured;
  270|    186|    } else if (strstr(buf, "\"type\":7,") != NULL
  ------------------
  |  Branch (270:16): [True: 3, False: 183]
  ------------------
  271|    183|               || strstr(buf, "\"type\":13,") != NULL) {
  ------------------
  |  Branch (271:19): [True: 1, False: 182]
  ------------------
  272|      4|        status = json_read_object(buf, json_ais7, endptr);
  273|    182|    } else if (strstr(buf, "\"type\":8,") != NULL) {
  ------------------
  |  Branch (273:16): [True: 119, False: 63]
  ------------------
  274|    119|        bool structured = false;
  275|    119|        if (strstr(buf, "\"dac\":1,") != NULL) {
  ------------------
  |  Branch (275:13): [True: 74, False: 45]
  ------------------
  276|     74|            if (strstr(buf, "\"fid\":11,") != NULL) {
  ------------------
  |  Branch (276:17): [True: 5, False: 69]
  ------------------
  277|      5|                status = json_read_object(buf, json_ais8_fid11, endptr);
  278|      5|                if (status == 0) {
  ------------------
  |  Branch (278:21): [True: 2, False: 3]
  ------------------
  279|       |                    // ais->type8.dac1fid11.day = AIS_DAY_NOT_AVAILABLE;
  280|      2|                    ais->type8.dac1fid11.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      2|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  281|      2|                    ais->type8.dac1fid11.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      2|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  282|      2|                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
  283|      2|                                 &ais->type8.dac1fid11.day,
  284|      2|                                 &ais->type8.dac1fid11.hour,
  285|      2|                                 &ais->type8.dac1fid11.minute);
  286|      2|                }
  287|      5|                structured = true;
  288|      5|            }
  289|     69|            else if (strstr(buf, "\"fid\":13,") != NULL) {
  ------------------
  |  Branch (289:22): [True: 3, False: 66]
  ------------------
  290|      3|                status = json_read_object(buf, json_ais8_fid13, endptr);
  291|      3|                if (status == 0) {
  ------------------
  |  Branch (291:21): [True: 1, False: 2]
  ------------------
  292|       |                    // no need to set zeros, again.
  293|       |                    // ais->type8.dac1fid13.fmonth = AIS_MONTH_NOT_AVAILABLE;
  294|       |                    // ais->type8.dac1fid13.fday = AIS_DAY_NOT_AVAILABLE;
  295|      1|                    ais->type8.dac1fid13.fhour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  296|      1|                    ais->type8.dac1fid13.fminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  297|      1|                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
  298|      1|                                 &ais->type8.dac1fid13.fmonth,
  299|      1|                                 &ais->type8.dac1fid13.fday,
  300|      1|                                 &ais->type8.dac1fid13.fhour,
  301|      1|                                 &ais->type8.dac1fid13.fminute);
  302|       |                    // no need to set zeros, again.
  303|       |                    // ais->type8.dac1fid13.tmonth = AIS_MONTH_NOT_AVAILABLE;
  304|       |                    // ais->type8.dac1fid13.tday = AIS_DAY_NOT_AVAILABLE;
  305|      1|                    ais->type8.dac1fid13.thour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  306|      1|                    ais->type8.dac1fid13.tminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  307|      1|                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
  308|      1|                                 &ais->type8.dac1fid13.tmonth,
  309|      1|                                 &ais->type8.dac1fid13.tday,
  310|      1|                                 &ais->type8.dac1fid13.thour,
  311|      1|                                 &ais->type8.dac1fid13.tminute);
  312|      1|                }
  313|      3|                structured = true;
  314|      3|            }
  315|     66|            else if (strstr(buf, "\"fid\":15,") != NULL) {
  ------------------
  |  Branch (315:22): [True: 1, False: 65]
  ------------------
  316|      1|                status = json_read_object(buf, json_ais8_fid15, endptr);
  317|      1|                structured = true;
  318|      1|            }
  319|     65|            else if (strstr(buf, "\"fid\":16,") != NULL) {
  ------------------
  |  Branch (319:22): [True: 47, False: 18]
  ------------------
  320|     47|                status = json_read_object(buf, json_ais8_fid16, endptr);
  321|     47|                if (status == 0) {
  ------------------
  |  Branch (321:21): [True: 1, False: 46]
  ------------------
  322|      1|                        structured = true;
  323|      1|                }
  324|     47|            }
  325|     18|            else if (strstr(buf, "\"fid\":17,") != NULL) {
  ------------------
  |  Branch (325:22): [True: 1, False: 17]
  ------------------
  326|      1|                status = json_read_object(buf, json_ais8_fid17, endptr);
  327|      1|                structured = true;
  328|      1|            }
  329|     17|            else if (strstr(buf, "\"fid\":19,") != NULL) {
  ------------------
  |  Branch (329:22): [True: 1, False: 16]
  ------------------
  330|      1|                status = json_read_object(buf, json_ais8_fid19, endptr);
  331|      1|                structured = true;
  332|      1|            }
  333|     16|            else if (strstr(buf, "\"fid\":23,") != NULL) {
  ------------------
  |  Branch (333:22): [True: 6, False: 10]
  ------------------
  334|      6|                status = json_read_object(buf, json_ais8_fid23, endptr);
  335|      6|                if (status == 0) {
  ------------------
  |  Branch (335:21): [True: 1, False: 5]
  ------------------
  336|       |                    // no need to set zeros, again.
  337|       |                    /* ais->type8.dac200fid23.start_year =
  338|       |                     *     AIS_YEAR_NOT_AVAILABLE;
  339|       |                     * ais->type8.dac200fid23.start_month =
  340|       |                     *    AIS_MONTH_NOT_AVAILABLE; */
  341|       |                    // ais->type8.dac200fid23.start_day = AIS_DAY_NOT_AVAILABLE;
  342|      1|                    ais->type8.dac200fid23.start_hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  343|      1|                    ais->type8.dac200fid23.start_minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  344|       |                    /* ais->type8.dac200fid23.end_year =
  345|       |                     *     AIS_YEAR_NOT_AVAILABLE;
  346|       |                     * ais->type8.dac200fid23.end_month =
  347|       |                     *     AIS_MONTH_NOT_AVAILABLE; */
  348|       |                    // ais->type8.dac200fid23.end_day = AIS_DAY_NOT_AVAILABLE;
  349|      1|                    ais->type8.dac200fid23.end_hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  350|      1|                    ais->type8.dac200fid23.end_minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  351|      1|                    (void)sscanf(start, "%09u-%02u-%02uT%02u:%02u",
  352|      1|                             &ais->type8.dac200fid23.start_year,
  353|      1|                             &ais->type8.dac200fid23.start_month,
  354|      1|                             &ais->type8.dac200fid23.start_day,
  355|      1|                             &ais->type8.dac200fid23.start_hour,
  356|      1|                             &ais->type8.dac200fid23.start_minute);
  357|      1|                    (void)sscanf(end, "%09u-%02u-%02uT%02u:%02u",
  358|      1|                             &ais->type8.dac200fid23.end_year,
  359|      1|                             &ais->type8.dac200fid23.end_month,
  360|      1|                             &ais->type8.dac200fid23.end_day,
  361|      1|                             &ais->type8.dac200fid23.end_hour,
  362|      1|                             &ais->type8.dac200fid23.end_minute);
  363|      1|                }
  364|      6|                structured = true;
  365|      6|            }
  366|     10|            else if (strstr(buf, "\"fid\":24,") != NULL) {
  ------------------
  |  Branch (366:22): [True: 1, False: 9]
  ------------------
  367|      1|                status = json_read_object(buf, json_ais8_fid24, endptr);
  368|      1|                structured = true;
  369|      1|            }
  370|      9|            else if (strstr(buf, "\"fid\":27,") != NULL) {
  ------------------
  |  Branch (370:22): [True: 5, False: 4]
  ------------------
  371|      5|                status = json_read_object(buf, json_ais8_fid27, endptr);
  372|      5|                if (status == 0) {
  ------------------
  |  Branch (372:21): [True: 1, False: 4]
  ------------------
  373|       |                    // no need to set zeros, again.
  374|       |                    // ais->type8.dac1fid27.month = AIS_MONTH_NOT_AVAILABLE;
  375|       |                    // ais->type8.dac1fid27.day = AIS_DAY_NOT_AVAILABLE;
  376|      1|                    ais->type8.dac1fid27.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  377|      1|                    ais->type8.dac1fid27.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  378|      1|                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
  379|      1|                                 &ais->type8.dac1fid27.month,
  380|      1|                                 &ais->type8.dac1fid27.day,
  381|      1|                                 &ais->type8.dac1fid27.hour,
  382|      1|                                 &ais->type8.dac1fid27.minute);
  383|      1|                }
  384|      5|                structured = true;
  385|      5|            }
  386|      4|            else if (strstr(buf, "\"fid\":29,") != NULL) {
  ------------------
  |  Branch (386:22): [True: 1, False: 3]
  ------------------
  387|      1|                status = json_read_object(buf, json_ais8_fid29, endptr);
  388|      1|                structured = true;
  389|      1|            }
  390|      3|            else if (strstr(buf, "\"fid\":31,") != NULL) {
  ------------------
  |  Branch (390:22): [True: 2, False: 1]
  ------------------
  391|      2|                status = json_read_object(buf, json_ais8_fid31, endptr);
  392|      2|                if (status == 0) {
  ------------------
  |  Branch (392:21): [True: 1, False: 1]
  ------------------
  393|       |                    // ais->type8.dac1fid31.day = AIS_DAY_NOT_AVAILABLE;
  394|      1|                    ais->type8.dac1fid31.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1584|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  395|      1|                    ais->type8.dac1fid31.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1586|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  396|      1|                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
  397|      1|                                 &ais->type8.dac1fid31.day,
  398|      1|                                 &ais->type8.dac1fid31.hour,
  399|      1|                                 &ais->type8.dac1fid31.minute);
  400|      1|                }
  401|      2|                structured = true;
  402|      2|            }
  403|     74|        }
  404|     45|        else if (strstr(buf, "\"dac\":200,") != NULL &&
  ------------------
  |  Branch (404:18): [True: 6, False: 39]
  ------------------
  405|      6|                 strstr(buf,"data")==NULL) {
  ------------------
  |  Branch (405:18): [True: 5, False: 1]
  ------------------
  406|      5|            if (strstr(buf, "\"fid\":10,") != NULL) {
  ------------------
  |  Branch (406:17): [True: 3, False: 2]
  ------------------
  407|      3|                status = json_read_object(buf, json_ais8_fid10, endptr);
  408|      3|                structured = true;
  409|      3|            }
  410|      5|            if (strstr(buf, "\"fid\":40,") != NULL) {
  ------------------
  |  Branch (410:17): [True: 3, False: 2]
  ------------------
  411|      3|                status = json_read_object(buf, json_ais8_fid40, endptr);
  412|      3|                structured = true;
  413|      3|            }
  414|      5|        }
  415|    119|        if (!structured) {
  ------------------
  |  Branch (415:13): [True: 88, False: 31]
  ------------------
  416|     88|            status = json_read_object(buf, json_ais8, endptr);
  417|     88|            if (status == 0)
  ------------------
  |  Branch (417:17): [True: 33, False: 55]
  ------------------
  418|     33|                lenhex_unpack(data, &ais->type8.bitcount,
  419|     33|                              ais->type8.bitdata, sizeof(ais->type8.bitdata));
  420|     88|        }
  421|    119|        ais->type8.structured = structured;
  422|    119|    } else if (strstr(buf, "\"type\":9,") != NULL) {
  ------------------
  |  Branch (422:16): [True: 1, False: 62]
  ------------------
  423|      1|        status = json_read_object(buf, json_ais9, endptr);
  424|     62|    } else if (strstr(buf, "\"type\":10,") != NULL) {
  ------------------
  |  Branch (424:16): [True: 1, False: 61]
  ------------------
  425|      1|        status = json_read_object(buf, json_ais10, endptr);
  426|     61|    } else if (strstr(buf, "\"type\":12,") != NULL) {
  ------------------
  |  Branch (426:16): [True: 3, False: 58]
  ------------------
  427|      3|        status = json_read_object(buf, json_ais12, endptr);
  428|     58|    } else if (strstr(buf, "\"type\":14,") != NULL) {
  ------------------
  |  Branch (428:16): [True: 2, False: 56]
  ------------------
  429|      2|        status = json_read_object(buf, json_ais14, endptr);
  430|     56|    } else if (strstr(buf, "\"type\":15,") != NULL) {
  ------------------
  |  Branch (430:16): [True: 1, False: 55]
  ------------------
  431|      1|        status = json_read_object(buf, json_ais15, endptr);
  432|     55|    } else if (strstr(buf, "\"type\":16,") != NULL) {
  ------------------
  |  Branch (432:16): [True: 1, False: 54]
  ------------------
  433|      1|        status = json_read_object(buf, json_ais16, endptr);
  434|     54|    } else if (strstr(buf, "\"type\":17,") != NULL) {
  ------------------
  |  Branch (434:16): [True: 3, False: 51]
  ------------------
  435|      3|        status = json_read_object(buf, json_ais17, endptr);
  436|      3|        if (status == 0)
  ------------------
  |  Branch (436:13): [True: 1, False: 2]
  ------------------
  437|      1|            lenhex_unpack(data, &ais->type17.bitcount,
  438|      1|                          ais->type17.bitdata, sizeof(ais->type17.bitdata));
  439|     51|    } else if (strstr(buf, "\"type\":18,") != NULL) {
  ------------------
  |  Branch (439:16): [True: 3, False: 48]
  ------------------
  440|      3|        status = json_read_object(buf, json_ais18, endptr);
  441|     48|    } else if (strstr(buf, "\"type\":19,") != NULL) {
  ------------------
  |  Branch (441:16): [True: 1, False: 47]
  ------------------
  442|      1|        status = json_read_object(buf, json_ais19, endptr);
  443|     47|    } else if (strstr(buf, "\"type\":20,") != NULL) {
  ------------------
  |  Branch (443:16): [True: 1, False: 46]
  ------------------
  444|      1|        status = json_read_object(buf, json_ais20, endptr);
  445|     46|    } else if (strstr(buf, "\"type\":21,") != NULL) {
  ------------------
  |  Branch (445:16): [True: 2, False: 44]
  ------------------
  446|      2|        status = json_read_object(buf, json_ais21, endptr);
  447|     44|    } else if (strstr(buf, "\"type\":22,") != NULL) {
  ------------------
  |  Branch (447:16): [True: 2, False: 42]
  ------------------
  448|      2|        status = json_read_object(buf, json_ais22, endptr);
  449|     42|    } else if (strstr(buf, "\"type\":23,") != NULL) {
  ------------------
  |  Branch (449:16): [True: 20, False: 22]
  ------------------
  450|     20|        status = json_read_object(buf, json_ais23, endptr);
  451|     22|    } else if (strstr(buf, "\"type\":24,") != NULL) {
  ------------------
  |  Branch (451:16): [True: 1, False: 21]
  ------------------
  452|      1|        status = json_read_object(buf, json_ais24, endptr);
  453|     21|    } else if (strstr(buf, "\"type\":25,") != NULL) {
  ------------------
  |  Branch (453:16): [True: 11, False: 10]
  ------------------
  454|     11|        status = json_read_object(buf, json_ais25, endptr);
  455|     11|        if (status == 0)
  ------------------
  |  Branch (455:13): [True: 9, False: 2]
  ------------------
  456|      9|            lenhex_unpack(data, &ais->type25.bitcount,
  457|      9|                          ais->type25.bitdata, sizeof(ais->type25.bitdata));
  458|     11|    } else if (strstr(buf, "\"type\":26,") != NULL) {
  ------------------
  |  Branch (458:16): [True: 8, False: 2]
  ------------------
  459|      8|        status = json_read_object(buf, json_ais26, endptr);
  460|      8|        if (status == 0)
  ------------------
  |  Branch (460:13): [True: 4, False: 4]
  ------------------
  461|      4|            lenhex_unpack(data, &ais->type26.bitcount,
  462|      4|                          ais->type26.bitdata, sizeof(ais->type26.bitdata));
  463|      8|    } else if (strstr(buf, "\"type\":27,") != NULL) {
  ------------------
  |  Branch (463:16): [True: 1, False: 1]
  ------------------
  464|      1|        status = json_read_object(buf, json_ais27, endptr);
  465|      1|    } else {
  466|      1|        if (NULL != endptr) {
  ------------------
  |  Branch (466:13): [True: 0, False: 1]
  ------------------
  467|      0|            *endptr = NULL;
  468|      0|        }
  469|      1|        return JSON_ERR_MISC;
  ------------------
  |  |  172|      1|#define JSON_ERR_MISC          21      // other data conversion error
  ------------------
  470|      1|    }
  471|    322|    return status;
  472|    323|}
ais_json.c:lenhex_unpack:
   29|    114|{
   30|    114|    const char *colon = strchr(from, ':');
   31|       |
   32|    114|    *plen = (size_t)atoi(from);
   33|    114|    if (NULL != colon) {
  ------------------
  |  Branch (33:9): [True: 105, False: 9]
  ------------------
   34|    105|        (void)gps_hexpack(colon + 1, (unsigned char *)to, maxlen);
   35|    105|    }
   36|    114|}

safe_atof:
  294|  5.68k|{
  295|  5.68k|    static int maxExponent = 511;   /* Largest possible base 10 exponent.  Any
  296|       |                                     * exponent larger than this will already
  297|       |                                     * produce underflow or overflow, so there's
  298|       |                                     * no need to worry about additional digits.
  299|       |                                     */
  300|       |    /* Table giving binary powers of 10.  Entry is 10^2^i.
  301|       |     * Used to convert decimal exponents into floating-point numbers. */
  302|  5.68k|    static double powersOf10[] = {
  303|  5.68k|        10.,
  304|  5.68k|        100.,
  305|  5.68k|        1.0e4,
  306|  5.68k|        1.0e8,
  307|  5.68k|        1.0e16,
  308|  5.68k|        1.0e32,
  309|  5.68k|        1.0e64,
  310|  5.68k|        1.0e128,
  311|  5.68k|        1.0e256
  312|  5.68k|    };
  313|       |
  314|  5.68k|    bool sign = false, expSign = false;
  315|  5.68k|    double fraction, dblExp, *d;
  316|  5.68k|    const char *p;
  317|  5.68k|    unsigned char c;
  318|  5.68k|    int exp = 0;                // Exponent read from "EX" field.
  319|  5.68k|    int fracExp = 0;            /* Exponent that derives from the fractional
  320|       |                                 * part.  Under normal circumstatnces, it is
  321|       |                                 * the negative of the number of digits in F.
  322|       |                                 * However, if I is very long, the last digits
  323|       |                                 * of I get dropped (otherwise a long I with a
  324|       |                                 * large negative exponent could cause an
  325|       |                                 * unnecessary overflow on I alone).  In this
  326|       |                                 * case, fracExp is incremented one for each
  327|       |                                 * dropped digit. */
  328|  5.68k|    int mantSize;               // Number of digits in mantissa.
  329|  5.68k|    int decPt;                  /* Number of mantissa digits BEFORE decimal
  330|       |                                 * point. */
  331|  5.68k|    const char *pExp;           /* Temporarily holds location of exponent
  332|       |                                 * in string. */
  333|       |
  334|       |    /*
  335|       |     * Strip off leading blanks and check for a sign.
  336|       |     */
  337|       |
  338|       |    // FIXME: JSON is UTF-8, but isspace() islocale dependent...
  339|       |
  340|  5.68k|    p = string;
  341|  5.68k|    while (isspace((int)*p)) {
  ------------------
  |  Branch (341:12): [True: 0, False: 5.68k]
  ------------------
  342|      0|        p += 1;
  343|      0|    }
  344|  5.68k|    if (isdigit((unsigned char)*p)) {
  ------------------
  |  Branch (344:9): [True: 2.80k, False: 2.87k]
  ------------------
  345|       |        // ignore
  346|  2.87k|    } else if ('-' == *p) {
  ------------------
  |  Branch (346:16): [True: 854, False: 2.02k]
  ------------------
  347|    854|        sign = true;
  348|    854|        p += 1;
  349|  2.02k|    } else if ('+' == *p) {
  ------------------
  |  Branch (349:16): [True: 201, False: 1.82k]
  ------------------
  350|    201|        p += 1;
  351|  1.82k|    } else if ('.' == *p) {
  ------------------
  |  Branch (351:16): [True: 1.18k, False: 637]
  ------------------
  352|       |        // ignore
  353|  1.18k|    } else {
  354|    637|        return NAN;
  355|    637|    }
  356|       |
  357|       |    /*
  358|       |     * Count the number of digits in the mantissa (including the decimal
  359|       |     * point), and also locate the decimal point.
  360|       |     */
  361|       |
  362|  5.05k|    decPt = -1;
  363|  21.9k|    for (mantSize = 0; ; mantSize += 1) {
  364|  21.9k|        c = *p;
  365|  21.9k|        if (!isdigit(c)) {
  ------------------
  |  Branch (365:13): [True: 6.50k, False: 15.4k]
  ------------------
  366|  6.50k|            if ((c != '.') || (decPt >= 0)) {
  ------------------
  |  Branch (366:17): [True: 4.84k, False: 1.65k]
  |  Branch (366:31): [True: 203, False: 1.45k]
  ------------------
  367|  5.05k|                break;
  368|  5.05k|            }
  369|  1.45k|            decPt = mantSize;
  370|  1.45k|        }
  371|  16.8k|        p += 1;
  372|  16.8k|    }
  373|       |
  374|       |    /*
  375|       |     * Now suck up the digits in the mantissa.  Use two integers to
  376|       |     * collect 9 digits each (this is faster than using floating-point).
  377|       |     * If the mantissa has more than 18 digits, ignore the extras, since
  378|       |     * they can't affect the value anyway.
  379|       |     */
  380|       |
  381|  5.05k|    pExp  = p;
  382|  5.05k|    p -= mantSize;
  383|  5.05k|    if (decPt < 0) {
  ------------------
  |  Branch (383:9): [True: 3.59k, False: 1.45k]
  ------------------
  384|  3.59k|        decPt = mantSize;
  385|  3.59k|    } else {
  386|  1.45k|        mantSize -= 1;                  // One of the digits was the point.
  387|  1.45k|    }
  388|  5.05k|    if (mantSize > 18) {
  ------------------
  |  Branch (388:9): [True: 241, False: 4.80k]
  ------------------
  389|    241|        fracExp = decPt - 18;
  390|    241|        mantSize = 18;
  391|  4.80k|    } else {
  392|  4.80k|        fracExp = decPt - mantSize;
  393|  4.80k|    }
  394|  5.05k|    if (mantSize == 0) {
  ------------------
  |  Branch (394:9): [True: 1.40k, False: 3.64k]
  ------------------
  395|  1.40k|        fraction = 0.0;
  396|       |        // p = string;
  397|  1.40k|        goto done;
  398|  3.64k|    } else {
  399|  3.64k|        int frac1, frac2;
  400|       |
  401|  3.64k|        frac1 = 0;
  402|  6.69k|        for ( ; mantSize > 9; mantSize -= 1) {
  ------------------
  |  Branch (402:17): [True: 3.04k, False: 3.64k]
  ------------------
  403|  3.04k|            c = *p;
  404|  3.04k|            p += 1;
  405|  3.04k|            if ('.' == c) {
  ------------------
  |  Branch (405:17): [True: 194, False: 2.84k]
  ------------------
  406|    194|                c = *p;
  407|    194|                p += 1;
  408|    194|            }
  409|  3.04k|            frac1 = 10*frac1 + (c - '0');
  410|  3.04k|        }
  411|  3.64k|        frac2 = 0;
  412|  13.3k|        for (; mantSize > 0; mantSize -= 1) {
  ------------------
  |  Branch (412:16): [True: 9.72k, False: 3.64k]
  ------------------
  413|  9.72k|            c = *p;
  414|  9.72k|            p += 1;
  415|  9.72k|            if ('.' == c) {
  ------------------
  |  Branch (415:17): [True: 221, False: 9.50k]
  ------------------
  416|    221|                c = *p;
  417|    221|                p += 1;
  418|    221|            }
  419|  9.72k|            frac2 = 10*frac2 + (c - '0');
  420|  9.72k|        }
  421|  3.64k|        fraction = (1.0e9 * frac1) + frac2;
  422|  3.64k|    }
  423|       |
  424|       |    /*
  425|       |     * Skim off the exponent.
  426|       |     */
  427|       |
  428|  3.64k|    p = pExp;
  429|  3.64k|    if (('E' == *p) ||
  ------------------
  |  Branch (429:9): [True: 1.20k, False: 2.44k]
  ------------------
  430|  2.44k|        ('e' == *p)) {
  ------------------
  |  Branch (430:9): [True: 1.00k, False: 1.44k]
  ------------------
  431|  2.20k|        p += 1;
  432|  2.20k|        if ('-' == *p) {
  ------------------
  |  Branch (432:13): [True: 600, False: 1.60k]
  ------------------
  433|    600|            expSign = true;
  434|    600|            p += 1;
  435|  1.60k|        } else {
  436|  1.60k|            if ('+' == *p) {
  ------------------
  |  Branch (436:17): [True: 238, False: 1.36k]
  ------------------
  437|    238|                p += 1;
  438|    238|            }
  439|  1.60k|            expSign = false;
  440|  1.60k|        }
  441|  4.50k|        while (isdigit((unsigned char) *p)) {
  ------------------
  |  Branch (441:16): [True: 4.50k, False: 1.42k]
  ------------------
  442|  4.50k|            exp = exp * 10 + (*p - '0');
  443|  4.50k|            if (1024 < exp) {
  ------------------
  |  Branch (443:17): [True: 783, False: 3.71k]
  ------------------
  444|    783|                if (true == expSign) {
  ------------------
  |  Branch (444:21): [True: 390, False: 393]
  ------------------
  445|       |                    // exponent underflow!
  446|    390|                    if (sign) {
  ------------------
  |  Branch (446:25): [True: 196, False: 194]
  ------------------
  447|    196|                        return -0.0;
  448|    196|                    }
  449|    194|                    return 0.0;
  450|    390|                } // else  exponent overflow!
  451|    393|                if (sign) {
  ------------------
  |  Branch (451:21): [True: 194, False: 199]
  ------------------
  452|    194|                    return -INFINITY;
  453|    194|                }
  454|    199|                return INFINITY;
  455|    393|            }
  456|  3.71k|            p += 1;
  457|  3.71k|        }
  458|  2.20k|    }
  459|  2.86k|    if (expSign) {
  ------------------
  |  Branch (459:9): [True: 210, False: 2.65k]
  ------------------
  460|    210|        exp = fracExp - exp;
  461|  2.65k|    } else {
  462|  2.65k|        exp = fracExp + exp;
  463|  2.65k|    }
  464|       |
  465|       |    /*
  466|       |     * Generate a floating-point number that represents the exponent.
  467|       |     * Do this by processing the exponent one bit at a time to combine
  468|       |     * many powers of 2 of 10. Then combine the exponent with the
  469|       |     * fraction.
  470|       |     */
  471|       |
  472|  2.86k|    if (0 > exp) {
  ------------------
  |  Branch (472:9): [True: 406, False: 2.46k]
  ------------------
  473|    406|        expSign = true;
  474|    406|        exp = -exp;
  475|  2.46k|    } else {
  476|  2.46k|        expSign = false;
  477|  2.46k|    }
  478|  2.86k|    if (exp > maxExponent) {
  ------------------
  |  Branch (478:9): [True: 226, False: 2.64k]
  ------------------
  479|    226|        exp = maxExponent;
  480|    226|        errno = ERANGE;
  481|    226|    }
  482|  2.86k|    dblExp = 1.0;
  483|  7.55k|    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
  ------------------
  |  Branch (483:26): [True: 4.69k, False: 2.86k]
  ------------------
  484|  4.69k|        if (exp & 01) {
  ------------------
  |  Branch (484:13): [True: 3.63k, False: 1.05k]
  ------------------
  485|  3.63k|            dblExp *= *d;
  486|  3.63k|        }
  487|  4.69k|    }
  488|  2.86k|    if (expSign) {
  ------------------
  |  Branch (488:9): [True: 406, False: 2.46k]
  ------------------
  489|    406|        fraction /= dblExp;
  490|  2.46k|    } else {
  491|  2.46k|        fraction *= dblExp;
  492|  2.46k|    }
  493|       |
  494|  4.26k|done:
  495|  4.26k|    if (sign) {
  ------------------
  |  Branch (495:9): [True: 464, False: 3.80k]
  ------------------
  496|    464|        return -fraction;
  497|    464|    }
  498|  3.80k|    return fraction;
  499|  4.26k|}
mkgmtime:
  849|  1.91k|{
  850|  1.91k|    int year;
  851|  1.91k|    time_t result;
  852|  1.91k|    static const int cumdays[MONTHSPERYEAR] =
  853|  1.91k|        { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  854|       |
  855|       |    // check ranges, ignore tm_isdst and max tm_year
  856|  1.91k|    if (0 > t->tm_sec ||
  ------------------
  |  Branch (856:9): [True: 0, False: 1.91k]
  ------------------
  857|  1.91k|        0 > t->tm_min ||
  ------------------
  |  Branch (857:9): [True: 0, False: 1.91k]
  ------------------
  858|  1.91k|        0 > t->tm_hour ||
  ------------------
  |  Branch (858:9): [True: 0, False: 1.91k]
  ------------------
  859|  1.91k|        1 > t->tm_mday ||
  ------------------
  |  Branch (859:9): [True: 197, False: 1.72k]
  ------------------
  860|  1.72k|        0 > t->tm_mon ||
  ------------------
  |  Branch (860:9): [True: 0, False: 1.72k]
  ------------------
  861|  1.72k|        0 > t->tm_year ||
  ------------------
  |  Branch (861:9): [True: 624, False: 1.09k]
  ------------------
  862|  1.09k|        0 > t->tm_wday ||
  ------------------
  |  Branch (862:9): [True: 0, False: 1.09k]
  ------------------
  863|  1.09k|        0 > t->tm_yday ||
  ------------------
  |  Branch (863:9): [True: 0, False: 1.09k]
  ------------------
  864|  1.09k|        61 < t->tm_sec ||
  ------------------
  |  Branch (864:9): [True: 0, False: 1.09k]
  ------------------
  865|  1.09k|        59 < t->tm_min ||
  ------------------
  |  Branch (865:9): [True: 0, False: 1.09k]
  ------------------
  866|  1.09k|        23 < t->tm_hour ||
  ------------------
  |  Branch (866:9): [True: 0, False: 1.09k]
  ------------------
  867|  1.09k|        31 < t->tm_mday ||
  ------------------
  |  Branch (867:9): [True: 0, False: 1.09k]
  ------------------
  868|  1.09k|        11 < t->tm_mon ||
  ------------------
  |  Branch (868:9): [True: 0, False: 1.09k]
  ------------------
  869|  1.09k|        6 < t->tm_wday ||
  ------------------
  |  Branch (869:9): [True: 0, False: 1.09k]
  ------------------
  870|  1.09k|        365 < t->tm_yday) {
  ------------------
  |  Branch (870:9): [True: 0, False: 1.09k]
  ------------------
  871|    821|        errno = EOVERFLOW;
  872|    821|        return -1;
  873|    821|    }
  874|  1.91k|    errno = 0;
  875|  1.09k|    year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR;
  ------------------
  |  |  501|  1.09k|#define MONTHSPERYEAR   12      // months per calendar year
  ------------------
  876|  1.09k|    result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR];
  ------------------
  |  |  501|  1.09k|#define MONTHSPERYEAR   12      // months per calendar year
  ------------------
  877|  1.09k|    result += (year - 1968) / 4;
  878|  1.09k|    result -= (year - 1900) / 100;
  879|  1.09k|    result += (year - 1600) / 400;
  880|  1.09k|    if (0 == (year % 4) &&
  ------------------
  |  Branch (880:9): [True: 618, False: 478]
  ------------------
  881|    618|        (0 != (year % 100) ||
  ------------------
  |  Branch (881:10): [True: 218, False: 400]
  ------------------
  882|    400|         0 == (year % 400)) &&
  ------------------
  |  Branch (882:10): [True: 202, False: 198]
  ------------------
  883|    420|        (2 > (t->tm_mon % MONTHSPERYEAR))) {
  ------------------
  |  |  501|    420|#define MONTHSPERYEAR   12      // months per calendar year
  ------------------
  |  Branch (883:9): [True: 211, False: 209]
  ------------------
  884|    211|        result--;
  885|    211|    }
  886|  1.09k|    result += t->tm_mday - 1;
  887|  1.09k|    result *= 24;
  888|  1.09k|    result += t->tm_hour;
  889|  1.09k|    result *= 60;
  890|  1.09k|    result += t->tm_min;
  891|  1.09k|    result *= 60;
  892|  1.09k|    result += t->tm_sec;
  893|       |    /* this is UTC, no DST
  894|       |     * if (t->tm_isdst == 1)
  895|       |     * result -= 3600;
  896|       |     */
  897|  1.09k|    return result;
  898|  1.91k|}
iso8601_to_timespec:
  902|  1.91k|{
  903|  1.91k|    timespec_t ret = {0};
  904|       |
  905|       |#ifdef USE_QT
  906|       |  #ifndef __clang_analyzer__
  907|       |    double usec = 0;
  908|       |
  909|       |    QString t(isotime);
  910|       |    QDateTime d = QDateTime::fromString(isotime, Qt::ISODate);
  911|       |    QStringList sl = t.split(".");
  912|       |    if (1 < sl.size()) {
  913|       |        usec = sl[1].toInt() / pow(10., (double)sl[1].size());
  914|       |    }
  915|       |// toSecsSinceEpoch wasn't introduced until 5.8
  916|       |#if QT_VERSION < QT_VERSION_CHECK(5,8,0)
  917|       |    ret.tv_sec = d.toTime_t();
  918|       |#else
  919|       |    ret.tv_sec = d.toSecsSinceEpoch();
  920|       |#endif
  921|       |    ret.tv_nsec = usec * 1e9;
  922|       |  #endif  // __clang_analyzer__
  923|       |#else  // USE_QT
  924|  1.91k|    double usec = 0;
  925|  1.91k|    struct tm tm = {0};
  926|       |
  927|  1.91k|    {
  928|  1.91k|        char *dp = NULL;
  929|  1.91k|        dp = strptime(isotime, "%Y-%m-%dT%H:%M:%S", &tm);
  930|  1.91k|        if (NULL != dp &&
  ------------------
  |  Branch (930:13): [True: 622, False: 1.29k]
  ------------------
  931|    622|            '.' == *dp) {
  ------------------
  |  Branch (931:13): [True: 194, False: 428]
  ------------------
  932|    194|            usec = strtod(dp, NULL);
  933|    194|        }
  934|  1.91k|    }
  935|       |
  936|       |    /*
  937|       |     * It would be nice if we could say mktime(&tm) - timezone + usec instead,
  938|       |     * but timezone is not available at all on some BSDs. Besides, when working
  939|       |     * with historical dates the value of timezone after an ordinary tzset(3)
  940|       |     * can be wrong; you have to do a redirect through the IANA historical
  941|       |     * timezone database to get it right.
  942|       |     */
  943|  1.91k|    ret.tv_sec = mkgmtime(&tm);
  944|  1.91k|    ret.tv_nsec = usec * 1e9;
  945|  1.91k|#endif  // USE_QT
  946|       |
  947|  1.91k|#if 4 < SIZEOF_TIME_T
  948|  1.91k|    if (253402300799LL < ret.tv_sec) {
  ------------------
  |  Branch (948:9): [True: 194, False: 1.72k]
  ------------------
  949|       |        // enforce max "9999-12-31T23:59:59.999Z"
  950|    194|        ret.tv_sec = 253402300799LL;
  951|    194|    }
  952|  1.91k|#endif
  953|  1.91k|    return ret;
  954|  1.91k|}

gps_hexpack:
  119|    105|{
  120|    105|    ssize_t i, j;
  121|       |
  122|    105|    j = strnlen(src, BUFSIZ) / 2;
  123|    105|    if ((1 > j) ||
  ------------------
  |  Branch (123:9): [True: 2, False: 103]
  ------------------
  124|    103|        ((size_t)j > len)) {
  ------------------
  |  Branch (124:9): [True: 10, False: 93]
  ------------------
  125|     12|        return -2;
  126|     12|    }
  127|       |
  128|    416|    for (i = 0; i < j; i++) {
  ------------------
  |  Branch (128:17): [True: 380, False: 36]
  ------------------
  129|    380|        int k;
  130|    380|        if (-1 == (k = hex2bin(src + i * 2))) {
  ------------------
  |  Branch (130:13): [True: 57, False: 323]
  ------------------
  131|     57|            return -1;
  132|     57|        }
  133|    323|        dst[i] = (char)(k & 0xff);
  134|    323|    }
  135|     36|    (void)memset(dst + i, '\0', (size_t)(len - i));
  136|     36|    return j;
  137|     93|}
hex.c:hex2bin:
   82|    380|{
   83|    380|    int a, b;
   84|       |
   85|    380|    a = s[0] & 0xff;
   86|    380|    b = s[1] & 0xff;
   87|       |
   88|    380|    if ((a >= 'a') &&
  ------------------
  |  Branch (88:9): [True: 110, False: 270]
  ------------------
   89|    110|        (a <= 'f')) {
  ------------------
  |  Branch (89:9): [True: 103, False: 7]
  ------------------
   90|    103|        a = a + 10 - 'a';
   91|    277|    } else if ((a >= 'A') &&
  ------------------
  |  Branch (91:16): [True: 151, False: 126]
  ------------------
   92|    151|               (a <= 'F')) {
  ------------------
  |  Branch (92:16): [True: 139, False: 12]
  ------------------
   93|    139|        a = a + 10 - 'A';
   94|    139|    } else if ((a >= '0') &&
  ------------------
  |  Branch (94:16): [True: 136, False: 2]
  ------------------
   95|    136|               (a <= '9')) {
  ------------------
  |  Branch (95:16): [True: 120, False: 16]
  ------------------
   96|    120|        a -= '0';
   97|    120|    } else {
   98|     18|        return -1;
   99|     18|    }
  100|       |
  101|    362|    if ((b >= 'a') &&
  ------------------
  |  Branch (101:9): [True: 100, False: 262]
  ------------------
  102|    100|        (b <= 'f')) {
  ------------------
  |  Branch (102:9): [True: 85, False: 15]
  ------------------
  103|     85|        b = b + 10 - 'a';
  104|    277|    } else if ((b >= 'A') &&
  ------------------
  |  Branch (104:16): [True: 160, False: 117]
  ------------------
  105|    160|               (b <= 'F')) {
  ------------------
  |  Branch (105:16): [True: 133, False: 27]
  ------------------
  106|    133|        b = b + 10 - 'A';
  107|    144|    } else if ((b >= '0') &&
  ------------------
  |  Branch (107:16): [True: 137, False: 7]
  ------------------
  108|    137|               (b <= '9')) {
  ------------------
  |  Branch (108:16): [True: 105, False: 32]
  ------------------
  109|    105|        b -= '0';
  110|    105|    } else {
  111|     39|        return -1;
  112|     39|    }
  113|       |
  114|    323|    return ((a << 4) + b);
  115|    362|}

json_read_array:
  802|    915|{
  803|    915|    int substatus;
  804|    915|    unsigned offset, arrcount;
  805|    915|    char *tp;
  806|       |
  807|    915|    if (NULL != end) {
  ------------------
  |  Branch (807:9): [True: 915, False: 0]
  ------------------
  808|    915|        *end = NULL;    // give it a well-defined value on parse failure
  809|    915|    }
  810|       |
  811|    915|    json_debug_trace(1, "json: %s", "Entered json_read_array()\n");
  ------------------
  |  |  108|    915|    do {                                              \
  |  |  109|    915|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    915|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 915]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 915]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    915|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    915|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 915]
  |  |  ------------------
  ------------------
  812|       |
  813|    915|    while (isspace((unsigned char)*cp)) {
  ------------------
  |  Branch (813:12): [True: 0, False: 915]
  ------------------
  814|      0|        cp++;
  815|      0|    }
  816|    915|    if (*cp != '[') {
  ------------------
  |  Branch (816:9): [True: 0, False: 915]
  ------------------
  817|      0|        json_debug_trace(1, "json: %s", "Didn't find expected array start\n");
  ------------------
  |  |  108|      0|    do {                                              \
  |  |  109|      0|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      0|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 0]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      0|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 0]
  |  |  ------------------
  ------------------
  818|      0|        return JSON_ERR_ARRAYSTART;
  ------------------
  |  |  161|      0|#define JSON_ERR_ARRAYSTART    10      // didn't find expected array start
  ------------------
  819|      0|    }
  820|    915|    cp++;
  821|       |
  822|    915|    tp = arr->arr.strings.store;
  823|    915|    arrcount = 0;
  824|       |
  825|       |    // Check for empty array
  826|    915|    while (isspace((unsigned char)*cp)) {
  ------------------
  |  Branch (826:12): [True: 194, False: 915]
  ------------------
  827|    194|        cp++;
  828|    194|    }
  829|    915|    if (*cp == ']') {
  ------------------
  |  Branch (829:9): [True: 219, False: 696]
  ------------------
  830|    219|        goto breakout;
  831|    219|    }
  832|       |
  833|  8.82k|    for (offset = 0; offset < arr->maxlen; offset++) {
  ------------------
  |  Branch (833:22): [True: 8.82k, False: 1]
  ------------------
  834|  8.82k|        char *ep = NULL;
  835|       |
  836|  8.82k|        json_debug_trace(1, "json: Looking at %s\n", cp);
  ------------------
  |  |  108|  8.82k|    do {                                              \
  |  |  109|  8.82k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|  8.82k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 8.82k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 8.82k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|  8.82k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|  8.82k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 8.82k]
  |  |  ------------------
  ------------------
  837|  8.82k|        switch (arr->element_type) {
  ------------------
  |  Branch (837:17): [True: 8.82k, False: 0]
  ------------------
  838|  3.10k|        case t_string:
  ------------------
  |  Branch (838:9): [True: 3.10k, False: 5.72k]
  ------------------
  839|  3.10k|            if (isspace((unsigned char) *cp)) {
  ------------------
  |  Branch (839:17): [True: 194, False: 2.90k]
  ------------------
  840|    194|                cp++;
  841|    194|            }
  842|  3.10k|            if (*cp != '"') {
  ------------------
  |  Branch (842:17): [True: 16, False: 3.08k]
  ------------------
  843|     16|                return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|     16|#define JSON_ERR_BADSTRING     15      // error while string parsing
  ------------------
  844|  3.08k|            } else {
  845|  3.08k|                ++cp;
  846|  3.08k|            }
  847|  3.08k|            arr->arr.strings.ptrs[offset] = tp;
  848|  13.9k|            for (; tp - arr->arr.strings.store < arr->arr.strings.storelen;
  ------------------
  |  Branch (848:20): [True: 13.8k, False: 3]
  ------------------
  849|  10.8k|                 tp++)
  850|  13.8k|                if (*cp == '"') {
  ------------------
  |  Branch (850:21): [True: 3.08k, False: 10.8k]
  ------------------
  851|  3.08k|                    ++cp;
  852|  3.08k|                    *tp++ = '\0';
  853|  3.08k|                    goto stringend;
  854|  10.8k|                } else if (*cp == '\0') {
  ------------------
  |  Branch (854:28): [True: 1, False: 10.8k]
  ------------------
  855|      1|                    json_debug_trace(1, "json: %s",
  ------------------
  |  |  108|      1|    do {                                              \
  |  |  109|      1|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      1|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 1]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 1]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      1|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 1]
  |  |  ------------------
  ------------------
  856|      1|                                      "Bad string syntax in string list.\n");
  857|      1|                    return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      1|#define JSON_ERR_BADSTRING     15      // error while string parsing
  ------------------
  858|  10.8k|                } else {
  859|  10.8k|                    *tp = *cp++;
  860|  10.8k|                }
  861|      3|            json_debug_trace(1, "json: %s",
  ------------------
  |  |  108|      3|    do {                                              \
  |  |  109|      3|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      3|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 3]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 3]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      3|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      3|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 3]
  |  |  ------------------
  ------------------
  862|      3|                             "Bad string syntax in string list.\n");
  863|      3|            return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      3|#define JSON_ERR_BADSTRING     15      // error while string parsing
  ------------------
  864|  3.08k|          stringend:
  865|  3.08k|            break;
  866|      0|        case t_object:
  ------------------
  |  Branch (866:9): [True: 0, False: 8.82k]
  ------------------
  867|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  868|  5.72k|        case t_structobject:
  ------------------
  |  Branch (868:9): [True: 5.72k, False: 3.10k]
  ------------------
  869|  5.72k|            substatus =
  870|  5.72k|                json_internal_read_object(cp, arr->arr.objects.subtype, arr,
  871|  5.72k|                                          offset, &cp);
  872|  5.72k|            if (substatus != 0) {
  ------------------
  |  Branch (872:17): [True: 148, False: 5.57k]
  ------------------
  873|    148|                if (NULL != end) {
  ------------------
  |  Branch (873:21): [True: 148, False: 0]
  ------------------
  874|    148|                    *end = cp;
  875|    148|                }
  876|    148|                return substatus;
  877|    148|            }
  878|  5.57k|            break;
  879|  5.57k|        case t_integer:
  ------------------
  |  Branch (879:9): [True: 0, False: 8.82k]
  ------------------
  880|      0|            arr->arr.integers.store[offset] = (int)strtol(cp, &ep, 0);
  881|      0|            if (ep == cp) {
  ------------------
  |  Branch (881:17): [True: 0, False: 0]
  ------------------
  882|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  883|      0|            }
  884|      0|            cp = ep;
  885|      0|            break;
  886|      0|        case t_uinteger:
  ------------------
  |  Branch (886:9): [True: 0, False: 8.82k]
  ------------------
  887|      0|            arr->arr.uintegers.store[offset] = (unsigned int)strtoul(cp,
  888|      0|                                                                     &ep, 0);
  889|      0|            if (ep == cp) {
  ------------------
  |  Branch (889:17): [True: 0, False: 0]
  ------------------
  890|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  891|      0|            }
  892|      0|            cp = ep;
  893|      0|            break;
  894|      0|        case t_longint:
  ------------------
  |  Branch (894:9): [True: 0, False: 8.82k]
  ------------------
  895|      0|            arr->arr.longint.store[offset] = strtol(cp, &ep, 0);
  896|      0|            if (ep == cp) {
  ------------------
  |  Branch (896:17): [True: 0, False: 0]
  ------------------
  897|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  898|      0|            }
  899|      0|            cp = ep;
  900|      0|            break;
  901|      0|        case t_ulongint:
  ------------------
  |  Branch (901:9): [True: 0, False: 8.82k]
  ------------------
  902|      0|            arr->arr.ulongint.store[offset] = strtoul(cp, &ep, 0);
  903|      0|            if (ep == cp) {
  ------------------
  |  Branch (903:17): [True: 0, False: 0]
  ------------------
  904|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  905|      0|            }
  906|      0|            cp = ep;
  907|      0|            break;
  908|      0|        case t_byte:
  ------------------
  |  Branch (908:9): [True: 0, False: 8.82k]
  ------------------
  909|      0|            arr->arr.bytes.store[offset] = (char)strtol(cp, &ep, 0);
  910|      0|            if (ep == cp) {
  ------------------
  |  Branch (910:17): [True: 0, False: 0]
  ------------------
  911|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  912|      0|            }
  913|      0|            cp = ep;
  914|      0|            break;
  915|      0|        case t_ubyte:
  ------------------
  |  Branch (915:9): [True: 0, False: 8.82k]
  ------------------
  916|      0|            arr->arr.ubytes.store[offset] = (unsigned char)strtoul(cp,
  917|      0|                                                                   &ep, 0);
  918|      0|            if (ep == cp) {
  ------------------
  |  Branch (918:17): [True: 0, False: 0]
  ------------------
  919|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  920|      0|            }
  921|      0|            cp = ep;
  922|      0|            break;
  923|      0|        case t_short:
  ------------------
  |  Branch (923:9): [True: 0, False: 8.82k]
  ------------------
  924|      0|            arr->arr.shorts.store[offset] = (short)strtol(cp, &ep, 0);
  925|      0|            if (ep == cp) {
  ------------------
  |  Branch (925:17): [True: 0, False: 0]
  ------------------
  926|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  927|      0|            }
  928|      0|            cp = ep;
  929|      0|            break;
  930|      0|        case t_ushort:
  ------------------
  |  Branch (930:9): [True: 0, False: 8.82k]
  ------------------
  931|      0|            arr->arr.ushorts.store[offset] = (unsigned short)strtoul(cp,
  932|      0|                                                                     &ep, 0);
  933|      0|            if (ep == cp) {
  ------------------
  |  Branch (933:17): [True: 0, False: 0]
  ------------------
  934|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  935|      0|            }
  936|      0|            cp = ep;
  937|      0|            break;
  938|      0|        case t_time:
  ------------------
  |  Branch (938:9): [True: 0, False: 8.82k]
  ------------------
  939|      0|            {
  940|      0|                timespec_t ts_tmp;
  941|      0|                if (*cp != '"') {
  ------------------
  |  Branch (941:21): [True: 0, False: 0]
  ------------------
  942|      0|                    return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      0|#define JSON_ERR_BADSTRING     15      // error while string parsing
  ------------------
  943|      0|                } else {
  944|      0|                    ++cp;
  945|      0|                }
  946|      0|                ts_tmp = iso8601_to_timespec(cp);
  947|      0|                arr->arr.timespecs.store[offset] = ts_tmp;
  948|      0|                while (*cp &&
  ------------------
  |  Branch (948:24): [True: 0, False: 0]
  ------------------
  949|      0|                       *cp != '"') {
  ------------------
  |  Branch (949:24): [True: 0, False: 0]
  ------------------
  950|      0|                    cp++;
  951|      0|                }
  952|      0|                if (*cp != '"') {
  ------------------
  |  Branch (952:21): [True: 0, False: 0]
  ------------------
  953|      0|                    return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      0|#define JSON_ERR_BADSTRING     15      // error while string parsing
  ------------------
  954|      0|                }
  955|      0|                ++cp;
  956|      0|            }
  957|      0|            break;
  958|      0|        case t_timespec:
  ------------------
  |  Branch (958:9): [True: 0, False: 8.82k]
  ------------------
  959|       |            // TODO not sure how to implement this
  960|      0|            return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  961|      0|            break;
  962|      0|        case t_real:
  ------------------
  |  Branch (962:9): [True: 0, False: 8.82k]
  ------------------
  963|      0|            arr->arr.reals.store[offset] = strtod(cp, &ep);
  964|      0|            if (ep == cp) {
  ------------------
  |  Branch (964:17): [True: 0, False: 0]
  ------------------
  965|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM        22      // error parsing a numerical argument
  ------------------
  966|      0|            }
  967|      0|            cp = ep;
  968|      0|            break;
  969|      0|        case t_boolean:
  ------------------
  |  Branch (969:9): [True: 0, False: 8.82k]
  ------------------
  970|      0|            if (str_starts_with(cp, "true")) {
  ------------------
  |  Branch (970:17): [True: 0, False: 0]
  ------------------
  971|      0|                arr->arr.booleans.store[offset] = true;
  972|      0|                cp += 4;
  973|      0|            } else if (str_starts_with(cp, "false")) {
  ------------------
  |  Branch (973:24): [True: 0, False: 0]
  ------------------
  974|      0|                arr->arr.booleans.store[offset] = false;
  975|      0|                cp += 5;
  976|      0|            }
  977|      0|            break;
  978|      0|        case t_character:
  ------------------
  |  Branch (978:9): [True: 0, False: 8.82k]
  ------------------
  979|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  980|      0|        case t_array:
  ------------------
  |  Branch (980:9): [True: 0, False: 8.82k]
  ------------------
  981|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  982|      0|        case t_check:
  ------------------
  |  Branch (982:9): [True: 0, False: 8.82k]
  ------------------
  983|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  984|      0|        case t_ignore:
  ------------------
  |  Branch (984:9): [True: 0, False: 8.82k]
  ------------------
  985|      0|            json_debug_trace(1, "json: %s", "Invalid array subtype.\n");
  ------------------
  |  |  108|      0|    do {                                              \
  |  |  109|      0|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      0|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 0]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      0|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 0]
  |  |  ------------------
  ------------------
  986|      0|            return JSON_ERR_SUBTYPE;
  ------------------
  |  |  165|      0|#define JSON_ERR_SUBTYPE       14      // unsupported array element type
  ------------------
  987|  8.82k|        }
  988|  8.65k|        arrcount++;
  989|  8.65k|        if (isspace((unsigned char)*cp)) {
  ------------------
  |  Branch (989:13): [True: 194, False: 8.46k]
  ------------------
  990|    194|            cp++;
  991|    194|        }
  992|  8.65k|        if (*cp == ']') {
  ------------------
  |  Branch (992:13): [True: 377, False: 8.28k]
  ------------------
  993|    377|            json_debug_trace(1, "json: %s", "End of array found.\n");
  ------------------
  |  |  108|    377|    do {                                              \
  |  |  109|    377|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    377|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 377]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 377]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    377|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    377|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 377]
  |  |  ------------------
  ------------------
  994|    377|            goto breakout;
  995|    377|        }
  996|  8.28k|        if (*cp == ',') {
  ------------------
  |  Branch (996:13): [True: 8.13k, False: 150]
  ------------------
  997|  8.13k|            cp++;
  998|  8.13k|        } else {
  999|    150|            json_debug_trace(1, "json: %s", "Bad trailing syntax on array.\n");
  ------------------
  |  |  108|    150|    do {                                              \
  |  |  109|    150|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    150|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 150]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 150]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    150|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    150|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 150]
  |  |  ------------------
  ------------------
 1000|    150|            return JSON_ERR_BADSUBTRAIL;
  ------------------
  |  |  164|    150|#define JSON_ERR_BADSUBTRAIL   13      // garbage while expecting array comma
  ------------------
 1001|    150|        }
 1002|  8.28k|    }
 1003|      1|    json_debug_trace(1, "json: %s", "Too many elements in array.\n");
  ------------------
  |  |  108|      1|    do {                                              \
  |  |  109|      1|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      1|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 1]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 1]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      1|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 1]
  |  |  ------------------
  ------------------
 1004|      1|    if (NULL != end) {
  ------------------
  |  Branch (1004:9): [True: 1, False: 0]
  ------------------
 1005|      1|        *end = cp;
 1006|      1|    }
 1007|      1|    return JSON_ERR_SUBTOOLONG;
  ------------------
  |  |  163|      1|#define JSON_ERR_SUBTOOLONG    12      // too many array elements
  ------------------
 1008|    596|  breakout:
 1009|    596|    if (NULL != arr->count) {
  ------------------
  |  Branch (1009:9): [True: 596, False: 0]
  ------------------
 1010|    596|        *(arr->count) = arrcount;
 1011|    596|    }
 1012|    596|    if (NULL != end) {
  ------------------
  |  Branch (1012:9): [True: 596, False: 0]
  ------------------
 1013|    596|        *end = cp;
 1014|    596|    }
 1015|    596|    json_debug_trace(1, "json: leaving json_read_array() with %d elements\n",
  ------------------
  |  |  108|    596|    do {                                              \
  |  |  109|    596|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    596|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 596]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 596]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    596|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    596|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 596]
  |  |  ------------------
  ------------------
 1016|    596|                      arrcount);
 1017|    596|    return 0;
 1018|    696|}
json_read_object:
 1022|  5.22k|{
 1023|  5.22k|    int st;
 1024|       |
 1025|  5.22k|    json_debug_trace(1, "json: json_read_object() sees '%s'\n", cp);
  ------------------
  |  |  108|  5.22k|    do {                                              \
  |  |  109|  5.22k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|  5.22k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 5.22k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 5.22k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|  5.22k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|  5.22k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 5.22k]
  |  |  ------------------
  ------------------
 1026|       |    st = json_internal_read_object(cp, attrs, NULL, 0, end);
 1027|  5.22k|    return st;
 1028|  5.22k|}
json.c:json_internal_read_object:
  199|  10.9k|{
  200|  10.9k|    enum
  201|  10.9k|    { init, await_attr, in_attr, await_value, in_val_string,
  202|  10.9k|        in_escape, in_val_token, post_val, post_element, in_ignore_array
  203|  10.9k|    } state = 0;
  204|  10.9k|    char *statenames[] = {
  205|  10.9k|        "init", "await_attr", "in_attr", "await_value", "in_val_string",
  206|  10.9k|        "in_escape", "in_val_token", "post_val", "post_element",
  207|  10.9k|        "in_ignore_array"
  208|  10.9k|    };
  209|  10.9k|    char attrbuf[JSON_ATTR_MAX + 1], *pattr = NULL;
  210|  10.9k|    char valbuf[JSON_VAL_MAX + 1], *pval = NULL;
  211|  10.9k|    bool value_quoted = false;
  212|  10.9k|    char uescape[5];            // enough space for 4 hex digits and a NUL
  213|  10.9k|    const struct json_attr_t *cursor;
  214|  10.9k|    int substatus, maxlen = 0;
  215|  10.9k|    unsigned int u;
  216|  10.9k|    const struct json_enum_t *mp;
  217|  10.9k|    char *lptr;
  218|       |
  219|  10.9k|    if (NULL != end) {
  ------------------
  |  Branch (219:9): [True: 5.72k, False: 5.22k]
  ------------------
  220|  5.72k|        *end = NULL;    // give it a well-defined value on parse failure
  221|  5.72k|    }
  222|  10.9k|    memset(valbuf, 0, sizeof(valbuf));
  223|       |
  224|       |    // stuff fields with defaults in case they're omitted in the JSON input
  225|   166k|    for (cursor = attrs; cursor->attribute != NULL; cursor++)
  ------------------
  |  Branch (225:26): [True: 155k, False: 10.9k]
  ------------------
  226|   155k|        if (!cursor->nodefault) {
  ------------------
  |  Branch (226:13): [True: 155k, False: 162]
  ------------------
  227|   155k|            lptr = json_target_address(cursor, parent, offset);
  228|   155k|            if (NULL != lptr)
  ------------------
  |  Branch (228:17): [True: 145k, False: 10.5k]
  ------------------
  229|   145k|                switch (cursor->type) {
  ------------------
  |  Branch (229:25): [True: 145k, False: 0]
  ------------------
  230|  3.66k|                case t_byte:
  ------------------
  |  Branch (230:17): [True: 3.66k, False: 141k]
  ------------------
  231|  3.66k|                    lptr[0] = cursor->dflt.byte;
  232|  3.66k|                    break;
  233|  23.1k|                case t_ubyte:
  ------------------
  |  Branch (233:17): [True: 23.1k, False: 122k]
  ------------------
  234|  23.1k|                    lptr[0] = cursor->dflt.ubyte;
  235|  23.1k|                    break;
  236|  17.8k|                case t_integer:
  ------------------
  |  Branch (236:17): [True: 17.8k, False: 127k]
  ------------------
  237|  17.8k|                    memcpy(lptr, &cursor->dflt.integer, sizeof(int));
  238|  17.8k|                    break;
  239|  7.70k|                case t_uinteger:
  ------------------
  |  Branch (239:17): [True: 7.70k, False: 137k]
  ------------------
  240|  7.70k|                    memcpy(lptr, &cursor->dflt.uinteger, sizeof(unsigned int));
  241|  7.70k|                    break;
  242|    898|                case t_longint:
  ------------------
  |  Branch (242:17): [True: 898, False: 144k]
  ------------------
  243|    898|                    memcpy(lptr, &cursor->dflt.longint, sizeof(long));
  244|    898|                    break;
  245|    133|                case t_ulongint:
  ------------------
  |  Branch (245:17): [True: 133, False: 145k]
  ------------------
  246|    133|                    memcpy(lptr, &cursor->dflt.ulongint,
  247|    133|                           sizeof(unsigned long));
  248|    133|                    break;
  249|  3.66k|                case t_short:
  ------------------
  |  Branch (249:17): [True: 3.66k, False: 141k]
  ------------------
  250|  3.66k|                    memcpy(lptr, &cursor->dflt.shortint, sizeof(short));
  251|  3.66k|                    break;
  252|      0|                case t_ushort:
  ------------------
  |  Branch (252:17): [True: 0, False: 145k]
  ------------------
  253|      0|                    memcpy(lptr, &cursor->dflt.ushortint,
  254|      0|                           sizeof(unsigned short));
  255|      0|                    break;
  256|  1.74k|                case t_time:
  ------------------
  |  Branch (256:17): [True: 1.74k, False: 143k]
  ------------------
  257|  1.74k|                    memcpy(lptr, &cursor->dflt.ts, sizeof(timespec_t));
  258|  1.74k|                    break;
  259|  1.26k|                case t_timespec:
  ------------------
  |  Branch (259:17): [True: 1.26k, False: 143k]
  ------------------
  260|  1.26k|                    memcpy(lptr, &cursor->dflt.ts, sizeof(timespec_t));
  261|  1.26k|                    break;
  262|  61.1k|                case t_real:
  ------------------
  |  Branch (262:17): [True: 61.1k, False: 84.0k]
  ------------------
  263|  61.1k|                    memcpy(lptr, &cursor->dflt.real, sizeof(double));
  264|  61.1k|                    break;
  265|  11.6k|                case t_string:
  ------------------
  |  Branch (265:17): [True: 11.6k, False: 133k]
  ------------------
  266|  11.6k|                    if (parent != NULL
  ------------------
  |  Branch (266:25): [True: 5.19k, False: 6.43k]
  ------------------
  267|  5.19k|                        && parent->element_type != t_structobject
  ------------------
  |  Branch (267:28): [True: 0, False: 5.19k]
  ------------------
  268|      0|                        && offset > 0)
  ------------------
  |  Branch (268:28): [True: 0, False: 0]
  ------------------
  269|      0|                        return JSON_ERR_NOPARSTR;
  ------------------
  |  |  168|      0|#define JSON_ERR_NOPARSTR      17      // no strings in parallel arrays
  ------------------
  270|  11.6k|                    lptr[0] = '\0';
  271|  11.6k|                    break;
  272|  4.74k|                case t_boolean:
  ------------------
  |  Branch (272:17): [True: 4.74k, False: 140k]
  ------------------
  273|  4.74k|                    memcpy(lptr, &cursor->dflt.boolean, sizeof(bool));
  274|  4.74k|                    break;
  275|  1.18k|                case t_character:
  ------------------
  |  Branch (275:17): [True: 1.18k, False: 144k]
  ------------------
  276|  1.18k|                    lptr[0] = cursor->dflt.character;
  277|  1.18k|                    break;
  278|      0|                case t_object:  // silences a compiler warning
  ------------------
  |  Branch (278:17): [True: 0, False: 145k]
  ------------------
  279|      0|                    FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  280|      0|                case t_structobject:
  ------------------
  |  Branch (280:17): [True: 0, False: 145k]
  ------------------
  281|      0|                    FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  282|      0|                case t_array:
  ------------------
  |  Branch (282:17): [True: 0, False: 145k]
  ------------------
  283|      0|                    FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  284|    630|                case t_check:
  ------------------
  |  Branch (284:17): [True: 630, False: 144k]
  ------------------
  285|    630|                    FALLTHROUGH
  ------------------
  |  |   55|    630|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  286|  6.33k|                case t_ignore:
  ------------------
  |  Branch (286:17): [True: 5.70k, False: 139k]
  ------------------
  287|  6.33k|                    break;
  288|   145k|                }
  289|   155k|        }
  290|       |
  291|  10.9k|    json_debug_trace(1, "json: JSON parse of '%s' begins.\n", cp);
  ------------------
  |  |  108|  10.9k|    do {                                              \
  |  |  109|  10.9k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|  10.9k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 10.9k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 10.9k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|  10.9k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|  10.9k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 10.9k]
  |  |  ------------------
  ------------------
  292|       |
  293|       |    // parse input JSON
  294|   604k|    for (; *cp != '\0'; cp++) {
  ------------------
  |  Branch (294:12): [True: 601k, False: 3.10k]
  ------------------
  295|   601k|        json_debug_trace(2, "json: State %-14s, looking at '%c' (%p)\n",
  ------------------
  |  |  108|   601k|    do {                                              \
  |  |  109|   601k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|   601k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 601k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 601k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|   601k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|   601k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 601k]
  |  |  ------------------
  ------------------
  296|   601k|                          statenames[state], *cp, cp);
  297|   601k|        switch (state) {
  ------------------
  |  Branch (297:17): [True: 601k, False: 0]
  ------------------
  298|  11.4k|        case init:
  ------------------
  |  Branch (298:9): [True: 11.4k, False: 589k]
  ------------------
  299|  11.4k|            if (isspace((unsigned char) *cp)) {
  ------------------
  |  Branch (299:17): [True: 593, False: 10.9k]
  ------------------
  300|    593|                continue;
  301|    593|            }
  302|  10.9k|            if (*cp == '{') {
  ------------------
  |  Branch (302:17): [True: 10.8k, False: 41]
  ------------------
  303|  10.8k|                state = await_attr;
  304|  10.8k|            } else {
  305|     41|                json_debug_trace(1, "json: %s",
  ------------------
  |  |  108|     41|    do {                                              \
  |  |  109|     41|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     41|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 41]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 41]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     41|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     41|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 41]
  |  |  ------------------
  ------------------
  306|     41|                                  "Non-WS when expecting object start.\n");
  307|     41|                if (NULL != end) {
  ------------------
  |  Branch (307:21): [True: 41, False: 0]
  ------------------
  308|     41|                    *end = cp;
  309|     41|                }
  310|     41|                return JSON_ERR_OBSTART;
  ------------------
  |  |  152|     41|#define JSON_ERR_OBSTART        1      // non-WS when expecting object start
  ------------------
  311|     41|            }
  312|  10.8k|            break;
  313|  41.8k|        case await_attr:
  ------------------
  |  Branch (313:9): [True: 41.8k, False: 559k]
  ------------------
  314|  41.8k|            if (isspace((unsigned char) *cp)) {
  ------------------
  |  Branch (314:17): [True: 230, False: 41.6k]
  ------------------
  315|    230|                continue;
  316|    230|            }
  317|  41.6k|            if (*cp == '"') {
  ------------------
  |  Branch (317:17): [True: 41.3k, False: 305]
  ------------------
  318|  41.3k|                state = in_attr;
  319|  41.3k|                pattr = attrbuf;
  320|  41.3k|                if (NULL != end) {
  ------------------
  |  Branch (320:21): [True: 7.11k, False: 34.2k]
  ------------------
  321|  7.11k|                    *end = cp;
  322|  7.11k|                }
  323|  41.3k|            } else if (*cp == '}') {
  ------------------
  |  Branch (323:24): [True: 210, False: 95]
  ------------------
  324|    210|                break;
  325|    210|            } else {
  326|     95|                json_debug_trace(1, "json: %s",
  ------------------
  |  |  108|     95|    do {                                              \
  |  |  109|     95|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     95|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 95]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 95]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     95|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     95|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 95]
  |  |  ------------------
  ------------------
  327|     95|                          "Non-WS when expecting attribute.\n");
  328|     95|                if (NULL != end) {
  ------------------
  |  Branch (328:21): [True: 4, False: 91]
  ------------------
  329|      4|                    *end = cp;
  330|      4|                }
  331|     95|                return JSON_ERR_ATTRSTART;
  ------------------
  |  |  153|     95|#define JSON_ERR_ATTRSTART      2      // non-WS when expecting attrib start
  ------------------
  332|     95|            }
  333|  41.3k|            break;
  334|   175k|        case in_attr:
  ------------------
  |  Branch (334:9): [True: 175k, False: 425k]
  ------------------
  335|   175k|            if (NULL == pattr) {
  ------------------
  |  Branch (335:17): [True: 0, False: 175k]
  ------------------
  336|       |                // don't update end here, leave at attribute start
  337|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR       23      // unexpected null value or attribute
  ------------------
  338|      0|            }
  339|   175k|            if (*cp == '"') {
  ------------------
  |  Branch (339:17): [True: 41.2k, False: 134k]
  ------------------
  340|  41.2k|                *pattr++ = '\0';
  341|  41.2k|                json_debug_trace(1, "json: Collected attribute name %s\n",
  ------------------
  |  |  108|  41.2k|    do {                                              \
  |  |  109|  41.2k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|  41.2k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 41.2k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 41.2k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|  41.2k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|  41.2k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 41.2k]
  |  |  ------------------
  ------------------
  342|  41.2k|                                  attrbuf);
  343|   440k|                for (cursor = attrs; cursor->attribute != NULL; cursor++) {
  ------------------
  |  Branch (343:38): [True: 440k, False: 90]
  ------------------
  344|   440k|                    json_debug_trace(2, "json: Checking against %s\n",
  ------------------
  |  |  108|   440k|    do {                                              \
  |  |  109|   440k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|   440k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 440k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 440k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|   440k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|   440k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 440k]
  |  |  ------------------
  ------------------
  345|   440k|                                      cursor->attribute);
  346|   440k|                    if (strcmp(cursor->attribute, attrbuf) == 0) {
  ------------------
  |  Branch (346:25): [True: 27.9k, False: 412k]
  ------------------
  347|  27.9k|                        break;
  348|  27.9k|                    }
  349|   412k|                    if (cursor->type == t_ignore &&
  ------------------
  |  Branch (349:25): [True: 13.5k, False: 399k]
  ------------------
  350|  13.5k|                        strncmp(cursor->attribute, "", 1) == 0) {
  ------------------
  |  Branch (350:25): [True: 13.2k, False: 235]
  ------------------
  351|  13.2k|                        break;
  352|  13.2k|                    }
  353|   412k|                }
  354|  41.2k|                if (NULL == cursor->attribute) {
  ------------------
  |  Branch (354:21): [True: 90, False: 41.1k]
  ------------------
  355|     90|                    json_debug_trace(1,
  ------------------
  |  |  108|     90|    do {                                              \
  |  |  109|     90|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     90|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 90]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 90]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     90|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     90|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 90]
  |  |  ------------------
  ------------------
  356|     90|                                      "json: Unknown attribute name '%s'"
  357|     90|                                      " (attributes begin with '%s').\n",
  358|     90|                                      attrbuf, attrs->attribute);
  359|       |                    // don't update end here, leave at attribute start
  360|     90|                    return JSON_ERR_BADATTR;
  ------------------
  |  |  154|     90|#define JSON_ERR_BADATTR        3      // unknown attribute name
  ------------------
  361|     90|                }
  362|  41.1k|                state = await_value;
  363|  41.1k|                if (cursor->type == t_string) {
  ------------------
  |  Branch (363:21): [True: 1.25k, False: 39.9k]
  ------------------
  364|  1.25k|                    maxlen = (int)cursor->len - 1;
  365|  39.9k|                } else if (cursor->type == t_check) {
  ------------------
  |  Branch (365:28): [True: 2.16k, False: 37.7k]
  ------------------
  366|  2.16k|                    maxlen = (int)strnlen(cursor->dflt.check, JSON_VAL_MAX);
  ------------------
  |  |  135|  2.16k|#define JSON_VAL_MAX    512     // max chars in JSON value part
  ------------------
  367|  37.7k|                } else if (cursor->type == t_time ||
  ------------------
  |  Branch (367:28): [True: 2.75k, False: 35.0k]
  ------------------
  368|  35.0k|                           cursor->type == t_ignore) {
  ------------------
  |  Branch (368:28): [True: 19.2k, False: 15.7k]
  ------------------
  369|  22.0k|                    maxlen = JSON_VAL_MAX;
  ------------------
  |  |  135|  22.0k|#define JSON_VAL_MAX    512     // max chars in JSON value part
  ------------------
  370|  22.0k|                } else if (NULL != cursor->map) {
  ------------------
  |  Branch (370:28): [True: 447, False: 15.3k]
  ------------------
  371|    447|                    maxlen = (int)sizeof(valbuf) - 1;
  372|    447|                }
  373|  41.1k|                pval = valbuf;
  374|   134k|            } else if (pattr >= attrbuf + JSON_ATTR_MAX - 1) {
  ------------------
  |  |  134|   134k|#define JSON_ATTR_MAX   31      // max chars in JSON attribute name
  ------------------
  |  Branch (374:24): [True: 16, False: 134k]
  ------------------
  375|     16|                json_debug_trace(1, "json: %s","Attribute name too long.\n");
  ------------------
  |  |  108|     16|    do {                                              \
  |  |  109|     16|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     16|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 16]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 16]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     16|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     16|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 16]
  |  |  ------------------
  ------------------
  376|       |                // don't update end here, leave at attribute start
  377|     16|                return JSON_ERR_ATTRLEN;
  ------------------
  |  |  155|     16|#define JSON_ERR_ATTRLEN        4      // attribute name too long
  ------------------
  378|   134k|            } else {
  379|   134k|                *pattr++ = *cp;
  380|   134k|            }
  381|   175k|            break;
  382|   175k|        case await_value:
  ------------------
  |  Branch (382:9): [True: 43.6k, False: 557k]
  ------------------
  383|  43.6k|            if (isspace((unsigned char) *cp) ||
  ------------------
  |  Branch (383:17): [True: 208, False: 43.4k]
  ------------------
  384|  43.4k|                *cp == ':') {
  ------------------
  |  Branch (384:17): [True: 2.32k, False: 41.0k]
  ------------------
  385|  2.53k|                continue;
  386|  2.53k|            }
  387|  41.0k|            if (*cp == '[') {
  ------------------
  |  Branch (387:17): [True: 2.68k, False: 38.3k]
  ------------------
  388|  2.68k|                if (cursor->type == t_ignore) {
  ------------------
  |  Branch (388:21): [True: 1.74k, False: 946]
  ------------------
  389|       |                    /* skip to terminating ], not being fooled by
  390|       |                     * sub arrays, etc.
  391|       |                     * FIXME:  someday  */
  392|  1.74k|                    state = in_ignore_array;;
  393|  1.74k|                    value_quoted = false;
  394|  1.74k|                    break;
  395|  1.74k|                }
  396|    946|                if (cursor->type != t_array) {
  ------------------
  |  Branch (396:21): [True: 31, False: 915]
  ------------------
  397|     31|                    json_debug_trace(1,"json: %s",
  ------------------
  |  |  108|     31|    do {                                              \
  |  |  109|     31|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     31|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 31]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 31]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     31|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     31|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 31]
  |  |  ------------------
  ------------------
  398|     31|                                      "Saw [ when not expecting array.\n");
  399|     31|                    if (NULL != end) {
  ------------------
  |  Branch (399:25): [True: 3, False: 28]
  ------------------
  400|      3|                        *end = cp;
  401|      3|                    }
  402|     31|                    return JSON_ERR_NOARRAY;
  ------------------
  |  |  156|     31|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  ------------------
  403|     31|                }
  404|    915|                substatus = json_read_array(cp, &cursor->addr.array, &cp);
  405|    915|                if (substatus != 0) {
  ------------------
  |  Branch (405:21): [True: 319, False: 596]
  ------------------
  406|    319|                    return substatus;
  407|    319|                }
  408|    596|                state = post_element;
  409|  38.3k|            } else if (cursor->type == t_array) {
  ------------------
  |  Branch (409:24): [True: 1, False: 38.3k]
  ------------------
  410|      1|                json_debug_trace(1, "json: %s",
  ------------------
  |  |  108|      1|    do {                                              \
  |  |  109|      1|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      1|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 1]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 1]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      1|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 1]
  |  |  ------------------
  ------------------
  411|      1|                                  "Array element was specified, but no [.\n");
  412|      1|                if (NULL != end) {
  ------------------
  |  Branch (412:21): [True: 0, False: 1]
  ------------------
  413|      0|                    *end = cp;
  414|      0|                }
  415|      1|                return JSON_ERR_NOBRAK;
  ------------------
  |  |  157|      1|#define JSON_ERR_NOBRAK         6      // array element specified, but no [
  ------------------
  416|  38.3k|            } else if (*cp == '"') {
  ------------------
  |  Branch (416:24): [True: 9.34k, False: 29.0k]
  ------------------
  417|  9.34k|                value_quoted = true;
  418|  9.34k|                state = in_val_string;
  419|  9.34k|                pval = valbuf;
  420|  29.0k|            } else {
  421|  29.0k|                value_quoted = false;
  422|  29.0k|                state = in_val_token;
  423|  29.0k|                pval = valbuf;
  424|  29.0k|                *pval++ = *cp;
  425|  29.0k|            }
  426|  38.9k|            break;
  427|   110k|        case in_ignore_array:
  ------------------
  |  Branch (427:9): [True: 110k, False: 490k]
  ------------------
  428|   110k|            if (*cp == '"') {
  ------------------
  |  Branch (428:17): [True: 25.8k, False: 84.9k]
  ------------------
  429|  25.8k|                if (value_quoted == false) {
  ------------------
  |  Branch (429:21): [True: 12.9k, False: 12.8k]
  ------------------
  430|       |                    // now in quotes
  431|  12.9k|                    value_quoted = true;
  432|  12.9k|                } else {
  433|  12.8k|                    value_quoted = false;
  434|  12.8k|                }
  435|  84.9k|            } else if (*cp == ']') {
  ------------------
  |  Branch (435:24): [True: 1.56k, False: 83.4k]
  ------------------
  436|       |                // FIXME: does not handle sub arrays, etc.
  437|  1.56k|                if (value_quoted == false) {
  ------------------
  |  Branch (437:21): [True: 1.35k, False: 214]
  ------------------
  438|  1.35k|                    state = post_val;
  439|  1.35k|                }
  440|       |                // else in quotes, ignore it.
  441|  1.56k|            }
  442|   110k|            break;
  443|  67.0k|        case in_val_string:
  ------------------
  |  Branch (443:9): [True: 67.0k, False: 534k]
  ------------------
  444|  67.0k|            if (NULL == pval) {
  ------------------
  |  Branch (444:17): [True: 0, False: 67.0k]
  ------------------
  445|       |                // don't update end here, leave at value start
  446|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR       23      // unexpected null value or attribute
  ------------------
  447|      0|            }
  448|  67.0k|            if (*cp == '\\') {
  ------------------
  |  Branch (448:17): [True: 1.68k, False: 65.3k]
  ------------------
  449|  1.68k|                state = in_escape;
  450|  65.3k|            } else if (*cp == '"') {
  ------------------
  |  Branch (450:24): [True: 8.89k, False: 56.4k]
  ------------------
  451|  8.89k|                *pval++ = '\0';
  452|  8.89k|                json_debug_trace(1, "json: Collected string value %s\n", valbuf);
  ------------------
  |  |  108|  8.89k|    do {                                              \
  |  |  109|  8.89k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|  8.89k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 8.89k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 8.89k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|  8.89k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|  8.89k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 8.89k]
  |  |  ------------------
  ------------------
  453|  8.89k|                state = post_val;
  454|  56.4k|            } else if (pval > valbuf + JSON_VAL_MAX - 1 ||
  ------------------
  |  |  135|  56.4k|#define JSON_VAL_MAX    512     // max chars in JSON value part
  ------------------
  |  Branch (454:24): [True: 3, False: 56.4k]
  ------------------
  455|  56.4k|                       pval > valbuf + maxlen - 1) {
  ------------------
  |  Branch (455:24): [True: 132, False: 56.3k]
  ------------------
  456|    135|                json_debug_trace(1, "json: %s",  "String value too long.\n");
  ------------------
  |  |  108|    135|    do {                                              \
  |  |  109|    135|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    135|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 135]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 135]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    135|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    135|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 135]
  |  |  ------------------
  ------------------
  457|       |                // don't update end here, leave at value start
  458|    135|                return JSON_ERR_STRLONG;
  ------------------
  |  |  158|    135|#define JSON_ERR_STRLONG        7      // string value too long
  ------------------
  459|  56.3k|            } else {
  460|  56.3k|                *pval++ = *cp;
  461|  56.3k|            }
  462|  66.9k|            break;
  463|  66.9k|        case in_escape:
  ------------------
  |  Branch (463:9): [True: 1.68k, False: 599k]
  ------------------
  464|  1.68k|            if (NULL == pval) {
  ------------------
  |  Branch (464:17): [True: 0, False: 1.68k]
  ------------------
  465|       |                /* don't update end here, leave at value start */
  466|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR       23      // unexpected null value or attribute
  ------------------
  467|      0|            }
  468|  1.68k|            if (pval > valbuf + JSON_VAL_MAX - 1 ||
  ------------------
  |  |  135|  1.68k|#define JSON_VAL_MAX    512     // max chars in JSON value part
  ------------------
  |  Branch (468:17): [True: 3, False: 1.67k]
  ------------------
  469|  1.67k|                pval > valbuf + maxlen) {
  ------------------
  |  Branch (469:17): [True: 6, False: 1.67k]
  ------------------
  470|      9|                json_debug_trace(1, "json: %s",  "String value too long.\n");
  ------------------
  |  |  108|      9|    do {                                              \
  |  |  109|      9|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      9|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 9]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 9]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      9|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      9|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 9]
  |  |  ------------------
  ------------------
  471|       |                // don't update end here, leave at value start
  472|      9|                return JSON_ERR_STRLONG;
  ------------------
  |  |  158|      9|#define JSON_ERR_STRLONG        7      // string value too long
  ------------------
  473|      9|            }
  474|  1.67k|            switch (*cp) {
  475|    208|            case 'b':
  ------------------
  |  Branch (475:13): [True: 208, False: 1.46k]
  ------------------
  476|    208|                *pval++ = '\b';
  477|    208|                break;
  478|    195|            case 'f':
  ------------------
  |  Branch (478:13): [True: 195, False: 1.47k]
  ------------------
  479|    195|                *pval++ = '\f';
  480|    195|                break;
  481|    198|            case 'n':
  ------------------
  |  Branch (481:13): [True: 198, False: 1.47k]
  ------------------
  482|    198|                *pval++ = '\n';
  483|    198|                break;
  484|    194|            case 'r':
  ------------------
  |  Branch (484:13): [True: 194, False: 1.47k]
  ------------------
  485|    194|                *pval++ = '\r';
  486|    194|                break;
  487|    381|            case 't':
  ------------------
  |  Branch (487:13): [True: 381, False: 1.29k]
  ------------------
  488|    381|                *pval++ = '\t';
  489|    381|                break;
  490|    278|            case 'u':
  ------------------
  |  Branch (490:13): [True: 278, False: 1.39k]
  ------------------
  491|    278|                {
  492|    278|                    unsigned n;
  493|       |
  494|    278|                    cp++;                   // skip the 'u'
  495|       |                    // NetBSD 6 wants the cast
  496|  1.11k|                    for (n = 0; n < 4 && isxdigit((int)*cp); n++) {
  ------------------
  |  Branch (496:33): [True: 922, False: 194]
  |  Branch (496:42): [True: 838, False: 84]
  ------------------
  497|    838|                        uescape[n] = *cp++;
  498|    838|                    }
  499|    278|                    uescape[n] = '\0';      // terminate
  500|    278|                    --cp;
  501|       |                    // ECMA-404 says JSON \u must have 4 hex digits
  502|    278|                    if ((4 != n) ||
  ------------------
  |  Branch (502:25): [True: 84, False: 194]
  ------------------
  503|    194|                        (1 != sscanf(uescape, "%4x", &u))) {
  ------------------
  |  Branch (503:25): [True: 0, False: 194]
  ------------------
  504|     84|                        return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|     84|#define JSON_ERR_BADSTRING     15      // error while string parsing
  ------------------
  505|     84|                    }
  506|       |                    // truncate values above 0xff
  507|    194|                    *pval++ = (unsigned char)u;
  508|    194|                }
  509|      0|                break;
  510|    219|            default:            // handles double quote and solidus
  ------------------
  |  Branch (510:13): [True: 219, False: 1.45k]
  ------------------
  511|    219|                *pval++ = *cp;
  512|    219|                break;
  513|  1.67k|            }
  514|  1.58k|            state = in_val_string;
  515|  1.58k|            break;
  516|   110k|        case in_val_token:
  ------------------
  |  Branch (516:9): [True: 110k, False: 490k]
  ------------------
  517|   110k|            if (NULL == pval) {
  ------------------
  |  Branch (517:17): [True: 0, False: 110k]
  ------------------
  518|       |                // don't update end here, leave at value start
  519|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR       23      // unexpected null value or attribute
  ------------------
  520|      0|            }
  521|   110k|            if (isspace((unsigned char) *cp) ||
  ------------------
  |  Branch (521:17): [True: 332, False: 109k]
  ------------------
  522|   109k|                *cp == ',' ||
  ------------------
  |  Branch (522:17): [True: 22.8k, False: 87.1k]
  ------------------
  523|  87.1k|                *cp == '}') {
  ------------------
  |  Branch (523:17): [True: 5.66k, False: 81.4k]
  ------------------
  524|  28.8k|                *pval = '\0';
  525|  28.8k|                json_debug_trace(1, "json: Collected token valuen %s\n",
  ------------------
  |  |  108|  28.8k|    do {                                              \
  |  |  109|  28.8k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|  28.8k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 28.8k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 28.8k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|  28.8k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|  28.8k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 28.8k]
  |  |  ------------------
  ------------------
  526|  28.8k|                                 valbuf);
  527|  28.8k|                state = post_val;
  528|  28.8k|                if (*cp == '}' ||
  ------------------
  |  Branch (528:21): [True: 5.66k, False: 23.1k]
  ------------------
  529|  28.5k|                    *cp == ',') {
  ------------------
  |  Branch (529:21): [True: 22.8k, False: 332]
  ------------------
  530|  28.5k|                    --cp;
  531|  28.5k|                }
  532|  81.4k|            } else if (pval > valbuf + JSON_VAL_MAX - 1) {
  ------------------
  |  |  135|  81.4k|#define JSON_VAL_MAX    512     // max chars in JSON value part
  ------------------
  |  Branch (532:24): [True: 8, False: 81.4k]
  ------------------
  533|      8|                json_debug_trace(1, "json: %s", "Token value too long.\n");
  ------------------
  |  |  108|      8|    do {                                              \
  |  |  109|      8|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|      8|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 8]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 8]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|      8|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|      8|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 8]
  |  |  ------------------
  ------------------
  534|       |                // don't update end here, leave at value start
  535|      8|                return JSON_ERR_TOKLONG;
  ------------------
  |  |  159|      8|#define JSON_ERR_TOKLONG        8      // token value too long
  ------------------
  536|  81.4k|            } else {
  537|  81.4k|                *pval++ = *cp;
  538|  81.4k|            }
  539|   110k|            break;
  540|       |            // coverity[unterminated_case]
  541|   110k|        case post_val:
  ------------------
  |  Branch (541:9): [True: 37.9k, False: 563k]
  ------------------
  542|       |            // Ignore whitespace after either string or token values.
  543|  37.9k|	  if (isspace((unsigned char) *cp)) {
  ------------------
  |  Branch (543:8): [True: 240, False: 37.7k]
  ------------------
  544|  1.03k|                while (*cp != '\0' && isspace((unsigned char) *cp)) {
  ------------------
  |  Branch (544:24): [True: 1.01k, False: 18]
  |  Branch (544:39): [True: 791, False: 222]
  ------------------
  545|    791|                    ++cp;
  546|    791|                }
  547|    240|                json_debug_trace(1,
  ------------------
  |  |  108|    240|    do {                                              \
  |  |  109|    240|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    240|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 240]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 240]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    240|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    240|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 240]
  |  |  ------------------
  ------------------
  548|    240|                    "json: Skipped trailing whitespace: value \"%s\"\n", valbuf);
  549|    240|            }
  550|       |            /*
  551|       |             * We know that cursor points at the first spec matching
  552|       |             * the current attribute.  We don't know that it's *the*
  553|       |             * correct spec; our dialect allows there to be any number
  554|       |             * of adjacent ones with the same attrname but different
  555|       |             * types.  Here's where we try to seek forward for a
  556|       |             * matching type/attr pair if we're not looking at one.
  557|       |             */
  558|  37.9k|            for (;;) {
  559|  37.9k|                int seeking = cursor->type;
  560|       |
  561|  37.9k|                if (value_quoted &&
  ------------------
  |  Branch (561:21): [True: 7.82k, False: 30.1k]
  ------------------
  562|  7.82k|                    (cursor->type == t_string ||
  ------------------
  |  Branch (562:22): [True: 1.21k, False: 6.60k]
  ------------------
  563|  6.60k|                     cursor->type == t_time)) {
  ------------------
  |  Branch (563:22): [True: 1.91k, False: 4.68k]
  ------------------
  564|  3.13k|                    break;
  565|  3.13k|                }
  566|  34.8k|                if ((strcmp(valbuf, "true") == 0 ||
  ------------------
  |  Branch (566:22): [True: 2.22k, False: 32.6k]
  ------------------
  567|  32.6k|                     strcmp(valbuf, "false") == 0) &&
  ------------------
  |  Branch (567:22): [True: 195, False: 32.4k]
  ------------------
  568|  2.41k|                    seeking == t_boolean) {
  ------------------
  |  Branch (568:21): [True: 1.91k, False: 500]
  ------------------
  569|  1.91k|                    break;
  570|  1.91k|                }
  571|  32.9k|                if (isdigit((unsigned char) valbuf[0])) {
  ------------------
  |  Branch (571:21): [True: 17.1k, False: 15.7k]
  ------------------
  572|  17.1k|                    bool decimal = strchr(valbuf, '.') != NULL;
  573|       |
  574|  17.1k|                    if (decimal &&
  ------------------
  |  Branch (574:25): [True: 837, False: 16.3k]
  ------------------
  575|    837|                        seeking == t_real) {
  ------------------
  |  Branch (575:25): [True: 210, False: 627]
  ------------------
  576|    210|                        break;
  577|    210|                    }
  578|  16.9k|                    if (!decimal && (seeking == t_byte ||
  ------------------
  |  Branch (578:25): [True: 16.3k, False: 627]
  |  Branch (578:38): [True: 201, False: 16.1k]
  ------------------
  579|  16.1k|                                     seeking == t_ubyte ||
  ------------------
  |  Branch (579:38): [True: 760, False: 15.3k]
  ------------------
  580|  15.3k|                                     seeking == t_integer ||
  ------------------
  |  Branch (580:38): [True: 1.14k, False: 14.1k]
  ------------------
  581|  14.1k|                                     seeking == t_uinteger ||
  ------------------
  |  Branch (581:38): [True: 755, False: 13.4k]
  ------------------
  582|  13.4k|                                     seeking == t_longint ||
  ------------------
  |  Branch (582:38): [True: 611, False: 12.8k]
  ------------------
  583|  12.8k|                                     seeking == t_ulongint ||
  ------------------
  |  Branch (583:38): [True: 255, False: 12.5k]
  ------------------
  584|  12.5k|                                     seeking == t_time ||
  ------------------
  |  Branch (584:38): [True: 216, False: 12.3k]
  ------------------
  585|  12.3k|                                     seeking == t_short ||
  ------------------
  |  Branch (585:38): [True: 1.82k, False: 10.5k]
  ------------------
  586|  10.5k|                                     seeking == t_ushort))
  ------------------
  |  Branch (586:38): [True: 0, False: 10.5k]
  ------------------
  587|  5.76k|                        break;
  588|  16.9k|                }
  589|  26.9k|                if (NULL == cursor[1].attribute) {  // out of possibilities
  ------------------
  |  Branch (589:21): [True: 18.5k, False: 8.39k]
  ------------------
  590|  18.5k|                    break;
  591|  18.5k|                }
  592|  8.39k|                if (0 != strcmp(cursor[1].attribute, attrbuf)) {
  ------------------
  |  Branch (592:21): [True: 8.39k, False: 0]
  ------------------
  593|  8.39k|                    break;
  594|  8.39k|                }
  595|      0|                ++cursor;
  596|      0|            }
  597|  37.9k|            if (value_quoted &&
  ------------------
  |  Branch (597:17): [True: 7.82k, False: 30.1k]
  ------------------
  598|  7.82k|                (cursor->type != t_string &&
  ------------------
  |  Branch (598:18): [True: 6.60k, False: 1.21k]
  ------------------
  599|  6.60k|                 cursor->type != t_character &&
  ------------------
  |  Branch (599:18): [True: 6.40k, False: 200]
  ------------------
  600|  6.40k|                 cursor->type != t_check &&
  ------------------
  |  Branch (600:18): [True: 5.65k, False: 747]
  ------------------
  601|  5.65k|                 cursor->type != t_time &&
  ------------------
  |  Branch (601:18): [True: 3.74k, False: 1.91k]
  ------------------
  602|  3.74k|                 cursor->type != t_ignore &&
  ------------------
  |  Branch (602:18): [True: 461, False: 3.27k]
  ------------------
  603|    461|                 cursor->map == 0)) {
  ------------------
  |  Branch (603:18): [True: 22, False: 439]
  ------------------
  604|     22|                json_debug_trace(1, "json: %s", "Saw quoted value when expecting"
  ------------------
  |  |  108|     22|    do {                                              \
  |  |  109|     22|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     22|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 22]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 22]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     22|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     22|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 22]
  |  |  ------------------
  ------------------
  605|     22|                                  " non-string.\n");
  606|     22|                return JSON_ERR_QNONSTRING;
  ------------------
  |  |  170|     22|#define JSON_ERR_QNONSTRING    19      // quoted value when expecting nonstring
  ------------------
  607|     22|            }
  608|  37.9k|            if (!value_quoted &&
  ------------------
  |  Branch (608:17): [True: 30.1k, False: 7.79k]
  ------------------
  609|  30.1k|                (cursor->type == t_string ||
  ------------------
  |  Branch (609:18): [True: 21, False: 30.1k]
  ------------------
  610|  30.1k|                 cursor->type == t_check ||
  ------------------
  |  Branch (610:18): [True: 31, False: 30.0k]
  ------------------
  611|  30.0k|                 cursor->map != 0)) {
  ------------------
  |  Branch (611:18): [True: 7, False: 30.0k]
  ------------------
  612|     59|                json_debug_trace(1, "json: %s",
  ------------------
  |  |  108|     59|    do {                                              \
  |  |  109|     59|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     59|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 59]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 59]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     59|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     59|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 59]
  |  |  ------------------
  ------------------
  613|     59|                                 "Didn't see quoted value when expecting"
  614|     59|                                 " string.\n");
  615|     59|                return JSON_ERR_NONQSTRING;
  ------------------
  |  |  171|     59|#define JSON_ERR_NONQSTRING    20      // no quoted value when expecting string
  ------------------
  616|     59|            }
  617|  37.8k|            if (cursor->map != 0) {
  ------------------
  |  Branch (617:17): [True: 439, False: 37.4k]
  ------------------
  618|    882|                for (mp = cursor->map; mp->name != NULL; mp++)
  ------------------
  |  Branch (618:40): [True: 817, False: 65]
  ------------------
  619|    817|                    if (strcmp(mp->name, valbuf) == 0) {
  ------------------
  |  Branch (619:25): [True: 374, False: 443]
  ------------------
  620|    374|                        goto foundit;
  621|    374|                    }
  622|     65|                json_debug_trace(1,
  ------------------
  |  |  108|     65|    do {                                              \
  |  |  109|     65|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     65|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 65]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 65]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     65|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     65|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 65]
  |  |  ------------------
  ------------------
  623|     65|                                 "json: Invalid enumerated value string %s.\n",
  624|     65|                                  valbuf);
  625|     65|                return JSON_ERR_BADENUM;
  ------------------
  |  |  169|     65|#define JSON_ERR_BADENUM       18      // invalid enumerated value
  ------------------
  626|    374|              foundit:
  627|    374|                (void)snprintf(valbuf, sizeof(valbuf), "%d", mp->value);
  628|    374|            }
  629|  37.8k|            if (cursor->type == t_check) {
  ------------------
  |  Branch (629:17): [True: 747, False: 37.0k]
  ------------------
  630|    747|                lptr = cursor->dflt.check;
  631|  37.0k|            } else {
  632|  37.0k|                lptr = json_target_address(cursor, parent, offset);
  633|  37.0k|            }
  634|  37.8k|            if (NULL != lptr) {
  ------------------
  |  Branch (634:17): [True: 21.7k, False: 16.1k]
  ------------------
  635|  21.7k|                switch (cursor->type) {
  ------------------
  |  Branch (635:25): [True: 21.7k, False: 0]
  ------------------
  636|    228|                case t_byte:
  ------------------
  |  Branch (636:17): [True: 228, False: 21.4k]
  ------------------
  637|    228|                    {
  638|    228|                        int tmp = atoi(valbuf);
  639|    228|                        lptr[0] = (char)tmp;
  640|    228|                    }
  641|    228|                    break;
  642|    873|                case t_ubyte:
  ------------------
  |  Branch (642:17): [True: 873, False: 20.8k]
  ------------------
  643|    873|                    {
  644|    873|                        int tmp = atoi(valbuf);
  645|    873|                        lptr[0] = (unsigned char)tmp;
  646|    873|                    }
  647|    873|                    break;
  648|  1.70k|                case t_integer:
  ------------------
  |  Branch (648:17): [True: 1.70k, False: 20.0k]
  ------------------
  649|  1.70k|                    {
  650|  1.70k|                        int tmp = atoi(valbuf);
  651|  1.70k|                        memcpy(lptr, &tmp, sizeof(int));
  652|  1.70k|                    }
  653|  1.70k|                    break;
  654|  1.05k|                case t_uinteger:
  ------------------
  |  Branch (654:17): [True: 1.05k, False: 20.6k]
  ------------------
  655|  1.05k|                    {
  656|  1.05k|                        unsigned int tmp = (unsigned int)atol(valbuf);
  657|  1.05k|                        memcpy(lptr, &tmp, sizeof(unsigned int));
  658|  1.05k|                    }
  659|  1.05k|                    break;
  660|    659|                case t_longint:
  ------------------
  |  Branch (660:17): [True: 659, False: 21.0k]
  ------------------
  661|    659|                    {
  662|    659|                        long tmp = atol(valbuf);
  663|    659|                        memcpy(lptr, &tmp, sizeof(long));
  664|    659|                    }
  665|    659|                    break;
  666|    281|                case t_ulongint:
  ------------------
  |  Branch (666:17): [True: 281, False: 21.4k]
  ------------------
  667|    281|                    {
  668|    281|                        unsigned long tmp = (unsigned long)atoll(valbuf);
  669|    281|                        memcpy(lptr, &tmp, sizeof(unsigned long));
  670|    281|                    }
  671|    281|                    break;
  672|  1.86k|                case t_short:
  ------------------
  |  Branch (672:17): [True: 1.86k, False: 19.8k]
  ------------------
  673|  1.86k|                    {
  674|  1.86k|                        short tmp = atoi(valbuf);
  675|  1.86k|                        memcpy(lptr, &tmp, sizeof(short));
  676|  1.86k|                    }
  677|  1.86k|                    break;
  678|      0|                case t_ushort:
  ------------------
  |  Branch (678:17): [True: 0, False: 21.7k]
  ------------------
  679|      0|                    {
  680|      0|                        unsigned short tmp = (unsigned int)atoi(valbuf);
  681|      0|                        memcpy(lptr, &tmp, sizeof(unsigned short));
  682|      0|                    }
  683|      0|                    break;
  684|  2.74k|                case t_time:
  ------------------
  |  Branch (684:17): [True: 2.74k, False: 18.9k]
  ------------------
  685|  2.74k|                    {
  686|  2.74k|                        timespec_t ts_tmp = {0, 0};
  687|       |
  688|  2.74k|                        if (value_quoted) {
  ------------------
  |  Branch (688:29): [True: 1.91k, False: 830]
  ------------------
  689|  1.91k|                            ts_tmp = iso8601_to_timespec(valbuf);
  690|  1.91k|                        } else if (NULL == strchr(valbuf, '.')) {
  ------------------
  |  Branch (690:36): [True: 292, False: 538]
  ------------------
  691|       |                            // integer
  692|    292|                            ts_tmp.tv_sec = (time_t)atoll(valbuf);
  693|    538|                        } else {
  694|       |                            // real
  695|    538|                            double sec_tmp = safe_atof(valbuf);
  696|    538|                            if (0 != isfinite(sec_tmp)) {
  ------------------
  |  Branch (696:33): [True: 344, False: 194]
  ------------------
  697|    344|                                DTOTS(&ts_tmp, sec_tmp);
  ------------------
  |  |  144|    344|    do { \
  |  |  145|    344|        double int_part; \
  |  |  146|    344|        (ts)->tv_nsec = (long)(modf(d, &int_part) * 1e9); \
  |  |  147|    344|        (ts)->tv_sec = (time_t)int_part; \
  |  |  148|    344|    } while (0)
  |  |  ------------------
  |  |  |  Branch (148:14): [Folded, False: 344]
  |  |  ------------------
  ------------------
  698|    344|                            }  // else, leave at default
  699|    538|                        }
  700|  2.74k|                        memcpy(lptr, &ts_tmp, sizeof(timespec_t));
  701|  2.74k|                    }
  702|  2.74k|                    break;
  703|    430|                case t_timespec:
  ------------------
  |  Branch (703:17): [True: 430, False: 21.2k]
  ------------------
  704|    430|                    {
  705|    430|                        double sec_tmp = safe_atof(valbuf);
  706|    430|                        timespec_t ts_tmp;
  707|    430|                        if (0 != isfinite(sec_tmp)) {
  ------------------
  |  Branch (707:29): [True: 234, False: 196]
  ------------------
  708|    234|                            DTOTS(&ts_tmp, sec_tmp);
  ------------------
  |  |  144|    234|    do { \
  |  |  145|    234|        double int_part; \
  |  |  146|    234|        (ts)->tv_nsec = (long)(modf(d, &int_part) * 1e9); \
  |  |  147|    234|        (ts)->tv_sec = (time_t)int_part; \
  |  |  148|    234|    } while (0)
  |  |  ------------------
  |  |  |  Branch (148:14): [Folded, False: 234]
  |  |  ------------------
  ------------------
  709|    234|                            memcpy(lptr, &ts_tmp, sizeof(timespec_t));
  710|    234|                        } // else leave at .dflt
  711|    430|                    }
  712|    430|                    break;
  713|  4.71k|                case t_real:
  ------------------
  |  Branch (713:17): [True: 4.71k, False: 16.9k]
  ------------------
  714|  4.71k|                    {
  715|  4.71k|                        double tmp = safe_atof(valbuf);
  716|  4.71k|                        if (0 != isfinite(tmp)) {
  ------------------
  |  Branch (716:29): [True: 3.84k, False: 873]
  ------------------
  717|  3.84k|                            memcpy(lptr, &tmp, sizeof(double));
  718|  3.84k|                        } // else leave at .dflt
  719|  4.71k|                    }
  720|  4.71k|                    break;
  721|  1.21k|                case t_string:
  ------------------
  |  Branch (721:17): [True: 1.21k, False: 20.4k]
  ------------------
  722|  1.21k|                    if (NULL != parent &&
  ------------------
  |  Branch (722:25): [True: 417, False: 800]
  ------------------
  723|    417|                        parent->element_type != t_structobject &&
  ------------------
  |  Branch (723:25): [True: 0, False: 417]
  ------------------
  724|      0|                        offset > 0) {
  ------------------
  |  Branch (724:25): [True: 0, False: 0]
  ------------------
  725|      0|                        return JSON_ERR_NOPARSTR;
  ------------------
  |  |  168|      0|#define JSON_ERR_NOPARSTR      17      // no strings in parallel arrays
  ------------------
  726|      0|                    }
  727|  1.21k|                    (void)strlcpy(lptr, valbuf, cursor->len);
  728|  1.21k|                    break;
  729|  2.30k|                case t_boolean:
  ------------------
  |  Branch (729:17): [True: 2.30k, False: 19.4k]
  ------------------
  730|  2.30k|                    {
  731|  2.30k|                        bool tmp = (strcmp(valbuf, "true") == 0);
  732|  2.30k|                        memcpy(lptr, &tmp, sizeof(bool));
  733|  2.30k|                    }
  734|  2.30k|                    break;
  735|    561|                case t_character:
  ------------------
  |  Branch (735:17): [True: 561, False: 21.1k]
  ------------------
  736|    561|                    if (strnlen(valbuf, 2) > 1) {
  ------------------
  |  Branch (736:25): [True: 6, False: 555]
  ------------------
  737|       |                        // don't update end here, leave at value start
  738|      6|                        return JSON_ERR_STRLONG;
  ------------------
  |  |  158|      6|#define JSON_ERR_STRLONG        7      // string value too long
  ------------------
  739|    555|                    } else {
  740|    555|                        lptr[0] = valbuf[0];
  741|    555|                    }
  742|    555|                    break;
  743|  2.32k|                case t_ignore:  // silences a compiler warning
  ------------------
  |  Branch (743:17): [True: 2.32k, False: 19.3k]
  ------------------
  744|  2.32k|                    FALLTHROUGH
  ------------------
  |  |   55|  2.32k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  745|  2.32k|                case t_object:  // silences a compiler warning
  ------------------
  |  Branch (745:17): [True: 0, False: 21.7k]
  ------------------
  746|  2.32k|                    FALLTHROUGH
  ------------------
  |  |   55|  2.32k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  747|  2.32k|                case t_structobject:
  ------------------
  |  Branch (747:17): [True: 0, False: 21.7k]
  ------------------
  748|  2.32k|                    FALLTHROUGH
  ------------------
  |  |   55|  2.32k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  749|  2.32k|                case t_array:
  ------------------
  |  Branch (749:17): [True: 0, False: 21.7k]
  ------------------
  750|  2.32k|                    break;
  751|    747|                case t_check:
  ------------------
  |  Branch (751:17): [True: 747, False: 20.9k]
  ------------------
  752|    747|                    if (strcmp(cursor->dflt.check, valbuf) != 0) {
  ------------------
  |  Branch (752:25): [True: 181, False: 566]
  ------------------
  753|    181|                        json_debug_trace(1, "json: Required attribute value %s"
  ------------------
  |  |  108|    181|    do {                                              \
  |  |  109|    181|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    181|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 181]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 181]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    181|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    181|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 181]
  |  |  ------------------
  ------------------
  754|    181|                                          " not present.\n",
  755|    181|                                          cursor->dflt.check);
  756|       |                        // don't update end here, leave at start of attribute
  757|    181|                        return JSON_ERR_CHECKFAIL;
  ------------------
  |  |  167|    181|#define JSON_ERR_CHECKFAIL     16      // check attribute not matched
  ------------------
  758|    181|                    }
  759|    566|                    break;
  760|  21.7k|                }
  761|  21.7k|            }
  762|  37.6k|            FALLTHROUGH
  ------------------
  |  |   55|  37.6k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  763|  38.5k|        case post_element:
  ------------------
  |  Branch (763:9): [True: 920, False: 600k]
  ------------------
  764|  38.5k|            if (isspace((unsigned char) *cp)) {
  ------------------
  |  Branch (764:17): [True: 374, False: 38.1k]
  ------------------
  765|    374|                continue;
  766|    374|            }
  767|  38.1k|            if (*cp == ',') {
  ------------------
  |  Branch (767:17): [True: 31.4k, False: 6.68k]
  ------------------
  768|  31.4k|                state = await_attr;
  769|  31.4k|            } else if (*cp == '}') {
  ------------------
  |  Branch (769:24): [True: 6.05k, False: 629]
  ------------------
  770|  6.05k|                ++cp;
  771|  6.05k|                goto good_parse;
  772|  6.05k|            } else {
  773|    629|                json_debug_trace(1, "json: %s",
  ------------------
  |  |  108|    629|    do {                                              \
  |  |  109|    629|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|    629|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 629]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 629]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|    629|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|    629|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 629]
  |  |  ------------------
  ------------------
  774|    629|                                "Garbage while expecting comma or }\n");
  775|    629|                if (NULL != end) {
  ------------------
  |  Branch (775:21): [True: 23, False: 606]
  ------------------
  776|     23|                    *end = cp;
  777|     23|                }
  778|    629|                return JSON_ERR_BADTRAIL;
  ------------------
  |  |  160|    629|#define JSON_ERR_BADTRAIL       9      // garbage expecting comma or } or ]
  ------------------
  779|    629|            }
  780|  31.4k|            break;
  781|   601k|        }
  782|   601k|    }
  783|  3.10k|    if (state == init) {
  ------------------
  |  Branch (783:9): [True: 46, False: 3.05k]
  ------------------
  784|     46|        json_debug_trace(1, "json: %s", "Input was empty or white-space only\n");
  ------------------
  |  |  108|     46|    do {                                              \
  |  |  109|     46|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|     46|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 46]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 46]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|     46|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|     46|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 46]
  |  |  ------------------
  ------------------
  785|     46|        return JSON_ERR_EMPTY;
  ------------------
  |  |  176|     46|#define JSON_ERR_EMPTY         25      // input was empty or white-space only
  ------------------
  786|     46|    }
  787|       |
  788|  9.11k|  good_parse:
  789|       |    // in case there's another object following, consume trailing WS
  790|  9.11k|    while (isspace((unsigned char)*cp)) {
  ------------------
  |  Branch (790:12): [True: 215, False: 9.11k]
  ------------------
  791|    215|        ++cp;
  792|    215|    }
  793|  9.11k|    if (NULL != end) {
  ------------------
  |  Branch (793:9): [True: 5.57k, False: 3.53k]
  ------------------
  794|  5.57k|        *end = cp;
  795|  5.57k|    }
  796|  9.11k|    json_debug_trace(1, "%s", "json: JSON parse ends.\n");
  ------------------
  |  |  108|  9.11k|    do {                                              \
  |  |  109|  9.11k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|  9.11k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 9.11k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 9.11k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|  9.11k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|  9.11k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 9.11k]
  |  |  ------------------
  ------------------
  797|  9.11k|    return 0;
  798|  3.10k|}
json.c:json_target_address:
  119|   192k|{
  120|   192k|    char *targetaddr = NULL;
  121|   192k|    if (NULL == parent ||
  ------------------
  |  Branch (121:9): [True: 104k, False: 88.3k]
  ------------------
  122|   104k|        parent->element_type != t_structobject) {
  ------------------
  |  Branch (122:9): [True: 0, False: 88.3k]
  ------------------
  123|       |        // ordinary case - use the address in the cursor structure
  124|   104k|        switch (cursor->type) {
  125|      0|        case t_byte:
  ------------------
  |  Branch (125:9): [True: 0, False: 104k]
  ------------------
  126|      0|            targetaddr = (char *)&cursor->addr.byte[offset];
  127|      0|            break;
  128|    865|        case t_ubyte:
  ------------------
  |  Branch (128:9): [True: 865, False: 103k]
  ------------------
  129|    865|            targetaddr = (char *)&cursor->addr.ubyte[offset];
  130|    865|            break;
  131|  20.7k|        case t_ignore:
  ------------------
  |  Branch (131:9): [True: 20.7k, False: 83.7k]
  ------------------
  132|  20.7k|            targetaddr = NULL;
  133|  20.7k|            break;
  134|  18.2k|        case t_integer:
  ------------------
  |  Branch (134:9): [True: 18.2k, False: 86.1k]
  ------------------
  135|  18.2k|            targetaddr = (char *)&cursor->addr.integer[offset];
  136|  18.2k|            break;
  137|  6.02k|        case t_uinteger:
  ------------------
  |  Branch (137:9): [True: 6.02k, False: 98.4k]
  ------------------
  138|  6.02k|            targetaddr = (char *)&cursor->addr.uinteger[offset];
  139|  6.02k|            break;
  140|  1.55k|        case t_longint:
  ------------------
  |  Branch (140:9): [True: 1.55k, False: 102k]
  ------------------
  141|  1.55k|            targetaddr = (char *)&cursor->addr.longint[offset];
  142|  1.55k|            break;
  143|    414|        case t_ulongint:
  ------------------
  |  Branch (143:9): [True: 414, False: 104k]
  ------------------
  144|    414|            targetaddr = (char *)&cursor->addr.ulongint[offset];
  145|    414|            break;
  146|      0|        case t_short:
  ------------------
  |  Branch (146:9): [True: 0, False: 104k]
  ------------------
  147|      0|            targetaddr = (char *)&cursor->addr.shortint[offset];
  148|      0|            break;
  149|      0|        case t_ushort:
  ------------------
  |  Branch (149:9): [True: 0, False: 104k]
  ------------------
  150|      0|            targetaddr = (char *)&cursor->addr.ushortint[offset];
  151|      0|            break;
  152|  3.86k|        case t_time:
  ------------------
  |  Branch (152:9): [True: 3.86k, False: 100k]
  ------------------
  153|  3.86k|            targetaddr = (char *)&cursor->addr.ts[offset];
  154|  3.86k|            break;
  155|      0|        case t_timespec:
  ------------------
  |  Branch (155:9): [True: 0, False: 104k]
  ------------------
  156|      0|            targetaddr = (char *)&cursor->addr.ts[offset];
  157|      0|            break;
  158|  36.8k|        case t_real:
  ------------------
  |  Branch (158:9): [True: 36.8k, False: 67.6k]
  ------------------
  159|  36.8k|            targetaddr = (char *)&cursor->addr.real[offset];
  160|  36.8k|            break;
  161|  7.23k|        case t_string:
  ------------------
  |  Branch (161:9): [True: 7.23k, False: 97.2k]
  ------------------
  162|  7.23k|            targetaddr = cursor->addr.string;
  163|  7.23k|            break;
  164|  1.60k|        case t_boolean:
  ------------------
  |  Branch (164:9): [True: 1.60k, False: 102k]
  ------------------
  165|  1.60k|            targetaddr = (char *)&cursor->addr.boolean[offset];
  166|  1.60k|            break;
  167|  1.11k|        case t_character:
  ------------------
  |  Branch (167:9): [True: 1.11k, False: 103k]
  ------------------
  168|  1.11k|            targetaddr = (char *)&cursor->addr.character[offset];
  169|  1.11k|            break;
  170|    677|        case t_array:
  ------------------
  |  Branch (170:9): [True: 677, False: 103k]
  ------------------
  171|    677|            FALLTHROUGH
  ------------------
  |  |   55|    677|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  172|  5.90k|        case t_check:
  ------------------
  |  Branch (172:9): [True: 5.22k, False: 99.2k]
  ------------------
  173|  5.90k|            FALLTHROUGH
  ------------------
  |  |   55|  5.90k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  174|  5.90k|        case t_object:
  ------------------
  |  Branch (174:9): [True: 0, False: 104k]
  ------------------
  175|  5.90k|            FALLTHROUGH
  ------------------
  |  |   55|  5.90k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  176|  5.90k|        case t_structobject:
  ------------------
  |  Branch (176:9): [True: 0, False: 104k]
  ------------------
  177|  5.90k|            FALLTHROUGH
  ------------------
  |  |   55|  5.90k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  178|  5.90k|        default:
  ------------------
  |  Branch (178:9): [True: 0, False: 104k]
  ------------------
  179|  5.90k|            targetaddr = NULL;
  180|  5.90k|            break;
  181|   104k|        }
  182|   104k|    } else {
  183|       |        // tricky case - hacking a member in an array of structures
  184|  88.3k|        targetaddr =
  185|  88.3k|            parent->arr.objects.base + (offset * parent->arr.objects.stride) +
  186|  88.3k|            cursor->addr.offset;
  187|  88.3k|    }
  188|   192k|    json_debug_trace(1, "json: Target address for %s (offset %d) is %p\n",
  ------------------
  |  |  108|   192k|    do {                                              \
  |  |  109|   192k|        if (unlikely((lvl) <= debuglevel &&           \
  |  |  ------------------
  |  |  |  |  136|   192k|    #define unlikely(x)     __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (136:29): [True: 0, False: 192k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 192k]
  |  |  |  |  |  Branch (136:49): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  110|   192k|                      NULL != debugjsfp) ) {            \
  |  |  111|      0|            json_trace(fmt, __VA_ARGS__);              \
  |  |  112|      0|        }                                             \
  |  |  113|   192k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded, False: 192k]
  |  |  ------------------
  ------------------
  189|   192k|                      cursor->attribute, offset, targetaddr);
  190|   192k|    return targetaddr;
  191|   192k|}

json_toff_read:
  687|  2.93k|{
  688|  2.93k|    int real_sec = 0, real_nsec = 0, clock_sec = 0, clock_nsec = 0;
  689|  2.93k|    const struct json_attr_t json_attrs_toff[] = {
  690|       |        // *INDENT-OFF*
  691|  2.93k|        {"class",     t_check,   .dflt.check = "TOFF"},
  692|  2.93k|        {"device",    t_string,  .addr.string = gpsdata->dev.path,
  693|  2.93k|                                 .len = sizeof(gpsdata->dev.path)},
  694|  2.93k|        {"real_sec",  t_integer, .addr.integer = &real_sec,
  695|  2.93k|                                 .dflt.integer = 0},
  696|  2.93k|        {"real_nsec", t_integer, .addr.integer = &real_nsec,
  697|  2.93k|                                 .dflt.integer = 0},
  698|  2.93k|        {"clock_sec", t_integer, .addr.integer = &clock_sec,
  699|  2.93k|                                 .dflt.integer = 0},
  700|  2.93k|        {"clock_nsec",t_integer, .addr.integer = &clock_nsec,
  701|  2.93k|                                 .dflt.integer = 0},
  702|       |        // ignore unknown keys, for cross-version compatibility
  703|  2.93k|        {"", t_ignore},
  704|  2.93k|        {NULL},
  705|       |        // *INDENT-ON*
  706|  2.93k|    };
  707|  2.93k|    int status;
  708|       |
  709|  2.93k|    memset(&gpsdata->toff, 0, sizeof(gpsdata->toff));
  710|  2.93k|    status = json_read_object(buf, json_attrs_toff, endptr);
  711|  2.93k|    gpsdata->toff.real.tv_sec = (time_t)real_sec;
  712|  2.93k|    gpsdata->toff.real.tv_nsec = (long)real_nsec;
  713|  2.93k|    gpsdata->toff.clock.tv_sec = (time_t)clock_sec;
  714|  2.93k|    gpsdata->toff.clock.tv_nsec = (long)clock_nsec;
  715|  2.93k|    if (status != 0)
  ------------------
  |  Branch (715:9): [True: 666, False: 2.27k]
  ------------------
  716|    666|        return status;
  717|       |
  718|  2.27k|    return status;
  719|  2.93k|}
json_pps_read:
  723|     37|{
  724|     37|    int real_sec = 0, real_nsec = 0, clock_sec = 0, clock_nsec = 0, precision=0;
  725|     37|    int qErr = 0;
  726|       |
  727|     37|    const struct json_attr_t json_attrs_pps[] = {
  728|       |        // *INDENT-OFF*
  729|     37|        {"class",     t_check,   .dflt.check = "PPS"},
  730|     37|        {"device",    t_string,  .addr.string = gpsdata->dev.path,
  731|     37|                                 .len = sizeof(gpsdata->dev.path)},
  732|     37|        {"real_sec",  t_integer, .addr.integer = &real_sec,
  733|     37|                                 .dflt.integer = 0},
  734|     37|        {"real_nsec", t_integer, .addr.integer = &real_nsec,
  735|     37|                                 .dflt.integer = 0},
  736|     37|        {"clock_sec", t_integer, .addr.integer = &clock_sec,
  737|     37|                                 .dflt.integer = 0},
  738|     37|        {"clock_nsec",t_integer, .addr.integer = &clock_nsec,
  739|     37|                                 .dflt.integer = 0},
  740|     37|        {"precision", t_integer, .addr.integer = &precision,
  741|     37|                                 .dflt.integer = 0},
  742|     37|        {"qErr", t_integer, .addr.integer = &qErr,
  743|     37|                                 .dflt.integer = 0},
  744|       |        // ignore unknown keys, for cross-version compatibility
  745|     37|        {"", t_ignore},
  746|     37|        {NULL},
  747|       |        // *INDENT-ON*
  748|     37|    };
  749|     37|    int status;
  750|       |
  751|     37|    memset(&gpsdata->pps, 0, sizeof(gpsdata->pps));
  752|     37|    status = json_read_object(buf, json_attrs_pps, endptr);
  753|       |
  754|       |    // This is good until GPS are more than nanosec accurate
  755|     37|    gpsdata->pps.real.tv_sec = (time_t)real_sec;
  756|     37|    gpsdata->pps.real.tv_nsec = (long)real_nsec;
  757|     37|    gpsdata->pps.clock.tv_sec = (time_t)clock_sec;
  758|     37|    gpsdata->pps.clock.tv_nsec = (long)clock_nsec;
  759|       |    // hope qErr fits in int
  760|     37|    gpsdata->qErr = (long)qErr;
  761|       |
  762|       |    // FIXME: precision is currently parsed but discarded
  763|     37|    return status;
  764|     37|}
json_oscillator_read:
  768|     11|{
  769|     11|    bool running = false, reference = false, disciplined = false;
  770|     11|    int delta = 0;
  771|     11|    const struct json_attr_t json_attrs_osc[] = {
  772|       |        // *INDENT-OFF*
  773|     11|        {"class",       t_check,   .dflt.check = "OSC"},
  774|     11|        {"device",      t_string,  .addr.string = gpsdata->dev.path,
  775|     11|                                   .len = sizeof(gpsdata->dev.path)},
  776|     11|        {"running",     t_boolean, .addr.boolean = &running,
  777|     11|                                   .dflt.boolean = false},
  778|     11|        {"reference",   t_boolean, .addr.boolean = &reference,
  779|     11|                                   .dflt.boolean = false},
  780|     11|        {"disciplined", t_boolean, .addr.boolean = &disciplined,
  781|     11|                                   .dflt.boolean = false},
  782|     11|        {"delta",       t_integer, .addr.integer = &delta,
  783|     11|                                   .dflt.integer = 0},
  784|       |        // ignore unknown keys, for cross-version compatibility
  785|     11|        {"", t_ignore},
  786|     11|        {NULL},
  787|       |        // *INDENT-ON*
  788|     11|    };
  789|     11|    int status;
  790|       |
  791|     11|    memset(&gpsdata->osc, 0, sizeof(gpsdata->osc));
  792|     11|    status = json_read_object(buf, json_attrs_osc, endptr);
  793|       |
  794|     11|    gpsdata->osc.running = running;
  795|     11|    gpsdata->osc.reference = reference;
  796|     11|    gpsdata->osc.disciplined = disciplined;
  797|     11|    gpsdata->osc.delta = delta;
  798|       |
  799|     11|    return status;
  800|     11|}
libgps_json_unpack:
  820|  2.90k|{
  821|  2.90k|    int status;
  822|  2.90k|    const char *classtag = strstr(buf, "\"class\":");
  823|       |
  824|  2.90k|    if (NULL == classtag) {
  ------------------
  |  Branch (824:9): [True: 413, False: 2.49k]
  ------------------
  825|    413|        return -1;
  826|    413|    }
  827|       |
  828|  2.49k|    if (str_starts_with(classtag, "\"class\":\"TPV\"")) {
  ------------------
  |  Branch (828:9): [True: 449, False: 2.04k]
  ------------------
  829|    449|        status = json_tpv_read(buf, gpsdata, end);
  830|    449|        gpsdata->set = STATUS_SET;
  ------------------
  |  | 2886|    449|#define STATUS_SET      (1llu<<9)
  ------------------
  831|    449|        if (0 != gpsdata->fix.time.tv_sec) {
  ------------------
  |  Branch (831:13): [True: 278, False: 171]
  ------------------
  832|    278|            gpsdata->set |= TIME_SET;
  ------------------
  |  | 2879|    278|#define TIME_SET        (1llu<<2)
  ------------------
  833|    278|        }
  834|    449|        if (0 != isfinite(gpsdata->fix.ept)) {
  ------------------
  |  Branch (834:13): [True: 1, False: 448]
  ------------------
  835|      1|            gpsdata->set |= TIMERR_SET;
  ------------------
  |  | 2880|      1|#define TIMERR_SET      (1llu<<3)
  ------------------
  836|      1|        }
  837|    449|        if (0 != isfinite(gpsdata->fix.longitude)) {
  ------------------
  |  Branch (837:13): [True: 1, False: 448]
  ------------------
  838|      1|            gpsdata->set |= LATLON_SET;
  ------------------
  |  | 2881|      1|#define LATLON_SET      (1llu<<4)
  ------------------
  839|      1|        }
  840|    449|        if (0 != isfinite(gpsdata->fix.altitude) ||
  ------------------
  |  Branch (840:13): [True: 1, False: 448]
  ------------------
  841|    448|            0 != isfinite(gpsdata->fix.altHAE) ||
  ------------------
  |  Branch (841:13): [True: 1, False: 447]
  ------------------
  842|    447|            0 != isfinite(gpsdata->fix.depth) ||
  ------------------
  |  Branch (842:13): [True: 1, False: 446]
  ------------------
  843|    446|            0 != isfinite(gpsdata->fix.altMSL)) {
  ------------------
  |  Branch (843:13): [True: 1, False: 445]
  ------------------
  844|      4|            gpsdata->set |= ALTITUDE_SET;
  ------------------
  |  | 2882|      4|#define ALTITUDE_SET    (1llu<<5)
  ------------------
  845|      4|        }
  846|    449|        if (0 != isfinite(gpsdata->fix.epx) &&
  ------------------
  |  Branch (846:13): [True: 3, False: 446]
  ------------------
  847|      3|            0 != isfinite(gpsdata->fix.epy)) {
  ------------------
  |  Branch (847:13): [True: 2, False: 1]
  ------------------
  848|      2|            gpsdata->set |= HERR_SET;
  ------------------
  |  | 2889|      2|#define HERR_SET        (1llu<<12)
  ------------------
  849|      2|        }
  850|    449|        if (0 != isfinite(gpsdata->fix.epv)) {
  ------------------
  |  Branch (850:13): [True: 1, False: 448]
  ------------------
  851|      1|            gpsdata->set |= VERR_SET;
  ------------------
  |  | 2890|      1|#define VERR_SET        (1llu<<13)
  ------------------
  852|      1|        }
  853|    449|        if (0 != isfinite(gpsdata->fix.track)) {
  ------------------
  |  Branch (853:13): [True: 1, False: 448]
  ------------------
  854|      1|            gpsdata->set |= TRACK_SET;
  ------------------
  |  | 2884|      1|#define TRACK_SET       (1llu<<7)
  ------------------
  855|      1|        }
  856|    449|        if (0 != isfinite(gpsdata->fix.magnetic_track) ||
  ------------------
  |  Branch (856:13): [True: 1, False: 448]
  ------------------
  857|    448|            0 != isfinite(gpsdata->fix.magnetic_var)) {
  ------------------
  |  Branch (857:13): [True: 1, False: 447]
  ------------------
  858|      2|            gpsdata->set |= MAGNETIC_TRACK_SET;
  ------------------
  |  | 2915|      2|#define MAGNETIC_TRACK_SET (1llu<<38)
  ------------------
  859|      2|        }
  860|    449|        if (0 != isfinite(gpsdata->fix.speed)) {
  ------------------
  |  Branch (860:13): [True: 1, False: 448]
  ------------------
  861|      1|            gpsdata->set |= SPEED_SET;
  ------------------
  |  | 2883|      1|#define SPEED_SET       (1llu<<6)
  ------------------
  862|      1|        }
  863|    449|        if (0 != isfinite(gpsdata->fix.climb)) {
  ------------------
  |  Branch (863:13): [True: 1, False: 448]
  ------------------
  864|      1|            gpsdata->set |= CLIMB_SET;
  ------------------
  |  | 2885|      1|#define CLIMB_SET       (1llu<<8)
  ------------------
  865|      1|        }
  866|    449|        if (0 != isfinite(gpsdata->fix.epd)) {
  ------------------
  |  Branch (866:13): [True: 1, False: 448]
  ------------------
  867|      1|            gpsdata->set |= TRACKERR_SET;
  ------------------
  |  | 2894|      1|#define TRACKERR_SET    (1llu<<17)
  ------------------
  868|      1|        }
  869|    449|        if (0 != isfinite(gpsdata->fix.eps)) {
  ------------------
  |  Branch (869:13): [True: 2, False: 447]
  ------------------
  870|      2|            gpsdata->set |= SPEEDERR_SET;
  ------------------
  |  | 2893|      2|#define SPEEDERR_SET    (1llu<<16)
  ------------------
  871|      2|        }
  872|    449|        if (0 != isfinite(gpsdata->fix.epc)) {
  ------------------
  |  Branch (872:13): [True: 1, False: 448]
  ------------------
  873|      1|            gpsdata->set |= CLIMBERR_SET;
  ------------------
  |  | 2895|      1|#define CLIMBERR_SET    (1llu<<18)
  ------------------
  874|      1|        }
  875|    449|        if (MODE_NOT_SEEN != gpsdata->fix.mode) {
  ------------------
  |  |  217|    449|#define MODE_NOT_SEEN   0       // mode update not seen yet
  ------------------
  |  Branch (875:13): [True: 50, False: 399]
  ------------------
  876|     50|            gpsdata->set |= MODE_SET;
  ------------------
  |  | 2887|     50|#define MODE_SET        (1llu<<10)
  ------------------
  877|     50|        }
  878|    449|        if (0 != isfinite(gpsdata->fix.wanglem) ||
  ------------------
  |  Branch (878:13): [True: 1, False: 448]
  ------------------
  879|    448|            0 != isfinite(gpsdata->fix.wangler) ||
  ------------------
  |  Branch (879:13): [True: 1, False: 447]
  ------------------
  880|    447|            0 != isfinite(gpsdata->fix.wanglet) ||
  ------------------
  |  Branch (880:13): [True: 1, False: 446]
  ------------------
  881|    446|            0 != isfinite(gpsdata->fix.wspeedr) ||
  ------------------
  |  Branch (881:13): [True: 1, False: 445]
  ------------------
  882|    445|            0 != isfinite(gpsdata->fix.wspeedt)) {
  ------------------
  |  Branch (882:13): [True: 1, False: 444]
  ------------------
  883|      5|            gpsdata->set |= NAVDATA_SET;
  ------------------
  |  | 2911|      5|#define NAVDATA_SET     (1llu<<34)
  ------------------
  884|      5|        }
  885|    449|        if (0 != isfinite(gpsdata->fix.NED.relPosN) ||
  ------------------
  |  Branch (885:13): [True: 1, False: 448]
  ------------------
  886|    448|            0 != isfinite(gpsdata->fix.NED.relPosE) ||
  ------------------
  |  Branch (886:13): [True: 1, False: 447]
  ------------------
  887|    447|            0 != isfinite(gpsdata->fix.NED.relPosD) ||
  ------------------
  |  Branch (887:13): [True: 1, False: 446]
  ------------------
  888|    446|            0 != isfinite(gpsdata->fix.NED.relPosH) ||
  ------------------
  |  Branch (888:13): [True: 1, False: 445]
  ------------------
  889|    445|            0 != isfinite(gpsdata->fix.NED.relPosL) ||
  ------------------
  |  Branch (889:13): [True: 1, False: 444]
  ------------------
  890|    444|            0 != isfinite(gpsdata->fix.NED.velN) ||
  ------------------
  |  Branch (890:13): [True: 1, False: 443]
  ------------------
  891|    443|            0 != isfinite(gpsdata->fix.NED.velE) ||
  ------------------
  |  Branch (891:13): [True: 1, False: 442]
  ------------------
  892|    442|            0 != isfinite(gpsdata->fix.NED.velD)) {
  ------------------
  |  Branch (892:13): [True: 1, False: 441]
  ------------------
  893|      8|            gpsdata->set |= NED_SET;
  ------------------
  |  | 2917|      8|#define NED_SET         (1llu<<40)
  ------------------
  894|      8|        }
  895|    449|        if ((0 != isfinite(gpsdata->fix.ecef.x)) &&
  ------------------
  |  Branch (895:13): [True: 3, False: 446]
  ------------------
  896|      3|            (0 != isfinite(gpsdata->fix.ecef.y)) &&
  ------------------
  |  Branch (896:13): [True: 2, False: 1]
  ------------------
  897|      2|            (0 != isfinite(gpsdata->fix.ecef.z))) {
  ------------------
  |  Branch (897:13): [True: 1, False: 1]
  ------------------
  898|       |            // All, or none.  Clients can just do their own isfinite()s
  899|      1|            gpsdata->set |= ECEF_SET;
  ------------------
  |  | 2913|      1|#define ECEF_SET        (1llu<<36)
  ------------------
  900|      1|        }
  901|    449|        if ((0 != isfinite(gpsdata->fix.ecef.vx)) &&
  ------------------
  |  Branch (901:13): [True: 3, False: 446]
  ------------------
  902|      3|            (0 != isfinite(gpsdata->fix.ecef.vy)) &&
  ------------------
  |  Branch (902:13): [True: 2, False: 1]
  ------------------
  903|      2|            (0 != isfinite(gpsdata->fix.ecef.vz))) {
  ------------------
  |  Branch (903:13): [True: 1, False: 1]
  ------------------
  904|       |            // All, or none.  Clients can just do their own isfinite()s
  905|      1|            gpsdata->set |= VECEF_SET;
  ------------------
  |  | 2914|      1|#define VECEF_SET       (1llu<<37)
  ------------------
  906|      1|        }
  907|    449|        return FILTER(status);
  ------------------
  |  |  808|    449|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    898|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 449]
  |  |  ------------------
  |  |  809|    449|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|    449|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 448]
  |  |  ------------------
  ------------------
  908|    449|    }
  909|  2.04k|    if (str_starts_with(classtag, "\"class\":\"GST\"")) {
  ------------------
  |  Branch (909:9): [True: 326, False: 1.72k]
  ------------------
  910|    326|        status = json_noise_read(buf, gpsdata, end);
  911|    326|        if (PASS(status)) {
  ------------------
  |  |  810|    326|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|    326|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    652|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 326]
  |  |  |  |  ------------------
  |  |  |  |  809|    326|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|    326|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 325]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 295, False: 31]
  |  |  ------------------
  ------------------
  912|    295|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|    295|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|    295|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|    295|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|    295|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|    295|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|    295|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|    295|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|    295|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|    295|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|    295|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|    295|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|    295|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|    295|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|    295|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|    295|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|    295|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|    295|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  913|    295|            gpsdata->set |= GST_SET;
  ------------------
  |  | 2904|    295|#define GST_SET         (1llu<<27)
  ------------------
  914|    295|        }
  915|    326|        return FILTER(status);
  ------------------
  |  |  808|    326|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    652|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 326]
  |  |  ------------------
  |  |  809|    326|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|    326|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 325]
  |  |  ------------------
  ------------------
  916|    326|    }
  917|  1.72k|    if (str_starts_with(classtag, "\"class\":\"SKY\"")) {
  ------------------
  |  Branch (917:9): [True: 185, False: 1.53k]
  ------------------
  918|    185|        status = json_sky_read(buf, gpsdata, end);
  919|    185|        return FILTER(status);
  ------------------
  |  |  808|    185|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    370|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 185]
  |  |  ------------------
  |  |  809|    185|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|    185|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 3, False: 182]
  |  |  ------------------
  ------------------
  920|    185|    }
  921|  1.53k|    if (str_starts_with(classtag, "\"class\":\"ATT\"")) {
  ------------------
  |  Branch (921:9): [True: 75, False: 1.46k]
  ------------------
  922|     75|        status = json_att_read(buf, gpsdata, end);
  923|     75|        if (PASS(status)) {
  ------------------
  |  |  810|     75|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     75|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    150|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 75]
  |  |  |  |  ------------------
  |  |  |  |  809|     75|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     75|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 2, False: 73]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 40, False: 35]
  |  |  ------------------
  ------------------
  924|     40|            gpsdata->set |= ATTITUDE_SET;
  ------------------
  |  | 2891|     40|#define ATTITUDE_SET    (1llu<<14)
  ------------------
  925|     40|        }
  926|     75|        return FILTER(status);
  ------------------
  |  |  808|     75|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    150|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 75]
  |  |  ------------------
  |  |  809|     75|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     75|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 2, False: 73]
  |  |  ------------------
  ------------------
  927|     75|    }
  928|  1.46k|    if (str_starts_with(classtag, "\"class\":\"IMU\"")) {
  ------------------
  |  Branch (928:9): [True: 58, False: 1.40k]
  ------------------
  929|     58|        status = json_imu_read(buf, gpsdata, end);
  930|     58|        if (PASS(status)) {
  ------------------
  |  |  810|     58|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     58|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    116|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 58]
  |  |  |  |  ------------------
  |  |  |  |  809|     58|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     58|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 57]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 31, False: 27]
  |  |  ------------------
  ------------------
  931|     31|            gpsdata->set |= IMU_SET;
  ------------------
  |  | 2920|     31|#define IMU_SET         (1llu<<43)
  ------------------
  932|     31|        }
  933|     58|        return FILTER(status);
  ------------------
  |  |  808|     58|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    116|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 58]
  |  |  ------------------
  |  |  809|     58|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     58|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 57]
  |  |  ------------------
  ------------------
  934|     58|    }
  935|  1.40k|    if (str_starts_with(classtag, "\"class\":\"DEVICES\"")) {
  ------------------
  |  Branch (935:9): [True: 67, False: 1.33k]
  ------------------
  936|     67|        status = json_devicelist_read(buf, gpsdata, end);
  937|     67|        if (PASS(status)) {
  ------------------
  |  |  810|     67|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     67|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    134|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 67]
  |  |  |  |  ------------------
  |  |  |  |  809|     67|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     67|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 66]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 7, False: 60]
  |  |  ------------------
  ------------------
  938|      7|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|      7|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|      7|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|      7|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|      7|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|      7|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|      7|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|      7|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|      7|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|      7|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|      7|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|      7|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|      7|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|      7|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|      7|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|      7|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|      7|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|      7|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  939|      7|            gpsdata->set |= DEVICELIST_SET;
  ------------------
  |  | 2897|      7|#define DEVICELIST_SET  (1llu<<20)
  ------------------
  940|      7|        }
  941|     67|        return FILTER(status);
  ------------------
  |  |  808|     67|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    134|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 67]
  |  |  ------------------
  |  |  809|     67|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     67|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 66]
  |  |  ------------------
  ------------------
  942|     67|    }
  943|  1.33k|    if (str_starts_with(classtag, "\"class\":\"DEVICE\"")) {
  ------------------
  |  Branch (943:9): [True: 21, False: 1.31k]
  ------------------
  944|     21|        status = json_device_read(buf, &gpsdata->dev, end);
  945|     21|        if (PASS(status))
  ------------------
  |  |  810|     21|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     21|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|     42|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 21]
  |  |  |  |  ------------------
  |  |  |  |  809|     21|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     21|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 20]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 6, False: 15]
  |  |  ------------------
  ------------------
  946|      6|            gpsdata->set |= DEVICE_SET;
  ------------------
  |  | 2896|      6|#define DEVICE_SET      (1llu<<19)
  ------------------
  947|     21|        return FILTER(status);
  ------------------
  |  |  808|     21|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|     42|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 21]
  |  |  ------------------
  |  |  809|     21|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     21|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 20]
  |  |  ------------------
  ------------------
  948|     21|    }
  949|  1.31k|    if (str_starts_with(classtag, "\"class\":\"WATCH\"")) {
  ------------------
  |  Branch (949:9): [True: 54, False: 1.26k]
  ------------------
  950|     54|        status = json_watch_read(buf, &gpsdata->policy, end);
  951|     54|        if (PASS(status)) {
  ------------------
  |  |  810|     54|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     54|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    108|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 54]
  |  |  |  |  ------------------
  |  |  |  |  809|     54|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     54|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 53]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 47, False: 7]
  |  |  ------------------
  ------------------
  952|     47|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|     47|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|     47|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|     47|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|     47|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|     47|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|     47|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|     47|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|     47|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|     47|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|     47|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|     47|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|     47|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|     47|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|     47|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|     47|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|     47|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|     47|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  953|     47|            gpsdata->set |= POLICY_SET;
  ------------------
  |  | 2906|     47|#define POLICY_SET      (1llu<<29)
  ------------------
  954|     47|        }
  955|     54|        return FILTER(status);
  ------------------
  |  |  808|     54|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    108|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 54]
  |  |  ------------------
  |  |  809|     54|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     54|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 53]
  |  |  ------------------
  ------------------
  956|     54|    }
  957|  1.26k|    if (str_starts_with(classtag, "\"class\":\"VERSION\"")) {
  ------------------
  |  Branch (957:9): [True: 15, False: 1.24k]
  ------------------
  958|     15|        status = json_version_read(buf, gpsdata, end);
  959|     15|        if (status ==  0) {
  ------------------
  |  Branch (959:13): [True: 3, False: 12]
  ------------------
  960|      3|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|      3|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|      3|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|      3|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|      3|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|      3|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|      3|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|      3|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|      3|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|      3|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|      3|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|      3|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|      3|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|      3|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|      3|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|      3|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|      3|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|      3|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  961|      3|            gpsdata->set |= VERSION_SET;
  ------------------
  |  | 2905|      3|#define VERSION_SET     (1llu<<28)
  ------------------
  962|      3|        }
  963|     15|        return FILTER(status);
  ------------------
  |  |  808|     15|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|     30|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 15]
  |  |  ------------------
  |  |  809|     15|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     15|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 14]
  |  |  ------------------
  ------------------
  964|     15|    }
  965|  1.24k|    if (str_starts_with(classtag, "\"class\":\"RTCM2\"")) {
  ------------------
  |  Branch (965:9): [True: 312, False: 933]
  ------------------
  966|    312|        status = json_rtcm2_read(buf,
  967|    312|                                 gpsdata->dev.path, sizeof(gpsdata->dev.path),
  968|    312|                                 &gpsdata->rtcm2, end);
  969|    312|        if (PASS(status)) {
  ------------------
  |  |  810|    312|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|    312|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    624|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 34, False: 278]
  |  |  |  |  ------------------
  |  |  |  |  809|    312|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|    278|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 277]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 125, False: 187]
  |  |  ------------------
  ------------------
  970|    125|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|    125|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|    125|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|    125|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|    125|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|    125|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|    125|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|    125|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|    125|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|    125|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|    125|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|    125|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|    125|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|    125|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|    125|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|    125|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|    125|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|    125|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  971|    125|            gpsdata->set |= RTCM2_SET;
  ------------------
  |  | 2899|    125|#define RTCM2_SET       (1llu<<22)
  ------------------
  972|    125|        }
  973|    312|        return FILTER(status);
  ------------------
  |  |  808|    312|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    624|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 34, False: 278]
  |  |  ------------------
  |  |  809|    312|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|    278|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 277]
  |  |  ------------------
  ------------------
  974|    312|    }
  975|    933|    if (str_starts_with(classtag, "\"class\":\"RTCM3\"")) {
  ------------------
  |  Branch (975:9): [True: 139, False: 794]
  ------------------
  976|    139|        status = json_rtcm3_read(buf,
  977|    139|                                 gpsdata->dev.path, sizeof(gpsdata->dev.path),
  978|    139|                                 &gpsdata->rtcm3, end);
  979|    139|        if (PASS(status)) {
  ------------------
  |  |  810|    139|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|    139|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    278|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 1, False: 138]
  |  |  |  |  ------------------
  |  |  |  |  809|    139|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|    138|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 137]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 42, False: 97]
  |  |  ------------------
  ------------------
  980|     42|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|     42|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|     42|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|     42|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|     42|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|     42|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|     42|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|     42|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|     42|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|     42|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|     42|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|     42|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|     42|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|     42|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|     42|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|     42|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|     42|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|     42|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  981|     42|            gpsdata->set |= RTCM3_SET;
  ------------------
  |  | 2900|     42|#define RTCM3_SET       (1llu<<23)
  ------------------
  982|     42|        }
  983|    139|        return FILTER(status);
  ------------------
  |  |  808|    139|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    278|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 1, False: 138]
  |  |  ------------------
  |  |  809|    139|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|    138|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 137]
  |  |  ------------------
  ------------------
  984|    139|    }
  985|    794|#ifdef AIVDM_ENABLE
  986|    794|    if (str_starts_with(classtag, "\"class\":\"AIS\"")) {
  ------------------
  |  Branch (986:9): [True: 323, False: 471]
  ------------------
  987|    323|        status = json_ais_read(buf,
  988|    323|                               gpsdata->dev.path, sizeof(gpsdata->dev.path),
  989|    323|                               &gpsdata->ais, end);
  990|    323|        if (PASS(status)) {
  ------------------
  |  |  810|    323|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|    323|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    646|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 41, False: 282]
  |  |  |  |  ------------------
  |  |  |  |  809|    323|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|    282|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 2, False: 280]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 184, False: 139]
  |  |  ------------------
  ------------------
  991|    184|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|    184|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|    184|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|    184|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|    184|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|    184|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|    184|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|    184|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|    184|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|    184|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|    184|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|    184|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|    184|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|    184|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|    184|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|    184|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|    184|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|    184|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  992|    184|            gpsdata->set |= AIS_SET;
  ------------------
  |  | 2901|    184|#define AIS_SET         (1llu<<24)
  ------------------
  993|    184|        }
  994|    323|        return FILTER(status);
  ------------------
  |  |  808|    323|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    646|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 41, False: 282]
  |  |  ------------------
  |  |  809|    323|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|    282|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 2, False: 280]
  |  |  ------------------
  ------------------
  995|    323|    }
  996|    471|#endif  // AIVDM_ENABLE
  997|    471|    if (str_starts_with(classtag, "\"class\":\"ERROR\"")) {
  ------------------
  |  Branch (997:9): [True: 9, False: 462]
  ------------------
  998|      9|        status = json_error_read(buf, gpsdata, end);
  999|      9|        if (PASS(status)) {
  ------------------
  |  |  810|      9|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|      9|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|     18|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 9]
  |  |  |  |  ------------------
  |  |  |  |  809|      9|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|      9|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 8]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 3, False: 6]
  |  |  ------------------
  ------------------
 1000|      3|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|      3|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|      3|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|      3|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|      3|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|      3|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|      3|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|      3|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|      3|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|      3|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|      3|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|      3|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|      3|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|      3|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|      3|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|      3|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|      3|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|      3|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
 1001|      3|            gpsdata->set |= ERROR_SET;
  ------------------
  |  | 2908|      3|#define ERROR_SET       (1llu<<31)
  ------------------
 1002|      3|        }
 1003|      9|        return FILTER(status);
  ------------------
  |  |  808|      9|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|     18|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 9]
  |  |  ------------------
  |  |  809|      9|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|      9|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 8]
  |  |  ------------------
  ------------------
 1004|      9|    }
 1005|    462|    if (str_starts_with(classtag, "\"class\":\"TOFF\"")) {
  ------------------
  |  Branch (1005:9): [True: 29, False: 433]
  ------------------
 1006|     29|        status = json_toff_read(buf, gpsdata, end);
 1007|     29|        if (PASS(status)) {
  ------------------
  |  |  810|     29|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     29|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|     58|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 29]
  |  |  |  |  ------------------
  |  |  |  |  809|     29|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     29|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 28]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 15, False: 14]
  |  |  ------------------
  ------------------
 1008|     15|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|     15|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|     15|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|     15|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|     15|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|     15|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|     15|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|     15|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|     15|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|     15|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|     15|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|     15|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|     15|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|     15|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|     15|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|     15|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|     15|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|     15|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
 1009|     15|            gpsdata->set |= TOFF_SET;
  ------------------
  |  | 2909|     15|#define TOFF_SET        (1llu<<32)      // not yet used
  ------------------
 1010|     15|        }
 1011|     29|        return FILTER(status);
  ------------------
  |  |  808|     29|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|     58|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 29]
  |  |  ------------------
  |  |  809|     29|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     29|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 28]
  |  |  ------------------
  ------------------
 1012|     29|    }
 1013|    433|    if (str_starts_with(classtag, "\"class\":\"PPS\"")) {
  ------------------
  |  Branch (1013:9): [True: 37, False: 396]
  ------------------
 1014|     37|        status = json_pps_read(buf, gpsdata, end);
 1015|     37|        if (PASS(status)) {
  ------------------
  |  |  810|     37|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     37|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|     74|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 37]
  |  |  |  |  ------------------
  |  |  |  |  809|     37|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     37|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 36]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 24, False: 13]
  |  |  ------------------
  ------------------
 1016|     24|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|     24|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|     24|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|     24|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|     24|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|     24|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|     24|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|     24|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|     24|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|     24|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|     24|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|     24|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|     24|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|     24|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|     24|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|     24|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|     24|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|     24|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
 1017|     24|            gpsdata->set |= PPS_SET;
  ------------------
  |  | 2910|     24|#define PPS_SET         (1llu<<33)
  ------------------
 1018|     24|        }
 1019|     37|        return FILTER(status);
  ------------------
  |  |  808|     37|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|     74|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 37]
  |  |  ------------------
  |  |  809|     37|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     37|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 36]
  |  |  ------------------
  ------------------
 1020|     37|    }
 1021|    396|    if (str_starts_with(classtag, "\"class\":\"OSC\"")) {
  ------------------
  |  Branch (1021:9): [True: 11, False: 385]
  ------------------
 1022|     11|        status = json_oscillator_read(buf, gpsdata, end);
 1023|     11|        if (PASS(status)) {
  ------------------
  |  |  810|     11|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|     11|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|     22|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 11]
  |  |  |  |  ------------------
  |  |  |  |  809|     11|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|     11|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 1, False: 10]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 5, False: 6]
  |  |  ------------------
  ------------------
 1024|      5|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|      5|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|      5|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|      5|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|      5|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|      5|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|      5|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|      5|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|      5|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|      5|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|      5|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|      5|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|      5|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|      5|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|      5|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|      5|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|      5|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|      5|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
 1025|      5|            gpsdata->set |= OSCILLATOR_SET;
  ------------------
  |  | 2912|      5|#define OSCILLATOR_SET  (1llu<<35)
  ------------------
 1026|      5|        }
 1027|     11|        return FILTER(status);
  ------------------
  |  |  808|     11|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|     22|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 11]
  |  |  ------------------
  |  |  809|     11|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|     11|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 1, False: 10]
  |  |  ------------------
  ------------------
 1028|     11|    }
 1029|    385|    if (str_starts_with(classtag, "\"class\":\"RAW\"")) {
  ------------------
  |  Branch (1029:9): [True: 158, False: 227]
  ------------------
 1030|    158|        status = json_raw_read(buf, gpsdata, end);
 1031|    158|        if (PASS(status)) {
  ------------------
  |  |  810|    158|#define PASS(n) (0 == FILTER(n))
  |  |  ------------------
  |  |  |  |  808|    158|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|    316|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (808:21): [True: 0, False: 158]
  |  |  |  |  ------------------
  |  |  |  |  809|    158|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  156|    158|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (809:21): [True: 3, False: 155]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (810:17): [True: 35, False: 123]
  |  |  ------------------
  ------------------
 1032|     35|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2977|     35|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2901|     35|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2908|     35|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2904|     35|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2978|     35|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2907|     35|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2912|     35|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2910|     35|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2916|     35|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2979|     35|                         RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2899|     35|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2900|     35|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2922|     35|#define SPARTN_SET      (1llu<<45)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SPARTN_SET|SUBFRAME_SET| \
  |  |  ------------------
  |  |  |  | 2903|     35|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  | 2980|     35|                         TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2909|     35|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2905|     35|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
 1033|     35|            gpsdata->set |= RAW_SET;
  ------------------
  |  | 2916|     35|#define RAW_SET         (1llu<<39)
  ------------------
 1034|     35|        }
 1035|    158|        return FILTER(status);
  ------------------
  |  |  808|    158|#define FILTER(n) (((n) == JSON_ERR_BADATTR ||   \
  |  |  ------------------
  |  |  |  |  154|    316|#define JSON_ERR_BADATTR        3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (808:21): [True: 0, False: 158]
  |  |  ------------------
  |  |  809|    158|                    (n) == JSON_ERR_NOARRAY) ? 0 : n)
  |  |  ------------------
  |  |  |  |  156|    158|#define JSON_ERR_NOARRAY        5      // saw [ when not expecting array
  |  |  ------------------
  |  |  |  Branch (809:21): [True: 3, False: 155]
  |  |  ------------------
  ------------------
 1036|    158|    }
 1037|       |    // else, unknown class type
 1038|    227|    return -1;
 1039|    385|}
libgps_json.c:json_tpv_read:
   37|    449|{
   38|    449|    int ret;
   39|       |
   40|    449|    const struct json_attr_t json_attrs_1[] = {
   41|       |        // *INDENT-OFF*
   42|    449|        {"class",  t_check,   .dflt.check = "TPV"},
   43|    449|        {"alt",    t_real,    .addr.real = &gpsdata->fix.altitude,
   44|    449|                                 .dflt.real = NAN}, // DEPRECATED, undefined
   45|    449|        {"altHAE", t_real,    .addr.real = &gpsdata->fix.altHAE,
   46|    449|                                 .dflt.real = NAN},
   47|    449|        {"altMSL", t_real,    .addr.real = &gpsdata->fix.altMSL,
   48|    449|                                 .dflt.real = NAN},
   49|    449|        {"ant",    t_integer, .addr.integer = &gpsdata->fix.ant_stat,
   50|    449|                                 .dflt.integer = 0},
   51|    449|        {"antPwr",    t_integer, .addr.integer = &gpsdata->fix.ant_power,
   52|    449|                                 .dflt.integer = 0},
   53|    449|        {"baseS",     t_integer,   .addr.integer = &gpsdata->fix.base.status,
   54|    449|         .dflt.integer = STATUS_UNK},     // aka zero
  ------------------
  |  |  228|    449|#define STATUS_UNK      0       // Unknown status
  ------------------
   55|    449|        {"baseE",     t_real,      .addr.real = &gpsdata->fix.base.east,
   56|    449|         .dflt.real = NAN},
   57|    449|        {"baseN",     t_real,      .addr.real = &gpsdata->fix.base.north,
   58|    449|         .dflt.real = NAN},
   59|    449|        {"baseU",     t_real,      .addr.real = &gpsdata->fix.base.up,
   60|    449|         .dflt.real = NAN},
   61|    449|        {"baseL",     t_real,      .addr.real = &gpsdata->fix.base.length,
   62|    449|         .dflt.real = NAN},
   63|    449|        {"baseC",     t_real,      .addr.real = &gpsdata->fix.base.course,
   64|    449|         .dflt.real = NAN},
   65|    449|        {"climb",     t_real,      .addr.real = &gpsdata->fix.climb,
   66|    449|                                   .dflt.real = NAN},
   67|    449|        {"clockbias", t_longint, .addr.longint = &gpsdata->fix.clockbias,
   68|    449|                                 .dflt.longint = 0},
   69|    449|        {"clockdrift", t_longint, .addr.longint = &gpsdata->fix.clockdrift,
   70|    449|                                 .dflt.longint = 0},
   71|    449|        {"datum",  t_string,  .addr.string = gpsdata->fix.datum,
   72|    449|                                 .len = sizeof(gpsdata->fix.datum)},
   73|    449|        {"device", t_string,  .addr.string = gpsdata->dev.path,
   74|    449|                                 .len = sizeof(gpsdata->dev.path)},
   75|    449|        {"depth", t_real,  .addr.real = &gpsdata->fix.depth,
   76|    449|                                 .dflt.real = NAN},
   77|    449|        {"dgpsAge", t_real, .addr.real = &gpsdata->fix.dgps_age,
   78|    449|                                 .dflt.real = NAN},
   79|    449|        {"dgpsRatio", t_real, .addr.real = &gpsdata->fix.base.ratio,
   80|    449|                                 .dflt.real = NAN},
   81|    449|        {"dgpsSta", t_integer, .addr.integer = &gpsdata->fix.dgps_station,
   82|    449|                                 .dflt.integer = -1},
   83|    449|        {"ecefx",  t_real,    .addr.real = &gpsdata->fix.ecef.x,
   84|    449|                                 .dflt.real = NAN},
   85|    449|        {"ecefy",  t_real,    .addr.real = &gpsdata->fix.ecef.y,
   86|    449|                                 .dflt.real = NAN},
   87|    449|        {"ecefz",  t_real,    .addr.real = &gpsdata->fix.ecef.z,
   88|    449|                                 .dflt.real = NAN},
   89|    449|        {"ecefvx", t_real,    .addr.real = &gpsdata->fix.ecef.vx,
   90|    449|                                 .dflt.real = NAN},
   91|    449|        {"ecefvy", t_real,    .addr.real = &gpsdata->fix.ecef.vy,
   92|    449|                                 .dflt.real = NAN},
   93|    449|        {"ecefvz", t_real,    .addr.real = &gpsdata->fix.ecef.vz,
   94|    449|                                 .dflt.real = NAN},
   95|    449|        {"ecefpAcc", t_real,  .addr.real = &gpsdata->fix.ecef.pAcc,
   96|    449|                                 .dflt.real = NAN},
   97|    449|        {"ecefvAcc", t_real,  .addr.real = &gpsdata->fix.ecef.vAcc,
   98|    449|                                 .dflt.real = NAN},
   99|    449|        {"epc",    t_real,    .addr.real = &gpsdata->fix.epc,
  100|    449|                                 .dflt.real = NAN},
  101|    449|        {"epd",    t_real,    .addr.real = &gpsdata->fix.epd,
  102|    449|                                 .dflt.real = NAN},
  103|    449|        {"eph",    t_real,    .addr.real = &gpsdata->fix.eph,
  104|    449|                                 .dflt.real = NAN},
  105|    449|        {"eps",    t_real,    .addr.real = &gpsdata->fix.eps,
  106|    449|                                 .dflt.real = NAN},
  107|    449|        {"ept",    t_real,    .addr.real = &gpsdata->fix.ept,
  108|    449|                                 .dflt.real = NAN},
  109|    449|        {"epx",    t_real,    .addr.real = &gpsdata->fix.epx,
  110|    449|                                 .dflt.real = NAN},
  111|    449|        {"epy",    t_real,    .addr.real = &gpsdata->fix.epy,
  112|    449|                                 .dflt.real = NAN},
  113|    449|        {"epv",    t_real,    .addr.real = &gpsdata->fix.epv,
  114|    449|                                 .dflt.real = NAN},
  115|    449|        {"geoidSep", t_real,  .addr.real = &gpsdata->fix.geoid_sep,
  116|    449|                                 .dflt.real = NAN},
  117|    449|        {"lat",    t_real,    .addr.real = &gpsdata->fix.latitude,
  118|    449|                                 .dflt.real = NAN},
  119|    449|        {"jam",    t_integer, .addr.integer = &gpsdata->fix.jam,
  120|    449|                                 .dflt.integer = -1},
  121|    449|        {"leapseconds",   t_integer, .addr.integer = &gpsdata->leap_seconds,
  122|    449|                                 .dflt.integer = 0},
  123|    449|        {"lon",    t_real,    .addr.real = &gpsdata->fix.longitude,
  124|    449|                                 .dflt.real = NAN},
  125|    449|        {"magdev",  t_real,   .addr.real = &gpsdata->fix.magnetic_dev,
  126|    449|                                 .dflt.real = NAN},
  127|    449|        {"magtrack",  t_real,    .addr.real = &gpsdata->fix.magnetic_track,
  128|    449|                                 .dflt.real = NAN},
  129|    449|        {"magvar",  t_real,   .addr.real = &gpsdata->fix.magnetic_var,
  130|    449|                                 .dflt.real = NAN},
  131|    449|        {"mode",   t_integer, .addr.integer = &gpsdata->fix.mode,
  132|    449|                                 .dflt.integer = MODE_NOT_SEEN},
  ------------------
  |  |  217|    449|#define MODE_NOT_SEEN   0       // mode update not seen yet
  ------------------
  133|    449|        {"relD", t_real,  .addr.real = &gpsdata->fix.NED.relPosD,
  134|    449|                                 .dflt.real = NAN},
  135|    449|        {"relE", t_real,  .addr.real = &gpsdata->fix.NED.relPosE,
  136|    449|                                 .dflt.real = NAN},
  137|    449|        {"relN", t_real,  .addr.real = &gpsdata->fix.NED.relPosN,
  138|    449|                                 .dflt.real = NAN},
  139|    449|        {"relH", t_real,  .addr.real = &gpsdata->fix.NED.relPosH,
  140|    449|                                 .dflt.real = NAN},
  141|    449|        {"relL", t_real,  .addr.real = &gpsdata->fix.NED.relPosL,
  142|    449|                                 .dflt.real = NAN},
  143|    449|        {"temp",   t_real, .addr.real = &gpsdata->fix.temp,
  144|    449|                                 .dflt.real = NAN},
  145|    449|        {"time",   t_time,    .addr.ts = &gpsdata->fix.time,
  146|    449|                                 .dflt.ts = {0, 0}},
  147|    449|        {"track",  t_real,    .addr.real = &gpsdata->fix.track,
  148|    449|                                 .dflt.real = NAN},
  149|    449|        {"sep",    t_real,    .addr.real = &gpsdata->fix.sep,
  150|    449|                                 .dflt.real = NAN},
  151|    449|        {"speed",  t_real,    .addr.real = &gpsdata->fix.speed,
  152|    449|                                 .dflt.real = NAN},
  153|    449|        {"status", t_integer, .addr.integer = &gpsdata->fix.status,
  154|    449|                                 .dflt.integer = STATUS_UNK},
  ------------------
  |  |  228|    449|#define STATUS_UNK      0       // Unknown status
  ------------------
  155|    449|        {"velD", t_real,  .addr.real = &gpsdata->fix.NED.velD,
  156|    449|                                 .dflt.real = NAN},
  157|    449|        {"velE", t_real,  .addr.real = &gpsdata->fix.NED.velE,
  158|    449|                                 .dflt.real = NAN},
  159|    449|        {"velN", t_real,  .addr.real = &gpsdata->fix.NED.velN,
  160|    449|                                 .dflt.real = NAN},
  161|    449|        {"wanglem", t_real, .addr.real = &gpsdata->fix.wanglem,
  162|    449|                                 .dflt.real = NAN},
  163|    449|        {"wangler", t_real, .addr.real = &gpsdata->fix.wangler,
  164|    449|                                 .dflt.real = NAN},
  165|    449|        {"wanglet", t_real, .addr.real = &gpsdata->fix.wanglet,
  166|    449|                                 .dflt.real = NAN},
  167|    449|        {"wspeedr", t_real, .addr.real = &gpsdata->fix.wspeedr,
  168|    449|                                 .dflt.real = NAN},
  169|    449|        {"wspeedt", t_real, .addr.real = &gpsdata->fix.wspeedt,
  170|    449|                                 .dflt.real = NAN},
  171|    449|        {"wtemp", t_real, .addr.real = &gpsdata->fix.wtemp,
  172|    449|                                 .dflt.real = NAN},
  173|       |        // ignore unknown keys, for cross-version compatibility
  174|    449|        {"", t_ignore},
  175|       |
  176|    449|        {NULL},
  177|       |        // *INDENT-ON*
  178|    449|    };
  179|       |
  180|    449|    ret = json_read_object(buf, json_attrs_1, endptr);
  181|    449|    if (1 == isfinite(gpsdata->fix.magnetic_dev) ||
  ------------------
  |  Branch (181:9): [True: 0, False: 449]
  ------------------
  182|    449|        1 == isfinite(gpsdata->fix.magnetic_track) ||
  ------------------
  |  Branch (182:9): [True: 1, False: 448]
  ------------------
  183|    448|        1 == isfinite(gpsdata->fix.magnetic_var)) {
  ------------------
  |  Branch (183:9): [True: 1, False: 447]
  ------------------
  184|      2|        gpsdata->set |= MAGNETIC_TRACK_SET;
  ------------------
  |  | 2915|      2|#define MAGNETIC_TRACK_SET (1llu<<38)
  ------------------
  185|      2|    }
  186|    449|    if (1 == isfinite(gpsdata->fix.track)) {
  ------------------
  |  Branch (186:9): [True: 1, False: 448]
  ------------------
  187|      1|        gpsdata->set |= TRACK_SET;
  ------------------
  |  | 2884|      1|#define TRACK_SET       (1llu<<7)
  ------------------
  188|      1|    }
  189|    449|    return ret;
  190|    449|}
libgps_json.c:json_noise_read:
  194|    326|{
  195|    326|    int ret;
  196|       |
  197|    326|    const struct json_attr_t json_attrs_1[] = {
  198|       |        // *INDENT-OFF*
  199|    326|        {"class",  t_check,   .dflt.check = "GST"},
  200|    326|        {"device", t_string,  .addr.string = gpsdata->dev.path,
  201|    326|                                 .len = sizeof(gpsdata->dev.path)},
  202|    326|        {"time",   t_time,    .addr.ts = &gpsdata->gst.utctime,
  203|    326|                                 .dflt.ts = {0, 0}},
  204|    326|        {"alt",    t_real,    .addr.real = &gpsdata->gst.alt_err_deviation,
  205|    326|                                 .dflt.real = NAN},
  206|    326|        {"lat",    t_real,    .addr.real = &gpsdata->gst.lat_err_deviation,
  207|    326|                                 .dflt.real = NAN},
  208|    326|        {"lon",    t_real,    .addr.real = &gpsdata->gst.lon_err_deviation,
  209|    326|                                 .dflt.real = NAN},
  210|    326|        {"major",  t_real,    .addr.real = &gpsdata->gst.smajor_deviation,
  211|    326|                                 .dflt.real = NAN},
  212|    326|        {"minor",  t_real,    .addr.real = &gpsdata->gst.sminor_deviation,
  213|    326|                                 .dflt.real = NAN},
  214|    326|        {"orient", t_real,    .addr.real = &gpsdata->gst.smajor_orientation,
  215|    326|                                 .dflt.real = NAN},
  216|    326|        {"rms",    t_real,    .addr.real = &gpsdata->gst.rms_deviation,
  217|    326|                                 .dflt.real = NAN},
  218|    326|        {"ve",     t_real,    .addr.real = &gpsdata->gst.ve_err_deviation,
  219|    326|                                 .dflt.real = NAN},
  220|    326|        {"vn",     t_real,    .addr.real = &gpsdata->gst.vn_err_deviation,
  221|    326|                                 .dflt.real = NAN},
  222|    326|        {"vu",     t_real,    .addr.real = &gpsdata->gst.vu_err_deviation,
  223|    326|                                 .dflt.real = NAN},
  224|       |        // ignore unknown keys, for cross-version compatibility
  225|    326|        {"", t_ignore},
  226|    326|        {NULL},
  227|       |        // *INDENT-ON*
  228|    326|    };
  229|       |
  230|    326|    ret = json_read_object(buf, json_attrs_1, endptr);
  231|       |
  232|    326|    return ret;
  233|    326|}
libgps_json.c:json_sky_read:
  310|    185|{
  311|       |
  312|    185|    const struct json_attr_t json_attrs_satellites[] = {
  313|       |        // *INDENT-OFF*
  314|    185|        {"PRN",    t_short,   STRUCTOBJECT(struct satellite_t, PRN)},
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  315|    185|        {"az",     t_real,    STRUCTOBJECT(struct satellite_t, azimuth),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  316|    185|                              .dflt.real = NAN},
  317|    185|        {"el",     t_real,    STRUCTOBJECT(struct satellite_t, elevation),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  318|    185|                              .dflt.real = NAN},
  319|    185|        {"freqid", t_byte,    STRUCTOBJECT(struct satellite_t, freqid),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  320|    185|                              .dflt.byte = -1},
  321|    185|        {"gnssid", t_ubyte,   STRUCTOBJECT(struct satellite_t, gnssid)},
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  322|    185|        {"health", t_ubyte,   STRUCTOBJECT(struct satellite_t, health),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  323|    185|                              .dflt.ubyte = SAT_HEALTH_UNK},
  ------------------
  |  | 2617|    185|#define SAT_HEALTH_UNK 0
  ------------------
  324|    185|        {"pr",     t_real,    STRUCTOBJECT(struct satellite_t, pr),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  325|    185|                              .dflt.real = NAN},
  326|    185|        {"prRate", t_real,    STRUCTOBJECT(struct satellite_t, prRate),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  327|    185|                              .dflt.real = NAN},
  328|    185|        {"prRes",  t_real,    STRUCTOBJECT(struct satellite_t, prRes),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  329|    185|                              .dflt.real = NAN},
  330|    185|        {"ss",     t_real,    STRUCTOBJECT(struct satellite_t, ss),
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  331|    185|                              .dflt.real = NAN},
  332|    185|        {"sigid",  t_ubyte,   STRUCTOBJECT(struct satellite_t, sigid)},
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  333|    185|        {"svid",   t_ubyte,   STRUCTOBJECT(struct satellite_t, svid)},
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  334|    185|        {"used",   t_boolean, STRUCTOBJECT(struct satellite_t, used)},
  ------------------
  |  |  188|    185|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  335|       |        // ignore unknown keys, for cross-version compatibility
  336|    185|        {"", t_ignore},
  337|       |        // *INDENT-ON*
  338|    185|        {NULL},
  339|    185|    };
  340|       |
  341|    185|    int nSat = -1;  // Use nSat only to know if sats are in SKY
  342|       |
  343|    185|    const struct json_attr_t json_attrs_2[] = {
  344|       |        // *INDENT-OFF*
  345|    185|        {"class",      t_check,   .dflt.check = "SKY"},
  346|    185|        {"device",     t_string,  .addr.string  = gpsdata->dev.path,
  347|    185|                                     .len = sizeof(gpsdata->dev.path)},
  348|    185|        {"gdop",       t_real,    .addr.real    = &gpsdata->dop.gdop,
  349|    185|                                     .dflt.real = NAN},
  350|    185|        {"hdop",       t_real,    .addr.real    = &gpsdata->dop.hdop,
  351|    185|                                     .dflt.real = NAN},
  352|    185|        {"nSat",       t_integer, .addr.integer = &nSat,
  353|    185|                                     .dflt.integer = -1},
  354|    185|        {"pdop",       t_real,    .addr.real    = &gpsdata->dop.pdop,
  355|    185|                                     .dflt.real = NAN},
  356|    185|        {"tdop",       t_real,    .addr.real    = &gpsdata->dop.tdop,
  357|    185|                                     .dflt.real = NAN},
  358|    185|        {"vdop",       t_real,    .addr.real    = &gpsdata->dop.vdop,
  359|    185|                                     .dflt.real = NAN},
  360|    185|        {"xdop",       t_real,    .addr.real    = &gpsdata->dop.xdop,
  361|    185|                                     .dflt.real = NAN},
  362|    185|        {"ydop",       t_real,    .addr.real    = &gpsdata->dop.ydop,
  363|    185|                                     .dflt.real = NAN},
  364|    185|        {"satellites", t_array,
  365|    185|                                   STRUCTARRAY(gpsdata->skyview,
  ------------------
  |  |  190|    185|        .addr.array.element_type = t_structobject, \
  |  |  191|    185|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    185|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    185|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    185|        .addr.array.count = n, \
  |  |  195|    185|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    185|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    185|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    185|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    185|            struct { \
  |  |  |  |  |  |   71|    185|                int unused_int; \
  |  |  |  |  |  |   72|    185|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    185|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    185|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    185|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    185|            }; \
  |  |  |  |  |  |   77|    185|            1; \
  |  |  |  |  |  |   78|    185|        })) \
  |  |  |  |  |  |   79|    185|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  366|    185|                                         json_attrs_satellites,
  367|    185|                                         &gpsdata->satellites_visible)},
  368|    185|        {"time",       t_time,    .addr.ts = &gpsdata->skyview_time,
  369|    185|                                     .dflt.ts = {0, 0}},
  370|    185|        {"uSat",       t_integer, .addr.integer = &gpsdata->satellites_used,
  371|    185|                                     .dflt.integer = 0},
  372|       |        // ignore unknown keys, for cross-version compatibility
  373|    185|        {"", t_ignore},
  374|    185|        {NULL},
  375|       |        // *INDENT-ON*
  376|    185|    };
  377|    185|    int status, i;
  378|       |
  379|    185|    memset(&gpsdata->skyview, 0, sizeof(gpsdata->skyview));
  380|       |
  381|    185|    status = json_read_object(buf, json_attrs_2, endptr);
  382|    185|    if (0 != status) {
  ------------------
  |  Branch (382:9): [True: 60, False: 125]
  ------------------
  383|     60|        return status;
  384|     60|    }
  385|       |
  386|    125|    if (1 == isfinite(gpsdata->dop.hdop) ||
  ------------------
  |  Branch (386:9): [True: 1, False: 124]
  ------------------
  387|    124|        1 == isfinite(gpsdata->dop.xdop) ||
  ------------------
  |  Branch (387:9): [True: 1, False: 123]
  ------------------
  388|    123|        1 == isfinite(gpsdata->dop.ydop) ||
  ------------------
  |  Branch (388:9): [True: 1, False: 122]
  ------------------
  389|    122|        1 == isfinite(gpsdata->dop.vdop) ||
  ------------------
  |  Branch (389:9): [True: 1, False: 121]
  ------------------
  390|    121|        1 == isfinite(gpsdata->dop.tdop) ||
  ------------------
  |  Branch (390:9): [True: 1, False: 120]
  ------------------
  391|    120|        1 == isfinite(gpsdata->dop.pdop) ||
  ------------------
  |  Branch (391:9): [True: 1, False: 119]
  ------------------
  392|    119|        1 == isfinite(gpsdata->dop.gdop)) {
  ------------------
  |  Branch (392:9): [True: 1, False: 118]
  ------------------
  393|       |        // got at least one DOP
  394|      7|        gpsdata->set |= DOP_SET;
  ------------------
  |  | 2888|      7|#define DOP_SET         (1llu<<11)
  ------------------
  395|      7|    }
  396|       |
  397|    125|    gpsdata->satellites_visible = 0;
  398|       |
  399|    125|    if (-1 == nSat) {
  ------------------
  |  Branch (399:9): [True: 24, False: 101]
  ------------------
  400|       |        // no sats in the SKY, likely just dops.  Maybe uSat
  401|     24|        gpsdata->set &= ~SATELLITE_SET;
  ------------------
  |  | 2892|     24|#define SATELLITE_SET   (1llu<<15)
  ------------------
  402|     24|        return 0;
  403|     24|    }
  404|    101|    gpsdata->satellites_used = 0;
  405|       |
  406|    101|    gpsdata->set |= SATELLITE_SET;
  ------------------
  |  | 2892|    101|#define SATELLITE_SET   (1llu<<15)
  ------------------
  407|       |    // recalculate used and visible, do not use nSat, uSat
  408|  23.3k|    for (i = 0; i < MAXCHANNELS; i++) {
  ------------------
  |  |  134|  23.3k|#define MAXCHANNELS     230
  ------------------
  |  Branch (408:17): [True: 23.2k, False: 101]
  ------------------
  409|  23.2k|        if (0 < gpsdata->skyview[i].PRN) {
  ------------------
  |  Branch (409:13): [True: 1.62k, False: 21.6k]
  ------------------
  410|  1.62k|            gpsdata->satellites_visible++;
  411|  1.62k|        }
  412|  23.2k|        if (gpsdata->skyview[i].used) {
  ------------------
  |  Branch (412:13): [True: 1.61k, False: 21.6k]
  ------------------
  413|  1.61k|            gpsdata->satellites_used++;
  414|  1.61k|        }
  415|  23.2k|    }
  416|       |
  417|    101|    return 0;
  418|    125|}
libgps_json.c:json_att_read:
  423|     75|{
  424|     75|    struct attitude_t *datap = &gpsdata->attitude;
  425|       |
  426|     75|    const struct json_attr_t json_attrs_1[] = {
  427|       |        // *INDENT-OFF*
  428|     75|        {"class",     t_check,     .dflt.check = "ATT"},
  429|     75|        {"device",    t_string,    .addr.string = gpsdata->dev.path,
  430|     75|         .len = sizeof(gpsdata->dev.path)},
  431|     75|        {"acc_len",   t_real,      .addr.real = &datap->acc_len,
  432|     75|         .dflt.real = NAN},
  433|     75|        {"acc_x",     t_real,      .addr.real = &datap->acc_x,
  434|     75|         .dflt.real = NAN},
  435|     75|        {"acc_y",     t_real,      .addr.real = &datap->acc_y,
  436|     75|         .dflt.real = NAN},
  437|     75|        {"acc_z",     t_real,      .addr.real = &datap->acc_z,
  438|     75|         .dflt.real = NAN},
  439|     75|        {"baseS",     t_integer,   .addr.integer = &datap->base.status,
  440|     75|         .dflt.integer = STATUS_UNK},     // aka zero
  ------------------
  |  |  228|     75|#define STATUS_UNK      0       // Unknown status
  ------------------
  441|     75|        {"baseE",     t_real,      .addr.real = &datap->base.east,
  442|     75|         .dflt.real = NAN},
  443|     75|        {"baseN",     t_real,      .addr.real = &datap->base.north,
  444|     75|         .dflt.real = NAN},
  445|     75|        {"baseU",     t_real,      .addr.real = &datap->base.up,
  446|     75|         .dflt.real = NAN},
  447|     75|        {"baseL",     t_real,      .addr.real = &datap->base.length,
  448|     75|         .dflt.real = NAN},
  449|     75|        {"baseC",     t_real,      .addr.real = &datap->base.course,
  450|     75|         .dflt.real = NAN},
  451|     75|        {"dgpsRatio", t_real, .addr.real = &datap->base.ratio,
  452|     75|         .dflt.real = NAN},
  453|     75|        {"depth",     t_real,      .addr.real = &datap->depth,
  454|     75|         .dflt.real = NAN},
  455|     75|        {"dip",       t_real,      .addr.real = &datap->dip,
  456|     75|         .dflt.real = NAN},
  457|     75|        {"gyro_temp", t_real,      .addr.real = &datap->gyro_x,
  458|     75|         .dflt.real = NAN},
  459|     75|        {"gyro_x",    t_real,      .addr.real = &datap->gyro_x,
  460|     75|         .dflt.real = NAN},
  461|     75|        {"gyro_y",    t_real,      .addr.real = &datap->gyro_y,
  462|     75|         .dflt.real = NAN},
  463|     75|        {"gyro_z",    t_real,      .addr.real = &datap->gyro_z,
  464|     75|         .dflt.real = NAN},
  465|     75|        {"heading",   t_real,      .addr.real = &datap->heading,
  466|     75|         .dflt.real = NAN},
  467|     75|        {"mag_len",   t_real,      .addr.real = &datap->mag_len,
  468|     75|         .dflt.real = NAN},
  469|     75|        {"mag_st",    t_character, .addr.character = &datap->mag_st},
  470|     75|        {"mag_x",     t_real,      .addr.real = &datap->mag_x,
  471|     75|         .dflt.real = NAN},
  472|     75|        {"mag_y",     t_real,      .addr.real = &datap->mag_y,
  473|     75|         .dflt.real = NAN},
  474|     75|        {"mag_z",     t_real,      .addr.real = &datap->mag_z,
  475|     75|         .dflt.real = NAN},
  476|     75|        {"mheading",   t_real,     .addr.real = &datap->mheading,
  477|     75|         .dflt.real = NAN},
  478|     75|        {"msg",       t_string,    .addr.string = datap->msg,
  479|     75|         .len = sizeof(datap->msg)},
  480|     75|        {"pitch_st",  t_character, .addr.character = &datap->pitch_st},
  481|     75|        {"pitch",     t_real,      .addr.real = &datap->pitch,
  482|     75|         .dflt.real = NAN},
  483|     75|        {"roll_st",   t_character, .addr.character = &datap->roll_st},
  484|     75|        {"roll",      t_real,      .addr.real = &datap->roll,
  485|     75|         .dflt.real = NAN},
  486|     75|        {"temp",      t_real,      .addr.real = &datap->temp,
  487|     75|         .dflt.real = NAN},
  488|     75|        {"time",      t_time,      .addr.ts = &datap->mtime, .dflt.ts = {0, 0}},
  489|     75|        {"timeTag",   t_ulongint,  .addr.ulongint = &datap->timeTag,
  490|     75|         .dflt.ulongint = 0},
  491|     75|        {"yaw_st",    t_character, .addr.character = &datap->yaw_st},
  492|     75|        {"yaw",       t_real,      .addr.real = &datap->yaw, .dflt.real = NAN},
  493|       |
  494|       |        // ignore unknown keys, for cross-version compatibility
  495|     75|        {"", t_ignore},
  496|     75|        {NULL},
  497|       |        // *INDENT-ON*
  498|     75|    };
  499|       |
  500|     75|    return json_read_object(buf, json_attrs_1, endptr);
  501|     75|}
libgps_json.c:json_imu_read:
  506|     58|{
  507|       |    // the client only uses the first slot.
  508|     58|    struct attitude_t *datap = &gpsdata->imu[0];
  509|       |
  510|     58|    const struct json_attr_t json_attrs_1[] = {
  511|       |        // *INDENT-OFF*
  512|     58|        {"class",     t_check,     .dflt.check = "IMU"},
  513|     58|        {"device",    t_string,    .addr.string = gpsdata->dev.path,
  514|     58|         .len = sizeof(gpsdata->dev.path)},
  515|     58|        {"acc_len",   t_real,      .addr.real = &datap->acc_len,
  516|     58|         .dflt.real = NAN},
  517|     58|        {"acc_x",     t_real,      .addr.real = &datap->acc_x,
  518|     58|         .dflt.real = NAN},
  519|     58|        {"acc_y",     t_real,      .addr.real = &datap->acc_y,
  520|     58|         .dflt.real = NAN},
  521|     58|        {"acc_z",     t_real,      .addr.real = &datap->acc_z,
  522|     58|         .dflt.real = NAN},
  523|     58|        {"depth",     t_real,      .addr.real = &datap->depth,
  524|     58|         .dflt.real = NAN},
  525|     58|        {"dip",       t_real,      .addr.real = &datap->dip,
  526|     58|         .dflt.real = NAN},
  527|     58|        {"gyro_temp", t_real,      .addr.real = &datap->gyro_temp,
  528|     58|         .dflt.real = NAN},
  529|     58|        {"gyro_x",    t_real,      .addr.real = &datap->gyro_x,
  530|     58|         .dflt.real = NAN},
  531|     58|        {"gyro_y",    t_real,      .addr.real = &datap->gyro_y,
  532|     58|         .dflt.real = NAN},
  533|     58|        {"gyro_z",    t_real,      .addr.real = &datap->gyro_z,
  534|     58|         .dflt.real = NAN},
  535|     58|        {"heading",   t_real,      .addr.real = &datap->heading,
  536|     58|         .dflt.real = NAN},
  537|     58|        {"mag_len",   t_real,      .addr.real = &datap->mag_len,
  538|     58|         .dflt.real = NAN},
  539|     58|        {"mag_st",    t_character, .addr.character = &datap->mag_st},
  540|     58|        {"mag_x",     t_real,      .addr.real = &datap->mag_x,
  541|     58|         .dflt.real = NAN},
  542|     58|        {"mag_y",     t_real,      .addr.real = &datap->mag_y,
  543|     58|         .dflt.real = NAN},
  544|     58|        {"mag_z",     t_real,      .addr.real = &datap->mag_z,
  545|     58|         .dflt.real = NAN},
  546|     58|        {"msg",       t_string,    .addr.string = datap->msg,
  547|     58|         .len = sizeof(datap->msg)},
  548|     58|        {"pitch_st",  t_character, .addr.character = &datap->pitch_st},
  549|     58|        {"pitch",     t_real,      .addr.real = &datap->pitch,
  550|     58|         .dflt.real = NAN},
  551|     58|        {"roll_st",   t_character, .addr.character = &datap->roll_st},
  552|     58|        {"roll",      t_real,      .addr.real = &datap->roll,
  553|     58|         .dflt.real = NAN},
  554|     58|        {"temp",      t_real,      .addr.real = &datap->temp,
  555|     58|         .dflt.real = NAN},
  556|     58|        {"time",      t_time,      .addr.ts = &datap->mtime, .dflt.ts = {0, 0}},
  557|     58|        {"timeTag",   t_ulongint,  .addr.ulongint = &datap->timeTag,
  558|     58|         .dflt.ulongint = 0},
  559|     58|        {"yaw_st",    t_character, .addr.character = &datap->yaw_st},
  560|     58|        {"yaw",       t_real,      .addr.real = &datap->yaw, .dflt.real = NAN},
  561|       |
  562|       |        // ignore unknown keys, for cross-version compatibility
  563|     58|        {"", t_ignore},
  564|     58|        {NULL},
  565|       |        // *INDENT-ON*
  566|     58|    };
  567|       |
  568|     58|    return json_read_object(buf, json_attrs_1, endptr);
  569|     58|}
libgps_json.c:json_devicelist_read:
  573|     67|{
  574|     67|    const struct json_attr_t json_attrs_subdevices[] = {
  575|       |        // *INDENT-OFF*
  576|     67|        {"class",      t_check,      .dflt.check = "DEVICE"},
  577|     67|        {"path",       t_string,     STRUCTOBJECT(struct devconfig_t, path),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  578|     67|         .len = sizeof(gpsdata->devices.list[0].path)},
  579|     67|        {"activated",  t_time,
  580|     67|         STRUCTOBJECT(struct devconfig_t, activated)},
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  581|     67|        {"flags",      t_integer,    STRUCTOBJECT(struct devconfig_t, flags)},
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  582|     67|        {"driver",     t_string,     STRUCTOBJECT(struct devconfig_t, driver),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  583|     67|         .len = sizeof(gpsdata->devices.list[0].driver)},
  584|     67|        {"hexdata",    t_string,     STRUCTOBJECT(struct devconfig_t, hexdata),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  585|     67|         .len = sizeof(gpsdata->devices.list[0].hexdata)},
  586|     67|        {"sernum",     t_string,     STRUCTOBJECT(struct devconfig_t, sernum),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  587|     67|                            .len = sizeof(gpsdata->devices.list[0].sernum)},
  588|     67|        {"subtype",    t_string,     STRUCTOBJECT(struct devconfig_t, subtype),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  589|     67|                            .len = sizeof(gpsdata->devices.list[0].subtype)},
  590|     67|        {"subtype1",   t_string,     STRUCTOBJECT(struct devconfig_t, subtype1),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  591|     67|                            .len = sizeof(gpsdata->devices.list[0].subtype1)},
  592|     67|        {"native",     t_integer, STRUCTOBJECT(struct devconfig_t, driver_mode),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  593|     67|                                        .dflt.integer = -1},
  594|     67|        {"bps",        t_uinteger,   STRUCTOBJECT(struct devconfig_t, baudrate),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  595|     67|                                        .dflt.uinteger = DEVDEFAULT_BPS},
  ------------------
  |  |   49|     67|#define DEVDEFAULT_BPS          0
  ------------------
  596|     67|        {"parity",     t_character,  STRUCTOBJECT(struct devconfig_t, parity),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  597|     67|                                        .dflt.character = DEVDEFAULT_PARITY},
  ------------------
  |  |   50|     67|#define DEVDEFAULT_PARITY       'X'
  ------------------
  598|     67|        {"stopbits",   t_uinteger,   STRUCTOBJECT(struct devconfig_t, stopbits),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  599|     67|                                        .dflt.integer = DEVDEFAULT_STOPBITS},
  ------------------
  |  |   51|     67|#define DEVDEFAULT_STOPBITS     3
  ------------------
  600|     67|        {"cycle",      t_timespec,   STRUCTOBJECT(struct devconfig_t, cycle),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  601|     67|                                        .dflt.ts = {0,0}},
  602|     67|        {"mincycle",   t_timespec,   STRUCTOBJECT(struct devconfig_t, mincycle),
  ------------------
  |  |  188|     67|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  603|     67|                                        .dflt.ts = {0,0}},
  604|       |        // ignore unknown keys, for cross-version compatibility
  605|     67|        {"", t_ignore},
  606|     67|        {NULL},
  607|       |        // *INDENT-ON*
  608|     67|    };
  609|     67|    const struct json_attr_t json_attrs_devices[] = {
  610|     67|        {"class", t_check,.dflt.check = "DEVICES"},
  611|     67|        {"devices", t_array, STRUCTARRAY(gpsdata->devices.list,
  ------------------
  |  |  190|     67|        .addr.array.element_type = t_structobject, \
  |  |  191|     67|        .addr.array.arr.objects.subtype = e, \
  |  |  192|     67|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|     67|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|     67|        .addr.array.count = n, \
  |  |  195|     67|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|     67|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|     67|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|     67|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|     67|            struct { \
  |  |  |  |  |  |   71|     67|                int unused_int; \
  |  |  |  |  |  |   72|     67|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|     67|            } zero_init = {0}; \
  |  |  |  |  |  |   74|     67|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|     67|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|     67|            }; \
  |  |  |  |  |  |   77|     67|            1; \
  |  |  |  |  |  |   78|     67|        })) \
  |  |  |  |  |  |   79|     67|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  612|     67|                                         json_attrs_subdevices,
  613|     67|                                         &gpsdata->devices.ndevices)},
  614|       |        // ignore unknown keys, for cross-version compatibility
  615|     67|        {"", t_ignore},
  616|     67|        {NULL},
  617|     67|    };
  618|     67|    int status;
  619|       |
  620|     67|    memset(&gpsdata->devices, 0, sizeof(gpsdata->devices));
  621|     67|    status = json_read_object(buf, json_attrs_devices, endptr);
  622|     67|    if (status != 0) {
  ------------------
  |  Branch (622:9): [True: 61, False: 6]
  ------------------
  623|     61|        return status;
  624|     61|    }
  625|       |
  626|       |    // json.c should ensure this never happens
  627|     67|    assert(MAXUSERDEVS >= gpsdata->devices.ndevices);
  ------------------
  |  Branch (627:5): [True: 0, False: 6]
  |  Branch (627:5): [True: 6, False: 0]
  ------------------
  628|       |
  629|      6|    (void)clock_gettime(CLOCK_REALTIME, &gpsdata->devices.time);
  630|      6|    return 0;
  631|      6|}
libgps_json.c:json_version_read:
  635|     15|{
  636|     15|    const struct json_attr_t json_attrs_version[] = {
  637|       |        // *INDENT-OFF*
  638|     15|        {"class",     t_check,   .dflt.check = "VERSION"},
  639|     15|        {"release",   t_string,  .addr.string  = gpsdata->version.release,
  640|     15|                                    .len = sizeof(gpsdata->version.release)},
  641|     15|        {"rev",       t_string,  .addr.string  = gpsdata->version.rev,
  642|     15|                                    .len = sizeof(gpsdata->version.rev)},
  643|     15|        {"proto_major", t_integer,
  644|     15|         .addr.integer = &gpsdata->version.proto_major},
  645|     15|        {"proto_minor", t_integer,
  646|     15|         .addr.integer = &gpsdata->version.proto_minor},
  647|     15|        {"remote",    t_string,  .addr.string  = gpsdata->version.remote,
  648|     15|                                    .len = sizeof(gpsdata->version.remote)},
  649|       |        // ignore unknown keys, for cross-version compatibility
  650|     15|        {"", t_ignore},
  651|     15|        {NULL},
  652|       |        // *INDENT-ON*
  653|     15|    };
  654|     15|    int status;
  655|       |
  656|     15|    memset(&gpsdata->version, 0, sizeof(gpsdata->version));
  657|     15|    status = json_read_object(buf, json_attrs_version, endptr);
  658|       |
  659|     15|    return status;
  660|     15|}
libgps_json.c:json_error_read:
  664|      9|{
  665|      9|    const struct json_attr_t json_attrs_error[] = {
  666|       |        // *INDENT-OFF*
  667|      9|        {"class",     t_check,   .dflt.check = "ERROR"},
  668|      9|        {"message",   t_string,  .addr.string  = gpsdata->error,
  669|      9|                                    .len = sizeof(gpsdata->error)},
  670|       |        // ignore unknown keys, for cross-version compatibility
  671|      9|        {"", t_ignore},
  672|      9|        {NULL},
  673|       |        // *INDENT-ON*
  674|      9|    };
  675|      9|    int status;
  676|       |
  677|      9|    memset(&gpsdata->error, 0, sizeof(gpsdata->error));
  678|      9|    status = json_read_object(buf, json_attrs_error, endptr);
  679|      9|    if (status != 0)
  ------------------
  |  Branch (679:9): [True: 7, False: 2]
  ------------------
  680|      7|        return status;
  681|       |
  682|      2|    return status;
  683|      9|}
libgps_json.c:json_raw_read:
  238|    158|{
  239|    158|    unsigned measurements;
  240|       |    // initialized to shut up clang
  241|    158|    double mtime_s = 0.0, mtime_ns = 0.0;
  242|       |
  243|    158|    const struct json_attr_t json_attrs_meas[] = {
  244|       |        // *INDENT-OFF*
  245|    158|        {"gnssid",       t_ubyte,    STRUCTOBJECT(struct meas_t, gnssid)},
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  246|    158|        {"svid",         t_ubyte,    STRUCTOBJECT(struct meas_t, svid)},
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  247|    158|        {"sigid",        t_ubyte,    STRUCTOBJECT(struct meas_t, sigid),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  248|    158|                                     .dflt.ubyte = 0},
  249|    158|        {"snr",          t_ubyte,    STRUCTOBJECT(struct meas_t, snr)},
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  250|    158|        {"freqid",       t_ubyte,    STRUCTOBJECT(struct meas_t, freqid),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  251|    158|                                     .dflt.ubyte = 0},
  252|    158|        {"obs",          t_string,   STRUCTOBJECT(struct meas_t, obs_code),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  253|    158|                                .len = sizeof(gpsdata->raw.meas[0].obs_code)},
  254|    158|        {"lli",          t_ubyte,    STRUCTOBJECT(struct meas_t, lli),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  255|    158|                                     .dflt.ubyte = 0},
  256|    158|        {"locktime",     t_uinteger, STRUCTOBJECT(struct meas_t, locktime),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  257|    158|                                     .dflt.uinteger = 0},
  258|    158|        {"carrierphase", t_real,     STRUCTOBJECT(struct meas_t, carrierphase),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  259|    158|                                     .dflt.real = NAN},
  260|    158|        {"pseudorange",  t_real,     STRUCTOBJECT(struct meas_t, pseudorange),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  261|    158|                                     .dflt.real = NAN},
  262|    158|        {"doppler",      t_real,     STRUCTOBJECT(struct meas_t, doppler),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  263|    158|                                     .dflt.real = NAN},
  264|    158|        {"c2c",          t_real,     STRUCTOBJECT(struct meas_t, c2c),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  265|    158|                                    .dflt.real = NAN},
  266|    158|        {"l2c",          t_real,     STRUCTOBJECT(struct meas_t, l2c),
  ------------------
  |  |  188|    158|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  267|    158|                                    .dflt.real = NAN},
  268|       |        // ignore unknown keys, for cross-version compatibility
  269|    158|        {"", t_ignore},
  270|       |        // *INDENT-ON*
  271|    158|        {NULL},
  272|    158|    };
  273|    158|    const struct json_attr_t json_attrs_raw[] = {
  274|       |        // *INDENT-OFF*
  275|    158|        {"class",      t_check,   .dflt.check = "RAW"},
  276|    158|        {"device",     t_string,  .addr.string  = gpsdata->dev.path,
  277|    158|                                    .len = sizeof(gpsdata->dev.path)},
  278|    158|        {"time",       t_real,    .addr.real = &mtime_s,
  279|    158|                                 .dflt.real = NAN},
  280|    158|        {"nsec",       t_real,    .addr.real = &mtime_ns,
  281|    158|                                 .dflt.real = NAN},
  282|    158|        {"rawdata",    t_array,   STRUCTARRAY(gpsdata->raw.meas,
  ------------------
  |  |  190|    158|        .addr.array.element_type = t_structobject, \
  |  |  191|    158|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    158|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    158|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    158|        .addr.array.count = n, \
  |  |  195|    158|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    158|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    158|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    158|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    158|            struct { \
  |  |  |  |  |  |   71|    158|                int unused_int; \
  |  |  |  |  |  |   72|    158|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    158|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    158|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    158|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    158|            }; \
  |  |  |  |  |  |   77|    158|            1; \
  |  |  |  |  |  |   78|    158|        })) \
  |  |  |  |  |  |   79|    158|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  283|    158|                                     json_attrs_meas, &measurements)},
  284|       |        // ignore unknown keys, for cross-version compatibility
  285|    158|        {"", t_ignore},
  286|    158|        {NULL},
  287|       |        // *INDENT-ON*
  288|    158|    };
  289|    158|    int status;
  290|       |
  291|    158|    memset(&gpsdata->raw, 0, sizeof(gpsdata->raw));
  292|       |
  293|    158|    status = json_read_object(buf, json_attrs_raw, endptr);
  294|    158|    if (0 != status) {
  ------------------
  |  Branch (294:9): [True: 126, False: 32]
  ------------------
  295|    126|        return status;
  296|    126|    }
  297|     32|    gpsdata->set |= RAW_SET;
  ------------------
  |  | 2916|     32|#define RAW_SET         (1llu<<39)
  ------------------
  298|     32|    if (0 == isfinite(mtime_s) ||
  ------------------
  |  Branch (298:9): [True: 30, False: 2]
  ------------------
  299|     31|        0 == isfinite(mtime_ns)) {
  ------------------
  |  Branch (299:9): [True: 1, False: 1]
  ------------------
  300|     31|        return status;
  301|     31|    }
  302|      1|    gpsdata->raw.mtime.tv_sec = (time_t)mtime_s;
  303|      1|    gpsdata->raw.mtime.tv_nsec = (long)mtime_ns;
  304|       |
  305|      1|    return 0;
  306|     32|}

strlcpy:
  275|  1.21k|{
  276|  1.21k|    size_t len = strlen(src);
  277|  1.21k|    if (0!= siz ) {
  ------------------
  |  Branch (277:9): [True: 1.21k, False: 0]
  ------------------
  278|  1.21k|        if (len >= siz) {
  ------------------
  |  Branch (278:13): [True: 194, False: 1.02k]
  ------------------
  279|    194|            memcpy(dst, src, siz - 1);
  280|    194|            dst[siz - 1] = '\0';
  281|  1.02k|        } else {
  282|  1.02k|            memcpy(dst, src, len + 1);
  283|  1.02k|        }
  284|  1.21k|    }
  285|  1.21k|    return len;
  286|  1.21k|}

json_rtcm2_read:
   32|    312|{
   33|       |
   34|       |    // Why are these static???
   35|    312|    static char *stringptrs[NITEMS(rtcm2->words)];
   36|    312|    static char stringstore[sizeof(rtcm2->words) * 2];
   37|    312|    static unsigned stringcount;
   38|       |
   39|       |// *INDENT-OFF*
   40|    312|#define RTCM2_HEADER \
   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
   43|    312|        {"device",         t_string,   .addr.string = path, \
   44|    312|                                          .len = pathlen}, \
   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
   47|    312|                                          .dflt.real = NAN}, \
   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
   51|       |
   52|    312|    int status = 0;
   53|    312|    unsigned satcount = 0;
   54|       |
   55|    312|    const struct json_attr_t rtcm1_satellite[] = {
   56|    312|        {"ident",     t_uinteger, STRUCTOBJECT(struct gps_rangesat_t, ident)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   57|    312|        {"udre",      t_uinteger, STRUCTOBJECT(struct gps_rangesat_t, udre)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   58|    312|        {"iod",       t_uinteger, STRUCTOBJECT(struct gps_rangesat_t, iod)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   59|    312|        {"prc",       t_real,     STRUCTOBJECT(struct gps_rangesat_t, prc)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   60|    312|        {"rrc",       t_real,     STRUCTOBJECT(struct gps_rangesat_t, rrc)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   61|    312|        {NULL},
   62|    312|    };
   63|    312|    const struct json_attr_t json_rtcm1[] = {
   64|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
   65|    312|        {"satellites", t_array, STRUCTARRAY(rtcm2->gps_ranges.sat,
  ------------------
  |  |  190|    312|        .addr.array.element_type = t_structobject, \
  |  |  191|    312|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    312|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    312|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    312|        .addr.array.count = n, \
  |  |  195|    312|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    312|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    312|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    312|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    312|            struct { \
  |  |  |  |  |  |   71|    312|                int unused_int; \
  |  |  |  |  |  |   72|    312|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    312|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    312|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    312|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    312|            }; \
  |  |  |  |  |  |   77|    312|            1; \
  |  |  |  |  |  |   78|    312|        })) \
  |  |  |  |  |  |   79|    312|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   66|    312|                                            rtcm1_satellite, &satcount)},
   67|    312|        {NULL},
   68|    312|    };
   69|       |
   70|    312|    const struct json_attr_t json_rtcm3[] = {
   71|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
   72|    312|        {"x",              t_real,    .addr.real = &rtcm2->ref_sta.x,
   73|    312|                                         .dflt.real = NAN},
   74|    312|        {"y",              t_real,    .addr.real = &rtcm2->ref_sta.y,
   75|    312|                                         .dflt.real = NAN},
   76|    312|        {"z",              t_real,    .addr.real = &rtcm2->ref_sta.z,
   77|    312|                                         .dflt.real = NAN},
   78|    312|        {NULL},
   79|    312|    };
   80|       |
   81|       |    /*
   82|       |     * Beware! Needs to stay synchronized with a corresponding
   83|       |     * name array in the RTCM2 JSON dump code. This interpretation of
   84|       |     * NAVSYSTEM_GALILEO is assumed from RTCM3, it's not actually
   85|       |     * documented in RTCM 2.1.
   86|       |     */
   87|    312|    const struct json_enum_t system_table[] = {
   88|    312|        {"GPS", 0}, {"GLONASS", 1}, {"GALILEO", 2}, {"UNKNOWN", 3}, {NULL}
   89|    312|    };
   90|    312|    const struct json_attr_t json_rtcm4[] = {
   91|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
   92|    312|        {"valid",          t_boolean, .addr.boolean = &rtcm2->reference.valid},
   93|    312|        {"system",         t_integer, .addr.integer = &rtcm2->reference.system,
   94|    312|                                         .map=system_table},
   95|    312|        {"sense",          t_integer, .addr.integer = &rtcm2->reference.sense},
   96|    312|        {"datum",          t_string,  .addr.string = rtcm2->reference.datum,
   97|    312|                                         .len = sizeof(rtcm2->reference.datum)},
   98|    312|        {"dx",             t_real,    .addr.real = &rtcm2->reference.dx,
   99|    312|                                         .dflt.real = NAN},
  100|    312|        {"dy",             t_real,    .addr.real = &rtcm2->reference.dy,
  101|    312|                                         .dflt.real = NAN},
  102|    312|        {"dz",             t_real,    .addr.real = &rtcm2->reference.dz,
  103|    312|                                         .dflt.real = NAN},
  104|    312|        {NULL},
  105|    312|    };
  106|       |
  107|    312|    const struct json_attr_t rtcm5_satellite[] = {
  108|    312|        {"ident",       t_uinteger, STRUCTOBJECT(struct consat_t, ident)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  109|    312|        {"iodl",        t_boolean,  STRUCTOBJECT(struct consat_t, iodl)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  110|    312|        {"health",      t_uinteger, STRUCTOBJECT(struct consat_t, health)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  111|    312|        {"snr",         t_integer,  STRUCTOBJECT(struct consat_t, snr)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  112|    312|        {"health_en",   t_boolean,  STRUCTOBJECT(struct consat_t, health_en)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  113|    312|        {"new_data",    t_boolean,  STRUCTOBJECT(struct consat_t, new_data)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  114|    312|        {"los_warning", t_boolean,  STRUCTOBJECT(struct consat_t, los_warning)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  115|    312|        {"tou",         t_uinteger, STRUCTOBJECT(struct consat_t, tou)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  116|    312|        {NULL},
  117|    312|    };
  118|    312|    const struct json_attr_t json_rtcm5[] = {
  119|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  120|    312|        {"satellites", t_array, STRUCTARRAY(rtcm2->conhealth.sat,
  ------------------
  |  |  190|    312|        .addr.array.element_type = t_structobject, \
  |  |  191|    312|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    312|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    312|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    312|        .addr.array.count = n, \
  |  |  195|    312|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    312|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    312|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    312|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    312|            struct { \
  |  |  |  |  |  |   71|    312|                int unused_int; \
  |  |  |  |  |  |   72|    312|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    312|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    312|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    312|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    312|            }; \
  |  |  |  |  |  |   77|    312|            1; \
  |  |  |  |  |  |   78|    312|        })) \
  |  |  |  |  |  |   79|    312|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  121|    312|                                            rtcm5_satellite, &satcount)},
  122|    312|        {NULL},
  123|    312|    };
  124|       |
  125|    312|    const struct json_attr_t json_rtcm6[] = {
  126|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  127|       |        // No-op or keepalive message
  128|    312|        {NULL},
  129|    312|    };
  130|       |
  131|    312|    const struct json_attr_t rtcm7_satellite[] = {
  132|    312|        {"lat",         t_real,     STRUCTOBJECT(struct station_t, latitude)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  133|    312|        {"lon",         t_real,     STRUCTOBJECT(struct station_t, longitude)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  134|    312|        {"range",       t_uinteger, STRUCTOBJECT(struct station_t, range)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  135|    312|        {"frequency",   t_real,     STRUCTOBJECT(struct station_t, frequency)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  136|    312|        {"health",      t_uinteger, STRUCTOBJECT(struct station_t, health)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  137|    312|        {"station_id",  t_uinteger, STRUCTOBJECT(struct station_t, station_id)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  138|    312|        {"bitrate",     t_uinteger, STRUCTOBJECT(struct station_t, bitrate)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  139|    312|        {NULL},
  140|    312|    };
  141|    312|    const struct json_attr_t json_rtcm7[] = {
  142|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  143|    312|        {"satellites", t_array, STRUCTARRAY(rtcm2->almanac.station,
  ------------------
  |  |  190|    312|        .addr.array.element_type = t_structobject, \
  |  |  191|    312|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    312|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    312|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    312|        .addr.array.count = n, \
  |  |  195|    312|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    312|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    312|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    312|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    312|            struct { \
  |  |  |  |  |  |   71|    312|                int unused_int; \
  |  |  |  |  |  |   72|    312|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    312|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    312|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    312|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    312|            }; \
  |  |  |  |  |  |   77|    312|            1; \
  |  |  |  |  |  |   78|    312|        })) \
  |  |  |  |  |  |   79|    312|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  144|    312|                                            rtcm7_satellite, &satcount)},
  145|    312|        {NULL},
  146|    312|    };
  147|       |
  148|    312|    const struct json_attr_t json_rtcm13[] = {
  149|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  150|    312|        {"status",       t_boolean,  .addr.boolean = &rtcm2->xmitter.status},
  151|    312|        {"rangeflag",    t_boolean,  .addr.boolean = &rtcm2->xmitter.rangeflag},
  152|    312|        {"lat",          t_real,     .addr.real = &rtcm2->xmitter.lat,
  153|    312|                                        .dflt.real = NAN},
  154|    312|        {"lon",          t_real,     .addr.real = &rtcm2->xmitter.lon,
  155|    312|                                        .dflt.real = NAN},
  156|    312|        {"range",        t_uinteger, .addr.uinteger = &rtcm2->xmitter.range},
  157|    312|        {NULL},
  158|    312|    };
  159|       |
  160|    312|    const struct json_attr_t json_rtcm14[] = {
  161|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  162|    312|        {"week",              t_uinteger,
  163|    312|                              .addr.uinteger = &rtcm2->gpstime.week},
  164|    312|        {"hour",              t_uinteger,
  165|    312|                              .addr.uinteger = &rtcm2->gpstime.hour},
  166|    312|        {"leapsecs",          t_uinteger,
  167|    312|                              .addr.uinteger = &rtcm2->gpstime.leapsecs},
  168|    312|        {NULL},
  169|    312|    };
  170|       |
  171|    312|    const struct json_attr_t json_rtcm16[] = {
  172|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  173|    312|        {"message",        t_string,  .addr.string = rtcm2->message,
  174|    312|                                         .len = sizeof(rtcm2->message)},
  175|    312|        {NULL},
  176|    312|    };
  177|       |
  178|    312|    const struct json_attr_t rtcm31_satellite[] = {
  179|    312|        {"ident",     t_uinteger,
  180|    312|                              STRUCTOBJECT(struct glonass_rangesat_t, ident)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  181|    312|        {"udre",      t_uinteger,
  182|    312|                              STRUCTOBJECT(struct glonass_rangesat_t, udre)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  183|    312|        {"change",    t_boolean,
  184|    312|                              STRUCTOBJECT(struct glonass_rangesat_t, change)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  185|    312|        {"tod",       t_uinteger, STRUCTOBJECT(struct glonass_rangesat_t, tod)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  186|    312|        {"prc",       t_real,     STRUCTOBJECT(struct glonass_rangesat_t, prc)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  187|    312|        {"rrc",       t_real,     STRUCTOBJECT(struct glonass_rangesat_t, rrc)},
  ------------------
  |  |  188|    312|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  188|    312|        {NULL},
  189|    312|    };
  190|    312|    const struct json_attr_t json_rtcm31[] = {
  191|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  192|    312|        {"satellites", t_array, STRUCTARRAY(rtcm2->glonass_ranges.sat,
  ------------------
  |  |  190|    312|        .addr.array.element_type = t_structobject, \
  |  |  191|    312|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    312|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    312|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    312|        .addr.array.count = n, \
  |  |  195|    312|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    312|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    312|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    312|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    312|            struct { \
  |  |  |  |  |  |   71|    312|                int unused_int; \
  |  |  |  |  |  |   72|    312|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    312|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    312|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    312|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    312|            }; \
  |  |  |  |  |  |   77|    312|            1; \
  |  |  |  |  |  |   78|    312|        })) \
  |  |  |  |  |  |   79|    312|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  193|    312|                                            rtcm31_satellite, &satcount)},
  194|    312|        {NULL},
  195|    312|    };
  196|       |
  197|    312|    const struct json_attr_t json_rtcm2_fallback[] = {
  198|    312|        RTCM2_HEADER
  ------------------
  |  |   41|    312|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    312|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    312|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    312|                                          .len = pathlen}, \
  |  |   45|    312|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    312|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    312|                                          .dflt.real = NAN}, \
  |  |   48|    312|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    312|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    312|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  199|    312|        {"data",         t_array, .addr.array.element_type = t_string,
  200|    312|                         .addr.array.arr.strings.ptrs = stringptrs,
  201|    312|                         .addr.array.arr.strings.store = stringstore,
  202|    312|                         .addr.array.arr.strings.storelen = sizeof(stringstore),
  203|    312|                         .addr.array.count = &stringcount,
  204|    312|                         .addr.array.maxlen = NITEMS(stringptrs)},
  ------------------
  |  | 1232|    312|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|    312|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|    312|        0 * (int) sizeof(({ \
  |  |  |  |   70|    312|            struct { \
  |  |  |  |   71|    312|                int unused_int; \
  |  |  |  |   72|    312|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|    312|            } zero_init = {0}; \
  |  |  |  |   74|    312|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|    312|                zero_init.unused_arr[0], \
  |  |  |  |   76|    312|            }; \
  |  |  |  |   77|    312|            1; \
  |  |  |  |   78|    312|        })) \
  |  |  |  |   79|    312|    )
  |  |  ------------------
  ------------------
  205|    312|        {NULL},
  206|    312|    };
  207|       |
  208|    312|#undef RTCM2_HEADER
  209|       |/* *INDENT-ON* */
  210|       |
  211|    312|    memset(rtcm2, '\0', sizeof(struct rtcm2_t));
  212|       |
  213|    312|    if (strstr(buf, "\"type\":1,") != NULL
  ------------------
  |  Branch (213:9): [True: 6, False: 306]
  ------------------
  214|    306|        || strstr(buf, "\"type\":9,") != NULL) {
  ------------------
  |  Branch (214:12): [True: 1, False: 305]
  ------------------
  215|      7|        status = json_read_object(buf, json_rtcm1, endptr);
  216|      7|        if (status == 0)
  ------------------
  |  Branch (216:13): [True: 1, False: 6]
  ------------------
  217|      1|            rtcm2->gps_ranges.nentries = (unsigned)satcount;
  218|    305|    } else if (strstr(buf, "\"type\":3,") != NULL) {
  ------------------
  |  Branch (218:16): [True: 80, False: 225]
  ------------------
  219|     80|        status = json_read_object(buf, json_rtcm3, endptr);
  220|     80|        if (status == 0) {
  ------------------
  |  Branch (220:13): [True: 75, False: 5]
  ------------------
  221|     75|            rtcm2->ref_sta.valid = (isfinite(rtcm2->ref_sta.x) != 0)
  ------------------
  |  Branch (221:36): [True: 28, False: 47]
  ------------------
  222|     28|                && (isfinite(rtcm2->ref_sta.y) != 0)
  ------------------
  |  Branch (222:20): [True: 20, False: 8]
  ------------------
  223|     20|                && (isfinite(rtcm2->ref_sta.z) != 0);
  ------------------
  |  Branch (223:20): [True: 2, False: 18]
  ------------------
  224|     75|        }
  225|    225|    } else if (strstr(buf, "\"type\":4,") != NULL) {
  ------------------
  |  Branch (225:16): [True: 89, False: 136]
  ------------------
  226|     89|        status = json_read_object(buf, json_rtcm4, endptr);
  227|     89|        if (status == 0)
  ------------------
  |  Branch (227:13): [True: 4, False: 85]
  ------------------
  228|      4|            rtcm2->reference.valid = (isfinite(rtcm2->reference.dx) != 0)
  ------------------
  |  Branch (228:38): [True: 2, False: 2]
  ------------------
  229|      2|                && (isfinite(rtcm2->reference.dy) != 0)
  ------------------
  |  Branch (229:20): [True: 1, False: 1]
  ------------------
  230|      1|                && (isfinite(rtcm2->reference.dz) != 0);
  ------------------
  |  Branch (230:20): [True: 0, False: 1]
  ------------------
  231|    136|    } else if (strstr(buf, "\"type\":5,") != NULL) {
  ------------------
  |  Branch (231:16): [True: 7, False: 129]
  ------------------
  232|      7|        status = json_read_object(buf, json_rtcm5, endptr);
  233|      7|        if (status == 0)
  ------------------
  |  Branch (233:13): [True: 1, False: 6]
  ------------------
  234|      1|            rtcm2->conhealth.nentries = (unsigned)satcount;
  235|    129|    } else if (strstr(buf, "\"type\":6,") != NULL) {
  ------------------
  |  Branch (235:16): [True: 1, False: 128]
  ------------------
  236|      1|        status = json_read_object(buf, json_rtcm6, endptr);
  237|    128|    } else if (strstr(buf, "\"type\":7,") != NULL) {
  ------------------
  |  Branch (237:16): [True: 5, False: 123]
  ------------------
  238|      5|        status = json_read_object(buf, json_rtcm7, endptr);
  239|      5|        if (status == 0)
  ------------------
  |  Branch (239:13): [True: 1, False: 4]
  ------------------
  240|      1|            rtcm2->almanac.nentries = (unsigned)satcount;
  241|    123|    } else if (strstr(buf, "\"type\":13,") != NULL) {
  ------------------
  |  Branch (241:16): [True: 1, False: 122]
  ------------------
  242|      1|        status = json_read_object(buf, json_rtcm13, endptr);
  243|    122|    } else if (strstr(buf, "\"type\":14,") != NULL) {
  ------------------
  |  Branch (243:16): [True: 1, False: 121]
  ------------------
  244|      1|        status = json_read_object(buf, json_rtcm14, endptr);
  245|    121|    } else if (strstr(buf, "\"type\":16,") != NULL) {
  ------------------
  |  Branch (245:16): [True: 2, False: 119]
  ------------------
  246|      2|        status = json_read_object(buf, json_rtcm16, endptr);
  247|    119|    } else if (strstr(buf, "\"type\":31,") != NULL) {
  ------------------
  |  Branch (247:16): [True: 5, False: 114]
  ------------------
  248|      5|        status = json_read_object(buf, json_rtcm31, endptr);
  249|      5|        if (status == 0)
  ------------------
  |  Branch (249:13): [True: 1, False: 4]
  ------------------
  250|      1|            rtcm2->glonass_ranges.nentries = (unsigned)satcount;
  251|    114|    } else {
  252|    114|        unsigned n;
  253|    114|        status = json_read_object(buf, json_rtcm2_fallback, endptr);
  254|  2.92k|        for (n = 0; n < NITEMS(rtcm2->words); n++) {
  ------------------
  |  | 1232|  2.92k|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|  2.92k|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|  2.92k|        0 * (int) sizeof(({ \
  |  |  |  |   70|  2.92k|            struct { \
  |  |  |  |   71|  2.92k|                int unused_int; \
  |  |  |  |   72|  2.92k|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|  2.92k|            } zero_init = {0}; \
  |  |  |  |   74|  2.92k|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|  2.92k|                zero_init.unused_arr[0], \
  |  |  |  |   76|  2.92k|            }; \
  |  |  |  |   77|  2.92k|            1; \
  |  |  |  |   78|  2.92k|        })) \
  |  |  |  |   79|  2.92k|    )
  |  |  ------------------
  ------------------
  |  Branch (254:21): [True: 2.83k, False: 90]
  ------------------
  255|  2.83k|            if (n >= stringcount) {
  ------------------
  |  Branch (255:17): [True: 2.64k, False: 186]
  ------------------
  256|  2.64k|                rtcm2->words[n] = 0;
  257|  2.64k|            } else {
  258|    186|                unsigned int u;
  259|    186|                int fldcount = sscanf(stringptrs[n], "0x%08x\n", &u);
  260|    186|                if (1 != fldcount) {
  ------------------
  |  Branch (260:21): [True: 24, False: 162]
  ------------------
  261|     24|                    return JSON_ERR_MISC;
  ------------------
  |  |  172|     24|#define JSON_ERR_MISC          21      // other data conversion error
  ------------------
  262|     24|                }  // else
  263|    162|                rtcm2->words[n] = (isgps30bits_t) u;
  264|    162|            }
  265|  2.83k|        }
  266|    114|    }
  267|    288|    return status;
  268|    312|}

json_rtcm3_read:
   29|    139|{
   30|       |    // why static??
   31|    139|    static char *stringptrs[NITEMS(rtcm3->rtcmtypes.data)];
   32|    139|    static char stringstore[sizeof(rtcm3->rtcmtypes.data) * 2];
   33|    139|    static unsigned stringcount;
   34|       |
   35|       |// *INDENT-OFF*
   36|    139|#define RTCM3_HEADER \
   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
   41|       |
   42|    139|    int status = 0;
   43|    139|    unsigned satcount = 0;
   44|       |
   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
   46|    139|    const struct json_attr_t rtcm1001_satellite[] = {
   47|    139|        {"ident",     t_uinteger, RTCM3FIELD(1001, ident)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   48|    139|        {"ind",       t_uinteger, RTCM3FIELD(1001, L1.indicator)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   49|    139|        {"prange",    t_real,     RTCM3FIELD(1001, L1.pseudorange)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   50|    139|        {"delta",     t_real,     RTCM3FIELD(1001, L1.rangediff)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   51|    139|        {"lockt",     t_uinteger, RTCM3FIELD(1001, L1.locktime)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   52|    139|        {NULL},
   53|    139|    };
   54|       |
   55|    139|    const struct json_attr_t rtcm1002_satellite[] = {
   56|    139|        {"ident",     t_uinteger, RTCM3FIELD(1002, ident)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   57|    139|        {"ind",       t_uinteger, RTCM3FIELD(1002, L1.indicator)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   58|    139|        {"prange",    t_real,     RTCM3FIELD(1002, L1.pseudorange)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   59|    139|        {"delta",     t_real,     RTCM3FIELD(1002, L1.rangediff)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   60|    139|        {"lockt",     t_uinteger, RTCM3FIELD(1002, L1.locktime)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   61|    139|        {"amb",       t_uinteger, RTCM3FIELD(1002, L1.ambiguity)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   62|    139|        {"CNR",       t_real,     RTCM3FIELD(1002, L1.CNR)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   63|    139|        {NULL},
   64|    139|    };
   65|       |
   66|    139|    const struct json_attr_t rtcm1009_satellite[] = {
   67|    139|        {"ident",     t_uinteger, RTCM3FIELD(1009, ident)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   68|    139|        {"ind",       t_uinteger, RTCM3FIELD(1009, L1.indicator)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   69|    139|        {"channel",   t_uinteger, RTCM3FIELD(1009, L1.channel)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   70|    139|        {"prange",    t_real,     RTCM3FIELD(1009, L1.pseudorange)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   71|    139|        {"delta",     t_real,     RTCM3FIELD(1009, L1.rangediff)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   72|    139|        {"lockt",     t_uinteger, RTCM3FIELD(1009, L1.locktime)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   73|    139|        {NULL},
   74|    139|    };
   75|       |
   76|    139|    const struct json_attr_t rtcm1010_satellite[] = {
   77|    139|        {"ident",     t_uinteger, RTCM3FIELD(1010, ident)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   78|    139|        {"ind",       t_uinteger, RTCM3FIELD(1010, L1.indicator)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   79|    139|        {"channel",   t_uinteger, RTCM3FIELD(1010, L1.channel)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   80|    139|        {"prange",    t_real,     RTCM3FIELD(1010, L1.pseudorange)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   81|    139|        {"delta",     t_real,     RTCM3FIELD(1010, L1.rangediff)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   82|    139|        {"lockt",     t_uinteger, RTCM3FIELD(1010, L1.locktime)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   83|    139|        {"amb",       t_uinteger, RTCM3FIELD(1010, L1.ambiguity)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   84|    139|        {"CNR",       t_real,     RTCM3FIELD(1010, L1.CNR)},
  ------------------
  |  |   45|    139|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    139|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   85|    139|        {NULL},
   86|    139|    };
   87|    139|#undef RTCM3FIELD
   88|       |
   89|    139|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
   90|    139|    const struct json_attr_t json_rtcm1001[] = {
   91|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
   92|    139|        {"station_id", t_uinteger, .addr.uinteger = R1001.station_id},
  ------------------
  |  |   89|    139|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   93|    139|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1001.tow},
  ------------------
  |  |   89|    139|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   94|    139|        {"sync",       t_boolean,  .addr.boolean = R1001.sync},
  ------------------
  |  |   89|    139|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   95|    139|        {"smoothing",  t_boolean,  .addr.boolean = R1001.smoothing},
  ------------------
  |  |   89|    139|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   96|    139|        {"interval",   t_uinteger, .addr.uinteger = R1001.interval},
  ------------------
  |  |   89|    139|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   97|    139|        {"satellites", t_array,
   98|    139|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1001.rtk_data,
  ------------------
  |  |  190|    139|        .addr.array.element_type = t_structobject, \
  |  |  191|    139|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    139|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    139|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    139|        .addr.array.count = n, \
  |  |  195|    139|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    139|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    139|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    139|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    139|            struct { \
  |  |  |  |  |  |   71|    139|                int unused_int; \
  |  |  |  |  |  |   72|    139|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    139|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    139|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    139|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    139|            }; \
  |  |  |  |  |  |   77|    139|            1; \
  |  |  |  |  |  |   78|    139|        })) \
  |  |  |  |  |  |   79|    139|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   99|    139|         rtcm1001_satellite, &satcount)},
  100|    139|        {NULL},
  101|    139|    };
  102|    139|#undef R1001
  103|       |
  104|    139|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  105|    139|    const struct json_attr_t json_rtcm1002[] = {
  106|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  107|    139|        {"station_id", t_uinteger, .addr.uinteger = R1002.station_id},
  ------------------
  |  |  104|    139|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  108|    139|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1002.tow},
  ------------------
  |  |  104|    139|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  109|    139|        {"sync",       t_boolean,  .addr.boolean = R1002.sync},
  ------------------
  |  |  104|    139|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  110|    139|        {"smoothing",  t_boolean,  .addr.boolean = R1002.smoothing},
  ------------------
  |  |  104|    139|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  111|    139|        {"interval",   t_uinteger, .addr.uinteger = R1002.interval},
  ------------------
  |  |  104|    139|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  112|    139|        {"satellites", t_array,
  113|    139|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1002.rtk_data,
  ------------------
  |  |  190|    139|        .addr.array.element_type = t_structobject, \
  |  |  191|    139|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    139|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    139|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    139|        .addr.array.count = n, \
  |  |  195|    139|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    139|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    139|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    139|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    139|            struct { \
  |  |  |  |  |  |   71|    139|                int unused_int; \
  |  |  |  |  |  |   72|    139|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    139|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    139|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    139|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    139|            }; \
  |  |  |  |  |  |   77|    139|            1; \
  |  |  |  |  |  |   78|    139|        })) \
  |  |  |  |  |  |   79|    139|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  114|    139|         rtcm1002_satellite, &satcount)},
  115|    139|        {NULL},
  116|    139|    };
  117|    139|#undef R1002
  118|       |
  119|    139|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  120|    139|    const struct json_attr_t json_rtcm1007[] = {
  121|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  122|    139|        {"station_id", t_uinteger, .addr.uinteger = &R1007.station_id},
  ------------------
  |  |  119|    139|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  123|    139|        {"desc",       t_string,   .addr.string = R1007.descriptor,
  ------------------
  |  |  119|    139|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  124|    139|                                         .len = sizeof(R1007.descriptor)},
  ------------------
  |  |  119|    139|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  125|    139|        {"setup_id",   t_uinteger, .addr.uinteger = &R1007.setup_id},
  ------------------
  |  |  119|    139|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  126|    139|        {NULL},
  127|    139|    };
  128|    139|#undef R1002
  129|       |
  130|    139|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  131|    139|    const struct json_attr_t json_rtcm1008[] = {
  132|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  133|    139|        {"station_id", t_uinteger, .addr.uinteger = &R1008.station_id},
  ------------------
  |  |  130|    139|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  134|    139|        {"desc",       t_string,   .addr.string = R1008.descriptor,
  ------------------
  |  |  130|    139|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  135|    139|                                         .len = sizeof(R1008.descriptor)},
  ------------------
  |  |  130|    139|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  136|    139|        {"setup_id",   t_uinteger, .addr.uinteger = &R1008.setup_id},
  ------------------
  |  |  130|    139|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  137|    139|        {"serial",     t_string,   .addr.string = R1008.serial,
  ------------------
  |  |  130|    139|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  138|    139|                                         .len = sizeof(R1008.serial)},
  ------------------
  |  |  130|    139|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  139|    139|        {NULL},
  140|    139|    };
  141|    139|#undef R1008
  142|       |
  143|    139|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  144|    139|    const struct json_attr_t json_rtcm1009[] = {
  145|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  146|    139|        {"station_id", t_uinteger, .addr.uinteger = R1009.station_id},
  ------------------
  |  |  143|    139|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  147|    139|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1009.tow},
  ------------------
  |  |  143|    139|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  148|    139|        {"sync",       t_boolean,  .addr.boolean = R1009.sync},
  ------------------
  |  |  143|    139|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  149|    139|        {"smoothing",  t_boolean,  .addr.boolean = R1009.smoothing},
  ------------------
  |  |  143|    139|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  150|    139|        {"interval",   t_uinteger, .addr.uinteger = R1009.interval},
  ------------------
  |  |  143|    139|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  151|    139|        {"satellites", t_array,
  152|    139|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1009.rtk_data,
  ------------------
  |  |  190|    139|        .addr.array.element_type = t_structobject, \
  |  |  191|    139|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    139|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    139|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    139|        .addr.array.count = n, \
  |  |  195|    139|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    139|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    139|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    139|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    139|            struct { \
  |  |  |  |  |  |   71|    139|                int unused_int; \
  |  |  |  |  |  |   72|    139|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    139|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    139|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    139|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    139|            }; \
  |  |  |  |  |  |   77|    139|            1; \
  |  |  |  |  |  |   78|    139|        })) \
  |  |  |  |  |  |   79|    139|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  153|    139|         rtcm1009_satellite, &satcount)},
  154|    139|        {NULL},
  155|    139|    };
  156|    139|#undef R1010
  157|       |
  158|    139|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  159|    139|    const struct json_attr_t json_rtcm1010[] = {
  160|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  161|    139|        {"station_id", t_uinteger, .addr.uinteger = R1010.station_id},
  ------------------
  |  |  158|    139|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  162|    139|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1010.tow},
  ------------------
  |  |  158|    139|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  163|    139|        {"sync",       t_boolean,  .addr.boolean = R1010.sync},
  ------------------
  |  |  158|    139|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  164|    139|        {"smoothing",  t_boolean,  .addr.boolean = R1010.smoothing},
  ------------------
  |  |  158|    139|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  165|    139|        {"interval",   t_uinteger, .addr.uinteger = R1010.interval},
  ------------------
  |  |  158|    139|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  166|    139|        {"satellites", t_array,
  167|    139|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1010.rtk_data,
  ------------------
  |  |  190|    139|        .addr.array.element_type = t_structobject, \
  |  |  191|    139|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    139|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    139|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    139|        .addr.array.count = n, \
  |  |  195|    139|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1232|    139|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    139|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    139|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    139|            struct { \
  |  |  |  |  |  |   71|    139|                int unused_int; \
  |  |  |  |  |  |   72|    139|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    139|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    139|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    139|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    139|            }; \
  |  |  |  |  |  |   77|    139|            1; \
  |  |  |  |  |  |   78|    139|        })) \
  |  |  |  |  |  |   79|    139|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  168|    139|         rtcm1010_satellite, &satcount)},
  169|    139|        {NULL},
  170|    139|    };
  171|    139|#undef R1010
  172|       |
  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  174|    139|    const struct json_attr_t json_rtcm1014[] = {
  175|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  176|    139|        {"netid",      t_uinteger, .addr.uinteger = R1014.network_id},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  177|    139|        {"subnetid",   t_uinteger, .addr.uinteger = R1014.subnetwork_id},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  178|    139|        {"statcount",  t_uinteger, .addr.uinteger = R1014.stationcount},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  179|    139|        {"master",     t_uinteger, .addr.uinteger = R1014.master_id},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  180|    139|        {"aux",        t_uinteger, .addr.uinteger = R1014.aux_id},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  181|    139|        {"lat",        t_real,     .addr.real = R1014.d_lat},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  182|    139|        {"lon",        t_real,     .addr.real = R1014.d_lon},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  183|    139|        {"alt",        t_real,     .addr.real = R1014.d_alt},
  ------------------
  |  |  173|    139|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  184|    139|        {NULL},
  185|    139|    };
  186|    139|#undef R1014
  187|       |
  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  189|    139|    const struct json_attr_t json_rtcm1033[] = {
  190|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  191|    139|        {"station_id", t_uinteger, .addr.uinteger = &R1033.station_id},
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  192|    139|        {"desc",       t_string,   .addr.string = R1033.descriptor,
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  193|    139|                                         .len = sizeof(R1033.descriptor)},
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  194|    139|        {"setup_id",   t_uinteger, .addr.uinteger = &R1033.setup_id},
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  195|    139|        {"serial",     t_string,   .addr.string = R1033.serial,
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  196|    139|                                         .len = sizeof(R1033.serial)},
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  197|    139|        {"receiver",   t_string,   .addr.string = R1033.receiver,
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  198|    139|                                         .len = sizeof(R1033.receiver)},
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  199|    139|        {"firmware",   t_string,   .addr.string = R1033.firmware,
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  200|    139|                                         .len = sizeof(R1033.firmware)},
  ------------------
  |  |  188|    139|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  201|    139|        {NULL},
  202|    139|    };
  203|    139|#undef R1033
  204|       |
  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  206|    139|    const struct json_attr_t json_rtcm1230[] = {
  207|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  208|    139|        {"station_id", t_uinteger, .addr.uinteger = &R1230.station_id},
  ------------------
  |  |  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  209|    139|        {"ind",        t_ubyte,    .addr.ubyte = &R1230.bias_indicator},
  ------------------
  |  |  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  210|    139|        {"sm",         t_ubyte,    .addr.ubyte = &R1230.signals_mask},
  ------------------
  |  |  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  211|    139|        {"l1_ca",      t_integer,  .addr.integer = &R1230.l1_ca_bias,
  ------------------
  |  |  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  212|    139|                                   .dflt.integer = 0},
  213|    139|        {"l1p",        t_integer,  .addr.integer = &R1230.l1_p_bias,
  ------------------
  |  |  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  214|    139|                                   .dflt.integer = 0},
  215|    139|        {"l2ca",       t_integer,  .addr.integer = &R1230.l2_ca_bias,
  ------------------
  |  |  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  216|    139|                                   .dflt.integer = 0},
  217|    139|        {"l2p",        t_integer,  .addr.integer = &R1230.l2_p_bias,
  ------------------
  |  |  205|    139|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  218|    139|                                   .dflt.integer = 0},
  219|    139|        {NULL},
  220|    139|    };
  221|    139|#undef R1033
  222|       |
  223|    139|    const struct json_attr_t json_rtcm3_fallback[] = {
  224|    139|        RTCM3_HEADER
  ------------------
  |  |   37|    139|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   38|    139|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   39|    139|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   40|    139|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  225|    139|        {"data", t_array, .addr.array.element_type = t_string,
  226|    139|                          .addr.array.arr.strings.ptrs = stringptrs,
  227|    139|                          .addr.array.arr.strings.store = stringstore,
  228|    139|                         .addr.array.arr.strings.storelen = sizeof(stringstore),
  229|    139|                          .addr.array.count = &stringcount,
  230|    139|                          .addr.array.maxlen = NITEMS(stringptrs)},
  ------------------
  |  | 1232|    139|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|    139|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|    139|        0 * (int) sizeof(({ \
  |  |  |  |   70|    139|            struct { \
  |  |  |  |   71|    139|                int unused_int; \
  |  |  |  |   72|    139|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|    139|            } zero_init = {0}; \
  |  |  |  |   74|    139|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|    139|                zero_init.unused_arr[0], \
  |  |  |  |   76|    139|            }; \
  |  |  |  |   77|    139|            1; \
  |  |  |  |   78|    139|        })) \
  |  |  |  |   79|    139|    )
  |  |  ------------------
  ------------------
  231|       |        // ignore unknown keys
  232|    139|        {"", t_ignore},
  233|       |
  234|    139|        {NULL},
  235|    139|    };
  236|       |
  237|    139|#undef RTCM3_HEADER
  238|       |// *INDENT-ON*
  239|       |
  240|    139|    memset(rtcm3, '\0', sizeof(struct rtcm3_t));
  241|       |
  242|    139|    if (strstr(buf, "\"type\":1001,") != NULL) {
  ------------------
  |  Branch (242:9): [True: 5, False: 134]
  ------------------
  243|      5|        status = json_read_object(buf, json_rtcm1001, endptr);
  244|      5|        if (0 == status) {
  ------------------
  |  Branch (244:13): [True: 1, False: 4]
  ------------------
  245|      1|            rtcm3->rtcmtypes.rtcm3_1001.header.satcount =
  246|      1|                (unsigned short)satcount;
  247|      1|        }
  248|    134|    } else if (NULL != strstr(buf, "\"type\":1002,")) {
  ------------------
  |  Branch (248:16): [True: 6, False: 128]
  ------------------
  249|      6|        status = json_read_object(buf, json_rtcm1002, endptr);
  250|      6|        if (0 == status) {
  ------------------
  |  Branch (250:13): [True: 1, False: 5]
  ------------------
  251|      1|            rtcm3->rtcmtypes.rtcm3_1002.header.satcount =
  252|      1|               (unsigned short)satcount;
  253|      1|        }
  254|    128|    } else if (NULL != strstr(buf, "\"type\":1007,")) {
  ------------------
  |  Branch (254:16): [True: 1, False: 127]
  ------------------
  255|      1|        status = json_read_object(buf, json_rtcm1007, endptr);
  256|    127|    } else if (NULL != strstr(buf, "\"type\":1008,")) {
  ------------------
  |  Branch (256:16): [True: 1, False: 126]
  ------------------
  257|      1|        status = json_read_object(buf, json_rtcm1008, endptr);
  258|    126|    } else if (NULL != strstr(buf, "\"type\":1009,")) {
  ------------------
  |  Branch (258:16): [True: 1, False: 125]
  ------------------
  259|      1|        status = json_read_object(buf, json_rtcm1009, endptr);
  260|    125|    } else if (NULL != strstr(buf, "\"type\":1010,")) {
  ------------------
  |  Branch (260:16): [True: 1, False: 124]
  ------------------
  261|      1|        status = json_read_object(buf, json_rtcm1010, endptr);
  262|    124|    } else if (NULL != strstr(buf, "\"type\":1014,")) {
  ------------------
  |  Branch (262:16): [True: 1, False: 123]
  ------------------
  263|      1|        status = json_read_object(buf, json_rtcm1014, endptr);
  264|    123|    } else if (NULL != strstr(buf, "\"type\":1033,")) {
  ------------------
  |  Branch (264:16): [True: 1, False: 122]
  ------------------
  265|      1|        status = json_read_object(buf, json_rtcm1033, endptr);
  266|    122|    } else if (NULL != strstr(buf, "\"type\":1230,")) {
  ------------------
  |  Branch (266:16): [True: 23, False: 99]
  ------------------
  267|     23|        status = json_read_object(buf, json_rtcm1230, endptr);
  268|     99|    } else {
  269|       |        // a type we don't decode yet, grabe just the header.
  270|     99|        unsigned n;
  271|     99|        status = json_read_object(buf, json_rtcm3_fallback, endptr);
  272|  70.8k|        for (n = 0; n < NITEMS(rtcm3->rtcmtypes.data); n++) {
  ------------------
  |  | 1232|  70.8k|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|  70.8k|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|  70.8k|        0 * (int) sizeof(({ \
  |  |  |  |   70|  70.8k|            struct { \
  |  |  |  |   71|  70.8k|                int unused_int; \
  |  |  |  |   72|  70.8k|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|  70.8k|            } zero_init = {0}; \
  |  |  |  |   74|  70.8k|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|  70.8k|                zero_init.unused_arr[0], \
  |  |  |  |   76|  70.8k|            }; \
  |  |  |  |   77|  70.8k|            1; \
  |  |  |  |   78|  70.8k|        })) \
  |  |  |  |   79|  70.8k|    )
  |  |  ------------------
  ------------------
  |  Branch (272:21): [True: 70.7k, False: 69]
  ------------------
  273|  70.7k|            if (n >= stringcount) {
  ------------------
  |  Branch (273:17): [True: 68.7k, False: 2.02k]
  ------------------
  274|  68.7k|                rtcm3->rtcmtypes.data[n] = '\0';
  275|  68.7k|            } else {
  276|  2.02k|                unsigned int u;
  277|  2.02k|                int fldcount = sscanf(stringptrs[n], "0x%02x\n", &u);
  278|  2.02k|                if (fldcount != 1) {
  ------------------
  |  Branch (278:21): [True: 30, False: 1.99k]
  ------------------
  279|     30|                    return JSON_ERR_MISC;
  ------------------
  |  |  172|     30|#define JSON_ERR_MISC          21      // other data conversion error
  ------------------
  280|     30|                } // else
  281|  1.99k|                rtcm3->rtcmtypes.data[n] = (char)u;
  282|  1.99k|            }
  283|  70.7k|        }
  284|     99|    }
  285|    109|    return status;
  286|    139|}

json_device_read:
   31|     21|{
   32|       |    // initialized to shut up clang
   33|     21|    double d_cycle = 0.0, d_mincycle = 0.0;
   34|       |
   35|       |    // *INDENT-OFF*
   36|     21|    const struct json_attr_t json_attrs_device[] = {
   37|     21|        {"class",      t_check,      .dflt.check = "DEVICE"},
   38|       |
   39|     21|        {"path",       t_string,     .addr.string  = dev->path,
   40|     21|                                        .len = sizeof(dev->path)},
   41|       |        // odd, device->gpsdata.online is sent, but put in dev->activated?
   42|     21|        {"activated",  t_time,       .addr.ts = &dev->activated,
   43|     21|                                        .dflt.ts = {0, 0}},
   44|     21|        {"flags",      t_integer,    .addr.integer = &dev->flags},
   45|     21|        {"driver",     t_string,     .addr.string  = dev->driver,
   46|     21|                                        .len = sizeof(dev->driver)},
   47|     21|        {"sernum",     t_string,     .addr.string  = dev->sernum,
   48|     21|                                        .len = sizeof(dev->sernum)},
   49|     21|        {"subtype",    t_string,     .addr.string  = dev->subtype,
   50|     21|                                        .len = sizeof(dev->subtype)},
   51|     21|        {"subtype1",   t_string,     .addr.string  = dev->subtype1,
   52|     21|                                        .len = sizeof(dev->subtype1)},
   53|     21|        {"hexdata",    t_string,     .addr.string  = dev->hexdata,
   54|     21|                                        .len = sizeof(dev->hexdata)},
   55|     21|        {"native",     t_integer,    .addr.integer = &dev->driver_mode,
   56|     21|                                        .dflt.integer = DEVDEFAULT_NATIVE},
  ------------------
  |  |   52|     21|#define DEVDEFAULT_NATIVE       -1
  ------------------
   57|     21|        {"bps",        t_uinteger,   .addr.uinteger = &dev->baudrate,
   58|     21|                                        .dflt.uinteger = DEVDEFAULT_BPS},
  ------------------
  |  |   49|     21|#define DEVDEFAULT_BPS          0
  ------------------
   59|     21|        {"parity",     t_character,  .addr.character = &dev->parity,
   60|     21|                                        .dflt.character = DEVDEFAULT_PARITY},
  ------------------
  |  |   50|     21|#define DEVDEFAULT_PARITY       'X'
  ------------------
   61|     21|        {"stopbits",   t_uinteger,   .addr.uinteger = &dev->stopbits,
   62|     21|                                        .dflt.uinteger = DEVDEFAULT_STOPBITS},
  ------------------
  |  |   51|     21|#define DEVDEFAULT_STOPBITS     3
  ------------------
   63|     21|        {"cycle",      t_real,       .addr.real = &d_cycle,
   64|     21|                                        .dflt.real = NAN},
   65|     21|        {"mincycle",   t_real,       .addr.real = &d_mincycle,
   66|     21|                                        .dflt.real = NAN},
   67|       |        // ignore unknown keys, for cross-version compatibility
   68|     21|        {"", t_ignore},
   69|     21|        {NULL},
   70|     21|    };
   71|       |    // *INDENT-ON*
   72|     21|    int status;
   73|       |
   74|     21|    status = json_read_object(buf, json_attrs_device, endptr);
   75|     21|    if (0 != status) {
  ------------------
  |  Branch (75:9): [True: 16, False: 5]
  ------------------
   76|     16|        return status;
   77|     16|    }
   78|       |
   79|      5|    if (0 == isfinite(d_cycle)) {
  ------------------
  |  Branch (79:9): [True: 4, False: 1]
  ------------------
   80|      4|        dev->cycle.tv_sec = 0;
   81|      4|        dev->cycle.tv_nsec = 0;
   82|      4|    } else {
   83|      1|        DTOTS(&dev->cycle, d_cycle);
  ------------------
  |  |  144|      1|    do { \
  |  |  145|      1|        double int_part; \
  |  |  146|      1|        (ts)->tv_nsec = (long)(modf(d, &int_part) * 1e9); \
  |  |  147|      1|        (ts)->tv_sec = (time_t)int_part; \
  |  |  148|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (148:14): [Folded, False: 1]
  |  |  ------------------
  ------------------
   84|      1|    }
   85|      5|    if (0 == isfinite(d_mincycle)) {
  ------------------
  |  Branch (85:9): [True: 4, False: 1]
  ------------------
   86|      4|        dev->mincycle.tv_sec = 0;
   87|      4|        dev->mincycle.tv_nsec = 0;
   88|      4|    } else {
   89|      1|        DTOTS(&dev->mincycle, d_mincycle);
  ------------------
  |  |  144|      1|    do { \
  |  |  145|      1|        double int_part; \
  |  |  146|      1|        (ts)->tv_nsec = (long)(modf(d, &int_part) * 1e9); \
  |  |  147|      1|        (ts)->tv_sec = (time_t)int_part; \
  |  |  148|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (148:14): [Folded, False: 1]
  |  |  ------------------
  ------------------
   90|      1|    }
   91|       |
   92|      5|    return 0;
   93|     21|}
json_watch_read:
   98|     54|{
   99|       |    // *INDENT-OFF*
  100|     54|    struct json_attr_t chanconfig_attrs[] = {
  101|     54|        {"class",          t_check,    .dflt.check = "WATCH"},
  102|       |
  103|     54|        {"device",         t_string,   .addr.string = ccp->devpath,
  104|     54|                                          .len = sizeof(ccp->devpath)},
  105|     54|        {"enable",         t_boolean,  .addr.boolean = &ccp->watcher,
  106|     54|                                          .dflt.boolean = true},
  107|     54|        {"json",           t_boolean,  .addr.boolean = &ccp->json,
  108|     54|                                          .nodefault = true},
  109|     54|        {"nmea",           t_boolean,  .addr.boolean = &ccp->nmea,
  110|     54|                                          .nodefault = true},
  111|     54|        {"pps",            t_boolean,  .addr.boolean = &ccp->pps},
  112|     54|        {"raw",            t_integer,  .addr.integer = &ccp->raw,
  113|     54|                                          .nodefault = true},
  114|     54|        {"remote",         t_string,   .addr.string = ccp->remote,
  115|     54|                                          .len = sizeof(ccp->remote)},
  116|     54|        {"scaled",         t_boolean,  .addr.boolean = &ccp->scaled},
  117|     54|        {"split24",        t_boolean,  .addr.boolean = &ccp->split24},
  118|     54|        {"timing",         t_boolean,  .addr.boolean = &ccp->timing},
  119|       |        // ignore unknown keys, for cross-version compatibility
  120|     54|        {"", t_ignore},
  121|     54|        {NULL},
  122|     54|    };
  123|       |    // *INDENT-ON*
  124|     54|    int status;
  125|       |
  126|     54|    status = json_read_object(buf, chanconfig_attrs, endptr);
  127|     54|    return status;
  128|     54|}

