redcarpet 2.0.0b3 → 2.0.0b4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- data/README.markdown +39 -5
- data/Rakefile +2 -2
- data/ext/redcarpet/autolink.c +12 -12
- data/ext/redcarpet/autolink.h +4 -4
- data/ext/redcarpet/buffer.c +123 -218
- data/ext/redcarpet/buffer.h +49 -112
- data/ext/redcarpet/html.c +83 -117
- data/ext/redcarpet/html.h +9 -10
- data/ext/redcarpet/html_blocks.h +205 -0
- data/ext/redcarpet/html_smartypants.c +63 -39
- data/ext/redcarpet/markdown.c +456 -377
- data/ext/redcarpet/markdown.h +43 -29
- data/ext/redcarpet/rc_markdown.c +60 -34
- data/ext/redcarpet/rc_render.c +29 -35
- data/ext/redcarpet/redcarpet.h +4 -3
- data/ext/redcarpet/stack.c +81 -0
- data/ext/redcarpet/stack.h +21 -0
- data/lib/redcarpet.rb +4 -23
- data/redcarpet.gemspec +6 -4
- data/test/redcarpet_test.rb +39 -43
- metadata +56 -33
- data/ext/redcarpet/array.c +0 -300
- data/ext/redcarpet/array.h +0 -147
data/README.markdown
CHANGED
@@ -19,7 +19,7 @@ library so awesome.
|
|
19
19
|
This library is written by people
|
20
20
|
-------------------------------------------------------
|
21
21
|
|
22
|
-
Redcarpet 2 has been rewritten from scratch by Vicent
|
22
|
+
Redcarpet 2 has been rewritten from scratch by Vicent Martí (@tanoku). Why
|
23
23
|
are you not following me on Twitter?
|
24
24
|
|
25
25
|
Redcarpet would not be possible without the Sundown library and its authors
|
@@ -56,7 +56,7 @@ settings, and reused between parses.
|
|
56
56
|
If the given object has not been instantiated, the library
|
57
57
|
will do it with default arguments.
|
58
58
|
|
59
|
-
extensions - a hash containing the Markdown
|
59
|
+
extensions - a hash containing the Markdown extensions which the parser
|
60
60
|
will identify. The following extensions are accepted:
|
61
61
|
|
62
62
|
:no_intra_emphasis - do not parse emphasis inside of words.
|
@@ -85,7 +85,7 @@ settings, and reused between parses.
|
|
85
85
|
by an empty line as in the Markdown standard.
|
86
86
|
|
87
87
|
:space_after_headers - A space is always required between the
|
88
|
-
hash at the
|
88
|
+
hash at the beginning of a header and its name, e.g.
|
89
89
|
`#this is my header` would not be a valid header.
|
90
90
|
|
91
91
|
:superscript - parse superscripts after the `^` character;
|
@@ -123,6 +123,40 @@ renderers are actually implemented in C, and hence offer a brilliant
|
|
123
123
|
performance, several degrees of magnitude faster than other Ruby Markdown
|
124
124
|
solutions.
|
125
125
|
|
126
|
+
All the rendering flags that previously applied only to HTML output have
|
127
|
+
now been moved to the `Render::HTML` class, and may be enabled when
|
128
|
+
instantiating the renderer:
|
129
|
+
|
130
|
+
Render::HTML.new(render_options={})
|
131
|
+
|
132
|
+
Initializes an HTML renderer. The following flags are available:
|
133
|
+
|
134
|
+
:filter_html - do not allow any user-inputted HTML in the output
|
135
|
+
|
136
|
+
:no_images - do not generate any `<img>` tags
|
137
|
+
|
138
|
+
:no_links - do not generate any `<a>` tags
|
139
|
+
|
140
|
+
:no_styles - do not generate any `<style>` tags
|
141
|
+
|
142
|
+
:safe_links_only - only generate links for protocols which are considered safe
|
143
|
+
|
144
|
+
:with_toc_data - add HTML anchors to each header in the output HTML,
|
145
|
+
to allow liking to each section.
|
146
|
+
|
147
|
+
:hard_wrap - insert HTML `<br>` tags inside on paragraphs where the origin
|
148
|
+
Markdown document had newlines (by default, Markdown ignores these
|
149
|
+
newlines).
|
150
|
+
|
151
|
+
:xhtml - output XHTML-conformant tags. This option is always enabled in the
|
152
|
+
`Render::XHTML` renderer.
|
153
|
+
|
154
|
+
|
155
|
+
Example:
|
156
|
+
|
157
|
+
rndr = Redcarpet::Render::HTML.new(:no_links => true, :hard_wrap => true)
|
158
|
+
|
159
|
+
|
126
160
|
The `HTML` renderer has an alternate version, `Redcarpet::Render::HTML_TOC`,
|
127
161
|
which will output a table of contents in HTML based on the headers of the
|
128
162
|
Markdown document.
|
@@ -136,7 +170,7 @@ And you can even cook your own
|
|
136
170
|
------------------------------
|
137
171
|
|
138
172
|
Custom renderers are created by inheriting from an existing renderer. The
|
139
|
-
|
173
|
+
built-in renderers, `HTML` and `XHTML` may be extended as such:
|
140
174
|
|
141
175
|
~~~~~ ruby
|
142
176
|
# create a custom renderer that allows highlighting of code blocks
|
@@ -226,7 +260,7 @@ Also, now our Pants are much smarter
|
|
226
260
|
|
227
261
|
Redcarpet 2 comes with a standalone [SmartyPants](
|
228
262
|
http://daringfireball.net/projects/smartypants/) implementation. It is fully
|
229
|
-
|
263
|
+
compliant with the original implementation. It is the fastest SmartyPants
|
230
264
|
parser there is, with a difference of several orders of magnitude.
|
231
265
|
|
232
266
|
The SmartyPants parser can be found in `Redcarpet::Render::SmartyPants`. It has
|
data/Rakefile
CHANGED
@@ -113,8 +113,8 @@ desc 'Gather required Sundown sources into extension directory'
|
|
113
113
|
task :gather => 'sundown/src/markdown.h' do |t|
|
114
114
|
files =
|
115
115
|
FileList[
|
116
|
-
'sundown/src/{markdown,buffer,
|
117
|
-
'sundown/src/{markdown,buffer,
|
116
|
+
'sundown/src/{markdown,buffer,stack,autolink,html_blocks}.h',
|
117
|
+
'sundown/src/{markdown,buffer,stack,autolink}.c',
|
118
118
|
'sundown/html/{html,html_smartypants}.c',
|
119
119
|
'sundown/html/html.h',
|
120
120
|
]
|
data/ext/redcarpet/autolink.c
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
#include <ctype.h>
|
23
23
|
|
24
24
|
int
|
25
|
-
sd_autolink_issafe(const
|
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 @@ sd_autolink_issafe(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 @@ sd_autolink_issafe(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
|
-
sd_autolink__www(size_t *rewind_p, struct buf *link,
|
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 @@ sd_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset,
|
|
177
177
|
}
|
178
178
|
|
179
179
|
size_t
|
180
|
-
sd_autolink__email(size_t *rewind_p, struct buf *link,
|
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 @@ sd_autolink__email(size_t *rewind_p, struct buf *link, char *data, size_t offset
|
|
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 @@ sd_autolink__email(size_t *rewind_p, struct buf *link, char *data, size_t offset
|
|
226
226
|
}
|
227
227
|
|
228
228
|
size_t
|
229
|
-
sd_autolink__url(size_t *rewind_p, struct buf *link,
|
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
|
|
@@ -238,7 +238,7 @@ sd_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset,
|
|
238
238
|
|
239
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/redcarpet/autolink.h
CHANGED
@@ -20,16 +20,16 @@
|
|
20
20
|
#include "buffer.h"
|
21
21
|
|
22
22
|
extern int
|
23
|
-
sd_autolink_issafe(const
|
23
|
+
sd_autolink_issafe(const uint8_t *link, size_t link_len);
|
24
24
|
|
25
25
|
extern size_t
|
26
|
-
sd_autolink__www(size_t *rewind_p, struct buf *link,
|
26
|
+
sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
|
27
27
|
|
28
28
|
extern size_t
|
29
|
-
sd_autolink__email(size_t *rewind_p, struct buf *link,
|
29
|
+
sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
|
30
30
|
|
31
31
|
extern size_t
|
32
|
-
sd_autolink__url(size_t *rewind_p, struct buf *link,
|
32
|
+
sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size);
|
33
33
|
|
34
34
|
#endif
|
35
35
|
|
data/ext/redcarpet/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: */
|