summaryrefslogtreecommitdiff
path: root/mh/mh_format.h
blob: 3c902178502aff619bc2409bf92775ba406be6e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* GNU Mailutils -- a suite of utilities for electronic mail
   Copyright (C) 2006-2007, 2010-2012, 2014-2017 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 <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
   */
  mhop_atoi,
  
  /* Convert numeric register to string
     Format: mhop_itoa */
  mhop_itoa,

  /* Print num reg */
  mhop_printn,

  /* Print str reg */
  mhop_prints,

  /* Print literal
     Format: mhop_printlit length string */
  mhop_printlit,
  
  /* Set format specification.
     Format: mhop_fmtspec number */
  mhop_fmtspec,
};    

enum regid { R_REG, R_ARG };

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_fvm *);

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 */
  /* The tree and pool members are filled only if mh_format_parse
     was called with MH_FMT_PARSE_TREE flag */
  struct node *tree;       /* Parse tree */  
  mu_opool_t pool;         /* Literal pool */
};

#define MHA_DEFAULT       0
#define MHA_OPTARG        0x1
#define MHA_LITERAL       0x2
#define MHA_VOID          0x4
#define MHA_OPTARG_NIL    0x8

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 flags;
};

struct mh_string
{
  size_t size;
  char *ptr;
};
  
struct mh_fvm
{
  long num[2];              /* numeric registers */
  struct mh_string str[2];  /* string registers */
  
  size_t pc;                /* Program counter */
  size_t progcnt;           /* 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 */
  int flags;
  
  mu_list_t addrlist;       /* The list of email addresses output this far */
  int fmtflags;             /* Current formatting flags */

  mu_message_t message;     /* Current message */
  size_t msgno;             /* Its number */
};

mh_builtin_t *mh_lookup_builtin (char *name, size_t len);
void mh_print_fmtspec (int fmtspec);

Return to:

Send suggestions and report system problems to the System administrator.