diff options
| author | Curtis McEnroe | 2019-02-25 23:10:40 -0500 | 
|---|---|---|
| committer | Curtis McEnroe | 2019-02-25 23:10:40 -0500 | 
| commit | 4cda410b574c93c2ea7ad467e2b27809d0a0ba62 (patch) | |
| tree | aaffc0e9b1379f1a9fb7fa571b2807077d4acbbe | |
| parent | b2f6082dffb6a5fce557882e18183c2438ea4a3d (diff) | |
Move nick and tag coloring to color.c
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | README | 3 | ||||
| -rw-r--r-- | catgirl.7 | 4 | ||||
| -rw-r--r-- | chat.h | 30 | ||||
| -rw-r--r-- | color.c | 50 | ||||
| -rw-r--r-- | format.c | 20 | ||||
| -rw-r--r-- | handle.c | 65 | ||||
| -rw-r--r-- | input.c | 4 | ||||
| -rw-r--r-- | tag.c | 20 | ||||
| -rw-r--r-- | ui.c | 8 | 
10 files changed, 117 insertions, 88 deletions
@@ -15,6 +15,7 @@ MAN1 = catgirl.1  -include config.mk  OBJS += chat.o +OBJS += color.o  OBJS += edit.o  OBJS += event.o  OBJS += format.o @@ -39,6 +39,7 @@ FILES       input.c    input command handling       irc.c      TLS client connection       format.c   IRC formatting +     color.c    nick and channel coloring       ui.c       cursed UI       term.c     terminal features unsupported by curses       edit.c     line editing @@ -53,4 +54,4 @@ FILES  SEE ALSO       catgirl(1), sandman(1) -Causal Agency                  January 25, 2019                  Causal Agency +Causal Agency                  February 25, 2019                 Causal Agency @@ -1,4 +1,4 @@ -.Dd January 25, 2019 +.Dd February 25, 2019  .Dt CATGIRL 7  .Os "Causal Agency"  . @@ -79,6 +79,8 @@ input command handling  TLS client connection  .It Pa format.c  IRC formatting +.It Pa color.c +nick and channel coloring  .It Pa ui.c  cursed UI  .It Pa term.c @@ -52,6 +52,18 @@ void eventWait(const char *argv[static 2]);  void eventPipe(const char *argv[static 2]);  noreturn void eventLoop(void); +struct Tag { +	size_t id; +	const char *name; +}; + +enum { TagsLen = 256 }; +const struct Tag TagNone; +const struct Tag TagStatus; +const struct Tag TagRaw; +struct Tag tagFind(const char *name); +struct Tag tagFor(const char *name); +  enum IRCColor {  	IRCWhite,  	IRCBlack, @@ -80,19 +92,6 @@ enum {  	IRCUnderline = 037,  }; -struct Tag { -	size_t id; -	const char *name; -	enum IRCColor color; -}; - -enum { TagsLen = 256 }; -const struct Tag TagNone; -const struct Tag TagStatus; -const struct Tag TagRaw; -struct Tag tagFind(const char *name); -struct Tag tagFor(const char *name, enum IRCColor color); -  struct Format {  	const wchar_t *str;  	size_t len; @@ -102,7 +101,10 @@ struct Format {  };  void formatReset(struct Format *format);  bool formatParse(struct Format *format, const wchar_t *split); -enum IRCColor formatColor(const char *str); + +enum IRCColor colorGen(const char *str); +struct Tag colorTag(struct Tag tag, const char *gen); +enum IRCColor colorFor(struct Tag tag);  void handle(char *line);  void input(struct Tag tag, char *line); @@ -0,0 +1,50 @@ +/* Copyright (C) 2019  C. McEnroe <june@causal.agency> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdint.h> + +#include "chat.h" + +// Adapted from <https://github.com/cbreeden/fxhash/blob/master/lib.rs>. +static uint32_t hashChar(uint32_t hash, char ch) { +	hash = (hash << 5) | (hash >> 27); +	hash ^= ch; +	hash *= 0x27220A95; +	return hash; +} + +enum IRCColor colorGen(const char *str) { +	if (!str) return IRCDefault; +	uint32_t hash = 0; +	for (; str[0]; ++str) { +		hash = hashChar(hash, str[0]); +	} +	while (IRCBlack == (hash & IRCLightGray)) { +		hash = hashChar(hash, '\0'); +	} +	return (hash & IRCLightGray); +} + +static enum IRCColor colors[TagsLen]; + +struct Tag colorTag(struct Tag tag, const char *gen) { +	if (!colors[tag.id]) colors[tag.id] = 1 + colorGen(gen); +	return tag; +} + +enum IRCColor colorFor(struct Tag tag) { +	return colors[tag.id] ? colors[tag.id] - 1 : IRCDefault; +} @@ -21,26 +21,6 @@  #include "chat.h" -// Adapted from <https://github.com/cbreeden/fxhash/blob/master/lib.rs>. -static uint32_t hashChar(uint32_t hash, char ch) { -	hash = (hash << 5) | (hash >> 27); -	hash ^= ch; -	hash *= 0x27220A95; -	return hash; -} - -enum IRCColor formatColor(const char *str) { -	if (!str) return IRCDefault; -	uint32_t hash = 0; -	for (; str[0]; ++str) { -		hash = hashChar(hash, str[0]); -	} -	while (IRCBlack == (hash & IRCLightGray)) { -		hash = hashChar(hash, '\0'); -	} -	return (hash & IRCLightGray); -} -  void formatReset(struct Format *format) {  	format->bold = false;  	format->italic = false; @@ -160,7 +160,7 @@ static void handleReplyWhoisUser(char *prefix, char *params) {  		prefix, NULL, NULL, NULL,  		params, 6, 0, NULL, &nick, &user, &host, NULL, &real  	); -	whoisColor = formatColor(user[0] == '~' ? &user[1] : user); +	whoisColor = colorGen(user[0] == '~' ? &user[1] : user);  	uiFmt(  		TagStatus, UIWarm,  		"\3%d%s\3 is %s@%s, \"%s\"", @@ -214,7 +214,7 @@ static void handleErrorNoSuchNick(char *prefix, char *params) {  static void handleJoin(char *prefix, char *params) {  	char *nick, *user, *chan;  	parse(prefix, &nick, &user, NULL, params, 1, 0, &chan); -	struct Tag tag = tagFor(chan, formatColor(chan)); +	struct Tag tag = colorTag(tagFor(chan), chan);  	if (!strcmp(nick, self.nick)) {  		tabTouch(TagNone, chan); @@ -226,7 +226,7 @@ static void handleJoin(char *prefix, char *params) {  	uiFmt(  		tag, UICold,  		"\3%d%s\3 arrives in \3%d%s\3", -		formatColor(user), nick, formatColor(chan), chan +		colorGen(user), nick, colorGen(chan), chan  	);  	logFmt(tag, NULL, "%s arrives in %s", nick, chan);  } @@ -234,7 +234,7 @@ static void handleJoin(char *prefix, char *params) {  static void handlePart(char *prefix, char *params) {  	char *nick, *user, *chan, *mesg;  	parse(prefix, &nick, &user, NULL, params, 1, 1, &chan, &mesg); -	struct Tag tag = tagFor(chan, formatColor(chan)); +	struct Tag tag = colorTag(tagFor(chan), chan);  	if (!strcmp(nick, self.nick)) {  		tabClear(tag); @@ -247,14 +247,14 @@ static void handlePart(char *prefix, char *params) {  		uiFmt(  			tag, UICold,  			"\3%d%s\3 leaves \3%d%s\3, \"%s\"", -			formatColor(user), nick, formatColor(chan), chan, dequote(mesg) +			colorGen(user), nick, colorGen(chan), chan, dequote(mesg)  		);  		logFmt(tag, NULL, "%s leaves %s, \"%s\"", nick, chan, dequote(mesg));  	} else {  		uiFmt(  			tag, UICold,  			"\3%d%s\3 leaves \3%d%s\3", -			formatColor(user), nick, formatColor(chan), chan +			colorGen(user), nick, colorGen(chan), chan  		);  		logFmt(tag, NULL, "%s leaves %s", nick, chan);  	} @@ -263,7 +263,7 @@ static void handlePart(char *prefix, char *params) {  static void handleKick(char *prefix, char *params) {  	char *nick, *user, *chan, *kick, *mesg;  	parse(prefix, &nick, &user, NULL, params, 2, 1, &chan, &kick, &mesg); -	struct Tag tag = tagFor(chan, formatColor(chan)); +	struct Tag tag = colorTag(tagFor(chan), chan);  	bool kicked = !strcmp(kick, self.nick);  	if (kicked) { @@ -277,9 +277,9 @@ static void handleKick(char *prefix, char *params) {  		uiFmt(  			tag, (kicked ? UIHot : UICold),  			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"", -			formatColor(user), nick, -			formatColor(kick), kick, -			formatColor(chan), chan, +			colorGen(user), nick, +			colorGen(kick), kick, +			colorGen(chan), chan,  			dequote(mesg)  		);  		logFmt( @@ -290,9 +290,9 @@ static void handleKick(char *prefix, char *params) {  		uiFmt(  			tag, (kicked ? UIHot : UICold),  			"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3", -			formatColor(user), nick, -			formatColor(kick), kick, -			formatColor(chan), chan +			colorGen(user), nick, +			colorGen(kick), kick, +			colorGen(chan), chan  		);  		logFmt(tag, NULL, "%s kicks %s out of %s", nick, kick, chan);  	} @@ -311,11 +311,11 @@ static void handleQuit(char *prefix, char *params) {  			uiFmt(  				tag, UICold,  				"\3%d%s\3 leaves, \"%s\"", -				formatColor(user), nick, dequote(mesg) +				colorGen(user), nick, dequote(mesg)  			);  			logFmt(tag, NULL, "%s leaves, \"%s\"", nick, dequote(mesg));  		} else { -			uiFmt(tag, UICold, "\3%d%s\3 leaves", formatColor(user), nick); +			uiFmt(tag, UICold, "\3%d%s\3 leaves", colorGen(user), nick);  			logFmt(tag, NULL, "%s leaves", nick);  		}  	} @@ -324,13 +324,13 @@ static void handleQuit(char *prefix, char *params) {  static void handleReplyTopic(char *prefix, char *params) {  	char *chan, *topic;  	parse(prefix, NULL, NULL, NULL, params, 3, 0, NULL, &chan, &topic); -	struct Tag tag = tagFor(chan, formatColor(chan)); +	struct Tag tag = colorTag(tagFor(chan), chan);  	urlScan(tag, topic);  	uiFmt(  		tag, UICold,  		"The sign in \3%d%s\3 reads, \"%s\"", -		formatColor(chan), chan, topic +		colorGen(chan), chan, topic  	);  	logFmt(tag, NULL, "The sign in %s reads, \"%s\"", chan, topic);  } @@ -338,7 +338,7 @@ static void handleReplyTopic(char *prefix, char *params) {  static void handleTopic(char *prefix, char *params) {  	char *nick, *user, *chan, *topic;  	parse(prefix, &nick, &user, NULL, params, 2, 0, &chan, &topic); -	struct Tag tag = tagFor(chan, formatColor(chan)); +	struct Tag tag = colorTag(tagFor(chan), chan);  	if (strcmp(nick, self.nick)) tabTouch(tag, nick); @@ -346,7 +346,7 @@ static void handleTopic(char *prefix, char *params) {  	uiFmt(  		tag, UICold,  		"\3%d%s\3 places a new sign in \3%d%s\3, \"%s\"", -		formatColor(user), nick, formatColor(chan), chan, topic +		colorGen(user), nick, colorGen(chan), chan, topic  	);  	logFmt(tag, NULL, "%s places a new sign in %s, \"%s\"", nick, chan, topic);  } @@ -369,7 +369,7 @@ static void handleReplyWho(char *prefix, char *params) {  		params, 6, 0, NULL, &chan, &user, NULL, NULL, &nick  	);  	if (user[0] == '~') user = &user[1]; -	struct Tag tag = tagFor(chan, formatColor(chan)); +	struct Tag tag = colorTag(tagFor(chan), chan);  	tabAdd(tag, nick); @@ -377,7 +377,7 @@ static void handleReplyWho(char *prefix, char *params) {  	int len = snprintf(  		&who.buf[who.len], cap,  		"%s\3%d%s\3", -		(who.len ? ", " : ""), formatColor(user), nick +		(who.len ? ", " : ""), colorGen(user), nick  	);  	if ((size_t)len < cap) who.len += len;  } @@ -385,12 +385,12 @@ static void handleReplyWho(char *prefix, char *params) {  static void handleReplyEndOfWho(char *prefix, char *params) {  	char *chan;  	parse(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &chan); -	struct Tag tag = tagFor(chan, formatColor(chan)); +	struct Tag tag = colorTag(tagFor(chan), chan);  	uiFmt(  		tag, UICold,  		"In \3%d%s\3 are %s", -		formatColor(chan), chan, who.buf +		colorGen(chan), chan, who.buf  	);  	who.len = 0;  } @@ -413,7 +413,7 @@ static void handleNick(char *prefix, char *params) {  		uiFmt(  			tag, UICold,  			"\3%d%s\3 is now known as \3%d%s\3", -			formatColor(user), prev, formatColor(user), next +			colorGen(user), prev, colorGen(user), next  		);  		logFmt(tag, NULL, "%s is now known as %s", prev, next);  	} @@ -432,7 +432,7 @@ static void handleCTCP(struct Tag tag, char *nick, char *user, char *mesg) {  	uiFmt(  		tag, (ping ? UIHot : UIWarm),  		"%c\3%d* %s\17 %s", -		ping["\17\26"], formatColor(user), nick, params +		ping["\17\26"], colorGen(user), nick, params  	);  	logFmt(tag, NULL, "* %s %s", nick, params);  } @@ -441,9 +441,8 @@ static void handlePrivmsg(char *prefix, char *params) {  	char *nick, *user, *chan, *mesg;  	parse(prefix, &nick, &user, NULL, params, 2, 0, &chan, &mesg);  	bool direct = !strcmp(chan, self.nick); -	struct Tag tag = direct -		? tagFor(nick, formatColor(user)) -		: tagFor(chan, formatColor(chan)); +	struct Tag tag = tagFor(direct ? nick : chan); +	colorTag(tag, direct ? user : chan);  	if (mesg[0] == '\1') {  		handleCTCP(tag, nick, user, mesg);  		return; @@ -459,7 +458,7 @@ static void handlePrivmsg(char *prefix, char *params) {  		tag, (hot ? UIHot : UIWarm),  		"%c%c\3%d<%s>%c %s",  		(me ? IRCUnderline : IRCColor), (ping ? IRCReverse : IRCColor), -		formatColor(user), nick, IRCReset, mesg +		colorGen(user), nick, IRCReset, mesg  	);  	logFmt(tag, NULL, "<%s> %s", nick, mesg);  } @@ -467,11 +466,11 @@ static void handlePrivmsg(char *prefix, char *params) {  static void handleNotice(char *prefix, char *params) {  	char *nick, *user, *chan, *mesg;  	parse(prefix, &nick, &user, NULL, params, 2, 0, &chan, &mesg); +	bool direct = !strcmp(chan, self.nick);  	struct Tag tag = TagStatus;  	if (user) { -		tag = strcmp(chan, self.nick) -			? tagFor(chan, formatColor(chan)) -			: tagFor(nick, formatColor(user)); +		tag = tagFor(direct ? nick : chan); +		colorTag(tag, direct ? user : chan);  	}  	if (strcmp(nick, self.nick)) tabTouch(tag, nick); @@ -481,7 +480,7 @@ static void handleNotice(char *prefix, char *params) {  	uiFmt(  		tag, (ping ? UIHot : UIWarm),  		"%c\3%d-%s-\17 %s", -		ping["\17\26"], formatColor(user), nick, mesg +		ping["\17\26"], colorGen(user), nick, mesg  	);  	logFmt(tag, NULL, "-%s- %s", nick, mesg);  } @@ -66,8 +66,8 @@ static void inputQuery(struct Tag tag, char *params) {  	char *nick = strsep(¶ms, " ");  	if (nick) {  		tabTouch(TagNone, nick); -		uiShowTag(tagFor(nick, IRCDefault)); -		logReplay(tagFor(nick, IRCDefault)); +		uiShowTag(tagFor(nick)); +		logReplay(tagFor(nick));  	} else {  		uiLog(tag, UIHot, L"/query requires a nickname");  	} @@ -23,37 +23,31 @@  static struct {  	char *name[TagsLen]; -	enum IRCColor color[TagsLen];  	size_t len;  } tags = {  	.name = { "<none>", "<status>", "<raw>" }, -	.color = { IRCBlack, IRCDefault, IRCRed },  	.len = 3,  }; -const struct Tag TagNone   = { 0, "<none>", IRCBlack }; -const struct Tag TagStatus = { 1, "<status>", IRCDefault }; -const struct Tag TagRaw    = { 2, "<raw>", IRCRed }; +const struct Tag TagNone   = { 0, "<none>" }; +const struct Tag TagStatus = { 1, "<status>" }; +const struct Tag TagRaw    = { 2, "<raw>" };  struct Tag tagFind(const char *name) {  	for (size_t id = 0; id < tags.len; ++id) {  		if (strcmp(tags.name[id], name)) continue; -		return (struct Tag) { id, tags.name[id], tags.color[id] }; +		return (struct Tag) { id, tags.name[id] };  	}  	return TagNone;  } -struct Tag tagFor(const char *name, enum IRCColor color) { +struct Tag tagFor(const char *name) {  	struct Tag tag = tagFind(name); -	if (tag.id != TagNone.id) { -		tag.color = tags.color[tag.id] = color; -		return tag; -	} +	if (tag.id != TagNone.id) return tag;  	if (tags.len == TagsLen) return TagStatus;  	size_t id = tags.len++;  	tags.name[id] = strdup(name); -	tags.color[id] = color;  	if (!tags.name[id]) err(EX_OSERR, "strdup"); -	return (struct Tag) { id, tags.name[id], color }; +	return (struct Tag) { id, tags.name[id] };  } @@ -339,10 +339,10 @@ static void uiStatus(void) {  		wchar_t *str;  		int len = aswprintf(  			&str, L"%c\3%d %d %s %n(\3%02d%u\3%d) ", -			(windows.active == win ? IRCReverse : IRCReset), win->tag.color, +			(windows.active == win ? IRCReverse : IRCReset), colorFor(win->tag),  			num, win->tag.name, -			&unread, (win->hot ? IRCWhite : win->tag.color), win->unread, -			win->tag.color +			&unread, (win->hot ? IRCWhite : colorFor(win->tag)), win->unread, +			colorFor(win->tag)  		);  		if (len < 0) err(EX_OSERR, "aswprintf");  		if (!win->unread) str[unread] = L'\0'; @@ -557,7 +557,7 @@ void uiPrompt(bool nickChanged) {  	if (nickChanged || !promptMesg || !promptAction) {  		free(promptMesg);  		free(promptAction); -		enum IRCColor color = formatColor(self.user); +		enum IRCColor color = colorGen(self.user);  		int len = aswprintf(&promptMesg, L"\3%d<%s>\3 ", color, self.nick);  		if (len < 0) err(EX_OSERR, "aswprintf");  		len = aswprintf(&promptAction, L"\3%d* %s\3 ", color, self.nick);  | 
