📄 defs.py
字号:
if is_array_declarator: stream.out(template.exception_array_declarator, memtype = memtype, cxx_id = cxx_id, dims = dims_string, private_prefix = config.state['Private Prefix']) stream.out(template.exception_member, memtype = memtype, cxx_id = cxx_id, dims = dims_string) # deal with ctor args ctor_args = [] for m in node.members(): memberType = types.Type(m.memberType()) d_memberType = memberType.deref() for d in m.declarators(): decl_dims = d.sizes() is_array_declarator = decl_dims != [] ctor_arg_type = memberType.op(types.IN, environment) # sequences are not passed by reference here if d_memberType.sequence(): if memberType.typedef(): ctor_arg_type = "const " + id.Name(memberType.type().decl().scopedName()).unambiguous(environment) else: ctor_arg_type = "const " + memberType.sequenceTemplate(environment) elif d_memberType.typecode(): ctor_arg_type = "CORBA::TypeCode_ptr" ident = d.identifier() cxx_id = id.mapID(ident) if is_array_declarator: ctor_arg_type = "const " + config.state['Private Prefix'] +\ "_" + cxx_id ctor_args.append(ctor_arg_type + " i_" + cxx_id) ctor = "" if ctor_args != []: ctor = cxx_exname + "(" + string.join(ctor_args, ", ") + ");" if no_members: inline = "inline " body = "{ }" alignedSize = "" else: inline = "" body = ";" alignedSize = "size_t _NP_alignedSize(size_t) const;" # output the main exception declaration stream.out(template.exception, name = cxx_exname, Other_IDL = Other_IDL, members = members, constructor = ctor, alignedSize = alignedSize, inline = inline, body = body) self.__insideClass = insideClass # Typecode and Any if config.state['Typecode']: qualifier = const_qualifier(self.__insideModule, self.__insideClass) stream.out(template.typecode, qualifier = qualifier, name = cxx_exname) def visitUnion(node): ident = node.identifier() cxx_id = id.mapID(ident) outer_environment = id.lookup(node) environment = outer_environment.enter(ident) scope = environment.scope() insideClass = self.__insideClass self.__insideClass = 1 switchType = types.Type(node.switchType()) d_switchType = switchType.deref() #################################################################### # in the case where there is no default case and an implicit default # member, choose a discriminator value to set. Note that attempting # to access the data is undefined def chooseArbitraryDefault(switchType = switchType, values = ast.allCaseLabelValues(node), environment = environment): # dereference the switch_type (ie if CASE <scoped_name>) switchType = switchType.deref() # for integer types, find the lowest unused number def min_unused(start, used = values): x = start while x in used: x = x + 1 return x kind = switchType.type().kind() if switchType.integer(): (low, high) = ast.integer_type_ranges[kind] s = switchType.literal(min_unused(low+1)) return s # for other types, first compute the set of all legal values # (sets are all fairly small) elif kind == idltype.tk_char: all = map(chr, range(0, 255)) elif kind == idltype.tk_boolean: all = [0, 1] elif kind == idltype.tk_enum: all = switchType.type().decl().enumerators() else: util.fatalError("Failed to generate a default union " +\ "discriminator value") # remove all those values which are already in use to leave # a set of possible unused values possibles = util.minus(all, values) # return the first one for simplicity return switchType.literal(possibles[0], environment) # ############################################################### # does the IDL union have any default case? # It'll be handy to know which case is the default one later- # so add a new attribute to mark it ast.markDefaultCase(node) hasDefault = ast.defaultCase(node) != None # CORBA 2.3 C++ Mapping 1-34 # "A union has an implicit default member if it does not have # a default case and not all permissible values of the union # discriminant are listed" exhaustive = ast.exhaustiveMatch(switchType, ast.allCaseLabelValues(node)) implicitDefault = not hasDefault and not exhaustive if types.variableDecl(node): fixed = "Variable" else: fixed = "Fix" def Other_IDL(stream = stream, node = node): # deal with constructed switch type if node.constrType(): node.switchType().decl().accept(self) # deal with children defined in this scope for n in node.cases(): if n.constrType(): n.caseType().decl().accept(self) # create the default constructor body def default_constructor(stream = stream, implicitDefault = implicitDefault, hasDefault = hasDefault, choose = chooseArbitraryDefault): if implicitDefault: stream.out(template.union_constructor_implicit) elif hasDefault: stream.out(template.union_constructor_default, default = choose()) return def ctor_cases(stream = stream, node = node, switchType = switchType, environment = environment, exhaustive = exhaustive): for c in node.cases(): for l in c.labels(): if l.default(): continue discrimvalue = switchType.literal(l.value(), environment) name = id.mapID(c.declarator().identifier()) stream.out(template.union_ctor_case, discrimvalue = discrimvalue, name = name) # Booleans are a special case (isn't everything?) booleanWrap = switchType.boolean() and exhaustive if booleanWrap: stream.out(template.union_ctor_bool_default) else: stream.out(template.union_ctor_default) return # create the copy constructor and the assignment operator # bodies def copy_constructor(stream = stream, exhaustive = exhaustive, node = node, ctor_cases = ctor_cases): if not exhaustive: # grab the default case default = "" for c in node.cases(): if c.isDefault: case_id = c.declarator().identifier() cxx_case_id = id.mapID(case_id) default = cxx_case_id + "(_value._pd_" + cxx_case_id + ");" stream.out(template.union_ctor_nonexhaustive, default = default, cases = ctor_cases) else: stream.out(template.union_ctor_exhaustive, cases = ctor_cases) return # do we need an implicit _default function? def implicit_default(stream = stream, choose = chooseArbitraryDefault, implicitDefault = implicitDefault): if implicitDefault: stream.out(template.union_implicit_default, arbitraryDefault = choose()) return # The body of the union _d(_value) function generated here def _d_fn(stream = stream, node = node, switchType = switchType, implicitDefault = implicitDefault, environment = environment): # The plan: # * Check the _pd__initialised flag is set, else throw BAD_PARAM # * Check for the simple case where _value == _pd__d and return # * Have a nested switch, the outer switch is keyed on the current # discriminator value and the inner one is the requested new value # # Possibilities: # * Could perform some code minimisation eg for the case # union foo switch(boolean){ # case TRUE: # case FALSE: # T bar; # }; # This is equivalent to a single default: case and no switch is # required. # Make sure we don't output a switch with no cases (if there is a # one-to-one mapping of labels to cases) need_switch = 0 # Need to fill in a default case only if the union has none itself outer_has_default = 0 cases = output.StringStream() # keep track of which cases have been done cases_done = [] # Produce a set of "case <foo>: goto fail;" for every label # except those in an exception list def fail_all_but(exceptions, node = node, cases = cases, switchType = switchType, environment = environment): for c in node.cases(): for l in c.labels(): if l not in exceptions: cases.out("case @label@: goto fail;", label = switchType.literal(l.value(), environment)) # switch (currently active case){ # outer_has_default = 0 # only mention default: once for c in node.cases(): need_switch = 1 # If the currently active case has only one non-default label, # then the only legal action is to set it to its current value. # We've already checked for this in an if (...) statement before # here. if len(c.labels()) == 1 and not c.labels()[0].default(): cases.out("case @label@: goto fail;", label = switchType.literal(c.labels()[0].value(), environment)) continue # output one C++ case label for each IDL case label # case 1: # case 2: # default: this_case_is_default = 0 for l in c.labels(): if l.default(): this_case_is_default = 1 outer_has_default = 1 cases.out("default:") continue cases.out("case @label@:", label = switchType.literal(l.value(), environment)) # switch (case to switch to){ # cases.inc_indent() cases.out("switch (_value){\n") cases.inc_indent() inner_has_default = 0 # If we currently are in the default case, fail all attempts # to switch cases. if this_case_is_default: fail_all_but(c.labels()) cases.out("default: _pd__d = _value; return;") cases.dec_indent() cases.out("}\n") cases.dec_indent() continue # This is not the default case, all possibilities have associated # UnionCaseLabels for l in c.labels(): cases.out("case @label@: _pd__d = @label@; return;", label = switchType.literal(l.value(), environment)) cases.out("default: goto fail;") cases.dec_indent() cases.out("}\n") cases.dec_indent()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -