Let's assume that you have already read a STAR file into memory
using yyparse()
as shown in the
main example. This star file is pointed to by the variable
called AST
To search for a tag, use the method searchByTag()
.
This is a member function of ASTnode
, so you can be
assured that it exists at all levels of the star file tree.
List<ASTnode*> *results; results = AST->searchByTag( "_Author_name" ); Write some code here to look at the results list to see what's in it, and do whatever you wanted to do with the matches that were found. // You must always delete the list returned by the search // function when you are done with it delete results;At this point,
results
is a list of all the hits
that were returned by searchByTag
. All the
searching functions are designed to return a List
of hits rather than one single hit, since they could be used
in places where there are multiple matched items. For example,
in this code it is perfectly possible to find multiple tags with
the name "_Author_name" in different save frames, since we are
searching the contents of the entire star file.
Now that we have a list of all the matches to "_Author_name", we can walk through them all and do whatever it was that was intended by this code. (Note, see list.h for a list of all the primitives that can be performed on the List template class):
List<ASTnode*> *results; results = AST->searchByTag( "_Author_name" ); for( results->Reset() ; ! results->AtEnd() ; results->Next() ) { ASTnode *thisOne = results->Current(); ... Now do whatever you wanted to do with thisOne ... } // You must always delete the list returned by the search // function when you are done with it delete results;
But we have a problem here, and that is that all we have in the
list of matches are pointers to the generic type ASTnode
.
What if we were expecting to get a DataItemNode
and we
wanted to only act on those hits that were DataItemNode
s?
(In other words, we don't want to operate on any matches we found
inside a loop.)
This is where the self-awareness of the starlib classes comes in.
All the classes in starlib are aware of what their own types are.
(See the functions in astnode.h
for explanations of
the functions used here.) Therefore it is possible to query the
matched nodes and ask them what they are. Also, each node is aware
of what STAR file element it is inside of. (In other words, what
its parent is in the star file tree). These two things combined
can be used to determine what kind of thing the match was found
inside of. Going back to the example above, we might add these
lines:
List<ASTnode*> *results; results = AST->searchByTag( "_Author_name" ); for( results->Reset() ; ! results->AtEnd() ; results->Next() ) { ASTnode *thisOne = results->Current(); // Walk up the parent tree until something that is a // DATAITEMNODE is found, or the root of the tree is // passed up: while( thisOne != NULL && ! thisOne->isOfType( ASTnode::DATAITEMNODE ) ) { thisOne = thisOne->myParent(); } if( thisOne != NULL ) { Now do whatever you wanted to do with thisOne } } // You must always delete the list returned by the search // function when you are done with it delete results;The methods shown above,
isOfType()
and
myParent()
, as well as the possible types for
ASTtype (the argument to isOfType()
) are described in
astnode.h
NOTE: Despite its name, searchByTag()
can be used to search for any sort of name, not just tags. For
example, you could search for a save frame.
Other similar searching functions that might be of interest are:
searchByTagValue()
searchForTypeByTag()
DataLoopNode
in
which a tag appears, rather than the tag itself.
astnode.h
.