[Pkg-javascript-commits] [node-expat] 88/371: Imported Upstream version 1.4.0

Jonas Smedegaard dr at jones.dk
Sun Feb 28 09:59:48 UTC 2016


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository node-expat.

commit f87253d94ef569eb9746e7d6737ba83faca2453b
Author: Jonas Smedegaard <dr at jones.dk>
Date:   Sun Aug 21 11:00:42 2011 +0200

    Imported Upstream version 1.4.0
---
 .gitignore        |   4 +
 bench.js          |   2 +-
 install.sh        |   4 -
 lib/node-expat.js |  38 +++++++
 node-expat.cc     |  81 +++++++++++----
 package.json      |  12 ++-
 test.js           | 305 +++++++++++++++++++++++++++++++-----------------------
 wscript           |   7 ++
 8 files changed, 291 insertions(+), 162 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5c68e8c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.lock-wscript
+node_modules
+build
+*.swp
diff --git a/bench.js b/bench.js
index 4db66f0..ce282a1 100644
--- a/bench.js
+++ b/bench.js
@@ -1,7 +1,7 @@
 var sys = require('sys');
 var node_xml = require("node-xml");
 var libxml = require("libxmljs");
-var expat = require('./build/default/node-expat');
+var expat = require('./lib/node-expat');
 
 function NodeXmlParser() {
     var parser = new node_xml.SaxParser(function(cb) { });
diff --git a/install.sh b/install.sh
deleted file mode 100755
index 8c8a895..0000000
--- a/install.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-node-waf configure
-node-waf build
diff --git a/lib/node-expat.js b/lib/node-expat.js
new file mode 100644
index 0000000..cd7f91a
--- /dev/null
+++ b/lib/node-expat.js
@@ -0,0 +1,38 @@
+var EventEmitter = require('events').EventEmitter;
+var util = require('util');
+var expat = require('../build/default/node-expat');
+
+/**
+ * Simple wrapper because EventEmitter has turned pure-JS as of node
+ * 0.5.x.
+ */
+exports.Parser = function(encoding) {
+    this.parser = new expat.Parser(encoding);
+
+    var that = this;
+    this.parser.emit = function() {
+	that.emit.apply(that, arguments);
+    };
+};
+util.inherits(exports.Parser, EventEmitter);
+
+exports.Parser.prototype.parse = function(buf, isFinal) {
+    return this.parser.parse(buf, isFinal);
+};
+
+exports.Parser.prototype.setEncoding = function(encoding) {
+    return this.parser.setEncoding(encoding);
+};
+
+exports.Parser.prototype.getError = function() {
+    return this.parser.getError();
+};
+exports.Parser.prototype.stop = function() {
+    return this.parser.stop();
+};
+exports.Parser.prototype.pause = function() {
+    return this.stop();
+};
+exports.Parser.prototype.resume = function() {
+    return this.parser.resume();
+};
diff --git a/node-expat.cc b/node-expat.cc
index 9917043..6243f07 100644
--- a/node-expat.cc
+++ b/node-expat.cc
@@ -1,6 +1,6 @@
 #include <node.h>
 #include <node_version.h>
-#include <node_events.h>
+#include <node_object_wrap.h>
 #include <node_buffer.h>
 extern "C" {
 #include <expat.h>
@@ -12,16 +12,16 @@ using namespace node;
 static Persistent<String> sym_startElement, sym_endElement,
   sym_startCdata, sym_endCdata,
   sym_text, sym_processingInstruction,
-  sym_comment, sym_xmlDecl;
+  sym_comment, sym_xmlDecl, sym_entityDecl,
+  sym_emit;
 
-class Parser : public EventEmitter {
+class Parser : public ObjectWrap {
 public:
   static void Initialize(Handle<Object> target)
   {
     HandleScope scope;
     Local<FunctionTemplate> t = FunctionTemplate::New(New);
 
-    t->Inherit(EventEmitter::constructor_template);
     t->InstanceTemplate()->SetInternalFieldCount(1);
 
     NODE_SET_PROTOTYPE_METHOD(t, "parse", Parse);
@@ -40,6 +40,8 @@ public:
     sym_processingInstruction = NODE_PSYMBOL("processingInstruction");
     sym_comment = NODE_PSYMBOL("comment");
     sym_xmlDecl = NODE_PSYMBOL("xmlDecl");
+    sym_entityDecl = NODE_PSYMBOL("entityDecl");
+    sym_emit = NODE_PSYMBOL("emit");
   }
 
 protected:
@@ -63,7 +65,7 @@ protected:
   }
 
   Parser(const XML_Char *encoding)
-    : EventEmitter()
+    : ObjectWrap()
   {
     parser = XML_ParserCreate(encoding);
     assert(parser != NULL);
@@ -75,6 +77,7 @@ protected:
     XML_SetProcessingInstructionHandler(parser, ProcessingInstruction);
     XML_SetCommentHandler(parser, Comment);
     XML_SetXmlDeclHandler(parser, XmlDecl);
+    XML_SetEntityDeclHandler(parser, EntityDecl);
   }
 
   ~Parser()
@@ -131,6 +134,9 @@ protected:
   bool parseString(String &str, int isFinal)
   {
     int len = str.Utf8Length();
+    if (len == 0)
+      return true;
+
     void *buf = XML_GetBuffer(parser, len);
     assert(buf != NULL);
     assert(str.WriteUtf8(static_cast<char *>(buf), len) == len);
@@ -254,8 +260,10 @@ private:
       attr->Set(String::New(atts1[0]), String::New(atts1[1]));
 
     /* Trigger event */
-    Handle<Value> argv[2] = { String::New(name), attr };
-    parser->Emit(sym_startElement, 2, argv);
+    Handle<Value> argv[3] = { sym_startElement,
+                              String::New(name),
+                              attr };
+    parser->Emit(3, argv);
   }
 
   static void EndElement(void *userData,
@@ -264,8 +272,8 @@ private:
     Parser *parser = reinterpret_cast<Parser *>(userData);
 
     /* Trigger event */
-    Handle<Value> argv[1] = { String::New(name) };
-    parser->Emit(sym_endElement, 1, argv);
+    Handle<Value> argv[2] = { sym_endElement, String::New(name) };
+    parser->Emit(2, argv);
   }
   
   static void StartCdata(void *userData)
@@ -273,8 +281,8 @@ private:
     Parser *parser = reinterpret_cast<Parser *>(userData);
 
     /* Trigger event */
-    Handle<Value> argv[0] = {};
-    parser->Emit(sym_startCdata, 0, argv);
+    Handle<Value> argv[1] = { sym_startCdata };
+    parser->Emit(1, argv);
   }
 
   static void EndCdata(void *userData)
@@ -282,8 +290,8 @@ private:
     Parser *parser = reinterpret_cast<Parser *>(userData);
 
     /* Trigger event */
-    Handle<Value> argv[0] = {};
-    parser->Emit(sym_endCdata, 0, argv);
+    Handle<Value> argv[1] = { sym_endCdata };
+    parser->Emit(1, argv);
   }
 
   static void Text(void *userData,
@@ -292,8 +300,9 @@ private:
     Parser *parser = reinterpret_cast<Parser *>(userData);
 
     /* Trigger event */
-    Handle<Value> argv[1] = { String::New(s, len) };
-    parser->Emit(sym_text, 1, argv);
+    Handle<Value> argv[2] = { sym_text,
+                              String::New(s, len) };
+    parser->Emit(2, argv);
   }
 
   static void ProcessingInstruction(void *userData,
@@ -302,8 +311,10 @@ private:
     Parser *parser = reinterpret_cast<Parser *>(userData);
 
     /* Trigger event */
-    Handle<Value> argv[2] = { String::New(target), String::New(data) };
-    parser->Emit(sym_processingInstruction, 2, argv);
+    Handle<Value> argv[3] = { sym_processingInstruction,
+                              String::New(target),
+                              String::New(data) };
+    parser->Emit(3, argv);
   }
 
   static void Comment(void *userData,
@@ -312,8 +323,8 @@ private:
     Parser *parser = reinterpret_cast<Parser *>(userData);
 
     /* Trigger event */
-    Handle<Value> argv[1] = { String::New(data) };
-    parser->Emit(sym_comment, 1, argv);
+    Handle<Value> argv[2] = { sym_comment, String::New(data) };
+    parser->Emit(2, argv);
   }
 
   static void XmlDecl(void *userData,
@@ -323,10 +334,38 @@ private:
     Parser *parser = reinterpret_cast<Parser *>(userData);
 
     /* Trigger event */
-    Handle<Value> argv[3] = { version ? String::New(version) : Null(),
+    Handle<Value> argv[4] = { sym_xmlDecl,
+                              version ? String::New(version) : Null(),
                               encoding ? String::New(encoding) : Null(),
                               Boolean::New(standalone) };
-    parser->Emit(sym_xmlDecl, 3, argv);
+    parser->Emit(4, argv);
+  }
+
+  static void EntityDecl(void *userData, const XML_Char *entityName, int is_parameter_entity,
+                         const XML_Char *value, int value_length, const XML_Char *base,
+                         const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName)
+  {
+    Parser *parser = reinterpret_cast<Parser *>(userData);
+
+    /* Trigger event */
+    Handle<Value> argv[8] = { sym_entityDecl,
+                              entityName ? String::New(entityName) : Null(),
+                              Boolean::New(is_parameter_entity),
+                              value ? String::New(value) : Null(),
+                              base ? String::New(base) : Null(),
+                              systemId ? String::New(systemId) : Null(),
+                              publicId ? String::New(publicId) : Null(),
+                              notationName ? String::New(notationName) : Null(),
+    };
+    parser->Emit(8, argv);
+  }
+
+  void Emit(int argc, Handle<Value> argv[])
+  {
+    HandleScope scope;
+
+    Local<Function> emit = Local<Function>::Cast(handle_->Get(sym_emit));
+    emit->Call(handle_, argc, argv);
   }
 };
 
diff --git a/package.json b/package.json
index 6122ae1..605f4aa 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,13 @@
 { "name": "node-expat"
-,"version": "1.3.0"
-,"main": "./build/default/node-expat"
+,"version": "1.4.0"
+,"main": "./lib/node-expat"
 ,"description": "NodeJS binding for fast XML parsing."
-,"scripts" : { "install" : "./install.sh" }
+,"scripts" : { "install": "node-waf configure build"
+	      ,"update": "node-waf build"
+	      ,"test": "node test.js"
+	     }
 ,"dependencies": []
+,"devDependencies": ["vows"]
 ,"repositories": [{ "type": "git"
 		   ,"path": "git://github.com/astro/node-expat.git"
 		  }]
@@ -13,7 +17,7 @@
 		  ,"email": "astro at spaceboyz.net"
 		  ,"web": "http://spaceboyz.net/~astro/"
 		 }]
