- 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:
- cp =PUTSF (cp, str, fmt->f_width, fmt->f_fill);
- break;
- case FT_STRFW:
- adios (NULL, "internal error (FT_STRFW)");
-
- case FT_NUM:
- n = snprintf(cp, ep - cp, "%d", value);
- if (n >= 0) cp += n;
- 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 == NULL || *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:
- if (!(value = (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 (!(value = (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 != NULL && *str != 0);
- break;
-
- case FT_S_NULL:
- value = (str == NULL || *str == 0);
- 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_GETENV:
- if (!(str = getenv (fmt->f_text)))
- str = "";
- break;
- case FT_LS_CFIND:
- if (!(str = context_find (fmt->f_text)))
- str = "";
- break;
-
- case FT_LS_DECODECOMP:
- if (decode_rfc2047(fmt->f_comp->c_text, buffer2, sizeof(buffer2)))
- str = buffer2;
- else
- str = fmt->f_comp->c_text;
- break;
-
- case FT_LS_DECODE:
- if (str && decode_rfc2047(str, buffer2, sizeof(buffer2)))
- str = buffer2;
- break;
-
- case FT_LS_TRIM:
- if (str) {
- char *xp;
-
- strncpy(buffer, str, sizeof(buffer));
- buffer[sizeof(buffer)-1] = '\0';
- str = buffer;
- while (isspace(*str))
- str++;
- ljust = 0;
- if ((i = fmt->f_width) < 0) {
- i = -i;
- ljust++;
- }
-
- if (!ljust && i > 0 && strlen(str) > i)
- str[i] = '\0';
- xp = str;
- xp += strlen(str) - 1;
- while (xp > str && isspace(*xp))
- *xp-- = '\0';
- if (ljust && i > 0 && strlen(str) > i)
- str += strlen(str) - i;
- }
- break;
-
- case FT_LV_COMPFLAG:
- value = (fmt->f_comp->c_flags & CF_TRUE) != 0;
- 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:
- value = dat[fmt->f_value];
- break;
- case FT_LV_STRLEN:
- if (str != NULL)
- value = strlen(str);
- else
- value = 0;
- break;
- case FT_LV_CHAR_LEFT:
- value = width - (cp - scanl);
- break;
- case FT_LV_PLUS_L:
- value += fmt->f_value;
- break;
- case FT_LV_MINUS_L:
- value = fmt->f_value - value;
- break;
- case FT_LV_DIVIDE_L:
- if (fmt->f_value)
- value = value / fmt->f_value;
- else
- value = 0;
- break;
- case FT_LV_MODULO_L:
- if (fmt->f_value)
- value = value % fmt->f_value;
- else
- value = 0;
- break;
- case FT_SAVESTR:
- savestr = str;
- break;
-
- case FT_LV_SEC:
- value = fmt->f_comp->c_tws->tw_sec;
- break;
- case FT_LV_MIN:
- value = fmt->f_comp->c_tws->tw_min;
- break;
- case FT_LV_HOUR:
- value = fmt->f_comp->c_tws->tw_hour;
- break;
- case FT_LV_MDAY:
- value = fmt->f_comp->c_tws->tw_mday;
- break;
- case FT_LV_MON:
- value = fmt->f_comp->c_tws->tw_mon + 1;
- break;
- case FT_LS_MONTH:
- str = tw_moty[fmt->f_comp->c_tws->tw_mon];
- break;
- case FT_LS_LMONTH:
- str = lmonth[fmt->f_comp->c_tws->tw_mon];
- break;
- case FT_LS_ZONE:
- str = dtwszone (fmt->f_comp->c_tws);
- break;
- case FT_LV_YEAR:
- value = fmt->f_comp->c_tws->tw_year;
- break;
- case FT_LV_WDAY:
- if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
- set_dotw (tws);
- value = tws->tw_wday;
- break;
- case FT_LS_DAY:
- if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
- set_dotw (tws);
- str = tw_dotw[tws->tw_wday];
- break;
- case FT_LS_WEEKDAY:
- if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
- set_dotw (tws);
- str = tw_ldotw[tws->tw_wday];
- break;
- case FT_LV_YDAY:
- value = fmt->f_comp->c_tws->tw_yday;
- break;
- case FT_LV_ZONE:
- value = fmt->f_comp->c_tws->tw_zone;
- break;
- case FT_LV_CLOCK:
- if ((value = fmt->f_comp->c_tws->tw_clock) == 0)
- value = dmktime(fmt->f_comp->c_tws);
- break;
- case FT_LV_RCLOCK:
- if ((value = fmt->f_comp->c_tws->tw_clock) == 0)
- value = dmktime(fmt->f_comp->c_tws);
- value = time((time_t *) 0) - value;
- break;
- case FT_LV_DAYF:
- if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
- set_dotw (tws);
- switch (fmt->f_comp->c_tws->tw_flags & TW_SDAY) {
- case TW_SEXP:
- value = 1; break;
- case TW_SIMP:
- value = 0; break;
- default:
- value = -1; break;
- }
- case FT_LV_ZONEF:
- if ((fmt->f_comp->c_tws->tw_flags & TW_SZONE) == TW_SZEXP)
- value = 1;
- else
- value = -1;
- break;
- case FT_LV_DST:
- value = fmt->f_comp->c_tws->tw_flags & TW_DST;
- break;
- case FT_LS_822DATE:
- str = dasctime (fmt->f_comp->c_tws , TW_ZONE);
- break;
- case FT_LS_PRETTY:
- str = dasctime (fmt->f_comp->c_tws, TW_NULL);
- break;
-
- case FT_LS_PERS:
- str = fmt->f_comp->c_mn->m_pers;
- break;
- case FT_LS_MBOX:
- str = fmt->f_comp->c_mn->m_mbox;
- break;
- case FT_LS_HOST:
- str = fmt->f_comp->c_mn->m_host;
- break;
- case FT_LS_PATH:
- str = fmt->f_comp->c_mn->m_path;
- break;
- case FT_LS_GNAME:
- str = fmt->f_comp->c_mn->m_gname;
- break;
- case FT_LS_NOTE:
- str = fmt->f_comp->c_mn->m_note;
- break;
- case FT_LS_822ADDR:
- str = adrformat( fmt->f_comp->c_mn );
- break;
- case FT_LV_HOSTTYPE:
- value = fmt->f_comp->c_mn->m_type;
- break;
- case FT_LV_INGRPF:
- value = fmt->f_comp->c_mn->m_ingrp;
- break;
- case FT_LV_NOHOSTF:
- value = fmt->f_comp->c_mn->m_nohost;
- break;
- case FT_LS_ADDR:
- case FT_LS_FRIENDLY:
- if ((mn = fmt->f_comp->c_mn) == &fmt_mnull) {
- str = fmt->f_comp->c_text;
- break;
- }
- if (fmt->f_type == FT_LS_ADDR)
- goto unfriendly;
- if ((str = mn->m_pers) == NULL) {
- if ((str = mn->m_note)) {
- strncpy (buffer, str, sizeof(buffer));
- buffer[sizeof(buffer)-1] = '\0';
- str = buffer;
- if (*str == '(')
- str++;
- sp = str + strlen(str) - 1;
- if (*sp == ')') {
- *sp-- = '\0';
- while (sp >= str)
- if (*sp == ' ')
- *sp-- = '\0';
- else
- break;
- }
- } else if (!(str = get_x400_friendly (mn->m_mbox,
- buffer, sizeof(buffer)))) {
- unfriendly: ;
- switch (mn->m_type) {
- case LOCALHOST:
- str = mn->m_mbox;
- break;
- case UUCPHOST:
- snprintf (buffer, sizeof(buffer), "%s!%s",
- mn->m_host, mn->m_mbox);
- str = buffer;
- break;
- default:
- if (mn->m_mbox) {
- snprintf (buffer, sizeof(buffer), "%s@%s",
- mn->m_mbox, mn->m_host);
- str= buffer;
+ ljust++;
+ }
+
+ if (!ljust && i > 0 && (int)strlen(dst) > i) {
+ dst[i] = '\0';
+ }
+ xp = dst;
+ xp += strlen(dst) - 1;
+ while (xp > dst && isspace(*xp)) {
+ *xp-- = '\0';
+ }
+ if (ljust && i > 0 && (int)strlen(dst) > i) {
+ dst += strlen(dst) - i;
+ }
+ strncpy(str, dst, strlen(str) + 1);
+ return str;
+}
+
+struct format *
+fmt_scan(struct format *format, char *scanl, int width, int *dat)
+{
+ char *cp, *ep;
+ unsigned char *sp;
+ char *savestr = NULL;
+ unsigned char *str = NULL;
+ char buffer[BUFSIZ], buffer2[BUFSIZ];
+ int i, c, ljust, n;
+ int value = 0;
+ time_t t;
+ struct format *fmt;
+ struct comp *comp;
+ struct tws *tws;
+ struct mailname *mn;
+
+ cp = scanl;
+ ep = scanl + width - 1;
+
+ for (fmt = format; fmt->f_type != FT_DONE; fmt++)
+ switch (fmt->f_type) {
+ case FT_PARSEADDR:
+ case FT_PARSEDATE:
+ fmt->f_comp->c_flags &= ~CF_PARSED;
+ break;
+ }
+
+ fmt = format;
+
+ while (cp < ep) {
+ switch (fmt->f_type) {
+
+ case FT_COMP:
+ cpstripped(&cp, ep, fmt->f_comp->c_text);
+ break;
+ case FT_COMPF:
+ cptrimmed(&cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill, ep - cp);
+ 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:
+ cpstripped(&cp, ep, str);
+ break;
+ case FT_STRF:
+ cptrimmed(&cp, str, fmt->f_width, fmt->f_fill, ep - cp);
+ break;
+ case FT_STRFW:
+ adios(EX_SOFTWARE, NULL, "internal error (FT_STRFW)");
+
+ case FT_NUM:
+ n = snprintf(cp, ep - cp + 1, "%d", value);
+ if (n >= 0) {
+ if (n >= ep - cp) {
+ cp = ep;
+ } else
+ cp += n;
+ }
+ break;
+ case FT_NUMF:
+ cpnumber(&cp, value, fmt->f_width, fmt->f_fill, ep - cp);
+ 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 == NULL || *str == 0))) {
+ fmt += fmt->f_skip;
+ continue;
+ }
+ break;
+
+ case FT_IF_V_EQ:
+ if (value != fmt->f_value) {
+ fmt += fmt->f_skip;
+ continue;