glib/glib/tests/markup-collect.c
Dan Winship 4b94c0831e Use 'dumb quotes' rather than `really dumb quotes'
Back in the far-off twentieth century, it was normal on unix
workstations for U+0060 GRAVE ACCENT to be drawn as "‛" and for U+0027
APOSTROPHE to be drawn as "’". This led to the convention of using
them as poor-man's ‛smart quotes’ in ASCII-only text.

However, "'" is now universally drawn as a vertical line, and "`" at a
45-degree angle, making them an `odd couple' when used together.

Unfortunately, there are lots of very old strings in glib, and also
lots of new strings in which people have kept up the old tradition,
perhaps entirely unaware that it used to not look stupid.

Fix this by just using 'dumb quotes' everywhere.

https://bugzilla.gnome.org/show_bug.cgi?id=700746
2013-05-21 11:23:22 -03:00

235 lines
7.7 KiB
C

/*
* Copyright © 2007 Ryan Lortie
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#include <stdlib.h>
#include <string.h>
#include <glib.h>
static void
start (GMarkupParseContext *context,
const char *element_name,
const char **attribute_names,
const char **attribute_values,
gpointer user_data,
GError **error)
{
GString *string = user_data;
gboolean result;
#define collect(...) \
g_markup_collect_attributes (element_name, attribute_names, \
attribute_values, error, __VA_ARGS__, \
G_MARKUP_COLLECT_INVALID)
#define BOOL G_MARKUP_COLLECT_BOOLEAN
#define OPTBOOL G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL
#define TRI G_MARKUP_COLLECT_TRISTATE
#define STR G_MARKUP_COLLECT_STRING
#define STRDUP G_MARKUP_COLLECT_STRDUP
#define OPTSTR G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL
#define OPTDUP G_MARKUP_COLLECT_STRDUP | G_MARKUP_COLLECT_OPTIONAL
#define n(x) ((x)?(x):"(null)")
if (strcmp (element_name, "bool") == 0)
{
gboolean mb = 2, ob = 2, tri = 2;
result = collect (BOOL, "mb", &mb,
OPTBOOL, "ob", &ob,
TRI, "tri", &tri);
g_assert (result ||
(mb == FALSE && ob == FALSE && tri != TRUE && tri != FALSE));
if (tri != FALSE && tri != TRUE)
tri = -1;
g_string_append_printf (string, "<bool(%d) %d %d %d>",
result, mb, ob, tri);
}
else if (strcmp (element_name, "str") == 0)
{
const char *cm, *co;
char *am, *ao;
result = collect (STR, "cm", &cm,
STRDUP, "am", &am,
OPTDUP, "ao", &ao,
OPTSTR, "co", &co);
g_assert (result ||
(cm == NULL && am == NULL && ao == NULL && co == NULL));
g_string_append_printf (string, "<str(%d) %s %s %s %s>",
result, n (cm), n (am), n (ao), n (co));
g_free (am);
g_free (ao);
}
}
static GMarkupParser parser = { start };
struct test
{
const char *document;
const char *result;
GMarkupError error_code;
const char *error_info;
};
static struct test tests[] =
{
{ "<bool mb='y'>", "<bool(1) 1 0 -1>",
G_MARKUP_ERROR_PARSE, "'bool'" },
{ "<bool mb='false'/>", "<bool(1) 0 0 -1>" },
{ "<bool mb='true'/>", "<bool(1) 1 0 -1>" },
{ "<bool mb='t' ob='f' tri='1'/>", "<bool(1) 1 0 1>" },
{ "<bool mb='y' ob='n' tri='0'/>", "<bool(1) 1 0 0>" },
{ "<bool ob='y'/>", "<bool(0) 0 0 -1>",
G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" },
{ "<bool mb='y' mb='y'/>", "<bool(0) 0 0 -1>",
G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
{ "<bool mb='y' tri='y' tri='n'/>", "<bool(0) 0 0 -1>",
G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" },
{ "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>" },
{ "<str am='x' co='y'/>", "<str(0) (null) (null) (null) (null)>",
G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
{ "<str am='x'/>", "<str(0) (null) (null) (null) (null)>",
G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
{ "<str am='x' cm='x' am='y'/>", "<str(0) (null) (null) (null) (null)>",
G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
{ "<str am='x' qm='y' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'qm'" },
{ "<str am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
{ "<str cm='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x'/>", "<str(0) (null) (null) (null) (null)>",
G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
{ "<str a='x' b='x' c='x' d='x' e='x' f='x' g='x' h='x' i='x' j='x' k='x' l='x' m='x' n='x' o='x' p='x' q='x' r='x' s='x' t='x' u='x' v='x' w='x' x='x' y='x' z='x' aa='x' bb='x' cc='x' dd='x' ee='x' ff='x' gg='x' hh='x' ii='x' jj='x' kk='x' ll='x' mm='x' nn='x' oo='x' pp='x' qq='x' rr='x' ss='x' tt='x' uu='x' vv='x' ww='x' xx='x' yy='x' zz='x' am='x' cm='x'/>",
"<str(0) (null) (null) (null) (null)>",
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'a'" },
{ "<bool mb='ja'/>", "<bool(0) 0 0 -1>",
G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
{ "<bool mb='nein'/>", "<bool(0) 0 0 -1>",
G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }
};
static void
test_collect (gconstpointer d)
{
const struct test *test = d;
GMarkupParseContext *ctx;
GError *error = NULL;
GString *string;
gboolean result;
string = g_string_new ("");
ctx = g_markup_parse_context_new (&parser, 0, string, NULL);
result = g_markup_parse_context_parse (ctx,
test->document,
-1, &error);
if (result)
result = g_markup_parse_context_end_parse (ctx, &error);
if (result)
{
g_assert_no_error (error);
g_assert_cmpint (test->error_code, ==, 0);
g_assert_cmpstr (test->result, ==, string->str);
}
else
{
g_assert_error (error, G_MARKUP_ERROR, test->error_code);
}
g_markup_parse_context_free (ctx);
g_string_free (string, TRUE);
g_clear_error (&error);
}
#define XML "<element a='1' b='2' c='3'/>"
static void
start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
/* Omitting "c" attribute intentionally to trigger crash. */
g_markup_collect_attributes (element_name,
attribute_names,
attribute_values,
error,
G_MARKUP_COLLECT_STRING, "a", NULL,
G_MARKUP_COLLECT_STRING, "b", NULL,
G_MARKUP_COLLECT_INVALID);
}
static GMarkupParser cleanup_parser = {
start_element
};
static void
test_cleanup (void)
{
GMarkupParseContext *context;
if (!g_test_undefined ())
return;
context = g_markup_parse_context_new (&cleanup_parser, 0, NULL, NULL);
g_markup_parse_context_parse (context, XML, -1, NULL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"g_markup_parse_context_end_parse: assertion 'context->state != STATE_ERROR' failed");
g_markup_parse_context_end_parse (context, NULL);
g_test_assert_expected_messages ();
g_markup_parse_context_free (context);
}
int
main (int argc, char **argv)
{
int i;
gchar *path;
g_test_init (&argc, &argv, NULL);
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
path = g_strdup_printf ("/markup/collect/%d", i);
g_test_add_data_func (path, &tests[i], test_collect);
g_free (path);
}
g_test_add_func ("/markup/collect/cleanup", test_cleanup);
return g_test_run ();
}