degesch: refactor logging a bit

This commit is contained in:
Přemysl Eric Janouch 2015-04-25 13:41:10 +02:00
parent a75fc35295
commit c38dfced51
1 changed files with 97 additions and 77 deletions

174
degesch.c
View File

@ -284,6 +284,14 @@ enum buffer_line_type
BUFFER_LINE_ERROR ///< Whatever error messages BUFFER_LINE_ERROR ///< Whatever error messages
}; };
struct buffer_line_args
{
char *who; ///< Name of the origin or NULL (user)
char *object; ///< Object of action
char *text; ///< Text of message
char *reason; ///< Reason for PART, KICK, QUIT
};
struct buffer_line struct buffer_line
{ {
LIST_HEADER (struct buffer_line) LIST_HEADER (struct buffer_line)
@ -294,9 +302,7 @@ struct buffer_line
int flags; ///< Flags int flags; ///< Flags
time_t when; ///< Time of the event time_t when; ///< Time of the event
char *who; ///< Name of the origin or NULL (user) struct buffer_line_args args; ///< Arguments
char *object; ///< Text of message, object of action
char *reason; ///< Reason for PART, KICK, QUIT
}; };
struct buffer_line * struct buffer_line *
@ -309,9 +315,10 @@ buffer_line_new (void)
static void static void
buffer_line_destroy (struct buffer_line *self) buffer_line_destroy (struct buffer_line *self)
{ {
free (self->who); free (self->args.who);
free (self->object); free (self->args.object);
free (self->reason); free (self->args.text);
free (self->args.reason);
free (self); free (self);
} }
@ -824,10 +831,6 @@ setup_signal_handlers (void)
// --- Buffers ----------------------------------------------------------------- // --- Buffers -----------------------------------------------------------------
static void buffer_send (struct app_context *ctx, struct buffer *buffer,
enum buffer_line_type type, int flags, const char *origin,
const char *reason, const char *format, ...) ATTRIBUTE_PRINTF (7, 8);
static void static void
buffer_update_time (struct app_context *ctx, time_t now) buffer_update_time (struct app_context *ctx, time_t now)
{ {
@ -859,19 +862,25 @@ buffer_line_display (struct app_context *ctx, struct buffer_line *line)
// confused as to when an event has happened // confused as to when an event has happened
buffer_update_time (ctx, line->when); buffer_update_time (ctx, line->when);
struct str text; struct str output;
str_init (&text); str_init (&output);
struct tm current; struct tm current;
if (!localtime_r (&line->when, &current)) if (!localtime_r (&line->when, &current))
print_error ("%s: %s", "localtime_r", strerror (errno)); print_error ("%s: %s", "localtime_r", strerror (errno));
else else
str_append_printf (&text, "%02d:%02d:%02d ", str_append_printf (&output, "%02d:%02d:%02d ",
current.tm_hour, current.tm_min, current.tm_sec); current.tm_hour, current.tm_min, current.tm_sec);
char *who = iconv_xstrdup (ctx->term_from_utf8, line->who, -1, NULL); #define GET_FIELD(name) char *name = line->args.name \
char *object = iconv_xstrdup (ctx->term_from_utf8, line->object, -1, NULL); ? iconv_xstrdup (ctx->term_from_utf8, line->args.name, -1, NULL) : NULL
char *reason = iconv_xstrdup (ctx->term_from_utf8, line->reason, -1, NULL);
GET_FIELD (who);
GET_FIELD (object);
GET_FIELD (text);
GET_FIELD (reason);
#undef GET_FIELD
// TODO: colorize the output, note that we shouldn't put everything through // TODO: colorize the output, note that we shouldn't put everything through
// tputs but only the attribute strings. That might prove a bit // tputs but only the attribute strings. That might prove a bit
@ -882,7 +891,7 @@ buffer_line_display (struct app_context *ctx, struct buffer_line *line)
char *nick = NULL; char *nick = NULL;
const char *userhost = NULL; const char *userhost = NULL;
if (*who) if (who)
{ {
nick = irc_cut_nickname (who); nick = irc_cut_nickname (who);
userhost = irc_find_userhost (who); userhost = irc_find_userhost (who);
@ -891,70 +900,71 @@ buffer_line_display (struct app_context *ctx, struct buffer_line *line)
switch (line->type) switch (line->type)
{ {
case BUFFER_LINE_PRIVMSG: case BUFFER_LINE_PRIVMSG:
str_append_printf (&text, "<%s> %s", nick, object); str_append_printf (&output, "<%s> %s", nick, text);
break; break;
case BUFFER_LINE_ACTION: case BUFFER_LINE_ACTION:
str_append_printf (&text, " * %s %s", nick, object); str_append_printf (&output, " * %s %s", nick, text);
break; break;
case BUFFER_LINE_NOTICE: case BUFFER_LINE_NOTICE:
str_append_printf (&text, " - Notice(%s): %s", nick, object); str_append_printf (&output, " - Notice(%s): %s", nick, text);
break; break;
case BUFFER_LINE_JOIN: case BUFFER_LINE_JOIN:
if (*who) if (who)
str_append_printf (&text, "--> %s (%s) has joined %s", str_append_printf (&output, "--> %s (%s) has joined %s",
nick, userhost, object); nick, userhost, object);
else else
str_append_printf (&text, "--> You have joined %s", object); str_append_printf (&output, "--> You have joined %s", object);
break; break;
case BUFFER_LINE_PART: case BUFFER_LINE_PART:
if (*who) if (who)
str_append_printf (&text, "<-- %s (%s) has left %s (%s)", str_append_printf (&output, "<-- %s (%s) has left %s (%s)",
nick, userhost, object, reason); nick, userhost, object, reason);
else else
str_append_printf (&text, "<-- You have left %s (%s)", str_append_printf (&output, "<-- You have left %s (%s)",
object, reason); object, reason);
break; break;
case BUFFER_LINE_KICK: case BUFFER_LINE_KICK:
if (*who) if (who)
str_append_printf (&text, "<-- %s has kicked %s (%s)", str_append_printf (&output, "<-- %s has kicked %s (%s)",
nick, object, reason); nick, object, reason);
else else
str_append_printf (&text, "<-- You have kicked %s (%s)", str_append_printf (&output, "<-- You have kicked %s (%s)",
object, reason); object, reason);
break; break;
case BUFFER_LINE_NICK: case BUFFER_LINE_NICK:
if (*who) if (who)
str_append_printf (&text, " - %s is now known as %s", str_append_printf (&output, " - %s is now known as %s",
nick, object); nick, object);
else else
str_append_printf (&text, " - You are now known as %s", object); str_append_printf (&output, " - You are now known as %s", object);
break; break;
case BUFFER_LINE_TOPIC: case BUFFER_LINE_TOPIC:
if (*who) if (who)
str_append_printf (&text, str_append_printf (&output,
" - %s has changed the topic to: %s", nick, object); " - %s has changed the topic to: %s", nick, text);
else else
str_append_printf (&text, str_append_printf (&output,
" - You have changed the topic to: %s", object); " - You have changed the topic to: %s", text);
break; break;
case BUFFER_LINE_QUIT: case BUFFER_LINE_QUIT:
if (*who) if (who)
str_append_printf (&text, "<-- %s (%s) has quit (%s)", str_append_printf (&output, "<-- %s (%s) has quit (%s)",
nick, userhost, reason); nick, userhost, reason);
else else
str_append_printf (&text, "<-- You have quit (%s)", reason); str_append_printf (&output, "<-- You have quit (%s)", reason);
break; break;
case BUFFER_LINE_STATUS: case BUFFER_LINE_STATUS:
str_append_printf (&text, " - %s", object); str_append_printf (&output, " - %s", text);
break; break;
case BUFFER_LINE_ERROR: case BUFFER_LINE_ERROR:
str_append_printf (&text, "=!= %s", object); str_append_printf (&output, "=!= %s", text);
} }
free (nick); free (nick);
free (who); free (who);
free (object); free (object);
free (text);
free (reason); free (reason);
struct app_readline_state state; struct app_readline_state state;
@ -964,32 +974,23 @@ buffer_line_display (struct app_context *ctx, struct buffer_line *line)
// TODO: write the line to a log file; note that the global and server // TODO: write the line to a log file; note that the global and server
// buffers musn't collide with filenames // buffers musn't collide with filenames
printf ("%s\n", text.str); printf ("%s\n", output.str);
str_free (&text); str_free (&output);
if (ctx->readline_prompt_shown) if (ctx->readline_prompt_shown)
app_readline_restore (&state, ctx->readline_prompt); app_readline_restore (&state, ctx->readline_prompt);
} }
static void static void
buffer_send (struct app_context *ctx, struct buffer *buffer, buffer_send_internal (struct app_context *ctx, struct buffer *buffer,
enum buffer_line_type type, int flags, enum buffer_line_type type, int flags,
const char *origin, const char *reason, const char *format, ...) struct buffer_line_args a)
{ {
va_list ap;
va_start (ap, format);
struct str text;
str_init (&text);
str_append_vprintf (&text, format, ap);
va_end (ap);
struct buffer_line *line = buffer_line_new (); struct buffer_line *line = buffer_line_new ();
line->type = type; line->type = type;
line->flags = flags; line->flags = flags;
line->when = time (NULL); line->when = time (NULL);
line->who = xstrdup (origin ? origin : ""); line->args = a;
line->object = str_steal (&text);
line->reason = xstrdup (reason ? reason : "");
LIST_APPEND_WITH_TAIL (buffer->lines, buffer->lines_tail, line); LIST_APPEND_WITH_TAIL (buffer->lines, buffer->lines_tail, line);
buffer->lines_count++; buffer->lines_count++;
@ -1007,10 +1008,16 @@ buffer_send (struct app_context *ctx, struct buffer *buffer,
} }
} }
#define buffer_send_status(ctx, buffer, ...) \ #define buffer_send(ctx, buffer, type, flags, ...) \
buffer_send (ctx, buffer, BUFFER_LINE_STATUS, 0, NULL, NULL, __VA_ARGS__) buffer_send_internal ((ctx), (buffer), (type), (flags), \
#define buffer_send_error(ctx, buffer, ...) \ (struct buffer_line_args) { __VA_ARGS__ })
buffer_send (ctx, buffer, BUFFER_LINE_ERROR, 0, NULL, NULL, __VA_ARGS__)
#define buffer_send_status(ctx, buffer, ...) \
buffer_send (ctx, buffer, BUFFER_LINE_STATUS, 0, \
.text = xstrdup_printf (__VA_ARGS__))
#define buffer_send_error(ctx, buffer, ...) \
buffer_send (ctx, buffer, BUFFER_LINE_ERROR, 0, \
.text = xstrdup_printf (__VA_ARGS__))
static struct buffer * static struct buffer *
buffer_by_name (struct app_context *ctx, const char *name) buffer_by_name (struct app_context *ctx, const char *name)
@ -1962,7 +1969,8 @@ irc_handle_join (struct app_context *ctx, const struct irc_message *msg)
if (buffer) if (buffer)
{ {
buffer_send (ctx, buffer, BUFFER_LINE_JOIN, 0, buffer_send (ctx, buffer, BUFFER_LINE_JOIN, 0,
msg->prefix, NULL, "%s", channel_name); .who = xstrdup (msg->prefix),
.object = xstrdup (channel_name));
} }
} }
@ -1978,7 +1986,7 @@ irc_handle_kick (struct app_context *ctx, const struct irc_message *msg)
|| irc_is_channel (ctx, target)) || irc_is_channel (ctx, target))
return; return;
const char *message = NULL; const char *message = "";
if (msg->params.len > 2) if (msg->params.len > 2)
message = msg->params.vector[2]; message = msg->params.vector[2];
@ -1995,7 +2003,9 @@ irc_handle_kick (struct app_context *ctx, const struct irc_message *msg)
if (buffer) if (buffer)
{ {
buffer_send (ctx, buffer, BUFFER_LINE_KICK, 0, buffer_send (ctx, buffer, BUFFER_LINE_KICK, 0,
msg->prefix, message, "%s", target); .who = xstrdup (msg->prefix),
.object = xstrdup (target),
.reason = xstrdup (message));
} }
} }
@ -2035,7 +2045,8 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
str_map_set (&ctx->irc_buffer_map, user->nickname, NULL); str_map_set (&ctx->irc_buffer_map, user->nickname, NULL);
buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0, buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0,
msg->prefix, NULL, "%s", new_nickname); .who = xstrdup (msg->prefix),
.object = xstrdup (new_nickname));
// TODO: use a full weechat-style buffer name here // TODO: use a full weechat-style buffer name here
buffer_rename (ctx, pm_buffer, new_nickname); buffer_rename (ctx, pm_buffer, new_nickname);
} }
@ -2053,7 +2064,7 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
continue; continue;
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0, buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
NULL, NULL, "%s", new_nickname); .object = xstrdup (new_nickname));
} }
} }
else else
@ -2065,7 +2076,8 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
str_map_find (&ctx->irc_buffer_map, iter->channel->name); str_map_find (&ctx->irc_buffer_map, iter->channel->name);
hard_assert (buffer != NULL); hard_assert (buffer != NULL);
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0, buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
msg->prefix, NULL, "%s", new_nickname); .who = xstrdup (msg->prefix),
.object = xstrdup (new_nickname));
} }
} }
@ -2096,7 +2108,7 @@ irc_handle_part (struct app_context *ctx, const struct irc_message *msg)
if (!irc_is_channel (ctx, channel_name)) if (!irc_is_channel (ctx, channel_name))
return; return;
const char *message = NULL; const char *message = "";
if (msg->params.len > 1) if (msg->params.len > 1)
message = msg->params.vector[1]; message = msg->params.vector[1];
@ -2116,7 +2128,9 @@ irc_handle_part (struct app_context *ctx, const struct irc_message *msg)
if (buffer) if (buffer)
{ {
buffer_send (ctx, buffer, BUFFER_LINE_PART, 0, buffer_send (ctx, buffer, BUFFER_LINE_PART, 0,
msg->prefix, message, "%s", channel_name); .who = xstrdup (msg->prefix),
.object = xstrdup (channel_name),
.reason = xstrdup (message));
} }
} }
@ -2161,7 +2175,8 @@ irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg)
// TODO: handle CTCP messages // TODO: handle CTCP messages
// TODO: highlights // TODO: highlights
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0, buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
msg->prefix, NULL, "%s", message); .who = xstrdup (msg->prefix),
.text = xstrdup (message));
} }
} }
@ -2181,7 +2196,7 @@ irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
if (!user) if (!user)
return; return;
const char *message = NULL; const char *message = "";
if (msg->params.len > 0) if (msg->params.len > 0)
message = msg->params.vector[0]; message = msg->params.vector[0];
@ -2191,7 +2206,8 @@ irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
if (buffer) if (buffer)
{ {
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0, buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
msg->prefix, message, "%s", ""); .who = xstrdup (msg->prefix),
.reason = xstrdup (message));
// TODO: set some kind of a flag in the buffer and when the user // TODO: set some kind of a flag in the buffer and when the user
// reappers on a channel (JOIN), log a "is back online" message. // reappers on a channel (JOIN), log a "is back online" message.
@ -2205,7 +2221,8 @@ irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
buffer = str_map_find (&ctx->irc_buffer_map, iter->channel->name); buffer = str_map_find (&ctx->irc_buffer_map, iter->channel->name);
if (buffer) if (buffer)
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0, buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
msg->prefix, message, "%s", ""); .who = xstrdup (msg->prefix),
.reason = xstrdup (message));
// This destroys "iter" which doesn't matter to us // This destroys "iter" which doesn't matter to us
irc_remove_user_from_channel (user, iter->channel); irc_remove_user_from_channel (user, iter->channel);
@ -2238,7 +2255,8 @@ irc_handle_topic (struct app_context *ctx, const struct irc_message *msg)
if (buffer) if (buffer)
{ {
buffer_send (ctx, buffer, BUFFER_LINE_TOPIC, 0, buffer_send (ctx, buffer, BUFFER_LINE_TOPIC, 0,
msg->prefix, NULL, "%s", topic); .who = xstrdup (msg->prefix),
.text = xstrdup (topic));
} }
} }
@ -2559,11 +2577,12 @@ log_outcoming_privmsg (struct app_context *ctx,
{ {
if (buffer) if (buffer)
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0, buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
ctx->irc_user->nickname, NULL, "%s", line); .who = xstrdup (ctx->irc_user->nickname),
.text = xstrdup (line));
else else
// TODO: fix logging // TODO: fix logging
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0, buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
NULL, NULL, "MSG(%s): %s", a->target, line); .text = xstrdup_printf ("MSG(%s): %s", a->target, line));
} }
#define SEND_AUTOSPLIT_PRIVMSG(ctx, target, message) \ #define SEND_AUTOSPLIT_PRIVMSG(ctx, target, message) \
@ -2576,11 +2595,12 @@ log_outcoming_notice (struct app_context *ctx,
{ {
if (buffer) if (buffer)
buffer_send (ctx, buffer, BUFFER_LINE_NOTICE, 0, buffer_send (ctx, buffer, BUFFER_LINE_NOTICE, 0,
ctx->irc_user->nickname, NULL, "%s", line); .who = xstrdup (ctx->irc_user->nickname),
.text = xstrdup (line));
else else
// TODO: fix logging // TODO: fix logging
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0, buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
NULL, NULL, "Notice -> %s: %s", a->target, line); .text = xstrdup_printf ("Notice -> %s: %s", a->target, line));
} }
#define SEND_AUTOSPLIT_NOTICE(ctx, target, message) \ #define SEND_AUTOSPLIT_NOTICE(ctx, target, message) \