- Timestamp:
- 02/02/17 15:14:19 (8 years ago)
- Location:
- cpp/frams/param
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/param/param.cpp
r645 r650 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 20 20 { { "Empty", 1, 0, "Empty", }, { 0, 0, 0, }, }; 21 21 22 static void czytdotyldy(VirtFILE *f, SString &s) 22 /** return: true if tilde was found, false if finished at EOF */ 23 static bool readUntilTilde(VirtFILE *f, SString &s) 23 24 { 24 25 SString temp; 25 26 int z; 26 27 char last_char = 0; 28 bool tilde_found = false; 27 29 while ((z = f->Vgetc()) != EOF) 28 30 { 29 31 if (z == '~') 30 if (last_char != '\\') break;32 if (last_char != '\\') { tilde_found = true; break; } 31 33 last_char = (char)z; 32 34 temp += last_char; 33 35 } 34 36 s = temp; 37 return tilde_found; 35 38 } 36 39 … … 72 75 int ParamInterface::getMinMax(int prop, paInt& minumum, paInt& maximum, paInt &def) 73 76 { 74 return getMinMax(type(prop), minumum,maximum,def);77 return getMinMax(type(prop), minumum, maximum, def); 75 78 } 76 79 77 80 int ParamInterface::getMinMax(int prop, double& minumum, double& maximum, double& def) 78 81 { 79 return getMinMax(type(prop), minumum,maximum,def);82 return getMinMax(type(prop), minumum, maximum, def); 80 83 } 81 84 82 85 int ParamInterface::getMinMax(int prop, int& minumum, int& maximum, SString& def) 83 86 { 84 return getMinMax(type(prop), minumum,maximum,def);87 return getMinMax(type(prop), minumum, maximum, def); 85 88 } 86 89 … … 404 407 } 405 408 409 static void closingTildeError(ParamInterface *pi, VirtFILE *file, int field_index) 410 { 411 SString fileinfo; 412 const char* fname = file->VgetPath(); 413 if (fname != NULL) 414 fileinfo = SString::sprintf(" while reading from '%s'", fname); 415 SString field; 416 if (field_index >= 0) 417 field = SString::sprintf("'%s.%s'", pi->getName(), pi->id(field_index)); 418 else 419 field = SString::sprintf("unknown property of '%s'", pi->getName()); 420 logPrintf("ParamInterface", "load", LOG_WARN, "Closing '~' (tilde) not found in %s%s", field.c_str(), fileinfo.c_str()); 421 } 422 406 423 int ParamInterface::load(VirtFILE* f, bool warn_unknown_fields, bool *abortable, int *linenum) 407 424 { … … 415 432 vector<bool> seen; 416 433 seen.resize(getPropCount()); 417 if ((i =findId("beforeLoad"))>=0)418 call(i, NULL,NULL);434 if ((i = findId("beforeLoad")) >= 0) 435 call(i, NULL, NULL); 419 436 while (((!abortable) || (!*abortable)) && loadSStringLine(f, buf)) 420 437 { … … 426 443 p = strchr(p0, ':'); 427 444 if (!p) 445 { 446 switch (unexpected_line) 428 447 { 429 switch(unexpected_line) 430 { 431 case 0: 432 logPrintf("ParamInterface", "load", LOG_WARN, "Ignored unexpected line %s while reading object '%s'", 433 linenum ? 434 SString::sprintf("%d",*linenum).c_str() 448 case 0: 449 logPrintf("ParamInterface", "load", LOG_WARN, "Ignored unexpected line %s while reading object '%s'", 450 linenum ? 451 SString::sprintf("%d", *linenum).c_str() 435 452 : SString::sprintf("'%s'", p0).c_str(), 436 437 438 439 440 441 453 getName()); 454 break; 455 case 1: 456 logPrintf("ParamInterface", "load", LOG_WARN, "The following line(s) were also unexpected and were ignored"); 457 break; 458 } 442 459 unexpected_line++; 443 460 continue; 444 461 } 445 462 unexpected_line = 0; 446 463 p_len = (int)(p - p0); … … 449 466 { 450 467 if (seen[i]) 468 { 469 SString fileinfo; 470 const char* fname = f->VgetPath(); 471 if (fname != NULL) 451 472 { 452 SString fileinfo; 453 const char* fname=f->VgetPath(); 454 if (fname!=NULL) 455 { 456 fileinfo=SString::sprintf(" while reading from '%s'",fname); 473 fileinfo = SString::sprintf(" while reading from '%s'", fname); 457 474 if (linenum) 458 fileinfo+=SString::sprintf(" (line %d)",*linenum); 459 } 460 logPrintf("ParamInterface", "load", LOG_WARN, "Multiple '%s.%s' fields found%s",getName(),id(i),fileinfo.c_str()); 475 fileinfo += SString::sprintf(" (line %d)", *linenum); 461 476 } 477 logPrintf("ParamInterface", "load", LOG_WARN, "Multiple '%s.%s' fields found%s", getName(), id(i), fileinfo.c_str()); 478 } 462 479 else 463 seen[i] =true;480 seen[i] = true; 464 481 if (!(flags(i)&PARAM_DONTLOAD)) 465 482 { … … 467 484 { 468 485 SString s; 469 czytdotyldy(f, s); 486 if (!readUntilTilde(f, s)) 487 closingTildeError(this, f, i); 470 488 int lfcount = 1; 471 489 const char* tmp = s.c_str(); … … 501 519 { // eat unrecognized multiline field 502 520 SString s; 503 czytdotyldy(f, s); 521 if (!readUntilTilde(f, s)) 522 closingTildeError(this, f, -1); 504 523 if (linenum) 505 524 { … … 516 535 } 517 536 } 518 if ((i =findId("afterLoad"))>=0)519 call(i, NULL,NULL);537 if ((i = findId("afterLoad")) >= 0) 538 call(i, NULL, NULL); 520 539 return fields_loaded; 521 540 } … … 634 653 case 's': { SString t = v.getString(); return setString(i, t); } 635 654 case 'o': 636 if ((v.type !=TUnknown)&&(v.type!=TObj))655 if ((v.type != TUnknown) && (v.type != TObj)) 637 656 logPrintf("ParamInterface", "set", LOG_ERROR, "Setting object '%s.%s' from %s", getName(), id(i), v.typeAndValue().c_str()); 638 657 else … … 724 743 bool ParamInterface::isValidTypeDescription(const char* t) 725 744 { 726 if (t==NULL) return false;727 if (*t==0) return false;728 if (strchr("dfsoxp", *t)==NULL) return false;729 switch(*t)745 if (t == NULL) return false; 746 if (*t == 0) return false; 747 if (strchr("dfsoxp", *t) == NULL) return false; 748 switch (*t) 730 749 { 731 750 case 'd': 732 {paInt a,b,c; if (getMinMax(t,a,b,c)==1) return false;}751 {paInt a, b, c; if (getMinMax(t, a, b, c) == 1) return false; } 733 752 break; 734 753 case 'f': 735 {double a,b,c; if (getMinMax(t,a,b,c)==1) return false;}736 break; 737 } 738 return true;754 {double a, b, c; if (getMinMax(t, a, b, c) == 1) return false; } 755 break; 756 } 757 return true; 739 758 } 740 759 741 760 SString ParamInterface::describeType(const char* type) 742 761 { 743 SString t;744 switch(type[0])745 { 746 case 'd': t +="integer";747 {paInt a, b,c; int n=getMinMax(type,a,b,c); if ((n>=2)&&(b>=a)) t+=SString::sprintf(" %d..%d",a,b); if (n>=3) t+=SString::sprintf(" (default %d)",c);}748 break;749 case 'f': t +="float";750 {double a, b,c; int n=getMinMax(type,a,b,c); if ((n>=2)&&(b>=a)) t+=SString::sprintf(" %g..%g",a,b); if (n>=3) t+=SString::sprintf(" (default %g)",c);}751 break;752 case 's': t +="string";753 {int a, b; SString c; int n=getMinMax(type,a,b,c); if ((n>=2)&&(b>0)) t+=SString::sprintf(", max %d chars",b); if (n>=3) t+=SString::sprintf(" (default \"%s\")",c.c_str());}754 break;755 case 'x': t +="untyped value"; break;756 case 'p': t +="function"; break;757 case 'o': t +="object"; if (type[1]) {t+=" of class "; t+=type+1;} break;762 SString t; 763 switch (type[0]) 764 { 765 case 'd': t += "integer"; 766 {paInt a, b, c; int n = getMinMax(type, a, b, c); if ((n >= 2) && (b >= a)) t += SString::sprintf(" %d..%d", a, b); if (n >= 3) t += SString::sprintf(" (default %d)", c); } 767 break; 768 case 'f': t += "float"; 769 {double a, b, c; int n = getMinMax(type, a, b, c); if ((n >= 2) && (b >= a)) t += SString::sprintf(" %g..%g", a, b); if (n >= 3) t += SString::sprintf(" (default %g)", c); } 770 break; 771 case 's': t += "string"; 772 {int a, b; SString c; int n = getMinMax(type, a, b, c); if ((n >= 2) && (b > 0)) t += SString::sprintf(", max %d chars", b); if (n >= 3) t += SString::sprintf(" (default \"%s\")", c.c_str()); } 773 break; 774 case 'x': t += "untyped value"; break; 775 case 'p': t += "function"; break; 776 case 'o': t += "object"; if (type[1]) { t += " of class "; t += type + 1; } break; 758 777 default: return "unknown type"; 759 778 } 760 return t;779 return t; 761 780 } 762 781 … … 766 785 void SimpleAbstractParam::sanityCheck(int i) 767 786 { 768 ParamEntry *pe =entry(i);769 770 const char* t =pe->type;771 const char* err =NULL;787 ParamEntry *pe = entry(i); 788 789 const char* t = pe->type; 790 const char* err = NULL; 772 791 773 792 if (!isValidTypeDescription(t)) 774 err ="invalid type description";775 if (*t =='p')776 { 777 if (pe->fun1 ==NULL)778 err ="no procedure defined";793 err = "invalid type description"; 794 if (*t == 'p') 795 { 796 if (pe->fun1 == NULL) 797 err = "no procedure defined"; 779 798 } 780 799 else … … 782 801 if (!(pe->flags & PARAM_READONLY)) 783 802 { //write access 784 if ((pe->fun2 ==NULL)&&(pe->offset==PARAM_ILLEGAL_OFFSET))785 err ="no field defined (GETONLY without PARAM_READONLY?)";786 } 787 } 788 if (err !=NULL)789 logPrintf("SimpleAbstractParam", "sanityCheck", LOG_ERROR,803 if ((pe->fun2 == NULL) && (pe->offset == PARAM_ILLEGAL_OFFSET)) 804 err = "no field defined (GETONLY without PARAM_READONLY?)"; 805 } 806 } 807 if (err != NULL) 808 logPrintf("SimpleAbstractParam", "sanityCheck", LOG_ERROR, 790 809 "Invalid ParamEntry for %s.%s (%s)", getName(), pe->id, err); 791 } 810 } 792 811 #endif 793 812 … … 903 922 paInt mn = 0, mx = 0, de = 0; 904 923 int result = 0; 905 if (getMinMax(pe->type, mn,mx,de)>=2)924 if (getMinMax(pe->type, mn, mx, de) >= 2) 906 925 if (mn <= mx) // else if mn>mx then the min/max constraint makes no sense and there is no checking 907 926 { … … 937 956 double mn = 0, mx = 0, de = 0; 938 957 int result = 0; 939 if (getMinMax(pe->type, mn,mx,de)>=2)958 if (getMinMax(pe->type, mn, mx, de) >= 2) 940 959 if (mn <= mx) // else if mn>mx then the min/max constraint makes no sense and there is no checking 941 960 { … … 1010 1029 if (pe->flags&PARAM_READONLY) return PSET_RONLY; 1011 1030 if (pe->flags&PARAM_OBJECTSET) 1012 1013 ExtObject o =getObject(i);1031 { 1032 ExtObject o = getObject(i); 1014 1033 Param tmp; 1015 ParamInterface* oif =o.getParamInterface(tmp);1034 ParamInterface* oif = o.getParamInterface(tmp); 1016 1035 int ass; 1017 if (oif && ((ass =oif->findId("assign"))>=0))1018 1019 ExtValue arg =x;1020 oif->call(ass, &arg,&v);1021 1036 if (oif && ((ass = oif->findId("assign")) >= 0)) 1037 { 1038 ExtValue arg = x; 1039 oif->call(ass, &arg, &v); 1040 } 1022 1041 else 1023 1042 logPrintf("SimpleAbstractParam", "setObject", LOG_ERROR, 1024 1043 "'%s.%s' is PARAM_OBJECTSET but no 'assign()' in %s", getName(), pe->id, o.interfaceName()); 1025 1044 return PSET_CHANGED; 1026 1045 } 1027 1046 ExtObject xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below 1028 1047 if (pe->fun2) … … 1122 1141 const char *value, *valstop; 1123 1142 SString tmpvalue; 1124 bool parse_failed =false;1143 bool parse_failed = false; 1125 1144 if (poz >= s.len()) return fields_loaded; 1126 1145 t = s.c_str() + poz; … … 1178 1197 else 1179 1198 #ifdef SAVE_SELECTED_NAMES 1180 if ((i >=getPropCount()) || !(flags(i)&PARAM_CANOMITNAME))1199 if ((i >= getPropCount()) || !(flags(i)&PARAM_CANOMITNAME)) 1181 1200 #endif 1182 1201 { … … 1208 1227 id(i), getName(), (ret&PSET_HITMAX) ? "big" : "small"); 1209 1228 if (ret&PSET_PARSEFAILED) 1210 parse_failed =true;1229 parse_failed = true; 1211 1230 *(char*)valstop = remember; 1212 1231 } -
cpp/frams/param/param.h
r645 r650 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 118 118 ExtValue getById(const char* prop); 119 119 120 int setInt(int i, const char* str, bool strict =false);120 int setInt(int i, const char* str, bool strict = false); 121 121 int setDouble(int i, const char* str); 122 122 virtual int setInt(int, paInt) = 0; ///< set long value, you can only use this for "d" type prop … … 128 128 int set(int, const ExtValue &);///< most universal set, can be used for every datatype 129 129 130 int set(int, const char*, bool strict =false); ///< oldstyle set, can convert string to long or double130 int set(int, const char*, bool strict = false); ///< oldstyle set, can convert string to long or double 131 131 132 132 int setIntById(const char* prop, paInt);///< set long value, you can only use this for "d" type prop … … 157 157 /** return the human readable description of the given type */ 158 158 static SString describeType(const char* type); 159 SString describeType(int i) { return describeType(type(i));}160 159 SString describeType(int i) { return describeType(type(i)); } 160 161 161 /** copy all property values from other ParamInterface object */ 162 162 void copyFrom(ParamInterface *src); … … 176 176 177 177 static const char* SERIALIZATION_PREFIX; 178 static const int LOAD2_PARSE_FAILED =(1<<30); ///< this bit is set in return value from load2 if a parse error was detected while loading. usage: if (load2(...) & LOAD2_PARSE_FAILED) ...179 static const int LOAD2_IGNORE_PARSE_FAILED =(~LOAD2_PARSE_FAILED); ///< bitmask to be used if the parsing error is to be ignored. usage: int number_of_loaded_fields=load2(...) & LOAD2_IGNORE_PARSE_FAILED;178 static const int LOAD2_PARSE_FAILED = (1 << 30); ///< this bit is set in return value from load2 if a parse error was detected while loading. usage: if (load2(...) & LOAD2_PARSE_FAILED) ... 179 static const int LOAD2_IGNORE_PARSE_FAILED = (~LOAD2_PARSE_FAILED); ///< bitmask to be used if the parsing error is to be ignored. usage: int number_of_loaded_fields=load2(...) & LOAD2_IGNORE_PARSE_FAILED; 180 180 181 181 static bool isValidTypeDescription(const char* t);
Note: See TracChangeset
for help on using the changeset viewer.