}
}
-void mutt_FormatString (char *dest, /* output buffer */
- ssize_t destlen, /* output buffer len */
- const char *src, /* template string */
- format_t * callback, /* callback for processing */
- unsigned long data, /* callback data */
- format_flag flags)
-{ /* callback flags */
- char prefix[STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
- char ifstring[STRING], elsestring[STRING];
- ssize_t wlen, wid, count, col, len;
-
- prefix[0] = '\0';
- destlen--; /* save room for the terminal \0 */
- wlen = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3 : 0;
- col = wlen;
-
- while (*src && wlen < destlen) {
- if (*src == '%') {
- if (*++src == '%') {
- *wptr++ = '%';
- wlen++;
- col++;
- src++;
- continue;
- }
+ssize_t
+mutt_FormatString(char *dst, ssize_t dlen, const char *fmt,
+ format_t *callback, unsigned long data, format_flag flags)
+{
+ ssize_t pos = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3 : 0;
- if (*src == '?') {
- flags |= M_FORMAT_OPTIONAL;
- src++;
- }
- else {
- flags &= ~M_FORMAT_OPTIONAL;
-
- /* eat the format string */
- cp = prefix;
- count = 0;
- while (count < ssizeof (prefix) &&
- (isdigit ((unsigned char) *src) || *src == '.' || *src == '-'))
- {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
- }
+ while (*fmt) {
+ char ifstring[STRING] = "", elsestring[STRING] = "", prefix[STRING] = "";
+ int ch;
- if (!*src)
- break; /* bad format */
+ if (*fmt == '%') {
+ if (*++fmt == '%') {
+ pos += m_strputc(dst + pos, dlen - pos, '%');
+ fmt++;
+ continue;
+ }
- ch = *src++; /* save the character to switch on */
+ if (*fmt == '?') {
+ flags |= M_FORMAT_OPTIONAL;
+ fmt++;
+ } else {
+ ssize_t pfxlen;
+ flags &= ~M_FORMAT_OPTIONAL;
- if (flags & M_FORMAT_OPTIONAL) {
- if (*src != '?')
- break; /* bad format */
- src++;
+ /* eat the format string */
+ pfxlen = strspn(fmt, "0123456789.-");
+ m_strncpy(prefix, sizeof(prefix), fmt, pfxlen);
+ fmt += pfxlen;
+ }
- /* eat the `if' part of the string */
- cp = ifstring;
- count = 0;
- while (count < ssizeof (ifstring) && *src && *src != '?'
- && *src != '&') {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
-
- /* eat the `else' part of the string (optional) */
- if (*src == '&')
- src++; /* skip the & */
- cp = elsestring;
- count = 0;
- while (count < ssizeof (elsestring) && *src && *src != '?') {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
+ /* save the character to switch on */
+ if (!(ch = *fmt++))
+ break;
- if (!*src)
- break; /* bad format */
+ if (flags & M_FORMAT_OPTIONAL) {
+ ssize_t iflen;
+ const char *p;
- src++; /* move past the trailing `?' */
- }
+ if (*fmt++ != '?')
+ break; /* bad format */
- /* handle generic cases first */
- if (ch == '>') {
- /* right justify to EOL */
- ch = *src++; /* pad char */
- /* calculate space left on line. if we've already written more data
- than will fit on the line, ignore the rest of the line */
- if (DrawFullLine || option (OPTSTATUSONTOP))
- count = (COLS < destlen ? COLS : destlen);
- else
- count = ((COLS - SW) < destlen ? (COLS - SW) : destlen);
- if (count > col) {
- count -= col; /* how many columns left on this line */
- mutt_FormatString (buf, sizeof (buf), src, callback, data, flags);
- wid = m_strlen(buf);
- if (count > wid) {
- count -= wid; /* how many chars to pad */
- memset (wptr, ch, count);
- wptr += count;
- col += count;
- }
- if (wid + wlen > destlen)
- len = destlen - wlen;
- else
- len = wid;
- memcpy (wptr, buf, len);
- wptr += len;
- wlen += len;
- col += mutt_strwidth (buf);
- }
- break; /* skip rest of input */
- }
- else if (ch == '|') {
- /* pad to EOL */
- ch = *src++;
- if (destlen > COLS)
- destlen = COLS;
- if (destlen > wlen) {
- count = destlen - wlen;
- memset (wptr, ch, count);
- wptr += count;
- }
- break; /* skip rest of input */
- }
- else {
- short lower = 0;
- short nodots = 0;
+ /* eat the `if' part of the string */
+ iflen = strcspn(fmt, "?&");
+ m_strncpy(ifstring, ssizeof(ifstring), fmt, iflen);
+ fmt += iflen;
- while (ch == '_' || ch == ':') {
- if (ch == '_')
- lower = 1;
- else if (ch == ':')
- nodots = 1;
+ /* eat the `else' part of the string (optional) */
+ if (*fmt == '&')
+ fmt++; /* skip the & */
- ch = *src++;
- }
+ p = m_strchrnul(fmt, '?');
+ m_strncpy(elsestring, ssizeof(elsestring), fmt, p - fmt);
+ fmt = p;
+
+ if (!*fmt++) /* move past the trailing `?' */
+ break; /* bad format */
+ }
+
+ switch (ch) {
+ ssize_t col;
+ char lower, nodots, buf[LONG_STRING];
+
+ case '>': /* right justify to EOL */
+ col = mutt_strwidth(dst);
+
+ ch = *fmt++; /* pad char */
+
+ if (COLS - SW > col) {
+ ssize_t wid;
+
+ mutt_FormatString(buf, sizeof(buf), fmt, callback, data, flags);
+ wid = mutt_strwidth(buf);
+
+ pos += m_strpad(dst + pos, dlen - pos, ch, COLS - SW - col - wid);
+ pos += m_strcpy(dst + pos, dlen - pos, buf);
+ }
+ return pos; /* skip rest of input */
- /* use callback function to handle this case */
- src =
- callback (buf, sizeof (buf), ch, src, prefix, ifstring, elsestring,
- data, flags);
+ case '|':
+ col = mutt_strwidth(dst);
- if (lower)
- m_strtolower(buf);
- if (nodots) {
- char *p = buf;
+ ch = *fmt++;
+ /* pad to EOL */
+ pos += m_strpad(dst + pos, dlen - pos, ch, COLS - SW - col);
+ return pos; /* skip rest of input */
- for (; *p; p++)
- if (*p == '.')
- *p = '_';
+ default:
+ lower = nodots = 0;
+
+ while (ch == '_' || ch == ':') {
+ lower |= ch == '_';
+ nodots |= ch == ':';
+ ch = *fmt++;
+ }
+
+ /* use callback function to handle this case */
+ fmt = callback(buf, sizeof (buf), ch, fmt, prefix,
+ ifstring, elsestring, data, flags);
+
+ if (lower)
+ m_strtolower(buf);
+
+ if (nodots) {
+ char *p;
+
+ for (p = buf; *p; p++) {
+ if (*p == '.')
+ *p = '_';
+ }
+ }
+
+ pos += m_strcpy(dst + pos, dlen - pos, buf);
+ continue;
+ }
}
- if ((len = m_strlen(buf)) + wlen > destlen)
- len = (destlen - wlen > 0) ? (destlen - wlen) : 0;
+ if (*fmt == '\\') {
+ if (!*++fmt)
+ break;
+ switch (*fmt) {
+ case 'n': pos += m_strputc(dst + pos, dlen - pos, '\n'); break;
+ case 't': pos += m_strputc(dst + pos, dlen - pos, '\t'); break;
+ case 'r': pos += m_strputc(dst + pos, dlen - pos, '\r'); break;
+ case 'f': pos += m_strputc(dst + pos, dlen - pos, '\f'); break;
+ case 'v': pos += m_strputc(dst + pos, dlen - pos, '\v'); break;
+ default: pos += m_strputc(dst + pos, dlen - pos, *fmt); break;
+ }
+ fmt++;
+ } else {
+ ssize_t len = strcspn(fmt, "%\\");
- memcpy (wptr, buf, len);
- wptr += len;
- wlen += len;
- col += mutt_strwidth (buf);
- }
- }
- else if (*src == '\\') {
- if (!*++src)
- break;
- switch (*src) {
- case 'n':
- *wptr = '\n';
- break;
- case 't':
- *wptr = '\t';
- break;
- case 'r':
- *wptr = '\r';
- break;
- case 'f':
- *wptr = '\f';
- break;
- case 'v':
- *wptr = '\v';
- break;
- default:
- *wptr = *src;
- break;
- }
- src++;
- wptr++;
- wlen++;
- col++;
+ pos += m_strncpy(dst + pos, dlen - pos, fmt, len);
+ fmt += len;
+ }
}
- else {
- unsigned int bar = strcspn(src, "%\\");
- char *bar2 = p_dupstr(src, bar);
- while (bar--) {
- *wptr++ = *src++;
- wlen++;
- }
- col += mutt_strwidth (bar2);
- p_delete(&bar2);
- }
- }
- *wptr = 0;
+ return pos;
}
/* returns 0 if OK to proceed, -1 to abort, 1 to retry */