📄 formatsbr.c
字号:
/* formatsbr.c - format string interpretation */#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 VANstruct msgs *fmt_current_folder; /* current folder (set by main program) */#endifstatic normalize();static char *address_break_point();int fmt_norm = 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, 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 NULL: cp--; /* fall */ default: *dp++ = *cp; break; } *dp = NULL;}/* *//* * 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; 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; } 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;\ }\ }\ }#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++ = ' ';\ }\ }\ }static char *lmonth[] = { "January", "February","March", "April", "May", "June", "July", "August", "September","October", "November","December" };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 (str == NULLCP || *str == NULL) { fmt += fmt->f_skip; continue; } break; case FT_IF_S_NULL: if (str != NULLCP && *str != NULL) { 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: if (!str || !match (str, fmt->f_text)) { fmt += fmt->f_skip; continue; } break; case FT_V_MATCH: if (str) value = match (str, fmt->f_text); else value = 0; break; case FT_IF_AMATCH: if (!str || !uprf (str, fmt->f_text)) { fmt += fmt->f_skip; continue; } break; case FT_V_AMATCH: value = uprf (str, fmt->f_text); break; case FT_S_NONNULL: value = (str != NULLCP && *str != NULL); break; case FT_S_NULL: value = (str == NULLCP || *str == NULL); break; case FT_V_EQ: value = (fmt->f_value == value); break; case FT_V_NE: value = (fmt->f_value != value); break; case FT_V_GT: value = (fmt->f_value > value); break; case FT_GOTO: fmt += fmt->f_skip; continue; case FT_NOP: break; case FT_LS_COMP: str = fmt->f_comp->c_text; break; case FT_LS_LIT: str = fmt->f_text; break; case FT_LS_TRIM: if (str) { register char *xp; (void) strcpy(buffer, str); str = buffer; while (isspace(*str)) str++; ljust = 0; if ((i = fmt->f_width) < 0) { i = -i; ljust++; /* XXX should do something with this */ } if (i > 0 && strlen(str) > i) str[i] = '\0'; xp = str; xp += strlen(str) - 1; while (xp > str && isspace(*xp)) *xp-- = '\0'; } break; case FT_LV_COMPFLAG: value = fmt->f_comp->c_flags; break; case FT_LV_COMP: value = (comp = fmt->f_comp)->c_text ? atoi(comp->c_text) : 0; break; case FT_LV_LIT: value = fmt->f_value; break; case FT_LV_DAT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -