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

Last change on this file since 288 was 286, checked in by Maciej Komosinski, 9 years ago

Updated headers

  • Property svn:eol-style set to native
File size: 4.6 KB
Line 
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.
4
5#include "multiparamload.h"
6#include <frams/util/sstringutils.h>
7#include "common/framsg.h"
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;
21aborting=false;
22emptyparam.setParamTab(empty_paramtab);
23}
24
25int MultiParamLoader::findObject(const ExtObject &o)
26{
27for(int i=0;i<objects.size();i++)
28        if ((*objects(i))==o)
29                return i;
30return -1;
31}
32
33void MultiParamLoader::removeObject(const ExtObject &o)
34{
35int i=findObject(o);
36if (i>=0)
37        {
38        delete objects(i);
39        objects-=i;
40        }
41}
42
43void MultiParamLoader::clearObjects()
44{
45FOREACH(ExtObject*,o,objects)
46        delete o;
47objects.clear();
48}
49
50void MultiParamLoader::load()
51{
52clearstack();
53if (!file)
54        {
55        lasterror="can't open file";
56        status=OnError;
57        return;
58        }
59status=Loading;
60aborting=false;
61}
62
63void MultiParamLoader::abort()
64{
65if (file && ownfile)
66        {
67        fclose(file);
68        file=0;
69        }
70clearstack();
71status=Finished;
72aborting=true;
73}
74
75void MultiParamLoader::load(VirtFILE *f)
76{
77abort();
78ownfile=0;
79file=f;
80load();
81}
82
83void MultiParamLoader::load(const char* filename)
84{
85abort();
86ownfile=1;
87file=Vfopen(filename,FOPEN_READ_BINARY);
88load();
89}
90
91int MultiParamLoader::go()
92{
93SString buf;
94if (status==OnError) return status;
95while (!finished())
96        {
97        if ((status==BeforeObject) || ((status==BeforeUnknown) && !lastobject.isEmpty()))
98                {
99                Param tmp_param;
100                ParamInterface *pi=lastobject.getParamInterface(tmp_param);
101                pi->load(file,true,&aborting);
102                if ((status!=Finished) && maybeBreak(AfterObject))
103                        break;
104                continue;
105                }
106        else if (status==BeforeUnknown)
107                {
108                FMprintf("MultiParamLoader","go",FMLV_WARN,"Skipping object '%s'",(const char*)lastunknown);
109                loadObjectNow(&emptyparam,false);
110                continue;
111                }
112        if (!loadSStringLine(file,buf))
113                {
114                if (!returnFromIncluded())
115                        {
116                        abort();
117                        break;
118                        }
119                else
120                        continue;
121                }
122        if (buf[0]=='#')
123                {
124                if (buf.startsWith("#include"))
125                        {
126                        const char* t=strchr((const char*)buf,'\"'),*t2=0;
127                        if (t)
128                                t2=strchr(t+1,'\"');
129                        if (t2)
130                                {
131                                SString filename(t+1,t2-t-1);
132                                includeFile(filename);
133                                }
134                        else
135                                {
136                                const char* thisfilename=file->VgetPath();
137                                FMprintf("MultiParamLoader","go",FMLV_WARN,"invalid \"%s\"%s%s",(const char*)buf,
138                                         (thisfilename?" in ":""),(thisfilename?thisfilename:""));
139                                }
140                        continue;
141                        }
142                else if ((status!=Finished) && maybeBreak(OnComment))
143                        {
144                        lastcomment=buf.substr(1);
145                        break;
146                        }
147                continue;
148                }
149        buf=trim(buf);
150        if ((buf.len()>1)&&(buf[buf.len()-1]==':'))
151                {
152                lastunknown=0;
153                lastunknown=buf.substr(0,buf.len()-1);
154                lastobject.setEmpty();
155                FOREACH(ExtObject*,o,objects)
156                        {
157                        if (!strcmp(o->interfaceName(),lastunknown)) {lastobject=*o; break;}
158                        }
159                        if (!lastobject.isEmpty())
160                                {
161                                if (maybeBreak(BeforeObject))
162                                        break;
163                                }
164                        else
165                                {
166                                if (maybeBreak(BeforeUnknown))
167                                        break;
168                                }
169               
170                }
171        }
172return status;
173}
174
175bool MultiParamLoader::alreadyIncluded(const char* filename)
176{
177int i;
178const char* t;
179for(i=0;i<filestack.size();i++)
180        {
181        t=filestack(i)->VgetPath();
182        if (!t) continue;
183        if (!strcmp(filename,t)) return true;
184        }
185return false;
186}
187
188void MultiParamLoader::includeFile(SString& filename)
189{
190const char* thisfilename=file->VgetPath();
191SString newfilename;
192const char* t=thisfilename?strrchr(thisfilename,PATH_SEPARATOR_CHAR):0;
193
194if (thisfilename && t)
195        {
196        newfilename.append(thisfilename,t-thisfilename+1);
197        newfilename+=filename;
198        }
199else
200        newfilename=filename;
201
202if (alreadyIncluded(newfilename))
203        {
204        FMprintf("MultiParamLoader","include",FMLV_WARN,"circular reference ignored (\"%s\")",
205                    (const char*)filename);
206        return;
207        }
208
209VirtFILE *f=Vfopen(newfilename,FOPEN_READ_BINARY);
210if (!f)
211        {
212        FMprintf("MultiParamLoader","include",FMLV_WARN,"\"%s\" not found",(const char*)newfilename);
213        }
214else
215        {
216        filestack+=file;
217        file=f;
218        }
219}
220
221VirtFILE* MultiParamLoader::popstack()
222{
223if (!filestack.size()) return 0;
224VirtFILE* f=filestack(filestack.size()-1);
225filestack.remove(filestack.size()-1);
226return f;
227}
228
229void MultiParamLoader::clearstack()
230{
231VirtFILE *f;
232while(f=popstack()) fclose(f);
233}
234
235bool MultiParamLoader::returnFromIncluded()
236{
237if (!filestack.size()) return false;
238if (file) fclose(file);
239file=popstack();
240return true;
241}
242
243int MultiParamLoader::loadObjectNow(const ExtObject& o,bool warn_unknown_fields)
244{
245Param tmp_param;
246ParamInterface *pi=o.getParamInterface(tmp_param);
247pi->load(file,warn_unknown_fields,&aborting);
248status=AfterObject;
249return 0;
250}
251
252int MultiParamLoader::run()
253{
254int stat;
255breakOn(OnError);
256while(stat=go())
257        if (stat==OnError)
258                {
259                abort();
260                return 0;
261                }
262return 1;
263}
Note: See TracBrowser for help on using the repository browser.