fast_xs 0.2

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/CHANGELOG ADDED
@@ -0,0 +1,8 @@
1
+ = 0.2
2
+ === 6th December, 2007
3
+ * First real release
4
+ * added fast_xs_html and fast_xs_cgi methods
5
+
6
+ = 0.1
7
+ === 3rd October, 2007
8
+ * initial implementation, not officially released
data/COPYING ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2007 Eric Wong <normalperson@yhbt.net>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,18 @@
1
+ = fast_xs, a fast C extension for cleaning XML
2
+
3
+ == Overview
4
+
5
+ The original fast_xs method is based on the xchar code by Sam Ruby:
6
+
7
+ http://intertwingly.net/stories/2005/09/28/xchar.rb
8
+ http://intertwingly.net/blog/2005/09/28/XML-Cleansing
9
+
10
+ _why also packages a slightly modified version in the latest version
11
+ of Hpricot (not-yet-released) that also escapes '"' to "&quot;" (which
12
+ is optional).
13
+
14
+ This is an exact translation (to the best of my knowledge :) of Sam's
15
+ original implementation, so it does not escape "&quot;". The version
16
+ of XML::Builder packaged with Rails also uses Sam's version, and
17
+ XML::Builder as packaged in Rails 2.0 will be automatically use
18
+ fast_xs if available.
data/Rakefile ADDED
@@ -0,0 +1,119 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/testtask'
6
+ require 'hoe'
7
+ require 'fileutils'
8
+ include FileUtils
9
+
10
+ name = "fast_xs"
11
+ rev = `git describe 2>/dev/null`.chomp rescue nil
12
+ version = ENV['VERSION'] || "0.2" + (rev && rev.length > 0 ? "-#{rev}" : "")
13
+ pkg = "#{name}-#{version}"
14
+ bin = "*.{so,o}"
15
+ archlib = "lib/#{::Config::CONFIG['arch']}"
16
+ CLEAN.include ["ext/fast_xs/#{bin}", "lib/**/#{bin}",
17
+ 'ext/fast_xs/Makefile', '**/.*.sw?', '*.gem', '.config']
18
+ rdoc_opts = ['--quiet', '--title', 'fast_xs notes', '--main', 'README',
19
+ '--inline-source']
20
+ pkg_files = %w(CHANGELOG COPYING README Rakefile) +
21
+ Dir.glob("{test,lib}/**/*.rb") +
22
+ Dir.glob("ext/**/*.{c,rb}")
23
+
24
+
25
+ spec = Gem::Specification.new do |s|
26
+ s.name = name
27
+ s.version = version
28
+ s.platform = Gem::Platform::RUBY
29
+ s.has_rdoc = true
30
+ s.rdoc_options += rdoc_opts
31
+ s.extra_rdoc_files = ["README", "CHANGELOG", "COPYING"]
32
+ s.summary = "escape faster!"
33
+ s.description = s.summary
34
+ s.author = "Eric Wong"
35
+ s.email = 'normalperson@yhbt.net'
36
+ s.homepage = 'http://bogonips.org/fast_xs/'
37
+ s.files = pkg_files
38
+ s.require_paths = [archlib, "lib"]
39
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
40
+ end
41
+
42
+ hoe = Hoe.new(name, version) do |p|
43
+ p.author = spec.author
44
+ p.description = spec.description
45
+ p.email = spec.email
46
+ p.summary = spec.summary
47
+ p.url = spec.homepage
48
+ p.rubyforge_name = 'fast-xs'
49
+ end
50
+
51
+ desc "Does a full compile, test run"
52
+ task :default => [:compile, :test]
53
+
54
+ desc "Run all the tests"
55
+ Rake::TestTask.new do |t|
56
+ t.libs << "test" << archlib
57
+ t.test_files = FileList['test/test_*.rb']
58
+ t.verbose = true
59
+ end
60
+
61
+ Rake::RDocTask.new do |rdoc|
62
+ rdoc.rdoc_dir = 'doc/rdoc'
63
+ rdoc.options += rdoc_opts
64
+ rdoc.main = "README"
65
+ rdoc.rdoc_files.add ['README', 'CHANGELOG', 'COPYING' ]
66
+ end
67
+
68
+ Rake::GemPackageTask.new(spec) do |p|
69
+ p.need_tar = true
70
+ p.gem_spec = spec
71
+ end
72
+
73
+ ['fast_xs'].each do |extension|
74
+ ext = "ext/#{extension}"
75
+ ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
76
+ ext_files = FileList[
77
+ "#{ext}/*.c",
78
+ "#{ext}/*.h",
79
+ "#{ext}/*.rl",
80
+ "#{ext}/extconf.rb",
81
+ "#{ext}/Makefile",
82
+ "lib"
83
+ ]
84
+
85
+ desc "Builds just the #{extension} extension"
86
+ task extension.to_sym => ["#{ext}/Makefile", ext_so ]
87
+
88
+ file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
89
+ Dir.chdir(ext) do ruby "extconf.rb" end
90
+ end
91
+
92
+ file ext_so => ext_files do
93
+ Dir.chdir(ext) do sh('make') end
94
+ mkdir_p archlib
95
+ chmod 0644, ext_so
96
+ cp ext_so, archlib
97
+ end
98
+ end
99
+
100
+ task "lib" do
101
+ directory "lib"
102
+ end
103
+
104
+ desc "Compiles the Ruby extension"
105
+ task :compile => [:fast_xs] do
106
+ if Dir.glob(File.join(archlib,"fast_xs.*")).empty?
107
+ STDERR.puts 'Gem failed to build'
108
+ exit(1)
109
+ end
110
+ end
111
+
112
+ task :install do
113
+ sh %{rake package}
114
+ sh %{sudo gem install pkg/#{name}-#{version}}
115
+ end
116
+
117
+ task :uninstall => [:clean] do
118
+ sh %{sudo gem uninstall #{name}}
119
+ end
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ have_header('assert.h') or exit
3
+ dir_config('fast_xs')
4
+ create_makefile('fast_xs')
@@ -0,0 +1,279 @@
1
+ #define VERSION "0.1"
2
+
3
+ #include <ruby.h>
4
+ #include <assert.h>
5
+
6
+ static ID unpack_id;
7
+ static VALUE U_fmt, C_fmt;
8
+
9
+ /* give GCC hints for better branch prediction
10
+ * (we layout branches so that ASCII characters are handled faster) */
11
+ #if defined(__GNUC__) && (__GNUC__ >= 3)
12
+ # define likely(x) __builtin_expect (!!(x), 1)
13
+ # define unlikely(x) __builtin_expect (!!(x), 0)
14
+ #else
15
+ # define unlikely(x) (x)
16
+ # define likely(x) (x)
17
+ #endif
18
+
19
+ /* pass-through certain characters for CP-1252 */
20
+ #define p(x) (x-128)
21
+
22
+ static const int cp_1252[] = {
23
+ 8364, /* 128 => 8364, euro sign */
24
+ p(129), /* 129 => 129, pass-through */
25
+ 8218, /* 130 => 8218, single low-9 quotation mark */
26
+ 402, /* 131 => 402, latin small letter f with hook */
27
+ 8222, /* 132 => 8222, double low-9 quotation mark */
28
+ 8230, /* 133 => 8230, horizontal ellipsis */
29
+ 8224, /* 134 => 8224, dagger */
30
+ 8225, /* 135 => 8225, double dagger */
31
+ 710, /* 136 => 710, modifier letter circumflex accent */
32
+ 8240, /* 137 => 8240, per mille sign */
33
+ 352, /* 138 => 352, latin capital letter s with caron */
34
+ 8249, /* 139 => 8249, single left-pointing angle quotation mark */
35
+ 338, /* 140 => 338, latin capital ligature oe */
36
+ p(141), /* 141 => 141, pass-through */
37
+ 381, /* 142 => 381, latin capital letter z with caron */
38
+ p(143), /* 143 => 143, pass-through */
39
+ p(144), /* 144 => 144, pass-through */
40
+ 8216, /* 145 => 8216, left single quotation mark */
41
+ 8217, /* 146 => 8217, right single quotation mark */
42
+ 8220, /* 147 => 8220, left double quotation mark */
43
+ 8221, /* 148 => 8221, right double quotation mark */
44
+ 8226, /* 149 => 8226, bullet */
45
+ 8211, /* 150 => 8211, en dash */
46
+ 8212, /* 151 => 8212, em dash */
47
+ 732, /* 152 => 732, small tilde */
48
+ 8482, /* 153 => 8482, trade mark sign */
49
+ 353, /* 154 => 353, latin small letter s with caron */
50
+ 8250, /* 155 => 8250, single right-pointing angle quotation mark */
51
+ 339, /* 156 => 339, latin small ligature oe */
52
+ p(157), /* 157 => 157, pass-through */
53
+ 382, /* 158 => 382, latin small letter z with caron */
54
+ 376 /* 159 => 376} latin capital letter y with diaeresis */
55
+ };
56
+
57
+ #define VALID_VALUE(n) \
58
+ (n >= 0x20 && n <= 0xD7FF) || \
59
+ (n >= 0xE000 && n <= 0xFFFD) || \
60
+ (n >= 0x10000 && n <= 0x10FFFF)
61
+
62
+ #define CP_1252_ESCAPE(n) do { \
63
+ if (n >= 128 && n <= 159) \
64
+ n = cp_1252[n - 128]; \
65
+ } while(0)
66
+
67
+ static inline size_t bytes_for(int n)
68
+ {
69
+ if (n < 1000)
70
+ return sizeof("&#999;") - 1;
71
+ if (n < 10000)
72
+ return sizeof("&#9999;") - 1;
73
+ if (n < 100000)
74
+ return sizeof("&#99999;") - 1;
75
+ if (n < 1000000)
76
+ return sizeof("&#999999;") - 1;
77
+ /* if (n < 10000000), we won't have cases above 0x10FFFF */
78
+ return sizeof("&#9999999;") - 1;
79
+ }
80
+
81
+ static size_t escape(char *buf, int n)
82
+ {
83
+
84
+ #define return_const_len(x) do { \
85
+ memcpy(buf, x, sizeof(x) - 1); \
86
+ return (sizeof(x) - 1); \
87
+ } while (0)
88
+
89
+ /* handle ASCII first */
90
+ if (likely(n < 128)) {
91
+ if (likely(n >= 0x20 || n == '\t' || n == '\n' || n == '\r')) {
92
+ if (unlikely(n == '&'))
93
+ return_const_len("&amp;");
94
+ if (unlikely(n == '<'))
95
+ return_const_len("&lt;");
96
+ if (unlikely(n == '>'))
97
+ return_const_len("&gt;");
98
+ buf[0] = (char)n;
99
+ return 1;
100
+ }
101
+
102
+ buf[0] = '*';
103
+ return 1;
104
+ }
105
+
106
+ #undef return_const_len
107
+
108
+ CP_1252_ESCAPE(n);
109
+
110
+ if (VALID_VALUE(n)) {
111
+ /* return snprintf(buf, sizeof("&#1114111;"), "&#%i;", n); */
112
+ extern const char ruby_digitmap[];
113
+ size_t rv = sizeof("&#;") - 1;
114
+ buf += bytes_for(n);
115
+ *--buf = ';';
116
+ do {
117
+ *--buf = ruby_digitmap[(int)(n % 10)];
118
+ ++rv;
119
+ } while (n /= 10);
120
+ *--buf = '#';
121
+ *--buf = '&';
122
+ return rv;
123
+ }
124
+ buf[0] = '*';
125
+ return 1;
126
+ }
127
+
128
+ static long escaped_len(int n)
129
+ {
130
+ if (likely(n < 128)) {
131
+ if (unlikely(n == '&'))
132
+ return (sizeof("&amp;") - 1);
133
+ if (unlikely(n == '>' || n == '<'))
134
+ return (sizeof("&gt;") - 1);
135
+ return 1;
136
+ }
137
+
138
+ CP_1252_ESCAPE(n);
139
+
140
+ return VALID_VALUE(n) ? bytes_for(n) : 1;
141
+ }
142
+
143
+ static VALUE unpack_utf8(VALUE self)
144
+ {
145
+ return rb_funcall(self, unpack_id, 1, U_fmt);
146
+ }
147
+
148
+ static VALUE unpack_uchar(VALUE self)
149
+ {
150
+ return rb_funcall(self, unpack_id, 1, C_fmt);
151
+ }
152
+
153
+ static VALUE fast_xs(VALUE self)
154
+ {
155
+ long i;
156
+ struct RArray *array;
157
+ char *s, *c;
158
+ size_t s_len = 0;
159
+ VALUE *tmp;
160
+
161
+ array = RARRAY(rb_rescue(unpack_utf8, self, unpack_uchar, self));
162
+
163
+ for (tmp = array->ptr, i = array->len; --i >= 0; tmp++)
164
+ s_len += escaped_len(NUM2INT(*tmp));
165
+
166
+ c = s = alloca(s_len);
167
+
168
+ for (tmp = array->ptr, i = array->len; --i >= 0; tmp++)
169
+ c += escape(c, NUM2INT(*tmp));
170
+
171
+ return rb_str_new(s, s_len);
172
+ }
173
+
174
+ /*
175
+ * This is coding agnostic, and works on each byte, so some multibyte
176
+ * character sets may not be fully supported (but UTF-8 should be).
177
+ * This is meant to be 100% compatible with the
178
+ * ERB::Util::escape_html and CGI::escapeHTML methods
179
+ */
180
+ static VALUE fast_xs_html(VALUE self)
181
+ {
182
+ struct RString *string = RSTRING(self);
183
+ long i;
184
+ char *s;
185
+ size_t new_len = 0;
186
+ char *new_str;
187
+
188
+ for (s = string->ptr, i = string->len; --i >= 0; ++s) {
189
+ if (unlikely(*s == '&'))
190
+ new_len += (sizeof("&amp;") - 1);
191
+ else if (unlikely(*s == '<' || *s == '>'))
192
+ new_len += (sizeof("&gt;") - 1);
193
+ else if (unlikely(*s == '"'))
194
+ new_len += (sizeof("&quot;") - 1);
195
+ else
196
+ new_len += 1;
197
+ }
198
+
199
+ new_str = alloca(new_len);
200
+
201
+ #define append_const(buf, x) do { \
202
+ buf = memcpy(buf, x, sizeof(x) - 1) + sizeof(x) - 1; \
203
+ } while (0)
204
+
205
+ for (s = string->ptr, i = string->len; --i >= 0; ++s) {
206
+ if (unlikely(*s == '&'))
207
+ append_const(new_str, "&amp;");
208
+ else if (unlikely(*s == '<'))
209
+ append_const(new_str, "&lt;");
210
+ else if (unlikely(*s == '>'))
211
+ append_const(new_str, "&gt;");
212
+ else if (unlikely(*s == '"'))
213
+ append_const(new_str, "&quot;");
214
+ else
215
+ *new_str++ = *s;
216
+ }
217
+
218
+ #undef append_const
219
+
220
+ return rb_str_new(new_str - new_len, new_len);
221
+ }
222
+
223
+ #define CGI_URI_OK(x) \
224
+ ((x >= 'a' && x <= 'z') || \
225
+ (x >= 'A' && x <= 'Z') || \
226
+ (x >= '0' && x <= '9') || \
227
+ (x == '.' || x == '-' || x == '_'))
228
+
229
+ /*
230
+ * Compatible with CGI::escape(), this iterates through each byte, so
231
+ * multibyte character sets may not supported (but UTF-8 should be).
232
+ */
233
+ static VALUE fast_xs_cgi(VALUE self)
234
+ {
235
+ struct RString *string = RSTRING(self);
236
+ long i;
237
+ char *s;
238
+ size_t new_len = 0;
239
+ char *new_str;
240
+
241
+ for (s = string->ptr, i = string->len; --i >= 0; ++s) {
242
+ if (likely(CGI_URI_OK(*s) || *s == ' '))
243
+ ++new_len;
244
+ else /* we'll only get <= "%FF" here */
245
+ new_len += 3;
246
+ }
247
+
248
+ new_str = alloca(new_len);
249
+
250
+ for (s = string->ptr, i = string->len; --i >= 0; ++s) {
251
+ if (likely(CGI_URI_OK(*s)))
252
+ *new_str++ = *s;
253
+ else if (*s == ' ')
254
+ *new_str++ = '+';
255
+ else {
256
+ static const char cgi_digitmap[] = "0123456789ABCDEF";
257
+ new_str[2] = cgi_digitmap[(*s % 16)];
258
+ new_str[1] = cgi_digitmap[((*s/16) % 16)];
259
+ new_str[0] = '%';
260
+ new_str += 3;
261
+ }
262
+ }
263
+ return rb_str_new(new_str - new_len, new_len);
264
+ }
265
+
266
+ void Init_fast_xs(void)
267
+ {
268
+ assert(cp_1252[159 - 128] == 376); /* just in case I skipped a line */
269
+
270
+ unpack_id = rb_intern("unpack");
271
+ U_fmt = rb_str_new("U*", 2);
272
+ C_fmt = rb_str_new("C*", 2);
273
+ rb_global_variable(&U_fmt);
274
+ rb_global_variable(&C_fmt);
275
+
276
+ rb_define_method(rb_cString, "fast_xs", fast_xs, 0);
277
+ rb_define_method(rb_cString, "fast_xs_html", fast_xs_html, 0);
278
+ rb_define_method(rb_cString, "fast_xs_cgi", fast_xs_cgi, 0);
279
+ }
@@ -0,0 +1,32 @@
1
+ require 'fast_xs'
2
+
3
+ if defined?(CGI)
4
+
5
+ class CGI
6
+
7
+ def CGI::escapeHTML(value)
8
+ value.to_s.fast_xs_html
9
+ end
10
+
11
+ def CGI::escape(value)
12
+ value.to_s.fast_xs_cgi
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ if defined?(ERB::Util)
20
+
21
+ module ERB::Util
22
+
23
+ def html_escape(value)
24
+ value.to_s.fast_xs_html
25
+ end
26
+ alias h html_escape
27
+ module_function :h
28
+ module_function :html_escape
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,35 @@
1
+ require 'test/unit'
2
+ require 'cgi'
3
+ load 'fast_xs_monkey_patcher.rb'
4
+
5
+ class TestCgiClassOverrides < Test::Unit::TestCase
6
+
7
+ def test_escape_html_predefined
8
+ assert_equal '&amp;', CGI::escapeHTML('&')
9
+ assert_equal '&quot;', CGI::escapeHTML('"')
10
+ assert_equal '&lt;', CGI::escapeHTML('<')
11
+ assert_equal '&gt;', CGI::escapeHTML('>')
12
+ end
13
+
14
+ def test_escape_html_normal
15
+ assert_equal 'hello world', CGI::escapeHTML('hello world')
16
+ assert_equal '', CGI::escapeHTML('')
17
+ end
18
+
19
+ def test_escape_html_ignore
20
+ assert_equal "\x00", CGI::escapeHTML("\x00")
21
+ assert_equal "\x0C", CGI::escapeHTML("\x0C")
22
+ assert_equal "\xEF\xBF\xBF", CGI::escapeHTML("\xEF\xBF\xBF")
23
+ end
24
+
25
+ def test_escape_cgi
26
+ assert_equal 'hello%3Dworld', CGI::escape('hello=world')
27
+ assert_equal '+', CGI::escape(' ')
28
+ assert_equal '%2B', CGI::escape('+')
29
+ assert_equal '%2C', CGI::escape(',')
30
+ assert_equal 'hello-world', CGI::escape('hello-world')
31
+ assert_equal 'H3LL0+W0RLD', CGI::escape('H3LL0 W0RLD')
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,29 @@
1
+ require 'erb'
2
+ require 'test/unit'
3
+ load 'fast_xs_monkey_patcher.rb'
4
+
5
+ class TestErbUtilModuleOverrides < Test::Unit::TestCase
6
+
7
+ include ERB::Util
8
+
9
+ def test_escape_html_predefined
10
+ assert_equal '&amp;', html_escape('&')
11
+ assert_equal '&quot;', html_escape('"')
12
+ assert_equal '&lt;', html_escape('<')
13
+ assert_equal '&gt;', html_escape('>')
14
+ end
15
+
16
+ def test_escape_html_normal
17
+ assert_equal 'hello world', html_escape('hello world')
18
+ assert_equal '', html_escape('')
19
+ end
20
+
21
+ def test_escape_html_ignore
22
+ assert_equal "\x00", html_escape("\x00")
23
+ assert_equal "\x0C", html_escape("\x0C")
24
+ assert_equal "\xEF\xBF\xBF", html_escape("\xEF\xBF\xBF")
25
+ end
26
+
27
+ end
28
+
29
+
@@ -0,0 +1,39 @@
1
+ require 'fast_xs'
2
+ require 'test/unit'
3
+
4
+ # Based on Sam's original xchar.rb tests:
5
+
6
+ class TestXmlEscaping < Test::Unit::TestCase
7
+
8
+ def test_ascii
9
+ assert_equal 'abc', 'abc'.fast_xs
10
+ end
11
+
12
+ def test_predefined
13
+ assert_equal '&amp;', '&'.fast_xs # ampersand
14
+ assert_equal '&lt;', '<'.fast_xs # left angle bracket
15
+ assert_equal '&gt;', '>'.fast_xs # right angle bracket
16
+ end
17
+
18
+ def test_invalid
19
+ assert_equal '*', "\x00".fast_xs # null
20
+ assert_equal '*', "\x0C".fast_xs # form feed
21
+ assert_equal '*', "\xEF\xBF\xBF".fast_xs # U+FFFF
22
+ end
23
+
24
+ def test_iso_8859_1
25
+ assert_equal '&#231;', "\xE7".fast_xs # small c cedilla
26
+ assert_equal '&#169;', "\xA9".fast_xs # copyright symbol
27
+ end
28
+
29
+ def test_win_1252
30
+ assert_equal '&#8217;', "\x92".fast_xs # smart quote
31
+ assert_equal '&#8364;', "\x80".fast_xs # euro
32
+ end
33
+
34
+ def test_utf8
35
+ assert_equal '&#8217;', "\xE2\x80\x99".fast_xs # right single quote
36
+ assert_equal '&#169;', "\xC2\xA9".fast_xs # copy
37
+ end
38
+
39
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4.7
3
+ specification_version: 2
4
+ name: fast_xs
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.2"
7
+ date: 2007-12-07 00:00:00 -08:00
8
+ summary: escape faster!
9
+ require_paths:
10
+ - lib/i486-linux
11
+ - lib
12
+ email: normalperson@yhbt.net
13
+ homepage: http://bogonips.org/fast_xs/
14
+ rubyforge_project:
15
+ description: escape faster!
16
+ autorequire:
17
+ default_executable:
18
+ bindir: bin
19
+ has_rdoc: true
20
+ required_ruby_version: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ required_rubygems_version: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: "0"
31
+ version:
32
+ platform: ruby
33
+ signing_key:
34
+ cert_chain: []
35
+
36
+ post_install_message:
37
+ authors:
38
+ - Eric Wong
39
+ files:
40
+ - CHANGELOG
41
+ - COPYING
42
+ - README
43
+ - Rakefile
44
+ - test/test_cgi_class_overrides.rb
45
+ - test/test_xml_escaping.rb
46
+ - test/test_erb_util_module_overrides.rb
47
+ - lib/fast_xs_monkey_patcher.rb
48
+ - ext/fast_xs/fast_xs.c
49
+ - ext/fast_xs/extconf.rb
50
+ test_files: []
51
+
52
+ rdoc_options:
53
+ - --quiet
54
+ - --title
55
+ - fast_xs notes
56
+ - --main
57
+ - README
58
+ - --inline-source
59
+ extra_rdoc_files:
60
+ - README
61
+ - CHANGELOG
62
+ - COPYING
63
+ executables: []
64
+
65
+ extensions:
66
+ - ext/fast_xs/extconf.rb
67
+ requirements: []
68
+
69
+ dependencies: []
70
+