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}