- int ret = 0;
- const char *p = s;
-
- while (s && *s) {
- register const char *t = c;
-
- while (t && *t) {
- if (*t == *s)
- return (ret);
- t++;
- }
- ret++;
- s++;
- }
- return (mutt_strlen (p));
-}
-
-void mutt_FormatString (char *dest, /* output buffer */
- size_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[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
- char ifstring[SHORT_STRING], elsestring[SHORT_STRING];
- size_t wlen, count, len, col, wid;
-
- 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;
- }
-
- if (*src == '?') {
- flags |= M_FORMAT_OPTIONAL;
- src++;
- }
- else {
- flags &= ~M_FORMAT_OPTIONAL;
-
- /* eat the format string */
- cp = prefix;
- count = 0;
- while (count < sizeof (prefix) &&
- (isdigit ((unsigned char) *src) || *src == '.' || *src == '-'))
- {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
- }
-
- if (!*src)
- break; /* bad format */
-
- ch = *src++; /* save the character to switch on */
-
- if (flags & M_FORMAT_OPTIONAL) {
- if (*src != '?')
- break; /* bad format */
- src++;
-
- /* eat the `if' part of the string */
- cp = ifstring;
- count = 0;
- while (count < sizeof (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 < sizeof (elsestring) && *src && *src != '?') {
- *cp++ = *src++;
- count++;
- }
- *cp = 0;
-
- if (!*src)
- break; /* bad format */
-
- src++; /* move past the trailing `?' */
- }
-
- /* 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 - SidebarWidth) <
- destlen ? (COLS - SidebarWidth) : destlen);
- if (count > col) {
- count -= col; /* how many columns left on this line */
- mutt_FormatString (buf, sizeof (buf), src, callback, data, flags);
- wid = mutt_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 tolower = 0;
- short nodots = 0;
-
- while (ch == '_' || ch == ':') {
- if (ch == '_')
- tolower = 1;
- else if (ch == ':')
- nodots = 1;
-
- ch = *src++;
- }
-
- /* use callback function to handle this case */
- src =
- callback (buf, sizeof (buf), ch, src, prefix, ifstring, elsestring,
- data, flags);
-
- if (tolower)
- str_tolower (buf);
- if (nodots) {
- char *p = buf;
-
- for (; *p; p++)
- if (*p == '.')
- *p = '_';
- }
-
- if ((len = mutt_strlen (buf)) + wlen > destlen)
- len = (destlen - wlen > 0) ? (destlen - wlen) : 0;
-
- memcpy (wptr, buf, len);
- wptr += len;
- wlen += len;
- col += mutt_strwidth (buf);
- }