pidgin/pidgin

Use Meson summary() function.

2021-07-27, Elliott Sales de Andrade
cb640ea0f315
Use Meson summary() function.

Now that we require at least 0.52, we can use Meson's builtin summary printing to display the results of configuration.

Testing Done:
Configured with defaults, and with pixmaps disabled to trigger the warning: https://asciinema.org/a/mV2oxOoVCJNdmrPwgqqUJ3mkU?t=17

Reviewed at https://reviews.imfreedom.org/r/848/
/*
* Purple - Internet Messaging Library
* Copyright (C) Pidgin Developers <devel@pidgin.im>
*
* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <ctype.h>
#include <purple.h>
#include "zephyr_html.h"
typedef struct _zframe zframe;
struct _zframe {
/* common part */
/* true for everything but @color, since inside the parens of that one is
* the color. */
gboolean has_closer;
/* </i>, </font>, </b>, etc. */
const char *closing;
/* text including the opening html thingie. */
GString *text;
/* html_to_zephyr */
/* @i, @b, etc. */
const char *env;
/* }=1, ]=2, )=4, >=8 */
int closer_mask;
/* href for links */
gboolean is_href;
GString *href;
/* zephyr_to_html */
/* }, ], ), > */
char *closer;
};
static zframe *
zframe_new_with_text(const gchar *text, const gchar *closing, gboolean has_closer)
{
zframe *frame = g_new(zframe, 1);
frame->text = g_string_new(text);
frame->closing = closing;
frame->has_closer = has_closer;
return frame;
}
static inline zframe *
zframe_new(const gchar *closing, gboolean has_closer)
{
return zframe_new_with_text("", closing, has_closer);
}
static gboolean
zframe_href_has_prefix(const zframe *frame, const gchar *prefix)
{
gsize prefix_len = strlen(prefix);
return (frame->href->len == (prefix_len + frame->text->len)) &&
!strncmp(frame->href->str, prefix, prefix_len) &&
purple_strequal(frame->href->str + prefix_len, frame->text->str);
}
static gsize
html_to_zephyr_pop(GQueue *frames)
{
zframe *popped = (zframe *)g_queue_pop_head(frames);
zframe *head = (zframe *)g_queue_peek_head(frames);
gsize result = strlen(popped->closing);
if (popped->is_href) {
head->href = popped->text;
} else {
g_string_append(head->text, popped->env);
if (popped->has_closer) {
g_string_append_c(head->text,
(popped->closer_mask & 1) ? '{' :
(popped->closer_mask & 2) ? '[' :
(popped->closer_mask & 4) ? '(' :
'<');
}
g_string_append(head->text, popped->text->str);
if (popped->href) {
if (!purple_strequal(popped->href->str, popped->text->str) &&
!zframe_href_has_prefix(popped, "http://") &&
!zframe_href_has_prefix(popped, "mailto:")) {
g_string_append(head->text, " <");
g_string_append(head->text, popped->href->str);
if (popped->closer_mask & ~8) {
g_string_append_c(head->text, '>');
popped->closer_mask &= ~8;
} else {
g_string_append(head->text, "@{>}");
}
}
g_string_free(popped->href, TRUE);
}
if (popped->has_closer) {
g_string_append_c(head->text,
(popped->closer_mask & 1) ? '}' :
(popped->closer_mask & 2) ? ']' :
(popped->closer_mask & 4) ? ')' :
'>');
}
if (!popped->has_closer) {
head->closer_mask = popped->closer_mask;
}
g_string_free(popped->text, TRUE);
}
g_free(popped);
return result;
}
char *
html_to_zephyr(const char *message)
{
GQueue frames = G_QUEUE_INIT;
zframe *frame, *new_f;
char *ret;
if (*message == '\0')
return g_strdup("");
frame = zframe_new(NULL, FALSE);
frame->href = NULL;
frame->is_href = FALSE;
frame->env = "";
frame->closer_mask = 15;
g_queue_push_head(&frames, frame);
purple_debug_info("zephyr", "html received %s\n", message);
while (*message) {
frame = (zframe *)g_queue_peek_head(&frames);
if (frame->closing && purple_str_has_caseprefix(message, frame->closing)) {
message += html_to_zephyr_pop(&frames);
} else if (*message == '<') {
if (!g_ascii_strncasecmp(message + 1, "i>", 2)) {
new_f = zframe_new("</i>", TRUE);
new_f->href = NULL;
new_f->is_href = FALSE;
new_f->env = "@i";
new_f->closer_mask = 15;
g_queue_push_head(&frames, new_f);
message += 3;
} else if (!g_ascii_strncasecmp(message + 1, "b>", 2)) {
new_f = zframe_new("</b>", TRUE);
new_f->href = NULL;
new_f->is_href = FALSE;
new_f->env = "@b";
new_f->closer_mask = 15;
g_queue_push_head(&frames, new_f);
message += 3;
} else if (!g_ascii_strncasecmp(message + 1, "br>", 3)) {
g_string_append_c(frame->text, '\n');
message += 4;
} else if (!g_ascii_strncasecmp(message + 1, "a href=\"", 8)) {
message += 9;
new_f = zframe_new("</a>", FALSE);
new_f->href = NULL;
new_f->is_href = FALSE;
new_f->env = "";
new_f->closer_mask = frame->closer_mask;
g_queue_push_head(&frames, new_f);
new_f = zframe_new("\">", FALSE);
new_f->href = NULL;
new_f->is_href = TRUE;
new_f->closer_mask = frame->closer_mask;
g_queue_push_head(&frames, new_f);
} else if (!g_ascii_strncasecmp(message + 1, "font", 4)) {
new_f = zframe_new("</font>", TRUE);
new_f->href = NULL;
new_f->is_href = FALSE;
new_f->closer_mask = 15;
g_queue_push_head(&frames, new_f);
message += 5;
while (*message == ' ') {
message++;
}
if (!g_ascii_strncasecmp(message, "color=\"", 7)) {
message += 7;
new_f->env = "@";
new_f = zframe_new("\">", TRUE);
new_f->env = "@color";
new_f->href = NULL;
new_f->is_href = FALSE;
new_f->closer_mask = 15;
g_queue_push_head(&frames, new_f);
} else if (!g_ascii_strncasecmp(message, "face=\"", 6)) {
message += 6;
new_f->env = "@";
new_f = zframe_new("\">", TRUE);
new_f->env = "@font";
new_f->href = NULL;
new_f->is_href = FALSE;
new_f->closer_mask = 15;
g_queue_push_head(&frames, new_f);
} else if (!g_ascii_strncasecmp(message, "size=\"", 6)) {
message += 6;
if ((*message == '1') || (*message == '2')) {
new_f->env = "@small";
} else if ((*message == '3') || (*message == '4')) {
new_f->env = "@medium";
} else if ((*message == '5') || (*message == '6')
|| (*message == '7')) {
new_f->env = "@large";
} else {
new_f->env = "";
new_f->has_closer = FALSE;
new_f->closer_mask = frame->closer_mask;
}
message += 3;
} else {
/* Drop all unrecognized/misparsed font tags */
new_f->env = "";
new_f->has_closer = FALSE;
new_f->closer_mask = frame->closer_mask;
while (g_ascii_strncasecmp(message, "\">", 2) != 0) {
message++;
}
if (*message != '\0') {
message += 2;
}
}
} else {
/* Catch all for all unrecognized/misparsed <foo> tage */
g_string_append_c(frame->text, *message++);
}
} else if (*message == '@') {
g_string_append(frame->text, "@@");
message++;
} else if (*message == '}') {
if (frame->closer_mask & ~1) {
frame->closer_mask &= ~1;
g_string_append_c(frame->text, *message++);
} else {
g_string_append(frame->text, "@[}]");
message++;
}
} else if (*message == ']') {
if (frame->closer_mask & ~2) {
frame->closer_mask &= ~2;
g_string_append_c(frame->text, *message++);
} else {
g_string_append(frame->text, "@{]}");
message++;
}
} else if (*message == ')') {
if (frame->closer_mask & ~4) {
frame->closer_mask &= ~4;
g_string_append_c(frame->text, *message++);
} else {
g_string_append(frame->text, "@{)}");
message++;
}
} else if (!g_ascii_strncasecmp(message, "&gt;", 4)) {
if (frame->closer_mask & ~8) {
frame->closer_mask &= ~8;
g_string_append_c(frame->text, *message++);
} else {
g_string_append(frame->text, "@{>}");
message += 4;
}
} else {
g_string_append_c(frame->text, *message++);
}
}
frame = (zframe *)g_queue_pop_head(&frames);
ret = g_string_free(frame->text, FALSE);
g_free(frame);
purple_debug_info("zephyr", "zephyr outputted %s\n", ret);
return ret;
}
static void
zephyr_to_html_pop(GQueue *frames, gboolean *last_had_closer)
{
zframe *popped = (zframe *)g_queue_pop_head(frames);
zframe *head = (zframe *)g_queue_peek_head(frames);
g_string_append(head->text, popped->text->str);
g_string_append(head->text, popped->closing);
if (last_had_closer != NULL) {
*last_had_closer = popped->has_closer;
}
g_string_free(popped->text, TRUE);
g_free(popped);
}
char *
zephyr_to_html(const char *message)
{
GQueue frames = G_QUEUE_INIT;
zframe *frame;
char *ret;
frame = zframe_new("", FALSE);
frame->closer = NULL;
g_queue_push_head(&frames, frame);
while (*message) {
frame = (zframe *)g_queue_peek_head(&frames);
if (*message == '@' && message[1] == '@') {
g_string_append(frame->text, "@");
message += 2;
} else if (*message == '@') {
int end = 1;
while (message[end] && (isalnum(message[end]) || message[end] == '_')) {
end++;
}
if (message[end] &&
(message[end] == '{' || message[end] == '[' || message[end] == '(' ||
!g_ascii_strncasecmp(message + end, "&lt;", 4))) {
zframe *new_f;
char *buf;
char *closer;
buf = g_new0(char, end);
g_snprintf(buf, end, "%s", message + 1);
message += end;
closer = (*message == '{' ? "}" :
*message == '[' ? "]" :
*message == '(' ? ")" :
"&gt;");
message += (*message == '&' ? 4 : 1);
if (!g_ascii_strcasecmp(buf, "italic") || !g_ascii_strcasecmp(buf, "i")) {
new_f = zframe_new_with_text("<i>", "</i>", TRUE);
} else if (!g_ascii_strcasecmp(buf, "small")) {
new_f = zframe_new_with_text("<font size=\"1\">", "</font>", TRUE);
} else if (!g_ascii_strcasecmp(buf, "medium")) {
new_f = zframe_new_with_text("<font size=\"3\">", "</font>", TRUE);
} else if (!g_ascii_strcasecmp(buf, "large")) {
new_f = zframe_new_with_text("<font size=\"7\">", "</font>", TRUE);
} else if (!g_ascii_strcasecmp(buf, "bold")
|| !g_ascii_strcasecmp(buf, "b")) {
new_f = zframe_new_with_text("<b>", "</b>", TRUE);
} else if (!g_ascii_strcasecmp(buf, "font")) {
zframe *extra_f;
extra_f = zframe_new("</font>", FALSE);
extra_f->closer = frame->closer;
g_queue_push_head(&frames, extra_f);
new_f = zframe_new_with_text("<font face=\"", "\">", TRUE);
} else if (!g_ascii_strcasecmp(buf, "color")) {
zframe *extra_f;
extra_f = zframe_new("</font>", FALSE);
extra_f->closer = frame->closer;
g_queue_push_head(&frames, extra_f);
new_f = zframe_new_with_text("<font color=\"", "\">", TRUE);
} else {
new_f = zframe_new("", TRUE);
}
new_f->closer = closer;
g_queue_push_head(&frames, new_f);
g_free(buf);
} else {
/* Not a formatting tag, add the character as normal. */
g_string_append_c(frame->text, *message++);
}
} else if (frame->closer && purple_str_has_caseprefix(message, frame->closer)) {
message += strlen(frame->closer);
if (g_queue_get_length(&frames) > 1) {
gboolean last_had_closer;
do {
zephyr_to_html_pop(&frames, &last_had_closer);
} while (g_queue_get_length(&frames) > 1 && !last_had_closer);
} else {
g_string_append_c(frame->text, *message);
}
} else if (*message == '\n') {
g_string_append(frame->text, "<br>");
message++;
} else {
g_string_append_c(frame->text, *message++);
}
}
/* go through all the stuff that they didn't close */
while (g_queue_get_length(&frames) > 1) {
zephyr_to_html_pop(&frames, NULL);
}
frame = (zframe *)g_queue_pop_head(&frames);
ret = g_string_free(frame->text, FALSE);
g_free(frame);
return ret;
}