]> diplodocus.org Git - nmh/blob - h/fmt_scan.h
Temporarily added a few hacks to diagnose problems found by buildbot.
[nmh] / h / fmt_scan.h
1
2 /*
3 * fmt_scan.h -- definitions for fmt_scan()
4 */
5
6 /*
7 * This structure describes an "interesting" component. It holds
8 * the name & text from the component (if found) and one piece of
9 * auxilary info. The structure for a particular component is located
10 * by (open) hashing the name and using it as an index into the ptr array
11 * "wantcomp". All format entries that reference a particular component
12 * point to its comp struct (so we only have to do component specific
13 * processing once. e.g., parse an address.).
14 *
15 * In previous implementations "wantcomp" was made available to other
16 * functions, but now it's private and is accessed via functions.
17 */
18 struct comp {
19 char *c_name; /* component name (in lower case) */
20 char *c_text; /* component text (if found) */
21 struct comp *c_next; /* hash chain linkage */
22 short c_flags; /* misc. flags (from fmt_scan) */
23 short c_type; /* type info (from fmt_compile) */
24 union {
25 struct tws *c_u_tws;
26 struct mailname *c_u_mn;
27 } c_un;
28 int c_refcount; /* Reference count */
29 };
30
31 #define c_tws c_un.c_u_tws
32 #define c_mn c_un.c_u_mn
33
34 /*
35 * c_type bits
36 */
37 #define CT_ADDR (1<<0) /* referenced as address */
38 #define CT_DATE (1<<1) /* referenced as date */
39
40 #define CT_BITS "\020\01ADDR\02DATE"
41
42 /*
43 * c_flags bits
44 */
45 #define CF_TRUE (1<<0) /* usually means component is present */
46 #define CF_PARSED (1<<1) /* address/date has been parsed */
47 #define CF_DATEFAB (1<<2) /* datefield fabricated */
48 #define CF_TRIMMED (1<<3) /* Component has been trimmed */
49
50 #define CF_BITS "\020\01TRUE\02PARSED\03CF_DATEFAB\04TRIMMED"
51
52 extern int fmt_norm;
53
54 /*
55 * This structure defines one formatting instruction.
56 */
57 struct format {
58 unsigned char f_type;
59 char f_fill;
60 short f_width; /* output field width */
61 union {
62 struct comp *f_u_comp; /* associated component */
63 char *f_u_text; /* literal text */
64 char f_u_char; /* literal character */
65 int f_u_value; /* literal value */
66 } f_un;
67 short f_flags; /* misc. flags */
68 };
69
70 #define f_skip f_width /* instr to skip (false "if") */
71
72 #define f_comp f_un.f_u_comp
73 #define f_text f_un.f_u_text
74 #define f_char f_un.f_u_char
75 #define f_value f_un.f_u_value
76
77 /*
78 * f_flags bits
79 */
80
81 #define FF_STRALLOC (1<<0) /* String has been allocated */
82 #define FF_COMPREF (1<<1) /* Component reference */
83
84 /*
85 * prototypes used by the format engine
86 */
87
88 /*
89 * These are the definitions used by the callbacks for fmt_scan()
90 */
91
92 typedef char * (*formataddr_cb)(char *, char *);
93 typedef char * (*concataddr_cb)(char *, char *);
94 typedef void (*trace_cb)(void *, struct format *, int, char *, char *);
95
96 struct fmt_callbacks {
97 formataddr_cb formataddr;
98 concataddr_cb concataddr;
99 trace_cb trace_func;
100 void * trace_context;
101 };
102
103 /*
104 * Create a new format string. Arguments are:
105 *
106 * form - Name of format file. Will be searched by etcpath(), see that
107 * function for details.
108 * format - The format string to be used if no format file is given
109 * default_fs - The default format string to be used if neither form nor
110 * format is given
111 *
112 * This function also takes care of processing \ escapes like \n, \t, etc.
113 *
114 * Returns an allocated format string.
115 */
116
117 char *new_fs (char *form, char *format, char *default_fs);
118
119 /*
120 * Compile a format string into a set of format instructions. Arguments are:
121 *
122 * fstring - The format string (the "source code").
123 * fmt - Returns an allocated array of "struct fmt" elements. Each
124 * struct fmt is one format instruction interpreted by the
125 * format engine.
126 * reset - If set to true, the format compiler will reset the
127 * component hash table. The component hash table contains
128 * all of the references to message components refered to in
129 * the format instructions. If you have multiple format
130 * strings that you want to compile and operate on the
131 * same message, this should be set to false.
132 *
133 * Returns the total number of components referenced by all format instructions
134 * since the last reset of the hash table.
135 */
136
137 int fmt_compile (char *fstring, struct format **fmt, int reset);
138
139 /*
140 * Interpret a sequence of compiled format instructions. Arguments are:
141 *
142 * format - Array of format instructions generated by fmt_compile()
143 * scanl - Passed-in character array that will contain the output
144 * of the format instructions. Is always terminated with
145 * a newline (\n).
146 * max - Maximum number of bytes to be written to "scanl" (in other
147 * words, the buffer size). Includes the trailing NUL.
148 * width - Maximum number of displayed characters. Does not include
149 * characters marked as nonprinting or (depending on the
150 * encoding) bytes in a multibyte encoding that exceed the
151 * character's column width.
152 * dat - An integer array that contains data used by certain format
153 * functions. Currently the following instructions use
154 * dat[]:
155 *
156 * dat[0] - %(msg), %(dat)
157 * dat[1] - %(cur)
158 * dat[2] - %(size)
159 * dat[3] - %(width)
160 * dat[4] - %(unseen)
161 *
162 * callbacks - A set of a callback functions used by the format engine.
163 * Can be NULL. If structure elements are NULL, a default
164 * function will be used. Callback structure elements are:
165 *
166 * formataddr - A callback for the %(formataddr) instruction
167 * concataddr - A callback for the %(concataddr) instruction
168 * trace - Called for every format instruction executed
169 *
170 * The return value is a pointer to the next format instruction to
171 * execute, which is currently always NULL.
172 */
173
174 struct format *fmt_scan (struct format *format, char *scanl, size_t max,
175 int width, int *dat, struct fmt_callbacks *callbacks);
176
177 /*
178 * Free a format structure and/or component hash table. Arguments are:
179 *
180 * format - An array of format structures allocated by fmt_compile,
181 * or NULL.
182 * reset - If true, reset and remove all references in the component
183 * hash table.
184 */
185
186 void fmt_free (struct format *fmt, int reset);
187
188 /*
189 * Free all of the component text structures in the component hash table
190 */
191
192 void fmt_freecomptext(void);
193
194 /*
195 * Search for a component structure in the component hash table. Arguments are:
196 *
197 * component - The name of the component to search for. By convention
198 * all component names used in format strings are lower case,
199 * but for backwards compatibility this search is done in
200 * a case-SENSITIVE manner.
201 *
202 * This function returns a "struct comp" corresponding to the named component,
203 * or NULL if the component is not found in the hash table.
204 */
205
206 struct comp *fmt_findcomp(char *component);
207
208 /*
209 * Search for a component structure in the component hash table.
210 *
211 * Identical to fmd_findcomp(), but is case-INSENSITIVE.
212 */
213
214 struct comp *fmt_findcasecomp(char *component);
215
216 /*
217 * Add a component entry to the component hash table
218 *
219 * component - The name of the component to add to the hash table.
220 *
221 * If the component is already in the hash table, this function will do
222 * nothing. Returns 1 if a component was added, 0 if it already existed.
223 */
224
225 int fmt_addcompentry(char *component);
226
227 /*
228 * Add a string to a component hash table entry. Arguments are:
229 *
230 * component - The name of the component to add text to. The component
231 * is searched for in a case-INSENSITIVE manner (note that
232 * this is different than fmt_findcomp()). If the component
233 * is not found in the hash table, this function will silently
234 * return.
235 * text - The text to add to a component hash table entry. Note that
236 * if the last character of the existing component
237 * text is a newline AND it is marked as an address
238 * component (the the CT_ADDR flag is set) existing
239 * component buffer is a newline, it will be separated
240 * from previous text by ",\n\t"; otherwise if the last
241 * character of the previous text is a newline it will
242 * simply be seperated by a "\t". This unusual processing
243 * is designed to handle the case where you have multiple
244 * headers with the same name (e.g.: multiple "cc:" headers,
245 * even though that isn't technically allowed in the RFCs).
246 *
247 * This function is designed to be called when you start processing a new
248 * component. The function returns the integer value of the hash table
249 * bucket corresponding to this component. If there was no entry found
250 * in the component hash table, this function will return -1.
251 */
252
253 int fmt_addcomptext(char *component, char *text);
254
255 /*
256 * Append to an existing component. Arguments are:
257 *
258 * bucket - The hash table bucket corresponding to this component,
259 * as returned by fmt_addcomp(). If -1, this function will
260 * return with no actions performed.
261 * component - The component to append text to. Like fmt_addcomp, the
262 * component is searched case-INSENSITIVELY.
263 * text - The text to append to the component. No special processing
264 * is done.
265 *
266 * This function is designed to be called when you are processing continuation
267 * lines on the same header (state == FLDPLUS).
268 */
269
270 void fmt_appendcomp(int bucket, char *component, char *text);
271
272 /*
273 * The implementation of the %(formataddr) function. This is available for
274 * programs to provide their own local implementation if they wish to do
275 * special processing (see uip/replsbr.c for an example). Arguments are:
276 *
277 * orig - Existing list of addresses
278 * str - New address(es) to append to list.
279 *
280 * This function returns an allocated string containing the new list of
281 * addresses.
282 */
283
284 char *formataddr(char *orig, char *str);
285
286 /*
287 * The implementation of the %(concataddr) function. Arguments and behavior
288 * are the same as %(formataddr). Again, see uip/replsbr.c to see how you
289 * can override this behavior.
290 */
291
292 char *concataddr(char *orig, char *str);