-,"contributors": ["Stephan Maka", "Derek Hammer", "Iein Valdez", "Peter Körner"]
+,"contributors": ["Stephan Maka", "Derek Hammer", "Iein Valdez", "Peter Körner", "Camilo Aguilar"]
 ,"licenses": [{ "type": "MIT" }]
 ,"engine": "node"
 }
diff --git a/test.js b/test.js
index 8148ab1..d1dfe7f 100644
--- a/test.js
+++ b/test.js
@@ -1,6 +1,8 @@
 var sys = require('sys');
-var expat = require('./build/default/node-expat');
+var expat = require('./lib/node-expat');
 var Buffer = require('buffer').Buffer;
+var vows = require('vows');
+var assert = require('assert');
 
 function collapseTexts(evs) {
     var r = [];
@@ -20,11 +22,8 @@ function collapseTexts(evs) {
     return r;
 }
 
-var tests = 0, iterations = 0, fails = 0;
 function expect(s, evs_expected) {
-    tests++;
     for(var step = s.length; step > 0; step--) {
-	iterations++;
 	var evs_received = [];
 	var p = new expat.Parser("UTF-8");
 	//p.setEncoding("UTF-8");
@@ -52,6 +51,9 @@ function expect(s, evs_expected) {
 	p.addListener('endCdata', function() {
 	    evs_received.push(['endCdata']);
 	});
+	p.addListener('entityDecl', function(entityName, isParameterEntity, value, base, systemId, publicId, notationName) {
+	    evs_received.push(['entityDecl', entityName, isParameterEntity, value, base, systemId, publicId, notationName]);
+	});
 	for(var l = 0; l < s.length; l += step)
 	{
 	    var end = l + step;
@@ -64,21 +66,117 @@ function expect(s, evs_expected) {
 
 	var expected = JSON.stringify(evs_expected);
 	var received = JSON.stringify(collapseTexts(evs_received));
-	if (expected != received) {
-	    fails++;
-	    sys.puts("Fail for: " + s + " (step=" + step + ")");
-	    sys.puts("Expected: " + expected);
-	    sys.puts("Received: " + received);
-	    return;  // don't try with smaller step size
-	}
+	assert.equal(received, expected);
     }
 }
 
-function testStopResume(cb)
-{
-	var p = new expat.Parser("UTF-8");
-	
-	var input = '\
+vows.describe('node-expat').addBatch({
+    'single element': {
+	'simple': function() {
+	    expect("<r/>",
+		[['startElement', 'r', {}],
+		['endElement', 'r']]);
+	},
+	'single element with attribute': function() {
+	    expect("<r foo='bar'/>",
+		[['startElement', 'r', {foo: 'bar'}],
+		['endElement', 'r']]);
+	},
+	'single elemeht with differently quoted attributes': function() {
+	    expect("<r foo='bar' baz=\"quux\" test=\"tset\"/>",
+		[['startElement', 'r', {foo: 'bar', baz: 'quux', test: 'tset'}],
+		['endElement', 'r']]);
+	},
+	'single element with namespaces': function() {
+	    expect("<r xmlns='http://localhost/' xmlns:x=\"http://example.com/\"></r>",
+		[['startElement', 'r', {xmlns: 'http://localhost/', 'xmlns:x': 'http://example.com/'}],
+		['endElement', 'r']]);
+	},
+	'single element with text content': function() {
+	    expect("<r>foo</r>",
+		[['startElement', 'r', {}],
+		['text', "foo"],
+		['endElement', 'r']]);
+	},
+	'single element with text content and line break': function() {
+	    expect("<r>foo\nbar</r>",
+		[['startElement', 'r', {}],
+		['text', "foo\nbar"],
+		['endElement', 'r']]);
+	},
+	'single element with CDATA content': function() {
+	    expect("<r><![CDATA[<greeting>Hello, world!</greeting>]]></r>",
+		[['startElement', 'r', {}],
+		['startCdata'],
+		['text', "<greeting>Hello, world!</greeting>"],
+		['endCdata'],
+		['endElement', 'r']]);
+	},
+	'single element with entity text': function() {
+	    expect("<r>foo&bar</r>",
+		[['startElement', 'r', {}],
+		['text', "foo&bar"],
+		['endElement', 'r']]);
+	},
+	'single element with umlaut text': function() {
+	    expect("<r>ß</r>",
+		[['startElement', 'r', {}],
+		['text', "ß"],
+		['endElement', 'r']]);
+	},
+	'from buffer': function() {
+	    expect(new Buffer('<foo>bar</foo>'),
+		[['startElement', 'foo', {}],
+		['text', 'bar'],
+		['endElement', 'foo']]);
+	}
+    },
+    'entity declaration': {
+	'a billion laughs': function() {
+	    expect('<!DOCTYPE b [<!ELEMENT b (#PCDATA)>' +
+		   '<!ENTITY l0 "ha"><!ENTITY l1 "&l0;&l0;"><!ENTITY l2 "&l1;&l1;">' +
+		   ']><b>&l2;</b>',
+		   [["entityDecl","l0",false,"ha",null,null,null,null],
+		   ["entityDecl","l1",false,"&l0;&l0;",null,null,null,null],
+		   ["entityDecl","l2",false,"&l1;&l1;",null,null,null,null],
+		   ["startElement","b",{}],["text","hahahaha"],["endElement","b"]]);
+	}
+    },
+    'processing instruction': {
+	'with parameters': function() {
+	    expect("<?i like xml?>",
+		[['processingInstruction', 'i', 'like xml']]);
+	},
+	'simple': function() {
+	    expect("<?dragons?>",
+		[['processingInstruction', 'dragons', '']]);
+	},
+	'XML declaration with encoding': function() {
+	    expect("<?xml version='1.0' encoding='UTF-8'?>",
+		[['xmlDecl', '1.0', 'UTF-8', true]]);
+	},
+	'XML declaration': function() {
+	    expect("<?xml version='1.0'?>",
+		[['xmlDecl', '1.0', null, true]]);
+	}
+    },
+    'comment': {
+	'simple': function() {
+	    expect("<!-- no comment -->",
+		[['comment', ' no comment ']]);
+	}
+    },
+    'error': {
+	'tag name starting with ampersand': function() {
+	    expect("<&", [['error']]);
+	}
+    },
+    'stop and resume': {
+	topic: function() {
+	    var cb = this.callback;
+	    var p = new expat.Parser("UTF-8");
+
+	    var input = '\
 		<wrap> \
 			<short /> \
 			<short></short> \
@@ -86,128 +184,71 @@ function testStopResume(cb)
 			<short /> \
 			<long>foo</long> \
 		</wrap>';
-	
-	var expected = ['wrap', 'short', 'short', 'long', 'short', 'long'];
-	var received = [];
-	
-	var tolerance = 10/100;
-	var expectedRuntime = 1000;
-	var start = new Date();
-	
-	p.addListener('startElement', function(name, attrs) {
+
+	    var expected = ['wrap', 'short', 'short', 'long', 'short', 'long'];
+	    var received = [];
+
+	    var tolerance = 10/100;
+	    var expectedRuntime = 1000;
+	    var start = new Date();
+
+	    p.addListener('startElement', function(name, attrs) {
 		received.push(name);
-		
+
 		// suspend parser for 1/2 second
 		if(name == 'long') {
-			p.stop();
-			
-			setTimeout(function() {
-				p.resume();
-			}, 500);
+		    p.stop();
+
+		    setTimeout(function() {
+			p.resume();
+		    }, 500);
 		}
-	})
-	
-	p.addListener('endElement', function(name) {
+	    });
+
+	    p.addListener('endElement', function(name) {
 		// finished parsing
 		if(name == 'wrap') {
-			// test elements received (count. naming, order)
-			if(JSON.stringify(expected) != JSON.stringify(received)) {
-				sys.puts("Failed Stop/Resume test");
-				sys.puts("Expected: " + expected);
-				sys.puts("Received: " + received);
-				return cb(false);
-			}
-			
-			// test timing (+-5%)
-			var now = new Date();
-			var diff = now.getTime() - start.getTime();
-			var max = expectedRuntime + expectedRuntime * tolerance, 
-				min = expectedRuntime - expectedRuntime * tolerance;
-			
-			if(diff > max) {
-				sys.puts("Failed Stop/Resume test");
-				sys.puts("Expected Runtime < " + max);
-				sys.puts("Taken Runtime: " + diff);
-				return cb(false);
-			}
-			
-			if(diff < min) {
-				sys.puts("Failed Stop/Resume test");
-				sys.puts("Expected Runtime > " + min);
-				sys.puts("Taken Runtime: " + diff);
-				return cb(false);
-			}
-			
-			return cb(true);
+		    // test elements received (count. naming, order)
+		    assert.equal(JSON.stringify(received), JSON.stringify(expected));
+
+		    // test timing (+-5%)
+		    var now = new Date();
+		    var diff = now.getTime() - start.getTime();
+		    var max = expectedRuntime + expectedRuntime * tolerance,
+			min = expectedRuntime - expectedRuntime * tolerance;
+
+		    assert.ok(diff < max, 'Runtime within maximum expected time');
+		    assert.ok(diff > min, 'Runtime at least minimum expected time');
+
+		    return cb(true);
 		}
-	});
-	
-	if(!p.parse(input)) {
-		sys.puts("Failed Stop/Resume test: parse returned error: "+p.getError());
-		return cb(false);
-	}
-}
+	    });
 
-expect("<r/>",
-       [['startElement', 'r', {}],
-	['endElement', 'r']]);
-expect("<r foo='bar'/>",
-       [['startElement', 'r', {foo: 'bar'}],
-	['endElement', 'r']]);
-expect("<r foo='bar' baz=\"quux\" test=\"tset\"/>",
-       [['startElement', 'r', {foo: 'bar', baz: 'quux', test: 'tset'}],
-	['endElement', 'r']]);
-expect("<r xmlns='http://localhost/' xmlns:x=\"http://example.com/\"></r>",
-       [['startElement', 'r', {xmlns: 'http://localhost/', 'xmlns:x': 'http://example.com/'}],
-	['endElement', 'r']]);
-expect("<r>foo</r>",
-       [['startElement', 'r', {}],
-	['text', "foo"],
-	['endElement', 'r']]);
-expect("<r>foo\nbar</r>",
-       [['startElement', 'r', {}],
-	['text', "foo\nbar"],
-	['endElement', 'r']]);
-expect("<r><![CDATA[<greeting>Hello, world!</greeting>]]></r>",
-       [['startElement', 'r', {}],
-	['startCdata'],
-	['text', "<greeting>Hello, world!</greeting>"],
-	['endCdata'],
-	['endElement', 'r']]);
-expect("<r>foo&bar</r>",
-       [['startElement', 'r', {}],
-	['text', "foo&bar"],
-	['endElement', 'r']]);
-expect("<r>ß</r>",
-       [['startElement', 'r', {}],
-	['text', "ß"],
-	['endElement', 'r']]);
-expect("<?i like xml?>",
-       [['processingInstruction', 'i', 'like xml']]);
-expect("<?dragons?>",
-       [['processingInstruction', 'dragons', '']]);
-expect("<!-- no comment -->",
-       [['comment', ' no comment ']]);
-expect("<&", [['error']]);
-expect("<?xml version='1.0' encoding='UTF-8'?>",
-       [['xmlDecl', '1.0', 'UTF-8', true]]);
-expect("<?xml version='1.0'?>",
-       [['xmlDecl', '1.0', null, true]]);
-expect(new Buffer('<foo>bar</foo>'),
-       [['startElement', 'foo', {}],
-	['text', 'bar'],
-	['endElement', 'foo']]);
-expect(new Buffer('<foo><![CDATA[bar]]></foo>'),
-       [['startElement', 'foo', {}],
-	['startCdata'],
-	['text', 'bar'],
-	['endCdata'],
-	['endElement', 'foo']]);
-
-sys.puts("Ran "+tests+" tests with "+iterations+" iterations: "+fails+" failures.");
-
-sys.puts("Starting Stop/Resume Test (wait for result...)");
-testStopResume(function(success) {
-	sys.puts("Stop/Resume Test "+(success ? 'succeeded' : 'failed'));
-});
+	    assert.ok(p.parse(input));
+	},
+	'should have worked': function() {
+	    assert.ok(true, 'start & stop works');
+	}
+    },
+    'corner cases': {
+	'parse empty string': function() {
+	    var p = new expat.Parser("UTF-8");
+	    p.parse('');
+	    assert.ok(true, "Did not segfault");
+	}, 
+ 	
+	'parsing twice the same document with the same parser instance should be fine': 'reset() not yet implemented'
+	/*function() {
+	   var p = new expat.Parser("UTF-8");
+           var xml = "<foo>bar</foo>";
+           var result = p.parse(xml);
+           assert.ok(result);
+           assert.isNull(p.getError());
 
+           var result2 = p.parse(xml);
+           assert.isNull(p.getError());
+           assert.ok(result2);
+            
+        }*/
+    }
+}).run();
diff --git a/wscript b/wscript
index ff67c1e..66922b9 100644
--- a/wscript
+++ b/wscript
@@ -8,9 +8,16 @@ def set_options(opt):
 def configure(conf):
   conf.check_tool('compiler_cxx')
   conf.check_tool('node_addon')
+  conf.check( header_name='expat.h', 
+              mandatory = True,
+	          errmsg = "not installed")
+	
+  conf.env['LIB_EXPAT'] = ['expat']
+
 
 def build(bld):
   obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
   obj.target = 'node-expat'
   obj.source = 'node-expat.cc'
   obj.lib = 'expat'
+  obj.uselib = 'EXPAT'

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-expat.git



More information about the Pkg-javascript-commits mailing list