/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2021 Free Software Foundation, Inc.
GNU Mailutils 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 3, or (at your option)
any later version.
GNU Mailutils 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 GNU Mailutils. If not, see . */
/* fmtcheck */
#include
static char prog_doc[] = N_("Check MH format string");
static char args_doc[] = N_("[FILE]");
static char *format_str;
static struct mu_locus_point locus = MU_LOCUS_POINT_INITIALIZER;
static mh_format_t format;
static int dump_option;
static int disass_option;
static int debug_option;
static char *input_file;
static size_t width;
static size_t msgno;
static int pc_option;
void
opt_formfile (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
free (format_str);
if (mh_read_formfile (arg, &format_str))
exit (1);
mu_locus_point_set_file (&locus, arg);
locus.mu_line = 1;
locus.mu_col = 0;
}
void
opt_format (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
free (format_str);
format_str = mu_strdup (arg);
}
static struct mu_option options[] = {
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, NULL, opt_formfile },
{ "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT,
N_("use this format string"),
mu_c_string, NULL, opt_format },
{ "dump", 0, NULL, MU_OPTION_DEFAULT,
N_("dump the listing of compiled format code"),
mu_c_bool, &dump_option },
{ "disassemble", 0, NULL, MU_OPTION_DEFAULT,
N_("dump disassembled format code"),
mu_c_bool, &disass_option },
{ "pc", 0, NULL, MU_OPTION_DEFAULT,
N_("print program counter along with disassembled code (implies --disassemble)"),
mu_c_bool, &pc_option },
{ "debug", 0, NULL, MU_OPTION_DEFAULT,
N_("enable parser debugging output"),
mu_c_bool, &debug_option },
{ "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output width"),
mu_c_size, &width },
{ "msgno", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set message number"),
mu_c_size, &msgno },
MU_OPTION_END
};
static int
msg_uid (mu_message_t msg MU_ARG_UNUSED, size_t *ret)
{
if (!ret)
return MU_ERR_OUT_PTR_NULL;
*ret = msgno;
return 0;
}
static void
run (void)
{
mu_message_t msg = mh_file_to_message (NULL, input_file);
mh_fvm_t fvm;
MU_ASSERT (mu_message_set_uid (msg, msg_uid, mu_message_get_owner (msg)));
mh_fvm_create (&fvm, MH_FMT_FORCENL);
mh_fvm_set_width (fvm, width ? width : mh_width ());
mh_fvm_set_format (fvm, format);
mh_fvm_run (fvm, msg);
mh_fvm_destroy (&fvm);
}
int
main (int argc, char **argv)
{
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (pc_option)
disass_option = 1;
switch (argc)
{
case 0:
if (!disass_option)
dump_option = 1;
break;
case 1:
input_file = argv[0];
break;
default:
mu_error (_("too many arguments"));
return 1;
}
if (!format_str)
{
mu_error (_("Format string not specified"));
return 1;
}
if (mh_format_string_parse (&format, format_str, &locus,
MH_FMT_PARSE_TREE
| (debug_option ? MH_FMT_PARSE_DEBUG : 0)))
return 1;
if (dump_option)
mh_format_dump_code (format);
if (disass_option)
mh_format_dump_disass (format, pc_option);
if (input_file)
run ();
return 0;
}