1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
|
/*
* 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 */
#define CT_BITS "\020\01ADDR\02DATE"
/*
* 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 */
#define CF_BITS "\020\01TRUE\02PARSED\03CF_DATEFAB\04TRIMMED"
/*
* 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
*/
/*
* These are the definitions used by the callbacks for fmt_scan()
*/
typedef char * (*formataddr_cb)(char *, char *);
typedef char * (*concataddr_cb)(char *, char *);
typedef void (*trace_cb)(void *, struct format *, int, char *, char *);
struct fmt_callbacks {
formataddr_cb formataddr;
concataddr_cb concataddr;
trace_cb trace_func;
void * trace_context;
};
/*
* 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)
*
* callbacks - A set of a callback functions used by the format engine.
* Can be NULL. If structure elements are NULL, a default
* function will be used. Callback structure elements are:
*
* formataddr - A callback for the %(formataddr) instruction
* concataddr - A callback for the %(concataddr) instruction
* trace - Called for every format instruction executed
*
* 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, struct fmt_callbacks *callbacks);
/*
* 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);
/*
* Free all of the component text structures in the component hash table
*/
void fmt_freecomptext(void);
/*
* 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);
/*
* Iterate over the complete hash table of component structures.
*
* Arguments are:
*
* comp - Pointer to the current component structure. The next
* component in the hash table after this component. To
* start (or restart) the iteration of the hash table
* this argument should be NULL.
* bucket - Pointer to hash bucket. Will be managed by this function,
* the caller should not modify this value.
*
* Returns the next component in the hash table. This value should be
* passed into the next call to fmt_nextcomp(). Returns NULL at the end
* of the hash table.
*/
struct comp *fmt_nextcomp(struct comp *comp, unsigned int *bucket);
/*
* 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);
|