/*description: { Script that operates the transformation of a C++ source file to insert profiling code in the body of functions. Here, no parsing is processed for recognizing the signature of functions and the body. So, some troubles might appear if a \samp{\#define} macro describes a part or the whole of the function. One activates the profiling by setting the preprocessor definition \textbf{RAW_PROFILING} at compile-time (\samp{-D RAW_PROFILING} on the command line of the C++ compiler). To make it simple, the header of the \textit{profiling module} is inserted after the first \samp{\#include} encountered. It may cause some troubles if the first include is put in a conditional preprocessing block (\samp{\#ifdef WIN32} ... \samp{\#endif}/\samp{\#else}). The body of the function starts by incrementing its assigned counter held by the \textit{profiling module} and by timing the visit of the controlled sequence. Note that the transformation can be applied more than once: the second pass will not affect the source file. } */ #implicitCopy profiling ::= #ignore(C++) // ignore C++/JAVA-like comments [insert_include]? [ => local sName1; => local sName2; => local sPrefix2; => local bNewLine; ->[ #readCompleteIdentifier:sName1 [ "::" ['~' => sPrefix2 = "destructor_"; | => sPrefix2 = "";] #readIdentifier:sName2 => set sName2 = sPrefix2 + sName2; | => set sName2 = ""; ]? #check(sName2 || ((sName1 != "if") && (sName1 != "while") && (sName1 != "catch"))) '(' [parameter_token_list]? ')' [post_function_token_decl]? [':' constructor_initialization_token_list | !':'] '{' #!ignore ignoreLineBlanks ['\n' | => set bNewLine = true;] !"#ifdef RAW_PROFILING" ] => { if bNewLine { @@endl()@@ } local sKey = sName1 + "_" + sName2; insert this.listOfKeys[sKey] = sKey; if sName2 { insert this.listOfKeys[sKey].class = sName1; insert this.listOfKeys[sKey].name = sName2; } else { insert this.listOfKeys[sKey].name = sName1; } @#ifdef RAW_PROFILING RawProfiling::RawProfiling::@sKey@_counter++; RawProfiling::RawProfiling theProfiling(RawProfiling::RawProfiling::@sKey@_chronograph); #endif @ } ]* ->#empty; insert_include ::= ![->["#ifdef" "RAW_PROFILING" '#' "include"]] ->["#include" #!ignore ->'\n'] => { @ #ifdef RAW_PROFILING # include "RawProfiling.h" #endif @ }; parameter_token_list ::= parameter_tokens [',' parameter_tokens]*; parameter_tokens ::= [ #readIdentifier | '[' | ']' | '.' | // JAVA only #readInteger | '*' | '&' | "::" // C++ only ]+; post_function_token_decl ::= [#readIdentifier | '(' post_function_token_decl ')' | '.' | "::"]+; constructor_initialization_token_list ::= constructor_initialization_tokens [',' constructor_initialization_tokens]*; constructor_initialization_tokens ::= #readIdentifier '(' expression ')'; expression ::= [[~['[' | ']' '(' | ')' | '{' | '}' | ',']]+ | '[' expression ']' | '(' expression ')']+; ignoreLineBlanks : #!ignore ::= ["//" [~'\n']* | '\t' | ' ' | '\r']*;