From a324795b8610b7c3e5626ac72d202ce6207066d7 Mon Sep 17 00:00:00 2001
From: "C. McEnroe" <june@causal.agency>
Date: Sat, 9 Jan 2021 17:58:29 -0500
Subject: Allow configuring the upper bound of the hash function

This allows limiting the nick colors used to the 16-color terminal set
without modifying the TERM environment variable. Produces different
results from just using the default configuration in a 16-color
terminal, but what can you do?
---
 catgirl.1 | 11 ++++++++---
 chat.c    | 12 +++++++++---
 chat.h    |  3 ++-
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/catgirl.1 b/catgirl.1
index 1c782cf..04216a6 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -1,4 +1,4 @@
-.Dd December 30, 2020
+.Dd January  9, 2021
 .Dt CATGIRL 1
 .Os
 .
@@ -77,9 +77,14 @@ The default is the first available of
 .Xr xclip 1 ,
 .Xr xsel 1 .
 .
-.It Fl H Ar hash , Cm hash = Ar hash
+.It Fl H Ar init,bound , Cm hash = Ar init,bound
 Set the initial value of
-the nick color hash function.
+the nick color hash function
+and the maximum IRC color value used.
+The default is 0,75.
+To use only colors from
+the 16-color terminal set,
+use 0,15.
 .
 .It Fl N Ar util , Cm notify = Ar util
 Send notifications using a utility.
diff --git a/chat.c b/chat.c
index 016d604..fd2b89a 100644
--- a/chat.c
+++ b/chat.c
@@ -87,8 +87,6 @@ static void exitSave(void) {
 	}
 }
 
-uint32_t hashInit;
-
 uint execID;
 int execPipe[2] = { -1, -1 };
 int utilPipe[2] = { -1, -1 };
@@ -117,6 +115,14 @@ static void utilRead(void) {
 	}
 }
 
