File: fmt_scan.h

package info (click to toggle)
nmh 1.6-2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 6,204 kB
  • ctags: 3,851
  • sloc: ansic: 48,922; sh: 16,422; makefile: 559; perl: 509; lex: 402; awk: 74
file content (309 lines) | stat: -rw-r--r-- 10,658 bytes parent folder | download | duplicates (2)
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);