Ignore:
Timestamp:
03/01/14 22:25:20 (10 years ago)
Author:
sz
Message:

reformatting, english translation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/param/param.cpp

    r144 r154  
    1717char MakeCodeGuardHappy;
    1818
    19 ParamEntry empty_paramtab[]=
    20 { {"Empty",1,0,"Empty",}, {0,0,0,}, };
    21 
    22 static void czytdotyldy(VirtFILE *f,SString &s)
    23 {
    24 SString temp;
    25 int z;
    26 char last_char=0;
    27 while((z=fgetc(f))!=EOF)
    28         {
    29         if (z=='~')
    30                 if (last_char!='\\') break;
    31         last_char=(char)z;
    32         temp+=last_char;
    33         }
    34 s=temp;
    35 }
    36 
    37 static const char *strchrlimit(const char *t,int ch,const char *limit)
    38 {
    39 int n=limit-t;
    40 for (;(n>0)&&*t;t++,n--)
    41         if (*t==ch) return t;
    42 return 0;
     19ParamEntry empty_paramtab[] =
     20{ { "Empty", 1, 0, "Empty", }, { 0, 0, 0, }, };
     21
     22static void czytdotyldy(VirtFILE *f, SString &s)
     23{
     24        SString temp;
     25        int z;
     26        char last_char = 0;
     27        while ((z = fgetc(f)) != EOF)
     28        {
     29                if (z == '~')
     30                        if (last_char != '\\') break;
     31                last_char = (char)z;
     32                temp += last_char;
     33        }
     34        s = temp;
     35}
     36
     37static const char *strchrlimit(const char *t, int ch, const char *limit)
     38{
     39        int n = limit - t;
     40        for (; (n > 0) && *t; t++, n--)
     41                if (*t == ch) return t;
     42        return 0;
    4343}
    4444
    4545void ParamInterface::copyFrom(ParamInterface *src)
    4646{
    47 int n=getPropCount();
    48 ExtValue v;
    49 int j;
    50 for(int i=0;i<n;i++)
    51   if ((!(flags(i)&PARAM_READONLY))
    52           && (*type(i)!='p'))
    53         {
    54         j=src->findId(id(i));
    55         if (j<0) continue;
    56         src->get(j,v);
    57         set(i,v);
    58         }
     47        int n = getPropCount();
     48        ExtValue v;
     49        int j;
     50        for (int i = 0; i < n; i++)
     51                if ((!(flags(i)&PARAM_READONLY))
     52                        && (*type(i) != 'p'))
     53                {
     54                        j = src->findId(id(i));
     55                        if (j < 0) continue;
     56                        src->get(j, v);
     57                        set(i, v);
     58                }
    5959}
    6060
    6161void ParamInterface::quickCopyFrom(ParamInterface *src)
    6262{
    63 int n=getPropCount();
    64 ExtValue v;
    65 for(int i=0;i<n;i++)
    66   if ((!(flags(i)&PARAM_READONLY))
    67           && (*type(i)!='p'))
    68           {
    69           src->get(i,v);
    70           set(i,v);
    71           }
    72 }
    73 
    74 int ParamInterface::getMinMax(int prop,long& minumum,long& maximum,long &def)
    75 {
    76 const char* t=type(prop)+1;
    77 while(*t) if (*t==' ') break; else t++;
    78 return sscanf(t,"%ld %ld %ld",&minumum,&maximum,&def);
    79 }
    80 
    81 int ParamInterface::getMinMax(int prop,double& minumum,double& maximum,double& def)
    82 {
    83 const char* t=type(prop)+1;
    84 while(*t) if (*t==' ') break; else t++;
    85 return sscanf(t,"%lg %lg %lg",&minumum,&maximum,&def);
     63        int n = getPropCount();
     64        ExtValue v;
     65        for (int i = 0; i < n; i++)
     66                if ((!(flags(i)&PARAM_READONLY))
     67                        && (*type(i) != 'p'))
     68                {
     69                        src->get(i, v);
     70                        set(i, v);
     71                }
     72}
     73
     74int ParamInterface::getMinMax(int prop, long& minumum, long& maximum, long &def)
     75{
     76        const char* t = type(prop) + 1;
     77        while (*t) if (*t == ' ') break; else t++;
     78        return sscanf(t, "%ld %ld %ld", &minumum, &maximum, &def);
     79}
     80
     81int ParamInterface::getMinMax(int prop, double& minumum, double& maximum, double& def)
     82{
     83        const char* t = type(prop) + 1;
     84        while (*t) if (*t == ' ') break; else t++;
     85        return sscanf(t, "%lg %lg %lg", &minumum, &maximum, &def);
    8686}
    8787
    8888void ParamInterface::setDefault(bool numericonly)
    8989{
    90 int n=getPropCount();
    91 for(int i=0;i<n;i++)
    92         setDefault(i,numericonly);
     90        int n = getPropCount();
     91        for (int i = 0; i < n; i++)
     92                setDefault(i, numericonly);
    9393}
    9494
    9595void ParamInterface::setMin()
    9696{
    97 int n=getPropCount();
    98 for(int i=0;i<n;i++)
    99         setMin(i);
     97        int n = getPropCount();
     98        for (int i = 0; i < n; i++)
     99                setMin(i);
    100100}
    101101
    102102void ParamInterface::setMax()
    103103{
    104 int n=getPropCount();
    105 for(int i=0;i<n;i++)
    106         setMax(i);
    107 }
    108 
    109 void ParamInterface::setDefault(int i,bool numericonly)
    110 {
    111 const char *t=type(i);
    112 switch(*t)
     104        int n = getPropCount();
     105        for (int i = 0; i < n; i++)
     106                setMax(i);
     107}
     108
     109void ParamInterface::setDefault(int i, bool numericonly)
     110{
     111        const char *t = type(i);
     112        switch (*t)
    113113        {
    114114        case 'f':
    115115        {
    116         double a=0,b=0,c=0;
    117         if (getMinMax(i,a,b,c)<3) c=a;
    118         setDouble(i,c);
    119         }
    120         break;
     116                double a = 0, b = 0, c = 0;
     117                if (getMinMax(i, a, b, c) < 3) c = a;
     118                setDouble(i, c);
     119        }
     120                break;
    121121        case 'd':
    122122        {
    123         long a=0,b=0,c=0;
    124         if (getMinMax(i,a,b,c)<3) c=a;
    125         setInt(i,c);
    126         }
    127         break;
    128         default: if (!numericonly) set(i,"");
     123                long a = 0, b = 0, c = 0;
     124                if (getMinMax(i, a, b, c) < 3) c = a;
     125                setInt(i, c);
     126        }
     127                break;
     128        default: if (!numericonly) set(i, "");
    129129        }
    130130}
     
    132132void ParamInterface::setMin(int i)
    133133{
    134 const char *t=type(i);
    135 switch(*t)
     134        const char *t = type(i);
     135        switch (*t)
    136136        {
    137137        case 'f':
    138138        {
    139         double a=0,b=0,c=0;
    140         getMinMax(i,a,b,c);
    141         setDouble(i,a);
    142         }
    143         break;
     139                double a = 0, b = 0, c = 0;
     140                getMinMax(i, a, b, c);
     141                setDouble(i, a);
     142        }
     143                break;
    144144        case 'd':
    145145        {
    146         long a=0,b=0,c=0;
    147         getMinMax(i,a,b,c);
    148         setInt(i,a);
    149         }
    150         break;
    151         default: set(i,"");
     146                long a = 0, b = 0, c = 0;
     147                getMinMax(i, a, b, c);
     148                setInt(i, a);
     149        }
     150                break;
     151        default: set(i, "");
    152152        }
    153153}
     
    155155void ParamInterface::setMax(int i)
    156156{
    157 const char *t=type(i);
    158 switch(*t)
     157        const char *t = type(i);
     158        switch (*t)
    159159        {
    160160        case 'f':
    161161        {
    162         double a=0,b=0,c=0;
    163         getMinMax(i,a,b,c);
    164         setDouble(i,b);
    165         }
    166         break;
     162                double a = 0, b = 0, c = 0;
     163                getMinMax(i, a, b, c);
     164                setDouble(i, b);
     165        }
     166                break;
    167167        case 'd':
    168168        {
    169         long a=0,b=0,c=0;
    170         getMinMax(i,a,b,c);
    171         setInt(i,b);
    172         }
    173         break;
    174         default: set(i,"");
     169                long a = 0, b = 0, c = 0;
     170                getMinMax(i, a, b, c);
     171                setInt(i, b);
     172        }
     173                break;
     174        default: set(i, "");
    175175        }
    176176}
     
    200200{int i=findId(prop); if (i>=0) return set(i,v); else return PSET_NOPROPERTY;}
    201201
    202 int ParamInterface::save(VirtFILE* f,const char* altname,bool force)
    203 {
    204 const char *p;
    205 SString ws;
    206 int err=0,i;
    207 bool withname=false;
    208 if ((altname==NULL)||(altname[0]!=0))
    209         {
    210         err|=(fputs(altname?altname:getName(),f)==EOF);
    211         err|=(fputs(":\n",f)==EOF);
    212         withname=true;
    213         }
    214 for (i=0;p=id(i);i++)
    215         err|=saveprop(f,i,p,force);
    216 if (withname)
    217         err|=(fputs("\n",f)==EOF);
    218 return err;
    219 }
    220 
    221 const char* ParamInterface::SERIALIZATION_PREFIX="@Serialized:";
    222 
    223 int ParamInterface::saveprop(VirtFILE* f,int i,const char* p,bool force)
    224 {
    225 if ((flags(i)&PARAM_DONTSAVE)&&(!force)) return 0;
    226 const char *typ=type(i);
    227 if ((*typ=='p')||(*typ=='o')) return 0;
    228 
    229 const char *t,*w;
    230 SString ws;
    231 int err=0,cr;
    232 
    233 err|=(fputs(p,f)==EOF); fputc(':',f);
    234 cr=0;
    235 if (*typ=='x')
    236         {
    237         ExtValue ex;
    238         get(i,ex);
    239         ws=SString(SERIALIZATION_PREFIX)+ex.serialize();
    240         }
    241 else
    242         ws=get(i);
    243 quoteTilde(ws);
    244 w=ws;
    245 if (ws.len()>50) cr=1;
    246 else for (t=w;*t;t++) if ((*t==10)||(*t==13)) {cr=1; break;}
    247 if (cr) fputs("~\n",f);
    248 err|=(fputs(w,f)==EOF);
    249 err|=(fputs(cr ? "~\n" : "\n",f)==EOF);
    250 return err;
    251 }
    252 
    253 
    254 int SimpleAbstractParam::isequal(int i,void* defdata)
     202int ParamInterface::save(VirtFILE* f, const char* altname, bool force)
     203{
     204        const char *p;
     205        SString ws;
     206        int err = 0, i;
     207        bool withname = false;
     208        if ((altname == NULL) || (altname[0] != 0))
     209        {
     210                err |= (fputs(altname ? altname : getName(), f) == EOF);
     211                err |= (fputs(":\n", f) == EOF);
     212                withname = true;
     213        }
     214        for (i = 0; p = id(i); i++)
     215                err |= saveprop(f, i, p, force);
     216        if (withname)
     217                err |= (fputs("\n", f) == EOF);
     218        return err;
     219}
     220
     221const char* ParamInterface::SERIALIZATION_PREFIX = "@Serialized:";
     222
     223int ParamInterface::saveprop(VirtFILE* f, int i, const char* p, bool force)
     224{
     225        if ((flags(i)&PARAM_DONTSAVE) && (!force)) return 0;
     226        const char *typ = type(i);
     227        if ((*typ == 'p') || (*typ == 'o')) return 0;
     228
     229        const char *t, *w;
     230        SString ws;
     231        int err = 0, cr;
     232
     233        err |= (fputs(p, f) == EOF); fputc(':', f);
     234        cr = 0;
     235        if (*typ == 'x')
     236        {
     237                ExtValue ex;
     238                get(i, ex);
     239                ws = SString(SERIALIZATION_PREFIX) + ex.serialize();
     240        }
     241        else
     242                ws = get(i);
     243        quoteTilde(ws);
     244        w = ws;
     245        if (ws.len() > 50) cr = 1;
     246        else for (t = w; *t; t++) if ((*t == 10) || (*t == 13)) { cr = 1; break; }
     247        if (cr) fputs("~\n", f);
     248        err |= (fputs(w, f) == EOF);
     249        err |= (fputs(cr ? "~\n" : "\n", f) == EOF);
     250        return err;
     251}
     252
     253
     254int SimpleAbstractParam::isequal(int i, void* defdata)
    255255{ // defdata->member == object->member ?
    256 void *backup=object;
    257 switch(type(i)[0])
     256        void *backup = object;
     257        switch (type(i)[0])
    258258        {
    259259        case 'd':
    260                 {
     260        {
    261261                select(defdata);
    262                 long x=getInt(i);
     262                long x = getInt(i);
    263263                select(backup);
    264                 return x==getInt(i);
    265                 }
     264                return x == getInt(i);
     265        }
    266266        case 'f':
    267                 {
     267        {
    268268                select(defdata);
    269                 double x=getDouble(i);
     269                double x = getDouble(i);
    270270                select(backup);
    271                 return x==getDouble(i);
    272                 }
     271                return x == getDouble(i);
     272        }
    273273        case 's':
    274                 {
     274        {
    275275                select(defdata);
    276                 SString x=getString(i);
     276                SString x = getString(i);
    277277                select(backup);
    278                 return x==getString(i);
    279                 }
    280         }
    281 return 1;
    282 }
    283 
    284 void SimpleAbstractParam::save2(SString& f,void *defdata,bool addcr,bool all_names)
    285 { // defdata!=NULL -> nie zapisuje wartosci domyslnych
    286 const char *p;
    287 int i;
    288 int needlabel=0;
    289 int first=1;
    290 SString val;
    291 SString t;
    292 int fl;
    293 // t+=SString(getName()); t+=':';
    294 for (i=0;p=id(i);i++)
    295         if (!((fl=flags(i))&PARAM_DONTSAVE))
    296         {
    297         if (defdata && isequal(i,defdata))
    298                 needlabel=1;
    299         else
    300                 {
    301                 if (!first) t+=", ";
     278                return x == getString(i);
     279        }
     280        }
     281        return 1;
     282}
     283
     284void SimpleAbstractParam::save2(SString& f, void *defdata, bool addcr, bool all_names)
     285{ // defdata!=NULL -> does not save default values
     286        const char *p;
     287        int i;
     288        int needlabel = 0;
     289        int first = 1;
     290        SString val;
     291        SString t;
     292        int fl;
     293        // t+=SString(getName()); t+=':';
     294        for (i = 0; p = id(i); i++)
     295                if (!((fl = flags(i))&PARAM_DONTSAVE))
     296                {
     297                        if (defdata && isequal(i, defdata))
     298                                needlabel = 1;
     299                        else
     300                        {
     301                                if (!first) t += ", ";
    302302#ifndef SAVE_ALL_NAMES
    303303#ifdef SAVE_SELECTED_NAMES
    304                 if (needlabel || all_names || !(fl & PARAM_CANOMITNAME))
     304                                if (needlabel || all_names || !(fl & PARAM_CANOMITNAME))
    305305#else
    306                 if (needlabel)
     306                                if (needlabel)
    307307#endif
    308308#endif
    309                         { t+=p; t+="="; needlabel=0; }
    310                 if (type(i)[0]=='s')
    311                         { // string - special case
    312                         SString str=getString(i);
    313                         if (strContainsOneOf(str,", \\\n\r\t\""))
    314309                                {
    315                                 t+="\"";
    316                                 sstringQuote(str);
    317                                 t+=str;
    318                                 t+="\"";
     310                                        t += p; t += "="; needlabel = 0;
    319311                                }
     312                                if (type(i)[0] == 's')
     313                                { // string - special case
     314                                        SString str = getString(i);
     315                                        if (strContainsOneOf(str, ", \\\n\r\t\""))
     316                                        {
     317                                                t += "\"";
     318                                                sstringQuote(str);
     319                                                t += str;
     320                                                t += "\"";
     321                                        }
     322                                        else
     323                                                t += str;
     324                                }
     325                                else
     326                                        t += get(i);
     327                                first = 0;
     328                        }
     329                }
     330        if (addcr)
     331                t += "\n";
     332        f += t;
     333}
     334
     335int ParamInterface::load(VirtFILE* f)
     336{
     337        SString buf;
     338        int i;
     339        const char *p, *p0;
     340        int p_len;
     341        bool loaded;
     342        int fields_loaded = 0;
     343        while (loadSStringLine(f, buf))
     344        {
     345                const char* t = (const char*)buf;
     346                p0 = t; while ((*p0 == ' ') || (*p0 == '\t')) p0++;
     347                if (!*p0) break;
     348                p = strchr(p0, ':'); if (!p) continue;
     349                p_len = p - p0;
     350                loaded = false;
     351                if (p_len && ((i = findIdn(p0, p_len)) >= 0) && (!(flags(i)&PARAM_DONTLOAD)))
     352                {
     353                        if (p0[p_len + 1] == '~')
     354                        {
     355                                SString s;
     356                                czytdotyldy(f, s);
     357                                removeCR(s);
     358                                int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break;
     359                                unquoteTilde(s);
     360                                set(i, (const char*)s);
     361                        }
    320362                        else
    321                                 t+=str;
     363                        {
     364                                set(i, p0 + p_len + 1);
    322365                        }
    323                 else
    324                         t+=get(i);
    325                 first=0;
    326                 }
    327         }
    328 if (addcr)
    329         t+="\n";
    330 f+=t;
    331 }
    332 
    333 int ParamInterface::load(VirtFILE* f)
    334 {
    335 SString buf;
    336 int i;
    337 const char *p,*p0;
    338 int p_len;
    339 bool loaded;
    340 int fields_loaded=0;
    341 while(loadSStringLine(f,buf))
    342         {
    343         const char* t=(const char*)buf;
    344         p0=t; while ((*p0==' ')||(*p0=='\t')) p0++;
    345         if (!*p0) break;
    346         p=strchr(p0,':'); if (!p) continue;
    347         p_len=p-p0;
    348         loaded=false;
    349         if (p_len&&((i=findIdn(p0,p_len))>=0)&&(!(flags(i)&PARAM_DONTLOAD)))
    350                 {
    351                 if (p0[p_len+1]=='~')
    352                         {
     366                        fields_loaded++;
     367                        loaded = true;
     368                }
     369                if ((!loaded) && (p0[p_len + 1] == '~'))
     370                { // eat unrecognized multiline field
    353371                        SString s;
    354                         czytdotyldy(f,s);
    355                         removeCR(s);
    356                         int ch; while((ch=fgetc(f))!=EOF) if (ch=='\n') break;
    357                         unquoteTilde(s);
    358                         set(i,(const char*)s);
    359                         }
    360                 else
    361                         {
    362                         set(i,p0+p_len+1);
    363                         }
    364                 fields_loaded++;
    365                 loaded=true;
    366                 }
    367         if ((!loaded) && (p0[p_len+1]=='~'))
    368                 { // eat unrecognized multiline field
    369                 SString s;
    370                 czytdotyldy(f,s);
    371                 int ch; while((ch=fgetc(f))!=EOF) if (ch=='\n') break;
    372                 }
    373         }
    374 return fields_loaded;
     372                        czytdotyldy(f, s);
     373                        int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break;
     374                }
     375        }
     376        return fields_loaded;
    375377}
    376378
     
    403405int ParamInterface::findId(const char* n)
    404406{
    405 int i; const char *p;
    406         for (i=0;p=id(i);i++) if (!strcmp(n,p)) return i;
    407 return -1;
    408 }
    409 
    410 int ParamInterface::findIdn(const char* naz,int n)
    411 {
    412 int i; const char *p;
    413         for (i=0;p=id(i);i++) if ((!strncmp(naz,p,n))&&(!p[n])) return i;
    414 return -1;
    415 }
    416 
    417 void ParamInterface::get(int i,ExtValue &ret)
    418 {
    419 switch(type(i)[0])
     407        int i; const char *p;
     408        for (i = 0; p = id(i); i++) if (!strcmp(n, p)) return i;
     409        return -1;
     410}
     411
     412int ParamInterface::findIdn(const char* naz, int n)
     413{
     414        int i; const char *p;
     415        for (i = 0; p = id(i); i++) if ((!strncmp(naz, p, n)) && (!p[n])) return i;
     416        return -1;
     417}
     418
     419void ParamInterface::get(int i, ExtValue &ret)
     420{
     421        switch (type(i)[0])
    420422        {
    421423        case 'd':       ret.setInt(getInt(i)); break;
     
    423425        case 's':       ret.setString(getString(i)); break;
    424426        case 'o':       ret.setObject(getObject(i)); break;
    425         case 'x':       ret=getExtValue(i); break;
    426         default: FMprintf("ParamInterface","get",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));
     427        case 'x':       ret = getExtValue(i); break;
     428        default: FMprintf("ParamInterface", "get", FMLV_ERROR, "'%s.%s' is not a field", getName(), id(i));
    427429        }
    428430}
     
    430432static bool stringIsNumeric(const char* str)
    431433{//   /-?.?[0-9]+/
    432 if (!str) return false;
    433 if (*str=='-') str++;
    434 if (*str=='.') str++;
    435 return isdigit(*str)!=0;
    436 }
    437 
    438 int ParamInterface::setInt(int i,const char* str)
    439 {
    440 if (!stringIsNumeric(str))
    441         {
    442         long a,b,c;
    443         if (getMinMax(i,a,b,c)>=3)
    444                 return setInt(i,c);
    445         else
    446                 return setInt(i,(long)0);
    447         }
    448 else
    449         return setInt(i,ExtValue::getInt(str));
    450 }
    451 
    452 int ParamInterface::setDouble(int i,const char* str)
    453 {
    454 if (!stringIsNumeric(str))
    455         {
    456         double a,b,c;
    457         if (getMinMax(i,a,b,c)>=3)
    458                 return setDouble(i,c);
    459         else
    460                 return setDouble(i,(double)0);
    461         }
    462 else
    463         return setDouble(i,ExtValue::getDouble(str));
    464 }
    465 
    466 int ParamInterface::set(int i,const ExtValue &v)
    467 {
    468 switch(type(i)[0])
     434        if (!str) return false;
     435        if (*str == '-') str++;
     436        if (*str == '.') str++;
     437        return isdigit(*str) != 0;
     438}
     439
     440int ParamInterface::setInt(int i, const char* str)
     441{
     442        if (!stringIsNumeric(str))
     443        {
     444                long a, b, c;
     445                if (getMinMax(i, a, b, c) >= 3)
     446                        return setInt(i, c);
     447                else
     448                        return setInt(i, (long)0);
     449        }
     450        else
     451                return setInt(i, ExtValue::getInt(str));
     452}
     453
     454int ParamInterface::setDouble(int i, const char* str)
     455{
     456        if (!stringIsNumeric(str))
     457        {
     458                double a, b, c;
     459                if (getMinMax(i, a, b, c) >= 3)
     460                        return setDouble(i, c);
     461                else
     462                        return setDouble(i, (double)0);
     463        }
     464        else
     465                return setDouble(i, ExtValue::getDouble(str));
     466}
     467
     468int ParamInterface::set(int i, const ExtValue &v)
     469{
     470        switch (type(i)[0])
    469471        {
    470472        case 'd':
    471                 if ((v.type==TInt)||(v.type==TDouble)) return setInt(i,v.getInt());
     473                if ((v.type == TInt) || (v.type == TDouble)) return setInt(i, v.getInt());
    472474                else
    473                         {
    474                         if (v.type==TObj)
    475                                 FMprintf("ParamInterface","set",FMLV_WARN,"Getting integer value from object reference (%s)",(const char*)v.getString());
    476                         return setInt(i,(const char*)v.getString());
    477                         }
     475                {
     476                        if (v.type == TObj)
     477                                FMprintf("ParamInterface", "set", FMLV_WARN, "Getting integer value from object reference (%s)", (const char*)v.getString());
     478                        return setInt(i, (const char*)v.getString());
     479                }
    478480        case 'f':
    479                 if ((v.type==TInt)||(v.type==TDouble)) return setDouble(i,v.getDouble());
     481                if ((v.type == TInt) || (v.type == TDouble)) return setDouble(i, v.getDouble());
    480482                else
    481                         {
    482                         if (v.type==TObj)
    483                                 FMprintf("ParamInterface","set",FMLV_WARN,"Getting floating point value from object reference (%s)",(const char*)v.getString());
    484                         return setDouble(i,(const char*)v.getString());
    485                         }
    486         case 's': { SString t=v.getString(); return setString(i,t); }
    487         case 'o': return setObject(i,v.getObject());
    488         case 'x': return setExtValue(i,v);
    489         default: FMprintf("ParamInterface","set",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));
    490         }
    491 return 0;
    492 }
    493 
    494 int ParamInterface::set(int i,const char *v)
    495 {
    496 switch(type(i)[0])
    497         {
    498         case 'd': return setInt(i,v);
    499         case 'f': return setDouble(i,v);
    500         case 's': { SString t(v); return setString(i,t); }
     483                {
     484                        if (v.type == TObj)
     485                                FMprintf("ParamInterface", "set", FMLV_WARN, "Getting floating point value from object reference (%s)", (const char*)v.getString());
     486                        return setDouble(i, (const char*)v.getString());
     487                }
     488        case 's': { SString t = v.getString(); return setString(i, t); }
     489        case 'o': return setObject(i, v.getObject());
     490        case 'x': return setExtValue(i, v);
     491        default: FMprintf("ParamInterface", "set", FMLV_ERROR, "'%s.%s' is not a field", getName(), id(i));
     492        }
     493        return 0;
     494}
     495
     496int ParamInterface::set(int i, const char *v)
     497{
     498        switch (type(i)[0])
     499        {
     500        case 'd': return setInt(i, v);
     501        case 'f': return setDouble(i, v);
     502        case 's': { SString t(v); return setString(i, t); }
    501503        case 'x':
    502504        {
    503         ExtValue e;
    504         const char* after;
    505         if (!strncmp(v,SERIALIZATION_PREFIX,strlen(SERIALIZATION_PREFIX)))
    506                 {
    507                 after=e.deserialize(v+strlen(SERIALIZATION_PREFIX));
    508                 if ((after==NULL)||(*after))
    509                         FMprintf("ParamInterface","set",FMLV_WARN,"serialization format mismatch in %s.%s",(getName()?getName():"<Unknown>"),id(i));
    510                 }
    511         else if ((after=e.parseNumber(v))&&(*after==0)) //consumed the whole string
    512                 {
    513                 //OK!
    514                 }
    515         else
    516                 {
    517                 e.setString(SString(v));
    518                 }
    519         return setExtValue(i,e);
    520         }
    521         }
    522 return 0;
     505                ExtValue e;
     506                const char* after;
     507                if (!strncmp(v, SERIALIZATION_PREFIX, strlen(SERIALIZATION_PREFIX)))
     508                {
     509                        after = e.deserialize(v + strlen(SERIALIZATION_PREFIX));
     510                        if ((after == NULL) || (*after))
     511                                FMprintf("ParamInterface", "set", FMLV_WARN, "serialization format mismatch in %s.%s", (getName() ? getName() : "<Unknown>"), id(i));
     512                }
     513                else if ((after = e.parseNumber(v)) && (*after == 0)) //consumed the whole string
     514                {
     515                        //OK!
     516                }
     517                else
     518                {
     519                        e.setString(SString(v));
     520                }
     521                return setExtValue(i, e);
     522        }
     523        }
     524        return 0;
    523525}
    524526
    525527SString ParamInterface::getText(int i)
    526528{
    527 const char *t;
    528 if ((*(t=type(i)))=='d')
    529         {
    530         for (int j=getInt(i);j>=0;j--) if (t) t=strchr(t+1,'~');
    531         if (t)
    532                 {
    533                 t++;
    534                 const char *t2=strchr(t,'~');
    535                 if (!t2) t2=t+strlen(t);
    536                 return SString(t,t2-t);
    537                 }
    538         }
    539 return get(i);
     529        const char *t;
     530        if ((*(t = type(i))) == 'd')
     531        {
     532                for (int j = getInt(i); j >= 0; j--) if (t) t = strchr(t + 1, '~');
     533                if (t)
     534                {
     535                        t++;
     536                        const char *t2 = strchr(t, '~');
     537                        if (!t2) t2 = t + strlen(t);
     538                        return SString(t, t2 - t);
     539                }
     540        }
     541        return get(i);
    540542}
    541543
    542544SString ParamInterface::get(int i)
    543545{
    544 switch(type(i)[0])
     546        switch (type(i)[0])
    545547        {
    546548        case 'd': return SString::valueOf(getInt(i));
     
    548550        case 's': return getString(i);
    549551        }
    550 ExtValue v;
    551 get(i,v);
    552 return v.getString();
     552        ExtValue v;
     553        get(i, v);
     554        return v.getString();
    553555}
    554556
     
    558560void *SimpleAbstractParam::getTarget(int i)
    559561{
    560 return (void*)(((char*)object)+entry(i)->offset);
    561 //return &(object->*(entry(i)->fldptr));
     562        return (void*)(((char*)object) + entry(i)->offset);
     563        //return &(object->*(entry(i)->fldptr));
    562564}
    563565
     
    566568long SimpleAbstractParam::getInt(int i)
    567569{
    568 ExtValue v;
    569 ParamEntry *pe=entry(i);
    570 if (pe->fun1)
    571         {
    572         (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
    573         return v.getInt();
    574         }
    575 else
    576         {
    577         void *target=getTarget(i);
    578         return *((long*)target);
     570        ExtValue v;
     571        ParamEntry *pe = entry(i);
     572        if (pe->fun1)
     573        {
     574                (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v);
     575                return v.getInt();
     576        }
     577        else
     578        {
     579                void *target = getTarget(i);
     580                return *((long*)target);
    579581        }
    580582}
     
    582584double SimpleAbstractParam::getDouble(int i)
    583585{
    584 ExtValue v;
    585 ParamEntry *pe=entry(i);
    586 if (pe->fun1)
    587         {
    588         (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
    589         return v.getDouble();
    590         }
    591 else
    592         {
    593         void *target=getTarget(i);
    594         return *((double*)target);
     586        ExtValue v;
     587        ParamEntry *pe = entry(i);
     588        if (pe->fun1)
     589        {
     590                (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v);
     591                return v.getDouble();
     592        }
     593        else
     594        {
     595                void *target = getTarget(i);
     596                return *((double*)target);
    595597        }
    596598}
     
    598600SString SimpleAbstractParam::getString(int i)
    599601{
    600 ExtValue v;
    601 ParamEntry *pe=entry(i);
    602 if (pe->fun1)
    603         {
    604         (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
    605         return v.getString();
    606         }
    607 else
    608         {
    609         void *target=getTarget(i);
    610         return *((SString*)target);
     602        ExtValue v;
     603        ParamEntry *pe = entry(i);
     604        if (pe->fun1)
     605        {
     606                (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v);
     607                return v.getString();
     608        }
     609        else
     610        {
     611                void *target = getTarget(i);
     612                return *((SString*)target);
    611613        }
    612614}
     
    614616ExtObject SimpleAbstractParam::getObject(int i)
    615617{
    616 ExtValue v;
    617 ParamEntry *pe=entry(i);
    618 if (pe->fun1)
    619         {
    620         (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
    621         return v.getObject();
    622         }
    623 else
    624         {
    625         void *target=getTarget(i);
    626         return *((ExtObject*)target);
     618        ExtValue v;
     619        ParamEntry *pe = entry(i);
     620        if (pe->fun1)
     621        {
     622                (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v);
     623                return v.getObject();
     624        }
     625        else
     626        {
     627                void *target = getTarget(i);
     628                return *((ExtObject*)target);
    627629        }
    628630}
     
    630632ExtValue SimpleAbstractParam::getExtValue(int i)
    631633{
    632 ExtValue v;
    633 ParamEntry *pe=entry(i);
    634 if (pe->fun1)
    635         {
    636         (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
    637         return v;
    638         }
    639 else
    640         {
    641         void *target=getTarget(i);
    642         return *((ExtValue*)target);
     634        ExtValue v;
     635        ParamEntry *pe = entry(i);
     636        if (pe->fun1)
     637        {
     638                (*(void(*)(void*, ExtValue*))pe->fun1)(object, &v);
     639                return v;
     640        }
     641        else
     642        {
     643                void *target = getTarget(i);
     644                return *((ExtValue*)target);
    643645        }
    644646}
     
    647649//////// set
    648650
    649 int SimpleAbstractParam::setInt(int i,long x)
    650 {
    651 ExtValue v;
    652 ParamEntry *pe=entry(i);
    653 if (pe->flags&PARAM_READONLY) return PSET_RONLY;
    654 long xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
    655 long a=0,b=0;
    656 int result=0;
    657 const char* t=pe->type+1;
    658 while(*t) if (*t==' ') break; else t++;
    659 if (sscanf(t,"%ld %ld",&a,&b)==2)
    660         if (a<=b) // jezeli max<min to znaczy ze min/max nie obowiazuje
    661                 {
    662                 if (x<a) {x=a; result=PSET_HITMIN;}
    663                 else if (x>b) {x=b; result=PSET_HITMAX;}
    664                 }
    665 
    666 if (pe->fun2)
    667         {
    668         v.setInt(x);
    669         result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
    670         }
    671 else
    672         {
    673         void *target=getTarget(i);
    674         if (dontcheckchanges || (*((long*)target)!=x))
     651int SimpleAbstractParam::setInt(int i, long x)
     652{
     653        ExtValue v;
     654        ParamEntry *pe = entry(i);
     655        if (pe->flags&PARAM_READONLY) return PSET_RONLY;
     656        long xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
     657        long a = 0, b = 0;
     658        int result = 0;
     659        const char* t = pe->type + 1;
     660        while (*t) if (*t == ' ') break; else t++;
     661        if (sscanf(t, "%ld %ld", &a, &b) == 2)
     662                if (a <= b) // if max<min then the min/max constraint check is not supported
     663                {
     664                        if (x<a) { x = a; result = PSET_HITMIN; }
     665                        else if (x>b) { x = b; result = PSET_HITMAX; }
     666                }
     667
     668        if (pe->fun2)
     669        {
     670                v.setInt(x);
     671                result |= (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v);
     672        }
     673        else
     674        {
     675                void *target = getTarget(i);
     676                if (dontcheckchanges || (*((long*)target) != x))
     677                {
     678                        result |= PSET_CHANGED;
     679                        *((long*)target) = x;
     680                }
     681        }
     682        messageOnExceedRange(i, result, xcopy);
     683        return result;
     684}
     685
     686int SimpleAbstractParam::setDouble(int i, double x)
     687{
     688        ExtValue v;
     689        ParamEntry *pe = entry(i);
     690        if (pe->flags&PARAM_READONLY) return PSET_RONLY;
     691        double xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
     692        double a = 0, b = 0;
     693        int result = 0;
     694        const char* t = pe->type + 1;
     695        while (*t) if (*t == ' ') break; else t++;
     696        if (sscanf(t, "%lg %lg", &a, &b) == 2)
     697                if (a <= b) // if max<min then the min/max constraint check is not supported
     698                {
     699                        if (x<a) { x = a; result = PSET_HITMIN; }
     700                        else if (x>b) { x = b; result = PSET_HITMAX; }
     701                }
     702
     703        if (pe->fun2)
     704        {
     705                v.setDouble(x);
     706                result |= (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v);
     707        }
     708        else
     709        {
     710                void *target = getTarget(i);
     711                if (dontcheckchanges || (*((double*)target) != x))
     712                {
     713                        result |= PSET_CHANGED;
     714                        *((double*)target) = x;
     715                }
     716        }
     717        messageOnExceedRange(i, result, xcopy);
     718        return result;
     719}
     720
     721int SimpleAbstractParam::setString(int i, const SString& x)
     722{
     723        ExtValue v;
     724        SString vs;
     725        const SString *xx = &x;
     726        ParamEntry *pe = entry(i);
     727        if (pe->flags&PARAM_READONLY) return PSET_RONLY;
     728        SString xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
     729        const char* t = pe->type + 1;
     730        while (*t) if (*t == ' ') break; else t++;
     731        long a = 0, b = 0;
     732        int result = 0;
     733        if (sscanf(t, "%ld %ld", &a, &b) == 2)
     734        {
     735                if ((x.len() > b) && (b > 0))
     736                {
     737                        vs = x.substr(0, b);
     738                        xx = &vs;
     739                        result |= PSET_HITMAX;
     740                }
     741        }
     742
     743        if (pe->fun2)
     744        {
     745                v.setString(*xx);
     746                result |= (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v);
     747        }
     748        else
     749        {
     750                void *target = getTarget(i);
     751                if (dontcheckchanges || (!(*((SString*)target) == *xx)))
     752                {
     753                        result |= PSET_CHANGED;
     754                        *((SString*)target) = x;
     755                }
     756        }
     757        messageOnExceedRange(i, result, xcopy);
     758        return result;
     759}
     760
     761int SimpleAbstractParam::setObject(int i, const ExtObject& x)
     762{
     763        ExtValue v;
     764        ParamEntry *pe = entry(i);
     765        if (pe->flags&PARAM_READONLY) return PSET_RONLY;
     766        ExtObject xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
     767        if (pe->fun2)
     768        {
     769                v.setObject(x);
     770                int result = (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &v);
     771                messageOnExceedRange(i, result, xcopy);
     772                return result;
     773        }
     774        else
     775        {
     776                void *target = getTarget(i);
     777                *((ExtObject*)target) = x;
     778                return PSET_CHANGED;
     779        }
     780}
     781
     782int SimpleAbstractParam::setExtValue(int i, const ExtValue& x)
     783{
     784        ParamEntry *pe = entry(i);
     785        if (pe->flags&PARAM_READONLY) return PSET_RONLY;
     786        ExtValue xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
     787        if (pe->fun2)
     788        {
     789                int result = (*(int(*)(void*, const ExtValue*))pe->fun2)(object, &x);
     790                messageOnExceedRange(i, result, xcopy);
     791                return result;
     792        }
     793        else
     794        {
     795                void *target = getTarget(i);
     796                *((ExtValue*)target) = x;
     797                return PSET_CHANGED;
     798        }
     799}
     800
     801void SimpleAbstractParam::call(int i, ExtValue *args, ExtValue *ret)
     802{
     803        ParamEntry *pe = entry(i);
     804        if (!pe) return;
     805        if (pe->fun1 && (pe->type[0] == 'p'))
     806                (*(void(*)(void*, ExtValue*, ExtValue*))pe->fun1)(object, args, ret);
     807        else
     808        {
     809                FMprintf("SimpleAbstractParam", "call", FMLV_ERROR,
     810                        (*pe->type != 'p') ? "'%s.%s' is not a function" : "Internal error - undefined function pointer for '%s.%s'", getName(), pe->id);
     811        }
     812}
     813
     814void SimpleAbstractParam::setDefault(bool numericonly)
     815{
     816        bool save = dontcheckchanges;
     817        dontcheckchanges = 1;
     818        ParamInterface::setDefault(numericonly);
     819        dontcheckchanges = save;
     820}
     821
     822void SimpleAbstractParam::setDefault(int i, bool numericonly)
     823{
     824        bool save = dontcheckchanges;
     825        dontcheckchanges = 1;
     826        ParamInterface::setDefault(i, numericonly);
     827        dontcheckchanges = save;
     828}
     829
     830// Returns the address of the beginning of the line.
     831// len = line length (without \n).
     832// 0 may mean the line with length=0 or the end of the SString.
     833// poz is advanced to the beginning of the next line.
     834// A typical loop: for(poz=0;poz<s.d;) {line=getline(s,poz,len);...
     835static const char *getline(const SString &s, int &poz, int &len)
     836{
     837        const char *beg = (const char*)s + poz;
     838        if (poz >= s.len()) { poz = s.len(); len = 0; return (const char*)s + s.len(); }
     839        const char *lf = strchr(beg, '\n');
     840        if (!lf) { lf = (const char*)s + s.len() - 1; poz = s.len(); }
     841        else { poz = (lf - (const char*)s) + 1; if (poz > s.len()) poz = s.len(); }
     842        while (lf >= beg) if ((*lf == '\n') || (*lf == '\r')) lf--; else break;
     843        len = lf - beg + 1;
     844        return beg;
     845}
     846
     847int ParamInterface::load2(const SString &s, int &poz)
     848{
     849        int i; // the index number of the parameter
     850        int tmpi;
     851        int len;
     852        int ret;
     853        int fields_loaded = 0;
     854        const char *t, *lin, *end;
     855        const char *equals_sign, *comma_sign;
     856        char remember;
     857        const char *quote, *quote2;
     858        const char *value, *valstop;
     859        SString tmpvalue;
     860        if (poz >= s.len()) return fields_loaded;
     861        t = (const char*)s + poz;
     862
     863        lin = getline(s, poz, len); // all fields must be encoded in a single line
     864        if (!len) return fields_loaded; // empty line = end
     865        i = 0;
     866        end = lin + len;
     867        while (t < end)
     868        {
     869                // processing a single field
     870                while (strchr(" \n\r\t", *t)) if (t<end) t++; else return fields_loaded;
     871
     872                comma_sign = strchrlimit(t, ',', end); if (!comma_sign) comma_sign = end;
     873                quote = strchrlimit(t, '\"', comma_sign);
     874                if (quote)
     875                {
     876                        quote2 = skipQuoteString(quote + 1, end);
     877                        if (quote2>comma_sign)
    675878                        {
    676                         result |= PSET_CHANGED;
    677                         *((long*)target)=x;
     879                                comma_sign = strchrlimit(quote2 + 1, ',', end);
     880                                if (!comma_sign) comma_sign = end;
    678881                        }
    679         }
    680     messageOnExceedRange(i,result,xcopy);
    681         return result;
    682 }
    683 
    684 int SimpleAbstractParam::setDouble(int i,double x)
    685 {
    686 ExtValue v;
    687 ParamEntry *pe=entry(i);
    688 if (pe->flags&PARAM_READONLY) return PSET_RONLY;
    689 double xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
    690 double a=0,b=0;
    691 int result=0;
    692 const char* t=pe->type+1;
    693 while(*t) if (*t==' ') break; else t++;
    694 if (sscanf(t,"%lg %lg",&a,&b)==2)
    695         if (a<=b) // jezeli max<min to znaczy ze min/max nie obowiazuje
    696                 {
    697                 if (x<a) {x=a; result=PSET_HITMIN;}
    698                 else if (x>b) {x=b; result=PSET_HITMAX;}
    699                 }
    700 
    701 if (pe->fun2)
    702         {
    703         v.setDouble(x);
    704         result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
    705         }
    706 else
    707         {
    708         void *target=getTarget(i);
    709         if (dontcheckchanges || (*((double*)target)!=x))
    710                 {
    711                 result|=PSET_CHANGED;
    712                 *((double*)target)=x;
    713                 }
    714         }
    715     messageOnExceedRange(i,result,xcopy);
    716         return result;
    717 }
    718 
    719 int SimpleAbstractParam::setString(int i,const SString& x)
    720 {
    721 ExtValue v;
    722 SString vs;
    723 const SString *xx=&x;
    724 ParamEntry *pe=entry(i);
    725 if (pe->flags&PARAM_READONLY) return PSET_RONLY;
    726 SString xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
    727 const char* t=pe->type+1;
    728 while(*t) if (*t==' ') break; else t++;
    729 long a=0,b=0;
    730 int result=0;
    731 if (sscanf(t,"%ld %ld",&a,&b)==2)
    732         {
    733         if ((x.len()>b)&&(b>0))
    734                 {
    735                 vs=x.substr(0,b);
    736                 xx=&vs;
    737                 result|=PSET_HITMAX;
    738                 }
    739         }
    740 
    741 if (pe->fun2)
    742         {
    743         v.setString(*xx);
    744         result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
    745         }
    746 else
    747         {
    748         void *target=getTarget(i);
    749         if (dontcheckchanges || (!(*((SString*)target) == *xx)))
    750                 {
    751                 result|=PSET_CHANGED;
    752                 *((SString*)target)=x;
    753                 }
    754         }
    755     messageOnExceedRange(i,result,xcopy);
    756         return result;
    757 }
    758 
    759 int SimpleAbstractParam::setObject(int i,const ExtObject& x)
    760 {
    761 ExtValue v;
    762 ParamEntry *pe=entry(i);
    763 if (pe->flags&PARAM_READONLY) return PSET_RONLY;
    764 ExtObject xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
    765 if (pe->fun2)
    766         {
    767         v.setObject(x);
    768         int result=(*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
    769     messageOnExceedRange(i,result,xcopy);
    770     return result;
    771         }
    772 else
    773         {
    774         void *target=getTarget(i);
    775         *((ExtObject*)target)=x;
    776         return PSET_CHANGED;
    777         }
    778 }
    779 
    780 int SimpleAbstractParam::setExtValue(int i,const ExtValue& x)
    781 {
    782 ParamEntry *pe=entry(i);
    783 if (pe->flags&PARAM_READONLY) return PSET_RONLY;
    784 ExtValue xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
    785 if (pe->fun2)
    786         {
    787         int result=(*(int(*)(void*,const ExtValue*))pe->fun2)(object,&x);
    788     messageOnExceedRange(i,result,xcopy);
    789     return result;
    790         }
    791 else
    792         {
    793         void *target=getTarget(i);
    794         *((ExtValue*)target)=x;
    795         return PSET_CHANGED;
    796         }
    797 }
    798 
    799 void SimpleAbstractParam::call(int i,ExtValue *args,ExtValue *ret)
    800 {
    801 ParamEntry *pe=entry(i);
    802 if (!pe) return;
    803 if (pe->fun1 && (pe->type[0]=='p'))
    804         (*(void(*)(void*,ExtValue*,ExtValue*))pe->fun1)(object,args,ret);
    805 else
    806         {
    807         FMprintf("SimpleAbstractParam","call",FMLV_ERROR,
    808                  (*pe->type!='p')?"'%s.%s' is not a function":"Internal error - undefined function pointer for '%s.%s'",getName(),pe->id);
    809         }
    810 }
    811 
    812 void SimpleAbstractParam::setDefault(bool numericonly)
    813 {
    814 bool save=dontcheckchanges;
    815 dontcheckchanges=1;
    816 ParamInterface::setDefault(numericonly);
    817 dontcheckchanges=save;
    818 }
    819 
    820 void SimpleAbstractParam::setDefault(int i,bool numericonly)
    821 {
    822 bool save=dontcheckchanges;
    823 dontcheckchanges=1;
    824 ParamInterface::setDefault(i,numericonly);
    825 dontcheckchanges=save;
    826 }
    827 
    828 // zwraca adres poczatku linii
    829 // len = dlugosc linii (bez \n)
    830 // 0 moze oznaczac linie dlugosci 0 lub koniec SStringa
    831 // poz jest przesuwane na poczatek nastepnej linii
    832 // typowa petla: for(poz=0;poz<s.d;) {line=getline(s,poz,len);...
    833 static const char *getline(const SString &s,int &poz,int &len)
    834 {
    835 const char *beg=(const char*)s+poz;
    836 if (poz>=s.len()) {poz=s.len(); len=0; return (const char*)s+s.len();}
    837 const char *lf=strchr(beg,'\n');
    838 if (!lf) { lf=(const char*)s+s.len()-1; poz=s.len(); }
    839 else {poz=(lf-(const char*)s)+1; if (poz>s.len()) poz=s.len();}
    840 while (lf>=beg) if ((*lf=='\n')||(*lf=='\r')) lf--; else break;
    841 len=lf-beg+1;
    842 return beg;
    843 }
    844 
    845 int ParamInterface::load2(const SString &s,int &poz)
    846 {
    847 int i; // numer akt. parametru
    848 int tmpi;
    849 int len;
    850 int ret;
    851 int fields_loaded=0;
    852 const char *t,*lin,*end;
    853 const char *rownasie,*przecinek;
    854 char remember;
    855 const char *quote,*quote2;
    856 const char *value,*valstop;
    857 SString tmpvalue;
    858 if (poz>=s.len()) return fields_loaded;
    859 t=(const char*)s+poz;
    860 
    861 // na razie wszystko musi byc w jednej linii...
    862 lin=getline(s,poz,len);
    863 if (!len) return fields_loaded; // pusta linia = koniec
    864 i=0;
    865 end=lin+len;
    866 while(t<end)
    867 {
    868 // przetwarzanie jednego par
    869 while (strchr(" \n\r\t",*t)) if (t<end) t++; else return fields_loaded;
    870 
    871 przecinek=strchrlimit(t,',',end); if (!przecinek) przecinek=end;
    872 quote=strchrlimit(t,'\"',przecinek);
    873 if (quote)
    874         {
    875         quote2=skipQuoteString(quote+1,end);
    876         if (quote2>przecinek)
    877                 {
    878                 przecinek=strchrlimit(quote2+1,',',end);
    879                 if (!przecinek) przecinek=end;
    880                 }
    881         rownasie=strchrlimit(t,'=',quote);
    882         }
    883 else
    884         {
    885         rownasie=strchrlimit(t,'=',przecinek);
    886         quote2=0;
    887         }
    888 if (rownasie==t) { t++; rownasie=0; }
    889 if (przecinek==t)       // skip empty value
    890         {
    891         t++; i++;
    892         continue;
    893         }
    894 if (rownasie) // have parameter name
    895         {
    896         tmpi=findIdn(t,rownasie-t);
    897         i=tmpi;
    898         if (tmpi<0)
    899                 FMprintf("Param","load2",FMLV_WARN,"Unknown property name for '%s' (ignored)",getName());
    900         t=rownasie+1; // t=value
    901         }
     882                        equals_sign = strchrlimit(t, '=', quote);
     883                }
     884                else
     885                {
     886                        equals_sign = strchrlimit(t, '=', comma_sign);
     887                        quote2 = 0;
     888                }
     889                if (equals_sign == t) { t++; equals_sign = 0; }
     890                if (comma_sign == t)    // skip empty value
     891                {
     892                        t++; i++;
     893                        continue;
     894                }
     895                if (equals_sign) // have parameter name
     896                {
     897                        tmpi = findIdn(t, equals_sign - t);
     898                        i = tmpi;
     899                        if (tmpi < 0)
     900                                FMprintf("Param", "load2", FMLV_WARN, "Unknown property name for '%s' (ignored)", getName());
     901                        t = equals_sign + 1; // t=value
     902                }
    902903#ifdef WARN_MISSING_NAME
    903 else
     904                else
    904905#ifdef SAVE_SELECTED_NAMES
    905 if (!(flags(i)&PARAM_CANOMITNAME))
     906                        if (!(flags(i)&PARAM_CANOMITNAME))
    906907#endif
    907         {
    908         FMprintf("Param","load2",FMLV_WARN,"Missing property name in '%s' (assuming '%s')",
    909                  getName(),id(i)?id(i):"unknown property?");
    910         }
     908                        {
     909                                FMprintf("Param", "load2", FMLV_WARN, "Missing property name in '%s' (assuming '%s')",
     910                                        getName(), id(i) ? id(i) : "unknown property?");
     911                        }
    911912#endif
    912 if ((i>=0)&&id(i))
    913         {
    914         value=t;
    915         if (quote)
    916                 {
    917                 tmpvalue.copyFrom(quote+1,quote2-quote-1);
    918                 sstringUnquote(tmpvalue);
    919                 value=tmpvalue;
    920                 valstop=quote2;
    921                 }
    922         else
    923                 if (przecinek<end) valstop=przecinek; else valstop=end;
    924 
    925         remember=*valstop;
    926         *(char*)valstop=0;
    927         ret=set(i,value);
    928         fields_loaded++;
    929         if (ret&(PSET_HITMAX|PSET_HITMIN))
    930                 FMprintf("Param","load2",FMLV_WARN,"Adjusted '%s' in '%s' (was too %s)",
    931                         id(i),getName(),(ret&PSET_HITMAX)?"big":"small");
    932         *(char*)valstop=remember;
    933         }
    934 
    935 if (i>=0) i++;
     913                if ((i >= 0) && id(i))
     914                {
     915                        value = t;
     916                        if (quote)
     917                        {
     918                                tmpvalue.copyFrom(quote + 1, quote2 - quote - 1);
     919                                sstringUnquote(tmpvalue);
     920                                value = tmpvalue;
     921                                valstop = quote2;
     922                        }
     923                        else
     924                                if (comma_sign < end) valstop = comma_sign; else valstop = end;
     925
     926                        remember = *valstop;
     927                        *(char*)valstop = 0;
     928                        ret = set(i, value);
     929                        fields_loaded++;
     930                        if (ret&(PSET_HITMAX | PSET_HITMIN))
     931                                FMprintf("Param", "load2", FMLV_WARN, "Adjusted '%s' in '%s' (was too %s)",
     932                                id(i), getName(), (ret&PSET_HITMAX) ? "big" : "small");
     933                        *(char*)valstop = remember;
     934                }
     935
     936                if (i >= 0) i++;
    936937#ifdef __CODEGUARD__
    937 if (przecinek<end-1) t=przecinek+1; else return fields_loaded;
     938                if (comma_sign<end-1) t=comma_sign+1; else return fields_loaded;
    938939#else
    939 t=przecinek+1;
     940                t = comma_sign + 1;
    940941#endif
    941 }
    942 return fields_loaded;
    943 }
    944 
    945 int Param::grmember(int g,int a)
    946 {
    947 if ((getGroupCount()<2)&&(!g))
    948         return (a<getPropCount())?a:-9999;
    949 
    950 ParamEntry *e=entry(0);
    951 int x=0,i=0;
    952 for (;e->id;i++,e++)
    953         {
    954         if (e->group==g)
    955                 if (a==x) return i; else x++;
    956         }
    957 return -9999;
    958 }
    959 
     942        }
     943        return fields_loaded;
     944}
     945
     946int Param::grmember(int g, int a)
     947{
     948        if ((getGroupCount() < 2) && (!g))
     949                return (a < getPropCount()) ? a : -9999;
     950
     951        ParamEntry *e = entry(0);
     952        int x = 0, i = 0;
     953        for (; e->id; i++, e++)
     954        {
     955                if (e->group == g)
     956                        if (a == x) return i; else x++;
     957        }
     958        return -9999;
     959}
Note: See TracChangeset for help on using the changeset viewer.