teius 0.0.2-mswin32 → 0.1.0-mswin32

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/Makefile ADDED
@@ -0,0 +1,138 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = .
7
+ topdir = d:/msys/local/lib/ruby/1.8/i386-mingw32
8
+ hdrdir = $(topdir)
9
+ VPATH = $(srcdir);$(topdir);$(hdrdir)
10
+
11
+ DESTDIR = d:
12
+ prefix = $(DESTDIR)/msys/local
13
+ exec_prefix = $(DESTDIR)/msys/local
14
+ sitedir = $(prefix)/lib/ruby/site_ruby
15
+ rubylibdir = $(libdir)/ruby/$(ruby_version)
16
+ archdir = $(rubylibdir)/$(arch)
17
+ sbindir = $(exec_prefix)/sbin
18
+ datadir = $(prefix)/share
19
+ includedir = $(prefix)/include
20
+ infodir = $(prefix)/info
21
+ sysconfdir = $(prefix)/etc
22
+ mandir = $(prefix)/man
23
+ libdir = $(DESTDIR)/msys/local/lib
24
+ sharedstatedir = $(prefix)/com
25
+ oldincludedir = $(DESTDIR)/usr/include
26
+ sitearchdir = $(sitelibdir)/$(sitearch)
27
+ bindir = $(exec_prefix)/bin
28
+ localstatedir = $(prefix)/var
29
+ sitelibdir = $(sitedir)/$(ruby_version)
30
+ libexecdir = $(exec_prefix)/libexec
31
+
32
+ CC = gcc
33
+ LIBRUBY = lib$(LIBRUBY_SO).a
34
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
35
+ LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
36
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
37
+
38
+ CFLAGS = -g -O2
39
+ CPPFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) -Id:/msys/local/include/libxml2
40
+ CXXFLAGS = $(CFLAGS)
41
+ DLDFLAGS = -Wl,--enable-auto-import,--export-all
42
+ LDSHARED = gcc -shared -s
43
+ AR = ar
44
+ EXEEXT = .exe
45
+
46
+ RUBY_INSTALL_NAME = ruby
47
+ RUBY_SO_NAME = msvcrt-ruby18
48
+ arch = i386-mingw32
49
+ sitearch = i386-msvcrt
50
+ ruby_version = 1.8
51
+ ruby = d:/msys/local/bin/ruby
52
+ RUBY = $(ruby)
53
+ RM = rm -f
54
+ MAKEDIRS = mkdir -p
55
+ INSTALL = /bin/install -c
56
+ INSTALL_PROG = $(INSTALL) -m 0755
57
+ INSTALL_DATA = $(INSTALL) -m 644
58
+ COPY = cp
59
+
60
+ #### End of system configuration section. ####
61
+
62
+ preload =
63
+
64
+ libpath = d:/msys/local/lib $(libdir)
65
+ LIBPATH = -L"d:/msys/local/lib" -L"$(libdir)"
66
+ DEFFILE =
67
+
68
+ CLEANFILES =
69
+ DISTCLEANFILES =
70
+
71
+ extout =
72
+ extout_prefix =
73
+ target_prefix =
74
+ LOCAL_LIBS =
75
+ LIBS = $(LIBRUBYARG_SHARED) -lxml2 -lwsock32
76
+ SRCS = teius.c
77
+ OBJS = teius.o
78
+ TARGET = teius
79
+ DLLIB = $(TARGET).so
80
+ STATIC_LIB =
81
+
82
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
83
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
84
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
85
+
86
+ TARGET_SO = $(DLLIB)
87
+ CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
88
+ CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
89
+
90
+ all: $(DLLIB)
91
+ static: $(STATIC_LIB)
92
+
93
+ clean:
94
+ @-$(RM) $(CLEANLIBS:/=\) $(CLEANOBJS:/=\) $(CLEANFILES:/=\)
95
+
96
+ distclean: clean
97
+ @-$(RM) Makefile extconf.h conftest.* mkmf.log
98
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES:/=\)
99
+
100
+ realclean: distclean
101
+ install: install-so install-rb
102
+
103
+ install-so: $(RUBYARCHDIR)
104
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
105
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
106
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
107
+ install-rb: pre-install-rb install-rb-default
108
+ install-rb-default: pre-install-rb-default
109
+ pre-install-rb: Makefile
110
+ pre-install-rb-default: Makefile
111
+ $(RUBYARCHDIR):
112
+ $(MAKEDIRS) $@
113
+
114
+ site-install: site-install-so site-install-rb
115
+ site-install-so: install-so
116
+ site-install-rb: install-rb
117
+
118
+ .SUFFIXES: .c .m .cc .cxx .cpp .o
119
+
120
+ .cc.o:
121
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
122
+
123
+ .cxx.o:
124
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
125
+
126
+ .cpp.o:
127
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
128
+
129
+ .c.o:
130
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
131
+
132
+ $(DLLIB): $(OBJS)
133
+ @-$(RM) $@
134
+ $(LDSHARED) $(DLDFLAGS) $(LIBPATH) -o $@ $(OBJS) $(LOCAL_LIBS) $(LIBS)
135
+
136
+
137
+
138
+ $(OBJS): ruby.h defines.h
data/ext/teius.c CHANGED
@@ -6,12 +6,14 @@
6
6
 
