📄 formatsbr.c
字号:
/* formatsbr.c - format string interpretation */#ifndef lintstatic char ident[] = "@(#)$Id: formatsbr.c,v 1.24 1993/08/20 15:48:14 jromine Exp $";#endif /* lint */#include "../h/mh.h"#include "../h/addrsbr.h"#include "../h/formatsbr.h"#include "../zotnet/tws.h"#include "../h/fmtcompile.h"#include <ctype.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>/* */#define NFMTS MAXARGS#define QUOTE '\\'static char *formats = 0;extern char *formataddr (); /* hook for custom address formatting */#ifdef LBLstruct msgs *fmt_current_folder; /* current folder (set by main program) */#endifstatic normalize();static int get_x400_comp();extern int fmt_norm; /* defined in sbr/formatdef.c = AD_NAME */struct mailname fmt_mnull;long time ();/* *//* MAJOR HACK: See MHCHANGES for discussion */char *new_fs (form, format, def)register char *form, *format, *def;{ struct stat st; register FILE *fp; if (formats) free (formats); if (form) { if ((fp = fopen (libpath (form), "r")) == NULL) adios (form, "unable to open format file"); if (fstat (fileno (fp), &st) == NOTOK) adios (form, "unable to stat format file"); if ((formats = malloc ((unsigned) st.st_size + 1)) == NULLCP) adios (form, "unable to allocate space for format"); if (read (fileno(fp), formats, (int) st.st_size) != st.st_size) adios (form, "error reading format file"); formats[st.st_size] = '\0'; (void) fclose (fp); } else { formats = getcpy (format ? format : def); } normalize (formats); return formats;}/* */static normalize (cp)register char *cp;{ register char *dp; for (dp = cp; *cp; cp++) if (*cp != QUOTE) *dp++ = *cp; else switch (*++cp) {#define grot(y,z) case y: *dp++ = z; break; grot ('b', '\b'); grot ('f', '\f'); grot ('n', '\n'); grot ('r', '\r'); grot ('t', '\t'); case '\n': break; case 0: cp--; /* fall */ default: *dp++ = *cp; break; } *dp = 0;}/* *//* * test if string "sub" appears anywhere in string "str" * (case insensitive). */static int match (str, sub)register char *str, *sub;{ register int c1; register int c2; register char *s1; register char *s2;#ifdef LOCALE while (c1 = *sub) { c1 = (isalpha(c1) && isupper(c1)) ? tolower(c1) : c1; while ((c2 = *str++) && c1 != ((isalpha(c2) && isupper(c2)) ? tolower(c2) : c2)) ; if (! c2) return 0; s1 = sub + 1; s2 = str; while ((c1 = *s1++) && ((isalpha(c1) && isupper(c1)) ? tolower(c1) : c1) == ((isalpha(c2 =*s2++) && isupper(c2)) ? tolower(c2) : c2)) ; if (! c1) return 1; }#else while (c1 = *sub) { while ((c2 = *str++) && (c1 | 040) != (c2 | 040)) ; if (! c2) return 0; s1 = sub + 1; s2 = str; while ((c1 = *s1++) && (c1 | 040) == (*s2++ | 040)) ; if (! c1) return 1; }#endif return 1;}/* *//* macros to format data */#define PUTDF(cp, num, wid, fill) if (cp + wid < ep){\ if((i = (num))<0) i = -(num);\ if((c = (wid))<0) c = -c;\ sp = cp + c;\ do {\ *--sp = (i % 10) + '0';\ i /= 10;\ } while (i > 0 && sp > cp);\ if (i > 0)\ *sp = '?';\ else if ((num) < 0 && sp > cp)\ *--sp = '-';\ while (sp > cp)\ *--sp = fill;\ cp += c;\ }#define PUTD(cp, num) if (cp < ep){\ if((i = (num))==0) *cp++ = '0';\ else {\ if((i = (num))<0) \ *cp++ = '-', i = -(num);\ c = 10;\ while (c <= i) \ c *= 10;\ while (cp < ep && c > 1) {\ c /= 10;\ *cp++ = (i / c) + '0';\ i %= c;\ }\ }\ }#ifdef LOCALE#define PUTSF(cp, str, wid, fill) {\ ljust = 0;\ if ((i = (wid)) < 0) {\ i = -i;\ ljust++;\ }\ if (sp = (str)) {\ if (ljust) {\ c = strlen(sp);\ if (c > i)\ sp += c - i;\ else {\ while( --i >= c && cp < ep)\ *cp++ = fill;\ i++;\ }\ } else {\ while ((c = *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ }\ while ((c = *sp++) && --i >= 0 && cp < ep)\ if (isgraph(c)) \ *cp++ = c;\ else {\ while ((c = *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ *cp++ = ' ';\ }\ }\ if (!ljust)\ while( --i >= 0 && cp < ep)\ *cp++ = fill;\ }#define PUTS(cp, str) {\ if (sp = (str)) {\ while ((c = *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ while((c = *sp++) && cp < ep)\ if (isgraph(c)) \ *cp++ = c;\ else {\ while ((c = *sp) && (iscntrl(c) || isspace(c)))\ sp++;\ *cp++ = ' ';\ }\ }\ }#else /* LOCALE */#define PUTSF(cp, str, wid, fill) {\ ljust = 0;\ if ((i = (wid)) < 0) {\ i = -i;\ ljust++;\ }\ if (sp = (str)) {\ if (ljust) {\ c = strlen(sp);\ if (c > i)\ sp += c - i;\ else {\ while( --i >= c && cp < ep)\ *cp++ = fill;\ i++;\ }\ } else {\ while ((c = *sp) && c <= 32)\ sp++;\ }\ while ((c = *sp++) && --i >= 0 && cp < ep)\ if (c > 32) \ *cp++ = c;\ else {\ while ((c = *sp) && c <= 32)\ sp++;\ *cp++ = ' ';\ }\ }\ if (!ljust)\ while( --i >= 0 && cp < ep)\ *cp++ = fill;\ }#define PUTS(cp, str) {\ if (sp = (str)) {\ while ((c = *sp) && c <= 32)\ sp++;\ while( (c = *sp++) && cp < ep)\ if ( c > 32 ) \ *cp++ = c;\ else {\ while ( (c = *sp) && c <= 32 )\ sp++;\ *cp++ = ' ';\ }\ }\ }#endifstatic char *lmonth[] = { "January", "February","March", "April", "May", "June", "July", "August", "September","October", "November","December" };static char *get_x400_friendly (mbox, buffer)char *mbox, *buffer;{ char given[BUFSIZ], surname[BUFSIZ]; if (mbox == NULLCP) return NULLCP; if (*mbox == '"') mbox++; if (*mbox != '/') return NULLCP; if (get_x400_comp (mbox, "/PN=", buffer)) { for (mbox = buffer; mbox = index (mbox, '.'); ) *mbox++ = ' '; return buffer; } if (!get_x400_comp (mbox, "/S=", surname)) return NULLCP; if (get_x400_comp (mbox, "/G=", given)) (void) sprintf (buffer, "%s %s", given, surname); else (void) strcpy (buffer, surname); return buffer;}static int get_x400_comp (mbox, key, buffer)char *mbox, *key, *buffer;{ int idx; char *cp; if ((idx = stringdex (key, mbox)) < 0 || !(cp = index (mbox += idx + strlen (key), '/'))) return 0; (void) sprintf (buffer, "%*.*s", cp - mbox, cp - mbox, mbox); return 1;}struct format *fmtscan (format, scanl, width, dat) struct format *format; char *scanl; int width; int dat[];{ register char *cp = scanl; register char *ep = scanl + width - 1; register struct format *fmt = format; register char *str = NULLCP; register int value = 0; register char *sp; register int i; register int c; register struct comp *comp; register struct tws *tws; register struct mailname *mn; int ljust; long l; char *savestr; char buffer[BUFSIZ]; while (cp < ep) { switch (fmt->f_type) { case FT_COMP: PUTS (cp, fmt->f_comp->c_text); break; case FT_COMPF: PUTSF (cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill); break; case FT_LIT: sp = fmt->f_text; while( (c = *sp++) && cp < ep) *cp++ = c; break; case FT_LITF: sp = fmt->f_text; ljust = 0; i = fmt->f_width; if (i < 0) { i = -i; ljust++; /* XXX should do something with this */ } while( (c = *sp++) && --i >= 0 && cp < ep) *cp++ = c; while( --i >= 0 && cp < ep) *cp++ = fmt->f_fill; break; case FT_STR: PUTS (cp, str); break; case FT_STRF: PUTSF (cp, str, fmt->f_width, fmt->f_fill); break; case FT_STRFW: adios (NULLCP, "internal error (FT_STRFW)"); case FT_NUM: PUTD (cp, value); break; case FT_NUMF: PUTDF (cp, value, fmt->f_width, fmt->f_fill); break; case FT_CHAR: *cp++ = fmt->f_char; break; case FT_DONE: goto finished; case FT_IF_S: if (!(value = (str && *str))) { fmt += fmt->f_skip; continue; } break; case FT_IF_S_NULL: if (!(value = (str == NULLCP || *str == 0))) { fmt += fmt->f_skip; continue; } break; case FT_IF_V_EQ: if (value != fmt->f_value) { fmt += fmt->f_skip; continue; } break; case FT_IF_V_NE: if (value == fmt->f_value) { fmt += fmt->f_skip; continue; } break; case FT_IF_V_GT: if (value <= fmt->f_value) { fmt += fmt->f_skip; continue; } break; case FT_IF_MATCH:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -