1 /**
2   @file
3   @author Stefan Frings
4 */
5 
6 #include "template.h"
7 #include <QFileInfo>
8 
9 using namespace stefanfrings;
10 
Template(const QString source,const QString sourceName)11 Template::Template(const QString source, const QString sourceName)
12     : QString(source)
13 {
14     this->sourceName=sourceName;
15     this->warnings=false;
16 }
17 
Template(QFile & file,const QTextCodec * textCodec)18 Template::Template(QFile& file, const QTextCodec* textCodec)
19 {
20     this->warnings=false;
21     sourceName=QFileInfo(file.fileName()).baseName();
22     if (!file.isOpen())
23     {
24         file.open(QFile::ReadOnly | QFile::Text);
25     }
26     QByteArray data=file.readAll();
27     file.close();
28     if (data.size()==0 || file.error())
29     {
30         qCritical("Template: cannot read from %s, %s",qPrintable(sourceName),qPrintable(file.errorString()));
31     }
32     else
33     {
34         append(textCodec->toUnicode(data));
35     }
36 }
37 
38 
setVariable(const QString name,const QString value)39 int Template::setVariable(const QString name, const QString value)
40 {
41     int count=0;
42     QString variable="{"+name+"}";
43     int start=indexOf(variable);
44     while (start>=0)
45     {
46         replace(start, variable.length(), value);
47         count++;
48         start=indexOf(variable,start+value.length());
49     }
50     if (count==0 && warnings)
51     {
52         qWarning("Template: missing variable %s in %s",qPrintable(variable),qPrintable(sourceName));
53     }
54     return count;
55 }
56 
setCondition(const QString name,const bool value)57 int Template::setCondition(const QString name, const bool value)
58 {
59     int count=0;
60     QString startTag=QString("{if %1}").arg(name);
61     QString elseTag=QString("{else %1}").arg(name);
62     QString endTag=QString("{end %1}").arg(name);
63     // search for if-else-end
64     int start=indexOf(startTag);
65     while (start>=0)
66     {
67         int end=indexOf(endTag,start+startTag.length());
68         if (end>=0)
69         {
70             count++;
71             int ellse=indexOf(elseTag,start+startTag.length());
72             if (ellse>start && ellse<end)
73             {
74                 // there is an else part
75                 if (value==true)
76                 {
77                     QString truePart=mid(start+startTag.length(), ellse-start-startTag.length());
78                     replace(start, end-start+endTag.length(), truePart);
79                 }
80                 else
81                 {
82                     // value==false
83                     QString falsePart=mid(ellse+elseTag.length(), end-ellse-elseTag.length());
84                     replace(start, end-start+endTag.length(), falsePart);
85                 }
86             }
87             else if (value==true)
88             {
89                 // and no else part
90                 QString truePart=mid(start+startTag.length(), end-start-startTag.length());
91                 replace(start, end-start+endTag.length(), truePart);
92             }
93             else
94             {
95                 // value==false and no else part
96                 replace(start, end-start+endTag.length(), "");
97             }
98             start=indexOf(startTag,start);
99         }
100         else
101         {
102             qWarning("Template: missing condition end %s in %s",qPrintable(endTag),qPrintable(sourceName));
103         }
104     }
105     // search for ifnot-else-end
106     QString startTag2="{ifnot "+name+"}";
107     start=indexOf(startTag2);
108     while (start>=0)
109     {
110         int end=indexOf(endTag,start+startTag2.length());
111         if (end>=0)
112         {
113             count++;
114             int ellse=indexOf(elseTag,start+startTag2.length());
115             if (ellse>start && ellse<end)
116             {
117                 // there is an else part
118                 if (value==false)
119                 {
120                     QString falsePart=mid(start+startTag2.length(), ellse-start-startTag2.length());
121                     replace(start, end-start+endTag.length(), falsePart);
122                 }
123                 else
124                 {
125                     // value==true
126                     QString truePart=mid(ellse+elseTag.length(), end-ellse-elseTag.length());
127                     replace(start, end-start+endTag.length(), truePart);
128                 }
129             }
130             else if (value==false)
131             {
132                 // and no else part
133                 QString falsePart=mid(start+startTag2.length(), end-start-startTag2.length());
134                 replace(start, end-start+endTag.length(), falsePart);
135             }
136             else
137             {
138                 // value==true and no else part
139                 replace(start, end-start+endTag.length(), "");
140             }
141             start=indexOf(startTag2,start);
142         }
143         else
144         {
145             qWarning("Template: missing condition end %s in %s",qPrintable(endTag),qPrintable(sourceName));
146         }
147     }
148     if (count==0 && warnings)
149     {
150         qWarning("Template: missing condition %s or %s in %s",qPrintable(startTag),qPrintable(startTag2),qPrintable(sourceName));
151     }
152     return count;
153 }
154 
loop(const QString name,const int repetitions)155 int Template::loop(const QString name, const int repetitions)
156 {
157     Q_ASSERT(repetitions>=0);
158     int count=0;
159     QString startTag="{loop "+name+"}";
160     QString elseTag="{else "+name+"}";
161     QString endTag="{end "+name+"}";
162     // search for loop-else-end
163     int start=indexOf(startTag);
164     while (start>=0)
165     {
166         int end=indexOf(endTag,start+startTag.length());
167         if (end>=0)
168         {
169             count++;
170             int ellse=indexOf(elseTag,start+startTag.length());
171             if (ellse>start && ellse<end)
172             {
173                 // there is an else part
174                 if (repetitions>0)
175                 {
176                     QString loopPart=mid(start+startTag.length(), ellse-start-startTag.length());
177                     QString insertMe;
178                     for (int i=0; i<repetitions; ++i)
179                     {
180                         // number variables, conditions and sub-loop within the loop
181                         QString nameNum=name+QString::number(i);
182                         QString s=loopPart;
183                         s.replace(QString("{%1.").arg(name), QString("{%1.").arg(nameNum));
184                         s.replace(QString("{if %1.").arg(name), QString("{if %1.").arg(nameNum));
185                         s.replace(QString("{ifnot %1.").arg(name), QString("{ifnot %1.").arg(nameNum));
186                         s.replace(QString("{else %1.").arg(name), QString("{else %1.").arg(nameNum));
187                         s.replace(QString("{end %1.").arg(name), QString("{end %1.").arg(nameNum));
188                         s.replace(QString("{loop %1.").arg(name), QString("{loop %1.").arg(nameNum));
189                         insertMe.append(s);
190                     }
191                     replace(start, end-start+endTag.length(), insertMe);
192                 }
193                 else
194                 {
195                     // repetitions==0
196                     QString elsePart=mid(ellse+elseTag.length(), end-ellse-elseTag.length());
197                     replace(start, end-start+endTag.length(), elsePart);
198                 }
199             }
200             else if (repetitions>0)
201             {
202                 // and no else part
203                 QString loopPart=mid(start+startTag.length(), end-start-startTag.length());
204                 QString insertMe;
205                 for (int i=0; i<repetitions; ++i)
206                 {
207                     // number variables, conditions and sub-loop within the loop
208                     QString nameNum=name+QString::number(i);
209                     QString s=loopPart;
210                     s.replace(QString("{%1.").arg(name), QString("{%1.").arg(nameNum));
211                     s.replace(QString("{if %1.").arg(name), QString("{if %1.").arg(nameNum));
212                     s.replace(QString("{ifnot %1.").arg(name), QString("{ifnot %1.").arg(nameNum));
213                     s.replace(QString("{else %1.").arg(name), QString("{else %1.").arg(nameNum));
214                     s.replace(QString("{end %1.").arg(name), QString("{end %1.").arg(nameNum));
215                     s.replace(QString("{loop %1.").arg(name), QString("{loop %1.").arg(nameNum));
216                     insertMe.append(s);
217                 }
218                 replace(start, end-start+endTag.length(), insertMe);
219             }
220             else
221             {
222                 // repetitions==0 and no else part
223                 replace(start, end-start+endTag.length(), "");
224             }
225             start=indexOf(startTag,start);
226         }
227         else
228         {
229             qWarning("Template: missing loop end %s in %s",qPrintable(endTag),qPrintable(sourceName));
230         }
231     }
232     if (count==0 && warnings)
233     {
234         qWarning("Template: missing loop %s in %s",qPrintable(startTag),qPrintable(sourceName));
235     }
236     return count;
237 }
238 
enableWarnings(const bool enable)239 void Template::enableWarnings(const bool enable)
240 {
241     warnings=enable;
242 }
243 
244