From: Chris M. <zm...@us...> - 2000-11-03 23:23:02
|
Update of /cvsroot/kuml/kuml/libkuml/uml/tools In directory slayer.i.sourceforge.net:/tmp/cvs-serv8449/uml/tools Added Files: autogen.awk Log Message: Stage 1 of autogenerator. Stage 2 will include full gen of associations. --- NEW FILE --- BEGIN{ # Separate records at the closing curly bracket RS="};" } # Given a "Namespace::typename string", return the Namespace part # Deals with A::B::typename correctly. :=) function namespace(in_string, pos) { pos = match(in_string, /[A-Za-z:]*::/) return substr(in_string, pos, RLENGTH-2); } # Given a "Namespace::typename" string, return the typename part # Deals with A::B::typename correctly. :=) function typename(in_string, out_str) { out_str = in_string sub(/^[A-Za-z:]*::/, "", out_str) sub(/,$/, "", out_str) return out_str } # Given a "set_attribute(" string, return the attribute part function attr_name(in_string, out_str) { # len = length(in_string) # return substr(in_string, 5, len-5) out_str = in_string sub(/^set_/, "", out_str) sub(/\($/, "", out_str) return out_str } # Given a "attribute()" string, return the attributes name. function method_name_to_attr(in_string, out_str) { out_str = in_string sub(/\(.*/, "", out_str) sub(/^_cxx_/, "", out_str) sub(/_ref$/, "", out_str) return out_str } # Loop through the fields, determining structure. { # Deal with very last record if ($1 == "#endif") exit base = 1 # Skip the include at the top of the file if ($1 == "#ifndef") { top_include = $6 base += 6 } # While there are still comments, skip over them while ($base == "//") { cmmnt = base current_class = $(base + 4) base += 5 } if (current_class ~ /^A[A-Z]/) { class_is_association = 1 } else { class_is_association = 0 } virtual_start = base + 3 virtual_next = virtual_start while ($virtual_next == "virtual") { virtual_next += 3 } method_decl = virtual_next + 2 # For each method declaration for (ind = 1; method_decl < NF; ind++) { ret_type[ind] = method_decl method_name = method_decl + 1 saved_method_name[ind] = method_name # Initialise the string used to build the first line # of the method declaration decl1 = $method_name if ($method_name ~ /\(\)/ ) { has_params[ind] = 0 param_next = method_name } else { has_params[ind] = 1 param_start[ind] = method_name + 1 param_next = param_start[ind] do { if ($param_next == "const") { decl1 = decl1 " " $param_next " " $(param_next+1) " " $(param_next+2) param_next += 3 } else { decl1 = decl1 " " $param_next " " $(param_next+1) param_next += 2 } } while ($param_next != ")") decl1 = decl1 " )" } decl_line1[ind] = decl1 possible_throw = param_next + 1 if ($possible_throw == "throw(") { raises_exceptions[ind] = 1 excpt_start[ind] = possible_throw + 1 excpt_next = excpt_start[ind] while ($excpt_next != ";") { excpt_next++ } method_decl = excpt_next + 1 } else { raises_exceptions[ind] = 0 method_decl = possible_throw } } # end main for loop max_ind = ind -1 } # So now we have: # current_class Name of the current class # full_type The full interface type declaration # class_is_association Boolean # top_include The filename included at the very top of the header file # decl_line1[ind] The first line of a method declaration # max_ind The nuber of methods # (The following mostly hold field numbers) # cmmnt The start of the comment that introduces the class # virtual_start The start of the inheritance part of the class defn # ret_type[ind] Array of method return values # saved_method_name[ind] # has_params[ind] Boolean # param_start[ind] # raises_exceptions[ind] Boolean # excpt_start[ind] { # Output the _impl.h file prefix = "fc_" # Output standard ifndef/define header pattern h_file = current_class "_impl.h" upper_case_class = toupper(current_class) print ("#ifndef __" upper_case_class "_H__") > h_file print ("#define __" upper_case_class "_H__") >> h_file print "" >> h_file # Process superclasses to generate includes virtual_next = virtual_start while ($virtual_next == "virtual") { inherited = virtual_next + 2 if ($inherited ~ /^Ref[A-Z]/) { print "#include \"Reflective_impl.h\"" >> h_file print "" >> h_file } else { if ($inherited ~ /^POA_/) { print "#include " top_include >> h_file print "" >> h_file # Save full type for use in constructor implementation full_type = $inherited sub(/^POA_/, "", full_type) } else { tn = typename($inherited) print ( "#include \"" tn ".h\"" ) >> h_file print "" >> h_file } } virtual_next += 3 } # Output the comment print $cmmnt, $(cmmnt+1), $(cmmnt+2), $(cmmnt+3), $(cmmnt+4) >> h_file # Output start of class declaration print ($base " " $(base+1) " " $(base+2) " " ) >> h_file # Re-process superclasses, outputting them vn = virtual_start while ($vn == "virtual") { print " ", $vn, $(vn+1), $(vn+2) >> h_file vn += 3 } # Process the "{ public:" bit print "{" >> h_file print " public:" >> h_file # If the current class is a Package, output the constructor declaration. if (!class_is_association && (current_class ~ /Package$/ || current_class in all_types)) { print " " current_class "_impl();" >> h_file } if (!class_is_association) { print " ~" current_class "_impl();" >> h_file } # Output the menthod decls for (ind = 1; ind <= max_ind; ind++) { # There are two format output by the idl compiler # based on whether there are any exceptions or not. # I want to mimic this so the diffs wont be too big! if (raises_exceptions[ind]) { print "" >> h_file print " " $ret_type[ind] " " decl_line1[ind] >> h_file print " throw(" >> h_file excpt_next = excpt_start[ind] while ($excpt_next != ";") { print " ", $excpt_next >> h_file excpt_next++ } print " ;" >> h_file } else { print " " $ret_type[ind] " " decl_line1[ind] >> h_file } } print "" >> h_file print " protected:" >> h_file print "" >> h_file for (ind = 1; ind <= max_ind; ind++) { if ( $saved_method_name[ind] ~ /^all_of_class_/ ) { tn = $ret_type[ind] sub(/Set\*$/, "_ptr", tn) attr = $saved_method_name[ind] sub(/\(.*/, "", attr) print " static list<" tn "> " prefix attr ";" >> h_file # Store reference for use in determining constructor of *next* class class = current_class sub(/Class$/, "", class) all_classes[class] = attr } if ( $saved_method_name[ind] ~ /^all_of_type_/ ) { tn = $ret_type[ind] sub(/Set\*$/, "_ptr", tn) attr = $saved_method_name[ind] sub(/\(.*/, "", attr) print " static list<" tn "> " prefix attr ";" >> h_file # Store reference for use in determining destructor of *next* class class = current_class sub(/Class$/, "", class) all_types[class] = attr } } # Generate the private members. print "" >> h_file print " private:" >> h_file print "" >> h_file for (ind = 1; ind <= max_ind; ind++) { # Process all the set_ methods. if ( $saved_method_name[ind] ~ /^set_/ ) { attr = attr_name($saved_method_name[ind]) # Find the type of the parameter (there's only one in set_ methods) ps = param_start[ind] if ($ps == "const") param_type = ps+1 else param_type = ps # Generate a private attribute based on the type of param passed if ( $param_type ~ /Set\&$/ ) { tn = $param_type sub(/Set\&$/, "_ptr", tn) print " list<" tn "> " prefix attr ";" >> h_file } else { if ( $param_type ~ /UList\&$/ ) { tn = $param_type sub(/UList\&$/, "_ptr", tn) print " list<" tn "> " prefix attr ";" >> h_file } else { if ( $param_type ~ /_ptr$/ ) { print " " $param_type " " prefix attr ";" >> h_file } else { if ($param_type == "char*") { print " CORBA::String_var " prefix attr ";" >> h_file } else { pt = $param_type sub(/\&$/, "", pt) print " " pt " " prefix attr ";" >> h_file } } } } } # end of set_ methods # Deal with factory methods. if ( $saved_method_name[ind] ~ /_ref\(\);$/ ) { attr = $saved_method_name[ind] sub(/_ref\(\);$/, "", attr) retv = $ret_type[ind] print " " retv " " prefix attr ";" >> h_file } } # end of for loop # Print the field separator print "" >> h_file print "};" >> h_file print "" >> h_file print "#endif" >> h_file } # # C FILE # { # Output the _impl.cc file cc_file = current_class "_impl.cc" # Include the <class>_impl.h file h_incl_file = current_class "_impl" includes[h_incl_file] = 1 # If this class is a class proxy class (i.e. <class>Class) or a Factory, # we probably have a create_<class> method # which needs to include the header file defining the returned type. if ( current_class ~ /[A-Za-z]+Class/ || current_class ~ /Factory/ ) { for (ind = 1; ind <= max_ind; ind++) { if ($saved_method_name[ind] ~ /^create_/ ) { attr = typename($ret_type[ind]) sub(/_ptr$/, "_impl", attr) includes[attr] = 1 } } } include_list_ops = 0 if (current_class in all_classes || current_class in all_types) { include_list_ops = 1 } # If any of the methods return a set, include set ops header files. for (ind = 1; ind <= max_ind; ind++) { if ( $ret_type[ind] ~ /Set\*$/ || $ret_type[ind] ~ /UList\*$/ ) { include_list_ops = 1 break } } # Add includes for Package required by constructor. if (current_class ~ /Package$/ ) { for (ind = 1; ind <= max_ind; ind++) { if ($saved_method_name[ind] ~ /_ref\(\);/) { rt = typename($ret_type[ind]) sub(/_ptr/, "_impl", rt) includes[rt] = 1 } } } # Output the calculated includes. first_pass = 1 for (incs in includes) { if (first_pass) { print "#include \"" incs ".h\"" > cc_file first_pass = 0 } else { print "#include \"" incs ".h\"" >> cc_file } } if (include_list_ops) { print "#include \"copy_to_iseq.h\"" >> cc_file print "#include \"list_ops.h\"" >> cc_file } # Cleanup delete includes # Output the comment print "" >> cc_file print $cmmnt, $(cmmnt+1), $(cmmnt+2), $(cmmnt+3), $(cmmnt+4) >> cc_file print "" >> cc_file for (ind = 1; ind <= max_ind; ind++) { if ( $saved_method_name[ind] ~ /^all_of_type_/ || $saved_method_name[ind] ~ /^all_of_class_/ ) { # $saved_method_name[ind] ~ /^all_[a-z_]*_links()/ ) { tn = $ret_type[ind] if (class_is_association) { sub(/LinkSet\*$/, "_ptr", tn) } else { sub(/Set\*$/, "_ptr", tn) } attr = $saved_method_name[ind] sub(/\(.*/, "", attr) print "list<" tn "> " \ current_class "_impl::" prefix attr ";\n" >> cc_file } } # If the current class is a package, output the constructor implementation. if (current_class ~ /Package$/) { print current_class "_impl::" current_class "_impl() {" >> cc_file for (ind = 1; ind <= max_ind; ind++) { rt = typename($ret_type[ind]) sub(/_ptr$/, "", rt) attr = method_name_to_attr($saved_method_name[ind]) print " " rt "_impl* local_" attr " = new " rt "_impl;" >> cc_file print " " prefix attr " = local_" attr "->_this();" >> cc_file } print "};\n" >> cc_file } else { # If need to add class to <class>Class sequence. if (current_class in all_types) { print current_class "_impl::" current_class "_impl() {" >> cc_file print " " prefix all_types[current_class] ".push_back(" >> cc_file print " " full_type "::_duplicate(_this()));" >> cc_file print "};\n" >> cc_file } } # Output the destructor implementation. if (!class_is_association) { print current_class "_impl::~" current_class "_impl() {" >> cc_file for (ind = 1; ind <= max_ind; ind++) { rt = $ret_type[ind] if (rt ~ /_ptr$/ && current_class !~ /Factory$/ && $saved_method_name[ind] !~ /^create_/) { sub(/_ptr$/, "", rt) attr = method_name_to_attr($saved_method_name[ind]) print " if (!CORBA::is_nil(" prefix attr "))" >> cc_file print " CORBA::release(" prefix attr ");" >> cc_file } if (rt ~ /Set\*/) { # need another template to free set. } } if (current_class in all_types) { print " remove_list_elem(" \ prefix all_types[current_class] \ ", _this());" >> cc_file } if (current_class in all_classes) { print " remove_list_elem(" \ prefix all_classes[current_class] \ ", _this());" >> cc_file } print "};\n" >> cc_file } # Output the method declaration part. for (ind = 1; ind <= max_ind; ind++) { print $ret_type[ind] >> cc_file decl1 = decl_line1[ind] sub(/;$/, "", decl1) print current_class "_impl::" decl1 >> cc_file if (raises_exceptions[ind]) { print " throw(" >> cc_file excpt_next = excpt_start[ind] while ($excpt_next != ";") { print " " $excpt_next >> cc_file excpt_next++ } } # Holy moley. You've followed things so far? # Weell, now things get INTERESTING... # THE IMPLEMENTATIONS -> matched = 0 if (!class_is_association) { if ($saved_method_name[ind] ~ /^all_of_type_/ || $saved_method_name[ind] ~ /^all_of_class_/ || $ret_type[ind] ~ /Set\*$/ || $ret_type[ind] ~ /UList\*$/ ) { matched++ name = prefix $saved_method_name[ind] sub(/\(.*/, "", name) tn = $ret_type[ind] sub(/\*$/, "", tn) print "{ " tn "_var seq = new " tn ";" >> cc_file print " copy_to_seq(seq, " name ");" >> cc_file print " return seq._retn();" >> cc_file } if ( $saved_method_name[ind] ~ /^create_/ ) { matched++ rc = typename($ret_type[ind]) sub(/_ptr$/, "", rc) print "{ " rc "_impl* impl = new " rc "_impl;" >> cc_file print " " $ret_type[ind] " retval = impl->_this();" >> cc_file if (has_params[ind]) { # Loop through parameters, setting attributes. param_next = param_start[ind] do { if ($param_next == "const") { attr = $(param_next+2) param_next += 3 } else { attr = $(param_next+1) param_next += 2 } sub(/,$/, "", attr) print " impl->set_" attr "(" attr ");" >> cc_file } while ($param_next != ")") } # end has_params for (ind2 = 1; ind2 <= max_ind; ind2++) { if ($saved_method_name[ind2] ~ /^all_of_class_/) { attr = $saved_method_name[ind2] sub(/\(.*/, "", attr) rt = $ret_type[ind] sub(/_ptr$/, "", rt) print " " prefix attr ".push_back(" \ rt "::_duplicate(retval));" >> cc_file } } print " return retval;" >> cc_file } if ($saved_method_name[ind] ~ /^set_/ ) { matched++ attr = attr_name($saved_method_name[ind]) ps = param_start[ind] # if not const char* or a simple type from the DataTypes package.. if ( $ps == "const" && $(ps+1) != "char*" && $(ps+1) !~ /^Foundation::DataTypes::/ ) { print "{ set_list_from_seq(" prefix attr ", new_value);" >> cc_file } else { print "{ " prefix attr " = new_value;" >> cc_file } } if ($saved_method_name[ind] ~ /^unset_/ ) { matched++ # Work out the attributes name from method name attr = $saved_method_name[ind] sub(/^unset_/, "", attr) sub(/\(.*/, "", attr) # Yikes. Look at the previous set_methods parameter. tn = $param_start[ind-1] # Deal with unset_constrained_element if (tn == "const") { print "{ " prefix attr ".clear();" >> cc_file } else { sub(/_ptr$/, "", tn) print "{ if (!CORBA::is_nil(" prefix attr \ ")) CORBA::release(" prefix attr ");" >> cc_file print " " prefix attr " = " tn "::_nil();" >> cc_file } } if ($saved_method_name[ind] ~ /^add_/ ) { matched++ attr = $saved_method_name[ind] if (attr ~ /_before\($/) { sub(/^add_/, "", attr) sub(/_before\($/, "", attr) print "{ add_list_elem_before(" prefix attr \ ", new_element, before_element);" >> cc_file } else { # Work out the attributes name from method name sub(/^add_/, "", attr) sub(/\(.*/, "", attr) print "{ add_list_elem(" prefix attr ", new_element);" >> cc_file } } if ($saved_method_name[ind] ~ /^modify_/ ) { matched++ # Work out the attributes name from method name attr = $saved_method_name[ind] sub(/^modify_/, "", attr) sub(/\(.*/, "", attr) print "{ replace_list_elem(" prefix attr \ ", old_element, new_element);" >> cc_file } if ($saved_method_name[ind] ~ /^remove_/ ) { matched++ # Work out the attributes name from method name attr = $saved_method_name[ind] sub(/^remove_/, "", attr) sub(/\(.*/, "", attr) print "{ remove_list_elem(" prefix attr \ ", old_element);" >> cc_file } if ($saved_method_name[ind] ~ /_ref\(\);/ ) { matched++ rt = $ret_type[ind] sub(/_ptr$/, "", rt) attr = $saved_method_name[ind] sub(/_ref\(\);$/, "", attr) print "{ return " rt "::_duplicate(" prefix attr ");" >> cc_file # print "{ return " prefix attr ";" >> cc_file } # If the *next* method is a set_ one and # this one refers to the same attr # i.e. we have the one that returns the attrs value if (!matched && $saved_method_name[ind+1] ~ /^set_/ ) { ret_name = method_name_to_attr($saved_method_name[ind]) set_name = $saved_method_name[ind+1] sub(/^set_/, "", set_name) sub(/\(.*/, "", set_name) if ( ret_name == set_name ) { matched++ if ($ret_type[ind] == "char*") { print "{ CORBA::String_var str;" >> cc_file print " str = " prefix ret_name ";" >> cc_file print " return str._retn();" >> cc_file } else { if ( $ret_type[ind] ~ /\*$/ ) { rt = $ret_type[ind] sub(/\*$/, "", rt) print "{ " $ret_type[ind] " retv = new " rt ";" >> cc_file print " *retv = " prefix ret_name ";" >> cc_file print " return retv;" >> cc_file } else { print "\{ return " prefix ret_name ";" >> cc_file } } } } } # else class is an association if (!matched) { print "{ mico_throw(::CORBA::NO_IMPLEMENT());" >> cc_file } print "}" >> cc_file print "" >> cc_file } # end of method for loop } # end section { delete ret_type delete saved_method_name delete has_params delete param_start delete decl_line1 delete raises_exceptions delete excpt_start } |