def walk_a_record(self, rec=None): if rec is None: rec = self.base my_log.debug("walk_a_record: %s" % rec.name) my_log.debug("rec fields: %s" % rec.fpos) for field in rec.fpos: self.walk_a_field(rec.fields[field])
def exitNumber_declaration(self, ctx): if self.ctx.cur_spec is not None: av = AdaVar(self.ctx.cur_idents.pop(), self.ctx.cur_spec.package, self.ctx) av.solve_value(cpu.get_texts(ctx.expression())) self.ctx.cur_spec.add_var(av) my_log.debug("exitNumber_declaration: %s" % av) for ident in self.ctx.cur_idents: self.ctx.cur_spec.add_var(av.copy(ident)) self.exit_state(FileMng.States.VAR, ctx)
def exitComponent_clause(self, ctx): if self.ctx.cur_spec is not None: field_n = cpu.get_texts(ctx.component_local_name()).upper() my_log.debug("exitComponent_clause: %s" % field_n) cur_type = self.ctx.cur_spec.types[self.ctx.cur_type.package][self.ctx.cur_type.name] my_log.debug(self.ctx.cur_type.package) my_log.debug(self.ctx.cur_type.name) cur_type.fields[field_n].solve_pos(cpu.get_texts(ctx.position())) cur_type.fields[field_n].solve_start_bit(cpu.get_texts(ctx.first_bit())) cur_type.fields[field_n].solve_end_bit(cpu.get_texts(ctx.last_bit())) cur_type.add_pos(field_n) my_log.debug(cur_type.fields[field_n]) my_log.debug(cur_type.fpos)
def exitRange_state(self, ctx): if self.ctx.cur_spec is not None: self.ctx.cur_range = {} rar = ctx.range_attribute_reference() if rar: rar = cpu.get_texts(rar) self.ctx.cur_range = {'type': 'attr', 'base': rar[:rar.find("'")]} else: self.ctx.cur_range = {'type': 'range', 'first': cpu.solve_expr(self.ctx, cpu.get_texts(ctx.simple_expression(0)))[0], 'last': cpu.solve_expr(self.ctx, cpu.get_texts(ctx.simple_expression(1)))[0] } if self.ctx.cur_const and self.ctx.cur_const['type'] == 'range': self.ctx.cur_const.update({'range': self.ctx.cur_range}) # always here my_log.debug("exitRange_state1: %s" % self.ctx.cur_type) my_log.debug("exitRange_state2: %s" % self.ctx.cur_const) elif self.ctx.cur_fm.cur_states[-1] == FileMng.States.SUB_DER_TYPE: self.ctx.cur_const = {'type': 'range', 'range': self.ctx.cur_range} my_log.debug("exitRange_state3: %s" % self.ctx.cur_type) my_log.debug("exitRange_state4: %s" % self.ctx.cur_const) elif self.ctx.cur_fm.cur_states[-1] in (FileMng.States.FIELD_TYPE, FileMng.States.VAR_TYPE, FileMng.States.ARRAY_DEFINE): self.ctx.cur_const = {'type': 'range', 'range': self.ctx.cur_range} else: my_log.error("ignore range statement: %s" % ctx.getText())
def enterEnumeration_type_definition(self, ctx): if self.ctx.cur_spec is not None: self.ctx.cur_type = AdaEnumType( self.ctx.cur_type, self.ctx.cur_spec.package, self.ctx) #if self.ctx.cur_discrim: # self.ctx.cur_type.add_discrim(self.ctx.cur_discrim) enums = cpu.get_texts(ctx.enumeration_literal_specification()) my_log.debug("enterEnumeration_type_definition: %s" % enums) for e in enums: e_item = AdaEnumItem(e, self.ctx.cur_type, self.ctx) self.ctx.cur_type.add_enum(e_item) self.ctx.cur_spec.add_enum(e_item) my_log.debug(self.ctx.cur_type) self.ctx.cur_field = None
def walk_a_base_type(self, field, typ, i_size=None, i_name=None, enum_type=None): my_log.debug("walk_a_base_type: [%s][%s][%s]" % (field, typ, i_size)) num = None if typ == 'STRING': num = (i_size - 1) // 8 + 1 #if getattr(field, 'size', None) is None: # setattr(field, 'size', 8 *num) elif typ == 'FLOAT': size = i_size or (int(field.end_bit) - int(field.start_bit)) if size > 32: typ = 'LONG_FLOAT' elif typ == 'INTEGER': size = i_size or (int(field.end_bit) - int(field.start_bit)) if size <= 8: typ = 'SHORT_SHORT_INTEGER' elif size <= 16: typ = 'SHORT_INTEGER' elif size > 32: typ = 'LONG_LONG_INTEGER' struc, leng = GenFmt.get_struct(typ, num) pos = self.get_pos(int(field.pos)) name = self.get_name(i_name or getattr(field, 'tmp_name_in_array', None) or field.name) my_log.debug("name: [%s], pos: [%s], struct: [%s], length: [%s]" % (name, pos, struc, leng)) tmp = { 'pos': pos, 'length': leng, 'leaf': True, 'struct': struc, } if (getattr(field, 'start_bit', None) is not None) and (getattr( field, 'end_bit', None) is not None) and (( (int(field.end_bit) - int(field.start_bit) + 1) % 8) in range(1, 8)): tmp['start_bit'] = field.start_bit tmp['end_bit'] = field.end_bit if enum_type is not None: tmp['enum_type'] = enum_type self.set_result(tmp, name)
def solve_expr(ctx, i_expr): TO_DO = "check enum items" res = re.findall("[a-zA-Z]\w*(?:[.'][a-zA-Z]\w*)*", i_expr) res = set(res) for name in res: has_attr = "'" in name attr = "" if has_attr: attr = name[name.find("'") + 1:] name = name[:name.find("'")] var, found = find_name(name, ctx, 'var') if found and not has_attr: if var.value_solved and var.value: i_expr = i_expr.replace(name, var.value) else: if found: var = var.data_type else: var, found = find_name(name, ctx, 'type') if found: attr2 = attr.lower() attr_v = getattr(var, attr2, None) if attr_v: i_expr = i_expr.replace("'".join([name, attr]), attr_v) i_expr = re.sub('(\d)_(\d)', '\\1\\2', i_expr) i_expr = re.sub('(\d+)#(\d+)#', lambda x: str(int(x.group(2), int(x.group(1)))), i_expr) try: i_expr = str(eval(i_expr)) except (NameError, SyntaxError) as ne: enum, found = find_name(i_expr, ctx, 'enum') if not found: my_log.error('No solved: %s\n[%s] in [%s]' % (ne, i_expr, ctx.cur_fm.f_path)) my_log.debug("types: %s" % ctx.types) my_log.debug("vars: %s" % ctx.vars) return i_expr, False return i_expr, True
def find_name(name, ctx, itype='var'): #print(ctx.types) cur_uses = ctx.cur_spec.uses cur_withs = ctx.cur_spec.withs my_log.debug("uses: %s" % cur_uses) my_log.debug("withs: %s" % cur_withs) name = name.upper() if itype == 'var': check_info = ctx.vars elif itype == 'type': check_info = ctx.types elif itype == 'enum': check_info = ctx.enums direct_packages = [ctx.cur_spec.package, ADA_SYSTEM_DEFINED] if cur_uses: direct_packages.extend(cur_uses) for pakcage in direct_packages: if pakcage in check_info: if name in check_info[pakcage]: return check_info[pakcage][name], True idents = name.split('.') if len(idents) > 1 and cur_withs: for i in range(1, len(idents)): pakcage = ".".join(idents[:i]) t_name = ".".join(idents[i:]) pakcages = [pakcage] pakcages.extend(map(lambda x: '.'.join([x, pakcage]), cur_uses)) for pakcage in pakcages: units = pakcage.split('.') to_checks = set() for j in range(len(units)): to_checks.add(".".join(units[:j + 1])) if ( to_checks & cur_withs ) and pakcage in check_info and t_name in check_info[pakcage]: return check_info[pakcage][t_name], True return name, False
def exitSubtype_indication(self, ctx): if self.ctx.cur_spec is not None: cur_mark = self.get_cur_submark(ctx) if self.ctx.cur_fm.cur_states[-1] == FileMng.States.SUB_DER_TYPE and self.ctx.cur_type: if not isinstance(self.ctx.cur_type, str): my_log.debug("exitSubtype_indication1: %s" % self.ctx.cur_type) my_log.debug('cur_const: %s' % self.ctx.cur_const) self.ctx.cur_type.solve_constraint(self.ctx.cur_const) my_log.debug("exitSubtype_indication2: %s" % self.ctx.cur_type) self.ctx.cur_type.solve_based(cur_mark) my_log.debug("exitSubtype_indication3: %s" % self.ctx.cur_type) else: my_log.error("Type error [%s:%s, %s:%s] %s" % (ctx.start.line, ctx.start.column, ctx.stop.line, ctx.stop.column, self.ctx.cur_type )) elif self.ctx.cur_fm.cur_states[-1] == FileMng.States.VAR_TYPE and self.ctx.cur_var: if not isinstance(self.ctx.cur_var, str): self.ctx.cur_var.solve_data_type(cur_mark) self.ctx.cur_var.solve_constraint(self.ctx.cur_const) else: my_log.error("Var error [%s:%s, %s:%s] %s" % (ctx.start.line, ctx.start.column, ctx.stop.line, ctx.stop.column, self.ctx.cur_var )) elif self.ctx.cur_fm.cur_states[-1] == FileMng.States.FIELD_TYPE: self.ctx.cur_field = {'based': cur_mark, 'constraint': self.ctx.cur_const} elif self.ctx.cur_fm.cur_states[-1] == FileMng.States.ARRAY_ELEM: self.ctx.cur_type.solve_elem(cur_mark) if self.ctx.cur_fm.cur_states[-1] in [FileMng.States.SUB_DER_TYPE, FileMng.States.VAR_TYPE, FileMng.States.FIELD_TYPE, FileMng.States.ARRAY_ELEM, ]: self.ctx.cur_const = None self.ctx.cur_range = None self.exit_state([FileMng.States.SUB_DER_TYPE, FileMng.States.VAR_TYPE, FileMng.States.FIELD_TYPE, FileMng.States.ARRAY_ELEM, ], ctx)
def enterPackage_specification(self, ctx): self.ctx.cur_fm.cur_states.append(FileMng.States.PACKAGE) if self.ctx.cur_spec: self.ctx.cur_spec_list.append(self.ctx.cur_spec) self.ctx.cur_spec = AdaSpec( ctx.parser.getTokenStream().tokenSource.inputStream.fileName, self.ctx) self.ctx.cur_spec.uses.update(map(lambda x: x.package, self.ctx.cur_spec_list)) self.ctx.cur_spec.package = cpu.get_texts(ctx.defining_program_unit_name()).upper() if self.ctx.cur_spec_list: self.ctx.cur_spec.package = ".".join([self.ctx.cur_spec_list[-1].package, self.ctx.cur_spec.package]) self.ctx.cur_spec.withs.add(self.ctx.cur_spec_list[0].package) self.ctx.cur_spec.uses.update(self.ctx.cur_fm.uses) self.ctx.cur_spec.withs.update(self.ctx.cur_fm.withs) self.ctx.cur_spec.use_types.update(self.ctx.cur_fm.use_types) my_log.debug("enterPackage_specification: %s" % self.ctx.cur_spec.package) my_log.debug("withs: %s" % self.ctx.cur_spec.withs) my_log.debug("uses: %s" % self.ctx.cur_spec.uses)
def get_spce_list(self, check_dirs, depth=0): depth += 1 my_log.debug('[%s][%s][%s]' % (depth, self.stopped, check_dirs)) if not self.stopped: for dir in check_dirs: vars = self.get_makefile_vars( os.path.join(dir, CsciMng.MAKEFILE), self.check_vars) if CsciMng.SUBDIRS in vars and vars[CsciMng.SUBDIRS]: dirs = re.split('\s+', vars[CsciMng.SUBDIRS]) dirs = list(map(lambda x: os.path.join(dir, x), dirs)) my_log.debug(dirs) if self.stop_dir != dir: for t_dir in dirs: if self.stop_dir and self.stop_dir.startswith( "".join([t_dir, os.path.sep])): dirs = dirs[:dirs.index(t_dir) + 1] break self.get_spce_list(dirs, depth) files = [] if CsciMng.SOURCES1 in vars and vars[CsciMng.SOURCES1]: files = re.split('\s+', vars[CsciMng.SOURCES1]) if CsciMng.SOURCES2 in vars and vars[CsciMng.SOURCES2]: files.extend(re.split('\s+', vars[CsciMng.SOURCES2])) if not files: if os.path.isdir(dir): files = os.listdir(dir) if files: files = list( filter( lambda x: (x.endswith('.a') or x.endswith('.ads')) and not x.endswith('_b.a'), files)) my_log.debug("[%s]%s" % (depth, files)) self.specs.extend( list(map(lambda x: os.path.join(dir, x), files))) if self.stop_dir == dir: self.stopped = True break
def walk_a_field(self, field, is_field=True): my_log.debug("walk_a_field: %s" % field) ft = field.field_type if is_field else field if ft.ttype in [AdaType.DERIVED_TYPE, AdaType.SUBTYPE]: ft2 = copy.deepcopy(ft.based) for attr in [ 'first', 'last', 'size', 'pos', 'end_bit', 'start_bit' ]: if getattr(ft2, attr, None) is None: if hasattr(ft, attr): setattr(ft2, attr, getattr(ft, attr)) elif hasattr(field, attr): setattr(ft2, attr, getattr(field, attr)) ft = ft2 my_log.debug("ttype: %s" % ft.ttype) if ft.name == 'STRING': if is_field: for attr in [ 'first', 'last', 'size', 'pos', 'end_bit', 'start_bit' ]: if getattr(field, attr, None) is None: if hasattr(ft, attr): setattr(field, attr, getattr(ft, attr)) if getattr(field, 'size', None) is None: setattr(field, 'size', (int(field.last) - int(field.first) + 1) * 8) self.walk_a_base_type(field, 'STRING', i_size=field.size or (int(ft.last) - int(ft.first) + 1) * 8) elif ft.ttype == AdaType.RECORD_TYPE: self.pos_stack.append(int(field.pos)) self.name_stack.append(field.name) self.walk_a_record(ft) self.name_stack.pop() self.pos_stack.pop() return elif ft.ttype == AdaType.ARRAY_TYPE: self.pos_stack.append(int(field.pos)) self.name_stack.append(field.name) i_size = getattr(field, 'size', None) if not i_size and getattr(field, 'start_bit', None) is not None and getattr( field, 'end_bit', None) is not None: try: i_size = int(field.end_bit) - int(field.start_bit) + 1 except TypeError: i_size = None self.walk_an_array(ft, i_size=i_size) self.name_stack.pop() self.pos_stack.pop() elif ft.ttype == AdaType.REAL_TYPE: self.walk_a_base_type(field, 'FLOAT', field.size) elif ft.ttype == AdaType.INT_TYPE: self.walk_a_base_type(field, 'INTEGER', field.size) elif ft.ttype == AdaType.ENUM_TYPE: enum_type = '.'.join([ft.package, ft.name]) if enum_type not in self.result['gen_fmt_enums']: enums = {} t_val = 0 for e in ft.items.keys(): enums[ft.items[e].value or str(t_val)] = e t_val += 1 self.result['gen_fmt_enums'][enum_type] = enums self.walk_a_base_type(field, 'INTEGER', field.size, enum_type=enum_type)
def walk_an_array(self, arr, i_size=None): my_log.debug("walk_an_array: %s, %s" % (i_size, arr)) elem_num = 1 array_index = [] try: for index in arr.index_list: for attr in ['first', 'last']: if getattr(index, attr, None) is None: if getattr(index.based, attr, None) is not None: setattr(index, attr, getattr(index.based, attr)) based = index.based while based is not None and based.ttype in [ AdaType.DERIVED_TYPE, AdaType.SUBTYPE ]: based = based.based if based is not None and based.ttype == AdaType.ENUM_TYPE: setattr(index, 'enums', based.enums) if getattr(index, 'first', None) is None: setattr(index, 'first', 0) if getattr(index, 'last', None) is None: setattr(index, 'last', len(based.enums) - 1) if (isinstance(index.first, str) and not index.first.isdigit()) and (isinstance( index.last, str) and not index.last.isdigit()): start = index.enums.index(index.first) last = index.enums.index(index.last) elem_num *= last - start + 1 array_index.append(index.enums[start:last + 1]) my_log.debug("hd1: %s" % array_index) else: start = int(index.first) last = int(index.last) elem_num *= last - start + 1 array_index.append(index.enums[start:last + 1]) my_log.debug("hd2: %s" % array_index) else: start = int(index.first) last = int(index.last) elem_num *= last - start + 1 array_index.append(list(map(str, range(start, last + 1)))) my_log.debug("hd3: %s" % array_index) except TypeError: elem_num = int(arr.last) - int(arr.first) + 1 array_index.append( list(map(str, range(int(arr.first), int(arr.last) + 1)))) my_log.debug("hd4: %s" % array_index) my_log.debug("hd5: %s" % array_index) cur_elem_name = arr.elem.name #array_index_names = list(map(lambda x: '_'.join(x), zip(*array_index))) array_index_names = list( map(lambda x: '_'.join(x), itertools.product(*array_index))) my_log.debug("array: %s" % arr) my_log.debug('array index names: %s' % list(array_index_names)) my_log.debug("elem_num: %s" % elem_num) for i in range(elem_num): for attr in [ 'size', ]: if getattr(arr.elem, attr, None) is None: if hasattr(arr.elem, 'based') and hasattr( arr.elem.based, attr): setattr(arr.elem, attr, getattr(arr.elem.based, attr)) if isinstance(arr.elem.size, str): arr.elem.size = eval( arr.elem.size.replace('STANDARD_TYPES.OCTET', '8').replace('OCTET', '8')) if (arr.elem.size is None or arr.elem.size < 8) and i_size: setattr(arr.elem, 'size', i_size // elem_num) if arr.elem.size is not None: setattr(arr.elem, 'pos', i * arr.elem.size // 8) elif i == 0: setattr(arr.elem, 'pos', 0) my_log.debug( "hd test size: %s, %s, %s, %s" % (arr.elem.size, arr.elem.size_solved, i, arr.elem.pos)) #arr.elem.name = "%s_%s" % (cur_elem_name, i) setattr(arr.elem, 'tmp_name_in_array', array_index_names[i]) self.walk_a_field(arr.elem, is_field=False) delattr(arr.elem, 'tmp_name_in_array') if getattr(arr, 'size', None) is None: if getattr(arr.elem, 'size', None) is not None: setattr(arr, 'size', arr.elem.size * elem_num) else: based = arr.elem while based.ttype in [AdaType.DERIVED_TYPE, AdaType.SUBTYPE] \ and getattr(based, 'based', None) is not None \ and getattr(based, 'size', None) is None: based = based.based if getattr(based, 'size', None) is not None: setattr(arr, 'size', based.size * elem_num) elif i_size: setattr(arr, 'size', i_size) arr.elem.name = cur_elem_name
def get_name(self, f_n): my_log.debug("get_name: %s" % self.name_stack) #return "%s.%s" % (reduce(lambda x, y: ".".join([x, y]), self.name_stack), f_n) if self.name_stack else f_n return f_n
def get_pos(self, f_p): my_log.debug("get_pos: %s" % self.pos_stack) return reduce(lambda x, y: x + y, self.pos_stack) + f_p