7
7
  static VALUE cParseError;
8
8
  static VALUE cXpathError;
9
- static VALUE cElementNotFound;
9
+ static VALUE cNodeNotFound;
10
+ static VALUE cNodeNotUnique;
10
11
  static VALUE cNode;
11
12
  static VALUE cDocument;
12
13
  static ID sRequired;
13
14
  static ID sFirst;
14
15
  static ID sAll;
16
+ static ID sUnique;
15
17
 
16
18
  static void doc_free(void *p) {
17
19
  xmlFreeDoc(p);
@@ -62,24 +64,24 @@ static VALUE node_find(int argc, VALUE *argv, VALUE self) {
62
64
  rb_scan_args(argc, argv, "21", &rType, &rXpath, &rOptions);
63
65
  int required = 0;
64
66
  if (argc == 3) {
65
- VALUE rRequired = rb_hash_aref(rOptions, sRequired);
66
- required = rRequired != Qnil;
67
+ VALUE rRequired = rb_hash_aref(rOptions, ID2SYM(sRequired));
68
+ required = rRequired != Qnil && rRequired != Qfalse;
67
69
  }
68
70
 
69
71
  xmlNodePtr node = NULL;
70
72
  Data_Get_Struct(self, xmlNode, node);
71
73
  xmlDocPtr doc = node->doc;
72
74
 
73
- xmlXPathContextPtr context;
74
- xmlXPathObjectPtr result;
75
+ xmlXPathContextPtr context;
76
+ xmlXPathObjectPtr result;
75
77
 
76
- context = xmlXPathNewContext(doc);
78
+ context = xmlXPathNewContext(doc);
77
79
  context->node = node;
78
80
 
79
81
  char *xpath = StringValuePtr(rXpath);
80
82
  result = xmlXPathEvalExpression(xpath, context);
81
83
  if (result == NULL) {
82
- xmlErrorPtr err = xmlGetLastError();
84
+ xmlErrorPtr err = xmlGetLastError();
83
85
  xmlXPathFreeContext(context);
84
86
  rb_raise(cXpathError, "Couldn't evaluate xpath [%s]: %s",
85
87
  xpath, err->message);
@@ -88,19 +90,24 @@ static VALUE node_find(int argc, VALUE *argv, VALUE self) {
88
90
  xmlNodeSetPtr node_set = result->nodesetval;
89
91
  int size = node_set != NULL ? node_set->nodeNr : 0;
90
92
 
93
+ ID type = SYM2ID(rType);
91
94
  if (size == 0 && required) {
92
95
  xmlXPathFreeObject(result);
93
96
  xmlXPathFreeContext(context);
94
- rb_raise(cElementNotFound, "No such element in %s: %s", node->name, xpath);
97
+ rb_raise(cNodeNotFound, "No such node in %s: %s", node->name, xpath);
98
+ } else if (size > 1 && type == sUnique) {
99
+ xmlXPathFreeObject(result);
100
+ xmlXPathFreeContext(context);
101
+ rb_raise(cNodeNotUnique, "node at path %s from %s is not unique",
102
+ xpath, node->name);
95
103
  }
96
104
 
97
105
  VALUE rResult;
98
- ID type = SYM2ID(rType);
99
- if (type == sFirst) { /* Just return first node */
106
+ if (type == sFirst || type == sUnique) { /* Just return first node */
100
107
  if (size == 0) {
101
108
  rResult = Qnil;
102
109
  } else {
103
- rResult = Data_Wrap_Struct(cNode, 0, 0, node_set->nodeTab[0]);
110
+ rResult = Data_Wrap_Struct(cNode, 0, 0, node_set->nodeTab[0]);
104
111
  }
105
112
  } else if (type == sAll) { /* Return ruby array of all nodes */
106
113
  int i;
@@ -108,15 +115,15 @@ static VALUE node_find(int argc, VALUE *argv, VALUE self) {
108
115
  for (i=0; i < size; i++) {
109
116
  xmlNodePtr cur_node = node_set->nodeTab[i];
110
117
 
111
- /* Create LibxmlElement and store it in arr */
118
+ /* Create Node and store it in arr */
112
119
  VALUE rNode = Data_Wrap_Struct(cNode, 0, 0, cur_node);
113
120
  rb_ary_store(arr, i, rNode);
114
121
  }
115
- rResult = arr;
122
+ rResult = arr;
116
123
  } else {
117
124
  xmlXPathFreeObject(result);
118
125
  xmlXPathFreeContext(context);
119
- rb_raise(rb_eArgError, "Unknown type: :%s (should be :first or :all)",
126
+ rb_raise(rb_eArgError, "Unknown type: :%s (should be :first, :unique or :all)",
120
127
  rb_id2name(type));
121
128
  }
122
129
 
@@ -132,18 +139,56 @@ static VALUE node_name(VALUE self) {
132
139
  return rb_str_new2(node->name);
133
140
  }
134
141
 
142
+ static VALUE node_xpath(VALUE self) {
143
+ xmlNodePtr node = NULL;
144
+ Data_Get_Struct(self, xmlNode, node);
145
+ return rb_str_new2(xmlGetNodePath(node));
146
+ }
147
+
148
+ static VALUE node_pointer(VALUE self) {
149
+ xmlNodePtr node = NULL;
150
+ Data_Get_Struct(self, xmlNode, node);
151
+ return INT2NUM((int)node);
152
+ }
153
+
135
154
  static VALUE parse_file(VALUE self, VALUE rFilename) {
136
- xmlDocPtr doc = xmlReadFile(StringValuePtr(rFilename), NULL, 0);
155
+ xmlDocPtr doc = xmlReadFile(StringValuePtr(rFilename), NULL, 0);
137
156
  if (doc == NULL) {
138
- xmlErrorPtr err = xmlGetLastError();
139
- rb_raise(cParseError, "could not parse file %s: %s",
140
- StringValuePtr(rFilename), err->message);
157
+ xmlErrorPtr err = xmlGetLastError();
158
+ rb_raise(cParseError, "could not parse file %s: %s",
159
+ StringValuePtr(rFilename), err->message);
141
160
  }
142
161
 
143
- /* Load new document */
144
- VALUE rDoc = Data_Wrap_Struct(cDocument, 0, doc_free, doc);
162
+ /* Load new document */
163
+ VALUE rDoc = Data_Wrap_Struct(cDocument, 0, doc_free, doc);
145
164
 
146
- return rDoc;
165
+ return rDoc;
166
+ }
167
+
168
+ static VALUE parse_string(VALUE self, VALUE rDocString) {
169
+ xmlDocPtr doc = xmlReadDoc(StringValuePtr(rDocString), NULL, NULL, 0);
170
+ if (doc == NULL) {
171
+ xmlErrorPtr err = xmlGetLastError();
172
+ rb_raise(cParseError, "could not parse string: %s", err->message);
173
+ }
174
+
175
+ /* Load new document */
176
+ VALUE rDoc = Data_Wrap_Struct(cDocument, 0, doc_free, doc);
177
+
178
+ return rDoc;
179
+ }
180
+
181
+ static VALUE document_to_s(VALUE self, VALUE rDocString) {
182
+ xmlDocPtr doc = NULL;
183
+ xmlChar *mem;
184
+ int size;
185
+
186
+ Data_Get_Struct(self, xmlDoc, doc);
187
+ xmlDocDumpMemory(doc, &mem, &size);
188
+ VALUE rStr = rb_str_new2(mem);
189
+ xmlFree(mem);
190
+
191
+ return rStr;
147
192
  }
148
193
 
149
194
  void Init_teius() {
@@ -153,25 +198,32 @@ void Init_teius() {
153
198
  sRequired = rb_intern("required");
154
199
  sFirst = rb_intern("first");
155
200
  sAll = rb_intern("all");
201
+ sUnique = rb_intern("unique");
156
202
 
157
203
  /* Modules */
158
204
  VALUE mTeius = rb_define_module("Teius");
159
205
 
160
206
  /* Exceptions */
161
- cParseError = rb_define_class_under(mTeius, "ParseError", rb_eStandardError);
162
- cXpathError = rb_define_class_under(mTeius, "XpathError", rb_eStandardError);
163
- cElementNotFound = rb_define_class_under(mTeius,
164
- "ElementNotFound", rb_eStandardError);
165
-
166
- /* LibxmlElement */
167
- cNode = rb_define_class_under(mTeius, "Node", rb_cObject);
168
- rb_define_method(cNode, "value", node_value, 0);
169
- rb_define_method(cNode, "document", node_document, 0);
170
- rb_define_method(cNode, "attributes", node_attributes, 0);
171
- rb_define_method(cNode, "find", node_find, -1);
172
- rb_define_method(cNode, "name", node_name, 0);
173
-
174
- /* LibxmlDocument */
207
+ cParseError = rb_define_class_under(mTeius, "ParseError", rb_eStandardError);
208
+ cXpathError = rb_define_class_under(mTeius, "XpathError", rb_eStandardError);
209
+ cNodeNotFound = rb_define_class_under(mTeius,
210
+ "NodeNotFound", rb_eStandardError);
211
+ cNodeNotUnique = rb_define_class_under(mTeius,
212
+ "NodeNotUnique", rb_eStandardError);
213
+
214
+ /* Node */
215
+ cNode = rb_define_class_under(mTeius, "Node", rb_cObject);
216
+ rb_define_method(cNode, "value", node_value, 0);
217
+ rb_define_method(cNode, "document", node_document, 0);
218
+ rb_define_method(cNode, "attributes", node_attributes, 0);
219
+ rb_define_method(cNode, "find", node_find, -1);
220
+ rb_define_method(cNode, "name", node_name, 0);
221
+ rb_define_method(cNode, "xpath", node_xpath, 0);
222
+ rb_define_method(cNode, "pointer", node_pointer, 0);
223
+
224
+ /* Document */
175
225
  cDocument = rb_define_class_under(mTeius, "Document", cNode);
176
- rb_define_singleton_method(cDocument, "parse_file", parse_file, 1);
226
+ rb_define_singleton_method(cDocument, "parse_file", parse_file, 1);
227
+ rb_define_singleton_method(cDocument, "parse_string", parse_string, 1);
228
+ rb_define_method(cNode, "to_s", document_to_s, 0);
177
229
  }
data/ext/teius.o ADDED
Binary file
data/ext/teius.so ADDED
Binary file
data/lib/teius.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'teius.so'
2
+
3
+ module Teius
4
+ class Node
5
+ def fetch(xpath)
6
+ node = find(:unique, xpath, :required => true)
7
+ return node ? node.value : nil
8
+ end
9
+
10
+ def ==(other)
11
+ self.pointer == other.pointer
12
+ end
13
+
14
+ def eql?(other)
15
+ self.pointer == other.pointer
16
+ end
17
+
18
+ def hash
19
+ self.pointer
20
+ end
21
+
22
+ def parent
23
+ self.find :first, '..'
24
+ end
25
+
26
+ def siblings
27
+ self.find :all, 'preceding-sibling::*|following-sibling::*'
28
+ end
29
+
30
+ def children
31
+ self.find :all, 'child::*'
32
+ end
33
+
34
+ end
35
+ end
data/lib/teius.so ADDED
Binary file
data/test/teius_test.rb CHANGED
@@ -1,6 +1,4 @@
1
- $:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'lib')
2
- require 'rubygems'
3
- # need require_gem?
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
2
  require 'test/unit'
5
3
  require 'teius'
6
4
 
@@ -80,5 +78,61 @@ class TeiusTest < Test::Unit::TestCase
80
78
  assert_equal 'en-US', atts['language']
81
79
  assert_equal 8, atts.length
82
80
  end
81
+
82
+ def test_unique_find
83
+ el = @doc.find :unique, '/sports-content/sports-metadata/sports-title'
84
+ assert_equal 'Score Update: Chicago vs. Green Bay (Final)', el.value
85
+ assert_raise(NodeNotUnique) { @doc.find :unique, '//sports-content-code' }
86
+ assert_nil @doc.find(:unique, '/bogus')
87
+ assert_raise(NodeNotFound) { @doc.find :unique, '/bogus', { :required => true } }
88
+ end
89
+
90
+ def test_fetch
91
+ assert_equal 'Score Update: Chicago vs. Green Bay (Final)',
92
+ @doc.fetch('/sports-content/sports-metadata/sports-title')
93
+ end
83
94
 
95
+ def test_equality
96
+ n1 = @doc.find :first, '//team[1]'
97
+ assert_not_nil n1
98
+ n2 = @doc.find :first, '/sports-content/sports-event/team[1]'
99
+ assert_not_nil n2
100
+ assert_equal n1, n2
101
+ end
102
+
103
+ def test_hash
104
+ n1 = @doc.find :first, '//team[1]'
105
+ assert_not_nil n1
106
+ n2 = @doc.find :first, '/sports-content/sports-event/team[1]'
107
+ assert n1.eql?(n2)
108
+ hash = Hash.new
109
+ hash[n1] = 'test'
110
+ assert_equal 'test', hash[n2]
111
+ end
112
+
113
+ def test_parse_string
114
+ doc = Document.parse_string '<library><book /></library>'
115
+ book = doc.find :first, '//book'
116
+ assert_not_nil book
117
+ end
118
+
119
+ def test_xpath
120
+ n1 = @doc.find :first, '//team[1]'
121
+ n2 = @doc.find :first, '/sports-content/sports-event/team[1]'
122
+ assert_equal '/sports-content/sports-event/team[1]', n1.xpath
123
+ assert_equal n1, n2
124
+ end
125
+
126
+ def test_to_s
127
+ txt = @doc.to_s
128
+ assert_match /<\?xml version=/, txt
129
+ assert_match /Chicago 3 for 11 yards/, txt
130
+ end
131
+
132
+ def test_siblings
133
+ e = @doc.find :first, '//sports-content-code[5]'
134
+ sibs = e.siblings
135
+ assert_equal 9, sibs.size
136
+ end
137
+
84
138
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: teius
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.2
7
- date: 2006-03-06 00:00:00 +02:00
6
+ version: 0.1.0
7
+ date: 2006-05-05 00:00:00 +02:00
8
8
  summary: Light-weight Ruby API to LibXML.
9
9
  require_paths:
10
10
  - dll
@@ -29,7 +29,12 @@ authors:
29
29
  - Joshua Harvey
30
30
  files:
31
31
  - ext/extconf.rb
32
+ - ext/Makefile
32
33
  - ext/teius.c
34
+ - ext/teius.o
35
+ - ext/teius.so
36
+ - lib/teius.rb
37
+ - lib/teius.so
33
38
  - test/teius_test.rb
34
39
  - xml/xt.3608774-update-mid-event.xml
35
40
  - xml/xt.3608787-update-post-event.xml