Cleaned up samrc parsing code. - sam - An updated version of the sam text editor.
(HTM) git clone git://vernunftzentrum.de/sam.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
(DIR) commit 41933571a81e6e8d174bdbcc39662ee8f1b81088
(DIR) parent f30a2c98826775afa72b1e7dab7cac14ece9e8dc
(HTM) Author: Rob King <jking@deadpixi.com>
Date: Sat, 10 Sep 2016 16:47:38 -0500
Cleaned up samrc parsing code.
Diffstat:
samterm/samrc.c | 189 +++++++++++++++++++++++++------
1 file changed, 152 insertions(+), 37 deletions(-)
---
(DIR) diff --git a/samterm/samrc.c b/samterm/samrc.c
@@ -209,6 +209,144 @@ statetomask(const char *n, Namemapping *m)
return r;
}
+static int
+dirchord(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ return installchord(statetomask(s1, buttonmapping), statetomask(s2, buttonmapping), nametocommand(s3), nametotarget(s4));
+}
+
+static int
+dirraw(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ return installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kraw, strtol(s3, NULL, 16));
+}
+
+static int
+dircomposed(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ return installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcomposed, strtol(s3, NULL, 16));
+}
+
+static int
+dirrawliteral(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ if (strlen(s3) != 1)
+ return -1;
+ return installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kraw, s3[0]);
+}
+
+static int
+dircomposedliteral(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ if (strlen(s3) != 1)
+ return -1;
+ return installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcomposed, s3[0]);
+}
+
+static int
+dirbind(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ return installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcommand, nametocommand(s3));
+}
+
+static int
+dirunbind(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ return removebinding(statetomask(s1, modmapping), XStringToKeysym(s2));
+}
+
+static int
+dirunchord(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ return removechord(statetomask(s1, buttonmapping), statetomask(s2, buttonmapping));
+}
+
+static int
+dirforeground(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ if (strlen(s1) == 0)
+ return -1;
+
+ strncpy(foregroundspec, s1, sizeof(foregroundspec) - 1);
+ return 0;
+}
+
+static int
+dirbackground(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ if (strlen(s1) == 0)
+ return -1;
+
+ strncpy(backgroundspec, s1, sizeof(backgroundspec) - 1);
+ return 0;
+}
+
+static int
+dirborder(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ if (strlen(s1) == 0)
+ return -1;
+
+ strncpy(borderspec, s1, sizeof(borderspec) - 1);
+ return 0;
+}
+
+static int
+dirfont(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ if (strlen(s1) == 0)
+ return -1;
+
+ strncpy(fontspec, s1, sizeof(fontspec) - 1);
+ return 0;
+}
+
+static int
+dirtabs(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ int i = atoi(s1);
+ if (i <= 0 || i > 12)
+ return -1;
+
+ tabwidth = i;
+ return 0;
+}
+
+static int
+direxpandtabs(const char *s1, const char *s2, const char *s3, const char *s4)
+{
+ if (strcasecmp(s1, "true") != 0 && strcasecmp(s1, "false") != 0)
+ return -1;
+
+ expandtabs = (strcasecmp(s1, "true") == 0);
+ return 0;
+}
+
+typedef struct Directive Directive;
+struct Directive{
+ const char *format;
+ int result;
+ int (*action)(const char *, const char *, const char *, const char *);
+};
+
+Directive directives[] ={
+ {" chord %5[Nn12345] %5[Nn12345] %99s %99s", 4, dirchord},
+ {" unchord %5[Nn12345] %5[Nn12345]", 2, dirunchord},
+ {" bind %5[*camshNCAMSH12345] %99s raw 0x%4[0-9a-fA-F]", 3, dirraw},
+ {" bind %5[*camshNCAMSH12345] %99s composed 0x%4[0-9a-fA-F]", 3, dircomposed},
+ {" bind %5[*camshNCAMSH12345] %99s raw %1s", 3, dirrawliteral},
+ {" bind %5[*camshNCAMSH12345] %99s composed %1s", 3, dircomposedliteral},
+ {" bind %5[*camshNCAMSH12345] %99s command %99s", 3, dirbind},
+ {" unbind %5[*camshNCAMSH12345] %99s", 2, dirunbind},
+ {" foreground %1023s", 1, dirforeground},
+ {" background %1023s", 1, dirbackground},
+ {" border %1023s", 1, dirborder},
+ {" font %1023s", 1, dirfont},
+ {" tabs %2[0-9]", 1, dirtabs},
+ {" expandtabs %99s", 1, direxpandtabs},
+ {NULL, 0, NULL}
+};
+
void
loadrcfile(FILE *f)
{
@@ -218,48 +356,25 @@ loadrcfile(FILE *f)
size_t ln = 0;
while ((r = getline(&l, &n, f)) >= 0){
- char s1[100] = {0};
- char s2[100] = {0};
- char cname[1024] = {0};
- char tname[1024] = {0};
- char c = 0;
- unsigned short s = 0;
+ char s1[1024] = {0};
+ char s2[1024] = {0};
+ char s3[1024] = {0};
+ char s4[1024] = {0};
int rc = 0;
- int i = 0;
+ bool found = false;
ln++;
- if (r == 0 || l[0] == '\n' || l[0] == 0 || sscanf(l, " %[#]", &c) == 1)
+ if (r == 0 || l[0] == '\n' || l[0] == 0 || sscanf(l, " %1[#]", s1) == 1)
continue;
- if (sscanf(l, " chord %5[Nn12345] %5[Nn12345] %99s %99s", s1, s2, cname, tname) == 4)
- rc = installchord(statetomask(s1, buttonmapping), statetomask(s2, buttonmapping), nametocommand(cname), nametotarget(tname));
- else if (sscanf(l, " bind %5[*camshNCAMSH12345] %99s raw 0x%hx", s1, s2, &s) == 3)
- rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kraw, i);
- else if (sscanf(l, " bind %5[*camshNCAMSH12345] %99s composed 0x%hx", s1, s2, &s) == 3)
- rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcomposed, i);
- else if (sscanf(l, " bind %5[*camshNCAMSH12345] %99s raw %c", s1, s2, &c) == 3)
- rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kraw, c);
- else if (sscanf(l, " bind %5[*camshNCAMSH12345] %99s composed %c", s1, s2, &c) == 3)
- rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcomposed, c);
- else if (sscanf(l, " bind %5[*camshNCAMSH12345] %99s command %99s", s1, s2, cname) == 3)
- rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcommand, nametocommand(cname));
- else if (sscanf(l, " unbind %5[*camshNCAMSH12345] %99s", s1, s2) == 2)
- rc = removebinding(statetomask(s1, modmapping), XStringToKeysym(s2));
- else if (sscanf(l, " unchord %5[Nn12345] %5[Nn12345]", s1, s2) == 2)
- rc = removechord(statetomask(s1, buttonmapping), statetomask(s2, buttonmapping));
- else if (sscanf(l, " foreground %1023s", cname) == 1)
- strncpy(foregroundspec, cname, sizeof(foregroundspec) - 1);
- else if (sscanf(l, " background %1023s", cname) == 1)
- strncpy(backgroundspec, cname, sizeof(backgroundspec) - 1);
- else if (sscanf(l, " border %1023s", cname) == 1)
- strncpy(borderspec, cname, sizeof(borderspec) - 1);
- else if (sscanf(l, " font %1023s", cname) == 1)
- strncpy(fontspec, cname, sizeof(fontspec) - 1);
- else if (sscanf(l, " tabs %hu", &s) == 1 && s < 12 && s > 0)
- tabwidth = s;
- else if (sscanf(l, " expandtabs%n", &i) == 0 && i)
- expandtabs = 1;
- else
+ for (Directive *d = directives; d->format && !found; d++){
+ if (sscanf(l, d->format, s1, s2, s3, s4) == d->result){
+ rc = d->action(s1, s2, s3, s4);
+ found = true;
+ }
+ }
+
+ if (!found)
fprintf(stderr, "invalid rc line %zd\n", ln);
if (rc != 0)