nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #!/usr/bin/env python
2  
3 #
4 # asn2wrs.py
5 # ASN.1 to Wireshark dissector compiler
6 # Copyright 2004 Tomas Kukosa
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a
9 # copy of this software and associated documentation files (the
10 # "Software"), to deal in the Software without restriction, including
11 # without limitation the rights to use, copy, modify, merge, publish,
12 # distribute, and/or sell copies of the Software, and to permit persons
13 # to whom the Software is furnished to do so, provided that the above
14 # copyright notice(s) and this permission notice appear in all copies of
15 # the Software and that both the above copyright notice(s) and this
16 # permission notice appear in supporting documentation.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
21 # OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 # HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
23 # INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
24 # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
25 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
26 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 #
28 # Except as contained in this notice, the name of a copyright holder
29 # shall not be used in advertising or otherwise to promote the sale, use
30 # or other dealings in this Software without prior written authorization
31 # of the copyright holder.
32  
33  
34 """ASN.1 to Wireshark dissector compiler"""
35  
36 #
37 # Compiler from ASN.1 specification to the Wireshark dissector
38 #
39 # Based on ASN.1 to Python compiler from Aaron S. Lav's PyZ3950 package licensed under the X Consortium license
40 # http://www.pobox.com/~asl2/software/PyZ3950/
41 # (ASN.1 to Python compiler functionality is broken but not removed, it could be revived if necessary)
42 #
43 # It requires Dave Beazley's PLY parsing package licensed under the LGPL (tested with version 2.3)
44 # http://www.dabeaz.com/ply/
45 #
46 #
47 # ITU-T Recommendation X.680 (07/2002),
48 # Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation
49 #
50 # ITU-T Recommendation X.681 (07/2002),
51 # Information technology - Abstract Syntax Notation One (ASN.1): Information object specification
52 #
53 # ITU-T Recommendation X.682 (07/2002),
54 # Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification
55 #
56 # ITU-T Recommendation X.683 (07/2002),
57 # Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications
58 #
59 # ITU-T Recommendation X.880 (07/1994),
60 # Information technology - Remote Operations: Concepts, model and notation
61 #
62  
63 import warnings
64  
65 import re
66 import sys
67 import os
68 import os.path
69 import time
70 import getopt
71 import traceback
72  
73 import lex
74 import yacc
75  
76 if sys.version_info[0] < 3:
77 from string import maketrans
78  
79  
80 # OID name -> number conversion table
81 oid_names = {
82 '/itu-t' : 0,
83 '/itu' : 0,
84 '/ccitt' : 0,
85 '/itu-r' : 0,
86 '0/recommendation' : 0,
87 '0.0/a' : 1,
88 '0.0/b' : 2,
89 '0.0/c' : 3,
90 '0.0/d' : 4,
91 '0.0/e' : 5,
92 '0.0/f' : 6,
93 '0.0/g' : 7,
94 '0.0/h' : 8,
95 '0.0/i' : 9,
96 '0.0/j' : 10,
97 '0.0/k' : 11,
98 '0.0/l' : 12,
99 '0.0/m' : 13,
100 '0.0/n' : 14,
101 '0.0/o' : 15,
102 '0.0/p' : 16,
103 '0.0/q' : 17,
104 '0.0/r' : 18,
105 '0.0/s' : 19,
106 '0.0/t' : 20,
107 '0.0/tseries' : 20,
108 '0.0/u' : 21,
109 '0.0/v' : 22,
110 '0.0/w' : 23,
111 '0.0/x' : 24,
112 '0.0/y' : 25,
113 '0.0/z' : 26,
114 '0/question' : 1,
115 '0/administration' : 2,
116 '0/network-operator' : 3,
117 '0/identified-organization' : 4,
118 '0/r-recommendation' : 5,
119 '0/data' : 9,
120 '/iso' : 1,
121 '1/standard' : 0,
122 '1/registration-authority' : 1,
123 '1/member-body' : 2,
124 '1/identified-organization' : 3,
125 '/joint-iso-itu-t' : 2,
126 '/joint-iso-ccitt' : 2,
127 '2/presentation' : 0,
128 '2/asn1' : 1,
129 '2/association-control' : 2,
130 '2/reliable-transfer' : 3,
131 '2/remote-operations' : 4,
132 '2/ds' : 5,
133 '2/directory' : 5,
134 '2/mhs' : 6,
135 '2/mhs-motis' : 6,
136 '2/ccr' : 7,
137 '2/oda' : 8,
138 '2/ms' : 9,
139 '2/osi-management' : 9,
140 '2/transaction-processing' : 10,
141 '2/dor' : 11,
142 '2/distinguished-object-reference' : 11,
143 '2/reference-data-transfe' : 12,
144 '2/network-layer' : 13,
145 '2/network-layer-management' : 13,
146 '2/transport-layer' : 14,
147 '2/transport-layer-management' : 14,
148 '2/datalink-layer' : 15,
149 '2/datalink-layer-managemen' : 15,
150 '2/datalink-layer-management-information' : 15,
151 '2/country' : 16,
152 '2/registration-procedures' : 17,
153 '2/registration-procedure' : 17,
154 '2/physical-layer' : 18,
155 '2/physical-layer-management' : 18,
156 '2/mheg' : 19,
157 '2/genericULS' : 20,
158 '2/generic-upper-layers-security' : 20,
159 '2/guls' : 20,
160 '2/transport-layer-security-protocol' : 21,
161 '2/network-layer-security-protocol' : 22,
162 '2/international-organizations' : 23,
163 '2/internationalRA' : 23,
164 '2/sios' : 24,
165 '2/uuid' : 25,
166 '2/odp' : 26,
167 '2/upu' : 40,
168 }
169  
170 ITEM_FIELD_NAME = '_item'
171 UNTAG_TYPE_NAME = '_untag'
172  
173 def asn2c(id):
174 return id.replace('-', '_').replace('.', '_').replace('&', '_')
175  
176 input_file = None
177 g_conform = None
178 lexer = None
179 in_oid = False
180  
181 class LexError(Exception):
182 def __init__(self, tok, filename=None):
183 self.tok = tok
184 self.filename = filename
185 self.msg = "Unexpected character %r" % (self.tok.value[0])
186 Exception.__init__(self, self.msg)
187 def __repr__(self):
188 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
189 __str__ = __repr__
190  
191  
192 class ParseError(Exception):
193 def __init__(self, tok, filename=None):
194 self.tok = tok
195 self.filename = filename
196 self.msg = "Unexpected token %s(%r)" % (self.tok.type, self.tok.value)
197 Exception.__init__(self, self.msg)
198 def __repr__(self):
199 return "%s:%d: %s" % (self.filename, self.tok.lineno, self.msg)
200 __str__ = __repr__
201  
202  
203 class DuplicateError(Exception):
204 def __init__(self, type, ident):
205 self.type = type
206 self.ident = ident
207 self.msg = "Duplicate %s for %s" % (self.type, self.ident)
208 Exception.__init__(self, self.msg)
209 def __repr__(self):
210 return self.msg
211 __str__ = __repr__
212  
213 class CompError(Exception):
214 def __init__(self, msg):
215 self.msg = msg
216 Exception.__init__(self, self.msg)
217 def __repr__(self):
218 return self.msg
219 __str__ = __repr__
220  
221  
222 states = (
223 ('braceignore','exclusive'),
224 )
225  
226 precedence = (
227 ('left', 'UNION', 'BAR'),
228 ('left', 'INTERSECTION', 'CIRCUMFLEX'),
229 )
230 # 11 ASN.1 lexical items
231  
232 static_tokens = {
233 r'::=' : 'ASSIGNMENT', # 11.16 Assignment lexical item
234 r'\.\.' : 'RANGE', # 11.17 Range separator
235 r'\.\.\.' : 'ELLIPSIS', # 11.18 Ellipsis
236 r'\[\[' : 'LVERBRACK', # 11.19 Left version brackets
237 r'\]\]' : 'RVERBRACK', # 11.20 Right version brackets
238 # 11.26 Single character lexical items
239 r'\{' : 'LBRACE',
240 r'\}' : 'RBRACE',
241 r'<' : 'LT',
242 #r'>' : 'GT',
243 r',' : 'COMMA',
244 r'\.' : 'DOT',
245 r'\(' : 'LPAREN',
246 r'\)' : 'RPAREN',
247 r'\[' : 'LBRACK',
248 r'\]' : 'RBRACK',
249 r'-' : 'MINUS',
250 r':' : 'COLON',
251 #r'=' : 'EQ',
252 #r'"' : 'QUOTATION',
253 #r"'" : 'APOSTROPHE',
254 r';' : 'SEMICOLON',
255 r'@' : 'AT',
256 r'\!' : 'EXCLAMATION',
257 r'\^' : 'CIRCUMFLEX',
258 r'\&' : 'AMPERSAND',
259 r'\|' : 'BAR'
260 }
261  
262 # 11.27 Reserved words
263  
264 # all keys in reserved_words must start w/ upper case
265 reserved_words = {
266 'ABSENT' : 'ABSENT',
267 'ABSTRACT-SYNTAX' : 'ABSTRACT_SYNTAX',
268 'ALL' : 'ALL',
269 'APPLICATION' : 'APPLICATION',
270 'AUTOMATIC' : 'AUTOMATIC',
271 'BEGIN' : 'BEGIN',
272 'BIT' : 'BIT',
273 'BOOLEAN' : 'BOOLEAN',
274 'BY' : 'BY',
275 'CHARACTER' : 'CHARACTER',
276 'CHOICE' : 'CHOICE',
277 'CLASS' : 'CLASS',
278 'COMPONENT' : 'COMPONENT',
279 'COMPONENTS' : 'COMPONENTS',
280 'CONSTRAINED' : 'CONSTRAINED',
281 'CONTAINING' : 'CONTAINING',
282 'DEFAULT' : 'DEFAULT',
283 'DEFINITIONS' : 'DEFINITIONS',
284 'EMBEDDED' : 'EMBEDDED',
285 # 'ENCODED' : 'ENCODED',
286 'END' : 'END',
287 'ENUMERATED' : 'ENUMERATED',
288 # 'EXCEPT' : 'EXCEPT',
289 'EXPLICIT' : 'EXPLICIT',
290 'EXPORTS' : 'EXPORTS',
291 # 'EXTENSIBILITY' : 'EXTENSIBILITY',
292 'EXTERNAL' : 'EXTERNAL',
293 'FALSE' : 'FALSE',
294 'FROM' : 'FROM',
295 'GeneralizedTime' : 'GeneralizedTime',
296 'IDENTIFIER' : 'IDENTIFIER',
297 'IMPLICIT' : 'IMPLICIT',
298 # 'IMPLIED' : 'IMPLIED',
299 'IMPORTS' : 'IMPORTS',
300 'INCLUDES' : 'INCLUDES',
301 'INSTANCE' : 'INSTANCE',
302 'INTEGER' : 'INTEGER',
303 'INTERSECTION' : 'INTERSECTION',
304 'MAX' : 'MAX',
305 'MIN' : 'MIN',
306 'MINUS-INFINITY' : 'MINUS_INFINITY',
307 'NULL' : 'NULL',
308 'OBJECT' : 'OBJECT',
309 'ObjectDescriptor' : 'ObjectDescriptor',
310 'OCTET' : 'OCTET',
311 'OF' : 'OF',
312 'OPTIONAL' : 'OPTIONAL',
313 'PATTERN' : 'PATTERN',
314 'PDV' : 'PDV',
315 'PLUS-INFINITY' : 'PLUS_INFINITY',
316 'PRESENT' : 'PRESENT',
317 'PRIVATE' : 'PRIVATE',
318 'REAL' : 'REAL',
319 'RELATIVE-OID' : 'RELATIVE_OID',
320 'SEQUENCE' : 'SEQUENCE',
321 'SET' : 'SET',
322 'SIZE' : 'SIZE',
323 'STRING' : 'STRING',
324 'SYNTAX' : 'SYNTAX',
325 'TAGS' : 'TAGS',
326 'TRUE' : 'TRUE',
327 'TYPE-IDENTIFIER' : 'TYPE_IDENTIFIER',
328 'UNION' : 'UNION',
329 'UNIQUE' : 'UNIQUE',
330 'UNIVERSAL' : 'UNIVERSAL',
331 'UTCTime' : 'UTCTime',
332 'WITH' : 'WITH',
333 # X.208 obsolete but still used
334 'ANY' : 'ANY',
335 'DEFINED' : 'DEFINED',
336 }
337  
338 for k in list(static_tokens.keys()):
339 if static_tokens [k] == None:
340 static_tokens [k] = k
341  
342 StringTypes = ['Numeric', 'Printable', 'IA5', 'BMP', 'Universal', 'UTF8',
343 'Teletex', 'T61', 'Videotex', 'Graphic', 'ISO646', 'Visible',
344 'General']
345  
346 for s in StringTypes:
347 reserved_words[s + 'String'] = s + 'String'
348  
349 tokens = list(static_tokens.values()) \
350 + list(reserved_words.values()) \
351 + ['BSTRING', 'HSTRING', 'QSTRING',
352 'UCASE_IDENT', 'LCASE_IDENT', 'LCASE_IDENT_ASSIGNED', 'CLASS_IDENT',
353 'REAL_NUMBER', 'NUMBER', 'PYQUOTE']
354  
355  
356 cur_mod = __import__ (__name__) # XXX blech!
357  
358 for (k, v) in list(static_tokens.items ()):
359 cur_mod.__dict__['t_' + v] = k
360  
361 # 11.10 Binary strings
362 def t_BSTRING (t):
363 r"'[01]*'B"
364 return t
365  
366 # 11.12 Hexadecimal strings
367 def t_HSTRING (t):
368 r"'[0-9A-Fa-f]*'H"
369 return t
370  
371 def t_QSTRING (t):
372 r'"([^"]|"")*"'
373 return t
374  
375 def t_UCASE_IDENT (t):
376 r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
377 if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
378 if (is_class_syntax(t.value)): t.type = t.value
379 t.type = reserved_words.get(t.value, t.type)
380 return t
381  
382 lcase_ident_assigned = {}
383 def t_LCASE_IDENT (t):
384 r"[a-z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
385 if (not in_oid and (t.value in lcase_ident_assigned)): t.type = 'LCASE_IDENT_ASSIGNED'
386 return t
387  
388 # 11.9 Real numbers
389 def t_REAL_NUMBER (t):
390 r"[0-9]+\.[0-9]*(?!\.)"
391 return t
392  
393 # 11.8 Numbers
394 def t_NUMBER (t):
395 r"0|([1-9][0-9]*)"
396 return t
397  
398 # 11.6 Comments
399 pyquote_str = 'PYQUOTE'
400 def t_COMMENT(t):
401 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
402 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
403 if t.value[2:2+len (pyquote_str)] == pyquote_str:
404 t.value = t.value[2+len(pyquote_str):]
405 t.value = t.value.lstrip ()
406 t.type = pyquote_str
407 return t
408 return None
409  
410 t_ignore = " \t\r"
411  
412 def t_NEWLINE(t):
413 r'\n+'
414 t.lexer.lineno += t.value.count("\n")
415  
416 def t_error(t):
417 global input_file
418 raise LexError(t, input_file)
419  
420 # state 'braceignore'
421  
422 def t_braceignore_lbrace(t):
423 r'\{'
424 t.lexer.level +=1
425  
426 def t_braceignore_rbrace(t):
427 r'\}'
428 t.lexer.level -=1
429 # If closing brace, return token
430 if t.lexer.level == 0:
431 t.type = 'RBRACE'
432 return t
433  
434 def t_braceignore_QSTRING (t):
435 r'"([^"]|"")*"'
436 t.lexer.lineno += t.value.count("\n")
437  
438 def t_braceignore_COMMENT(t):
439 r"--(-[^\-\n]|[^\-\n])*(--|\n|-\n|$|-$)"
440 if (t.value.find("\n") >= 0) : t.lexer.lineno += 1
441  
442 def t_braceignore_nonspace(t):
443 r'[^\s\{\}\"-]+|-(?!-)'
444  
445 t_braceignore_ignore = " \t\r"
446  
447 def t_braceignore_NEWLINE(t):
448 r'\n+'
449 t.lexer.lineno += t.value.count("\n")
450  
451 def t_braceignore_error(t):
452 t.lexer.skip(1)
453  
454 class Ctx:
455 def __init__ (self, defined_dict, indent = 0):
456 self.tags_def = 'EXPLICIT' # default = explicit
457 self.indent_lev = 0
458 self.assignments = {}
459 self.dependencies = {}
460 self.pyquotes = []
461 self.defined_dict = defined_dict
462 self.name_ctr = 0
463 def spaces (self):
464 return " " * (4 * self.indent_lev)
465 def indent (self):
466 self.indent_lev += 1
467 def outdent (self):
468 self.indent_lev -= 1
469 assert (self.indent_lev >= 0)
470 def register_assignment (self, ident, val, dependencies):
471 if ident in self.assignments:
472 raise DuplicateError("assignment", ident)
473 if ident in self.defined_dict:
474 raise Exception("cross-module duplicates for %s" % ident)
475 self.defined_dict [ident] = 1
476 self.assignments[ident] = val
477 self.dependencies [ident] = dependencies
478 return ""
479 # return "#%s depends on %s" % (ident, str (dependencies))
480 def register_pyquote (self, val):
481 self.pyquotes.append (val)
482 return ""
483 def output_assignments (self):
484 already_output = {}
485 text_list = []
486 assign_keys = list(self.assignments.keys())
487 to_output_count = len (assign_keys)
488 while True:
489 any_output = 0
490 for (ident, val) in list(self.assignments.items ()):
491 if ident in already_output:
492 continue
493 ok = 1
494 for d in self.dependencies [ident]:
495 if ((d not in already_output) and
496 (d in assign_keys)):
497 ok = 0
498 if ok:
499 text_list.append ("%s=%s" % (ident,
500 self.assignments [ident]))
501 already_output [ident] = 1
502 any_output = 1
503 to_output_count -= 1
504 assert (to_output_count >= 0)
505 if not any_output:
506 if to_output_count == 0:
507 break
508 # OK, we detected a cycle
509 cycle_list = []
510 for ident in list(self.assignments.keys ()):
511 if ident not in already_output:
512 depend_list = [d for d in self.dependencies[ident] if d in assign_keys]
513 cycle_list.append ("%s(%s)" % (ident, ",".join (depend_list)))
514  
515 text_list.append ("# Cycle XXX " + ",".join (cycle_list))
516 for (ident, val) in list(self.assignments.items ()):
517 if ident not in already_output:
518 text_list.append ("%s=%s" % (ident, self.assignments [ident]))
519 break
520  
521 return "\n".join (text_list)
522 def output_pyquotes (self):
523 return "\n".join (self.pyquotes)
524 def make_new_name (self):
525 self.name_ctr += 1
526 return "_compiler_generated_name_%d" % (self.name_ctr,)
527  
528 #--- Flags for EXPORT, USER_DEFINED, NO_EMIT, MAKE_ENUM -------------------------------
529 EF_TYPE = 0x0001
530 EF_VALS = 0x0002
531 EF_ENUM = 0x0004
532 EF_WS_DLL = 0x0010 # exported from shared library
533 EF_EXTERN = 0x0020
534 EF_NO_PROT = 0x0040
535 EF_NO_TYPE = 0x0080
536 EF_UCASE = 0x0100
537 EF_TABLE = 0x0400
538 EF_DEFINE = 0x0800
539 EF_MODULE = 0x1000
540  
541 #--- common dependency computation ---
542 # Input : list of items
543 # dictionary with lists of dependency
544 #
545 #
546 # Output : list of two outputs:
547 # [0] list of items in dependency
548 # [1] list of cycle dependency cycles
549 def dependency_compute(items, dependency, map_fn = lambda t: t, ignore_fn = lambda t: False):
550 item_ord = []
551 item_cyc = []
552 x = {} # already emitted
553 #print '# Dependency computation'
554 for t in items:
555 if map_fn(t) in x:
556 #print 'Continue: %s : %s' % (t, (map_fn(t))
557 continue
558 stack = [t]
559 stackx = {t : dependency.get(t, [])[:]}
560 #print 'Push: %s : %s' % (t, str(stackx[t]))
561 while stack:
562 if stackx[stack[-1]]: # has dependencies
563 d = stackx[stack[-1]].pop(0)
564 if map_fn(d) in x or ignore_fn(d):
565 continue
566 if d in stackx: # cyclic dependency
567 c = stack[:]
568 c.reverse()
569 c = [d] + c[0:c.index(d)+1]
570 c.reverse()
571 item_cyc.append(c)
572 #print 'Cyclic: %s ' % (' -> '.join(c))
573 continue
574 stack.append(d)
575 stackx[d] = dependency.get(d, [])[:]
576 #print 'Push: %s : %s' % (d, str(stackx[d]))
577 else:
578 #print 'Pop: %s' % (stack[-1])
579 del stackx[stack[-1]]
580 e = map_fn(stack.pop())
581 if e in x:
582 continue
583 #print 'Add: %s' % (e)
584 item_ord.append(e)
585 x[e] = True
586 return (item_ord, item_cyc)
587  
588 # Given a filename, return a relative path from the current directory
589 def relpath(filename):
590 return os.path.relpath(filename)
591  
592 # Given a filename, return a relative path from epan/dissectors
593 def rel_dissector_path(filename):
594 path_parts = os.path.abspath(filename).split(os.sep)
595 while (len(path_parts) > 3 and path_parts[0] != 'asn1'):
596 path_parts.pop(0)
597 path_parts.insert(0, '.')
598 return '/'.join(path_parts)
599  
600  
601 #--- EthCtx -------------------------------------------------------------------
602 class EthCtx:
603 def __init__(self, conform, output, indent = 0):
604 self.conform = conform
605 self.output = output
606 self.conform.ectx = self
607 self.output.ectx = self
608 self.encoding = 'per'
609 self.aligned = False
610 self.default_oid_variant = ''
611 self.default_opentype_variant = ''
612 self.default_containing_variant = '_pdu_new'
613 self.default_embedded_pdv_cb = None
614 self.default_external_type_cb = None
615 self.remove_prefix = None
616 self.srcdir = None
617 self.emitted_pdu = {}
618 self.module = {}
619 self.module_ord = []
620 self.all_type_attr = {}
621 self.all_tags = {}
622 self.all_vals = {}
623  
624 def encp(self): # encoding protocol
625 encp = self.encoding
626 return encp
627  
628 # Encoding
629 def Per(self): return self.encoding == 'per'
630 def Ber(self): return self.encoding == 'ber'
631 def Aligned(self): return self.aligned
632 def Unaligned(self): return not self.aligned
633 def NeedTags(self): return self.tag_opt or self.Ber()
634 def NAPI(self): return False # disable planned features
635  
636 def Module(self): # current module name
637 return self.modules[-1][0]
638  
639 def groups(self):
640 return self.group_by_prot or (self.conform.last_group > 0)
641  
642 def dbg(self, d):
643 if (self.dbgopt.find(d) >= 0):
644 return True
645 else:
646 return False
647  
648 def value_max(self, a, b):
649 if (a == 'MAX') or (b == 'MAX'): return 'MAX';
650 if a == 'MIN': return b;
651 if b == 'MIN': return a;
652 try:
653 if (int(a) > int(b)):
654 return a
655 else:
656 return b
657 except (ValueError, TypeError):
658 pass
659 return "MAX((%s),(%s))" % (a, b)
660  
661 def value_min(self, a, b):
662 if (a == 'MIN') or (b == 'MIN'): return 'MIN';
663 if a == 'MAX': return b;
664 if b == 'MAX': return a;
665 try:
666 if (int(a) < int(b)):
667 return a
668 else:
669 return b
670 except (ValueError, TypeError):
671 pass
672 return "MIN((%s),(%s))" % (a, b)
673  
674 def value_get_eth(self, val):
675 if isinstance(val, Value):
676 return val.to_str(self)
677 ethname = val
678 if val in self.value:
679 ethname = self.value[val]['ethname']
680 return ethname
681  
682 def value_get_val(self, nm):
683 val = asn2c(nm)
684 if nm in self.value:
685 if self.value[nm]['import']:
686 v = self.get_val_from_all(nm, self.value[nm]['import'])
687 if v is None:
688 msg = 'Need value of imported value identifier %s from %s (%s)' % (nm, self.value[nm]['import'], self.value[nm]['proto'])
689 warnings.warn_explicit(msg, UserWarning, '', 0)
690 else:
691 val = v
692 else:
693 val = self.value[nm]['value']
694 if isinstance (val, Value):
695 val = val.to_str(self)
696 else:
697 msg = 'Need value of unknown value identifier %s' % (nm)
698 warnings.warn_explicit(msg, UserWarning, '', 0)
699 return val
700  
701 def eth_get_type_attr(self, type):
702 #print "eth_get_type_attr(%s)" % (type)
703 types = [type]
704 while (not self.type[type]['import']):
705 val = self.type[type]['val']
706 #print val
707 ttype = type
708 while (val.type == 'TaggedType'):
709 val = val.val
710 ttype += '/' + UNTAG_TYPE_NAME
711 if (val.type != 'Type_Ref'):
712 if (type != ttype):
713 types.append(ttype)
714 break
715 type = val.val
716 types.append(type)
717 attr = {}
718 #print " ", types
719 while len(types):
720 t = types.pop()
721 if (self.type[t]['import']):
722 attr.update(self.type[t]['attr'])
723 attr.update(self.eth_get_type_attr_from_all(t, self.type[t]['import']))
724 elif (self.type[t]['val'].type == 'SelectionType'):
725 val = self.type[t]['val']
726 (ftype, display) = val.eth_ftype(self)
727 attr.update({ 'TYPE' : ftype, 'DISPLAY' : display,
728 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' });
729 else:
730 attr.update(self.type[t]['attr'])
731 attr.update(self.eth_type[self.type[t]['ethname']]['attr'])
732 #print " ", attr
733 return attr
734  
735 def eth_get_type_attr_from_all(self, type, module):
736 attr = {}
737 if module in self.all_type_attr and type in self.all_type_attr[module]:
738 attr = self.all_type_attr[module][type]
739 return attr
740  
741 def get_ttag_from_all(self, type, module):
742 ttag = None
743 if module in self.all_tags and type in self.all_tags[module]:
744 ttag = self.all_tags[module][type]
745 return ttag
746  
747 def get_val_from_all(self, nm, module):
748 val = None
749 if module in self.all_vals and nm in self.all_vals[module]:
750 val = self.all_vals[module][nm]
751 return val
752  
753 def get_obj_repr(self, ident, flds=[], not_flds=[]):
754 def set_type_fn(cls, field, fnfield):
755 obj[fnfield + '_fn'] = 'NULL'
756 obj[fnfield + '_pdu'] = 'NULL'
757 if field in val and isinstance(val[field], Type_Ref):
758 p = val[field].eth_type_default_pars(self, '')
759 obj[fnfield + '_fn'] = p['TYPE_REF_FN']
760 obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p # one iteration
761 if (self.conform.check_item('PDU', cls + '.' + field)):
762 obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname']
763 return
764 # end of get_type_fn()
765 obj = { '_name' : ident, '_ident' : asn2c(ident)}
766 obj['_class'] = self.oassign[ident].cls
767 obj['_module'] = self.oassign[ident].module
768 val = self.oassign[ident].val
769 for f in flds:
770 if f not in val:
771 return None
772 for f in not_flds:
773 if f in val:
774 return None
775 for f in list(val.keys()):
776 if isinstance(val[f], Node):
777 obj[f] = val[f].fld_obj_repr(self)
778 else:
779 obj[f] = str(val[f])
780 if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'):
781 set_type_fn(obj['_class'], '&Type', '_type')
782 if (obj['_class'] == 'OPERATION'):
783 set_type_fn(obj['_class'], '&ArgumentType', '_argument')
784 set_type_fn(obj['_class'], '&ResultType', '_result')
785 if (obj['_class'] == 'ERROR'):
786 set_type_fn(obj['_class'], '&ParameterType', '_parameter')
787 return obj
788  
789 #--- eth_reg_module -----------------------------------------------------------
790 def eth_reg_module(self, module):
791 #print "eth_reg_module(module='%s')" % (module)
792 name = module.get_name()
793 self.modules.append([name, module.get_proto(self)])
794 if name in self.module:
795 raise DuplicateError("module", name)
796 self.module[name] = []
797 self.module_ord.append(name)
798  
799 #--- eth_module_dep_add ------------------------------------------------------------
800 def eth_module_dep_add(self, module, dep):
801 self.module[module].append(dep)
802  
803 #--- eth_exports ------------------------------------------------------------
804 def eth_exports(self, exports):
805 self.exports_all = False
806 if ((len(exports) == 1) and (exports[0] == 'ALL')):
807 self.exports_all = True
808 return
809 for e in (exports):
810 if isinstance(e, Type_Ref):
811 self.exports.append(e.val)
812 elif isinstance(e, Class_Ref):
813 self.cexports.append(e.val)
814 else:
815 self.vexports.append(e)
816  
817 #--- eth_reg_assign ---------------------------------------------------------
818 def eth_reg_assign(self, ident, val, virt=False):
819 #print "eth_reg_assign(ident='%s')" % (ident)
820 if ident in self.assign:
821 raise DuplicateError("assignment", ident)
822 self.assign[ident] = { 'val' : val , 'virt' : virt }
823 self.assign_ord.append(ident)
824 if (self.exports_all):
825 self.exports.append(ident)
826  
827 #--- eth_reg_vassign --------------------------------------------------------
828 def eth_reg_vassign(self, vassign):
829 ident = vassign.ident
830 #print "eth_reg_vassign(ident='%s')" % (ident)
831 if ident in self.vassign:
832 raise DuplicateError("value assignment", ident)
833 self.vassign[ident] = vassign
834 self.vassign_ord.append(ident)
835 if (self.exports_all):
836 self.vexports.append(ident)
837  
838 #--- eth_reg_oassign --------------------------------------------------------
839 def eth_reg_oassign(self, oassign):
840 ident = oassign.ident
841 #print "eth_reg_oassign(ident='%s')" % (ident)
842 if ident in self.oassign:
843 if self.oassign[ident] == oassign:
844 return # OK - already defined
845 else:
846 raise DuplicateError("information object assignment", ident)
847 self.oassign[ident] = oassign
848 self.oassign_ord.append(ident)
849 self.oassign_cls.setdefault(oassign.cls, []).append(ident)
850  
851 #--- eth_import_type --------------------------------------------------------
852 def eth_import_type(self, ident, mod, proto):
853 #print "eth_import_type(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
854 if ident in self.type:
855 #print "already defined '%s' import=%s, module=%s" % (ident, str(self.type[ident]['import']), self.type[ident].get('module', '-'))
856 if not self.type[ident]['import'] and (self.type[ident]['module'] == mod) :
857 return # OK - already defined
858 elif self.type[ident]['import'] and (self.type[ident]['import'] == mod) :
859 return # OK - already imported
860 else:
861 raise DuplicateError("type", ident)
862 self.type[ident] = {'import' : mod, 'proto' : proto,
863 'ethname' : '' }
864 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
865 'STRINGS' : 'NULL', 'BITMASK' : '0' }
866 mident = "$%s$%s" % (mod, ident)
867 if (self.conform.check_item('TYPE_ATTR', mident)):
868 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', mident))
869 else:
870 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
871 if (self.conform.check_item('IMPORT_TAG', mident)):
872 self.conform.copy_item('IMPORT_TAG', ident, mident)
873 self.type_imp.append(ident)
874  
875 #--- dummy_import_type --------------------------------------------------------
876 def dummy_import_type(self, ident):
877 # dummy imported
878 if ident in self.type:
879 raise Exception("Try to dummy import for existing type :%s" % ident)
880 ethtype = asn2c(ident)
881 self.type[ident] = {'import' : 'xxx', 'proto' : 'xxx',
882 'ethname' : ethtype }
883 self.type[ident]['attr'] = { 'TYPE' : 'FT_NONE', 'DISPLAY' : 'BASE_NONE',
884 'STRINGS' : 'NULL', 'BITMASK' : '0' }
885 self.eth_type[ethtype] = { 'import' : 'xxx', 'proto' : 'xxx' , 'attr' : {}, 'ref' : []}
886 print("Dummy imported: %s (%s)" % (ident, ethtype))
887 return ethtype
888  
889 #--- eth_import_class --------------------------------------------------------
890 def eth_import_class(self, ident, mod, proto):
891 #print "eth_import_class(ident='%s', mod='%s', prot='%s')" % (ident, mod, proto)
892 if ident in self.objectclass:
893 #print "already defined import=%s, module=%s" % (str(self.objectclass[ident]['import']), self.objectclass[ident]['module'])
894 if not self.objectclass[ident]['import'] and (self.objectclass[ident]['module'] == mod) :
895 return # OK - already defined
896 elif self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == mod) :
897 return # OK - already imported
898 else:
899 raise DuplicateError("object class", ident)
900 self.objectclass[ident] = {'import' : mod, 'proto' : proto,
901 'ethname' : '' }
902 self.objectclass_imp.append(ident)
903  
904 #--- eth_import_value -------------------------------------------------------
905 def eth_import_value(self, ident, mod, proto):
906 #print "eth_import_value(ident='%s', mod='%s', prot='%s')" % (ident, mod, prot)
907 if ident in self.value:
908 #print "already defined import=%s, module=%s" % (str(self.value[ident]['import']), self.value[ident]['module'])
909 if not self.value[ident]['import'] and (self.value[ident]['module'] == mod) :
910 return # OK - already defined
911 elif self.value[ident]['import'] and (self.value[ident]['import'] == mod) :
912 return # OK - already imported
913 else:
914 raise DuplicateError("value", ident)
915 self.value[ident] = {'import' : mod, 'proto' : proto,
916 'ethname' : ''}
917 self.value_imp.append(ident)
918  
919 #--- eth_sel_req ------------------------------------------------------------
920 def eth_sel_req(self, typ, sel):
921 key = typ + '.' + sel
922 if key not in self.sel_req:
923 self.sel_req[key] = { 'typ' : typ , 'sel' : sel}
924 self.sel_req_ord.append(key)
925 return key
926  
927 #--- eth_comp_req ------------------------------------------------------------
928 def eth_comp_req(self, type):
929 self.comp_req_ord.append(type)
930  
931 #--- eth_dep_add ------------------------------------------------------------
932 def eth_dep_add(self, type, dep):
933 if type not in self.type_dep:
934 self.type_dep[type] = []
935 self.type_dep[type].append(dep)
936  
937 #--- eth_reg_type -----------------------------------------------------------
938 def eth_reg_type(self, ident, val):
939 #print "eth_reg_type(ident='%s', type='%s')" % (ident, val.type)
940 if ident in self.type:
941 if self.type[ident]['import'] and (self.type[ident]['import'] == self.Module()) :
942 # replace imported type
943 del self.type[ident]
944 self.type_imp.remove(ident)
945 else:
946 raise DuplicateError("type", ident)
947 val.ident = ident
948 self.type[ident] = { 'val' : val, 'import' : None }
949 self.type[ident]['module'] = self.Module()
950 self.type[ident]['proto'] = self.proto
951 if len(ident.split('/')) > 1:
952 self.type[ident]['tname'] = val.eth_tname()
953 else:
954 self.type[ident]['tname'] = asn2c(ident)
955 self.type[ident]['export'] = self.conform.use_item('EXPORTS', ident)
956 self.type[ident]['enum'] = self.conform.use_item('MAKE_ENUM', ident)
957 self.type[ident]['vals_ext'] = self.conform.use_item('USE_VALS_EXT', ident)
958 self.type[ident]['user_def'] = self.conform.use_item('USER_DEFINED', ident)
959 self.type[ident]['no_emit'] = self.conform.use_item('NO_EMIT', ident)
960 self.type[ident]['tname'] = self.conform.use_item('TYPE_RENAME', ident, val_dflt=self.type[ident]['tname'])
961 self.type[ident]['ethname'] = ''
962 if (val.type == 'Type_Ref') or (val.type == 'TaggedType') or (val.type == 'SelectionType') :
963 self.type[ident]['attr'] = {}
964 else:
965 (ftype, display) = val.eth_ftype(self)
966 self.type[ident]['attr'] = { 'TYPE' : ftype, 'DISPLAY' : display,
967 'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
968 self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
969 self.type_ord.append(ident)
970 # PDU
971 if (self.conform.check_item('PDU', ident)):
972 self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident))
973  
974 #--- eth_reg_objectclass ----------------------------------------------------------
975 def eth_reg_objectclass(self, ident, val):
976 #print "eth_reg_objectclass(ident='%s')" % (ident)
977 if ident in self.objectclass:
978 if self.objectclass[ident]['import'] and (self.objectclass[ident]['import'] == self.Module()) :
979 # replace imported object class
980 del self.objectclass[ident]
981 self.objectclass_imp.remove(ident)
982 elif isinstance(self.objectclass[ident]['val'], Class_Ref) and \
983 isinstance(val, Class_Ref) and \
984 (self.objectclass[ident]['val'].val == val.val):
985 pass # ignore duplicated CLASS1 ::= CLASS2
986 else:
987 raise DuplicateError("object class", ident)
988 self.objectclass[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto }
989 self.objectclass[ident]['val'] = val
990 self.objectclass[ident]['export'] = self.conform.use_item('EXPORTS', ident)
991 self.objectclass_ord.append(ident)
992  
993 #--- eth_reg_value ----------------------------------------------------------
994 def eth_reg_value(self, ident, type, value, ethname=None):
995 #print "eth_reg_value(ident='%s')" % (ident)
996 if ident in self.value:
997 if self.value[ident]['import'] and (self.value[ident]['import'] == self.Module()) :
998 # replace imported value
999 del self.value[ident]
1000 self.value_imp.remove(ident)
1001 elif ethname:
1002 self.value[ident]['ethname'] = ethname
1003 return
1004 else:
1005 raise DuplicateError("value", ident)
1006 self.value[ident] = { 'import' : None, 'module' : self.Module(), 'proto' : self.proto,
1007 'type' : type, 'value' : value,
1008 'no_emit' : False }
1009 self.value[ident]['export'] = self.conform.use_item('EXPORTS', ident)
1010 self.value[ident]['ethname'] = ''
1011 if (ethname): self.value[ident]['ethname'] = ethname
1012 self.value_ord.append(ident)
1013  
1014 #--- eth_reg_field ----------------------------------------------------------
1015 def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
1016 #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
1017 if ident in self.field:
1018 if pdu and (type == self.field[ident]['type']):
1019 pass # OK already created PDU
1020 else:
1021 raise DuplicateError("field", ident)
1022 self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
1023 'modified' : '', 'attr' : {} }
1024 name = ident.split('/')[-1]
1025 if self.remove_prefix and name.startswith(self.remove_prefix):
1026 name = name[len(self.remove_prefix):]
1027  
1028 if len(ident.split('/')) > 1 and name == ITEM_FIELD_NAME: # Sequence/Set of type
1029 if len(self.field[ident]['type'].split('/')) > 1:
1030 self.field[ident]['attr']['NAME'] = '"%s item"' % ident.split('/')[-2]
1031 self.field[ident]['attr']['ABBREV'] = asn2c(ident.split('/')[-2] + name)
1032 else:
1033 self.field[ident]['attr']['NAME'] = '"%s"' % self.field[ident]['type']
1034 self.field[ident]['attr']['ABBREV'] = asn2c(self.field[ident]['type'])
1035 else:
1036 self.field[ident]['attr']['NAME'] = '"%s"' % name
1037 self.field[ident]['attr']['ABBREV'] = asn2c(name)
1038 if self.conform.check_item('FIELD_ATTR', ident):
1039 self.field[ident]['modified'] = '#' + str(id(self))
1040 self.field[ident]['attr'].update(self.conform.use_item('FIELD_ATTR', ident))
1041 if (pdu):
1042 self.field[ident]['pdu']['export'] = (self.conform.use_item('EXPORTS', ident + '_PDU') != 0)
1043 self.pdu_ord.append(ident)
1044 else:
1045 self.field_ord.append(ident)
1046 if parent:
1047 self.eth_dep_add(parent, type)
1048  
1049 def eth_dummy_eag_field_required(self):
1050 if (not self.dummy_eag_field):
1051 self.dummy_eag_field = 'eag_field'
1052  
1053 #--- eth_clean --------------------------------------------------------------
1054 def eth_clean(self):
1055 self.proto = self.proto_opt;
1056 #--- ASN.1 tables ----------------
1057 self.assign = {}
1058 self.assign_ord = []
1059 self.field = {}
1060 self.pdu_ord = []
1061 self.field_ord = []
1062 self.type = {}
1063 self.type_ord = []
1064 self.type_imp = []
1065 self.type_dep = {}
1066 self.sel_req = {}
1067 self.sel_req_ord = []
1068 self.comp_req_ord = []
1069 self.vassign = {}
1070 self.vassign_ord = []
1071 self.value = {}
1072 self.value_ord = []
1073 self.value_imp = []
1074 self.objectclass = {}
1075 self.objectclass_ord = []
1076 self.objectclass_imp = []
1077 self.oassign = {}
1078 self.oassign_ord = []
1079 self.oassign_cls = {}
1080 #--- Modules ------------
1081 self.modules = []
1082 self.exports_all = False
1083 self.exports = []
1084 self.cexports = []
1085 self.vexports = []
1086 #--- types -------------------
1087 self.eth_type = {}
1088 self.eth_type_ord = []
1089 self.eth_export_ord = []
1090 self.eth_type_dupl = {}
1091 self.named_bit = []
1092 #--- value dependencies -------------------
1093 self.value_dep = {}
1094 #--- values -------------------
1095 self.eth_value = {}
1096 self.eth_value_ord = []
1097 #--- fields -------------------------
1098 self.eth_hf = {}
1099 self.eth_hf_ord = []
1100 self.eth_hfpdu_ord = []
1101 self.eth_hf_dupl = {}
1102 self.dummy_eag_field = None
1103 #--- type dependencies -------------------
1104 self.eth_type_ord1 = []
1105 self.eth_dep_cycle = []
1106 self.dep_cycle_eth_type = {}
1107 #--- value dependencies and export -------------------
1108 self.eth_value_ord1 = []
1109 self.eth_vexport_ord = []
1110  
1111 #--- eth_prepare ------------------------------------------------------------
1112 def eth_prepare(self):
1113 self.eproto = asn2c(self.proto)
1114  
1115 #--- dummy types/fields for PDU registration ---
1116 nm = 'NULL'
1117 if (self.conform.check_item('PDU', nm)):
1118 self.eth_reg_type('_dummy/'+nm, NullType())
1119 self.eth_reg_field(nm, '_dummy/'+nm, pdu=self.conform.use_item('PDU', nm))
1120  
1121 #--- required PDUs ----------------------------
1122 for t in self.type_ord:
1123 pdu = self.type[t]['val'].eth_need_pdu(self)
1124 if not pdu: continue
1125 f = pdu['type']
1126 pdu['reg'] = None
1127 pdu['hidden'] = False
1128 pdu['need_decl'] = True
1129 if f not in self.field:
1130 self.eth_reg_field(f, f, pdu=pdu)
1131  
1132 #--- values -> named values -------------------
1133 t_for_update = {}
1134 for v in self.value_ord:
1135 if (self.value[v]['type'].type == 'Type_Ref') or self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1136 if self.conform.check_item('ASSIGN_VALUE_TO_TYPE', v):
1137 tnm = self.conform.use_item('ASSIGN_VALUE_TO_TYPE', v)
1138 else:
1139 tnm = self.value[v]['type'].val
1140 if tnm in self.type \
1141 and not self.type[tnm]['import'] \
1142 and (self.type[tnm]['val'].type == 'IntegerType'):
1143 self.type[tnm]['val'].add_named_value(v, self.value[v]['value'])
1144 self.value[v]['no_emit'] = True
1145 t_for_update[tnm] = True
1146 for t in list(t_for_update.keys()):
1147 self.type[t]['attr']['STRINGS'] = self.type[t]['val'].eth_strings()
1148 self.type[t]['attr'].update(self.conform.use_item('TYPE_ATTR', t))
1149  
1150 #--- required components of ---------------------------
1151 #print "self.comp_req_ord = ", self.comp_req_ord
1152 for t in self.comp_req_ord:
1153 self.type[t]['val'].eth_reg_sub(t, self, components_available=True)
1154  
1155 #--- required selection types ---------------------------
1156 #print "self.sel_req_ord = ", self.sel_req_ord
1157 for t in self.sel_req_ord:
1158 tt = self.sel_req[t]['typ']
1159 if tt not in self.type:
1160 self.dummy_import_type(t)
1161 elif self.type[tt]['import']:
1162 self.eth_import_type(t, self.type[tt]['import'], self.type[tt]['proto'])
1163 else:
1164 self.type[tt]['val'].sel_req(t, self.sel_req[t]['sel'], self)
1165  
1166 #--- types -------------------
1167 for t in self.type_imp: # imported types
1168 nm = asn2c(t)
1169 self.eth_type[nm] = { 'import' : self.type[t]['import'],
1170 'proto' : asn2c(self.type[t]['proto']),
1171 'attr' : {}, 'ref' : []}
1172 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1173 self.type[t]['ethname'] = nm
1174 for t in self.type_ord: # dummy import for missing type reference
1175 tp = self.type[t]['val']
1176 #print "X : %s %s " % (t, tp.type)
1177 if isinstance(tp, TaggedType):
1178 #print "%s : %s " % (tp.type, t)
1179 tp = tp.val
1180 if isinstance(tp, Type_Ref):
1181 #print "%s : %s ::= %s " % (tp.type, t, tp.val)
1182 if tp.val not in self.type:
1183 self.dummy_import_type(tp.val)
1184 for t in self.type_ord:
1185 nm = self.type[t]['tname']
1186 if ((nm.find('#') >= 0) or
1187 ((len(t.split('/'))>1) and
1188 (self.conform.get_fn_presence(t) or self.conform.check_item('FN_PARS', t) or
1189 self.conform.get_fn_presence('/'.join((t,ITEM_FIELD_NAME))) or self.conform.check_item('FN_PARS', '/'.join((t,ITEM_FIELD_NAME)))) and
1190 not self.conform.check_item('TYPE_RENAME', t))):
1191 if len(t.split('/')) == 2 and t.split('/')[1] == ITEM_FIELD_NAME: # Sequence of type at the 1st level
1192 nm = t.split('/')[0] + t.split('/')[1]
1193 elif t.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type at next levels
1194 nm = 'T_' + self.conform.use_item('FIELD_RENAME', '/'.join(t.split('/')[0:-1]), val_dflt=t.split('/')[-2]) + t.split('/')[-1]
1195 elif t.split('/')[-1] == UNTAG_TYPE_NAME: # Untagged type
1196 nm = self.type['/'.join(t.split('/')[0:-1])]['ethname'] + '_U'
1197 else:
1198 nm = 'T_' + self.conform.use_item('FIELD_RENAME', t, val_dflt=t.split('/')[-1])
1199 nm = asn2c(nm)
1200 if nm in self.eth_type:
1201 if nm in self.eth_type_dupl:
1202 self.eth_type_dupl[nm].append(t)
1203 else:
1204 self.eth_type_dupl[nm] = [self.eth_type[nm]['ref'][0], t]
1205 nm += '_%02d' % (len(self.eth_type_dupl[nm])-1)
1206 if nm in self.eth_type:
1207 self.eth_type[nm]['ref'].append(t)
1208 else:
1209 self.eth_type_ord.append(nm)
1210 self.eth_type[nm] = { 'import' : None, 'proto' : self.eproto, 'export' : 0, 'enum' : 0, 'vals_ext' : 0,
1211 'user_def' : EF_TYPE|EF_VALS, 'no_emit' : EF_TYPE|EF_VALS,
1212 'val' : self.type[t]['val'],
1213 'attr' : {}, 'ref' : [t]}
1214 self.type[t]['ethname'] = nm
1215 if (not self.eth_type[nm]['export'] and self.type[t]['export']): # new export
1216 self.eth_export_ord.append(nm)
1217 self.eth_type[nm]['export'] |= self.type[t]['export']
1218 self.eth_type[nm]['enum'] |= self.type[t]['enum']
1219 self.eth_type[nm]['vals_ext'] |= self.type[t]['vals_ext']
1220 self.eth_type[nm]['user_def'] &= self.type[t]['user_def']
1221 self.eth_type[nm]['no_emit'] &= self.type[t]['no_emit']
1222 if self.type[t]['attr'].get('STRINGS') == '$$':
1223 use_ext = self.type[t]['vals_ext']
1224 if (use_ext):
1225 self.eth_type[nm]['attr']['STRINGS'] = '&%s_ext' % (self.eth_vals_nm(nm))
1226 else:
1227 self.eth_type[nm]['attr']['STRINGS'] = 'VALS(%s)' % (self.eth_vals_nm(nm))
1228 self.eth_type[nm]['attr'].update(self.conform.use_item('ETYPE_ATTR', nm))
1229 for t in self.eth_type_ord:
1230 bits = self.eth_type[t]['val'].eth_named_bits()
1231 if (bits):
1232 for (val, id) in bits:
1233 self.named_bit.append({'name' : id, 'val' : val,
1234 'ethname' : 'hf_%s_%s_%s' % (self.eproto, t, asn2c(id)),
1235 'ftype' : 'FT_BOOLEAN', 'display' : '8',
1236 'strings' : 'NULL',
1237 'bitmask' : '0x'+('80','40','20','10','08','04','02','01')[val%8]})
1238 if self.eth_type[t]['val'].eth_need_tree():
1239 self.eth_type[t]['tree'] = "ett_%s_%s" % (self.eth_type[t]['proto'], t)
1240 else:
1241 self.eth_type[t]['tree'] = None
1242  
1243 #--- register values from enums ------------
1244 for t in self.eth_type_ord:
1245 if (self.eth_type[t]['val'].eth_has_enum(t, self)):
1246 self.eth_type[t]['val'].reg_enum_vals(t, self)
1247  
1248 #--- value dependencies -------------------
1249 for v in self.value_ord:
1250 if isinstance (self.value[v]['value'], Value):
1251 dep = self.value[v]['value'].get_dep()
1252 else:
1253 dep = self.value[v]['value']
1254 if dep and dep in self.value:
1255 self.value_dep.setdefault(v, []).append(dep)
1256  
1257 #--- exports all necessary values
1258 for v in self.value_ord:
1259 if not self.value[v]['export']: continue
1260 deparr = self.value_dep.get(v, [])
1261 while deparr:
1262 d = deparr.pop()
1263 if not self.value[d]['import']:
1264 if not self.value[d]['export']:
1265 self.value[d]['export'] = EF_TYPE
1266 deparr.extend(self.value_dep.get(d, []))
1267  
1268 #--- values -------------------
1269 for v in self.value_imp:
1270 nm = asn2c(v)
1271 self.eth_value[nm] = { 'import' : self.value[v]['import'],
1272 'proto' : asn2c(self.value[v]['proto']),
1273 'ref' : []}
1274 self.value[v]['ethname'] = nm
1275 for v in self.value_ord:
1276 if (self.value[v]['ethname']):
1277 continue
1278 if (self.value[v]['no_emit']):
1279 continue
1280 nm = asn2c(v)
1281 self.eth_value[nm] = { 'import' : None,
1282 'proto' : asn2c(self.value[v]['proto']),
1283 'export' : self.value[v]['export'], 'ref' : [v] }
1284 self.eth_value[nm]['value'] = self.value[v]['value']
1285 self.eth_value_ord.append(nm)
1286 self.value[v]['ethname'] = nm
1287  
1288 #--- fields -------------------------
1289 for f in (self.pdu_ord + self.field_ord):
1290 if len(f.split('/')) > 1 and f.split('/')[-1] == ITEM_FIELD_NAME: # Sequence/Set of type
1291 nm = self.conform.use_item('FIELD_RENAME', '/'.join(f.split('/')[0:-1]), val_dflt=f.split('/')[-2]) + f.split('/')[-1]
1292 else:
1293 nm = f.split('/')[-1]
1294 nm = self.conform.use_item('FIELD_RENAME', f, val_dflt=nm)
1295 nm = asn2c(nm)
1296 if (self.field[f]['pdu']):
1297 nm += '_PDU'
1298 if (not self.merge_modules or self.field[f]['pdu']['export']):
1299 nm = self.eproto + '_' + nm
1300 t = self.field[f]['type']
1301 if t in self.type:
1302 ethtype = self.type[t]['ethname']
1303 else: # undefined type
1304 ethtype = self.dummy_import_type(t)
1305 ethtypemod = ethtype + self.field[f]['modified']
1306 if nm in self.eth_hf:
1307 if nm in self.eth_hf_dupl:
1308 if ethtypemod in self.eth_hf_dupl[nm]:
1309 nm = self.eth_hf_dupl[nm][ethtypemod]
1310 self.eth_hf[nm]['ref'].append(f)
1311 self.field[f]['ethname'] = nm
1312 continue
1313 else:
1314 nmx = nm + ('_%02d' % (len(self.eth_hf_dupl[nm])))
1315 self.eth_hf_dupl[nm][ethtype] = nmx
1316 nm = nmx
1317 else:
1318 if (self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified']) == ethtypemod:
1319 self.eth_hf[nm]['ref'].append(f)
1320 self.field[f]['ethname'] = nm
1321 continue
1322 else:
1323 nmx = nm + '_01'
1324 self.eth_hf_dupl[nm] = {self.eth_hf[nm]['ethtype']+self.eth_hf[nm]['modified'] : nm, \
1325 ethtypemod : nmx}
1326 nm = nmx
1327 if (self.field[f]['pdu']):
1328 self.eth_hfpdu_ord.append(nm)
1329 else:
1330 self.eth_hf_ord.append(nm)
1331 fullname = 'hf_%s_%s' % (self.eproto, nm)
1332 attr = self.eth_get_type_attr(self.field[f]['type']).copy()
1333 attr.update(self.field[f]['attr'])
1334 if (self.NAPI() and 'NAME' in attr):
1335 attr['NAME'] += self.field[f]['idx']
1336 attr.update(self.conform.use_item('EFIELD_ATTR', nm))
1337 use_vals_ext = self.eth_type[ethtype].get('vals_ext')
1338 if (use_vals_ext):
1339 attr['DISPLAY'] += '|BASE_EXT_STRING'
1340 self.eth_hf[nm] = {'fullname' : fullname, 'pdu' : self.field[f]['pdu'],
1341 'ethtype' : ethtype, 'modified' : self.field[f]['modified'],
1342 'attr' : attr.copy(),
1343 'ref' : [f]}
1344 self.field[f]['ethname'] = nm
1345 if (self.dummy_eag_field):
1346 # Prepending "dummy_" avoids matching checkhf.pl.
1347 self.dummy_eag_field = 'dummy_hf_%s_%s' % (self.eproto, self.dummy_eag_field)
1348 #--- type dependencies -------------------
1349 (self.eth_type_ord1, self.eth_dep_cycle) = dependency_compute(self.type_ord, self.type_dep, map_fn = lambda t: self.type[t]['ethname'], ignore_fn = lambda t: self.type[t]['import'])
1350 i = 0
1351 while i < len(self.eth_dep_cycle):
1352 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1353 self.dep_cycle_eth_type.setdefault(t, []).append(i)
1354 i += 1
1355  
1356 #--- value dependencies and export -------------------
1357 for v in self.eth_value_ord:
1358 if self.eth_value[v]['export']:
1359 self.eth_vexport_ord.append(v)
1360 else:
1361 self.eth_value_ord1.append(v)
1362  
1363 #--- export tags, values, ... ---
1364 for t in self.exports:
1365 if t not in self.type:
1366 continue
1367 if self.type[t]['import']:
1368 continue
1369 m = self.type[t]['module']
1370 if not self.Per():
1371 if m not in self.all_tags:
1372 self.all_tags[m] = {}
1373 self.all_tags[m][t] = self.type[t]['val'].GetTTag(self)
1374 if m not in self.all_type_attr:
1375 self.all_type_attr[m] = {}
1376 self.all_type_attr[m][t] = self.eth_get_type_attr(t).copy()
1377 for v in self.vexports:
1378 if v not in self.value:
1379 continue
1380 if self.value[v]['import']:
1381 continue
1382 m = self.value[v]['module']
1383 if m not in self.all_vals:
1384 self.all_vals[m] = {}
1385 vv = self.value[v]['value']
1386 if isinstance (vv, Value):
1387 vv = vv.to_str(self)
1388 self.all_vals[m][v] = vv
1389  
1390 #--- eth_vals_nm ------------------------------------------------------------
1391 def eth_vals_nm(self, tname):
1392 out = ""
1393 if (not self.eth_type[tname]['export'] & EF_NO_PROT):
1394 out += "%s_" % (self.eproto)
1395 out += "%s_vals" % (tname)
1396 return out
1397  
1398 #--- eth_vals ---------------------------------------------------------------
1399 def eth_vals(self, tname, vals):
1400 out = ""
1401 has_enum = self.eth_type[tname]['enum'] & EF_ENUM
1402 use_ext = self.eth_type[tname]['vals_ext']
1403 if (use_ext):
1404 vals.sort(key=lambda vals_entry: int(vals_entry[0]))
1405 if (not self.eth_type[tname]['export'] & EF_VALS):
1406 out += 'static '
1407 if (self.eth_type[tname]['export'] & EF_VALS) and (self.eth_type[tname]['export'] & EF_TABLE):
1408 out += 'static '
1409 out += "const value_string %s[] = {\n" % (self.eth_vals_nm(tname))
1410 for (val, id) in vals:
1411 if (has_enum):
1412 vval = self.eth_enum_item(tname, id)
1413 else:
1414 vval = val
1415 out += ' { %3s, "%s" },\n' % (vval, id)
1416 out += " { 0, NULL }\n};\n"
1417 if (use_ext):
1418 out += "\nstatic value_string_ext %s_ext = VALUE_STRING_EXT_INIT(%s);\n" % (self.eth_vals_nm(tname), self.eth_vals_nm(tname))
1419 return out
1420  
1421 #--- eth_enum_prefix ------------------------------------------------------------
1422 def eth_enum_prefix(self, tname, type=False):
1423 out = ""
1424 if (self.eth_type[tname]['export'] & EF_ENUM):
1425 no_prot = self.eth_type[tname]['export'] & EF_NO_PROT
1426 else:
1427 no_prot = self.eth_type[tname]['enum'] & EF_NO_PROT
1428 if (not no_prot):
1429 out += self.eproto
1430 if ((not self.eth_type[tname]['enum'] & EF_NO_TYPE) or type):
1431 if (out): out += '_'
1432 out += tname
1433 if (self.eth_type[tname]['enum'] & EF_UCASE):
1434 out = out.upper()
1435 if (out): out += '_'
1436 return out
1437  
1438 #--- eth_enum_nm ------------------------------------------------------------
1439 def eth_enum_nm(self, tname):
1440 out = self.eth_enum_prefix(tname, type=True)
1441 out += "enum"
1442 return out
1443  
1444 #--- eth_enum_item ---------------------------------------------------------------
1445 def eth_enum_item(self, tname, ident):
1446 out = self.eth_enum_prefix(tname)
1447 out += asn2c(ident)
1448 if (self.eth_type[tname]['enum'] & EF_UCASE):
1449 out = out.upper()
1450 return out
1451  
1452 #--- eth_enum ---------------------------------------------------------------
1453 def eth_enum(self, tname, vals):
1454 out = ""
1455 if (self.eth_type[tname]['enum'] & EF_DEFINE):
1456 out += "/* enumerated values for %s */\n" % (tname)
1457 for (val, id) in vals:
1458 out += '#define %-12s %3s\n' % (self.eth_enum_item(tname, id), val)
1459 else:
1460 out += "typedef enum _%s {\n" % (self.eth_enum_nm(tname))
1461 first_line = 1
1462 for (val, id) in vals:
1463 if (first_line == 1):
1464 first_line = 0
1465 else:
1466 out += ",\n"
1467 out += ' %-12s = %3s' % (self.eth_enum_item(tname, id), val)
1468 out += "\n} %s;\n" % (self.eth_enum_nm(tname))
1469 return out
1470  
1471 #--- eth_bits ---------------------------------------------------------------
1472 def eth_bits(self, tname, bits):
1473 out = ""
1474 out += "static const "
1475 out += "asn_namedbit %(TABLE)s[] = {\n"
1476 for (val, id) in bits:
1477 out += ' { %2d, &hf_%s_%s_%s, -1, -1, "%s", NULL },\n' % (val, self.eproto, tname, asn2c(id), id)
1478 out += " { 0, NULL, 0, 0, NULL, NULL }\n};\n"
1479 return out
1480  
1481 #--- eth_type_fn_h ----------------------------------------------------------
1482 def eth_type_fn_h(self, tname):
1483 out = ""
1484 if (not self.eth_type[tname]['export'] & EF_TYPE):
1485 out += 'static '
1486 out += "int "
1487 if (self.Ber()):
1488 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname)
1489 elif (self.Per()):
1490 out += "dissect_%s_%s(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)" % (self.eth_type[tname]['proto'], tname)
1491 out += ";\n"
1492 return out
1493  
1494 #--- eth_fn_call ------------------------------------------------------------
1495 def eth_fn_call(self, fname, ret=None, indent=2, par=None):
1496 out = indent * ' '
1497 if (ret):
1498 if (ret == 'return'):
1499 out += 'return '
1500 else:
1501 out += ret + ' = '
1502 out += fname + '('
1503 ind = len(out)
1504 for i in range(len(par)):
1505 if (i>0): out += ind * ' '
1506 out += ', '.join(par[i])
1507 if (i<(len(par)-1)): out += ',\n'
1508 out += ');\n'
1509 return out
1510  
1511 #--- eth_type_fn_hdr --------------------------------------------------------
1512 def eth_type_fn_hdr(self, tname):
1513 out = '\n'
1514 if (not self.eth_type[tname]['export'] & EF_TYPE):
1515 out += 'static '
1516 out += "int\n"
1517 if (self.Ber()):
1518 out += "dissect_%s_%s(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname)
1519 elif (self.Per()):
1520 out += "dissect_%s_%s(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {\n" % (self.eth_type[tname]['proto'], tname)
1521 #if self.conform.get_fn_presence(tname):
1522 # out += self.conform.get_fn_text(tname, 'FN_HDR')
1523 #el
1524 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1525 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_HDR')
1526 return out
1527  
1528 #--- eth_type_fn_ftr --------------------------------------------------------
1529 def eth_type_fn_ftr(self, tname):
1530 out = '\n'
1531 #if self.conform.get_fn_presence(tname):
1532 # out += self.conform.get_fn_text(tname, 'FN_FTR')
1533 #el
1534 if self.conform.get_fn_presence(self.eth_type[tname]['ref'][0]):
1535 out += self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_FTR')
1536 out += " return offset;\n"
1537 out += "}\n"
1538 return out
1539  
1540 #--- eth_type_fn_body -------------------------------------------------------
1541 def eth_type_fn_body(self, tname, body, pars=None):
1542 out = body
1543 #if self.conform.get_fn_body_presence(tname):
1544 # out = self.conform.get_fn_text(tname, 'FN_BODY')
1545 #el
1546 if self.conform.get_fn_body_presence(self.eth_type[tname]['ref'][0]):
1547 out = self.conform.get_fn_text(self.eth_type[tname]['ref'][0], 'FN_BODY')
1548 if pars:
1549 try:
1550 out = out % pars
1551 except (TypeError):
1552 pass
1553 return out
1554  
1555 #--- eth_out_pdu_decl ----------------------------------------------------------
1556 def eth_out_pdu_decl(self, f):
1557 t = self.eth_hf[f]['ethtype']
1558 out = ''
1559 if (not self.eth_hf[f]['pdu']['export']):
1560 out += 'static '
1561 out += 'int '
1562 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);\n'
1563 return out
1564  
1565 #--- eth_output_hf ----------------------------------------------------------
1566 def eth_output_hf (self):
1567 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1568 fx = self.output.file_open('hf')
1569 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1570 fx.write("%-50s/* %s */\n" % ("static int %s = -1; " % (self.eth_hf[f]['fullname']), self.eth_hf[f]['ethtype']))
1571 if (self.named_bit):
1572 fx.write('/* named bits */\n')
1573 for nb in self.named_bit:
1574 fx.write("static int %s = -1;\n" % (nb['ethname']))
1575 if (self.dummy_eag_field):
1576 fx.write("static int %s = -1; /* never registered */\n" % (self.dummy_eag_field))
1577 self.output.file_close(fx)
1578  
1579 #--- eth_output_hf_arr ------------------------------------------------------
1580 def eth_output_hf_arr (self):
1581 if not len(self.eth_hf_ord) and not len(self.eth_hfpdu_ord) and not len(self.named_bit): return
1582 fx = self.output.file_open('hfarr')
1583 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
1584 t = self.eth_hf[f]['ethtype']
1585 if self.remove_prefix and t.startswith(self.remove_prefix):
1586 t = t[len(self.remove_prefix):]
1587 name=self.eth_hf[f]['attr']['NAME']
1588 try: # Python < 3
1589 trantab = maketrans("- ", "__")
1590 except:
1591 trantab = str.maketrans("- ", "__")
1592 name = name.translate(trantab)
1593 namelower = name.lower()
1594 tquoted_lower = '"' + t.lower() + '"'
1595 # Try to avoid giving blurbs that give no more info than the name
1596 if tquoted_lower == namelower or \
1597 t == "NULL" or \
1598 tquoted_lower.replace("t_", "") == namelower:
1599 blurb = 'NULL'
1600 else:
1601 blurb = '"%s"' % (t)
1602 attr = self.eth_hf[f]['attr'].copy()
1603 if attr['TYPE'] == 'FT_NONE':
1604 attr['ABBREV'] = '"%s.%s_element"' % (self.proto, attr['ABBREV'])
1605 else:
1606 attr['ABBREV'] = '"%s.%s"' % (self.proto, attr['ABBREV'])
1607 if 'BLURB' not in attr:
1608 attr['BLURB'] = blurb
1609 fx.write(' { &%s,\n' % (self.eth_hf[f]['fullname']))
1610 fx.write(' { %(NAME)s, %(ABBREV)s,\n' % attr)
1611 fx.write(' %(TYPE)s, %(DISPLAY)s, %(STRINGS)s, %(BITMASK)s,\n' % attr)
1612 fx.write(' %(BLURB)s, HFILL }},\n' % attr)
1613 for nb in self.named_bit:
1614 fx.write(' { &%s,\n' % (nb['ethname']))
1615 fx.write(' { "%s", "%s.%s",\n' % (nb['name'], self.proto, nb['name']))
1616 fx.write(' %s, %s, %s, %s,\n' % (nb['ftype'], nb['display'], nb['strings'], nb['bitmask']))
1617 fx.write(' NULL, HFILL }},\n')
1618 self.output.file_close(fx)
1619  
1620 #--- eth_output_ett ---------------------------------------------------------
1621 def eth_output_ett (self):
1622 fx = self.output.file_open('ett')
1623 fempty = True
1624 #fx.write("static gint ett_%s = -1;\n" % (self.eproto))
1625 for t in self.eth_type_ord:
1626 if self.eth_type[t]['tree']:
1627 fx.write("static gint %s = -1;\n" % (self.eth_type[t]['tree']))
1628 fempty = False
1629 self.output.file_close(fx, discard=fempty)
1630  
1631 #--- eth_output_ett_arr -----------------------------------------------------
1632 def eth_output_ett_arr(self):
1633 fx = self.output.file_open('ettarr')
1634 fempty = True
1635 #fx.write(" &ett_%s,\n" % (self.eproto))
1636 for t in self.eth_type_ord:
1637 if self.eth_type[t]['tree']:
1638 fx.write(" &%s,\n" % (self.eth_type[t]['tree']))
1639 fempty = False
1640 self.output.file_close(fx, discard=fempty)
1641  
1642 #--- eth_output_export ------------------------------------------------------
1643 def eth_output_export(self):
1644 fx = self.output.file_open('exp', ext='h')
1645 for t in self.eth_export_ord: # vals
1646 if (self.eth_type[t]['export'] & EF_ENUM) and self.eth_type[t]['val'].eth_has_enum(t, self):
1647 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1648 if (self.eth_type[t]['export'] & EF_VALS) and self.eth_type[t]['val'].eth_has_vals():
1649 if not self.eth_type[t]['export'] & EF_TABLE:
1650 if self.eth_type[t]['export'] & EF_WS_DLL:
1651 fx.write("WS_DLL_PUBLIC ")
1652 else:
1653 fx.write("extern ")
1654 fx.write("const value_string %s[];\n" % (self.eth_vals_nm(t)))
1655 else:
1656 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1657 for t in self.eth_export_ord: # functions
1658 if (self.eth_type[t]['export'] & EF_TYPE):
1659 if self.eth_type[t]['export'] & EF_EXTERN:
1660 if self.eth_type[t]['export'] & EF_WS_DLL:
1661 fx.write("WS_DLL_PUBLIC ")
1662 else:
1663 fx.write("extern ")
1664 fx.write(self.eth_type_fn_h(t))
1665 for f in self.eth_hfpdu_ord: # PDUs
1666 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['export']):
1667 fx.write(self.eth_out_pdu_decl(f))
1668 self.output.file_close(fx)
1669  
1670 #--- eth_output_expcnf ------------------------------------------------------
1671 def eth_output_expcnf(self):
1672 fx = self.output.file_open('exp', ext='cnf')
1673 fx.write('#.MODULE\n')
1674 maxw = 0
1675 for (m, p) in self.modules:
1676 if (len(m) > maxw): maxw = len(m)
1677 for (m, p) in self.modules:
1678 fx.write("%-*s %s\n" % (maxw, m, p))
1679 fx.write('#.END\n\n')
1680 for cls in self.objectclass_ord:
1681 if self.objectclass[cls]['export']:
1682 cnm = cls
1683 if self.objectclass[cls]['export'] & EF_MODULE:
1684 cnm = "$%s$%s" % (self.objectclass[cls]['module'], cnm)
1685 fx.write('#.CLASS %s\n' % (cnm))
1686 maxw = 2
1687 for fld in self.objectclass[cls]['val'].fields:
1688 w = len(fld.fld_repr()[0])
1689 if (w > maxw): maxw = w
1690 for fld in self.objectclass[cls]['val'].fields:
1691 repr = fld.fld_repr()
1692 fx.write('%-*s %s\n' % (maxw, repr[0], ' '.join(repr[1:])))
1693 fx.write('#.END\n\n')
1694 if self.Ber():
1695 fx.write('#.IMPORT_TAG\n')
1696 for t in self.eth_export_ord: # tags
1697 if (self.eth_type[t]['export'] & EF_TYPE):
1698 fx.write('%-24s ' % self.eth_type[t]['ref'][0])
1699 fx.write('%s %s\n' % self.eth_type[t]['val'].GetTag(self))
1700 fx.write('#.END\n\n')
1701 fx.write('#.TYPE_ATTR\n')
1702 for t in self.eth_export_ord: # attributes
1703 if (self.eth_type[t]['export'] & EF_TYPE):
1704 tnm = self.eth_type[t]['ref'][0]
1705 if self.eth_type[t]['export'] & EF_MODULE:
1706 tnm = "$%s$%s" % (self.type[tnm]['module'], tnm)
1707 fx.write('%-24s ' % tnm)
1708 attr = self.eth_get_type_attr(self.eth_type[t]['ref'][0]).copy()
1709 fx.write('TYPE = %(TYPE)-9s DISPLAY = %(DISPLAY)-9s STRINGS = %(STRINGS)s BITMASK = %(BITMASK)s\n' % attr)
1710 fx.write('#.END\n\n')
1711 self.output.file_close(fx, keep_anyway=True)
1712  
1713 #--- eth_output_val ------------------------------------------------------
1714 def eth_output_val(self):
1715 fx = self.output.file_open('val', ext='h')
1716 for v in self.eth_value_ord1:
1717 vv = self.eth_value[v]['value']
1718 if isinstance (vv, Value):
1719 vv = vv.to_str(self)
1720 fx.write("#define %-30s %s\n" % (v, vv))
1721 for t in self.eth_type_ord1:
1722 if self.eth_type[t]['import']:
1723 continue
1724 if self.eth_type[t]['val'].eth_has_enum(t, self) and not (self.eth_type[t]['export'] & EF_ENUM):
1725 fx.write(self.eth_type[t]['val'].eth_type_enum(t, self))
1726 self.output.file_close(fx)
1727  
1728 #--- eth_output_valexp ------------------------------------------------------
1729 def eth_output_valexp(self):
1730 if (not len(self.eth_vexport_ord)): return
1731 fx = self.output.file_open('valexp', ext='h')
1732 for v in self.eth_vexport_ord:
1733 vv = self.eth_value[v]['value']
1734 if isinstance (vv, Value):
1735 vv = vv.to_str(self)
1736 fx.write("#define %-30s %s\n" % (v, vv))
1737 self.output.file_close(fx)
1738  
1739 #--- eth_output_types -------------------------------------------------------
1740 def eth_output_types(self):
1741 def out_pdu(f):
1742 t = self.eth_hf[f]['ethtype']
1743 impl = 'FALSE'
1744 out = ''
1745 if (not self.eth_hf[f]['pdu']['export']):
1746 out += 'static '
1747 out += 'int '
1748 out += 'dissect_'+f+'(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {\n'
1749 out += ' int offset = 0;\n'
1750 off_par = 'offset'
1751 ret_par = 'offset'
1752 if (self.Per()):
1753 if (self.Aligned()):
1754 aligned = 'TRUE'
1755 else:
1756 aligned = 'FALSE'
1757 out += " asn1_ctx_t asn1_ctx;\n"
1758 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_PER', aligned, 'pinfo'),))
1759 if (self.Ber()):
1760 out += " asn1_ctx_t asn1_ctx;\n"
1761 out += self.eth_fn_call('asn1_ctx_init', par=(('&asn1_ctx', 'ASN1_ENC_BER', 'TRUE', 'pinfo'),))
1762 par=((impl, 'tvb', off_par,'&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1763 elif (self.Per()):
1764 par=(('tvb', off_par, '&asn1_ctx', 'tree', self.eth_hf[f]['fullname']),)
1765 else:
1766 par=((),)
1767 out += self.eth_fn_call('dissect_%s_%s' % (self.eth_type[t]['proto'], t), ret=ret_par, par=par)
1768 if (self.Per()):
1769 out += ' offset += 7; offset >>= 3;\n'
1770 out += ' return offset;\n'
1771 out += '}\n'
1772 return out
1773 #end out_pdu()
1774 fx = self.output.file_open('fn')
1775 pos = fx.tell()
1776 if (len(self.eth_hfpdu_ord)):
1777 first_decl = True
1778 for f in self.eth_hfpdu_ord:
1779 if (self.eth_hf[f]['pdu'] and self.eth_hf[f]['pdu']['need_decl']):
1780 if first_decl:
1781 fx.write('/*--- PDUs declarations ---*/\n')
1782 first_decl = False
1783 fx.write(self.eth_out_pdu_decl(f))
1784 if not first_decl:
1785 fx.write('\n')
1786 if self.eth_dep_cycle:
1787 fx.write('/*--- Cyclic dependencies ---*/\n\n')
1788 i = 0
1789 while i < len(self.eth_dep_cycle):
1790 t = self.type[self.eth_dep_cycle[i][0]]['ethname']
1791 if self.dep_cycle_eth_type[t][0] != i: i += 1; continue
1792 fx.write(''.join(['/* %s */\n' % ' -> '.join(self.eth_dep_cycle[i]) for i in self.dep_cycle_eth_type[t]]))
1793 if not self.eth_type[t]['export'] & EF_TYPE:
1794 fx.write(self.eth_type_fn_h(t))
1795 else:
1796 fx.write('/*' + self.eth_type_fn_h(t).strip() + '*/\n')
1797 fx.write('\n')
1798 i += 1
1799 fx.write('\n')
1800 for t in self.eth_type_ord1:
1801 if self.eth_type[t]['import']:
1802 continue
1803 if self.eth_type[t]['val'].eth_has_vals():
1804 if self.eth_type[t]['no_emit'] & EF_VALS:
1805 pass
1806 elif self.eth_type[t]['user_def'] & EF_VALS:
1807 fx.write("extern const value_string %s[];\n" % (self.eth_vals_nm(t)))
1808 elif (self.eth_type[t]['export'] & EF_VALS) and (self.eth_type[t]['export'] & EF_TABLE):
1809 pass
1810 else:
1811 fx.write(self.eth_type[t]['val'].eth_type_vals(t, self))
1812 if self.eth_type[t]['no_emit'] & EF_TYPE:
1813 pass
1814 elif self.eth_type[t]['user_def'] & EF_TYPE:
1815 fx.write(self.eth_type_fn_h(t))
1816 else:
1817 fx.write(self.eth_type[t]['val'].eth_type_fn(self.eth_type[t]['proto'], t, self))
1818 fx.write('\n')
1819 if (len(self.eth_hfpdu_ord)):
1820 fx.write('/*--- PDUs ---*/\n\n')
1821 for f in self.eth_hfpdu_ord:
1822 if (self.eth_hf[f]['pdu']):
1823 if (f in self.emitted_pdu):
1824 fx.write(" /* %s already emitted */\n" % (f))
1825 else:
1826 fx.write(out_pdu(f))
1827 self.emitted_pdu[f] = True
1828 fx.write('\n')
1829 fempty = pos == fx.tell()
1830 self.output.file_close(fx, discard=fempty)
1831  
1832 #--- eth_output_dis_hnd -----------------------------------------------------
1833 def eth_output_dis_hnd(self):
1834 fx = self.output.file_open('dis-hnd')
1835 fempty = True
1836 for f in self.eth_hfpdu_ord:
1837 pdu = self.eth_hf[f]['pdu']
1838 if (pdu and pdu['reg'] and not pdu['hidden']):
1839 dis = self.proto
1840 if (pdu['reg'] != '.'):
1841 dis += '.' + pdu['reg']
1842 fx.write('static dissector_handle_t %s_handle;\n' % (asn2c(dis)))
1843 fempty = False
1844 fx.write('\n')
1845 self.output.file_close(fx, discard=fempty)
1846  
1847 #--- eth_output_dis_reg -----------------------------------------------------
1848 def eth_output_dis_reg(self):
1849 fx = self.output.file_open('dis-reg')
1850 fempty = True
1851 for f in self.eth_hfpdu_ord:
1852 pdu = self.eth_hf[f]['pdu']
1853 if (pdu and pdu['reg']):
1854 new_prefix = ''
1855 if (pdu['new']): new_prefix = 'new_'
1856 dis = self.proto
1857 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1858 fx.write(' %sregister_dissector("%s", dissect_%s, proto_%s);\n' % (new_prefix, dis, f, self.eproto))
1859 if (not pdu['hidden']):
1860 fx.write(' %s_handle = find_dissector("%s");\n' % (asn2c(dis), dis))
1861 fempty = False
1862 fx.write('\n')
1863 self.output.file_close(fx, discard=fempty)
1864  
1865 #--- eth_output_dis_tab -----------------------------------------------------
1866 def eth_output_dis_tab(self):
1867 fx = self.output.file_open('dis-tab')
1868 fempty = True
1869 for k in self.conform.get_order('REGISTER'):
1870 reg = self.conform.use_item('REGISTER', k)
1871 if reg['pdu'] not in self.field: continue
1872 f = self.field[reg['pdu']]['ethname']
1873 pdu = self.eth_hf[f]['pdu']
1874 new_prefix = ''
1875 if (pdu['new']): new_prefix = 'new_'
1876 if (reg['rtype'] in ('NUM', 'STR')):
1877 rstr = ''
1878 if (reg['rtype'] == 'STR'):
1879 rstr = 'string'
1880 else:
1881 rstr = 'uint'
1882 if (pdu['reg']):
1883 dis = self.proto
1884 if (pdu['reg'] != '.'): dis += '.' + pdu['reg']
1885 if (not pdu['hidden']):
1886 hnd = '%s_handle' % (asn2c(dis))
1887 else:
1888 hnd = 'find_dissector("%s")' % (dis)
1889 else:
1890 hnd = '%screate_dissector_handle(dissect_%s, proto_%s)' % (new_prefix, f, self.eproto)
1891 rport = self.value_get_eth(reg['rport'])
1892 fx.write(' dissector_add_%s("%s", %s, %s);\n' % (rstr, reg['rtable'], rport, hnd))
1893 elif (reg['rtype'] in ('BER', 'PER')):
1894 roid = self.value_get_eth(reg['roid'])
1895 fx.write(' %sregister_%s_oid_dissector(%s, dissect_%s, proto_%s, %s);\n' % (new_prefix, reg['rtype'].lower(), roid, f, self.eproto, reg['roidname']))
1896 fempty = False
1897 fx.write('\n')
1898 self.output.file_close(fx, discard=fempty)
1899  
1900 #--- eth_output_syn_reg -----------------------------------------------------
1901 def eth_output_syn_reg(self):
1902 fx = self.output.file_open('syn-reg')
1903 fempty = True
1904 first_decl = True
1905 for k in self.conform.get_order('SYNTAX'):
1906 reg = self.conform.use_item('SYNTAX', k)
1907 if reg['pdu'] not in self.field: continue
1908 f = self.field[reg['pdu']]['ethname']
1909 pdu = self.eth_hf[f]['pdu']
1910 new_prefix = ''
1911 if (pdu['new']): new_prefix = 'new_'
1912 if first_decl:
1913 fx.write(' /*--- Syntax registrations ---*/\n')
1914 first_decl = False
1915 fx.write(' %sregister_ber_syntax_dissector(%s, proto_%s, dissect_%s_PDU);\n' % (new_prefix, k, self.eproto, reg['pdu']));
1916 fempty=False
1917 self.output.file_close(fx, discard=fempty)
1918  
1919 #--- eth_output_tables -----------------------------------------------------
1920 def eth_output_tables(self):
1921 for num in list(self.conform.report.keys()):
1922 fx = self.output.file_open('table' + num)
1923 for rep in self.conform.report[num]:
1924 self.eth_output_table(fx, rep)
1925 self.output.file_close(fx)
1926  
1927 #--- eth_output_table -----------------------------------------------------
1928 def eth_output_table(self, fx, rep):
1929 if rep['type'] == 'HDR':
1930 fx.write('\n')
1931 if rep['var']:
1932 var = rep['var']
1933 var_list = var.split('.', 1)
1934 cls = var_list[0]
1935 del var_list[0]
1936 flds = []
1937 not_flds = []
1938 sort_flds = []
1939 for f in var_list:
1940 if f[0] == '!':
1941 not_flds.append(f[1:])
1942 continue
1943 if f[0] == '#':
1944 flds.append(f[1:])
1945 sort_flds.append(f)
1946 continue
1947 if f[0] == '@':
1948 flds.append(f[1:])
1949 sort_flds.append(f[1:])
1950 continue
1951 flds.append(f)
1952 objs = {}
1953 objs_ord = []
1954 if (cls in self.oassign_cls):
1955 for ident in self.oassign_cls[cls]:
1956 obj = self.get_obj_repr(ident, flds, not_flds)
1957 if not obj:
1958 continue
1959 obj['_LOOP'] = var
1960 obj['_DICT'] = str(obj)
1961 objs[ident] = obj
1962 objs_ord.append(ident)
1963 if (sort_flds):
1964 # Sort identifiers according to the matching object in objs.
1965 # The order is determined by sort_flds, keys prefixed by a
1966 # '#' are compared numerically.
1967 def obj_key_fn(name):
1968 obj = objs[name]
1969 return list(
1970 int(obj[f[1:]]) if f[0] == '#' else obj[f]
1971 for f in sort_flds
1972 )
1973 objs_ord.sort(key=obj_key_fn)
1974 for ident in objs_ord:
1975 obj = objs[ident]
1976 try:
1977 text = rep['text'] % obj
1978 except (KeyError):
1979 raise sys.exc_info()[0]("%s:%s invalid key %s for information object %s of %s" % (rep['fn'], rep['lineno'], sys.exc_info()[1], ident, var))
1980 fx.write(text)
1981 else:
1982 fx.write("/* Unknown or empty loop list %s */\n" % (var))
1983 else:
1984 fx.write(rep['text'])
1985 if rep['type'] == 'FTR':
1986 fx.write('\n')
1987  
1988 #--- dupl_report -----------------------------------------------------
1989 def dupl_report(self):
1990 # types
1991 tmplist = sorted(self.eth_type_dupl.keys())
1992 for t in tmplist:
1993 msg = "The same type names for different types. Explicit type renaming is recommended.\n"
1994 msg += t + "\n"
1995 for tt in self.eth_type_dupl[t]:
1996 msg += " %-20s %s\n" % (self.type[tt]['ethname'], tt)
1997 warnings.warn_explicit(msg, UserWarning, '', 0)
1998 # fields
1999 tmplist = list(self.eth_hf_dupl.keys())
2000 tmplist.sort()
2001 for f in tmplist:
2002 msg = "The same field names for different types. Explicit field renaming is recommended.\n"
2003 msg += f + "\n"
2004 for tt in list(self.eth_hf_dupl[f].keys()):
2005 msg += " %-20s %-20s " % (self.eth_hf_dupl[f][tt], tt)
2006 msg += ", ".join(self.eth_hf[self.eth_hf_dupl[f][tt]]['ref'])
2007 msg += "\n"
2008 warnings.warn_explicit(msg, UserWarning, '', 0)
2009  
2010 #--- eth_do_output ------------------------------------------------------------
2011 def eth_do_output(self):
2012 if self.dbg('a'):
2013 print("\n# Assignments")
2014 for a in self.assign_ord:
2015 v = ' '
2016 if (self.assign[a]['virt']): v = '*'
2017 print(v, a)
2018 print("\n# Value assignments")
2019 for a in self.vassign_ord:
2020 print(' ', a)
2021 print("\n# Information object assignments")
2022 for a in self.oassign_ord:
2023 print(" %-12s (%s)" % (a, self.oassign[a].cls))
2024 if self.dbg('t'):
2025 print("\n# Imported Types")
2026 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2027 print("-" * 100)
2028 for t in self.type_imp:
2029 print("%-40s %-24s %-24s" % (t, self.type[t]['import'], self.type[t]['proto']))
2030 print("\n# Imported Values")
2031 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2032 print("-" * 100)
2033 for t in self.value_imp:
2034 print("%-40s %-24s %-24s" % (t, self.value[t]['import'], self.value[t]['proto']))
2035 print("\n# Imported Object Classes")
2036 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2037 print("-" * 100)
2038 for t in self.objectclass_imp:
2039 print("%-40s %-24s %-24s" % (t, self.objectclass[t]['import'], self.objectclass[t]['proto']))
2040 print("\n# Exported Types")
2041 print("%-31s %s" % ("Wireshark type", "Export Flag"))
2042 print("-" * 100)
2043 for t in self.eth_export_ord:
2044 print("%-31s 0x%02X" % (t, self.eth_type[t]['export']))
2045 print("\n# Exported Values")
2046 print("%-40s %s" % ("Wireshark name", "Value"))
2047 print("-" * 100)
2048 for v in self.eth_vexport_ord:
2049 vv = self.eth_value[v]['value']
2050 if isinstance (vv, Value):
2051 vv = vv.to_str(self)
2052 print("%-40s %s" % (v, vv))
2053 print("\n# ASN.1 Object Classes")
2054 print("%-40s %-24s %-24s" % ("ASN.1 name", "Module", "Protocol"))
2055 print("-" * 100)
2056 for t in self.objectclass_ord:
2057 print("%-40s " % (t))
2058 print("\n# ASN.1 Types")
2059 print("%-49s %-24s %-24s" % ("ASN.1 unique name", "'tname'", "Wireshark type"))
2060 print("-" * 100)
2061 for t in self.type_ord:
2062 print("%-49s %-24s %-24s" % (t, self.type[t]['tname'], self.type[t]['ethname']))
2063 print("\n# Wireshark Types")
2064 print("Wireshark type References (ASN.1 types)")
2065 print("-" * 100)
2066 for t in self.eth_type_ord:
2067 sys.stdout.write("%-31s %d" % (t, len(self.eth_type[t]['ref'])))
2068 print(', '.join(self.eth_type[t]['ref']))
2069 print("\n# ASN.1 Values")
2070 print("%-40s %-18s %-20s %s" % ("ASN.1 unique name", "Type", "Value", "Wireshark value"))
2071 print("-" * 100)
2072 for v in self.value_ord:
2073 vv = self.value[v]['value']
2074 if isinstance (vv, Value):
2075 vv = vv.to_str(self)
2076 print("%-40s %-18s %-20s %s" % (v, self.value[v]['type'].eth_tname(), vv, self.value[v]['ethname']))
2077 #print "\n# Wireshark Values"
2078 #print "%-40s %s" % ("Wireshark name", "Value")
2079 #print "-" * 100
2080 #for v in self.eth_value_ord:
2081 # vv = self.eth_value[v]['value']
2082 # if isinstance (vv, Value):
2083 # vv = vv.to_str(self)
2084 # print "%-40s %s" % (v, vv)
2085 print("\n# ASN.1 Fields")
2086 print("ASN.1 unique name Wireshark name ASN.1 type")
2087 print("-" * 100)
2088 for f in (self.pdu_ord + self.field_ord):
2089 print("%-40s %-20s %s" % (f, self.field[f]['ethname'], self.field[f]['type']))
2090 print("\n# Wireshark Fields")
2091 print("Wireshark name Wireshark type References (ASN.1 fields)")
2092 print("-" * 100)
2093 for f in (self.eth_hfpdu_ord + self.eth_hf_ord):
2094 sys.stdout.write("%-30s %-20s %s" % (f, self.eth_hf[f]['ethtype'], len(self.eth_hf[f]['ref'])))
2095 print(', '.join(self.eth_hf[f]['ref']))
2096 #print "\n# Order after dependencies"
2097 #print '\n'.join(self.eth_type_ord1)
2098 print("\n# Cyclic dependencies")
2099 for c in self.eth_dep_cycle:
2100 print(' -> '.join(c))
2101 self.dupl_report()
2102 self.output.outnm = self.outnm_opt
2103 if (not self.output.outnm):
2104 self.output.outnm = self.proto
2105 self.output.outnm = self.output.outnm.replace('.', '-')
2106 if not self.justexpcnf:
2107 self.eth_output_hf()
2108 self.eth_output_ett()
2109 self.eth_output_types()
2110 self.eth_output_hf_arr()
2111 self.eth_output_ett_arr()
2112 self.eth_output_export()
2113 self.eth_output_val()
2114 self.eth_output_valexp()
2115 self.eth_output_dis_hnd()
2116 self.eth_output_dis_reg()
2117 self.eth_output_dis_tab()
2118 self.eth_output_syn_reg()
2119 self.eth_output_tables()
2120 if self.expcnf:
2121 self.eth_output_expcnf()
2122  
2123 def dbg_modules(self):
2124 def print_mod(m):
2125 sys.stdout.write("%-30s " % (m))
2126 dep = self.module[m][:]
2127 for i in range(len(dep)):
2128 if dep[i] not in self.module:
2129 dep[i] = '*' + dep[i]
2130 print(', '.join(dep))
2131 # end of print_mod()
2132 (mod_ord, mod_cyc) = dependency_compute(self.module_ord, self.module, ignore_fn = lambda t: t not in self.module)
2133 print("\n# ASN.1 Moudules")
2134 print("Module name Dependency")
2135 print("-" * 100)
2136 new_ord = False
2137 for m in (self.module_ord):
2138 print_mod(m)
2139 new_ord = new_ord or (self.module_ord.index(m) != mod_ord.index(m))
2140 if new_ord:
2141 print("\n# ASN.1 Moudules - in dependency order")
2142 print("Module name Dependency")
2143 print("-" * 100)
2144 for m in (mod_ord):
2145 print_mod(m)
2146 if mod_cyc:
2147 print("\nCyclic dependencies:")
2148 for i in (list(range(len(mod_cyc)))):
2149 print("%02d: %s" % (i + 1, str(mod_cyc[i])))
2150  
2151  
2152 #--- EthCnf -------------------------------------------------------------------
2153 class EthCnf:
2154 def __init__(self):
2155 self.ectx = None
2156 self.tblcfg = {}
2157 self.table = {}
2158 self.order = {}
2159 self.fn = {}
2160 self.report = {}
2161 self.suppress_line = False
2162 self.include_path = []
2163 # Value name Default value Duplicity check Usage check
2164 self.tblcfg['EXPORTS'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2165 self.tblcfg['MAKE_ENUM'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2166 self.tblcfg['USE_VALS_EXT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2167 self.tblcfg['PDU'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2168 self.tblcfg['SYNTAX'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2169 self.tblcfg['REGISTER'] = { 'val_nm' : 'attr', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2170 self.tblcfg['USER_DEFINED'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2171 self.tblcfg['NO_EMIT'] = { 'val_nm' : 'flag', 'val_dflt' : 0, 'chk_dup' : True, 'chk_use' : True }
2172 self.tblcfg['MODULE'] = { 'val_nm' : 'proto', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : False }
2173 self.tblcfg['OMIT_ASSIGNMENT'] = { 'val_nm' : 'omit', 'val_dflt' : False, 'chk_dup' : True, 'chk_use' : True }
2174 self.tblcfg['NO_OMIT_ASSGN'] = { 'val_nm' : 'omit', 'val_dflt' : True, 'chk_dup' : True, 'chk_use' : True }
2175 self.tblcfg['VIRTUAL_ASSGN'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2176 self.tblcfg['SET_TYPE'] = { 'val_nm' : 'type', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2177 self.tblcfg['TYPE_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2178 self.tblcfg['FIELD_RENAME'] = { 'val_nm' : 'eth_name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2179 self.tblcfg['IMPORT_TAG'] = { 'val_nm' : 'ttag', 'val_dflt' : (), 'chk_dup' : True, 'chk_use' : False }
2180 self.tblcfg['FN_PARS'] = { 'val_nm' : 'pars', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2181 self.tblcfg['TYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2182 self.tblcfg['ETYPE_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : False }
2183 self.tblcfg['FIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2184 self.tblcfg['EFIELD_ATTR'] = { 'val_nm' : 'attr', 'val_dflt' : {}, 'chk_dup' : True, 'chk_use' : True }
2185 self.tblcfg['ASSIGNED_ID'] = { 'val_nm' : 'ids', 'val_dflt' : {}, 'chk_dup' : False,'chk_use' : False }
2186 self.tblcfg['ASSIGN_VALUE_TO_TYPE'] = { 'val_nm' : 'name', 'val_dflt' : None, 'chk_dup' : True, 'chk_use' : True }
2187  
2188 for k in list(self.tblcfg.keys()) :
2189 self.table[k] = {}
2190 self.order[k] = []
2191  
2192 def add_item(self, table, key, fn, lineno, **kw):
2193 if self.tblcfg[table]['chk_dup'] and key in self.table[table]:
2194 warnings.warn_explicit("Duplicated %s for %s. Previous one is at %s:%d" %
2195 (table, key, self.table[table][key]['fn'], self.table[table][key]['lineno']),
2196 UserWarning, fn, lineno)
2197 return
2198 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2199 self.table[table][key].update(kw)
2200 self.order[table].append(key)
2201  
2202 def update_item(self, table, key, fn, lineno, **kw):
2203 if key not in self.table[table]:
2204 self.table[table][key] = {'fn' : fn, 'lineno' : lineno, 'used' : False}
2205 self.order[table].append(key)
2206 self.table[table][key][self.tblcfg[table]['val_nm']] = {}
2207 self.table[table][key][self.tblcfg[table]['val_nm']].update(kw[self.tblcfg[table]['val_nm']])
2208  
2209 def get_order(self, table):
2210 return self.order[table]
2211  
2212 def check_item(self, table, key):
2213 return key in self.table[table]
2214  
2215 def copy_item(self, table, dst_key, src_key):
2216 if (src_key in self.table[table]):
2217 self.table[table][dst_key] = self.table[table][src_key]
2218  
2219 def check_item_value(self, table, key, **kw):
2220 return key in self.table[table] and kw.get('val_nm', self.tblcfg[table]['val_nm']) in self.table[table][key]
2221  
2222 def use_item(self, table, key, **kw):
2223 vdflt = kw.get('val_dflt', self.tblcfg[table]['val_dflt'])
2224 if key not in self.table[table]: return vdflt
2225 vname = kw.get('val_nm', self.tblcfg[table]['val_nm'])
2226 #print "use_item() - set used for %s %s" % (table, key)
2227 self.table[table][key]['used'] = True
2228 return self.table[table][key].get(vname, vdflt)
2229  
2230 def omit_assignment(self, type, ident, module):
2231 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', ident):
2232 return True
2233 if self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*') or \
2234 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type) or \
2235 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*/'+module) or \
2236 self.ectx.conform.use_item('OMIT_ASSIGNMENT', '*'+type+'/'+module):
2237 return self.ectx.conform.use_item('NO_OMIT_ASSGN', ident)
2238 return False
2239  
2240 def add_fn_line(self, name, ctx, line, fn, lineno):
2241 if name not in self.fn:
2242 self.fn[name] = {'FN_HDR' : None, 'FN_FTR' : None, 'FN_BODY' : None}
2243 if (self.fn[name][ctx]):
2244 self.fn[name][ctx]['text'] += line
2245 else:
2246 self.fn[name][ctx] = {'text' : line, 'used' : False,
2247 'fn' : fn, 'lineno' : lineno}
2248 def get_fn_presence(self, name):
2249 #print "get_fn_presence('%s'):%s" % (name, str(self.fn.has_key(name)))
2250 #if self.fn.has_key(name): print self.fn[name]
2251 return name in self.fn
2252 def get_fn_body_presence(self, name):
2253 return name in self.fn and self.fn[name]['FN_BODY']
2254 def get_fn_text(self, name, ctx):
2255 if (name not in self.fn):
2256 return '';
2257 if (not self.fn[name][ctx]):
2258 return '';
2259 self.fn[name][ctx]['used'] = True
2260 out = self.fn[name][ctx]['text']
2261 if (not self.suppress_line):
2262 out = '#line %u "%s"\n%s\n' % (self.fn[name][ctx]['lineno'], rel_dissector_path(self.fn[name][ctx]['fn']), out);
2263 return out
2264  
2265 def add_pdu(self, par, fn, lineno):
2266 #print "add_pdu(par=%s, %s, %d)" % (str(par), fn, lineno)
2267 (reg, hidden) = (None, False)
2268 if (len(par) > 1): reg = par[1]
2269 if (reg and reg[0]=='@'): (reg, hidden) = (reg[1:], True)
2270 attr = {'new' : False, 'reg' : reg, 'hidden' : hidden, 'need_decl' : False, 'export' : False}
2271 self.add_item('PDU', par[0], attr=attr, fn=fn, lineno=lineno)
2272 return
2273  
2274 def add_syntax(self, par, fn, lineno):
2275 #print "add_syntax(par=%s, %s, %d)" % (str(par), fn, lineno)
2276 if( (len(par) >=2)):
2277 name = par[1]
2278 else:
2279 name = '"'+par[0]+'"'
2280 attr = { 'pdu' : par[0] }
2281 self.add_item('SYNTAX', name, attr=attr, fn=fn, lineno=lineno)
2282 return
2283  
2284 def add_register(self, pdu, par, fn, lineno):
2285 #print "add_register(pdu=%s, par=%s, %s, %d)" % (pdu, str(par), fn, lineno)
2286 if (par[0] in ('N', 'NUM')): rtype = 'NUM'; (pmin, pmax) = (2, 2)
2287 elif (par[0] in ('S', 'STR')): rtype = 'STR'; (pmin, pmax) = (2, 2)
2288 elif (par[0] in ('B', 'BER')): rtype = 'BER'; (pmin, pmax) = (1, 2)
2289 elif (par[0] in ('P', 'PER')): rtype = 'PER'; (pmin, pmax) = (1, 2)
2290 else: warnings.warn_explicit("Unknown registration type '%s'" % (par[2]), UserWarning, fn, lineno); return
2291 if ((len(par)-1) < pmin):
2292 warnings.warn_explicit("Too few parameters for %s registration type. At least %d parameters are required" % (rtype, pmin), UserWarning, fn, lineno)
2293 return
2294 if ((len(par)-1) > pmax):
2295 warnings.warn_explicit("Too many parameters for %s registration type. Only %d parameters are allowed" % (rtype, pmax), UserWarning, fn, lineno)
2296 attr = {'pdu' : pdu, 'rtype' : rtype}
2297 if (rtype in ('NUM', 'STR')):
2298 attr['rtable'] = par[1]
2299 attr['rport'] = par[2]
2300 rkey = '/'.join([rtype, attr['rtable'], attr['rport']])
2301 elif (rtype in ('BER', 'PER')):
2302 attr['roid'] = par[1]
2303 attr['roidname'] = '""'
2304 if (len(par)>=3):
2305 attr['roidname'] = par[2]
2306 elif attr['roid'][0] != '"':
2307 attr['roidname'] = '"' + attr['roid'] + '"'
2308 rkey = '/'.join([rtype, attr['roid']])
2309 self.add_item('REGISTER', rkey, attr=attr, fn=fn, lineno=lineno)
2310  
2311 def check_par(self, par, pmin, pmax, fn, lineno):
2312 for i in range(len(par)):
2313 if par[i] == '-':
2314 par[i] = None
2315 continue
2316 if par[i][0] == '#':
2317 par[i:] = []
2318 break
2319 if len(par) < pmin:
2320 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2321 return None
2322 if (pmax >= 0) and (len(par) > pmax):
2323 warnings.warn_explicit("Too many parameters. Only %d parameters are allowed" % (pmax), UserWarning, fn, lineno)
2324 return par[0:pmax]
2325 return par
2326  
2327 def read(self, fn):
2328 def get_par(line, pmin, pmax, fn, lineno):
2329 par = line.split(None, pmax)
2330 par = self.check_par(par, pmin, pmax, fn, lineno)
2331 return par
2332  
2333 def get_par_nm(line, pmin, pmax, fn, lineno):
2334 if pmax:
2335 par = line.split(None, pmax)
2336 else:
2337 par = [line,]
2338 for i in range(len(par)):
2339 if par[i][0] == '#':
2340 par[i:] = []
2341 break
2342 if len(par) < pmin:
2343 warnings.warn_explicit("Too few parameters. At least %d parameters are required" % (pmin), UserWarning, fn, lineno)
2344 return None
2345 if len(par) > pmax:
2346 nmpar = par[pmax]
2347 else:
2348 nmpar = ''
2349 nmpars = {}
2350 nmpar_first = re.compile(r'^\s*(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2351 nmpar_next = re.compile(r'\s+(?P<attr>[_A-Z][_A-Z0-9]*)\s*=\s*')
2352 nmpar_end = re.compile(r'\s*$')
2353 result = nmpar_first.search(nmpar)
2354 pos = 0
2355 while result:
2356 k = result.group('attr')
2357 pos = result.end()
2358 result = nmpar_next.search(nmpar, pos)
2359 p1 = pos
2360 if result:
2361 p2 = result.start()
2362 else:
2363 p2 = nmpar_end.search(nmpar, pos).start()
2364 v = nmpar[p1:p2]
2365 nmpars[k] = v
2366 if len(par) > pmax:
2367 par[pmax] = nmpars
2368 return par
2369  
2370 f = open(fn, "r")
2371 lineno = 0
2372 is_import = False
2373 directive = re.compile(r'^\s*#\.(?P<name>[A-Z_][A-Z_0-9]*)(\s+|$)')
2374 cdirective = re.compile(r'^\s*##')
2375 report = re.compile(r'^TABLE(?P<num>\d*)_(?P<type>HDR|BODY|FTR)$')
2376 comment = re.compile(r'^\s*#[^.#]')
2377 empty = re.compile(r'^\s*$')
2378 ctx = None
2379 name = ''
2380 default_flags = 0x00
2381 stack = []
2382 while True:
2383 if not f.closed:
2384 line = f.readline()
2385 lineno += 1
2386 else:
2387 line = None
2388 if not line:
2389 if not f.closed:
2390 f.close()
2391 if stack:
2392 frec = stack.pop()
2393 fn, f, lineno, is_import = frec['fn'], frec['f'], frec['lineno'], frec['is_import']
2394 continue
2395 else:
2396 break
2397 if comment.search(line): continue
2398 result = directive.search(line)
2399 if result: # directive
2400 rep_result = report.search(result.group('name'))
2401 if result.group('name') == 'END_OF_CNF':
2402 f.close()
2403 elif result.group('name') == 'OPT':
2404 ctx = result.group('name')
2405 par = get_par(line[result.end():], 0, -1, fn=fn, lineno=lineno)
2406 if not par: continue
2407 self.set_opt(par[0], par[1:], fn, lineno)
2408 ctx = None
2409 elif result.group('name') in ('PDU', 'REGISTER',
2410 'MODULE', 'MODULE_IMPORT',
2411 'OMIT_ASSIGNMENT', 'NO_OMIT_ASSGN',
2412 'VIRTUAL_ASSGN', 'SET_TYPE', 'ASSIGN_VALUE_TO_TYPE',
2413 'TYPE_RENAME', 'FIELD_RENAME', 'TF_RENAME', 'IMPORT_TAG',
2414 'TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR',
2415 'SYNTAX'):
2416 ctx = result.group('name')
2417 elif result.group('name') in ('OMIT_ALL_ASSIGNMENTS', 'OMIT_ASSIGNMENTS_EXCEPT',
2418 'OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT',
2419 'OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2420 ctx = result.group('name')
2421 key = '*'
2422 if ctx in ('OMIT_ALL_TYPE_ASSIGNMENTS', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT'):
2423 key += 'T'
2424 if ctx in ('OMIT_ALL_VALUE_ASSIGNMENTS', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2425 key += 'V'
2426 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2427 if par:
2428 key += '/' + par[0]
2429 self.add_item('OMIT_ASSIGNMENT', key, omit=True, fn=fn, lineno=lineno)
2430 if ctx in ('OMIT_ASSIGNMENTS_EXCEPT', 'OMIT_TYPE_ASSIGNMENTS_EXCEPT', 'OMIT_VALUE_ASSIGNMENTS_EXCEPT'):
2431 ctx = 'NO_OMIT_ASSGN'
2432 else:
2433 ctx = None
2434 elif result.group('name') in ('EXPORTS', 'MODULE_EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2435 ctx = result.group('name')
2436 default_flags = EF_TYPE|EF_VALS
2437 if ctx == 'MODULE_EXPORTS':
2438 ctx = 'EXPORTS'
2439 default_flags |= EF_MODULE
2440 if ctx == 'EXPORTS':
2441 par = get_par(line[result.end():], 0, 5, fn=fn, lineno=lineno)
2442 else:
2443 par = get_par(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2444 if not par: continue
2445 p = 1
2446 if (par[0] == 'WITH_VALS'): default_flags |= EF_TYPE|EF_VALS
2447 elif (par[0] == 'WITHOUT_VALS'): default_flags |= EF_TYPE; default_flags &= ~EF_TYPE
2448 elif (par[0] == 'ONLY_VALS'): default_flags &= ~EF_TYPE; default_flags |= EF_VALS
2449 elif (ctx == 'EXPORTS'): p = 0
2450 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[0]), UserWarning, fn, lineno)
2451 for i in range(p, len(par)):
2452 if (par[i] == 'ONLY_ENUM'): default_flags &= ~(EF_TYPE|EF_VALS); default_flags |= EF_ENUM
2453 elif (par[i] == 'WITH_ENUM'): default_flags |= EF_ENUM
2454 elif (par[i] == 'VALS_WITH_TABLE'): default_flags |= EF_TABLE
2455 elif (par[i] == 'WS_DLL'): default_flags |= EF_WS_DLL
2456 elif (par[i] == 'EXTERN'): default_flags |= EF_EXTERN
2457 elif (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2458 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2459 elif result.group('name') in ('MAKE_ENUM', 'MAKE_DEFINES'):
2460 ctx = result.group('name')
2461 default_flags = EF_ENUM
2462 if ctx == 'MAKE_ENUM': default_flags |= EF_NO_PROT|EF_NO_TYPE
2463 if ctx == 'MAKE_DEFINES': default_flags |= EF_DEFINE|EF_UCASE|EF_NO_TYPE
2464 par = get_par(line[result.end():], 0, 3, fn=fn, lineno=lineno)
2465 for i in range(0, len(par)):
2466 if (par[i] == 'NO_PROT_PREFIX'): default_flags |= EF_NO_PROT
2467 elif (par[i] == 'PROT_PREFIX'): default_flags &= ~ EF_NO_PROT
2468 elif (par[i] == 'NO_TYPE_PREFIX'): default_flags |= EF_NO_TYPE
2469 elif (par[i] == 'TYPE_PREFIX'): default_flags &= ~ EF_NO_TYPE
2470 elif (par[i] == 'UPPER_CASE'): default_flags |= EF_UCASE
2471 elif (par[i] == 'NO_UPPER_CASE'): default_flags &= ~EF_UCASE
2472 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2473 elif result.group('name') == 'USE_VALS_EXT':
2474 ctx = result.group('name')
2475 default_flags = 0xFF
2476 elif result.group('name') == 'FN_HDR':
2477 minp = 1
2478 if (ctx in ('FN_PARS',)) and name: minp = 0
2479 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2480 if (not par) and (minp > 0): continue
2481 ctx = result.group('name')
2482 if par: name = par[0]
2483 elif result.group('name') == 'FN_FTR':
2484 minp = 1
2485 if (ctx in ('FN_PARS','FN_HDR')) and name: minp = 0
2486 par = get_par(line[result.end():], minp, 1, fn=fn, lineno=lineno)
2487 if (not par) and (minp > 0): continue
2488 ctx = result.group('name')
2489 if par: name = par[0]
2490 elif result.group('name') == 'FN_BODY':
2491 par = get_par_nm(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2492 if not par: continue
2493 ctx = result.group('name')
2494 name = par[0]
2495 if len(par) > 1:
2496 self.add_item('FN_PARS', name, pars=par[1], fn=fn, lineno=lineno)
2497 elif result.group('name') == 'FN_PARS':
2498 par = get_par_nm(line[result.end():], 0, 1, fn=fn, lineno=lineno)
2499 ctx = result.group('name')
2500 if not par:
2501 name = None
2502 elif len(par) == 1:
2503 name = par[0]
2504 self.add_item(ctx, name, pars={}, fn=fn, lineno=lineno)
2505 elif len(par) > 1:
2506 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2507 ctx = None
2508 elif result.group('name') == 'CLASS':
2509 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2510 if not par: continue
2511 ctx = result.group('name')
2512 name = par[0]
2513 add_class_ident(name)
2514 if not name.split('$')[-1].isupper():
2515 warnings.warn_explicit("No lower-case letters shall be included in information object class name (%s)" % (name),
2516 UserWarning, fn, lineno)
2517 elif result.group('name') == 'ASSIGNED_OBJECT_IDENTIFIER':
2518 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2519 if not par: continue
2520 self.update_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER', ids={par[0] : par[0]}, fn=fn, lineno=lineno)
2521 elif rep_result: # Reports
2522 num = rep_result.group('num')
2523 type = rep_result.group('type')
2524 if type == 'BODY':
2525 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2526 if not par: continue
2527 else:
2528 par = get_par(line[result.end():], 0, 0, fn=fn, lineno=lineno)
2529 rep = { 'type' : type, 'var' : None, 'text' : '', 'fn' : fn, 'lineno' : lineno }
2530 if len(par) > 0:
2531 rep['var'] = par[0]
2532 self.report.setdefault(num, []).append(rep)
2533 ctx = 'TABLE'
2534 name = num
2535 elif result.group('name') in ('INCLUDE', 'IMPORT') :
2536 is_imp = result.group('name') == 'IMPORT'
2537 par = get_par(line[result.end():], 1, 1, fn=fn, lineno=lineno)
2538 if not par:
2539 warnings.warn_explicit("%s requires parameter" % (result.group('name'),), UserWarning, fn, lineno)
2540 continue
2541 fname = par[0]
2542 #print "Try include: %s" % (fname)
2543 if (not os.path.exists(fname)):
2544 fname = os.path.join(os.path.split(fn)[0], par[0])
2545 #print "Try include: %s" % (fname)
2546 i = 0
2547 while not os.path.exists(fname) and (i < len(self.include_path)):
2548 fname = os.path.join(self.include_path[i], par[0])
2549 #print "Try include: %s" % (fname)
2550 i += 1
2551 if (not os.path.exists(fname)):
2552 if is_imp:
2553 continue # just ignore
2554 else:
2555 fname = par[0] # report error
2556 fnew = open(fname, "r")
2557 stack.append({'fn' : fn, 'f' : f, 'lineno' : lineno, 'is_import' : is_import})
2558 fn, f, lineno, is_import = par[0], fnew, 0, is_imp
2559 elif result.group('name') == 'END':
2560 ctx = None
2561 else:
2562 warnings.warn_explicit("Unknown directive '%s'" % (result.group('name')), UserWarning, fn, lineno)
2563 continue
2564 if not ctx:
2565 if not empty.match(line):
2566 warnings.warn_explicit("Non-empty line in empty context", UserWarning, fn, lineno)
2567 elif ctx == 'OPT':
2568 if empty.match(line): continue
2569 par = get_par(line, 1, -1, fn=fn, lineno=lineno)
2570 if not par: continue
2571 self.set_opt(par[0], par[1:], fn, lineno)
2572 elif ctx in ('EXPORTS', 'USER_DEFINED', 'NO_EMIT'):
2573 if empty.match(line): continue
2574 if ctx == 'EXPORTS':
2575 par = get_par(line, 1, 6, fn=fn, lineno=lineno)
2576 else:
2577 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2578 if not par: continue
2579 flags = default_flags
2580 p = 2
2581 if (len(par)>=2):
2582 if (par[1] == 'WITH_VALS'): flags |= EF_TYPE|EF_VALS
2583 elif (par[1] == 'WITHOUT_VALS'): flags |= EF_TYPE; flags &= ~EF_TYPE
2584 elif (par[1] == 'ONLY_VALS'): flags &= ~EF_TYPE; flags |= EF_VALS
2585 elif (ctx == 'EXPORTS'): p = 1
2586 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[1]), UserWarning, fn, lineno)
2587 for i in range(p, len(par)):
2588 if (par[i] == 'ONLY_ENUM'): flags &= ~(EF_TYPE|EF_VALS); flags |= EF_ENUM
2589 elif (par[i] == 'WITH_ENUM'): flags |= EF_ENUM
2590 elif (par[i] == 'VALS_WITH_TABLE'): flags |= EF_TABLE
2591 elif (par[i] == 'WS_DLL'): flags |= EF_WS_DLL
2592 elif (par[i] == 'EXTERN'): flags |= EF_EXTERN
2593 elif (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2594 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2595 self.add_item(ctx, par[0], flag=flags, fn=fn, lineno=lineno)
2596 elif ctx in ('MAKE_ENUM', 'MAKE_DEFINES'):
2597 if empty.match(line): continue
2598 par = get_par(line, 1, 4, fn=fn, lineno=lineno)
2599 if not par: continue
2600 flags = default_flags
2601 for i in range(1, len(par)):
2602 if (par[i] == 'NO_PROT_PREFIX'): flags |= EF_NO_PROT
2603 elif (par[i] == 'PROT_PREFIX'): flags &= ~ EF_NO_PROT
2604 elif (par[i] == 'NO_TYPE_PREFIX'): flags |= EF_NO_TYPE
2605 elif (par[i] == 'TYPE_PREFIX'): flags &= ~ EF_NO_TYPE
2606 elif (par[i] == 'UPPER_CASE'): flags |= EF_UCASE
2607 elif (par[i] == 'NO_UPPER_CASE'): flags &= ~EF_UCASE
2608 else: warnings.warn_explicit("Unknown parameter value '%s'" % (par[i]), UserWarning, fn, lineno)
2609 self.add_item('MAKE_ENUM', par[0], flag=flags, fn=fn, lineno=lineno)
2610 elif ctx == 'USE_VALS_EXT':
2611 if empty.match(line): continue
2612 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2613 if not par: continue
2614 flags = default_flags
2615 self.add_item('USE_VALS_EXT', par[0], flag=flags, fn=fn, lineno=lineno)
2616 elif ctx == 'PDU':
2617 if empty.match(line): continue
2618 par = get_par(line, 1, 5, fn=fn, lineno=lineno)
2619 if not par: continue
2620 self.add_pdu(par[0:2], fn, lineno)
2621 if (len(par)>=3):
2622 self.add_register(par[0], par[2:5], fn, lineno)
2623 elif ctx == 'SYNTAX':
2624 if empty.match(line): continue
2625 par = get_par(line, 1, 2, fn=fn, lineno=lineno)
2626 if not par: continue
2627 if not self.check_item('PDU', par[0]):
2628 self.add_pdu(par[0:1], fn, lineno)
2629 self.add_syntax(par, fn, lineno)
2630 elif ctx == 'REGISTER':
2631 if empty.match(line): continue
2632 par = get_par(line, 3, 4, fn=fn, lineno=lineno)
2633 if not par: continue
2634 if not self.check_item('PDU', par[0]):
2635 self.add_pdu(par[0:1], fn, lineno)
2636 self.add_register(par[0], par[1:4], fn, lineno)
2637 elif ctx in ('MODULE', 'MODULE_IMPORT'):
2638 if empty.match(line): continue
2639 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2640 if not par: continue
2641 self.add_item('MODULE', par[0], proto=par[1], fn=fn, lineno=lineno)
2642 elif ctx == 'IMPORT_TAG':
2643 if empty.match(line): continue
2644 par = get_par(line, 3, 3, fn=fn, lineno=lineno)
2645 if not par: continue
2646 self.add_item(ctx, par[0], ttag=(par[1], par[2]), fn=fn, lineno=lineno)
2647 elif ctx == 'OMIT_ASSIGNMENT':
2648 if empty.match(line): continue
2649 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2650 if not par: continue
2651 self.add_item(ctx, par[0], omit=True, fn=fn, lineno=lineno)
2652 elif ctx == 'NO_OMIT_ASSGN':
2653 if empty.match(line): continue
2654 par = get_par(line, 1, 1, fn=fn, lineno=lineno)
2655 if not par: continue
2656 self.add_item(ctx, par[0], omit=False, fn=fn, lineno=lineno)
2657 elif ctx == 'VIRTUAL_ASSGN':
2658 if empty.match(line): continue
2659 par = get_par(line, 2, -1, fn=fn, lineno=lineno)
2660 if not par: continue
2661 if (len(par[1].split('/')) > 1) and not self.check_item('SET_TYPE', par[1]):
2662 self.add_item('SET_TYPE', par[1], type=par[0], fn=fn, lineno=lineno)
2663 self.add_item('VIRTUAL_ASSGN', par[1], name=par[0], fn=fn, lineno=lineno)
2664 for nm in par[2:]:
2665 self.add_item('SET_TYPE', nm, type=par[0], fn=fn, lineno=lineno)
2666 if not par[0][0].isupper():
2667 warnings.warn_explicit("Virtual assignment should have uppercase name (%s)" % (par[0]),
2668 UserWarning, fn, lineno)
2669 elif ctx == 'SET_TYPE':
2670 if empty.match(line): continue
2671 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2672 if not par: continue
2673 if not self.check_item('VIRTUAL_ASSGN', par[0]):
2674 self.add_item('SET_TYPE', par[0], type=par[1], fn=fn, lineno=lineno)
2675 if not par[1][0].isupper():
2676 warnings.warn_explicit("Set type should have uppercase name (%s)" % (par[1]),
2677 UserWarning, fn, lineno)
2678 elif ctx == 'ASSIGN_VALUE_TO_TYPE':
2679 if empty.match(line): continue
2680 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2681 if not par: continue
2682 self.add_item(ctx, par[0], name=par[1], fn=fn, lineno=lineno)
2683 elif ctx == 'TYPE_RENAME':
2684 if empty.match(line): continue
2685 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2686 if not par: continue
2687 self.add_item('TYPE_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2688 if not par[1][0].isupper():
2689 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2690 UserWarning, fn, lineno)
2691 elif ctx == 'FIELD_RENAME':
2692 if empty.match(line): continue
2693 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2694 if not par: continue
2695 self.add_item('FIELD_RENAME', par[0], eth_name=par[1], fn=fn, lineno=lineno)
2696 if not par[1][0].islower():
2697 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2698 UserWarning, fn, lineno)
2699 elif ctx == 'TF_RENAME':
2700 if empty.match(line): continue
2701 par = get_par(line, 2, 2, fn=fn, lineno=lineno)
2702 if not par: continue
2703 tmpu = par[1][0].upper() + par[1][1:]
2704 tmpl = par[1][0].lower() + par[1][1:]
2705 self.add_item('TYPE_RENAME', par[0], eth_name=tmpu, fn=fn, lineno=lineno)
2706 if not tmpu[0].isupper():
2707 warnings.warn_explicit("Type should be renamed to uppercase name (%s)" % (par[1]),
2708 UserWarning, fn, lineno)
2709 self.add_item('FIELD_RENAME', par[0], eth_name=tmpl, fn=fn, lineno=lineno)
2710 if not tmpl[0].islower():
2711 warnings.warn_explicit("Field should be renamed to lowercase name (%s)" % (par[1]),
2712 UserWarning, fn, lineno)
2713 elif ctx in ('TYPE_ATTR', 'ETYPE_ATTR', 'FIELD_ATTR', 'EFIELD_ATTR'):
2714 if empty.match(line): continue
2715 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2716 if not par: continue
2717 self.add_item(ctx, par[0], attr=par[1], fn=fn, lineno=lineno)
2718 elif ctx == 'FN_PARS':
2719 if empty.match(line): continue
2720 if name:
2721 par = get_par_nm(line, 0, 0, fn=fn, lineno=lineno)
2722 else:
2723 par = get_par_nm(line, 1, 1, fn=fn, lineno=lineno)
2724 if not par: continue
2725 if name:
2726 self.update_item(ctx, name, pars=par[0], fn=fn, lineno=lineno)
2727 else:
2728 self.add_item(ctx, par[0], pars=par[1], fn=fn, lineno=lineno)
2729 elif ctx in ('FN_HDR', 'FN_FTR', 'FN_BODY'):
2730 result = cdirective.search(line)
2731 if result: # directive
2732 line = '#' + line[result.end():]
2733 self.add_fn_line(name, ctx, line, fn=fn, lineno=lineno)
2734 elif ctx == 'CLASS':
2735 if empty.match(line): continue
2736 par = get_par(line, 1, 3, fn=fn, lineno=lineno)
2737 if not par: continue
2738 if not set_type_to_class(name, par[0], par[1:]):
2739 warnings.warn_explicit("Could not set type of class member %s.&%s to %s" % (name, par[0], par[1]),
2740 UserWarning, fn, lineno)
2741 elif ctx == 'TABLE':
2742 self.report[name][-1]['text'] += line
2743  
2744 def set_opt(self, opt, par, fn, lineno):
2745 #print "set_opt: %s, %s" % (opt, par)
2746 if opt in ("-I",):
2747 par = self.check_par(par, 1, 1, fn, lineno)
2748 if not par: return
2749 self.include_path.append(relpath(par[0]))
2750 elif opt in ("-b", "BER", "CER", "DER"):
2751 par = self.check_par(par, 0, 0, fn, lineno)
2752 self.ectx.encoding = 'ber'
2753 elif opt in ("PER",):
2754 par = self.check_par(par, 0, 0, fn, lineno)
2755 self.ectx.encoding = 'per'
2756 elif opt in ("-p", "PROTO"):
2757 par = self.check_par(par, 1, 1, fn, lineno)
2758 if not par: return
2759 self.ectx.proto_opt = par[0]
2760 self.ectx.merge_modules = True
2761 elif opt in ("ALIGNED",):
2762 par = self.check_par(par, 0, 0, fn, lineno)
2763 self.ectx.aligned = True
2764 elif opt in ("-u", "UNALIGNED"):
2765 par = self.check_par(par, 0, 0, fn, lineno)
2766 self.ectx.aligned = False
2767 elif opt in ("-d",):
2768 par = self.check_par(par, 1, 1, fn, lineno)
2769 if not par: return
2770 self.ectx.dbgopt = par[0]
2771 elif opt in ("-e",):
2772 par = self.check_par(par, 0, 0, fn, lineno)
2773 self.ectx.expcnf = True
2774 elif opt in ("-S",):
2775 par = self.check_par(par, 0, 0, fn, lineno)
2776 self.ectx.merge_modules = True
2777 elif opt in ("GROUP_BY_PROT",):
2778 par = self.check_par(par, 0, 0, fn, lineno)
2779 self.ectx.group_by_prot = True
2780 elif opt in ("-o",):
2781 par = self.check_par(par, 1, 1, fn, lineno)
2782 if not par: return
2783 self.ectx.outnm_opt = par[0]
2784 elif opt in ("-O",):
2785 par = self.check_par(par, 1, 1, fn, lineno)
2786 if not par: return
2787 self.ectx.output.outdir = relpath(par[0])
2788 elif opt in ("-s",):
2789 par = self.check_par(par, 1, 1, fn, lineno)
2790 if not par: return
2791 self.ectx.output.single_file = relpath(par[0])
2792 elif opt in ("-k",):
2793 par = self.check_par(par, 0, 0, fn, lineno)
2794 self.ectx.output.keep = True
2795 elif opt in ("-L",):
2796 par = self.check_par(par, 0, 0, fn, lineno)
2797 self.suppress_line = True
2798 elif opt in ("EMBEDDED_PDV_CB",):
2799 par = self.check_par(par, 1, 1, fn, lineno)
2800 if not par: return
2801 self.ectx.default_embedded_pdv_cb = par[0]
2802 elif opt in ("EXTERNAL_TYPE_CB",):
2803 par = self.check_par(par, 1, 1, fn, lineno)
2804 if not par: return
2805 self.ectx.default_external_type_cb = par[0]
2806 elif opt in ("-r",):
2807 par = self.check_par(par, 1, 1, fn, lineno)
2808 if not par: return
2809 self.ectx.remove_prefix = par[0]
2810 else:
2811 warnings.warn_explicit("Unknown option %s" % (opt),
2812 UserWarning, fn, lineno)
2813  
2814 def dbg_print(self):
2815 print("\n# Conformance values")
2816 print("%-15s %-4s %-15s %-20s %s" % ("File", "Line", "Table", "Key", "Value"))
2817 print("-" * 100)
2818 tbls = sorted(self.table.keys())
2819 for t in tbls:
2820 keys = sorted(self.table[t].keys())
2821 for k in keys:
2822 print("%-15s %4s %-15s %-20s %s" % (
2823 self.table[t][k]['fn'], self.table[t][k]['lineno'], t, k, str(self.table[t][k][self.tblcfg[t]['val_nm']])))
2824  
2825 def unused_report(self):
2826 tbls = sorted(self.table.keys())
2827 for t in tbls:
2828 if not self.tblcfg[t]['chk_use']: continue
2829 keys = sorted(self.table[t].keys())
2830 for k in keys:
2831 if not self.table[t][k]['used']:
2832 warnings.warn_explicit("Unused %s for %s" % (t, k),
2833 UserWarning, self.table[t][k]['fn'], self.table[t][k]['lineno'])
2834 fnms = list(self.fn.keys())
2835 fnms.sort()
2836 for f in fnms:
2837 keys = sorted(self.fn[f].keys())
2838 for k in keys:
2839 if not self.fn[f][k]: continue
2840 if not self.fn[f][k]['used']:
2841 warnings.warn_explicit("Unused %s for %s" % (k, f),
2842 UserWarning, self.fn[f][k]['fn'], self.fn[f][k]['lineno'])
2843  
2844 #--- EthOut -------------------------------------------------------------------
2845 class EthOut:
2846 def __init__(self):
2847 self.ectx = None
2848 self.outnm = None
2849 self.outdir = '.'
2850 self.single_file = None
2851 self.created_files = {}
2852 self.created_files_ord = []
2853 self.keep = False
2854  
2855 def outcomment(self, ln, comment=None):
2856 if comment:
2857 return '%s %s\n' % (comment, ln)
2858 else:
2859 return '/* %-74s */\n' % (ln)
2860  
2861 def created_file_add(self, name, keep_anyway):
2862 name = os.path.normcase(os.path.abspath(name))
2863 if name not in self.created_files:
2864 self.created_files_ord.append(name)
2865 self.created_files[name] = keep_anyway
2866 else:
2867 self.created_files[name] = self.created_files[name] or keep_anyway
2868  
2869 def created_file_exists(self, name):
2870 name = os.path.normcase(os.path.abspath(name))
2871 return name in self.created_files
2872  
2873 #--- output_fname -------------------------------------------------------
2874 def output_fname(self, ftype, ext='c'):
2875 fn = ''
2876 if not ext in ('cnf',):
2877 fn += 'packet-'
2878 fn += self.outnm
2879 if (ftype):
2880 fn += '-' + ftype
2881 fn += '.' + ext
2882 return fn
2883 #--- file_open -------------------------------------------------------
2884 def file_open(self, ftype, ext='c'):
2885 fn = self.output_fname(ftype, ext=ext)
2886 if self.created_file_exists(fn):
2887 fx = open(fn, 'a')
2888 else:
2889 fx = open(fn, 'w')
2890 comment = None
2891 if ext in ('cnf',):
2892 comment = '#'
2893 fx.write(self.fhdr(fn, comment = comment))
2894 else:
2895 if (not self.single_file and not self.created_file_exists(fn)):
2896 fx.write(self.fhdr(fn))
2897 if not self.ectx.merge_modules:
2898 fx.write('\n')
2899 mstr = "--- "
2900 if self.ectx.groups():
2901 mstr += "Module"
2902 if (len(self.ectx.modules) > 1):
2903 mstr += "s"
2904 for (m, p) in self.ectx.modules:
2905 mstr += " %s" % (m)
2906 else:
2907 mstr += "Module %s" % (self.ectx.Module())
2908 mstr += " --- --- ---"
2909 fx.write(self.outcomment(mstr, comment))
2910 fx.write('\n')
2911 return fx
2912 #--- file_close -------------------------------------------------------
2913 def file_close(self, fx, discard=False, keep_anyway=False):
2914 fx.close()
2915 if discard and not self.created_file_exists(fx.name):
2916 os.unlink(fx.name)
2917 else:
2918 self.created_file_add(fx.name, keep_anyway)
2919 #--- fhdr -------------------------------------------------------
2920 def fhdr(self, fn, comment=None):
2921 out = ''
2922 out += self.outcomment('Do not modify this file. Changes will be overwritten.', comment)
2923 out += self.outcomment('Generated automatically by the ASN.1 to Wireshark dissector compiler', comment)
2924 out += self.outcomment(os.path.basename(fn), comment)
2925 out += self.outcomment(' '.join(['asn2wrs.py'] + sys.argv[1:]), comment)
2926 out += '\n'
2927 # Make Windows path separator look like Unix path separator
2928 out = out.replace('\\', '/')
2929 # Change absolute paths and relative paths generated outside
2930 # source directory to paths relative to asn1/<proto> subdir.
2931 out = re.sub(r'(\s)[./A-Z]\S*/dissectors\b', r'\1../..', out)
2932 out = re.sub(r'(\s)[./A-Z]\S*/asn1/\S*?([\s/])', r'\1.\2', out)
2933 return out
2934  
2935 #--- dbg_print -------------------------------------------------------
2936 def dbg_print(self):
2937 print("\n# Output files")
2938 print("\n".join(self.created_files_ord))
2939 print("\n")
2940  
2941 #--- make_single_file -------------------------------------------------------
2942 def make_single_file(self):
2943 if (not self.single_file): return
2944 in_nm = self.single_file + '.c'
2945 out_nm = os.path.join(self.outdir, self.output_fname(''))
2946 self.do_include(out_nm, in_nm)
2947 in_nm = self.single_file + '.h'
2948 if (os.path.exists(in_nm)):
2949 out_nm = os.path.join(self.outdir, self.output_fname('', ext='h'))
2950 self.do_include(out_nm, in_nm)
2951 if (not self.keep):
2952 for fn in self.created_files_ord:
2953 if not self.created_files[fn]:
2954 os.unlink(fn)
2955  
2956 #--- do_include -------------------------------------------------------
2957 def do_include(self, out_nm, in_nm):
2958 def check_file(fn, fnlist):
2959 fnfull = os.path.normcase(os.path.abspath(fn))
2960 if (fnfull in fnlist and os.path.exists(fnfull)):
2961 return os.path.normpath(fn)
2962 return None
2963 fin = open(in_nm, "r")
2964 fout = open(out_nm, "w")
2965 fout.write(self.fhdr(out_nm))
2966 fout.write('/* Input file: ' + os.path.basename(in_nm) +' */\n')
2967 fout.write('\n')
2968 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(in_nm)))
2969  
2970 include = re.compile(r'^\s*#\s*include\s+[<"](?P<fname>[^>"]+)[>"]', re.IGNORECASE)
2971  
2972 cont_linenum = 0;
2973  
2974 while (True):
2975 cont_linenum = cont_linenum + 1;
2976 line = fin.readline()
2977 if (line == ''): break
2978 ifile = None
2979 result = include.search(line)
2980 #if (result): print os.path.normcase(os.path.abspath(result.group('fname')))
2981 if (result):
2982 ifile = check_file(os.path.join(os.path.split(in_nm)[0], result.group('fname')), self.created_files)
2983 if (not ifile):
2984 ifile = check_file(os.path.join(self.outdir, result.group('fname')), self.created_files)
2985 if (not ifile):
2986 ifile = check_file(result.group('fname'), self.created_files)
2987 if (ifile):
2988 fout.write('\n')
2989 fout.write('/*--- Included file: ' + ifile + ' ---*/\n')
2990 fout.write('#line %u "%s"\n' % (1, rel_dissector_path(ifile)))
2991 finc = open(ifile, "r")
2992 fout.write(finc.read())
2993 fout.write('\n')
2994 fout.write('/*--- End of included file: ' + ifile + ' ---*/\n')
2995 fout.write('#line %u "%s"\n' % (cont_linenum+1, rel_dissector_path(in_nm)) )
2996 finc.close()
2997 else:
2998 fout.write(line)
2999  
3000 fout.close()
3001 fin.close()
3002  
3003  
3004 #--- Node ---------------------------------------------------------------------
3005 class Node:
3006 def __init__(self,*args, **kw):
3007 if len (args) == 0:
3008 self.type = self.__class__.__name__
3009 else:
3010 assert (len(args) == 1)
3011 self.type = args[0]
3012 self.__dict__.update (kw)
3013 def str_child (self, key, child, depth):
3014 indent = " " * (2 * depth)
3015 keystr = indent + key + ": "
3016 if key == 'type': # already processed in str_depth
3017 return ""
3018 if isinstance (child, Node): # ugh
3019 return keystr + "\n" + child.str_depth (depth+1)
3020 if isinstance(child, type ([])):
3021 l = []
3022 for x in child:
3023 if isinstance (x, Node):
3024 l.append (x.str_depth (depth+1))
3025 else:
3026 l.append (indent + " " + str(x) + "\n")
3027 return keystr + "[\n" + ''.join(l) + indent + "]\n"
3028 else:
3029 return keystr + str (child) + "\n"
3030 def str_depth (self, depth): # ugh
3031 indent = " " * (2 * depth)
3032 l = ["%s%s" % (indent, self.type)]
3033 l.append ("".join ([self.str_child (k_v[0], k_v[1], depth + 1) for k_v in list(self.__dict__.items ())]))
3034 return "\n".join (l)
3035 def __repr__(self):
3036 return "\n" + self.str_depth (0)
3037 def to_python (self, ctx):
3038 return self.str_depth (ctx.indent_lev)
3039  
3040 def eth_reg(self, ident, ectx):
3041 pass
3042  
3043 def fld_obj_repr(self, ectx):
3044 return "/* TO DO %s */" % (str(self))
3045  
3046  
3047 #--- ValueAssignment -------------------------------------------------------------
3048 class ValueAssignment (Node):
3049 def __init__(self,*args, **kw) :
3050 Node.__init__ (self,*args, **kw)
3051  
3052 def eth_reg(self, ident, ectx):
3053 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3054 ectx.eth_reg_vassign(self)
3055 ectx.eth_reg_value(self.ident, self.typ, self.val)
3056  
3057 #--- ObjectAssignment -------------------------------------------------------------
3058 class ObjectAssignment (Node):
3059 def __init__(self,*args, **kw) :
3060 Node.__init__ (self,*args, **kw)
3061  
3062 def __eq__(self, other):
3063 if self.cls != other.cls:
3064 return False
3065 if len(self.val) != len(other.val):
3066 return False
3067 for f in (list(self.val.keys())):
3068 if f not in other.val:
3069 return False
3070 if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
3071 if not self.val[f].fld_obj_eq(other.val[f]):
3072 return False
3073 else:
3074 if str(self.val[f]) != str(other.val[f]):
3075 return False
3076 return True
3077  
3078 def eth_reg(self, ident, ectx):
3079 def make_virtual_type(cls, field, prefix):
3080 if isinstance(self.val, str): return
3081 if field in self.val and not isinstance(self.val[field], Type_Ref):
3082 vnm = prefix + '-' + self.ident
3083 virtual_tr = Type_Ref(val = vnm)
3084 t = self.val[field]
3085 self.val[field] = virtual_tr
3086 ectx.eth_reg_assign(vnm, t, virt=True)
3087 ectx.eth_reg_type(vnm, t)
3088 t.eth_reg_sub(vnm, ectx)
3089 if field in self.val and ectx.conform.check_item('PDU', cls + '.' + field):
3090 ectx.eth_reg_field(self.val[field].val, self.val[field].val, impl=self.val[field].HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', cls + '.' + field))
3091 return
3092 # end of make_virtual_type()
3093 if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
3094 self.module = ectx.Module()
3095 ectx.eth_reg_oassign(self)
3096 if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
3097 make_virtual_type(self.cls, '&Type', 'TYPE')
3098 if (self.cls == 'OPERATION'):
3099 make_virtual_type(self.cls, '&ArgumentType', 'ARG')
3100 make_virtual_type(self.cls, '&ResultType', 'RES')
3101 if (self.cls == 'ERROR'):
3102 make_virtual_type(self.cls, '&ParameterType', 'PAR')
3103  
3104  
3105 #--- Type ---------------------------------------------------------------------
3106 class Type (Node):
3107 def __init__(self,*args, **kw) :
3108 self.name = None
3109 self.constr = None
3110 self.tags = []
3111 self.named_list = None
3112 Node.__init__ (self,*args, **kw)
3113  
3114 def IsNamed(self):
3115 if self.name is None :
3116 return False
3117 else:
3118 return True
3119  
3120 def HasConstraint(self):
3121 if self.constr is None :
3122 return False
3123 else :
3124 return True
3125  
3126 def HasSizeConstraint(self):
3127 return self.HasConstraint() and self.constr.IsSize()
3128  
3129 def HasValueConstraint(self):
3130 return self.HasConstraint() and self.constr.IsValue()
3131  
3132 def HasPermAlph(self):
3133 return self.HasConstraint() and self.constr.IsPermAlph()
3134  
3135 def HasContentsConstraint(self):
3136 return self.HasConstraint() and self.constr.IsContents()
3137  
3138 def HasOwnTag(self):
3139 return len(self.tags) > 0
3140  
3141 def HasImplicitTag(self, ectx):
3142 return (self.HasOwnTag() and self.tags[0].IsImplicit(ectx))
3143  
3144 def IndetermTag(self, ectx):
3145 return False
3146  
3147 def AddTag(self, tag):
3148 self.tags[0:0] = [tag]
3149  
3150 def GetTag(self, ectx):
3151 #print "GetTag(%s)\n" % self.name;
3152 if (self.HasOwnTag()):
3153 return self.tags[0].GetTag(ectx)
3154 else:
3155 return self.GetTTag(ectx)
3156  
3157 def GetTTag(self, ectx):
3158 print("#Unhandled GetTTag() in %s" % (self.type))
3159 print(self.str_depth(1))
3160 return ('BER_CLASS_unknown', 'TAG_unknown')
3161  
3162 def SetName(self, name):
3163 self.name = name
3164  
3165 def AddConstraint(self, constr):
3166 if not self.HasConstraint():
3167 self.constr = constr
3168 else:
3169 self.constr = Constraint(type = 'Intersection', subtype = [self.constr, constr])
3170  
3171 def eth_tname(self):
3172 return '#' + self.type + '_' + str(id(self))
3173  
3174 def eth_ftype(self, ectx):
3175 return ('FT_NONE', 'BASE_NONE')
3176  
3177 def eth_strings(self):
3178 return 'NULL'
3179  
3180 def eth_omit_field(self):
3181 return False
3182  
3183 def eth_need_tree(self):
3184 return False
3185  
3186 def eth_has_vals(self):
3187 return False
3188  
3189 def eth_has_enum(self, tname, ectx):
3190 return self.eth_has_vals() and (ectx.eth_type[tname]['enum'] & EF_ENUM)
3191  
3192 def eth_need_pdu(self, ectx):
3193 return None
3194  
3195 def eth_named_bits(self):
3196 return None
3197  
3198 def eth_reg_sub(self, ident, ectx):
3199 pass
3200  
3201 def get_components(self, ectx):
3202 print("#Unhandled get_components() in %s" % (self.type))
3203 print(self.str_depth(1))
3204 return []
3205  
3206 def sel_req(self, sel, ectx):
3207 print("#Selection '%s' required for non-CHOICE type %s" % (sel, self.type))
3208 print(self.str_depth(1))
3209  
3210 def fld_obj_eq(self, other):
3211 return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
3212  
3213 def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
3214 #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
3215 #print " ", self
3216 if (ectx.NeedTags() and (len(self.tags) > tstrip)):
3217 tagged_type = self
3218 for i in range(len(self.tags)-1, tstrip-1, -1):
3219 tagged_type = TaggedType(val=tagged_type, tstrip=i)
3220 tagged_type.AddTag(self.tags[i])
3221 if not tagflag: # 1st tagged level
3222 if self.IsNamed() and not selflag:
3223 tagged_type.SetName(self.name)
3224 tagged_type.eth_reg(ident, ectx, tstrip=1, tagflag=tagflag, idx=idx, parent=parent)
3225 return
3226 nm = ''
3227 if ident and self.IsNamed() and not tagflag and not selflag:
3228 nm = ident + '/' + self.name
3229 elif ident:
3230 nm = ident
3231 elif self.IsNamed():
3232 nm = self.name
3233 if not ident and ectx.conform.omit_assignment('T', nm, ectx.Module()): return # Assignment to omit
3234 if not ident: # Assignment
3235 ectx.eth_reg_assign(nm, self)
3236 if self.type == 'Type_Ref' and not self.tr_need_own_fn(ectx):
3237 ectx.eth_reg_type(nm, self)
3238 virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
3239 if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
3240 if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
3241 if ectx.conform.check_item('SET_TYPE', nm):
3242 ectx.eth_reg_type(nm, virtual_tr) # dummy Type Reference
3243 else:
3244 ectx.eth_reg_type(nm, self) # new type
3245 trnm = nm
3246 elif ectx.conform.check_item('SET_TYPE', nm):
3247 trnm = ectx.conform.use_item('SET_TYPE', nm)
3248 elif (self.type == 'Type_Ref') and self.tr_need_own_fn(ectx):
3249 ectx.eth_reg_type(nm, self) # need own function, e.g. for constraints
3250 trnm = nm
3251 else:
3252 trnm = self.val
3253 else:
3254 ectx.eth_reg_type(nm, self)
3255 trnm = nm
3256 if ectx.conform.check_item('VIRTUAL_ASSGN', nm):
3257 vnm = ectx.conform.use_item('VIRTUAL_ASSGN', nm)
3258 ectx.eth_reg_assign(vnm, self, virt=True)
3259 ectx.eth_reg_type(vnm, self)
3260 self.eth_reg_sub(vnm, ectx)
3261 if parent and (ectx.type[parent]['val'].type == 'TaggedType'):
3262 ectx.type[parent]['val'].eth_set_val_name(parent, trnm, ectx)
3263 if ident and not tagflag and not self.eth_omit_field():
3264 ectx.eth_reg_field(nm, trnm, idx=idx, parent=parent, impl=self.HasImplicitTag(ectx))
3265 if ectx.conform.check_item('SET_TYPE', nm):
3266 virtual_tr.eth_reg_sub(nm, ectx)
3267 else:
3268 self.eth_reg_sub(nm, ectx)
3269  
3270 def eth_get_size_constr(self, ectx):
3271 (minv, maxv, ext) = ('MIN', 'MAX', False)
3272 if self.HasSizeConstraint():
3273 if self.constr.IsSize():
3274 (minv, maxv, ext) = self.constr.GetSize(ectx)
3275 if (self.constr.type == 'Intersection'):
3276 if self.constr.subtype[0].IsSize():
3277 (minv, maxv, ext) = self.constr.subtype[0].GetSize(ectx)
3278 elif self.constr.subtype[1].IsSize():
3279 (minv, maxv, ext) = self.constr.subtype[1].GetSize(ectx)
3280 if minv == 'MIN': minv = 'NO_BOUND'
3281 if maxv == 'MAX': maxv = 'NO_BOUND'
3282 if (ext): ext = 'TRUE'
3283 else: ext = 'FALSE'
3284 return (minv, maxv, ext)
3285  
3286 def eth_get_value_constr(self, ectx):
3287 (minv, maxv, ext) = ('MIN', 'MAX', False)
3288 if self.HasValueConstraint():
3289 (minv, maxv, ext) = self.constr.GetValue(ectx)
3290 if minv == 'MIN': minv = 'NO_BOUND'
3291 if maxv == 'MAX': maxv = 'NO_BOUND'
3292 if str(minv).isdigit():
3293 minv += 'U'
3294 elif (str(minv)[0] == "-") and str(minv)[1:].isdigit():
3295 if (int(minv) == -(2**31)):
3296 minv = "G_MININT32"
3297 elif (int(minv) < -(2**31)):
3298 minv = "G_GINT64_CONSTANT(%s)" % (str(minv))
3299 if str(maxv).isdigit():
3300 if (int(maxv) >= 2**32):
3301 maxv = "G_GUINT64_CONSTANT(%s)" % (str(maxv))
3302 else:
3303 maxv += 'U'
3304 if (ext): ext = 'TRUE'
3305 else: ext = 'FALSE'
3306 return (minv, maxv, ext)
3307  
3308 def eth_get_alphabet_constr(self, ectx):
3309 (alph, alphlen) = ('NULL', '0')
3310 if self.HasPermAlph():
3311 alph = self.constr.GetPermAlph(ectx)
3312 if not alph:
3313 alph = 'NULL'
3314 if (alph != 'NULL'):
3315 if (((alph[0] + alph[-1]) == '""') and (not alph.count('"', 1, -1))):
3316 alphlen = str(len(alph) - 2)
3317 else:
3318 alphlen = 'strlen(%s)' % (alph)
3319 return (alph, alphlen)
3320  
3321 def eth_type_vals(self, tname, ectx):
3322 if self.eth_has_vals():
3323 print("#Unhandled eth_type_vals('%s') in %s" % (tname, self.type))
3324 print(self.str_depth(1))
3325 return ''
3326  
3327 def eth_type_enum(self, tname, ectx):
3328 if self.eth_has_enum(tname, ectx):
3329 print("#Unhandled eth_type_enum('%s') in %s" % (tname, self.type))
3330 print(self.str_depth(1))
3331 return ''
3332  
3333 def eth_type_default_table(self, ectx, tname):
3334 return ''
3335  
3336 def eth_type_default_body(self, ectx):
3337 print("#Unhandled eth_type_default_body() in %s" % (self.type))
3338 print(self.str_depth(1))
3339 return ''
3340  
3341 def eth_type_default_pars(self, ectx, tname):
3342 pars = {
3343 'TNAME' : tname,
3344 'ER' : ectx.encp(),
3345 'FN_VARIANT' : '',
3346 'TREE' : 'tree',
3347 'TVB' : 'tvb',
3348 'OFFSET' : 'offset',
3349 'ACTX' : 'actx',
3350 'HF_INDEX' : 'hf_index',
3351 'VAL_PTR' : 'NULL',
3352 'IMPLICIT_TAG' : 'implicit_tag',
3353 }
3354 if (ectx.eth_type[tname]['tree']):
3355 pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
3356 if (ectx.merge_modules):
3357 pars['PROTOP'] = ''
3358 else:
3359 pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
3360 return pars
3361  
3362 def eth_type_fn(self, proto, tname, ectx):
3363 body = self.eth_type_default_body(ectx, tname)
3364 pars = self.eth_type_default_pars(ectx, tname)
3365 if ectx.conform.check_item('FN_PARS', tname):
3366 pars.update(ectx.conform.use_item('FN_PARS', tname))
3367 elif ectx.conform.check_item('FN_PARS', ectx.eth_type[tname]['ref'][0]):
3368 pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
3369 pars['DEFAULT_BODY'] = body
3370 for i in range(4):
3371 for k in list(pars.keys()):
3372 try:
3373 pars[k] = pars[k] % pars
3374 except (ValueError,TypeError):
3375 raise sys.exc_info()[0]("%s\n%s" % (str(pars), sys.exc_info()[1]))
3376 out = '\n'
3377 out += self.eth_type_default_table(ectx, tname) % pars
3378 out += ectx.eth_type_fn_hdr(tname)
3379 out += ectx.eth_type_fn_body(tname, body, pars=pars)
3380 out += ectx.eth_type_fn_ftr(tname)
3381 return out
3382  
3383 #--- Value --------------------------------------------------------------------
3384 class Value (Node):
3385 def __init__(self,*args, **kw) :
3386 self.name = None
3387 Node.__init__ (self,*args, **kw)
3388  
3389 def SetName(self, name) :
3390 self.name = name
3391  
3392 def to_str(self, ectx):
3393 return str(self.val)
3394  
3395 def get_dep(self):
3396 return None
3397  
3398 def fld_obj_repr(self, ectx):
3399 return self.to_str(ectx)
3400  
3401 #--- Value_Ref -----------------------------------------------------------------
3402 class Value_Ref (Value):
3403 def to_str(self, ectx):
3404 return asn2c(self.val)
3405  
3406 #--- ObjectClass ---------------------------------------------------------------------
3407 class ObjectClass (Node):
3408 def __init__(self,*args, **kw) :
3409 self.name = None
3410 Node.__init__ (self,*args, **kw)
3411  
3412 def SetName(self, name):
3413 self.name = name
3414 add_class_ident(self.name)
3415  
3416 def eth_reg(self, ident, ectx):
3417 if ectx.conform.omit_assignment('C', self.name, ectx.Module()): return # Assignment to omit
3418 ectx.eth_reg_objectclass(self.name, self)
3419  
3420 #--- Class_Ref -----------------------------------------------------------------
3421 class Class_Ref (ObjectClass):
3422 pass
3423  
3424 #--- ObjectClassDefn ---------------------------------------------------------------------
3425 class ObjectClassDefn (ObjectClass):
3426 def reg_types(self):
3427 for fld in self.fields:
3428 repr = fld.fld_repr()
3429 set_type_to_class(self.name, repr[0], repr[1:])
3430  
3431  
3432 #--- Tag ---------------------------------------------------------------
3433 class Tag (Node):
3434 def to_python (self, ctx):
3435 return 'asn1.TYPE(%s,%s)' % (mk_tag_str (ctx, self.tag.cls,
3436 self.tag_typ,
3437 self.tag.num),
3438 self.typ.to_python (ctx))
3439 def IsImplicit(self, ectx):
3440 return ((self.mode == 'IMPLICIT') or ((self.mode == 'default') and (ectx.tag_def != 'EXPLICIT')))
3441  
3442 def GetTag(self, ectx):
3443 tc = ''
3444 if (self.cls == 'UNIVERSAL'): tc = 'BER_CLASS_UNI'
3445 elif (self.cls == 'APPLICATION'): tc = 'BER_CLASS_APP'
3446 elif (self.cls == 'CONTEXT'): tc = 'BER_CLASS_CON'
3447 elif (self.cls == 'PRIVATE'): tc = 'BER_CLASS_PRI'
3448 return (tc, self.num)
3449  
3450 def eth_tname(self):
3451 n = ''
3452 if (self.cls == 'UNIVERSAL'): n = 'U'
3453 elif (self.cls == 'APPLICATION'): n = 'A'
3454 elif (self.cls == 'CONTEXT'): n = 'C'
3455 elif (self.cls == 'PRIVATE'): n = 'P'
3456 return n + str(self.num)
3457  
3458 #--- Constraint ---------------------------------------------------------------
3459 constr_cnt = 0
3460 class Constraint (Node):
3461 def to_python (self, ctx):
3462 print("Ignoring constraint:", self.type)
3463 return self.subtype.typ.to_python (ctx)
3464 def __str__ (self):
3465 return "Constraint: type=%s, subtype=%s" % (self.type, self.subtype)
3466  
3467 def eth_tname(self):
3468 return '#' + self.type + '_' + str(id(self))
3469  
3470 def IsSize(self):
3471 return (self.type == 'Size' and self.subtype.IsValue()) \
3472 or (self.type == 'Intersection' and (self.subtype[0].IsSize() or self.subtype[1].IsSize())) \
3473  
3474 def GetSize(self, ectx):
3475 (minv, maxv, ext) = ('MIN', 'MAX', False)
3476 if self.IsSize():
3477 if self.type == 'Size':
3478 (minv, maxv, ext) = self.subtype.GetValue(ectx)
3479 elif self.type == 'Intersection':
3480 if self.subtype[0].IsSize() and not self.subtype[1].IsSize():
3481 (minv, maxv, ext) = self.subtype[0].GetSize(ectx)
3482 elif not self.subtype[0].IsSize() and self.subtype[1].IsSize():
3483 (minv, maxv, ext) = self.subtype[1].GetSize(ectx)
3484 return (minv, maxv, ext)
3485  
3486 def IsValue(self):
3487 return self.type == 'SingleValue' \
3488 or self.type == 'ValueRange' \
3489 or (self.type == 'Intersection' and (self.subtype[0].IsValue() or self.subtype[1].IsValue())) \
3490 or (self.type == 'Union' and (self.subtype[0].IsValue() and self.subtype[1].IsValue()))
3491  
3492 def GetValue(self, ectx):
3493 (minv, maxv, ext) = ('MIN', 'MAX', False)
3494 if self.IsValue():
3495 if self.type == 'SingleValue':
3496 minv = ectx.value_get_eth(self.subtype)
3497 maxv = ectx.value_get_eth(self.subtype)
3498 ext = hasattr(self, 'ext') and self.ext
3499 elif self.type == 'ValueRange':
3500 minv = ectx.value_get_eth(self.subtype[0])
3501 maxv = ectx.value_get_eth(self.subtype[1])
3502 ext = hasattr(self, 'ext') and self.ext
3503 elif self.type == 'Intersection':
3504 if self.subtype[0].IsValue() and not self.subtype[1].IsValue():
3505 (minv, maxv, ext) = self.subtype[0].GetValue(ectx)
3506 elif not self.subtype[0].IsValue() and self.subtype[1].IsValue():
3507 (minv, maxv, ext) = self.subtype[1].GetValue(ectx)
3508 elif self.subtype[0].IsValue() and self.subtype[1].IsValue():
3509 v0 = self.subtype[0].GetValue(ectx)
3510 v1 = self.subtype[1].GetValue(ectx)
3511 (minv, maxv, ext) = (ectx.value_max(v0[0],v1[0]), ectx.value_min(v0[1],v1[1]), v0[2] and v1[2])
3512 elif self.type == 'Union':
3513 if self.subtype[0].IsValue() and self.subtype[1].IsValue():
3514 v0 = self.subtype[0].GetValue(ectx)
3515 v1 = self.subtype[1].GetValue(ectx)
3516 (minv, maxv, ext) = (ectx.value_min(v0[0],v1[0]), ectx.value_max(v0[1],v1[1]), v0[2] or v1[2])
3517 return (minv, maxv, ext)
3518  
3519 def IsAlphabet(self):
3520 return self.type == 'SingleValue' \
3521 or self.type == 'ValueRange' \
3522 or (self.type == 'Intersection' and (self.subtype[0].IsAlphabet() or self.subtype[1].IsAlphabet())) \
3523 or (self.type == 'Union' and (self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet()))
3524  
3525 def GetAlphabet(self, ectx):
3526 alph = None
3527 if self.IsAlphabet():
3528 if self.type == 'SingleValue':
3529 alph = ectx.value_get_eth(self.subtype)
3530 elif self.type == 'ValueRange':
3531 if ((len(self.subtype[0]) == 3) and ((self.subtype[0][0] + self.subtype[0][-1]) == '""') \
3532 and (len(self.subtype[1]) == 3) and ((self.subtype[1][0] + self.subtype[1][-1]) == '""')):
3533 alph = '"'
3534 for c in range(ord(self.subtype[0][1]), ord(self.subtype[1][1]) + 1):
3535 alph += chr(c)
3536 alph += '"'
3537 elif self.type == 'Union':
3538 if self.subtype[0].IsAlphabet() and self.subtype[1].IsAlphabet():
3539 a0 = self.subtype[0].GetAlphabet(ectx)
3540 a1 = self.subtype[1].GetAlphabet(ectx)
3541 if (((a0[0] + a0[-1]) == '""') and not a0.count('"', 1, -1) \
3542 and ((a1[0] + a1[-1]) == '""') and not a1.count('"', 1, -1)):
3543 alph = '"' + a0[1:-1] + a1[1:-1] + '"'
3544 else:
3545 alph = a0 + ' ' + a1
3546 return alph
3547  
3548 def IsPermAlph(self):
3549 return self.type == 'From' and self.subtype.IsAlphabet() \
3550 or (self.type == 'Intersection' and (self.subtype[0].IsPermAlph() or self.subtype[1].IsPermAlph())) \
3551  
3552 def GetPermAlph(self, ectx):
3553 alph = None
3554 if self.IsPermAlph():
3555 if self.type == 'From':
3556 alph = self.subtype.GetAlphabet(ectx)
3557 elif self.type == 'Intersection':
3558 if self.subtype[0].IsPermAlph() and not self.subtype[1].IsPermAlph():
3559 alph = self.subtype[0].GetPermAlph(ectx)
3560 elif not self.subtype[0].IsPermAlph() and self.subtype[1].IsPermAlph():
3561 alph = self.subtype[1].GetPermAlph(ectx)
3562 return alph
3563  
3564 def IsContents(self):
3565 return self.type == 'Contents' \
3566 or (self.type == 'Intersection' and (self.subtype[0].IsContents() or self.subtype[1].IsContents())) \
3567  
3568 def GetContents(self, ectx):
3569 contents = None
3570 if self.IsContents():
3571 if self.type == 'Contents':
3572 if self.subtype.type == 'Type_Ref':
3573 contents = self.subtype.val
3574 elif self.type == 'Intersection':
3575 if self.subtype[0].IsContents() and not self.subtype[1].IsContents():
3576 contents = self.subtype[0].GetContents(ectx)
3577 elif not self.subtype[0].IsContents() and self.subtype[1].IsContents():
3578 contents = self.subtype[1].GetContents(ectx)
3579 return contents
3580  
3581 def IsNegativ(self):
3582 def is_neg(sval):
3583 return isinstance(sval, str) and (sval[0] == '-')
3584 if self.type == 'SingleValue':
3585 return is_neg(self.subtype)
3586 elif self.type == 'ValueRange':
3587 if self.subtype[0] == 'MIN': return True
3588 return is_neg(self.subtype[0])
3589 return False
3590  
3591 def eth_constrname(self):
3592 def int2str(val):
3593 if isinstance(val, Value_Ref):
3594 return asn2c(val.val)
3595 try:
3596 if (int(val) < 0):
3597 return 'M' + str(-int(val))
3598 else:
3599 return str(int(val))
3600 except (ValueError, TypeError):
3601 return asn2c(str(val))
3602  
3603 ext = ''
3604 if hasattr(self, 'ext') and self.ext:
3605 ext = '_'
3606 if self.type == 'SingleValue':
3607 return int2str(self.subtype) + ext
3608 elif self.type == 'ValueRange':
3609 return int2str(self.subtype[0]) + '_' + int2str(self.subtype[1]) + ext
3610 elif self.type == 'Size':
3611 return 'SIZE_' + self.subtype.eth_constrname() + ext
3612 else:
3613 if (not hasattr(self, 'constr_num')):
3614 global constr_cnt
3615 constr_cnt += 1
3616 self.constr_num = constr_cnt
3617 return 'CONSTR%03d%s' % (self.constr_num, ext)
3618  
3619 def Needs64b(self, ectx):
3620 (minv, maxv, ext) = self.GetValue(ectx)
3621 if (str(minv).isdigit() or ((str(minv)[0] == "-") and str(minv)[1:].isdigit())) \
3622 and str(maxv).isdigit() and (abs(int(maxv) - int(minv)) >= 2**32):
3623 return True
3624 return False
3625  
3626 class Module (Node):
3627 def to_python (self, ctx):
3628 ctx.tag_def = self.tag_def.dfl_tag
3629 return """#%s
3630 %s""" % (self.ident, self.body.to_python (ctx))
3631  
3632 def get_name(self):
3633 return self.ident.val
3634  
3635 def get_proto(self, ectx):
3636 if (ectx.proto):
3637 prot = ectx.proto
3638 else:
3639 prot = ectx.conform.use_item('MODULE', self.get_name(), val_dflt=self.get_name())
3640 return prot
3641  
3642 def to_eth(self, ectx):
3643 ectx.tags_def = 'EXPLICIT' # default = explicit
3644 ectx.proto = self.get_proto(ectx)
3645 ectx.tag_def = self.tag_def.dfl_tag
3646 ectx.eth_reg_module(self)
3647 self.body.to_eth(ectx)
3648  
3649 class Module_Body (Node):
3650 def to_python (self, ctx):
3651 # XXX handle exports, imports.
3652 l = [x.to_python (ctx) for x in self.assign_list]
3653 l = [a for a in l if a != '']
3654 return "\n".join (l)
3655  
3656 def to_eth(self, ectx):
3657 # Exports
3658 ectx.eth_exports(self.exports)
3659 # Imports
3660 for i in self.imports:
3661 mod = i.module.val
3662 proto = ectx.conform.use_item('MODULE', mod, val_dflt=mod)
3663 ectx.eth_module_dep_add(ectx.Module(), mod)
3664 for s in i.symbol_list:
3665 if isinstance(s, Type_Ref):
3666 ectx.eth_import_type(s.val, mod, proto)
3667 elif isinstance(s, Value_Ref):
3668 ectx.eth_import_value(s.val, mod, proto)
3669 elif isinstance(s, Class_Ref):
3670 ectx.eth_import_class(s.val, mod, proto)
3671 else:
3672 msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
3673 warnings.warn_explicit(msg, UserWarning, '', 0)
3674 # AssignmentList
3675 for a in self.assign_list:
3676 a.eth_reg('', ectx)
3677  
3678 class Default_Tags (Node):
3679 def to_python (self, ctx): # not to be used directly
3680 assert (0)
3681  
3682 # XXX should just calculate dependencies as we go along.
3683 def calc_dependencies (node, dict, trace = 0):
3684 if not hasattr (node, '__dict__'):
3685 if trace: print("#returning, node=", node)
3686 return
3687 if isinstance (node, Type_Ref):
3688 dict [node.val] = 1
3689 if trace: print("#Setting", node.val)
3690 return
3691 for (a, val) in list(node.__dict__.items ()):
3692 if trace: print("# Testing node ", node, "attr", a, " val", val)
3693 if a[0] == '_':
3694 continue
3695 elif isinstance (val, Node):
3696 calc_dependencies (val, dict, trace)
3697 elif isinstance (val, type ([])):
3698 for v in val:
3699 calc_dependencies (v, dict, trace)
3700  
3701  
3702 class Type_Assign (Node):
3703 def __init__ (self, *args, **kw):
3704 Node.__init__ (self, *args, **kw)
3705 if isinstance (self.val, Tag): # XXX replace with generalized get_typ_ignoring_tag (no-op for Node, override in Tag)
3706 to_test = self.val.typ
3707 else:
3708 to_test = self.val
3709 if isinstance (to_test, SequenceType):
3710 to_test.sequence_name = self.name.name
3711  
3712 def to_python (self, ctx):
3713 dep_dict = {}
3714 calc_dependencies (self.val, dep_dict, 0)
3715 depend_list = list(dep_dict.keys ())
3716 return ctx.register_assignment (self.name.name,
3717 self.val.to_python (ctx),
3718 depend_list)
3719  
3720 class PyQuote (Node):
3721 def to_python (self, ctx):
3722 return ctx.register_pyquote (self.val)
3723  
3724 #--- Type_Ref -----------------------------------------------------------------
3725 class Type_Ref (Type):
3726 def to_python (self, ctx):
3727 return self.val
3728  
3729 def eth_reg_sub(self, ident, ectx):
3730 ectx.eth_dep_add(ident, self.val)
3731  
3732 def eth_tname(self):
3733 if self.HasSizeConstraint():
3734 return asn2c(self.val) + '_' + self.constr.eth_constrname()
3735 else:
3736 return asn2c(self.val)
3737  
3738 def tr_need_own_fn(self, ectx):
3739 return ectx.Per() and self.HasSizeConstraint()
3740  
3741 def fld_obj_repr(self, ectx):
3742 return self.val
3743  
3744 def get_components(self, ectx):
3745 if self.val not in ectx.type or ectx.type[self.val]['import']:
3746 msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
3747 warnings.warn_explicit(msg, UserWarning, '', 0)
3748 return []
3749 else:
3750 return ectx.type[self.val]['val'].get_components(ectx)
3751  
3752 def GetTTag(self, ectx):
3753 #print "GetTTag(%s)\n" % self.val;
3754 if (ectx.type[self.val]['import']):
3755 if 'ttag' not in ectx.type[self.val]:
3756 ttag = ectx.get_ttag_from_all(self.val, ectx.type[self.val]['import'])
3757 if not ttag and not ectx.conform.check_item('IMPORT_TAG', self.val):
3758 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.val, ectx.type[self.val]['import'], ectx.type[self.val]['proto'])
3759 warnings.warn_explicit(msg, UserWarning, '', 0)
3760 ttag = ('-1/*imported*/', '-1/*imported*/')
3761 ectx.type[self.val]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.val, val_dflt=ttag)
3762 return ectx.type[self.val]['ttag']
3763 else:
3764 return ectx.type[self.val]['val'].GetTag(ectx)
3765  
3766 def IndetermTag(self, ectx):
3767 if (ectx.type[self.val]['import']):
3768 return False
3769 else:
3770 return ectx.type[self.val]['val'].IndetermTag(ectx)
3771  
3772 def eth_type_default_pars(self, ectx, tname):
3773 if tname:
3774 pars = Type.eth_type_default_pars(self, ectx, tname)
3775 else:
3776 pars = {}
3777 t = ectx.type[self.val]['ethname']
3778 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3779 pars['TYPE_REF_TNAME'] = t
3780 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3781 if self.HasSizeConstraint():
3782 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
3783 return pars
3784  
3785 def eth_type_default_body(self, ectx, tname):
3786 if (ectx.Ber()):
3787 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3788 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3789 elif (ectx.Per()):
3790 if self.HasSizeConstraint():
3791 body = ectx.eth_fn_call('dissect_%(ER)s_size_constrained_type', ret='offset',
3792 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),
3793 ('"%(TYPE_REF_TNAME)s"', '%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
3794 else:
3795 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3796 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3797 else:
3798 body = '#error Can not decode %s' % (tname)
3799 return body
3800  
3801 #--- SelectionType ------------------------------------------------------------
3802 class SelectionType (Type):
3803 def to_python (self, ctx):
3804 return self.val
3805  
3806 def sel_of_typeref(self):
3807 return self.typ.type == 'Type_Ref'
3808  
3809 def eth_reg_sub(self, ident, ectx):
3810 if not self.sel_of_typeref():
3811 self.seltype = ''
3812 return
3813 self.seltype = ectx.eth_sel_req(self.typ.val, self.sel)
3814 ectx.eth_dep_add(ident, self.seltype)
3815  
3816 def eth_ftype(self, ectx):
3817 (ftype, display) = ('FT_NONE', 'BASE_NONE')
3818 if self.sel_of_typeref() and not ectx.type[self.seltype]['import']:
3819 (ftype, display) = ectx.type[self.typ.val]['val'].eth_ftype_sel(self.sel, ectx)
3820 return (ftype, display)
3821  
3822 def GetTTag(self, ectx):
3823 #print "GetTTag(%s)\n" % self.seltype;
3824 if (ectx.type[self.seltype]['import']):
3825 if 'ttag' not in ectx.type[self.seltype]:
3826 if not ectx.conform.check_item('IMPORT_TAG', self.seltype):
3827 msg = 'Missing tag information for imported type %s from %s (%s)' % (self.seltype, ectx.type[self.seltype]['import'], ectx.type[self.seltype]['proto'])
3828 warnings.warn_explicit(msg, UserWarning, '', 0)
3829 ectx.type[self.seltype]['ttag'] = ectx.conform.use_item('IMPORT_TAG', self.seltype, val_dflt=('-1 /*imported*/', '-1 /*imported*/'))
3830 return ectx.type[self.seltype]['ttag']
3831 else:
3832 return ectx.type[self.typ.val]['val'].GetTTagSel(self.sel, ectx)
3833  
3834 def eth_type_default_pars(self, ectx, tname):
3835 pars = Type.eth_type_default_pars(self, ectx, tname)
3836 if self.sel_of_typeref():
3837 t = ectx.type[self.seltype]['ethname']
3838 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3839 pars['TYPE_REF_TNAME'] = t
3840 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3841 return pars
3842  
3843 def eth_type_default_body(self, ectx, tname):
3844 if not self.sel_of_typeref():
3845 body = '#error Can not decode %s' % (tname)
3846 elif (ectx.Ber()):
3847 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3848 par=(('%(IMPLICIT_TAG)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3849 elif (ectx.Per()):
3850 body = ectx.eth_fn_call('%(TYPE_REF_FN)s', ret='offset',
3851 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
3852 else:
3853 body = '#error Can not decode %s' % (tname)
3854 return body
3855  
3856 #--- TaggedType -----------------------------------------------------------------
3857 class TaggedType (Type):
3858 def eth_tname(self):
3859 tn = ''
3860 for i in range(self.tstrip, len(self.val.tags)):
3861 tn += self.val.tags[i].eth_tname()
3862 tn += '_'
3863 tn += self.val.eth_tname()
3864 return tn
3865  
3866 def eth_set_val_name(self, ident, val_name, ectx):
3867 #print "TaggedType::eth_set_val_name(): ident=%s, val_name=%s" % (ident, val_name)
3868 self.val_name = val_name
3869 ectx.eth_dep_add(ident, self.val_name)
3870  
3871 def eth_reg_sub(self, ident, ectx):
3872 self.val_name = ident + '/' + UNTAG_TYPE_NAME
3873 self.val.eth_reg(self.val_name, ectx, tstrip=self.tstrip+1, tagflag=True, parent=ident)
3874  
3875 def GetTTag(self, ectx):
3876 #print "GetTTag(%s)\n" % self.seltype;
3877 return self.GetTag(ectx)
3878  
3879 def eth_ftype(self, ectx):
3880 return self.val.eth_ftype(ectx)
3881  
3882 def eth_type_default_pars(self, ectx, tname):
3883 pars = Type.eth_type_default_pars(self, ectx, tname)
3884 t = ectx.type[self.val_name]['ethname']
3885 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
3886 pars['TYPE_REF_TNAME'] = t
3887 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
3888 (pars['TAG_CLS'], pars['TAG_TAG']) = self.GetTag(ectx)
3889 if self.HasImplicitTag(ectx):
3890 pars['TAG_IMPL'] = 'TRUE'
3891 else:
3892 pars['TAG_IMPL'] = 'FALSE'
3893 return pars
3894  
3895 def eth_type_default_body(self, ectx, tname):
3896 if (ectx.Ber()):
3897 body = ectx.eth_fn_call('dissect_%(ER)s_tagged_type', ret='offset',
3898 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
3899 ('%(HF_INDEX)s', '%(TAG_CLS)s', '%(TAG_TAG)s', '%(TAG_IMPL)s', '%(TYPE_REF_FN)s',),))
3900 else:
3901 body = '#error Can not decode %s' % (tname)
3902 return body
3903  
3904 #--- SqType -----------------------------------------------------------
3905 class SqType (Type):
3906 def out_item(self, f, val, optional, ext, ectx):
3907 if (val.eth_omit_field()):
3908 t = ectx.type[val.ident]['ethname']
3909 fullname = ectx.dummy_eag_field
3910 else:
3911 ef = ectx.field[f]['ethname']
3912 t = ectx.eth_hf[ef]['ethtype']
3913 fullname = ectx.eth_hf[ef]['fullname']
3914 if (ectx.Ber()):
3915 #print "optional=%s, e.val.HasOwnTag()=%s, e.val.IndetermTag()=%s" % (str(e.optional), str(e.val.HasOwnTag()), str(e.val.IndetermTag(ectx)))
3916 #print val.str_depth(1)
3917 opt = ''
3918 if (optional):
3919 opt = 'BER_FLAGS_OPTIONAL'
3920 if (not val.HasOwnTag()):
3921 if (opt): opt += '|'
3922 opt += 'BER_FLAGS_NOOWNTAG'
3923 elif (val.HasImplicitTag(ectx)):
3924 if (opt): opt += '|'
3925 opt += 'BER_FLAGS_IMPLTAG'
3926 if (val.IndetermTag(ectx)):
3927 if (opt): opt += '|'
3928 opt += 'BER_FLAGS_NOTCHKTAG'
3929 if (not opt): opt = '0'
3930 else:
3931 if optional:
3932 opt = 'ASN1_OPTIONAL'
3933 else:
3934 opt = 'ASN1_NOT_OPTIONAL'
3935 if (ectx.Ber()):
3936 (tc, tn) = val.GetTag(ectx)
3937 out = ' { %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
3938 % ('&'+fullname, tc, tn, opt, ectx.eth_type[t]['proto'], t)
3939 elif (ectx.Per()):
3940 out = ' { %-24s, %-23s, %-17s, dissect_%s_%s },\n' \
3941 % ('&'+fullname, ext, opt, ectx.eth_type[t]['proto'], t)
3942 else:
3943 out = ''
3944 return out
3945  
3946 #--- SeqType -----------------------------------------------------------
3947 class SeqType (SqType):
3948  
3949 def all_components(self):
3950 lst = self.elt_list[:]
3951 if hasattr(self, 'ext_list'):
3952 lst.extend(self.ext_list)
3953 if hasattr(self, 'elt_list2'):
3954 lst.extend(self.elt_list2)
3955 return lst
3956  
3957 def need_components(self):
3958 lst = self.all_components()
3959 for e in (lst):
3960 if e.type == 'components_of':
3961 return True
3962 return False
3963  
3964 def expand_components(self, ectx):
3965 while self.need_components():
3966 for i in range(len(self.elt_list)):
3967 if self.elt_list[i].type == 'components_of':
3968 comp = self.elt_list[i].typ.get_components(ectx)
3969 self.elt_list[i:i+1] = comp
3970 break
3971 if hasattr(self, 'ext_list'):
3972 for i in range(len(self.ext_list)):
3973 if self.ext_list[i].type == 'components_of':
3974 comp = self.ext_list[i].typ.get_components(ectx)
3975 self.ext_list[i:i+1] = comp
3976 break
3977 if hasattr(self, 'elt_list2'):
3978 for i in range(len(self.elt_list2)):
3979 if self.elt_list2[i].type == 'components_of':
3980 comp = self.elt_list2[i].typ.get_components(ectx)
3981 self.elt_list2[i:i+1] = comp
3982 break
3983  
3984 def get_components(self, ectx):
3985 lst = self.elt_list[:]
3986 if hasattr(self, 'elt_list2'):
3987 lst.extend(self.elt_list2)
3988 return lst
3989  
3990 def eth_reg_sub(self, ident, ectx, components_available=False):
3991 # check if autotag is required
3992 autotag = False
3993 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
3994 autotag = True
3995 lst = self.all_components()
3996 for e in (self.elt_list):
3997 if e.val.HasOwnTag(): autotag = False; break;
3998 # expand COMPONENTS OF
3999 if self.need_components():
4000 if components_available:
4001 self.expand_components(ectx)
4002 else:
4003 ectx.eth_comp_req(ident)
4004 return
4005 # extension addition groups
4006 if hasattr(self, 'ext_list'):
4007 if (ectx.Per()): # add names
4008 eag_num = 1
4009 for e in (self.ext_list):
4010 if isinstance(e.val, ExtensionAdditionGroup):
4011 e.val.parent_ident = ident
4012 e.val.parent_tname = ectx.type[ident]['tname']
4013 if (e.val.ver):
4014 e.val.SetName("eag_v%s" % (e.val.ver))
4015 else:
4016 e.val.SetName("eag_%d" % (eag_num))
4017 eag_num += 1;
4018 else: # expand
4019 new_ext_list = []
4020 for e in (self.ext_list):
4021 if isinstance(e.val, ExtensionAdditionGroup):
4022 new_ext_list.extend(e.val.elt_list)
4023 else:
4024 new_ext_list.append(e)
4025 self.ext_list = new_ext_list
4026 # do autotag
4027 if autotag:
4028 atag = 0
4029 for e in (self.elt_list):
4030 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4031 atag += 1
4032 if autotag and hasattr(self, 'elt_list2'):
4033 for e in (self.elt_list2):
4034 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4035 atag += 1
4036 if autotag and hasattr(self, 'ext_list'):
4037 for e in (self.ext_list):
4038 e.val.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4039 atag += 1
4040 # register components
4041 for e in (self.elt_list):
4042 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4043 if hasattr(self, 'ext_list'):
4044 for e in (self.ext_list):
4045 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4046 if hasattr(self, 'elt_list2'):
4047 for e in (self.elt_list2):
4048 e.val.eth_reg(ident, ectx, tstrip=1, parent=ident)
4049  
4050 def eth_type_default_table(self, ectx, tname):
4051 #print "eth_type_default_table(tname='%s')" % (tname)
4052 fname = ectx.eth_type[tname]['ref'][0]
4053 table = "static const %(ER)s_sequence_t %(TABLE)s[] = {\n"
4054 if hasattr(self, 'ext_list'):
4055 ext = 'ASN1_EXTENSION_ROOT'
4056 else:
4057 ext = 'ASN1_NO_EXTENSIONS'
4058 empty_ext_flag = '0'
4059 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0) and (not hasattr(self, 'elt_list2') or (len(self.elt_list2)==0)):
4060 empty_ext_flag = ext
4061 for e in (self.elt_list):
4062 f = fname + '/' + e.val.name
4063 table += self.out_item(f, e.val, e.optional, ext, ectx)
4064 if hasattr(self, 'ext_list'):
4065 for e in (self.ext_list):
4066 f = fname + '/' + e.val.name
4067 table += self.out_item(f, e.val, e.optional, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4068 if hasattr(self, 'elt_list2'):
4069 for e in (self.elt_list2):
4070 f = fname + '/' + e.val.name
4071 table += self.out_item(f, e.val, e.optional, ext, ectx)
4072 if (ectx.Ber()):
4073 table += " { NULL, 0, 0, 0, NULL }\n};\n"
4074 else:
4075 table += " { NULL, %s, 0, NULL }\n};\n" % (empty_ext_flag)
4076 return table
4077  
4078 #--- SeqOfType -----------------------------------------------------------
4079 class SeqOfType (SqType):
4080 def eth_type_default_table(self, ectx, tname):
4081 #print "eth_type_default_table(tname='%s')" % (tname)
4082 fname = ectx.eth_type[tname]['ref'][0]
4083 if self.val.IsNamed ():
4084 f = fname + '/' + self.val.name
4085 else:
4086 f = fname + '/' + ITEM_FIELD_NAME
4087 table = "static const %(ER)s_sequence_t %(TABLE)s[1] = {\n"
4088 table += self.out_item(f, self.val, False, 'ASN1_NO_EXTENSIONS', ectx)
4089 table += "};\n"
4090 return table
4091  
4092 #--- SequenceOfType -----------------------------------------------------------
4093 class SequenceOfType (SeqOfType):
4094 def to_python (self, ctx):
4095 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4096 # or '' + (1,) for optional
4097 sizestr = ''
4098 if self.size_constr != None:
4099 print("#Ignoring size constraint:", self.size_constr.subtype)
4100 return "%sasn1.SEQUENCE_OF (%s%s)" % (ctx.spaces (),
4101 self.val.to_python (ctx),
4102 sizestr)
4103  
4104 def eth_reg_sub(self, ident, ectx):
4105 itmnm = ident
4106 if not self.val.IsNamed ():
4107 itmnm += '/' + ITEM_FIELD_NAME
4108 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='[##]', parent=ident)
4109  
4110 def eth_tname(self):
4111 if self.val.type != 'Type_Ref':
4112 return '#' + self.type + '_' + str(id(self))
4113 if not self.HasConstraint():
4114 return "SEQUENCE_OF_" + self.val.eth_tname()
4115 elif self.constr.IsSize():
4116 return 'SEQUENCE_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4117 else:
4118 return '#' + self.type + '_' + str(id(self))
4119  
4120 def eth_ftype(self, ectx):
4121 return ('FT_UINT32', 'BASE_DEC')
4122  
4123 def eth_need_tree(self):
4124 return True
4125  
4126 def GetTTag(self, ectx):
4127 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4128  
4129 def eth_type_default_pars(self, ectx, tname):
4130 pars = Type.eth_type_default_pars(self, ectx, tname)
4131 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4132 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
4133 return pars
4134  
4135 def eth_type_default_body(self, ectx, tname):
4136 if (ectx.Ber()):
4137 if (ectx.constraints_check and self.HasSizeConstraint()):
4138 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4139 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4140 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4141 else:
4142 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4143 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4144 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4145 elif (ectx.Per() and not self.HasConstraint()):
4146 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_of', ret='offset',
4147 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4148 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4149 elif (ectx.Per() and self.constr.type == 'Size'):
4150 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_sequence_of', ret='offset',
4151 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4152 ('%(ETT_INDEX)s', '%(TABLE)s',),
4153 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s'),))
4154 else:
4155 body = '#error Can not decode %s' % (tname)
4156 return body
4157  
4158  
4159 #--- SetOfType ----------------------------------------------------------------
4160 class SetOfType (SeqOfType):
4161 def eth_reg_sub(self, ident, ectx):
4162 itmnm = ident
4163 if not self.val.IsNamed ():
4164 itmnm += '/' + ITEM_FIELD_NAME
4165 self.val.eth_reg(itmnm, ectx, tstrip=1, idx='(##)', parent=ident)
4166  
4167 def eth_tname(self):
4168 if self.val.type != 'Type_Ref':
4169 return '#' + self.type + '_' + str(id(self))
4170 if not self.HasConstraint():
4171 return "SET_OF_" + self.val.eth_tname()
4172 elif self.constr.IsSize():
4173 return 'SET_' + self.constr.eth_constrname() + '_OF_' + self.val.eth_tname()
4174 else:
4175 return '#' + self.type + '_' + str(id(self))
4176  
4177 def eth_ftype(self, ectx):
4178 return ('FT_UINT32', 'BASE_DEC')
4179  
4180 def eth_need_tree(self):
4181 return True
4182  
4183 def GetTTag(self, ectx):
4184 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4185  
4186 def eth_type_default_pars(self, ectx, tname):
4187 pars = Type.eth_type_default_pars(self, ectx, tname)
4188 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
4189 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
4190 return pars
4191  
4192 def eth_type_default_body(self, ectx, tname):
4193 if (ectx.Ber()):
4194 if (ectx.constraints_check and self.HasSizeConstraint()):
4195 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4196 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4197 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4198 else:
4199 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4200 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4201 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4202 elif (ectx.Per() and not self.HasConstraint()):
4203 body = ectx.eth_fn_call('dissect_%(ER)s_set_of', ret='offset',
4204 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4205 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4206 elif (ectx.Per() and self.constr.type == 'Size'):
4207 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_set_of', ret='offset',
4208 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4209 ('%(ETT_INDEX)s', '%(TABLE)s',),
4210 ('%(MIN_VAL)s', '%(MAX_VAL)s','%(EXT)s',),))
4211 else:
4212 body = '#error Can not decode %s' % (tname)
4213 return body
4214  
4215 def mk_tag_str (ctx, cls, typ, num):
4216  
4217 # XXX should do conversion to int earlier!
4218 val = int (num)
4219 typ = typ.upper()
4220 if typ == 'DEFAULT':
4221 typ = ctx.tags_def
4222 return 'asn1.%s(%d,cls=asn1.%s_FLAG)' % (typ, val, cls) # XXX still ned
4223  
4224 #--- SequenceType -------------------------------------------------------------
4225 class SequenceType (SeqType):
4226 def to_python (self, ctx):
4227 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4228 # or '' + (1,) for optional
4229 # XXX should also collect names for SEQUENCE inside SEQUENCE or
4230 # CHOICE or SEQUENCE_OF (where should the SEQUENCE_OF name come
4231 # from? for others, element or arm name would be fine)
4232 seq_name = getattr (self, 'sequence_name', None)
4233 if seq_name == None:
4234 seq_name = 'None'
4235 else:
4236 seq_name = "'" + seq_name + "'"
4237 if 'ext_list' in self.__dict__:
4238 return "%sasn1.SEQUENCE ([%s], ext=[%s], seq_name = %s)" % (ctx.spaces (),
4239 self.elts_to_py (self.elt_list, ctx),
4240 self.elts_to_py (self.ext_list, ctx), seq_name)
4241 else:
4242 return "%sasn1.SEQUENCE ([%s]), seq_name = %s" % (ctx.spaces (),
4243 self.elts_to_py (self.elt_list, ctx), seq_name)
4244 def elts_to_py (self, list, ctx):
4245 # we have elt_type, val= named_type, maybe default=, optional=
4246 # named_type node: either ident = or typ =
4247 # need to dismember these in order to generate Python output syntax.
4248 ctx.indent ()
4249 def elt_to_py (e):
4250 assert (e.type == 'elt_type')
4251 nt = e.val
4252 optflag = e.optional
4253 #assert (not hasattr (e, 'default')) # XXX add support for DEFAULT!
4254 assert (nt.type == 'named_type')
4255 tagstr = 'None'
4256 identstr = nt.ident
4257 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4258 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4259 nt.typ.tag.tag_typ,nt.typ.tag.num)
4260  
4261  
4262 nt = nt.typ
4263 return "('%s',%s,%s,%d)" % (identstr, tagstr,
4264 nt.typ.to_python (ctx), optflag)
4265 indentstr = ",\n" + ctx.spaces ()
4266 rv = indentstr.join ([elt_to_py (e) for e in list])
4267 ctx.outdent ()
4268 return rv
4269  
4270 def eth_need_tree(self):
4271 return True
4272  
4273 def GetTTag(self, ectx):
4274 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SEQUENCE')
4275  
4276 def eth_type_default_pars(self, ectx, tname):
4277 pars = Type.eth_type_default_pars(self, ectx, tname)
4278 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4279 return pars
4280  
4281 def eth_type_default_body(self, ectx, tname):
4282 if (ectx.Ber()):
4283 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4284 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4285 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4286 elif (ectx.Per()):
4287 body = ectx.eth_fn_call('dissect_%(ER)s_sequence', ret='offset',
4288 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4289 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4290 else:
4291 body = '#error Can not decode %s' % (tname)
4292 return body
4293  
4294 #--- ExtensionAdditionGroup ---------------------------------------------------
4295 class ExtensionAdditionGroup (SeqType):
4296 def __init__(self,*args, **kw) :
4297 self.parent_ident = None
4298 self.parent_tname = None
4299 SeqType.__init__ (self,*args, **kw)
4300  
4301 def eth_omit_field(self):
4302 return True
4303  
4304 def eth_tname(self):
4305 if (self.parent_tname and self.IsNamed()):
4306 return self.parent_tname + "_" + self.name
4307 else:
4308 return SeqType.eth_tname(self)
4309  
4310 def eth_reg_sub(self, ident, ectx):
4311 ectx.eth_dummy_eag_field_required()
4312 ectx.eth_dep_add(self.parent_ident, ident)
4313 SeqType.eth_reg_sub(self, ident, ectx)
4314  
4315 def eth_type_default_pars(self, ectx, tname):
4316 pars = Type.eth_type_default_pars(self, ectx, tname)
4317 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
4318 return pars
4319  
4320 def eth_type_default_body(self, ectx, tname):
4321 if (ectx.Per()):
4322 body = ectx.eth_fn_call('dissect_%(ER)s_sequence_eag', ret='offset',
4323 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(TABLE)s',),))
4324 else:
4325 body = '#error Can not decode %s' % (tname)
4326 return body
4327  
4328  
4329 #--- SetType ------------------------------------------------------------------
4330 class SetType (SeqType):
4331  
4332 def eth_need_tree(self):
4333 return True
4334  
4335 def GetTTag(self, ectx):
4336 return ('BER_CLASS_UNI', 'BER_UNI_TAG_SET')
4337  
4338 def eth_type_default_pars(self, ectx, tname):
4339 pars = Type.eth_type_default_pars(self, ectx, tname)
4340 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
4341 return pars
4342  
4343 def eth_type_default_body(self, ectx, tname):
4344 if (ectx.Ber()):
4345 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4346 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4347 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),))
4348 elif (ectx.Per()):
4349 body = ectx.eth_fn_call('dissect_%(ER)s_set', ret='offset',
4350 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4351 ('%(ETT_INDEX)s', '%(TABLE)s',),))
4352 else:
4353 body = '#error Can not decode %s' % (tname)
4354 return body
4355  
4356 #--- ChoiceType ---------------------------------------------------------------
4357 class ChoiceType (Type):
4358 def to_python (self, ctx):
4359 # name, tag (None for no tag, EXPLICIT() for explicit), typ)
4360 # or '' + (1,) for optional
4361 if 'ext_list' in self.__dict__:
4362 return "%sasn1.CHOICE ([%s], ext=[%s])" % (ctx.spaces (),
4363 self.elts_to_py (self.elt_list, ctx),
4364 self.elts_to_py (self.ext_list, ctx))
4365 else:
4366 return "%sasn1.CHOICE ([%s])" % (ctx.spaces (), self.elts_to_py (self.elt_list, ctx))
4367 def elts_to_py (self, list, ctx):
4368 ctx.indent ()
4369 def elt_to_py (nt):
4370 assert (nt.type == 'named_type')
4371 tagstr = 'None'
4372 if hasattr (nt, 'ident'):
4373 identstr = nt.ident
4374 else:
4375 if hasattr (nt.typ, 'val'):
4376 identstr = nt.typ.val # XXX, making up name
4377 elif hasattr (nt.typ, 'name'):
4378 identstr = nt.typ.name
4379 else:
4380 identstr = ctx.make_new_name ()
4381  
4382 if hasattr (nt.typ, 'type') and nt.typ.type == 'tag': # ugh
4383 tagstr = mk_tag_str (ctx,nt.typ.tag.cls,
4384 nt.typ.tag.tag_typ,nt.typ.tag.num)
4385  
4386  
4387 nt = nt.typ
4388 return "('%s',%s,%s)" % (identstr, tagstr,
4389 nt.typ.to_python (ctx))
4390 indentstr = ",\n" + ctx.spaces ()
4391 rv = indentstr.join ([elt_to_py (e) for e in list])
4392 ctx.outdent ()
4393 return rv
4394  
4395 def eth_reg_sub(self, ident, ectx):
4396 #print "eth_reg_sub(ident='%s')" % (ident)
4397 # check if autotag is required
4398 autotag = False
4399 if (ectx.NeedTags() and (ectx.tag_def == 'AUTOMATIC')):
4400 autotag = True
4401 for e in (self.elt_list):
4402 if e.HasOwnTag(): autotag = False; break;
4403 if autotag and hasattr(self, 'ext_list'):
4404 for e in (self.ext_list):
4405 if e.HasOwnTag(): autotag = False; break;
4406 # do autotag
4407 if autotag:
4408 atag = 0
4409 for e in (self.elt_list):
4410 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4411 atag += 1
4412 if autotag and hasattr(self, 'ext_list'):
4413 for e in (self.ext_list):
4414 e.AddTag(Tag(cls = 'CONTEXT', num = str(atag), mode = 'IMPLICIT'))
4415 atag += 1
4416 for e in (self.elt_list):
4417 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4418 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4419 ectx.eth_sel_req(ident, e.name)
4420 if hasattr(self, 'ext_list'):
4421 for e in (self.ext_list):
4422 e.eth_reg(ident, ectx, tstrip=1, parent=ident)
4423 if ectx.conform.check_item('EXPORTS', ident + '.' + e.name):
4424 ectx.eth_sel_req(ident, e.name)
4425  
4426 def sel_item(self, ident, sel, ectx):
4427 lst = self.elt_list[:]
4428 if hasattr(self, 'ext_list'):
4429 lst.extend(self.ext_list)
4430 ee = None
4431 for e in (self.elt_list):
4432 if e.IsNamed() and (e.name == sel):
4433 ee = e
4434 break
4435 if not ee:
4436 print("#CHOICE %s does not contain item %s" % (ident, sel))
4437 return ee
4438  
4439 def sel_req(self, ident, sel, ectx):
4440 #print "sel_req(ident='%s', sel=%s)\n%s" % (ident, sel, str(self))
4441 ee = self.sel_item(ident, sel, ectx)
4442 if ee:
4443 ee.eth_reg(ident, ectx, tstrip=0, selflag=True)
4444  
4445 def eth_ftype(self, ectx):
4446 return ('FT_UINT32', 'BASE_DEC')
4447  
4448 def eth_ftype_sel(self, sel, ectx):
4449 ee = self.sel_item('', sel, ectx)
4450 if ee:
4451 return ee.eth_ftype(ectx)
4452 else:
4453 return ('FT_NONE', 'BASE_NONE')
4454  
4455 def eth_strings(self):
4456 return '$$'
4457  
4458 def eth_need_tree(self):
4459 return True
4460  
4461 def eth_has_vals(self):
4462 return True
4463  
4464 def GetTTag(self, ectx):
4465 lst = self.elt_list
4466 cls = 'BER_CLASS_ANY/*choice*/'
4467 #if hasattr(self, 'ext_list'):
4468 # lst.extend(self.ext_list)
4469 #if (len(lst) > 0):
4470 # cls = lst[0].GetTag(ectx)[0]
4471 #for e in (lst):
4472 # if (e.GetTag(ectx)[0] != cls):
4473 # cls = '-1/*choice*/'
4474 return (cls, '-1/*choice*/')
4475  
4476 def GetTTagSel(self, sel, ectx):
4477 ee = self.sel_item('', sel, ectx)
4478 if ee:
4479 return ee.GetTag(ectx)
4480 else:
4481 return ('BER_CLASS_ANY/*unknown selection*/', '-1/*unknown selection*/')
4482  
4483 def IndetermTag(self, ectx):
4484 #print "Choice IndetermTag()=%s" % (str(not self.HasOwnTag()))
4485 return not self.HasOwnTag()
4486  
4487 def detect_tagval(self, ectx):
4488 tagval = False
4489 lst = self.elt_list[:]
4490 if hasattr(self, 'ext_list'):
4491 lst.extend(self.ext_list)
4492 if (len(lst) > 0) and (not ectx.Per() or lst[0].HasOwnTag()):
4493 t = lst[0].GetTag(ectx)[0]
4494 tagval = True
4495 else:
4496 t = ''
4497 tagval = False
4498 if (t == 'BER_CLASS_UNI'):
4499 tagval = False
4500 for e in (lst):
4501 if not ectx.Per() or e.HasOwnTag():
4502 tt = e.GetTag(ectx)[0]
4503 else:
4504 tt = ''
4505 tagval = False
4506 if (tt != t):
4507 tagval = False
4508 return tagval
4509  
4510 def get_vals(self, ectx):
4511 tagval = self.detect_tagval(ectx)
4512 vals = []
4513 cnt = 0
4514 for e in (self.elt_list):
4515 if (tagval): val = e.GetTag(ectx)[1]
4516 else: val = str(cnt)
4517 vals.append((val, e.name))
4518 cnt += 1
4519 if hasattr(self, 'ext_list'):
4520 for e in (self.ext_list):
4521 if (tagval): val = e.GetTag(ectx)[1]
4522 else: val = str(cnt)
4523 vals.append((val, e.name))
4524 cnt += 1
4525 return vals
4526  
4527 def eth_type_vals(self, tname, ectx):
4528 out = '\n'
4529 vals = self.get_vals(ectx)
4530 out += ectx.eth_vals(tname, vals)
4531 return out
4532  
4533 def reg_enum_vals(self, tname, ectx):
4534 vals = self.get_vals(ectx)
4535 for (val, id) in vals:
4536 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4537  
4538 def eth_type_enum(self, tname, ectx):
4539 out = '\n'
4540 vals = self.get_vals(ectx)
4541 out += ectx.eth_enum(tname, vals)
4542 return out
4543  
4544 def eth_type_default_pars(self, ectx, tname):
4545 pars = Type.eth_type_default_pars(self, ectx, tname)
4546 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
4547 return pars
4548  
4549 def eth_type_default_table(self, ectx, tname):
4550 def out_item(val, e, ext, ectx):
4551 has_enum = ectx.eth_type[tname]['enum'] & EF_ENUM
4552 if (has_enum):
4553 vval = ectx.eth_enum_item(tname, e.name)
4554 else:
4555 vval = val
4556 f = fname + '/' + e.name
4557 ef = ectx.field[f]['ethname']
4558 t = ectx.eth_hf[ef]['ethtype']
4559 if (ectx.Ber()):
4560 opt = ''
4561 if (not e.HasOwnTag()):
4562 opt = 'BER_FLAGS_NOOWNTAG'
4563 elif (e.HasImplicitTag(ectx)):
4564 if (opt): opt += '|'
4565 opt += 'BER_FLAGS_IMPLTAG'
4566 if (not opt): opt = '0'
4567 if (ectx.Ber()):
4568 (tc, tn) = e.GetTag(ectx)
4569 out = ' { %3s, %-24s, %-13s, %s, %s, dissect_%s_%s },\n' \
4570 % (vval, '&'+ectx.eth_hf[ef]['fullname'], tc, tn, opt, ectx.eth_type[t]['proto'], t)
4571 elif (ectx.Per()):
4572 out = ' { %3s, %-24s, %-23s, dissect_%s_%s },\n' \
4573 % (vval, '&'+ectx.eth_hf[ef]['fullname'], ext, ectx.eth_type[t]['proto'], t)
4574 else:
4575 out = ''
4576 return out
4577 # end out_item()
4578 #print "eth_type_default_table(tname='%s')" % (tname)
4579 fname = ectx.eth_type[tname]['ref'][0]
4580 tagval = self.detect_tagval(ectx)
4581 table = "static const %(ER)s_choice_t %(TABLE)s[] = {\n"
4582 cnt = 0
4583 if hasattr(self, 'ext_list'):
4584 ext = 'ASN1_EXTENSION_ROOT'
4585 else:
4586 ext = 'ASN1_NO_EXTENSIONS'
4587 empty_ext_flag = '0'
4588 if (len(self.elt_list)==0) and hasattr(self, 'ext_list') and (len(self.ext_list)==0):
4589 empty_ext_flag = ext
4590 for e in (self.elt_list):
4591 if (tagval): val = e.GetTag(ectx)[1]
4592 else: val = str(cnt)
4593 table += out_item(val, e, ext, ectx)
4594 cnt += 1
4595 if hasattr(self, 'ext_list'):
4596 for e in (self.ext_list):
4597 if (tagval): val = e.GetTag(ectx)[1]
4598 else: val = str(cnt)
4599 table += out_item(val, e, 'ASN1_NOT_EXTENSION_ROOT', ectx)
4600 cnt += 1
4601 if (ectx.Ber()):
4602 table += " { 0, NULL, 0, 0, 0, NULL }\n};\n"
4603 else:
4604 table += " { 0, NULL, %s, NULL }\n};\n" % (empty_ext_flag)
4605 return table
4606  
4607 def eth_type_default_body(self, ectx, tname):
4608 if (ectx.Ber()):
4609 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4610 par=(('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4611 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s'),
4612 ('%(VAL_PTR)s',),))
4613 elif (ectx.Per()):
4614 body = ectx.eth_fn_call('dissect_%(ER)s_choice', ret='offset',
4615 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4616 ('%(ETT_INDEX)s', '%(TABLE)s',),
4617 ('%(VAL_PTR)s',),))
4618 else:
4619 body = '#error Can not decode %s' % (tname)
4620 return body
4621  
4622 #--- ChoiceValue ----------------------------------------------------
4623 class ChoiceValue (Value):
4624 def to_str(self, ectx):
4625 return self.val.to_str(ectx)
4626  
4627 def fld_obj_eq(self, other):
4628 return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
4629  
4630 #--- EnumeratedType -----------------------------------------------------------
4631 class EnumeratedType (Type):
4632 def to_python (self, ctx):
4633 def strify_one (named_num):
4634 return "%s=%s" % (named_num.ident, named_num.val)
4635 return "asn1.ENUM(%s)" % ",".join (map (strify_one, self.val))
4636  
4637 def eth_ftype(self, ectx):
4638 return ('FT_UINT32', 'BASE_DEC')
4639  
4640 def eth_strings(self):
4641 return '$$'
4642  
4643 def eth_has_vals(self):
4644 return True
4645  
4646 def GetTTag(self, ectx):
4647 return ('BER_CLASS_UNI', 'BER_UNI_TAG_ENUMERATED')
4648  
4649 def get_vals_etc(self, ectx):
4650 vals = []
4651 lastv = 0
4652 used = {}
4653 maxv = 0
4654 root_num = 0
4655 ext_num = 0
4656 map_table = []
4657 for e in (self.val):
4658 if e.type == 'NamedNumber':
4659 used[int(e.val)] = True
4660 for e in (self.val):
4661 if e.type == 'NamedNumber':
4662 val = int(e.val)
4663 else:
4664 while lastv in used:
4665 lastv += 1
4666 val = lastv
4667 used[val] = True
4668 vals.append((val, e.ident))
4669 map_table.append(val)
4670 root_num += 1
4671 if val > maxv:
4672 maxv = val
4673 if self.ext is not None:
4674 for e in (self.ext):
4675 if e.type == 'NamedNumber':
4676 used[int(e.val)] = True
4677 for e in (self.ext):
4678 if e.type == 'NamedNumber':
4679 val = int(e.val)
4680 else:
4681 while lastv in used:
4682 lastv += 1
4683 val = lastv
4684 used[val] = True
4685 vals.append((val, e.ident))
4686 map_table.append(val)
4687 ext_num += 1
4688 if val > maxv:
4689 maxv = val
4690 need_map = False
4691 for i in range(len(map_table)):
4692 need_map = need_map or (map_table[i] != i)
4693 if (not need_map):
4694 map_table = None
4695 return (vals, root_num, ext_num, map_table)
4696  
4697 def eth_type_vals(self, tname, ectx):
4698 out = '\n'
4699 vals = self.get_vals_etc(ectx)[0]
4700 out += ectx.eth_vals(tname, vals)
4701 return out
4702  
4703 def reg_enum_vals(self, tname, ectx):
4704 vals = self.get_vals_etc(ectx)[0]
4705 for (val, id) in vals:
4706 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
4707  
4708 def eth_type_enum(self, tname, ectx):
4709 out = '\n'
4710 vals = self.get_vals_etc(ectx)[0]
4711 out += ectx.eth_enum(tname, vals)
4712 return out
4713  
4714 def eth_type_default_pars(self, ectx, tname):
4715 pars = Type.eth_type_default_pars(self, ectx, tname)
4716 (root_num, ext_num, map_table) = self.get_vals_etc(ectx)[1:]
4717 if (self.ext != None):
4718 ext = 'TRUE'
4719 else:
4720 ext = 'FALSE'
4721 pars['ROOT_NUM'] = str(root_num)
4722 pars['EXT'] = ext
4723 pars['EXT_NUM'] = str(ext_num)
4724 if (map_table):
4725 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
4726 else:
4727 pars['TABLE'] = 'NULL'
4728 return pars
4729  
4730 def eth_type_default_table(self, ectx, tname):
4731 if (not ectx.Per()): return ''
4732 map_table = self.get_vals_etc(ectx)[3]
4733 if (map_table == None): return ''
4734 table = "static guint32 %(TABLE)s[%(ROOT_NUM)s+%(EXT_NUM)s] = {"
4735 table += ", ".join([str(v) for v in map_table])
4736 table += "};\n"
4737 return table
4738  
4739 def eth_type_default_body(self, ectx, tname):
4740 if (ectx.Ber()):
4741 if (ectx.constraints_check and self.HasValueConstraint()):
4742 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer', ret='offset',
4743 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
4744 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4745 else:
4746 body = ectx.eth_fn_call('dissect_%(ER)s_integer', ret='offset',
4747 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4748 ('%(VAL_PTR)s',),))
4749 elif (ectx.Per()):
4750 body = ectx.eth_fn_call('dissect_%(ER)s_enumerated', ret='offset',
4751 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
4752 ('%(ROOT_NUM)s', '%(VAL_PTR)s', '%(EXT)s', '%(EXT_NUM)s', '%(TABLE)s',),))
4753 else:
4754 body = '#error Can not decode %s' % (tname)
4755 return body
4756  
4757 #--- EmbeddedPDVType -----------------------------------------------------------
4758 class EmbeddedPDVType (Type):
4759 def eth_tname(self):
4760 return 'EMBEDDED_PDV'
4761  
4762 def eth_ftype(self, ectx):
4763 return ('FT_NONE', 'BASE_NONE')
4764  
4765 def GetTTag(self, ectx):
4766 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EMBEDDED_PDV')
4767  
4768 def eth_type_default_pars(self, ectx, tname):
4769 pars = Type.eth_type_default_pars(self, ectx, tname)
4770 if ectx.default_embedded_pdv_cb:
4771 pars['TYPE_REF_FN'] = ectx.default_embedded_pdv_cb
4772 else:
4773 pars['TYPE_REF_FN'] = 'NULL'
4774 return pars
4775  
4776 def eth_type_default_body(self, ectx, tname):
4777 if (ectx.Ber()):
4778 body = ectx.eth_fn_call('dissect_%(ER)s_EmbeddedPDV_Type', ret='offset',
4779 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4780 elif (ectx.Per()):
4781 body = ectx.eth_fn_call('dissect_%(ER)s_embedded_pdv', ret='offset',
4782 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4783 else:
4784 body = '#error Can not decode %s' % (tname)
4785 return body
4786  
4787 #--- ExternalType -----------------------------------------------------------
4788 class ExternalType (Type):
4789 def eth_tname(self):
4790 return 'EXTERNAL'
4791  
4792 def eth_ftype(self, ectx):
4793 return ('FT_NONE', 'BASE_NONE')
4794  
4795 def GetTTag(self, ectx):
4796 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4797  
4798 def eth_type_default_pars(self, ectx, tname):
4799 pars = Type.eth_type_default_pars(self, ectx, tname)
4800 if ectx.default_external_type_cb:
4801 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4802 else:
4803 pars['TYPE_REF_FN'] = 'NULL'
4804 return pars
4805  
4806 def eth_type_default_body(self, ectx, tname):
4807 if (ectx.Ber()):
4808 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4809 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4810 elif (ectx.Per()):
4811 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4812 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4813 else:
4814 body = '#error Can not decode %s' % (tname)
4815 return body
4816  
4817 #--- OpenType -----------------------------------------------------------
4818 class OpenType (Type):
4819 def to_python (self, ctx):
4820 return "asn1.ANY"
4821  
4822 def single_type(self):
4823 if (self.HasConstraint() and
4824 self.constr.type == 'Type' and
4825 self.constr.subtype.type == 'Type_Ref'):
4826 return self.constr.subtype.val
4827 return None
4828  
4829 def eth_reg_sub(self, ident, ectx):
4830 t = self.single_type()
4831 if t:
4832 ectx.eth_dep_add(ident, t)
4833  
4834 def eth_tname(self):
4835 t = self.single_type()
4836 if t:
4837 return 'OpenType_' + t
4838 else:
4839 return Type.eth_tname(self)
4840  
4841 def eth_ftype(self, ectx):
4842 return ('FT_NONE', 'BASE_NONE')
4843  
4844 def GetTTag(self, ectx):
4845 return ('BER_CLASS_ANY', '0')
4846  
4847 def eth_type_default_pars(self, ectx, tname):
4848 pars = Type.eth_type_default_pars(self, ectx, tname)
4849 pars['FN_VARIANT'] = ectx.default_opentype_variant
4850 t = self.single_type()
4851 if t:
4852 t = ectx.type[t]['ethname']
4853 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
4854 pars['TYPE_REF_TNAME'] = t
4855 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
4856 else:
4857 pars['TYPE_REF_FN'] = 'NULL'
4858 return pars
4859  
4860 def eth_type_default_body(self, ectx, tname):
4861 if (ectx.Per()):
4862 body = ectx.eth_fn_call('dissect_%(ER)s_open_type%(FN_VARIANT)s', ret='offset',
4863 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4864 else:
4865 body = '#error Can not decode %s' % (tname)
4866 return body
4867  
4868 #--- InstanceOfType -----------------------------------------------------------
4869 class InstanceOfType (Type):
4870 def eth_tname(self):
4871 return 'INSTANCE_OF'
4872  
4873 def eth_ftype(self, ectx):
4874 return ('FT_NONE', 'BASE_NONE')
4875  
4876 def GetTTag(self, ectx):
4877 return ('BER_CLASS_UNI', 'BER_UNI_TAG_EXTERNAL')
4878  
4879 def eth_type_default_pars(self, ectx, tname):
4880 pars = Type.eth_type_default_pars(self, ectx, tname)
4881 if ectx.default_external_type_cb:
4882 pars['TYPE_REF_FN'] = ectx.default_external_type_cb
4883 else:
4884 pars['TYPE_REF_FN'] = 'NULL'
4885 return pars
4886  
4887 def eth_type_default_body(self, ectx, tname):
4888 if (ectx.Ber()):
4889 body = ectx.eth_fn_call('dissect_%(ER)s_external_type', ret='offset',
4890 par=(('%(IMPLICIT_TAG)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(HF_INDEX)s', '%(TYPE_REF_FN)s',),))
4891 elif (ectx.Per()):
4892 body = '#error Can not decode %s' % (tname)
4893 else:
4894 body = '#error Can not decode %s' % (tname)
4895 return body
4896  
4897 #--- AnyType -----------------------------------------------------------
4898 class AnyType (Type):
4899 def to_python (self, ctx):
4900 return "asn1.ANY"
4901  
4902 def eth_ftype(self, ectx):
4903 return ('FT_NONE', 'BASE_NONE')
4904  
4905 def GetTTag(self, ectx):
4906 return ('BER_CLASS_ANY', '0')
4907  
4908 def eth_type_default_body(self, ectx, tname):
4909 body = '#error Can not decode %s' % (tname)
4910 return body
4911  
4912 class Literal (Node):
4913 def to_python (self, ctx):
4914 return self.val
4915  
4916 #--- NullType -----------------------------------------------------------------
4917 class NullType (Type):
4918 def to_python (self, ctx):
4919 return 'asn1.NULL'
4920  
4921 def eth_tname(self):
4922 return 'NULL'
4923  
4924 def GetTTag(self, ectx):
4925 return ('BER_CLASS_UNI', 'BER_UNI_TAG_NULL')
4926  
4927 def eth_type_default_body(self, ectx, tname):
4928 if (ectx.Ber()):
4929 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4930 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
4931 elif (ectx.Per()):
4932 body = ectx.eth_fn_call('dissect_%(ER)s_null', ret='offset',
4933 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
4934 else:
4935 body = '#error Can not decode %s' % (tname)
4936 return body
4937  
4938 #--- NullValue ----------------------------------------------------
4939 class NullValue (Value):
4940 def to_str(self, ectx):
4941 return 'NULL'
4942  
4943 #--- RealType -----------------------------------------------------------------
4944 class RealType (Type):
4945 def to_python (self, ctx):
4946 return 'asn1.REAL'
4947  
4948 def eth_tname(self):
4949 return 'REAL'
4950  
4951 def GetTTag(self, ectx):
4952 return ('BER_CLASS_UNI', 'BER_UNI_TAG_REAL')
4953  
4954 def eth_ftype(self, ectx):
4955 return ('FT_DOUBLE', 'BASE_NONE')
4956  
4957 def eth_type_default_body(self, ectx, tname):
4958 if (ectx.Ber()):
4959 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4960 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
4961 ('%(VAL_PTR)s',),))
4962 elif (ectx.Per()):
4963 body = ectx.eth_fn_call('dissect_%(ER)s_real', ret='offset',
4964 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4965 else:
4966 body = '#error Can not decode %s' % (tname)
4967 return body
4968  
4969 #--- BooleanType --------------------------------------------------------------
4970 class BooleanType (Type):
4971 def to_python (self, ctx):
4972 return 'asn1.BOOLEAN'
4973  
4974 def eth_tname(self):
4975 return 'BOOLEAN'
4976  
4977 def GetTTag(self, ectx):
4978 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BOOLEAN')
4979  
4980 def eth_ftype(self, ectx):
4981 return ('FT_BOOLEAN', 'BASE_NONE')
4982  
4983 def eth_type_default_body(self, ectx, tname):
4984 if (ectx.Ber()):
4985 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4986 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
4987 elif (ectx.Per()):
4988 body = ectx.eth_fn_call('dissect_%(ER)s_boolean', ret='offset',
4989 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
4990 else:
4991 body = '#error Can not decode %s' % (tname)
4992 return body
4993  
4994 #--- OctetStringType ----------------------------------------------------------
4995 class OctetStringType (Type):
4996 def to_python (self, ctx):
4997 return 'asn1.OCTSTRING'
4998  
4999 def eth_tname(self):
5000 if not self.HasConstraint():
5001 return 'OCTET_STRING'
5002 elif self.constr.type == 'Size':
5003 return 'OCTET_STRING' + '_' + self.constr.eth_constrname()
5004 else:
5005 return '#' + self.type + '_' + str(id(self))
5006  
5007 def eth_ftype(self, ectx):
5008 return ('FT_BYTES', 'BASE_NONE')
5009  
5010 def GetTTag(self, ectx):
5011 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OCTETSTRING')
5012  
5013 def eth_need_pdu(self, ectx):
5014 pdu = None
5015 if self.HasContentsConstraint():
5016 t = self.constr.GetContents(ectx)
5017 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5018 pdu = { 'type' : t,
5019 'new' : ectx.default_containing_variant == '_pdu_new' }
5020 return pdu
5021  
5022 def eth_type_default_pars(self, ectx, tname):
5023 pars = Type.eth_type_default_pars(self, ectx, tname)
5024 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5025 if self.HasContentsConstraint():
5026 pars['FN_VARIANT'] = ectx.default_containing_variant
5027 t = self.constr.GetContents(ectx)
5028 if t:
5029 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5030 t = ectx.field[t]['ethname']
5031 pars['TYPE_REF_PROTO'] = ''
5032 pars['TYPE_REF_TNAME'] = t
5033 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5034 else:
5035 t = ectx.type[t]['ethname']
5036 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5037 pars['TYPE_REF_TNAME'] = t
5038 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5039 else:
5040 pars['TYPE_REF_FN'] = 'NULL'
5041 return pars
5042  
5043 def eth_type_default_body(self, ectx, tname):
5044 if (ectx.Ber()):
5045 if (ectx.constraints_check and self.HasSizeConstraint()):
5046 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_octet_string', ret='offset',
5047 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5048 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5049 else:
5050 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5051 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5052 ('%(VAL_PTR)s',),))
5053 elif (ectx.Per()):
5054 if self.HasContentsConstraint():
5055 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string_containing%(FN_VARIANT)s', ret='offset',
5056 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5057 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s',),))
5058 else:
5059 body = ectx.eth_fn_call('dissect_%(ER)s_octet_string', ret='offset',
5060 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5061 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s',),))
5062 else:
5063 body = '#error Can not decode %s' % (tname)
5064 return body
5065  
5066 #--- CharacterStringType ------------------------------------------------------
5067 class CharacterStringType (Type):
5068 def eth_tname(self):
5069 if not self.HasConstraint():
5070 return self.eth_tsname()
5071 elif self.constr.type == 'Size':
5072 return self.eth_tsname() + '_' + self.constr.eth_constrname()
5073 else:
5074 return '#' + self.type + '_' + str(id(self))
5075  
5076 def eth_ftype(self, ectx):
5077 return ('FT_STRING', 'BASE_NONE')
5078  
5079 class RestrictedCharacterStringType (CharacterStringType):
5080 def to_python (self, ctx):
5081 return 'asn1.' + self.eth_tsname()
5082  
5083 def GetTTag(self, ectx):
5084 return ('BER_CLASS_UNI', 'BER_UNI_TAG_' + self.eth_tsname())
5085  
5086 def eth_type_default_pars(self, ectx, tname):
5087 pars = Type.eth_type_default_pars(self, ectx, tname)
5088 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5089 (pars['STRING_TYPE'], pars['STRING_TAG']) = (self.eth_tsname(), self.GetTTag(ectx)[1])
5090 (pars['ALPHABET'], pars['ALPHABET_LEN']) = self.eth_get_alphabet_constr(ectx)
5091 return pars
5092  
5093 def eth_type_default_body(self, ectx, tname):
5094 if (ectx.Ber()):
5095 if (ectx.constraints_check and self.HasSizeConstraint()):
5096 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_restricted_string', ret='offset',
5097 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5098 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5099 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5100 else:
5101 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_string', ret='offset',
5102 par=(('%(IMPLICIT_TAG)s', '%(STRING_TAG)s'),
5103 ('%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5104 ('%(VAL_PTR)s',),))
5105 elif (ectx.Per() and self.HasPermAlph()):
5106 body = ectx.eth_fn_call('dissect_%(ER)s_restricted_character_string', ret='offset',
5107 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5108 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(ALPHABET)s', '%(ALPHABET_LEN)s'),
5109 ('%(VAL_PTR)s',),))
5110 elif (ectx.Per()):
5111 if (self.eth_tsname() == 'GeneralString'):
5112 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5113 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),))
5114 elif (self.eth_tsname() == 'GeneralizedTime'):
5115 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
5116 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5117 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5118 elif (self.eth_tsname() == 'UTCTime'):
5119 body = ectx.eth_fn_call('dissect_%(ER)s_VisibleString', ret='offset',
5120 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5121 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5122 else:
5123 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5124 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5125 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s',),))
5126 else:
5127 body = '#error Can not decode %s' % (tname)
5128 return body
5129  
5130 class BMPStringType (RestrictedCharacterStringType):
5131 def eth_tsname(self):
5132 return 'BMPString'
5133  
5134 class GeneralStringType (RestrictedCharacterStringType):
5135 def eth_tsname(self):
5136 return 'GeneralString'
5137  
5138 class GraphicStringType (RestrictedCharacterStringType):
5139 def eth_tsname(self):
5140 return 'GraphicString'
5141  
5142 class IA5StringType (RestrictedCharacterStringType):
5143 def eth_tsname(self):
5144 return 'IA5String'
5145  
5146 class NumericStringType (RestrictedCharacterStringType):
5147 def eth_tsname(self):
5148 return 'NumericString'
5149  
5150 class PrintableStringType (RestrictedCharacterStringType):
5151 def eth_tsname(self):
5152 return 'PrintableString'
5153  
5154 class TeletexStringType (RestrictedCharacterStringType):
5155 def eth_tsname(self):
5156 return 'TeletexString'
5157  
5158 class T61StringType (RestrictedCharacterStringType):
5159 def eth_tsname(self):
5160 return 'T61String'
5161 def GetTTag(self, ectx):
5162 return ('BER_CLASS_UNI', 'BER_UNI_TAG_TeletexString')
5163  
5164 class UniversalStringType (RestrictedCharacterStringType):
5165 def eth_tsname(self):
5166 return 'UniversalString'
5167  
5168 class UTF8StringType (RestrictedCharacterStringType):
5169 def eth_tsname(self):
5170 return 'UTF8String'
5171  
5172 class VideotexStringType (RestrictedCharacterStringType):
5173 def eth_tsname(self):
5174 return 'VideotexString'
5175  
5176 class VisibleStringType (RestrictedCharacterStringType):
5177 def eth_tsname(self):
5178 return 'VisibleString'
5179  
5180 class ISO646StringType (RestrictedCharacterStringType):
5181 def eth_tsname(self):
5182 return 'ISO646String'
5183 def GetTTag(self, ectx):
5184 return ('BER_CLASS_UNI', 'BER_UNI_TAG_VisibleString')
5185  
5186 class UnrestrictedCharacterStringType (CharacterStringType):
5187 def to_python (self, ctx):
5188 return 'asn1.UnrestrictedCharacterString'
5189 def eth_tsname(self):
5190 return 'CHARACTER_STRING'
5191  
5192 #--- UsefulType ---------------------------------------------------------------
5193 class GeneralizedTime (RestrictedCharacterStringType):
5194 def eth_tsname(self):
5195 return 'GeneralizedTime'
5196  
5197 def eth_type_default_body(self, ectx, tname):
5198 if (ectx.Ber()):
5199 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5200 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5201 return body
5202 else:
5203 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5204  
5205 class UTCTime (RestrictedCharacterStringType):
5206 def eth_tsname(self):
5207 return 'UTCTime'
5208  
5209 def eth_type_default_body(self, ectx, tname):
5210 if (ectx.Ber()):
5211 body = ectx.eth_fn_call('dissect_%(ER)s_%(STRING_TYPE)s', ret='offset',
5212 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),))
5213 return body
5214 else:
5215 return RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5216  
5217 class ObjectDescriptor (RestrictedCharacterStringType):
5218 def eth_tsname(self):
5219 return 'ObjectDescriptor'
5220  
5221 def eth_type_default_body(self, ectx, tname):
5222 if (ectx.Ber()):
5223 body = RestrictedCharacterStringType.eth_type_default_body(self, ectx, tname)
5224 elif (ectx.Per()):
5225 body = ectx.eth_fn_call('dissect_%(ER)s_object_descriptor', ret='offset',
5226 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5227 else:
5228 body = '#error Can not decode %s' % (tname)
5229 return body
5230  
5231 #--- ObjectIdentifierType -----------------------------------------------------
5232 class ObjectIdentifierType (Type):
5233 def to_python (self, ctx):
5234 return 'asn1.OBJECT_IDENTIFIER'
5235  
5236 def eth_tname(self):
5237 return 'OBJECT_IDENTIFIER'
5238  
5239 def eth_ftype(self, ectx):
5240 return ('FT_OID', 'BASE_NONE')
5241  
5242 def GetTTag(self, ectx):
5243 return ('BER_CLASS_UNI', 'BER_UNI_TAG_OID')
5244  
5245 def eth_type_default_pars(self, ectx, tname):
5246 pars = Type.eth_type_default_pars(self, ectx, tname)
5247 pars['FN_VARIANT'] = ectx.default_oid_variant
5248 return pars
5249  
5250 def eth_type_default_body(self, ectx, tname):
5251 if (ectx.Ber()):
5252 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5253 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5254 elif (ectx.Per()):
5255 body = ectx.eth_fn_call('dissect_%(ER)s_object_identifier%(FN_VARIANT)s', ret='offset',
5256 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5257 else:
5258 body = '#error Can not decode %s' % (tname)
5259 return body
5260  
5261 #--- ObjectIdentifierValue ----------------------------------------------------
5262 class ObjectIdentifierValue (Value):
5263 def get_num(self, path, val):
5264 return str(oid_names.get(path + '/' + val, val))
5265  
5266 def to_str(self, ectx):
5267 out = ''
5268 path = ''
5269 first = True
5270 sep = ''
5271 for v in self.comp_list:
5272 if isinstance(v, Node) and (v.type == 'name_and_number'):
5273 vstr = v.number
5274 elif v.isdigit():
5275 vstr = v
5276 else:
5277 vstr = self.get_num(path, v)
5278 if not first and not vstr.isdigit():
5279 vstr = ectx.value_get_val(vstr)
5280 if first:
5281 if vstr.isdigit():
5282 out += '"' + vstr
5283 else:
5284 out += ectx.value_get_eth(vstr) + '"'
5285 else:
5286 out += sep + vstr
5287 path += sep + vstr
5288 first = False
5289 sep = '.'
5290 out += '"'
5291 return out
5292  
5293 def get_dep(self):
5294 v = self.comp_list[0]
5295 if isinstance(v, Node) and (v.type == 'name_and_number'):
5296 return None
5297 elif v.isdigit():
5298 return None
5299 else:
5300 vstr = self.get_num('', v)
5301 if vstr.isdigit():
5302 return None
5303 else:
5304 return vstr
5305  
5306 class NamedNumber(Node):
5307 def to_python (self, ctx):
5308 return "('%s',%s)" % (self.ident, self.val)
5309  
5310 class NamedNumListBase(Node):
5311 def to_python (self, ctx):
5312 return "asn1.%s_class ([%s])" % (self.asn1_typ,",".join (
5313 [x.to_python (ctx) for x in self.named_list]))
5314  
5315 #--- RelativeOIDType ----------------------------------------------------------
5316 class RelativeOIDType (Type):
5317  
5318 def eth_tname(self):
5319 return 'RELATIVE_OID'
5320  
5321 def eth_ftype(self, ectx):
5322 return ('FT_REL_OID', 'BASE_NONE')
5323  
5324 def GetTTag(self, ectx):
5325 return ('BER_CLASS_UNI', 'BER_UNI_TAG_RELATIVE_OID')
5326  
5327 def eth_type_default_pars(self, ectx, tname):
5328 pars = Type.eth_type_default_pars(self, ectx, tname)
5329 pars['FN_VARIANT'] = ectx.default_oid_variant
5330 return pars
5331  
5332 def eth_type_default_body(self, ectx, tname):
5333 if (ectx.Ber()):
5334 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5335 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5336 elif (ectx.Per()):
5337 body = ectx.eth_fn_call('dissect_%(ER)s_relative_oid%(FN_VARIANT)s', ret='offset',
5338 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5339 else:
5340 body = '#error Can not decode %s' % (tname)
5341 return body
5342  
5343  
5344 #--- IntegerType --------------------------------------------------------------
5345 class IntegerType (Type):
5346 def to_python (self, ctx):
5347 return "asn1.INTEGER_class ([%s])" % (",".join (
5348 [x.to_python (ctx) for x in self.named_list]))
5349  
5350 def add_named_value(self, ident, val):
5351 e = NamedNumber(ident = ident, val = val)
5352 if not self.named_list:
5353 self.named_list = []
5354 self.named_list.append(e)
5355  
5356 def eth_tname(self):
5357 if self.named_list:
5358 return Type.eth_tname(self)
5359 if not self.HasConstraint():
5360 return 'INTEGER'
5361 elif self.constr.type == 'SingleValue' or self.constr.type == 'ValueRange':
5362 return 'INTEGER' + '_' + self.constr.eth_constrname()
5363 else:
5364 return 'INTEGER' + '_' + self.constr.eth_tname()
5365  
5366 def GetTTag(self, ectx):
5367 return ('BER_CLASS_UNI', 'BER_UNI_TAG_INTEGER')
5368  
5369  
5370 def eth_ftype(self, ectx):
5371 if self.HasConstraint():
5372 if not self.constr.IsNegativ():
5373 if self.constr.Needs64b(ectx):
5374 return ('FT_UINT64', 'BASE_DEC')
5375 else:
5376 return ('FT_UINT32', 'BASE_DEC')
5377 if self.constr.Needs64b(ectx):
5378 return ('FT_INT64', 'BASE_DEC')
5379 return ('FT_INT32', 'BASE_DEC')
5380  
5381 def eth_strings(self):
5382 if (self.named_list):
5383 return '$$'
5384 else:
5385 return 'NULL'
5386  
5387 def eth_has_vals(self):
5388 if (self.named_list):
5389 return True
5390 else:
5391 return False
5392  
5393 def get_vals(self, ectx):
5394 vals = []
5395 for e in (self.named_list):
5396 vals.append((int(e.val), e.ident))
5397 return vals
5398  
5399 def eth_type_vals(self, tname, ectx):
5400 if not self.eth_has_vals(): return ''
5401 out = '\n'
5402 vals = self.get_vals(ectx)
5403 out += ectx.eth_vals(tname, vals)
5404 return out
5405  
5406 def reg_enum_vals(self, tname, ectx):
5407 vals = self.get_vals(ectx)
5408 for (val, id) in vals:
5409 ectx.eth_reg_value(id, self, val, ethname=ectx.eth_enum_item(tname, id))
5410  
5411 def eth_type_enum(self, tname, ectx):
5412 if not self.eth_has_enum(tname, ectx): return ''
5413 out = '\n'
5414 vals = self.get_vals(ectx)
5415 out += ectx.eth_enum(tname, vals)
5416 return out
5417  
5418 def eth_type_default_pars(self, ectx, tname):
5419 pars = Type.eth_type_default_pars(self, ectx, tname)
5420 if self.HasValueConstraint():
5421 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_value_constr(ectx)
5422 if (pars['FN_VARIANT'] == '') and self.constr.Needs64b(ectx):
5423 if ectx.Ber(): pars['FN_VARIANT'] = '64'
5424 else: pars['FN_VARIANT'] = '_64b'
5425 return pars
5426  
5427 def eth_type_default_body(self, ectx, tname):
5428 if (ectx.Ber()):
5429 if (ectx.constraints_check and self.HasValueConstraint()):
5430 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5431 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5432 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(HF_INDEX)s', '%(VAL_PTR)s',),))
5433 else:
5434 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5435 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s', '%(HF_INDEX)s'),
5436 ('%(VAL_PTR)s',),))
5437 elif (ectx.Per() and not self.HasValueConstraint()):
5438 body = ectx.eth_fn_call('dissect_%(ER)s_integer%(FN_VARIANT)s', ret='offset',
5439 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s', '%(VAL_PTR)s'),))
5440 elif (ectx.Per() and self.HasValueConstraint()):
5441 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_integer%(FN_VARIANT)s', ret='offset',
5442 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5443 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(VAL_PTR)s', '%(EXT)s'),))
5444 else:
5445 body = '#error Can not decode %s' % (tname)
5446 return body
5447  
5448 #--- BitStringType ------------------------------------------------------------
5449 class BitStringType (Type):
5450 def to_python (self, ctx):
5451 return "asn1.BITSTRING_class ([%s])" % (",".join (
5452 [x.to_python (ctx) for x in self.named_list]))
5453  
5454 def eth_tname(self):
5455 if self.named_list:
5456 return Type.eth_tname(self)
5457 elif not self.HasConstraint():
5458 return 'BIT_STRING'
5459 elif self.constr.IsSize():
5460 return 'BIT_STRING' + '_' + self.constr.eth_constrname()
5461 else:
5462 return '#' + self.type + '_' + str(id(self))
5463  
5464 def GetTTag(self, ectx):
5465 return ('BER_CLASS_UNI', 'BER_UNI_TAG_BITSTRING')
5466  
5467 def eth_ftype(self, ectx):
5468 return ('FT_BYTES', 'BASE_NONE')
5469  
5470 def eth_need_tree(self):
5471 return self.named_list
5472  
5473 def eth_need_pdu(self, ectx):
5474 pdu = None
5475 if self.HasContentsConstraint():
5476 t = self.constr.GetContents(ectx)
5477 if t and (ectx.default_containing_variant in ('_pdu', '_pdu_new')):
5478 pdu = { 'type' : t,
5479 'new' : ectx.default_containing_variant == '_pdu_new' }
5480 return pdu
5481  
5482 def eth_named_bits(self):
5483 bits = []
5484 if (self.named_list):
5485 for e in (self.named_list):
5486 bits.append((int(e.val), e.ident))
5487 return bits
5488  
5489 def eth_type_default_pars(self, ectx, tname):
5490 pars = Type.eth_type_default_pars(self, ectx, tname)
5491 pars['LEN_PTR'] = 'NULL'
5492 (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
5493 if 'ETT_INDEX' not in pars:
5494 pars['ETT_INDEX'] = '-1'
5495 pars['TABLE'] = 'NULL'
5496 if self.eth_named_bits():
5497 pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
5498 if self.HasContentsConstraint():
5499 pars['FN_VARIANT'] = ectx.default_containing_variant
5500 t = self.constr.GetContents(ectx)
5501 if t:
5502 if pars['FN_VARIANT'] in ('_pdu', '_pdu_new'):
5503 t = ectx.field[t]['ethname']
5504 pars['TYPE_REF_PROTO'] = ''
5505 pars['TYPE_REF_TNAME'] = t
5506 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_TNAME)s'
5507 else:
5508 t = ectx.type[t]['ethname']
5509 pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
5510 pars['TYPE_REF_TNAME'] = t
5511 pars['TYPE_REF_FN'] = 'dissect_%(TYPE_REF_PROTO)s_%(TYPE_REF_TNAME)s'
5512 else:
5513 pars['TYPE_REF_FN'] = 'NULL'
5514 return pars
5515  
5516 def eth_type_default_table(self, ectx, tname):
5517 #print "eth_type_default_table(tname='%s')" % (tname)
5518 table = ''
5519 bits = self.eth_named_bits()
5520 if (bits and ectx.Ber()):
5521 table = ectx.eth_bits(tname, bits)
5522 return table
5523  
5524 def eth_type_default_body(self, ectx, tname):
5525 if (ectx.Ber()):
5526 if (ectx.constraints_check and self.HasSizeConstraint()):
5527 body = ectx.eth_fn_call('dissect_%(ER)s_constrained_bitstring', ret='offset',
5528 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5529 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5530 ('%(VAL_PTR)s',),))
5531 else:
5532 body = ectx.eth_fn_call('dissect_%(ER)s_bitstring', ret='offset',
5533 par=(('%(IMPLICIT_TAG)s', '%(ACTX)s', '%(TREE)s', '%(TVB)s', '%(OFFSET)s'),
5534 ('%(TABLE)s', '%(HF_INDEX)s', '%(ETT_INDEX)s',),
5535 ('%(VAL_PTR)s',),))
5536 elif (ectx.Per()):
5537 if self.HasContentsConstraint():
5538 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string_containing%(FN_VARIANT)s', ret='offset',
5539 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5540 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(TYPE_REF_FN)s'),))
5541 else:
5542 body = ectx.eth_fn_call('dissect_%(ER)s_bit_string', ret='offset',
5543 par=(('%(TVB)s', '%(OFFSET)s', '%(ACTX)s', '%(TREE)s', '%(HF_INDEX)s'),
5544 ('%(MIN_VAL)s', '%(MAX_VAL)s', '%(EXT)s', '%(VAL_PTR)s', '%(LEN_PTR)s'),))
5545 else:
5546 body = '#error Can not decode %s' % (tname)
5547 return body
5548  
5549 #--- BStringValue ------------------------------------------------------------
5550 bstring_tab = {
5551 '0000' : '0',
5552 '0001' : '1',
5553 '0010' : '2',
5554 '0011' : '3',
5555 '0100' : '4',
5556 '0101' : '5',
5557 '0110' : '6',
5558 '0111' : '7',
5559 '1000' : '8',
5560 '1001' : '9',
5561 '1010' : 'A',
5562 '1011' : 'B',
5563 '1100' : 'C',
5564 '1101' : 'D',
5565 '1110' : 'E',
5566 '1111' : 'F',
5567 }
5568 class BStringValue (Value):
5569 def to_str(self, ectx):
5570 v = self.val[1:-2]
5571 if len(v) % 8:
5572 v += '0' * (8 - len(v) % 8)
5573 vv = '0x'
5574 for i in (list(range(0, len(v), 4))):
5575 vv += bstring_tab[v[i:i+4]]
5576 return vv
5577  
5578 #--- HStringValue ------------------------------------------------------------
5579 class HStringValue (Value):
5580 def to_str(self, ectx):
5581 vv = '0x'
5582 vv += self.val[1:-2]
5583 return vv
5584 def __int__(self):
5585 return int(self.val[1:-2], 16)
5586  
5587 #--- FieldSpec ----------------------------------------------------------------
5588 class FieldSpec (Node):
5589 def __init__(self,*args, **kw) :
5590 self.name = None
5591 Node.__init__ (self,*args, **kw)
5592  
5593 def SetName(self, name):
5594 self.name = name
5595  
5596 def get_repr(self):
5597 return ['#UNSUPPORTED_' + self.type]
5598  
5599 def fld_repr(self):
5600 repr = [self.name]
5601 repr.extend(self.get_repr())
5602 return repr
5603  
5604 class TypeFieldSpec (FieldSpec):
5605 def get_repr(self):
5606 return []
5607  
5608 class FixedTypeValueFieldSpec (FieldSpec):
5609 def get_repr(self):
5610 if isinstance(self.typ, Type_Ref):
5611 repr = ['TypeReference', self.typ.val]
5612 else:
5613 repr = [self.typ.type]
5614 return repr
5615  
5616 class VariableTypeValueFieldSpec (FieldSpec):
5617 def get_repr(self):
5618 return ['_' + self.type]
5619  
5620 class FixedTypeValueSetFieldSpec (FieldSpec):
5621 def get_repr(self):
5622 return ['_' + self.type]
5623  
5624 class ObjectFieldSpec (FieldSpec):
5625 def get_repr(self):
5626 return ['ClassReference', self.cls.val]
5627  
5628 class ObjectSetFieldSpec (FieldSpec):
5629 def get_repr(self):
5630 return ['ClassReference', self.cls.val]
5631  
5632 #==============================================================================
5633  
5634 def p_module_list_1 (t):
5635 'module_list : module_list ModuleDefinition'
5636 t[0] = t[1] + [t[2]]
5637  
5638 def p_module_list_2 (t):
5639 'module_list : ModuleDefinition'
5640 t[0] = [t[1]]
5641  
5642  
5643 #--- ITU-T Recommendation X.680 -----------------------------------------------
5644  
5645  
5646 # 11 ASN.1 lexical items --------------------------------------------------------
5647  
5648 # 11.2 Type references
5649 def p_type_ref (t):
5650 'type_ref : UCASE_IDENT'
5651 t[0] = Type_Ref(val=t[1])
5652  
5653 # 11.3 Identifiers
5654 def p_identifier (t):
5655 'identifier : LCASE_IDENT'
5656 t[0] = t[1]
5657  
5658 # 11.4 Value references
5659 # cause reduce/reduce conflict
5660 #def p_valuereference (t):
5661 # 'valuereference : LCASE_IDENT'
5662 # t[0] = Value_Ref(val=t[1])
5663  
5664 # 11.5 Module references
5665 def p_modulereference (t):
5666 'modulereference : UCASE_IDENT'
5667 t[0] = t[1]
5668  
5669  
5670 # 12 Module definition --------------------------------------------------------
5671  
5672 # 12.1
5673 def p_ModuleDefinition (t):
5674 'ModuleDefinition : ModuleIdentifier DEFINITIONS TagDefault ASSIGNMENT ModuleBegin BEGIN ModuleBody END'
5675 t[0] = Module (ident = t[1], tag_def = t[3], body = t[7])
5676  
5677 def p_ModuleBegin (t):
5678 'ModuleBegin : '
5679 if t[-4].val == 'Remote-Operations-Information-Objects':
5680 x880_module_begin()
5681  
5682 def p_TagDefault_1 (t):
5683 '''TagDefault : EXPLICIT TAGS
5684 | IMPLICIT TAGS
5685 | AUTOMATIC TAGS '''
5686 t[0] = Default_Tags (dfl_tag = t[1])
5687  
5688 def p_TagDefault_2 (t):
5689 'TagDefault : '
5690 # 12.2 The "TagDefault" is taken as EXPLICIT TAGS if it is "empty".
5691 t[0] = Default_Tags (dfl_tag = 'EXPLICIT')
5692  
5693 def p_ModuleIdentifier_1 (t):
5694 'ModuleIdentifier : modulereference DefinitiveIdentifier' # name, oid
5695 t [0] = Node('module_ident', val = t[1], ident = t[2])
5696  
5697 def p_ModuleIdentifier_2 (t):
5698 'ModuleIdentifier : modulereference' # name, oid
5699 t [0] = Node('module_ident', val = t[1], ident = None)
5700  
5701 def p_DefinitiveIdentifier (t):
5702 'DefinitiveIdentifier : ObjectIdentifierValue'
5703 t[0] = t[1]
5704  
5705 #def p_module_ref (t):
5706 # 'module_ref : UCASE_IDENT'
5707 # t[0] = t[1]
5708  
5709 def p_ModuleBody_1 (t):
5710 'ModuleBody : Exports Imports AssignmentList'
5711 t[0] = Module_Body (exports = t[1], imports = t[2], assign_list = t[3])
5712  
5713 def p_ModuleBody_2 (t):
5714 'ModuleBody : '
5715 t[0] = Node ('module_body', exports = [], imports = [], assign_list = [])
5716  
5717 def p_Exports_1 (t):
5718 'Exports : EXPORTS syms_exported SEMICOLON'
5719 t[0] = t[2]
5720  
5721 def p_Exports_2 (t):
5722 'Exports : EXPORTS ALL SEMICOLON'
5723 t[0] = [ 'ALL' ]
5724  
5725 def p_Exports_3 (t):
5726 'Exports : '
5727 t[0] = [ 'ALL' ]
5728  
5729 def p_syms_exported_1 (t):
5730 'syms_exported : exp_sym_list'
5731 t[0] = t[1]
5732  
5733 def p_syms_exported_2 (t):
5734 'syms_exported : '
5735 t[0] = []
5736  
5737 def p_exp_sym_list_1 (t):
5738 'exp_sym_list : Symbol'
5739 t[0] = [t[1]]
5740  
5741 def p_exp_sym_list_2 (t):
5742 'exp_sym_list : exp_sym_list COMMA Symbol'
5743 t[0] = t[1] + [t[3]]
5744  
5745  
5746 def p_Imports_1 (t):
5747 'Imports : importsbegin IMPORTS SymbolsImported SEMICOLON'
5748 t[0] = t[3]
5749 global lcase_ident_assigned
5750 lcase_ident_assigned = {}
5751  
5752 def p_importsbegin (t):
5753 'importsbegin : '
5754 global lcase_ident_assigned
5755 global g_conform
5756 lcase_ident_assigned = {}
5757 lcase_ident_assigned.update(g_conform.use_item('ASSIGNED_ID', 'OBJECT_IDENTIFIER'))
5758  
5759 def p_Imports_2 (t):
5760 'Imports : '
5761 t[0] = []
5762  
5763 def p_SymbolsImported_1(t):
5764 'SymbolsImported : '
5765 t[0] = []
5766  
5767 def p_SymbolsImported_2 (t):
5768 'SymbolsImported : SymbolsFromModuleList'
5769 t[0] = t[1]
5770  
5771 def p_SymbolsFromModuleList_1 (t):
5772 'SymbolsFromModuleList : SymbolsFromModuleList SymbolsFromModule'
5773 t[0] = t[1] + [t[2]]
5774  
5775 def p_SymbolsFromModuleList_2 (t):
5776 'SymbolsFromModuleList : SymbolsFromModule'
5777 t[0] = [t[1]]
5778  
5779 def p_SymbolsFromModule (t):
5780 'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
5781 t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
5782 for s in (t[0].symbol_list):
5783 if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
5784 import_symbols_from_module(t[0].module, t[0].symbol_list)
5785  
5786 def import_symbols_from_module(module, symbol_list):
5787 if module.val == 'Remote-Operations-Information-Objects':
5788 for i in range(len(symbol_list)):
5789 s = symbol_list[i]
5790 if isinstance(s, Type_Ref) or isinstance(s, Class_Ref):
5791 x880_import(s.val)
5792 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5793 symbol_list[i] = Class_Ref (val = s.val)
5794 return
5795 for i in range(len(symbol_list)):
5796 s = symbol_list[i]
5797 if isinstance(s, Type_Ref) and is_class_ident("$%s$%s" % (module.val, s.val)):
5798 import_class_from_module(module.val, s.val)
5799 if isinstance(s, Type_Ref) and is_class_ident(s.val):
5800 symbol_list[i] = Class_Ref (val = s.val)
5801  
5802 def p_GlobalModuleReference (t):
5803 'GlobalModuleReference : modulereference AssignedIdentifier'
5804 t [0] = Node('module_ident', val = t[1], ident = t[2])
5805  
5806 def p_AssignedIdentifier_1 (t):
5807 'AssignedIdentifier : ObjectIdentifierValue'
5808 t[0] = t[1]
5809  
5810 def p_AssignedIdentifier_2 (t):
5811 'AssignedIdentifier : LCASE_IDENT_ASSIGNED'
5812 t[0] = t[1]
5813  
5814 def p_AssignedIdentifier_3 (t):
5815 'AssignedIdentifier : '
5816 pass
5817  
5818 def p_SymbolList_1 (t):
5819 'SymbolList : Symbol'
5820 t[0] = [t[1]]
5821  
5822 def p_SymbolList_2 (t):
5823 'SymbolList : SymbolList COMMA Symbol'
5824 t[0] = t[1] + [t[3]]
5825  
5826 def p_Symbol (t):
5827 '''Symbol : Reference
5828 | ParameterizedReference'''
5829 t[0] = t[1]
5830  
5831 def p_Reference_1 (t):
5832 '''Reference : type_ref
5833 | objectclassreference '''
5834 t[0] = t[1]
5835  
5836 def p_Reference_2 (t):
5837 '''Reference : LCASE_IDENT_ASSIGNED
5838 | identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5839 t[0] = Value_Ref(val=t[1])
5840  
5841 def p_AssignmentList_1 (t):
5842 'AssignmentList : AssignmentList Assignment'
5843 t[0] = t[1] + [t[2]]
5844  
5845 def p_AssignmentList_2 (t):
5846 'AssignmentList : Assignment SEMICOLON'
5847 t[0] = [t[1]]
5848  
5849 def p_AssignmentList_3 (t):
5850 'AssignmentList : Assignment'
5851 t[0] = [t[1]]
5852  
5853 def p_Assignment (t):
5854 '''Assignment : TypeAssignment
5855 | ValueAssignment
5856 | ValueSetTypeAssignment
5857 | ObjectClassAssignment
5858 | ObjectAssignment
5859 | ObjectSetAssignment
5860 | ParameterizedAssignment
5861 | pyquote '''
5862 t[0] = t[1]
5863  
5864  
5865 # 13 Referencing type and value definitions -----------------------------------
5866  
5867 # 13.1
5868 def p_DefinedType (t):
5869 '''DefinedType : ExternalTypeReference
5870 | type_ref
5871 | ParameterizedType'''
5872 t[0] = t[1]
5873  
5874 def p_DefinedValue_1(t):
5875 '''DefinedValue : ExternalValueReference'''
5876 t[0] = t[1]
5877  
5878 def p_DefinedValue_2(t):
5879 '''DefinedValue : identifier ''' # instead of valuereference wich causes reduce/reduce conflict
5880 t[0] = Value_Ref(val=t[1])
5881  
5882 # 13.6
5883 def p_ExternalTypeReference (t):
5884 'ExternalTypeReference : modulereference DOT type_ref'
5885 t[0] = Node ('ExternalTypeReference', module = t[1], typ = t[3])
5886  
5887 def p_ExternalValueReference (t):
5888 'ExternalValueReference : modulereference DOT identifier'
5889 t[0] = Node ('ExternalValueReference', module = t[1], ident = t[3])
5890  
5891  
5892 # 15 Assigning types and values -----------------------------------------------
5893  
5894 # 15.1
5895 def p_TypeAssignment (t):
5896 'TypeAssignment : UCASE_IDENT ASSIGNMENT Type'
5897 t[0] = t[3]
5898 t[0].SetName(t[1])
5899  
5900 # 15.2
5901 def p_ValueAssignment (t):
5902 'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
5903 t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
5904  
5905 # only "simple" types are supported to simplify grammer
5906 def p_ValueType (t):
5907 '''ValueType : type_ref
5908 | BooleanType
5909 | IntegerType
5910 | ObjectIdentifierType
5911 | OctetStringType
5912 | RealType '''
5913  
5914 t[0] = t[1]
5915  
5916 # 15.6
5917 def p_ValueSetTypeAssignment (t):
5918 'ValueSetTypeAssignment : UCASE_IDENT ValueType ASSIGNMENT ValueSet'
5919 t[0] = Node('ValueSetTypeAssignment', name=t[1], typ=t[2], val=t[4])
5920  
5921 # 15.7
5922 def p_ValueSet (t):
5923 'ValueSet : lbraceignore rbraceignore'
5924 t[0] = None
5925  
5926  
5927 # 16 Definition of types and values -------------------------------------------
5928  
5929 # 16.1
5930 def p_Type (t):
5931 '''Type : BuiltinType
5932 | ReferencedType
5933 | ConstrainedType'''
5934 t[0] = t[1]
5935  
5936 # 16.2
5937 def p_BuiltinType (t):
5938 '''BuiltinType : AnyType
5939 | BitStringType
5940 | BooleanType
5941 | CharacterStringType
5942 | ChoiceType
5943 | EmbeddedPDVType
5944 | EnumeratedType
5945 | ExternalType
5946 | InstanceOfType
5947 | IntegerType
5948 | NullType
5949 | ObjectClassFieldType
5950 | ObjectIdentifierType
5951 | OctetStringType
5952 | RealType
5953 | RelativeOIDType
5954 | SequenceType
5955 | SequenceOfType
5956 | SetType
5957 | SetOfType
5958 | TaggedType'''
5959 t[0] = t[1]
5960  
5961 # 16.3
5962 def p_ReferencedType (t):
5963 '''ReferencedType : DefinedType
5964 | UsefulType
5965 | SelectionType'''
5966 t[0] = t[1]
5967  
5968 # 16.5
5969 def p_NamedType (t):
5970 'NamedType : identifier Type'
5971 t[0] = t[2]
5972 t[0].SetName (t[1])
5973  
5974 # 16.7
5975 def p_Value (t):
5976 '''Value : BuiltinValue
5977 | ReferencedValue
5978 | ObjectClassFieldValue'''
5979 t[0] = t[1]
5980  
5981 # 16.9
5982 def p_BuiltinValue (t):
5983 '''BuiltinValue : BooleanValue
5984 | ChoiceValue
5985 | IntegerValue
5986 | ObjectIdentifierValue
5987 | RealValue
5988 | SequenceValue
5989 | hex_string
5990 | binary_string
5991 | char_string''' # XXX we don't support {data} here
5992 t[0] = t[1]
5993  
5994 # 16.11
5995 def p_ReferencedValue (t):
5996 '''ReferencedValue : DefinedValue
5997 | ValueFromObject'''
5998 t[0] = t[1]
5999  
6000 # 16.13
6001 #def p_NamedValue (t):
6002 # 'NamedValue : identifier Value'
6003 # t[0] = Node ('NamedValue', ident = t[1], value = t[2])
6004  
6005  
6006 # 17 Notation for the boolean type --------------------------------------------
6007  
6008 # 17.1
6009 def p_BooleanType (t):
6010 'BooleanType : BOOLEAN'
6011 t[0] = BooleanType ()
6012  
6013 # 17.2
6014 def p_BooleanValue (t):
6015 '''BooleanValue : TRUE
6016 | FALSE'''
6017 t[0] = t[1]
6018  
6019  
6020 # 18 Notation for the integer type --------------------------------------------
6021  
6022 # 18.1
6023 def p_IntegerType_1 (t):
6024 'IntegerType : INTEGER'
6025 t[0] = IntegerType (named_list = None)
6026  
6027 def p_IntegerType_2 (t):
6028 'IntegerType : INTEGER LBRACE NamedNumberList RBRACE'
6029 t[0] = IntegerType(named_list = t[3])
6030  
6031 def p_NamedNumberList_1 (t):
6032 'NamedNumberList : NamedNumber'
6033 t[0] = [t[1]]
6034  
6035 def p_NamedNumberList_2 (t):
6036 'NamedNumberList : NamedNumberList COMMA NamedNumber'
6037 t[0] = t[1] + [t[3]]
6038  
6039 def p_NamedNumber (t):
6040 '''NamedNumber : identifier LPAREN SignedNumber RPAREN
6041 | identifier LPAREN DefinedValue RPAREN'''
6042 t[0] = NamedNumber(ident = t[1], val = t[3])
6043  
6044 def p_SignedNumber_1 (t):
6045 'SignedNumber : NUMBER'
6046 t[0] = t [1]
6047  
6048 def p_SignedNumber_2 (t):
6049 'SignedNumber : MINUS NUMBER'
6050 t[0] = '-' + t[2]
6051  
6052 # 18.9
6053 def p_IntegerValue (t):
6054 'IntegerValue : SignedNumber'
6055 t[0] = t [1]
6056  
6057 # 19 Notation for the enumerated type -----------------------------------------
6058  
6059 # 19.1
6060 def p_EnumeratedType (t):
6061 'EnumeratedType : ENUMERATED LBRACE Enumerations RBRACE'
6062 t[0] = EnumeratedType (val = t[3]['val'], ext = t[3]['ext'])
6063  
6064 def p_Enumerations_1 (t):
6065 'Enumerations : Enumeration'
6066 t[0] = { 'val' : t[1], 'ext' : None }
6067  
6068 def p_Enumerations_2 (t):
6069 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec'
6070 t[0] = { 'val' : t[1], 'ext' : [] }
6071  
6072 def p_Enumerations_3 (t):
6073 'Enumerations : Enumeration COMMA ELLIPSIS ExceptionSpec COMMA Enumeration'
6074 t[0] = { 'val' : t[1], 'ext' : t[6] }
6075  
6076 def p_Enumeration_1 (t):
6077 'Enumeration : EnumerationItem'
6078 t[0] = [t[1]]
6079  
6080 def p_Enumeration_2 (t):
6081 'Enumeration : Enumeration COMMA EnumerationItem'
6082 t[0] = t[1] + [t[3]]
6083  
6084 def p_EnumerationItem (t):
6085 '''EnumerationItem : Identifier
6086 | NamedNumber'''
6087 t[0] = t[1]
6088  
6089 def p_Identifier (t):
6090 'Identifier : identifier'
6091 t[0] = Node ('Identifier', ident = t[1])
6092  
6093  
6094 # 20 Notation for the real type -----------------------------------------------
6095  
6096 # 20.1
6097 def p_RealType (t):
6098 'RealType : REAL'
6099 t[0] = RealType ()
6100  
6101 # 20.6
6102 def p_RealValue (t):
6103 '''RealValue : REAL_NUMBER
6104 | SpecialRealValue'''
6105 t[0] = t [1]
6106  
6107 def p_SpecialRealValue (t):
6108 '''SpecialRealValue : PLUS_INFINITY
6109 | MINUS_INFINITY'''
6110 t[0] = t[1]
6111  
6112  
6113 # 21 Notation for the bitstring type ------------------------------------------
6114  
6115 # 21.1
6116 def p_BitStringType_1 (t):
6117 'BitStringType : BIT STRING'
6118 t[0] = BitStringType (named_list = None)
6119  
6120 def p_BitStringType_2 (t):
6121 'BitStringType : BIT STRING LBRACE NamedBitList RBRACE'
6122 t[0] = BitStringType (named_list = t[4])
6123  
6124 def p_NamedBitList_1 (t):
6125 'NamedBitList : NamedBit'
6126 t[0] = [t[1]]
6127  
6128 def p_NamedBitList_2 (t):
6129 'NamedBitList : NamedBitList COMMA NamedBit'
6130 t[0] = t[1] + [t[3]]
6131  
6132 def p_NamedBit (t):
6133 '''NamedBit : identifier LPAREN NUMBER RPAREN
6134 | identifier LPAREN DefinedValue RPAREN'''
6135 t[0] = NamedNumber (ident = t[1], val = t[3])
6136  
6137  
6138 # 22 Notation for the octetstring type ----------------------------------------
6139  
6140 # 22.1
6141 def p_OctetStringType (t):
6142 'OctetStringType : OCTET STRING'
6143 t[0] = OctetStringType ()
6144  
6145  
6146 # 23 Notation for the null type -----------------------------------------------
6147  
6148 # 23.1
6149 def p_NullType (t):
6150 'NullType : NULL'
6151 t[0] = NullType ()
6152  
6153 # 23.3
6154 def p_NullValue (t):
6155 'NullValue : NULL'
6156 t[0] = NullValue ()
6157  
6158  
6159 # 24 Notation for sequence types ----------------------------------------------
6160  
6161 # 24.1
6162 def p_SequenceType_1 (t):
6163 'SequenceType : SEQUENCE LBRACE RBRACE'
6164 t[0] = SequenceType (elt_list = [])
6165  
6166 def p_SequenceType_2 (t):
6167 'SequenceType : SEQUENCE LBRACE ComponentTypeLists RBRACE'
6168 t[0] = SequenceType (elt_list = t[3]['elt_list'])
6169 if 'ext_list' in t[3]:
6170 t[0].ext_list = t[3]['ext_list']
6171 if 'elt_list2' in t[3]:
6172 t[0].elt_list2 = t[3]['elt_list2']
6173  
6174 def p_ExtensionAndException_1 (t):
6175 'ExtensionAndException : ELLIPSIS'
6176 t[0] = []
6177  
6178 def p_OptionalExtensionMarker_1 (t):
6179 'OptionalExtensionMarker : COMMA ELLIPSIS'
6180 t[0] = True
6181  
6182 def p_OptionalExtensionMarker_2 (t):
6183 'OptionalExtensionMarker : '
6184 t[0] = False
6185  
6186 def p_ComponentTypeLists_1 (t):
6187 'ComponentTypeLists : ComponentTypeList'
6188 t[0] = {'elt_list' : t[1]}
6189  
6190 def p_ComponentTypeLists_2 (t):
6191 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException OptionalExtensionMarker'
6192 t[0] = {'elt_list' : t[1], 'ext_list' : []}
6193  
6194 def p_ComponentTypeLists_3 (t):
6195 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6196 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6197  
6198 def p_ComponentTypeLists_4 (t):
6199 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionEndMarker COMMA ComponentTypeList'
6200 t[0] = {'elt_list' : t[1], 'ext_list' : [], 'elt_list2' : t[6]}
6201  
6202 def p_ComponentTypeLists_5 (t):
6203 'ComponentTypeLists : ComponentTypeList COMMA ExtensionAndException ExtensionAdditionList ExtensionEndMarker COMMA ComponentTypeList'
6204 t[0] = {'elt_list' : t[1], 'ext_list' : t[4], 'elt_list2' : t[7]}
6205  
6206 def p_ComponentTypeLists_6 (t):
6207 'ComponentTypeLists : ExtensionAndException OptionalExtensionMarker'
6208 t[0] = {'elt_list' : [], 'ext_list' : []}
6209  
6210 def p_ComponentTypeLists_7 (t):
6211 'ComponentTypeLists : ExtensionAndException ExtensionAdditionList OptionalExtensionMarker'
6212 t[0] = {'elt_list' : [], 'ext_list' : t[2]}
6213  
6214 def p_ExtensionEndMarker (t):
6215 'ExtensionEndMarker : COMMA ELLIPSIS'
6216 pass
6217  
6218 def p_ExtensionAdditionList_1 (t):
6219 'ExtensionAdditionList : COMMA ExtensionAddition'
6220 t[0] = [t[2]]
6221  
6222 def p_ExtensionAdditionList_2 (t):
6223 'ExtensionAdditionList : ExtensionAdditionList COMMA ExtensionAddition'
6224 t[0] = t[1] + [t[3]]
6225  
6226 def p_ExtensionAddition_1 (t):
6227 'ExtensionAddition : ExtensionAdditionGroup'
6228 t[0] = Node ('elt_type', val = t[1], optional = 0)
6229  
6230 def p_ExtensionAddition_2 (t):
6231 'ExtensionAddition : ComponentType'
6232 t[0] = t[1]
6233  
6234 def p_ExtensionAdditionGroup (t):
6235 'ExtensionAdditionGroup : LVERBRACK VersionNumber ComponentTypeList RVERBRACK'
6236 t[0] = ExtensionAdditionGroup (ver = t[2], elt_list = t[3])
6237  
6238 def p_VersionNumber_1 (t):
6239 'VersionNumber : '
6240  
6241 def p_VersionNumber_2 (t):
6242 'VersionNumber : NUMBER COLON'
6243 t[0] = t[1]
6244  
6245 def p_ComponentTypeList_1 (t):
6246 'ComponentTypeList : ComponentType'
6247 t[0] = [t[1]]
6248  
6249 def p_ComponentTypeList_2 (t):
6250 'ComponentTypeList : ComponentTypeList COMMA ComponentType'
6251 t[0] = t[1] + [t[3]]
6252  
6253 def p_ComponentType_1 (t):
6254 'ComponentType : NamedType'
6255 t[0] = Node ('elt_type', val = t[1], optional = 0)
6256  
6257 def p_ComponentType_2 (t):
6258 'ComponentType : NamedType OPTIONAL'
6259 t[0] = Node ('elt_type', val = t[1], optional = 1)
6260  
6261 def p_ComponentType_3 (t):
6262 'ComponentType : NamedType DEFAULT DefaultValue'
6263 t[0] = Node ('elt_type', val = t[1], optional = 1, default = t[3])
6264  
6265 def p_ComponentType_4 (t):
6266 'ComponentType : COMPONENTS OF Type'
6267 t[0] = Node ('components_of', typ = t[3])
6268  
6269 def p_DefaultValue_1 (t):
6270 '''DefaultValue : ReferencedValue
6271 | BooleanValue
6272 | ChoiceValue
6273 | IntegerValue
6274 | RealValue
6275 | hex_string
6276 | binary_string
6277 | char_string
6278 | ObjectClassFieldValue'''
6279 t[0] = t[1]
6280  
6281 def p_DefaultValue_2 (t):
6282 'DefaultValue : lbraceignore rbraceignore'
6283 t[0] = ''
6284  
6285 # 24.17
6286 def p_SequenceValue_1 (t):
6287 'SequenceValue : LBRACE RBRACE'
6288 t[0] = []
6289  
6290  
6291 #def p_SequenceValue_2 (t):
6292 # 'SequenceValue : LBRACE ComponentValueList RBRACE'
6293 # t[0] = t[2]
6294  
6295 #def p_ComponentValueList_1 (t):
6296 # 'ComponentValueList : NamedValue'
6297 # t[0] = [t[1]]
6298  
6299 #def p_ComponentValueList_2 (t):
6300 # 'ComponentValueList : ComponentValueList COMMA NamedValue'
6301 # t[0] = t[1] + [t[3]]
6302  
6303  
6304 # 25 Notation for sequence-of types -------------------------------------------
6305  
6306 # 25.1
6307 def p_SequenceOfType (t):
6308 '''SequenceOfType : SEQUENCE OF Type
6309 | SEQUENCE OF NamedType'''
6310 t[0] = SequenceOfType (val = t[3], size_constr = None)
6311  
6312  
6313 # 26 Notation for set types ---------------------------------------------------
6314  
6315 # 26.1
6316 def p_SetType_1 (t):
6317 'SetType : SET LBRACE RBRACE'
6318 t[0] = SetType (elt_list = [])
6319  
6320 def p_SetType_2 (t):
6321 'SetType : SET LBRACE ComponentTypeLists RBRACE'
6322 t[0] = SetType (elt_list = t[3]['elt_list'])
6323 if 'ext_list' in t[3]:
6324 t[0].ext_list = t[3]['ext_list']
6325 if 'elt_list2' in t[3]:
6326 t[0].elt_list2 = t[3]['elt_list2']
6327  
6328  
6329 # 27 Notation for set-of types ------------------------------------------------
6330  
6331 # 27.1
6332 def p_SetOfType (t):
6333 '''SetOfType : SET OF Type
6334 | SET OF NamedType'''
6335 t[0] = SetOfType (val = t[3])
6336  
6337 # 28 Notation for choice types ------------------------------------------------
6338  
6339 # 28.1
6340 def p_ChoiceType (t):
6341 'ChoiceType : CHOICE LBRACE AlternativeTypeLists RBRACE'
6342 if 'ext_list' in t[3]:
6343 t[0] = ChoiceType (elt_list = t[3]['elt_list'], ext_list = t[3]['ext_list'])
6344 else:
6345 t[0] = ChoiceType (elt_list = t[3]['elt_list'])
6346  
6347 def p_AlternativeTypeLists_1 (t):
6348 'AlternativeTypeLists : AlternativeTypeList'
6349 t[0] = {'elt_list' : t[1]}
6350  
6351 def p_AlternativeTypeLists_2 (t):
6352 'AlternativeTypeLists : AlternativeTypeList COMMA ExtensionAndException ExtensionAdditionAlternatives OptionalExtensionMarker'
6353 t[0] = {'elt_list' : t[1], 'ext_list' : t[4]}
6354  
6355 def p_ExtensionAdditionAlternatives_1 (t):
6356 'ExtensionAdditionAlternatives : ExtensionAdditionAlternativesList'
6357 t[0] = t[1]
6358  
6359 def p_ExtensionAdditionAlternatives_2 (t):
6360 'ExtensionAdditionAlternatives : '
6361 t[0] = []
6362  
6363 def p_ExtensionAdditionAlternativesList_1 (t):
6364 'ExtensionAdditionAlternativesList : COMMA ExtensionAdditionAlternative'
6365 t[0] = t[2]
6366  
6367 def p_ExtensionAdditionAlternativesList_2 (t):
6368 'ExtensionAdditionAlternativesList : ExtensionAdditionAlternativesList COMMA ExtensionAdditionAlternative'
6369 t[0] = t[1] + t[3]
6370  
6371 def p_ExtensionAdditionAlternative_1 (t):
6372 'ExtensionAdditionAlternative : NamedType'
6373 t[0] = [t[1]]
6374  
6375 def p_ExtensionAdditionAlternative_2 (t):
6376 'ExtensionAdditionAlternative : ExtensionAdditionAlternativesGroup'
6377 t[0] = t[1]
6378  
6379 def p_ExtensionAdditionAlternativesGroup (t):
6380 'ExtensionAdditionAlternativesGroup : LVERBRACK VersionNumber AlternativeTypeList RVERBRACK'
6381 t[0] = t[3]
6382  
6383 def p_AlternativeTypeList_1 (t):
6384 'AlternativeTypeList : NamedType'
6385 t[0] = [t[1]]
6386  
6387 def p_AlternativeTypeList_2 (t):
6388 'AlternativeTypeList : AlternativeTypeList COMMA NamedType'
6389 t[0] = t[1] + [t[3]]
6390  
6391 # 28.10
6392 def p_ChoiceValue_1 (t):
6393 '''ChoiceValue : identifier COLON Value
6394 | identifier COLON NullValue '''
6395 val = t[3]
6396 if not isinstance(val, Value):
6397 val = Value(val=val)
6398 t[0] = ChoiceValue (choice = t[1], val = val)
6399  
6400 # 29 Notation for selection types
6401  
6402 # 29.1
6403 def p_SelectionType (t): #
6404 'SelectionType : identifier LT Type'
6405 t[0] = SelectionType (typ = t[3], sel = t[1])
6406  
6407 # 30 Notation for tagged types ------------------------------------------------
6408  
6409 # 30.1
6410 def p_TaggedType_1 (t):
6411 'TaggedType : Tag Type'
6412 t[1].mode = 'default'
6413 t[0] = t[2]
6414 t[0].AddTag(t[1])
6415  
6416 def p_TaggedType_2 (t):
6417 '''TaggedType : Tag IMPLICIT Type
6418 | Tag EXPLICIT Type'''
6419 t[1].mode = t[2]
6420 t[0] = t[3]
6421 t[0].AddTag(t[1])
6422  
6423 def p_Tag (t):
6424 'Tag : LBRACK Class ClassNumber RBRACK'
6425 t[0] = Tag(cls = t[2], num = t[3])
6426  
6427 def p_ClassNumber_1 (t):
6428 'ClassNumber : number'
6429 t[0] = t[1]
6430  
6431 def p_ClassNumber_2 (t):
6432 'ClassNumber : DefinedValue'
6433 t[0] = t[1]
6434  
6435 def p_Class_1 (t):
6436 '''Class : UNIVERSAL
6437 | APPLICATION
6438 | PRIVATE'''
6439 t[0] = t[1]
6440  
6441 def p_Class_2 (t):
6442 'Class :'
6443 t[0] = 'CONTEXT'
6444  
6445  
6446 # 31 Notation for the object identifier type ----------------------------------
6447  
6448 # 31.1
6449 def p_ObjectIdentifierType (t):
6450 'ObjectIdentifierType : OBJECT IDENTIFIER'
6451 t[0] = ObjectIdentifierType()
6452  
6453 # 31.3
6454 def p_ObjectIdentifierValue (t):
6455 'ObjectIdentifierValue : LBRACE oid_comp_list RBRACE'
6456 t[0] = ObjectIdentifierValue (comp_list=t[2])
6457  
6458 def p_oid_comp_list_1 (t):
6459 'oid_comp_list : oid_comp_list ObjIdComponents'
6460 t[0] = t[1] + [t[2]]
6461  
6462 def p_oid_comp_list_2 (t):
6463 'oid_comp_list : ObjIdComponents'
6464 t[0] = [t[1]]
6465  
6466 def p_ObjIdComponents (t):
6467 '''ObjIdComponents : NameForm
6468 | NumberForm
6469 | NameAndNumberForm'''
6470 t[0] = t[1]
6471  
6472 def p_NameForm (t):
6473 '''NameForm : LCASE_IDENT
6474 | LCASE_IDENT_ASSIGNED'''
6475 t [0] = t[1]
6476  
6477 def p_NumberForm (t):
6478 '''NumberForm : NUMBER'''
6479 # | DefinedValue'''
6480 t [0] = t[1]
6481  
6482 def p_NameAndNumberForm (t):
6483 '''NameAndNumberForm : LCASE_IDENT_ASSIGNED LPAREN NumberForm RPAREN
6484 | LCASE_IDENT LPAREN NumberForm RPAREN'''
6485 t[0] = Node('name_and_number', ident = t[1], number = t[3])
6486  
6487 # 32 Notation for the relative object identifier type -------------------------
6488  
6489 # 32.1
6490 def p_RelativeOIDType (t):
6491 'RelativeOIDType : RELATIVE_OID'
6492 t[0] = RelativeOIDType()
6493  
6494 # 33 Notation for the embedded-pdv type ---------------------------------------
6495  
6496 # 33.1
6497 def p_EmbeddedPDVType (t):
6498 'EmbeddedPDVType : EMBEDDED PDV'
6499 t[0] = EmbeddedPDVType()
6500  
6501 # 34 Notation for the external type -------------------------------------------
6502  
6503 # 34.1
6504 def p_ExternalType (t):
6505 'ExternalType : EXTERNAL'
6506 t[0] = ExternalType()
6507  
6508 # 36 Notation for character string types --------------------------------------
6509  
6510 # 36.1
6511 def p_CharacterStringType (t):
6512 '''CharacterStringType : RestrictedCharacterStringType
6513 | UnrestrictedCharacterStringType'''
6514 t[0] = t[1]
6515  
6516  
6517 # 37 Definition of restricted character string types --------------------------
6518  
6519 def p_RestrictedCharacterStringType_1 (t):
6520 'RestrictedCharacterStringType : BMPString'
6521 t[0] = BMPStringType ()
6522 def p_RestrictedCharacterStringType_2 (t):
6523 'RestrictedCharacterStringType : GeneralString'
6524 t[0] = GeneralStringType ()
6525 def p_RestrictedCharacterStringType_3 (t):
6526 'RestrictedCharacterStringType : GraphicString'
6527 t[0] = GraphicStringType ()
6528 def p_RestrictedCharacterStringType_4 (t):
6529 'RestrictedCharacterStringType : IA5String'
6530 t[0] = IA5StringType ()
6531 def p_RestrictedCharacterStringType_5 (t):
6532 'RestrictedCharacterStringType : ISO646String'
6533 t[0] = ISO646StringType ()
6534 def p_RestrictedCharacterStringType_6 (t):
6535 'RestrictedCharacterStringType : NumericString'
6536 t[0] = NumericStringType ()
6537 def p_RestrictedCharacterStringType_7 (t):
6538 'RestrictedCharacterStringType : PrintableString'
6539 t[0] = PrintableStringType ()
6540 def p_RestrictedCharacterStringType_8 (t):
6541 'RestrictedCharacterStringType : TeletexString'
6542 t[0] = TeletexStringType ()
6543 def p_RestrictedCharacterStringType_9 (t):
6544 'RestrictedCharacterStringType : T61String'
6545 t[0] = T61StringType ()
6546 def p_RestrictedCharacterStringType_10 (t):
6547 'RestrictedCharacterStringType : UniversalString'
6548 t[0] = UniversalStringType ()
6549 def p_RestrictedCharacterStringType_11 (t):
6550 'RestrictedCharacterStringType : UTF8String'
6551 t[0] = UTF8StringType ()
6552 def p_RestrictedCharacterStringType_12 (t):
6553 'RestrictedCharacterStringType : VideotexString'
6554 t[0] = VideotexStringType ()
6555 def p_RestrictedCharacterStringType_13 (t):
6556 'RestrictedCharacterStringType : VisibleString'
6557 t[0] = VisibleStringType ()
6558  
6559  
6560 # 40 Definition of unrestricted character string types ------------------------
6561  
6562 # 40.1
6563 def p_UnrestrictedCharacterStringType (t):
6564 'UnrestrictedCharacterStringType : CHARACTER STRING'
6565 t[0] = UnrestrictedCharacterStringType ()
6566  
6567  
6568 # 41 Notation for types defined in clauses 42 to 44 ---------------------------
6569  
6570 # 42 Generalized time ---------------------------------------------------------
6571  
6572 def p_UsefulType_1 (t):
6573 'UsefulType : GeneralizedTime'
6574 t[0] = GeneralizedTime()
6575  
6576 # 43 Universal time -----------------------------------------------------------
6577  
6578 def p_UsefulType_2 (t):
6579 'UsefulType : UTCTime'
6580 t[0] = UTCTime()
6581  
6582 # 44 The object descriptor type -----------------------------------------------
6583  
6584 def p_UsefulType_3 (t):
6585 'UsefulType : ObjectDescriptor'
6586 t[0] = ObjectDescriptor()
6587  
6588  
6589 # 45 Constrained types --------------------------------------------------------
6590  
6591 # 45.1
6592 def p_ConstrainedType_1 (t):
6593 'ConstrainedType : Type Constraint'
6594 t[0] = t[1]
6595 t[0].AddConstraint(t[2])
6596  
6597 def p_ConstrainedType_2 (t):
6598 'ConstrainedType : TypeWithConstraint'
6599 t[0] = t[1]
6600  
6601 # 45.5
6602 def p_TypeWithConstraint_1 (t):
6603 '''TypeWithConstraint : SET Constraint OF Type
6604 | SET SizeConstraint OF Type'''
6605 t[0] = SetOfType (val = t[4], constr = t[2])
6606  
6607 def p_TypeWithConstraint_2 (t):
6608 '''TypeWithConstraint : SEQUENCE Constraint OF Type
6609 | SEQUENCE SizeConstraint OF Type'''
6610 t[0] = SequenceOfType (val = t[4], constr = t[2])
6611  
6612 def p_TypeWithConstraint_3 (t):
6613 '''TypeWithConstraint : SET Constraint OF NamedType
6614 | SET SizeConstraint OF NamedType'''
6615 t[0] = SetOfType (val = t[4], constr = t[2])
6616  
6617 def p_TypeWithConstraint_4 (t):
6618 '''TypeWithConstraint : SEQUENCE Constraint OF NamedType
6619 | SEQUENCE SizeConstraint OF NamedType'''
6620 t[0] = SequenceOfType (val = t[4], constr = t[2])
6621  
6622 # 45.6
6623 # 45.7
6624 def p_Constraint (t):
6625 'Constraint : LPAREN ConstraintSpec ExceptionSpec RPAREN'
6626 t[0] = t[2]
6627  
6628 def p_ConstraintSpec (t):
6629 '''ConstraintSpec : ElementSetSpecs
6630 | GeneralConstraint'''
6631 t[0] = t[1]
6632  
6633 # 46 Element set specification ------------------------------------------------
6634  
6635 # 46.1
6636 def p_ElementSetSpecs_1 (t):
6637 'ElementSetSpecs : RootElementSetSpec'
6638 t[0] = t[1]
6639  
6640 def p_ElementSetSpecs_2 (t):
6641 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS'
6642 t[0] = t[1]
6643 t[0].ext = True
6644  
6645 def p_ElementSetSpecs_3 (t):
6646 'ElementSetSpecs : RootElementSetSpec COMMA ELLIPSIS COMMA AdditionalElementSetSpec'
6647 t[0] = t[1]
6648 t[0].ext = True
6649  
6650 def p_RootElementSetSpec (t):
6651 'RootElementSetSpec : ElementSetSpec'
6652 t[0] = t[1]
6653  
6654 def p_AdditionalElementSetSpec (t):
6655 'AdditionalElementSetSpec : ElementSetSpec'
6656 t[0] = t[1]
6657  
6658 def p_ElementSetSpec (t):
6659 'ElementSetSpec : Unions'
6660 t[0] = t[1]
6661  
6662 def p_Unions_1 (t):
6663 'Unions : Intersections'
6664 t[0] = t[1]
6665  
6666 def p_Unions_2 (t):
6667 'Unions : UElems UnionMark Intersections'
6668 t[0] = Constraint(type = 'Union', subtype = [t[1], t[3]])
6669  
6670 def p_UElems (t):
6671 'UElems : Unions'
6672 t[0] = t[1]
6673  
6674 def p_Intersections_1 (t):
6675 'Intersections : IntersectionElements'
6676 t[0] = t[1]
6677  
6678 def p_Intersections_2 (t):
6679 'Intersections : IElems IntersectionMark IntersectionElements'
6680 t[0] = Constraint(type = 'Intersection', subtype = [t[1], t[3]])
6681  
6682 def p_IElems (t):
6683 'IElems : Intersections'
6684 t[0] = t[1]
6685  
6686 def p_IntersectionElements (t):
6687 'IntersectionElements : Elements'
6688 t[0] = t[1]
6689  
6690 def p_UnionMark (t):
6691 '''UnionMark : BAR
6692 | UNION'''
6693  
6694 def p_IntersectionMark (t):
6695 '''IntersectionMark : CIRCUMFLEX
6696 | INTERSECTION'''
6697  
6698 # 46.5
6699 def p_Elements_1 (t):
6700 'Elements : SubtypeElements'
6701 t[0] = t[1]
6702  
6703 def p_Elements_2 (t):
6704 'Elements : LPAREN ElementSetSpec RPAREN'
6705 t[0] = t[2]
6706  
6707 # 47 Subtype elements ---------------------------------------------------------
6708  
6709 # 47.1 General
6710 def p_SubtypeElements (t):
6711 '''SubtypeElements : SingleValue
6712 | ContainedSubtype
6713 | ValueRange
6714 | PermittedAlphabet
6715 | SizeConstraint
6716 | TypeConstraint
6717 | InnerTypeConstraints
6718 | PatternConstraint'''
6719 t[0] = t[1]
6720  
6721 # 47.2 Single value
6722 # 47.2.1
6723 def p_SingleValue (t):
6724 'SingleValue : Value'
6725 t[0] = Constraint(type = 'SingleValue', subtype = t[1])
6726  
6727 # 47.3 Contained subtype
6728 # 47.3.1
6729 def p_ContainedSubtype (t):
6730 'ContainedSubtype : Includes Type'
6731 t[0] = Constraint(type = 'ContainedSubtype', subtype = t[2])
6732  
6733 def p_Includes (t):
6734 '''Includes : INCLUDES
6735 | '''
6736  
6737 # 47.4 Value range
6738 # 47.4.1
6739 def p_ValueRange (t):
6740 'ValueRange : LowerEndpoint RANGE UpperEndpoint'
6741 t[0] = Constraint(type = 'ValueRange', subtype = [t[1], t[3]])
6742  
6743 # 47.4.3
6744 def p_LowerEndpoint_1 (t):
6745 'LowerEndpoint : LowerEndValue'
6746 t[0] = t[1]
6747  
6748 def p_LowerEndpoint_2 (t):
6749 'LowerEndpoint : LowerEndValue LT'
6750 t[0] = t[1] # but not inclusive range
6751  
6752 def p_UpperEndpoint_1 (t):
6753 'UpperEndpoint : UpperEndValue'
6754 t[0] = t[1]
6755  
6756 def p_UpperEndpoint_2 (t):
6757 'UpperEndpoint : LT UpperEndValue'
6758 t[0] = t[1] # but not inclusive range
6759  
6760 # 47.4.4
6761 def p_LowerEndValue (t):
6762 '''LowerEndValue : Value
6763 | MIN'''
6764 t[0] = t[1] # XXX
6765  
6766 def p_UpperEndValue (t):
6767 '''UpperEndValue : Value
6768 | MAX'''
6769 t[0] = t[1]
6770  
6771 # 47.5 Size constraint
6772 # 47.5.1
6773 def p_SizeConstraint (t):
6774 'SizeConstraint : SIZE Constraint'
6775 t[0] = Constraint (type = 'Size', subtype = t[2])
6776  
6777 # 47.6 Type constraint
6778 # 47.6.1
6779 def p_TypeConstraint (t):
6780 'TypeConstraint : Type'
6781 t[0] = Constraint (type = 'Type', subtype = t[1])
6782  
6783 # 47.7 Permitted alphabet
6784 # 47.7.1
6785 def p_PermittedAlphabet (t):
6786 'PermittedAlphabet : FROM Constraint'
6787 t[0] = Constraint (type = 'From', subtype = t[2])
6788  
6789 # 47.8 Inner subtyping
6790 # 47.8.1
6791 def p_InnerTypeConstraints (t):
6792 '''InnerTypeConstraints : WITH COMPONENT SingleTypeConstraint
6793 | WITH COMPONENTS MultipleTypeConstraints'''
6794 pass # ignore PER invisible constraint
6795  
6796 # 47.8.3
6797 def p_SingleTypeConstraint (t):
6798 'SingleTypeConstraint : Constraint'
6799 t[0] = t[1]
6800  
6801 # 47.8.4
6802 def p_MultipleTypeConstraints (t):
6803 '''MultipleTypeConstraints : FullSpecification
6804 | PartialSpecification'''
6805 t[0] = t[1]
6806  
6807 def p_FullSpecification (t):
6808 'FullSpecification : LBRACE TypeConstraints RBRACE'
6809 t[0] = t[2]
6810  
6811 def p_PartialSpecification (t):
6812 'PartialSpecification : LBRACE ELLIPSIS COMMA TypeConstraints RBRACE'
6813 t[0] = t[4]
6814  
6815 def p_TypeConstraints_1 (t):
6816 'TypeConstraints : named_constraint'
6817 t [0] = [t[1]]
6818  
6819 def p_TypeConstraints_2 (t):
6820 'TypeConstraints : TypeConstraints COMMA named_constraint'
6821 t[0] = t[1] + [t[3]]
6822  
6823 def p_named_constraint_1 (t):
6824 'named_constraint : identifier constraint'
6825 return Node ('named_constraint', ident = t[1], constr = t[2])
6826  
6827 def p_named_constraint_2 (t):
6828 'named_constraint : constraint'
6829 return Node ('named_constraint', constr = t[1])
6830  
6831 def p_constraint (t):
6832 'constraint : value_constraint presence_constraint'
6833 t[0] = Node ('constraint', value = t[1], presence = t[2])
6834  
6835 def p_value_constraint_1 (t):
6836 'value_constraint : Constraint'
6837 t[0] = t[1]
6838  
6839 def p_value_constraint_2 (t):
6840 'value_constraint : '
6841 pass
6842  
6843 def p_presence_constraint_1 (t):
6844 '''presence_constraint : PRESENT
6845 | ABSENT
6846 | OPTIONAL'''
6847 t[0] = t[1]
6848  
6849 def p_presence_constraint_2 (t):
6850 '''presence_constraint : '''
6851 pass
6852  
6853 # 47.9 Pattern constraint
6854 # 47.9.1
6855 def p_PatternConstraint (t):
6856 'PatternConstraint : PATTERN Value'
6857 t[0] = Constraint (type = 'Pattern', subtype = t[2])
6858  
6859 # 49 The exception identifier
6860  
6861 # 49.4
6862 def p_ExceptionSpec_1 (t):
6863 'ExceptionSpec : EXCLAMATION ExceptionIdentification'
6864 pass
6865  
6866 def p_ExceptionSpec_2 (t):
6867 'ExceptionSpec : '
6868 pass
6869  
6870 def p_ExceptionIdentification (t):
6871 '''ExceptionIdentification : SignedNumber
6872 | DefinedValue
6873 | Type COLON Value '''
6874 pass
6875  
6876 # /*-----------------------------------------------------------------------*/
6877 # /* Value Notation Productions */
6878 # /*-----------------------------------------------------------------------*/
6879  
6880  
6881  
6882 def p_binary_string (t):
6883 'binary_string : BSTRING'
6884 t[0] = BStringValue(val = t[1])
6885  
6886 def p_hex_string (t):
6887 'hex_string : HSTRING'
6888 t[0] = HStringValue(val = t[1])
6889  
6890 def p_char_string (t):
6891 'char_string : QSTRING'
6892 t[0] = t[1]
6893  
6894 def p_number (t):
6895 'number : NUMBER'
6896 t[0] = t[1]
6897  
6898  
6899 #--- ITU-T Recommendation X.208 -----------------------------------------------
6900  
6901 # 27 Notation for the any type ------------------------------------------------
6902  
6903 # 27.1
6904 def p_AnyType (t):
6905 '''AnyType : ANY
6906 | ANY DEFINED BY identifier'''
6907 t[0] = AnyType()
6908  
6909 #--- ITU-T Recommendation X.681 -----------------------------------------------
6910  
6911 # 7 ASN.1 lexical items -------------------------------------------------------
6912  
6913 # 7.1 Information object class references
6914  
6915 def p_objectclassreference (t):
6916 'objectclassreference : CLASS_IDENT'
6917 t[0] = Class_Ref(val=t[1])
6918  
6919 # 7.2 Information object references
6920  
6921 def p_objectreference (t):
6922 'objectreference : LCASE_IDENT'
6923 t[0] = t[1]
6924  
6925 # 7.3 Information object set references
6926  
6927 #def p_objectsetreference (t):
6928 # 'objectsetreference : UCASE_IDENT'
6929 # t[0] = t[1]
6930  
6931 # 7.4 Type field references
6932 # ucasefieldreference
6933 # 7.5 Value field references
6934 # lcasefieldreference
6935 # 7.6 Value set field references
6936 # ucasefieldreference
6937 # 7.7 Object field references
6938 # lcasefieldreference
6939 # 7.8 Object set field references
6940 # ucasefieldreference
6941  
6942 def p_ucasefieldreference (t):
6943 'ucasefieldreference : AMPERSAND UCASE_IDENT'
6944 t[0] = '&' + t[2]
6945  
6946 def p_lcasefieldreference (t):
6947 'lcasefieldreference : AMPERSAND LCASE_IDENT'
6948 t[0] = '&' + t[2]
6949  
6950 # 8 Referencing definitions
6951  
6952 # 8.1
6953 def p_DefinedObjectClass (t):
6954 '''DefinedObjectClass : objectclassreference
6955 | UsefulObjectClassReference'''
6956 t[0] = t[1]
6957 global obj_class
6958 obj_class = t[0].val
6959  
6960 def p_DefinedObject (t):
6961 '''DefinedObject : objectreference'''
6962 t[0] = t[1]
6963  
6964 # 8.4
6965 def p_UsefulObjectClassReference (t):
6966 '''UsefulObjectClassReference : TYPE_IDENTIFIER
6967 | ABSTRACT_SYNTAX'''
6968 t[0] = Class_Ref(val=t[1])
6969  
6970 # 9 Information object class definition and assignment
6971  
6972 # 9.1
6973 def p_ObjectClassAssignment (t):
6974 '''ObjectClassAssignment : CLASS_IDENT ASSIGNMENT ObjectClass
6975 | UCASE_IDENT ASSIGNMENT ObjectClass'''
6976 t[0] = t[3]
6977 t[0].SetName(t[1])
6978 if isinstance(t[0], ObjectClassDefn):
6979 t[0].reg_types()
6980  
6981 # 9.2
6982 def p_ObjectClass (t):
6983 '''ObjectClass : DefinedObjectClass
6984 | ObjectClassDefn
6985 | ParameterizedObjectClass '''
6986 t[0] = t[1]
6987  
6988 # 9.3
6989 def p_ObjectClassDefn (t):
6990 '''ObjectClassDefn : CLASS LBRACE FieldSpecs RBRACE
6991 | CLASS LBRACE FieldSpecs RBRACE WithSyntaxSpec'''
6992 t[0] = ObjectClassDefn(fields = t[3])
6993  
6994 def p_FieldSpecs_1 (t):
6995 'FieldSpecs : FieldSpec'
6996 t[0] = [t[1]]
6997  
6998 def p_FieldSpecs_2 (t):
6999 'FieldSpecs : FieldSpecs COMMA FieldSpec'
7000 t[0] = t[1] + [t[3]]
7001  
7002 def p_WithSyntaxSpec (t):
7003 'WithSyntaxSpec : WITH SYNTAX lbraceignore rbraceignore'
7004 t[0] = None
7005  
7006 # 9.4
7007 def p_FieldSpec (t):
7008 '''FieldSpec : TypeFieldSpec
7009 | FixedTypeValueFieldSpec
7010 | VariableTypeValueFieldSpec
7011 | FixedTypeValueSetFieldSpec
7012 | ObjectFieldSpec
7013 | ObjectSetFieldSpec '''
7014 t[0] = t[1]
7015  
7016 # 9.5
7017 def p_TypeFieldSpec (t):
7018 '''TypeFieldSpec : ucasefieldreference
7019 | ucasefieldreference TypeOptionalitySpec '''
7020 t[0] = TypeFieldSpec()
7021 t[0].SetName(t[1])
7022  
7023 def p_TypeOptionalitySpec_1 (t):
7024 'TypeOptionalitySpec ::= OPTIONAL'
7025 pass
7026  
7027 def p_TypeOptionalitySpec_2 (t):
7028 'TypeOptionalitySpec ::= DEFAULT Type'
7029 pass
7030  
7031 # 9.6
7032 def p_FixedTypeValueFieldSpec (t):
7033 '''FixedTypeValueFieldSpec : lcasefieldreference Type
7034 | lcasefieldreference Type UNIQUE
7035 | lcasefieldreference Type ValueOptionalitySpec
7036 | lcasefieldreference Type UNIQUE ValueOptionalitySpec '''
7037 t[0] = FixedTypeValueFieldSpec(typ = t[2])
7038 t[0].SetName(t[1])
7039  
7040 def p_ValueOptionalitySpec_1 (t):
7041 'ValueOptionalitySpec ::= OPTIONAL'
7042 pass
7043  
7044 def p_ValueOptionalitySpec_2 (t):
7045 'ValueOptionalitySpec ::= DEFAULT Value'
7046 pass
7047  
7048 # 9.8
7049  
7050 def p_VariableTypeValueFieldSpec (t):
7051 '''VariableTypeValueFieldSpec : lcasefieldreference FieldName
7052 | lcasefieldreference FieldName ValueOptionalitySpec '''
7053 t[0] = VariableTypeValueFieldSpec()
7054 t[0].SetName(t[1])
7055  
7056 # 9.9
7057 def p_FixedTypeValueSetFieldSpec (t):
7058 '''FixedTypeValueSetFieldSpec : ucasefieldreference Type
7059 | ucasefieldreference Type ValueSetOptionalitySpec '''
7060 t[0] = FixedTypeValueSetFieldSpec()
7061 t[0].SetName(t[1])
7062  
7063 def p_ValueSetOptionalitySpec_1 (t):
7064 'ValueSetOptionalitySpec ::= OPTIONAL'
7065 pass
7066  
7067 def p_ValueSetOptionalitySpec_2 (t):
7068 'ValueSetOptionalitySpec ::= DEFAULT ValueSet'
7069 pass
7070  
7071 # 9.11
7072 def p_ObjectFieldSpec (t):
7073 '''ObjectFieldSpec : lcasefieldreference DefinedObjectClass
7074 | lcasefieldreference DefinedObjectClass ObjectOptionalitySpec '''
7075 t[0] = ObjectFieldSpec(cls=t[2])
7076 t[0].SetName(t[1])
7077 global obj_class
7078 obj_class = None
7079  
7080 def p_ObjectOptionalitySpec_1 (t):
7081 'ObjectOptionalitySpec ::= OPTIONAL'
7082 pass
7083  
7084 def p_ObjectOptionalitySpec_2 (t):
7085 'ObjectOptionalitySpec ::= DEFAULT Object'
7086 pass
7087  
7088 # 9.12
7089 def p_ObjectSetFieldSpec (t):
7090 '''ObjectSetFieldSpec : ucasefieldreference DefinedObjectClass
7091 | ucasefieldreference DefinedObjectClass ObjectSetOptionalitySpec '''
7092 t[0] = ObjectSetFieldSpec(cls=t[2])
7093 t[0].SetName(t[1])
7094  
7095 def p_ObjectSetOptionalitySpec_1 (t):
7096 'ObjectSetOptionalitySpec ::= OPTIONAL'
7097 pass
7098  
7099 def p_ObjectSetOptionalitySpec_2 (t):
7100 'ObjectSetOptionalitySpec ::= DEFAULT ObjectSet'
7101 pass
7102  
7103 # 9.13
7104 def p_PrimitiveFieldName (t):
7105 '''PrimitiveFieldName : ucasefieldreference
7106 | lcasefieldreference '''
7107 t[0] = t[1]
7108  
7109 # 9.13
7110 def p_FieldName_1 (t):
7111 'FieldName : PrimitiveFieldName'
7112 t[0] = t[1]
7113  
7114 def p_FieldName_2 (t):
7115 'FieldName : FieldName DOT PrimitiveFieldName'
7116 t[0] = t[1] + '.' + t[3]
7117  
7118 # 11 Information object definition and assignment
7119  
7120 # 11.1
7121 def p_ObjectAssignment (t):
7122 'ObjectAssignment : objectreference DefinedObjectClass ASSIGNMENT Object'
7123 t[0] = ObjectAssignment (ident = t[1], cls=t[2].val, val=t[4])
7124 global obj_class
7125 obj_class = None
7126  
7127 # 11.3
7128 def p_Object (t):
7129 '''Object : DefinedObject
7130 | ObjectDefn
7131 | ParameterizedObject'''
7132 t[0] = t[1]
7133  
7134 # 11.4
7135 def p_ObjectDefn (t):
7136 'ObjectDefn : lbraceobject bodyobject rbraceobject'
7137 t[0] = t[2]
7138  
7139 # {...} block of object definition
7140 def p_lbraceobject(t):
7141 'lbraceobject : braceobjectbegin LBRACE'
7142 t[0] = t[1]
7143  
7144 def p_braceobjectbegin(t):
7145 'braceobjectbegin : '
7146 global lexer
7147 global obj_class
7148 if set_class_syntax(obj_class):
7149 state = 'INITIAL'
7150 else:
7151 lexer.level = 1
7152 state = 'braceignore'
7153 lexer.push_state(state)
7154  
7155 def p_rbraceobject(t):
7156 'rbraceobject : braceobjectend RBRACE'
7157 t[0] = t[2]
7158  
7159 def p_braceobjectend(t):
7160 'braceobjectend : '
7161 global lexer
7162 lexer.pop_state()
7163 set_class_syntax(None)
7164  
7165 def p_bodyobject_1 (t):
7166 'bodyobject : '
7167 t[0] = { }
7168  
7169 def p_bodyobject_2 (t):
7170 'bodyobject : cls_syntax_list'
7171 t[0] = t[1]
7172  
7173 def p_cls_syntax_list_1 (t):
7174 'cls_syntax_list : cls_syntax_list cls_syntax'
7175 t[0] = t[1]
7176 t[0].update(t[2])
7177  
7178 def p_cls_syntax_list_2 (t):
7179 'cls_syntax_list : cls_syntax'
7180 t[0] = t[1]
7181  
7182 # X.681
7183 def p_cls_syntax_1 (t):
7184 'cls_syntax : Type IDENTIFIED BY Value'
7185 t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
7186  
7187 def p_cls_syntax_2 (t):
7188 'cls_syntax : HAS PROPERTY Value'
7189 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7190  
7191 # X.880
7192 def p_cls_syntax_3 (t):
7193 '''cls_syntax : ERRORS ObjectSet
7194 | LINKED ObjectSet
7195 | RETURN RESULT BooleanValue
7196 | SYNCHRONOUS BooleanValue
7197 | INVOKE PRIORITY Value
7198 | RESULT_PRIORITY Value
7199 | PRIORITY Value
7200 | ALWAYS RESPONDS BooleanValue
7201 | IDEMPOTENT BooleanValue '''
7202 t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
7203  
7204 def p_cls_syntax_4 (t):
7205 '''cls_syntax : ARGUMENT Type
7206 | RESULT Type
7207 | PARAMETER Type '''
7208 t[0] = { get_class_fieled(t[1]) : t[2] }
7209  
7210 def p_cls_syntax_5 (t):
7211 'cls_syntax : CODE Value'
7212 fld = get_class_fieled(t[1]);
7213 t[0] = { fld : t[2] }
7214 if isinstance(t[2], ChoiceValue):
7215 fldt = fld + '.' + t[2].choice
7216 t[0][fldt] = t[2]
7217  
7218 def p_cls_syntax_6 (t):
7219 '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
7220 | RESULT Type OPTIONAL BooleanValue
7221 | PARAMETER Type OPTIONAL BooleanValue '''
7222 t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
7223  
7224 # 12 Information object set definition and assignment
7225  
7226 # 12.1
7227 def p_ObjectSetAssignment (t):
7228 'ObjectSetAssignment : UCASE_IDENT CLASS_IDENT ASSIGNMENT ObjectSet'
7229 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[2], val=t[4])
7230  
7231 # 12.3
7232 def p_ObjectSet (t):
7233 'ObjectSet : lbraceignore rbraceignore'
7234 t[0] = None
7235  
7236 # 14 Notation for the object class field type ---------------------------------
7237  
7238 # 14.1
7239 def p_ObjectClassFieldType (t):
7240 'ObjectClassFieldType : DefinedObjectClass DOT FieldName'
7241 t[0] = get_type_from_class(t[1], t[3])
7242  
7243 # 14.6
7244 def p_ObjectClassFieldValue (t):
7245 '''ObjectClassFieldValue : OpenTypeFieldVal'''
7246 t[0] = t[1]
7247  
7248 def p_OpenTypeFieldVal (t):
7249 '''OpenTypeFieldVal : Type COLON Value
7250 | NullType COLON NullValue'''
7251 t[0] = t[3]
7252  
7253  
7254 # 15 Information from objects -------------------------------------------------
7255  
7256 # 15.1
7257  
7258 def p_ValueFromObject (t):
7259 'ValueFromObject : LCASE_IDENT DOT FieldName'
7260 t[0] = t[1] + '.' + t[3]
7261  
7262  
7263 # Annex C - The instance-of type ----------------------------------------------
7264  
7265 # C.2
7266 def p_InstanceOfType (t):
7267 'InstanceOfType : INSTANCE OF DefinedObjectClass'
7268 t[0] = InstanceOfType()
7269  
7270  
7271 # --- tables ---
7272  
7273 useful_object_class_types = {
7274 # Annex A
7275 'TYPE-IDENTIFIER.&id' : lambda : ObjectIdentifierType(),
7276 'TYPE-IDENTIFIER.&Type' : lambda : OpenType(),
7277 # Annex B
7278 'ABSTRACT-SYNTAX.&id' : lambda : ObjectIdentifierType(),
7279 'ABSTRACT-SYNTAX.&Type' : lambda : OpenType(),
7280 'ABSTRACT-SYNTAX.&property' : lambda : BitStringType(),
7281 }
7282  
7283 object_class_types = { }
7284  
7285 object_class_typerefs = { }
7286  
7287 object_class_classrefs = { }
7288  
7289 # dummy types
7290 class _VariableTypeValueFieldSpec (AnyType):
7291 pass
7292  
7293 class _FixedTypeValueSetFieldSpec (AnyType):
7294 pass
7295  
7296 class_types_creator = {
7297 'BooleanType' : lambda : BooleanType(),
7298 'IntegerType' : lambda : IntegerType(),
7299 'ObjectIdentifierType' : lambda : ObjectIdentifierType(),
7300 'OpenType' : lambda : OpenType(),
7301 # dummy types
7302 '_VariableTypeValueFieldSpec' : lambda : _VariableTypeValueFieldSpec(),
7303 '_FixedTypeValueSetFieldSpec' : lambda : _FixedTypeValueSetFieldSpec(),
7304 }
7305  
7306 class_names = { }
7307  
7308 x681_syntaxes = {
7309 'TYPE-IDENTIFIER' : {
7310 ' ' : '&Type',
7311 'IDENTIFIED' : 'IDENTIFIED',
7312 #'BY' : 'BY',
7313 'IDENTIFIED BY' : '&id',
7314 },
7315 'ABSTRACT-SYNTAX' : {
7316 ' ' : '&Type',
7317 'IDENTIFIED' : 'IDENTIFIED',
7318 #'BY' : 'BY',
7319 'IDENTIFIED BY' : '&id',
7320 'HAS' : 'HAS',
7321 'PROPERTY' : 'PROPERTY',
7322 'HAS PROPERTY' : '&property',
7323 },
7324 }
7325  
7326 class_syntaxes_enabled = {
7327 'TYPE-IDENTIFIER' : True,
7328 'ABSTRACT-SYNTAX' : True,
7329 }
7330  
7331 class_syntaxes = {
7332 'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
7333 'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
7334 }
7335  
7336 class_current_syntax = None
7337  
7338 def get_syntax_tokens(syntaxes):
7339 tokens = { }
7340 for s in (syntaxes):
7341 for k in (list(syntaxes[s].keys())):
7342 if k.find(' ') < 0:
7343 tokens[k] = k
7344 tokens[k] = tokens[k].replace('-', '_')
7345 return list(tokens.values())
7346  
7347 tokens = tokens + get_syntax_tokens(x681_syntaxes)
7348  
7349 def set_class_syntax(syntax):
7350 global class_syntaxes_enabled
7351 global class_current_syntax
7352 #print "set_class_syntax", syntax, class_current_syntax
7353 if class_syntaxes_enabled.get(syntax, False):
7354 class_current_syntax = syntax
7355 return True
7356 else:
7357 class_current_syntax = None
7358 return False
7359  
7360 def is_class_syntax(name):
7361 global class_syntaxes
7362 global class_current_syntax
7363 #print "is_class_syntax", name, class_current_syntax
7364 if not class_current_syntax:
7365 return False
7366 return name in class_syntaxes[class_current_syntax]
7367  
7368 def get_class_fieled(name):
7369 if not class_current_syntax:
7370 return None
7371 return class_syntaxes[class_current_syntax][name]
7372  
7373 def is_class_ident(name):
7374 return name in class_names
7375  
7376 def add_class_ident(name):
7377 #print "add_class_ident", name
7378 class_names[name] = name
7379  
7380 def get_type_from_class(cls, fld):
7381 flds = fld.split('.')
7382 if (isinstance(cls, Class_Ref)):
7383 key = cls.val + '.' + flds[0]
7384 else:
7385 key = cls + '.' + flds[0]
7386  
7387 if key in object_class_classrefs:
7388 return get_type_from_class(object_class_classrefs[key], '.'.join(flds[1:]))
7389  
7390 if key in object_class_typerefs:
7391 return Type_Ref(val=object_class_typerefs[key])
7392  
7393 creator = lambda : AnyType()
7394 creator = useful_object_class_types.get(key, creator)
7395 creator = object_class_types.get(key, creator)
7396 return creator()
7397  
7398 def set_type_to_class(cls, fld, pars):
7399 #print "set_type_to_class", cls, fld, pars
7400 key = cls + '.' + fld
7401 typename = 'OpenType'
7402 if (len(pars) > 0):
7403 typename = pars[0]
7404 else:
7405 pars.append(typename)
7406 typeref = None
7407 if (len(pars) > 1):
7408 if (isinstance(pars[1], Class_Ref)):
7409 pars[1] = pars[1].val
7410 typeref = pars[1]
7411  
7412 msg = None
7413 if key in object_class_types:
7414 msg = object_class_types[key]().type
7415 if key in object_class_typerefs:
7416 msg = "TypeReference " + object_class_typerefs[key]
7417 if key in object_class_classrefs:
7418 msg = "ClassReference " + object_class_classrefs[key]
7419  
7420 if msg == ' '.join(pars):
7421 msg = None
7422  
7423 if msg:
7424 msg0 = "Can not define CLASS field %s as '%s'\n" % (key, ' '.join(pars))
7425 msg1 = "Already defined as '%s'" % (msg)
7426 raise CompError(msg0 + msg1)
7427  
7428 if (typename == 'ClassReference'):
7429 if not typeref: return False
7430 object_class_classrefs[key] = typeref
7431 return True
7432  
7433 if (typename == 'TypeReference'):
7434 if not typeref: return False
7435 object_class_typerefs[key] = typeref
7436 return True
7437  
7438 creator = class_types_creator.get(typename)
7439 if creator:
7440 object_class_types[key] = creator
7441 return True
7442 else:
7443 return False
7444  
7445 def import_class_from_module(mod, cls):
7446 add_class_ident(cls)
7447 mcls = "$%s$%s" % (mod, cls)
7448 for k in list(object_class_classrefs.keys()):
7449 kk = k.split('.', 1)
7450 if kk[0] == mcls:
7451 object_class_classrefs[cls + '.' + kk[0]] = object_class_classrefs[k]
7452 for k in list(object_class_typerefs.keys()):
7453 kk = k.split('.', 1)
7454 if kk[0] == mcls:
7455 object_class_typerefs[cls + '.' + kk[0]] = object_class_typerefs[k]
7456 for k in list(object_class_types.keys()):
7457 kk = k.split('.', 1)
7458 if kk[0] == mcls:
7459 object_class_types[cls + '.' + kk[0]] = object_class_types[k]
7460  
7461 #--- ITU-T Recommendation X.682 -----------------------------------------------
7462  
7463 # 8 General constraint specification ------------------------------------------
7464  
7465 # 8.1
7466 def p_GeneralConstraint (t):
7467 '''GeneralConstraint : UserDefinedConstraint
7468 | TableConstraint
7469 | ContentsConstraint'''
7470 t[0] = t[1]
7471  
7472 # 9 User-defined constraints --------------------------------------------------
7473  
7474 # 9.1
7475 def p_UserDefinedConstraint (t):
7476 'UserDefinedConstraint : CONSTRAINED BY LBRACE UserDefinedConstraintParameterList RBRACE'
7477 t[0] = Constraint(type = 'UserDefined', subtype = t[4])
7478  
7479 def p_UserDefinedConstraintParameterList_1 (t):
7480 'UserDefinedConstraintParameterList : '
7481 t[0] = []
7482  
7483 def p_UserDefinedConstraintParameterList_2 (t):
7484 'UserDefinedConstraintParameterList : UserDefinedConstraintParameter'
7485 t[0] = [t[1]]
7486  
7487 def p_UserDefinedConstraintParameterList_3 (t):
7488 'UserDefinedConstraintParameterList : UserDefinedConstraintParameterList COMMA UserDefinedConstraintParameter'
7489 t[0] = t[1] + [t[3]]
7490  
7491 # 9.3
7492 def p_UserDefinedConstraintParameter (t):
7493 'UserDefinedConstraintParameter : Type'
7494 t[0] = t[1]
7495  
7496 # 10 Table constraints, including component relation constraints --------------
7497  
7498 # 10.3
7499 def p_TableConstraint (t):
7500 '''TableConstraint : SimpleTableConstraint
7501 | ComponentRelationConstraint'''
7502 t[0] = Constraint(type = 'Table', subtype = t[1])
7503  
7504 def p_SimpleTableConstraint (t):
7505 'SimpleTableConstraint : LBRACE UCASE_IDENT RBRACE'
7506 t[0] = t[2]
7507  
7508 # 10.7
7509 def p_ComponentRelationConstraint (t):
7510 'ComponentRelationConstraint : LBRACE UCASE_IDENT RBRACE LBRACE AtNotations RBRACE'
7511 t[0] = t[2] + str(t[5])
7512  
7513 def p_AtNotations_1 (t):
7514 'AtNotations : AtNotation'
7515 t[0] = [t[1]]
7516  
7517 def p_AtNotations_2 (t):
7518 'AtNotations : AtNotations COMMA AtNotation'
7519 t[0] = t[1] + [t[3]]
7520  
7521 def p_AtNotation_1 (t):
7522 'AtNotation : AT ComponentIdList'
7523 t[0] = '@' + t[2]
7524  
7525 def p_AtNotation_2 (t):
7526 'AtNotation : AT DOT Level ComponentIdList'
7527 t[0] = '@.' + t[3] + t[4]
7528  
7529 def p_Level_1 (t):
7530 'Level : DOT Level'
7531 t[0] = '.' + t[2]
7532  
7533 def p_Level_2 (t):
7534 'Level : '
7535 t[0] = ''
7536  
7537 def p_ComponentIdList_1 (t):
7538 'ComponentIdList : LCASE_IDENT'
7539 t[0] = t[1]
7540  
7541 def p_ComponentIdList_2 (t):
7542 'ComponentIdList : ComponentIdList DOT LCASE_IDENT'
7543 t[0] = t[1] + '.' + t[3]
7544  
7545 # 11 Contents constraints -----------------------------------------------------
7546  
7547 # 11.1
7548 def p_ContentsConstraint (t):
7549 'ContentsConstraint : CONTAINING type_ref'
7550 t[0] = Constraint(type = 'Contents', subtype = t[2])
7551  
7552  
7553 #--- ITU-T Recommendation X.683 -----------------------------------------------
7554  
7555 # 8 Parameterized assignments -------------------------------------------------
7556  
7557 # 8.1
7558 def p_ParameterizedAssignment (t):
7559 '''ParameterizedAssignment : ParameterizedTypeAssignment
7560 | ParameterizedObjectClassAssignment
7561 | ParameterizedObjectAssignment
7562 | ParameterizedObjectSetAssignment'''
7563 t[0] = t[1]
7564  
7565 # 8.2
7566 def p_ParameterizedTypeAssignment (t):
7567 'ParameterizedTypeAssignment : UCASE_IDENT ParameterList ASSIGNMENT Type'
7568 t[0] = t[4]
7569 t[0].SetName(t[1]) # t[0].SetName(t[1] + 'xxx')
7570  
7571 def p_ParameterizedObjectClassAssignment (t):
7572 '''ParameterizedObjectClassAssignment : CLASS_IDENT ParameterList ASSIGNMENT ObjectClass
7573 | UCASE_IDENT ParameterList ASSIGNMENT ObjectClass'''
7574 t[0] = t[4]
7575 t[0].SetName(t[1])
7576 if isinstance(t[0], ObjectClassDefn):
7577 t[0].reg_types()
7578  
7579 def p_ParameterizedObjectAssignment (t):
7580 'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
7581 t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
7582 global obj_class
7583 obj_class = None
7584  
7585 def p_ParameterizedObjectSetAssignment (t):
7586 'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
7587 t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
7588  
7589 # 8.3
7590 def p_ParameterList (t):
7591 'ParameterList : lbraceignore rbraceignore'
7592  
7593 #def p_ParameterList (t):
7594 # 'ParameterList : LBRACE Parameters RBRACE'
7595 # t[0] = t[2]
7596  
7597 #def p_Parameters_1 (t):
7598 # 'Parameters : Parameter'
7599 # t[0] = [t[1]]
7600  
7601 #def p_Parameters_2 (t):
7602 # 'Parameters : Parameters COMMA Parameter'
7603 # t[0] = t[1] + [t[3]]
7604  
7605 #def p_Parameter_1 (t):
7606 # 'Parameter : Type COLON Reference'
7607 # t[0] = [t[1], t[3]]
7608  
7609 #def p_Parameter_2 (t):
7610 # 'Parameter : Reference'
7611 # t[0] = t[1]
7612  
7613  
7614 # 9 Referencing parameterized definitions -------------------------------------
7615  
7616 # 9.1
7617 def p_ParameterizedReference (t):
7618 'ParameterizedReference : Reference LBRACE RBRACE'
7619 t[0] = t[1]
7620 #t[0].val += 'xxx'
7621  
7622 # 9.2
7623 def p_ParameterizedType (t):
7624 'ParameterizedType : type_ref ActualParameterList'
7625 t[0] = t[1]
7626 #t[0].val += 'xxx'
7627  
7628  
7629 def p_ParameterizedObjectClass (t):
7630 'ParameterizedObjectClass : DefinedObjectClass ActualParameterList'
7631 t[0] = t[1]
7632 #t[0].val += 'xxx'
7633  
7634 def p_ParameterizedObject (t):
7635 'ParameterizedObject : DefinedObject ActualParameterList'
7636 t[0] = t[1]
7637 #t[0].val += 'xxx'
7638  
7639 # 9.5
7640 def p_ActualParameterList (t):
7641 'ActualParameterList : lbraceignore rbraceignore'
7642  
7643 #def p_ActualParameterList (t):
7644 # 'ActualParameterList : LBRACE ActualParameters RBRACE'
7645 # t[0] = t[2]
7646  
7647 #def p_ActualParameters_1 (t):
7648 # 'ActualParameters : ActualParameter'
7649 # t[0] = [t[1]]
7650  
7651 #def p_ActualParameters_2 (t):
7652 # 'ActualParameters : ActualParameters COMMA ActualParameter'
7653 # t[0] = t[1] + [t[3]]
7654  
7655 #def p_ActualParameter (t):
7656 # '''ActualParameter : Type
7657 # | Value'''
7658 # t[0] = t[1]
7659  
7660  
7661 #--- ITU-T Recommendation X.880 -----------------------------------------------
7662  
7663 x880_classes = {
7664 'OPERATION' : {
7665 '&ArgumentType' : [],
7666 '&argumentTypeOptional' : [ 'BooleanType' ],
7667 '&returnResult' : [ 'BooleanType' ],
7668 '&ResultType' : [],
7669 '&resultTypeOptional' : [ 'BooleanType' ],
7670 '&Errors' : [ 'ClassReference', 'ERROR' ],
7671 '&Linked' : [ 'ClassReference', 'OPERATION' ],
7672 '&synchronous' : [ 'BooleanType' ],
7673 '&idempotent' : [ 'BooleanType' ],
7674 '&alwaysReturns' : [ 'BooleanType' ],
7675 '&InvokePriority' : [ '_FixedTypeValueSetFieldSpec' ],
7676 '&ResultPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7677 '&operationCode' : [ 'TypeReference', 'Code' ],
7678 },
7679 'ERROR' : {
7680 '&ParameterType' : [],
7681 '&parameterTypeOptional' : [ 'BooleanType' ],
7682 '&ErrorPriority' : [ '_FixedTypeValueSetFieldSpec' ],
7683 '&errorCode' : [ 'TypeReference', 'Code' ],
7684 },
7685 'OPERATION-PACKAGE' : {
7686 '&Both' : [ 'ClassReference', 'OPERATION' ],
7687 '&Consumer' : [ 'ClassReference', 'OPERATION' ],
7688 '&Supplier' : [ 'ClassReference', 'OPERATION' ],
7689 '&id' : [ 'ObjectIdentifierType' ],
7690 },
7691 'CONNECTION-PACKAGE' : {
7692 '&bind' : [ 'ClassReference', 'OPERATION' ],
7693 '&unbind' : [ 'ClassReference', 'OPERATION' ],
7694 '&responderCanUnbind' : [ 'BooleanType' ],
7695 '&unbindCanFail' : [ 'BooleanType' ],
7696 '&id' : [ 'ObjectIdentifierType' ],
7697 },
7698 'CONTRACT' : {
7699 '&connection' : [ 'ClassReference', 'CONNECTION-PACKAGE' ],
7700 '&OperationsOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7701 '&InitiatorConsumerOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7702 '&InitiatorSupplierOf' : [ 'ClassReference', 'OPERATION-PACKAGE' ],
7703 '&id' : [ 'ObjectIdentifierType' ],
7704 },
7705 'ROS-OBJECT-CLASS' : {
7706 '&Is' : [ 'ClassReference', 'ROS-OBJECT-CLASS' ],
7707 '&Initiates' : [ 'ClassReference', 'CONTRACT' ],
7708 '&Responds' : [ 'ClassReference', 'CONTRACT' ],
7709 '&InitiatesAndResponds' : [ 'ClassReference', 'CONTRACT' ],
7710 '&id' : [ 'ObjectIdentifierType' ],
7711 },
7712 }
7713  
7714 x880_syntaxes = {
7715 'OPERATION' : {
7716 'ARGUMENT' : '&ArgumentType',
7717 'ARGUMENT OPTIONAL' : '&argumentTypeOptional',
7718 'RESULT' : '&ResultType',
7719 'RESULT OPTIONAL' : '&resultTypeOptional',
7720 'RETURN' : 'RETURN',
7721 'RETURN RESULT' : '&returnResult',
7722 'ERRORS' : '&Errors',
7723 'LINKED' : '&Linked',
7724 'SYNCHRONOUS' : '&synchronous',
7725 'IDEMPOTENT' : '&idempotent',
7726 'ALWAYS' : 'ALWAYS',
7727 'RESPONDS' : 'RESPONDS',
7728 'ALWAYS RESPONDS' : '&alwaysReturns',
7729 'INVOKE' : 'INVOKE',
7730 'PRIORITY' : 'PRIORITY',
7731 'INVOKE PRIORITY' : '&InvokePriority',
7732 'RESULT-PRIORITY': '&ResultPriority',
7733 'CODE' : '&operationCode',
7734 },
7735 'ERROR' : {
7736 'PARAMETER' : '&ParameterType',
7737 'PARAMETER OPTIONAL' : '&parameterTypeOptional',
7738 'PRIORITY' : '&ErrorPriority',
7739 'CODE' : '&errorCode',
7740 },
7741 # 'OPERATION-PACKAGE' : {
7742 # },
7743 # 'CONNECTION-PACKAGE' : {
7744 # },
7745 # 'CONTRACT' : {
7746 # },
7747 # 'ROS-OBJECT-CLASS' : {
7748 # },
7749 }
7750  
7751 def x880_module_begin():
7752 #print "x880_module_begin()"
7753 for name in list(x880_classes.keys()):
7754 add_class_ident(name)
7755  
7756 def x880_import(name):
7757 if name in x880_syntaxes:
7758 class_syntaxes_enabled[name] = True
7759 class_syntaxes[name] = x880_syntaxes[name]
7760 if name in x880_classes:
7761 add_class_ident(name)
7762 for f in (list(x880_classes[name].keys())):
7763 set_type_to_class(name, f, x880_classes[name][f])
7764  
7765 tokens = tokens + get_syntax_tokens(x880_syntaxes)
7766  
7767 # {...} OID value
7768 #def p_lbrace_oid(t):
7769 # 'lbrace_oid : brace_oid_begin LBRACE'
7770 # t[0] = t[1]
7771  
7772 #def p_brace_oid_begin(t):
7773 # 'brace_oid_begin : '
7774 # global in_oid
7775 # in_oid = True
7776  
7777 #def p_rbrace_oid(t):
7778 # 'rbrace_oid : brace_oid_end RBRACE'
7779 # t[0] = t[2]
7780  
7781 #def p_brace_oid_end(t):
7782 # 'brace_oid_end : '
7783 # global in_oid
7784 # in_oid = False
7785  
7786 # {...} block to be ignored
7787 def p_lbraceignore(t):
7788 'lbraceignore : braceignorebegin LBRACE'
7789 t[0] = t[1]
7790  
7791 def p_braceignorebegin(t):
7792 'braceignorebegin : '
7793 global lexer
7794 lexer.level = 1
7795 lexer.push_state('braceignore')
7796  
7797 def p_rbraceignore(t):
7798 'rbraceignore : braceignoreend RBRACE'
7799 t[0] = t[2]
7800  
7801 def p_braceignoreend(t):
7802 'braceignoreend : '
7803 global lexer
7804 lexer.pop_state()
7805  
7806 def p_error(t):
7807 global input_file
7808 raise ParseError(t, input_file)
7809  
7810 def p_pyquote (t):
7811 '''pyquote : PYQUOTE'''
7812 t[0] = PyQuote (val = t[1])
7813  
7814  
7815 def testlex (s):
7816 lexer.input (s)
7817 while True:
7818 token = lexer.token ()
7819 if not token:
7820 break
7821 print(token)
7822  
7823  
7824 def do_module (ast, defined_dict):
7825 assert (ast.type == 'Module')
7826 ctx = Ctx (defined_dict)
7827 print(ast.to_python (ctx))
7828 print(ctx.output_assignments ())
7829 print(ctx.output_pyquotes ())
7830  
7831 def eth_do_module (ast, ectx):
7832 assert (ast.type == 'Module')
7833 if ectx.dbg('s'): print(ast.str_depth(0))
7834 ast.to_eth(ectx)
7835  
7836 def testyacc(s, fn, defined_dict):
7837 ast = yacc.parse(s, debug=0)
7838 time_str = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
7839 print("""#!/usr/bin/env python
7840 # Auto-generated from %s at %s
7841 from PyZ3950 import asn1""" % (fn, time_str))
7842 for module in ast:
7843 eth_do_module (module, defined_dict)
7844  
7845  
7846 # Wireshark compiler
7847 def eth_usage():
7848 print("""
7849 asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ...
7850 -h|? : Usage
7851 -b : BER (default is PER)
7852 -u : Unaligned (default is aligned)
7853 -p proto : Protocol name (implies -S). Default is module-name
7854 from input_file (renamed by #.MODULE if present)
7855 -o name : Output files name core (default is <proto>)
7856 -O dir : Output directory for dissector
7857 -c cnf_file : Conformance file
7858 -I path : Path for conformance file includes
7859 -e : Create conformance file for exported types
7860 -E : Just create conformance file for exported types
7861 -S : Single output for multiple modules
7862 -s template : Single file output (template is input file
7863 without .c/.h extension)
7864 -k : Keep intermediate files though single file output is used
7865 -L : Suppress #line directive from .cnf file
7866 -D dir : Directory for input_file(s) (default: '.')
7867 -C : Add check for SIZE constraints
7868 -r prefix : Remove the prefix from type names
7869  
7870 input_file(s) : Input ASN.1 file(s)
7871  
7872 -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o]
7873 l - lex
7874 y - yacc
7875 p - parsing
7876 s - internal ASN.1 structure
7877 a - list of assignments
7878 t - tables
7879 c - conformance values
7880 m - list of compiled modules with dependency
7881 o - list of output files
7882 """)
7883  
7884 def eth_main():
7885 global input_file
7886 global g_conform
7887 global lexer
7888 print("ASN.1 to Wireshark dissector compiler");
7889 try:
7890 opts, args = getopt.getopt(sys.argv[1:], "h?d:D:buXp:FTo:O:c:I:eESs:kLCr:");
7891 except getopt.GetoptError:
7892 eth_usage(); sys.exit(2)
7893 if len(args) < 1:
7894 eth_usage(); sys.exit(2)
7895  
7896 conform = EthCnf()
7897 conf_to_read = None
7898 output = EthOut()
7899 ectx = EthCtx(conform, output)
7900 ectx.encoding = 'per'
7901 ectx.proto_opt = None
7902 ectx.fld_opt = {}
7903 ectx.tag_opt = False
7904 ectx.outnm_opt = None
7905 ectx.aligned = True
7906 ectx.dbgopt = ''
7907 ectx.new = True
7908 ectx.expcnf = False
7909 ectx.justexpcnf = False
7910 ectx.merge_modules = False
7911 ectx.group_by_prot = False
7912 ectx.conform.last_group = 0
7913 ectx.conform.suppress_line = False;
7914 ectx.output.outnm = None
7915 ectx.output.single_file = None
7916 ectx.constraints_check = False;
7917 for o, a in opts:
7918 if o in ("-h", "-?"):
7919 eth_usage(); sys.exit(2)
7920 if o in ("-c",):
7921 conf_to_read = relpath(a)
7922 if o in ("-I",):
7923 ectx.conform.include_path.append(relpath(a))
7924 if o in ("-E",):
7925 ectx.expcnf = True
7926 ectx.justexpcnf = True
7927 if o in ("-D",):
7928 ectx.srcdir = relpath(a)
7929 if o in ("-C",):
7930 ectx.constraints_check = True
7931 if o in ("-X",):
7932 warnings.warn("Command line option -X is obsolete and can be removed")
7933 if o in ("-T",):
7934 warnings.warn("Command line option -T is obsolete and can be removed")
7935  
7936 if conf_to_read:
7937 ectx.conform.read(conf_to_read)
7938  
7939 for o, a in opts:
7940 if o in ("-h", "-?", "-c", "-I", "-E", "-D", "-C", "-X", "-T"):
7941 pass # already processed
7942 else:
7943 par = []
7944 if a: par.append(a)
7945 ectx.conform.set_opt(o, par, "commandline", 0)
7946  
7947 (ld, yd, pd) = (0, 0, 0);
7948 if ectx.dbg('l'): ld = 1
7949 if ectx.dbg('y'): yd = 1
7950 if ectx.dbg('p'): pd = 2
7951 lexer = lex.lex(debug=ld)
7952 parser = yacc.yacc(method='LALR', debug=yd, outputdir='.')
7953 parser.defaulted_states = {}
7954 g_conform = ectx.conform
7955 ast = []
7956 for fn in args:
7957 input_file = fn
7958 lexer.lineno = 1
7959 if (ectx.srcdir): fn = ectx.srcdir + '/' + fn
7960 # Read ASN.1 definition, trying one of the common encodings.
7961 data = open(fn, "rb").read()
7962 for encoding in ('utf-8', 'windows-1252'):
7963 try:
7964 data = data.decode(encoding)
7965 break
7966 except:
7967 warnings.warn_explicit("Decoding %s as %s failed, trying next." % (fn, encoding), UserWarning, '', 0)
7968 # Py2 compat, name.translate in eth_output_hf_arr fails with unicode
7969 if not isinstance(data, str):
7970 data = data.encode('utf-8')
7971 ast.extend(yacc.parse(data, lexer=lexer, debug=pd))
7972 ectx.eth_clean()
7973 if (ectx.merge_modules): # common output for all module
7974 ectx.eth_clean()
7975 for module in ast:
7976 eth_do_module(module, ectx)
7977 ectx.eth_prepare()
7978 ectx.eth_do_output()
7979 elif (ectx.groups()): # group by protocols/group
7980 groups = []
7981 pr2gr = {}
7982 if (ectx.group_by_prot): # group by protocols
7983 for module in ast:
7984 prot = module.get_proto(ectx)
7985 if prot not in pr2gr:
7986 pr2gr[prot] = len(groups)
7987 groups.append([])
7988 groups[pr2gr[prot]].append(module)
7989 else: # group by groups
7990 pass
7991 for gm in (groups):
7992 ectx.eth_clean()
7993 for module in gm:
7994 eth_do_module(module, ectx)
7995 ectx.eth_prepare()
7996 ectx.eth_do_output()
7997 else: # output for each module
7998 for module in ast:
7999 ectx.eth_clean()
8000 eth_do_module(module, ectx)
8001 ectx.eth_prepare()
8002 ectx.eth_do_output()
8003  
8004 if ectx.dbg('m'):
8005 ectx.dbg_modules()
8006  
8007 if ectx.dbg('c'):
8008 ectx.conform.dbg_print()
8009 if not ectx.justexpcnf:
8010 ectx.conform.unused_report()
8011  
8012 if ectx.dbg('o'):
8013 ectx.output.dbg_print()
8014 ectx.output.make_single_file()
8015  
8016  
8017 # Python compiler
8018 def main():
8019 testfn = testyacc
8020 if len (sys.argv) == 1:
8021 while True:
8022 s = input ('Query: ')
8023 if len (s) == 0:
8024 break
8025 testfn (s, 'console', {})
8026 else:
8027 defined_dict = {}
8028 for fn in sys.argv [1:]:
8029 f = open (fn, "r")
8030 testfn (f.read (), fn, defined_dict)
8031 f.close ()
8032 lexer.lineno = 1
8033  
8034  
8035 #--- BODY ---------------------------------------------------------------------
8036  
8037 if __name__ == '__main__':
8038 if (os.path.splitext(os.path.basename(sys.argv[0]))[0].lower() in ('asn2wrs', 'asn2eth')):
8039 eth_main()
8040 else:
8041 main()
8042  
8043 #------------------------------------------------------------------------------
8044 #
8045 # Editor modelines - http://www.wireshark.org/tools/modelines.html
8046 #
8047 # c-basic-offset: 4; tab-width: 8; indent-tabs-mode: nil
8048 # vi: set shiftwidth=4 tabstop=8 expandtab:
8049 # :indentSize=4:tabSize=8:noTabs=true: