rinku 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +0 -18
- data/ext/rinku/autolink.c +13 -13
- data/ext/rinku/autolink.h +7 -4
- data/ext/rinku/buffer.c +123 -218
- data/ext/rinku/buffer.h +49 -112
- data/ext/rinku/houdini.h +28 -0
- data/ext/rinku/houdini_href_e.c +108 -0
- data/ext/rinku/houdini_html_e.c +84 -0
- data/ext/rinku/rinku.c +123 -78
- data/lib/rails_rinku.rb +2 -2
- data/rinku.gemspec +4 -1
- data/test/autolink_test.rb +36 -3
- metadata +8 -7
data/Rakefile
CHANGED
@@ -50,21 +50,3 @@ file package('.gem') => %w[pkg/ rinku.gemspec] + $spec.files do |f|
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# GEMSPEC HELPERS ==========================================================
|
53
|
-
|
54
|
-
desc 'Gather required Upskirt sources into extension directory'
|
55
|
-
task :gather => 'upskirt/src/markdown.h' do |t|
|
56
|
-
files =
|
57
|
-
FileList[
|
58
|
-
'upskirt/src/{buffer,autolink}.h',
|
59
|
-
'upskirt/src/{buffer,autolink}.c'
|
60
|
-
]
|
61
|
-
cp files, 'ext/rinku/',
|
62
|
-
:preserve => true,
|
63
|
-
:verbose => true
|
64
|
-
end
|
65
|
-
|
66
|
-
file 'upskirt/src/markdown.h' do |t|
|
67
|
-
abort "The Upskirt submodule is required."
|
68
|
-
end
|
69
|
-
|
70
|
-
|
data/ext/rinku/autolink.c
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
#include <ctype.h>
|
23
23
|
|
24
24
|
int
|
25
|
-
|
25
|
+
sd_autolink_issafe(const uint8_t *link, size_t link_len)
|
26
26
|
{
|
27
27
|
static const size_t valid_uris_count = 4;
|
28
28
|
static const char *valid_uris[] = {
|
@@ -35,7 +35,7 @@ is_safe_link(const char *link, size_t link_len)
|
|
35
35
|
size_t len = strlen(valid_uris[i]);
|
36
36
|
|
37
37
|
if (link_len > len &&
|
38
|
-
strncasecmp(link, valid_uris[i], len) == 0 &&
|
38
|
+
strncasecmp((char *)link, valid_uris[i], len) == 0 &&
|
39
39
|
isalnum(link[len]))
|
40
40
|
return 1;
|
41
41
|
}
|
@@ -44,9 +44,9 @@ is_safe_link(const char *link, size_t link_len)
|
|
44
44
|
}
|
45
45
|
|
46
46
|
static size_t
|
47
|
-
autolink_delim(
|
47
|
+
autolink_delim(uint8_t *data, size_t link_end, size_t offset, size_t size)
|
48
48
|
{
|
49
|
-
|
49
|
+
uint8_t cclose, copen = 0;
|
50
50
|
size_t i;
|
51
51
|
|
52
52
|
for (i = 0; i < link_end; ++i)
|
@@ -128,7 +128,7 @@ autolink_delim(char *data, size_t link_end, size_t offset, size_t size)
|
|
128
128
|
}
|
129
129
|
|
130
130
|
static size_t
|
131
|
-
check_domain(
|
131
|
+
check_domain(uint8_t *data, size_t size)
|
132
132
|
{
|
133
133
|
size_t i, np = 0;
|
134
134
|
|
@@ -147,14 +147,14 @@ check_domain(char *data, size_t size)
|
|
147
147
|
}
|
148
148
|
|
149
149
|
size_t
|
150
|
-
|
150
|
+
sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
|
151
151
|
{
|
152
152
|
size_t link_end;
|
153
153
|
|
154
154
|
if (offset > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
|
155
155
|
return 0;
|
156
156
|
|
157
|
-
if (size < 4 || memcmp(data, "www.",
|
157
|
+
if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
|
158
158
|
return 0;
|
159
159
|
|
160
160
|
link_end = check_domain(data, size);
|
@@ -177,13 +177,13 @@ ups_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset,
|
|
177
177
|
}
|
178
178
|
|
179
179
|
size_t
|
180
|
-
|
180
|
+
sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
|
181
181
|
{
|
182
182
|
size_t link_end, rewind;
|
183
183
|
int nb = 0, np = 0;
|
184
184
|
|
185
185
|
for (rewind = 0; rewind < offset; ++rewind) {
|
186
|
-
|
186
|
+
uint8_t c = data[-rewind - 1];
|
187
187
|
|
188
188
|
if (isalnum(c))
|
189
189
|
continue;
|
@@ -198,7 +198,7 @@ ups_autolink__email(size_t *rewind_p, struct buf *link, char *data, size_t offse
|
|
198
198
|
return 0;
|
199
199
|
|
200
200
|
for (link_end = 0; link_end < size; ++link_end) {
|
201
|
-
|
201
|
+
uint8_t c = data[link_end];
|
202
202
|
|
203
203
|
if (isalnum(c))
|
204
204
|
continue;
|
@@ -226,7 +226,7 @@ ups_autolink__email(size_t *rewind_p, struct buf *link, char *data, size_t offse
|
|
226
226
|
}
|
227
227
|
|
228
228
|
size_t
|
229
|
-
|
229
|
+
sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
|
230
230
|
{
|
231
231
|
size_t link_end, rewind = 0, domain_len;
|
232
232
|
|
@@ -236,9 +236,9 @@ ups_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset,
|
|
236
236
|
while (rewind < offset && isalpha(data[-rewind - 1]))
|
237
237
|
rewind++;
|
238
238
|
|
239
|
-
if (!
|
239
|
+
if (!sd_autolink_issafe(data - rewind, size + rewind))
|
240
240
|
return 0;
|
241
|
-
link_end =
|
241
|
+
link_end = strlen("://");
|
242
242
|
|
243
243
|
domain_len = check_domain(data + link_end, size - link_end);
|
244
244
|
if (domain_len == 0)
|
data/ext/rinku/autolink.h
CHANGED
@@ -15,18 +15,21 @@
|
|
15
15
|
*/
|
16
16
|
|
17
17
|
#ifndef UPSKIRT_AUTOLINK_H
|
18
|
-
#define
|
18
|
+
#define UPSKIRT_AUTOLINK_H
|
19
19
|
|
20
20
|
#include "buffer.h"
|
21
21
|
|
22
|
+
extern int
|
23
|
+
sd_autolink_issafe(const uint8_t *link, size_t link_len);
|
24
|
+
|
22
25
|
extern size_t
|
23
|
-
|
26
|
+
sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
|
24
27
|
|
25
28
|
extern size_t
|
26
|
-
|
29
|
+
sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
|
27
30
|
|
28
31
|
extern size_t
|
29
|
-
|
32
|
+
sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
|
30
33
|
|
31
34
|
#endif
|
32
35
|
|
data/ext/rinku/buffer.c
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
/* buffer.c - automatic buffer structure */
|
2
|
-
|
3
1
|
/*
|
4
2
|
* Copyright (c) 2008, Natacha Porté
|
3
|
+
* Copyright (c) 2011, Vicent Martí
|
5
4
|
*
|
6
5
|
* Permission to use, copy, modify, and distribute this software for any
|
7
6
|
* purpose with or without fee is hereby granted, provided that the above
|
@@ -16,13 +15,6 @@
|
|
16
15
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
17
16
|
*/
|
18
17
|
|
19
|
-
/*
|
20
|
-
* COMPILE TIME OPTIONS
|
21
|
-
*
|
22
|
-
* BUFFER_STATS • if defined, stats are kept about memory usage
|
23
|
-
*/
|
24
|
-
|
25
|
-
#define BUFFER_STDARG
|
26
18
|
#define BUFFER_MAX_ALLOC_SIZE (1024 * 1024 * 16) //16mb
|
27
19
|
|
28
20
|
#include "buffer.h"
|
@@ -31,78 +23,13 @@
|
|
31
23
|
#include <stdlib.h>
|
32
24
|
#include <string.h>
|
33
25
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
#ifdef BUFFER_STATS
|
40
|
-
long buffer_stat_nb = 0;
|
41
|
-
size_t buffer_stat_alloc_bytes = 0;
|
26
|
+
/* MSVC compat */
|
27
|
+
#if defined(_MSC_VER)
|
28
|
+
# define _buf_vsnprintf _vsnprintf
|
29
|
+
#else
|
30
|
+
# define _buf_vsnprintf vsnprintf
|
42
31
|
#endif
|
43
32
|
|
44
|
-
|
45
|
-
/***************************
|
46
|
-
* STATIC HELPER FUNCTIONS *
|
47
|
-
***************************/
|
48
|
-
|
49
|
-
/* lower • retruns the lower-case variant of the input char */
|
50
|
-
static char
|
51
|
-
lower(char c) {
|
52
|
-
return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; }
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
/********************
|
57
|
-
* BUFFER FUNCTIONS *
|
58
|
-
********************/
|
59
|
-
|
60
|
-
/* bufcasecmp • case-insensitive buffer comparison */
|
61
|
-
int
|
62
|
-
bufcasecmp(const struct buf *a, const struct buf *b) {
|
63
|
-
size_t i = 0;
|
64
|
-
size_t cmplen;
|
65
|
-
if (a == b) return 0;
|
66
|
-
if (!a) return -1; else if (!b) return 1;
|
67
|
-
cmplen = (a->size < b->size) ? a->size : b->size;
|
68
|
-
while (i < cmplen && lower(a->data[i]) == lower(b->data[i])) ++i;
|
69
|
-
if (i < a->size) {
|
70
|
-
if (i < b->size) return lower(a->data[i]) - lower(b->data[i]);
|
71
|
-
else return 1; }
|
72
|
-
else { if (i < b->size) return -1;
|
73
|
-
else return 0; } }
|
74
|
-
|
75
|
-
|
76
|
-
/* bufcmp • case-sensitive buffer comparison */
|
77
|
-
int
|
78
|
-
bufcmp(const struct buf *a, const struct buf *b) {
|
79
|
-
size_t i = 0;
|
80
|
-
size_t cmplen;
|
81
|
-
if (a == b) return 0;
|
82
|
-
if (!a) return -1; else if (!b) return 1;
|
83
|
-
cmplen = (a->size < b->size) ? a->size : b->size;
|
84
|
-
while (i < cmplen && a->data[i] == b->data[i]) ++i;
|
85
|
-
if (i < a->size) {
|
86
|
-
if (i < b->size) return a->data[i] - b->data[i];
|
87
|
-
else return 1; }
|
88
|
-
else { if (i < b->size) return -1;
|
89
|
-
else return 0; } }
|
90
|
-
|
91
|
-
|
92
|
-
/* bufcmps • case-sensitive comparison of a string to a buffer */
|
93
|
-
int
|
94
|
-
bufcmps(const struct buf *a, const char *b) {
|
95
|
-
const size_t len = strlen(b);
|
96
|
-
size_t cmplen = len;
|
97
|
-
int r;
|
98
|
-
if (!a || !a->size) return b ? 0 : -1;
|
99
|
-
if (len < a->size) cmplen = a->size;
|
100
|
-
r = strncmp(a->data, b, cmplen);
|
101
|
-
if (r) return r;
|
102
|
-
else if (a->size == len) return 0;
|
103
|
-
else if (a->size < len) return -1;
|
104
|
-
else return 1; }
|
105
|
-
|
106
33
|
int
|
107
34
|
bufprefix(const struct buf *buf, const char *prefix)
|
108
35
|
{
|
@@ -119,200 +46,179 @@ bufprefix(const struct buf *buf, const char *prefix)
|
|
119
46
|
return 0;
|
120
47
|
}
|
121
48
|
|
122
|
-
|
123
|
-
/* bufdup • buffer duplication */
|
124
|
-
struct buf *
|
125
|
-
bufdup(const struct buf *src, size_t dupunit) {
|
126
|
-
size_t blocks;
|
127
|
-
struct buf *ret;
|
128
|
-
if (src == 0) return 0;
|
129
|
-
ret = malloc(sizeof (struct buf));
|
130
|
-
if (ret == 0) return 0;
|
131
|
-
ret->unit = dupunit;
|
132
|
-
ret->size = src->size;
|
133
|
-
ret->ref = 1;
|
134
|
-
if (!src->size) {
|
135
|
-
ret->asize = 0;
|
136
|
-
ret->data = 0;
|
137
|
-
return ret; }
|
138
|
-
blocks = (src->size + dupunit - 1) / dupunit;
|
139
|
-
ret->asize = blocks * dupunit;
|
140
|
-
ret->data = malloc(ret->asize);
|
141
|
-
if (ret->data == 0) {
|
142
|
-
free(ret);
|
143
|
-
return 0; }
|
144
|
-
memcpy(ret->data, src->data, src->size);
|
145
|
-
#ifdef BUFFER_STATS
|
146
|
-
buffer_stat_nb += 1;
|
147
|
-
buffer_stat_alloc_bytes += ret->asize;
|
148
|
-
#endif
|
149
|
-
return ret; }
|
150
|
-
|
151
|
-
/* bufgrow • increasing the allocated size to the given value */
|
49
|
+
/* bufgrow: increasing the allocated size to the given value */
|
152
50
|
int
|
153
|
-
bufgrow(struct buf *buf, size_t neosz)
|
51
|
+
bufgrow(struct buf *buf, size_t neosz)
|
52
|
+
{
|
154
53
|
size_t neoasz;
|
155
54
|
void *neodata;
|
156
|
-
if (!buf || !buf->unit || neosz > BUFFER_MAX_ALLOC_SIZE)
|
157
|
-
|
55
|
+
if (!buf || !buf->unit || neosz > BUFFER_MAX_ALLOC_SIZE)
|
56
|
+
return BUF_ENOMEM;
|
57
|
+
|
58
|
+
if (buf->asize >= neosz)
|
59
|
+
return BUF_OK;
|
60
|
+
|
158
61
|
neoasz = buf->asize + buf->unit;
|
159
|
-
while (neoasz < neosz)
|
62
|
+
while (neoasz < neosz)
|
63
|
+
neoasz += buf->unit;
|
64
|
+
|
160
65
|
neodata = realloc(buf->data, neoasz);
|
161
|
-
if (!neodata)
|
162
|
-
|
163
|
-
|
164
|
-
#endif
|
66
|
+
if (!neodata)
|
67
|
+
return BUF_ENOMEM;
|
68
|
+
|
165
69
|
buf->data = neodata;
|
166
70
|
buf->asize = neoasz;
|
167
|
-
return
|
71
|
+
return BUF_OK;
|
72
|
+
}
|
168
73
|
|
169
74
|
|
170
|
-
/* bufnew
|
75
|
+
/* bufnew: allocation of a new buffer */
|
171
76
|
struct buf *
|
172
|
-
bufnew(size_t unit)
|
77
|
+
bufnew(size_t unit)
|
78
|
+
{
|
173
79
|
struct buf *ret;
|
174
80
|
ret = malloc(sizeof (struct buf));
|
81
|
+
|
175
82
|
if (ret) {
|
176
|
-
#ifdef BUFFER_STATS
|
177
|
-
buffer_stat_nb += 1;
|
178
|
-
#endif
|
179
83
|
ret->data = 0;
|
180
84
|
ret->size = ret->asize = 0;
|
181
|
-
ret->
|
182
|
-
|
183
|
-
return ret;
|
85
|
+
ret->unit = unit;
|
86
|
+
}
|
87
|
+
return ret;
|
88
|
+
}
|
184
89
|
|
90
|
+
/* bufnullterm: NULL-termination of the string array */
|
91
|
+
const char *
|
92
|
+
bufcstr(struct buf *buf)
|
93
|
+
{
|
94
|
+
if (!buf || !buf->unit)
|
95
|
+
return NULL;
|
185
96
|
|
186
|
-
|
187
|
-
|
188
|
-
bufnullterm(struct buf *buf) {
|
189
|
-
if (!buf || !buf->unit) return;
|
190
|
-
if (buf->size < buf->asize && buf->data[buf->size] == 0) return;
|
191
|
-
if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1))
|
192
|
-
buf->data[buf->size] = 0; }
|
97
|
+
if (buf->size < buf->asize && buf->data[buf->size] == 0)
|
98
|
+
return (char *)buf->data;
|
193
99
|
|
100
|
+
if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1) == 0) {
|
101
|
+
buf->data[buf->size] = 0;
|
102
|
+
return (char *)buf->data;
|
103
|
+
}
|
104
|
+
|
105
|
+
return NULL;
|
106
|
+
}
|
194
107
|
|
195
|
-
/* bufprintf
|
108
|
+
/* bufprintf: formatted printing to a buffer */
|
196
109
|
void
|
197
|
-
bufprintf(struct buf *buf, const char *fmt, ...)
|
110
|
+
bufprintf(struct buf *buf, const char *fmt, ...)
|
111
|
+
{
|
198
112
|
va_list ap;
|
199
|
-
if (!buf || !buf->unit)
|
113
|
+
if (!buf || !buf->unit)
|
114
|
+
return;
|
115
|
+
|
200
116
|
va_start(ap, fmt);
|
201
117
|
vbufprintf(buf, fmt, ap);
|
202
|
-
va_end(ap);
|
203
|
-
|
118
|
+
va_end(ap);
|
119
|
+
}
|
204
120
|
|
205
|
-
/* bufput
|
121
|
+
/* bufput: appends raw data to a buffer */
|
206
122
|
void
|
207
|
-
bufput(struct buf *buf, const void *data, size_t len)
|
208
|
-
|
209
|
-
if (
|
123
|
+
bufput(struct buf *buf, const void *data, size_t len)
|
124
|
+
{
|
125
|
+
if (!buf)
|
210
126
|
return;
|
211
|
-
memcpy(buf->data + buf->size, data, len);
|
212
|
-
buf->size += len; }
|
213
127
|
|
128
|
+
if (buf->size + len > buf->asize && bufgrow(buf, buf->size + len) < 0)
|
129
|
+
return;
|
214
130
|
|
215
|
-
|
131
|
+
memcpy(buf->data + buf->size, data, len);
|
132
|
+
buf->size += len;
|
133
|
+
}
|
134
|
+
|
135
|
+
/* bufputs: appends a NUL-terminated string to a buffer */
|
216
136
|
void
|
217
|
-
bufputs(struct buf *buf, const char *str)
|
218
|
-
|
137
|
+
bufputs(struct buf *buf, const char *str)
|
138
|
+
{
|
139
|
+
bufput(buf, str, strlen(str));
|
140
|
+
}
|
219
141
|
|
220
142
|
|
221
|
-
/* bufputc
|
143
|
+
/* bufputc: appends a single uint8_t to a buffer */
|
222
144
|
void
|
223
|
-
bufputc(struct buf *buf,
|
224
|
-
|
225
|
-
if (
|
145
|
+
bufputc(struct buf *buf, int c)
|
146
|
+
{
|
147
|
+
if (!buf)
|
226
148
|
return;
|
227
|
-
buf->data[buf->size] = c;
|
228
|
-
buf->size += 1; }
|
229
|
-
|
230
149
|
|
231
|
-
|
232
|
-
|
233
|
-
bufrelease(struct buf *buf) {
|
234
|
-
if (!buf) return;
|
235
|
-
buf->ref -= 1;
|
236
|
-
if (buf->ref == 0) {
|
237
|
-
#ifdef BUFFER_STATS
|
238
|
-
buffer_stat_nb -= 1;
|
239
|
-
buffer_stat_alloc_bytes -= buf->asize;
|
240
|
-
#endif
|
241
|
-
free(buf->data);
|
242
|
-
free(buf); } }
|
150
|
+
if (buf->size + 1 > buf->asize && bufgrow(buf, buf->size + 1) < 0)
|
151
|
+
return;
|
243
152
|
|
153
|
+
buf->data[buf->size] = c;
|
154
|
+
buf->size += 1;
|
155
|
+
}
|
244
156
|
|
245
|
-
/*
|
157
|
+
/* bufrelease: decrease the reference count and free the buffer if needed */
|
246
158
|
void
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
159
|
+
bufrelease(struct buf *buf)
|
160
|
+
{
|
161
|
+
if (!buf)
|
162
|
+
return;
|
163
|
+
|
252
164
|
free(buf->data);
|
253
|
-
buf
|
254
|
-
|
165
|
+
free(buf);
|
166
|
+
}
|
255
167
|
|
256
168
|
|
257
|
-
/*
|
169
|
+
/* bufreset: frees internal data of the buffer */
|
258
170
|
void
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
bufrelease(*dest);
|
264
|
-
*dest = src; }
|
171
|
+
bufreset(struct buf *buf)
|
172
|
+
{
|
173
|
+
if (!buf)
|
174
|
+
return;
|
265
175
|
|
176
|
+
free(buf->data);
|
177
|
+
buf->data = NULL;
|
178
|
+
buf->size = buf->asize = 0;
|
179
|
+
}
|
266
180
|
|
267
|
-
/* bufslurp
|
181
|
+
/* bufslurp: removes a given number of bytes from the head of the array */
|
268
182
|
void
|
269
|
-
bufslurp(struct buf *buf, size_t len)
|
270
|
-
|
183
|
+
bufslurp(struct buf *buf, size_t len)
|
184
|
+
{
|
185
|
+
if (!buf || !buf->unit || len <= 0)
|
186
|
+
return;
|
187
|
+
|
271
188
|
if (len >= buf->size) {
|
272
189
|
buf->size = 0;
|
273
|
-
return;
|
274
|
-
|
275
|
-
memmove(buf->data, buf->data + len, buf->size); }
|
190
|
+
return;
|
191
|
+
}
|
276
192
|
|
193
|
+
buf->size -= len;
|
194
|
+
memmove(buf->data, buf->data + len, buf->size);
|
195
|
+
}
|
277
196
|
|
278
|
-
/*
|
279
|
-
int
|
280
|
-
buftoi(struct buf *buf, size_t offset_i, size_t *offset_o) {
|
281
|
-
int r = 0, neg = 0;
|
282
|
-
size_t i = offset_i;
|
283
|
-
if (!buf || !buf->size) return 0;
|
284
|
-
if (buf->data[i] == '+') i += 1;
|
285
|
-
else if (buf->data[i] == '-') {
|
286
|
-
neg = 1;
|
287
|
-
i += 1; }
|
288
|
-
while (i < buf->size && buf->data[i] >= '0' && buf->data[i] <= '9') {
|
289
|
-
r = (r * 10) + buf->data[i] - '0';
|
290
|
-
i += 1; }
|
291
|
-
if (offset_o) *offset_o = i;
|
292
|
-
return neg ? -r : r; }
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
/* vbufprintf • stdarg variant of formatted printing into a buffer */
|
197
|
+
/* vbufprintf: stdarg variant of formatted printing into a buffer */
|
297
198
|
void
|
298
|
-
vbufprintf(struct buf *buf, const char *fmt, va_list ap)
|
199
|
+
vbufprintf(struct buf *buf, const char *fmt, va_list ap)
|
200
|
+
{
|
299
201
|
int n;
|
300
|
-
|
301
|
-
if (buf == 0
|
302
|
-
|| (buf->size >= buf->asize && !bufgrow (buf, buf->size + 1)))
|
202
|
+
|
203
|
+
if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0)
|
303
204
|
return;
|
304
205
|
|
305
|
-
|
306
|
-
|
206
|
+
n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
|
207
|
+
|
208
|
+
if (n < 0) {
|
209
|
+
#ifdef _MSC_VER
|
210
|
+
n = _vscprintf(fmt, ap);
|
211
|
+
#else
|
212
|
+
return;
|
213
|
+
#endif
|
214
|
+
}
|
307
215
|
|
308
|
-
if (
|
309
|
-
|
310
|
-
if (!bufgrow (buf, buf->size + new_size + 1))
|
216
|
+
if ((size_t)n >= buf->asize - buf->size) {
|
217
|
+
if (bufgrow(buf, buf->size + n + 1) < 0)
|
311
218
|
return;
|
312
219
|
|
313
|
-
n =
|
220
|
+
n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
|
314
221
|
}
|
315
|
-
va_end(ap_save);
|
316
222
|
|
317
223
|
if (n < 0)
|
318
224
|
return;
|
@@ -320,4 +226,3 @@ vbufprintf(struct buf *buf, const char *fmt, va_list ap) {
|
|
320
226
|
buf->size += n;
|
321
227
|
}
|
322
228
|
|
323
|
-
/* vim: set filetype=c: */
|