source: cpp/gdk/param.cpp @ 81

Last change on this file since 81 was 81, checked in by Maciej Komosinski, 11 years ago

improved parsing of properties (e.g. in f0 genotypes)

  • Property svn:eol-style set to native
File size: 18.7 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include <stdio.h>
6#include <ctype.h>
7
8#include "param.h"
9#include "extvalue.h"
10#include "framsg.h"
11#include "sstringutils.h"
12
13//#define SAVE_ALL_NAMES
14#define SAVE_SELECTED_NAMES
15#define WARN_MISSING_NAME
16
17char MakeCodeGuardHappy;
18
19ParamEntry empty_paramtab[]=
20{ {"Empty",1,0,"Empty",}, {0,0,0,}, };
21
22static void czytdotyldy(VirtFILE *f,SString &s)
23{
24SString temp;
25int z;
26char last_char=0;
27while((z=fgetc(f))!=EOF)
28        {
29        if (z=='~')
30                if (last_char!='\\') break;
31        last_char=(char)z;
32        temp+=last_char;
33        }
34s=temp;
35}
36
37static const char *strchrlimit(const char *t,int ch,const char *limit)
38{
39int n=limit-t;
40for (;(n>0)&&*t;t++,n--)
41        if (*t==ch) return t;
42return 0;
43}
44
45static char* fgets0(char*t,int d,VirtFILE *f, bool& eolfound)
46{
47char *r=fgets(t,d,f);
48eolfound=false;
49if (r)
50        {
51        int d=strlen(r);
52        while (d-- > 0) if ((r[d]=='\r')||(r[d]=='\n')) {r[d]=0; eolfound=true;} else break;
53        }
54return r;
55}
56
57void ParamInterface::copyFrom(ParamInterface *src)
58{
59int n=getPropCount();
60ExtValue v;
61int j;
62for(int i=0;i<n;i++)
63  if ((!(flags(i)&PARAM_READONLY))
64          && (*type(i)!='p'))
65        {
66        j=src->findId(id(i));
67        if (j<0) continue;
68        src->get(j,v);
69        set(i,v);
70        }
71}
72
73void ParamInterface::quickCopyFrom(ParamInterface *src)
74{
75int n=getPropCount();
76ExtValue v;
77for(int i=0;i<n;i++)
78  if ((!(flags(i)&PARAM_READONLY))
79          && (*type(i)!='p'))
80          {
81          src->get(i,v);
82          set(i,v);
83          }
84}
85
86int ParamInterface::getMinMax(int prop,long& minumum,long& maximum,long &def)
87{
88const char* t=type(prop)+1;
89while(*t) if (*t==' ') break; else t++;
90return sscanf(t,"%ld %ld %ld",&minumum,&maximum,&def);
91}
92
93int ParamInterface::getMinMax(int prop,double& minumum,double& maximum,double& def)
94{
95const char* t=type(prop)+1;
96while(*t) if (*t==' ') break; else t++;
97return sscanf(t,"%lg %lg %lg",&minumum,&maximum,&def);
98}
99
100void ParamInterface::setDefault(bool numericonly)
101{
102int n=getPropCount();
103for(int i=0;i<n;i++)
104        setDefault(i,numericonly);
105}
106
107void ParamInterface::setMin()
108{
109int n=getPropCount();
110for(int i=0;i<n;i++)
111        setMin(i);
112}
113
114void ParamInterface::setMax()
115{
116int n=getPropCount();
117for(int i=0;i<n;i++)
118        setMax(i);
119}
120
121void ParamInterface::setDefault(int i,bool numericonly)
122{
123const char *t=type(i);
124switch(*t)
125        {
126        case 'f':
127        {
128        double a=0,b=0,c=0;
129        getMinMax(i,a,b,c);
130        setDouble(i,c);
131        }
132        break;
133        case 'd':
134        {
135        long a=0,b=0,c=0;
136        getMinMax(i,a,b,c);
137        setInt(i,c);
138        }
139        break;
140        default: if (!numericonly) set(i,"");
141        }
142}
143
144void ParamInterface::setMin(int i)
145{
146const char *t=type(i);
147switch(*t)
148        {
149        case 'f':
150        {
151        double a=0,b=0,c=0;
152        getMinMax(i,a,b,c);
153        setDouble(i,a);
154        }
155        break;
156        case 'd':
157        {
158        long a=0,b=0,c=0;
159        getMinMax(i,a,b,c);
160        setInt(i,a);
161        }
162        break;
163        default: set(i,"");
164        }
165}
166
167void ParamInterface::setMax(int i)
168{
169const char *t=type(i);
170switch(*t)
171        {
172        case 'f':
173        {
174        double a=0,b=0,c=0;
175        getMinMax(i,a,b,c);
176        setDouble(i,b);
177        }
178        break;
179        case 'd':
180        {
181        long a=0,b=0,c=0;
182        getMinMax(i,a,b,c);
183        setInt(i,b);
184        }
185        break;
186        default: set(i,"");
187        }
188}
189
190SString ParamInterface::getStringById(const char*prop)
191{int i=findId(prop); if (i>=0) return getString(i); else return SString();}
192long ParamInterface::getIntById(const char*prop)
193{int i=findId(prop); if (i>=0) return getInt(i); else return 0;}
194double ParamInterface::getDoubleById(const char*prop)
195{int i=findId(prop); if (i>=0) return getDouble(i); else return 0;}
196ExtObject ParamInterface::getObjectById(const char*prop)
197{int i=findId(prop); if (i>=0) return getObject(i); else return ExtObject();}
198ExtValue ParamInterface::getExtValueById(const char*prop)
199{int i=findId(prop); if (i>=0) return getExtValue(i); else return ExtValue();}
200
201int ParamInterface::setIntById(const char* prop,long v)
202{int i=findId(prop); if (i>=0) return setInt(i,v); else return PSET_NOPROPERTY;}
203int ParamInterface::setDoubleById(const char* prop,double v)
204{int i=findId(prop); if (i>=0) return setDouble(i,v); else return PSET_NOPROPERTY;}
205int ParamInterface::setStringById(const char* prop,const SString &v)
206{int i=findId(prop); if (i>=0) return setString(i,v); else return PSET_NOPROPERTY;}
207int ParamInterface::setObjectById(const char* prop,const ExtObject &v)
208{int i=findId(prop); if (i>=0) return setObject(i,v); else return PSET_NOPROPERTY;}
209int ParamInterface::setExtValueById(const char* prop,const ExtValue &v)
210{int i=findId(prop); if (i>=0) return setExtValue(i,v); else return PSET_NOPROPERTY;}
211
212int ParamInterface::save(VirtFILE* f,const SString* altname,bool force)
213{
214const char *p;
215SString ws;
216int err=0,i;
217bool withname=false;
218if ((!altname)||(altname->len()))
219        {
220        err|=(fputs(altname?((const char*)(*altname)):getName(),f)==EOF);
221        err|=(fputs(":\n",f)==EOF);
222        withname=true;
223        }
224for (i=0;p=id(i);i++)
225        err|=saveprop(f,i,p,force);
226if (withname)
227        err|=(fputs("\n",f)==EOF);
228return err;
229}
230
231int ParamInterface::saveprop(VirtFILE* f,int i,const char* p,bool force)
232{
233if ((flags(i)&PARAM_DONTSAVE)&&(!force)) return 0;
234const char *typ=type(i);
235if ((*typ=='p')||(*typ=='o')) return 0;
236
237const char *t,*w;
238SString ws;
239int err=0,cr;
240
241err|=(fputs(p,f)==EOF); fputc(':',f);
242cr=0;
243ws=get(i);
244quoteTilde(ws);
245w=ws;
246if (ws.len()>50) cr=1;
247else for (t=w;*t;t++) if ((*t==10)||(*t==13)) {cr=1; break;}
248if (cr) fputs("~\n",f);
249err|=(fputs(w,f)==EOF);
250err|=(fputs(cr ? "~\n" : "\n",f)==EOF);
251return err;
252}
253
254
255int SimpleAbstractParam::isequal(int i,void* defdata)
256{ // defdata->member == object->member ?
257void *backup=object;
258switch(type(i)[0])
259        {
260        case 'd':
261                {
262                select(defdata);
263                long x=getInt(i);
264                select(backup);
265                return x==getInt(i);
266                }
267        case 'f':
268                {
269                select(defdata);
270                double x=getDouble(i);
271                select(backup);
272                return x==getDouble(i);
273                }
274        case 's':
275                {
276                select(defdata);
277                SString x=getString(i);
278                select(backup);
279                return x==getString(i);
280                }
281        }
282return 1;
283}
284
285void SimpleAbstractParam::save2(SString& f,void *defdata,bool addcr,bool all_names)
286{ // defdata!=NULL -> nie zapisuje wartosci domyslnych
287const char *p;
288int i;
289int needlabel=0;
290int first=1;
291SString val;
292SString t;
293int fl;
294// t+=SString(getName()); t+=':';
295for (i=0;p=id(i);i++)
296        if (!((fl=flags(i))&PARAM_DONTSAVE))
297        {
298        if (defdata && isequal(i,defdata))
299                needlabel=1;
300        else
301                {
302                if (!first) t+=", ";
303#ifndef SAVE_ALL_NAMES
304#ifdef SAVE_SELECTED_NAMES
305                if (needlabel || all_names || !(fl & PARAM_CANOMITNAME))
306#else
307                if (needlabel)
308#endif
309#endif
310                        { t+=p; t+="="; needlabel=0; }
311                if (type(i)[0]=='s')
312                        { // string - special case
313                        SString str=getString(i);
314                        if (strContainsOneOf(str,", \\\n\r\t\""))
315                                {
316                                t+="\"";
317                                sstringQuote(str);
318                                t+=str;
319                                t+="\"";
320                                }
321                        else
322                                t+=str;
323                        }
324                else
325                        t+=get(i);
326                first=0;
327                }
328        }
329if (addcr)
330        t+="\n";
331f+=t;
332}
333
334void ParamInterface::load(VirtFILE* f)
335{
336char t[100];
337int i;
338const char *p,*p0;
339int p_len;
340bool eol,loaded;
341int ret;
342while(fgets0(t,100,f,eol))
343        {
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                        {
353                        SString s;
354                        czytdotyldy(f,s);
355                        int ch; while((ch=fgetc(f))!=EOF) if (ch=='\n') break;
356                        unquoteTilde(s);
357                        ret=set(i,(const char*)s);
358                        }
359                else
360                        {
361                        if (eol)
362                                ret=set(i,p0+p_len+1);
363                        else
364                                {
365                                SString tmp=p0+p_len+1;
366                                while(!eol)
367                                        {
368                                        if (!fgets0(t,100,f,eol)) break;
369                                        tmp+=t;
370                                        }
371                                ret=set(i,(const char*)tmp);
372                                }
373                        }
374                if (ret & (PSET_HITMIN | PSET_HITMAX))
375                        FMprintf("Param","load2",FMLV_WARN,"Adjusted '%s' in '%s' (was too %s)",
376                                 id(i),getName(),(ret&PSET_HITMAX)?"big":"small");
377                loaded=true;
378                }
379        if ((!loaded) && (p0[p_len+1]=='~'))
380                { // eat unrecognized multiline field
381                SString s;
382                czytdotyldy(f,s);
383                int ch; while((ch=fgetc(f))!=EOF) if (ch=='\n') break;
384                }
385        }
386}
387
388
389/*
390SString SimpleAbstractParam::getString(int i)
391{
392char *t;
393switch (*(t=type(i)))
394        {
395        case 'd':
396        {
397        for (i=atol(get(i));i>=0;i--) if (t) t=strchr(t+1,'~');
398        if (t)
399                {
400                t++;
401                char *t2=strchr(t,'~');
402                if (!t2) t2=t+strlen(t);
403                SString str;
404                strncpy(str.directWrite(t2-t),t,t2-t);
405                str.endWrite(t2-t);
406                return str;
407                }
408        }
409        }
410return get(i);
411}
412*/
413
414int ParamInterface::findId(const char* n)
415{
416int i; const char *p;
417        for (i=0;p=id(i);i++) if (!strcmp(n,p)) return i;
418return -1;
419}
420
421int ParamInterface::findIdn(const char* naz,int n)
422{
423int i; const char *p;
424        for (i=0;p=id(i);i++) if ((!strncmp(naz,p,n))&&(!p[n])) return i;
425return -1;
426}
427
428void ParamInterface::get(int i,ExtValue &ret)
429{
430switch(type(i)[0])
431        {
432        case 'd':       ret.setInt(getInt(i)); break;
433        case 'f':       ret.setDouble(getDouble(i)); break;
434        case 's':       ret.setString(getString(i)); break;
435        case 'o':       ret.setObject(getObject(i)); break;
436        case 'x':       ret=getExtValue(i); break;
437        default: FMprintf("ParamInterface","get",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));
438        }
439}
440
441static bool stringIsNumeric(const char* str)
442{//   /-?.?[0-9]+/
443if (!str) return false;
444if (*str=='-') str++;
445if (*str=='.') str++;
446return isdigit(*str);
447}
448
449int ParamInterface::setInt(int i,const char* str)
450{
451if (!stringIsNumeric(str))
452        {
453        long a,b,c;
454        if (getMinMax(i,a,b,c)>=3)
455                return setInt(i,c);
456        else
457                return setInt(i,(long)0);
458        }
459else
460        return setInt(i,atol(str));
461}
462
463int ParamInterface::setDouble(int i,const char* str)
464{
465if (!stringIsNumeric(str))
466        {
467        double a,b,c;
468        if (getMinMax(i,a,b,c)>=3)
469                return setDouble(i,c);
470        else
471                return setDouble(i,(double)0);
472        }
473else
474        return setDouble(i,atof(str));
475}
476
477int ParamInterface::set(int i,const ExtValue &v)
478{
479switch(type(i)[0])
480        {
481        case 'd': if ((v.type==TInt)||(v.type==TDouble)) return setInt(i,v.getInt()); else return setInt(i,(const char*)v.getString());
482        case 'f': if ((v.type==TInt)||(v.type==TDouble)) return setDouble(i,v.getDouble()); else return setDouble(i,(const char*)v.getString());
483        case 's': { SString t=v.getString(); return setString(i,t); }
484        case 'o': return setObject(i,v.getObject());
485        case 'x': return setExtValue(i,v);
486        default: FMprintf("ParamInterface","get",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));
487        }
488return 0;
489}
490
491int ParamInterface::set(int i,const char *v)
492{
493switch(type(i)[0])
494        {
495        case 'd': return setInt(i,v);
496        case 'f': return setDouble(i,v);
497        case 's': { SString t(v); return setString(i,t); }
498        case 'x':
499        {
500        ExtValue e;
501        if (isdigit(*v)||((*v=='-')&&isdigit(v[1])))
502                {
503                if (strchr(v,'.')) e.setDouble(atof(v));
504                else e.setInt(atol(v));
505                }
506        else
507                {
508                e.setString(SString(v));
509                }
510        return setExtValue(i,e);
511        }
512        }
513return 0;
514}
515
516SString ParamInterface::getText(int i)
517{
518const char *t;
519if ((*(t=type(i)))=='d')
520        {
521        for (int j=getInt(i);j>=0;j--) if (t) t=strchr(t+1,'~');
522        if (t)
523                {
524                t++;
525                const char *t2=strchr(t,'~');
526                if (!t2) t2=t+strlen(t);
527                return SString(t,t2-t);
528                }
529        }
530return get(i);
531}
532
533SString ParamInterface::get(int i)
534{
535switch(type(i)[0])
536        {
537        case 'd':
538                {
539                SString tmp;
540                sprintf(tmp.directWrite(20),"%ld",getInt(i)); tmp.endWrite();
541                return tmp;
542                }
543        case 'f':
544                {
545                SString tmp;
546                sprintf(tmp.directWrite(20),"%lg",getDouble(i)); tmp.endWrite();
547                return tmp;
548                }
549        case 's':
550                return getString(i);
551        }
552ExtValue v;
553get(i,v);
554return v.getString();
555}
556
557
558//////////////////////////////// PARAM ////////////////////////////////////
559
560void *SimpleAbstractParam::getTarget(int i)
561{
562return (void*)(((char*)object)+entry(i)->offset);
563//return &(object->*(entry(i)->fldptr));
564}
565
566///////// get
567
568long SimpleAbstractParam::getInt(int i)
569{
570static ExtValue v;
571ParamEntry *pe=entry(i);
572if (pe->fun1)
573        {
574        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
575        return v.getInt();
576        }
577else
578        {
579        void *target=getTarget(i);
580        return *((long*)target);
581        }
582}
583
584double SimpleAbstractParam::getDouble(int i)
585{
586static ExtValue v;
587ParamEntry *pe=entry(i);
588if (pe->fun1)
589        {
590        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
591        return v.getDouble();
592        }
593else
594        {
595        void *target=getTarget(i);
596        return *((double*)target);
597        }
598}
599
600SString SimpleAbstractParam::getString(int i)
601{
602static ExtValue v;
603ParamEntry *pe=entry(i);
604if (pe->fun1)
605        {
606        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
607        return v.getString();
608        }
609else
610        {
611        void *target=getTarget(i);
612        return *((SString*)target);
613        }
614}
615
616ExtObject SimpleAbstractParam::getObject(int i)
617{
618static ExtValue v;
619ParamEntry *pe=entry(i);
620if (pe->fun1)
621        {
622        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
623        return v.getObject();
624        }
625else
626        {
627        void *target=getTarget(i);
628        return *((ExtObject*)target);
629        }
630}
631
632ExtValue SimpleAbstractParam::getExtValue(int i)
633{
634static ExtValue v;
635ParamEntry *pe=entry(i);
636if (pe->fun1)
637        {
638        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
639        return v;
640        }
641else
642        {
643        void *target=getTarget(i);
644        return *((ExtValue*)target);
645        }
646}
647
648
649//////// set
650
651int SimpleAbstractParam::setInt(int i,long x)
652{
653static ExtValue v;
654ParamEntry *pe=entry(i);
655if (pe->flags&PARAM_READONLY) return PSET_RONLY;
656long a=0,b=0,result=0;
657const char* t=pe->type+1;
658while(*t) if (*t==' ') break; else t++;
659if (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
666if (pe->fun2)
667        {
668        v.setInt(x);
669        return result | (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
670        }
671else
672        {
673        void *target=getTarget(i);
674        if (dontcheckchanges || (*((long*)target)!=x))
675                        {
676                        result |= PSET_CHANGED;
677                        *((long*)target)=x;
678                        }
679        return result;
680        }
681}
682
683int SimpleAbstractParam::setDouble(int i,double x)
684{
685static ExtValue v;
686ParamEntry *pe=entry(i);
687if (pe->flags&PARAM_READONLY) return PSET_RONLY;
688double a=0,b=0; int result=0;
689const char* t=pe->type+1;
690while(*t) if (*t==' ') break; else t++;
691if (sscanf(t,"%lg %lg",&a,&b)==2)
692        if (a<=b) // jezeli max<min to znaczy ze min/max nie obowiazuje
693                {
694                if (x<a) {x=a; result=PSET_HITMIN;}
695                else if (x>b) {x=b; result=PSET_HITMAX;}
696                }
697
698if (pe->fun2)
699        {
700        v.setDouble(x);
701        return result | (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
702        }
703else
704        {
705        void *target=getTarget(i);
706        if (dontcheckchanges || (*((double*)target)!=x))
707                {
708                result|=PSET_CHANGED;
709                *((double*)target)=x;
710                }
711        return result;
712        }
713}
714
715int SimpleAbstractParam::setString(int i,const SString& x)
716{
717static ExtValue v;
718static SString vs;
719const SString *xx=&x;
720ParamEntry *pe=entry(i);
721if (pe->flags&PARAM_READONLY) return PSET_RONLY;
722const char* t=pe->type+1;
723while(*t) if (*t==' ') break; else t++;
724long a=0,b=0,result=0;
725if (sscanf(t,"%ld %ld",&a,&b)==2)
726        {
727        if ((x.len()>b)&&(b>0))
728                {
729                vs=x.substr(0,b);
730                xx=&vs;
731                result|=PSET_HITMAX;
732                }
733        }
734
735if (pe->fun2)
736        {
737        v.setString(*xx);
738        return result | (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
739        }
740else
741        {
742        void *target=getTarget(i);
743        if (dontcheckchanges || (!(*((SString*)target) == *xx)))
744                {
745                result|=PSET_CHANGED;
746                *((SString*)target)=x;
747                }
748        return result;
749        }
750}
751
752int SimpleAbstractParam::setObject(int i,const ExtObject& x)
753{
754static ExtValue v;
755ParamEntry *pe=entry(i);
756if (pe->flags&PARAM_READONLY) return PSET_RONLY;
757if (pe->fun2)
758        {
759        v.setObject(x);
760        return (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
761        }
762else
763        {
764        void *target=getTarget(i);
765        *((ExtObject*)target)=x;
766        return PSET_CHANGED;
767        }
768}
769
770int SimpleAbstractParam::setExtValue(int i,const ExtValue& x)
771{
772ParamEntry *pe=entry(i);
773if (pe->flags&PARAM_READONLY) return PSET_RONLY;
774if (pe->fun2)
775        {
776        return (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&x);
777        }
778else
779        {
780        void *target=getTarget(i);
781        *((ExtValue*)target)=x;
782        return PSET_CHANGED;
783        }
784}
785
786void SimpleAbstractParam::call(int i,ExtValue *args,ExtValue *ret)
787{
788ParamEntry *pe=entry(i);
789if (!pe) return;
790if (pe->fun1 && (pe->type[0]=='p'))
791        (*(void(*)(void*,ExtValue*,ExtValue*))pe->fun1)(object,args,ret);
792else
793        {
794        FMprintf("SimpleAbstractParam","call",FMLV_ERROR,
795                 (*pe->type!='p')?"'%s.%s' is not a function":"internal error - undefined function pointer for '%s.%s'",getName(),pe->id);
796        }
797}
798
799void SimpleAbstractParam::setDefault(bool numericonly)
800{
801bool save=dontcheckchanges;
802dontcheckchanges=1;
803ParamInterface::setDefault(numericonly);
804dontcheckchanges=save;
805}
806
807void SimpleAbstractParam::setDefault(int i,bool numericonly)
808{
809bool save=dontcheckchanges;
810dontcheckchanges=1;
811ParamInterface::setDefault(i,numericonly);
812dontcheckchanges=save;
813}
814
815// zwraca adres poczatku linii
816// len = dlugosc linii (bez \n)
817// 0 moze oznaczac linie dlugosci 0 lub koniec SStringa
818// poz jest przesuwane na poczatek nastepnej linii
819// typowa petla: for(poz=0;poz<s.d;) {line=getline(s,poz,len);...
820static const char *getline(const SString &s,int &poz,int &len)
821{
822const char *beg=(const char*)s+poz;
823if (poz>=s.len()) {poz=s.len(); len=0; return (const char*)s+s.len();}
824const char *lf=strchr(beg,'\n');
825if (!lf) { lf=(const char*)s+s.len()-1; poz=s.len(); }
826else {poz=(lf-(const char*)s)+1; if (poz>s.len()) poz=s.len();}
827while (lf>=beg) if ((*lf=='\n')||(*lf=='\r')) lf--; else break;
828len=lf-beg+1;
829return beg;
830}
831
832void ParamInterface::load2(const SString &s,int &poz)
833{
834int i; // numer akt. parametru
835int tmpi;
836int len;
837int ret;
838const char *t,*lin,*end;
839const char *rownasie,*przecinek;
840char remember;
841const char *quote,*quote2;
842const char *value,*valstop;
843SString tmpvalue;
844if (poz>=s.len()) return;
845t=(const char*)s+poz;
846
847// na razie wszystko musi byc w jednej linii...
848lin=getline(s,poz,len);
849if (!len) return; // pusta linia = koniec
850i=0;
851end=lin+len;
852while(t<end)
853{
854// przetwarzanie jednego par
855while (strchr(" \n\r\t",*t)) if (t<end) t++; else return;
856
857przecinek=strchrlimit(t,',',end); if (!przecinek) przecinek=end;
858quote=strchrlimit(t,'\"',przecinek);
859if (quote)
860        {
861        quote2=skipQuoteString(quote+1,end);
862        if (quote2>przecinek)
863                {
864                przecinek=strchrlimit(quote2+1,',',end);
865                if (!przecinek) przecinek=end;
866                }
867        rownasie=strchrlimit(t,'=',quote);
868        }
869else
870        {
871        rownasie=strchrlimit(t,'=',przecinek);
872        quote2=0;
873        }
874if (rownasie==t) { t++; rownasie=0; }
875if (przecinek==t)       // skip empty value
876        {
877        t++; i++;
878        continue;
879        }
880if (rownasie) // have parameter name
881        {
882        tmpi=findIdn(t,rownasie-t);
883        i=tmpi;
884        if (tmpi<0)
885                FMprintf("Param","load2",FMLV_WARN,"Unknown property name for '%s' (ignored)",getName());
886        t=rownasie+1; // t=value
887        }
888#ifdef WARN_MISSING_NAME
889else
890#ifdef SAVE_SELECTED_NAMES
891if (!(flags(i)&PARAM_CANOMITNAME))
892#endif
893        {
894        FMprintf("Param","load2",FMLV_WARN,"Missing property name in '%s' (assuming '%s')",
895                 getName(),id(i)?id(i):"unknown property?");
896        }
897#endif
898if ((i>=0)&&id(i))
899        {
900        value=t;
901        if (quote)
902                {
903                tmpvalue.copyFrom(quote+1,quote2-quote-1);
904                sstringUnquote(tmpvalue);
905                value=tmpvalue;
906                valstop=quote2;
907                }
908        else
909                if (przecinek<end) valstop=przecinek; else valstop=end;
910
911        remember=*valstop;
912        *(char*)valstop=0;
913        ret=set(i,value);
914        if (ret&(PSET_HITMAX|PSET_HITMIN))
915                FMprintf("Param","load2",FMLV_WARN,"Adjusted '%s' in '%s' (was too %s)",
916                        id(i),getName(),(ret&PSET_HITMAX)?"big":"small");
917        *(char*)valstop=remember;
918        }
919
920if (i>=0) i++;
921#ifdef __CODEGUARD__
922if (przecinek<end-1) t=przecinek+1; else return;
923#else
924t=przecinek+1;
925#endif
926}
927return;
928}
929
930int Param::grmember(int g,int a)
931{
932if ((getGroupCount()<2)&&(!g))
933        return (a<getPropCount())?a:-9999;
934
935ParamEntry *e=entry(0);
936int x=0,i=0;
937for (;e->id;i++,e++)
938        {
939        if (e->group==g)
940                if (a==x) return i; else x++;
941        }
942return -9999;
943}
Note: See TracBrowser for help on using the repository browser.