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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
/*
* ustring.c: Unicode string routines
*/
#include <wchar.h>
#include <time.h>
#include "buttress.h"
wchar_t *ustrdup(wchar_t *s) {
wchar_t *r;
if (s) {
r = smalloc((1+ustrlen(s)) * sizeof(wchar_t));
ustrcpy(r, s);
} else {
r = smalloc(1);
*r = 0;
}
return r;
}
char *ustrtoa(wchar_t *s, char *outbuf, int size) {
char *p;
if (!s) {
*outbuf = '\0';
return outbuf;
}
for (p = outbuf; *s && p < outbuf+size; p++,s++)
*p = *s;
if (p < outbuf+size)
*p = '\0';
else
outbuf[size-1] = '\0';
return outbuf;
}
int ustrlen(wchar_t *s) {
int len = 0;
while (*s++) len++;
return len;
}
wchar_t *ustrcpy(wchar_t *dest, wchar_t *source) {
wchar_t *ret = dest;
do {
*dest++ = *source;
} while (*source++);
return ret;
}
int ustrcmp(wchar_t *lhs, wchar_t *rhs) {
while (*lhs && *rhs && *lhs==*rhs)
lhs++, rhs++;
if (*lhs < *rhs)
return -1;
else if (*lhs > *rhs)
return 1;
return 0;
}
wchar_t *ustrlow(wchar_t *s) {
wchar_t *p = s;
while (*p) {
/* FIXME: this doesn't even come close */
if (*p >= 'A' && *p <= 'Z')
*p += 'a'-'A';
p++;
}
return s;
}
#define USTRFTIME_DELTA 128
wchar_t *ustrftime(wchar_t *wfmt, struct tm *timespec) {
void *blk = NULL;
wchar_t *wblk, *wp;
char *fmt, *text, *p;
size_t size = 0;
size_t len;
/*
* strftime has the entertaining property that it returns 0
* _either_ on out-of-space _or_ on successful generation of
* the empty string. Hence we must ensure our format can never
* generate the empty string. Somebody throw a custard pie at
* whoever was responsible for that. Please?
*/
if (wfmt) {
len = ustrlen(wfmt);
fmt = smalloc(2+len);
ustrtoa(wfmt, fmt+1, len+1);
fmt[0] = ' ';
} else
fmt = " %c";
while (1) {
size += USTRFTIME_DELTA;
blk = srealloc(blk, size);
len = strftime((char *)blk, size-1, fmt, timespec);
if (len > 0)
break;
}
/* Note: +1 for the terminating 0, -1 for the initial space in fmt */
wblk = srealloc(blk, len * sizeof(wchar_t));
text = smalloc(len);
strftime(text, len, fmt+1, timespec);
/*
* We operate in the C locale, so this all ought to be kosher
* ASCII. If we ever move outside ASCII machines, we may need
* to make this more portable...
*/
for (wp = wblk, p = text; *p; p++, wp++)
*wp = *p;
*wp = 0;
if (wfmt)
sfree(fmt);
sfree(text);
return wblk;
}
|