wikitext 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/ary.c +63 -0
- data/ext/ary.h +11 -66
- data/ext/depend +8 -7
- data/ext/parser.c +16 -19
- data/ext/parser.h +1 -1
- data/ext/ruby_compat.h +25 -0
- data/ext/str.c +93 -0
- data/ext/str.h +13 -85
- data/ext/token.h +1 -1
- data/ext/wikitext.h +1 -1
- metadata +3 -2
data/ext/ary.c
CHANGED
@@ -14,6 +14,69 @@
|
|
14
14
|
|
15
15
|
#include "ary.h"
|
16
16
|
|
17
|
+
ary_t *ary_new(void)
|
18
|
+
{
|
19
|
+
ary_t *ary = ALLOC_N(ary_t, 1);
|
20
|
+
ary->count = 0;
|
21
|
+
ary->max = DEFAULT_ENTRY_COUNT;
|
22
|
+
ary->entries = ALLOC_N(int, DEFAULT_ENTRY_COUNT);
|
23
|
+
return ary;
|
24
|
+
}
|
25
|
+
|
26
|
+
int ary_entry(ary_t *ary, int idx)
|
27
|
+
{
|
28
|
+
if (idx < 0)
|
29
|
+
idx = ary->count + idx;
|
30
|
+
return (idx >= 0 && ary->count > idx) ? ary->entries[idx] : INT_MAX;
|
31
|
+
}
|
32
|
+
|
33
|
+
void ary_clear(ary_t *ary)
|
34
|
+
{
|
35
|
+
ary->count = 0;
|
36
|
+
}
|
37
|
+
|
38
|
+
int ary_pop(ary_t *ary)
|
39
|
+
{
|
40
|
+
if (ary->count > 0)
|
41
|
+
{
|
42
|
+
ary->count--;
|
43
|
+
return 1;
|
44
|
+
}
|
45
|
+
return 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
void ary_push(ary_t *ary, int val)
|
49
|
+
{
|
50
|
+
if (ary->count == ary->max)
|
51
|
+
{
|
52
|
+
ary->max += DEFAULT_ENTRY_COUNT;
|
53
|
+
REALLOC_N(ary->entries, int, ary->max);
|
54
|
+
}
|
55
|
+
ary->entries[ary->count] = val;
|
56
|
+
ary->count++;
|
57
|
+
}
|
58
|
+
|
59
|
+
int ary_includes(ary_t *ary, int val)
|
60
|
+
{
|
61
|
+
for (int i = 0, max = ary->count; i < max; i++)
|
62
|
+
{
|
63
|
+
if (ary->entries[i] == val)
|
64
|
+
return 1;
|
65
|
+
}
|
66
|
+
return 0;
|
67
|
+
}
|
68
|
+
|
69
|
+
int ary_count(ary_t *ary, int item)
|
70
|
+
{
|
71
|
+
int count = 0;
|
72
|
+
for (int i = 0, max = ary->count; i < max; i++)
|
73
|
+
{
|
74
|
+
if (ary->entries[i] == item)
|
75
|
+
count++;
|
76
|
+
}
|
77
|
+
return count;
|
78
|
+
}
|
79
|
+
|
17
80
|
void ary_free(ary_t *ary)
|
18
81
|
{
|
19
82
|
free(ary->entries);
|
data/ext/ary.h
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
// You should have received a copy of the GNU General Public License
|
13
13
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
14
|
|
15
|
-
#include
|
15
|
+
#include "ruby_compat.h"
|
16
16
|
|
17
17
|
typedef struct
|
18
18
|
{
|
@@ -28,73 +28,18 @@ typedef struct
|
|
28
28
|
|
29
29
|
// Mark the ary struct designated by ptr as a participant in Ruby's mark-and-sweep garbage collection scheme.
|
30
30
|
// A variable named name is placed on the C stack to prevent the structure from being prematurely collected.
|
31
|
-
#define GC_WRAP_ARY(ptr, name) volatile VALUE name = Data_Wrap_Struct(rb_cObject, 0, ary_free, ptr)
|
31
|
+
#define GC_WRAP_ARY(ptr, name) volatile VALUE name __attribute__((unused)) = Data_Wrap_Struct(rb_cObject, 0, ary_free, ptr)
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
return ary;
|
40
|
-
}
|
41
|
-
|
42
|
-
// this method not inlined so its address can be passed to the Data_Wrap_Struct function.
|
43
|
-
void ary_free(ary_t *ary);
|
44
|
-
|
45
|
-
inline int ary_entry(ary_t *ary, int idx)
|
46
|
-
{
|
47
|
-
if (idx < 0)
|
48
|
-
idx = ary->count + idx;
|
49
|
-
return (idx >= 0 && ary->count > idx) ? ary->entries[idx] : INT_MAX;
|
50
|
-
}
|
51
|
-
|
52
|
-
inline void ary_clear(ary_t *ary)
|
53
|
-
{
|
54
|
-
ary->count = 0;
|
55
|
-
}
|
56
|
-
|
57
|
-
inline int ary_pop(ary_t *ary)
|
58
|
-
{
|
59
|
-
if (ary->count > 0)
|
60
|
-
{
|
61
|
-
ary->count--;
|
62
|
-
return 1;
|
63
|
-
}
|
64
|
-
return 0;
|
65
|
-
}
|
66
|
-
|
67
|
-
inline void ary_push(ary_t *ary, int val)
|
68
|
-
{
|
69
|
-
if (ary->count == ary->max)
|
70
|
-
{
|
71
|
-
ary->max += DEFAULT_ENTRY_COUNT;
|
72
|
-
REALLOC_N(ary->entries, int, ary->max);
|
73
|
-
}
|
74
|
-
ary->entries[ary->count] = val;
|
75
|
-
ary->count++;
|
76
|
-
}
|
77
|
-
|
78
|
-
inline int ary_includes(ary_t *ary, int val)
|
79
|
-
{
|
80
|
-
for (int i = 0, max = ary->count; i < max; i++)
|
81
|
-
{
|
82
|
-
if (ary->entries[i] == val)
|
83
|
-
return 1;
|
84
|
-
}
|
85
|
-
return 0;
|
86
|
-
}
|
33
|
+
ary_t *ary_new(void);
|
34
|
+
int ary_entry(ary_t *ary, int idx);
|
35
|
+
void ary_clear(ary_t *ary);
|
36
|
+
int ary_pop(ary_t *ary);
|
37
|
+
void ary_push(ary_t *ary, int val);
|
38
|
+
int ary_includes(ary_t *ary, int val);
|
87
39
|
|
88
40
|
// returns a count indicating the number of times the value appears in the collection
|
89
41
|
// refactored from _Wikitext_count()
|
90
|
-
|
91
|
-
{
|
92
|
-
int count = 0;
|
93
|
-
for (int i = 0, max = ary->count; i < max; i++)
|
94
|
-
{
|
95
|
-
if (ary->entries[i] == item)
|
96
|
-
count++;
|
97
|
-
}
|
98
|
-
return count;
|
99
|
-
}
|
42
|
+
int ary_count(ary_t *ary, int item);
|
100
43
|
|
44
|
+
// this method not inlined so its address can be passed to the Data_Wrap_Struct function.
|
45
|
+
void ary_free(ary_t *ary);
|
data/ext/depend
CHANGED
@@ -14,11 +14,12 @@
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
|
17
|
-
|
17
|
+
# don't warn about unused params because many Ruby methods accept "self" but don't use it
|
18
|
+
CFLAGS += -std=gnu99 -Wall -Wextra -Wno-unused-parameter
|
18
19
|
|
19
|
-
ary.o : ary.c ary.h
|
20
|
-
parser.o : ary.c ary.h parser.c parser.h
|
21
|
-
str.o : str.c str.h
|
22
|
-
token.o : token.c token.h wikitext.h
|
23
|
-
wikitext.o : parser.h token.h wikitext.c wikitext.h wikitext_ragel.h
|
24
|
-
wikitext_ragel.o : token.h wikitext.h wikitext_ragel.h wikitext_ragel.c
|
20
|
+
ary.o : ary.c ary.h ruby_compat.h
|
21
|
+
parser.o : ary.c ary.h parser.c parser.h ruby_compat.h str.c str.h token.h wikitext.h wikitext_ragel.h
|
22
|
+
str.o : ruby_compat.h str.c str.h
|
23
|
+
token.o : ruby_compat.h token.c token.h wikitext.h
|
24
|
+
wikitext.o : parser.h ruby_compat.h token.h wikitext.c wikitext.h wikitext_ragel.h
|
25
|
+
wikitext_ragel.o : ruby_compat.h token.h wikitext.h wikitext_ragel.h wikitext_ragel.c
|
data/ext/parser.c
CHANGED
@@ -158,7 +158,7 @@ VALUE Wikitext_parser_benchmarking_tokenize(VALUE self, VALUE string)
|
|
158
158
|
}
|
159
159
|
|
160
160
|
// we downcase "in place", overwriting the original contents of the buffer and returning the same string
|
161
|
-
|
161
|
+
VALUE _Wikitext_downcase(VALUE string)
|
162
162
|
{
|
163
163
|
char *ptr = RSTRING_PTR(string);
|
164
164
|
long len = RSTRING_LEN(string);
|
@@ -170,7 +170,7 @@ inline VALUE _Wikitext_downcase(VALUE string)
|
|
170
170
|
return string;
|
171
171
|
}
|
172
172
|
|
173
|
-
|
173
|
+
VALUE _Wikitext_hyperlink(VALUE link_prefix, VALUE link_target, VALUE link_text, VALUE link_class)
|
174
174
|
{
|
175
175
|
VALUE string = rb_str_new(a_start, sizeof(a_start) - 1); // <a href="
|
176
176
|
if (!NIL_P(link_prefix))
|
@@ -187,7 +187,7 @@ inline VALUE _Wikitext_hyperlink(VALUE link_prefix, VALUE link_target, VALUE lin
|
|
187
187
|
return string;
|
188
188
|
}
|
189
189
|
|
190
|
-
|
190
|
+
void _Wikitext_append_img(parser_t *parser, char *token_ptr, int token_len)
|
191
191
|
{
|
192
192
|
rb_str_cat(parser->output, img_start, sizeof(img_start) - 1); // <img src="
|
193
193
|
if (!NIL_P(parser->img_prefix))
|
@@ -201,7 +201,7 @@ inline void _Wikitext_append_img(parser_t *parser, char *token_ptr, int token_le
|
|
201
201
|
// will emit indentation only if we are about to emit any of:
|
202
202
|
// <blockquote>, <p>, <ul>, <ol>, <li>, <h1> etc, <pre>
|
203
203
|
// each time we enter one of those spans must ++ the indentation level
|
204
|
-
|
204
|
+
void _Wikitext_indent(parser_t *parser)
|
205
205
|
{
|
206
206
|
int space_count = parser->current_indent + parser->base_indent;
|
207
207
|
if (space_count > 0)
|
@@ -220,7 +220,7 @@ inline void _Wikitext_indent(parser_t *parser)
|
|
220
220
|
parser->current_indent += 2;
|
221
221
|
}
|
222
222
|
|
223
|
-
|
223
|
+
void _Wikitext_dedent(parser_t *parser, VALUE emit)
|
224
224
|
{
|
225
225
|
parser->current_indent -= 2;
|
226
226
|
if (emit != Qtrue)
|
@@ -393,7 +393,7 @@ void _Wikitext_pop_from_stack_up_to(parser_t *parser, VALUE target, int item, VA
|
|
393
393
|
} while (continue_looping);
|
394
394
|
}
|
395
395
|
|
396
|
-
|
396
|
+
void _Wikitext_start_para_if_necessary(parser_t *parser)
|
397
397
|
{
|
398
398
|
if (!NIL_P(parser->capture)) // we don't do anything if in capturing mode
|
399
399
|
return;
|
@@ -442,7 +442,7 @@ inline void _Wikitext_start_para_if_necessary(parser_t *parser)
|
|
442
442
|
// on the line scope.
|
443
443
|
// Luckily, BLOCKQUOTE_START tokens can only appear at the start of the scope array, so we can check for them first before
|
444
444
|
// entering the for loop.
|
445
|
-
void
|
445
|
+
void _Wikitext_pop_excess_elements(parser_t *parser)
|
446
446
|
{
|
447
447
|
if (!NIL_P(parser->capture)) // we don't pop anything if in capturing mode
|
448
448
|
return;
|
@@ -471,7 +471,7 @@ void inline _Wikitext_pop_excess_elements(parser_t *parser)
|
|
471
471
|
// the number of bytes in the UTF-8 character (between 1 and 4) is returned by reference in width_out
|
472
472
|
// raises a RangeError if the supplied character is invalid UTF-8
|
473
473
|
// (in which case it also frees the block of memory indicated by dest_ptr if it is non-NULL)
|
474
|
-
|
474
|
+
uint32_t _Wikitext_utf8_to_utf32(char *src, char *end, long *width_out, void *dest_ptr)
|
475
475
|
{
|
476
476
|
uint32_t dest;
|
477
477
|
if ((unsigned char)src[0] <= 0x7f) // ASCII
|
@@ -515,7 +515,7 @@ inline uint32_t _Wikitext_utf8_to_utf32(char *src, char *end, long *width_out, v
|
|
515
515
|
return dest;
|
516
516
|
}
|
517
517
|
|
518
|
-
|
518
|
+
VALUE _Wikitext_utf32_char_to_entity(uint32_t character)
|
519
519
|
{
|
520
520
|
// TODO: consider special casing some entities (ie. quot, amp, lt, gt etc)?
|
521
521
|
char hex_string[8] = { '&', '#', 'x', 0, 0, 0, 0, ';' };
|
@@ -530,7 +530,7 @@ inline VALUE _Wikitext_utf32_char_to_entity(uint32_t character)
|
|
530
530
|
return rb_str_new((const char *)hex_string, sizeof(hex_string));
|
531
531
|
}
|
532
532
|
|
533
|
-
|
533
|
+
VALUE _Wikitext_parser_trim_link_target(VALUE string)
|
534
534
|
{
|
535
535
|
string = StringValue(string);
|
536
536
|
char *src = RSTRING_PTR(string);
|
@@ -544,7 +544,7 @@ inline VALUE _Wikitext_parser_trim_link_target(VALUE string)
|
|
544
544
|
if (*src == ' ')
|
545
545
|
{
|
546
546
|
if (src == left)
|
547
|
-
|
547
|
+
left++;
|
548
548
|
}
|
549
549
|
else
|
550
550
|
non_space = src;
|
@@ -560,7 +560,7 @@ inline VALUE _Wikitext_parser_trim_link_target(VALUE string)
|
|
560
560
|
// - QUOT and AMP characters converted to named entities
|
561
561
|
// - if rollback is Qtrue, there is no special treatment of spaces
|
562
562
|
// - if rollback is Qfalse, leading and trailing whitespace trimmed if trimmed
|
563
|
-
|
563
|
+
VALUE _Wikitext_parser_sanitize_link_target(parser_t *parser, VALUE rollback)
|
564
564
|
{
|
565
565
|
VALUE string = StringValue(parser->link_target); // raises if string is nil or doesn't quack like a string
|
566
566
|
char *src = RSTRING_PTR(string);
|
@@ -667,7 +667,7 @@ VALUE Wikitext_parser_sanitize_link_target(VALUE self, VALUE string)
|
|
667
667
|
// thing. [[Foo]] was...
|
668
668
|
// this is also where we check treat_slash_as_special is true and act accordingly
|
669
669
|
// basically any link target matching /\A[a-z]+\/\d+\z/ is flagged as special
|
670
|
-
|
670
|
+
static void _Wikitext_parser_encode_link_target(parser_t *parser)
|
671
671
|
{
|
672
672
|
VALUE in = StringValue(parser->link_target);
|
673
673
|
char *input = RSTRING_PTR(in);
|
@@ -784,8 +784,7 @@ VALUE Wikitext_parser_encode_special_link_target(VALUE self, VALUE in)
|
|
784
784
|
return parser.link_target;
|
785
785
|
}
|
786
786
|
|
787
|
-
|
788
|
-
inline void _Wikitext_rollback_failed_link(parser_t *parser)
|
787
|
+
void _Wikitext_rollback_failed_link(parser_t *parser)
|
789
788
|
{
|
790
789
|
if (!IN(LINK_START))
|
791
790
|
return; // nothing to do!
|
@@ -808,7 +807,7 @@ inline void _Wikitext_rollback_failed_link(parser_t *parser)
|
|
808
807
|
parser->link_text = Qnil;
|
809
808
|
}
|
810
809
|
|
811
|
-
|
810
|
+
void _Wikitext_rollback_failed_external_link(parser_t *parser)
|
812
811
|
{
|
813
812
|
if (!IN(EXT_LINK_START))
|
814
813
|
return; // nothing to do!
|
@@ -880,6 +879,7 @@ VALUE Wikitext_parser_profiling_parse(VALUE self, VALUE string)
|
|
880
879
|
{
|
881
880
|
for (int i = 0; i < 100000; i++)
|
882
881
|
Wikitext_parser_parse(1, &string, self);
|
882
|
+
return Qnil;
|
883
883
|
}
|
884
884
|
|
885
885
|
VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
|
@@ -970,9 +970,6 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
|
|
970
970
|
}
|
971
971
|
int type = token->type;
|
972
972
|
|
973
|
-
// many restrictions depend on what is at the top of the stack
|
974
|
-
int top = ary_entry(parser->scope, -1);
|
975
|
-
|
976
973
|
// can't declare new variables inside a switch statement, so predeclare them here
|
977
974
|
long remove_strong = -1;
|
978
975
|
long remove_em = -1;
|
data/ext/parser.h
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
// You should have received a copy of the GNU General Public License
|
13
13
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
14
|
|
15
|
-
#include
|
15
|
+
#include "ruby_compat.h"
|
16
16
|
|
17
17
|
VALUE Wikitext_parser_initialize(int argc, VALUE *argv, VALUE self);
|
18
18
|
|
data/ext/ruby_compat.h
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
// Copyright 2008 Wincent Colaiuta
|
2
|
+
// This program is free software: you can redistribute it and/or modify
|
3
|
+
// it under the terms of the GNU General Public License as published by
|
4
|
+
// the Free Software Foundation, either version 3 of the License, or
|
5
|
+
// (at your option) any later version.
|
6
|
+
//
|
7
|
+
// This program is distributed in the hope that it will be useful,
|
8
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
// GNU General Public License for more details.
|
11
|
+
//
|
12
|
+
// You should have received a copy of the GNU General Public License
|
13
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
|
+
|
15
|
+
#include <ruby.h>
|
16
|
+
|
17
|
+
// for compatibility with Ruby 1.8.5, which doesn't declare RSTRING_PTR
|
18
|
+
#ifndef RSTRING_PTR
|
19
|
+
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
20
|
+
#endif
|
21
|
+
|
22
|
+
// for compatibility with Ruby 1.8.5, which doesn't declare RSTRING_LEN
|
23
|
+
#ifndef RSTRING_LEN
|
24
|
+
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
25
|
+
#endif
|
data/ext/str.c
CHANGED
@@ -14,6 +14,99 @@
|
|
14
14
|
|
15
15
|
#include "str.h"
|
16
16
|
|
17
|
+
str_t *str_new(void)
|
18
|
+
{
|
19
|
+
str_t *str = ALLOC_N(str_t, 1);
|
20
|
+
str->ptr = NULL;
|
21
|
+
str->len = 0;
|
22
|
+
str->capacity = 0;
|
23
|
+
return str;
|
24
|
+
}
|
25
|
+
|
26
|
+
str_t *str_new_size(long len)
|
27
|
+
{
|
28
|
+
str_t *str = ALLOC_N(str_t, 1);
|
29
|
+
str->ptr = ALLOC_N(char, len);
|
30
|
+
str->len = 0;
|
31
|
+
str->capacity = len;
|
32
|
+
return str;
|
33
|
+
}
|
34
|
+
|
35
|
+
str_t *str_new_copy(char *src, long len)
|
36
|
+
{
|
37
|
+
str_t *str = ALLOC_N(str_t, 1);
|
38
|
+
str->ptr = ALLOC_N(char, len);
|
39
|
+
memcpy(str->ptr, src, len);
|
40
|
+
str->len = len;
|
41
|
+
str->capacity = len;
|
42
|
+
return str;
|
43
|
+
}
|
44
|
+
|
45
|
+
str_t *str_new_no_copy(char *src, long len)
|
46
|
+
{
|
47
|
+
str_t *str = ALLOC_N(str_t, 1);
|
48
|
+
str->ptr = src;
|
49
|
+
str->len = len;
|
50
|
+
str->capacity = len;
|
51
|
+
return str;
|
52
|
+
}
|
53
|
+
|
54
|
+
str_t *str_new_from_string(VALUE string)
|
55
|
+
{
|
56
|
+
string = StringValue(string);
|
57
|
+
return str_new_copy(RSTRING_PTR(string), RSTRING_LEN(string));
|
58
|
+
}
|
59
|
+
|
60
|
+
VALUE string_from_str(str_t *str)
|
61
|
+
{
|
62
|
+
return rb_str_new(str->ptr, str->len);
|
63
|
+
}
|
64
|
+
|
65
|
+
void str_grow(str_t *str, long len)
|
66
|
+
{
|
67
|
+
if (str->capacity < len)
|
68
|
+
{
|
69
|
+
if (str->ptr)
|
70
|
+
REALLOC_N(str->ptr, char, len);
|
71
|
+
else
|
72
|
+
str->ptr = ALLOC_N(char, len);
|
73
|
+
str->capacity = len;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
void str_append(str_t *str, char *src, long len)
|
78
|
+
{
|
79
|
+
long new_len = str->len + len;
|
80
|
+
if (str->capacity < new_len)
|
81
|
+
{
|
82
|
+
if (str->ptr)
|
83
|
+
REALLOC_N(str->ptr, char, new_len);
|
84
|
+
else
|
85
|
+
str->ptr = ALLOC_N(char, new_len);
|
86
|
+
str->capacity = new_len;
|
87
|
+
}
|
88
|
+
memcpy(str->ptr + str->len, src, len);
|
89
|
+
str->len = new_len;
|
90
|
+
}
|
91
|
+
|
92
|
+
void str_append_str(str_t *str, str_t *other)
|
93
|
+
{
|
94
|
+
str_append(str, other->ptr, other->len);
|
95
|
+
}
|
96
|
+
|
97
|
+
void str_swap(str_t **a, str_t **b)
|
98
|
+
{
|
99
|
+
str_t *c;
|
100
|
+
c = *a;
|
101
|
+
*a = *b;
|
102
|
+
*b = c;
|
103
|
+
}
|
104
|
+
|
105
|
+
void str_clear(str_t *str)
|
106
|
+
{
|
107
|
+
str->len = 0;
|
108
|
+
}
|
109
|
+
|
17
110
|
void str_free(str_t *str)
|
18
111
|
{
|
19
112
|
if (str->ptr)
|
data/ext/str.h
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
// You should have received a copy of the GNU General Public License
|
13
13
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
14
|
|
15
|
-
#include
|
15
|
+
#include "ruby_compat.h"
|
16
16
|
|
17
17
|
typedef struct
|
18
18
|
{
|
@@ -23,113 +23,41 @@ typedef struct
|
|
23
23
|
|
24
24
|
// Mark the str struct designated by ptr as a participant in Ruby's mark-and-sweep garbage collection scheme.
|
25
25
|
// A variable named name is placed on the C stack to prevent the structure from being prematurely collected.
|
26
|
-
#define GC_WRAP_STR(ptr, name) volatile VALUE name = Data_Wrap_Struct(rb_cObject, 0, str_free, ptr)
|
26
|
+
#define GC_WRAP_STR(ptr, name) volatile VALUE name __attribute__((unused)) = Data_Wrap_Struct(rb_cObject, 0, str_free, ptr)
|
27
27
|
|
28
28
|
// create a new, empty string struct
|
29
|
-
|
30
|
-
{
|
31
|
-
str_t *str = ALLOC_N(str_t, 1);
|
32
|
-
str->ptr = NULL;
|
33
|
-
str->len = 0;
|
34
|
-
str->capacity = 0;
|
35
|
-
return str;
|
36
|
-
}
|
29
|
+
str_t *str_new(void);
|
37
30
|
|
38
31
|
// create a new, empty string struct with capacity len
|
39
|
-
|
40
|
-
{
|
41
|
-
str_t *str = ALLOC_N(str_t, 1);
|
42
|
-
str->ptr = ALLOC_N(char, len);
|
43
|
-
str->len = 0;
|
44
|
-
str->capacity = len;
|
45
|
-
return str;
|
46
|
-
}
|
32
|
+
str_t *str_new_size(long len);
|
47
33
|
|
48
34
|
// create a new string struct and initialize it with a copy of the buffer of length len pointed to by src
|
49
|
-
|
50
|
-
{
|
51
|
-
str_t *str = ALLOC_N(str_t, 1);
|
52
|
-
str->ptr = ALLOC_N(char, len);
|
53
|
-
memcpy(str->ptr, src, len);
|
54
|
-
str->len = len;
|
55
|
-
str->capacity = len;
|
56
|
-
return str;
|
57
|
-
}
|
35
|
+
str_t *str_new_copy(char *src, long len);
|
58
36
|
|
59
37
|
// create a new string struct and initialize it with the buffer of length len pointed to by src
|
60
38
|
// no copy is made; the struct takes ownership of the buffer and will free it when the struct is disposed of
|
61
|
-
|
62
|
-
{
|
63
|
-
str_t *str = ALLOC_N(str_t, 1);
|
64
|
-
str->ptr = src;
|
65
|
-
str->len = len;
|
66
|
-
str->capacity = len;
|
67
|
-
return str;
|
68
|
-
}
|
39
|
+
str_t *str_new_no_copy(char *src, long len);
|
69
40
|
|
70
41
|
// convenience method for testing
|
71
|
-
|
72
|
-
{
|
73
|
-
string = StringValue(string);
|
74
|
-
return str_new_copy(RSTRING_PTR(string), RSTRING_LEN(string));
|
75
|
-
}
|
42
|
+
str_t *str_new_from_string(VALUE string);
|
76
43
|
|
77
44
|
// convenience method for testing
|
78
|
-
|
79
|
-
{
|
80
|
-
return rb_str_new(str->ptr, str->len);
|
81
|
-
}
|
45
|
+
VALUE string_from_str(str_t *str);
|
82
46
|
|
83
47
|
// grows a string's capacity to the specified length
|
84
|
-
|
85
|
-
{
|
86
|
-
if (str->capacity < len)
|
87
|
-
{
|
88
|
-
if (str->ptr)
|
89
|
-
REALLOC_N(str->ptr, char, len);
|
90
|
-
else
|
91
|
-
str->ptr = ALLOC_N(char, len);
|
92
|
-
str->capacity = len;
|
93
|
-
}
|
94
|
-
}
|
48
|
+
void str_grow(str_t *str, long len);
|
95
49
|
|
96
|
-
|
97
|
-
{
|
98
|
-
long new_len = str->len + len;
|
99
|
-
if (str->capacity < new_len)
|
100
|
-
{
|
101
|
-
if (str->ptr)
|
102
|
-
REALLOC_N(str->ptr, char, new_len);
|
103
|
-
else
|
104
|
-
str->ptr = ALLOC_N(char, new_len);
|
105
|
-
str->capacity = new_len;
|
106
|
-
}
|
107
|
-
memcpy(str->ptr + str->len, src, len);
|
108
|
-
str->len = new_len;
|
109
|
-
}
|
50
|
+
void str_append(str_t *str, char *src, long len);
|
110
51
|
|
111
52
|
// appends the "other" string struct onto str
|
112
|
-
|
113
|
-
{
|
114
|
-
str_append(str, other->ptr, other->len);
|
115
|
-
}
|
53
|
+
void str_append_str(str_t *str, str_t *other);
|
116
54
|
|
117
55
|
// this is a temporary convenience measure
|
118
56
|
// later on if I develop in-place variants of some functions this won't be needed
|
119
|
-
|
120
|
-
{
|
121
|
-
str_t *c;
|
122
|
-
c = *a;
|
123
|
-
*a = *b;
|
124
|
-
*b = c;
|
125
|
-
}
|
57
|
+
void str_swap(str_t **a, str_t **b);
|
126
58
|
|
127
59
|
// don't actually free the memory yet
|
128
60
|
// this makes str structs very useful when reusing buffers because it avoids reallocation
|
129
|
-
|
130
|
-
{
|
131
|
-
str->len = 0;
|
132
|
-
}
|
61
|
+
void str_clear(str_t *str);
|
133
62
|
|
134
|
-
// this method not inlined so its address can be passed to the Data_Wrap_Struct function.
|
135
63
|
void str_free(str_t *str);
|
data/ext/token.h
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
// You should have received a copy of the GNU General Public License
|
13
13
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
14
|
|
15
|
-
#include
|
15
|
+
#include "ruby_compat.h"
|
16
16
|
#include <stdint.h> /* uint32_t */
|
17
17
|
|
18
18
|
#define TOKEN_TEXT(token) rb_str_new((const char *)token->start, (token->stop - token->start))
|
data/ext/wikitext.h
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
// You should have received a copy of the GNU General Public License
|
13
13
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
14
|
|
15
|
-
#include
|
15
|
+
#include "ruby_compat.h"
|
16
16
|
#include <stdint.h>
|
17
17
|
|
18
18
|
#define ruby_inspect(obj) rb_funcall(rb_mKernel, rb_intern("p"), 1, obj)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wikitext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.6"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wincent Colaiuta
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-29 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- ext/wikitext_ragel.c
|
62
62
|
- ext/ary.h
|
63
63
|
- ext/parser.h
|
64
|
+
- ext/ruby_compat.h
|
64
65
|
- ext/str.h
|
65
66
|
- ext/token.h
|
66
67
|
- ext/wikitext.h
|