1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 module utils.DefReader;
21 
22 import std.algorithm;
23 import std.array;
24 import std.file;
25 import std.string : splitLines, strip, indexOf;
26 
27 import utils.WrapError;
28 
29 public class DefReader
30 {
31 	string filename;
32 	string key;
33 	string value;
34 
35 	int lineNumber;
36 	string[] lines;
37 
38 	public this(string filename)
39 	{
40 		this.filename = filename;
41 
42 		lines = readText(filename).splitLines();
43 		//Skip utf8 BOM.
44 		lines[0].skipOver(x"efbbbf");
45 
46 		this.popFront();
47 	}
48 
49 	public void popFront()
50 	{
51 		string line;
52 
53 		if ( !lines.empty )
54 		{
55 			line = lines.front.strip();
56 			lines.popFront();
57 			lineNumber++;
58 
59 			while ( !lines.empty && ( line.empty || line.startsWith("#") ) )
60 			{
61 				line = lines.front.strip();
62 				lines.popFront();
63 				lineNumber++;
64 			}
65 		}
66 
67 		if ( !line.empty && !line.startsWith("#") )
68 		{
69 			size_t index = line.indexOf(':');
70 
71 			key   = line[0 .. max(index, 0)].strip();
72 			value = line[index +1 .. $].strip();
73 		}
74 		else
75 		{
76 			key.length = 0;
77 			value.length = 0;
78 		}
79 	}
80 
81 	/**
82 	 * Gets the contends of a block value
83 	 */
84 	public string[] readBlock(string key = "")
85 	{
86 		string[] block;
87 
88 		if ( key.empty )
89 			key = this.key;
90 
91 		while ( !lines.empty )
92 		{
93 			if ( startsWith(lines.front.strip(), key) )
94 			{
95 				lines.popFront();
96 				lineNumber++;
97 				return block;
98 			}
99 
100 			block ~= lines.front ~ '\n';
101 			lines.popFront();
102 			lineNumber++;
103 		}
104 
105 		throw new WrapError(this, "Found EOF while expecting: \""~key~": end\"");
106 	}
107 
108 	/**
109 	 * Gets the current value as a bool
110 	 */
111 	public @property bool valueBool()
112 	{
113 		return !!value.among("1", "ok", "OK", "Ok", "true", "TRUE", "True", "Y", "y", "yes", "YES", "Yes");
114 	}
115 
116 	public @property bool empty()
117 	{
118 		return lines.empty && key.empty;
119 	}
120 }