[PATCH 1/3] Remove unused time_t parameter

[PATCH 1/3] Remove unused time_t parameter

From: Klemens Nanni
uiFormat() passes time through multiple functions up into the flow()
where it is assigned per line doing nothing.

flow(), where actual messages are wrapped and marked up, seems to
be the wrong place to handle time(stamps) anyway since at this point
the nick/action/etc. was already printed.

The following warning will be dealt with in the next commit:

ui.c:591:41: warning: unused parameter 'time' [-Wunused-parameter]
        uint id, enum Heat heat, const time_t *time, const char *format, ...

No functional change.
---
 buffer.c |  5 +----
 chat.h   |  4 ++--
 handle.c |  4 ++--
 ui.c     | 13 ++++++-------
 4 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/buffer.c b/buffer.c
index ef175b8..7ef52fe 100644
--- a/buffer.c
+++ b/buffer.c
@@ -103,7 +103,6 @@ static int flow(struct Lines *hard, int cols, const struct Line *soft) {
 
 	struct Line *line = linesNext(hard);
 	line->heat = soft->heat;
-	line->time = soft->time;
 	line->str = strdup(soft->str);
 	if (!line->str) err(EX_OSERR, "strdup");
 
@@ -178,7 +177,6 @@ static int flow(struct Lines *hard, int cols, const struct Line *soft) {
 		flowed++;
 		line = linesNext(hard);
 		line->heat = soft->heat;
-		line->time = soft->time;
 
 		size_t cap = StyleCap + align + strlen(&wrap[n]) + 1;
 		line->str = malloc(cap);
@@ -200,11 +198,10 @@ static int flow(struct Lines *hard, int cols, const struct Line *soft) {
 
 int bufferPush(
 	struct Buffer *buffer, int cols, enum Heat thresh,
-	enum Heat heat, time_t time, const char *str
+	enum Heat heat, const char *str
 ) {
 	struct Line *soft = linesNext(&buffer->soft);
 	soft->heat = heat;
-	soft->time = time;
 	soft->str = strdup(str);
 	if (!soft->str) err(EX_OSERR, "strdup");
 	if (heat < thresh) return 0;
diff --git a/chat.h b/chat.h
index 1b1c338..a1bc77e 100644
--- a/chat.h
+++ b/chat.h
@@ -290,7 +290,7 @@ void uiMoveID(uint id, uint num);
 void uiCloseID(uint id);
 void uiCloseNum(uint id);
 void uiRead(void);
-void uiWrite(uint id, enum Heat heat, const time_t *time, const char *str);
+void uiWrite(uint id, enum Heat heat, const char *str);
 void uiFormat(
 	uint id, enum Heat heat, const time_t *time, const char *format, ...
 ) __attribute__((format(printf, 4, 5)));
@@ -310,7 +310,7 @@ const struct Line *bufferSoft(const struct Buffer *buffer, size_t i);
 const struct Line *bufferHard(const struct Buffer *buffer, size_t i);
 int bufferPush(
 	struct Buffer *buffer, int cols, enum Heat thresh,
-	enum Heat heat, time_t time, const char *str
+	enum Heat heat, const char *str
 );
 int bufferReflow(
 	struct Buffer *buffer, int cols, enum Heat thresh, size_t tail
diff --git a/handle.c b/handle.c
index ddf43e8..5989d98 100644
--- a/handle.c
+++ b/handle.c
@@ -317,7 +317,7 @@ static void handleErrorNoMOTD(struct Message *msg) {
 static void handleReplyHelp(struct Message *msg) {
 	require(msg, false, 3);
 	urlScan(Network, NULL, msg->params[2]);
-	uiWrite(Network, Warm, tagTime(msg), msg->params[2]);
+	uiWrite(Network, Warm, msg->params[2]);
 }
 
 static void handleJoin(struct Message *msg) {
@@ -565,7 +565,7 @@ static void handleReplyWho(struct Message *msg) {
 
 static void handleReplyEndOfWho(struct Message *msg) {
 	require(msg, false, 2);
-	uiWrite(idFor(msg->params[1]), Cold, tagTime(msg), whoBuf);
+	uiWrite(idFor(msg->params[1]), Cold, whoBuf);
 	whoCat.len = 0;
 }
 
diff --git a/ui.c b/ui.c
index e3fd467..d84265b 100644
--- a/ui.c
+++ b/ui.c
@@ -558,16 +558,15 @@ static void notify(uint id, const char *str) {
 	_exit(EX_CONFIG);
 }
 
-void uiWrite(uint id, enum Heat heat, const time_t *src, const char *str) {
+void uiWrite(uint id, enum Heat heat, const char *str) {
 	struct Window *window = windows.ptrs[windowFor(id)];
-	time_t ts = (src ? *src : time(NULL));
 
 	if (heat >= window->thresh) {
 		if (!window->unreadSoft++) window->unreadHard = 0;
 	}
 	if (window->mark && heat > Cold) {
 		if (!window->unreadWarm++) {
-			int lines = bufferPush(window->buffer, COLS, false, Warm, ts, "");
+			int lines = bufferPush(window->buffer, COLS, false, Warm, "");
 			if (window->scroll) windowScroll(window, lines);
 			if (window->unreadSoft > 1) {
 				window->unreadSoft++;
@@ -577,7 +576,7 @@ void uiWrite(uint id, enum Heat heat, const time_t *src, const char *str) {
 		if (heat > window->heat) window->heat = heat;
 		statusUpdate();
 	}
-	int lines = bufferPush(window->buffer, COLS, window->thresh, heat, ts, str);
+	int lines = bufferPush(window->buffer, COLS, window->thresh, heat, str);
 	window->unreadHard += lines;
 	if (window->scroll) windowScroll(window, lines);
 	if (window == windows.ptrs[windows.show]) windowUpdate();
@@ -597,7 +596,7 @@ void uiFormat(
 	int len = vsnprintf(buf, sizeof(buf), format, ap);
 	va_end(ap);
 	assert((size_t)len < sizeof(buf));
-	uiWrite(id, heat, time, buf);
+	uiWrite(id, heat, buf);
 }
 
 static void resize(void) {
@@ -848,7 +847,7 @@ static void keyCode(int code) {
 		break; case KeyMetaD: edit(id, EditDeleteNextWord, 0);
 		break; case KeyMetaF: edit(id, EditNextWord, 0);
 		break; case KeyMetaL: bufferList(window->buffer);
-		break; case KeyMetaM: uiWrite(id, Cold, NULL, "");
+		break; case KeyMetaM: uiWrite(id, Cold, "");
 		break; case KeyMetaN: windowScrollHot(window, +1);
 		break; case KeyMetaP: windowScrollHot(window, -1);
 		break; case KeyMetaQ: edit(id, EditCollapse, 0);
@@ -1061,7 +1060,7 @@ void uiLoad(const char *name) {
 			if (!time) break;
 			enum Heat heat = (version > 2 ? readTime(file) : Cold);
 			readString(file, &buf, &cap);
-			bufferPush(window->buffer, COLS, window->thresh, heat, time, buf);
+			bufferPush(window->buffer, COLS, window->thresh, heat, buf);
 		}
 		window->unreadHard = bufferReflow(
 			window->buffer, COLS, window->thresh, window->unreadSoft
-- 
2.30.0

1 reply

[PATCH 2/3] Print timestamps for UI messages

From: Klemens Nanni
It is useful to know *when* a message arrived;  there is undocumented
functionality (Meta-L) to view buffers incl. timestamps but that is
not exactly user friendly.
---
 ui.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/ui.c b/ui.c
index d84265b..950d9d3 100644
--- a/ui.c
+++ b/ui.c
@@ -588,12 +588,22 @@ void uiWrite(uint id, enum Heat heat, const char *str) {
 }
 
 void uiFormat(
-	uint id, enum Heat heat, const time_t *time, const char *format, ...
+	uint id, enum Heat heat, const time_t *tagTime, const char *format, ...
 ) {
 	char buf[1024];
+	size_t formatsz = sizeof(buf);
+	char *formatp = buf;
+
+	time_t ts = (tagTime ? *tagTime : time(NULL));
+	struct tm *timeinfo = localtime(&ts);
+	if (!timeinfo) err(EX_OSERR, "localtime");
+	size_t timesz = strftime(buf, sizeof(buf), "[%T] ", timeinfo);
+	formatp += timesz;
+	formatsz -= timesz;
+
 	va_list ap;
 	va_start(ap, format);
-	int len = vsnprintf(buf, sizeof(buf), format, ap);
+	int len = vsnprintf(formatp, formatsz, format, ap);
 	va_end(ap);
 	assert((size_t)len < sizeof(buf));
 	uiWrite(id, heat, buf);
-- 
2.30.0

1 reply

[PATCH 3/3] Make timestamps optional with "-T, timestamps"

From: Klemens Nanni
Some might not want them so make this feature opt-in.
One could easily extend this into "-T fmt, timestamps = fmt" to allow
specifying a strftime(3) format string and therefore leave flexibility
to the user, but that might as well turn into feature-creep rather
quickly -- anyways, the code easily allows this, but that's time for
another commit.
---
 catgirl.1 |  5 ++++-
 chat.c    |  2 ++
 chat.h    |  1 +
 ui.c      | 16 ++++++++--------
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/catgirl.1 b/catgirl.1
index a7efeb3..0934de7 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -8,7 +8,7 @@
 .
 .Sh SYNOPSIS
 .Nm
-.Op Fl Relv
+.Op Fl RTelv
 .Op Fl C Ar copy
 .Op Fl H Ar hash
 .Op Fl I Ar highlight
@@ -159,6 +159,9 @@ Bind to source address
 .Ar host
 when connecting to the server.
 .
+.It Fl T , Cm timestamps
+Show message timestamps.
+.
 .It Fl a Ar user : Ns Ar pass , Cm sasl-plain = Ar user : Ns Ar pass
 Authenticate as
 .Ar user
diff --git a/chat.c b/chat.c
index ebffe46..1f80404 100644
--- a/chat.c
+++ b/chat.c
@@ -204,6 +204,7 @@ int main(int argc, char *argv[]) {
 		{ .val = 'O', .name = "open", required_argument },
 		{ .val = 'R', .name = "restrict", no_argument },
 		{ .val = 'S', .name = "bind", required_argument },
+		{ .val = 'T', .name = "timestamps", no_argument },
 		{ .val = 'a', .name = "sasl-plain", required_argument },
 		{ .val = 'c', .name = "cert", required_argument },
 		{ .val = 'e', .name = "sasl-external", no_argument },
@@ -240,6 +241,7 @@ int main(int argc, char *argv[]) {
 			break; case 'O': utilPush(&urlOpenUtil, optarg);
 			break; case 'R': self.restricted = true;
 			break; case 'S': bind = optarg;
+			break; case 'T': self.timestamps = true;
 			break; case 'a': sasl = true; self.plain = optarg;
 			break; case 'c': cert = optarg;
 			break; case 'e': sasl = true;
diff --git a/chat.h b/chat.h
index a1bc77e..6b935e5 100644
--- a/chat.h
+++ b/chat.h
@@ -193,6 +193,7 @@ extern struct Self {
 	char *host;
 	enum Color color;
 	char *quit;
+	bool timestamps;
 } self;
 
 static inline void set(char **field, const char *value) {
diff --git a/ui.c b/ui.c
index 950d9d3..0b8b762 100644
--- a/ui.c
+++ b/ui.c
@@ -593,14 +593,14 @@ void uiFormat(
 	char buf[1024];
 	size_t formatsz = sizeof(buf);
 	char *formatp = buf;
-
-	time_t ts = (tagTime ? *tagTime : time(NULL));
-	struct tm *timeinfo = localtime(&ts);
-	if (!timeinfo) err(EX_OSERR, "localtime");
-	size_t timesz = strftime(buf, sizeof(buf), "[%T] ", timeinfo);
-	formatp += timesz;
-	formatsz -= timesz;
-
+	if (self.timestamps) {
+		time_t ts = (tagTime ? *tagTime : time(NULL));
+		struct tm *timeinfo = localtime(&ts);
+		if (!timeinfo) err(EX_OSERR, "localtime");
+		size_t timesz = strftime(buf, sizeof(buf), "[%T] ", timeinfo);
+		formatp += timesz;
+		formatsz -= timesz;
+	}
 	va_list ap;
 	va_start(ap, format);
 	int len = vsnprintf(formatp, formatsz, format, ap);
-- 
2.30.0

2 replies

Re: [PATCH 1/3] Remove unused time_t parameter

From: June Bug
> On Jan 19, 2021, at 06:33, Klemens Nanni <klemens@posteo.de> wrote:
> 
> uiFormat() passes time through multiple functions up into the flow()
> where it is assigned per line doing nothing.
> 
> flow(), where actual messages are wrapped and marked up, seems to
> be the wrong place to handle time(stamps) anyway since at this point
> the nick/action/etc. was already printed.

I have an alternative approach in mind for this feature which makes
use of the timestamps stored in the Buffer, but I haven’t any work
on it yet. I’ll keep this series in mind, and I think allowing -T
to specify the format is a good idea.

Re: [PATCH 1/3] Remove unused time_t parameter

From: Klemens Nanni
On Tue, Jan 19, 2021 at 03:19:00PM -0500, June Bug wrote:
> I have an alternative approach in mind for this feature which makes
> use of the timestamps stored in the Buffer, but I haven’t any work
> on it yet. I’ll keep this series in mind, and I think allowing -T
> to specify the format is a good idea.

Thank you;  I'll just wait, then.