kspread Library API Documentation

kspread_functions_logic.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2002 The KSpread Team
00003                            www.koffice.org/kspread
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 // built-in logical functions
00022 
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <float.h>
00026 
00027 #include <koscript_parser.h>
00028 #include <koscript_util.h>
00029 #include <koscript_func.h>
00030 #include <koscript_synext.h>
00031 
00032 #include "kspread_functions.h"
00033 #include "kspread_util.h"
00034 
00035 // prototypes (sorted alphabetically)
00036 bool kspreadfunc_and( KSContext& context );
00037 bool kspreadfunc_false( KSContext& context );
00038 bool kspreadfunc_if( KSContext& context );
00039 bool kspreadfunc_nand( KSContext& context );
00040 bool kspreadfunc_nor( KSContext& context );
00041 bool kspreadfunc_not( KSContext& context );
00042 bool kspreadfunc_or( KSContext& context );
00043 bool kspreadfunc_true( KSContext& context );
00044 bool kspreadfunc_xor( KSContext& context );
00045 
00046 // registers all logic functions
00047 void KSpreadRegisterLogicFunctions()
00048 {
00049   KSpreadFunctionRepository* repo = KSpreadFunctionRepository::self();
00050 
00051   repo->registerFunction( "AND",   kspreadfunc_and );
00052   repo->registerFunction( "FALSE", kspreadfunc_false );
00053   repo->registerFunction( "IF",    kspreadfunc_if );
00054   repo->registerFunction( "NAND",  kspreadfunc_nand );  // KSpread-specific
00055   repo->registerFunction( "NOR",   kspreadfunc_nor );   // KSpread-specific
00056   repo->registerFunction( "NOT",   kspreadfunc_not );
00057   repo->registerFunction( "OR",    kspreadfunc_or );
00058   repo->registerFunction( "TRUE",  kspreadfunc_true );
00059   repo->registerFunction( "XOR",   kspreadfunc_xor );   // KSpread-specific
00060 }
00061 
00062 // Function: FALSE
00063 bool kspreadfunc_false( KSContext & context )
00064 {
00065   context.setValue( new KSValue( FALSE ) );
00066   return true;
00067 }
00068 
00069 // Function: TRUE
00070 bool kspreadfunc_true( KSContext & context )
00071 {
00072   context.setValue( new KSValue( TRUE ) );
00073   return true;
00074 }
00075 
00076 // Function: NOT
00077 bool kspreadfunc_not( KSContext& context )
00078 {
00079   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00080 
00081   if ( !KSUtil::checkArgumentsCount( context, 1, "NOT", true ) || !KSUtil::checkArgumentsCount( context, 1, "not", true ) )
00082     return false;
00083 
00084   if ( !KSUtil::checkType( context, args[0], KSValue::BoolType, true ) )
00085     return false;
00086 
00087   bool toto = !args[0]->boolValue();
00088   context.setValue( new KSValue(toto));
00089   return true;
00090 }
00091 
00092 bool kspreadfunc_or_helper( KSContext& context, QValueList<KSValue::Ptr>& args, bool& first )
00093 {
00094   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00095   QValueList<KSValue::Ptr>::Iterator end = args.end();
00096 
00097   for( ; it != end; ++it )
00098   {
00099     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00100     {
00101       if ( !kspreadfunc_or_helper( context, (*it)->listValue(), first ) )
00102         return false;
00103     }
00104     else if ( KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00105       first = (first || (*it)->boolValue());
00106     else
00107       return false;
00108   }
00109 
00110   return true;
00111 }
00112 
00113 // Function: OR
00114 bool kspreadfunc_or( KSContext& context )
00115 {
00116   bool first = false;
00117   bool b = kspreadfunc_or_helper( context, context.value()->listValue(), first );
00118 
00119   if ( b )
00120     context.setValue( new KSValue( first ) );
00121 
00122   return b;
00123 }
00124 
00125 // Function: NOR
00126 bool kspreadfunc_nor( KSContext& context )
00127 {
00128   bool first = false;
00129   bool b = kspreadfunc_or_helper( context, context.value()->listValue(), first );
00130 
00131   if ( b )
00132     context.setValue( new KSValue( !first ) );
00133 
00134   return b;
00135 }
00136 
00137 
00138 bool kspreadfunc_and_helper( KSContext& context, QValueList<KSValue::Ptr>& args, bool& first )
00139 {
00140   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00141   QValueList<KSValue::Ptr>::Iterator end = args.end();
00142 
00143   for( ; it != end; ++it )
00144   {
00145     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00146     {
00147       if ( !kspreadfunc_and_helper( context, (*it)->listValue(), first ) )
00148         return false;
00149     }
00150     else if ( KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00151       first = first && (*it)->boolValue();
00152     else
00153       return false;
00154   }
00155 
00156   return true;
00157 }
00158 
00159 // Function: AND
00160 bool kspreadfunc_and( KSContext& context )
00161 {
00162   bool first = true;
00163   bool b = kspreadfunc_and_helper( context, context.value()->listValue(), first );
00164 
00165   if ( b )
00166     context.setValue( new KSValue( first ) );
00167 
00168   return b;
00169 }
00170 
00171 // Function: NAND
00172 bool kspreadfunc_nand( KSContext& context )
00173 {
00174   bool first = true;
00175   bool b = kspreadfunc_and_helper( context, context.value()->listValue(), first );
00176 
00177   if ( b )
00178     context.setValue( new KSValue( !first ) );
00179 
00180   return b;
00181 }
00182 
00183 static bool kspreadfunc_xor_helper( KSContext& context, QValueList<KSValue::Ptr>& args, bool& first )
00184 {
00185   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00186   QValueList<KSValue::Ptr>::Iterator end = args.end();
00187 
00188   for( ; it != end; ++it )
00189   {
00190     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00191     {
00192       if ( !kspreadfunc_xor_helper( context, (*it)->listValue(), first ) )
00193         return false;
00194     }
00195     else if ( KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00196       first = first ^ (*it)->boolValue();
00197     else
00198       return false;
00199   }
00200 
00201   return true;
00202 }
00203 
00204 // Function: XOR
00205 bool kspreadfunc_xor( KSContext& context )
00206 {
00207   bool first = false;
00208   bool b = kspreadfunc_xor_helper( context, context.value()->listValue(), first );
00209 
00210   if ( b )
00211     context.setValue( new KSValue( first ) );
00212 
00213   return b;
00214 }
00215 
00216 // Function: IF
00217 bool kspreadfunc_if( KSContext& context )
00218 {
00219     QValueList<KSValue::Ptr>& args = context.value()->listValue();
00220 
00221     if ( !KSUtil::checkArgumentsCount( context, 3, "if", true ) || !KSUtil::checkArgumentsCount( context, 3, "IF", true ))
00222       return false;
00223 
00224     if ( !KSUtil::checkType( context, args[0], KSValue::BoolType, true ) )
00225       return false;
00226 
00227     if (  args[0]->boolValue() == true )
00228       context.setValue( new KSValue( *(args[1]) ) );
00229     else
00230       context.setValue( new KSValue( *(args[2]) ) );
00231 
00232     return true;
00233 }
KDE Logo
This file is part of the documentation for kspread Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:43:10 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003