- 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)
- mutt_strlower (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);
- }
- }
- 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++;
- }
- else
- {
- unsigned int bar = mutt_skipchars (src, "%\\");
- char* bar2 = safe_malloc (bar+1);
- strfcpy (bar2, src, bar+1);
- while (bar--) {
- *wptr++ = *src++;
- wlen++;
- }
- col += mutt_strwidth (bar2);
- FREE(&bar2);
- }
- }
- *wptr = 0;
-
-#if 0
- if (flags & M_FORMAT_MAKEPRINT)
- {
- /* Make sure that the string is printable by changing all non-printable
- chars to dots, or spaces for non-printable whitespace */
- for (cp = dest ; *cp ; cp++)
- if (!IsPrint (*cp) &&
- !((flags & M_FORMAT_TREE) && (*cp <= M_TREE_MAX)))
- *cp = isspace ((unsigned char) *cp) ? ' ' : '.';
- }
-#endif
-}
-
-/* This function allows the user to specify a command to read stdout from in
- place of a normal file. If the last character in the string is a pipe (|),
- then we assume it is a commmand to run instead of a normal file. */
-FILE *mutt_open_read (const char *path, pid_t *thepid)
-{
- FILE *f;
- struct stat s;
-
- int len = mutt_strlen (path);
-
- if (path[len - 1] == '|')
- {
- /* read from a pipe */
-
- char *s = safe_strdup (path);
-
- s[len - 1] = 0;
- mutt_endwin (NULL);
- *thepid = mutt_create_filter (s, NULL, &f, NULL);
- FREE (&s);
- }
- else
- {
- if (stat (path, &s) < 0)
- return (NULL);
- if (S_ISDIR (s.st_mode))
- {
- errno = EINVAL;
- return (NULL);
- }
- f = fopen (path, "r");
- *thepid = -1;
- }
- return (f);