From a75db3e11323c528d8fabb1812fd97a305467d2b Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Thu, 5 Dec 2019 15:51:18 -0500 Subject: Add textual format to unscoop --- unscoop.1 | 3 ++- unscoop.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/unscoop.1 b/unscoop.1 index 0478481..0a9f0db 100644 --- a/unscoop.1 +++ b/unscoop.1 @@ -40,7 +40,8 @@ for the default database path. .It Fl f Ar format Set the input log format. The following formats are supported: -.Sy generic . +.Sy generic , +.Sy textual . .Pp The .Sy generic diff --git a/unscoop.c b/unscoop.c index d5494e0..2e62b57 100644 --- a/unscoop.c +++ b/unscoop.c @@ -31,9 +31,9 @@ #define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) struct Matcher { - enum Type type; const char *pattern; regex_t regex; + enum Type type; size_t time; size_t nick; size_t user; @@ -42,25 +42,68 @@ struct Matcher { size_t message; }; -#define WS "[[:blank:]]*" +#define WS "[[:blank:]]" #define PAT_TIME "[[]([^]]+)[]]" #define PAT_MODE "[!~&@%+ ]?" static struct Matcher Generic[] = { { - .type = Privmsg, - .pattern = "^" PAT_TIME WS "<" PAT_MODE "([^>]+)" ">" WS "(.+)", - .time = 1, .nick = 2, .message = 3, + "^" PAT_TIME WS "<" PAT_MODE "([^>]+)" ">" WS "(.+)", + .type = Privmsg, .time = 1, .nick = 2, .message = 3, + }, + { + "^" PAT_TIME WS "-" PAT_MODE "([^-]+)" "-" WS "(.+)", + .type = Notice, .time = 1, .nick = 2, .message = 3, + }, + { + "^" PAT_TIME WS "[*]" WS PAT_MODE "([^[:blank:]]+)" WS "(.+)", + .type = Action, .time = 1, .nick = 2, .message = 3, + }, +}; + +#define PAT_USERHOST "[(]([^@]+)@([^)]+)[)]" +#define PAT_MESSAGE "[(]([^)]+)[)]" + +static struct Matcher Textual[] = { + { + "^" PAT_TIME " <" PAT_MODE "([^>]+)> (.+)", + .type = Privmsg, .time = 1, .nick = 2, .message = 3, + }, + { + "^" PAT_TIME " -" PAT_MODE "([^-]+)- (.+)", + .type = Notice, .time = 1, .nick = 2, .message = 3, + }, + { + "^" PAT_TIME " • ([^:]+): (.+)", + .type = Action, .time = 1, .nick = 2, .message = 3, + }, + { + "^" PAT_TIME " ([^ ]+) " PAT_USERHOST " joined the channel", + .type = Join, .time = 1, .nick = 2, .user = 3, .host = 4, + }, + { + "^" PAT_TIME " ([^ ]+) " PAT_USERHOST " left the channel$", + .type = Part, .time = 1, .nick = 2, .user = 3, .host = 4, + }, + { + "^" PAT_TIME " ([^ ]+) " PAT_USERHOST " left the channel " PAT_MESSAGE, + .type = Part, .time = 1, .nick = 2, .user = 3, .host = 4, .message = 5, + }, + { + "^" PAT_TIME " ([^ ]+) kicked ([^ ]+) from the channel " PAT_MESSAGE, + .type = Kick, .time = 1, .nick = 2, .target = 3, .message = 4, + }, + { + "^" PAT_TIME " ([^ ]+) " PAT_USERHOST " left IRC " PAT_MESSAGE, + .type = Quit, .time = 1, .nick = 2, .user = 3, .host = 4, .message = 5, }, { - .type = Notice, - .pattern = "^" PAT_TIME WS "-" PAT_MODE "([^-]+)" "-" WS "(.+)", - .time = 1, .nick = 2, .message = 3, + "^" PAT_TIME " ([^ ]+) is now known as ([^ ]+)", + .type = Nick, .time = 1, .nick = 2, .target = 3, }, { - .type = Action, - .pattern = "^" PAT_TIME WS "[*]" WS PAT_MODE "([^[:blank:]]+)" WS "(.+)", - .time = 1, .nick = 2, .message = 3, + "^" PAT_TIME " ([^ ]+) changed the topic to (.+)", + .type = Topic, .time = 1, .nick = 2, .message = 3, }, }; @@ -70,6 +113,7 @@ static const struct Format { size_t len; } Formats[] = { { "generic", Generic, ARRAY_LEN(Generic) }, + { "textual", Textual, ARRAY_LEN(Textual) }, }; static const struct Format *formatParse(const char *name) { -- cgit 1.4.1 span title='2019-11-14 00:32:56 -0500'>2019-11-14Replace filters with regex replacesJune McEnroe 2019-11-13Refactor filterUserhostInNamesJune McEnroe 2019-11-13Factor out wordcpy for filtersJune McEnroe 2019-11-11Revert "Test getopt_config"June McEnroe 2019-11-11Test getopt_configJune McEnroe 2019-11-11Add userhost-in-names to manualJune McEnroe 2019-11-11Skip initial NAMES parametersJune McEnroe 2019-11-11Filter userhost-in-namesJune McEnroe 2019-11-10Compare words without copying in filtersJune McEnroe 2019-11-10Separate tags from all targetJune McEnroe 2019-11-10Filter invite-notifyJune McEnroe 2019-11-10Add capsicum note to READMEJune McEnroe 2019-11-10Filter extended-joinJune McEnroe 2019-11-10Expand client configuration documentation and list capabilitiesJune McEnroe 2019-11-10Request all supported caps from serverJune McEnroe 2019-11-10Filter ACCOUNT, AWAY, CHGHOST for incapable clientsJune McEnroe 2019-11-10Rename listen to localJune McEnroe 2019-11-09Remove extended-join and invite-notifyJune McEnroe 2019-11-09Maintain stateCaps and offer them to clientsJune McEnroe 2019-11-09Parse capabilitiesJune McEnroe 2019-11-09Avoid the reserved _A names with BIT macroJune McEnroe 2019-11-09Define macro for bit flag enumsJune McEnroe 2019-11-08Check that password is hashedJune McEnroe 2019-11-08Avoid calling getopt_long again after it returns -1June McEnroe 2019-11-08Only change AWAY status for registered clientsJune McEnroe 2019-11-07Just write the example normallyJune McEnroe 2019-11-07Include path in readlinkat errorJune McEnroe 2019-11-07Call clientConsume before clientRecvJune McEnroe 2019-11-06Use -l:filename in Linux.mkJune McEnroe 2019-11-06Fix compat.h for #defined strlcpyJune McEnroe 2019-11-06Allow unsetting LIBRESSL_PREFIXJune McEnroe 2019-11-06Document calico service configurationJune McEnroe 2019-11-06Document SASL EXTERNAL configuration in more detailJune McEnroe 2019-11-06Document pounce service configurationJune McEnroe 2019-11-06Mention Darwin and GNU/Linux in READMEJune McEnroe 2019-11-06Assume LibreSSL from brew on DarwinJune McEnroe 2019-11-06Remove -DNO_EXPLICIT_BZERO from Darwin.mkJune McEnroe 2019-11-06Don't install rc scripts or dirs on LinuxJune McEnroe