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

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

GDK used by developers since 1999, distributed on the web since 2002

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