wikitext 0.4 → 0.5
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/ext/ary.c +21 -0
- data/ext/ary.h +6 -5
- data/ext/depend +3 -1
- data/ext/parser.c +7 -11
- data/ext/str.c +22 -0
- data/ext/str.h +6 -6
- data/lib/wikitext/rails.rb +14 -0
- data/lib/wikitext/string.rb +21 -0
- data/spec/integration_spec.rb +9 -0
- metadata +7 -2
data/ext/ary.c
ADDED
@@ -0,0 +1,21 @@
|
|
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 "ary.h"
|
16
|
+
|
17
|
+
void ary_free(ary_t *ary)
|
18
|
+
{
|
19
|
+
free(ary->entries);
|
20
|
+
free(ary);
|
21
|
+
}
|
data/ext/ary.h
CHANGED
@@ -26,6 +26,10 @@ typedef struct
|
|
26
26
|
|
27
27
|
#define NO_ITEM(item) (item == INT_MAX)
|
28
28
|
|
29
|
+
// Mark the ary struct designated by ptr as a participant in Ruby's mark-and-sweep garbage collection scheme.
|
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)
|
32
|
+
|
29
33
|
inline ary_t *ary_new(void)
|
30
34
|
{
|
31
35
|
ary_t *ary = ALLOC_N(ary_t, 1);
|
@@ -35,11 +39,8 @@ inline ary_t *ary_new(void)
|
|
35
39
|
return ary;
|
36
40
|
}
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
free(ary->entries);
|
41
|
-
free(ary);
|
42
|
-
}
|
42
|
+
// this method not inlined so its address can be passed to the Data_Wrap_Struct function.
|
43
|
+
void ary_free(ary_t *ary);
|
43
44
|
|
44
45
|
inline int ary_entry(ary_t *ary, int idx)
|
45
46
|
{
|
data/ext/depend
CHANGED
@@ -16,7 +16,9 @@
|
|
16
16
|
|
17
17
|
CFLAGS += -std=gnu99
|
18
18
|
|
19
|
-
|
19
|
+
ary.o : ary.c ary.h
|
20
|
+
parser.o : ary.c ary.h parser.c parser.h token.h str.c str.h wikitext.h wikitext_ragel.h
|
21
|
+
str.o : str.c str.h
|
20
22
|
token.o : token.c token.h wikitext.h
|
21
23
|
wikitext.o : parser.h token.h wikitext.c wikitext.h wikitext_ragel.h
|
22
24
|
wikitext_ragel.o : token.h wikitext.h wikitext_ragel.h wikitext_ragel.c
|
data/ext/parser.c
CHANGED
@@ -207,9 +207,7 @@ inline void _Wikitext_indent(parser_t *parser)
|
|
207
207
|
if (space_count > 0)
|
208
208
|
{
|
209
209
|
char *old_end, *new_end;
|
210
|
-
if (
|
211
|
-
parser->tabulation = str_new_size(space_count);
|
212
|
-
else if (parser->tabulation->len < space_count)
|
210
|
+
if (parser->tabulation->len < space_count)
|
213
211
|
str_grow(parser->tabulation, space_count); // reallocates if necessary
|
214
212
|
old_end = parser->tabulation->ptr + parser->tabulation->len;
|
215
213
|
new_end = parser->tabulation->ptr + space_count;
|
@@ -930,17 +928,22 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
|
|
930
928
|
parser->external_link_class = link_class;
|
931
929
|
parser->img_prefix = rb_iv_get(self, "@img_prefix");
|
932
930
|
parser->scope = ary_new();
|
931
|
+
GC_WRAP_ARY(parser->scope, scope_gc);
|
933
932
|
parser->line = ary_new();
|
933
|
+
GC_WRAP_ARY(parser->line, line_gc);
|
934
934
|
parser->line_buffer = ary_new();
|
935
|
+
GC_WRAP_ARY(parser->line_buffer, line_buffer_gc);
|
935
936
|
parser->pending_crlf = Qfalse;
|
936
937
|
parser->autolink = rb_iv_get(self, "@autolink");
|
937
938
|
parser->treat_slash_as_special = rb_iv_get(self, "@treat_slash_as_special");
|
938
939
|
parser->space_to_underscore = rb_iv_get(self, "@space_to_underscore");
|
939
940
|
parser->special_link = Qfalse;
|
940
941
|
parser->line_ending = str_new_from_string(line_ending);
|
942
|
+
GC_WRAP_STR(parser->line_ending, line_ending_gc);
|
941
943
|
parser->base_indent = base_indent;
|
942
944
|
parser->current_indent = 0;
|
943
|
-
parser->tabulation =
|
945
|
+
parser->tabulation = str_new();
|
946
|
+
GC_WRAP_STR(parser->tabulation, tabulation_gc);
|
944
947
|
|
945
948
|
token_t _token;
|
946
949
|
_token.type = NO_TOKEN;
|
@@ -2266,12 +2269,5 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
|
|
2266
2269
|
token = NULL;
|
2267
2270
|
} while (1);
|
2268
2271
|
return_output:
|
2269
|
-
// BUG: these will leak if we exit this function by raising an exception; need to investigate using Data_Wrap_Struct
|
2270
|
-
ary_free(parser->scope);
|
2271
|
-
ary_free(parser->line);
|
2272
|
-
ary_free(parser->line_buffer);
|
2273
|
-
str_free(parser->line_ending);
|
2274
|
-
if (parser->tabulation)
|
2275
|
-
str_free(parser->tabulation);
|
2276
2272
|
return parser->output;
|
2277
2273
|
}
|
data/ext/str.c
ADDED
@@ -0,0 +1,22 @@
|
|
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 "str.h"
|
16
|
+
|
17
|
+
void str_free(str_t *str)
|
18
|
+
{
|
19
|
+
if (str->ptr)
|
20
|
+
free(str->ptr);
|
21
|
+
free(str);
|
22
|
+
}
|
data/ext/str.h
CHANGED
@@ -21,6 +21,10 @@ typedef struct
|
|
21
21
|
long capacity;
|
22
22
|
} str_t;
|
23
23
|
|
24
|
+
// Mark the str struct designated by ptr as a participant in Ruby's mark-and-sweep garbage collection scheme.
|
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)
|
27
|
+
|
24
28
|
// create a new, empty string struct
|
25
29
|
inline str_t *str_new(void)
|
26
30
|
{
|
@@ -127,9 +131,5 @@ inline void str_clear(str_t *str)
|
|
127
131
|
str->len = 0;
|
128
132
|
}
|
129
133
|
|
130
|
-
|
131
|
-
|
132
|
-
if (str->ptr)
|
133
|
-
free(str->ptr);
|
134
|
-
free(str);
|
135
|
-
}
|
134
|
+
// this method not inlined so its address can be passed to the Data_Wrap_Struct function.
|
135
|
+
void str_free(str_t *str);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'wikitext'
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
def to_wikitext
|
6
|
+
@@shared_wikitext_parser ||= Wikitext::Parser.new(:space_to_underscore => true)
|
7
|
+
@@shared_wikitext_parser.parse wikitext_preprocess
|
8
|
+
end
|
9
|
+
|
10
|
+
# Convenience shortcut
|
11
|
+
alias :w :to_wikitext
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# for now do this in pure Ruby
|
16
|
+
# if speed later becomes a concern can whip up a Ragel C extension to do it
|
17
|
+
def wikitext_preprocess
|
18
|
+
gsub /\b(bug|issue|request) #(\d+)/i, '[[issues/\2|\1 #\2]]'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/spec/integration_spec.rb
CHANGED
@@ -265,4 +265,13 @@ describe Wikitext::Parser, 'with large slab of input text' do
|
|
265
265
|
|
266
266
|
@parser.parse(input).should == expected
|
267
267
|
end
|
268
|
+
|
269
|
+
# Without something like this it is possible to complete the entire spec suite without
|
270
|
+
# triggering garbage collection at all, or at least enough to expose memory-related bugs.
|
271
|
+
# So add one long-running spec to hopefully catch any GC and memory-related bugs.
|
272
|
+
it 'should work correctly during long runs (when Garbage Collection runs)' do
|
273
|
+
input = "a <strong>simple</strong> ''test'' of the [[wikitext parser]]"
|
274
|
+
expected = %Q{<p>a <strong>simple</strong> <em>test</em> of the <a href="/wiki/wikitext%20parser">wikitext parser</a></p>\n}
|
275
|
+
100_000.times { @parser.parse(input).should == expected }
|
276
|
+
end
|
268
277
|
end
|
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.5"
|
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-23 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -53,7 +53,9 @@ files:
|
|
53
53
|
- spec/ul_spec.rb
|
54
54
|
- spec/wikitext_spec.rb
|
55
55
|
- ext/extconf.rb
|
56
|
+
- ext/ary.c
|
56
57
|
- ext/parser.c
|
58
|
+
- ext/str.c
|
57
59
|
- ext/token.c
|
58
60
|
- ext/wikitext.c
|
59
61
|
- ext/wikitext_ragel.c
|
@@ -64,6 +66,8 @@ files:
|
|
64
66
|
- ext/wikitext.h
|
65
67
|
- ext/wikitext_ragel.h
|
66
68
|
- ext/depend
|
69
|
+
- lib/wikitext/rails.rb
|
70
|
+
- lib/wikitext/string.rb
|
67
71
|
has_rdoc: true
|
68
72
|
homepage: http://wikitext.rubyforge.org/
|
69
73
|
post_install_message:
|
@@ -71,6 +75,7 @@ rdoc_options: []
|
|
71
75
|
|
72
76
|
require_paths:
|
73
77
|
- ext
|
78
|
+
- lib
|
74
79
|
required_ruby_version: !ruby/object:Gem::Requirement
|
75
80
|
requirements:
|
76
81
|
- - ">="
|