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