source: cpp/gdk/param.cpp @ 93

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

every param.set(value) produces a helpful warning when the "value" exceeds allowed range for this param, e.g.

World.wrldtyp=5;

[WARN] Param::set - Setting 'World.wrldtyp = 5' exceeded allowed range (too big). Adjusted to 2.

World.wrldtyp=-5;

[WARN] Param::set - Setting 'World.wrldtyp = -5' exceeded allowed range (too small). Adjusted to 0.

  • Property svn:eol-style set to native
File size: 19.5 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2013  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;}
211int ParamInterface::setById(const char* prop,const ExtValue &v)
212{int i=findId(prop); if (i>=0) return set(i,v); else return PSET_NOPROPERTY;}
213
214int ParamInterface::save(VirtFILE* f,const SString* altname,bool force)
215{
216const char *p;
217SString ws;
218int err=0,i;
219bool withname=false;
220if ((!altname)||(altname->len()))
221        {
222        err|=(fputs(altname?((const char*)(*altname)):getName(),f)==EOF);
223        err|=(fputs(":\n",f)==EOF);
224        withname=true;
225        }
226for (i=0;p=id(i);i++)
227        err|=saveprop(f,i,p,force);
228if (withname)
229        err|=(fputs("\n",f)==EOF);
230return err;
231}
232
233int ParamInterface::saveprop(VirtFILE* f,int i,const char* p,bool force)
234{
235if ((flags(i)&PARAM_DONTSAVE)&&(!force)) return 0;
236const char *typ=type(i);
237if ((*typ=='p')||(*typ=='o')) return 0;
238
239const char *t,*w;
240SString ws;
241int err=0,cr;
242
243err|=(fputs(p,f)==EOF); fputc(':',f);
244cr=0;
245ws=get(i);
246quoteTilde(ws);
247w=ws;
248if (ws.len()>50) cr=1;
249else for (t=w;*t;t++) if ((*t==10)||(*t==13)) {cr=1; break;}
250if (cr) fputs("~\n",f);
251err|=(fputs(w,f)==EOF);
252err|=(fputs(cr ? "~\n" : "\n",f)==EOF);
253return err;
254}
255
256
257int SimpleAbstractParam::isequal(int i,void* defdata)
258{ // defdata->member == object->member ?
259void *backup=object;
260switch(type(i)[0])
261        {
262        case 'd':
263                {
264                select(defdata);
265                long x=getInt(i);
266                select(backup);
267                return x==getInt(i);
268                }
269        case 'f':
270                {
271                select(defdata);
272                double x=getDouble(i);
273                select(backup);
274                return x==getDouble(i);
275                }
276        case 's':
277                {
278                select(defdata);
279                SString x=getString(i);
280                select(backup);
281                return x==getString(i);
282                }
283        }
284return 1;
285}
286
287void SimpleAbstractParam::save2(SString& f,void *defdata,bool addcr,bool all_names)
288{ // defdata!=NULL -> nie zapisuje wartosci domyslnych
289const char *p;
290int i;
291int needlabel=0;
292int first=1;
293SString val;
294SString t;
295int fl;
296// t+=SString(getName()); t+=':';
297for (i=0;p=id(i);i++)
298        if (!((fl=flags(i))&PARAM_DONTSAVE))
299        {
300        if (defdata && isequal(i,defdata))
301                needlabel=1;
302        else
303                {
304                if (!first) t+=", ";
305#ifndef SAVE_ALL_NAMES
306#ifdef SAVE_SELECTED_NAMES
307                if (needlabel || all_names || !(fl & PARAM_CANOMITNAME))
308#else
309                if (needlabel)
310#endif
311#endif
312                        { t+=p; t+="="; needlabel=0; }
313                if (type(i)[0]=='s')
314                        { // string - special case
315                        SString str=getString(i);
316                        if (strContainsOneOf(str,", \\\n\r\t\""))
317                                {
318                                t+="\"";
319                                sstringQuote(str);
320                                t+=str;
321                                t+="\"";
322                                }
323                        else
324                                t+=str;
325                        }
326                else
327                        t+=get(i);
328                first=0;
329                }
330        }
331if (addcr)
332        t+="\n";
333f+=t;
334}
335
336void ParamInterface::load(VirtFILE* f)
337{
338char t[100];
339int i;
340const char *p,*p0;
341int p_len;
342bool eol,loaded;
343while(fgets0(t,100,f,eol))
344        {
345        p0=t; while ((*p0==' ')||(*p0=='\t')) p0++;
346        if (!*p0) break;
347        p=strchr(p0,':'); if (!p) continue;
348        p_len=p-p0;
349        loaded=false;
350        if (p_len&&((i=findIdn(p0,p_len))>=0)&&(!(flags(i)&PARAM_DONTLOAD)))
351                {
352                if (p0[p_len+1]=='~')
353                        {
354                        SString s;
355                        czytdotyldy(f,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                        if (eol)
363                                set(i,p0+p_len+1);
364                        else
365                                {
366                                SString tmp=p0+p_len+1;
367                                while(!eol)
368                                        {
369                                        if (!fgets0(t,100,f,eol)) break;
370                                        tmp+=t;
371                                        }
372                                set(i,(const char*)tmp);
373                                }
374                        }
375                loaded=true;
376                }
377        if ((!loaded) && (p0[p_len+1]=='~'))
378                { // eat unrecognized multiline field
379                SString s;
380                czytdotyldy(f,s);
381                int ch; while((ch=fgetc(f))!=EOF) if (ch=='\n') break;
382                }
383        }
384}
385
386
387/*
388SString SimpleAbstractParam::getString(int i)
389{
390char *t;
391switch (*(t=type(i)))
392        {
393        case 'd':
394        {
395        for (i=atol(get(i));i>=0;i--) if (t) t=strchr(t+1,'~');
396        if (t)
397                {
398                t++;
399                char *t2=strchr(t,'~');
400                if (!t2) t2=t+strlen(t);
401                SString str;
402                strncpy(str.directWrite(t2-t),t,t2-t);
403                str.endWrite(t2-t);
404                return str;
405                }
406        }
407        }
408return get(i);
409}
410*/
411
412int ParamInterface::findId(const char* n)
413{
414int i; const char *p;
415        for (i=0;p=id(i);i++) if (!strcmp(n,p)) return i;
416return -1;
417}
418
419int ParamInterface::findIdn(const char* naz,int n)
420{
421int i; const char *p;
422        for (i=0;p=id(i);i++) if ((!strncmp(naz,p,n))&&(!p[n])) return i;
423return -1;
424}
425
426void ParamInterface::get(int i,ExtValue &ret)
427{
428switch(type(i)[0])
429        {
430        case 'd':       ret.setInt(getInt(i)); break;
431        case 'f':       ret.setDouble(getDouble(i)); break;
432        case 's':       ret.setString(getString(i)); break;
433        case 'o':       ret.setObject(getObject(i)); break;
434        case 'x':       ret=getExtValue(i); break;
435        default: FMprintf("ParamInterface","get",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));
436        }
437}
438
439static bool stringIsNumeric(const char* str)
440{//   /-?.?[0-9]+/
441if (!str) return false;
442if (*str=='-') str++;
443if (*str=='.') str++;
444return isdigit(*str);
445}
446
447int ParamInterface::setInt(int i,const char* str)
448{
449if (!stringIsNumeric(str))
450        {
451        long a,b,c;
452        if (getMinMax(i,a,b,c)>=3)
453                return setInt(i,c);
454        else
455                return setInt(i,(long)0);
456        }
457else
458        return setInt(i,atol(str));
459}
460
461int ParamInterface::setDouble(int i,const char* str)
462{
463if (!stringIsNumeric(str))
464        {
465        double a,b,c;
466        if (getMinMax(i,a,b,c)>=3)
467                return setDouble(i,c);
468        else
469                return setDouble(i,(double)0);
470        }
471else
472        return setDouble(i,atof(str));
473}
474
475int ParamInterface::set(int i,const ExtValue &v)
476{
477switch(type(i)[0])
478        {
479        case 'd': if ((v.type==TInt)||(v.type==TDouble)) return setInt(i,v.getInt()); else return setInt(i,(const char*)v.getString());
480        case 'f': if ((v.type==TInt)||(v.type==TDouble)) return setDouble(i,v.getDouble()); else return setDouble(i,(const char*)v.getString());
481        case 's': { SString t=v.getString(); return setString(i,t); }
482        case 'o': return setObject(i,v.getObject());
483        case 'x': return setExtValue(i,v);
484        default: FMprintf("ParamInterface","get",FMLV_ERROR,"'%s.%s' is not a field",getName(),id(i));
485        }
486return 0;
487}
488
489int ParamInterface::set(int i,const char *v)
490{
491switch(type(i)[0])
492        {
493        case 'd': return setInt(i,v);
494        case 'f': return setDouble(i,v);
495        case 's': { SString t(v); return setString(i,t); }
496        case 'x':
497        {
498        ExtValue e;
499        if (isdigit(*v)||((*v=='-')&&isdigit(v[1])))
500                {
501                if (strchr(v,'.')) e.setDouble(atof(v));
502                else e.setInt(atol(v));
503                }
504        else
505                {
506                e.setString(SString(v));
507                }
508        return setExtValue(i,e);
509        }
510        }
511return 0;
512}
513
514SString ParamInterface::getText(int i)
515{
516const char *t;
517if ((*(t=type(i)))=='d')
518        {
519        for (int j=getInt(i);j>=0;j--) if (t) t=strchr(t+1,'~');
520        if (t)
521                {
522                t++;
523                const char *t2=strchr(t,'~');
524                if (!t2) t2=t+strlen(t);
525                return SString(t,t2-t);
526                }
527        }
528return get(i);
529}
530
531SString ParamInterface::get(int i)
532{
533switch(type(i)[0])
534        {
535        case 'd':
536                {
537                SString tmp;
538                sprintf(tmp.directWrite(20),"%ld",getInt(i)); tmp.endWrite();
539                return tmp;
540                }
541        case 'f':
542                {
543                SString tmp;
544                sprintf(tmp.directWrite(20),"%lg",getDouble(i)); tmp.endWrite();
545                return tmp;
546                }
547        case 's':
548                return getString(i);
549        }
550ExtValue v;
551get(i,v);
552return v.getString();
553}
554
555
556//////////////////////////////// PARAM ////////////////////////////////////
557
558void *SimpleAbstractParam::getTarget(int i)
559{
560return (void*)(((char*)object)+entry(i)->offset);
561//return &(object->*(entry(i)->fldptr));
562}
563
564///////// get
565
566long SimpleAbstractParam::getInt(int i)
567{
568static ExtValue v;
569ParamEntry *pe=entry(i);
570if (pe->fun1)
571        {
572        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
573        return v.getInt();
574        }
575else
576        {
577        void *target=getTarget(i);
578        return *((long*)target);
579        }
580}
581
582double SimpleAbstractParam::getDouble(int i)
583{
584static ExtValue v;
585ParamEntry *pe=entry(i);
586if (pe->fun1)
587        {
588        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
589        return v.getDouble();
590        }
591else
592        {
593        void *target=getTarget(i);
594        return *((double*)target);
595        }
596}
597
598SString SimpleAbstractParam::getString(int i)
599{
600static ExtValue v;
601ParamEntry *pe=entry(i);
602if (pe->fun1)
603        {
604        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
605        return v.getString();
606        }
607else
608        {
609        void *target=getTarget(i);
610        return *((SString*)target);
611        }
612}
613
614ExtObject SimpleAbstractParam::getObject(int i)
615{
616static ExtValue v;
617ParamEntry *pe=entry(i);
618if (pe->fun1)
619        {
620        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
621        return v.getObject();
622        }
623else
624        {
625        void *target=getTarget(i);
626        return *((ExtObject*)target);
627        }
628}
629
630ExtValue SimpleAbstractParam::getExtValue(int i)
631{
632static ExtValue v;
633ParamEntry *pe=entry(i);
634if (pe->fun1)
635        {
636        (*(void(*)(void*,ExtValue*))pe->fun1)(object,&v);
637        return v;
638        }
639else
640        {
641        void *target=getTarget(i);
642        return *((ExtValue*)target);
643        }
644}
645
646
647//////// set
648
649int SimpleAbstractParam::setInt(int i,long x)
650{
651static ExtValue v;
652ParamEntry *pe=entry(i);
653if (pe->flags&PARAM_READONLY) return PSET_RONLY;
654long xcopy=x; //only needed for helpful printed messages: retain original, requested value of x because it may be changed below
655long a=0,b=0;
656int 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        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        }
680    messageOnExceedRange(i,result,xcopy);
681        return result;
682}
683
684int SimpleAbstractParam::setDouble(int i,double x)
685{
686static ExtValue v;
687ParamEntry *pe=entry(i);
688if (pe->flags&PARAM_READONLY) return PSET_RONLY;
689double xcopy=x; //only needed for helpful printed messages: retain original, requested value of x because it may be changed below
690double a=0,b=0;
691int result=0;
692const char* t=pe->type+1;
693while(*t) if (*t==' ') break; else t++;
694if (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
701if (pe->fun2)
702        {
703        v.setDouble(x);
704        result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
705        }
706else
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
719int SimpleAbstractParam::setString(int i,const SString& x)
720{
721static ExtValue v;
722static SString vs;
723const SString *xx=&x;
724ParamEntry *pe=entry(i);
725if (pe->flags&PARAM_READONLY) return PSET_RONLY;
726SString xcopy=x; //only needed for helpful printed messages: retain original, requested value of x because it may be changed below
727const char* t=pe->type+1;
728while(*t) if (*t==' ') break; else t++;
729long a=0,b=0;
730int result=0;
731if (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
741if (pe->fun2)
742        {
743        v.setString(*xx);
744        result |= (*(int(*)(void*,const ExtValue*))pe->fun2)(object,&v);
745        }
746else
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
759int SimpleAbstractParam::setObject(int i,const ExtObject& x)
760{
761static ExtValue v;
762ParamEntry *pe=entry(i);
763if (pe->flags&PARAM_READONLY) return PSET_RONLY;
764ExtObject xcopy=x; //only needed for helpful printed messages: retain original, requested value of x because it may be changed below
765if (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        }
772else
773        {
774        void *target=getTarget(i);
775        *((ExtObject*)target)=x;
776        return PSET_CHANGED;
777        }
778}
779
780int SimpleAbstractParam::setExtValue(int i,const ExtValue& x)
781{
782ParamEntry *pe=entry(i);
783if (pe->flags&PARAM_READONLY) return PSET_RONLY;
784ExtValue xcopy=x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
785if (pe->fun2)
786        {
787        int result=(*(int(*)(void*,const ExtValue*))pe->fun2)(object,&x);
788    messageOnExceedRange(i,result,xcopy);
789    return result;
790        }
791else
792        {
793        void *target=getTarget(i);
794        *((ExtValue*)target)=x;
795        return PSET_CHANGED;
796        }
797}
798
799void SimpleAbstractParam::call(int i,ExtValue *args,ExtValue *ret)
800{
801ParamEntry *pe=entry(i);
802if (!pe) return;
803if (pe->fun1 && (pe->type[0]=='p'))
804        (*(void(*)(void*,ExtValue*,ExtValue*))pe->fun1)(object,args,ret);
805else
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
812void SimpleAbstractParam::setDefault(bool numericonly)
813{
814bool save=dontcheckchanges;
815dontcheckchanges=1;
816ParamInterface::setDefault(numericonly);
817dontcheckchanges=save;
818}
819
820void SimpleAbstractParam::setDefault(int i,bool numericonly)
821{
822bool save=dontcheckchanges;
823dontcheckchanges=1;
824ParamInterface::setDefault(i,numericonly);
825dontcheckchanges=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);...
833static const char *getline(const SString &s,int &poz,int &len)
834{
835const char *beg=(const char*)s+poz;
836if (poz>=s.len()) {poz=s.len(); len=0; return (const char*)s+s.len();}
837const char *lf=strchr(beg,'\n');
838if (!lf) { lf=(const char*)s+s.len()-1; poz=s.len(); }
839else {poz=(lf-(const char*)s)+1; if (poz>s.len()) poz=s.len();}
840while (lf>=beg) if ((*lf=='\n')||(*lf=='\r')) lf--; else break;
841len=lf-beg+1;
842return beg;
843}
844
845void ParamInterface::load2(const SString &s,int &poz)
846{
847int i; // numer akt. parametru
848int tmpi;
849int len;
850int ret;
851const char *t,*lin,*end;
852const char *rownasie,*przecinek;
853char remember;
854const char *quote,*quote2;
855const char *value,*valstop;
856SString tmpvalue;
857if (poz>=s.len()) return;
858t=(const char*)s+poz;
859
860// na razie wszystko musi byc w jednej linii...
861lin=getline(s,poz,len);
862if (!len) return; // pusta linia = koniec
863i=0;
864end=lin+len;
865while(t<end)
866{
867// przetwarzanie jednego par
868while (strchr(" \n\r\t",*t)) if (t<end) t++; else return;
869
870przecinek=strchrlimit(t,',',end); if (!przecinek) przecinek=end;
871quote=strchrlimit(t,'\"',przecinek);
872if (quote)
873        {
874        quote2=skipQuoteString(quote+1,end);
875        if (quote2>przecinek)
876                {
877                przecinek=strchrlimit(quote2+1,',',end);
878                if (!przecinek) przecinek=end;
879                }
880        rownasie=strchrlimit(t,'=',quote);
881        }
882else
883        {
884        rownasie=strchrlimit(t,'=',przecinek);
885        quote2=0;
886        }
887if (rownasie==t) { t++; rownasie=0; }
888if (przecinek==t)       // skip empty value
889        {
890        t++; i++;
891        continue;
892        }
893if (rownasie) // have parameter name
894        {
895        tmpi=findIdn(t,rownasie-t);
896        i=tmpi;
897        if (tmpi<0)
898                FMprintf("Param","load2",FMLV_WARN,"Unknown property name for '%s' (ignored)",getName());
899        t=rownasie+1; // t=value
900        }
901#ifdef WARN_MISSING_NAME
902else
903#ifdef SAVE_SELECTED_NAMES
904if (!(flags(i)&PARAM_CANOMITNAME))
905#endif
906        {
907        FMprintf("Param","load2",FMLV_WARN,"Missing property name in '%s' (assuming '%s')",
908                 getName(),id(i)?id(i):"unknown property?");
909        }
910#endif
911if ((i>=0)&&id(i))
912        {
913        value=t;
914        if (quote)
915                {
916                tmpvalue.copyFrom(quote+1,quote2-quote-1);
917                sstringUnquote(tmpvalue);
918                value=tmpvalue;
919                valstop=quote2;
920                }
921        else
922                if (przecinek<end) valstop=przecinek; else valstop=end;
923
924        remember=*valstop;
925        *(char*)valstop=0;
926        ret=set(i,value);
927        if (ret&(PSET_HITMAX|PSET_HITMIN))
928                FMprintf("Param","load2",FMLV_WARN,"Adjusted '%s' in '%s' (was too %s)",
929                        id(i),getName(),(ret&PSET_HITMAX)?"big":"small");
930        *(char*)valstop=remember;
931        }
932
933if (i>=0) i++;
934#ifdef __CODEGUARD__
935if (przecinek<end-1) t=przecinek+1; else return;
936#else
937t=przecinek+1;
938#endif
939}
940return;
941}
942
943int Param::grmember(int g,int a)
944{
945if ((getGroupCount()<2)&&(!g))
946        return (a<getPropCount())?a:-9999;
947
948ParamEntry *e=entry(0);
949int x=0,i=0;
950for (;e->id;i++,e++)
951        {
952        if (e->group==g)
953                if (a==x) return i; else x++;
954        }
955return -9999;
956}
957
Note: See TracBrowser for help on using the repository browser.