X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/34336376c78be0e80620c51581a1d1f347423846..167e542ba3ddb6a8cc2eadf2d88ca482b1e657ce:/sbr/fmt_compile.c diff --git a/sbr/fmt_compile.c b/sbr/fmt_compile.c index 0ed2779e..23e07263 100644 --- a/sbr/fmt_compile.c +++ b/sbr/fmt_compile.c @@ -47,6 +47,7 @@ #include #include #include +#include #ifdef HAVE_SYS_TIME_H # include @@ -211,7 +212,6 @@ static struct ftable functable[] = { { "friendly", TF_COMP, FT_LS_FRIENDLY, FT_PARSEADDR, TFL_PUTS }, { "mymbox", TF_COMP, FT_LV_COMPFLAG, FT_MYMBOX, TFL_PUTN }, - { "addtoseq", TF_STR, FT_ADDTOSEQ, 0, 0 }, { "unquote", TF_EXPR, FT_LS_UNQUOTE, 0, TFL_PUTS}, @@ -263,14 +263,14 @@ static struct ftable functable[] = { } while (0) #define LV(type, value) do { NEW(type,0,0); fp->f_value = (value); } while (0) -#define LS(type, str) do { NEW(type,0,0); fp->f_text = (str); fp->f_flags |= FF_STRALLOC; } while (0) +#define LS(type, str) do { NEW(type,0,0); fp->f_text = getcpy(str); fp->f_flags |= FF_STRALLOC; } while (0) #define PUTCOMP(comp) do { NEW(FT_COMP,0,0); ADDC(comp); } while (0) #define PUTLIT(str) do { NEW(FT_LIT,0,0); fp->f_text = getcpy(str); fp->f_flags |= FF_STRALLOC; } while (0) #define PUTC(c) do { NEW(FT_CHAR,0,0); fp->f_char = (c); } while (0) static char *format_string; -static unsigned char *usr_fstring; /* for CERROR */ +static char *usr_fstring; /* for CERROR */ #define CERROR(str) compile_error (str, cp) @@ -321,7 +321,7 @@ compile_error(char *str, char *cp) for (i = errpos-errctx; i < errpos; i++) { #ifdef LOCALE - if (iscntrl(usr_fstring[i])) + if (iscntrl((unsigned char) usr_fstring[i])) #else if (usr_fstring[i] < 32) #endif @@ -354,10 +354,6 @@ fmt_compile(char *fstring, struct format **fmt, int reset_comptable) comptable_initialized = 1; } - /* init the component hash table. */ - for (i = 0; i < sizeof(wantcomp)/sizeof(wantcomp[0]); i++) - wantcomp[i] = 0; - memset((char *) &fmt_mnull, 0, sizeof(fmt_mnull)); /* it takes at least 4 char to generate one format so we @@ -860,6 +856,24 @@ fmt_free(struct format *fmt, int reset_comptable) free_comptable(); } +/* + * Free just the text strings from all of the component hash table entries + */ + +void +fmt_freecomptext(void) +{ + unsigned int i; + struct comp *cm; + + for (i = 0; i < sizeof(wantcomp)/sizeof(wantcomp[0]); i++) + for (cm = wantcomp[i]; cm; cm = cm->c_next) + if (cm->c_text) { + free(cm->c_text); + cm->c_text = NULL; + } +} + /* * Find a component in our hash table. This is just a public interface to * the FINDCOMP macro, so we don't have to expose our hash table. @@ -875,6 +889,108 @@ fmt_findcomp(char *component) return cm; } +/* + * Like fmt_findcomp, but case-insensitive. + */ + +struct comp * +fmt_findcasecomp(char *component) +{ + struct comp *cm; + + for (cm = wantcomp[CHASH(component)]; cm; cm = cm->c_next) + if (strcasecmp(component, cm->c_name ? cm->c_name : "") == 0) + break; + + return cm; +} + +/* + * Add an entry to the component hash table + * + * Returns true if the component was added, 0 if it already existed. + * + */ + +int +fmt_addcompentry(char *component) +{ + struct comp *cm; + int i; + + FINDCOMP(cm, component); + + if (cm) + return 0; + + NEWCOMP(cm, component); + + /* + * ncomp is really meant for fmt_compile() and this function is + * meant to be used outside of it. So decrement it just to be safe + * (internal callers should be using NEWCOMP()). + */ + + ncomp--; + + return 1; +} + +/* + * Add a string to a component hash table entry. + * + * Note the special handling for components marked with CT_ADDR. The comments + * in fmt_scan.h explain this in more detail. + */ + +int +fmt_addcomptext(char *component, char *text) +{ + int i, found = 0, bucket = CHASH(component); + struct comp *cptr = wantcomp[bucket]; + char *cp; + + while (cptr) { + if (strcasecmp(component, cptr->c_name ? cptr->c_name : "") == 0) { + found++; + if (! cptr->c_text) { + cptr->c_text = getcpy(text); + } else { + i = strlen(cp = cptr->c_text) - 1; + if (cp[i] == '\n') { + if (cptr->c_type & CT_ADDR) { + cp[i] = '\0'; + cp = add(",\n\t", cp); + } else { + cp = add("\t", cp); + } + } + cptr->c_text = add(text, cp); + } + } + cptr = cptr->c_next; + } + + return found ? bucket : -1; +} + +/* + * Append text to a component we've already found. See notes in fmt_scan.h + * for more information. + */ + +void +fmt_appendcomp(int bucket, char *component, char *text) +{ + struct comp *cptr; + + if (bucket != -1) { + for (cptr = wantcomp[bucket]; cptr; cptr = cptr->c_next) + if (strcasecmp(component, cptr->c_name ? cptr->c_name : "") == 0) + cptr->c_text = add(text, cptr->c_text); + } +} + /* * Free and reset our component hash table */ @@ -882,7 +998,7 @@ fmt_findcomp(char *component) static void free_comptable(void) { - int i; + unsigned int i; struct comp *cm, *cm2; for (i = 0; i < sizeof(wantcomp)/sizeof(wantcomp[0]); i++) {