ruby-xslt 0.9.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/AUTHORS +23 -0
- data/COPYING +340 -0
- data/ChangeLog +64 -0
- data/README +137 -0
- data/debug/memwatch.c +2664 -0
- data/debug/memwatch.h +707 -0
- data/examples/commentary.dtd +34 -0
- data/examples/functions.xsl +51 -0
- data/examples/fuzface.rb +13 -0
- data/examples/fuzface.xml +154 -0
- data/examples/fuzface.xsl +4 -0
- data/examples/fuzface_REXML.rb +11 -0
- data/examples/fuzface_XML-Simple.rb +12 -0
- data/examples/fuzface_data.rb +13 -0
- data/examples/fuzface_error.rb +86 -0
- data/examples/fuzface_to_s.rb +9 -0
- data/examples/info.rb +19 -0
- data/examples/ramblings.xsl +46 -0
- data/examples/test.xml +5 -0
- data/examples/test.xsl +18 -0
- data/examples/test_functions.rb +18 -0
- data/examples/test_parameters.rb +13 -0
- data/extconf.rb +114 -0
- data/extfunc.c +216 -0
- data/extfunc.h +26 -0
- data/parameters.c +59 -0
- data/parameters.h +20 -0
- data/parser.c +228 -0
- data/parser.h +30 -0
- data/rb_utils.c +30 -0
- data/rb_utils.h +34 -0
- data/ruby-xslt.gemspec +19 -0
- data/tests/t.xml +2 -0
- data/tests/t.xsl +6 -0
- data/tests/test.rb +125 -0
- data/xslt.c +619 -0
- data/xslt.h +98 -0
- metadata +98 -0
data/examples/test.xml
ADDED
data/examples/test.xsl
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
3
|
+
<xsl:output method="text" encoding="iso-8859-1" indent="no"/>
|
4
|
+
<xsl:param name="p1"/>
|
5
|
+
<xsl:param name="p2"/>
|
6
|
+
|
7
|
+
<xsl:template match="/">
|
8
|
+
p1:<xsl:value-of select="$p1"/>
|
9
|
+
p2:<xsl:value-of select="$p2"/>
|
10
|
+
<xsl:apply-templates/>
|
11
|
+
</xsl:template>
|
12
|
+
|
13
|
+
<xsl:template match="node">
|
14
|
+
<xsl:value-of select="."/>(<xsl:value-of select="@number"/>)
|
15
|
+
</xsl:template>
|
16
|
+
|
17
|
+
</xsl:stylesheet>
|
18
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "../xslt"
|
2
|
+
|
3
|
+
class XML::XSLT
|
4
|
+
def round_trip( arg )
|
5
|
+
arg
|
6
|
+
end
|
7
|
+
def type( arg )
|
8
|
+
arg.class.to_s
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
xslt = XML::XSLT.new()
|
13
|
+
xslt.xsl = "functions.xsl"
|
14
|
+
xslt.xml = "test.xml"
|
15
|
+
XML::XSLT.extFunction("round-trip", "http://test.none", xslt)
|
16
|
+
XML::XSLT.extFunction("type", "http://test.none", xslt)
|
17
|
+
|
18
|
+
puts xslt.serve
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "../xslt"
|
2
|
+
|
3
|
+
xslt = XML::XSLT.new()
|
4
|
+
xslt.xsl = "test.xsl"
|
5
|
+
xslt.xml = "test.xml"
|
6
|
+
xslt.parameters = { "p1" => "the first parameter ...",
|
7
|
+
"p2" => "'and the second one!'" }
|
8
|
+
#xslt.save("test.html")
|
9
|
+
puts xslt.serve
|
10
|
+
xslt.parameters = { "p1" => "Ruby...",
|
11
|
+
"p2" => "'...is cool !'" }
|
12
|
+
#xslt.save("test.html")
|
13
|
+
puts xslt.serve
|
data/extconf.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# See the LICENSE file for copyright and distribution information
|
3
|
+
|
4
|
+
require "mkmf"
|
5
|
+
|
6
|
+
def help
|
7
|
+
print <<HELP
|
8
|
+
"extconf.rb" configures this package to adapt to many kinds of systems.
|
9
|
+
|
10
|
+
Usage: ruby extconf.rb [OPTION]...
|
11
|
+
|
12
|
+
Configuration:
|
13
|
+
--help display this help and exit
|
14
|
+
|
15
|
+
--with-xslt-lib=PATH
|
16
|
+
--with-xslt-include=PATH
|
17
|
+
--with-xslt-dir=PATH specify the directory name for the libxslt include
|
18
|
+
files and/or library
|
19
|
+
|
20
|
+
--enable-error-handler enables a VERY crude error handler. Error messages
|
21
|
+
are appended to the class variable XML::XSLT and can
|
22
|
+
be accessed with the class method XML::XSLT.errors
|
23
|
+
(will change in a future version)
|
24
|
+
--disable-exslt disables libexslt support <http://exslt.org/>
|
25
|
+
|
26
|
+
--enable-debug compile with memwatch
|
27
|
+
<http://www.linkdata.se/sourcecode.html>
|
28
|
+
|
29
|
+
HELP
|
30
|
+
end
|
31
|
+
|
32
|
+
if ARGV.include?( "--help" )
|
33
|
+
help()
|
34
|
+
exit 0
|
35
|
+
end
|
36
|
+
|
37
|
+
if enable_config("debug", false)
|
38
|
+
File.symlink( "debug/memwatch.h", "memwatch.h" ) if( ! File.exist?("memwatch.h") )
|
39
|
+
File.symlink( "debug/memwatch.c", "memwatch.c" ) if( ! File.exist?("memwatch.c") )
|
40
|
+
$CFLAGS += " -DMEMWATCH -D__DEBUG__"
|
41
|
+
end
|
42
|
+
|
43
|
+
if enable_config("error-handler", false)
|
44
|
+
$CFLAGS += " -DUSE_ERROR_HANDLER"
|
45
|
+
end
|
46
|
+
|
47
|
+
$LIBPATH.push(Config::CONFIG['libdir'])
|
48
|
+
|
49
|
+
def crash(str)
|
50
|
+
printf(" extconf failure: %s\n", str)
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
|
54
|
+
#unless have_library("z", "inflate")
|
55
|
+
# crash("need zlib")
|
56
|
+
#else
|
57
|
+
# $defs.push('-DHAVE_ZLIB_H')
|
58
|
+
#end
|
59
|
+
|
60
|
+
if dir_config( "xslt" ) != [nil, nil]
|
61
|
+
inc, lib = dir_config( 'xslt' )
|
62
|
+
$LDFLAGS << " -L#{lib} -lxslt -lxml2 -lz -lpthread -liconv -lm"
|
63
|
+
$CFLAGS << " -I#{inc}"
|
64
|
+
elsif ex = find_executable( "xslt-config" )
|
65
|
+
$LDFLAGS << ' ' + `#{ex} --libs`.chomp
|
66
|
+
$CFLAGS << ' ' + `#{ex} --cflags`.chomp
|
67
|
+
else
|
68
|
+
crash(<<EOL)
|
69
|
+
need libxslt.
|
70
|
+
|
71
|
+
Install the library or try one of the following options to extconf.rb:
|
72
|
+
|
73
|
+
--with-xslt-lib=/path/to/libxslt/lib
|
74
|
+
--with-xslt-include=/path/to/libxslt/include
|
75
|
+
EOL
|
76
|
+
end
|
77
|
+
|
78
|
+
if enable_config("exslt", true)
|
79
|
+
$LDFLAGS << " -lexslt"
|
80
|
+
$CFLAGS += " -DUSE_EXSLT"
|
81
|
+
end
|
82
|
+
|
83
|
+
$CFLAGS = '-g -Wall ' + $CFLAGS
|
84
|
+
|
85
|
+
puts "compile with : "
|
86
|
+
puts " CFLAGS = #{$CFLAGS}"
|
87
|
+
puts " LDFLAGS = #{$LDFLAGS}"
|
88
|
+
puts
|
89
|
+
|
90
|
+
create_header()
|
91
|
+
create_makefile("xml/xslt")
|
92
|
+
|
93
|
+
###### Modify Makefile: #######
|
94
|
+
File.rename( "Makefile", "Makefile.orig" )
|
95
|
+
oldmkfl = File.open( "Makefile.orig" )
|
96
|
+
newmkfl = File.open( "Makefile", "w" )
|
97
|
+
oldmkfl.each_line{ |line|
|
98
|
+
case(line)
|
99
|
+
when /^all:/
|
100
|
+
newmkfl.puts(line)
|
101
|
+
newmkfl.puts("")
|
102
|
+
newmkfl.puts("test: all") # insert the "test" target
|
103
|
+
newmkfl.puts("\t\t@cd tests && ruby test.rb && cd ..")
|
104
|
+
newmkfl.puts("doc: all") # insert the "doc" target
|
105
|
+
newmkfl.puts("\t\t@rdoc -S -t \"Ruby/XSLT Documentation\" README AUTHORS ChangeLog xslt.c")
|
106
|
+
when /^distclean:/
|
107
|
+
newmkfl.puts(line)
|
108
|
+
newmkfl.puts("\t\t@-$(RM) memwatch.h memwatch.c Makefile.orig")
|
109
|
+
newmkfl.puts("\t\t@-$(RM)r doc")
|
110
|
+
else
|
111
|
+
newmkfl.puts(line)
|
112
|
+
end
|
113
|
+
}
|
114
|
+
newmkfl.close
|
data/extfunc.c
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (C) 2005 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
3
|
+
*
|
4
|
+
* This program is free software; you can redistribute it and/or modify
|
5
|
+
* it under the terms of the GNU General Public License as published by
|
6
|
+
* the Free Software Foundation; either version 2 of the License, or
|
7
|
+
* (at your option) any later version.
|
8
|
+
*
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
* GNU General Public License for more details.
|
13
|
+
*
|
14
|
+
* You should have received a copy of the GNU General Public License
|
15
|
+
* along with this program; if not, write to the Free Software
|
16
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "xslt.h"
|
20
|
+
|
21
|
+
extern VALUE mXML;
|
22
|
+
extern VALUE cXSLT;
|
23
|
+
|
24
|
+
/**
|
25
|
+
* external function support, patch from :
|
26
|
+
*
|
27
|
+
* Brendan Taylor
|
28
|
+
* whateley@gmail.com
|
29
|
+
*
|
30
|
+
*/
|
31
|
+
|
32
|
+
|
33
|
+
/* converts an xmlXPathObjectPtr to a Ruby VALUE
|
34
|
+
* number -> float
|
35
|
+
* boolean -> boolean
|
36
|
+
* string -> string
|
37
|
+
* nodeset -> an array of REXML::Elements
|
38
|
+
*/
|
39
|
+
VALUE xpathObj2value(xmlXPathObjectPtr obj, xmlDocPtr doc)
|
40
|
+
{
|
41
|
+
VALUE ret = Qnil;
|
42
|
+
|
43
|
+
if (obj == NULL) {
|
44
|
+
return ret;
|
45
|
+
}
|
46
|
+
|
47
|
+
switch (obj->type) {
|
48
|
+
case XPATH_NODESET:
|
49
|
+
rb_require("rexml/document");
|
50
|
+
ret = rb_ary_new();
|
51
|
+
|
52
|
+
if ((obj->nodesetval != NULL) && (obj->nodesetval->nodeNr != 0)) {
|
53
|
+
xmlBufferPtr buff = xmlBufferCreate();
|
54
|
+
xmlNodePtr node;
|
55
|
+
int i;
|
56
|
+
|
57
|
+
// this assumes all the nodes are elements, which is a bad idea
|
58
|
+
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
59
|
+
node = obj->nodesetval->nodeTab[i];
|
60
|
+
|
61
|
+
if( node->type == XML_ELEMENT_NODE ) {
|
62
|
+
xmlNodeDump(buff, doc, node, 0, 0);
|
63
|
+
|
64
|
+
VALUE cREXML = rb_const_get(rb_cObject, rb_intern("REXML"));
|
65
|
+
VALUE cDocument = rb_const_get(cREXML, rb_intern("Document"));
|
66
|
+
VALUE rDocument = rb_funcall(cDocument, rb_intern("new"), 1,rb_str_new2((char *)buff->content));
|
67
|
+
VALUE rElement = rb_funcall(rDocument, rb_intern("root"), 0);
|
68
|
+
|
69
|
+
rb_ary_push(ret, rElement);
|
70
|
+
|
71
|
+
// empty the buffer (xmlNodeDump appends rather than replaces)
|
72
|
+
xmlBufferEmpty(buff);
|
73
|
+
} else if ( node->type == XML_TEXT_NODE ) {
|
74
|
+
rb_ary_push(ret, rb_str_new2((char *)node->content));
|
75
|
+
}
|
76
|
+
}
|
77
|
+
xmlBufferFree(buff);
|
78
|
+
}
|
79
|
+
break;
|
80
|
+
case XPATH_BOOLEAN:
|
81
|
+
ret = obj->boolval ? Qtrue : Qfalse;
|
82
|
+
break;
|
83
|
+
case XPATH_NUMBER:
|
84
|
+
ret = rb_float_new(obj->floatval);
|
85
|
+
break;
|
86
|
+
case XPATH_STRING:
|
87
|
+
ret = rb_str_new2((char *) obj->stringval);
|
88
|
+
break;
|
89
|
+
/* these cases were in libxslt's python bindings, but i don't know what they are, so i'll leave them alone */
|
90
|
+
case XPATH_XSLT_TREE:
|
91
|
+
case XPATH_POINT:
|
92
|
+
case XPATH_RANGE:
|
93
|
+
case XPATH_LOCATIONSET:
|
94
|
+
default:
|
95
|
+
rb_warning("xpathObj2value: can't convert XPath object type %d to Ruby object\n", obj->type );
|
96
|
+
}
|
97
|
+
xmlXPathFreeObject(obj);
|
98
|
+
return ret;
|
99
|
+
}
|
100
|
+
|
101
|
+
/*
|
102
|
+
* converts a Ruby VALUE to an xmlXPathObjectPtr
|
103
|
+
* boolean -> boolean
|
104
|
+
* number -> number
|
105
|
+
* string -> escaped string
|
106
|
+
* array -> array of parsed nodes
|
107
|
+
*/
|
108
|
+
xmlXPathObjectPtr value2xpathObj (VALUE val) {
|
109
|
+
xmlXPathObjectPtr ret = NULL;
|
110
|
+
|
111
|
+
switch (TYPE(val)) {
|
112
|
+
case T_TRUE:
|
113
|
+
case T_FALSE:
|
114
|
+
ret = xmlXPathNewBoolean(RTEST(val));
|
115
|
+
break;
|
116
|
+
case T_FIXNUM:
|
117
|
+
case T_FLOAT:
|
118
|
+
ret = xmlXPathNewFloat(NUM2DBL(val));
|
119
|
+
break;
|
120
|
+
case T_STRING:
|
121
|
+
{
|
122
|
+
xmlChar *str;
|
123
|
+
|
124
|
+
// we need the Strdup (this is the major bugfix for 0.8.1)
|
125
|
+
str = xmlStrdup((const xmlChar *) STR2CSTR(val));
|
126
|
+
ret = xmlXPathWrapString(str);
|
127
|
+
}
|
128
|
+
break;
|
129
|
+
case T_NIL:
|
130
|
+
ret = xmlXPathNewNodeSet(NULL);
|
131
|
+
break;
|
132
|
+
case T_ARRAY: {
|
133
|
+
int i,j;
|
134
|
+
ret = xmlXPathNewNodeSet(NULL);
|
135
|
+
|
136
|
+
for(i = RARRAY(val)->len; i > 0; i--) {
|
137
|
+
xmlXPathObjectPtr obj = value2xpathObj( rb_ary_shift( val ) );
|
138
|
+
if ((obj->nodesetval != NULL) && (obj->nodesetval->nodeNr != 0)) {
|
139
|
+
for(j = 0; j < obj->nodesetval->nodeNr; j++) {
|
140
|
+
xmlXPathNodeSetAdd( ret->nodesetval, obj->nodesetval->nodeTab[j] );
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
break; }
|
145
|
+
case T_DATA:
|
146
|
+
case T_OBJECT: {
|
147
|
+
if( strcmp( getRubyObjectName( val ), "REXML::Document" ) == 0 || strcmp(getRubyObjectName( val ), "REXML::Element") == 0 ) {
|
148
|
+
|
149
|
+
VALUE to_s = rb_funcall( val, rb_intern( "to_s" ), 0 );
|
150
|
+
xmlDocPtr doc = xmlParseDoc((xmlChar *) STR2CSTR(to_s));
|
151
|
+
|
152
|
+
ret = xmlXPathNewNodeSet((xmlNode *)doc->children);
|
153
|
+
break;
|
154
|
+
} else if( strcmp( getRubyObjectName( val ), "REXML::Text" ) == 0 ) {
|
155
|
+
VALUE to_s = rb_funcall( val, rb_intern( "to_s" ), 0 );
|
156
|
+
|
157
|
+
xmlChar *str;
|
158
|
+
|
159
|
+
str = xmlStrdup((const xmlChar *) STR2CSTR(to_s));
|
160
|
+
ret = xmlXPathWrapString(str);
|
161
|
+
break;
|
162
|
+
}
|
163
|
+
// this drops through so i can reuse the error message
|
164
|
+
}
|
165
|
+
default:
|
166
|
+
rb_warning( "value2xpathObj: can't convert class %s to XPath object\n", getRubyObjectName(val));
|
167
|
+
return NULL;
|
168
|
+
}
|
169
|
+
|
170
|
+
return ret;
|
171
|
+
}
|
172
|
+
|
173
|
+
/*
|
174
|
+
* chooses what registered function to call and calls it
|
175
|
+
*/
|
176
|
+
void xmlXPathFuncCallback( xmlXPathParserContextPtr ctxt, int nargs) {
|
177
|
+
VALUE result, arguments[nargs];
|
178
|
+
VALUE ns_hash, func_hash, object;
|
179
|
+
const xmlChar *namespace;
|
180
|
+
char *rb_func, *chr;
|
181
|
+
xmlXPathObjectPtr obj;
|
182
|
+
int i;
|
183
|
+
|
184
|
+
if (ctxt == NULL || ctxt->context == NULL)
|
185
|
+
return;
|
186
|
+
|
187
|
+
rb_func = strdup((char *)ctxt->context->function);
|
188
|
+
namespace = ctxt->context->functionURI;
|
189
|
+
|
190
|
+
ns_hash = rb_cvar_get(cXSLT, rb_intern("@@extFunctions"));
|
191
|
+
|
192
|
+
func_hash = rb_hash_aref(ns_hash, rb_str_new2((char *)namespace));
|
193
|
+
|
194
|
+
if(func_hash == Qnil) {
|
195
|
+
rb_warning( "xmlXPathFuncCallback: namespace %s not found!\n", namespace );
|
196
|
+
}
|
197
|
+
|
198
|
+
object = rb_hash_aref(func_hash, rb_str_new2((char *)rb_func));
|
199
|
+
|
200
|
+
for (i = nargs - 1; i >= 0; i--) {
|
201
|
+
obj = valuePop(ctxt);
|
202
|
+
arguments[i] = xpathObj2value(obj, ctxt->context->doc);
|
203
|
+
}
|
204
|
+
|
205
|
+
/* -s are common in XSLT function names, but illegal for Ruby method names */
|
206
|
+
while( (chr = strchr(rb_func, '-')) != NULL ) {
|
207
|
+
chr[0] = '_'; /* so we pretend the - was a _ all along */
|
208
|
+
}
|
209
|
+
|
210
|
+
result = rb_funcall2( object, rb_intern(rb_func), nargs, arguments);
|
211
|
+
|
212
|
+
free( rb_func );
|
213
|
+
|
214
|
+
obj = value2xpathObj(result);
|
215
|
+
valuePush(ctxt, obj);
|
216
|
+
}
|
data/extfunc.h
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (C) 2005 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
3
|
+
*
|
4
|
+
* This program is free software; you can redistribute it and/or modify
|
5
|
+
* it under the terms of the GNU General Public License as published by
|
6
|
+
* the Free Software Foundation; either version 2 of the License, or
|
7
|
+
* (at your option) any later version.
|
8
|
+
*
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
* GNU General Public License for more details.
|
13
|
+
*
|
14
|
+
* You should have received a copy of the GNU General Public License
|
15
|
+
* along with this program; if not, write to the Free Software
|
16
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "xslt.h"
|
20
|
+
|
21
|
+
#include <libxml/xpathInternals.h>
|
22
|
+
#include <libxslt/extensions.h>
|
23
|
+
|
24
|
+
VALUE xpathObj2value( xmlXPathObjectPtr, xmlDocPtr );
|
25
|
+
xmlXPathObjectPtr value2xpathObj( VALUE );
|
26
|
+
void xmlXPathFuncCallback( xmlXPathParserContextPtr, int );
|
data/parameters.c
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (C) 2005 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
3
|
+
*
|
4
|
+
* This program is free software; you can redistribute it and/or modify
|
5
|
+
* it under the terms of the GNU General Public License as published by
|
6
|
+
* the Free Software Foundation; either version 2 of the License, or
|
7
|
+
* (at your option) any later version.
|
8
|
+
*
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
* GNU General Public License for more details.
|
13
|
+
*
|
14
|
+
* You should have received a copy of the GNU General Public License
|
15
|
+
* along with this program; if not, write to the Free Software
|
16
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "xslt.h"
|
20
|
+
|
21
|
+
/**
|
22
|
+
* parameters support, patch from :
|
23
|
+
*
|
24
|
+
* Eust�quio "TaQ" Rangel
|
25
|
+
* eustaquiorangel@yahoo.com
|
26
|
+
* http://beam.to/taq
|
27
|
+
*
|
28
|
+
*/
|
29
|
+
VALUE each_pair( VALUE obj ) {
|
30
|
+
return rb_funcall( obj, rb_intern("each"), 0, 0 );
|
31
|
+
}
|
32
|
+
|
33
|
+
VALUE process_pair( VALUE pair, VALUE rbparams ) {
|
34
|
+
VALUE key, value;
|
35
|
+
// Thx to alex__
|
36
|
+
int count = FIX2INT( rb_funcall( rbparams, rb_intern("size"), 0, 0 ) );
|
37
|
+
// static int count = 0;
|
38
|
+
char *xValue = NULL;
|
39
|
+
|
40
|
+
Check_Type( pair, T_ARRAY );
|
41
|
+
|
42
|
+
key = RARRAY(pair)->ptr[0];
|
43
|
+
value = RARRAY(pair)->ptr[1];
|
44
|
+
|
45
|
+
Check_Type( key, T_STRING );
|
46
|
+
Check_Type( value, T_STRING );
|
47
|
+
|
48
|
+
xValue = STR2CSTR( value );
|
49
|
+
if( xValue[0] != '\'' && xValue[strlen( xValue ) - 1] != '\'' ) {
|
50
|
+
value = rb_str_concat( value, rb_str_new2( "'" ) );
|
51
|
+
value = rb_str_concat( rb_str_new2( "'" ), value );
|
52
|
+
}
|
53
|
+
|
54
|
+
rb_ary_store( rbparams, count, key );
|
55
|
+
rb_ary_store( rbparams, count + 1, value );
|
56
|
+
|
57
|
+
count += 2;
|
58
|
+
return Qnil;
|
59
|
+
}
|