commit de102ca20bbf0eeb7640ce142ee68eee952c6ee8
parent 9dafde08c0f8b2e232e77c60199ff03b218c6b57
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 9 Nov 2014 18:21:09 +0000
add config.h, make some options configurable at run-time
use regerror() to show clear error message what's wrong with the regex.
Diffstat:
M | Makefile | | | 8 | ++++++-- |
A | arg.h | | | 63 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | config.def.h | | | 35 | +++++++++++++++++++++++++++++++++++ |
M | hysteria-highlight.c | | | 112 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
4 files changed, 162 insertions(+), 56 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
include config.mk
SRC = hysteria-highlight.c hysteria-namelist.c
-HDR =
+HDR = arg.h config.def.h
OBJ = ${SRC:.c=.o}
all: options hysteria-highlight hysteria-namelist
@@ -16,7 +16,11 @@ options:
@echo CC $<
@${CC} -c -o $@ $< ${CFLAGS}
-${OBJ}: config.mk
+${OBJ}: config.mk config.h
+
+config.h:
+ @echo creating $@ from config.def.h
+ @cp config.def.h $@
hysteria-highlight: ${OBJ}
@echo CC -o $@
diff --git a/arg.h b/arg.h
@@ -0,0 +1,63 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][1]\
+ && argv[0][0] == '-';\
+ argc--, argv++) {\
+ char argc_;\
+ char **argv_;\
+ int brk_;\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ for (brk_ = 0, argv[0]++, argv_ = argv;\
+ argv[0][0] && !brk_;\
+ argv[0]++) {\
+ if (argv_ != argv)\
+ break;\
+ argc_ = argv[0][0];\
+ switch (argc_)
+
+/* Handles obsolete -NUM syntax */
+#define ARGNUM case '0':\
+ case '1':\
+ case '2':\
+ case '3':\
+ case '4':\
+ case '5':\
+ case '6':\
+ case '7':\
+ case '8':\
+ case '9'
+
+#define ARGEND }\
+ }
+
+#define ARGC() argc_
+
+#define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base)))
+
+#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ ((x), abort(), (char *)0) :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ (char *)0 :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#endif
diff --git a/config.def.h b/config.def.h
@@ -0,0 +1,35 @@
+/* escape codes: colors, reset */
+#define COLOR_GREEN "\x1b[1;32m"
+#define COLOR_YELLOW "\x1b[1;33m"
+#define COLOR_BLUE "\x1b[1;34m"
+#define COLOR_WHITE "\x1b[1;37m"
+
+static const char *reset = "\x1b[1;0m";
+
+/* colors */
+static const char *nickcolor = COLOR_WHITE;
+static const char *servercolor = COLOR_GREEN;
+static const char *urlcolor = COLOR_BLUE;
+static const char *wordcolor = COLOR_YELLOW;
+
+/* ignore message on match */
+static char *regexignore = "^$";
+/* match nickname */
+static char *regexnick = "(me|myself|irene)";
+/* highlight / color words */
+static char *regexword = "(me|myself|irene)";
+
+/* nickname to match and align */
+static const char *regexnickalign = "^[0-9]{2}:[0-9]{2} <([^>]+)>";
+/* match server messages */
+static const char *regexserver = "^([0-9]{2}:[0-9]{2} -!- .*)$";
+/* skip this prefix for each line (date part) */
+static const char *regextimestamp = "^[0-9]{4}-[0-9]{2}-[0-9]{2} ";
+/* convert unix timestamp prefix */
+static const char *regexunixtimestamp = "^[0-9]{10} ";
+/* buffer size to store formatted time string */
+#define TIMEFORMAT_BUFSIZ 18
+static const char *timeformat = "%Y-%m-%d %H:%M ";
+/* highlight / color urls */
+static const char *regexurl =
+ "(((https?|ftp)|mailto):(//)?[^ <>\"[:blank:]]*|(www|ftp)[0-9]?\\.[-a-z0-9.]+)";
diff --git a/hysteria-highlight.c b/hysteria-highlight.c
@@ -20,44 +20,16 @@
#include <sys/types.h>
#include <time.h>
-/* escape codes: colors, reset */
-static const char *green = "\x1b[1;32m";
-static const char *yellow = "\x1b[1;33m";
-static const char *blue = "\x1b[1;34m";
-static const char *white = "\x1b[1;37m";
-static const char *reset = "\x1b[1;0m";
-
-/* highlight / color words */
-static const char *regexword = "(evil_bob|bob|hiltjo)";
-/* match nickname */
-static const char *regexnick = "(evil_bob|bob|hiltjo)";
-/* nickname to match and align */
-static const char *regexnickalign = "^[0-9]{2}:[0-9]{2} <([^>]+)>";
-/* match server messages */
-static const char *regexserver = "^([0-9]{2}:[0-9]{2} -!- .*)$";
-/* skip this prefix for each line (date part) */
-static const char *regextimestamp = "^[0-9]{4}-[0-9]{2}-[0-9]{2} ";
-/* convert unix timestamp prefix */
-static const char *regexunixtimestamp = "^[0-9]{10} ";
-static const char *timeformat = "%Y-%m-%d %H:%M ";
-static char timebuf[18] = "";
-/* ignore message on match */
-static const char *regexignore = "^$";
-/* highlight / color urls */
-static const char *regexurl =
- "(((https?|ftp)|mailto):(//)?[^ <>\"[:blank:]]*|(www|ftp)[0-9]?\\.[-a-z0-9.]+)";
+#include "config.h"
+#include "arg.h"
+char *argv0;
+
+static char timebuf[TIMEFORMAT_BUFSIZ] = "";
static regex_t nick, nickalign, server, timestamp, ignore, url, word;
static regex_t unixtimestamp;
static void
-eprintf(const char *s)
-{
- fprintf(stderr, "%s\n", s);
- exit(EXIT_FAILURE);
-}
-
-static void
printalign(const char *s, size_t len, size_t maxlen)
{
size_t i;
@@ -70,8 +42,31 @@ printalign(const char *s, size_t len, size_t maxlen)
putchar(*s++);
}
+static int
+eregcomp(regex_t *preg, const char *regex, int cflags)
+{
+ char errbuf[BUFSIZ] = "";
+ int r;
+
+ if((r = regcomp(preg, regex, cflags)) == 0)
+ return r;
+
+ regerror(r, preg, errbuf, sizeof(errbuf));
+ fprintf(stderr, "%s: invalid regex: %s\n", argv0, errbuf);
+ exit(1);
+ return r;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-n nick] [-w word ] [-i ignore]\n", argv0);
+ exit(1);
+}
+
int
-main(void) {
+main(int argc, char *argv[])
+{
/* buffer: should be atleast 512 bytes (IRC RFC) + datetime prefix,
* assumes line length is lower than sizeof(buffer). */
char buffer[1024];
@@ -82,23 +77,32 @@ main(void) {
time_t t;
int hasmatch, ret;
+ ARGBEGIN {
+ case 'i':
+ regexignore = EARGF(usage());
+ break;
+ case 'n':
+ regexnick = EARGF(usage());
+ break;
+ case 'w':
+ regexword = EARGF(usage());
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if(argc > 0)
+ usage();
+
/* compile regex */
- if(regcomp(&nick, regexnick, REG_EXTENDED | REG_ICASE))
- eprintf("invalid regex: nick");
- if(regcomp(&nickalign, regexnickalign, REG_EXTENDED))
- eprintf("invalid regex: nickalign");
- if(regcomp(&server, regexserver, REG_EXTENDED))
- eprintf("invalid regex: server");
- if(regcomp(×tamp, regextimestamp, REG_EXTENDED))
- eprintf("invalid regex: timestamp");
- if(regcomp(&unixtimestamp, regexunixtimestamp, REG_EXTENDED))
- eprintf("invalid regex: unix timestamp");
- if(regcomp(&ignore, regexignore, REG_EXTENDED | REG_ICASE))
- eprintf("invalid regex: ignore");
- if(regcomp(&url, regexurl, REG_EXTENDED | REG_ICASE))
- eprintf("invalid regex: url");
- if(regcomp(&word, regexword, REG_EXTENDED | REG_ICASE))
- eprintf("invalid regex: word");
+ eregcomp(&nick, regexnick, REG_EXTENDED | REG_ICASE);
+ eregcomp(&nickalign, regexnickalign, REG_EXTENDED);
+ eregcomp(&server, regexserver, REG_EXTENDED);
+ eregcomp(×tamp, regextimestamp, REG_EXTENDED);
+ eregcomp(&unixtimestamp, regexunixtimestamp, REG_EXTENDED);
+ eregcomp(&ignore, regexignore, REG_EXTENDED | REG_ICASE);
+ eregcomp(&url, regexurl, REG_EXTENDED | REG_ICASE);
+ eregcomp(&word, regexword, REG_EXTENDED | REG_ICASE);
while(fgets(buffer, sizeof(buffer), stdin)) {
p = buffer;
@@ -121,7 +125,7 @@ main(void) {
/* highlight / color server messages */
if((ret = regexec(&server, p, 1, &match, 0)) != REG_NOMATCH) {
- fputs(green, stdout);
+ fputs(servercolor, stdout);
fputs(p, stdout);
fputs(reset, stdout);
fflush(stdout);
@@ -143,7 +147,7 @@ main(void) {
if((ret = regexec(&nick, p, 1, &match, 0)) != REG_NOMATCH &&
match.rm_so == 0 && match.rm_eo == len)
{
- fputs(white, stdout);
+ fputs(nickcolor, stdout);
printalign(p, len, 10);
fputs(reset, stdout);
} else {
@@ -159,7 +163,7 @@ main(void) {
/* highlight word */
if((ret = regexec(&word, p, 1, &match, 0)) != REG_NOMATCH) {
fwrite(p, 1, match.rm_so, stdout);
- fputs(yellow, stdout);
+ fputs(wordcolor, stdout);
p += match.rm_so;
fwrite(p, 1, match.rm_eo - match.rm_so, stdout);
fputs(reset, stdout);
@@ -171,7 +175,7 @@ main(void) {
/* highlight url */
if((ret = regexec(&url, p, 1, &match, 0)) != REG_NOMATCH) {
fwrite(p, 1, match.rm_so, stdout);
- fputs(blue, stdout);
+ fputs(urlcolor, stdout);
p += match.rm_so;
fwrite(p, 1, match.rm_eo - match.rm_so, stdout);
fputs(reset, stdout);