1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "primitive_cfg.h"
21 #include "nel/misc/config_file.h"
22 #include "nel/misc/path.h"
24 using namespace NLMISC
;
27 // std::vector<std::string> CPrimitiveCfg::_AllPrimitives;
28 std::vector
<std::string
> CPrimitiveCfg::_MapNames
;
29 std::map
<std::string
, std::vector
<std::string
> > CPrimitiveCfg::_Maps
;
30 std::map
<std::string
, std::vector
<std::string
> > CPrimitiveCfg::_ContinentFiles
;
32 void CPrimitiveCfg::addPrimitive(std::vector
<std::string
> &vectorlist
, const std::string
&str
)
34 for (uint32 i
=0;i
<vectorlist
.size();i
++)
35 if (vectorlist
[i
]==str
)
38 vectorlist
.push_back(str
);
42 std::string
CPrimitiveCfg::getContinentNameOf(const std::string
&fileName
)
44 CPrimitiveCfg::readPrimitiveCfg();
45 string name
= CFile::getFilename(fileName
);
47 std::map
<std::string
, std::vector
<std::string
> >::iterator
first(_ContinentFiles
.begin()), last(_ContinentFiles
.end());
48 for (; first
!= last
; ++first
)
49 if (find(first
->second
.begin(),first
->second
.end(), name
) != first
->second
.end())
55 // dumb routine to simplify repetitive text parsing code
56 inline bool isWhiteSpace(char c
)
58 return (c
==' ' || c
=='\t');
61 // -- stringToWordAndTail() --
62 // The following routine splits a text string into a keyword and a tail.
63 // A white space is used as separator between keyword and tail
64 // All leading and trailing ' ' and '\t' round keyword and tail characters are stripped
65 // If no keyword is found routine retuns false (keyword and tail retain previous content)
66 inline bool stringToWordAndTail(const std::string
&input
,std::string
&word
, std::string
&tail
)
71 while (i
<input
.size() && isWhiteSpace(input
[i
])) ++i
; // i points to start of word
73 // look for the end of the word
74 for (j
=i
;j
<input
.size() && !isWhiteSpace(input
[j
]);) ++j
; // j points to next character after word
76 // if no word found then give up
77 if (j
==i
) return false;
80 word
=input
.substr(i
,j
-i
);
82 // find the end of the tail text
83 for (i
=(uint
)input
.size();i
>j
&& isWhiteSpace(input
[i
-1]);) --i
; // i points to character after end of tail text
85 // find start of tail text
86 do { ++j
; } while(j
<i
&& isWhiteSpace(input
[j
])); // j points to start of tail text
88 // copy out the tail (or clear if no tail found in input)
90 tail
=input
.substr(j
,i
-j
);
97 void CPrimitiveCfg::readPrimitiveCfg(bool forceReload
)
100 && !_MapNames
.empty())
103 // _AllPrimitives.clear();
107 std::string filename
= CPath::lookup("primitives.cfg");
108 if (filename
.empty())
110 nlwarning("Can't find the primitive configuration file 'primitives.cfg'");
117 cfg
.load(filename
.c_str());
119 CConfigFile::CVar var
= cfg
.getVar("PrimitiveFiles");
121 std::vector
<std::string
> CurrentMapNames
;
122 set
<string
> mapNames
;
124 std::vector
<std::string
> *_CurrentContinentFiles
=NULL
;
126 for (uint32 i
=0;i
<var
.size();++i
)
130 // get the next string from the config file entry and make sure its not empty
131 const std::string s
=var
.asString(i
);
138 stringToWordAndTail(s
, keyword
, tail
);
142 // // skip opening white space and make sure there's not just white space
143 // for (j=0;j<s.size() && (s[j]==' ' || s[j]=='\t');++j);
146 // // separate the first word (we need it to know what to do next)
147 // for (k=j;k<s.size() && s[k]!=' ' && s[k]!='\t';++k);
148 // std::string keyword=s.substr(j,k-j);
150 // // separate out the tail, pruning trailing blanks
151 // // ignore leading blanks
152 // for (j=k;j<s.size() && (s[j]==' ' || s[j]=='\t');++j);
153 // // ignore trailing spaces
154 // for (k=s.size()-1;s[k]==' '||s[k]=='\t';--k);
155 // // if we found some non-blank text take a copy in a 'tail' variable
157 // if (k>=j) tail=s.substr(j,k-j+1);
160 // do something depending on the keyword found earlier
161 if (nlstricmp(keyword
,"MAPEND")==0)
163 // remove the last map entry
164 CurrentMapNames
.pop_back();
166 else if (nlstricmp(keyword
,"CONTINENT")==0)
168 _CurrentContinentFiles
=&_ContinentFiles
[tail
];
170 else if (nlstricmp(keyword
,"MAP")==0)
172 // store the map name for use later
173 CurrentMapNames
.push_back(tail
);
174 mapNames
.insert(tail
);
175 _Maps
.insert(make_pair(tail
, vector
<string
>()));
176 if (_CurrentContinentFiles
)
177 addPrimitive(*_CurrentContinentFiles
, tail
); // bad but not too ..
179 else if (nlstricmp(keyword
,"FILE")==0)
181 // if our file name is > 0 characters long then add it to the vector
184 string filename
= tail
; //s.substr(j,k-j+1);
185 if (CFile::getExtension(filename
).empty())
186 filename
+=".primitive";
188 for (uint32 mapInd
=0;mapInd
<CurrentMapNames
.size();mapInd
++)
189 addPrimitive(_Maps
[CurrentMapNames
[mapInd
]], filename
);
191 if (_CurrentContinentFiles
)
192 addPrimitive(*_CurrentContinentFiles
, filename
);
194 // nlwarning("Not Continents specified for %s",filename.c_str());
198 else if (nlstricmp(keyword
,"INCLUDE")==0)
200 // if our file name is > 0 characters long then add it to the vector
203 string includeName
= tail
; //s.substr(j,k-j+1);
205 if (_Maps
.find(includeName
)==_Maps
.end())
207 nlwarning("PrimitiveCfg: Include %s failed, not defined.",includeName
.c_str());
211 std::vector
<std::string
> &vectorlist
=_Maps
[includeName
];
212 for (uint32 primInd
=0;primInd
<vectorlist
.size();primInd
++)
214 const string
&primitiveFileName
=vectorlist
[primInd
];
216 for (uint32 mapInd
=0;mapInd
<CurrentMapNames
.size();mapInd
++)
217 addPrimitive(_Maps
[CurrentMapNames
[mapInd
]], primitiveFileName
);
218 if (_CurrentContinentFiles
)
219 addPrimitive(*_CurrentContinentFiles
, primitiveFileName
);
221 nlwarning("Not Continents specified for %s",includeName
.c_str());
230 nlwarning("Unknown keyword in PrimitiveFiles at line: '%s'",s
.c_str());
232 // fill the maps names vector
233 _MapNames
.insert(_MapNames
.begin(), mapNames
.begin(), mapNames
.end());
237 nlwarning("Error reading or parsing the primitive configuration file '%s'", filename
.c_str());