+uint32_t hashInit;
+uint32_t hashBound = 75;
+
+static void parseHash(char *str) {
+	hashInit = strtoul(str, &str, 0);
+	if (*str) hashBound = strtoul(&str[1], NULL, 0);
+}
+
 static volatile sig_atomic_t signals[NSIG];
 static void signalHandler(int signal) {
 	signals[signal] = 1;
@@ -179,7 +185,7 @@ int main(int argc, char *argv[]) {
 		switch (opt) {
 			break; case '!': insecure = true;
 			break; case 'C': utilPush(&urlCopyUtil, optarg);
-			break; case 'H': hashInit = strtoul(optarg, NULL, 0);
+			break; case 'H': parseHash(optarg);
 			break; case 'N': utilPush(&uiNotifyUtil, optarg);
 			break; case 'O': utilPush(&urlOpenUtil, optarg);
 			break; case 'R': self.restricted = true;
diff --git a/chat.h b/chat.h
index b06d383..8de5d55 100644
--- a/chat.h
+++ b/chat.h
@@ -137,6 +137,7 @@ static inline uint idFor(const char *name) {
 }
 
 extern uint32_t hashInit;
+extern uint32_t hashBound;
 static inline enum Color hash(const char *str) {
 	if (*str == '~') str++;
 	uint32_t hash = hashInit;
@@ -145,7 +146,7 @@ static inline enum Color hash(const char *str) {
 		hash ^= *str;
 		hash *= 0x27220A95;
 	}
-	return Blue + hash % 74;
+	return Blue + hash % (hashBound + 1 - Blue);
 }
 
 extern struct Network {
-- 
cgit 1.4.1

 (<a href='/torus/log/help.c?id=a8d1d0ca5b31887af39001b756c0361d75ee42a0&amp;follow=1'>Collapse</a>)</th><th class='left'>Author</th></tr>
<tr class='logheader'><td><span title='2018-07-22 19:17:09 -0400'>2018-07-22</span></td><td class='logsubject'><a href='/torus/commit/Makefile?id=8d589acc06cf66fdd46ae43ca81dec237586b3ad&amp;follow=1'>Link with -lm</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
Darwin's lack of separation strikes again.


</td></tr>
<tr class='logheader'><td><span title='2018-07-22 19:14:09 -0400'>2018-07-22</span></td><td class='logsubject'><a href='/torus/commit/client.c?id=1e9f09951a34d26100806f0048562bcecb6d59e6&amp;follow=1'>Add map to client</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-07-21 13:48:43 -0400'>2018-07-21</span></td><td class='logsubject'><a href='/torus/commit/client.c?id=4d8a54fd364982cb18241b18fe7739c0b6c0c143&amp;follow=1'>Refactor readInput for each mode</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-07-19 15:44:16 -0400'>2018-07-19</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=515992ffca07b2aeb6c13b333b194e42e5a1fe34&amp;follow=1'>Add ARRAY_LEN macro</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-07-17 23:35:21 -0400'>2018-07-17</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=d60d2573ad7ab869d040a438b328d5abc3bcebae&amp;follow=1'>Add server map generation</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-07-17 15:44:35 -0400'>2018-07-17</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=eb420c49bb731a48fc5183e12e62156cebc24ed3&amp;follow=1'>Tabify source</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
And other style changes.


</td></tr>
<tr class='logheader'><td><span title='2018-05-13 17:41:16 -0400'>2018-05-13</span></td><td class='logsubject'><a href='/torus/commit/client.c?id=de8e1ae01e4bd970b640b16728d416cef17a8c19&amp;follow=1'>Fix ncurses color pair numbering</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
This was dumb. Of course all the color pairs fit in 64, but I was
shifting too much because my own representation includes the bright bit.


</td></tr>
<tr class='logheader'><td><span title='2018-04-09 01:25:43 -0400'>2018-04-09</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=d5d7c11a43941f51b7fcbc7614fc81fb6cc8d883&amp;follow=1'>Use anonymous union</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-04-09 01:00:54 -0400'>2018-04-09</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=b2ad77d0be34b7cbfd5dd9dcc55c3c93811edbc6&amp;follow=1'>Replace #define with enum or const where possible</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-31 22:05:47 -0400'>2018-03-31</span></td><td class='logsubject'><a href='/torus/commit/Makefile?id=5273386983f8579f8fe8ba2d54daaacb4cb0d0a4&amp;follow=1'>Link against ncurses</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:58:58 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/server.c?id=a7339f0e1edff37a532c459ce6467f16749383d6&amp;follow=1'>Miscellaneous code cleanup</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:58:18 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/server.c?id=a3f0e073afa6e5ae84829e8b655afbff19e23a0e&amp;follow=1'>Pass message structs by value</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:55:46 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/meta.c?id=02bb28d98b614303f4a0dbcc4ea2f327ac46ed80&amp;follow=1'>Use stdio in merge and meta</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:55:18 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=8a4618a20339ed233cc5e5a6a4e32c4344f97c1c&amp;follow=1'>Clean up spawn constants</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:54:26 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=737c28c63c525fcc033bd9f0adb36e2c65d9f6a8&amp;follow=1'>Rename Tile timestamps {create,modify,access}Time</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:45:17 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=f883e5bf73cc11f545ef5a72cbebf8f2aeea69da&amp;follow=1'>Pack message type enums</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:39:40 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=456b632b849de3a9615ef17b51cf27046234f6f4&amp;follow=1'>Undef COLOR_ constants in torus.h</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2018-03-05 12:37:52 -0500'>2018-03-05</span></td><td class='logsubject'><a href='/torus/commit/Makefile?id=6f067e41c8163982310546246a5d5b64457f078f&amp;follow=1'>Generate tags</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-10-03 12:32:05 -0400'>2017-10-03</span></td><td class='logsubject'><a href='/torus/commit/Makefile?id=482b094a794c56a2052be81fdb50d3da1e87d15d&amp;follow=1'>Simplify Makefile with pattern rule</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
Insert rant about how GNU make handles the .c rule with extra
dependencies.

Also I don't care that everything links curses now.


</td></tr>
<tr class='logheader'><td><span title='2017-09-27 15:28:16 -0400'>2017-09-27</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=e3604c1fe2a8cf89e5d9d1e2919da103127af2dd&amp;follow=1'>Remove leading blank lines</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-09-27 15:25:58 -0400'>2017-09-27</span></td><td class='logsubject'><a href='/torus/commit/README?id=484c8a39e1cec59144babfcc0466c69557e5030b&amp;follow=1'>Add merge.c to README</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-09-03 15:34:21 -0400'>2017-09-03</span></td><td class='logsubject'><a href='/torus/commit/server.c?id=811419e17b70f93cb85fc26c9b7227f53349a7a7&amp;follow=1'>Assert client coords are valid after movement</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-09-03 14:57:17 -0400'>2017-09-03</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=7a95cab1c4f9bd8abfc721af63b7a33096d8dfb9&amp;follow=1'>Relicense AGPL</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
I know it's already published under a permissive license in what is
probably its final form, but I want to license it AGPL anyway on
principle following some conversations I had about open source,
corporations and copyleft.


</td></tr>
<tr class='logheader'><td><span title='2017-09-01 13:55:48 -0400'>2017-09-01</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=fbb416f2bdd9dedcbc7b4471af335e2b65331953&amp;follow=1'>Revert "Add client readOnly mode"</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
This reverts commit 34f25ae40a3db9369e9d98b3814f2b93bbc21451.


</td></tr>
<tr class='logheader'><td><span title='2017-09-01 12:33:54 -0400'>2017-09-01</span></td><td class='logsubject'><a href='/torus/commit/server.c?id=0dae2c10c7db909964d0c00607e983c1fc9db978&amp;follow=1'>Remove clientRemove call from clientCast</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
If an error occurs on a client socket during a broadcast, that client
will show up in the kqueue loop with EV_EOF and get removed that way.

Tested by sending SIGKILL to a client and watching its cursor disappear.


</td></tr>
<tr class='logheader'><td><span title='2017-09-01 00:08:07 -0400'>2017-09-01</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=34f25ae40a3db9369e9d98b3814f2b93bbc21451&amp;follow=1'>Add client readOnly mode</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-08-31 15:37:36 -0400'>2017-08-31</span></td><td class='logsubject'><a href='/torus/commit/merge.c?id=aa81ed84fc03060ea270766427d9e3232d130855&amp;follow=1'>Clean up merge tool</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
Choose the version with the most recent access if the modify times are
the same.


</td></tr>
<tr class='logheader'><td><span title='2017-08-31 13:45:12 -0400'>2017-08-31</span></td><td class='logsubject'><a href='/torus/commit/merge.c?id=cf94e1b5a227b0a64eae2de78884c14b44dada6b&amp;follow=1'>Choose B for tiles with equal modify times</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
This way newer access counts and times will be preserved.


</td></tr>
<tr class='logheader'><td><span title='2017-08-31 01:00:02 -0400'>2017-08-31</span></td><td class='logsubject'><a href='/torus/commit/merge.c?id=ccf62ec6e3bbf785928962223221eefc8cfef653&amp;follow=1'>Add quick data file merge tool</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
Hopefully I won't have to use it ever again.


</td></tr>
<tr class='logheader'><td><span title='2017-08-30 11:16:22 -0400'>2017-08-30</span></td><td class='logsubject'><a href='/torus/commit/client.c?id=3a556f5f020d627e40b002be5370799f411e7869&amp;follow=1'>Use only foreground color for selecting spawn</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-08-29 18:33:59 -0400'>2017-08-29</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=931289b9c11fbf1ba61442f83b3199e44bebaaf2&amp;follow=1'>Add four additional spawns</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-08-28 23:38:40 -0400'>2017-08-28</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=66761cd30ee1da5b820c89c38fac6caf42fbe715&amp;follow=1'>Add respawning</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-08-26 23:46:14 -0400'>2017-08-26</span></td><td class='logsubject'><a href='/torus/commit/torus.h?id=0fd1719a5de2fa9ca11f57564ee55cf0608bce16&amp;follow=1'>Move license above includes</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
Why was it down there?


</td></tr>
<tr class='logheader'><td><span title='2017-08-26 19:32:55 -0400'>2017-08-26</span></td><td class='logsubject'><a href='/torus/commit/snapshot.sh?id=49c49d4646aba28e1b92681af2e7f476607f5c7b&amp;follow=1'>Snapshot metadata</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-08-26 16:51:14 -0400'>2017-08-26</span></td><td class='logsubject'><a href='/torus/commit/README?id=77c3f17ae4e84fb83c6656f1b8496958f573a44b&amp;follow=1'>Add meta.c to README</a></td><td>June McEnroe</td></tr>
<tr class='nohover-highlight'><td/><td colspan='3' class='logmsg'>
</td></tr>
<tr class='logheader'><td><span title='2017-08-26 16:47:57 -0400'>2017-08-26</span></td><td class='logsubject'><a href='/torus/commit/server.c?id=c1eee615c85ef9aebbb1b86b372535e61ca8d6ce&amp;follow=1'>Use Makefile</a></td><td>June McEnroe