/*************************************************************************/ /* OPARI Version 1.1 */ /* Copyright (c) 2001-2005 */ /* Forschungszentrum Juelich, Zentralinstitut fuer Angewandte Mathematik */ /*************************************************************************/ #include using std::cerr; #include using std::stack; #include using std::vector; #include using std::map; #include using std::getline; using std::string; #include using std::isalnum; using std::isalpha; #include "opari.h" #include "handler.h" namespace { string find_next_word(vector& preStmt, unsigned size, unsigned& pline, string::size_type& ppos) { while ( pline < size ) { string::size_type wbeg = preStmt[pline].find_first_not_of(" \t", ppos); if ( preStmt[pline][wbeg] == '\\' || wbeg == string::npos ) { ++pline; if ( pline < size ) { ppos = 0; } else { return ""; } } else { ppos = preStmt[pline].find_first_of(" \t()", wbeg); return preStmt[pline].substr(wbeg, ppos==string::npos ? ppos : ppos-wbeg); } } return ""; } bool process_preStmt(vector& preStmt, ostream& os, const char* infile, int lineno, string::size_type ppos, bool* e, bool* f, bool asd) { unsigned s = preStmt.size(); bool inComment = false; unsigned int i; // "remove" comments for (i=0; i -> remove it string word = find_next_word(preStmt, s, pline, ppos); if ( (word == "\"omp.h\"") || (word == "") ) { s = 0; } } for (i=0; i preStmt; vector endStmt; stack nextEnd; map wrapper; wrapper["omp_init_lock"] = "POMP_Init_lock"; wrapper["omp_destroy_lock"] = "POMP_Destroy_lock"; wrapper["omp_set_lock"] = "POMP_Set_lock"; wrapper["omp_unset_lock"] = "POMP_Unset_lock"; wrapper["omp_test_lock"] = "POMP_Test_lock"; wrapper["omp_init_nest_lock"] = "POMP_Init_nest_lock"; wrapper["omp_destroy_nest_lock"] = "POMP_Destroy_nest_lock"; wrapper["omp_set_nest_lock"] = "POMP_Set_nest_lock"; wrapper["omp_unset_nest_lock"] = "POMP_Unset_nest_lock"; wrapper["omp_test_nest_lock"] = "POMP_Test_nest_lock"; nextEnd.push(-1); while ( getline(is, line) ) { /* workaround for bogus getline implementations */ if ( line.size() == 1 && line[0] == '\0' ) break; if ( preContLine ) { /* * preprocessor directive continuation */ preStmt.push_back(line); if ( line[line.size()-1] != '\\' ) { preContLine = false; if ( process_preStmt(preStmt, os, infile, lineno-preStmt.size()+1, lstart+1, &requiresEnd, &isFor, addSharedDecl) ) { if ( requiresEnd ) { nextEnd.push(level); numSemi = isFor ? 3 : 1; } else { numSemi = 0; } } } } else if ( !inComment && ((lstart = line.find_first_not_of(" \t")) != string::npos) && line[lstart] == '#' ) { /* * preprocessor directive */ preStmt.push_back(line); if ( line[line.size()-1] == '\\' ) { preContLine = true; } else { if ( process_preStmt(preStmt, os, infile, lineno, lstart+1, &requiresEnd, &isFor, addSharedDecl) ) { if ( requiresEnd ) { nextEnd.push(level); numSemi = isFor ? 3 : 1; } else { numSemi = 0; } } } } else { /* * regular line */ bool newlinePrinted = false; while ( pos < line.size() ) { newlinePrinted = false; if ( inComment ) { // look for comment end if ( line[pos] == '*' && line[pos+1] == '/' ) { os << "*/"; inComment = false; pos += 2; } else { os << line[pos++]; } } else if ( line[pos] == '/' ) { pos++; if ( line[pos] == '/' ) { // c++ comments pos++; os << "//"; while ( pos < line.size() ) { os << line[pos++]; } } else if ( line[pos] == '*' ) { // c comment start pos++; os << "/*"; inComment = true; } else { os << '/'; } } else if ( inString || line[pos] == '\"' ) { // character string constant if ( inString ) { inString = false; pos--; // to make sure current character gets reprcessed } else { os << "\""; } do { pos++; if ( line[pos] == '\\' ) { os << '\\'; pos++; if ( line[pos] == '\0' ) { inString = true; break; } else if ( line[pos] == '\"' ) { os << '\"'; pos++; } } os << line[pos]; } while ( line[pos] != '\"' ); pos++; } else if ( line[pos] == '\'' ) { // character constant os << "\'"; do { pos++; if ( line[pos] == '\\' ) { os << '\\'; pos++; if ( line[pos] == '\'' ) { os << '\''; pos++; } } os << line[pos]; } while ( line[pos] != '\'' ); pos++; } else if ( isalpha(line[pos]) || line[pos] == '_' ) { // identifier string::size_type startpos = pos; while ( pos < line.size() && (isalnum(line[pos]) || line[pos]=='_') ) { pos++; } string ident(line, startpos, pos-startpos); map::iterator w = wrapper.find(ident); if ( w != wrapper.end() && instrument_locks() ) os << w->second; else os << ident; if ( ident == "for" && numSemi == 1 ) numSemi = 3; } else if ( line[pos] == '{' ) { // block open os << line[pos++]; level++; numSemi = 0; } else if ( line[pos] == '}' ) { // block close os << line[pos++]; level--; if ( nextEnd.top() == level ) { int moreChars = (pos < line.size()); os << '\n'; newlinePrinted = true; // while because block can actually close more than one pragma while ( nextEnd.top() == level ) { // hack: use pline (arg3) for correction value for line info process_pragma(new OMPragmaC(infile, lineno+1-moreChars, 1-moreChars, 0, endStmt, addSharedDecl), os); nextEnd.pop(); } if ( moreChars ) for(unsigned i=0; i