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
};
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
{
LIST_HEADER (struct buffer_line)
@ -294,9 +302,7 @@ struct buffer_line
int flags; ///< Flags
time_t when; ///< Time of the event
char *who; ///< Name of the origin or NULL (user)
char *object; ///< Text of message, object of action
char *reason; ///< Reason for PART, KICK, QUIT
struct buffer_line_args args; ///< Arguments
};
struct buffer_line *
@ -309,9 +315,10 @@ buffer_line_new (void)
static void
buffer_line_destroy (struct buffer_line *self)
{
free (self->who);
free (self->object);
free (self->reason);
free (self->args.who);
free (self->args.object);
free (self->args.text);
free (self->args.reason);
free (self);
}
@ -824,10 +831,6 @@ setup_signal_handlers (void)
// --- 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
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
buffer_update_time (ctx, line->when);
struct str text;
str_init (&text);
struct str output;
str_init (&output);
struct tm current;
if (!localtime_r (&line->when, &current))
print_error ("%s: %s", "localtime_r", strerror (errno));
else
str_append_printf (&text, "%02d:%02d:%02d ",
str_append_printf (&output, "%02d:%02d:%02d ",
current.tm_hour, current.tm_min, current.tm_sec);
char *who = iconv_xstrdup (ctx->term_from_utf8, line->who, -1, NULL);
char *object = iconv_xstrdup (ctx->term_from_utf8, line->object, -1, NULL);
char *reason = iconv_xstrdup (ctx->term_from_utf8, line->reason, -1, NULL);
#define GET_FIELD(name) char *name = line->args.name \
? iconv_xstrdup (ctx->term_from_utf8, line->args.name, -1, NULL) : 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
// 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;
const char *userhost = NULL;
if (*who)
if (who)
{
nick = irc_cut_nickname (who);
userhost = irc_find_userhost (who);
@ -891,70 +900,71 @@ buffer_line_display (struct app_context *ctx, struct buffer_line *line)
switch (line->type)
{
case BUFFER_LINE_PRIVMSG:
str_append_printf (&text, "<%s> %s", nick, object);
str_append_printf (&output, "<%s> %s", nick, text);
break;
case BUFFER_LINE_ACTION:
str_append_printf (&text, " * %s %s", nick, object);
str_append_printf (&output, " * %s %s", nick, text);
break;
case BUFFER_LINE_NOTICE:
str_append_printf (&text, " - Notice(%s): %s", nick, object);
str_append_printf (&output, " - Notice(%s): %s", nick, text);
break;
case BUFFER_LINE_JOIN:
if (*who)
str_append_printf (&text, "--> %s (%s) has joined %s",
if (who)
str_append_printf (&output, "--> %s (%s) has joined %s",
nick, userhost, object);
else
str_append_printf (&text, "--> You have joined %s", object);
str_append_printf (&output, "--> You have joined %s", object);
break;
case BUFFER_LINE_PART:
if (*who)
str_append_printf (&text, "<-- %s (%s) has left %s (%s)",
if (who)
str_append_printf (&output, "<-- %s (%s) has left %s (%s)",
nick, userhost, object, reason);
else
str_append_printf (&text, "<-- You have left %s (%s)",
str_append_printf (&output, "<-- You have left %s (%s)",
object, reason);
break;
case BUFFER_LINE_KICK:
if (*who)
str_append_printf (&text, "<-- %s has kicked %s (%s)",
if (who)
str_append_printf (&output, "<-- %s has kicked %s (%s)",
nick, object, reason);
else
str_append_printf (&text, "<-- You have kicked %s (%s)",
str_append_printf (&output, "<-- You have kicked %s (%s)",
object, reason);
break;
case BUFFER_LINE_NICK:
if (*who)
str_append_printf (&text, " - %s is now known as %s",
if (who)
str_append_printf (&output, " - %s is now known as %s",
nick, object);
else
str_append_printf (&text, " - You are now known as %s", object);
str_append_printf (&output, " - You are now known as %s", object);
break;
case BUFFER_LINE_TOPIC:
if (*who)
str_append_printf (&text,
" - %s has changed the topic to: %s", nick, object);
if (who)
str_append_printf (&output,
" - %s has changed the topic to: %s", nick, text);
else
str_append_printf (&text,
" - You have changed the topic to: %s", object);
str_append_printf (&output,
" - You have changed the topic to: %s", text);
break;
case BUFFER_LINE_QUIT:
if (*who)
str_append_printf (&text, "<-- %s (%s) has quit (%s)",
if (who)
str_append_printf (&output, "<-- %s (%s) has quit (%s)",
nick, userhost, reason);
else
str_append_printf (&text, "<-- You have quit (%s)", reason);
str_append_printf (&output, "<-- You have quit (%s)", reason);
break;
case BUFFER_LINE_STATUS:
str_append_printf (&text, " - %s", object);
str_append_printf (&output, " - %s", text);
break;
case BUFFER_LINE_ERROR:
str_append_printf (&text, "=!= %s", object);
str_append_printf (&output, "=!= %s", text);
}
free (nick);
free (who);
free (object);
free (text);
free (reason);
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
// buffers musn't collide with filenames
printf ("%s\n", text.str);
str_free (&text);
printf ("%s\n", output.str);
str_free (&output);
if (ctx->readline_prompt_shown)
app_readline_restore (&state, ctx->readline_prompt);
}
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,
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 ();
line->type = type;
line->flags = flags;
line->when = time (NULL);
line->who = xstrdup (origin ? origin : "");
line->object = str_steal (&text);
line->reason = xstrdup (reason ? reason : "");
line->args = a;
LIST_APPEND_WITH_TAIL (buffer->lines, buffer->lines_tail, line);
buffer->lines_count++;
@ -1007,10 +1008,16 @@ buffer_send (struct app_context *ctx, struct buffer *buffer,
}
}
#define buffer_send_status(ctx, buffer, ...) \
buffer_send (ctx, buffer, BUFFER_LINE_STATUS, 0, NULL, NULL, __VA_ARGS__)
#define buffer_send_error(ctx, buffer, ...) \
buffer_send (ctx, buffer, BUFFER_LINE_ERROR, 0, NULL, NULL, __VA_ARGS__)
#define buffer_send(ctx, buffer, type, flags, ...) \
buffer_send_internal ((ctx), (buffer), (type), (flags), \
(struct buffer_line_args) { __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 *
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)
{
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))
return;
const char *message = NULL;
const char *message = "";
if (msg->params.len > 2)
message = msg->params.vector[2];
@ -1995,7 +2003,9 @@ irc_handle_kick (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
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);
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
buffer_rename (ctx, pm_buffer, new_nickname);
}
@ -2053,7 +2064,7 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
continue;
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
NULL, NULL, "%s", new_nickname);
.object = xstrdup (new_nickname));
}
}
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);
hard_assert (buffer != NULL);
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))
return;
const char *message = NULL;
const char *message = "";
if (msg->params.len > 1)
message = msg->params.vector[1];
@ -2116,7 +2128,9 @@ irc_handle_part (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
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: highlights
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)
return;
const char *message = NULL;
const char *message = "";
if (msg->params.len > 0)
message = msg->params.vector[0];
@ -2191,7 +2206,8 @@ irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
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
// 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);
if (buffer)
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
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)
{
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)
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
// TODO: fix logging
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) \
@ -2576,11 +2595,12 @@ log_outcoming_notice (struct app_context *ctx,
{
if (buffer)
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
// TODO: fix logging
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) \