PhoenixFileParser  1.0.0
Set of tools to ease file parsing
Loading...
Searching...
No Matches
dico_replace_var.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
7#include "PFileParser.h"
8#include "dico_replace_var.h"
9
11typedef std::vector<std::pair<PNestedCall, DicoValue*> > PVecReplaceVar;
13typedef std::map<PString, std::pair<PNestedCall, DicoValue*> > MapVarWithNestedCall;
14
16
21void dico_create_nested_call(PNestedCall & call, const PString & baseStr, const PString & varBegin, const PString & varEnd){
22 PFileParser parser;
23 parser.setFileContent(baseStr);
24 while(!parser.isEndOfFile()){
25 PString prevCall(parser.getUntilKeyWithoutPatern(varBegin));
26 if(prevCall != ""){
27 PNestedStr str;
28 str.setValue(prevCall);
29 str.setIsVarCall(false);
30 call.getVecNestedStr().push_back(str);
31 }
32 PString varNameCall(parser.getUntilKeyWithoutPatern(varEnd));
33 if(varNameCall != ""){
34 PNestedStr str;
35 str.setValue(varNameCall);
36 str.setIsVarCall(true);
37 call.getVecNestedStr().push_back(str);
38 }
39 }
40}
41
43
49void dico_replace_nested_call(PString & out, const PNestedCall & call, const PMapKnownVar & mapKeyVariable, const PString & varBegin, const PString & varEnd){
50 const std::vector<PNestedStr> & vecNestedStr = call.getVecNestedStr();
51 for(std::vector<PNestedStr>::const_iterator it(vecNestedStr.begin()); it != vecNestedStr.end(); ++it){
52 if(it->getIsVarCall()){
53 PMapKnownVar::const_iterator itCall(mapKeyVariable.find(varBegin + it->getValue() + varEnd));
54 if(itCall != mapKeyVariable.end()){
55 out += itCall->second;
56 }else{
57 out += varBegin + it->getValue() + varEnd;
58 }
59 }else{
60 out += it->getValue();
61 }
62 }
63}
64
66
72PString dico_replace_var_str(const PString & baseStr, const PMapKnownVar & mapKeyVariable, const PString & varBegin, const PString & varEnd){
73 if(varBegin == "" || varEnd == ""){return baseStr;}
74 PNestedCall call;
75 dico_create_nested_call(call, baseStr, varBegin, varEnd);
76 PString out("");
77 dico_replace_nested_call(out, call, mapKeyVariable, varBegin, varEnd);
78 return out;
79}
80
82
89bool createNestedCallFromStr(PNestedCall & call, const PString & value, const PString varName, const PString & varBegin, const PString & varEnd){
90 call.setName(varName);
91 PFileParser parser;
92 parser.setFileContent(value);
93 bool hasNestedCall(false);
94 while(!parser.isEndOfFile()){
95 PString prevCall(parser.getUntilKeyWithoutPatern(varBegin));
96 if(prevCall != ""){
97 PNestedStr str;
98 str.setValue(prevCall);
99 str.setIsVarCall(false);
100 call.getVecNestedStr().push_back(str);
101 }
102 PString varNameCall(parser.getUntilKeyWithoutPatern(varEnd));
103 if(varNameCall != ""){
104 PNestedStr str;
105 str.setValue(varNameCall);
106 str.setIsVarCall(true);
107 call.getVecNestedStr().push_back(str);
108 hasNestedCall = true;
109 }
110 }
111 return hasNestedCall;
112}
113
115
121void dico_find_all_var(PMapKnownVar & mapReadyVar, PVecReplaceVar & mapNestedVar, MapVarWithNestedCall & mapVarWithNestedCall, DicoValue & dico, const PString & varIdentifier){
122 if(dico.hasMap()){
123 MapDicoValue & mapDico = dico.getMapChild();
124 for(MapDicoValue::iterator it(mapDico.begin()); it != mapDico.end(); ++it){
125 dico_find_all_var(mapReadyVar, mapNestedVar, mapVarWithNestedCall, it->second, varIdentifier);
126 }
127 }else if(dico.hasVec()){
128 VecDicoValue & vecDico = dico.getVecChild();
129 for(VecDicoValue::iterator it(vecDico.begin()); it != vecDico.end(); ++it){
130 dico_find_all_var(mapReadyVar, mapNestedVar, mapVarWithNestedCall, *it, varIdentifier);
131 }
132 }else if(dico.hasKey()){ //No map, no vector but a key, this is a string variable
133 PString strValue(dico.getString()), varName(dico.getKey());
134 //Let's check is the value contains nested calls
135 //We will create a class to handle the split between string part and nested calls
136 PNestedCall call;
137 //We add the class in the proper map
138 if((createNestedCallFromStr(call, strValue, varName, varIdentifier + "{", "}"))){ //There is (at least) one nested call
139 mapNestedVar.push_back(std::pair<PNestedCall, DicoValue*>(call, &dico));
140 mapVarWithNestedCall[varName] = std::pair<PNestedCall, DicoValue*>(call, &dico);
141 }else{ //There is no nested call
142 mapReadyVar[varName] = strValue;
143 }
144 }
145}
146
147
149
156void dico_update_all_nestedCall(PMapKnownVar & mapReadyVar, PVecReplaceVar & mapNestedVar, MapVarWithNestedCall & mapVarWithNestedCall,
157 PNestedCall & nestedCall, DicoValue * dico, const PString & varIdentifier)
158{
159 //For each call, we check if it comes from the mapReadyVar, from the mapNestedVar or from nowhere
160 PString outputValue("");
161 std::vector<PNestedStr> & vecNestedStr = nestedCall.getVecNestedStr();
162 for(std::vector<PNestedStr>::iterator it(vecNestedStr.begin()); it != vecNestedStr.end(); ++it){
163 if(!it->getIsVarCall()){ //If it is not a var call, we skip it
164 outputValue += it->getValue();
165 continue;
166 }
167 PString varName(it->getValue());
168 //If the var comes from mapNestedVar, we have to resolve this one first
169 MapVarWithNestedCall::iterator itNested = mapVarWithNestedCall.find(varName);
170 if(itNested != mapVarWithNestedCall.end()){
171 dico_update_all_nestedCall(mapReadyVar, mapNestedVar, mapVarWithNestedCall, itNested->second.first, itNested->second.second, varIdentifier);
172 mapVarWithNestedCall.erase(varName); //We solve varName, so we erase it from the mapNestedVar
173 //But now, the varName entry does exist in the mapReadyVar
174 }
175 //If the var comes from mapReadyVar, we replace it
176 PMapKnownVar::iterator itReady = mapReadyVar.find(varName);
177 if(itReady != mapReadyVar.end()){
178 outputValue += itReady->second;
179 }else{
180 //If we cannot find it, let's keep it unsolved (it can we a global variable)
181 outputValue += varIdentifier + "{" + varName + "}";
182 }
183 }
184 //Finally, we can update the dico value, but we deal with the quotation
185 PString firstQuote(""), prevValue(dico->getValue());
186 if(prevValue.size() != 0lu){
187 if(prevValue.front() == '\''){firstQuote = "'";}
188 else if(prevValue.front() == '"'){firstQuote = "\"";}
189 }
190 dico->setValue(firstQuote + outputValue + firstQuote);
191
192 //And put its value into the mapReadyVar, because we solve it
193 mapReadyVar[nestedCall.getName()] = outputValue;
194}
195
197
202void dico_update_all_var(PMapKnownVar & mapReadyVar, PVecReplaceVar & mapNestedVar, MapVarWithNestedCall & mapVarWithNestedCall,
203 const PString & varIdentifier)
204{
205 //Let's try to complete the nested call
206 for(PVecReplaceVar::iterator itNested(mapNestedVar.begin()); itNested != mapNestedVar.end(); ++itNested){
207 PNestedCall & nestedCall = itNested->first;
208 DicoValue * dico = itNested->second;
209
210 dico_update_all_nestedCall(mapReadyVar, mapNestedVar, mapVarWithNestedCall, nestedCall, dico, varIdentifier);
211 }
212}
213
215
218void dico_replace_var(DicoValue & dico, const PString & varIdentifier){
219 //Let's find all the defined variables, linked to the DicoValue, string only
220 PMapKnownVar mapReadyVar;
221 PVecReplaceVar mapNestedVar;
222 MapVarWithNestedCall mapVarWithNestedCall;
223 dico_find_all_var(mapReadyVar, mapNestedVar, mapVarWithNestedCall, dico, varIdentifier);
224
225 //Update variables with nested call, separate those with nested call from the other
226 dico_update_all_var(mapReadyVar, mapNestedVar, mapVarWithNestedCall, varIdentifier);
227}
228
229
std::map< PString, DicoValue > MapDicoValue
Vector of DicoValue.
Definition DicoValue.h:82
std::vector< DicoValue > VecDicoValue
Vector of DicoValue.
Definition DicoValue.h:80
Dictionnary of values.
Definition DicoValue.h:17
const PString & getKey() const
Gets the key of the DicoValue.
bool hasKey() const
Say if the DicoValue has a key.
Definition DicoValue.cpp:92
const std::vector< DicoValue > & getVecChild() const
Gets the vecChild of the DicoValue.
void setValue(const PString &value)
Sets the value of the DicoValue.
bool hasMap() const
Say if the DicoValue has a map of children.
Definition DicoValue.cpp:97
const std::map< PString, DicoValue > & getMapChild() const
Gets the mapChild of the DicoValue.
T getValue() const
Convert the value of the current DicoValue into a type.
PString getString() const
Get a string value without the first and/or last quote or double quote in there are some.
bool hasVec() const
Say if the DicoValue has a vector of children.
classe qui permet de parser des fichiers texte en renvoyant les tokens les uns après les autres
Definition PFileParser.h:20
PString getUntilKeyWithoutPatern(const PString &patern)
Renvoie la chaine de caractère du caractère courant jusqu'à patern exclu.
void setFileContent(const PString &fileContent)
Set the file content.
bool isEndOfFile() const
Dit si on est à la fin du fichier.
Class used to parse nested call variables.
Definition PNestedCall.h:36
void setName(const PString &name)
Sets the name of the PNestedCall.
const PString & getName() const
Gets the name of the PNestedCall.
const std::vector< PNestedStr > & getVecNestedStr() const
Gets the vecNestedStr of the PNestedCall.
Nested string or variable call.
Definition PNestedCall.h:14
void setValue(const PString &value)
Sets the value of the PNestedStr.
void setIsVarCall(bool isVarCall)
Sets the isVarCall of the PNestedStr.
std::vector< std::pair< PNestedCall, DicoValue * > > PVecReplaceVar
Map used to replace variable value in nested calls (VariableName, PNestedCall)
bool createNestedCallFromStr(PNestedCall &call, const PString &value, const PString varName, const PString &varBegin, const PString &varEnd)
Create the PNestedCall from the given value.
void dico_replace_nested_call(PString &out, const PNestedCall &call, const PMapKnownVar &mapKeyVariable, const PString &varBegin, const PString &varEnd)
Replace the nested call by the variables in map.
void dico_update_all_nestedCall(PMapKnownVar &mapReadyVar, PVecReplaceVar &mapNestedVar, MapVarWithNestedCall &mapVarWithNestedCall, PNestedCall &nestedCall, DicoValue *dico, const PString &varIdentifier)
Update variables with nested calls.
PString dico_replace_var_str(const PString &baseStr, const PMapKnownVar &mapKeyVariable, const PString &varBegin, const PString &varEnd)
Update the suffix of the file.
void dico_update_all_var(PMapKnownVar &mapReadyVar, PVecReplaceVar &mapNestedVar, MapVarWithNestedCall &mapVarWithNestedCall, const PString &varIdentifier)
Update the variable which contains nested calls.
void dico_create_nested_call(PNestedCall &call, const PString &baseStr, const PString &varBegin, const PString &varEnd)
Create the nested calls of the input base string.
void dico_find_all_var(PMapKnownVar &mapReadyVar, PVecReplaceVar &mapNestedVar, MapVarWithNestedCall &mapVarWithNestedCall, DicoValue &dico, const PString &varIdentifier)
Get the variable which contains only a value and those with nested calls.
std::map< PString, std::pair< PNestedCall, DicoValue * > > MapVarWithNestedCall
Map of the variables which uses nested call.
void dico_replace_var(DicoValue &dico, const PString &varIdentifier)
Replace all the variables which are string in the given DicoValue, when ${variable}...
std::map< PString, PString > PMapKnownVar
Map of known variables.