source: cpp/frams/param/multiparamload.cpp @ 523

Last change on this file since 523 was 523, checked in by Maciej Komosinski, 8 years ago

No more overloading of fopen/fclose/... functions for the VirtFILE class. #define VIRTFILE_OVERLOADING to enable overloading only when necessary.

  • Property svn:eol-style set to native
File size: 5.3 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
[109]4
5#include "multiparamload.h"
6#include <frams/util/sstringutils.h>
[375]7#include "common/log.h"
[109]8#include <ctype.h>
9
10void MultiParamLoader::init()
11{
12file=0; ownfile=0;
13status=0;
14reset();
15}
16
17void MultiParamLoader::reset()
18{
19status=0;
20breakcond=OnError;
[277]21aborting=false;
[109]22emptyparam.setParamTab(empty_paramtab);
[333]23linenum=0;
[109]24}
25
26int MultiParamLoader::findObject(const ExtObject &o)
27{
28for(int i=0;i<objects.size();i++)
29        if ((*objects(i))==o)
30                return i;
31return -1;
32}
33
34void MultiParamLoader::removeObject(const ExtObject &o)
35{
36int i=findObject(o);
37if (i>=0)
38        {
39        delete objects(i);
40        objects-=i;
41        }
42}
43
44void MultiParamLoader::clearObjects()
45{
46FOREACH(ExtObject*,o,objects)
47        delete o;
48objects.clear();
49}
50
51void MultiParamLoader::load()
52{
53clearstack();
54if (!file)
55        {
56        lasterror="can't open file";
57        status=OnError;
58        return;
59        }
60status=Loading;
[277]61aborting=false;
[109]62}
63
64void MultiParamLoader::abort()
65{
66if (file && ownfile)
67        {
[523]68        delete file;
[109]69        file=0;
70        }
71clearstack();
72status=Finished;
[277]73aborting=true;
[109]74}
75
76void MultiParamLoader::load(VirtFILE *f)
77{
78abort();
79ownfile=0;
80file=f;
81load();
82}
83
84void MultiParamLoader::load(const char* filename)
85{
86abort();
87ownfile=1;
88file=Vfopen(filename,FOPEN_READ_BINARY);
89load();
90}
91
92int MultiParamLoader::go()
93{
94SString buf;
95if (status==OnError) return status;
[413]96int unexpected_line = 0;
[109]97while (!finished())
98        {
99        if ((status==BeforeObject) || ((status==BeforeUnknown) && !lastobject.isEmpty()))
100                {
101                Param tmp_param;
102                ParamInterface *pi=lastobject.getParamInterface(tmp_param);
[333]103                pi->load(file,true,&aborting,&linenum);
[109]104                if ((status!=Finished) && maybeBreak(AfterObject))
105                        break;
[413]106                unexpected_line = 0;
[109]107                continue;
108                }
109        else if (status==BeforeUnknown)
110                {
[375]111                logPrintf("MultiParamLoader","go",LOG_WARN,"Skipping object '%s'",lastunknown.c_str());
[268]112                loadObjectNow(&emptyparam,false);
[109]113                continue;
114                }
115        if (!loadSStringLine(file,buf))
116                {
[413]117                unexpected_line = 0;
[109]118                if (!returnFromIncluded())
119                        {
120                        abort();
121                        break;
122                        }
123                else
124                        continue;
125                }
[333]126        linenum++;
[109]127        if (buf[0]=='#')
128                {
[413]129                unexpected_line = 0;
[109]130                if (buf.startsWith("#include"))
131                        {
[348]132                        const char* t=strchr(buf.c_str(),'\"'),*t2=0;
[109]133                        if (t)
134                                t2=strchr(t+1,'\"');
135                        if (t2)
136                                {
137                                SString filename(t+1,t2-t-1);
[113]138                                includeFile(filename);
[109]139                                }
140                        else
141                                {
142                                const char* thisfilename=file->VgetPath();
[375]143                                logPrintf("MultiParamLoader","go",LOG_WARN,"invalid \"%s\"%s%s",buf.c_str(),
[109]144                                         (thisfilename?" in ":""),(thisfilename?thisfilename:""));
145                                }
146                        continue;
147                        }
148                else if ((status!=Finished) && maybeBreak(OnComment))
149                        {
150                        lastcomment=buf.substr(1);
151                        break;
152                        }
[268]153                continue;
[109]154                }
155        buf=trim(buf);
[413]156        if (buf.len()==0)
157                unexpected_line = 0;
158        else if ((buf.len()>1)&&(buf[buf.len()-1]==':'))
[109]159                {
[413]160                unexpected_line = 0;
[109]161                lastunknown=0;
162                lastunknown=buf.substr(0,buf.len()-1);
163                lastobject.setEmpty();
164                FOREACH(ExtObject*,o,objects)
165                        {
[348]166                        if (!strcmp(o->interfaceName(),lastunknown.c_str())) {lastobject=*o; break;}
[109]167                        }
168                        if (!lastobject.isEmpty())
169                                {
170                                if (maybeBreak(BeforeObject))
171                                        break;
172                                }
173                        else
174                                {
175                                if (maybeBreak(BeforeUnknown))
176                                        break;
177                                }
178               
179                }
[413]180        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                }
[109]199        }
200return status;
201}
202
203bool MultiParamLoader::alreadyIncluded(const char* filename)
204{
205int i;
206const char* t;
207for(i=0;i<filestack.size();i++)
208        {
209        t=filestack(i)->VgetPath();
210        if (!t) continue;
211        if (!strcmp(filename,t)) return true;
212        }
213return false;
214}
215
[113]216void MultiParamLoader::includeFile(SString& filename)
[109]217{
218const char* thisfilename=file->VgetPath();
219SString newfilename;
220const char* t=thisfilename?strrchr(thisfilename,PATH_SEPARATOR_CHAR):0;
221
222if (thisfilename && t)
223        {
224        newfilename.append(thisfilename,t-thisfilename+1);
225        newfilename+=filename;
226        }
227else
228        newfilename=filename;
229
[348]230if (alreadyIncluded(newfilename.c_str()))
[109]231        {
[375]232        logPrintf("MultiParamLoader","include",LOG_WARN,"circular reference ignored (\"%s\")",
[348]233                    filename.c_str());
[109]234        return;
235        }
236
[348]237VirtFILE *f=Vfopen(newfilename.c_str(),FOPEN_READ_BINARY);
[109]238if (!f)
239        {
[375]240        logPrintf("MultiParamLoader","include",LOG_WARN,"\"%s\" not found",newfilename.c_str());
[109]241        }
242else
243        {
244        filestack+=file;
245        file=f;
246        }
247}
248
249VirtFILE* MultiParamLoader::popstack()
250{
251if (!filestack.size()) return 0;
252VirtFILE* f=filestack(filestack.size()-1);
253filestack.remove(filestack.size()-1);
254return f;
255}
256
257void MultiParamLoader::clearstack()
258{
259VirtFILE *f;
[523]260while(f=popstack()) delete f;
[109]261}
262
263bool MultiParamLoader::returnFromIncluded()
264{
265if (!filestack.size()) return false;
[523]266if (file) delete file;
[109]267file=popstack();
268return true;
269}
270
[268]271int MultiParamLoader::loadObjectNow(const ExtObject& o,bool warn_unknown_fields)
[109]272{
273Param tmp_param;
274ParamInterface *pi=o.getParamInterface(tmp_param);
[333]275pi->load(file,warn_unknown_fields,&aborting,&linenum);
[109]276status=AfterObject;
277return 0;
278}
279
280int MultiParamLoader::run()
281{
282int stat;
283breakOn(OnError);
284while(stat=go())
285        if (stat==OnError)
286                {
287                abort();
288                return 0;
289                }
290return 1;
291}
Note: See TracBrowser for help on using the repository browser.