master
parser.c
ohmu
·
2026-09-24
1/* I'm so ashamed of this code, sorry */
2
3/*
4 * TODO: rewrite using p9p libs
5 */
6
7#include <stdio.h>
8#include <string.h>
9#include <stdlib.h>
10#include <inttypes.h>
11#include "parser.h"
12
13char *home;
14
15void
16defconfig(FILE *f)
17{
18 fprintf(f, "shell /usr/local/plan9/bin/rc\n");
19 fprintf(f, "mainfont /lib/font/bit/lucsans/euro.8.font\n");
20 fprintf(f, "monofont /lib/font/bit/lucm/unicode.9.font\n");
21 fprintf(f, "dumppath /tmp/acme.dump\n");
22 fprintf(f, "winbtnstyle def\n");
23 fprintf(f, "colbtnstyle def\n");
24 fprintf(f, "scrollstyle def\n");
25 fprintf(f, "pastels tagbg txtbg scrlfg\n");
26 fprintf(f, "\n");
27 fprintf(f, "mix FFFFFF\n");
28 fprintf(f, "root FFFFFF\n");
29 fprintf(f, "border 000000\n");
30 fprintf(f, "tagbg AAFFFF\n");
31 fprintf(f, "tagfg 000000\n");
32 fprintf(f, "htagbg 9EEEEE\n");
33 fprintf(f, "htagfg 000000\n");
34 fprintf(f, "txtbg FFFFAA\n");
35 fprintf(f, "txtfg 000000\n");
36 fprintf(f, "htxtbg EEEE9E\n");
37 fprintf(f, "htxtfg 000000\n");
38 fprintf(f, "winbtn 8888CC\n");
39 fprintf(f, "winbtnbord 8888CC\n");
40 fprintf(f, "colbtn 8888CC\n");
41 fprintf(f, "tmpbtn 000099\n");
42 fprintf(f, "scrlbg 99994C\n");
43 fprintf(f, "scrlfg FFFFAA\n");
44 fprintf(f, "scrlbord 99994C\n");
45 fprintf(f, "btn2hl AA0000\n");
46 fprintf(f, "btn3hl 006600\n");
47 fprintf(f, "\n");
48 fprintf(f, "autoindent yes\n");
49 fprintf(f, "swpscrlbtns no\n");
50 fprintf(f, "clicktofocus no\n");
51 fprintf(f, "colcount 2\n");
52 fprintf(f, "openarg yes\n");
53 fprintf(f, "showdotfiles yes\n");
54 fprintf(f, "newcolnewrow yes\n");
55}
56
57char
58*parsekeyvalue(FILE *file, char const *desired_name, char *def)
59{
60 char line[256];
61 char name[128];
62 char val[128];
63
64 rewind(file);
65
66 while(fgets(line, sizeof(line), file)){
67 if(line[0] == '\n' || line[0] == '\0')
68 continue;
69 if(strncmp(line, "@include", 8) == 0){
70 char path[256];
71 char homepath[256];
72 char *p = line + 8;
73 while (*p == ' ' || *p == '\t') p++;
74 strcpy(path, p);
75 path[strcspn(path, "\n")] = '\0';
76 FILE *fi = fopen(path, "r");
77 if(!fi){
78 snprintf(homepath, sizeof(homepath), "%s/%s", home, path);
79 fi = fopen(homepath, "r");
80 if (!fi) {
81 fprintf(stderr, "error: can't open included file from home\n");
82 exit(1);
83 }
84 }
85 char *found = parsekeyvalue(fi, desired_name, NULL);
86 fclose(fi);
87 if (found) return found;
88 }
89
90 if(sscanf(line, "%127s %127[^\n]", name, val) == 2){
91 if(strcmp(name, desired_name) == 0){
92 return strdup(val);
93 }
94 }
95 }
96 return def;
97}
98
99uint32_t
100getcolor(FILE *f, char *key, uint32_t def)
101{
102 char *temp = parsekeyvalue(f, key, NULL);
103 if(!temp)
104 return def;
105 uint32_t color = strtoul(temp, NULL, 16) << 8 | 0xFF;
106 free(temp);
107 return color;
108}
109
110int
111getintvalue(FILE *f, char *key, int def)
112{
113 int result;
114 char *temp = parsekeyvalue(f, key, NULL);
115 if(temp == NULL)
116 return def;
117 else
118 result = atoi(temp);
119 free(temp);
120 return result;
121}
122
123int
124getboolean(char *key, int def)
125{
126 if(strcmp(key, "yes") == 0)
127 return 1;
128 else if(strcmp(key, "no") == 0)
129 return 0;
130
131 return def;
132}
133
134void
135initconfig(char *custom_config)
136{
137 char path[1024];
138 char *pastels_str;
139
140 home = getenv("HOME");
141 if(!home){
142 fprintf(stderr, "error: $HOME not set\n");
143 exit(1);
144 }
145 if(!custom_config){
146 snprintf(path, sizeof(path), "%s/.acmerc", home);
147 }else{
148 snprintf(path, sizeof(path), "%s", custom_config);
149 FILE *custom_f = fopen(path, "r");
150 if(!custom_f){
151 fprintf(stderr, "warning: can't open custom config file\n");
152 free(custom_f);
153 snprintf(path, sizeof(path), "%s/.acmerc", home);
154 }
155 }
156 FILE *f = fopen(path, "r");
157 if(!f){
158 fprintf(stderr, "warning: can't open config file\n");
159 f = fopen(path, "w");
160 if(!f){
161 fprintf(stderr, "fatal: can't create config file, exiting\n");
162 exit(1);
163 }
164 defconfig(f);
165 }
166 pastels_str = parsekeyvalue(f, "pastels", NULL);
167 if(pastels_str == NULL)
168 pastels_str = strdup("tagbg txtbg scrlfg");
169
170 char *p = strtok(pastels_str, " \t\n");
171 npastels = 0;
172 while(p != NULL && npastels < MAXPASTELS){
173 pastels[npastels++] = strdup(p);
174 p = strtok(NULL, " \t\n");
175 }
176
177 free(pastels_str);
178
179 winbtnstyle = parsekeyvalue(f, "winbtnstyle", "def");
180 colbtnstyle = parsekeyvalue(f, "colbtnstyle", "def");
181 scrollstyle = parsekeyvalue(f, "scrollstyle", "def");
182
183 C_MIX = getcolor(f, "mix", 0xFFFFFFFF);
184 C_ROOTBG = getcolor(f, "root", 0xFFFFFFFF);
185 C_BORDER = getcolor(f, "border", 0x000000FF);
186 C_TAGBG = getcolor(f, "tagbg", 0xAAFFFFFF);
187 C_TAGFG = getcolor(f, "tagfg", 0x000000FF);
188 C_TAGHLBG = getcolor(f, "htagbg", 0x9EEEEEFF);
189 C_TAGHLFG = getcolor(f, "htagfg", 0x000000FF);
190 C_TXTBG = getcolor(f, "txtbg", 0xFFFFAAFF);
191 C_TXTFG = getcolor(f, "txtfg", 0x000000FF);
192 C_TXTHLBG = getcolor(f, "htxtbg", 0xEEEE9EFF);
193 C_TXTHLFG = getcolor(f, "htxtfg", 0x000000FF);
194 C_WINBUTTON = getcolor(f, "winbtn", 0x8888CCFF);
195 C_WINBTNBORDER = getcolor(f, "winbtnbord", 0x8888CCFF);
196 C_COLBUTTON = getcolor(f, "colbtn", 0x8888CCFF);
197 C_TMPBUTTON = getcolor(f, "tmpbtn", 0x000099FF);
198 C_SCROLLBG = getcolor(f, "scrlbg", 0x99994CFF);
199 C_SCROLLFG = getcolor(f, "scrlfg", 0xFFFFAAFF);
200 C_SCROLLBORDER = getcolor(f, "scrlbord", 0x99994CFF);
201 C_BUTTON2HL = getcolor(f, "btn2hl", 0xAA0000FF);
202 C_BUTTON3HL = getcolor(f, "btn3hl", 0x006600FF);
203 C_SCROLLTILEFG = getcolor(f, "scrolltilefg", 0x000000FF);
204 C_SCROLLTILEBG = getcolor(f, "scrolltilebg", 0xFFFFFFFF);
205 C_COLBTNTILEFG = getcolor(f, "colbtntilefg", 0xFFFFFFFF);
206 C_COLBTNTILEBG = getcolor(f, "colbtntilebg", 0x000000FF);
207
208 mainfont = parsekeyvalue(f, "mainfont", "/lib/font/bit/lucsans/euro.8.font");
209 monofont = parsekeyvalue(f, "monofont", "/lib/font/bit/lucm/unicode.9.font");
210 dumppath = parsekeyvalue(f, "dumppath", "/tmp/acme.dump");
211 acmeshell = parsekeyvalue(f, "shell", "/usr/local/plan9/bin/rc");
212
213 free(fontnames[0]);
214 free(fontnames[1]);
215 fontnames[0] = strdup(mainfont);
216 fontnames[1] = strdup(monofont);
217
218 globalautoindent = getboolean(parsekeyvalue(f, "autoindent", "yes"), 1);
219 swapscrollbuttons = getboolean(parsekeyvalue(f, "swpscrlbtns", "no"), 0);
220 bartflag = getboolean(parsekeyvalue(f, "clicktofocus", "no"), 0);
221 ncol = getintvalue(f, "colcount", 2);
222 openarg = getboolean(parsekeyvalue(f, "openarg", "yes"), 1);
223 showdotfiles = getboolean(parsekeyvalue(f, "showdotfiles", "yes"), 1);
224 ncolnrow = getboolean(parsekeyvalue(f, "newcolnewrow", "yes"), 1);
225
226 fclose(f);
227}