X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Ffmt_compile.c;h=1fc5f36d9984831c7609bb64e0f6d005d3b5b47b;hp=cf5c497bb938c7b212577a2d55c8bb6c9bcdf111;hb=db62cda50055368e5f4ac51df787053f70706c30;hpb=39cd310f18074231e3400e53f7e5234a8615a87e diff --git a/sbr/fmt_compile.c b/sbr/fmt_compile.c index cf5c497..1fc5f36 100644 --- a/sbr/fmt_compile.c +++ b/sbr/fmt_compile.c @@ -4,6 +4,38 @@ ** This code is Copyright (c) 2002, by the authors of nmh. See the ** COPYRIGHT file in the root directory of the nmh distribution for ** complete copyright information. +** +** This code compiles the format strings (documented in mh-format(5)) into +** an internal form to be later processed by fmt_scan.c. +** +** What happens here is that the format strings are parsed and an array +** of struct format structures are returned. Each format structure is +** a single operation interpreted by the the routines in fmt_scan.c. +** +** There is a NOT a one-to-one correspondence between format strings and +** format instructions; some functions have side effects that can result +** in multiple instructions being generated. The exact list of instructions +** generated by a format string can be seem with the nmh fmtdump utility. +** +** A list of format instructions can be found in fmt_compile.h. +** +** If you wish to add a new function, you will need to do the following +** things: +** +** - Add a new instruction to the list of instructions in fmt_compile.h. +** Note that test instructions (starting with FT_IF_S_NULL) have special +** handling, so if you are NOT writing a test function then you need +** to insert it into the list before that _and_ bump all of the +** following instruction numbers. +** +** - Add the function name to the functable[] array below, and write any +** special code that your function may require in terms of parsing +** (it very well may not need anything). +** +** - Add the code in fmt_scan.c to handle your new function. +** +** - Document the new function in the mh-format(5) man page. +** */ #include @@ -12,16 +44,10 @@ #include #include -#ifdef TIME_WITH_SYS_TIME +#ifdef HAVE_SYS_TIME_H # include -# include -#else -# ifdef TM_IN_SYS_TIME -# include -# else -# include -# endif #endif +#include /* ** hash table for deciding if a component is "interesting" @@ -57,6 +83,30 @@ extern struct mailname fmt_mnull; #define TFL_PUTS 1 /* implicit putstr if top level */ #define TFL_PUTN 2 /* implicit putnum if top level */ +/* +** The functable array maps between the text names of format functions and +** the format instructions interpreted by the engine in fmt_scan.c. +** +** The elements of this structure are as follows: +** +** name: The name of the function as seen in the format string. This is +** what maps a particular function name into a format instruction. +** type: The type of argument this function expects. Those types are +** listed above (with the TF_ prefix). This affects what gets +** placed in the format instruction (the f_un union). +** f_type: The instruction corresponding to this function (from the list +** in fmt_compile.h). +** extra: Used by some functions to provide extra data to the compiler. +** Uses include: +** - Providing an alternate instruction to combine a load +** and test operation (see do_if()). +** - Passed in f_value in the format instruction to provide +** extra information for the engine (see FT_LV_DAT handling +** in fmt_scan.c). +** - Provide a hint as to preprocessing that is required for +** this instruction (see do_name()). +** flags: See the definitions for TFL_PUTS & TFL_PUTN above. +*/ struct ftable { char *name; /* function name */ char type; /* argument type */ @@ -148,7 +198,6 @@ static struct ftable functable[] = { { "friendly", TF_COMP, FT_LS_FRIENDLY, FT_PARSEADDR, TFL_PUTS }, { "mymbox", TF_COMP, FT_LV_COMPFLAG, FT_MYMBOX, TFL_PUTN }, - { "addtoseq", TF_STR, FT_ADDTOSEQ, 0, 0 }, { "unquote", TF_EXPR, FT_LS_UNQUOTE, 0, TFL_PUTS}, @@ -192,11 +241,6 @@ static unsigned char *usr_fstring; /* for CERROR */ #define CERROR(str) compile_error(str, cp) /* -** external prototypes -*/ -extern char *getusername(void); - -/* ** static prototypes */ static struct ftable *lookup(char *); @@ -210,6 +254,9 @@ static char *do_loop(char *); static char *do_if(char *); +/* +** Lookup a function name in the functable +*/ static struct ftable * lookup(char *name) { @@ -242,7 +289,7 @@ compile_error(char *str, char *cp) } advise(NULL, "\"%s\": format compile error - %s", - &usr_fstring[errpos-errctx], str); + &usr_fstring[errpos-errctx], str); adios(NULL, "%*s", errctx+1, "^"); } @@ -251,12 +298,11 @@ compile_error(char *str, char *cp) ** Return the number of header components found in the format ** string. */ - int fmt_compile(char *fstring, struct format **fmt) { register char *cp; - int i; + size_t i; if (format_string) free(format_string); @@ -355,14 +401,15 @@ compile(char *sp) } +/* +** Process functions & components (handle field width here as well +*/ static char * do_spec(char *sp) { register char *cp = sp; register int c; -#ifndef lint register int ljust = 0; -#endif /* not lint */ register int wid = 0; register char fill = ' '; @@ -403,6 +450,12 @@ do_spec(char *sp) return (cp); } + +/* +** Process a component name. Normally this involves generating an FT_COMP +** instruction for the specified component. If preprocess is set, then we +** do some extra processing. +*/ static char * do_name(char *sp, int preprocess) { @@ -457,6 +510,11 @@ do_name(char *sp, int preprocess) return (cp); } + +/* +** Generate one or more instructions corresponding to the named function. +** The different type of function arguments are handled here. +*/ static char * do_func(char *sp) { @@ -549,6 +607,11 @@ do_func(char *sp) return (cp); } + +/* +** Handle an expression as an argument. Basically we call one of do_name(), +** do_func(), or do_if() +*/ static char * do_expr(char *sp, int preprocess) { @@ -570,6 +633,16 @@ do_expr(char *sp, int preprocess) return (cp); } + +/* +** I am guessing this was for some kind of loop statement, which would have +** looked like %[ .... %]. It looks like the way this would have worked +** is that the format engine would have seen that FT_DONE had a 1 in the +** f_un.f_un_value and then decided whether or not to continue the loop. +** There is no support for this in the format engine, so right now if +** you try using it you will reach the FT_DONE and simply stop. I'm leaving +** this here in case someone wants to continue the work. +*/ static char * do_loop(char *sp) { @@ -588,6 +661,13 @@ do_loop(char *sp) return cp; } + +/* +** Handle an if-elsif-endif statement. Note here that the branching +** is handled by the f_skip member of the struct format (which is really +** just f_width overloaded). This number controls how far to move forward +** (or back) in the format instruction array. +*/ static char * do_if(char *sp) {