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