[util] Use post_parse to validate
This commit is contained in:
parent
9468e46998
commit
c0ea4e2d33
|
@ -31,8 +31,20 @@
|
||||||
|
|
||||||
struct face_options_t
|
struct face_options_t
|
||||||
{
|
{
|
||||||
|
~face_options_t ()
|
||||||
|
{
|
||||||
|
g_free (font_file);
|
||||||
|
}
|
||||||
|
|
||||||
void add_options (option_parser_t *parser);
|
void add_options (option_parser_t *parser);
|
||||||
|
|
||||||
|
void post_parse (GError **error)
|
||||||
|
{
|
||||||
|
if (!this->font_file)
|
||||||
|
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||||
|
"No font file set");
|
||||||
|
}
|
||||||
|
|
||||||
hb_blob_t *get_blob () const;
|
hb_blob_t *get_blob () const;
|
||||||
hb_face_t *get_face () const;
|
hb_face_t *get_face () const;
|
||||||
|
|
||||||
|
@ -40,12 +52,12 @@ struct face_options_t
|
||||||
{
|
{
|
||||||
~cache_t ()
|
~cache_t ()
|
||||||
{
|
{
|
||||||
free ((void *) font_path);
|
g_free (font_path);
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
hb_face_destroy (face);
|
hb_face_destroy (face);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *font_path = nullptr;
|
char *font_path = nullptr;
|
||||||
hb_blob_t *blob = nullptr;
|
hb_blob_t *blob = nullptr;
|
||||||
unsigned face_index = (unsigned) -1;
|
unsigned face_index = (unsigned) -1;
|
||||||
hb_face_t *face = nullptr;
|
hb_face_t *face = nullptr;
|
||||||
|
@ -73,8 +85,7 @@ face_options_t::get_face () const
|
||||||
if (face)
|
if (face)
|
||||||
return face;
|
return face;
|
||||||
|
|
||||||
if (!font_file)
|
assert (font_file);
|
||||||
fail (true, "No font file set");
|
|
||||||
|
|
||||||
const char *font_path = font_file;
|
const char *font_path = font_file;
|
||||||
|
|
||||||
|
@ -94,7 +105,7 @@ face_options_t::get_face () const
|
||||||
cache.blob = hb_blob_create_from_file_or_fail (font_path);
|
cache.blob = hb_blob_create_from_file_or_fail (font_path);
|
||||||
|
|
||||||
free ((char *) cache.font_path);
|
free ((char *) cache.font_path);
|
||||||
cache.font_path = strdup (font_path);
|
cache.font_path = g_strdup (font_path);
|
||||||
|
|
||||||
if (!cache.blob)
|
if (!cache.blob)
|
||||||
fail (false, "%s: Failed reading file", font_path);
|
fail (false, "%s: Failed reading file", font_path);
|
||||||
|
|
|
@ -44,7 +44,6 @@ struct font_options_t : face_options_t
|
||||||
{
|
{
|
||||||
~font_options_t ()
|
~font_options_t ()
|
||||||
{
|
{
|
||||||
g_free (font_file);
|
|
||||||
free (variations);
|
free (variations);
|
||||||
g_free (font_funcs);
|
g_free (font_funcs);
|
||||||
hb_font_destroy (font);
|
hb_font_destroy (font);
|
||||||
|
|
|
@ -32,31 +32,12 @@
|
||||||
/* main() body for utilities taking font and processing text.*/
|
/* main() body for utilities taking font and processing text.*/
|
||||||
|
|
||||||
template <typename consumer_t, typename font_options_t, typename text_options_t>
|
template <typename consumer_t, typename font_options_t, typename text_options_t>
|
||||||
struct main_font_text_t : font_options_t, text_options_t, consumer_t
|
struct main_font_text_t : option_parser_t, font_options_t, text_options_t, consumer_t
|
||||||
{
|
{
|
||||||
void add_options (struct option_parser_t *parser)
|
int operator () (int argc, char **argv)
|
||||||
{
|
{
|
||||||
font_options_t::add_options (parser);
|
add_options ();
|
||||||
text_options_t::add_options (parser);
|
parse (&argc, &argv);
|
||||||
consumer_t::add_options (parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
operator () (int argc, char **argv)
|
|
||||||
{
|
|
||||||
option_parser_t options ("[FONT-FILE] [TEXT]");
|
|
||||||
add_options (&options);
|
|
||||||
options.parse (&argc, &argv);
|
|
||||||
|
|
||||||
argc--, argv++;
|
|
||||||
if (argc && !this->font_file) this->font_file = locale_to_utf8 (argv[0]), argc--, argv++;
|
|
||||||
if (argc && !this->text && !this->text_file) this->text = locale_to_utf8 (argv[0]), argc--, argv++;
|
|
||||||
if (argc)
|
|
||||||
fail (true, "Too many arguments on the command line");
|
|
||||||
if (!this->font_file)
|
|
||||||
options.usage ();
|
|
||||||
if (!this->text && !this->text_file)
|
|
||||||
this->text_file = g_strdup ("-");
|
|
||||||
|
|
||||||
this->init (this);
|
this->init (this);
|
||||||
|
|
||||||
|
@ -69,6 +50,51 @@ struct main_font_text_t : font_options_t, text_options_t, consumer_t
|
||||||
|
|
||||||
return this->failed ? 1 : 0;
|
return this->failed ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void add_options ()
|
||||||
|
{
|
||||||
|
font_options_t::add_options (this);
|
||||||
|
text_options_t::add_options (this);
|
||||||
|
consumer_t::add_options (this);
|
||||||
|
|
||||||
|
GOptionEntry entries[] =
|
||||||
|
{
|
||||||
|
{G_OPTION_REMAINING, 0, G_OPTION_FLAG_IN_MAIN,
|
||||||
|
G_OPTION_ARG_CALLBACK, (gpointer) &collect_rest, nullptr, "[FONT-FILE] [TEXT]"},
|
||||||
|
{nullptr}
|
||||||
|
};
|
||||||
|
add_main_group (entries, this);
|
||||||
|
option_parser_t::add_options ();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
collect_rest (const char *name G_GNUC_UNUSED,
|
||||||
|
const char *arg,
|
||||||
|
gpointer data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
main_font_text_t *thiz = (main_font_text_t *) data;
|
||||||
|
|
||||||
|
if (!thiz->font_file)
|
||||||
|
{
|
||||||
|
thiz->font_file = g_strdup (arg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!thiz->text && !thiz->text_file)
|
||||||
|
{
|
||||||
|
thiz->text = g_strdup (arg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||||
|
"Too many arguments on the command line");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -70,25 +70,9 @@ fail (hb_bool_t suggest_help, const char *format, ...)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char *
|
|
||||||
locale_to_utf8 (char *s)
|
|
||||||
{
|
|
||||||
char *t;
|
|
||||||
GError *error = nullptr;
|
|
||||||
|
|
||||||
t = g_locale_to_utf8 (s, -1, nullptr, nullptr, &error);
|
|
||||||
if (!t)
|
|
||||||
{
|
|
||||||
fail (true, "Failed converting text to UTF-8");
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct option_parser_t
|
struct option_parser_t
|
||||||
{
|
{
|
||||||
option_parser_t (const char *usage)
|
option_parser_t (const char *usage = nullptr)
|
||||||
: usage_str (usage),
|
: usage_str (usage),
|
||||||
context (g_option_context_new (usage)),
|
context (g_option_context_new (usage)),
|
||||||
to_free (g_ptr_array_new ())
|
to_free (g_ptr_array_new ())
|
||||||
|
@ -136,6 +120,17 @@ struct option_parser_t
|
||||||
g_option_context_add_group (context, group);
|
g_option_context_add_group (context, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
void add_main_group (GOptionEntry *entries,
|
||||||
|
Type *closure)
|
||||||
|
{
|
||||||
|
GOptionGroup *group = g_option_group_new (nullptr, nullptr, nullptr,
|
||||||
|
static_cast<gpointer>(closure), nullptr);
|
||||||
|
g_option_group_add_entries (group, entries);
|
||||||
|
g_option_group_set_parse_hooks (group, nullptr, post_parse<Type>);
|
||||||
|
g_option_context_set_main_group (context, group);
|
||||||
|
}
|
||||||
|
|
||||||
void free_later (char *p) {
|
void free_later (char *p) {
|
||||||
g_ptr_array_add (to_free, p);
|
g_ptr_array_add (to_free, p);
|
||||||
}
|
}
|
||||||
|
@ -147,7 +142,7 @@ struct option_parser_t
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
const char *usage_str;
|
const char *usage_str;
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
GPtrArray *to_free;
|
GPtrArray *to_free;
|
||||||
|
@ -201,8 +196,6 @@ option_parser_t::add_options ()
|
||||||
inline void
|
inline void
|
||||||
option_parser_t::parse (int *argc, char ***argv)
|
option_parser_t::parse (int *argc, char ***argv)
|
||||||
{
|
{
|
||||||
add_options ();
|
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
|
|
||||||
GError *parse_error = nullptr;
|
GError *parse_error = nullptr;
|
||||||
|
|
|
@ -17,6 +17,9 @@ struct text_options_t
|
||||||
|
|
||||||
void post_parse (GError **error G_GNUC_UNUSED)
|
void post_parse (GError **error G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
|
if (!this->text && !this->text_file)
|
||||||
|
this->text_file = g_strdup ("-");
|
||||||
|
|
||||||
if (text && text_file)
|
if (text && text_file)
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||||
|
|
Loading…
Reference in New Issue