📄 main.cpp
字号:
/***************************************************************** Qt based generic FORTRAN 77 conversion into C++ Pseudocode **** written by John Coe III -- July 21, 2007 **** Version 1.1 jciii@earthlink.net ******************************************************************/#include "main.h"int main( int argc, char ** argv ){ // Must start the Qt application first QApplication a( argc, argv ); // Load the configuration from the information file loadInfoFile( "convert.info" ); // Allow an command line argument to override selection dialog QStringList fileNameList; if ( argc >= 2 ) fileNameList << argv[1]; else fileNameList = QFileDialog::getOpenFileNames( "Program File (*.F *.f *.h)", QString::null, 0 ); // If something was selected proceed if ( fileNameList.size() > 0 ) { // If no command line arguments, ask user if overwrite is ok if Cpp file exists if ( argc == 1 && QFile::exists( makeIntoCppFile( fileNameList[0] ) ) ) { switch( QMessageBox::question( 0, "FORTRAN to Cpp:", "Overwrite existing Cpp file(s)?", "&Yes", "&Abort", 0, 1 ) ) { case 0: break; case 1: default: return -1; break; } } // Iterate over entire filename list for ( QStringList::const_iterator it = fileNameList.begin(); it != fileNameList.end(); it++ ) { if ( !convertFortran( *it ) ) qDebug( "File IO error during %s", *it ); } } return 0;}bool convertFortran(const QString fileName){ QStringList fortranCode; // Read entire file into memory QFile infile( fileName ); if ( !infile.open(IO_ReadOnly) ) return false; QTextStream in(&infile); while ( !in.atEnd() ) { fortranCode << in.readLine(); } infile.close(); // Set up file output for the new Cpp program QString fileNameNew = makeIntoCppFile( fileName ); qDebug( fileNameNew ); QFile outFile( fileNameNew ); if ( !outFile.open(IO_WriteOnly) ) return false; QTextStream cppOut(&outFile); // Write the file header out to the Cpp file first for ( QStringList::iterator it = fileHeader.begin(); it != fileHeader.end(); it++ ) cppOut << *it << "\n"; // Intialize int lineNo = 0; QString currentCode, nextCode, code, label, ignore; bool contLine = false; FortranType myType = eUnknown; int indent = 0; int doFlag = 0; int indentNext = 0; bool insideComment = false; bool ignoreLongLine = false; bool isLocalsWritten= true; // version 1.1 addition QStringList::iterator next; // Holds local variables - version 1.1 addition QStringList localVariables; // Temporary QStringList::iterator it2, it3; QString temp, common; int tempInt; FortranType type; QStringList parts; // Parse file data for ( QStringList::iterator it = fortranCode.begin(); it != fortranCode.end(); it++ ) { lineNo++; // Initialize for each loop indentNext = 0; ignoreLongLine = false; // Process a line of Fortran code myType = determineFortranType( (*it), currentCode, label, contLine ); // Ignore this, it was already processed if ( contLine ) continue; // Put all continuation lines into one big one (skip comments if any) if ( myType != eComment && myType != eBlank ) { next = it; next++; for ( ; next != fortranCode.end(); next++ ) { temp = *next; type = determineFortranType( temp, nextCode, ignore, contLine ); // Ignore comment and keep going if ( type == eComment ) continue; // If continuation line, add into existing line if ( contLine ) { currentCode += " " + nextCode; continue; } // Stop processing... break; } } /* **********Process the Fortran type********** */ // Is this the end of a comment? if ( insideComment && myType != eComment ) { cppOut << "*/\n"; insideComment = false; } // If code is reached, write out local variables first if ( !isLocalsWritten && ( myType != eComment && myType != eBlank && myType != eEquivalence && myType != eImplicit && myType != eIntrinsic && myType != eStructure && myType != eEndStructure && myType != eUnion && myType != eEndUnion && myType != eBlock && myType != eCommon && myType != eInclude && myType != eVariable && myType != eParameter && myType != eData && myType != eSave && myType != eExternal ) ) { if ( localVariables.size() > 0 ) { cppOut << "\n"; for ( QStringList::iterator var = localVariables.begin(); var != localVariables.end(); var++ ) { cppOut << *var << "\n"; } cppOut << "\n"; localVariables.clear(); } isLocalsWritten = true; } // Set the flag that allows variables to be written if this is the start of a program if ( myType == eBeginProgram || myType == eSubroutine ) isLocalsWritten = false; switch( myType ) { case eDo: doFlag++; indentNext = 1; currentCode = processDo( currentCode ); break; case eComment: if ( !insideComment ) { cppOut << "/*" << "\n"; insideComment = true; } currentCode = "**" + currentCode; ignoreLongLine = true; break; case eBeginProgram: currentCode = currentCode.replace( "program", "", FALSE ).stripWhiteSpace(); case eSubroutine: currentCode = currentCode.replace( "subroutine", "", FALSE ).stripWhiteSpace(); for ( it2 = programHeader.begin(); it2 != programHeader.end(); it2++ ) cppOut << *it2 << "\n"; if ( currentCode.find("(") == -1 ) currentCode += "()"; indentNext = 1; break; case eEndProgram: currentCode = "}"; indent--; break; case eInclude: currentCode.replace( "INCLUDE", "include", TRUE ); break; case eCode: swapKeywords( currentCode ); currentCode = swapVariables( currentCode, TRUE ); currentCode = swapConditionals( currentCode ); currentCode += ENDCHAR; break; case eReturn: currentCode.replace( "RETURN", "return", TRUE ); currentCode += ENDCHAR; break; case eVariable: // Swap from () to [] currentCode.replace( "(", "[" ); currentCode.replace( ")", "]" ); // version 1.1 addition to remove the '::' currentCode.replace( "::", "" ); // See if next line is a parameter next = it; next++; temp = *next; type = determineFortranType( temp, temp, ignore, contLine ); if ( type == eParameter ) { currentCode = currentCode.upper(); parts = QStringList::split( "=", temp, FALSE ); currentCode = currentCode + " (" + parts[1]; currentCode = cleanCode( currentCode ); swapKeywords( currentCode ); currentCode = swapVariables( currentCode, FALSE ); currentCode = "#define " + currentCode; } else { swapKeywords( currentCode ); currentCode = swapVariables( currentCode, TRUE ); // Clean the variable list currentCode = currentCode.simplifyWhiteSpace(); parts = QStringList::split( " ", currentCode, FALSE ); tempInt = _CppVarLength - parts[0].length(); if ( tempInt < 0 ) tempInt = 0; temp.fill( ' ', tempInt ); temp = parts[0] + temp; currentCode = currentCode.right( currentCode.length() - parts[0].length() ); currentCode = temp + currentCode + ENDCHAR; // version 1.1 addition localVariables << currentCode; // this skips the below code, as variables are added before the first code line continue; } break; case eDoWhile: currentCode.replace( "WHILE", "while", TRUE ); currentCode = swapConditionals( currentCode ); currentCode = currentCode.replace( "then", "", FALSE ); currentCode = currentCode.simplifyWhiteSpace(); indentNext = 1; break; case eIf: currentCode.replace( "IF", "if", TRUE ); currentCode = swapConditionals( currentCode ); //currentCode = currentCode.replace( "then", "", FALSE ); currentCode = currentCode.simplifyWhiteSpace(); //indentNext = 1; /* Version 1.1 fix for IF only Statements */ if ( currentCode.contains( "THEN", FALSE ) ) { currentCode = currentCode.replace( "then", "", FALSE ); indentNext = 1; } else { // This is a IF Statement -- doesn't have ENDIF } break; case eElseIf: indent--; cppOut << indentation( indent ) + "}" << "\n"; currentCode = swapConditionals( currentCode ); currentCode = currentCode.replace( "ELSEIF", "else if", FALSE ); currentCode = currentCode.replace( "then", "", FALSE ); currentCode = currentCode.simplifyWhiteSpace(); indentNext = 1; break; case eElse: currentCode.replace( "ELSE", "else", TRUE ); indent--; cppOut << indentation( indent ) + "}" << "\n"; indentNext = 1; break; case eContinue: if ( doFlag ) { doFlag--; indent--; currentCode = "}"; } if ( currentCode.contains( "CONTINUE", FALSE ) ) currentCode = "//" + currentCode; break; /* Version 1.1 fix for BLOCK DATA sections */ case eBlock: indentNext = 1; break; /* Version 1.1 fix for COMMON sections */ case eCommon: currentCode = "//" + currentCode; parts = QStringList::split( "/", currentCode, FALSE ); if ( parts.size() == 3 ) { cppOut << indentation( indent ) << "extern \"C\"\n"; cppOut << indentation( indent ) << "{\n"; indent++; common = parts[1].upper(); cppOut << indentation( indent ) << "extern struct " << common << "\n"; common = /*"s_" + */common.lower() + "_"; cppOut << indentation( indent ) << "{\n"; indent++; temp = parts[2]; // reset parts to the variable list parts = QStringList::split( ",", temp, FALSE ); if ( parts.size() == 0 ) { for ( it2 = localVariables.begin(); it2 != localVariables.end(); it2++ ) { if ( (*it2).contains( " "+temp.stripWhiteSpace() ) ) { cppOut << indentation( indent ) << *it2 << "\n"; break; } } } else { for ( it3 = parts.begin(); it3 != parts.end(); it3++ ) for ( it2 = localVariables.begin(); it2 != localVariables.end(); it2++ ) { if ( (*it2).contains( " "+(*it3).stripWhiteSpace() ) ) { cppOut << indentation( indent ) << *it2 << "\n"; break; } } } // add the struct name indent--; cppOut << indentation( indent ) << "} " << common << ENDCHAR << "\n"; indent--; cppOut << indentation( indent ) << "}\n"; } break; case eEndIf: case eEndDo: indent--; currentCode = "}"; break; case eCall: currentCode = currentCode.replace( "call", "", FALSE ).stripWhiteSpace(); if ( currentCode.find("(") == -1 ) currentCode += "()"; currentCode += ENDCHAR; break; case eGoto: currentCode = currentCode.replace( "goto", "", FALSE ).stripWhiteSpace(); currentCode = currentCode.replace( "go to", "", FALSE ).stripWhiteSpace(); currentCode = "goto " + LABEL + currentCode + ENDCHAR ; break; // Keep from running default case case eLabel: case eBlank: case eDefine: case eIfDef: case eEndDef: case eData: break; // Not known, comment it out default: currentCode = "//" + currentCode; ignoreLongLine = true; break; } // If label is not empty add a Cpp label if ( !label.isEmpty() ) cppOut << LABEL + label + ":" << "\n"; // Only indent the code if it is not one of these types if ( myType != eComment && myType != eInclude && myType != eDefine && myType != eIfDef && myType != eEndDef && myType != eVariable ) { currentCode = indentation( indent ) + currentCode; currentCode = cleanCode(currentCode); } // If not a comment or blank line, swap single quote with double quote if ( myType != eComment && myType != eBlank ) { currentCode = currentCode.replace( "'", "\"" ); // Swap out cpp keywords with uppercase version if not a comment if ( myType != eVariable && myType != eCode ) swapKeywords( currentCode ); } // This is where we cut long lines into multiple parts if ( !ignoreLongLine ) { int len = currentCode.length(); while ( len > _MaxLineLength ) { cppOut << breakApart( currentCode, currentCode ) << "\n"; currentCode = indentation( indent + 1 ) + currentCode; len = currentCode.length();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -