Commit 9da939eb 9da939ebc7cde925ee45f405786a6b0d451b7180 by Sergey Poznyakoff

Fix premature push.

1 parent 35056a6e
......@@ -25,7 +25,6 @@ static char args_doc[] = N_("[FILE]");
static char *format_str;
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;
......@@ -42,9 +41,6 @@ static struct mu_option options[] = {
{ "dump", 0, NULL, MU_OPTION_HIDDEN,
N_("dump the listing of compiled format code"),
mu_c_bool, &dump_option },
{ "disassemble", 0, NULL, MU_OPTION_HIDDEN,
N_("dump disassembled format code"),
mu_c_bool, &disass_option },
{ "debug", 0, NULL, MU_OPTION_DEFAULT,
N_("enable parser debugging output"),
mu_c_bool, &debug_option },
......@@ -62,8 +58,11 @@ static void
run (void)
{
mu_message_t msg = mh_file_to_message (NULL, input_file);
mh_format (format, msg, msgno, width, mu_strout);
mu_printf ("\n");
char *output;
mh_format (&format, msg, msgno, width, &output);
mu_printf ("%s\n", output);
}
int
......@@ -91,16 +90,14 @@ main (int argc, char **argv)
mu_error (_("Format string not specified"));
return 1;
}
if (mh_format_parse (&format, format_str, MH_FMT_PARSE_TREE))
if (mh_format_parse (format_str, &format))
{
mu_error (_("Bad format string"));
exit (1);
}
if (dump_option)
mh_format_dump_code (format);
if (disass_option)
mh_format_dump_disass (format);
mh_format_dump (&format);
if (input_file)
run ();
......
......@@ -65,6 +65,11 @@
#include <mu_umaxtostr.h>
#define MH_FMT_RALIGN 0x1000
#define MH_FMT_ZEROPAD 0x2000
#define MH_FMT_COMPWS 0x4000
#define MH_WIDTH_MASK 0x0fff
#define MH_SEQUENCES_FILE ".mh_sequences"
#define MH_USER_PROFILE ".mh_profile"
#define MH_GLOBAL_PROFILE "mh-profile"
......@@ -73,6 +78,118 @@
#define is_true(arg) ((arg) == NULL||mu_true_answer_p (arg) == 1)
enum mh_opcode
{
/* 0. Stop. Format: mhop_stop */
mhop_stop,
/* 1. Branch.
Format: mhop_branch offset */
mhop_branch,
/* 2. Assign to numeric register
Format: mhop_num_asgn */
mhop_num_asgn,
/* 3. Assign to string register
Format: mhop_str_asgn */
mhop_str_asgn,
/* 4. Numeric arg follows.
Format: mhop_num_arg number */
mhop_num_arg,
/* 5. String arg follows.
Format: mhop_str_arg length string */
mhop_str_arg,
/* 6. Branch if reg_num is zero.
Format: mhop_num_branch dest-off */
mhop_num_branch,
/* 7. Branch if reg_str is zero.
Format: mhop_str_branch dest-off */
mhop_str_branch,
/* 8. Set str to the value of the header component
Format: mhop_header */
mhop_header,
/* 9. Read message body contents into str.
Format: mhop_body */
mhop_body,
/* 10. Call a function.
Format: mhop_call function-pointer */
mhop_call,
/* 11. assign reg_num to arg_num */
mhop_num_to_arg,
/* 12. assign reg_str to arg_str */
mhop_str_to_arg,
/* 13. Convert arg_str to arg_num */
mhop_str_to_num,
/* 14. Convert arg_num to arg_str */
mhop_num_to_str,
/* 15. Print reg_num */
mhop_num_print,
/* 16. Print reg_str */
mhop_str_print,
/* 17. Set format specification.
Format: mhop_fmtspec number */
mhop_fmtspec,
/* 18. Noop */
mhop_nop
};
enum mh_type
{
mhtype_none,
mhtype_num,
mhtype_str
};
typedef enum mh_opcode mh_opcode_t;
struct mh_machine;
typedef void (*mh_builtin_fp) (struct mh_machine *);
typedef union {
mh_opcode_t opcode;
mh_builtin_fp builtin;
int num;
void *ptr;
char str[1]; /* Any number of characters follows */
} mh_instr_t;
#define MHI_OPCODE(m) (m).opcode
#define MHI_BUILTIN(m) (m).builtin
#define MHI_NUM(m) (m).num
#define MHI_PTR(m) (m).ptr
#define MHI_STR(m) (m).str
typedef struct mh_format mh_format_t;
struct mh_format
{
size_t progsize; /* Size of allocated program*/
mh_instr_t *prog; /* Program itself */
};
#define MHA_REQUIRED 0
#define MHA_OPTARG 1
#define MHA_OPT_CLEAR 2
typedef struct mh_builtin mh_builtin_t;
struct mh_builtin
{
char *name;
mh_builtin_fp fun;
int type;
int argtype;
int optarg;
};
typedef struct
{
const char *name;
......@@ -167,22 +284,14 @@ int mu_getans (const char *variants, const char *fmt, ...)
int mh_check_folder (const char *pathname, int confirm);
int mh_makedir (const char *p);
typedef struct mh_format *mh_format_t;
int mh_format (mh_format_t fmt, mu_message_t msg, size_t msgno,
size_t width, mu_stream_t str);
int mh_format_str (mh_format_t fmt, char *str, size_t width, char **pret);
void mh_format_dump_code (mh_format_t fmt);
void mh_format_dump_disass (mh_format_t fmt);
#define MH_FMT_PARSE_DEFAULT 0
#define MH_FMT_PARSE_TREE 0x01
int mh_format_parse (mh_format_t *fmt, char *format_str, int flags);
int mh_format (mh_format_t *fmt, mu_message_t msg, size_t msgno,
size_t width, char **pret);
int mh_format_str (mh_format_t *fmt, char *str, size_t width, char **pret);
void mh_format_dump (mh_format_t *fmt);
int mh_format_parse (char *format_str, mh_format_t *fmt);
void mh_format_debug (int val);
void mh_format_free (mh_format_t fmt);
void mh_format_destroy (mh_format_t *fmt);
void mh_format_free (mh_format_t *fmt);
mh_builtin_t *mh_lookup_builtin (char *name, int *rest);
void mh_error (const char *fmt, ...) MU_PRINTFLIKE(1,2);
void mh_err_memory (int fatal);
......@@ -241,7 +350,7 @@ int mh_whom_file (const char *filename, int check);
int mh_whom_message (mu_message_t msg, int check);
void mh_set_reply_regex (const char *str);
int mh_decode_2047 (char const *text, char **decoded_text);
int mh_decode_2047 (char *text, char **decoded_text);
const char *mh_charset (const char *);
int mh_alias_read (char const *name, int fail);
......
......@@ -15,146 +15,34 @@
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#define MH_FMT_DEFAULT 0
#define MH_FMT_RALIGN 0x1000
#define MH_FMT_ZEROPAD 0x2000
#define MH_FMT_COMPWS 0x4000
#define MH_WIDTH_MASK 0x0fff
enum mh_opcode
{
/* Stop. Format: mhop_stop */
mhop_stop,
/* Unconditional branch
Format: mhop_branch offset */
mhop_branch,
/* Branch if num reg is zero.
Format: mhop_brz_num dest-off */
mhop_brzn,
/* Branch if str reg is zero.
Format: mhop_brz_str dest-off */
mhop_brzs,
/* Set numeric register
Format: mhop_setn val */
mhop_setn,
/* Set string register
Format: mhop_sets reg length string */
mhop_sets,
/* Move value bewtween two numeric registers
Format: mhop_movn dest src */
mhop_movn,
/* Move value bewtween two string registers
Format: mhop_movs dest src */
mhop_movs,
/* Load component value into a string register
Format: mhop_load reg string */
mhop_ldcomp,
/* Load first width bytes of message body contents into a string register.
Format: mhop_body reg */
mhop_ldbody,
/* Call a function.
Format: mhop_call function-pointer */
mhop_call,
/* Convert string register to number reg
Format: mhop_atoi reg
*/
mhop_atoi,
/* Convert numeric register to string
Format: mhop_itoa reg */
mhop_itoa,
/* Print num reg */
mhop_printn,
/* Print str reg */
mhop_prints,
/* Set format specification.
Format: mhop_fmtspec number */
mhop_fmtspec,
};
enum regid { R_REG, R_ARG };
enum mh_type
typedef struct /* A string object type */
{
mhtype_none,
mhtype_num,
mhtype_str
};
typedef enum mh_opcode mh_opcode_t;
struct mh_machine;
typedef void (*mh_builtin_fp) (struct mh_machine *);
typedef union {
mh_opcode_t opcode;
mh_builtin_fp builtin;
long num;
void *ptr;
char str[1]; /* Any number of characters follows */
} mh_instr_t;
#define MHI_OPCODE(m) (m).opcode
#define MHI_BUILTIN(m) (m).builtin
#define MHI_NUM(m) (m).num
#define MHI_PTR(m) (m).ptr
#define MHI_STR(m) (m).str
struct mh_format
{
size_t progmax; /* Size of allocated program*/
size_t progcnt; /* Actual number of elements used */
mh_instr_t *prog; /* Program itself */
struct node *tree;
mu_opool_t pool;
};
int size; /* Allocated size or 0 for static storage */
char *ptr; /* Actual data */
}
strobj_t;
#define MHA_REQUIRED 0
#define MHA_OPTARG 1
#define MHA_OPT_CLEAR 2
#define MHA_VOID 3
#define strobj_ptr(p) ((p)->ptr ? (p)->ptr : "")
#define strobj_len(p) (strobj_is_null(p) ? 0 : strlen((p)->ptr))
#define strobj_is_null(p) ((p)->ptr == NULL)
#define strobj_is_static(p) ((p)->size == 0)
typedef struct mh_builtin mh_builtin_t;
struct mh_builtin
{
char *name;
mh_builtin_fp fun;
enum mh_type type;
enum mh_type argtype;
int optarg;
};
struct mh_string
{
size_t size;
char *ptr;
};
struct mh_machine
{
long num[2]; /* numeric registers */
struct mh_string str[2]; /* string registers */
strobj_t reg_str; /* String register */
int reg_num; /* Numeric register */
strobj_t arg_str; /* String argument */
long arg_num; /* Numeric argument */
size_t pc; /* Program counter */
size_t progcnt; /* Size of allocated program*/
size_t progsize; /* Size of allocated program*/
mh_instr_t *prog; /* Program itself */
int stop; /* Stop execution immediately */
size_t width; /* Output line width */
size_t ind; /* Output line index */
mu_stream_t output; /* Output stream */
mu_opool_t pool; /* Output buffer */
size_t width; /* Output buffer width */
size_t ind; /* Output buffer index */
mu_list_t addrlist; /* The list of email addresses output this far */
int fmtflags; /* Current formatting flags */
......@@ -163,5 +51,9 @@ struct mh_machine
size_t msgno; /* Its number */
};
mh_builtin_t *mh_lookup_builtin (char *name, size_t len);
void mh_print_fmtspec (int fmtspec);
void strobj_free (strobj_t *obj);
void strobj_create (strobj_t *lvalue, const char *str);
void strobj_set (strobj_t *lvalue, char *str);
void strobj_assign (strobj_t *lvalue, strobj_t *rvalue);
void strobj_copy (strobj_t *lvalue, strobj_t *rvalue);
void strobj_realloc (strobj_t *obj, size_t length);
......
......@@ -913,7 +913,7 @@ mh_charset (const char *dfl)
}
int
mh_decode_2047 (char const *text, char **decoded_text)
mh_decode_2047 (char *text, char **decoded_text)
{
const char *charset = mh_charset (NULL);
if (!charset)
......
......@@ -46,7 +46,7 @@ enum mhl_datatype
typedef union mhl_value {
char *str;
int num;
mh_format_t fmt;
mh_format_t *fmt;
} mhl_value_t;
typedef struct mhl_variable
......@@ -151,6 +151,7 @@ parse_variable (locus_t *loc, mu_list_t formlist, char *str)
{
size_t i;
struct mu_wordsplit ws;
mh_format_t fmt;
int wsflags;
if (strncmp (str, "ignores=", 8) == 0 && str[8] != '"')
......@@ -218,14 +219,15 @@ parse_variable (locus_t *loc, mu_list_t formlist, char *str)
break;
case dt_format:
if (mh_format_parse (&stmt->v.variable.value.fmt, value,
MH_FMT_PARSE_DEFAULT))
if (mh_format_parse (value, &fmt))
{
mu_error (_("%s:%d: bad format string"),
loc->filename,
loc->line);
exit (1);
}
stmt->v.variable.value.fmt = mu_alloc (sizeof (mh_format_t));
*stmt->v.variable.value.fmt = fmt;
break;
case dt_flag:
......@@ -454,7 +456,7 @@ struct eval_env
int ivar[I_MAX];
int bvar[B_MAX];
char *svar[S_MAX];
mh_format_t fvar[F_MAX];
mh_format_t *fvar[F_MAX];
char *prefix;
};
......