Nico Golde:
[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
16 #include "mutt.h"
17 #include "state.h"
18
19 static void state_prefix_put (const char *d, size_t dlen, STATE * s)
20 {
21   if (s->prefix)
22     while (dlen--)
23       state_prefix_putc (*d++, s);
24   else
25     fwrite (d, dlen, 1, s->fpout);
26 }
27
28 void mutt_convert_to_state (iconv_t cd, char *bufi, size_t * l, STATE * s)
29 {
30   char bufo[BUFO_SIZE];
31   ICONV_CONST char *ib;
32   char *ob;
33   size_t ibl, obl;
34
35   if (!bufi) {
36     if (cd != (iconv_t) (-1)) {
37       ob = bufo, obl = sizeof (bufo);
38       iconv (cd, 0, 0, &ob, &obl);
39       if (ob != bufo)
40         state_prefix_put (bufo, ob - bufo, s);
41     }
42     if (Quotebuf[0] != '\0')
43       state_prefix_putc ('\n', s);
44     return;
45   }
46
47   if (cd == (iconv_t) (-1)) {
48     state_prefix_put (bufi, *l, s);
49     *l = 0;
50     return;
51   }
52
53   ib = bufi, ibl = *l;
54   for (;;) {
55     ob = bufo, obl = sizeof (bufo);
56     mutt_iconv (cd, &ib, &ibl, &ob, &obl, 0, "?");
57     if (ob == bufo)
58       break;
59     state_prefix_put (bufo, ob - bufo, s);
60   }
61   memmove (bufi, ib, ibl);
62   *l = ibl;
63 }
64
65 void state_prefix_putc (char c, STATE * s)
66 {
67   if (s->flags & M_PENDINGPREFIX) {
68     int i;
69
70     i = str_len (Quotebuf);
71     Quotebuf[i++] = c;
72     Quotebuf[i] = '\0';
73     if (i == sizeof (Quotebuf) - 1 || c == '\n') {
74       char buf[2 * SHORT_STRING];
75       int j = 0, offset = 0;
76       regmatch_t pmatch[1];
77
78       state_reset_prefix (s);
79       while (regexec
80              ((regex_t *) QuoteRegexp.rx, &Quotebuf[offset], 1, pmatch,
81               0) == 0)
82         offset += pmatch->rm_eo;
83
84       if (!option (OPTQUOTEEMPTY) && Quotebuf[offset] == '\n') {
85         buf[0] = '\n';
86         buf[1] = '\0';
87       }
88       else if (option (OPTQUOTEQUOTED) && offset) {
89         for (i = 0; i < offset; i++)
90           if (Quotebuf[i] != ' ')
91             j = i;
92         strncpy (buf, Quotebuf, j + 1);
93         strcpy (buf + j + 1, Quotebuf + j);
94       }
95       else
96         snprintf (buf, sizeof (buf), "%s%s", NONULL (s->prefix), Quotebuf);
97
98       state_puts (buf, s);
99     }
100   }
101   else
102     state_putc (c, s);
103
104   if (c == '\n') {
105     state_set_prefix (s);
106     Quotebuf[0] = '\0';
107   }
108 }
109
110 int state_printf (STATE * s, const char *fmt, ...)
111 {
112   int rv;
113   va_list ap;
114
115   va_start (ap, fmt);
116   rv = vfprintf (s->fpout, fmt, ap);
117   va_end (ap);
118
119   return rv;
120 }
121
122 void state_mark_attach (STATE * s)
123 {
124   if ((s->flags & M_DISPLAY) && !str_cmp (Pager, "builtin"))
125     state_puts (AttachmentMarker, s);
126 }
127
128 void state_attach_puts (const char *t, STATE * s)
129 {
130   if (*t != '\n')
131     state_mark_attach (s);
132   while (*t) {
133     state_putc (*t, s);
134     if (*t++ == '\n' && *t)
135       if (*t != '\n')
136         state_mark_attach (s);
137   }
138 }