NeoMutt
2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Toggle main menu visibility
Loading...
Searching...
No Matches
format.c
Go to the documentation of this file.
1
22
28
29
#include "config.h"
30
#include <errno.h>
31
#include <limits.h>
32
#include <stdbool.h>
33
#include <string.h>
34
#include <wchar.h>
35
#include "
mutt/lib.h
"
36
#include "
gui/lib.h
"
37
#include "
format.h
"
38
#ifdef HAVE_ISWBLANK
39
#include <wctype.h>
40
#endif
41
49
void
buf_justify
(
struct
Buffer
*buf,
enum
FormatJustify
justify,
size_t
max_cols,
char
pad_char)
50
{
51
if
(!buf || (pad_char ==
'\0'
))
52
return
;
53
54
const
size_t
len =
buf_len
(buf);
55
if
(len >= max_cols)
56
return
;
57
58
const
size_t
pad = max_cols - len;
59
buf_alloc
(buf, max_cols + 1);
60
61
switch
(justify)
62
{
63
case
JUSTIFY_LEFT
:
64
{
65
memset(buf->
dptr
, pad_char, pad);
66
break
;
67
}
68
69
case
JUSTIFY_CENTER
:
70
{
71
if
(pad > 1)
72
{
73
memmove(buf->
data
+ (pad / 2), buf->
data
, len + 1);
74
memset(buf->
data
, pad_char, pad / 2);
75
}
76
memset(buf->
data
+ len + (pad / 2), pad_char, (pad + 1) / 2);
77
break
;
78
}
79
80
case
JUSTIFY_RIGHT
:
81
{
82
memmove(buf->
data
+ pad, buf->
data
, len + 1);
83
memset(buf->
data
, pad_char, pad);
84
break
;
85
}
86
}
87
88
buf->
dptr
+= pad;
89
buf->
dptr
[0] =
'\0'
;
90
}
91
107
int
format_string
(
struct
Buffer
*buf,
int
min_cols,
int
max_cols,
enum
FormatJustify
justify,
108
char
pad_char,
const
char
*str,
size_t
n,
bool
arboreal)
109
{
110
wchar_t
wc = 0;
111
int
w = 0;
112
size_t
k = 0;
113
char
scratch[MB_LEN_MAX] = { 0 };
114
mbstate_t mbstate1 = { 0 };
115
mbstate_t mbstate2 = { 0 };
116
bool
escaped =
false
;
117
int
used_cols = 0;
118
119
for
(; (n > 0) && (k = mbrtowc(&wc, str, n, &mbstate1)); str += k, n -= k)
120
{
121
if
((k ==
ICONV_ILLEGAL_SEQ
) || (k ==
ICONV_BUF_TOO_SMALL
))
122
{
123
if
((k ==
ICONV_ILLEGAL_SEQ
) && (errno ==
EILSEQ
))
124
memset(&mbstate1, 0,
sizeof
(mbstate1));
125
126
k = (k ==
ICONV_ILLEGAL_SEQ
) ? 1 : n;
127
wc =
ReplacementChar
;
128
}
129
130
// How many screen cells will the character require?
131
if
(escaped)
132
{
133
escaped =
false
;
134
w = 0;
135
}
136
else
if
(arboreal && (wc ==
MUTT_SPECIAL_INDEX
))
137
{
138
escaped =
true
;
139
w = 0;
140
}
141
else
if
(arboreal && (wc <
MUTT_TREE_MAX
))
142
{
143
w = 1;
/* hack */
144
}
145
else
if
(iswspace(wc))
146
{
147
w =
MAX
(1, wcwidth(wc));
148
}
149
else
150
{
151
#ifdef HAVE_ISWBLANK
152
if
(iswblank(wc))
153
wc =
' '
;
// LCOV_EXCL_LINE
154
else
155
#endif
156
if
(!
IsWPrint
(wc))
157
wc =
'?'
;
158
w = wcwidth(wc);
159
}
160
161
// It'll require _some_ space
162
if
(w >= 0)
163
{
164
if
(w > max_cols)
165
continue
;
166
size_t
k2 = wcrtomb(scratch, wc, &mbstate2);
167
if
(k2 ==
ICONV_ILLEGAL_SEQ
)
168
continue
;
// LCOV_EXCL_LINE
169
170
used_cols += w;
171
172
min_cols -= w;
173
max_cols -= w;
174
buf_addstr_n
(buf, scratch, k2);
175
}
176
}
177
178
// How much space is left?
179
w = min_cols;
180
if
(w > 0)
181
{
182
used_cols += w;
183
}
184
185
if
(w > 0)
186
buf_justify
(buf, justify,
buf_len
(buf) + w, pad_char);
187
188
return
used_cols;
189
}
buf_addstr_n
size_t buf_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition
buffer.c:109
buf_len
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition
buffer.c:497
buf_alloc
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition
buffer.c:342
buf_justify
void buf_justify(struct Buffer *buf, enum FormatJustify justify, size_t max_cols, char pad_char)
Justify a string.
Definition
format.c:49
format_string
int format_string(struct Buffer *buf, int min_cols, int max_cols, enum FormatJustify justify, char pad_char, const char *str, size_t n, bool arboreal)
Format a string, like snprintf().
Definition
format.c:107
format.h
Simple string formatting.
FormatJustify
FormatJustify
Alignment for format_string().
Definition
format.h:33
JUSTIFY_RIGHT
@ JUSTIFY_RIGHT
Right justify the text.
Definition
format.h:36
JUSTIFY_LEFT
@ JUSTIFY_LEFT
Left justify the text.
Definition
format.h:34
JUSTIFY_CENTER
@ JUSTIFY_CENTER
Centre the text.
Definition
format.h:35
lib.h
Convenience wrapper for the gui headers.
MUTT_TREE_MAX
@ MUTT_TREE_MAX
Definition
thread.h:70
MUTT_SPECIAL_INDEX
@ MUTT_SPECIAL_INDEX
Colour indicator.
Definition
thread.h:72
IsWPrint
#define IsWPrint(wc)
Definition
mbyte.h:40
MAX
#define MAX(a, b)
Return the maximum of two values.
Definition
memory.h:38
ReplacementChar
wchar_t ReplacementChar
When a Unicode character can't be displayed, use this instead.
Definition
charset.c:62
EILSEQ
#define EILSEQ
Definition
charset.c:56
ICONV_BUF_TOO_SMALL
#define ICONV_BUF_TOO_SMALL
Error value for iconv() - Buffer too small.
Definition
charset.h:116
ICONV_ILLEGAL_SEQ
#define ICONV_ILLEGAL_SEQ
Error value for iconv() - Illegal sequence.
Definition
charset.h:114
lib.h
Convenience wrapper for the library headers.
Buffer
String manipulation buffer.
Definition
buffer.h:36
Buffer::dptr
char * dptr
Current read/write position.
Definition
buffer.h:38
Buffer::data
char * data
Pointer to data.
Definition
buffer.h:37