diff -r 0cb2248d0edc -r ebe3f8f03b59 apicompatanamdw/compatanalysercmd/headeranalyser/src/CPPParser.cpp --- a/apicompatanamdw/compatanalysercmd/headeranalyser/src/CPPParser.cpp Thu Apr 22 17:15:08 2010 +0530 +++ b/apicompatanamdw/compatanalysercmd/headeranalyser/src/CPPParser.cpp Mon Apr 26 16:28:13 2010 +0530 @@ -45,6 +45,8 @@ const int KMaxFilenameLength = 512; const int KMaxDirLength=1024; +#define MAX_ARRAY_COUNT 200 + // The C++ parser executable #ifdef __WIN__ static const char* GCCXML_COMMAND = "ha_gccxml_cc1plus "; @@ -466,124 +468,533 @@ // CPPParser::HandleExports // ---------------------------------------------------------------------------- // + int CPPParser::HandleExports(string aFilename, string aVersion) { - int ret = 0; - string ofilename = aFilename + ".2"; - - ifstream input(aFilename.c_str(), ios::in); - ofstream output(ofilename.c_str(), ios::out); - iOutputFilename = ofilename; - char c; - string toflush = ""; - unsigned int matches = 0; - string tofind = STR_EXPORT_HACK; - string attribstr = STR_ATTRIBUTE_STR; - string outputBuffer; - outputBuffer.reserve(PREPROCESS_BUFFERSIZE); - int state = EStateSearching; - bool purevirtual = false; - bool possiblepurevirtual = false; - while (input.get(c)) - { - if (outputBuffer.length() >= PREPROCESS_BUFFERSIZE) - { - output << outputBuffer; - outputBuffer = ""; - } - if (state == EStateSearching) - { - if (c == tofind.at(matches)) - { - matches++; - toflush += c; - } else - { - matches = 0; - if (!toflush.empty()) - { - outputBuffer += toflush; - toflush = ""; - } - outputBuffer += c; - } - if (matches == tofind.length()) - { - toflush = ""; - state = EStateReplacing; - matches = 0; - } - } else if (state == EStateReplacing) - { - if (c == '=') - { - if (possiblepurevirtual == true && !toflush.empty()) - { - outputBuffer += toflush; - toflush = ""; - } - possiblepurevirtual = true; - toflush += c; - } else if (possiblepurevirtual == true && c!= ';') - { - if (c == ' ') - { - toflush += c; - } else if (c == '\t') - { - toflush += c; - } else if (c == '0') - { - toflush += c; - purevirtual = true; - } else - { - outputBuffer += toflush; - outputBuffer += c; - toflush = ""; - possiblepurevirtual = false; - purevirtual = false; - } - } else if (c == ';') - { - state = EStateSearching; - if (purevirtual) - { - } else if (possiblepurevirtual) - { - outputBuffer += toflush; - toflush = ""; - } + int ret = 0; + string ofilename = aFilename + ".2"; + + ifstream input(aFilename.c_str(), ios::in); + ofstream output(ofilename.c_str(), ios::out); + iOutputFilename = ofilename; + char c; + string toflush = ""; + string flush = ""; + unsigned int matches = 0; + string tofind = STR_EXPORT_HACK; + string attribstr = STR_ATTRIBUTE_STR; + string outputBuffer; + outputBuffer.reserve(PREPROCESS_BUFFERSIZE); + int state = EStateSearching; + char stackArray[MAX_ARRAY_COUNT] = {'\0'}; + int arryPos = 0; + + string isClass = "class"; + string isEnum = "enum"; + string isStruct = "struct"; + string isUnion = "union"; + string isInline = "inline"; + + unsigned int clsPos = 0; + unsigned int enmPos = 0; + unsigned int strctPos = 0; + unsigned int inlinePos = 0; + unsigned int unionPos = 0; + char arraychar = '\0'; + + unsigned int bufPos = 0; + + string temp; + string buf; + + bool possibleVirtualFunc = false; + bool virtualFunc = false; + bool ignorecheck = false; + while (input.get(c)) + { + ignorecheck = false; + if (outputBuffer.length() >= PREPROCESS_BUFFERSIZE) + { + output << outputBuffer; + outputBuffer = ""; + } + // Get the bufferpos + bufPos = (unsigned int)outputBuffer.length()-1; + + // delete buf (class\enum\struct) entry if next letter is not space + if ( buf.length() > 0 && state == EStateReplacing && (c != ' ' && c != '\t' && int(c) != 10)) + { + buf = ""; + } + if( c == isClass.at(clsPos)) + { + if( clsPos == 0 ) // searching for class keyword with space before and after + { + if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' + || int(outputBuffer.at(bufPos)) == 10 || int(outputBuffer.at(bufPos)) == 32 ) + clsPos++; + } + else + clsPos++; + } + + else + clsPos = 0; + if (clsPos == isClass.length()) // keyword found + { + clsPos = 0; + buf = isClass; + ignorecheck = true; // in the current iteration don't match buf string with class\enum\struct keyword + // as keyword may be part of some word like " classification" + } + + if( c == isUnion.at(unionPos)) + { + if( unionPos == 0 ) // searching for union keyword with space before and after + { + if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' + || int(outputBuffer.at(bufPos)) == 10 || int(outputBuffer.at(bufPos)) == 32 ) + unionPos++; + } + else + unionPos++; + } + + else + unionPos = 0; + if (unionPos == isUnion.length()) // keyword found + { + unionPos = 0; + buf = isUnion; + ignorecheck = true; // in the current iteration don't match buf string with class\enum\struct\union keyword + // as keyword may be part of some word like " classification" + } + + if(c == isStruct.at(strctPos))// searching for struct keyword with space before and after + { + if( strctPos == 0 ) + { + if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' + || int(outputBuffer.at(bufPos)) == 10 ) + strctPos++; + } + else + strctPos++; + } + else + strctPos = 0; + + if(strctPos == isStruct.length()) + { + strctPos = 0; + buf = isStruct; + ignorecheck = true; // in the current iteration don't match buf string with class\enum\struct keyword + // as keyword may be part of some word like " structural" + } + + if(c == isEnum.at(enmPos) )// searching for enum keyword with space before and after + { + if( enmPos == 0 ) + { + if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' + || int(outputBuffer.at(bufPos)) == 10 ) + enmPos++; + } + else + enmPos++; + } + else + enmPos = 0; + + if( enmPos == isEnum.length()) + { + enmPos = 0; + buf = isEnum; + ignorecheck = true;// in the current iteration don't match buf string with class\enum\struct keyword + // as keyword may be part of some word like " enumuration" + } + + if (state == EStateSearching) + { + memset(stackArray,'\0',MAX_ARRAY_COUNT); + if (c == tofind.at(matches)) + { + matches++; + toflush += c; + } else + { + matches = 0; + if (!toflush.empty()) + { + outputBuffer += toflush; + toflush = ""; + } + outputBuffer += c; + + if(buf.length() > 0 && ignorecheck == false && (c != ' ' && c != '\t' + && int(c) != 10 )) + { + buf = ""; + arraychar = '\0'; + } + } + if (matches == tofind.length()) + { + toflush = ""; + state = EStateReplacing; // export keyword match found, so make the stae as replacing + matches = 0; + } + } else if (state == EStateReplacing) + { + // under a exported class,for a function the exported keyword is present,it should be deleted. + if (c == tofind.at(matches)) + { + matches++; + toflush += c; + if (matches == tofind.length()) + { + toflush = ""; + matches = 0; + } + continue; + } else + { + matches = 0; + if (!toflush.empty()) + { + outputBuffer += toflush; + toflush = ""; + } + } + + + if(c == isInline.at(inlinePos)) + { + if( inlinePos == 0 )// searching for inline keyword with space before and after + { + if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' + || int(outputBuffer.at(bufPos)) == 10 ) + inlinePos++; + } + else + inlinePos++; + } + else + inlinePos = 0; + + if( inlinePos == isInline.length()) + { + inlinePos = 0; + buf = isInline; + + } + + if ( buf.length() > 0 && (c == ' ' || c == '\t' || int(c) == 10)) + { + if (buf == isClass) + { + arraychar = 'c'; + } + if (buf == isStruct ) + { + arraychar = 's'; + } + if (buf == isEnum) + { + arraychar = 'e'; + } + if(buf == isUnion) + { + arraychar = 'u'; + } + if(buf == isInline) + { + stackArray[arryPos] = 'i'; // place inline keyword in stack + arryPos++; + } + + buf = ""; + if(temp.length() > 0) + temp = ""; + } + else if (c == '{') + { + // place the keyword in stack for class\enum\struct + if(arraychar != '\0') + { + stackArray[arryPos] = arraychar; + arraychar = '\0'; + arryPos++; + } + stackArray[arryPos] = c; + arryPos++; - outputBuffer += " "; - outputBuffer += attribstr; - if (!toflush.empty()) - { - outputBuffer += " "; - outputBuffer += toflush; - toflush = ""; - } - possiblepurevirtual = false; - purevirtual = false; - outputBuffer += ';'; - } else - { - outputBuffer += c; - } - } else if (state == EStateReplaceDone) - { + if(temp.length() > 0) + temp = ""; + } + else if(c== '}') + { + temp = ""; + bool ignore = false; + // can be end of class\enum\struct + for (int i = arryPos-1; i >= 0; i-- ) + { + + if (stackArray[i] == '{' ) + { + if( stackArray[i-1] != 'c' && stackArray[i-1] != 's' + && stackArray[i-1] != 'e' && stackArray[i-1] != 'u') + // check if the function is inline + { + + ignore = true; + break; + } + } + } + if(ignore == false) + temp = c; + + stackArray[arryPos] = c; + arryPos++; + + if(temp == "") + { + int openbraceCount = 0; + int closebracecount = 0; + + // if it is end of a function then delete the entry from stack + // and it is ofcourse not a exported function, + //will definitely be a inline function with or without "inline" keyword + bool deleteEntry = false; + int setpos = 0; + // get the pos after class\struct\enum started + for(int i = arryPos; i >= 0; i--) + { + if(stackArray[i] == '{') + { + deleteEntry = true; + if (stackArray[i-1] == 'c' || stackArray[i-1] == 's' + || stackArray[i-1] == 'e' || stackArray[i-1] == 'u') + { + setpos = i+1; + break; + } + } + } + // find the end pos of the non exported function by matching the open and close flower brace count. + if(deleteEntry) + { + deleteEntry = false; + for(int i = setpos; i <= arryPos; i++ ) + { + if(stackArray[i] == '{') + openbraceCount++; + else if(stackArray[i] == '}') + closebracecount++; + } + if(openbraceCount > 0 && openbraceCount == closebracecount ) + { + deleteEntry = true;// need to delete the non exported function entry from stack now + } + } + // noe delete the non exported entry and re arrange the stack + if(deleteEntry) + { + for(int pos = setpos; pos <= arryPos; pos++ ) + stackArray[pos] = '\0'; + + arryPos = setpos; + } + } + + } + else if ( (c == '=' && stackArray[arryPos-1] == ')') || + (c == '0' && stackArray[arryPos-1] == '=') || + (c == '(' || c == ')' )|| + ( possibleVirtualFunc == true ||virtualFunc == true) + ) // can be a virtual function or normal function which might be exported + { + if(temp.length() > 0) + temp = ""; + + if( (possibleVirtualFunc == true && ( c!= '0' && c != ' ' && c != '\t' && int(c) != 10) ) || + (virtualFunc == true && (c!= ';' && c != ' ' && c != '\t' && int(c) != 10)) ) + { // if other than space and '0', then set posVirtual func to false + // or if other than space and ';', then set Virtual func to false + outputBuffer += flush; + outputBuffer += c; + flush = ""; + possibleVirtualFunc = false; + virtualFunc = false; + continue; + } - } + else if( c == '=') // possible virtual function + { + flush = c; + possibleVirtualFunc = true; + virtualFunc = false; + stackArray[arryPos] = c; + arryPos++; + continue; + } + else if (possibleVirtualFunc == true) + { + flush += c; + if ( c == '0') + { + virtualFunc = true; // pure virtual function + possibleVirtualFunc = false; + stackArray[arryPos] = c; + arryPos++; + } + continue; + } + else if (c == '(' || c == ')') + { + flush = ""; + stackArray[arryPos] = c; + arryPos++; + } + + } + + if (c == ';') + { + arraychar = '\0'; + // first check for inline function and delete the entry from stack for this func + bool isinline = false; + bool nonExpFun = false; + bool removeEntry = false; + + for (int i = arryPos-1; i >= 0; i-- ) + { + if ( stackArray[i] == 'i') // inline function with inline keyword + isinline = true; + + else if (stackArray[i] == '{')// check if the function is inline + { + if (stackArray[i-1] != 'c' && stackArray[i-1] != 's' + && stackArray[i-1] != 'e' && stackArray[i-1] != 'u') + nonExpFun = true; + } + } + + // end of struct/class/enum + if (stackArray[arryPos-1] == '}' && temp == "}" ) + { + //if(!isinline && !nonExpFun) + { + int cnt = arryPos-1; + bool flag = false; + for (int i = cnt; i>=0; i--) + { + if (stackArray[i] == 'c' || stackArray[i] == 's' + || stackArray[i] == 'e' || stackArray[i] == 'u') + { + flag = true; + } + stackArray[i] = '\0'; + arryPos--; + if( flag ) + { + break; + } + } + outputBuffer += c; + temp = ""; - } - if (outputBuffer.length() != 0) - { - output << outputBuffer; - } - return ret; + if(stackArray[0] == '\0') // check if exported class\struct is ended .. + // set state to searching and continue; + state = EStateSearching; + continue; + } + } + + if(stackArray[arryPos-1] == '('&& nonExpFun == false && isinline == false) + // not function, can be a for loop, so reset the stackArray ... + { + outputBuffer += c; + removeEntry = true; + } + else if(stackArray[arryPos-1] == ')' ) + // some exported function can be "abcd( xyz(0), pqr(0))" + { + if( nonExpFun == false && isinline == false ) + { + outputBuffer += " "; + outputBuffer += attribstr; + } + outputBuffer += c; + if (nonExpFun == false) + removeEntry = true; + } + else if( (stackArray[arryPos-1] == '0' && stackArray[arryPos-2] == '=' && virtualFunc == true) ) + { // can be a virtual function or normal function which is definitely exported + if(!isinline && !nonExpFun) + { + outputBuffer += " "; + outputBuffer += attribstr; + outputBuffer += " "; + } + outputBuffer += flush; + outputBuffer += c; + flush = ""; + if(nonExpFun == false) + removeEntry = true; + virtualFunc = false; + } + else + { + outputBuffer += c; + } + + if(removeEntry == true) + { + int cnt = arryPos-1; + bool flag = false; + for (int i = cnt; i>=0; i--) + { + if (stackArray[i] == '{' && + (stackArray[i-1] == 'c' || stackArray[i-1] == 's' + || stackArray[i-1] == 'e' || stackArray[i-1] == 'u') ) + flag = true; + + if(flag == false) + { + stackArray[i] = '\0'; + arryPos--; + } + } + } + + if(stackArray[0] == '\0') + state = EStateSearching; + } + else + { + if( virtualFunc == true ) + { + outputBuffer += flush; + flush = ""; + virtualFunc = false; + } + outputBuffer += c; + } + } else if (state == EStateReplaceDone) + { + + } + + } + if (outputBuffer.length() != 0) + { + output << outputBuffer; + } + return ret; } - // ---------------------------------------------------------------------------- // CPPParser::ReplaceExport // ----------------------------------------------------------------------------