fd4c555d10d54370de4eadebfea80e5e3d5cdae3
[mmh] / h / fmt_scan.h
1
2 /*
3  * fmt_scan.h -- definitions for fmt_scan()
4  *
5  * $Id$
6  */
7
8 /*
9  * This structure describes an "interesting" component.  It holds
10  * the name & text from the component (if found) and one piece of
11  * auxilary info.  The structure for a particular component is located
12  * by (open) hashing the name and using it as an index into the ptr array
13  * "wantcomp".  All format entries that reference a particular component
14  * point to its comp struct (so we only have to do component specific
15  * processing once.  e.g., parse an address.).
16  */
17 struct comp {
18     char        *c_name;        /* component name (in lower case) */
19     char        *c_text;        /* component text (if found)      */
20     struct comp *c_next;        /* hash chain linkage             */
21     short        c_flags;       /* misc. flags (from fmt_scan)    */
22     short        c_type;        /* type info   (from fmt_compile) */
23     union {
24         struct tws *c_u_tws;
25         struct mailname *c_u_mn;
26     } c_un;
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 #define CT_MYMBOX     (1<<2)    /* "mymbox" test being done */
38 #define CT_ADDRPARSE  (1<<3)    /* address parse being done */
39
40 extern int fmt_norm;
41
42 /*
43  * Hash table for deciding if a component is "interesting".
44  */
45 extern struct comp *wantcomp[128];
46
47 /* 
48  * Hash function for component name.  The function should be
49  * case independent and probably shouldn't involve a routine
50  * call.  This function is pretty good but will not work on
51  * single character component names.  
52  */
53 #define CHASH(nm) (((((nm)[0]) - ((nm)[1])) & 0x1f) + (((nm)[2]) & 0x5f))
54
55 /*
56  * Find a component in the hash table.
57  */
58 #define FINDCOMP(comp,name) \
59                 for (comp = wantcomp[CHASH(name)]; \
60                      comp && strcmp(comp->c_name,name); \
61                      comp = comp->c_next) ;
62
63 /*
64  * This structure defines one formatting instruction.
65  */
66 struct format {
67     unsigned char f_type;
68     char          f_fill;
69     short         f_width;      /* output field width   */
70     union {
71         struct comp *f_u_comp;  /* associated component */
72         char        *f_u_text;  /* literal text         */
73         char         f_u_char;  /* literal character    */
74         int          f_u_value; /* literal value        */
75     } f_un;
76 };
77
78 #define f_skip f_width          /* instr to skip (false "if") */
79
80 #define f_comp  f_un.f_u_comp
81 #define f_text  f_un.f_u_text
82 #define f_char  f_un.f_u_char
83 #define f_value f_un.f_u_value
84
85 /*
86  * prototypes
87  */
88 struct format *fmt_scan (struct format *, char *, int, int *);
89 char *new_fs (char *, char *, char *);
90 int fmt_compile (char *, struct format **);