- mutt_save_path (s, l, a);
- for (p = s; *p; p++)
- if (*p == '/' || ISSPACE (*p) || !IsPrint ((unsigned char) *p))
- *p = '_';
-}
-
-/* counts how many characters in s can be skipped while none of the
- * characters of c appears */
-int mutt_skipchars (const char *s, const char *c)
-{
- 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 (str_len (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 = str_len (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 = str_len (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 = str_len (path);
-
- if (path[len - 1] == '|') {
- /* read from a pipe */
-
- char *s = str_dup (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);