-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathruneconv.c
84 lines (71 loc) · 1.63 KB
/
runeconv.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Contributed by Erik Quanstrom <[email protected]>
#include "print.h"
#include "rune.h"
static void
pad(Format *format, size_t len, int c)
{
while (len-- != 0 && fmtputc(format, c));
}
static size_t
Runelen(const Rune *r)
{
const Rune *s = r;
while (*r)
r++;
return r - s;
}
// Delete this when you get a decent compiler.
static Rune runelit[] = { 923, 0 };
static int
Sconv(Format *format, int c)
{
size_t maxrunes, minwidth, extra;
Rune *R = va_arg(format->args, Rune *);
char s[UTFmax];
int i;
// if (!R) R = L"Λ"; // some compilers choke on this
if (!R)
R = runelit;
if (format->flags & FMT_altform) {
// maxrunes may overrun R, but this way we don't have
// to assume that R is null terminated when f2 is set.
maxrunes = (format->flags & FMT_f2set) ? format->f2 : Runelen(R);
} else {
// do f2 like printf
maxrunes = Runelen(R);
if ((format->flags & FMT_f2set) && (format->f2 < maxrunes))
maxrunes = format->f2;
}
minwidth = (format->flags & FMT_f1set) ? format->f1 : maxrunes;
extra = (minwidth > maxrunes) ? minwidth - maxrunes : 0;
if (format->flags & FMT_leftside) {
while (maxrunes--) {
i = runetochar(s, R++);
fmtappend(format, s, i);
}
pad(format, extra, ' ');
} else {
pad(format, extra, ' ');
while (maxrunes--) {
i = runetochar(s, R++);
fmtappend(format, s, i);
}
}
return FMT_verb;
}
static int
Cconv(Format *format, int c)
{
Rune r = (unsigned short)va_arg(format->args, int);
char s[UTFmax];
int i;
i = runetochar(s, &r);
fmtappend(format, s, i);
return FMT_verb;
}
void
fmt_install_runeconv()
{
fmtinstall('C', Cconv);
fmtinstall('S', Sconv);
}