Support new Trick comment tags

Added new doxygen style tags for truning on/off Trick attributes processing,
comment processing, and library dependencies.  Here are the tags we recognize

(@|\)trick_parse(everything|attributes|dependencies_only)
(@|\)trick_exclude_typename(class_name)
(@|\)trick_link_dependency(link_name)

refs #114
This commit is contained in:
Alex Lin 2015-09-10 14:50:22 -05:00
parent f9ed085c6c
commit 9b381f2edc
4 changed files with 119 additions and 47 deletions

View File

@ -16,6 +16,11 @@ sub get_lib_deps ($$) {
my (@inc_paths) ; my (@inc_paths) ;
my (@raw_lib_deps) ; my (@raw_lib_deps) ;
# Doxygen style
@lib_list = ($contents =~ /(?:@|\\)trick_li(?:nk|b)_dependency\s*\(\s*(.*?)\s*\)/gs) ;
# Classic style
# library dependency regular expression will match all the way through last parenthesis followed by # library dependency regular expression will match all the way through last parenthesis followed by
# another field in the trick header, a doxygen style keyword, or the end of comment *. # another field in the trick header, a doxygen style keyword, or the end of comment *.
# we capture all library dependencies at once into raw_lib_deps # we capture all library dependencies at once into raw_lib_deps

View File

@ -52,10 +52,16 @@ std::string CommentSaver::getTrickHeaderComment( std::string file_name ) {
trick_header_comments[file_name] = std::string() ; trick_header_comments[file_name] = std::string() ;
for ( cit = comment_map[file_name].begin() ; cit != comment_map[file_name].end() ; cit++ ) { for ( cit = comment_map[file_name].begin() ; cit != comment_map[file_name].end() ; cit++ ) {
std::string comment_str = getComment((*cit).second) ; std::string comment_str = getComment((*cit).second) ;
std::transform(comment_str.begin(), comment_str.end(), comment_str.begin(), ::toupper) ; if ( comment_str.find("@trick_parse") != std::string::npos or
if ( comment_str.find("PURPOSE") != std::string::npos ) { comment_str.find("\\trick_parse") != std::string::npos ) {
trick_header_comments[file_name] = getComment((*cit).second) ; trick_header_comments[file_name] = getComment((*cit).second) ;
break ; break ;
} else {
std::transform(comment_str.begin(), comment_str.end(), comment_str.begin(), ::toupper) ;
if ( comment_str.find("PURPOSE") != std::string::npos ) {
trick_header_comments[file_name] = getComment((*cit).second) ;
break ;
}
} }
} }
} }
@ -72,60 +78,93 @@ void CommentSaver::getICGField( std::string file_name ) {
std::string th_str = getTrickHeaderComment(file_name) ; std::string th_str = getTrickHeaderComment(file_name) ;
if ( ! th_str.empty() ) { if ( ! th_str.empty() ) {
std::transform(th_str.begin(), th_str.end(), th_str.begin(), ::toupper) ; size_t trick_parse_keyword ;
int ret ; if ( (trick_parse_keyword = th_str.find("trick_parse")) != std::string::npos ) {
regex_t reg_expr ; size_t trick_parse_everything = th_str.find("everything", trick_parse_keyword) ;
regmatch_t pmatch[10] ; size_t trick_parse_attributes = th_str.find("attributes", trick_parse_keyword) ;
memset(pmatch , 0 , sizeof(pmatch)) ; size_t trick_parse_dep_only = th_str.find("dependencies_only", trick_parse_keyword) ;
size_t closing_paren = th_str.find(")", trick_parse_keyword) ;
if ( closing_paren != std::string::npos ) {
if ( trick_parse_everything != std::string::npos and
trick_parse_everything < closing_paren ) {
icg_no_comment_found[file_name] = false ;
icg_no_found[file_name] = false ;
} else if ( trick_parse_attributes != std::string::npos and
trick_parse_attributes < closing_paren ) {
icg_no_comment_found[file_name] = true ;
icg_no_found[file_name] = false ;
} else if ( trick_parse_dep_only != std::string::npos and
trick_parse_dep_only < closing_paren ) {
icg_no_comment_found[file_name] = false ;
icg_no_found[file_name] = true ;
} else {
std::cout << "trick_parse directive found but no argument matched." << std::endl ;
std::cout << "Valid arguments are (everything|attributes|dependencies_only)" << std::endl ;
exit(-1) ;
}
}
} else {
/* POSIX regular expressions are always greedy, making our job harder. std::transform(th_str.begin(), th_str.end(), th_str.begin(), ::toupper) ;
We have to use several regular expressions to get the types. This was int ret ;
so much easier in perl! */ regex_t reg_expr ;
regmatch_t pmatch[10] ;
memset(pmatch , 0 , sizeof(pmatch)) ;
/* find the ICG field */ /* POSIX regular expressions are always greedy, making our job harder.
ret = regcomp( &reg_expr , "(ICG:)" , REG_EXTENDED | REG_ICASE ) ; We have to use several regular expressions to get the types. This was
ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ; so much easier in perl! */
regfree(&reg_expr) ;
if ( ret != 0 ) {
return ;
}
th_str = th_str.substr(pmatch[1].rm_eo) ;
/* find the end of the ICG field */ /* find the ICG field */
memset(pmatch , 0 , sizeof(pmatch)) ; ret = regcomp( &reg_expr , "(ICG:)" , REG_EXTENDED | REG_ICASE ) ;
ret = regcomp( &reg_expr , "(\\))" , REG_EXTENDED ) ; ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ;
ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ; regfree(&reg_expr) ;
regfree(&reg_expr) ; if ( ret != 0 ) {
return ;
}
th_str = th_str.substr(pmatch[1].rm_eo) ;
if ( ret != 0 ) { /* find the end of the ICG field */
return ; memset(pmatch , 0 , sizeof(pmatch)) ;
} ret = regcomp( &reg_expr , "(\\))" , REG_EXTENDED ) ;
th_str = th_str.substr(0 , pmatch[1].rm_so) ; ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ;
regfree(&reg_expr) ;
/* test for NoComment */ if ( ret != 0 ) {
memset(pmatch , 0 , sizeof(pmatch)) ; return ;
ret = regcomp( &reg_expr , "(NOCOMMENT)$" , REG_EXTENDED ) ; }
ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ; th_str = th_str.substr(0 , pmatch[1].rm_so) ;
regfree(&reg_expr) ;
if ( ret == 0 ) { /* test for NoComment */
icg_no_comment_found[file_name] = true ; memset(pmatch , 0 , sizeof(pmatch)) ;
} ret = regcomp( &reg_expr , "(NOCOMMENT)$" , REG_EXTENDED ) ;
ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ;
regfree(&reg_expr) ;
/* test for No */ if ( ret == 0 ) {
memset(pmatch , 0 , sizeof(pmatch)) ; icg_no_comment_found[file_name] = true ;
ret = regcomp( &reg_expr , "(NO)$" , REG_EXTENDED ) ; }
ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ;
regfree(&reg_expr) ;
if ( ret == 0 ) { /* test for No */
icg_no_found[file_name] = true ; memset(pmatch , 0 , sizeof(pmatch)) ;
icg_no_comment_found[file_name] = true ; ret = regcomp( &reg_expr , "(NO)$" , REG_EXTENDED ) ;
ret = regexec( &reg_expr , th_str.c_str() , 10 , pmatch , 0 ) ;
regfree(&reg_expr) ;
if ( ret == 0 ) {
icg_no_found[file_name] = true ;
icg_no_comment_found[file_name] = true ;
}
} }
} }
} }
bool CommentSaver::hasTrickHeader( std::string file_name ) {
std::string th_str = getTrickHeaderComment(file_name) ;
return (! th_str.empty()) ;
}
bool CommentSaver::hasICGNo( std::string file_name ) { bool CommentSaver::hasICGNo( std::string file_name ) {
if ( icg_no_found.find(file_name) == icg_no_found.end() ) { if ( icg_no_found.find(file_name) == icg_no_found.end() ) {
@ -148,12 +187,32 @@ std::set< std::string > CommentSaver::getIgnoreTypes( std::string file_name ) {
std::set< std::string > ignore_types ; std::set< std::string > ignore_types ;
std::string th_str = getTrickHeaderComment(file_name) ; std::string th_str = getTrickHeaderComment(file_name) ;
if ( ! th_str.empty() ) { if ( ! th_str.empty() ) {
//std::cout << "here in getIgnoreTypes\n" << th_str << std::endl ;
std::transform(th_str.begin(), th_str.end(), th_str.begin(), ::toupper) ;
int ret ; int ret ;
regex_t reg_expr ; regex_t reg_expr ;
regmatch_t pmatch[10] ; regmatch_t pmatch[10] ;
//std::cout << "here in getIgnoreTypes\n" << th_str << std::endl ;
size_t start = 0 ;
start = th_str.find( "trick_exclude_typename") ;
while ( start != std::string::npos ) {
start += strlen("trick_exclude_typename") ;
std::string temp_str = th_str.substr(start) ;
memset(pmatch , 0 , sizeof(pmatch)) ;
ret = regcomp( &reg_expr , "^\\s*\\(\\s*(\\S+)\\s*\\)" , REG_EXTENDED ) ;
ret = regexec( &reg_expr , temp_str.c_str() , 10 , pmatch , 0 ) ;
regfree(&reg_expr) ;
if ( ret == 0 ) {
std::string item = temp_str.substr(pmatch[1].rm_so, pmatch[1].rm_eo) ;
// regular expression leaving trailing space and parenthesis. Why?
item.erase(item.find_first_of(" \t)")) ;
//std::cout << "icg_ignore_types " << item << std::endl ;
ignore_types.insert(item) ;
}
start = th_str.find( "trick_exclude_typename", start ) ;
}
std::transform(th_str.begin(), th_str.end(), th_str.begin(), ::toupper) ;
memset(pmatch , 0 , sizeof(pmatch)) ; memset(pmatch , 0 , sizeof(pmatch)) ;
/* POSIX regular expressions are always greedy, making our job harder. /* POSIX regular expressions are always greedy, making our job harder.

View File

@ -59,6 +59,12 @@ class CommentSaver : public clang::CommentHandler {
*/ */
void getICGField( std::string file_name ) ; void getICGField( std::string file_name ) ;
/** Returns if the header has a Trick header comment
@param file_name = File name to search
@return true = if header comment found
*/
bool hasTrickHeader(std::string file_name ) ;
/** Searches the Trick header comment for the ICG:(No) entry. /** Searches the Trick header comment for the ICG:(No) entry.
@param file_name = File name to search @param file_name = File name to search
@return true = ICG:(No) was found. @return true = ICG:(No) was found.

View File

@ -148,7 +148,9 @@ bool FieldVisitor::VisitDeclaratorDecl( clang::DeclaratorDecl *dd ) {
if ( isInUserOrTrickCode( ci , dd_range.getEnd() , hsd ) ) { if ( isInUserOrTrickCode( ci , dd_range.getEnd() , hsd ) ) {
fdes->setLineNo(ci.getSourceManager().getSpellingLineNumber(dd_range.getEnd())) ; fdes->setLineNo(ci.getSourceManager().getSpellingLineNumber(dd_range.getEnd())) ;
/* process comment if neither ICG:(No) or ICG:(NoComment) is present */ /* process comment if neither ICG:(No) or ICG:(NoComment) is present */
if ( ! cs.hasICGNoComment(file_name) and ! hsd.isPathInICGNoComment(file_name) ) { if ( cs.hasTrickHeader(file_name) and
!cs.hasICGNoComment(file_name) and
!hsd.isPathInICGNoComment(file_name) ) {
/* Get the possible comment on this line and parse it */ /* Get the possible comment on this line and parse it */
fdes->parseComment(cs.getComment(file_name , fdes->getLineNo())) ; fdes->parseComment(cs.getComment(file_name , fdes->getLineNo())) ;
} }