66 : m_Type(eType_Primitive), m_IsTemplate(
false), m_DoStoreArg(
false)
68 if( var_name.empty() ) {
69 throw runtime_error(
"No var_name given for CTraversalNode");
100 : m_Type(eType_Primitive), m_IsTemplate(
false), m_DoStoreArg(
false)
125 while( parent_asn_node ) {
128 string parent_class_name = parent_type_strings->
GetCType(parent_ns);
163 throw runtime_error(
"possible bug in code generator: unknown type for '" +
m_TypeName +
"'");
186 traversal_output_file <<
"template< typename " <<
m_InputClassName <<
" >" << endl;
188 traversal_output_file <<
"void ";
190 traversal_output_file << func_class_name <<
"::" ;
194 traversal_output_file <<
m_FuncName <<
"( void )";
203 traversal_output_file <<
";" << endl;
207 traversal_output_file << endl;
212 traversal_output_file <<
" CRef<CSeq_feat> raw_ref( &arg0_raw );" << endl;
213 traversal_output_file <<
" CSeq_feat_EditHandle efh;" << endl;
214 traversal_output_file << endl;
215 traversal_output_file <<
" CRef<CSeq_feat> new_feat;" << endl;
216 traversal_output_file << endl;
217 traversal_output_file <<
" try {" << endl;
218 traversal_output_file <<
" // Try to use an edit handle so we can update the object manager" << endl;
219 traversal_output_file <<
" efh = CSeq_feat_EditHandle( m_Scope.GetSeq_featHandle( arg0_raw ) );" << endl;
220 traversal_output_file <<
" new_feat.Reset( new CSeq_feat );" << endl;
221 traversal_output_file <<
" new_feat->Assign( arg0_raw );" << endl;
222 traversal_output_file <<
" } catch(...) {" << endl;
223 traversal_output_file <<
" new_feat.Reset( &arg0_raw );" << endl;
224 traversal_output_file <<
" }" << endl;
225 traversal_output_file << endl;
226 traversal_output_file <<
" CSeq_feat &arg0 = *new_feat;" << endl;
227 traversal_output_file << endl;
233 traversal_output_file << endl;
238 traversal_output_file <<
" " << (*func_iter)->GetUserFuncName() <<
"( arg0";
240 _ASSERT( (*extra_arg_iter)->GetDoStoreArg() );
241 traversal_output_file <<
", *" << (*extra_arg_iter)->GetStoredArgVariable();
243 ITERATE( vector<string>, constant_arg_iter, (*func_iter)->GetConstantArgs() ) {
244 traversal_output_file <<
", " << *constant_arg_iter;
246 traversal_output_file <<
" );" << endl;
259 traversal_output_file <<
" switch( arg0.Which() ) {" << endl;
261 string case_name = (*child_iter)->GetVarName();
262 case_name[0] = (char)
toupper(case_name[0]);
264 traversal_output_file <<
" case " <<
m_InputClassName <<
"::e_" << case_name <<
":" << endl;;
265 string argString =
string(
"arg0.Set") + case_name +
"()";
267 traversal_output_file <<
" break;" << endl;
269 traversal_output_file <<
" default:" << endl;
270 traversal_output_file <<
" break;" << endl;
271 traversal_output_file <<
" }" << endl;
277 string case_name = (*child_iter)->GetVarName();
278 case_name[0] = (char)
toupper(case_name[0]);
280 traversal_output_file <<
" if( arg0.IsSet" << case_name <<
"() ) {" << endl;;
281 string argString =
string(
"arg0.Set") + case_name +
"()";
283 traversal_output_file <<
" }" << endl;
291 string case_name = child_call->GetVarName();
293 case_name[0] = (char)
toupper(case_name[0]);
300 const bool needs_isset = ( needs_set &&
304 traversal_output_file <<
" if( arg0.IsSet() ) {" << endl;
307 string argString = ( needs_set ?
"arg0.Set()" :
"arg0" );
311 traversal_output_file <<
" }" << endl;
319 string case_name = child_call->GetVarName();
321 case_name[0] = (char)
toupper(case_name[0]);
324 traversal_output_file <<
" NON_CONST_ITERATE( " << input_class_prefix <<
m_InputClassName <<
", iter, arg0 ) { " << endl;
326 int levelsOfDereference = 1;
328 ++levelsOfDereference;
331 ++levelsOfDereference;
333 string argString =
string(levelsOfDereference,
'*') +
"iter";
335 traversal_output_file <<
" }" << endl;
339 throw runtime_error(
"Unknown node type. Probably bug in code generator.");
345 traversal_output_file <<
" " << (*a_func_iter)->GetUserFuncName() <<
"( arg0";
347 _ASSERT( (*extra_arg_iter)->GetDoStoreArg() );
348 traversal_output_file <<
", *" << (*extra_arg_iter)->GetStoredArgVariable();
350 ITERATE( vector<string>, constant_arg_iter, (*a_func_iter)->GetConstantArgs() ) {
351 traversal_output_file <<
", " << *constant_arg_iter;
353 traversal_output_file <<
" );" << endl;
358 traversal_output_file << endl;
364 traversal_output_file << endl;
365 traversal_output_file <<
" if( efh ) {" << endl;
366 traversal_output_file <<
" efh.Replace(arg0);" << endl;
367 traversal_output_file <<
" arg0_raw.Assign( arg0 );" << endl;
368 traversal_output_file <<
" }" << endl;
369 traversal_output_file << endl;
373 traversal_output_file <<
"} // end of " <<
m_FuncName << endl;
374 traversal_output_file << endl;
382 TVarNameToCallersMap var_name_to_callers_map;
384 var_name_to_callers_map[(*caller_iter)->GetVarName()].push_back( (*caller_iter)->GetNode() );
390 if( var_name_to_callers_map.size() < 2 ) {
394 ITERATE( TVarNameToCallersMap, mapping_iter, var_name_to_callers_map ) {
395 const string &var_name = mapping_iter->first;
396 const TNodeVec &callers_for_this_var_name = mapping_iter->second;
401 new_node->
AddCaller( var_name, *caller_to_add_iter );
411 const vector<string> &constant_args )
412 : m_UserFuncName( user_func_name ), m_ExtraArgNodes(extra_arg_nodes),
413 m_ConstantArgs(constant_args)
416 (*extra_arg_iter)->m_ReferencingUserCalls.push_back(
CRef<CUserCall>(
this) );
424 x_DepthFirst( callback, node_path, nodesSeen, traversal_opts );
429 static const string kSequence =
"Sequence";
430 static const string kChoice =
"Choice";
431 static const string kPrimitive =
"Primitive";
432 static const string kNull =
"Null";
433 static const string kEnum =
"Enum";
434 static const string kReference =
"Reference";
435 static const string kUniSequence =
"UniSequence";
437 static const string kUnknown =
"???";
494 if( *node_iter == node_to_merge_into_this->
Ref() ) {
502 AddCaller( (*their_caller)->GetVarName(), (*their_caller)->GetNode() );
513 node_to_merge_into_this->
Clear();
524 (*caller_iter)->GetNode()->m_Callees.erase( node_ref );
531 (*callee_iter)->GetNode()->m_Callers.erase( node_ref );
546 node_path.push_back(
Ref() );
548 const bool post_traversal =
550 const bool allow_cycles =
553 const bool seen_before = ( nodesSeen.find(
Ref()) != nodesSeen.end() );
556 if( seen_before && (post_traversal || ! allow_cycles) ) {
557 node_path.pop_back();
565 if( ! post_traversal ) {
566 if( ! callback.
Call( *
this, node_path, is_cyclic ) ) {
567 node_path.pop_back();
572 const bool up_callers =
577 nodesSeen.insert(
Ref() );
579 (*child_iter)->GetNode()->x_DepthFirst( callback, node_path, nodesSeen, traversal_opts );
581 nodesSeen.erase(
Ref() );
584 if( post_traversal ) {
586 callback.
Call( *
this, node_path, is_cyclic );
589 node_path.pop_back();
596 traversal_output_file <<
" " << child->
m_FuncName <<
"();" << endl;
599 traversal_output_file <<
" _ASSERT( sizeof(int) == sizeof(" << arg <<
") );" << endl;
600 traversal_output_file <<
" // the casting, etc. is a hack to get around the fact that we sometimes use TSeqPos " << endl;
601 traversal_output_file <<
" // instead of int, but we can't tell where by looking at the .asn file." << endl;
602 traversal_output_file <<
" " << child->
m_FuncName <<
"( *(int*)&" << arg <<
" );" << endl;
604 traversal_output_file <<
" " << child->
m_FuncName <<
"( " << arg <<
" );" << endl;
622 string::iterator pos = type_name.begin();
623 while( pos != type_name.end() ) {
624 string::iterator next_bad_char = find_if( pos, type_name.end(),
CIsNotAlnum() );
627 if( next_bad_char != type_name.end() ) {
631 pos = find_if( next_bad_char, type_name.end(),
CIsAlnum() );
673 string::size_type last_underscore =
result->m_FuncName.find_last_of(
"_");
674 if( string::npos == last_underscore ) {
675 last_underscore =
result->m_FuncName.length();
678 result->m_FuncName.resize( last_underscore );
682 (*callee_iter)->GetNode()->AddCaller( (*callee_iter)->GetVarName(),
result );
690 static const string kObjectsStr =
"objects";
692 string::size_type objects_pos = asn_file_name.find( kObjectsStr );
693 string::size_type slash_after_objects = objects_pos + kObjectsStr.length();
694 string::size_type last_backslash_pos = asn_file_name.find_last_of(
"\\/");
695 if( (objects_pos == string::npos) ||
696 (slash_after_objects >= asn_file_name.length() ) ||
697 ( asn_file_name[slash_after_objects] !=
'\\' && asn_file_name[slash_after_objects] !=
'/') ||
698 ( last_backslash_pos == string::npos ) ||
699 ( last_backslash_pos <= slash_after_objects ) )
702 msg +=
"All ASN file names must contain 'objects' in their path so ";
703 msg +=
"we can extract the location of .hpp files in the ";
704 msg +=
"include/objects directory. Example: C:/foo/bar/objects/seqloc/seqloc.asn. ";
705 msg +=
"You gave this file name: '" + asn_file_name +
"'";
706 throw runtime_error(msg);
712 asn_file_name.begin() + slash_after_objects + 1,
713 asn_file_name.begin() + last_backslash_pos );
723 const ncbi::CRef<CNodeCall> ref1,
const ncbi::CRef<CNodeCall> ref2)
const
728 int var_comp =
NStr::Compare( ref1->GetVarName(), ref2->GetVarName() );
729 if( var_comp != 0 ) {
730 return ( var_comp < 0 );
733 return ( ref1->GetNode() < ref2->GetNode() );
bool IsEnumType(void) const
virtual AutoPtr< CTypeStrings > GetFullCType(void) const
string GetFullName(void) const
const CDataType * GetParentType(void) const
bool IsReference(void) const
const string & GetSourceFileName(void) const
bool IsContainer(void) const
bool IsStdType(void) const
virtual const CDataType * Resolve(void) const override
virtual bool Call(CTraversalNode &node, const TNodeVec &node_path, ECallType is_cyclic)=0
CUserCall(const std::string &user_func_name, const TNodeVec &extra_arg_nodes, const vector< string > &constant_args)
string x_ExtractIncludePathFromFileName(const string &asn_file_name)
void x_GenerateChildCall(CNcbiOstream &traversal_output_file, CRef< CTraversalNode > child, const string &arg)
std::string m_IncludePath
const string GetStoredArgVariable(void) const
@ fTraversalOpts_UpCallers
@ fTraversalOpts_AllowCycles
void x_LoadDataFromASNNode(CDataType *asn_node)
static int ms_FuncUniquerInt
TUserCallVec m_PostCalleesUserCalls
CRef< CTraversalNode > x_CloneWithoutCallers(const string &var_name) const
const string & GetTypeAsString(void) const
void x_DepthFirst(CDepthFirstCallback &callback, TNodeVec &node_path, TNodeSet &nodesSeen, TTraversalOpts traversal_opts)
void SplitByVarName(void)
static void x_MergeNames(string &result, const string &name1, const string &name2)
TUserCallVec m_PreCalleesUserCalls
@ eGenerateMode_Prototypes
@ eGenerateMode_Definitions
std::vector< CRef< CUserCall > > TUserCallVec
static CRef< CTraversalNode > Create(CRef< CTraversalNode > caller, const string &var_name, CDataType *asn_node)
const std::string & GetInputClassName(void) const
TUserCallVec m_ReferencingUserCalls
@ eMergeNameAllowed_AllowNameChange
std::vector< CRef< CTraversalNode > > TNodeVec
std::string m_InputClassName
void RemoveXFromFuncName(void)
void GenerateCode(const string &func_class_name, CNcbiOstream &traversal_output_file, EGenerateMode generate_mode)
std::set< CRef< CNodeCall >, SRefNodeCallLessthan > TNodeCallSet
void x_TemplatizeType(std::string &type_name)
unsigned int TTraversalOpts
void AddPostCalleesUserCall(CRef< CUserCall > user_call)
void DepthFirst(CDepthFirstCallback &callback, TTraversalOpts traversal_opts=0)
CRef< CTraversalNode > Ref()
std::map< CDataType *, CRef< CTraversalNode > > TASNNodeToNodeMap
static TASNNodeToNodeMap m_ASNNodeToNodeMap
void AddPreCalleesUserCall(CRef< CUserCall > user_call)
static set< CTraversalNode * > * ms_EveryNode
std::set< CRef< CTraversalNode > > TNodeSet
void AddCaller(const std::string &var_name, CRef< CTraversalNode > caller)
bool Merge(CRef< CTraversalNode > node_to_merge_into_this, EMergeNameAllowed merge_name_allowed=eMergeNameAllowed_AllowNameChange)
virtual string GetCType(const CNamespace &ns) const =0
virtual const CNamespace & GetNamespace(void) const
iterator_bool insert(const value_type &val)
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
TObjectType * GetPointerOrNull(void) THROWS_NONE
Get pointer value.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
static SIZE_TYPE FindNoCase(const CTempString str, const CTempString pattern, SIZE_TYPE start, SIZE_TYPE end, EOccurrence which=eFirst)
Find the pattern in the specified range of a string using a case insensitive search.
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
static string & Replace(const string &src, const string &search, const string &replace, string &dst, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
static int Compare(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2, ECase use_case=eCase)
Compare of a substring with another string.
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
const char *const kEmptyCStr
Empty "C" string (points to a '\0').
static string & ToLower(string &str)
Convert string to lower case – string& version.
double value_type
The numeric datatype used by the parser.
bool operator()(const char &ch)
bool operator()(const char &ch)
bool operator()(const CRef< CNodeCall > ref1, const CRef< CNodeCall > ref2) const
static const char * kUnknown