Ignore:
Timestamp:
03/01/15 01:19:56 (9 years ago)
Author:
Maciej Komosinski
Message:
  • use source/code mapping for line number and file information in vm error messages
  • enum ExtValue::CompareResult? instead of int
File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/util/extvalue.cpp

    r326 r333  
    1313#include <common/Convert.h>
    1414#include <climits>
     15#include <errno.h>
    1516
    1617#ifndef NO_BARRIER
     
    290291}
    291292
    292 static int longsign(paInt x)
    293 {
    294 if (x<0) return -1;
    295 if (x>0) return 1;
    296 return 0;
    297 }
    298 
    299 static int compareNull(const ExtValue& v)
    300 {
    301 switch(v.type)
    302         {
    303         case TDouble: return v.getDouble()!=0.0;
    304         case TInt: return v.getInt()?1:0;
    305         case TString: return 1;
    306         default: return !v.isNull();
    307         }
    308 }
    309 
    310 int ExtValue::compare(const ExtValue& src) const
     293static ExtValue::CompareResult longsign(paInt x)
     294{
     295if (x<0) return ExtValue::ResultLower;
     296if (x>0) return ExtValue::ResultHigher;
     297return ExtValue::ResultEqual;
     298}
     299
     300static ExtValue::CompareResult compareNull(const ExtValue& v)
     301{
     302if (v.isNull()) return ExtValue::ResultEqualUnordered;
     303if ((v.getType()==TInt)&&(v.getInt()==0)) return ExtValue::ResultUnequal_RelaxedEqual;
     304return ExtValue::ResultUnequal_RelaxedUnequal; //comparing anything else with null is valid but null is neither higher nor lower than numbers or strings
     305}
     306
     307static ExtValue::CompareResult compareFloat(double a,double b)
     308{
     309double t=a-b;
     310if (t<0) return ExtValue::ResultLower;
     311else if (t>0) return ExtValue::ResultHigher;
     312return ExtValue::ResultEqual;
     313}
     314
     315static ExtValue::CompareResult compareString(const SString &a,const SString &b)
     316{
     317const char* s1=(const char*)a;
     318const char* s2=(const char*)b;
     319return longsign(strcmp(s1,s2));
     320}
     321
     322ExtValue::CompareResult ExtValue::compare(const ExtValue& src) const
    311323{
    312324if (isNull())
     
    316328switch(type)
    317329        {
     330
    318331        case TInt:
    319         {
    320         paInt t=src.getInt();
    321         if (idata()>0)
    322                 {if (t>0) return longsign(idata()-t); else return +1;}
    323         else
    324                 {if (t<=0) return longsign(idata()-t); else return -1;}
    325         }
     332
     333                if (src.getType()==TInt)
     334                        {
     335                        paInt t=src.getInt();
     336                        if (idata()>0)
     337                                {if (t>0) return longsign(idata()-t); else return ResultHigher;}
     338                        else
     339                                {if (t<=0) return longsign(idata()-t); else return ResultLower;}
     340                        }
     341                else if (src.getType()==TDouble)
     342                        return compareFloat((double)idata(),src.getDouble());
     343                else
     344                        return ResultMismatch;//comparing numbers with other things is invalid
     345                break;
     346
    326347        case TDouble:
    327                 {
    328                 double t=ddata()-src.getDouble();
    329                 if (t<0) return -1;
    330                 else if (t>0) return 1;
    331                 return 0;
    332                 }
     348                if ((src.getType()==TDouble)||(src.getType()==TInt))
     349                        return compareFloat(getDouble(),src.getDouble());
     350                else
     351                        return ResultMismatch;
     352                break;
     353
    333354        case TString:
    334         {
    335         SString t=src.getString();
    336         SString& t2=sdata();
    337         const char* s1=(const char*)t2;
    338         const char* s2=(const char*)t;
    339         return longsign(strcmp(s1,s2));
    340         }
     355                if (src.getType()==TString)
     356                        return compareString(sdata(),src.getString());
     357                else
     358                        return ResultMismatch;
     359                break;
     360
    341361        case TObj:
    342362        {
    343363        if (src.type==TObj)
    344                 return !(odata()==src.odata());
    345         return 1;
     364                return odata()==src.odata() ? ResultEqualUnordered : ResultUnequal_RelaxedUnequal;
     365        if ((src.type==TInt)&&(src.getInt()==0))
     366                return ResultMismatch_RelaxedUnequal;
     367        return ResultMismatch;
    346368        }
    347369        default:;
    348370        }
    349 return 1;
     371return ResultMismatch;
     372}
     373
     374ExtValue::CmpMessageHandler ExtValue::default_cmp_message;
     375ExtValue::CmpContext ExtValue::default_cmp_context={NULL,NULL,&default_cmp_message};
     376
     377const char* ExtValue::cmp_op_names[]={"==","!=",">=","<=",">","<","~=","!~",NULL};
     378
     379void ExtValue::CmpMessageHandler::cmpMessage(SString& text)
     380{
     381FMprintf("ExtValue","interpretCompare",FMLV_ERROR,"%s",(const char*)text);
     382}
     383
     384int ExtValue::interpretCompare(CmpOperator op,CompareResult result,CmpContext *context)
     385{
     386int err=ResultUnequal_RelaxedEqual;//error when ResultUnequal_RelaxedEqual or higher (not comparable)
     387int ret=0;
     388switch (op)
     389        {
     390        case CmpEQ: ret=(result==ResultEqual)||(result==ResultEqualUnordered); err=ResultMismatch_RelaxedUnequal; break;
     391        case CmpNE: ret=!((result==ResultEqual)||(result==ResultEqualUnordered)); err=ResultMismatch_RelaxedUnequal; break;
     392        case CmpGT: ret=(result==ResultHigher); err=ResultEqualUnordered; break;
     393        case CmpGE: ret=(result==ResultEqual)||(result==ResultHigher); err=ResultEqualUnordered; break;
     394        case CmpLT: ret=(result==ResultLower); err=ResultEqualUnordered; break;
     395        case CmpLE: ret=(result==ResultEqual)||(result==ResultLower); err=ResultEqualUnordered; break;
     396        case CmpREQ: ret=(result==ResultEqual)||(result==ResultEqualUnordered)||(result==ResultUnequal_RelaxedEqual); err=ResultMismatch; break;
     397        case CmpRNE: ret=!((result==ResultEqual)||(result==ResultEqualUnordered)||(result==ResultUnequal_RelaxedEqual)); err=ResultMismatch; break;
     398        default:;
     399        }
     400if (result>=err)
     401        {
     402        if (context)
     403                {
     404                SString msg="Type mismatch";
     405                if (context->v1 && context->v2)
     406                        {
     407                        const char* opname=cmp_op_names[op-CmpFIRST];
     408                        msg+=": ";
     409                        if (context->v1->isNull())
     410                                msg+="null ";
     411                        else
     412                                msg+=SString::sprintf("%s '%s' ",(const char*)context->v1->typeDescription(),(const char*)context->v1->getString());
     413                        msg+=opname;
     414                        if (context->v2->isNull())
     415                                msg+=" null";
     416                        else
     417                                msg+=SString::sprintf(" %s '%s'",(const char*)context->v2->typeDescription(),(const char*)context->v2->getString());
     418                        }
     419                context->handler->cmpMessage(msg);
     420                }
     421        ret=-1;
     422        }
     423return ret;
    350424}
    351425
     
    814888                return ret+1;
    815889        else
     890                {
     891                FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing '\"' in string: '%s'",ret);
    816892                return NULL;
     893                }
    817894        }
    818895else if (*in=='[')
     
    832909                        p=ret;
    833910                        if (*p==',') p++;
     911                        else if (*p!=']')
     912                                {
     913                                FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ',' in Vector: '%s'",p);
     914                                return NULL;
     915                                }
    834916                        }
    835917                else
     
    855937                if ((!ret)||(args[1].getType()!=TString)) {p=NULL;break;}
    856938                p=ret;
    857                 if (*p!=':') {p=NULL;break;}
     939                if (*p!=':') {FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ':' in Dictionary: '%s'",p);p=NULL;break;}
    858940                p++;
    859941                ret=args[0].deserialize(p);
     
    862944                dic->p_set(args,&dummy_ret);
    863945                if (*p==',') p++;
     946                else if (*p!='}')
     947                        {
     948                        FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ',' in Dictionary: '%s'",p);
     949                        return NULL;
     950                        }
    864951                }
    865952        setObject(o);
     
    899986                        }
    900987                }
     988        FMprintf("ExtValue","deserialize",FMLV_ERROR,"Invalid reference: '%s'",in-1);
    901989        return NULL;
    902990        }
     
    9481036        return ret;
    9491037        }
     1038FMprintf("ExtValue","deserialize",FMLV_ERROR,"Bad syntax: '%s'",in);
    9501039setEmpty();
    9511040return NULL;
     
    9681057ExtValue ExtValue::getExtType()
    9691058{
    970 if (getType()!=TObj) return ExtValue((paInt)getType());
     1059static const char* typenames[]={"null","int","float","string","","invalid"};
     1060if (getType()!=TObj)
     1061        return ExtValue(typenames[(int)getType()]);
    9711062ExtObject& o=odata();
    9721063return ExtValue(SString(o.isEmpty()?"":o.interfaceName()));
Note: See TracChangeset for help on using the changeset viewer.