You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/languages/cpp/stringhelpers.cpp

297 lines
6.8 KiB

/***************************************************************************
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<TQString, TQString> splitTemplateParams( TQString str ) {
TQPair<TQString, TQString> 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<TQChar> 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;
}
}