1 /*
2  *  cInitFile.h
3  *  Avida
4  *
5  *  Called "init_file.hh" prior to 12/7/05.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *  Copyright 1993-2003 California Institute of Technology.
8  *
9  *
10  *  This file is part of Avida.
11  *
12  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14  *
15  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
19  *  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef cInitFile_h
24 #define cInitFile_h
25 
26 #include "apto/core/Set.h"
27 
28 #include "cString.h"
29 #include "cStringList.h"
30 #include "cUserFeedback.h"
31 #include "tDictionary.h"
32 #include "tSmartArray.h"
33 
34 #include <iostream>
35 
36 
37 // A class to handle initialization files.
38 class cInitFile
39 {
40 private:
41   cString m_filename;
42   bool m_found;
43   bool m_opened;
44   mutable cUserFeedback m_feedback;
45 
46   struct sLine {
47     cString line;
48     cString file;
49     int line_num;
50     mutable bool used;
51 
sLinesLine52     sLine(const cString& in_line, const cString& in_file, int in_line_num)
53       : line(in_line), file(in_file), line_num(in_line_num), used(false) { ; }
54   };
55 
56   tArray<sLine*> m_lines;
57   cString m_ftype;
58   cStringList m_format;
59   cStringList m_imported_files;
60 
61   tDictionary<cString> m_mappings;
62   tDictionary<cString> m_custom_directives;
63 
64 
65   cInitFile(const cInitFile&); // @not_implemented
66   cInitFile& operator=(const cInitFile&); // @not_implemented
67 
68 
69 public:
70   cInitFile(const cString& filename, const cString& working_dir, Feedback& feedback, const Apto::Set<cString>* custom_directives = NULL);
71   cInitFile(const cString& filename, const cString& working_dir, const Apto::Set<cString>* custom_directives = NULL);
72   cInitFile(const cString& filename, const tDictionary<cString>& mappings, const cString& working_dir);
73   cInitFile(std::istream& in_stream, const cString& working_dir);
74   ~cInitFile();
75 
WasFound()76   bool WasFound() const { return m_found; }
WasOpened()77   bool WasOpened() const { return m_opened; }
GetFeedback()78   const cUserFeedback& GetFeedback() const { return m_feedback; }
GetCustomDirectives()79   const tDictionary<cString>& GetCustomDirectives() const { return m_custom_directives; }
80 
81   void Save(const cString& in_filename = "");
82 
83   /**
84    * Get a line from the file in memory. If called without parameters,
85    * the first line of the file is returned.
86    *
87    * @param line_num The line count of the line to be returned
88    * (starting from 0).
89    **/
90   cString GetLine(int line_num = 0);
91 
92   tDictionary<cString>* GetLineAsDict(int line_num = 0);
93 
94 
95   /**
96    * Checks whether any line contains a given keyword in the specified
97    * column. Stops when the first occurrence of the keyword is found.
98    *
99    * @return TRUE if keyword is found, FALSE otherwise.
100    * @param in_string A string variable that will contain the found line
101    * if search succeeds, and will have undefined contents otherwise.
102    * @param keyword The keyword to look for.
103    * @param col The column in which the keyword should be found.
104    **/
105   bool Find(cString& in_string, const cString& keyword, int col) const;
106 
107   /**
108    * Reads an entry in the initialization file that has a given keyword in the first column.
109    * The keyword is not part of the returned string.
110    *
111    * @return The entry that has been found.
112    * @param name The keyword to look for (the name of the entry).
113    * @param def If the keyword is not found, def is returned. This allows
114    * one to set standard values that are used if the user does not override
115    * them.
116    **/
117   cString ReadString(const cString& name, cString def = "", bool warn_default = true) const;
118 
119   /**
120    * Reads an entry in the initialization file that has a given keyword OR ANY OF ITS ALIASES
121    * in the first column. The keyword is not part of the returned string.
122    *
123    * @return The entry that has been found.
124    * @param names An array of keywords to look for (the name of the entry).
125    * @param def If the keyword is not found, def is returned. This allows
126    * one to set standard values that are used if the user does not override
127    * them.
128    **/
129   cString ReadString(const tArray<cString>& names, cString def = "", bool warn_default = true) const;
130 
131   /**
132    * Looks over all lines loaded into the file, and warns if any of them
133    * have not been the targets of the Find() method.  All methods that
134    * search the file for a keyword use find, so this can be used to locate
135    * keywords that are not understood by the program.
136    **/
137   bool WarnUnused() const;
138 
MarkLineUsed(int line_id)139   void MarkLineUsed(int line_id) { m_lines[line_id]->used = true; }
140 
GetNumLines()141   int GetNumLines() const { return m_lines.GetSize(); }
142 
GetFiletype()143   const cString& GetFiletype() { return m_ftype; }
GetFormat()144   const cStringList& GetFormat() { return m_format; }
145 
146 
147 private:
148   void initMappings(const tDictionary<cString>& mappings);
149   bool loadFile(const cString& filename, tSmartArray<sLine*>& lines, const cString& working_dir,
150                 const Apto::Set<cString>* custom_directives, Feedback& feedback);
151   bool processCommand(cString cmdstr, tSmartArray<sLine*>& lines, const cString& filename, int linenum,
152                       const cString& working_dir, const Apto::Set<cString>* custom_directives, Feedback& feedback);
153   void postProcess(tSmartArray<sLine*>& lines);
154 };
155 
156 #endif
157