/*************************************************************************** k copyright : (C) 2006 by David Nolden email : david.nolden.kdevelop@art-master.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "stringhelpers.h" #include "safetycounter.h" namespace StringHelpers { void clearStr( TQString& str, int start, int end ) { for( int a = start; a < end; a++) str[a] = ' '; } bool isValidIdentifierSign( const TQChar& c ) { if( c.isLetter() || c.isDigit() || c == '_' ) return true; else return false; } TQString clearComments( TQString str ) { if( str.isEmpty() ) return ""; SafetyCounter s( 1000 ); int lastPos = 0; int pos; int len = str.length(); while( (pos = str.find( "/*", lastPos )) != -1 ) { if( !s ) return str; int i = str.find( "*/", pos ); if( i != -1 && i <= len - 2 ) { clearStr( str, pos, i+2 ); lastPos = i+2; if( lastPos == len ) break; } else { break; } } lastPos = 0; while( (pos = str.find( "//", lastPos )) != -1 ) { if( !s ) return str; int i = str.find( "\n", pos ); if( i != -1 && i <= len - 1 ) { clearStr( str, pos, i+1 ); lastPos = i+1; } else { clearStr( str, pos, len ); break; } } return str; } TQString cutTemplateParams( TQString str ) { int p; if( (p = str.find('<') ) != -1) { return str.left( p ); } return str.stripWhiteSpace().replace('*',""); } TQPair splitTemplateParams( TQString str ) { TQPair ret; int p; if( (p = str.find('<') ) != -1) { ret.first = str.left( p ).stripWhiteSpace(); ret.second = str.mid( p ).stripWhiteSpace(); } else { ret.first = str.stripWhiteSpace(); } return ret; } bool parenFits( TQChar c1, TQChar c2 ) { if( c1 == '<' && c2 == '>' ) return true; else if( c1 == '(' && c2 == ')' ) return true; else if( c1 == '[' && c2 == ']' ) return true; else if( c1 == '{' && c2 == '}' ) return true; else return false; } bool isParen( TQChar c1 ) { if( c1 == '<' || c1 == '>' ) return true; else if( c1 == '(' || c1 == ')' ) return true; else if( c1 == '[' || c1 == ']' ) return true; else if( c1 == '{' || c1 == '}' ) return true; else return false; } bool isTypeParen( TQChar c1 ) { if( c1 == '<' || c1 == '>' ) return true; else return false; } bool isTypeOpenParen( TQChar c1 ) { if( c1 == '<' ) return true; else return false; } bool isTypeCloseParen( TQChar c1 ) { if( c1 == '>' ) return true; else return false; } bool isLeftParen( TQChar c1 ) { if( c1 == '<' ) return true; else if( c1 == '(' ) return true; else if( c1 == '[' ) return true; else if( c1 == '{' ) return true; else return false; } int findClose( const TQString& str , int pos ) { int depth = 0; TQValueList st; TQChar last = ' '; for( int a = pos; a < (int)str.length(); a++) { switch(str[a]) { case '<': case '(': case '[': case '{': st.push_front( str[a] ); depth++; break; case '>': if( last == '-' ) break; case ')': case ']': case '}': if( !st.isEmpty() && parenFits(st.front(), str[a]) ) { depth--; st.pop_front(); } break; case '"': last = str[a]; a++; while( a < (int)str.length() && (str[a] != '"' || last == '\\')) { last = str[a]; a++; } continue; break; } last = str[a]; if( depth == 0 ) { return a; } } return -1; } TQString tagType( const Tag& tag ) { if ( tag.hasAttribute( "t" ) ) { TQString type = tag.attribute( "t" ).toString(); return type; } else if ( tag.kind() == Tag::Kind_Class || tag.kind() == Tag::Kind_Namespace ) { TQStringList l = tag.scope(); l << tag.name(); return l.join("::"); } return TQString(); } int findCommaOrEnd( const TQString& str , int pos, TQChar validEnd) { for( int a = pos; a < (int)str.length(); a++) { switch(str[a]) { case '"': case '(': case '[': case '{': case '<': a = findClose( str, a ); if( a == -1 ) return str.length(); break; case ')': case ']': case '}': case '>': if( validEnd != ' ' && validEnd != str[a] ) continue; case ',': return a; } } return str.length(); } int countExtract( TQChar c, const TQString& str ) { int ret = 0; for( int a = 0; a < (int)str.length(); a++) { if( str[a] == c ) ++ret; switch( str[a] ) { case '"': case '(': case '[': case '{': case '<': a = findClose( str, a ); if( a == -1 ) return ret; } } return ret; } TQString templateParamFromString( int num, TQString str ) { if( str.endsWith("::") ) str.truncate( str.length() - 2 ); int begin = str.find('<'); int end = str.findRev('>'); if(begin == -1 || end == -1) return ""; begin++; for(int a = 0; a < num; a++) { begin = findCommaOrEnd( str, begin ); if( begin == (int)str.length() ) return ""; begin++; } end = findCommaOrEnd( str, begin ); if( end == (int)str.length() ) return ""; return str.mid( begin, end - begin ).stripWhiteSpace(); } TQStringList splitType( TQString str ) { TQStringList ret; int currentStart = 0; bool was = false; for( int a = 0; a < (int)str.length(); ++a ) { if( isLeftParen( str[a] ) ) { a = findClose( str, a ); if( a == -1 ) { CompletionDebug::dbg() << "misformatted type: " << str << endl; return ret; } was = false; } else { if( str[a] == ':' ) { if( was ) { if( currentStart < a - 1 ) ret << str.mid( currentStart, (a - 1) - currentStart ).stripWhiteSpace(); currentStart = a + 1; } was = true; } else { was = false; } } } if( currentStart < (int)str.length() ) ret << str.mid( currentStart, str.length() - currentStart ).stripWhiteSpace(); return ret; } TQString stringMult( int count, TQString str ){ TQString ret; for( int a = 0; a < count; a++ ) ret += str; return ret; } }