fixed flibusta loader
[xreader.git] / xiniz.d
blob336c1573e98a66f91940937039ab93274620c70f
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*/;
19 import iv.nanovega;
20 import iv.strex;
21 import iv.vfs;
22 import iv.vfs.io;
25 // ////////////////////////////////////////////////////////////////////////// //
26 void xiniParse(A...) (VFile fl, A args) {
27 import std.traits;
28 char[] line, linebuf;
29 scope(exit) line.destroy;
30 bool eof = false;
31 while (!eof) {
32 line = null;
33 auto sz = line.length;
34 for (;;) {
35 char ch = void;
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");
40 line = null;
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;
51 uint eqp = 0;
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); }
61 bool found = false;
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) {
67 found = true;
68 static if (isCallable!(A[idx+1])) {
69 args[idx+1](name, value);
70 } else static if (is(A[idx+1] : T*, T)) {
71 import std.conv : to;
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);
75 } else {
76 *(args[idx+1]) = to!T(value);
78 } else static if (is(T == NVGColor)) {
79 uint v;
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;
83 } else {
84 v = to!uint(value);
85 v |= 0xff000000;
87 *(args[idx+1]) = NVGColor.fromUintARGB(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);
89 } else {
90 *(args[idx+1]) = to!T(value);
92 //{ import std.stdio; writeln("TA: ", args[idx].quote); }
93 } else {
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);
103 } else {
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);
119 void main () {
120 int sec = -1, par = -1, word = -1;
121 bool wasSec = false;
122 xiniParse(VFile("z00.rc"),
123 "section", &sec,
124 "?section", &wasSec,
125 "paragraph", &par,
126 "word", &word,
127 "boo", (const(char)[] name, const(char)[] value) { import std.stdio; writeln("<", name, ">=<", value, ">"); },
129 import std.stdio;
130 writeln("sec=", sec);
131 writeln("par=", par);
132 writeln("word=", word);
133 writeln("wasSec=", wasSec);