mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-19 14:16:01 +01:00
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
235 lines
7.7 KiB
C
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 ();
|
|
}
|