12f3e992f5325130029b7d0e05a66de2d3b57632
[apps/madmutt.git] / state.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9 #if HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <stdarg.h>
16
17 #include "mutt.h"
18 #include "state.h"
19 #include "rfc3676.h"
20
21 static void state_prefix_put (const char *d, ssize_t dlen, STATE * s)
22 {
23   if (s->prefix)
24     while (dlen--)
25       state_prefix_putc (*d++, s);
26   else
27     fwrite (d, dlen, 1, s->fpout);
28 }
29
30 void mutt_convert_to_state (iconv_t cd, char *bufi, ssize_t * l, STATE * s)
31 {
32   char bufo[BUFO_SIZE];
33   const char *ib;
34   char *ob;
35   ssize_t ibl, obl;
36
37   if (!bufi) {
38     if (cd != (iconv_t) (-1)) {
39       ob = bufo, obl = sizeof (bufo);
40       my_iconv(cd, 0, 0, &ob, &obl);
41       if (ob != bufo)
42         state_prefix_put (bufo, ob - bufo, s);
43     }
44     if (Quotebuf[0] != '\0')
45       state_prefix_putc ('\n', s);
46     return;
47   }
48
49   if (cd == (iconv_t) (-1)) {
50     state_prefix_put (bufi, *l, s);
51     *l = 0;
52     return;
53   }
54
55   ib = bufi, ibl = *l;
56   for (;;) {
57     ob = bufo, obl = sizeof (bufo);
58     mutt_iconv (cd, &ib, &ibl, &ob, &obl, 0, "?");
59     if (ob == bufo)
60       break;
61     state_prefix_put (bufo, ob - bufo, s);
62   }
63   memmove (bufi, ib, ibl);
64   *l = ibl;
65 }
66
67 void state_prefix_putc (char c, STATE * s)
68 {
69   if (s->flags & M_PENDINGPREFIX) {
70     int i;
71
72     i = m_strlen(Quotebuf);
73     Quotebuf[i++] = c;
74     Quotebuf[i] = '\0';
75     if (i == sizeof (Quotebuf) - 1 || c == '\n') {
76       char buf[2 * SHORT_STRING];
77       int j = 0, offset = 0;
78       regmatch_t pmatch[1];
79
80       state_reset_prefix (s);
81       while (regexec
82              ((regex_t *) QuoteRegexp.rx, &Quotebuf[offset], 1, pmatch,
83               0) == 0)
84         offset += pmatch->rm_eo;
85
86       if (!option (OPTQUOTEEMPTY) && Quotebuf[offset] == '\n') {
87         buf[0] = '\n';
88         buf[1] = '\0';
89       }
90       else if (!option (OPTTEXTFLOWED) && option (OPTQUOTEQUOTED) && offset) {
91         for (i = 0; i < offset; i++)
92           if (Quotebuf[i] != ' ')
93             j = i;
94         strncpy (buf, Quotebuf, j + 1);
95         strcpy (buf + j + 1, Quotebuf + j);
96       }
97       else
98         snprintf (buf, sizeof (buf), "%s%s", NONULL (s->prefix), Quotebuf);
99
100       state_puts (buf, s);
101     }
102   }
103   else
104     state_putc (c, s);
105
106   if (c == '\n') {
107     state_set_prefix (s);
108     Quotebuf[0] = '\0';
109   }
110 }
111
112 int state_printf (STATE * s, const char *fmt, ...)
113 {
114   int rv;
115   va_list ap;
116
117   va_start (ap, fmt);
118   rv = vfprintf (s->fpout, fmt, ap);
119   va_end (ap);
120
121   return rv;
122 }
123
124 void state_mark_attach (STATE * s)
125 {
126   if ((s->flags & M_DISPLAY) && !m_strcmp(Pager, "builtin"))
127     state_puts (AttachmentMarker, s);
128 }
129
130 void state_attach_puts (const char *t, STATE * s)
131 {
132   if (*t != '\n')
133     state_mark_attach (s);
134   while (*t) {
135     state_putc (*t, s);
136     if (*t++ == '\n' && *t)
137       if (*t != '\n')
138         state_mark_attach (s);
139   }
140 }