X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=h%2Ffmt_scan.h;h=466a9b5decc272ce156fac8f15210449a34884ed;hb=a3fd48a5f54f47e342d36c79a97d2fcad8919d20;hp=cece50e002bcf15ffcef91c15a06fc859875c43d;hpb=cafee7a804b8aa53166065e988ec0fc387862fc8;p=mmh diff --git a/h/fmt_scan.h b/h/fmt_scan.h index cece50e..466a9b5 100644 --- a/h/fmt_scan.h +++ b/h/fmt_scan.h @@ -1,8 +1,6 @@ /* * fmt_scan.h -- definitions for fmt_scan() - * - * $Id$ */ /* @@ -13,6 +11,9 @@ * "wantcomp". All format entries that reference a particular component * point to its comp struct (so we only have to do component specific * processing once. e.g., parse an address.). + * + * In previous implementations "wantcomp" was made available to other + * functions, but now it's private and is accessed via functions. */ struct comp { char *c_name; /* component name (in lower case) */ @@ -24,6 +25,7 @@ struct comp { struct tws *c_u_tws; struct mailname *c_u_mn; } c_un; + int c_refcount; /* Reference count */ }; #define c_tws c_un.c_u_tws @@ -41,31 +43,11 @@ struct comp { #define CF_TRUE (1<<0) /* usually means component is present */ #define CF_PARSED (1<<1) /* address/date has been parsed */ #define CF_DATEFAB (1<<2) /* datefield fabricated */ +#define CF_TRIMMED (1<<3) /* Component has been trimmed */ extern int fmt_norm; /* - * Hash table for deciding if a component is "interesting". - */ -extern struct comp *wantcomp[128]; - -/* - * Hash function for component name. The function should be - * case independent and probably shouldn't involve a routine - * call. This function is pretty good but will not work on - * single character component names. - */ -#define CHASH(nm) (((((nm)[0]) - ((nm)[1])) & 0x1f) + (((nm)[2]) & 0x5f)) - -/* - * Find a component in the hash table. - */ -#define FINDCOMP(comp,name) \ - for (comp = wantcomp[CHASH(name)]; \ - comp && strcmp(comp->c_name,name); \ - comp = comp->c_next) ; - -/* * This structure defines one formatting instruction. */ struct format { @@ -78,6 +60,7 @@ struct format { char f_u_char; /* literal character */ int f_u_value; /* literal value */ } f_un; + short f_flags; /* misc. flags */ }; #define f_skip f_width /* instr to skip (false "if") */ @@ -88,8 +71,170 @@ struct format { #define f_value f_un.f_u_value /* - * prototypes + * f_flags bits + */ + +#define FF_STRALLOC (1<<0) /* String has been allocated */ +#define FF_COMPREF (1<<1) /* Component reference */ + +/* + * prototypes used by the format engine + */ + +/* + * Create a new format string. Arguments are: + * + * form - Name of format file. Will be searched by etcpath(), see that + * function for details. + * format - The format string to be used if no format file is given + * default_fs - The default format string to be used if neither form nor + * format is given + * + * This function also takes care of processing \ escapes like \n, \t, etc. + * + * Returns an allocated format string. + */ + +char *new_fs (char *form, char *format, char *default_fs); + +/* + * Compile a format string into a set of format instructions. Arguments are: + * + * fstring - The format string (the "source code"). + * fmt - Returns an allocated array of "struct fmt" elements. Each + * struct fmt is one format instruction interpreted by the + * format engine. + * reset - If set to true, the format compiler will reset the + * component hash table. The component hash table contains + * all of the references to message components refered to in + * the format instructions. If you have multiple format + * strings that you want to compile and operate on the + * same message, this should be set to false. + * + * Returns the total number of components referenced by all format instructions + * since the last reset of the hash table. */ -struct format *fmt_scan (struct format *, char *, int, int *); -char *new_fs (char *, char *, char *); -int fmt_compile (char *, struct format **); + +int fmt_compile (char *fstring, struct format **fmt, int reset); + +/* + * Interpret a sequence of compiled format instructions. Arguments are: + * + * format - Array of format instructions generated by fmt_compile() + * scanl - Passed-in character array that will contain the output + * of the format instructions. Is always terminated with + * a newline (\n). + * max - Maximum number of bytes to be written to "scanl" (in other + * words, the buffer size). Includes the trailing NUL. + * width - Maximum number of displayed characters. Does not include + * characters marked as nonprinting or (depending on the + * encoding) bytes in a multibyte encoding that exceed the + * character's column width. + * dat - An integer array that contains data used by certain format + * functions. Currently the following instructions use + * dat[]: + * + * dat[0] - %(msg), %(dat) + * dat[1] - %(cur) + * dat[2] - %(size) + * dat[3] - %(width) + * dat[4] - %(unseen) + * + * The return value is a pointer to the next format instruction to + * execute, which is currently always NULL. + */ + +struct format *fmt_scan (struct format *format, char *scanl, size_t max, + int width, int *dat); + +/* + * Free a format structure and/or component hash table. Arguments are: + * + * format - An array of format structures allocated by fmt_compile, + * or NULL. + * reset - If true, reset and remove all references in the component + * hash table. + */ + +void fmt_free (struct format *fmt, int reset); + +/* + * Search for a component structure in the component hash table. Arguments are: + * + * component - The name of the component to search for. By convention + * all component names used in format strings are lower case, + * but for backwards compatibility this search is done in + * a case-SENSITIVE manner. + * + * This function returns a "struct comp" corresponding to the named component, + * or NULL if the component is not found in the hash table. + */ + +struct comp *fmt_findcomp(char *component); + +/* + * Add a string to a component hash table entry. Arguments are: + * + * component - The name of the component to add text to. The component + * is searched for in a case-INSENSITIVE manner (note that + * this is different than fmt_findcomp()). If the component + * is not found in the hash table, this function will silently + * return. + * text - The text to add to a component hash table entry. Note that + * if the last character of the existing component + * text is a newline AND it is marked as an address + * component (the the CT_ADDR flag is set) existing + * component buffer is a newline, it will be separated + * from previous text by ",\n\t"; otherwise if the last + * character of the previous text is a newline it will + * simply be seperated by a "\t". This unusual processing + * is designed to handle the case where you have multiple + * headers with the same name (e.g.: multiple "cc:" headers, + * even though that isn't technically allowed in the RFCs). + * + * This function is designed to be called when you start processing a new + * component. The function returns the integer value of the hash table + * bucket corresponding to this component. If there was no entry found + * in the component hash table, this function will return -1. + */ + +int fmt_addcomp(char *component, char *text); + +/* + * Append to an existing component. Arguments are: + * + * bucket - The hash table bucket corresponding to this component, + * as returned by fmt_addcomp(). If -1, this function will + * return with no actions performed. + * component - The component to append text to. Like fmt_addcomp, the + * component is searched case-INSENSITIVELY. + * text - The text to append to the component. No special processing + * is done. + * + * This function is designed to be called when you are processing continuation + * lines on the same header (state == FLDPLUS). + */ + +void fmt_appendcomp(int bucket, char *component, char *text); + +/* + * The implementation of the %(formataddr) function. This is available for + * programs to provide their own local implementation if they wish to do + * special processing (see uip/replsbr.c for an example). Arguments are: + * + * orig - Existing list of addresses + * str - New address(es) to append to list. + * + * This function returns an allocated string containing the new list of + * addresses. + */ + +char *formataddr(char *orig, char *str); + +/* + * The implementation of the %(concataddr) function. Arguments and behavior + * are the same as %(formataddr). Again, see uip/replsbr.c to see how you + * can override this behavior. + */ + +char *concataddr(char *orig, char *str);