aboutsummaryrefslogtreecommitdiff
path: root/degesch.c
diff options
context:
space:
mode:
Diffstat (limited to 'degesch.c')
-rw-r--r--degesch.c174
1 files changed, 97 insertions, 77 deletions
diff --git a/degesch.c b/degesch.c
index 8b79ffd..c3aab2d 100644
--- a/degesch.c
+++ b/degesch.c
@@ -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) \