NAME
fmttest - test programs in nmh’s mh-format(5) language
SYNOPSIS
fmttest |
[-help] [-version] [-form formatfile] [-format formatstring] |
[-address | -raw | -date | -message] [-file | -nofile] [--component component-text] [-dupaddrs | -nodupaddrs] [-ccme | -noccme] [-outsize size-in-characters] [-width column-width] [-msgnum number] [-msgcur flag] [-msgsize size] [-unseen flag] [-dump | -nodump] [-trace | -notrace] [+folder] [msgs | strings]
DESCRIPTION
fmttest is used to test programs written for the nmh format language as specified by mh-format(5). It is also intended to replace the ap, dp, and fmtdump programs.
Format
Program Selection
The -format string and -form
formatfile specify a format string or file to read. A
format string, if given, must be a single argument to the
-format switch. If a format file name is passed to
the -form, switch, the file is searched for using the
normal nmh rules: absolute pathnames are accessed
directly, tilde expansion is done on usernames, and files
are searched for in the user’s Mail directory
as specified in their profile. If not found there, the
directory “/etc/nmh” is checked.
Mode
Selection and Component Specification
fmttest has four operating modes - address, raw, date,
and message - which are selected by the -address,
-raw, -date, and -message switches,
respectively.
Address mode treats every argument as an email address to be processed by nmh’s email parser using the specified format program. The parsed address is made available as a special %{text} component escape, and the output from the program is printed on standard output. If there was an error parsing the email address the error message is stored in the %{error} component escape. If no format program is given on the command line, the following default program is used:
%<{error}%{error}: %{text}%|%(putstr(proper{text}))%>
Address mode is equivalent to ap(8).
In raw mode, no processing of the specified arguments is done. Each argument is run against the specified format program with the argument text available in the %{text} component. You must specify a format with -form or -format when using raw mode.
Date mode is identical to raw mode, with one exception: if no format is specified, the following format string is used:
%<(nodate{text})error: %{text}%|%(putstr(pretty{text}))%>
Date mode is equivalent to dp(8).
In message mode the arguments to fmttest are interpreted as an optional folder and messages. fmttest will read each specified message and make all of the components in the message available to the format program. Also, the appropriate information for the %(msg), %(cur), %(unseen), and %(size) function escapes will be made available for each message. If the -file switch is given, the arguments are interpreted as filenames instead of message numbers, but otherwise the behavior is the same (except that the %(msg), %(cur), and %(unseen) function escapes will not provide any useful information).
The default format used in address mode is the default format used by scan. The following command can replicate the functionality of the repl command.
fmttest -nodupaddrs -form replcomps -outsize max [+folder] message
Regardless of the mode, other components can be provided to the format program by the use of the --component switch. For example, the following program will test the use of the “encrypted” component:
fmttest --encrypted yes -message cur
In message mode, components supplied on the command line will override components from messages.
Additional
Switches
The -dupaddrs and -nodupaddrs switches control
whether duplicate addresses are allowed or suppressed by the
FORMATADDR instruction, which is used by the
’%(formataddr)’ function escape. In
normal operation duplicate addresses are only suppressed by
repl.
The -ccme and -noccme switches control whether or not to count the user’s local mailbox as a duplicate address. This replicates the behavior of the -cc me switch to repl, and only applies if -nodupaddrs is in effect.
The -outsize switch controls the maximum number of printable characters that the format engine will produce. Characters marked as non-printing by the format engine with ’%(zputlit)’, characters with zero width, and extra bytes that are part of a multibyte character are not counted against this total. Two special values are supported: “max”, which means as many characters as the format engine can produce (limited by internal buffers), and “width”, which will set the value to the width of the terminal. In message mode it defaults to “width”, otherwise the default is “max”.
The -width switch controls the column width which is used by the ’%(width)’ function escape. It defaults to the terminal width.
The -msgnum, -msgcur, -msgsize, and the -unseen switches all control the values used, respectively, by the following function escapes: ’%(num)’, ’%(cur)’, ’%(size)’, and ’%(unseen)’. If none are supplied, these values are taken from the message in message mode; in all other modes the default values are 0.
Compiling
and Tracing Format Programs
The -dump switch outputs the complete set of format
instructions for the specified format program. The
-trace switch will output each format instruction as
it is being executed, and show the values of the num
and str registers if they have changed from the
previous instruction. The output buffer is also printed if
it has changed from the previous instruction.
Format
Instructions
It should be noted that there is not a one-to-one
correspondence between format escapes and format
instructions; many instructions have side effects.
Instructions prefixed with “LV” generally
return a integer into the num (value) register;
instructions prefixed with a “LS” return
a string into the str register.
Instruction |
Description | |
COMP |
Output component | |
COMPF |
Formatted output component | |
LIT |
Output literal text | |
CHAR |
Output single character | |
NUM |
Output the num register | |
NUMF |
Formatted output of the num register | |
STR |
Output the str register | |
STRF |
Formatted output of the str register | |
STRFW |
Not used | |
PUTADDR |
Output address list in str register | |
STRLIT |
Output str, no space compression | |
STRLITZ |
Like STRLIT, but not counted against width | |
LS_COMP |
Write component to str register | |
LS_LIT |
Write literal to str register | |
LS_GETENV |
Write environment var to str register | |
LS_DECODECOMP |
Decode RFC 2047 encoded component to str register | |
LS_DECODE |
Decode RFC 2047 encoded string to str register | |
LS_TRIM |
Trim trailing whitespace from str register | |
LV_COMP |
Convert component to integer, store in num register | |
LV_COMPFLAG |
Set num to 1 if TRUE set in component | |
LV_LIT |
Load literal value into num register | |
LV_DAT |
Load value from dat array into num register (see note) | |
LV_STRLEN |
Set num to the length of str | |
LV_PLUS_L |
Add value to num register | |
LV_MINUS_L |
Subtract value from num register | |
LV_DIVIDE_L |
Divide num register by value | |
LV_MODULO_L |
num modulo value | |
LV_CHAR_LEFT |
Store remaining number of printable chars in num | |
LS_MONTH |
Write short name of month to str from date component | |
LS_LMONTH |
Write long name of month to str from date component | |
LS_ZONE |
Write time zone offset to str from date component | |
LS_DAY |
Write short name of day of week to str from date component | |
LS_WEEKDAY |
Write long name of day of week to str from date component | |
LS_822DATE |
Write RFC 822 compatible date to str from date component | |
LS_PRETTY |
Write date with “pretty” timezone to str | |
LV_SEC |
Write date component seconds to num | |
LV_MIN |
Write date component minutes to num | |
LV_HOUR |
Write date component hour to num | |
LV_MON |
Write date component numeric month to num (start at 1) | |
LV_YEAR |
Write date component year to num | |
LV_YDAY |
Write date component Julian day to num | |
LV_WDAY |
Write date component day of week to num (0 == Sunday) | |
LV_ZONE |
Write date component time zone offset to num | |
LV_CLOCK |
Write date component in Unix epoch time to num | |
LV_RCLOCK |
Write offset of date component from current time to num | |
LV_DAYF |
Write 1 to num if day of week is explicit | |
LV_DST |
Write 1 to num if DST is in effect for date component | |
LV_ZONEF |
Write 1 to num if timezone is explicit | |
LS_ADDR |
Write email address of addr component to str | |
LS_PERS |
Write personal name of addr component to str | |
LS_MBOX |
Write mailbox (username) of addr component to str | |
LS_HOST |
Write host of addr component to str | |
LS_PATH |
Write host route of addr component to str | |
LS_GNAME |
Write group name of addr component to str | |
LS_NOTE |
Write note portion of addr component to str | |
LS_822ADDR |
Write “proper” RFC 822 version of addr component to str | |
LS_FRIENDLY |
Write friendly (name or note) of address component to str | |
LS_UNQUOTE |
Remove RFC 2822 quotes from string | |
LV_HOSTTYPE |
Set num to type of host (0=local, 1=network) | |
LV_INGRPF |
Set num to 1 if address was inside of group | |
LV_NOHOSTF |
Set num to 1 of no host was present in address component | |
LOCALDATE |
Convert date component to local timezone | |
GMTDATE |
Convert date component to GMT | |
PARSEDATE |
Parse date component | |
PARSEADDR |
Parse address component | |
FORMATADDR |
Add address component to list in str | |
CONCATADDR |
Like FORMATADDR, but will not suppress duplicates | |
MYMBOX |
Set num if address component is a local address | |
SAVESTR |
Save str register temporarily | |
DONE |
End program | |
NOP |
No operation | |
GOTO |
Jump to new instruction | |
IF_S_NULL |
Branch if str is NULL | |
IF_S |
Branch if str is not NULL | |
IF_V_EQ |
Branch if num is equal to value | |
IF_V_NE |
Branch if num is not equal to value | |
IF_V_GT |
Branch if num is greater than value | |
IF_MATCH |
Branch if str contains string | |
IF_AMATCH |
Branch if str starts with string | |
S_NULL |
Set num to 1 if str is NULL | |
S_NONNULL |
Set num to 1 if str is not NULL | |
V_EQ |
Set num to 1 if num equals value | |
V_NE |
Set num to 1 if num does not equal value | |
V_GT |
Set num to 1 if num is greater than value | |
V_MATCH |
Set num to 1 if str contains string | |
V_AMATCH |
Set num to 1 if str starts with string |
The LV_DAT instruction is a bit special. Callers of the format library pass in an array of integers that are used by certain format escapes. The current list of format escapes and the indexes they use are:
dat[0] | ||
%(num) | ||
dat[1] | ||
%(cur) | ||
dat[2] | ||
%(size) | ||
dat[3] | ||
%(width) | ||
dat[4] | ||
%(unseen) |
SEE ALSO
mh-format(5), repl(1), ap(8), dp(8), fmtdump(8)
DEFAULTS
’-message’
’-nofile’
’-dupaddrs’
CONTEXT
If a folder is given, it will become the current folder.
BUGS
It shouldn’t require as much code from other programs as it does.