GCC Code Coverage Report


Directory: ./
File: tmp_project/PhoenixFileParser/src/dico_replace_var.cpp
Date: 2025-03-14 11:45:13
Exec Total Coverage
Lines: 38 107 35.5%
Branches: 54 222 24.3%

Line Branch Exec Source
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
10 ///Map used to replace variable value in nested calls (VariableName, PNestedCall)
11 typedef std::vector<std::pair<PNestedCall, DicoValue*> > PVecReplaceVar;
12 ///Map of the variables which uses nested call
13 typedef std::map<PString, std::pair<PNestedCall, DicoValue*> > MapVarWithNestedCall;
14
15 ///Create the nested calls of the input base string
16 /** @param[out] call : PNestedCall to be created
17 * @param baseStr : basic suffix to be used
18 * @param varBegin : characters which announce the begining of a variable (example ${)
19 * @param varEnd : characters which announce the ending of a variable (example })
20 */
21 4 void dico_create_nested_call(PNestedCall & call, const PString & baseStr, const PString & varBegin, const PString & varEnd){
22
1/1
✓ Branch 1 taken 4 times.
4 PFileParser parser;
23
1/1
✓ Branch 1 taken 4 times.
4 parser.setFileContent(baseStr);
24
3/3
✓ Branch 1 taken 9 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 4 times.
9 while(!parser.isEndOfFile()){
25
1/1
✓ Branch 1 taken 5 times.
5 PString prevCall(parser.getUntilKeyWithoutPatern(varBegin));
26
3/3
✓ Branch 1 taken 5 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
5 if(prevCall != ""){
27
1/1
✓ Branch 1 taken 4 times.
4 PNestedStr str;
28
1/1
✓ Branch 1 taken 4 times.
4 str.setValue(prevCall);
29
1/1
✓ Branch 1 taken 4 times.
4 str.setIsVarCall(false);
30
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
4 call.getVecNestedStr().push_back(str);
31 4 }
32
1/1
✓ Branch 1 taken 5 times.
5 PString varNameCall(parser.getUntilKeyWithoutPatern(varEnd));
33
3/3
✓ Branch 1 taken 5 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
5 if(varNameCall != ""){
34
1/1
✓ Branch 1 taken 4 times.
4 PNestedStr str;
35
1/1
✓ Branch 1 taken 4 times.
4 str.setValue(varNameCall);
36
1/1
✓ Branch 1 taken 4 times.
4 str.setIsVarCall(true);
37
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
4 call.getVecNestedStr().push_back(str);
38 4 }
39 5 }
40 4 }
41
42 ///Replace the nested call by the variables in map
43 /** @param[out] out : output string with replaced variables
44 * @param call : nested call to create the output string
45 * @param mapKeyVariable : map of all defined variabled to be used
46 * @param varBegin : characters which announce the begining of a variable (example ${) (in case variable is not found)
47 * @param varEnd : characters which announce the ending of a variable (example }) (in case variable is not found)
48 */
49 4 void dico_replace_nested_call(PString & out, const PNestedCall & call, const PMapKnownVar & mapKeyVariable, const PString & varBegin, const PString & varEnd){
50 4 const std::vector<PNestedStr> & vecNestedStr = call.getVecNestedStr();
51
2/2
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 4 times.
12 for(std::vector<PNestedStr>::const_iterator it(vecNestedStr.begin()); it != vecNestedStr.end(); ++it){
52
3/3
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
8 if(it->getIsVarCall()){
53
5/5
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
✓ Branch 11 taken 4 times.
✓ Branch 14 taken 4 times.
4 PMapKnownVar::const_iterator itCall(mapKeyVariable.find(varBegin + it->getValue() + varEnd));
54
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
4 if(itCall != mapKeyVariable.end()){
55
1/1
✓ Branch 2 taken 3 times.
3 out += itCall->second;
56 }else{
57
4/4
✓ Branch 2 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 11 taken 1 times.
1 out += varBegin + it->getValue() + varEnd;
58 }
59 }else{
60
2/2
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
4 out += it->getValue();
61 }
62 }
63 4 }
64
65 ///Update the suffix of the file
66 /** @param baseStr : basic suffix to be used
67 * @param mapKeyVariable : map of all defined variabled to be used
68 * @param varBegin : characters which announce the begining of a variable (example ${)
69 * @param varEnd : characters which announce the ending of a variable (example })
70 * @return updated string
71 */
72 7 PString dico_replace_var_str(const PString & baseStr, const PMapKnownVar & mapKeyVariable, const PString & varBegin, const PString & varEnd){
73
7/7
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 4 times.
✓ Branch 9 taken 3 times.
7 if(varBegin == "" || varEnd == ""){return baseStr;}
74
1/1
✓ Branch 1 taken 4 times.
4 PNestedCall call;
75
1/1
✓ Branch 1 taken 4 times.
4 dico_create_nested_call(call, baseStr, varBegin, varEnd);
76
1/1
✓ Branch 1 taken 4 times.
4 PString out("");
77
1/1
✓ Branch 1 taken 4 times.
4 dico_replace_nested_call(out, call, mapKeyVariable, varBegin, varEnd);
78
1/1
✓ Branch 1 taken 4 times.
4 return out;
79 4 }
80
81 ///Create the PNestedCall from the given value
82 /** @param[out] call : PNestedCall
83 * @param value : value to be used
84 * @param varName : name of the variable to be defined
85 * @param varBegin : characters which announce the begining of a variable (example ${)
86 * @param varEnd : characters which announce the ending of a variable (example })
87 * @return true if the value contains a nested call, false otherwise
88 */
89 bool 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
114 ///Get the variable which contains only a value and those with nested calls
115 /** @param[out] mapReadyVar : map of variables with values only
116 * @param[out] mapNestedVar : map of variables with nested calls
117 * @param[out] mapVarWithNestedCall : map of the variables which use nested calls
118 * @param varIdentifier : String used to detect the variable names (example: '$' for ${varName}, § for §{varName})
119 * @param dico : DicoValue to be used
120 */
121 void 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
148 ///Update variables with nested calls
149 /** @param[out] mapReadyVar : map of variables with values only
150 * @param[out] mapNestedVar : map of variables with nested calls
151 * @param nestedCall : nested call which is the split value of the dico
152 * @param mapVarWithNestedCall : map of the variables which use nested calls
153 * @param dico : DicoValue to be used
154 * @param varIdentifier : String used to detect the variable names (example: '$' for ${varName}, § for §{varName})
155 */
156 void 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
196 ///Update the variable which contains nested calls
197 /** @param[out] mapReadyVar : map of variables with values only
198 * @param[out] mapNestedVar : map of variables with nested calls
199 * @param mapVarWithNestedCall : map of variable with nested call
200 * @param varIdentifier : String used to detect the variable names (example: '$' for ${varName}, § for §{varName})
201 */
202 void 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
214 ///Replace all the variables which are string in the given DicoValue, when ${variable} apprears in the value
215 /** @param dico : DicoValue to be updated
216 * @param varIdentifier : String used to detect the variable names (example: '$' for ${varName}, § for §{varName})
217 */
218 void 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
230