Ignore:
Timestamp:
01/14/18 11:24:22 (6 years ago)
Author:
Maciej Komosinski
Message:

Param::save2() renamed to saveSingleLine(); unified Param::load() so that it gets a single-line/multi-line format selector

File:
1 edited

Legend:

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

    r535 r720  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1010void MultiParamLoader::init()
    1111{
    12 file=0; ownfile=0;
    13 status=0;
    14 reset();
     12        file = 0; ownfile = 0;
     13        status = 0;
     14        reset();
    1515}
    1616
    1717void MultiParamLoader::reset()
    1818{
    19 status=0;
    20 breakcond=OnError;
    21 aborting=false;
    22 emptyparam.setParamTab(empty_paramtab);
    23 linenum=0;
     19        status = 0;
     20        breakcond = OnError;
     21        aborting = false;
     22        emptyparam.setParamTab(empty_paramtab);
     23        linenum = 0;
    2424}
    2525
    2626int MultiParamLoader::findObject(const ExtObject &o)
    2727{
    28 for(int i=0;i<objects.size();i++)
    29         if ((*objects(i))==o)
    30                 return i;
    31 return -1;
     28        for (int i = 0; i < objects.size(); i++)
     29                if ((*objects(i)) == o)
     30                        return i;
     31        return -1;
    3232}
    3333
    3434void MultiParamLoader::removeObject(const ExtObject &o)
    3535{
    36 int i=findObject(o);
    37 if (i>=0)
    38         {
    39         delete objects(i);
    40         objects-=i;
     36        int i = findObject(o);
     37        if (i >= 0)
     38        {
     39                delete objects(i);
     40                objects -= i;
    4141        }
    4242}
     
    4444void MultiParamLoader::clearObjects()
    4545{
    46 FOREACH(ExtObject*,o,objects)
    47         delete o;
    48 objects.clear();
     46        FOREACH(ExtObject*, o, objects)
     47                delete o;
     48        objects.clear();
    4949}
    5050
    5151void MultiParamLoader::load()
    5252{
    53 clearstack();
    54 if (!file)
    55         {
    56         lasterror="can't open file";
    57         status=OnError;
    58         return;
    59         }
    60 status=Loading;
    61 aborting=false;
     53        clearstack();
     54        if (!file)
     55        {
     56                lasterror = "can't open file";
     57                status = OnError;
     58                return;
     59        }
     60        status = Loading;
     61        aborting = false;
    6262}
    6363
    6464void MultiParamLoader::abort()
    6565{
    66 if (file && ownfile)
    67         {
    68         delete file;
    69         file=0;
    70         }
    71 clearstack();
    72 status=Finished;
    73 aborting=true;
     66        if (file && ownfile)
     67        {
     68                delete file;
     69                file = 0;
     70        }
     71        clearstack();
     72        status = Finished;
     73        aborting = true;
    7474}
    7575
    7676void MultiParamLoader::load(VirtFILE *f)
    7777{
    78 abort();
    79 ownfile=0;
    80 file=f;
    81 load();
     78        abort();
     79        ownfile = 0;
     80        file = f;
     81        load();
    8282}
    8383
    8484void MultiParamLoader::load(const char* filename)
    8585{
    86 abort();
    87 ownfile=1;
    88 file=Vfopen(filename,FOPEN_READ_BINARY);
    89 load();
     86        abort();
     87        ownfile = 1;
     88        file = Vfopen(filename, FOPEN_READ_BINARY);
     89        load();
    9090}
    9191
    9292int MultiParamLoader::go()
    9393{
    94 SString buf;
    95 if (status==OnError) return status;
    96 int unexpected_line = 0;
    97 while (!finished())
    98         {
    99         if ((status==BeforeObject) || ((status==BeforeUnknown) && !lastobject.isEmpty()))
    100                 {
    101                 Param tmp_param;
    102                 ParamInterface *pi=lastobject.getParamInterface(tmp_param);
    103                 pi->load(file,true,&aborting,&linenum);
    104                 if ((status!=Finished) && maybeBreak(AfterObject))
    105                         break;
    106                 unexpected_line = 0;
    107                 continue;
    108                 }
    109         else if (status==BeforeUnknown)
    110                 {
    111                 logPrintf("MultiParamLoader","go",LOG_WARN,"Skipping object '%s'",lastunknown.c_str());
    112                 loadObjectNow(&emptyparam,false);
    113                 continue;
    114                 }
    115         if (!loadSStringLine(file,buf))
    116                 {
    117                 unexpected_line = 0;
    118                 if (!returnFromIncluded())
    119                         {
    120                         abort();
    121                         break;
    122                         }
    123                 else
     94        SString buf;
     95        if (status == OnError) return status;
     96        int unexpected_line = 0;
     97        while (!finished())
     98        {
     99                if ((status == BeforeObject) || ((status == BeforeUnknown) && !lastobject.isEmpty()))
     100                {
     101                        Param tmp_param;
     102                        ParamInterface *pi = lastobject.getParamInterface(tmp_param);
     103                        ParamInterface::LoadOptions opts;
     104                        opts.abortable = &aborting;
     105                        opts.warn_unknown_fields = true;
     106                        opts.linenum = &linenum;
     107                        pi->load(ParamInterface::FormatMultiLine, file, &opts);
     108                        if ((status != Finished) && maybeBreak(AfterObject))
     109                                break;
     110                        unexpected_line = 0;
    124111                        continue;
    125112                }
    126         linenum++;
    127         if (buf[0]=='#')
    128                 {
    129                 unexpected_line = 0;
    130                 if (buf.startsWith("#include"))
    131                         {
    132                         const char* t=strchr(buf.c_str(),'\"'),*t2=0;
    133                         if (t)
    134                                 t2=strchr(t+1,'\"');
    135                         if (t2)
     113                else if (status == BeforeUnknown)
     114                {
     115                        logPrintf("MultiParamLoader", "go", LOG_WARN, "Skipping object '%s'", lastunknown.c_str());
     116                        loadObjectNow(&emptyparam, false);
     117                        continue;
     118                }
     119                if (!loadSStringLine(file, buf))
     120                {
     121                        unexpected_line = 0;
     122                        if (!returnFromIncluded())
     123                        {
     124                                abort();
     125                                break;
     126                        }
     127                        else
     128                                continue;
     129                }
     130                linenum++;
     131                if (buf[0] == '#')
     132                {
     133                        unexpected_line = 0;
     134                        if (buf.startsWith("#include"))
     135                        {
     136                                const char* t = strchr(buf.c_str(), '\"'), *t2 = 0;
     137                                if (t)
     138                                        t2 = strchr(t + 1, '\"');
     139                                if (t2)
    136140                                {
    137                                 SString filename(t+1,t2-t-1);
    138                                 includeFile(filename);
     141                                        SString filename(t + 1, t2 - t - 1);
     142                                        includeFile(filename);
    139143                                }
    140                         else
     144                                else
    141145                                {
    142                                 const char* thisfilename=file->VgetPath();
    143                                 logPrintf("MultiParamLoader","go",LOG_WARN,"invalid \"%s\"%s%s",buf.c_str(),
    144                                          (thisfilename?" in ":""),(thisfilename?thisfilename:""));
     146                                        const char* thisfilename = file->VgetPath();
     147                                        logPrintf("MultiParamLoader", "go", LOG_WARN, "invalid \"%s\"%s%s", buf.c_str(),
     148                                                (thisfilename ? " in " : ""), (thisfilename ? thisfilename : ""));
    145149                                }
     150                                continue;
     151                        }
     152                        else if ((status != Finished) && maybeBreak(OnComment))
     153                        {
     154                                lastcomment = buf.substr(1);
     155                                break;
     156                        }
    146157                        continue;
    147                         }
    148                 else if ((status!=Finished) && maybeBreak(OnComment))
    149                         {
    150                         lastcomment=buf.substr(1);
    151                         break;
    152                         }
    153                 continue;
    154                 }
    155         buf=trim(buf);
    156         if (buf.len()==0)
    157                 unexpected_line = 0;
    158         else if ((buf.len()>1)&&(buf[buf.len()-1]==':'))
    159                 {
    160                 unexpected_line = 0;
    161                 lastunknown=0;
    162                 lastunknown=buf.substr(0,buf.len()-1);
    163                 lastobject.setEmpty();
    164                 FOREACH(ExtObject*,o,objects)
    165                         {
    166                         if (!strcmp(o->interfaceName(),lastunknown.c_str())) {lastobject=*o; break;}
     158                }
     159                buf = trim(buf);
     160                if (buf.len() == 0)
     161                        unexpected_line = 0;
     162                else if ((buf.len() > 1) && (buf[buf.len() - 1] == ':'))
     163                {
     164                        unexpected_line = 0;
     165                        lastunknown = 0;
     166                        lastunknown = buf.substr(0, buf.len() - 1);
     167                        lastobject.setEmpty();
     168                        FOREACH(ExtObject*, o, objects)
     169                        {
     170                                if (!strcmp(o->interfaceName(), lastunknown.c_str())) { lastobject = *o; break; }
    167171                        }
    168172                        if (!lastobject.isEmpty())
    169                                 {
     173                        {
    170174                                if (maybeBreak(BeforeObject))
    171175                                        break;
    172                                 }
     176                        }
    173177                        else
    174                                 {
     178                        {
    175179                                if (maybeBreak(BeforeUnknown))
    176180                                        break;
    177                                 }
    178                
    179                 }
     181                        }
     182
     183                }
     184                else
     185                {
     186                        switch (unexpected_line)
     187                        {
     188                        case 0:
     189                        {
     190                                const char* thisfilename = file->VgetPath();
     191                                logPrintf("MultiParamLoader", "go", LOG_WARN, "Ignored unexpected line %d%s",
     192                                        linenum,
     193                                        thisfilename ? SString::sprintf(" while reading '%s'", thisfilename).c_str() : "");
     194                        }
     195                                break;
     196
     197                        case 1:
     198                                logPrintf("MultiParamLoader", "go", LOG_WARN, "The following line(s) were also unexpected and were ignored");
     199                                break;
     200                        }
     201                        unexpected_line++;
     202                }
     203        }
     204        return status;
     205}
     206
     207bool MultiParamLoader::alreadyIncluded(const char* filename)
     208{
     209        int i;
     210        const char* t;
     211        for (i = 0; i < filestack.size(); i++)
     212        {
     213                t = filestack(i)->VgetPath();
     214                if (!t) continue;
     215                if (!strcmp(filename, t)) return true;
     216        }
     217        return false;
     218}
     219
     220void MultiParamLoader::includeFile(SString& filename)
     221{
     222        const char* thisfilename = file->VgetPath();
     223        SString newfilename;
     224        const char* t = thisfilename ? strrchr(thisfilename, PATH_SEPARATOR_CHAR) : 0;
     225
     226        if (thisfilename && t)
     227        {
     228                newfilename.append(thisfilename, t - thisfilename + 1);
     229                newfilename += filename;
     230        }
    180231        else
    181                 {
    182                 switch(unexpected_line)
    183                         {
    184                         case 0:
    185                         {
    186                         const char* thisfilename=file->VgetPath();
    187                         logPrintf("MultiParamLoader","go", LOG_WARN, "Ignored unexpected line %d%s",
    188                                   linenum,
    189                                   thisfilename ? SString::sprintf(" while reading '%s'",thisfilename).c_str():"");
    190                         }
    191                         break;
    192 
    193                         case 1:
    194                         logPrintf("MultiParamLoader","go", LOG_WARN, "The following line(s) were also unexpected and were ignored");
    195                         break;
    196                         }
    197                 unexpected_line++;
    198                 }
    199         }
    200 return status;
    201 }
    202 
    203 bool MultiParamLoader::alreadyIncluded(const char* filename)
    204 {
    205 int i;
    206 const char* t;
    207 for(i=0;i<filestack.size();i++)
    208         {
    209         t=filestack(i)->VgetPath();
    210         if (!t) continue;
    211         if (!strcmp(filename,t)) return true;
    212         }
    213 return false;
    214 }
    215 
    216 void MultiParamLoader::includeFile(SString& filename)
    217 {
    218 const char* thisfilename=file->VgetPath();
    219 SString newfilename;
    220 const char* t=thisfilename?strrchr(thisfilename,PATH_SEPARATOR_CHAR):0;
    221 
    222 if (thisfilename && t)
    223         {
    224         newfilename.append(thisfilename,t-thisfilename+1);
    225         newfilename+=filename;
    226         }
    227 else
    228         newfilename=filename;
    229 
    230 if (alreadyIncluded(newfilename.c_str()))
    231         {
    232         logPrintf("MultiParamLoader","include",LOG_WARN,"circular reference ignored (\"%s\")",
    233                     filename.c_str());
    234         return;
    235         }
    236 
    237 VirtFILE *f=Vfopen(newfilename.c_str(),FOPEN_READ_BINARY);
    238 if (!f)
    239         {
    240         logPrintf("MultiParamLoader","include",LOG_WARN,"\"%s\" not found",newfilename.c_str());
    241         }
    242 else
    243         {
    244         filestack+=file;
    245         file=f;
     232                newfilename = filename;
     233
     234        if (alreadyIncluded(newfilename.c_str()))
     235        {
     236                logPrintf("MultiParamLoader", "include", LOG_WARN, "circular reference ignored (\"%s\")",
     237                        filename.c_str());
     238                return;
     239        }
     240
     241        VirtFILE *f = Vfopen(newfilename.c_str(), FOPEN_READ_BINARY);
     242        if (!f)
     243        {
     244                logPrintf("MultiParamLoader", "include", LOG_WARN, "\"%s\" not found", newfilename.c_str());
     245        }
     246        else
     247        {
     248                filestack += file;
     249                file = f;
    246250        }
    247251}
     
    249253VirtFILE* MultiParamLoader::popstack()
    250254{
    251 if (!filestack.size()) return 0;
    252 VirtFILE* f=filestack(filestack.size()-1);
    253 filestack.remove(filestack.size()-1);
    254 return f;
     255        if (!filestack.size()) return 0;
     256        VirtFILE* f = filestack(filestack.size() - 1);
     257        filestack.remove(filestack.size() - 1);
     258        return f;
    255259}
    256260
    257261void MultiParamLoader::clearstack()
    258262{
    259 VirtFILE *f;
    260 while(f=popstack()) delete f;
     263        VirtFILE *f;
     264        while (f = popstack()) delete f;
    261265}
    262266
    263267bool MultiParamLoader::returnFromIncluded()
    264268{
    265 if (!filestack.size()) return false;
    266 if (file) delete file;
    267 file=popstack();
    268 return true;
    269 }
    270 
    271 int MultiParamLoader::loadObjectNow(const ExtObject& o,bool warn_unknown_fields)
    272 {
    273 Param tmp_param;
    274 ParamInterface *pi=o.getParamInterface(tmp_param);
    275 pi->load(file,warn_unknown_fields,&aborting,&linenum);
    276 status=AfterObject;
    277 return 0;
     269        if (!filestack.size()) return false;
     270        if (file) delete file;
     271        file = popstack();
     272        return true;
     273}
     274
     275int MultiParamLoader::loadObjectNow(const ExtObject& o, bool warn_unknown_fields)
     276{
     277        Param tmp_param;
     278        ParamInterface *pi = o.getParamInterface(tmp_param);
     279        ParamInterface::LoadOptions opts;
     280        opts.abortable = &aborting;
     281        opts.warn_unknown_fields = warn_unknown_fields;
     282        opts.linenum = &linenum;
     283        pi->load(ParamInterface::FormatMultiLine, file, &opts);
     284        status = AfterObject;
     285        return 0;
    278286}
    279287
    280288int MultiParamLoader::run()
    281289{
    282 int stat;
    283 breakOn(OnError);
    284 while(stat=go())
    285         if (stat==OnError)
     290        int stat;
     291        breakOn(OnError);
     292        while (stat = go())
     293                if (stat == OnError)
    286294                {
    287295                abort();
    288296                return 0;
    289297                }
    290 return 1;
     298        return 1;
    291299}
    292300
    293301SString MultiParamLoader::currentFilePathForErrorMessage()
    294302{
    295 const char* filename=getFile()->VgetPath();
    296 if (filename)
    297         return SString::sprintf(" in '%s'",filename);
    298 return SString::empty();
    299 }
     303        const char* filename = getFile()->VgetPath();
     304        if (filename)
     305                return SString::sprintf(" in '%s'", filename);
     306        return SString::empty();
     307}
Note: See TracChangeset for help on using the changeset viewer.