From b9f66bd3ad6d6784effc981e574175c83a4509e7 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Fri, 20 May 2011 13:59:25 +0100
Subject: [PATCH] Version 2011-05-20 14:59

---
 src/mio.py           |  2 --
 src/mio/exception.py |  9 +++++++
 src/mio/filecache.py |  7 +++++-
 src/mio/parser.py    | 57 +++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/src/mio.py b/src/mio.py
index bd65dbc..a64ac6a 100755
--- a/src/mio.py
+++ b/src/mio.py
@@ -39,8 +39,6 @@ def parse(url, repository):
 
     repository.add(tree._group_)
 
-
-
 def find_and_parse(target, builder, url=None):
     path = list(options.path)
     if url:
diff --git a/src/mio/exception.py b/src/mio/exception.py
index 8c25ee8..d676435 100755
--- a/src/mio/exception.py
+++ b/src/mio/exception.py
@@ -1,5 +1,6 @@
 import traceback
 import sys
+import urllib2
 
 def declaration(decl):
     try:
@@ -102,6 +103,14 @@ class NonLocalPath(Exception):
         
     def __str__(self):
         return "Non local path %s" % self.path
+
+class HTTPError(urllib2.HTTPError):
+    def __init__(self, url, reason):
+        self.url = url
+        self.reason = reason
+        
+    def __str__(self):
+        return "Failure on %s (%s)" % (self.url, self.reason)
         
 def Report(err, decl, action=None):
     traceback.print_exc()
diff --git a/src/mio/filecache.py b/src/mio/filecache.py
index 8838d48..5fec2ed 100755
--- a/src/mio/filecache.py
+++ b/src/mio/filecache.py
@@ -71,8 +71,13 @@ def loadfile(path):
         file = getfile(name)
         if file:
             cache[name] = file
+            pass
         else:
-            u = urllib2.urlopen(name)
+            try:
+                u = urllib2.urlopen(name)
+                pass
+            except urllib2.HTTPError, e:
+                raise mio.exception.HTTPError(name, e)
             f = createfile()
             f.write(u.read())
             u.close()
diff --git a/src/mio/parser.py b/src/mio/parser.py
index be97647..b71d07d 100755
--- a/src/mio/parser.py
+++ b/src/mio/parser.py
@@ -4,6 +4,8 @@ import sys
 import time
 import xml.sax
 import traceback
+import urlparse
+import urllib2
 
 __doc__ = """
 Package for xml parsing
@@ -424,30 +426,68 @@ class Node:
     def __repr__(self):
         return self._xml()
 
+class Comment:
+    def __init__(self, content, line=None):
+        self._content = content
+        self._line = line
+        self._parent = None
+
+    def __copy__(self):
+        """Copy self"""
+        result = Comment(self._content, self._line)
+        return result
+    
+    def __deepcopy__(self, memo):
+        """Copy node and all children"""
+        return self.__copy__()
+    
+    def _xml(self, indent=0, attr_sort=None, tag_sort=None, width=80):
+        """Generate a prettyprinted xml of the tree rooted in this node"""
+        result = "%s<!--" % ("  " * indent)
+        result += self._attribute['']
+        result += "-->\n"
+        return result
+
+    def __repr__(self):
+        return self._xml()
 
 class Parser(xml.sax.ContentHandler):
-    def __init__(self, url):
+    def __init__(self, url, include_comments=False):
         """Parse the given url inti .tree
 
         augment the tree with
           ._mtime == url modification time if url is a file, 0 otherwise
           ._url   == the url that was parsed
         """
+        self.include_comments = include_comments
         self.tree = None
         
         # Create a xml parser
-        parser = xml.sax.make_parser()
+        import xml.parsers.expat
+        self.parser = xml.parsers.expat.ParserCreate()
+        self.parser.StartElementHandler = self.startElement
+        self.parser.EndElementHandler = self.endElement
+        self.parser.CharacterDataHandler = self.characters
+        self.parser.CommentHandler = self.comment
+        """parser = xml.sax.make_parser()
         parser.setFeature(xml.sax.handler.feature_namespaces, 0)
         parser.setContentHandler(self)
         try:
             parser.setFeature(xml.sax.handler.feature_external_ges, 0)
         except:
             pass
+        """
 
         # Parse the url
         self.current = [ self ]
-        parser.parse(url)
-
+        (scheme, host, path, param, query, frag) = urlparse.urlparse(url)
+        if not scheme:
+            self.parser.Parse(open(url).read())
+            pass
+        else:
+            self.parser.Parse(urllib2.urlopen(url).read())
+            pass
+      
         # Set the mtime
         mtime = 0
         try:
@@ -469,7 +509,7 @@ class Parser(xml.sax.ContentHandler):
     # SAX parser callbacks
     #
     def startElement(self, tag, attrs):
-        child = Node(tag, self._locator.getLineNumber())
+        child = Node(tag, self.parser.CurrentLineNumber)
         for (name, value) in attrs.items():
             child._set(name, value)
         self.current.append(child)
@@ -481,7 +521,12 @@ class Parser(xml.sax.ContentHandler):
  
     def characters(self, char):
         if not char.isspace():
-            self.current[-1]._append(char)        
+            self.current[-1]._append(char)
+
+    def comment(self, data):
+        if self.include_comments:
+            parent = self.current[-1]
+            parent._add(Comment(data, self.parser.CurrentLineNumber))
 
 def parse(url):
     """Parse the given 'url' returning an easily traversable tree"""
-- 
GitLab