Changeset 326 for cpp/frams


Ignore:
Timestamp:
02/06/15 00:15:08 (7 years ago)
Author:
Maciej Komosinski
Message:

Unified parsing of ints and floats; hex notation

Location:
cpp/frams
Files:
5 edited

Legend:

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

    r325 r326  
    499499}
    500500
    501 static bool stringIsNumeric(const char* str)
    502 {//   /-?.?[0-9]+/
    503         if (!str) return false;
    504         if (*str == '-') str++;
    505         if (*str == '.') str++;
    506         return isdigit(*str) != 0;
    507 }
    508 
    509501int ParamInterface::setInt(int i, const char* str)
    510502{
    511         if (!stringIsNumeric(str))
     503        paInt value;
     504        if (!ExtValue::parseInt(str,value,false,true))
    512505        {
    513506                paInt mn, mx, def;
     
    518511        }
    519512        else
    520                 return setInt(i, ExtValue::getInt(str));
     513                return setInt(i, value);
    521514}
    522515
    523516int ParamInterface::setDouble(int i, const char* str)
    524517{
    525         if (!stringIsNumeric(str))
     518        double value;
     519        if (!ExtValue::parseDouble(str,value,true))
    526520        {
    527521                double mn, mx, def;
     
    532526        }
    533527        else
    534                 return setDouble(i, ExtValue::getDouble(str));
     528                return setDouble(i, value);
    535529}
    536530
  • cpp/frams/param/paramobj.cpp

    r286 r326  
    77#include <common/nonstd_stl.h>
    88
    9 static const char* maybedup(bool dup,const char* src)
    10 { return dup ? (src?strdup(src):0) : src; }
     9static const char* maybedup(bool dup, const char* src)
     10{
     11        return dup ? (src ? strdup(src) : 0) : src;
     12}
    1113static void maybefree(void* mem)
    12 { if (mem) free(mem); }
    13 
    14 ParamEntry* ParamObject::makeParamTab(ParamInterface *pi,bool stripgroups,bool stripproc,
    15                                       int firstprop, int maxprops, bool dupentries, int flagsexclude)
    16 {
    17 ParamEntry *tab,*t;
    18 int i,n,offs;
    19 static ExtValue ex;
    20 int count=0,gcount=1;
    21 if (!stripgroups) gcount=pi->getGroupCount();
    22 if (stripproc||flagsexclude)
    23 for (int i=firstprop;i < pi->getPropCount();i++)
    24         {
    25         const char*t=pi->type(i);
    26         if ((!stripproc)||(strchr("dfsox",*t)))
    27                 if ((!flagsexclude)||(!(pi->flags(i)&flagsexclude)))
    28                         if (++count >= maxprops) break;
    29         }
    30 else count=pi->getPropCount()-firstprop;
    31 t=tab=(ParamEntry*)malloc(sizeof(ParamEntry)*(count+gcount+1));
    32 t->group=(short)gcount;
    33 t->flags=(short)count;
    34 t->name=maybedup(dupentries,pi->getName());
    35 t->type=maybedup(dupentries,pi->getDescription());
    36 for(i=0;i<gcount;i++)
    37         {
    38         t->id=maybedup(dupentries,pi->grname(i));
    39         t->offset=0;
    40         t++;
    41         }
    42 n=1; offs=1;
    43 for (i=firstprop;i < pi->getPropCount();i++)
    44         {
    45         if ((!stripproc)||(strchr("dfsox",*pi->type(i))))
     14{
     15        if (mem) free(mem);
     16}
     17
     18int ParamObject::firstFieldOffset()
     19{
     20        static ParamObject dummy(0, NULL);
     21        return ((char*)&dummy.fields[0]) - (char*)&dummy;
     22}
     23
     24ParamEntry* ParamObject::makeParamTab(ParamInterface *pi, bool stripgroups, bool stripproc,
     25        int firstprop, int maxprops, bool dupentries, int flagsexclude, bool addnew, const char* rename)
     26{
     27        ParamEntry *tab, *t;
     28        int i, n, offset;
     29        static ExtValue ex;
     30        int count = 0, gcount = 1;
     31        if (!stripgroups) gcount = pi->getGroupCount();
     32        if (stripproc || flagsexclude)
     33                for (int i = firstprop; i < pi->getPropCount(); i++)
    4634                {
    47                 if ((!flagsexclude)||(!(pi->flags(i)&flagsexclude)))
     35                const char*t = pi->type(i);
     36                if ((!stripproc) || (strchr("dfsox", *t)))
     37                        if ((!flagsexclude) || (!(pi->flags(i)&flagsexclude)))
     38                                if (++count >= maxprops) break;
     39                }
     40        else count = pi->getPropCount() - firstprop;
     41        if (addnew) count++;
     42        t = tab = (ParamEntry*)malloc(sizeof(ParamEntry)*(count + gcount + 1));
     43        t->group = (short)gcount;
     44        t->flags = (short)count;
     45        t->name = maybedup(dupentries, rename ? rename : pi->getName());
     46        t->type = maybedup(dupentries, pi->getDescription());
     47        for (i = 0; i < gcount; i++)
     48        {
     49                t->id = maybedup(dupentries, pi->grname(i));
     50                t->offset = 0;
     51                t++;
     52        }
     53        n = 1;
     54        offset = firstFieldOffset();
     55        if (addnew)
     56        {
     57                t->id = maybedup(dupentries, "new");
     58                t->name = maybedup(dupentries, "create new object");
     59                SString tmp = SString::sprintf("p o%s()", pi->getName());
     60                t->type = maybedup(dupentries, (const char*)tmp);
     61                t->help = maybedup(dupentries, pi->help(i));
     62                t->flags = 0;
     63                t->group = 0;
     64                t->offset = PARAM_ILLEGAL_OFFSET;
     65                t->fun1 = (void*)p_new;
     66                t->fun2 = 0;
     67                t++;
     68        }
     69        for (i = firstprop; i < pi->getPropCount(); i++)
     70        {
     71                if ((!stripproc) || (strchr("dfsox", *pi->type(i))))
     72                {
     73                        if ((!flagsexclude) || (!(pi->flags(i)&flagsexclude)))
    4874                        {
    49                         t->offset=offs*sizeof(ExtValue);
    50                         if (*pi->type(i)!='x') t->offset+=(((char*)&ex.data[0])-((char*)&ex));
    51                         t->group=(short)(stripgroups?0:pi->group(i));
    52                         t->flags=(short)pi->flags(i);
    53                         t->fun1=0;
    54                         t->fun2=0;
    55                         t->id=maybedup(dupentries,pi->id(i));
    56                         t->name=maybedup(dupentries,pi->name(i));
    57                         t->type=maybedup(dupentries,pi->type(i));
    58                         t->help=maybedup(dupentries,pi->help(i));
    59                         t++; n++; offs++;
    60                         if (n>count) break;
     75                                t->offset = offset;
     76                                if (*pi->type(i) != 'x') t->offset += (((char*)&ex.data[0]) - ((char*)&ex));
     77                                t->group = (short)(stripgroups ? 0 : pi->group(i));
     78                                t->flags = (short)pi->flags(i);
     79                                t->fun1 = 0;
     80                                t->fun2 = 0;
     81                                t->id = maybedup(dupentries, pi->id(i));
     82                                t->name = maybedup(dupentries, pi->name(i));
     83                                t->type = maybedup(dupentries, pi->type(i));
     84                                t->help = maybedup(dupentries, pi->help(i));
     85                                t++; n++; offset += sizeof(ExtValue);
     86                                if (n > count) break;
    6187                        }
    6288                }
    6389        }
    64 t->id=0; t->group=0; t->flags=dupentries?MUTPARAM_ALLOCENTRY:0;
    65 return tab;
     90        t->id = 0; t->group = 0; t->flags = dupentries ? MUTPARAM_ALLOCENTRY : 0;
     91        return tab;
     92}
     93
     94void ParamObject::setParamTabText(ParamEntry *pe, const char* &ptr, const char* txt)
     95{
     96        if (!paramTabAllocatedString(pe))
     97                return;
     98        maybefree((char*)ptr);
     99        ptr = maybedup(true, txt);
     100}
     101
     102bool ParamObject::paramTabAllocatedString(ParamEntry *pe)
     103{
     104        return (pe[pe->flags + pe->group].flags & MUTPARAM_ALLOCENTRY) ? true : false;
    66105}
    67106
    68107void ParamObject::freeParamTab(ParamEntry *pe)
    69108{
    70 if (pe[pe->flags+pe->group].flags & MUTPARAM_ALLOCENTRY)
    71         {
    72         int i;
    73         ParamEntry *e;
    74         maybefree((void*)pe->name);
    75         maybefree((void*)pe->type);
    76         for (i=0,e=pe;i<pe->group;i++,e++)
    77                 maybefree((void*)e->id);
    78         for (i=pe->group,e=pe+i;i<pe->group+pe->flags;i++,e++)
     109        if (paramTabAllocatedString(pe))
     110        {
     111                int i;
     112                ParamEntry *e;
     113                maybefree((void*)pe->name);
     114                maybefree((void*)pe->type);
     115                for (i = 0, e = pe; i < pe->group; i++, e++)
     116                        maybefree((void*)e->id);
     117                for (i = pe->group, e = pe + i; i < pe->group + pe->flags; i++, e++)
    79118                {
    80                 maybefree((void*)e->id);
    81                 maybefree((void*)e->name);
    82                 maybefree((void*)e->type);
    83                 maybefree((void*)e->help);
     119                        maybefree((void*)e->id);
     120                        maybefree((void*)e->name);
     121                        maybefree((void*)e->type);
     122                        maybefree((void*)e->help);
    84123                }
    85124        }
    86 free(pe);
    87 }
    88 
    89 bool ParamObject::paramTabEqual(ParamEntry *pe1,ParamEntry *pe2)
    90 {
    91 if (pe1->flags != pe2->flags) return false;
    92 ParamEntry *e1=pe1+pe1->group, *e2=pe2+pe2->group;
    93 for(int i=0;i<pe1->flags;i++,e1++,e2++)
    94         {
    95         if (strcmp(e1->id,e2->id)) return false;
    96         if (strcmp(e1->name,e2->name)) return false;
    97         if (strcmp(e1->type,e2->type)) return false;
    98         if (e1->offset!=e2->offset) return false;
    99         }
    100 return true;
    101 }
    102 
    103 void* ParamObject::makeObject(ParamEntry *tab)
    104 {
    105 if (!tab) return 0;
    106 int n=tab->flags;
    107 if (!n) return 0;
    108 ExtValue *ret=new ExtValue[n+1];
    109 ret->setInt(n);
    110 ExtValue *v=ret+1;
    111 tab+=tab->group;
    112 for (;n>0;n--,v++,tab++)
    113         switch(*tab->type)
    114         {
    115         case 'd': v->setInt(0); break;
    116         case 'f': v->setDouble(0); break;
    117         case 's': v->setString(SString::empty()); break;
    118         case 'o': v->setObject(ExtObject()); break;
    119         case 'x': break;
    120         }
    121 return ret;
    122 }
    123 
    124 void ParamObject::copyObject(void* dst,void* src)
    125 {
    126 if ((!dst)||(!src)) return;
    127 ExtValue *s=(ExtValue *)src;
    128 ExtValue *d=(ExtValue *)dst;
    129 int n=min(s->getInt(),d->getInt());
    130 s++; d++;
    131 for (int i=0;i<n;i++,d++,s++)
    132         *d=*s;
     125        free(pe);
     126}
     127
     128bool ParamObject::paramTabEqual(ParamEntry *pe1, ParamEntry *pe2)
     129{
     130        if (pe1->flags != pe2->flags) return false;
     131        ParamEntry *e1 = pe1 + pe1->group, *e2 = pe2 + pe2->group;
     132        for (int i = 0; i < pe1->flags; i++, e1++, e2++)
     133        {
     134                if (strcmp(e1->id, e2->id)) return false;
     135                if (strcmp(e1->name, e2->name)) return false;
     136                if (strcmp(e1->type, e2->type)) return false;
     137                if (e1->offset != e2->offset) return false;
     138        }
     139        return true;
     140}
     141
     142void ParamObject::p_new(void* obj, ExtValue *args, ExtValue *ret)
     143{
     144        ParamObject *this_obj = (ParamObject*)obj;
     145        ParamObject *po = makeObject(this_obj->par.getParamTab());
     146        ret->setObject(ExtObject(&this_obj->par, po));
     147        po->par.setDefault();
     148}
     149
     150ParamObject::ParamObject(int _numfields, ParamEntry *_tab)
     151{
     152        numfields = _numfields;
     153        par.setParamTab(_tab);
     154        par.select(this);
     155        for (int i = 0; i < numfields; i++)
     156                new(&fields[i])ExtValue();
     157}
     158
     159ParamObject::~ParamObject()
     160{
     161        for (int i = 0; i < numfields; i++)
     162                fields[i].~ExtValue();
     163}
     164
     165ParamObject* ParamObject::makeObject(ParamEntry *tab)
     166{
     167        if (!tab) return 0;
     168        int n = tab->flags;
     169        if (!n) return 0;
     170        ParamObject *obj = new(n)ParamObject(n, tab); // new(n): allocate n fields ; ParamObject(n,...): tell the object it has n fields
     171        ExtValue *v = &obj->fields[0];
     172        tab += tab->group;
     173        for (; n > 0; n--, tab++)
     174                switch (*tab->type)
     175        {
     176                case 'd': v->setInt(0); v++; break;
     177                case 'f': v->setDouble(0); v++; break;
     178                case 's': v->setString(SString::empty()); v++; break;
     179                case 'o': v->setObject(ExtObject()); v++; break;
     180                case 'x': v++; break;
     181        }
     182        return obj;
     183}
     184
     185void ParamObject::operator=(const ParamObject& src)
     186{
     187        const ExtValue *s = &src.fields[0];
     188        ExtValue *d = &fields[0];
     189        int n = min(numfields, src.numfields);
     190        for (int i = 0; i < n; i++, d++, s++)
     191                *d = *s;
     192}
     193
     194ParamObject* ParamObject::clone()
     195{
     196        ParamObject *c = new(numfields)ParamObject(numfields, par.getParamTab());
     197        *c = *this;
     198        return c;
     199}
     200
     201void ParamObject::copyObject(void* dst, void* src)
     202{
     203        if ((!dst) || (!src)) return;
     204        ParamObject *s = (ParamObject*)src;
     205        ParamObject *d = (ParamObject*)dst;
     206        *d = *s;
    133207}
    134208
    135209void* ParamObject::dupObject(void* src)
    136210{
    137 if (!src) return NULL;
    138 ExtValue *s=(ExtValue *)src;
    139 int n=s->getInt();
    140 
    141 ExtValue *ret=new ExtValue[n+1];
    142 ExtValue *d=ret;
    143 d->setInt(n);
    144 d++; s++;
    145 
    146 for (int i=0;i<n;i++,d++,s++)
    147         *d=*s;
    148 
    149 return ret;
     211        if (!src) return NULL;
     212        ParamObject *s = (ParamObject*)src;
     213        return s->clone();
    150214}
    151215
    152216void ParamObject::freeObject(void* obj)
    153217{
    154 if (!obj) return;
    155 delete[] (ExtValue *)obj;
    156 }
    157 
    158 
    159 
    160 
    161 
    162 
    163 
    164 
    165 
     218        if (!obj) return;
     219        ParamObject *o = (ParamObject*)obj;
     220        delete o;
     221}
  • cpp/frams/param/paramobj.h

    r286 r326  
    77
    88#include "param.h"
     9#include <frams/util/extvalue.h>
    910
    10 class ParamObject
     11class ParamObject : public DestrBase
    1112{
    12   public:
    13 /** make a ParamEntry* array for use with Param object.
    14     offsets in the array are calculated for the ExtObject array as the target.
    15     valid array can be created with makeObject().
    16     sample code:
    17     @code
    18     ParamInterface *pi=...; // any param interface
    19     ParamEntry *tab=ParamObject::makeParamTab(pi);
    20     void* obj=ParamObject::makeObject(tab);
    21     void* obj2=ParamObject::makeObject(tab);
    22     Param par(tab,obj);
    23     par.set(...), par.get(...), par.load(...), par.save(...);
    24     par.select(obj);
    25     par.select(obj2);
    26     ParamObject::freeObject(obj);
    27     ParamObject::freeObject(obj2);
    28  */
    29 static ParamEntry* makeParamTab(ParamInterface *pi,bool stripgroups=0,bool stripproc=0,int firstprop=0,int maxprops=9999,bool dupentries=false, int flagsexclude=0);
     13        ParamObject(int _numfields, ParamEntry *_tab);
     14public:
     15        int numfields;
     16        Param par;
     17        ExtValue fields[0];
     18        ParamObject() { numfields = 0; }
     19        ~ParamObject();
    3020
    31 /** deallocate paramtab obtained from makeParamTab() */
    32 static void freeParamTab(ParamEntry *pe);
     21        void* operator new(size_t s, int numfields){ return ::operator new(s + sizeof(ExtValue)*numfields); }
     22        void* operator new(size_t s){ return ::operator new(s); }
     23        ParamObject *clone();
     24        static void p_new(void* obj, ExtValue *args, ExtValue *ret);
    3325
    34 static bool paramTabEqual(ParamEntry *pe1,ParamEntry *pe2);
     26        void operator=(const ParamObject& src);
    3527
    36 /** @return the object, suitable for Param.select(...).
    37     @return NULL if 'pi' has no usable properties */
    38 static void* makeObject(ParamEntry *tab);
     28        static int firstFieldOffset();
    3929
    40 /** copy data from src to dst  */
    41 static void copyObject(void* dst,void* src);
     30        /** make a ParamEntry* array for use with Param object.
     31                offsets in the array are calculated for the ExtObject array as the target.
     32                valid array can be created with makeObject().
     33                sample code:
     34                @code
     35                ParamInterface *pi=...; // any param interface
     36                ParamEntry *tab=ParamObject::makeParamTab(pi);
     37                void* obj=ParamObject::makeObject(tab);
     38                void* obj2=ParamObject::makeObject(tab);
     39                Param par(tab,obj);
     40                par.set(...), par.get(...), par.load(...), par.save(...);
     41                par.select(obj);
     42                par.select(obj2);
     43                ParamObject::freeObject(obj);
     44                ParamObject::freeObject(obj2);
     45                */
     46        static ParamEntry* makeParamTab(ParamInterface *pi, bool stripgroups = 0, bool stripproc = 0, int firstprop = 0, int maxprops = 9999, bool dupentries = false, int flagsexclude = 0, bool addnew = false, const char* rename = NULL);
    4247
    43 /** duplicate object */
    44 static void* dupObject(void* obj);
     48        /** deallocate paramtab obtained from makeParamTab() */
     49        static void freeParamTab(ParamEntry *pe);
    4550
    46 /** delete all data in the array and deallocate it  */
    47 static void freeObject(void* obj);
     51        static void setParamTabText(ParamEntry *pe, const char* &ptr, const char* txt);
     52        static bool paramTabAllocatedString(ParamEntry *pe);
     53        static bool paramTabEqual(ParamEntry *pe1, ParamEntry *pe2);
     54
     55        /** @return the object, suitable for Param.select(...).
     56                @return NULL if 'pi' has no usable properties */
     57        static ParamObject* makeObject(ParamEntry *tab);
     58
     59        /** copy data from src to dst (compatibility with older implementation), same as operator=  */
     60        static void copyObject(void* dst, void* src);
     61
     62        /** duplicate object (compatibility with older implementation), same as clone()  */
     63        static void* dupObject(void* obj);
     64
     65        /** delete all data in the array and deallocate it (compatibility with older implementation), same as delete */
     66        static void freeObject(void* obj);
     67};
     68
     69class ParamTabOwner
     70{
     71public:
     72        ParamEntry *pe;
     73        ParamTabOwner(ParamEntry *_pe) :pe(_pe) {}
     74        ~ParamTabOwner() { ParamObject::freeParamTab(pe); }
    4875};
    4976
  • cpp/frams/util/extvalue.cpp

    r325 r326  
    610610}
    611611
    612 bool ExtValue::parseInt(const char* s, paInt &result, bool strict)
     612bool ExtValue::parseInt(const char* s, paInt &result, bool strict, bool error)
    613613{
    614614        ExtValue tmp;
    615615        const char* after = tmp.parseNumber(s, strict ? TInt : TUnknown);
    616         if (after == NULL) return false;
    617         if (after[0] != 0) return false;
     616        if ((after == NULL) || (after[0] != 0))
     617                {
     618                if (error)
     619                        FMprintf("ExtValue", "parseInt", FMLV_ERROR, "Could not parse '%s'%s", s, strict?" (strict)":"");
     620                return false;
     621                }
    618622        result = tmp.getInt();
    619623        return true;
    620624}
    621625
    622 bool ExtValue::parseDouble(const char* s, double &result)
     626bool ExtValue::parseDouble(const char* s, double &result, bool error)
    623627{
    624628        ExtValue tmp;
    625629        const char* after = tmp.parseNumber(s, TDouble);
    626         if (after == NULL) return false;
    627         if (after[0] != 0) return false;
     630        if ((after == NULL) || (after[0] != 0))
     631                {
     632                if (error)
     633                        FMprintf("ExtValue", "parseDouble", FMLV_ERROR, "Could not parse '%s'", s);
     634                return false;
     635                }
    628636        result = tmp.getDouble();
    629637        return true;
     
    633641{
    634642        paInt result;
    635         if (parseInt(s, result, strict))
     643        if (parseInt(s, result, strict, true))
    636644                return result;
    637         FMprintf("ExtValue", "getInt", FMLV_ERROR, "Could not parse '%s'%s", s, strict?" (strict)":"");
    638645        return 0;
    639646}
     
    642649{
    643650        double result;
    644         if (parseDouble(s, result))
     651        if (parseDouble(s, result, true))
    645652                return result;
    646         FMprintf("ExtValue", "getDouble", FMLV_ERROR, "Could not parse '%s'", s);
    647653        return 0;
    648654}
     
    729735        if (in[0] == 0) return NULL;
    730736        while (isspace(*in)) in++;
    731         bool minus = false;
    732         if (((in[0] == '0') && (in[1] == 'x'))
    733                 || (((minus = (in[0] == '-')) && (in[1] == '0') && (in[2] == 'x'))))
    734         {
    735                 in += minus ? 3 : 2;
     737        bool minus = (in[0] == '-');
     738        bool plus = (in[0] == '+');
     739        if (((in[0] == '0') && ((in[1] == 'x') || (in[1]=='X')))
     740             || (((minus || plus) && (in[1] == '0') && ((in[2] == 'x') || (in[2] == 'X')))))
     741        {
     742                in += (minus || plus) ? 3 : 2;
    736743                if (isspace(*in)) return NULL;
    737744                errno = 0;
  • cpp/frams/util/extvalue.h

    r325 r326  
    160160        void setString(const SString &v) { if (type != TString) setrs(v); else sdata() = v; }
    161161        void setObject(const ExtObject &src) { if (type != TObj) setro(src); else odata() = src; }
    162         static bool parseInt(const char* s, paInt &result, bool strict = false);
    163         static bool parseDouble(const char* s, double &result);
     162        static bool parseInt(const char* s, paInt &result, bool strict, bool error);
     163        static bool parseDouble(const char* s, double &result, bool error);
    164164        static paInt getInt(const char* s, bool strict = false);//< @param strict=true will fail on floating point
    165165        static double getDouble(const char* s);
Note: See TracChangeset for help on using the changeset viewer.