xref: /trunk/main/autodoc/source/cosv/service/commandline.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*11c03c6dSDamjan Jovanovic /**************************************************************
2*11c03c6dSDamjan Jovanovic  *
3*11c03c6dSDamjan Jovanovic  * Licensed to the Apache Software Foundation (ASF) under one
4*11c03c6dSDamjan Jovanovic  * or more contributor license agreements.  See the NOTICE file
5*11c03c6dSDamjan Jovanovic  * distributed with this work for additional information
6*11c03c6dSDamjan Jovanovic  * regarding copyright ownership.  The ASF licenses this file
7*11c03c6dSDamjan Jovanovic  * to you under the Apache License, Version 2.0 (the
8*11c03c6dSDamjan Jovanovic  * "License"); you may not use this file except in compliance
9*11c03c6dSDamjan Jovanovic  * with the License.  You may obtain a copy of the License at
10*11c03c6dSDamjan Jovanovic  *
11*11c03c6dSDamjan Jovanovic  *   http://www.apache.org/licenses/LICENSE-2.0
12*11c03c6dSDamjan Jovanovic  *
13*11c03c6dSDamjan Jovanovic  * Unless required by applicable law or agreed to in writing,
14*11c03c6dSDamjan Jovanovic  * software distributed under the License is distributed on an
15*11c03c6dSDamjan Jovanovic  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*11c03c6dSDamjan Jovanovic  * KIND, either express or implied.  See the License for the
17*11c03c6dSDamjan Jovanovic  * specific language governing permissions and limitations
18*11c03c6dSDamjan Jovanovic  * under the License.
19*11c03c6dSDamjan Jovanovic  *
20*11c03c6dSDamjan Jovanovic  *************************************************************/
21*11c03c6dSDamjan Jovanovic 
22*11c03c6dSDamjan Jovanovic 
23*11c03c6dSDamjan Jovanovic 
24*11c03c6dSDamjan Jovanovic #include <precomp.h>
25*11c03c6dSDamjan Jovanovic #include <cosv/commandline.hxx>
26*11c03c6dSDamjan Jovanovic 
27*11c03c6dSDamjan Jovanovic // NOT FULLY DECLARED SERVICES
28*11c03c6dSDamjan Jovanovic #include <cosv/file.hxx>
29*11c03c6dSDamjan Jovanovic 
30*11c03c6dSDamjan Jovanovic 
31*11c03c6dSDamjan Jovanovic namespace csv
32*11c03c6dSDamjan Jovanovic {
33*11c03c6dSDamjan Jovanovic 
34*11c03c6dSDamjan Jovanovic namespace
35*11c03c6dSDamjan Jovanovic {
36*11c03c6dSDamjan Jovanovic 
37*11c03c6dSDamjan Jovanovic const intt C_nNoOption = -1;
38*11c03c6dSDamjan Jovanovic 
39*11c03c6dSDamjan Jovanovic const char * sIncludeOptionShort = "-A:";
40*11c03c6dSDamjan Jovanovic const char * sIncludeOptionLong  = "--Arguments:";
41*11c03c6dSDamjan Jovanovic const uintt nIncludeOptionShort_Length = strlen(sIncludeOptionShort);
42*11c03c6dSDamjan Jovanovic const uintt nIncludeOptionLong_Length = strlen(sIncludeOptionLong);
43*11c03c6dSDamjan Jovanovic 
44*11c03c6dSDamjan Jovanovic 
45*11c03c6dSDamjan Jovanovic /** Analyses, if an option is the one to include a file with
46*11c03c6dSDamjan Jovanovic     further command line arguments.
47*11c03c6dSDamjan Jovanovic */
48*11c03c6dSDamjan Jovanovic bool                IsIncludeOption(
49*11c03c6dSDamjan Jovanovic                         const String &      i_option );
50*11c03c6dSDamjan Jovanovic 
51*11c03c6dSDamjan Jovanovic /** Gets the file name from an include-arguments-option.
52*11c03c6dSDamjan Jovanovic */
53*11c03c6dSDamjan Jovanovic String              IncludeFile_fromIncludeOption(
54*11c03c6dSDamjan Jovanovic                         const String &      i_option );
55*11c03c6dSDamjan Jovanovic 
56*11c03c6dSDamjan Jovanovic 
57*11c03c6dSDamjan Jovanovic bool
IsIncludeOption(const String & i_option)58*11c03c6dSDamjan Jovanovic IsIncludeOption(const String & i_option)
59*11c03c6dSDamjan Jovanovic {
60*11c03c6dSDamjan Jovanovic     return strncmp(i_option, sIncludeOptionShort, nIncludeOptionShort_Length) == 0
61*11c03c6dSDamjan Jovanovic            OR
62*11c03c6dSDamjan Jovanovic            strncmp(i_option, sIncludeOptionLong, nIncludeOptionLong_Length) == 0;
63*11c03c6dSDamjan Jovanovic }
64*11c03c6dSDamjan Jovanovic 
65*11c03c6dSDamjan Jovanovic String
IncludeFile_fromIncludeOption(const String & i_option)66*11c03c6dSDamjan Jovanovic IncludeFile_fromIncludeOption(const String & i_option)
67*11c03c6dSDamjan Jovanovic {
68*11c03c6dSDamjan Jovanovic     if ( strncmp(i_option, sIncludeOptionShort, nIncludeOptionShort_Length)
69*11c03c6dSDamjan Jovanovic          == 0 )
70*11c03c6dSDamjan Jovanovic     {
71*11c03c6dSDamjan Jovanovic         return String(i_option, nIncludeOptionShort_Length, str::maxsize);
72*11c03c6dSDamjan Jovanovic     }
73*11c03c6dSDamjan Jovanovic     else
74*11c03c6dSDamjan Jovanovic     if ( strncmp(i_option, sIncludeOptionLong, nIncludeOptionLong_Length)
75*11c03c6dSDamjan Jovanovic          == 0 )
76*11c03c6dSDamjan Jovanovic     {
77*11c03c6dSDamjan Jovanovic         return String(i_option, nIncludeOptionLong_Length, str::maxsize);
78*11c03c6dSDamjan Jovanovic     }
79*11c03c6dSDamjan Jovanovic     return String::Null_();
80*11c03c6dSDamjan Jovanovic }
81*11c03c6dSDamjan Jovanovic 
82*11c03c6dSDamjan Jovanovic 
83*11c03c6dSDamjan Jovanovic }   // end anonymous namespace
84*11c03c6dSDamjan Jovanovic 
85*11c03c6dSDamjan Jovanovic 
86*11c03c6dSDamjan Jovanovic 
87*11c03c6dSDamjan Jovanovic 
88*11c03c6dSDamjan Jovanovic /** Local helper class for searching a possible option name in a vector of
89*11c03c6dSDamjan Jovanovic     ->OptionDescription.
90*11c03c6dSDamjan Jovanovic */
91*11c03c6dSDamjan Jovanovic struct CommandLine::
92*11c03c6dSDamjan Jovanovic FindOptionByText
93*11c03c6dSDamjan Jovanovic {
operator ()csv::CommandLine::FindOptionByText94*11c03c6dSDamjan Jovanovic     bool                operator()(
95*11c03c6dSDamjan Jovanovic                             const CommandLine::OptionDescription &
96*11c03c6dSDamjan Jovanovic                                                 i_option )
97*11c03c6dSDamjan Jovanovic                         { return i_option.sText == sOption; }
98*11c03c6dSDamjan Jovanovic 
99*11c03c6dSDamjan Jovanovic     /// @param i_searchText [i_searchText != ""]
FindOptionByTextcsv::CommandLine::FindOptionByText100*11c03c6dSDamjan Jovanovic                         FindOptionByText(
101*11c03c6dSDamjan Jovanovic                             const String &      i_option )
102*11c03c6dSDamjan Jovanovic                         :   sOption(i_option)   { }
103*11c03c6dSDamjan Jovanovic   private:
104*11c03c6dSDamjan Jovanovic     const String        sOption;
105*11c03c6dSDamjan Jovanovic };
106*11c03c6dSDamjan Jovanovic 
107*11c03c6dSDamjan Jovanovic 
108*11c03c6dSDamjan Jovanovic typedef std::vector<StringVector::const_iterator>   StringCIteratorList;
109*11c03c6dSDamjan Jovanovic typedef std::vector<intt>                           OptionIdList;
110*11c03c6dSDamjan Jovanovic 
111*11c03c6dSDamjan Jovanovic bool
Interpret(int argc,char * argv[])112*11c03c6dSDamjan Jovanovic CommandLine::Interpret( int    argc,
113*11c03c6dSDamjan Jovanovic                         char * argv[] )
114*11c03c6dSDamjan Jovanovic {
115*11c03c6dSDamjan Jovanovic     Get_Arguments(argc,argv);
116*11c03c6dSDamjan Jovanovic     csv_assert(aOptionPoints.size() == aOptionIds.size());
117*11c03c6dSDamjan Jovanovic 
118*11c03c6dSDamjan Jovanovic     StringVector::const_iterator
119*11c03c6dSDamjan Jovanovic         itNext          = aCommandLine.begin();
120*11c03c6dSDamjan Jovanovic         ++itNext;       // Move 1 forward from program name.
121*11c03c6dSDamjan Jovanovic     StringVector::const_iterator
122*11c03c6dSDamjan Jovanovic         itEnd           = aCommandLine.end();
123*11c03c6dSDamjan Jovanovic     StringCIteratorList::const_iterator
124*11c03c6dSDamjan Jovanovic         itOptPtsEnd     = aOptionPoints.end();
125*11c03c6dSDamjan Jovanovic 
126*11c03c6dSDamjan Jovanovic     OptionIdList::const_iterator
127*11c03c6dSDamjan Jovanovic         itOptIds = aOptionIds.begin();
128*11c03c6dSDamjan Jovanovic     for ( StringCIteratorList::const_iterator itOptPts = aOptionPoints.begin();
129*11c03c6dSDamjan Jovanovic           itOptPts != itOptPtsEnd AND bIsOk;
130*11c03c6dSDamjan Jovanovic           ++itOptPts, ++itOptIds )
131*11c03c6dSDamjan Jovanovic     {
132*11c03c6dSDamjan Jovanovic         // May be, there are arguments which do not belong to the last option:
133*11c03c6dSDamjan Jovanovic         // itNext != *is
134*11c03c6dSDamjan Jovanovic         Handle_FreeArguments(itNext, *itOptPts);
135*11c03c6dSDamjan Jovanovic 
136*11c03c6dSDamjan Jovanovic         itNext = do_HandleOption( *itOptIds,
137*11c03c6dSDamjan Jovanovic                                   *itOptPts + 1,
138*11c03c6dSDamjan Jovanovic                                   itOptPts+1 == itOptPtsEnd ? itEnd : *(itOptPts+1) );
139*11c03c6dSDamjan Jovanovic         csv_assert(itNext <= itEnd);
140*11c03c6dSDamjan Jovanovic     }   // end for (is)
141*11c03c6dSDamjan Jovanovic     Handle_FreeArguments(itNext, itEnd);
142*11c03c6dSDamjan Jovanovic 
143*11c03c6dSDamjan Jovanovic     return bIsOk;
144*11c03c6dSDamjan Jovanovic }
145*11c03c6dSDamjan Jovanovic 
CommandLine()146*11c03c6dSDamjan Jovanovic CommandLine::CommandLine()
147*11c03c6dSDamjan Jovanovic     :   aOptions(),
148*11c03c6dSDamjan Jovanovic         aCommandLine(),
149*11c03c6dSDamjan Jovanovic         bIsOk(false)
150*11c03c6dSDamjan Jovanovic {
151*11c03c6dSDamjan Jovanovic }
152*11c03c6dSDamjan Jovanovic 
153*11c03c6dSDamjan Jovanovic void
Add_Option(intt i_id,String i_text)154*11c03c6dSDamjan Jovanovic CommandLine::Add_Option( intt                i_id,
155*11c03c6dSDamjan Jovanovic                          String              i_text )
156*11c03c6dSDamjan Jovanovic {
157*11c03c6dSDamjan Jovanovic     aOptions.push_back(OptionDescription( i_id,
158*11c03c6dSDamjan Jovanovic                                           i_text ));
159*11c03c6dSDamjan Jovanovic }
160*11c03c6dSDamjan Jovanovic 
161*11c03c6dSDamjan Jovanovic void
Get_Arguments(int argc,char * argv[])162*11c03c6dSDamjan Jovanovic CommandLine::Get_Arguments( int    argc,
163*11c03c6dSDamjan Jovanovic                             char * argv[] )
164*11c03c6dSDamjan Jovanovic {
165*11c03c6dSDamjan Jovanovic     aCommandLine.erase(aCommandLine.begin(),aCommandLine.end());
166*11c03c6dSDamjan Jovanovic     aCommandLine.reserve(argc);
167*11c03c6dSDamjan Jovanovic 
168*11c03c6dSDamjan Jovanovic     char ** pArgEnd = argv + argc;
169*11c03c6dSDamjan Jovanovic     for ( char ** pArg = &argv[0];
170*11c03c6dSDamjan Jovanovic           pArg != pArgEnd;
171*11c03c6dSDamjan Jovanovic           ++pArg )
172*11c03c6dSDamjan Jovanovic     {
173*11c03c6dSDamjan Jovanovic         Store_Argument(*pArg);
174*11c03c6dSDamjan Jovanovic     }   // end for
175*11c03c6dSDamjan Jovanovic     Find_OptionPoints();
176*11c03c6dSDamjan Jovanovic     bIsOk = true;
177*11c03c6dSDamjan Jovanovic }
178*11c03c6dSDamjan Jovanovic 
179*11c03c6dSDamjan Jovanovic intt
Find_Option(const String & i_text) const180*11c03c6dSDamjan Jovanovic CommandLine::Find_Option( const String & i_text ) const
181*11c03c6dSDamjan Jovanovic {
182*11c03c6dSDamjan Jovanovic     if (i_text.empty())
183*11c03c6dSDamjan Jovanovic         return C_nNoOption;
184*11c03c6dSDamjan Jovanovic 
185*11c03c6dSDamjan Jovanovic     FindOptionByText aSearch(i_text);
186*11c03c6dSDamjan Jovanovic     OptionList::const_iterator
187*11c03c6dSDamjan Jovanovic         itFound = std::find_if( aOptions.begin(),
188*11c03c6dSDamjan Jovanovic                                 aOptions.end(),
189*11c03c6dSDamjan Jovanovic                                 aSearch );
190*11c03c6dSDamjan Jovanovic     if (itFound != aOptions.end())
191*11c03c6dSDamjan Jovanovic     {
192*11c03c6dSDamjan Jovanovic         return (*itFound).nId;
193*11c03c6dSDamjan Jovanovic     }
194*11c03c6dSDamjan Jovanovic     return C_nNoOption;
195*11c03c6dSDamjan Jovanovic }
196*11c03c6dSDamjan Jovanovic 
197*11c03c6dSDamjan Jovanovic bool
Store_Argument(const String & i_arg)198*11c03c6dSDamjan Jovanovic CommandLine::Store_Argument( const String & i_arg )
199*11c03c6dSDamjan Jovanovic {
200*11c03c6dSDamjan Jovanovic     if ( NOT IsIncludeOption(i_arg) )
201*11c03c6dSDamjan Jovanovic     {
202*11c03c6dSDamjan Jovanovic         aCommandLine.push_back(i_arg);
203*11c03c6dSDamjan Jovanovic         return true;
204*11c03c6dSDamjan Jovanovic     }
205*11c03c6dSDamjan Jovanovic 
206*11c03c6dSDamjan Jovanovic     return Try2Include_Options(i_arg);
207*11c03c6dSDamjan Jovanovic }
208*11c03c6dSDamjan Jovanovic 
209*11c03c6dSDamjan Jovanovic void
Find_OptionPoints()210*11c03c6dSDamjan Jovanovic CommandLine::Find_OptionPoints()
211*11c03c6dSDamjan Jovanovic {
212*11c03c6dSDamjan Jovanovic     StringVector::const_iterator    itEnd   = aCommandLine.end();
213*11c03c6dSDamjan Jovanovic     for ( StringVector::const_iterator it = aCommandLine.begin() + 1;
214*11c03c6dSDamjan Jovanovic           it != itEnd;
215*11c03c6dSDamjan Jovanovic           ++it )
216*11c03c6dSDamjan Jovanovic     {
217*11c03c6dSDamjan Jovanovic         intt    nOption = Find_Option(*it);
218*11c03c6dSDamjan Jovanovic         if (nOption != C_nNoOption)
219*11c03c6dSDamjan Jovanovic         {
220*11c03c6dSDamjan Jovanovic             aOptionPoints.push_back(it);
221*11c03c6dSDamjan Jovanovic             aOptionIds.push_back(nOption);
222*11c03c6dSDamjan Jovanovic         }
223*11c03c6dSDamjan Jovanovic     }   // end for (i)
224*11c03c6dSDamjan Jovanovic }
225*11c03c6dSDamjan Jovanovic 
226*11c03c6dSDamjan Jovanovic void
Handle_FreeArguments(StringVector::const_iterator i_begin,StringVector::const_iterator i_end)227*11c03c6dSDamjan Jovanovic CommandLine::Handle_FreeArguments( StringVector::const_iterator i_begin,
228*11c03c6dSDamjan Jovanovic                                    StringVector::const_iterator i_end )
229*11c03c6dSDamjan Jovanovic {
230*11c03c6dSDamjan Jovanovic     for ( StringVector::const_iterator it = i_begin;
231*11c03c6dSDamjan Jovanovic           it != i_end AND bIsOk;
232*11c03c6dSDamjan Jovanovic           ++it )
233*11c03c6dSDamjan Jovanovic     {
234*11c03c6dSDamjan Jovanovic         do_HandleFreeArgument(*it);
235*11c03c6dSDamjan Jovanovic     }
236*11c03c6dSDamjan Jovanovic }
237*11c03c6dSDamjan Jovanovic 
238*11c03c6dSDamjan Jovanovic bool
Try2Include_Options(const String & i_includeOption)239*11c03c6dSDamjan Jovanovic CommandLine::Try2Include_Options(const String & i_includeOption)
240*11c03c6dSDamjan Jovanovic {
241*11c03c6dSDamjan Jovanovic     static StringVector
242*11c03c6dSDamjan Jovanovic         aIncludedOptionFiles_;
243*11c03c6dSDamjan Jovanovic 
244*11c03c6dSDamjan Jovanovic     const String
245*11c03c6dSDamjan Jovanovic         aOptionFile(IncludeFile_fromIncludeOption(i_includeOption));
246*11c03c6dSDamjan Jovanovic 
247*11c03c6dSDamjan Jovanovic     // Avoid recursion deadlock 1
248*11c03c6dSDamjan Jovanovic     if ( std::find( aIncludedOptionFiles_.begin(),
249*11c03c6dSDamjan Jovanovic                     aIncludedOptionFiles_.end(),
250*11c03c6dSDamjan Jovanovic                     aOptionFile )
251*11c03c6dSDamjan Jovanovic          != aIncludedOptionFiles_.end() )
252*11c03c6dSDamjan Jovanovic     {
253*11c03c6dSDamjan Jovanovic         Cerr() << "\nError: Self inclusion of option file "
254*11c03c6dSDamjan Jovanovic                << aOptionFile
255*11c03c6dSDamjan Jovanovic                << ".\n"
256*11c03c6dSDamjan Jovanovic                << Endl();
257*11c03c6dSDamjan Jovanovic         return false;
258*11c03c6dSDamjan Jovanovic     }
259*11c03c6dSDamjan Jovanovic 
260*11c03c6dSDamjan Jovanovic     // Avoid recursion deadlock 2
261*11c03c6dSDamjan Jovanovic     aIncludedOptionFiles_.push_back(aOptionFile);
262*11c03c6dSDamjan Jovanovic 
263*11c03c6dSDamjan Jovanovic     bool ok = Include_Options(aOptionFile);
264*11c03c6dSDamjan Jovanovic 
265*11c03c6dSDamjan Jovanovic     // Avoid recursion deadlock 3
266*11c03c6dSDamjan Jovanovic     aIncludedOptionFiles_.pop_back();
267*11c03c6dSDamjan Jovanovic 
268*11c03c6dSDamjan Jovanovic     return ok;
269*11c03c6dSDamjan Jovanovic }
270*11c03c6dSDamjan Jovanovic 
271*11c03c6dSDamjan Jovanovic bool
Include_Options(const String & i_optionsFile)272*11c03c6dSDamjan Jovanovic CommandLine::Include_Options( const String & i_optionsFile )
273*11c03c6dSDamjan Jovanovic {
274*11c03c6dSDamjan Jovanovic     StreamStr
275*11c03c6dSDamjan Jovanovic         aIncludedText(500);
276*11c03c6dSDamjan Jovanovic     bool ok = Load_Options(aIncludedText, i_optionsFile);
277*11c03c6dSDamjan Jovanovic     if (NOT ok)
278*11c03c6dSDamjan Jovanovic         return false;
279*11c03c6dSDamjan Jovanovic 
280*11c03c6dSDamjan Jovanovic     StringVector
281*11c03c6dSDamjan Jovanovic         aIncludedOptions;
282*11c03c6dSDamjan Jovanovic     Split(aIncludedOptions, aIncludedText.c_str());
283*11c03c6dSDamjan Jovanovic 
284*11c03c6dSDamjan Jovanovic     StringVector::const_iterator itEnd = aIncludedOptions.end();
285*11c03c6dSDamjan Jovanovic     for ( StringVector::const_iterator it = aIncludedOptions.begin();
286*11c03c6dSDamjan Jovanovic           it != itEnd;
287*11c03c6dSDamjan Jovanovic           ++it )
288*11c03c6dSDamjan Jovanovic     {
289*11c03c6dSDamjan Jovanovic         Store_Argument(*it);
290*11c03c6dSDamjan Jovanovic     }   // end for
291*11c03c6dSDamjan Jovanovic 
292*11c03c6dSDamjan Jovanovic     return true;
293*11c03c6dSDamjan Jovanovic }
294*11c03c6dSDamjan Jovanovic 
295*11c03c6dSDamjan Jovanovic bool
Load_Options(StreamStr & o_text,const String & i_optionsFile)296*11c03c6dSDamjan Jovanovic CommandLine::Load_Options( StreamStr &      o_text,
297*11c03c6dSDamjan Jovanovic                            const String &   i_optionsFile )
298*11c03c6dSDamjan Jovanovic {
299*11c03c6dSDamjan Jovanovic     if (i_optionsFile.empty())
300*11c03c6dSDamjan Jovanovic         return false;
301*11c03c6dSDamjan Jovanovic 
302*11c03c6dSDamjan Jovanovic     File
303*11c03c6dSDamjan Jovanovic         aOptionsFile(i_optionsFile, CFM_READ);
304*11c03c6dSDamjan Jovanovic     OpenCloseGuard
305*11c03c6dSDamjan Jovanovic         aOFGuard(aOptionsFile);
306*11c03c6dSDamjan Jovanovic     if (NOT aOFGuard)
307*11c03c6dSDamjan Jovanovic     {
308*11c03c6dSDamjan Jovanovic         Cerr() << "\nError: Options file "
309*11c03c6dSDamjan Jovanovic                << i_optionsFile
310*11c03c6dSDamjan Jovanovic                << " not found.\n"
311*11c03c6dSDamjan Jovanovic                << Endl();
312*11c03c6dSDamjan Jovanovic         return false;
313*11c03c6dSDamjan Jovanovic     }
314*11c03c6dSDamjan Jovanovic 
315*11c03c6dSDamjan Jovanovic     StreamStr
316*11c03c6dSDamjan Jovanovic         aLoad(aOptionsFile);
317*11c03c6dSDamjan Jovanovic     o_text.swap(aLoad);
318*11c03c6dSDamjan Jovanovic     return true;
319*11c03c6dSDamjan Jovanovic }
320*11c03c6dSDamjan Jovanovic 
321*11c03c6dSDamjan Jovanovic 
322*11c03c6dSDamjan Jovanovic 
323*11c03c6dSDamjan Jovanovic 
324*11c03c6dSDamjan Jovanovic /******************         OptionDescription       ***********************/
325*11c03c6dSDamjan Jovanovic 
326*11c03c6dSDamjan Jovanovic 
327*11c03c6dSDamjan Jovanovic CommandLine::
OptionDescription(intt i_id,String i_text)328*11c03c6dSDamjan Jovanovic OptionDescription::OptionDescription( intt          i_id,
329*11c03c6dSDamjan Jovanovic                                       String        i_text )
330*11c03c6dSDamjan Jovanovic     :   nId(i_id),
331*11c03c6dSDamjan Jovanovic         sText(i_text)
332*11c03c6dSDamjan Jovanovic {
333*11c03c6dSDamjan Jovanovic }
334*11c03c6dSDamjan Jovanovic 
335*11c03c6dSDamjan Jovanovic 
336*11c03c6dSDamjan Jovanovic 
337*11c03c6dSDamjan Jovanovic 
338*11c03c6dSDamjan Jovanovic }   // namespace csv
339