/* * fmt_scan.h -- definitions for fmt_scan() */ /* * This structure describes an "interesting" component. It holds * the name & text from the component (if found) and one piece of * auxilary info. The structure for a particular component is located * by (open) hashing the name and using it as an index into the ptr array * "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) */ char *c_text; /* component text (if found) */ struct comp *c_next; /* hash chain linkage */ short c_flags; /* misc. flags (from fmt_scan) */ short c_type; /* type info (from fmt_compile) */ union { 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 #define c_mn c_un.c_u_mn /* * c_type bits */ #define CT_ADDR (1<<0) /* referenced as address */ #define CT_DATE (1<<1) /* referenced as date */ /* * c_flags bits */ #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; /* * This structure defines one formatting instruction. */ struct format { unsigned char f_type; char f_fill; short f_width; /* output field width */ union { struct comp *f_u_comp; /* associated component */ char *f_u_text; /* literal text */ 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") */ #define f_comp f_un.f_u_comp #define f_text f_un.f_u_text #define f_char f_un.f_u_char #define f_value f_un.f_u_value /* * 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. */ 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); /* * Search for a component structure in the component hash table. * * Identical to fmd_findcomp(), but is case-INSENSITIVE. */ struct comp *fmt_findcasecomp(char *component); /* * Add a component entry to the component hash table * * component - The name of the component to add to the hash table. * * If the component is already in the hash table, this function will do * nothing. Returns 1 if a component was added, 0 if it already existed. */ int fmt_addcompentry(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_addcomptext(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);