Changeset 720 for cpp/frams/param/multiparamload.cpp
- Timestamp:
- 01/14/18 11:24:22 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/param/multiparamload.cpp
r535 r720 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2018 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 10 10 void MultiParamLoader::init() 11 11 { 12 file=0; ownfile=0;13 status=0;14 reset();12 file = 0; ownfile = 0; 13 status = 0; 14 reset(); 15 15 } 16 16 17 17 void MultiParamLoader::reset() 18 18 { 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; 24 24 } 25 25 26 26 int MultiParamLoader::findObject(const ExtObject &o) 27 27 { 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; 32 32 } 33 33 34 34 void MultiParamLoader::removeObject(const ExtObject &o) 35 35 { 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; 41 41 } 42 42 } … … 44 44 void MultiParamLoader::clearObjects() 45 45 { 46 FOREACH(ExtObject*,o,objects)47 delete o;48 objects.clear();46 FOREACH(ExtObject*, o, objects) 47 delete o; 48 objects.clear(); 49 49 } 50 50 51 51 void MultiParamLoader::load() 52 52 { 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; 62 62 } 63 63 64 64 void MultiParamLoader::abort() 65 65 { 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; 74 74 } 75 75 76 76 void MultiParamLoader::load(VirtFILE *f) 77 77 { 78 abort();79 ownfile=0;80 file=f;81 load();78 abort(); 79 ownfile = 0; 80 file = f; 81 load(); 82 82 } 83 83 84 84 void MultiParamLoader::load(const char* filename) 85 85 { 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(); 90 90 } 91 91 92 92 int MultiParamLoader::go() 93 93 { 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; 124 111 continue; 125 112 } 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) 136 140 { 137 SString filename(t+1,t2-t-1);138 includeFile(filename);141 SString filename(t + 1, t2 - t - 1); 142 includeFile(filename); 139 143 } 140 else144 else 141 145 { 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 : "")); 145 149 } 150 continue; 151 } 152 else if ((status != Finished) && maybeBreak(OnComment)) 153 { 154 lastcomment = buf.substr(1); 155 break; 156 } 146 157 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; } 167 171 } 168 172 if (!lastobject.isEmpty()) 169 173 { 170 174 if (maybeBreak(BeforeObject)) 171 175 break; 172 176 } 173 177 else 174 178 { 175 179 if (maybeBreak(BeforeUnknown)) 176 180 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 207 bool 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 220 void 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 } 180 231 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; 246 250 } 247 251 } … … 249 253 VirtFILE* MultiParamLoader::popstack() 250 254 { 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; 255 259 } 256 260 257 261 void MultiParamLoader::clearstack() 258 262 { 259 VirtFILE *f;260 while(f=popstack()) delete f;263 VirtFILE *f; 264 while (f = popstack()) delete f; 261 265 } 262 266 263 267 bool MultiParamLoader::returnFromIncluded() 264 268 { 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 275 int 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; 278 286 } 279 287 280 288 int MultiParamLoader::run() 281 289 { 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) 286 294 { 287 295 abort(); 288 296 return 0; 289 297 } 290 return 1;298 return 1; 291 299 } 292 300 293 301 SString MultiParamLoader::currentFilePathForErrorMessage() 294 302 { 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.