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*/;
23 void xiniParse(A
...) (VFile fl
, A args
) {
26 scope(exit
) line
.destroy
;
30 auto sz
= line
.length
;
33 if (fl
.rawRead((&ch
)[0..1]).length
== 0) { eof
= true; break; }
34 if (ch
== '\n') break;
35 if (sz
>= linebuf
.length
) {
36 if (sz
> 1024*1024) throw new Exception("line too long");
38 linebuf
.assumeSafeAppend
;
39 linebuf
.length
= sz
+1024;
41 linebuf
.ptr
[sz
++] = ch
;
43 if (sz
== 0) continue;
44 line
= linebuf
[0..sz
];
45 while (line
.length
&& line
[0] <= ' ') line
= line
[1..$];
46 while (line
.length
&& line
[$-1] <= ' ') line
= line
[0..$-1];
47 if (line
.length
== 0 || line
[0] == '#' || line
[0] == ';') continue;
49 while (eqp
< line
.length
&& line
.ptr
[eqp
] != '=') ++eqp
;
50 if (eqp
>= line
.length
) continue;
51 auto name
= line
[0..eqp
];
52 auto value
= line
[eqp
+1..$];
53 while (name
.length
&& name
[0] <= ' ') name
= name
[1..$];
54 while (name
.length
&& name
[$-1] <= ' ') name
= name
[0..$-1];
55 while (value
.length
&& value
[0] <= ' ') value
= value
[1..$];
56 while (value
.length
&& value
[$-1] <= ' ') value
= value
[0..$-1];
57 //{ import std.stdio; writeln(name.quote, "=", value.quote); }
59 foreach (immutable idx
, immutable TA
; A
) {
60 //pragma(msg, idx, " : ", A[idx]);
61 static if (idx
%2 == 0) {
62 static if (is(TA
== string
)) {
63 if (args
[idx
] == name
) {
65 static if (isCallable
!(A
[idx
+1])) {
66 args
[idx
+1](name
, value
);
67 } else static if (is(A
[idx
+1] : T
*, T
)) {
69 static if (is(T
== ubyte) ||
is(T
== ushort) ||
is(T
== uint) ||
is(T
== ulong)) {
70 if (value
.length
> 2 && value
[0] == '0' && (value
[1] == 'x' || value
[1] == 'X')) {
71 *(args
[idx
+1]) = to
!T(value
[2..$], 16);
73 *(args
[idx
+1]) = to
!T(value
);
76 *(args
[idx
+1]) = to
!T(value
);
78 //{ import std.stdio; writeln("TA: ", args[idx].quote); }
80 static assert(0, "argument for value should be delegate or pointer");
82 } else if (args
[idx
].length
== name
.length
+1 && args
[idx
][0] == '?' && args
[idx
][1..$] == name
) {
83 // this should be bool -- "i've seen her" flag
84 static if (isCallable
!(A
[idx
+1])) {
85 } else static if (is(A
[idx
+1] : T
*, T
)) {
87 //pragma(msg, "b: ", T);
88 *(args
[idx
+1]) = to
!T(true);
90 static assert(0, "argument for checked should be var");
96 // call "unknown key" callback
97 static if (A
.length
%2 && isCallable
!(A
[$-1])) {
98 if (!found
) args
[$-1](name
, value
);
106 int sec = -1, par = -1, word = -1;
108 xiniParse(VFile("z00.rc"),
113 "boo", (const(char)[] name, const(char)[] value) { import std.stdio; writeln("<", name, ">=<", value, ">"); },
116 writeln("sec=", sec);
117 writeln("par=", par);
118 writeln("word=", word);
119 writeln("wasSec=", wasSec);