1 /* Written by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module xiniz
/*is aliced*/;
25 // ////////////////////////////////////////////////////////////////////////// //
26 void xiniParse(A
...) (VFile fl
, A args
) {
29 scope(exit
) line
.destroy
;
33 auto sz
= line
.length
;
36 if (fl
.rawRead((&ch
)[0..1]).length
== 0) { eof
= true; break; }
37 if (ch
== '\n') break;
38 if (sz
>= linebuf
.length
) {
39 if (sz
> 1024*1024) throw new Exception("line too long");
41 linebuf
.assumeSafeAppend
;
42 linebuf
.length
= sz
+1024;
44 linebuf
.ptr
[sz
++] = ch
;
46 if (sz
== 0) continue;
47 line
= linebuf
[0..sz
];
48 while (line
.length
&& line
[0] <= ' ') line
= line
[1..$];
49 while (line
.length
&& line
[$-1] <= ' ') line
= line
[0..$-1];
50 if (line
.length
== 0 || line
[0] == '#' || line
[0] == ';') continue;
52 while (eqp
< line
.length
&& line
.ptr
[eqp
] != '=') ++eqp
;
53 if (eqp
>= line
.length
) continue;
54 auto name
= line
[0..eqp
];
55 auto value
= line
[eqp
+1..$];
56 while (name
.length
&& name
[0] <= ' ') name
= name
[1..$];
57 while (name
.length
&& name
[$-1] <= ' ') name
= name
[0..$-1];
58 while (value
.length
&& value
[0] <= ' ') value
= value
[1..$];
59 while (value
.length
&& value
[$-1] <= ' ') value
= value
[0..$-1];
60 //{ import std.stdio; writeln(name.quote, "=", value.quote); }
62 foreach (immutable idx
, immutable TA
; A
) {
63 //pragma(msg, idx, " : ", A[idx]);
64 static if (idx
%2 == 0) {
65 static if (is(TA
== string
)) {
66 if (args
[idx
] == name
) {
68 static if (isCallable
!(A
[idx
+1])) {
69 args
[idx
+1](name
, value
);
70 } else static if (is(A
[idx
+1] : T
*, T
)) {
72 static if (is(T
== ubyte) ||
is(T
== ushort) ||
is(T
== uint) ||
is(T
== ulong)) {
73 if (value
.length
> 2 && value
[0] == '0' && (value
[1] == 'x' || value
[1] == 'X')) {
74 *(args
[idx
+1]) = to
!T(value
[2..$], 16);
76 *(args
[idx
+1]) = to
!T(value
);
78 } else static if (is(T
== NVGColor
)) {
80 if (value
.length
> 2 && value
[0] == '0' && (value
[1] == 'x' || value
[1] == 'X')) {
81 v
= to
!uint(value
[2..$], 16);
82 if (value
.length
<= 2+3*2) v |
= 0xff000000;
87 *(args
[idx
+1]) = NVGColor
.fromHtml(v
);
88 //writefln("v=0x%08x; r=%s; g=%s; b=%s; a=%s", v, (*(args[idx+1])).r, (*(args[idx+1])).g, (*(args[idx+1])).b, (*(args[idx+1])).a);
90 *(args
[idx
+1]) = to
!T(value
);
92 //{ import std.stdio; writeln("TA: ", args[idx].quote); }
94 static assert(0, "argument for value should be delegate or pointer");
96 } else if (args
[idx
].length
== name
.length
+1 && args
[idx
][0] == '?' && args
[idx
][1..$] == name
) {
97 // this should be bool -- "i've seen her" flag
98 static if (isCallable
!(A
[idx
+1])) {
99 } else static if (is(A
[idx
+1] : T
*, T
)) {
100 import std
.conv
: to
;
101 //pragma(msg, "b: ", T);
102 *(args
[idx
+1]) = to
!T(true);
104 static assert(0, "argument for checked should be var");
110 // call "unknown key" callback
111 static if (A
.length
%2 && isCallable
!(A
[$-1])) {
112 if (!found
) args
[$-1](name
, value
);
120 int sec = -1, par = -1, word = -1;
122 xiniParse(VFile("z00.rc"),
127 "boo", (const(char)[] name, const(char)[] value) { import std.stdio; writeln("<", name, ">=<", value, ">"); },
130 writeln("sec=", sec);
131 writeln("par=", par);
132 writeln("word=", word);
133 writeln("wasSec=", wasSec);