Changed msg_style and msg_delim to be file static to m_getfld.c
[mmh] / h / fmt_scan.h
index 9872e09..8de6f23 100644 (file)
@@ -11,6 +11,9 @@
  * "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) */
@@ -22,6 +25,7 @@ struct comp {
        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
@@ -39,31 +43,11 @@ struct comp {
 #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 */
 
 extern int fmt_norm;
 
 /*
- * Hash table for deciding if a component is "interesting".
- */
-extern struct comp *wantcomp[128];
-
-/* 
- * Hash function for component name.  The function should be
- * case independent and probably shouldn't involve a routine
- * call.  This function is pretty good but will not work on
- * single character component names.  
- */
-#define        CHASH(nm) (((((nm)[0]) - ((nm)[1])) & 0x1f) + (((nm)[2]) & 0x5f))
-
-/*
- * Find a component in the hash table.
- */
-#define FINDCOMP(comp,name) \
-               for (comp = wantcomp[CHASH(name)]; \
-                    comp && strcmp(comp->c_name,name); \
-                    comp = comp->c_next) ;
-
-/*
  * This structure defines one formatting instruction.
  */
 struct format {
@@ -76,6 +60,7 @@ struct format {
        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") */
@@ -86,8 +71,189 @@ struct format {
 #define f_value f_un.f_u_value
 
 /*
- * prototypes
+ * 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
+ */
+
+/*
+ * 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)
+ *
+ * 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);
+
+/*
+ * 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);
+
+/*
+ * 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);
+
+/*
+ * 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.
  */
-struct format *fmt_scan (struct format *, char *, int, int *);
-char *new_fs (char *, char *, char *);
-int fmt_compile (char *, struct format **);
+
+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);