- Timestamp:
- 03/01/15 01:19:56 (10 years ago)
- Location:
- cpp/frams
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/param/multiparamload.cpp
r286 r333 21 21 aborting=false; 22 22 emptyparam.setParamTab(empty_paramtab); 23 linenum=0; 23 24 } 24 25 … … 99 100 Param tmp_param; 100 101 ParamInterface *pi=lastobject.getParamInterface(tmp_param); 101 pi->load(file,true,&aborting );102 pi->load(file,true,&aborting,&linenum); 102 103 if ((status!=Finished) && maybeBreak(AfterObject)) 103 104 break; … … 120 121 continue; 121 122 } 123 linenum++; 122 124 if (buf[0]=='#') 123 125 { … … 245 247 Param tmp_param; 246 248 ParamInterface *pi=o.getParamInterface(tmp_param); 247 pi->load(file,warn_unknown_fields,&aborting );249 pi->load(file,warn_unknown_fields,&aborting,&linenum); 248 250 status=AfterObject; 249 251 return 0; -
cpp/frams/param/multiparamload.h
r286 r333 46 46 Param emptyparam; 47 47 bool aborting; 48 int linenum; 48 49 49 50 void init(); -
cpp/frams/param/param.cpp
r326 r333 37 37 static const char *strchrlimit(const char *t, int ch, const char *limit) 38 38 { 39 if (limit <t) return NULL;40 return (const char*)memchr((const void*)t, ch,limit-t);39 if (limit < t) return NULL; 40 return (const char*)memchr((const void*)t, ch, limit - t); 41 41 } 42 42 … … 392 392 } 393 393 394 int ParamInterface::load(VirtFILE* f, bool warn_unknown_fields, bool *abortable )394 int ParamInterface::load(VirtFILE* f, bool warn_unknown_fields, bool *abortable, int *linenum) 395 395 { 396 396 SString buf; … … 402 402 while (((!abortable) || (!*abortable)) && loadSStringLine(f, buf)) 403 403 { 404 if (linenum) (*linenum)++; 404 405 const char* t = (const char*)buf; 405 406 p0 = t; while ((*p0 == ' ') || (*p0 == '\t')) p0++; … … 417 418 SString s; 418 419 czytdotyldy(f, s); 420 int lfcount = 1; 421 const char* tmp = s; 422 while (tmp) 423 if ((tmp = strchr(tmp, '\n'))) 424 { 425 lfcount++; tmp++; 426 } 419 427 removeCR(s); 420 428 int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break; 421 429 unquoteTilde(s); 430 if (linenum && (flags(i)&PARAM_LINECOMMENT)) 431 s = SString::sprintf("@line %d\n", *linenum + 1) + s; 422 432 set(i, (const char*)s); 433 if (linenum) 434 (*linenum) += lfcount; 423 435 } 424 436 else … … 440 452 SString s; 441 453 czytdotyldy(f, s); 454 if (linenum) 455 { 456 const char* tmp = s; 457 int lfcount = 1; 458 while (tmp) 459 if ((tmp = strchr(tmp, '\n'))) 460 { 461 lfcount++; tmp++; 462 } 463 (*linenum) += lfcount; 464 } 442 465 int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break; 443 466 } … … 453 476 switch (*(t=type(i))) 454 477 { 455 456 457 458 459 460 461 462 463 464 465 466 467 468 478 case 'd': 479 { 480 for (i=atol(get(i));i>=0;i--) if (t) t=strchr(t+1,'~'); 481 if (t) 482 { 483 t++; 484 char *t2=strchr(t,'~'); 485 if (!t2) t2=t+strlen(t); 486 SString str; 487 strncpy(str.directWrite(t2-t),t,t2-t); 488 str.endWrite(t2-t); 489 return str; 490 } 491 } 469 492 } 470 493 return get(i); … … 502 525 { 503 526 paInt value; 504 if (!ExtValue::parseInt(str, value,false,true))527 if (!ExtValue::parseInt(str, value, false, true)) 505 528 { 506 529 paInt mn, mx, def; … … 517 540 { 518 541 double value; 519 if (!ExtValue::parseDouble(str, value,true))542 if (!ExtValue::parseDouble(str, value, true)) 520 543 { 521 544 double mn, mx, def; … … 538 561 { 539 562 if (v.type == TObj) 563 { 540 564 FMprintf("ParamInterface", "set", FMLV_WARN, "Getting integer value from object reference (%s)", (const char*)v.getString()); 541 return setInt(i, (const char*)v.getString()); 565 return 0; 566 } 567 else 568 return setInt(i, (const char*)v.getString()); 542 569 } 543 570 case 'f': … … 546 573 { 547 574 if (v.type == TObj) 575 { 548 576 FMprintf("ParamInterface", "set", FMLV_WARN, "Getting floating point value from object reference (%s)", (const char*)v.getString()); 549 return setDouble(i, (const char*)v.getString()); 577 return 0; 578 } 579 else 580 return setDouble(i, (const char*)v.getString()); 550 581 } 551 582 case 's': { SString t = v.getString(); return setString(i, t); } … … 995 1026 996 1027 field_end = strchrlimit(t, ',', end); if (!field_end) field_end = end; 997 next_field =field_end;1028 next_field = field_end; 998 1029 while ((field_end>t) && isblank(field_end[-1])) field_end--; 999 1030 quote = strchrlimit(t, '\"', field_end); -
cpp/frams/param/param.h
r319 r333 32 32 #define PARAM_NOISOLATION 4096 //< don't use proxy object in master/slave interactions 33 33 #define PARAM_DEPRECATED 8192 //< this member is deprecated 34 #define PARAM_LINECOMMENT 16384 //< Param::load() adds "@line ..." comment when loading multiline (internal use) 34 35 35 36 typedef int32_t paInt; … … 160 161 int save(VirtFILE*, const char* altname = NULL, bool force = 0); 161 162 int saveprop(VirtFILE*, int i, const char* p, bool force = 0); 162 int load(VirtFILE*, bool warn_unknown_fields=true,bool *abortable=NULL);///< @return the number of fields loaded163 int load(VirtFILE*, bool warn_unknown_fields = true, bool *abortable = NULL, int *linenum = NULL);///< @return the number of fields loaded 163 164 int load2(const SString &, int &);///< @return the number of fields loaded 164 165 -
cpp/frams/param/paramobj.h
r326 r333 15 15 int numfields; 16 16 Param par; 17 #ifdef _MSC_VER 18 #pragma warning(push) 19 #pragma warning(disable: 4200) //Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array 20 #endif 17 21 ExtValue fields[0]; 22 #ifdef _MSC_VER 23 #pragma warning(pop) 24 #endif 18 25 ParamObject() { numfields = 0; } 19 26 ~ParamObject(); … … 21 28 void* operator new(size_t s, int numfields){ return ::operator new(s + sizeof(ExtValue)*numfields); } 22 29 void* operator new(size_t s){ return ::operator new(s); } 30 void operator delete(void* ptr, int numfields) { ::operator delete(ptr); } 31 void operator delete(void* ptr) { ::operator delete(ptr); } 23 32 ParamObject *clone(); 24 33 static void p_new(void* obj, ExtValue *args, ExtValue *ret); -
cpp/frams/util/extvalue.cpp
r326 r333 13 13 #include <common/Convert.h> 14 14 #include <climits> 15 #include <errno.h> 15 16 16 17 #ifndef NO_BARRIER … … 290 291 } 291 292 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 293 static ExtValue::CompareResult longsign(paInt x) 294 { 295 if (x<0) return ExtValue::ResultLower; 296 if (x>0) return ExtValue::ResultHigher; 297 return ExtValue::ResultEqual; 298 } 299 300 static ExtValue::CompareResult compareNull(const ExtValue& v) 301 { 302 if (v.isNull()) return ExtValue::ResultEqualUnordered; 303 if ((v.getType()==TInt)&&(v.getInt()==0)) return ExtValue::ResultUnequal_RelaxedEqual; 304 return ExtValue::ResultUnequal_RelaxedUnequal; //comparing anything else with null is valid but null is neither higher nor lower than numbers or strings 305 } 306 307 static ExtValue::CompareResult compareFloat(double a,double b) 308 { 309 double t=a-b; 310 if (t<0) return ExtValue::ResultLower; 311 else if (t>0) return ExtValue::ResultHigher; 312 return ExtValue::ResultEqual; 313 } 314 315 static ExtValue::CompareResult compareString(const SString &a,const SString &b) 316 { 317 const char* s1=(const char*)a; 318 const char* s2=(const char*)b; 319 return longsign(strcmp(s1,s2)); 320 } 321 322 ExtValue::CompareResult ExtValue::compare(const ExtValue& src) const 311 323 { 312 324 if (isNull()) … … 316 328 switch(type) 317 329 { 330 318 331 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 326 347 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 333 354 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 341 361 case TObj: 342 362 { 343 363 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; 346 368 } 347 369 default:; 348 370 } 349 return 1; 371 return ResultMismatch; 372 } 373 374 ExtValue::CmpMessageHandler ExtValue::default_cmp_message; 375 ExtValue::CmpContext ExtValue::default_cmp_context={NULL,NULL,&default_cmp_message}; 376 377 const char* ExtValue::cmp_op_names[]={"==","!=",">=","<=",">","<","~=","!~",NULL}; 378 379 void ExtValue::CmpMessageHandler::cmpMessage(SString& text) 380 { 381 FMprintf("ExtValue","interpretCompare",FMLV_ERROR,"%s",(const char*)text); 382 } 383 384 int ExtValue::interpretCompare(CmpOperator op,CompareResult result,CmpContext *context) 385 { 386 int err=ResultUnequal_RelaxedEqual;//error when ResultUnequal_RelaxedEqual or higher (not comparable) 387 int ret=0; 388 switch (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 } 400 if (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 } 423 return ret; 350 424 } 351 425 … … 814 888 return ret+1; 815 889 else 890 { 891 FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing '\"' in string: '%s'",ret); 816 892 return NULL; 893 } 817 894 } 818 895 else if (*in=='[') … … 832 909 p=ret; 833 910 if (*p==',') p++; 911 else if (*p!=']') 912 { 913 FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ',' in Vector: '%s'",p); 914 return NULL; 915 } 834 916 } 835 917 else … … 855 937 if ((!ret)||(args[1].getType()!=TString)) {p=NULL;break;} 856 938 p=ret; 857 if (*p!=':') { p=NULL;break;}939 if (*p!=':') {FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ':' in Dictionary: '%s'",p);p=NULL;break;} 858 940 p++; 859 941 ret=args[0].deserialize(p); … … 862 944 dic->p_set(args,&dummy_ret); 863 945 if (*p==',') p++; 946 else if (*p!='}') 947 { 948 FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ',' in Dictionary: '%s'",p); 949 return NULL; 950 } 864 951 } 865 952 setObject(o); … … 899 986 } 900 987 } 988 FMprintf("ExtValue","deserialize",FMLV_ERROR,"Invalid reference: '%s'",in-1); 901 989 return NULL; 902 990 } … … 948 1036 return ret; 949 1037 } 1038 FMprintf("ExtValue","deserialize",FMLV_ERROR,"Bad syntax: '%s'",in); 950 1039 setEmpty(); 951 1040 return NULL; … … 968 1057 ExtValue ExtValue::getExtType() 969 1058 { 970 if (getType()!=TObj) return ExtValue((paInt)getType()); 1059 static const char* typenames[]={"null","int","float","string","","invalid"}; 1060 if (getType()!=TObj) 1061 return ExtValue(typenames[(int)getType()]); 971 1062 ExtObject& o=odata(); 972 1063 return ExtValue(SString(o.isEmpty()?"":o.interfaceName())); -
cpp/frams/util/extvalue.h
r326 r333 136 136 static ExtValue invalid() { ExtValue v; v.setInvalid(); return v; } 137 137 static const ExtValue& empty() { static const ExtValue v; return v; } 138 int compare(const ExtValue& src) const; 138 static const ExtValue& zero() { static const ExtValue v(0); return v; } 139 140 enum CompareResult 141 { 142 ResultLower=-1, ResultEqual=0, ResultHigher=1, 143 ResultEqualUnordered, 144 ResultUnequal_RelaxedEqual, 145 ResultUnequal_RelaxedUnequal, 146 ResultMismatch_RelaxedUnequal, 147 ResultMismatch 148 }; 149 // performs all script value comparisons. 150 // relaxed comparison (internal use only, not available in scripts) works like regular == with additional null~=0, notnull!~0 151 // and is used for pseudo-boolean conversion allowing for expressions like "if (null) ..." 152 CompareResult compare(const ExtValue& src) const; 153 154 enum CmpOperator { CmpFIRST,CmpEQ=CmpFIRST,CmpNE,CmpGE,CmpLE,CmpGT,CmpLT,/*relaxed (not)equal*/CmpREQ,CmpRNE }; 155 static const char* cmp_op_names[]; 156 class CmpMessageHandler { public: virtual void cmpMessage(SString& text); }; 157 struct CmpContext { const ExtValue *v1,*v2; CmpMessageHandler *handler; }; 158 static CmpMessageHandler default_cmp_message; 159 static CmpContext default_cmp_context; 160 // interpret compare() result, optional context controls error messages 161 // @return 0=false, 1=true, -1=undefined (null in script) 162 static int interpretCompare(CmpOperator op,CompareResult result,CmpContext *context=&default_cmp_context); 163 139 164 int operator==(const ExtValue& src) const; 140 165 void operator+=(const ExtValue& src); … … 154 179 void setInvalid() { setEmpty(); type = TInvalid; } 155 180 bool makeUnique() { return (type == TObj) && odata().makeUnique(); } //< @return false if nothing has changed 156 ExtPType getType() { return type; }181 ExtPType getType() const { return type; } 157 182 void *getObjectTarget(const char* classname, bool warn = true) const; 158 183 void setInt(paInt v) { if (type != TInt) setri(v); else idata() = v; } -
cpp/frams/vm/classes/collectionobj.cpp
r286 r333 203 203 { 204 204 public: 205 bool operator()(const ExtValue *a,const ExtValue *b) {return a->compare(*b) <0;}205 bool operator()(const ExtValue *a,const ExtValue *b) {return a->compare(*b)==ExtValue::ResultLower;} 206 206 }; 207 207 -
cpp/frams/vm/framscript.y
r332 r333 28 28 void warnTruthValue(const TokenValue& t); 29 29 void outFunName(const TokenValue& t); 30 static bool resultIsRelaxedEqual(ExtValue::CompareResult res); 30 31 31 32 static const char* assign_op_names[]={"add","sub","mul","div","mod"}; … … 46 47 %left NEG /* negation--unary minus */ 47 48 %left TYPEOF 48 %left INT 49 %left FLOAT 50 %left STRING 49 %left INT_TYPE 50 %left FLOAT_TYPE 51 %left STRING_TYPE 51 52 52 53 %token IDENT … … 67 68 %token DEFAULT "default" 68 69 69 %token TYPEOF "typeof"70 %token INT 71 %token FLOAT 72 %token STRING 70 %token TYPEOF "typeof" 71 %token INT_TYPE "int" 72 %token FLOAT_TYPE "float" 73 %token STRING_TYPE "string" 73 74 74 75 %token ASM … … 704 705 {trctx.out->printf("type s0,s0\n");} 705 706 } 706 | INT '(' expr ')' { trctx.emitLine(); $$.ident=0;707 | INT_TYPE '(' expr ')' { trctx.emitLine(); $$.ident=0; 707 708 if ($3.constant) 708 709 {$$.constant=1; $$=ExtValue($3.getInt());} … … 710 711 {trctx.out->printf("conv 1,s0\n");} 711 712 } 712 | FLOAT '(' expr ')' { trctx.emitLine(); $$.ident=0;713 | FLOAT_TYPE '(' expr ')' { trctx.emitLine(); $$.ident=0; 713 714 if ($3.constant) 714 715 {$$.constant=1; $$=ExtValue($3.getDouble());} … … 716 717 {trctx.out->printf("conv 2,s0\n");} 717 718 } 718 | STRING '(' expr ')' { trctx.emitLine(); $$.ident=0;719 | STRING_TYPE '(' expr ')' { trctx.emitLine(); $$.ident=0; 719 720 if ($3.constant) 720 721 {$$.constant=1; $$=ExtValue($3.getString());} … … 748 749 if ($1.constant) 749 750 { 750 int cond=$1.compare(ExtValue::zero());751 if ( (cond==0)||(cond==2))751 ExtValue::CompareResult cond=$1.compare(ExtValue::zero()); 752 if (resultIsRelaxedEqual(cond)) 752 753 { 753 754 $1.counter=0; … … 776 777 if (!($1.constant && $1.counter==0)) 777 778 { 778 intcond=$4.compare(ExtValue::zero());779 bool value=! ((cond==0)||(cond==2));779 ExtValue::CompareResult cond=$4.compare(ExtValue::zero()); 780 bool value=!resultIsRelaxedEqual(cond); 780 781 trstack.adjust(-1); 781 782 trctx.out->printf("push %d\n",value); … … 803 804 if ($1.constant) 804 805 { 805 intcond=$1.compare(ExtValue::zero());806 if (! ((cond==0)||(cond==2)))806 ExtValue::CompareResult cond=$1.compare(ExtValue::zero()); 807 if (!resultIsRelaxedEqual(cond)) 807 808 { 808 809 $1.counter=1; … … 831 832 if (!($1.constant && $1.counter==1)) 832 833 { 833 int cond=$4.compare(ExtValue::zero());834 bool value=! ((cond==0)||(cond==2));834 ExtValue::CompareResult cond=$4.compare(ExtValue::zero()); 835 bool value=!resultIsRelaxedEqual(cond); 835 836 trstack.adjust(-1); 836 837 trctx.out->printf("push %d\n",value); … … 854 855 trctx.emitLine(); $$.assign=$2.assign; $$.parens=0; $$.ident=0; 855 856 if ($2.constant) 856 {$$.constant=1; int res=$2.compare(ExtValue((paInt)0)); $$.setInt((res==0)||(res==2));}857 {$$.constant=1; ExtValue::CompareResult res=$2.compare(ExtValue((paInt)0)); $$.setInt(resultIsRelaxedEqual(res));} 857 858 else 858 859 {trctx.out->printf("setif ~=,s0,s0\n");} … … 1427 1428 { 1428 1429 result.constant=1; 1429 int cmp=arg1.compare(arg2);1430 ExtValue::CompareResult cmp=arg1.compare(arg2); 1430 1431 ExtValue::CmpContext context; 1431 1432 context.v1=&arg1; … … 1458 1459 } 1459 1460 1461 static bool resultIsRelaxedEqual(ExtValue::CompareResult res) 1462 { 1463 return (res==ExtValue::ResultEqual)||(res==ExtValue::ResultEqualUnordered)||(res==ExtValue::ResultUnequal_RelaxedEqual); 1464 } 1465 1460 1466 bool variableOk(TokenValue &tok, const TokenValue& var,int &loc) 1461 1467 {
Note: See TracChangeset
for help on using the changeset viewer.