Skip to content
Browse files

config: generate much of the config code from a concise descriptions …

…file
  • Loading branch information...
1 parent d86249c commit de4ae6080ee9c952fe1cefd4f8a57d4d714d8036 ec429 committed Apr 6, 2011
Showing with 943 additions and 340 deletions.
  1. +1 −0 .gitignore
  2. +12 −9 Makefile
  3. +7 −5 README
  4. +8 −109 config.c
  5. +10 −0 config.cdl
  6. +2 −9 config.h
  7. +40 −0 config_check.c
  8. +11 −0 config_def.c
  9. +11 −0 config_globals.h
  10. +14 −0 config_need.c
  11. +27 −0 config_pargs.c
  12. +86 −0 config_rcread.c
  13. +179 −0 config_set.c
  14. +514 −0 genconfig.c
  15. +1 −204 input.c
  16. +2 −0 quirc.c
  17. +6 −4 readme.htm
  18. +12 −0 spec-cdl
View
1 .gitignore
@@ -4,5 +4,6 @@ quirc
*.tar
*.tar.gz
*.tgz
+genconfig
version.h
version
View
21 Makefile
@@ -18,18 +18,13 @@ uninstall:
rm $(PREFIX)/bin/quirc
quirc: quirc.c $(LIBS) $(INCLUDE)
- $(CC) $(CFLAGS) $(CPPFLAGS) -o quirc quirc.c $(LIBS) -lm $(DEFINES)
-
-mtrace: quirc-mtrace
-
-quirc-mtrace: quirc.c $(LIBS) $(INCLUDE)
- $(CC) $(CFLAGS) $(CPPFLAGS) -o quirc-mtrace quirc.c $(LIBS) -lm -g -DUSE_MTRACE $(DEFINES)
+ $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $< $(LIBS) -lm $(DEFINES)
clean:
rm *.o quirc
realclean: clean
- rm c_init.c README version.h
+ rm c_init.c README version.h config_*
doc: README
@@ -51,9 +46,17 @@ colour.o: colour.c colour.h c_init.c ttyesc.h
buffer.o: buffer.c buffer.h ttyesc.h colour.h bits.h names.h text.h irc.h config.h version.h input.h
-config.o: config.c config.h names.h bits.h colour.h text.h version.h
+config.o: config.c config_check.c config_def.c config_need.c config_rcread.c config_pargs.c config.h config_globals.h names.h bits.h colour.h text.h version.h
+
+config_%.c: config.cdl genconfig
+ ./genconfig $@ < config.cdl > $@ || (rm $@ && false)
+
+config_%.h: config.cdl genconfig
+ ./genconfig $@ < config.cdl > $@ || (rm $@ && false)
+
+genconfig: genconfig.c
-input.o: input.c input.h ttyesc.h names.h buffer.h irc.h bits.h
+input.o: input.c config_set.c input.h ttyesc.h names.h buffer.h irc.h bits.h
names.o: names.c names.h buffer.h irc.h
View
12 README
@@ -134,14 +134,16 @@ buf buf-lines
the default being 256. Larger values will, of course, increase memory
consumption.
You can turn on a few display options too;
-fwc 1
-hts 1
-tsb 1
+fwc
+hts
+tsb
will turn on Full-Width-Colour (makes coloured backgrounds for lines (eg. /me)
run all the way across the terminal), Highlight-Tab-Strip (gives the tab strip
a magenta background, to make it more visible) and Top-Status-Bar (uses the top
-line of the terminal for some status information). To turn them off replace the
-1 with a 0. By default fwc and hts are turned off; tsb is turned on.
+line of the terminal for some status information). To turn them off prefix them
+with no-, like
+no-hts
+By default fwc and hts are turned off; tsb is turned on.
These settings and others can be overridden at runtime with commandline
options. For details run &quot;quirc --help&quot;.
You can also customise the colours quIRC uses. A custom colour line starts with
View
117 config.c
@@ -8,31 +8,15 @@
#include "config.h"
+#include "config_check.c"
+
int def_config(void)
{
- buflines=256;
- mirc_colour_compat=1; // silently strip
- force_redraw=2;
- full_width_colour=false;
- hilite_tabstrip=false;
- tsb=true; // show top status bar
+#include "config_def.c"
autojoin=true;
char *cols=getenv("COLUMNS"), *rows=getenv("LINES");
if(cols) sscanf(cols, "%u", &width);
if(rows) sscanf(rows, "%u", &height);
- if(!width) width=80;
- if(!height) height=24;
- if(width<30)
- {
- width=30;
- printf("width set to minimum 30\n");
- }
- if(height<5)
- {
- height=5;
- printf("height set to minimum 5\n");
- }
- maxnlen=16;
servs=NULL;
igns=NULL;
portno=strdup("6667");
@@ -41,7 +25,6 @@ int def_config(void)
nick=strdup("ac");
sprintf(fname, "quIRC %hhu.%hhu.%hhu%s%s : http://github.com/ec429/quIRC", VERSION_MAJ, VERSION_MIN, VERSION_REV, VERSION_TXT[0]?"-":"", VERSION_TXT);
sprintf(version, "%hhu.%hhu.%hhu%s%s", VERSION_MAJ, VERSION_MIN, VERSION_REV, VERSION_TXT[0]?"-":"", VERSION_TXT);
- tping=30;
#ifdef HAVE_DEBUG
debug=0;
#endif // HAVE_DEBUG
@@ -140,7 +123,9 @@ int rcread(FILE *rcfp)
else
{
char *rest=strtok(NULL, "");
- if(!rest)
+ bool need=true;
+#include "config_need.c"
+ if(need&&!rest)
{
char msg[40+strlen(cmd)];
sprintf(msg, "rc: Command (%s) without argument", cmd);
@@ -292,34 +277,7 @@ int rcread(FILE *rcfp)
new->igns=NULL;
servs->chans=new;
}
- else if(strcmp(cmd, "mnln")==0)
- sscanf(rest, "%u", &maxnlen);
- else if(strcmp(cmd, "mcc")==0)
- sscanf(rest, "%u", &mirc_colour_compat);
- else if(strcmp(cmd, "fwc")==0)
- {
- unsigned int fwc;
- sscanf(rest, "%u", &fwc);
- full_width_colour=fwc;
- }
- else if(strcmp(cmd, "hts")==0)
- {
- unsigned int hts;
- sscanf(rest, "%u", &hts);
- hilite_tabstrip=hts;
- }
- else if(strcmp(cmd, "tsb")==0)
- {
- unsigned int ntsb;
- sscanf(rest, "%u", &ntsb);
- tsb=ntsb;
- }
- else if(strcmp(cmd, "fred")==0)
- sscanf(rest, "%u", &force_redraw);
- else if(strcmp(cmd, "buf")==0)
- sscanf(rest, "%u", &buflines);
- else if(strcmp(cmd, "tping")==0)
- sscanf(rest, "%u", &tping);
+#include "config_rcread.c"
#ifdef HAVE_DEBUG
else if(strcmp(cmd, "debug")==0)
sscanf(rest, "%u", &debug);
@@ -353,64 +311,6 @@ signed int pargs(int argc, char *argv[])
fprintf(stderr, VERSION_MSG);
return(0);
}
- else if(strncmp(argv[arg], "--width=", 8)==0) // just in case you need to force them
- {
- sscanf(argv[arg]+8, "%u", &width);
- if(width<30)
- {
- width=30;
- asb_failsafe(c_status, "pargs: width set to minimum 30");
- }
- }
- else if(strncmp(argv[arg], "--height=", 9)==0)
- {
- sscanf(argv[arg]+9, "%u", &height);
- if(height<5)
- {
- height=5;
- asb_failsafe(c_status, "pargs: height set to minimum 5");
- }
- }
- else if(strncmp(argv[arg], "--maxnicklen=", 13)==0)
- {
- sscanf(argv[arg]+13, "%u", &maxnlen);
- }
- else if(strncmp(argv[arg], "--mcc=", 6)==0)
- {
- sscanf(argv[arg]+6, "%u", &mirc_colour_compat);
- }
- else if(strcmp(argv[arg], "--fwc")==0)
- {
- full_width_colour=true;
- }
- else if(strcmp(argv[arg], "--no-fwc")==0)
- {
- full_width_colour=false;
- }
- else if(strcmp(argv[arg], "--hts")==0)
- {
- hilite_tabstrip=true;
- }
- else if(strcmp(argv[arg], "--no-hts")==0)
- {
- hilite_tabstrip=false;
- }
- else if(strcmp(argv[arg], "--tsb")==0)
- {
- tsb=true;
- }
- else if(strcmp(argv[arg], "--no-tsb")==0)
- {
- tsb=false;
- }
- else if(strncmp(argv[arg], "--force-redraw=", 15)==0)
- {
- sscanf(argv[arg]+15, "%u", &force_redraw);
- }
- else if(strncmp(argv[arg], "--buf-lines=", 12)==0)
- {
- sscanf(argv[arg]+12, "%u", &buflines);
- }
else if((strcmp(argv[arg], "--no-server")==0)||(strcmp(argv[arg], "--no-auto-connect")==0)) // the "-auto" forms are from older versions; depr
{
freeservlist(servs);
@@ -467,14 +367,13 @@ signed int pargs(int argc, char *argv[])
new->igns=NULL;
servs->chans=new;
}
- else if(strncmp(argv[arg], "--tping=", 8)==0)
- sscanf(argv[arg]+8, "%u", &tping);
#ifdef HAVE_DEBUG
else if(strncmp(argv[arg], "--debug=", 8)==0)
sscanf(argv[arg]+8, "%u", &debug);
else if(strcmp(argv[arg], "--debug")==0)
debug=1;
#endif // HAVE_DEBUG
+#include "config_pargs.c"
else
{
char msg[40+strlen(argv[arg])];
View
10 config.cdl
@@ -0,0 +1,10 @@
+int:width:80:30:::width:width:S:display width
+int:height:24:5:::height:height:S:display height
+int:mirc_colour_compat:1:0:2:mcc:mcc:mcc:L:mirc colour compatibility
+int:force_redraw:2:0:3:fred:fred:fred:L:force-redraw
+int:buflines:256:32::buf:buf-lines:buf:S:buffer lines
+int:maxnlen:16:4::mnln:maxnicklen:mnln:S:max nick length
+bool:full_width_colour:false:::fwc:fwc:fwc:B:full width colour
+bool:hilite_tabstrip:false:::hts:hts:hts:B:highlight tabstrip
+bool:tsb:true:::tsb:tsb:tsb:B:top status bar
+int:tping:30:15::tping:tping:tping:S:outbound ping time
View
11 config.h
@@ -41,24 +41,17 @@ servlist;
#include "buffer.h"
// global settings & state
-unsigned int width, height; // term size
-unsigned int mirc_colour_compat;
-unsigned int force_redraw;
-unsigned int buflines;
-unsigned int maxnlen;
-bool full_width_colour;
-bool hilite_tabstrip;
-bool tsb; // top status bar
+#include "config_globals.h"
bool autojoin;
char *username, *fname, *nick, *portno;
servlist *servs;
name *igns;
-unsigned int tping; // ping timeout
#ifdef HAVE_DEBUG
unsigned int debug;
#endif // HAVE_DEBUG
char version[16+strlen(VERSION_TXT)];
+int conf_check(void); // writes diagnostics to start-buffer
int def_config(void); // set these to their defaults
int rcread(FILE *rcfp); // read & parse the rc file.
signed int pargs(int argc, char *argv[]); // parse the cmdline args. If return is >=0, main should return it also
View
40 config_check.c
@@ -0,0 +1,40 @@
+/* Generated by genconfig */
+int conf_check(void)
+{
+ if(width<30)
+ {
+ asb_failsafe(c_status, "width set to minimum 30");
+ width=30;
+ }
+ if(height<5)
+ {
+ asb_failsafe(c_status, "height set to minimum 5");
+ height=5;
+ }
+ if(mirc_colour_compat>2)
+ {
+ asb_failsafe(c_status, "mcc set to maximum 2");
+ mirc_colour_compat=2;
+ }
+ if(force_redraw>3)
+ {
+ asb_failsafe(c_status, "fred set to maximum 3");
+ force_redraw=3;
+ }
+ if(buflines<32)
+ {
+ asb_failsafe(c_status, "buf set to minimum 32");
+ buflines=32;
+ }
+ if(maxnlen<4)
+ {
+ asb_failsafe(c_status, "mnln set to minimum 4");
+ maxnlen=4;
+ }
+ if(tping<15)
+ {
+ asb_failsafe(c_status, "tping set to minimum 15");
+ tping=15;
+ }
+ return(0);
+}
View
11 config_def.c
@@ -0,0 +1,11 @@
+/* Generated by genconfig */
+ width=80;
+ height=24;
+ mirc_colour_compat=1;
+ force_redraw=2;
+ buflines=256;
+ maxnlen=16;
+ full_width_colour=-1;
+ hilite_tabstrip=-1;
+ tsb=-1;
+ tping=30;
View
11 config_globals.h
@@ -0,0 +1,11 @@
+/* Generated by genconfig */
+unsigned int width; // display width
+unsigned int height; // display height
+unsigned int mirc_colour_compat; // mirc colour compatibility
+unsigned int force_redraw; // force-redraw
+unsigned int buflines; // buffer lines
+unsigned int maxnlen; // max nick length
+bool full_width_colour; // full width colour
+bool hilite_tabstrip; // highlight tabstrip
+bool tsb; // top status bar
+unsigned int tping; // outbound ping time
View
14 config_need.c
@@ -0,0 +1,14 @@
+/* Generated by genconfig */
+ if(strcmp(cmd, "(null)")==0) need=false;
+ if(strcmp(cmd, "(null)")==0) need=false;
+ if(strcmp(cmd, "mcc")==0) need=false;
+ if(strcmp(cmd, "fred")==0) need=false;
+ if(strcmp(cmd, "buf")==0) need=false;
+ if(strcmp(cmd, "mnln")==0) need=false;
+ if(strcmp(cmd, "fwc")==0) need=false;
+ if(strcmp(cmd, "no-fwc")==0) need=false;
+ if(strcmp(cmd, "hts")==0) need=false;
+ if(strcmp(cmd, "no-hts")==0) need=false;
+ if(strcmp(cmd, "tsb")==0) need=false;
+ if(strcmp(cmd, "no-tsb")==0) need=false;
+ if(strcmp(cmd, "tping")==0) need=false;
View
27 config_pargs.c
@@ -0,0 +1,27 @@
+/* Generated by genconfig */
+ else if(strncmp(argv[arg], "--width=", 8)==0)
+ sscanf(argv[arg]+8, "%u", &width);
+ else if(strncmp(argv[arg], "--height=", 9)==0)
+ sscanf(argv[arg]+9, "%u", &height);
+ else if(strncmp(argv[arg], "--mcc=", 6)==0)
+ sscanf(argv[arg]+6, "%u", &mirc_colour_compat);
+ else if(strncmp(argv[arg], "--fred=", 7)==0)
+ sscanf(argv[arg]+7, "%u", &force_redraw);
+ else if(strncmp(argv[arg], "--buf-lines=", 12)==0)
+ sscanf(argv[arg]+12, "%u", &buflines);
+ else if(strncmp(argv[arg], "--maxnicklen=", 13)==0)
+ sscanf(argv[arg]+13, "%u", &maxnlen);
+ else if(strcmp(argv[arg], "--fwc")==0)
+ full_width_colour=true;
+ else if(strcmp(argv[arg], "--no-fwc")==0)
+ full_width_colour=false;
+ else if(strcmp(argv[arg], "--hts")==0)
+ hilite_tabstrip=true;
+ else if(strcmp(argv[arg], "--no-hts")==0)
+ hilite_tabstrip=false;
+ else if(strcmp(argv[arg], "--tsb")==0)
+ tsb=true;
+ else if(strcmp(argv[arg], "--no-tsb")==0)
+ tsb=false;
+ else if(strncmp(argv[arg], "--tping=", 8)==0)
+ sscanf(argv[arg]+8, "%u", &tping);
View
86 config_rcread.c
@@ -0,0 +1,86 @@
+/* Generated by genconfig */
+ else if(strcmp(cmd, "mcc")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ mirc_colour_compat=value;
+ else
+ {
+ asb_failsafe(c_err, "Malformed rc entry for mcc (value not numeric)");
+ asb_failsafe(c_err, rest);
+ }
+ }
+ else if(strcmp(cmd, "fred")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ force_redraw=value;
+ else
+ {
+ asb_failsafe(c_err, "Malformed rc entry for fred (value not numeric)");
+ asb_failsafe(c_err, rest);
+ }
+ }
+ else if(strcmp(cmd, "buf")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ buflines=value;
+ else
+ {
+ asb_failsafe(c_err, "Malformed rc entry for buf (value not numeric)");
+ asb_failsafe(c_err, rest);
+ }
+ }
+ else if(strcmp(cmd, "mnln")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ maxnlen=value;
+ else
+ {
+ asb_failsafe(c_err, "Malformed rc entry for mnln (value not numeric)");
+ asb_failsafe(c_err, rest);
+ }
+ }
+ else if(strcmp(cmd, "no-fwc")==0)
+ full_width_colour=false;
+ else if(strcmp(cmd, "fwc")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ full_width_colour=value;
+ else
+ full_width_colour=true;
+ }
+ else if(strcmp(cmd, "no-hts")==0)
+ hilite_tabstrip=false;
+ else if(strcmp(cmd, "hts")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ hilite_tabstrip=value;
+ else
+ hilite_tabstrip=true;
+ }
+ else if(strcmp(cmd, "no-tsb")==0)
+ tsb=false;
+ else if(strcmp(cmd, "tsb")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ tsb=value;
+ else
+ tsb=true;
+ }
+ else if(strcmp(cmd, "tping")==0)
+ {
+ unsigned int value;
+ if(rest&&sscanf(rest, "%u", &value))
+ tping=value;
+ else
+ {
+ asb_failsafe(c_err, "Malformed rc entry for tping (value not numeric)");
+ asb_failsafe(c_err, rest);
+ }
+ }
View
179 config_set.c
@@ -0,0 +1,179 @@
+/* Generated by genconfig */
+ if(strcmp(opt, "width")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ width=value;
+ }
+ else
+ width=80;
+ char smsg[37];
+ sprintf(smsg, "display width set to %u", width);
+ add_to_buffer(cbuf, c_status, smsg, "/set: ");
+ }
+ else if(strcmp(opt, "height")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ height=value;
+ }
+ else
+ height=24;
+ char smsg[38];
+ sprintf(smsg, "display height set to %u", height);
+ add_to_buffer(cbuf, c_status, smsg, "/set: ");
+ }
+ else if(strcmp(opt, "mcc")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ mirc_colour_compat=value;
+ }
+ else
+ mirc_colour_compat=1;
+ if(mirc_colour_compat)
+ {
+ char lmsg[57];
+ sprintf(lmsg, "mirc colour compatibility level %u enabled", mirc_colour_compat);
+ add_to_buffer(cbuf, c_status, lmsg, "/set: ");
+ }
+ else
+ add_to_buffer(cbuf, c_status, "mirc colour compatibility disabled", "/set: ");
+ }
+ else if(strcmp(opt, "no-mcc")==0)
+ {
+ mirc_colour_compat=0;
+ add_to_buffer(cbuf, c_status, "mirc colour compatibility disabled", "/set: ");
+ }
+ else if(strcmp(opt, "fred")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ force_redraw=value;
+ }
+ else
+ force_redraw=2;
+ if(force_redraw)
+ {
+ char lmsg[44];
+ sprintf(lmsg, "force-redraw level %u enabled", force_redraw);
+ add_to_buffer(cbuf, c_status, lmsg, "/set: ");
+ }
+ else
+ add_to_buffer(cbuf, c_status, "force-redraw disabled", "/set: ");
+ }
+ else if(strcmp(opt, "no-fred")==0)
+ {
+ force_redraw=0;
+ add_to_buffer(cbuf, c_status, "force-redraw disabled", "/set: ");
+ }
+ else if(strcmp(opt, "buf")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ buflines=value;
+ }
+ else
+ buflines=256;
+ char smsg[36];
+ sprintf(smsg, "buffer lines set to %u", buflines);
+ add_to_buffer(cbuf, c_status, smsg, "/set: ");
+ }
+ else if(strcmp(opt, "mnln")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ maxnlen=value;
+ }
+ else
+ maxnlen=16;
+ char smsg[39];
+ sprintf(smsg, "max nick length set to %u", maxnlen);
+ add_to_buffer(cbuf, c_status, smsg, "/set: ");
+ }
+ else if(strcmp(opt, "fwc")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ full_width_colour=value;
+ }
+ else
+ full_width_colour=-1;
+ if(full_width_colour)
+ add_to_buffer(cbuf, c_status, "full width colour enabled", "/set: ");
+ else
+ add_to_buffer(cbuf, c_status, "full width colour disabled", "/set: ");
+ }
+ else if(strcmp(opt, "no-fwc")==0)
+ {
+ full_width_colour=0;
+ add_to_buffer(cbuf, c_status, "full width colour disabled", "/set: ");
+ }
+ else if(strcmp(opt, "hts")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ hilite_tabstrip=value;
+ }
+ else
+ hilite_tabstrip=-1;
+ if(hilite_tabstrip)
+ add_to_buffer(cbuf, c_status, "highlight tabstrip enabled", "/set: ");
+ else
+ add_to_buffer(cbuf, c_status, "highlight tabstrip disabled", "/set: ");
+ }
+ else if(strcmp(opt, "no-hts")==0)
+ {
+ hilite_tabstrip=0;
+ add_to_buffer(cbuf, c_status, "highlight tabstrip disabled", "/set: ");
+ }
+ else if(strcmp(opt, "tsb")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ tsb=value;
+ }
+ else
+ tsb=-1;
+ if(tsb)
+ add_to_buffer(cbuf, c_status, "top status bar enabled", "/set: ");
+ else
+ add_to_buffer(cbuf, c_status, "top status bar disabled", "/set: ");
+ }
+ else if(strcmp(opt, "no-tsb")==0)
+ {
+ tsb=0;
+ add_to_buffer(cbuf, c_status, "top status bar disabled", "/set: ");
+ }
+ else if(strcmp(opt, "tping")==0)
+ {
+ if(val)
+ {
+ unsigned int value;
+ sscanf(val, "%u", &value);
+ tping=value;
+ }
+ else
+ tping=30;
+ char smsg[42];
+ sprintf(smsg, "outbound ping time set to %u", tping);
+ add_to_buffer(cbuf, c_status, smsg, "/set: ");
+ }
View
514 genconfig.c
@@ -0,0 +1,514 @@
+/*
+ quIRC - simple terminal-based IRC client
+ Copyright (C) 2010-11 Edward Cree
+
+ See quirc.c for license information
+ genconfig.c: generate various bits of config-parsing code from a cdl file
+*/
+
+// TODO: refactor this quite a lot, it's a mess
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+
+typedef struct
+{
+ enum {INT, BOOL} type;
+ char *cname;
+ int value;
+ int min,max;
+ char *rc_name;
+ char *cmdline_name;
+ char *set_name;
+ char *set_msg;
+ enum {SET, LEVEL, BOOLEAN} set_type;
+}
+ent;
+
+char * fgetl(FILE *); // gets a line of string data; returns a malloc-like pointer
+void init_char(char **buf, int *l, int *i); // initialises a string buffer in heap. *buf becomes a malloc-like pointer
+void append_char(char **buf, int *l, int *i, char c); // adds a character to a string buffer in heap (and realloc()s if needed)
+
+int main(int argc, char **argv)
+{
+ if(argc!=2)
+ {
+ fprintf(stderr, "usage: genconfig <outtype>\n");
+ return(EXIT_FAILURE);
+ }
+ int otype;
+ if(strcmp(argv[1], "config_globals.h")==0)
+ otype=0;
+ else if(strcmp(argv[1], "config_check.c")==0)
+ otype=1;
+ else if(strcmp(argv[1], "config_def.c")==0)
+ otype=2;
+ else if(strcmp(argv[1], "config_rcread.c")==0)
+ otype=3;
+ else if(strcmp(argv[1], "config_pargs.c")==0)
+ otype=4;
+ else if(strcmp(argv[1], "config_set.c")==0)
+ otype=5;
+ else if(strcmp(argv[1], "config_need.c")==0)
+ otype=6;
+ else
+ {
+ fprintf(stderr, "genconfig: unrecognised outtype '%s'\n", argv[1]);
+ return(EXIT_FAILURE);
+ }
+ int nents=0;
+ ent *ents=NULL;
+ while(!feof(stdin))
+ {
+ char *line=fgetl(stdin);
+ if(!*line)
+ {
+ free(line);
+ continue;
+ }
+ int nent=nents++;
+ ents=realloc(ents, nents*sizeof(ent));
+ if(!ents)
+ {
+ perror("genconfig: realloc");
+ return(EXIT_FAILURE);
+ }
+ char *p=line;
+ int tocolon=strcspn(p, ":");
+ if(strncmp(p, "int", tocolon)==0)
+ ents[nent].type=INT;
+ else if(strncmp(p, "bool", tocolon)==0)
+ ents[nent].type=BOOL;
+ else
+ {
+ fprintf(stderr, "genconfig: unrecognised type %.*s\n", tocolon, p);
+ return(EXIT_FAILURE);
+ }
+ p+=tocolon;
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u\n", nents);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ ents[nent].cname=malloc(tocolon+1);
+ if(!ents[nent].cname)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(ents[nent].cname, p, tocolon);
+ ents[nent].cname[tocolon]=0;
+ p+=tocolon;
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(tocolon)
+ {
+ char *value=malloc(tocolon+1);
+ if(!value)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(value, p, tocolon);
+ value[tocolon]=0;
+ if(!sscanf(value, "%d", &ents[nent].value)) ents[nent].value=-1;
+ free(value);
+ p+=tocolon;
+ }
+ else
+ {
+ ents[nent].value=-1;
+ }
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(tocolon)
+ {
+ char *min=malloc(tocolon+1);
+ if(!min)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(min, p, tocolon);
+ min[tocolon]=0;
+ if(!sscanf(min, "%d", &ents[nent].min)) ents[nent].min=-1;
+ free(min);
+ p+=tocolon;
+ }
+ else
+ {
+ ents[nent].min=-1;
+ }
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(tocolon)
+ {
+ char *max=malloc(tocolon+1);
+ if(!max)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(max, p, tocolon);
+ max[tocolon]=0;
+ if(!sscanf(max, "%d", &ents[nent].max)) ents[nent].max=-1;
+ free(max);
+ p+=tocolon;
+ }
+ else
+ {
+ ents[nent].max=-1;
+ }
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(tocolon)
+ {
+ ents[nent].rc_name=malloc(tocolon+1);
+ if(!ents[nent].rc_name)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(ents[nent].rc_name, p, tocolon);
+ ents[nent].rc_name[tocolon]=0;
+ p+=tocolon;
+ }
+ else
+ {
+ ents[nent].rc_name=NULL;
+ }
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(tocolon)
+ {
+ ents[nent].cmdline_name=malloc(tocolon+1);
+ if(!ents[nent].cmdline_name)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(ents[nent].cmdline_name, p, tocolon);
+ ents[nent].cmdline_name[tocolon]=0;
+ p+=tocolon;
+ }
+ else
+ {
+ ents[nent].cmdline_name=NULL;
+ }
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(tocolon)
+ {
+ ents[nent].set_name=malloc(tocolon+1);
+ if(!ents[nent].set_name)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(ents[nent].set_name, p, tocolon);
+ ents[nent].set_name[tocolon]=0;
+ p+=tocolon;
+ }
+ else
+ {
+ ents[nent].set_name=NULL;
+ }
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(strncmp(p, "SET", tocolon)==0)
+ ents[nent].set_type=SET;
+ else if(strncmp(p, "LEVEL", tocolon)==0)
+ ents[nent].set_type=LEVEL;
+ else if(strncmp(p, "BOOLEAN", tocolon)==0)
+ ents[nent].set_type=BOOLEAN;
+ else
+ {
+ fprintf(stderr, "genconfig: unrecognised set_type %.*s in line %u (%s)\n", tocolon, p, nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p+=tocolon;
+ if(!*p)
+ {
+ fprintf(stderr, "genconfig: premature end of line %u (%s)\n", nents, ents[nent].cname);
+ return(EXIT_FAILURE);
+ }
+ p++;tocolon=strcspn(p, ":");
+ if(tocolon)
+ {
+ ents[nent].set_msg=malloc(tocolon+1);
+ if(!ents[nent].set_msg)
+ {
+ perror("genconfig: malloc");
+ return(EXIT_FAILURE);
+ }
+ strncpy(ents[nent].set_msg, p, tocolon);
+ ents[nent].set_msg[tocolon]=0;
+ }
+ else
+ {
+ ents[nent].set_msg=NULL;
+ }
+ free(line);
+ }
+ printf("/* Generated by genconfig */\n");
+ switch(otype)
+ {
+ case 1:
+ printf("int conf_check(void)\n{\n");
+ break;
+ }
+ int i;
+ bool first=true;
+ for(i=0;i<nents;i++)
+ {
+ switch(otype)
+ {
+ case 0:
+ switch(ents[i].type)
+ {
+ case INT:
+ printf("unsigned int ");
+ break;
+ case BOOL:
+ printf("bool ");
+ break;
+ default:
+ fprintf(stderr, "Unsupported type %d in %s\n", ents[i].type, ents[i].cname);
+ return(EXIT_FAILURE);
+ }
+ printf("%s; // %s\n", ents[i].cname, ents[i].set_msg);
+ break;
+ case 1:
+ switch(ents[i].type)
+ {
+ case INT:
+ if(ents[i].min>0)
+ {
+ printf("\tif(%s<%d)\n\t{\n\t\tasb_failsafe(c_status, \"%s set to minimum %d\");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].min, ents[i].set_name, ents[i].min, ents[i].cname, ents[i].min);
+ }
+ if(ents[i].max!=-1)
+ {
+ printf("\tif(%s>%d)\n\t{\n\t\tasb_failsafe(c_status, \"%s set to maximum %d\");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].max, ents[i].set_name, ents[i].max, ents[i].cname, ents[i].max);
+ }
+ break;
+ case BOOL:
+ break;
+ default:
+ fprintf(stderr, "Unsupported type %d in %s\n", ents[i].type, ents[i].cname);
+ return(EXIT_FAILURE);
+ }
+ break;
+ case 2:
+ printf("\t%s=%d;\n", ents[i].cname, ents[i].value);
+ break;
+ case 3:
+ if(ents[i].rc_name)
+ {
+ switch(ents[i].type)
+ {
+ case BOOL:
+ printf("\t\t\telse if(strcmp(cmd, \"no-%s\")==0)\n", ents[i].rc_name);
+ printf("\t\t\t\t%s=false;\n", ents[i].cname);
+ case INT:
+ printf("\t\t\telse if(strcmp(cmd, \"%s\")==0)\n", ents[i].rc_name);
+ printf("\t\t\t{\n");
+ printf("\t\t\t\tunsigned int value;\n");
+ printf("\t\t\t\tif(rest&&sscanf(rest, \"%%u\", &value))\n");
+ printf("\t\t\t\t\t%s=value;\n", ents[i].cname);
+ printf("\t\t\t\telse\n");
+ if(ents[i].type==BOOL)
+ printf("\t\t\t\t\t%s=true;\n", ents[i].cname);
+ else
+ {
+ printf("\t\t\t\t{\n");
+ printf("\t\t\t\t\tasb_failsafe(c_err, \"Malformed rc entry for %s (value not numeric)\");\n", ents[i].rc_name);
+ printf("\t\t\t\t\tasb_failsafe(c_err, rest);\n");
+ printf("\t\t\t\t}\n");
+ }
+ printf("\t\t\t}\n");
+ break;
+ default:
+ fprintf(stderr, "Unsupported type %d in %s\n", ents[i].type, ents[i].cname);
+ return(EXIT_FAILURE);
+ }
+ }
+ break;
+ case 4:
+ if(ents[i].cmdline_name)
+ {
+ switch(ents[i].type)
+ {
+ case BOOL:
+ printf("\t\telse if(strcmp(argv[arg], \"--%s\")==0)\n", ents[i].cmdline_name);
+ printf("\t\t\t%s=true;\n", ents[i].cname);
+ printf("\t\telse if(strcmp(argv[arg], \"--no-%s\")==0)\n", ents[i].cmdline_name);
+ printf("\t\t\t%s=false;\n", ents[i].cname);
+ break;
+ case INT:
+ printf("\t\telse if(strncmp(argv[arg], \"--%s=\", %u)==0)\n", ents[i].cmdline_name, strlen(ents[i].cmdline_name)+3);
+ printf("\t\t\tsscanf(argv[arg]+%u, \"%%u\", &%s);\n", strlen(ents[i].cmdline_name)+3, ents[i].cname);
+ break;
+ }
+ }
+ break;
+ case 5:
+ if(ents[i].set_name)
+ {
+ printf("\t\t\t\t");
+ if(!first) printf("else ");
+ first=false;
+ printf( "if(strcmp(opt, \"%s\")==0)\n", ents[i].set_name);
+ printf("\t\t\t\t{\n");
+ printf("\t\t\t\t\tif(val)\n");
+ printf("\t\t\t\t\t{\n");
+ printf("\t\t\t\t\t\tunsigned int value;\n");
+ printf("\t\t\t\t\t\tsscanf(val, \"%%u\", &value);\n");
+ printf("\t\t\t\t\t\t%s=value;\n", ents[i].cname);
+ printf("\t\t\t\t\t}\n");
+ printf("\t\t\t\t\telse\n");
+ printf("\t\t\t\t\t\t%s=%d;\n", ents[i].cname, ents[i].value);
+ switch(ents[i].set_type)
+ {
+ case BOOLEAN:
+ printf("\t\t\t\t\tif(%s)\n", ents[i].cname);
+ printf("\t\t\t\t\t\tadd_to_buffer(cbuf, c_status, \"%s enabled\", \"/set: \");\n", ents[i].set_msg);
+ printf("\t\t\t\t\telse\n");
+ printf("\t\t\t\t\t\tadd_to_buffer(cbuf, c_status, \"%s disabled\", \"/set: \");\n", ents[i].set_msg);
+ break;
+ case LEVEL:
+ printf("\t\t\t\t\tif(%s)\n", ents[i].cname);
+ printf("\t\t\t\t\t{\n");
+ printf("\t\t\t\t\t\tchar lmsg[%u];\n", strlen(ents[i].set_msg)+32);
+ printf("\t\t\t\t\t\tsprintf(lmsg, \"%s level %%u enabled\", %s);\n", ents[i].set_msg, ents[i].cname);
+ printf("\t\t\t\t\t\tadd_to_buffer(cbuf, c_status, lmsg, \"/set: \");\n");
+ printf("\t\t\t\t\t}\n");
+ printf("\t\t\t\t\telse\n");
+ printf("\t\t\t\t\t\tadd_to_buffer(cbuf, c_status, \"%s disabled\", \"/set: \");\n", ents[i].set_msg);
+ break;
+ case SET:
+ printf("\t\t\t\t\tchar smsg[%u];\n", strlen(ents[i].set_msg)+24);
+ printf("\t\t\t\t\tsprintf(smsg, \"%s set to %%u\", %s);\n", ents[i].set_msg, ents[i].cname);
+ printf("\t\t\t\t\tadd_to_buffer(cbuf, c_status, smsg, \"/set: \");\n");
+ break;
+ }
+ printf("\t\t\t\t}\n");
+ if((ents[i].set_type==BOOLEAN)||(ents[i].set_type==LEVEL))
+ {
+ printf("\t\t\t\telse if(strcmp(opt, \"no-%s\")==0)\n", ents[i].set_name);
+ printf("\t\t\t\t{\n");
+ printf("\t\t\t\t\t%s=0;\n", ents[i].cname);
+ printf("\t\t\t\t\t\tadd_to_buffer(cbuf, c_status, \"%s disabled\", \"/set: \");\n", ents[i].set_msg);
+ printf("\t\t\t\t}\n");
+ }
+ }
+ break;
+ case 6:
+ printf("\t\t\tif(strcmp(cmd, \"%s\")==0) need=false;\n", ents[i].rc_name);
+ if(ents[i].type==BOOL)
+ printf("\t\t\tif(strcmp(cmd, \"no-%s\")==0) need=false;\n", ents[i].rc_name);
+ break;
+ default:
+ fprintf(stderr, "genconfig: otype %d not implemented!\n", otype);
+ return(EXIT_FAILURE);
+ break;
+ }
+ }
+ switch(otype)
+ {
+ case 1:
+ printf("\treturn(0);\n}\n");
+ break;
+ }
+
+}
+
+char * fgetl(FILE *fp)
+{
+ char * lout;
+ int l,i;
+ init_char(&lout, &l, &i);
+ signed int c;
+ while(!feof(fp))
+ {
+ c=fgetc(fp);
+ if((c==EOF)||(c=='\n'))
+ break;
+ if(c!=0)
+ {
+ append_char(&lout, &l, &i, c);
+ }
+ }
+ return(lout);
+}
+
+void append_char(char **buf, int *l, int *i, char c)
+{
+ if(!((c==0)||(c==EOF)))
+ {
+ if(*buf)
+ {
+ (*buf)[(*i)++]=c;
+ }
+ else
+ {
+ init_char(buf, l, i);
+ append_char(buf, l, i, c);
+ }
+ char *nbuf=*buf;
+ if((*i)>=(*l))
+ {
+ *l=*i*2;
+ nbuf=(char *)realloc(*buf, *l);
+ }
+ if(nbuf)
+ {
+ *buf=nbuf;
+ (*buf)[*i]=0;
+ }
+ else
+ {
+ free(*buf);
+ init_char(buf, l, i);
+ }
+ }
+}
+
+void init_char(char **buf, int *l, int *i)
+{
+ *l=80;
+ *buf=(char *)malloc(*l);
+ (*buf)[0]=0;
+ *i=0;
+}
View
205 input.c
@@ -545,210 +545,7 @@ int cmd_handle(char *inp, char **qmsg, fd_set *master, int *fdmax) // old state=
if(opt)
{
char *val=strtok(NULL, " ");
- if(strcmp(opt, "width")==0)
- {
- if(val)
- {
- sscanf(val, "%u", &width);
- }
- else
- {
- width=80;
- }
- if(width<30)
- {
- add_to_buffer(cbuf, c_status, "width set to minimum 30", "/set: ");
- width=30;
- }
- else
- {
- add_to_buffer(cbuf, c_status, "width set", "/set: ");
- }
- int buf;
- for(buf=0;buf<nbufs;buf++)
- bufs[buf].dirty=true;
- if(force_redraw<3)
- {
- redraw_buffer();
- }
- }
- else if(strcmp(opt, "height")==0)
- {
- if(val)
- {
- sscanf(val, "%u", &height);
- }
- else
- {
- height=24;
- }
- if(height<5)
- {
- add_to_buffer(cbuf, c_status, "height set to minimum 5", "/set: ");
- height=5;
- }
- else
- {
- add_to_buffer(cbuf, c_status, "height set", "/set: ");
- }
- if(force_redraw<3)
- {
- redraw_buffer();
- }
- }
- else if(strcmp(opt, "fred")==0)
- {
- if(val)
- {
- sscanf(val, "%u", &force_redraw);
- }
- else
- {
- force_redraw=1;
- }
- if(force_redraw)
- {
- char fmsg[36];
- sprintf(fmsg, "force-redraw level %u enabled", force_redraw);
- add_to_buffer(cbuf, c_status, fmsg, "/set: ");
- redraw_buffer();
- }
- else
- {
- add_to_buffer(cbuf, c_status, "force-redraw disabled", "/set: ");
- }
- }
- else if(strcmp(opt, "mnln")==0)
- {
- if(val)
- {
- sscanf(val, "%u", &maxnlen);
- }
- else
- {
- maxnlen=16;
- }
- if(maxnlen<4)
- {
- maxnlen=4;
- add_to_buffer(cbuf, c_status, "maxnicklen set to minimum 4", "/set: ");
- }
- else
- {
- add_to_buffer(cbuf, c_status, "maxnicklen set", "/set: ");
- }
- }
- else if(strcmp(opt, "mcc")==0)
- {
- if(val)
- {
- sscanf(val, "%u", &mirc_colour_compat);
- }
- else
- {
- mirc_colour_compat=1;
- }
- if(mirc_colour_compat)
- {
- char mmsg[26];
- sprintf(mmsg, "mcc level %u enabled", mirc_colour_compat);
- add_to_buffer(cbuf, c_status, mmsg, "/set: ");
- }
- else
- {
- add_to_buffer(cbuf, c_status, "mcc disabled", "/set: ");
- }
- int buf;
- for(buf=0;buf<nbufs;buf++)
- bufs[buf].dirty=true;
- }
- else if(strcmp(opt, "fwc")==0)
- {
- if(val)
- {
- unsigned int fwc;
- sscanf(val, "%u", &fwc);
- full_width_colour=fwc;
- }
- else
- {
- full_width_colour=true;
- }
- if(full_width_colour)
- {
- add_to_buffer(cbuf, c_status, "fwc enabled", "/set: ");
- }
- else
- {
- add_to_buffer(cbuf, c_status, "fwc disabled", "/set: ");
- }
- }
- else if(strcmp(opt, "hts")==0)
- {
- if(val)
- {
- unsigned int hts;
- sscanf(val, "%u", &hts);
- hilite_tabstrip=hts;
- }
- else
- {
- hilite_tabstrip=true;
- }
- if(hilite_tabstrip)
- {
- add_to_buffer(cbuf, c_status, "hts enabled", "/set: ");
- }
- else
- {
- add_to_buffer(cbuf, c_status, "hts disabled", "/set: ");
- }
- }
- else if(strcmp(opt, "tsb")==0)
- {
- if(val)
- {
- unsigned int ntsb;
- sscanf(val, "%u", &ntsb);
- tsb=ntsb;
- }
- else
- {
- tsb=true;
- }
- if(tsb)
- {
- add_to_buffer(cbuf, c_status, "tsb enabled", "/set: ");
- }
- else
- {
- add_to_buffer(cbuf, c_status, "tsb disabled", "/set: ");
- }
- }
- else if(strcmp(opt, "buf")==0)
- {
- if(val)
- {
- sscanf(val, "%u", &buflines);
- }
- else
- {
- buflines=256;
- }
- add_to_buffer(0, c_status, "Default buf set", "/set: ");
- }
- else if(strcmp(opt, "tping")==0)
- {
- if(val)
- {
- sscanf(val, "%u", &tping);
- }
- else
- {
- tping=60;
- }
- add_to_buffer(0, c_status, "Outbound ping timeout set", "/set: ");
- }
+#include "config_set.c"
#ifdef HAVE_DEBUG
else if(strcmp(opt, "debug")==0)
{
View
2 quirc.c
@@ -96,6 +96,8 @@ int main(int argc, char *argv[])
return(e);
}
+ conf_check();
+
e=ttyraw(STDOUT_FILENO);
if(e)
{
View
10 readme.htm
@@ -133,10 +133,12 @@
<tt>buf <em>buf-lines</em></tt><br />
the default being 256. Larger values will, of course, increase memory consumption.</p>
<p>You can turn on a few display options too;<br />
-<tt>fwc 1</tt><br />
-<tt>hts 1</tt><br />
-<tt>tsb 1</tt><br />
-will turn on Full-Width-Colour (makes coloured backgrounds for lines (eg. /me) run all the way across the terminal), Highlight-Tab-Strip (gives the tab strip a magenta background, to make it more visible) and Top-Status-Bar (uses the top line of the terminal for some status information). To turn them off replace the 1 with a 0. By default fwc and hts are turned off; tsb is turned on.</p>
+<tt>fwc</tt><br />
+<tt>hts</tt><br />
+<tt>tsb</tt><br />
+will turn on Full-Width-Colour (makes coloured backgrounds for lines (eg. /me) run all the way across the terminal), Highlight-Tab-Strip (gives the tab strip a magenta background, to make it more visible) and Top-Status-Bar (uses the top line of the terminal for some status information). To turn them off prefix them with <small>no-</small>, like<br />
+<tt>no-hts</tt><br />
+By default fwc and hts are turned off; tsb is turned on.</p>
<p>These settings and others can be overridden at runtime with commandline options. For details run &quot;quirc --help&quot;.</p>
<p>You can also customise the colours quIRC uses. A custom colour line starts with &apos;%&apos;, followed optionally by &apos;S&apos; or &apos;R&apos; (only use this colour when Sending or Receiving respectively), followed by an identifier, then space or tab, then four space-separated numbers. Like this:<br />
<tt>%[S|R]<em>ident</em> <em>fore</em> <em>back</em> <em>hi</em> <em>ul</em></tt></p>
View
12 spec-cdl
@@ -0,0 +1,12 @@
+== spec for config description language, config.cdl ==
+
+colon-separated values, the following fields:
+ type (int or bool)
+ C name
+ default value
+ min & max value
+ rc name
+ cmdline name
+ /set name
+ /set type (S[ET], L[EVEL] or B[OOLEAN])
+ /set message (also used for comments)

0 comments on commit de4ae60

Please sign in to comment.
Something went wrong with that request. Please try again.