00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "koscript_util.h"
00021 #include "koscript_context.h"
00022 #include "koscript_struct.h"
00023 #include <klocale.h>
00024
00025 bool KSUtil::checkArgumentsCount( KSContext& context, uint count, const QString& name, bool fatal )
00026 {
00027 Q_ASSERT( context.value() && context.value()->type() == KSValue::ListType );
00028
00029 QValueList<KSValue::Ptr>& args = context.value()->listValue();
00030
00031 if ( args.count() == count )
00032 return true;
00033
00034 if ( !fatal )
00035 return false;
00036
00037 if ( args.count() < count )
00038 tooFewArgumentsError( context, name );
00039 else
00040 tooManyArgumentsError( context, name );
00041
00042 return false;
00043 }
00044
00045 bool KSUtil::checkType( KSContext& context, KSValue* v, KSValue::Type t, bool fatal )
00046 {
00047 if ( !v->implicitCast( t ) )
00048 {
00049 if ( !fatal )
00050 return false;
00051
00052 castingError( context, v, t );
00053 return false;
00054 }
00055
00056 return true;
00057 }
00058
00059 bool KSUtil::checkType( KSContext& context, const KSValue::Ptr& v, KSValue::Type t, bool fatal )
00060 {
00061 if ( !v->implicitCast( t ) )
00062 {
00063 if ( !fatal )
00064 return false;
00065
00066 castingError( context, v, t );
00067 return false;
00068 }
00069
00070 return true;
00071 }
00072
00073 void KSUtil::castingError( KSContext& context, const QString& from, const QString& to )
00074 {
00075 QString tmp( i18n("From %1 to %2") );
00076 context.setException( new KSException( "CastingError", tmp.arg( from ).arg( to ), -1 ) );
00077 }
00078
00079 void KSUtil::castingError( KSContext& context, KSValue* v, KSValue::Type t )
00080 {
00081 QString tmp( i18n("From %1 to %2") );
00082 context.setException( new KSException( "CastingError", tmp.arg( v->typeName() ).arg( KSValue::typeToName( t ) ), -1 ) );
00083 }
00084
00085 void KSUtil::argumentsMismatchError( KSContext& context, const QString& methodname )
00086 {
00087 QString tmp( i18n("Arguments did not match the methods %1 parameter list.") );
00088 context.setException( new KSException( "ParameterMismatch", tmp.arg( methodname ) ) );
00089 }
00090
00091 void KSUtil::tooFewArgumentsError( KSContext& context, const QString& methodname )
00092 {
00093 QString tmp( i18n("Too few arguments for method %1") );
00094 context.setException( new KSException( "TooFewArguments", tmp.arg( methodname ), -1 ) );
00095 }
00096
00097 void KSUtil::tooManyArgumentsError( KSContext& context, const QString& methodname )
00098 {
00099 QString tmp( i18n("Too many arguments for method %1") );
00100 context.setException( new KSException( "TooManyArguments", tmp.arg( methodname ), -1 ) );
00101 }
00102
00103 bool KSUtil::checkArgs( KSContext& context, const QCString& signature, const QString& method, bool fatal )
00104 {
00105
00106 if ( !KSUtil::checkType( context, context.value(), KSValue::ListType, TRUE ) )
00107 return FALSE;
00108 return KSUtil::checkArgs( context, context.value()->listValue(), signature, method, fatal );
00109 }
00110
00111 bool KSUtil::checkArgs( KSContext& context, const QValueList<KSValue::Ptr>& args,
00112 const QCString& signature, const QString& method, bool fatal )
00113 {
00114 uint done = 0;
00115 uint count = args.count();
00116 uint len = signature.length();
00117 uint pos = 0;
00118 while ( pos < len )
00119 {
00120
00121 if ( done == count && signature[pos] == '|' )
00122 return TRUE;
00123 if ( signature[pos] == '|' )
00124 ++pos;
00125 if ( signature[pos] == 'i' )
00126 {
00127 if ( !checkType( context, args[done], KSValue::IntType, fatal ) )
00128 return FALSE;
00129 ++pos;
00130 }
00131 else if ( signature[pos] == 'f' )
00132 {
00133 if ( !checkType( context, args[done], KSValue::DoubleType, fatal ) )
00134 return FALSE;
00135 ++pos;
00136 }
00137 else if ( signature[pos] == 'b' )
00138 {
00139 if ( !checkType( context, args[done], KSValue::BoolType, fatal ) )
00140 return FALSE;
00141 ++pos;
00142 }
00143 else if ( signature[pos] == 's' )
00144 {
00145 if ( !checkType( context, args[done], KSValue::StringType, fatal ) )
00146 return FALSE;
00147 ++pos;
00148 }
00149 else if ( signature[pos] == 'c' )
00150 {
00151 if ( !checkType( context, args[done], KSValue::CharType, fatal ) )
00152 return FALSE;
00153 ++pos;
00154 }
00155 else if ( signature[pos] == '[' )
00156 {
00157 if ( !checkType( context, args[done], KSValue::ListType, fatal ) )
00158 return FALSE;
00159 ++pos;
00160 if ( signature[pos] == ']' ) { }
00161
00162 }
00163 else if ( signature[pos] == '{' )
00164 {
00165 if ( !checkType( context, args[done], KSValue::MapType, fatal ) )
00166 return FALSE;
00167 ++pos;
00168 if ( signature[pos] == '}' ) { }
00169
00170 }
00171 else if ( signature[pos] == 'S' )
00172 {
00173 if ( !checkType( context, args[done], KSValue::StructType, fatal ) )
00174 return FALSE;
00175 ++pos;
00176 uint x = pos;
00177 while( signature[pos] != ';' && signature[pos] != 0 )
00178 ++pos;
00179 Q_ASSERT( signature[pos] == ';' );
00180 if ( args[done]->structValue()->getClass()->fullName() != signature.mid( x, pos - x ).data() )
00181 {
00182 if ( fatal )
00183 castingError( context, args[done]->structValue()->getClass()->fullName(),
00184 signature.mid( x, pos - x ).data() );
00185 return FALSE;
00186 }
00187 ++pos;
00188 }
00189 else
00190 Q_ASSERT( 0 );
00191
00192 ++done;
00193 }
00194
00195
00196 if ( done < count )
00197 {
00198 if ( fatal )
00199 tooFewArgumentsError( context, method );
00200 return FALSE;
00201 }
00202
00203 return TRUE;
00204 }
00205
00206 bool KSUtil::checkArg( KSContext& context, const KSValue::Ptr& arg,
00207 const QCString& signature, const QString& , bool fatal )
00208 {
00209 int pos = 0;
00210
00211 if ( signature[pos] == 'i' )
00212 return checkType( context, arg, KSValue::IntType, fatal );
00213 else if ( signature[pos] == 'f' )
00214 return checkType( context, arg, KSValue::DoubleType, fatal );
00215 else if ( signature[pos] == 'b' )
00216 return checkType( context, arg, KSValue::BoolType, fatal );
00217 else if ( signature[pos] == 's' )
00218 return checkType( context, arg, KSValue::StringType, fatal );
00219 else if ( signature[pos] == 'c' )
00220 return checkType( context, arg, KSValue::CharType, fatal );
00221 else if ( signature[pos] == '[' )
00222 {
00223 if ( !checkType( context, arg, KSValue::ListType, fatal ) )
00224 return FALSE;
00225 ++pos;
00226
00227 return TRUE;
00228 }
00229 else if ( signature[pos] == '{' )
00230 {
00231 if ( !checkType( context, arg, KSValue::MapType, fatal ) )
00232 return FALSE;
00233 ++pos;
00234
00235 return TRUE;
00236 }
00237 else if ( signature[pos] == 'S' )
00238 {
00239 if ( !checkType( context, arg, KSValue::StructType, fatal ) )
00240 return FALSE;
00241 ++pos;
00242 uint x = pos;
00243 while( signature[pos] != ';' && signature[pos] != 0 )
00244 ++pos;
00245 Q_ASSERT( signature[pos] == ';' );
00246 if ( arg->structValue()->getClass()->fullName() != signature.mid( x, pos - x ).data() )
00247 {
00248 if ( fatal )
00249 castingError( context, arg->structValue()->getClass()->fullName(),
00250 signature.mid( x, pos - x ).data() );
00251 return FALSE;
00252 }
00253 return TRUE;
00254 }
00255
00256 Q_ASSERT( 0 );
00257 return FALSE;
00258 }