source: cpp/gdk/param.cpp @ 57

Last change on this file since 57 was 5, checked in by sz, 16 years ago

added the GDK (Genotype Development Kit)

File size: 17.9 KB
Line 
1// This file is a part of Framsticks GDK library.
2// Copyright (C) 2002-2006  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.frams.alife.pl/ 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,int addcr)
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 || !(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
441int ParamInterface::set(int i,const ExtValue &v)
442{
443switch(type(i)[0])
444        {
445        case 'd': return setInt(i,v.getInt());
446        case 'f': return setDouble(i,v.getDouble());
447        case 's': { SString t=v.getString(); return setString(i,t); }
448        case 'o': return setObject(i,v.getObject());
449        case 'x': return setExtValue(i,v);
450        default: FMprintf("ParamInterface","get",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));
451        }
452return 0;
453}
454
455int ParamInterface::set(int i,const char *v)
456{
457switch(type(i)[0])
458        {
459        case 'd': return setInt(i,atol(v));
460        case 'f': return setDouble(i,atof(v));
461        case 's': { SString t(v); return setString(i,t); }
462        case 'x':
463        {
464        ExtValue e;
465        if (isdigit(*v)||((*v=='-')&&isdigit(v[1])))
466                {
467                if (strchr(v,'.')) e.setDouble(atof(v));
468                else e.setInt(atol(v));
469                }
470        else
471                {
472                e.setString(SString(v));
473                }
474        return setExtValue(i,e);
475        }
476        }
477return 0;
478}
479
480SString ParamInterface::getText(int i)
481{
482const char *t;
483if ((*(t=type(i)))=='d')
484        {
485        for (int j=getInt(i);j>=0;j--) if (t) t=strchr(t+1,'~');
486        if (t)
487                {
488                t++;
489                const char *t2=strchr(t,'~');
490                if (!t2) t2=t+strlen(t);
491                return SString(t,t2-t);
492                }
493        }
494return get(i);
495}
496
497SString ParamInterface::get(int i)
498{
499switch(type(i)[0])
500        {
501        case 'd':
502                {
503                SString tmp;
504                sprintf(tmp.directWrite(20),"%ld",getInt(i)); tmp.endWrite();
505                return tmp;
506                }
507        case 'f':
508                {
509                SString tmp;
510                sprintf(tmp.directWrite(20),"%lg",getDouble(i)); tmp.endWrite();
511                return tmp;
512                }
513        case 's':
514                return getString(i);
515        }
516ExtValue v;
517get(i,v);
518return v.getString();
519}
520
521
522//////////////////////////////// PARAM ////////////////////////////////////
523
524void *SimpleAbstractParam::getTarget(int i)
525{
526return (void*)(((char*)object)+entry(i)->offset);
527//return &(object->*(entry(i)->fldptr));
528}
529
530///////// get
531
532long SimpleAbstractParam::getInt(int i)
533{
534static ExtValue v;
535ParamEntry *pe=entry(i);
536if (pe->fun1)
537        {
538        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
539        return v.getInt();
540        }
541else
542        {
543        void *target=getTarget(i);
544        return *((long*)target);
545        }
546}
547
548double SimpleAbstractParam::getDouble(int i)
549{
550static ExtValue v;
551ParamEntry *pe=entry(i);
552if (pe->fun1)
553        {
554        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
555        return v.getDouble();
556        }
557else
558        {
559        void *target=getTarget(i);
560        return *((double*)target);
561        }
562}
563
564SString SimpleAbstractParam::getString(int i)
565{
566static ExtValue v;
567ParamEntry *pe=entry(i);
568if (pe->fun1)
569        {
570        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
571        return v.getString();
572        }
573else
574        {
575        void *target=getTarget(i);
576        return *((SString*)target);
577        }
578}
579
580ExtObject SimpleAbstractParam::getObject(int i)
581{
582static ExtValue v;
583ParamEntry *pe=entry(i);
584if (pe->fun1)
585        {
586        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
587        return v.getObject();
588        }
589else
590        {
591        void *target=getTarget(i);
592        return *((ExtObject*)target);
593        }
594}
595
596ExtValue SimpleAbstractParam::getExtValue(int i)
597{
598static ExtValue v;
599ParamEntry *pe=entry(i);
600if (pe->fun1)
601        {
602        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
603        return v;
604        }
605else
606        {
607        void *target=getTarget(i);
608        return *((ExtValue*)target);
609        }
610}
611
612
613//////// set
614
615int SimpleAbstractParam::setInt(int i,long x)
616{
617static ExtValue v;
618ParamEntry *pe=entry(i);
619if (pe->flags&PARAM_READONLY) return PSET_RONLY;
620long a=0,b=0,result=0;
621const char* t=pe->type+1;
622while(*t) if (*t==' ') break; else t++;
623if (sscanf(t,"%ld %ld",&a,&b)==2)
624        if (a<=b) // jezeli max<min to znaczy ze min/max nie obowiazuje
625                {
626                if (x<a) {x=a; result=PSET_HITMIN;}
627                else if (x>b) {x=b; result=PSET_HITMAX;}
628                }
629
630if (pe->fun2)
631        {
632        v.setInt(x);
633        return result | (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
634        }
635else
636        {
637        void *target=getTarget(i);
638        if (dontcheckchanges || (*((long*)target)!=x))
639                        {
640                        result |= PSET_CHANGED;
641                        *((long*)target)=x;
642                        }
643        return result;
644        }
645}
646
647int SimpleAbstractParam::setDouble(int i,double x)
648{
649static ExtValue v;
650ParamEntry *pe=entry(i);
651if (pe->flags&PARAM_READONLY) return PSET_RONLY;
652double a=0,b=0; int result=0;
653const char* t=pe->type+1;
654while(*t) if (*t==' ') break; else t++;
655if (sscanf(t,"%lg %lg",&a,&b)==2)
656        if (a<=b) // jezeli max<min to znaczy ze min/max nie obowiazuje
657                {
658                if (x<a) {x=a; result=PSET_HITMIN;}
659                else if (x>b) {x=b; result=PSET_HITMAX;}
660                }
661
662if (pe->fun2)
663        {
664        v.setDouble(x);
665        return result | (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
666        }
667else
668        {
669        void *target=getTarget(i);
670        if (dontcheckchanges || (*((double*)target)!=x))
671                {
672                result|=PSET_CHANGED;
673                *((double*)target)=x;
674                }
675        return result;
676        }
677}
678
679int SimpleAbstractParam::setString(int i,const SString& x)
680{
681static ExtValue v;
682static SString vs;
683const SString *xx=&x;
684ParamEntry *pe=entry(i);
685if (pe->flags&PARAM_READONLY) return PSET_RONLY;
686const char* t=pe->type+1;
687while(*t) if (*t==' ') break; else t++;
688long a=0,b=0,result=0;
689if (sscanf(t,"%ld %ld",&a,&b)==2)
690        {
691        if ((x.len()>b)&&(b>0))
692                {
693                vs=x.substr(0,b);
694                xx=&vs;
695                result|=PSET_HITMAX;
696                }
697        }
698
699if (pe->fun2)
700        {
701        v.setString(*xx);
702        return result | (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
703        }
704else
705        {
706        void *target=getTarget(i);
707        if (dontcheckchanges || (!(*((SString*)target) == *xx)))
708                {
709                result|=PSET_CHANGED;
710                *((SString*)target)=x;
711                }
712        return result;
713        }
714}
715
716int SimpleAbstractParam::setObject(int i,const ExtObject& x)
717{
718static ExtValue v;
719ParamEntry *pe=entry(i);
720if (pe->flags&PARAM_READONLY) return PSET_RONLY;
721if (pe->fun2)
722        {
723        v.setObject(x);
724        return (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
725        }
726else
727        {
728        void *target=getTarget(i);
729        *((ExtObject*)target)=x;
730        return PSET_CHANGED;
731        }
732}
733
734int SimpleAbstractParam::setExtValue(int i,const ExtValue& x)
735{
736ParamEntry *pe=entry(i);
737if (pe->flags&PARAM_READONLY) return PSET_RONLY;
738if (pe->fun2)
739        {
740        return (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&x);
741        }
742else
743        {
744        void *target=getTarget(i);
745        *((ExtValue*)target)=x;
746        return PSET_CHANGED;
747        }
748}
749
750void SimpleAbstractParam::call(int i,ExtValue *args,ExtValue *ret)
751{
752ParamEntry *pe=entry(i);
753if (!pe) return;
754if (pe->fun1 && (pe->type[0]=='p'))
755        (*(void(*)(void*,ExtValue*,ExtValue*))pe->fun1)(object,args,ret);
756else
757        {
758        FMprintf("SimpleAbstractParam","call",FMLV_ERROR,
759                 (*pe->type!='p')?"'%s.%s' is not a function":"internal error - undefined function pointer for '%s.%s'",getName(),pe->id);
760        }
761}
762
763void SimpleAbstractParam::setDefault(bool numericonly)
764{
765bool save=dontcheckchanges;
766dontcheckchanges=1;
767ParamInterface::setDefault(numericonly);
768dontcheckchanges=save;
769}
770
771void SimpleAbstractParam::setDefault(int i,bool numericonly)
772{
773bool save=dontcheckchanges;
774dontcheckchanges=1;
775ParamInterface::setDefault(i,numericonly);
776dontcheckchanges=save;
777}
778
779// zwraca adres poczatku linii
780// len = dlugosc linii (bez \n)
781// 0 moze oznaczac linie dlugosci 0 lub koniec SStringa
782// poz jest przesuwane na poczatek nastepnej linii
783// typowa petla: for(poz=0;poz<s.d;) {line=getline(s,poz,len);...
784static const char *getline(const SString &s,int &poz,int &len)
785{
786const char *beg=(const char*)s+poz;
787if (poz>=s.len()) {poz=s.len(); len=0; return (const char*)s+s.len();}
788const char *lf=strchr(beg,'\n');
789if (!lf) { lf=(const char*)s+s.len()-1; poz=s.len(); }
790else {poz=(lf-(const char*)s)+1; if (poz>s.len()) poz=s.len();}
791while (lf>=beg) if ((*lf=='\n')||(*lf=='\r')) lf--; else break;
792len=lf-beg+1;
793return beg;
794}
795
796void ParamInterface::load2(const SString &s,int &poz)
797{
798int i; // numer akt. parametru
799int tmpi;
800int len;
801int ret;
802const char *t,*lin,*end;
803const char *rownasie,*przecinek;
804char remember;
805const char *quote,*quote2;
806const char *value,*valstop;
807SString tmpvalue;
808if (poz>=s.len()) return;
809t=(const char*)s+poz;
810
811// na razie wszystko musi byc w jednej linii...
812lin=getline(s,poz,len);
813if (!len) return; // pusta linia = koniec
814i=0;
815end=lin+len;
816while(t<end)
817{
818// przetwarzanie jednego par
819while (strchr(" \n\r\t",*t)) if (t<end) t++; else return;
820
821przecinek=strchrlimit(t,',',end); if (!przecinek) przecinek=end;
822quote=strchrlimit(t,'\"',przecinek);
823if (quote)
824        {
825        quote2=skipQuoteString(quote+1,end);
826        if (quote2>przecinek)
827                {
828                przecinek=strchrlimit(quote2+1,',',end);
829                if (!przecinek) przecinek=end;
830                }
831        rownasie=strchrlimit(t,'=',quote);
832        }
833else
834        {
835        rownasie=strchrlimit(t,'=',przecinek);
836        quote2=0;
837        }
838if (rownasie==t) { t++; rownasie=0; }
839if (przecinek==t)       // skip empty value
840        {
841        t++; i++;
842        continue;
843        }
844if (rownasie) // have parameter name
845        {
846        tmpi=findIdn(t,rownasie-t);
847        i=tmpi;
848        if (tmpi<0)
849                FMprintf("Param","load2",FMLV_WARN,"Unknown property name for '%s' (ignored)",getName());
850        t=rownasie+1; // t=value
851        }
852#ifdef WARN_MISSING_NAME
853else
854#ifdef SAVE_SELECTED_NAMES
855if (!(flags(i)&PARAM_CANOMITNAME))
856#endif
857        {
858        FMprintf("Param","load2",FMLV_WARN,"Missing property name in '%s' (assuming '%s')",
859                 getName(),id(i)?id(i):"unknown property?");
860        }
861#endif
862if ((i>=0)&&id(i))
863        {
864        value=t;
865        if (quote)
866                {
867                tmpvalue.copyFrom(quote+1,quote2-quote-1);
868                sstringUnquote(tmpvalue);
869                value=tmpvalue;
870                valstop=quote2;
871                }
872        else
873                if (przecinek<end) valstop=przecinek; else valstop=end;
874
875        remember=*valstop;
876        *(char*)valstop=0;
877        ret=set(i,value);
878        if (ret&(PSET_HITMAX|PSET_HITMIN))
879                FMprintf("Param","load2",FMLV_WARN,"Adjusted '%s' in '%s' (was too %s)",
880                        id(i),getName(),(ret&PSET_HITMAX)?"big":"small");
881        *(char*)valstop=remember;
882        }
883
884if (i>=0) i++;
885#ifdef __CODEGUARD__
886if (przecinek<end-1) t=przecinek+1; else return;
887#else
888t=przecinek+1;
889#endif
890}
891return;
892}
893
894int Param::grmember(int g,int a)
895{
896if ((getGroupCount()<2)&&(!g))
897        return (a<getPropCount())?a:-9999;
898
899ParamEntry *e=entry(0);
900int x=0,i=0;
901for (;e->id;i++,e++)
902        {
903        if (e->group==g)
904                if (a==x) return i; else x++;
905        }
906return -9999;
907}
Note: See TracBrowser for help on using the repository browser.