[util] Add --unicodes-before/after

Parallel to --unicodes for --text-before/after. To be used in tests.
pull/3150/head
Khaled Hosny 3 years ago
parent 65c622c689
commit 6ca0ffd42e
  1. 156
      util/text-options.hh

@ -119,6 +119,43 @@ parse_text (const char *name G_GNUC_UNUSED,
return true; return true;
} }
static bool
encode_unicodes (const char *unicodes,
GString *gs,
GError **error)
{
#define DELIMITERS "<+->{},;&#\\xXuUnNiI\n\t\v\f\r "
char *s = (char *) unicodes;
char *p;
while (s && *s)
{
while (*s && strchr (DELIMITERS, *s))
s++;
if (!*s)
break;
errno = 0;
hb_codepoint_t u = strtoul (s, &p, 16);
if (errno || s == p)
{
g_string_free (gs, TRUE);
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
"Failed parsing Unicode value at: '%s'", s);
return false;
}
g_string_append_unichar (gs, u);
s = p;
}
#undef DELIMITERS
return true;
}
static gboolean static gboolean
parse_unicodes (const char *name G_GNUC_UNUSED, parse_unicodes (const char *name G_GNUC_UNUSED,
const char *arg, const char *arg,
@ -136,41 +173,98 @@ parse_unicodes (const char *name G_GNUC_UNUSED,
GString *gs = g_string_new (nullptr); GString *gs = g_string_new (nullptr);
if (0 == strcmp (arg, "*")) if (0 == strcmp (arg, "*"))
{
g_string_append_c (gs, '*'); g_string_append_c (gs, '*');
}
else else
if (!encode_unicodes (arg, gs, error))
return false;
text_opts->text_len = gs->len;
text_opts->text = g_string_free (gs, FALSE);
return true;
}
static gboolean
parse_text_before (const char *name G_GNUC_UNUSED,
const char *arg,
gpointer data,
GError **error)
{
auto *opts = (shape_text_options_t *) data;
if (opts->text_before)
{ {
#define DELIMITERS "<+->{},;&#\\xXuUnNiI\n\t\v\f\r " g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
"Either --text-before or --unicodes-before can be provided but not both");
return false;
}
char *s = (char *) arg; opts->text_before = g_strdup (arg);
char *p; fprintf(stderr, "%s\n", opts->text_before);
return true;
}
while (s && *s) static gboolean
{ parse_unicodes_before (const char *name G_GNUC_UNUSED,
while (*s && strchr (DELIMITERS, *s)) const char *arg,
s++; gpointer data,
if (!*s) GError **error)
break; {
auto *opts = (shape_text_options_t *) data;
errno = 0;
hb_codepoint_t u = strtoul (s, &p, 16); if (opts->text_before)
if (errno || s == p) {
{ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
g_string_free (gs, TRUE); "Either --text-before or --unicodes-before can be provided but not both");
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, return false;
"Failed parsing Unicode value at: '%s'", s);
return false;
}
g_string_append_unichar (gs, u);
s = p;
}
} }
text_opts->text_len = gs->len; GString *gs = g_string_new (nullptr);
text_opts->text = g_string_free (gs, FALSE); if (!encode_unicodes (arg, gs, error))
return false;
opts->text_before = g_string_free (gs, FALSE);
return true;
}
static gboolean
parse_text_after (const char *name G_GNUC_UNUSED,
const char *arg,
gpointer data,
GError **error)
{
auto *opts = (shape_text_options_t *) data;
if (opts->text_after)
{
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
"Either --text-after or --unicodes-after can be provided but not both");
return false;
}
opts->text_after = g_strdup (arg);
return true;
}
static gboolean
parse_unicodes_after (const char *name G_GNUC_UNUSED,
const char *arg,
gpointer data,
GError **error)
{
auto *opts = (shape_text_options_t *) data;
if (opts->text_after)
{
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
"Either --text-after or --unicodes-after can be provided but not both");
return false;
}
GString *gs = g_string_new (nullptr);
if (!encode_unicodes (arg, gs, error))
return false;
opts->text_after = g_string_free (gs, FALSE);
return true; return true;
} }
@ -236,8 +330,10 @@ shape_text_options_t::add_options (option_parser_t *parser)
GOptionEntry entries[] = GOptionEntry entries[] =
{ {
{"text-before", 0, 0, G_OPTION_ARG_STRING, &this->text_before, "Set text context before each line", "string"}, {"text-before", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text_before, "Set text context before each line", "string"},
{"text-after", 0, 0, G_OPTION_ARG_STRING, &this->text_after, "Set text context after each line", "string"}, {"text-after", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text_after, "Set text context after each line", "string"},
{"unicodes-before", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes_before, "Set Unicode codepoints context before each line", "list of hex numbers"},
{"unicodes-after", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes_after, "Set Unicode codepoints context after each line", "list of hex numbers"},
{nullptr} {nullptr}
}; };
parser->add_group (entries, parser->add_group (entries,

Loading…
Cancel
Save