1#!/usr/local/bin/python3.8 2# 3# This file is Copyright (c) 2010 by the GPSD project 4# SPDX-License-Identifier: BSD-2-clause 5# 6# Never hand-hack what you can generate... 7# 8# This code generates template declarations for AIS-JSON parsing from a 9# declarative specification of a JSON structure. 10# 11# This code runs compatibly under Python 2 and 3.x for x >= 2. 12# Preserve this property! 13from __future__ import absolute_import, print_function, division 14 15import getopt 16import sys 17 18# 19# Here is the information that makes it all work - attribute, type, and 20# defult information for all fields. We generate a JSON 21# parser template spec. Doing it this way guarantees consistency. 22# 23# Notes on the fields: 24# initname: becomes the name of the generated structure initializer 25# header: common header to include in front of the structure template 26# structname: gets prepended to all fieldnames in the generated C 27# fieldmap: each member fills an initializer slot 28# stringbuffered: list strings that should be buffered rather than copied 29# directly into the structure. 30 31ais_specs = ( 32 { 33 "initname": "json_ais1", 34 "headers": ("AIS_HEADER",), 35 "structname": "ais->type1", 36 "fieldmap": ( 37 # fieldname type default 38 ('status', 'uinteger', '0'), 39 ('status_text', 'ignore', None), 40 ('turn', 'integer', 'AIS_TURN_NOT_AVAILABLE'), 41 ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), 42 ('accuracy', 'boolean', 'false'), 43 ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), 44 ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), 45 ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), 46 ('heading', 'uinteger', 'AIS_HEADING_NOT_AVAILABLE'), 47 ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), 48 ('maneuver', 'uinteger', 'AIS_SEC_INOPERATIVE'), 49 ('raim', 'boolean', 'false'), 50 ('radio', 'uinteger', '0'), 51 ), 52 }, 53 # Message types 2 and 3 duplicate 1 54 { 55 "initname": "json_ais4", 56 "headers": ("AIS_HEADER",), 57 "structname": "ais->type4", 58 "fieldmap": ( 59 # fieldname type default 60 ('timestamp', 'string', None), 61 ('accuracy', 'boolean', "true"), 62 ('lon', 'integer', "AIS_LON_NOT_AVAILABLE"), 63 ('lat', 'integer', "AIS_LAT_NOT_AVAILABLE"), 64 ('epfd', 'uinteger', "0"), 65 ('epfd_text', 'ignore', None), 66 ('raim', 'boolean', "false"), 67 ('radio', 'uinteger', "0"), 68 ), 69 "stringbuffered": ("timestamp",), 70 }, 71 { 72 "initname": "json_ais5", 73 "headers": ("AIS_HEADER",), 74 "structname": "ais->type5", 75 "fieldmap": ( 76 # fieldname type default 77 ('imo', 'uinteger', '0'), 78 ('ais_version', 'uinteger', '0'), 79 ('callsign', 'string', None), 80 ('shipname', 'string', None), 81 ('shiptype', 'uinteger', '0'), 82 ('shiptype_text', 'ignore', None), 83 ('to_bow', 'uinteger', '0'), 84 ('to_stern', 'uinteger', '0'), 85 ('to_port', 'uinteger', '0'), 86 ('to_starboard', 'uinteger', '0'), 87 ('epfd', 'uinteger', '0'), 88 ('epfd_text', 'ignore', None), 89 ('eta', 'string', None), 90 ('draught', 'uinteger', '0'), 91 ('destination', 'string', None), 92 ('dte', 'uinteger', '1'), 93 ), 94 "stringbuffered": ("eta",), 95 }, 96 { 97 "initname": "json_ais6", 98 "headers": ("AIS_HEADER", "AIS_TYPE6",), 99 "structname": "ais->type6", 100 "fieldmap": ( 101 # fieldname type default 102 ('data', 'string', None), 103 ), 104 "stringbuffered": ("data",), 105 }, 106 { 107 "initname": "json_ais6_fid10", 108 "headers": ("AIS_HEADER", "AIS_TYPE6",), 109 "structname": "ais->type6.dac235fid10", 110 "fieldmap": ( 111 # fieldname type default 112 ('ana_int', 'uinteger', '0'), 113 ('ana_ext1', 'uinteger', '0'), 114 ('ana_ext2', 'uinteger', '0'), 115 ('racon', 'uinteger', '0'), 116 ('racon_text', 'ignore', None), 117 ('light', 'uinteger', '0'), 118 ('light_text', 'ignore', None), 119 ('alarm', 'boolean', 'false'), 120 ('stat_ext', 'uinteger', '0'), 121 ('off_pos', 'boolean', 'false'), 122 ), 123 }, 124 { 125 "initname": "json_ais6_fid12", 126 "headers": ("AIS_HEADER", "AIS_TYPE6",), 127 "structname": "ais->type6.dac1fid12", 128 "fieldmap": ( 129 # fieldname type default 130 ('lastport', 'string', None), 131 ('departure', 'string', None), 132 ('nextport', 'string', None), 133 ('eta', 'string', None), 134 ('dangerous', 'string', None), 135 ('imdcat', 'string', None), 136 ('unid', 'uinteger', '0'), 137 ('amount', 'uinteger', '0'), 138 ('unit', 'uinteger', '0'), 139 ), 140 "stringbuffered": ("departure", "eta",), 141 }, 142 { 143 "initname": "json_ais6_fid15", 144 "headers": ("AIS_HEADER", "AIS_TYPE6",), 145 "structname": "ais->type6.dac1fid15", 146 "fieldmap": ( 147 # fieldname type default 148 ('airdraught', 'uinteger', '0'), 149 ), 150 }, 151 { 152 "initname": "json_ais6_fid16", 153 "headers": ("AIS_HEADER", "AIS_TYPE6",), 154 "structname": "ais->type6.dac1fid16", 155 "fieldmap": ( 156 # fieldname type default 157 ('persons', 'uinteger', '0'), 158 ), 159 }, 160 { 161 "initname": "json_ais6_fid18", 162 "headers": ("AIS_HEADER", "AIS_TYPE6",), 163 "structname": "ais->type6.dac1fid18", 164 "fieldmap": ( 165 # fieldname type default 166 ('linkage', 'uinteger', '0'), 167 ('arrival', 'string', None), 168 ('portname', 'string', None), 169 ('destination', 'string', None), 170 ('lon', 'integer', 'AIS_LON3_NOT_AVAILABLE'), 171 ('lat', 'integer', 'AIS_LAT3_NOT_AVAILABLE'), 172 ), 173 'stringbuffered': ('arrival',), 174 }, 175 { 176 "initname": "json_ais6_fid20", 177 "headers": ("AIS_HEADER", "AIS_TYPE6",), 178 "structname": "ais->type6.dac1fid20", 179 "fieldmap": ( 180 # fieldname type default 181 ('linkage', 'uinteger', '0'), 182 ('berth_length', 'uinteger', '0'), 183 ('berth_depth', 'uinteger', '0'), 184 ('position', 'uinteger', '0'), 185 ('position_text', 'ignore', None), 186 ('arrival', 'string', None), 187 ('availability', 'uinteger', '0'), 188 ('agent', 'uinteger', '0'), 189 ('fuel', 'uinteger', '0'), 190 ('chandler', 'uinteger', '0'), 191 ('stevedore', 'uinteger', '0'), 192 ('electrical', 'uinteger', '0'), 193 ('water', 'uinteger', '0'), 194 ('customs', 'uinteger', '0'), 195 ('cartage', 'uinteger', '0'), 196 ('crane', 'uinteger', '0'), 197 ('lift', 'uinteger', '0'), 198 ('medical', 'uinteger', '0'), 199 ('navrepair', 'uinteger', '0'), 200 ('provisions', 'uinteger', '0'), 201 ('shiprepair', 'uinteger', '0'), 202 ('surveyor', 'uinteger', '0'), 203 ('steam', 'uinteger', '0'), 204 ('tugs', 'uinteger', '0'), 205 ('solidwaste', 'uinteger', '0'), 206 ('liquidwaste', 'uinteger', '0'), 207 ('hazardouswaste', 'uinteger', '0'), 208 ('ballast', 'uinteger', '0'), 209 ('additional', 'uinteger', '0'), 210 ('regional1', 'uinteger', '0'), 211 ('regional2', 'uinteger', '0'), 212 ('future1', 'uinteger', '0'), 213 ('future2', 'uinteger', '0'), 214 ('berth_name', 'string', None), 215 ('berth_lon', 'integer', 'AIS_LON3_NOT_AVAILABLE'), 216 ('berth_lat', 'integer', 'AIS_LAT3_NOT_AVAILABLE'), 217 ), 218 'stringbuffered': ('arrival', 'berth_name',), 219 }, 220 { 221 "initname": "json_ais6_fid21", 222 "headers": ("AIS_HEADER", "AIS_TYPE6"), 223 "structname": "ais->type6.dac200fid21", 224 "fieldmap": ( 225 # fieldname type default 226 ('country', 'string', None), 227 ('locode', 'string', None), 228 ('section', 'string', None), 229 ('terminal', 'string', None), 230 ('hectometre', 'string', None), 231 ('eta', 'string', None), 232 ('tugs', 'uinteger', '0'), 233 ('airdraught', 'uinteger', '0'), 234 ), 235 "stringbuffered": ("eta",), 236 }, 237 { 238 "initname": "json_ais6_fid22", 239 "headers": ("AIS_HEADER", "AIS_TYPE6"), 240 "structname": "ais->type6.dac200fid22", 241 "fieldmap": ( 242 # fieldname type default 243 ('country', 'string', None), 244 ('locode', 'string', None), 245 ('section', 'string', None), 246 ('terminal', 'string', None), 247 ('hectometre', 'string', None), 248 ('rta', 'string', None), 249 ('status', 'uinteger', 'DAC200FID22_STATUS_NOT_AVAILABLE'), 250 ), 251 "stringbuffered": ("rta",), 252 }, 253 { 254 "initname": "json_ais6_fid25", 255 "headers": ("AIS_HEADER", "AIS_TYPE6",), 256 "structname": "ais->type6.dac1fid25", 257 "fieldmap": ( 258 # fieldname type default 259 ('unit', 'uinteger', '0'), 260 ('amount', 'uinteger', '0'), 261 ('cargos', 'array', ( 262 ('cargo_t', 'ncargos', ( 263 ('code', 'uinteger', '0'), 264 ('subtype', 'uinteger', '0'), 265 )))), 266 ), 267 }, 268 { 269 "initname": "json_ais6_fid28", 270 "headers": ("AIS_HEADER", "AIS_TYPE6",), 271 "structname": "ais->type6.dac1fid28", 272 "fieldmap": ( 273 # fieldname type default 274 ('linkage', 'uinteger', '0'), 275 ('sender', 'uinteger', '0'), 276 ('rtype', 'uinteger', '0'), 277 ('rtype_text', 'ignore', None), 278 ('start', 'string', None), 279 ('duration', 'uinteger', '0'), 280 ('waypoints', 'array', ( 281 ('waypoint_t', 'waycount', ( 282 ('lon', 'integer', 'AIS_LON4_NOT_AVAILABLE'), 283 ('lat', 'integer', 'AIS_LAT4_NOT_AVAILABLE'), 284 )))), 285 ), 286 'stringbuffered': ('start',), 287 }, 288 { 289 "initname": "json_ais6_fid30", 290 "headers": ("AIS_HEADER", "AIS_TYPE6",), 291 "structname": "ais->type6.dac1fid30", 292 "fieldmap": ( 293 # fieldname type default 294 ('linkage', 'uinteger', '0'), 295 ('text', 'string', '0'), 296 ), 297 }, 298 { 299 "initname": "json_ais6_fid32", 300 "headers": ("AIS_HEADER", "AIS_TYPE6"), 301 "structname": "ais->type6.dac1fid32", 302 "fieldmap": ( 303 # fieldname type default 304 ('month', 'uinteger', 'AIS_MONTH_NOT_AVAILABLE'), 305 ('day', 'uinteger', 'AIS_DAY_NOT_AVAILABLE'), 306 ('tidals', 'array', ( 307 ('tidal_t', 'ntidals', ( 308 ('lon', 'integer', 'AIS_LON3_NOT_AVAILABLE'), 309 ('lat', 'integer', 'AIS_LAT3_NOT_AVAILABLE'), 310 ('from_hour', 'uinteger', 'AIS_MONTH_NOT_AVAILABLE'), 311 ('from_min', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'), 312 ('to_hour', 'uinteger', 'AIS_HOUR_NOT_AVAILABLE'), 313 ('to_min', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'), 314 ('cdir', 'uinteger', 'DAC1FID32_CDIR_NOT_AVAILABLE'), 315 ('cspeed', 'uinteger', 'DAC1FID32_CSPEED_NOT_AVAILABLE'), 316 )))), 317 ), 318 }, 319 { 320 "initname": "json_ais6_fid55", 321 "headers": ("AIS_HEADER", "AIS_TYPE6"), 322 "structname": "ais->type6.dac200fid55", 323 "fieldmap": ( 324 # fieldname type default 325 ('crew', 'uinteger', 'DAC200FID55_COUNT_NOT_AVAILABLE'), 326 ('passengers', 'uinteger', 'DAC200FID55_COUNT_NOT_AVAILABLE'), 327 ('personnel', 'uinteger', 'DAC200FID55_COUNT_NOT_AVAILABLE'), 328 ), 329 }, 330 { 331 "initname": "json_ais7", 332 "headers": ("AIS_HEADER",), 333 "structname": "ais->type7", 334 "fieldmap": ( 335 # fieldname type default 336 ('mmsi1', 'uinteger', '0'), 337 ('mmsi2', 'uinteger', '0'), 338 ('mmsi3', 'uinteger', '0'), 339 ('mmsi4', 'uinteger', '0'), 340 ('seqno1', 'uinteger', '0'), 341 ('seqno2', 'uinteger', '0'), 342 ('seqno3', 'uinteger', '0'), 343 ('seqno4', 'uinteger', '0'), 344 ), 345 }, 346 { 347 "initname": "json_ais8", 348 "headers": ("AIS_HEADER", "AIS_TYPE8",), 349 "structname": "ais->type8", 350 "fieldmap": ( 351 # fieldname type default 352 ('data', 'string', None), 353 ), 354 "stringbuffered": ("data",), 355 }, 356 { 357 "initname": "json_ais8_fid10", 358 "headers": ("AIS_HEADER", "AIS_TYPE8",), 359 "structname": "ais->type8.dac200fid10", 360 "fieldmap": ( 361 # fieldname type default 362 ('vin', 'string', None), 363 ('length', 'uinteger', '0'), 364 ('beam', 'uinteger', '0'), 365 ('shiptype', 'uinteger', '0'), 366 ('shiptype_text', 'ignore', None), 367 ('hazard', 'uinteger', '0'), 368 ('hazard_text', 'ignore', None), 369 ('draught', 'uinteger', '0'), 370 ('loaded', 'uinteger', '0'), 371 ('loaded_text', 'ignore', None), 372 ('speed_q', 'boolean', 'false'), 373 ('course_q', 'boolean', 'false'), 374 ('heading_q', 'boolean', 'false'), 375 ), 376 }, 377 { 378 "initname": "json_ais8_fid11", 379 "headers": ("AIS_HEADER", "AIS_TYPE8",), 380 "structname": "ais->type8.dac1fid11", 381 "fieldmap": ( 382 # fieldname type default 383 ('lat', 'integer', 'DAC1FID11_LAT_NOT_AVAILABLE'), 384 ('lon', 'integer', 'DAC1FID11_LON_NOT_AVAILABLE'), 385 ('timestamp', 'string', None), 386 ('wspeed', 'uinteger', 'DAC1FID11_WSPEED_NOT_AVAILABLE'), 387 ('wgust', 'uinteger', 'DAC1FID11_WSPEED_NOT_AVAILABLE'), 388 ('wdir', 'uinteger', 'DAC1FID11_WDIR_NOT_AVAILABLE'), 389 ('wgustdir', 'uinteger', 'DAC1FID11_WDIR_NOT_AVAILABLE'), 390 ('airtemp', 'uinteger', 'DAC1FID11_AIRTEMP_NOT_AVAILABLE'), 391 ('humidity', 'uinteger', 'DAC1FID11_HUMIDITY_NOT_AVAILABLE'), 392 ('dewpoint', 'uinteger', 'DAC1FID11_DEWPOINT_NOT_AVAILABLE'), 393 ('pressure', 'uinteger', 'DAC1FID11_PRESSURE_NOT_AVAILABLE'), 394 ('pressuretend', 'uinteger', 395 'DAC1FID11_PRESSURETREND_NOT_AVAILABLE'), 396 ('visibility', 'uinteger', 'DAC1FID11_VISIBILITY_NOT_AVAILABLE'), 397 ('waterlevel', 'integer', 'DAC1FID11_WATERLEVEL_NOT_AVAILABLE'), 398 ('leveltrend', 'uinteger', 399 'DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE'), 400 ('cspeed', 'uinteger', 'DAC1FID11_CSPEED_NOT_AVAILABLE'), 401 ('cdir', 'uinteger', 'DAC1FID11_CDIR_NOT_AVAILABLE'), 402 ('cspeed2', 'uinteger', 'DAC1FID11_CSPEED_NOT_AVAILABLE'), 403 ('cdir2', 'uinteger', 'DAC1FID11_CDIR_NOT_AVAILABLE'), 404 ('cdepth2', 'uinteger', 'DAC1FID11_CDEPTH_NOT_AVAILABLE'), 405 ('cspeed3', 'uinteger', 'DAC1FID11_CSPEED_NOT_AVAILABLE'), 406 ('cdir3', 'uinteger', 'DAC1FID11_CDIR_NOT_AVAILABLE'), 407 ('cdepth3', 'uinteger', 'DAC1FID11_CDEPTH_NOT_AVAILABLE'), 408 ('waveheight', 'uinteger', 'DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE'), 409 ('waveperiod', 'uinteger', 'DAC1FID11_WAVEPERIOD_NOT_AVAILABLE'), 410 ('wavedir', 'uinteger', 'DAC1FID11_WAVEDIR_NOT_AVAILABLE'), 411 ('swellheight', 'uinteger', 'DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE'), 412 ('swellperiod', 'uinteger', 'DAC1FID11_WAVEPERIOD_NOT_AVAILABLE'), 413 ('swelldir', 'uinteger', 'DAC1FID11_WAVEDIR_NOT_AVAILABLE'), 414 ('seastate', 'uinteger', 'DAC1FID11_SEASTATE_NOT_AVAILABLE'), 415 ('watertemp', 'uinteger', 'DAC1FID11_WATERTEMP_NOT_AVAILABLE'), 416 ('preciptype', 'uinteger', 'DAC1FID11_PRECIPTYPE_NOT_AVAILABLE'), 417 ('preciptype_text', 'ignore', None), 418 ('salinity', 'uinteger', 'DAC1FID11_SALINITY_NOT_AVAILABLE'), 419 ('ice', 'uinteger', 'DAC1FID11_ICE_NOT_AVAILABLE'), 420 ('ice_text', 'ignore', None), 421 ), 422 "stringbuffered": ("timestamp",), 423 }, 424 { 425 "initname": "json_ais8_fid13", 426 "headers": ("AIS_HEADER", "AIS_TYPE8",), 427 "structname": "ais->type8.dac1fid13", 428 "fieldmap": ( 429 # fieldname type default 430 ('reason', 'string', None), 431 ('closefrom', 'string', None), 432 ('closeto', 'string', None), 433 ('radius', 'uinteger', 'AIS_DAC1FID13_RADIUS_NOT_AVAILABLE'), 434 ('extunit', 'uinteger', 'AIS_DAC1FID13_EXTUNIT_NOT_AVAILABLE'), 435 ('fday', 'uinteger', 'AIS_DAY_NOT_AVAILABLE'), 436 ('fmonth', 'uinteger', 'AIS_MONTH_NOT_AVAILABLE'), 437 ('fhour', 'uinteger', 'AIS_HOUR_NOT_AVAILABLE'), 438 ('fminute', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'), 439 ('tday', 'uinteger', 'AIS_DAY_NOT_AVAILABLE'), 440 ('tmonth', 'uinteger', 'AIS_MONTH_NOT_AVAILABLE'), 441 ('thour', 'uinteger', 'AIS_HOUR_NOT_AVAILABLE'), 442 ('tminute', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'), 443 ), 444 'stringbuffered': ('closefrom', 'closeto'), 445 }, 446 { 447 "initname": "json_ais8_fid15", 448 "headers": ("AIS_HEADER", "AIS_TYPE8",), 449 "structname": "ais->type8.dac1fid15", 450 "fieldmap": ( 451 # fieldname type default 452 ('airdraught', 'uinteger', '0'), 453 ), 454 }, 455 { 456 "initname": "json_ais8_fid16", 457 "headers": ("AIS_HEADER", "AIS_TYPE8",), 458 "structname": "ais->type8.dac1fid16", 459 "fieldmap": ( 460 # fieldname type default 461 ('persons', 'uinteger', '0'), 462 ), 463 }, 464 { 465 "initname": "json_ais8_fid17", 466 "headers": ("AIS_HEADER", "AIS_TYPE8",), 467 "structname": "ais->type8.dac1fid17", 468 "fieldmap": ( 469 # fieldname type default 470 ('targets', 'array', ( 471 ('target_t', 'ntargets', ( 472 ('idtype', 'uinteger', 'DAC1FID17_IDTYPE_OTHER'), 473 ("id.mmsi", 'uinteger', '0'), 474 ("id.imo", 'uinteger', '0'), 475 ("id.callsign", 'string', 'DAC1FID17_ID_LENGTH'), 476 ("id.other", 'string', 'DAC1FID17_ID_LENGTH'), 477 ('lat', 'integer', 'AIS_LAT3_NOT_AVAILABLE'), 478 ('lon', 'integer', 'AIS_LON3_NOT_AVAILABLE'), 479 ('course', 'uinteger', 'DAC1FID17_COURSE_NOT_AVAILABLE'), 480 ('second', 'uinteger', 'AIS_SECOND_NOT_AVAILABLE'), 481 ('speed', 'uinteger', 'DAC1FID17_SPEED_NOT_AVAILABLE'), 482 )))), 483 ), 484 }, 485 { 486 "initname": "json_ais8_fid19", 487 "headers": ("AIS_HEADER", "AIS_TYPE8",), 488 "structname": "ais->type8.dac1fid19", 489 "fieldmap": ( 490 # fieldname type default 491 ('linkage', 'uinteger', '0'), 492 ('station', 'string', None), 493 ('lon', 'integer', 'AIS_LON3_NOT_AVAILABLE'), 494 ('lat', 'integer', 'AIS_LAT3_NOT_AVAILABLE'), 495 ('status', 'uinteger', '0'), 496 ('signal', 'uinteger', '0'), 497 ('signal_text', 'ignore', None), 498 ('hour', 'uinteger', 'AIS_HOUR_NOT_AVAILABLE'), 499 ('minute', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'), 500 ('nextsignal', 'uinteger', '0'), 501 ('nextsignal_type', 'ignore', None), 502 ), 503 }, 504 { 505 "initname": "json_ais8_fid23", 506 "headers": ("AIS_HEADER", "AIS_TYPE8"), 507 "structname": "ais->type8.dac200fid23", 508 "fieldmap": ( 509 # fieldname type default 510 ('start', 'string', None), 511 ('end', 'string', None), 512 ('start_lon', 'integer', 'AIS_LON4_NOT_AVAILABLE'), 513 ('start_lat', 'integer', 'AIS_LAT4_NOT_AVAILABLE'), 514 ('end_lon', 'integer', 'AIS_LON4_NOT_AVAILABLE'), 515 ('end_lat', 'integer', 'AIS_LAT4_NOT_AVAILABLE'), 516 ('type', 'uinteger', 'DAC200FID23_TYPE_UNKNOWN'), 517 ('type_text', 'ignore', None), 518 ('min', 'integer', 'DAC200FID23_MIN_UNKNOWN'), 519 ('max', 'integer', 'DAC200FID23_MAX_UNKNOWN'), 520 ('intensity', 'uinteger', 'DAC200FID23_CLASS_UNKNOWN'), 521 ('intensity_text', 'ignore', None), 522 ('wind', 'uinteger', 'DAC200FID23_WIND_UNKNOWN'), 523 ('wind_text', 'ignore', None), 524 ), 525 'stringbuffered': ('start', 'end'), 526 }, 527 { 528 "initname": "json_ais8_fid24", 529 "headers": ("AIS_HEADER", "AIS_TYPE8"), 530 "structname": "ais->type8.dac200fid24", 531 "fieldmap": ( 532 # fieldname type default 533 ('country', 'string', None), 534 ('gauges', 'array', ( 535 ('gauge_t', 'ngauges', ( 536 ('id', 'uinteger', 'DAC200FID24_GAUGE_ID_UNKNOWN'), 537 ('level', 'integer', 'DAC200FID24_GAUGE_LEVEL_UNKNOWN'), 538 )))), 539 ), 540 }, 541 { 542 "initname": "json_ais8_fid27", 543 "headers": ("AIS_HEADER", "AIS_TYPE8",), 544 "structname": "ais->type8.dac1fid27", 545 "fieldmap": ( 546 # fieldname type default 547 ('linkage', 'uinteger', '0'), 548 ('sender', 'uinteger', '0'), 549 ('rtype', 'uinteger', '0'), 550 ('rtype_text', 'ignore', None), 551 ('start', 'string', None), 552 ('duration', 'uinteger', '0'), 553 ('waypoints', 'array', ( 554 ('waypoint_t', 'waycount', ( 555 ('lon', 'integer', 'AIS_LON4_NOT_AVAILABLE'), 556 ('lat', 'integer', 'AIS_LAT4_NOT_AVAILABLE'), 557 )))), 558 ), 559 'stringbuffered': ('start',), 560 }, 561 { 562 "initname": "json_ais8_fid29", 563 "headers": ("AIS_HEADER", "AIS_TYPE8",), 564 "structname": "ais->type8.dac1fid29", 565 "fieldmap": ( 566 # fieldname type default 567 ('linkage', 'uinteger', '0'), 568 ('text', 'string', '0'), 569 ), 570 }, 571 { 572 "initname": "json_ais8_fid31", 573 "headers": ("AIS_HEADER", "AIS_TYPE8",), 574 "structname": "ais->type8.dac1fid31", 575 "fieldmap": ( 576 # fieldname type default 577 ('lon', 'integer', 'DAC1FID31_LON_NOT_AVAILABLE'), 578 ('lat', 'integer', 'DAC1FID31_LAT_NOT_AVAILABLE'), 579 ('accuracy', 'boolean', 'false'), 580 ('timestamp', 'string', None), 581 ('wspeed', 'uinteger', 'DAC1FID31_WIND_NOT_AVAILABLE'), 582 ('wgust', 'uinteger', 'DAC1FID31_WIND_NOT_AVAILABLE'), 583 ('wdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), 584 ('wgustdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), 585 ('airtemp', 'integer', 'DAC1FID31_AIRTEMP_NOT_AVAILABLE'), 586 ('humidity', 'uinteger', 'DAC1FID31_HUMIDITY_NOT_AVAILABLE'), 587 ('dewpoint', 'integer', 'DAC1FID31_DEWPOINT_NOT_AVAILABLE'), 588 ('pressure', 'uinteger', 'DAC1FID31_PRESSURE_NOT_AVAILABLE'), 589 ('pressuretend', 'uinteger', 590 'DAC1FID31_PRESSURETEND_NOT_AVAILABLE'), 591 ('visgreater', 'boolean', 'false'), 592 ('visibility', 'uinteger', 'DAC1FID31_VISIBILITY_NOT_AVAILABLE'), 593 ('waterlevel', 'integer', 'DAC1FID31_WATERLEVEL_NOT_AVAILABLE'), 594 ('leveltrend', 'uinteger', 595 'DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE'), 596 ('cspeed', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'), 597 ('cdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), 598 ('cspeed2', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'), 599 ('cdir2', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), 600 ('cdepth2', 'uinteger', 'DAC1FID31_CDEPTH_NOT_AVAILABLE'), 601 ('cspeed3', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'), 602 ('cdir3', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), 603 ('cdepth3', 'uinteger', 'DAC1FID31_CDEPTH_NOT_AVAILABLE'), 604 ('waveheight', 'uinteger', 'DAC1FID31_HEIGHT_NOT_AVAILABLE'), 605 ('waveperiod', 'uinteger', 'DAC1FID31_PERIOD_NOT_AVAILABLE'), 606 ('wavedir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), 607 ('swellheight', 'uinteger', 'DAC1FID31_HEIGHT_NOT_AVAILABLE'), 608 ('swellperiod', 'uinteger', 'DAC1FID31_PERIOD_NOT_AVAILABLE'), 609 ('swelldir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'), 610 ('seastate', 'uinteger', 'DAC1FID31_SEASTATE_NOT_AVAILABLE'), 611 ('watertemp', 'integer', 'DAC1FID31_WATERTEMP_NOT_AVAILABLE'), 612 ('preciptype', 'uinteger', 'DAC1FID31_PRECIPTYPE_NOT_AVAILABLE'), 613 ('preciptype_text', 'ignore', None), 614 ('salinity', 'uinteger', 'DAC1FID31_SALINITY_NOT_AVAILABLE'), 615 ('ice', 'uinteger', 'DAC1FID31_ICE_NOT_AVAILABLE'), 616 ), 617 "stringbuffered": ("timestamp",), 618 }, 619 { 620 "initname": "json_ais8_fid40", 621 "headers": ("AIS_HEADER", "AIS_TYPE8"), 622 "structname": "ais->type8.dac200fid40", 623 "fieldmap": ( 624 # fieldname type default 625 ('form', 'uinteger', 'DAC200FID40_FORM_UNKNOWN'), 626 ('facing', 'uinteger', 'DAC200FID40_FACING_UNKNOWN'), 627 ('direction', 'uinteger', 'DAC200FID40_DIRECTION_UNKNOWN'), 628 ('direction_text', 'ignore', None), 629 ('status', 'uinteger', 'DAC200FID40_STATUS_UNKNOWN'), 630 ('status_text', 'ignore', None), 631 ), 632 }, 633 { 634 "initname": "json_ais9", 635 "headers": ("AIS_HEADER",), 636 "structname": "ais->type9", 637 "fieldmap": ( 638 # fieldname type default 639 ('alt', 'uinteger', 'AIS_ALT_NOT_AVAILABLE'), 640 ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), 641 ('accuracy', 'boolean', 'false'), 642 ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), 643 ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), 644 ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), 645 ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), 646 ('regional', 'uinteger', '0'), 647 ('dte', 'uinteger', '1'), 648 ('raim', 'boolean', 'false'), 649 ('radio', 'uinteger', '0'), 650 ), 651 }, 652 { 653 "initname": "json_ais10", 654 "headers": ("AIS_HEADER",), 655 "structname": "ais->type10", 656 "fieldmap": ( 657 # fieldname type default 658 ('dest_mmsi', 'uinteger', '0'), 659 ), 660 }, 661 # Message type 11 duplicates 4 662 { 663 "initname": "json_ais12", 664 "headers": ("AIS_HEADER",), 665 "structname": "ais->type12", 666 "fieldmap": ( 667 # fieldname type default 668 ('seqno', 'uinteger', '0'), 669 ('dest_mmsi', 'uinteger', '0'), 670 ('retransmit', 'boolean', '0'), 671 ('text', 'string', None), 672 ), 673 }, 674 # Message type 13 duplicates 7 675 { 676 "initname": "json_ais14", 677 "headers": ("AIS_HEADER",), 678 "structname": "ais->type14", 679 "fieldmap": ( 680 # fieldname type default 681 ('text', 'string', None), 682 ), 683 }, 684 { 685 "initname": "json_ais15", 686 "headers": ("AIS_HEADER",), 687 "structname": "ais->type15", 688 "fieldmap": ( 689 # fieldname type default 690 ('mmsi1', 'uinteger', '0'), 691 ('type1_1', 'uinteger', '0'), 692 ('offset1_1', 'uinteger', '0'), 693 ('type1_2', 'uinteger', '0'), 694 ('offset1_2', 'uinteger', '0'), 695 ('mmsi2', 'uinteger', '0'), 696 ('type2_1', 'uinteger', '0'), 697 ('offset2_1', 'uinteger', '0'), 698 ), 699 }, 700 { 701 "initname": "json_ais16", 702 "headers": ("AIS_HEADER",), 703 "structname": "ais->type16", 704 "fieldmap": ( 705 # fieldname type default 706 ('mmsi1', 'uinteger', '0'), 707 ('offset1', 'uinteger', '0'), 708 ('increment1', 'uinteger', '0'), 709 ('mmsi2', 'uinteger', '0'), 710 ('offset2', 'uinteger', '0'), 711 ('increment2', 'uinteger', '0'), 712 ), 713 }, 714 { 715 "initname": "json_ais17", 716 "headers": ("AIS_HEADER",), 717 "structname": "ais->type17", 718 "fieldmap": ( 719 # fieldname type default 720 ('lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), 721 ('lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), 722 ('data', 'string', None), 723 ), 724 "stringbuffered": ("data",), 725 }, 726 { 727 "initname": "json_ais18", 728 "headers": ("AIS_HEADER",), 729 "structname": "ais->type18", 730 "fieldmap": ( 731 # fieldname type default 732 ('reserved', 'uinteger', '0'), 733 ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), 734 ('accuracy', 'boolean', 'false'), 735 ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), 736 ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), 737 ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), 738 ('heading', 'uinteger', 'AIS_HEADING_NOT_AVAILABLE'), 739 ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), 740 ('regional', 'uinteger', '0'), 741 ('cs', 'boolean', 'false'), 742 ('display', 'boolean', 'false'), 743 ('dsc', 'boolean', 'false'), 744 ('band', 'boolean', 'false'), 745 ('msg22', 'boolean', 'false'), 746 ('raim', 'boolean', 'false'), 747 ('radio', 'uinteger', '0'), 748 ), 749 }, 750 { 751 "initname": "json_ais19", 752 "headers": ("AIS_HEADER",), 753 "structname": "ais->type19", 754 "fieldmap": ( 755 # fieldname type default 756 ('reserved', 'uinteger', '0'), 757 ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), 758 ('accuracy', 'boolean', 'false'), 759 ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), 760 ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), 761 ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), 762 ('heading', 'uinteger', 'AIS_HEADING_NOT_AVAILABLE'), 763 ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), 764 ('regional', 'uinteger', '0'), 765 ('shipname', 'string', None), 766 ('shiptype', 'uinteger', '0'), 767 ('shiptype_text', 'ignore', None), 768 ('to_bow', 'uinteger', '0'), 769 ('to_stern', 'uinteger', '0'), 770 ('to_port', 'uinteger', '0'), 771 ('to_starboard', 'uinteger', '0'), 772 ('epfd', 'uinteger', '0'), 773 ('epfd_text', 'ignore', None), 774 ('raim', 'boolean', 'false'), 775 ('dte', 'uinteger', '1'), 776 ('assigned', 'boolean', 'false'), 777 ), 778 }, 779 { 780 "initname": "json_ais20", 781 "headers": ("AIS_HEADER",), 782 "structname": "ais->type20", 783 "fieldmap": ( 784 # fieldname type default 785 ('offset1', 'uinteger', '0'), 786 ('number1', 'uinteger', '0'), 787 ('timeout1', 'uinteger', '0'), 788 ('increment1', 'uinteger', '0'), 789 ('offset2', 'uinteger', '0'), 790 ('number2', 'uinteger', '0'), 791 ('timeout2', 'uinteger', '0'), 792 ('increment2', 'uinteger', '0'), 793 ('offset3', 'uinteger', '0'), 794 ('number3', 'uinteger', '0'), 795 ('timeout3', 'uinteger', '0'), 796 ('increment3', 'uinteger', '0'), 797 ('offset4', 'uinteger', '0'), 798 ('number4', 'uinteger', '0'), 799 ('timeout4', 'uinteger', '0'), 800 ('increment4', 'uinteger', '0'), 801 ), 802 }, 803 { 804 "initname": "json_ais21", 805 "headers": ("AIS_HEADER",), 806 "structname": "ais->type21", 807 "fieldmap": ( 808 # fieldname type default 809 ('aid_type', 'uinteger', '0'), 810 ('aid_type_text', 'ignore', None), 811 ('name', 'string', None), 812 ('accuracy', 'boolean', 'false'), 813 ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), 814 ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), 815 ('to_bow', 'uinteger', '0'), 816 ('to_stern', 'uinteger', '0'), 817 ('to_port', 'uinteger', '0'), 818 ('to_starboard', 'uinteger', '0'), 819 ('epfd', 'uinteger', '0'), 820 ('epfd_text', 'ignore', None), 821 ('second', 'uinteger', '0'), 822 ('regional', 'uinteger', '0'), 823 ('off_position', 'boolean', 'false'), 824 ('raim', 'boolean', 'false'), 825 ('virtual_aid', 'boolean', 'false'), 826 ), 827 }, 828 { 829 "initname": "json_ais22", 830 "headers": ("AIS_HEADER",), 831 "structname": "ais->type22", 832 "fieldmap": ( 833 # fieldname type default 834 ('channel_a', 'uinteger', '0'), 835 ('channel_b', 'uinteger', '0'), 836 ('txrx', 'uinteger', '0'), 837 ('power', 'boolean', 'false'), 838 ('area.ne_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), 839 ('area.ne_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), 840 ('area.sw_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), 841 ('area.sw_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), 842 ('mmsi.dest1', 'uinteger', '0'), 843 ('mmsi.dest2', 'uinteger', '0'), 844 ('addressed', 'boolean', 'false'), 845 ('band_a', 'boolean', 'false'), 846 ('band_b', 'boolean', 'false'), 847 ('zonesize', 'uinteger', '0'), 848 ), 849 }, 850 { 851 "initname": "json_ais23", 852 "headers": ("AIS_HEADER",), 853 "structname": "ais->type23", 854 "fieldmap": ( 855 # fieldname type default 856 ('ne_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), 857 ('ne_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), 858 ('sw_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), 859 ('sw_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), 860 ('stationtype', 'uinteger', '0'), 861 ('stationtype_text', 'ignore', None), 862 ('shiptype', 'uinteger', '0'), 863 ('shiptype_text', 'ignore', None), 864 ('txrx', 'uinteger', '0'), 865 ('interval', 'uinteger', '0'), 866 ('quiet', 'uinteger', '0'), 867 ), 868 }, 869 { 870 "initname": "json_ais24", 871 "headers": ("AIS_HEADER",), 872 "structname": "ais->type24", 873 "fieldmap": ( 874 # fieldname type default 875 ('shipname', 'string', None), # Part A 876 ('shiptype', 'uinteger', '0'), # Part B 877 ('shiptype_text', 'ignore', None), 878 ('vendorid', 'string', None), # Part B 879 ('model', 'uinteger', '0'), # Part B 880 ('serial', 'uinteger', '0'), # Part B 881 ('callsign', 'string', None), # Part B 882 ('mothership_mmsi', 'uinteger', '0'), # Part B 883 ('dim.to_bow', 'uinteger', '0'), # Part B 884 ('dim.to_stern', 'uinteger', '0'), # Part B 885 ('dim.to_port', 'uinteger', '0'), # Part B 886 ('dim.to_starboard', 'uinteger', '0'), # Part B 887 ), 888 }, 889 { 890 "initname": "json_ais25", 891 "headers": ("AIS_HEADER",), 892 "structname": "ais->type25", 893 "fieldmap": ( 894 # fieldname type default 895 ('addressed', 'boolean', 'false'), 896 ('structured', 'boolean', 'false'), 897 ('dest_mmsi', 'uinteger', '0'), 898 ('app_id', 'uinteger', '0'), 899 ('data', 'string', None), 900 ), 901 "stringbuffered": ("data",), 902 }, 903 { 904 "initname": "json_ais26", 905 "headers": ("AIS_HEADER",), 906 "structname": "ais->type26", 907 "fieldmap": ( 908 # fieldname type default 909 ('addressed', 'boolean', 'false'), 910 ('structured', 'boolean', 'false'), 911 ('dest_mmsi', 'uinteger', '0'), 912 ('app_id', 'uinteger', '0'), 913 ('data', 'string', None), 914 ('radio', 'uinteger', '0'), 915 ), 916 "stringbuffered": ("data",), 917 }, 918 { 919 "initname": "json_ais27", 920 "headers": ("AIS_HEADER",), 921 "structname": "ais->type27", 922 "fieldmap": ( 923 # fieldname type default 924 ('status', 'uinteger', '0'), 925 ('speed', 'uinteger', 'AIS_LONGRANGE_SPEED_NOT_AVAILABLE'), 926 ('accuracy', 'boolean', 'false'), 927 ('lon', 'integer', 'AIS_LONGRANGE_LON_NOT_AVAILABLE'), 928 ('lat', 'integer', 'AIS_LONGRANGE_LAT_NOT_AVAILABLE'), 929 ('course', 'uinteger', 'AIS_LONGRANGE_COURSE_NOT_AVAILABLE'), 930 ('raim', 'boolean', 'false'), 931 ('gnss', 'boolean', 'true'), 932 ), 933 }, 934) 935 936# You should not need to modify anything below this line. 937 938 939def generate(spec): 940 report = "" 941 leader = " " * 39 942 initname = spec["initname"] 943 # Utter storage declarations for any fields that are declared to be 944 # stringbuffered. These will need to be postprocessed in json_ais_read(). 945 attributes = [t[0] for t in spec["fieldmap"]] 946 for attr in spec.get("stringbuffered", []): 947 if attr not in attributes: 948 sys.stderr.write("buffered %s is not in base attributes of %s\n" 949 % (attr, initname)) 950 raise SystemExit(1) 951 952 if attr not in outboard: 953 report += " char %s[JSON_VAL_MAX+1];\n" % attr 954 outboard.append(attr) 955 956 structname = spec["structname"] 957 # If there are structarrays describing array subobjects, we need 958 # to make a separate parse control initializer for each one. The 959 # attribute name is the name of the array; substructure and length 960 # fieldnames must be given in the defaults part. 961 for (attr, itype, arrayparts) in spec["fieldmap"]: 962 if itype == 'array': 963 (innerstruct, lengthfield, elements) = arrayparts 964 report += (" const struct json_attr_t %s_%s_subtype[] = {\n" 965 % (initname, attr)) 966 for (subattr, subitype, default) in elements: 967 report += ('\t{"%s",%st_%s,%sSTRUCTOBJECT(struct %s, %s),\n' 968 % (subattr, " " * (14 - len(subattr)), subitype, 969 " " * (8 - len(subitype)), innerstruct, subattr)) 970 if subitype != "string": 971 report += (leader + ".dflt.%s = %s},\n" 972 % (subitype, default)) 973 elif default: 974 report += leader + ".len = %s},\n" % (default,) 975 else: 976 sys.stderr.write( 977 "explicit length specification required\n") 978 raise SystemExit(1) 979 report += """\ 980 {NULL} 981 }; 982""" 983 # Generate the main structure definition describing this parse. 984 # It may have object subarrays. 985 report += " const struct json_attr_t %s[] = {\n" % initname 986 if "headers" in spec: 987 for header in spec["headers"]: 988 report += '\t' + header + "\n" 989 for (attr, itype, default) in spec["fieldmap"]: 990 if itype == 'array': 991 (innerstruct, lengthfield, elements) = default 992 report += ('\t{"%s",%st_array, ' 993 'STRUCTARRAY(%s.%s, %s_%s_subtype, &%s.%s)},\n' 994 % (attr, " " * (14 - len(attr)), structname, attr, 995 initname, attr, structname, lengthfield)) 996 else: 997 if itype == "string": 998 deref = "" 999 else: 1000 deref = "&" 1001 if attr in spec.get("stringbuffered", []): 1002 target = attr 1003 else: 1004 target = structname + "." + attr 1005 if "." in attr: 1006 attr = attr[attr.rfind(".") + 1:] 1007 if itype == 'ignore': 1008 report += '\t{"%s", t_ignore},\n' % attr 1009 continue 1010 report += '\t{"%s",%st_%s,%s.addr.%s = %s%s,\n' % \ 1011 (attr, " " * (14 - len(attr)), itype, " " * (10 - len(itype)), 1012 itype, deref, target) 1013 if itype == "string": 1014 report += leader + ".len = sizeof(%s)},\n" % target 1015 else: 1016 report += leader + ".dflt.%s = %s},\n" % (itype, default) 1017 report += """\ 1018 {NULL} 1019 }; 1020""" 1021 print(report) 1022 1023 1024if __name__ == '__main__': 1025 try: 1026 # The --ais and --target= options are (required) placeholders. 1027 # In the future, this script will generate more different kinds 1028 # of code. 1029 (options, arguments) = getopt.getopt(sys.argv[1:], "", 1030 ["ais", "target="]) 1031 except getopt.GetoptError as msg: 1032 print("jsongen.py: " + str(msg)) 1033 raise SystemExit(1) 1034 1035 spec = None 1036 target = None 1037 for (switch, val) in options: 1038 if switch == '--ais': 1039 spec = ais_specs 1040 elif switch == '--target': 1041 target = val 1042 1043 if not target or not spec: 1044 print("jsongen.py: must specify type and target.") 1045 raise SystemExit(1) 1046 1047 if target == 'parser': 1048 print("""/* 1049 * This is code generated by jsongen.py. Do not hand-hack it! 1050 */ 1051 #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0])) 1052 1053""") 1054 outboard = [] 1055 for description in spec: 1056 generate(description) 1057 print(""" 1058 1059/* Generated code ends. */ 1060""") 1061# The following sets edit modes for GNU EMACS 1062# Local Variables: 1063# mode:python 1064# End: 1065