Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
mailutils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
9da939eb
...
9da939ebc7cde925ee45f405786a6b0d451b7180
authored
2017-06-26 18:06:58 +0300
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Fix premature push.
1 parent
35056a6e
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
163 additions
and
163 deletions
mh/fmtcheck.c
mh/mh.h
mh/mh_fmtgram.y
mh/mh_format.c
mh/mh_format.h
mh/mh_init.c
mh/mh_list.c
mh/fmtcheck.c
View file @
9da939e
...
...
@@ -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
();
...
...
mh/mh.h
View file @
9da939e
...
...
@@ -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
*
fm
t
);
void
mh_format_free
(
mh_format_t
*
fmt
);
mh_builtin_t
*
mh_lookup_builtin
(
char
*
name
,
int
*
res
t
);
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
);
...
...
mh/mh_fmtgram.y
View file @
9da939e
This diff is collapsed.
Click to expand it.
mh/mh_format.c
View file @
9da939e
This diff is collapsed.
Click to expand it.
mh/mh_format.h
View file @
9da939e
...
...
@@ -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
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
;
};
#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)
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
prog
cnt
;
/* Size of allocated program*/
size_t
prog
size
;
/* 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
);
...
...
mh/mh_init.c
View file @
9da939e
...
...
@@ -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
)
...
...
mh/mh_list.c
View file @
9da939e
...
...
@@ -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
;
};
...
...
Please
register
or
sign in
to post a comment