diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8649cbf..0000000 --- a/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -*~ -*.out -*.o -*.gch -dom_parser - -libxmlquery.so -documentation/_build/singlehtml/ -bindings/python/_libxmlquery.so -bindings/python/libxmlquery.py -bindings/python/libxmlquery_wrap.c -*.pyc -documentation/_build/latex/*.sty -documentation/_build/latex/*.aux -documentation/_build/latex/*.idx -documentation/_build/latex/*.ind -documentation/_build/latex/*.log -documentation/_build/latex/*.tex -documentation/_build/latex/*.toc -documentation/_build/latex/*.ist -documentation/_build/latex/*.cls -documentation/_build/latex/*.sty -documentation/_build/doctrees/ -documentation/_build/latex/*.ilg -*/main.c diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 206aabd..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/Makefile b/Makefile deleted file mode 100644 index 7d3009a..0000000 --- a/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -include Makefile.inc - -DOM_SRC = ./dom -PARSER_SRC = ./parser -STRUCTS = ./data_structures -SELECTORS = ./selectors -OUT = xmlquery - -all: exec so - -object_code: - make -C $(DOM_SRC) all - make -C $(PARSER_SRC) all - make -C $(STRUCTS) all - make -C $(SELECTORS) all - -tests: so - make -C tests - -exec: object_code - $(CC) $(CFLAGS) -o $(OUT) $(PARSER_SRC)/*.o $(DOM_SRC)/*.o $(STRUCTS)/*.o $(SELECTORS)/*.o main.c - -clean: - make -C $(DOM_SRC) clean - make -C $(PARSER_SRC) clean - make -C $(STRUCTS) clean - make -C $(SELECTORS) clean - rm -rf *~ *.o $(OUT) libxmlquery.so - -so: object_code - $(CC) $(CFLAGS) $(PARSER_SRC)/*.o $(DOM_SRC)/*.o $(STRUCTS)/*.o $(SELECTORS)/*.o -shared -o libxmlquery.so - -install: - ./install.sh - -uninstall: - ./install.sh -u - diff --git a/Makefile.inc b/Makefile.inc deleted file mode 100644 index 1f09f18..0000000 --- a/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# common definitions - -CC = gcc -CFLAGS = -Wall -Os -g -DDEBUG -fPIC -LEXFLAGS = -DDEBUG -c -g -Os -fPIC - diff --git a/README.rst b/README.rst deleted file mode 100644 index 529e579..0000000 --- a/README.rst +++ /dev/null @@ -1,13 +0,0 @@ -=========== -libxmlquery -=========== - -C library to parse and query xml using css selectors, built for low -memory footprint and portability. - -This software is released under the `MIT license -`_. - -Both the software and its documentation are in a *pre alpha* stage, -please use with caution. - diff --git a/applications/shell.html b/applications/shell.html new file mode 100644 index 0000000..9c112a0 --- /dev/null +++ b/applications/shell.html @@ -0,0 +1,186 @@ + + + + + + + + Shell — libxmlquery v0.1.4 documentation + + + + + + + + + + + + +
+
+
+
+ +
+

Shell

+

The shell application is the most simplest application we’ve created to demonstrate the features of our querying engine. It has a simple interface and its purpose +is to load xml files, print them and query them.

+
+

Compiling

+

Compiling the shell is very easy. You just type make and it’ll generate a binary called shell.

+
+
+

Running

+

After compiling the shell application, you just need to run the binary file shell without any arguments.

+
+
+

Interaction

+

After running the application, you’ll be presented with a banner and a prompt. You can begin by typing help to see which commands it supports.

+

As an example:

+
############################################################################
+#                                                                          #
+#  ll   iii bbb  xx   xx mm   mm ll     qqqq   uu  uu eeeee rrrr  yy   yy  #
+#  ll    i  bb b  xx xx  mmm mmm ll    qq  qq  uu  uu ee    rr rr  yy yy   #
+#  ll    i  bbb    xxx   mmmmmmm ll   qq    qq uu  uu eeee  rrrr    yyy    #
+#  ll    i  bb b  xx xx  mm m mm ll    qq  qq  uu  uu ee    rr rr   yyy    #
+#  llll iii bbb  xx   xx mm   mm llll   qqqq q uuuuuu eeeee rr  rr  yyy    #
+#                                                                          #
+############################################################################
+
+>>> help
+gdb:
+Call gdb for a given program
+        Usage:gdb <binary_file>
+load:
+Load an xml file into a variable.
+        Usage: load <file_to_load> <variable_name>
+
+help:
+Print this help message
+
+query:
+Query an existing xml document
+        Usage:query <variable_name> "<query_expression>"
+
+quit:
+Exit from shell
+
+print_xml:
+Print a loaded document into xml format
+        Usage: print_xml <variable_name>
+>>>
+
+
+

From here you can deduce what commands we implemented. The gdb command is there just for development convenience. A typical interaction would be:

+
############################################################################
+#                                                                          #
+#  ll   iii bbb  xx   xx mm   mm ll     qqqq   uu  uu eeeee rrrr  yy   yy  #
+#  ll    i  bb b  xx xx  mmm mmm ll    qq  qq  uu  uu ee    rr rr  yy yy   #
+#  ll    i  bbb    xxx   mmmmmmm ll   qq    qq uu  uu eeee  rrrr    yyy    #
+#  ll    i  bb b  xx xx  mm m mm ll    qq  qq  uu  uu ee    rr rr   yyy    #
+#  llll iii bbb  xx   xx mm   mm llll   qqqq q uuuuuu eeeee rr  rr  yyy    #
+#                                                                          #
+############################################################################
+
+>>> load ../test.xml doc
+XML ../test.xml loaded and stored in doc
+>>> query doc "@title"
+Node:
+<title>
+  RSS Example
+</title>
+
+Node:
+<title>
+  Item Example
+</title>
+
+>>> quit
+exiting...
+
+
+

This example shows how to load and query a document.

+
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

Special Macros

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/bindings/Makefile b/bindings/Makefile deleted file mode 100644 index bc38a30..0000000 --- a/bindings/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -include ../Makefile.inc - -PYTHON = ./python - -all: helpers.o - make -C $(PYTHON) all - -helpers.o: helpers.c helpers.h - $(CC) $(CFLAGS) -c helpers.c - -clean: - make -C $(PYTHON) clean - rm helpers.o - diff --git a/bindings/helpers.c b/bindings/helpers.c deleted file mode 100644 index 43a51a5..0000000 --- a/bindings/helpers.c +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include - -dom_node* internal_parse_xml_file(char* xmlstring){ - return parse_xml_from_string(xmlstring)->root; -} - -char* node_to_xml_string(dom_node* root){ - return node_to_string(root, XML); -} - -int list_size(struct generic_list_s* l){ - return l->count; -} - -dom_node* get_dom_node_at(struct generic_list_s* l, int p){ - return (dom_node*)get_element_at(l, p); -} - diff --git a/bindings/helpers.h b/bindings/helpers.h deleted file mode 100644 index 3c3ba06..0000000 --- a/bindings/helpers.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __HELPERS_H__ -#define __HELPERS_H__ - -extern dom_node* internal_parse_xml_file(char* filename); -extern char* node_to_xml_string(dom_node* root); - -#endif - diff --git a/bindings/python/MANIFEST b/bindings/python/MANIFEST deleted file mode 100644 index 8bf854f..0000000 --- a/bindings/python/MANIFEST +++ /dev/null @@ -1,5 +0,0 @@ -helpers.c -libxmlquery.py -libxmlquery_wrap.c -setup.py -xmlquery.py diff --git a/bindings/python/Makefile b/bindings/python/Makefile deleted file mode 100644 index d5e0d0d..0000000 --- a/bindings/python/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -SO = pyxmlquery.so - -all: _libxmlquery.so - - -libxmlquery.py libxmlquery_wrap.c: libxmlquery.i - swig -python libxmlquery.i - -libxmlquery_wrap.o: libxmlquery_wrap.c - gcc -c -fpic libxmlquery_wrap.c -I/usr/include/python2.7 - -libxmlquery.so: - make -C ../.. so - sudo make -C ../.. uninstall - sudo make -C ../.. install - -_libxmlquery.so: libxmlquery_wrap.o libxmlquery.so ../helpers.o - gcc -shared -lxmlquery libxmlquery_wrap.o ../helpers.o -o _libxmlquery.so - -../helpers.o: ../helpers.c ../helpers.h - -clean: - rm -rf libxmlquery.py libxmlquery_wrap.c libxmlquery_wrap.o _libxmlquery.so - diff --git a/bindings/python/helpers.c b/bindings/python/helpers.c deleted file mode 120000 index 4f91024..0000000 --- a/bindings/python/helpers.c +++ /dev/null @@ -1 +0,0 @@ -../helpers.c \ No newline at end of file diff --git a/bindings/python/html2xml b/bindings/python/html2xml deleted file mode 120000 index a15ad53..0000000 --- a/bindings/python/html2xml +++ /dev/null @@ -1 +0,0 @@ -html2xml.py \ No newline at end of file diff --git a/bindings/python/html2xml.py b/bindings/python/html2xml.py deleted file mode 100755 index c4b37aa..0000000 --- a/bindings/python/html2xml.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/python - -import sys -from BeautifulSoup import BeautifulSoup -import re - - -def translate(html, force=False): - - if force: - html = re.sub(re.compile("(.*?)", re.I|re.S), r"", html) - else: - html = re.sub(re.compile("(.*?)", re.I|re.S), r"", html) - - - soup = BeautifulSoup(html) - - return soup.prettify() - -if __name__ == "__main__": - if len(sys.argv) == 1: - f = sys.stdin - elif len(sys.argv) == 2: - f = open(sys.argv[1], 'r') - print "Usage: html2python 'file.html'" - - print translate(f.read()) - f.close() - diff --git a/bindings/python/libxmlquery.i b/bindings/python/libxmlquery.i deleted file mode 100644 index 67c3466..0000000 --- a/bindings/python/libxmlquery.i +++ /dev/null @@ -1,51 +0,0 @@ - -%module libxmlquery -%{ -/* Put headers and other declarations here */ -#include -#include - -extern dom_node* internal_parse_xml_file(char* filename); -extern char* node_to_xml_string(dom_node* root); -extern int list_size(struct generic_list_s* l); -extern struct generic_list_s* query(char* q, dom_node*); -extern dom_node* get_dom_node_at(struct generic_list_s* l, int p); -%} - -extern void set_namespace(dom_node* node, char* namespace); -extern void set_name(dom_node* node, char* name); -extern void set_value(dom_node* node, char* value); -extern void set_parent(dom_node* node, dom_node* parent); - -extern char* get_namespace(dom_node* node); -extern char* get_name(dom_node* node); -extern char* get_value(dom_node* node); - -extern void prepend_child(dom_node* parent, dom_node* child); -extern void append_child(dom_node* parent, dom_node* child); -extern void append_children(dom_node* parent, struct generic_list_s* children); -extern void add_attribute(dom_node* node, dom_node* attribute); - -extern dom_node* new_element_node(char* name); -extern dom_node* new_text_node(char* text); -extern dom_node* new_attribute(char* name, char* value); -extern dom_node* new_cdata(char* cdata_text); - -extern dom_node* get_child_at(dom_node* parent, int index); -extern struct generic_list_s* get_children(dom_node* node); -extern dom_node* get_attribute_by_name(dom_node* node, char* attr_name); - -extern dom_node* delete_attribute(dom_node* node, char* name); - -//query_runner -extern struct generic_list_s* query(char* q, dom_node*); - -//helpers -extern dom_node* internal_parse_xml_file(char* filename); -extern char* node_to_xml_string(dom_node* root); -extern int list_size(struct generic_list_s* l); -extern dom_node* get_dom_node_at(struct generic_list_s* l, int p); - -//stack.h -extern void remove_element(struct generic_list_s* l, void* obj); - diff --git a/bindings/python/setup.py b/bindings/python/setup.py deleted file mode 100644 index 5074bc8..0000000 --- a/bindings/python/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -from distutils.core import setup -from distutils.extension import Extension - -setup(name='xmlquery', - version='0.9alpha', - py_modules=['xmlquery', 'libxmlquery', 'html2xml'], - ext_modules=[Extension('_libxmlquery', - ['libxmlquery_wrap.c', 'helpers.c'], - libraries=['xmlquery'])], - scripts=['html2xml'], - ) - diff --git a/bindings/python/test.py b/bindings/python/test.py deleted file mode 100644 index 9162d0a..0000000 --- a/bindings/python/test.py +++ /dev/null @@ -1,9 +0,0 @@ -import xmlquery - -xml = xmlquery.parse_xml("") -c = xml.query("*") -#c[1].name = "banana" - -for n in c: - print n.name - diff --git a/bindings/python/xmlquery.py b/bindings/python/xmlquery.py deleted file mode 100644 index e5eef4a..0000000 --- a/bindings/python/xmlquery.py +++ /dev/null @@ -1,145 +0,0 @@ -import libxmlquery as lxq -import collections - -def parse_xml(string): - if not isinstance(string, str) and not isinstance(string, unicode): raise TypeError - return NodeWrapper(lxq.internal_parse_xml_file(string)) - - -class NodeList: - def __init__(self, listptr): - self._list = listptr - - def __len__(self): - return lxq.list_size(self._list) - - def get_attribute(attr): - return map(lambda x: x.attributes[key], self) - - def __getitem__(self, key): - if isinstance(key, int): - if 0 <= key < len(self): return NodeWrapper(lxq.get_dom_node_at(self._list, key)) - elif -len(self) <= key < 0: return NodeWrapper(lxq.get_dom_node_at(self._list, len(self) + key)) - else: raise IndexError - elif isinstance(key, slice): - if key.start == None: start = 0 - if key.stop == None: stop = len(self) - if key.step == None: step = 1; - if key.step == 0: raise ValueError("Step value cannot be 0") - return lxq.slice_list(self._list, start, stop, step) - else: raise TypeError - - def __delitem__(self, key): - if not isinstance(key, int): - raise TypeError - lxq.remove_element(self._list, self[key]._node) - - def __contains__(self, item): - if not isinstance(item, Node): return False - return not lxq.get_element_pos(self._list, item._node) == -1 - -class Node: - def __init__(self, name, namespace=None): - self._node = lxq.new_element_node(name) - self._python_owner = True - if isinstance(namespace, str): - lxq.set_namespace(self._node, namespace) - - def query(self, q): - if not isinstance(q, str): raise TypeError - if not q or q[0] != "@": q = "@" + q - return NodeList(lxq.query(q, self._node)) - - def queryone(self, q): - r = self.query(q) - if(len(r) > 0): - return r[0] - else: - return None - - def __getattr__(self, name): - if name in self.__dict__: return self.__dict__[name] - elif name == 'name': return lxq.get_name(self._node) - elif name == 'namespace': return lxq.get_namespace(self._node) - elif name == 'children': return NodeList(lxq.get_children(self._node)) - elif name == 'attributes': return AttributeMap(self._node) - elif name == 'text': return str(reduce(lambda x, y: str(x)+ '\n' +str(y), self.__getattr__("children"))) - else: raise AttributeError - - def __setattr__(self, name, value): - if name == 'name': lxq.set_name(self._node, value) - elif name == 'namespace': lxq.set_namespace(self._node, value) - elif name == 'children': raise AttributeError("Attribute 'children' is read only") - elif name == 'attributes': raise AttributeError("Attribute 'attributes' is read only") - else: self.__dict__[name] = value - - def __str__(self): - return lxq.node_to_xml_string(self._node)[:-1] - - def __repr__(self): - name = self.name - if self.namespace: name = self.namespace + self.name - return "<" + name + " .../>" - - def __del__(self): - if self._python_owner: - lxq.destroy_dom_node(self._node) - self._node = None - - def append_child(self, child): - if isinstance(child, Node): - lxq.append_child(self._node, child._node) - else: raise TypeError - - -class NodeWrapper(Node): - def __init__(self, node_ptr): - self._node = node_ptr - self._python_owner = False - - -class AttributeMap: - def __init__(self, nodeptr): - self._node = nodeptr - - def __contains__(self, item): - if not isinstance(item, str): return False - return not lxq.get_attribute_by_name(self._node, item) == None - - def __getitem__(self, name): - if not isinstance(name, str): raise TypeError - r = lxq.get_attribute_by_name(self._node, name) - if r: return lxq.get_value(r) - else: raise KeyError - - def __setitem__(self, name, value): - if not (isinstance(name, str) and isinstance(value, str)): - raise TypeError - attr = lxq.new_attribute(name, value) - lxq.add_attribute(self._node, attr) - - def __delitem__(self, name): - if not isinstance(name, str): - raise TypeError - lxq.delete_attribute(self._node, name) - -#class Attribute: -# def __init__(self, name, value): -# self._node = lxq.new_attribute(name, value) -# self._python_owner = True -# -# def __getattr__(self, name): -# if name == 'name': return lxq.get_name(self._node) -# elif name == 'value': return lxq.get_value(self._node) -# else: raise AttributeError -# -# def __setattr__(self, name, value) -# if name == 'name': lxq.set_name(self._node, value) -# elif name == 'value': lxq.set_value(self._node, value) -# else: raise AttributeError -# -# def __del__(self): -# if self._python_owner: -# lxq.destroy_dom_node(self._node) -# self._node = None - diff --git a/data_structures/Makefile b/data_structures/Makefile deleted file mode 100644 index a85936d..0000000 --- a/data_structures/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -include ../Makefile.inc - - -OBJS = rbtree.o stack.o btree.o bitbuffer.o byte_buffer.o - -all: $(OBJS) - -rbtree.o: ../include/rbtree.h rbtree.c - $(CC) $(CFLAGS) -c rbtree.c -stack.o: ../include/stack.h stack.c - $(CC) $(CFLAGS) -c stack.c -btree.o: ../include/btree.h btree.c - $(CC) $(CFLAGS) -c btree.c -bitbuffer.o: ../include/bitbuffer.h bitbuffer.c - $(CC) $(CFLAGS) -c bitbuffer.c -byte_buffer.o: ../include/byte_buffer.h byte_buffer.c - $(CC) $(CFLAGS) -c byte_buffer.c - -clean: - rm -rf $(OBJS) *~ *.out - diff --git a/data_structures/bitbuffer.c b/data_structures/bitbuffer.c deleted file mode 100644 index 3da95c3..0000000 --- a/data_structures/bitbuffer.c +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include "../include/macros.h" -#include "../include/bitbuffer.h" - - -bitbuffer* new_bitbuffer(int byte_size){ - bitbuffer* r = alloc(bitbuffer, 1); - r->buffer = alloc(char, byte_size); - memset(r->buffer, 0, byte_size); - r->capacity = byte_size; - r->size = 0; - return r; -} - -bitbuffer* duplicate_bitbuffer(bitbuffer* bb){ - bitbuffer* r = new_bitbuffer(bb->capacity); - r->size = bb->size; - - //memcpy(r->buffer, bb->buffer, (r->size / 8)+1); - memcpy(r->buffer, bb->buffer, r->capacity); - return r; -} - -void append_bitbuffer_to_bitbuffer(const bitbuffer* from, bitbuffer* to){ - int i; - for(i = 0; i < from->size; i++){ - append_bit_to_buffer(get_bit_from_buffer(from, i), to); - } -} - -void print_bitbuffer(bitbuffer* bb){ - int j; - - for(j = 0; j < bb->size; j++){ - printf("%d", get_bit_from_buffer(bb, j)); - } - printf("\n"); -} - -void append_bit_to_buffer(char c, bitbuffer* bb){ - char v = c & (unsigned char) 0x01; - int bit_offset = bb->size % 8; - char* cur = bb->buffer + (bb->size / 8); - //char* cur = bb->buffer + (bb->size / 8); - - //for(i = 0; i < bit_offset; i++){ v <<= 1; } - - *cur |= (v << bit_offset); - - bb->size += 1; - if(bit_offset == 7){ - if(cur - bb->buffer >= bb->capacity){ - bb->buffer = (char*)realloc(bb->buffer, bb->capacity*2); - memset(bb->buffer + (bb->size/8), 0, bb->capacity*2 - (bb->size/8)); - bb->capacity *= 2; - } - } - - -} - -void append_bits_to_buffer(char c, int bit_count, bitbuffer* bb){ - int i; - for(i = bit_count; i > 0; i--){ - char v = c >> (i-1); - append_bit_to_buffer(v, bb); - } - -} - -char get_bit_from_buffer(const bitbuffer* bb, int offset){ - if(offset < 0 || offset > bb->size){ - exit(-1); - } - char* cur = bb->buffer + (offset / 8); - int bit_offset = offset % 8; - - return (*cur >> bit_offset) & 1; -} - -char get_byte_from_buffer(const bitbuffer* bb, int offset){ - char r = 0; - int i; - - for(i = 0; i < 7; i++){ - r |= get_bit_from_buffer(bb, offset+i); - r <<= 1; - } - r |= get_bit_from_buffer(bb, offset+i); - return r; -} - - -/*int main(){ - bitbuffer* bb = new_bitbuffer(1); - int i, seed = 12244543; - char c; - for(i = 0; i < 25; i++){ - c = (char) ((seed >> i) & 1); - append_bit_to_buffer(c, bb); - printf("%d", c); - } - printf("\n"); - - for(i = 0; i < bb->size; i++){ - printf("%d", get_bit_from_buffer(bb, i)); - } - printf("\n"); - - return 0; -}*/ - diff --git a/data_structures/btree.c b/data_structures/btree.c deleted file mode 100644 index e7c351d..0000000 --- a/data_structures/btree.c +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include "../include/btree.h" - -btree* new_btree(){ - btree* r = alloc(btree, 1); - r->value = NULL; - r->left = NULL; - r->right = NULL; - - return r; -} - diff --git a/data_structures/byte_buffer.c b/data_structures/byte_buffer.c deleted file mode 100644 index 9ca2018..0000000 --- a/data_structures/byte_buffer.c +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include "../include/byte_buffer.h" -#include "../include/macros.h" - -void destroy_byte_buffer(byte_buffer* bb){ - if(bb == NULL) return; - - free(bb->buffer); - free(bb); -} - -byte_buffer* new_byte_buffer(int initial){ - byte_buffer* b = alloc(byte_buffer, 1); - b->buffer = alloc(char, initial); - b->size = 0; - b->capacity = initial; - - return b; -} - -void append_string_to_buffer(const char* s, byte_buffer* b){ - int strl = strlen(s); - append_bytes_to_buffer(s, b, strl); -} - -void append_bytes_to_buffer(const char* bytes, byte_buffer* b, size_t size){ - if(b->size + size > b->capacity){ - b->buffer = (char*)realloc(b->buffer, (b->size+size)*2); - b->capacity = (b->size+size)*2; - } - - memcpy(b->buffer+b->size, bytes, size); - b->size += size; -} - -void append_buffer_to_buffer(byte_buffer* b2, byte_buffer* b){ - if(b->size + b2->size > b->capacity){ - b->buffer = (char*)realloc(b->buffer, (b->size+b2->size)*2); - b->capacity = (b->size+b2->size)*2; - } - - memcpy(b->buffer+b->size, b2->buffer, b2->size); - b->size += b2->size; -} diff --git a/data_structures/datastructures.html b/data_structures/datastructures.html new file mode 100644 index 0000000..26573db --- /dev/null +++ b/data_structures/datastructures.html @@ -0,0 +1,970 @@ + + + + + + + + Data Structures — libxmlquery v0.1.4 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

Data Structures

+
+

Generic List

+

Generic array list optimized for fast access. This structure is defined in stack.h and implemented in stack.c. It can act as a stack, queue or random access list. Although they seem different, the datastructure is the same and every function of one type can be used in another. This means that you can have a random access list and start poping out elements as though it was a stack.

+
+
+struct generic_list_s
+
+ +
+
+list
+
+ +

This structure defines the random access list. Its structure definition is:

+
typedef struct generic_list_s{
+  struct list_bucket** array;
+  int32_t start;
+  int32_t count;
+  int32_t capacity;
+} list;
+
+
+

As you can see this is just a list backed up by an array of struct list_bucket. These buckets are defined as follows:

+
+
+struct list_bucket
+
+ +
struct list_bucket
+{
+  int16_t type;
+  void* element;
+};
+
+
+

Finally, notice that the stack and queue type are just typedefs of list.

+
typedef struct generic_list_s stack;
+typedef struct generic_list_s queue;
+
+
+

The next sections will show how to use these types.

+
+

Function description

+
+
+uint8_t generic_list_is_empty(struct generic_list_s* l)
+

l The generic list to check if is empty.

+

This function checks if the generic list is empty. It return an integer bigger than 0 if true, or 0 if false.

+
+ +
+
+int32_t generic_list_get_count(struct generic_list_s* l)
+

l The generic list to obtain the count of elements.

+

This function return the number of elements in the generic list.

+
+ +
+
+struct generic_list_s *new_generic_list(int32_t initial)
+

initial Initial capcity for a generic list.

+

This function returns a generic list with a given initial capacity. Capacity dictates how much space the list will take. You don’t need to +worry about reallocation, but consider using small values for capacity when you know that the list will not grow that much.

+
+ +
+
+stack* new_stack(int32_t initial)
+

initial Initial capcity for a stack.

+

This function is just an alias for new_generic_list().

+
+ +
+
+queue* new_queue(int32_t initial)
+

initial Initial capcity for a queue.

+

This function is just an alias for new_generic_list().

+
+ +
+
+void* set_element_with_type_at(list *l, void* obj, int16_t type, int32_t pos)
+

l List where to set the element.

+

obj New element to store in the list.

+

type The type of the new element.

+

pos The position of the element to be set.

+

This function sets an already exiting element to a new one. A pointer to the old one is returned so the user can free the space used by it.

+
+ +
+
+void* set_element_at(list *l, void* obj, int32_t pos)
+

l List where to set the element.

+

obj New element to store in the list.

+

pos The position of the element to be set.

+

This function does exactly the same as set_element_with_type_at(), but without the type feature.

+
+ +
+
+void insert_element_with_type_at(list* l, void* obj, int16_t type, int32_t pos)
+

l List where to insert the element.

+

obj New element to store in the list.

+

type The type of the new element.

+

pos The position of the element to be set.

+

This function inserts an element at a given position with a given type. The list will be resized if necessary.

+
+ +
+
+void insert_element_at(list* l, void* obj, int32_t pos)
+

l List where to insert the element.

+

obj New element to store in the list.

+

pos The position of the element to be set.

+

This function does exactly the same thing as insert_element_with_type_at(), but without the type feature.

+
+ +
+
+void sorted_insert_element_with_type(list* l, void* obj, int16_t type, int(*compare)(void* o1, int16_t type1, void* o2, int16_t type2))
+

l List where to insert the element.

+

obj New element to store in the list.

+

type The type of the new element.

+

compare A function pointer to a function that compares elements in the list.

+

This function inserts an element into a list in sorted order, according to the function pointer passed as an argument.

+
+ +
+
+void append_element_with_type(list* l, void* obj, int16_t type)
+

l List where to append the element.

+

obj New element to store in the list.

+

type The type of the new element.

+

This function inserts an element at the end of the list.

+
+ +
+
+void prepend_element_with_type(list* l, void* obj, int16_t type)
+

l List where to prepend the element.

+

obj New element to store in the list.

+

type The type of the new element.

+

This function inserts an element at the beginning of the list.

+
+ +
+
+void add_element_with_type(list* l, void* obj, int16_t type)
+

l List where to add the element.

+

obj New element to store in the list.

+

type The type of the new element.

+

This function adds an element to a list. It differs from prepend_element() and append_element() in the sense that the user doesn’t need to know +Where the element will be added.

+
+ +
+
+void add_element(list* l, void* obj)
+

l List where to add the element.

+

obj New element to store in the list.

+

This function is exactly the same as add_element_with_type(), but without the type feature.

+
+ +
+
+void* get_element_at(const list* l, int32_t pos)
+

l List from where to get the element.

+

pos The element’s position.

+

This function returns the element stored at the given position.

+
+ +
+
+void* get_element_with_type_at(const list* l, int32_t pos, int16_t* type)
+

l List from where to get the element.

+

pos The element’s position.

+

type An address to store the elements type.

+

This function does the same as get_element_at(), but it also returns the element’s type. This is stored in a location passed as the third argument +to this function.

+
+ +
+
+int get_element_pos(const list* l, void* el)
+

l List from where to get the element’s position.

+

el The element to look for in the list.

+

This function returns the position of the element passed as an argument. If no element is found, then -1 is returned.

+
+ +
+
+int32_t remove_element(list *l, void* obj)
+

l List from where to remove the element.

+

obj The element to be removed.

+

This function removes the first occurrence of a given element from a list. If the element doesn’t exist then nothing will happen.

+
+ +
+
+int32_t remove_all(list *l, void* obj)
+

l List from where to remove the element.

+

obj The element to be removed.

+

This function removes all occurrences of a given element from a list. If no element is found then nothing will happen.

+
+ +
+
+void* remove_element_at(list* l, int32_t pos)
+

l List from where to remove the element.

+

pos Position of the element to be removed.

+

This function removes the element at a given position from a list.

+
+ +
+
+void enqueue_with_type(queue* q, void* obj, int16_t type)
+

q Queue where to enqueue the element.

+

obj Element to enqueue.

+

type The type of the element being enqueued.

+

This function enqueues an element with a given type in a given queue.

+
+ +
+
+void enqueue(queue* q, void* obj)
+

q Queue where to enqueue the element.

+

obj Element to enqueue.

+

This function is the same as enqueue_with_type(), but without the type feature.

+
+ +
+
+void* dequeue(queue* q)
+

q Queue from where to dequeue an element.

+

This function dequeues an element from a given queue. If no element is present, then NULL is returned.

+
+ +
+
+void push_stack_type(stack* s, void* obj, int16_t type)
+

s Stack where to push the element.

+

obj Element to push onto the stack.

+

type The type of the element being push.

+

This function pushes an element with a given type onto a given stack.

+
+ +
+
+void push_stack(stack* s, void* obj)
+

s Stack where to push the element.

+

obj Element to push onto the stack.

+

This function is the same as push_stack_type(), but without the type feature.

+
+ +
+
+void* pop_stack(stack* s)
+

s Stack from where to pop an element.

+

This function pops an element from a given stack. If no element is present, NULL is returned.

+
+ +
+
+list* remove_duplicates(list* l)
+

l List from where to remove duplicate elements.

+

This function removes duplicate values based on their memory address.

+
+ +
+
+int16_t peek_element_type_at(list* l, int32_t pos)
+

l List from where to peek an element’s type.

+

pos The element’s position in the list.

+

This function lets you see which type the element at a given position has. If no element is in that position the program will exit.

+
+ +
+
+int16_t peek_stack_type(stack *s)
+

s Stack from where to peek the element’s type.

+

This function is the same as peek_element_type_at(), but it applies only to stacks. This means that it will only check the element at the head of the stack.

+
+ +
+
+int16_t peek_queue_type(queue *s)
+

s Queue from where to peek the element’s type.

+

This function is the same as peek_stack_type(). However, it applies only to queues.

+
+ +
+
+struct generic_list_s *merge_lists(struct generic_list_s *l1, struct generic_list_s *l2)
+

l1 Any list.

+

l2 Any list.

+

This function merges two list onto a single one. The list l2 will be append to l1. Beware that the input lists will be destroyed. The merged list is returned. If +both lists are NULL, then NULL is returned.

+
+ +
+
+struct generic_list_s *duplicate_generic_list(const struct generic_list_s*)
+

s List to be duplicated.

+

This function allocates and fills a new list with the same values as the given list. Only the buckets are duplicated, the elements on the list stay exactly the same.

+
+ +
+
+void destroy_generic_list(struct generic_list_s *s)
+

s List to be destroyed

+

This function destroys a given list. Only the buckets get destroyed, the elements must be detroyed by the user.

+

Example:

+
#include <stdlib.h>
+#include <stdio.h>
+#include "stack.h"
+
+int main(){
+   list* l = new_generic_list(2);
+   int *a, *b;
+
+   a = (int*) malloc(sizeof(int));
+   b = (int*) malloc(sizeof(int));
+   if(!a || !b){
+     printf("malloc failed\n");
+     return -1;
+   }
+
+   *a = 9;
+   *b = 7;
+
+   append_element(l, a, 0);
+   append_element(l, b, 0);
+
+   generic_list_iterator* it = new_generic_list_iterator(l);
+   while(generic_list_iterator_has_next(it)){
+     int *c = (int*) generic_list_iterator_next(it);
+     free(c);
+   }
+   destroy_generic_list_iterator(it);
+
+   destroy_generic_list(l);
+
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where stack.h is kept>
+
+
+
+ +
+
+generic_list_iterator* new_generic_list_iterator(struct generic_list_s* s)
+

s List to be iterated.

+

This function creates an iterator for the given list.

+
+ +
+
+uint8_t generic_list_iterator_has_next(generic_list_iterator* i)
+

i A list iterator.

+

This function checks if there are elements still to be iterated. If not 0 is returned, otherwise a value different from 0 is returned.

+
+ +
+
+void* generic_list_iterator_next(generic_list_iterator* i)
+

i A list iterator

+

This function returns an element from the list and advances the iterator to the next position.

+
+ +
+
+void destroy_generic_list_iterator(generic_list_iterator* i)
+

i A list iterator

+

This function frees a list iterator.

+
+ +
+
+
+

Generic Red Black Tree

+

The file rbtree.c contains the source code for a generic red black tree. This data structure is capable of storing any kind of data and its defined in rbtree.h as:

+
+
+tree_root
+
+ +
+
+struct sroot
+
+ +
typedef struct sroot{
+   struct stree_node* root;
+   void* (*key)(struct stree_node* node);
+   int64_t (*compare)(void* keyA, void* keyB);
+}tree_root;
+
+
+

There are two things to notice here. First, this is only the root of the tree and points to the first tree_node of the rbtree. Second, it contains two function pointers. The first points to a function, which receives a tree_node and should return a pointer to that node’s key. The second is a pointer to a compare function, which compares two keys and should return:

+
    +
  • A negative integer if the first key is smaller than the second.
  • +
  • 0 if the keys are the same.
  • +
  • A positive integer if the first key is bigger than the second.
  • +
+

The compare function must be:

+
    +
  • Reflexive: Given an object a. compare(a, a) should always return 0.
  • +
  • Symetric: Given two identical objects a and b, if compare(a,b) returns 0, then compare(b,a) must return 0.
  • +
  • Transitive: Given three objects a, b, c. If compare(a,b) returns 0, and compare(b,c) returns 0, then compare(a,c) must return 0.
  • +
  • Consistent: Multiple invocations of compare on the same objects in the same other, must return always the same value.
  • +
+

These properties should hold even if objects aren’t equal.

+

The compare and key function pointers must be provided by the user. Why do we need these pointers? Because the data stored in the rbtree can be anything, but we still need to know how to sort it. Nevertheless, if you wish to use this data structure as a container and don’t care how things are sorted, you can always use the method new_simple_rbtree().

+

Each node in an rbtree is called a tree_node and is defined in rbtree.h as:

+
+
+tree_node
+
+ +
+
+struct stree_node
+
+ +
typedef struct stree_node{
+   void* node;
+
+   uint8_t color;
+
+   struct stree_node* parent;
+   struct stree_node* left;
+   struct stree_node* right;
+ }tree_node;
+
+
+

There’s not much to say about this structure, the only thing relevant is the field node, which is used to store the actual data. The other fields are used to keep the rbtree intact.

+

Finally, there’s one more structure, which is defined in rbtree.h as:

+
+
+tree_iterator
+
+ +
+
+struct siterator
+
+ +
typedef struct siterator{
+   struct stree_node* current;
+}tree_iterator;
+
+
+

As the name implies, this structure is an iterator to the tree nodes.

+

As a final note, remember that we provide functions to destroy our structures, but the actual data must be destroyed by you. Do not use iterators for this purpose.

+
+

Function description

+
+
+tree_root* new_simple_rbtree()
+

This function creates an rbtree, which sorts the data acording to its memory pointer. This function should be used when you just want the rbtree to behave as a container, +but you still need O(log(n)) when accessing the data. Keep in mind that in order to retreive the stored data, you need to know it’s memory pointer.

+

The return value is a tree_root structure.

+
+ +
+
+tree_root* new_rbtree(void* (*key_function_pointer)(struct stree_node* node), int64_t (*compare_function_pointer)(void* keyA, void* keyB))
+

key_function_pointer A function that should return the address of the node’s key.

+

compare_function_pointer A function that should compare two keys and return values as described above. It receives the addresses of each key.

+

This function creates an rbtree, which sorts the data according to the given functions. The following example shows how to create an rbtree to store integers.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
+ +
+
+void* rb_tree_insert(tree_root* root, void* node)
+

root A pointer to the tree root where to insert the data represented by node.

+

node A pointer to the data, which will be inserted in the tree.

+

As the name implies this function inserts data into the rbtree. In the eventuality that the inserted value is already in the tree, it will be replaced and a pointer to the older value is returned. This is done so the user can free the space stored by that data. The following example shows how to insert integers in an rbtree.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10, d = 6;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+   int older = *((int *) rb_tree_insert(rbtree, &d));
+
+   //don't free older because it was "alloched" by the compiler.
+   printf("Found a %d already stored in the tree.\n", older);
+
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
+ +
+
+void* rb_tree_delete(tree_root* root, void* key)
+

root A pointer to the tree root where to delete the data with key pointed by key.

+

key A pointer to the key of the node to be deleted.

+

This function deletes a node from an rbtree. If a node with a key equal to the one pointed by key does not exist, NULL will be return. However, if such a node is found, then a pointer to the data is returned. This is done so the user can free the space used by that data. The following example shows how to use this function on an rbtree that stores integers.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+
+   int d = 10, stored;
+   stored = *((int *) rb_tree_delete(rbtree, &d));
+
+   //don't free stored because it was "alloched" by the compiler.
+   printf("Found a %d stored in the tree.\n", stored);
+
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
+ +
+
+void* search_rbtree(tree_root root, void* key)
+

root The root of the tree where to perform the search.

+

key A pointer to the key of the node to be searched.

+

This function searchs an rbtree for a node. It returns NULL if nothing is found, or the data stored in the tree with a key equal to the value pointed by key. The following example shows how to search a tree that stores integers.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+
+   int d = 10, stored;
+   stored = *((int *) search_rbtree(*rbtree, &d));
+
+   printf("Found a %d stored in the tree.\n", stored);
+
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
+ +
+
+void destroy_rbtree(tree_root* root)
+

root A pointer to the tree to be destroyed.

+

This function destroys an rbtree. Note that this doesn’t free the user stored data. The following example shows how to use this in a tree that stores integers.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+
+   destroy_rbtree(rbtree);
+   //We do not need to free the stored data because it was "alloched" by the compiler.
+
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+

Notice that running the command

+
valgrind --show-reachable=yes --leak-check=full ./test
+
+
+

produces the ouput:

+
==1188== HEAP SUMMARY:
+==1188==     in use at exit: 0 bytes in 0 blocks
+==1188==   total heap usage: 4 allocs, 4 frees, 72 bytes allocated
+==1188==
+==1188== All heap blocks were freed -- no leaks are possible
+
+
+

Which means that there are no memory leaks and you should always use this function to free the space stored by any rbtree you use.

+
+ +
+
+tree_iterator* new_tree_iterator(tree_root* root)
+

root A pointer to a tree root, which the iteration will be performed.

+

This function creates an iterator to an rbtree. Note that when you create an iterator, you should not insert or delete nodes from the tree before the iteration is over. Otherwise, the behaviour of the program will be unpredictable. It returns pointer to the created iterator. The following example shows how to create an iterator for a tree that stores integers.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+
+   tree_iterator* it = new_tree_iterator(rbtree);
+
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
+ +
+
+uint8_t tree_iterator_has_next(tree_iterator* it)
+

it A tree iterator created by calling new_tree_iterator().

+

This function returns 1 if there are more elements in the tree to be iterated. The following code shows a simple usage of this function.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+
+   tree_iterator* it = new_tree_iterator(rbtree);
+
+   if(tree_iterator_has_next(it))
+     printf("There are still elements to be iterated.\n");
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
+ +
+
+void* tree_iterator_next(tree_iterator* it)
+

it A tree iterator created by calling new_tree_iterator().

+

This functions returns the current element pointed by iterator it and advances to the next element in the iteration. This function should be used with tree_iterator_has_next(). Note that there is no guaranty about the order of iteration. The following code shows how to use it.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+
+   tree_iterator* it = new_tree_iterator(rbtree);
+
+   while(tree_iterator_has_next(it)){
+     int d = *((int *) tree_iterator_next(it));
+     printf("%d\n", d);
+   }
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
+ +
+
+void destroy_iterator(tree_iterator* it)
+

it A tree iterator created by calling new_tree_iterator().

+

This function frees the iterator pointed by it. The following example shows how to use it.

+

Example:

+
#include <stdio.h>
+#include "rbtree.h"
+
+void* key_address(tree_node* node){
+   return node->node;
+}
+
+int64_t compare_integers(void* keyA, void* keyB){
+   return *((int *) keyA) - *((int *) keyB);
+}
+
+int main(){
+   tree_root* rbtree = new_rbtree(& key_address, & compare_integers);
+   int a = 9, b = 6, c = 10;
+
+   rb_tree_insert(rbtree, &a);
+   rb_tree_insert(rbtree, &b);
+   rb_tree_insert(rbtree, &c);
+
+   tree_iterator* it = new_tree_iterator(rbtree);
+
+   while(tree_iterator_has_next(it)){
+     int d = *((int *) tree_iterator_next(it));
+     printf("%d\n", d);
+   }
+   destroy_iterator(it);
+
+   destroy_rbtree(rbtree);
+   return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where rbtree.h is kept>
+
+
+
valgrind --show-reachable=yes --leak-check=full ./test
+
+
+

produces the ouput:

+
==4432== HEAP SUMMARY:
+==4432==     in use at exit: 0 bytes in 0 blocks
+==4432==   total heap usage: 5 allocs, 5 frees, 76 bytes allocated
+==4432==
+==4432== All heap blocks were freed -- no leaks are possible
+
+
+

Which means that there are no memory leaks and you should always use this function when iterating.

+
+ +
+
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

Querying

+

Next topic

+

Special Macros

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/data_structures/rbtree.c b/data_structures/rbtree.c deleted file mode 100644 index 8ad748d..0000000 --- a/data_structures/rbtree.c +++ /dev/null @@ -1,426 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include "../include/rbtree.h" - - - -tree_node RBNIL = { - .node = NULL, - .color = BLACK, - .parent = &RBNIL, - .left = &RBNIL, - .right = &RBNIL -}; - -const void* ident(const struct stree_node* o){ - return o->node; -} - -int64_t compare_string(const void* keyA, const void* keyB){ - return strcmp((char*) keyA, (char*) keyB); -} - -static tree_node* new_rbtree_node(void* node){ - tree_node *z = alloc(tree_node, 1); - - z->node = node; - z->parent = &RBNIL; - z->left = &RBNIL; - z->right = &RBNIL; - z->color = RED; - return z; -} - -static const void* __pointer(const tree_node* node){ - return node->node; -} - -static int64_t __compare_by_pointer(const void* keyA, const void* keyB){ - return keyA - keyB; -} - -tree_root* new_simple_rbtree(){ - return new_rbtree(NULL, NULL); -} - -tree_root* new_rbtree(const void* (*key_function_pointer)(const struct stree_node* node), - int64_t (*compare_function_pointer)(const void* keyA, const void* keyB)){ - tree_root* r = alloc(tree_root, 1); - r->root = &RBNIL; - if(key_function_pointer == NULL && compare_function_pointer == NULL){ - r->key = &__pointer; - r->compare = &__compare_by_pointer; - }else{ - r->key = key_function_pointer; - r->compare = compare_function_pointer; - } - return r; -} - -/*WARNNING left_rbrotate assumes that rbrotate_on->right is NOT &RBNIL and that root->parent IS &RBNIL*/ -static void left_rbrotate(tree_root* root, tree_node* rbrotate_on){ - tree_node* y = rbrotate_on->right; - rbrotate_on->right = y->left; - - if(y->left != &RBNIL) - y->left->parent = rbrotate_on; - - y->parent = rbrotate_on->parent; - - if(rbrotate_on->parent == &RBNIL) - root->root = y; - else - if(rbrotate_on == rbrotate_on->parent->left) - rbrotate_on->parent->left = y; - else - rbrotate_on->parent->right = y; - - y->left = rbrotate_on; - rbrotate_on->parent = y; - return; -} - -/*WARNNING right_rbrotate assumes that rbrotate_on->left is NOT &RBNIL and that root->parent IS &RBNIL*/ -static void right_rbrotate(tree_root* root, tree_node* rbrotate_on){ - tree_node* y = rbrotate_on->left; - rbrotate_on->left = y->right; - - if(y->right != &RBNIL) - y->right->parent = rbrotate_on; - - y->parent = rbrotate_on->parent; - - if(rbrotate_on->parent == &RBNIL) - root->root = y; - else - if(rbrotate_on == rbrotate_on->parent->right) - rbrotate_on->parent->right = y; - else - rbrotate_on->parent->left = y; - - y->right = rbrotate_on; - rbrotate_on->parent = y; - return; -} - -static void rb_tree_insert_fixup(tree_root* root, tree_node* z){ - tree_node* y; - - while(z->parent->color == RED){ - - if(z->parent == z->parent->parent->left){ - y = z->parent->parent->right; - - if(y->color == RED){ - z->parent->color = BLACK; - y->color = BLACK; - z->parent->parent->color = RED; - z = z->parent->parent; - }else{ - if(z == z->parent->right){ - z = z->parent; - left_rbrotate(root, z); - } - z->parent->color = BLACK; - z->parent->parent->color = RED; - right_rbrotate(root, z->parent->parent); - } - - }else{ - y = z->parent->parent->left; - - if(y->color == RED){ - z->parent->color = BLACK; - y->color = BLACK; - z->parent->parent->color = RED; - z = z->parent->parent; - }else{ - if(z == z->parent->left){ - z = z->parent; - right_rbrotate(root, z); - } - z->parent->color = BLACK; - z->parent->parent->color = RED; - left_rbrotate(root, z->parent->parent); - } - } - } - - root->root->color = BLACK; -} - -void* rb_tree_insert(tree_root* root, void* node){ - tree_node *y = &RBNIL, *x = root->root; - - tree_node *z = new_rbtree_node(node); - - while(x != &RBNIL){ - y = x; - - if(root->compare(root->key(z), root->key(x)) == 0){ - void* holder = x->node; - free(z); - x->node = node; - return holder; - } - - if(root->compare(root->key(z), root->key(x)) < 0) - x = x->left; - else - x = x->right; - } - - z->parent = y; - - if(y == &RBNIL) - root->root = z; - else{ - if(root->compare(root->key(z),root->key(y)) < 0) - y->left = z; - else - y->right = z; - } - - rb_tree_insert_fixup(root, z); - return NULL; -} - -static tree_node* __search_rbtree_node(const tree_root* root, const void* key){ - tree_node *z = root->root; - - while(z != &RBNIL){ - if(root->compare(root->key(z), key) == 0) - return z; - - if(root->compare(root->key(z), key) < 0) - z = z->right; - else - z = z->left; - } - - return NULL; -} - -void* search_rbtree(const tree_root* root, const void* key){ - tree_node *z = __search_rbtree_node(root, key); - if(z) - return z->node; - return NULL; -} - -static void __destroy_rbtree(tree_node* root){ - tree_node *l, *r; - - if(root == &RBNIL) - return; - - l = root->left; - r = root->right; - - free(root); - - __destroy_rbtree(l); - __destroy_rbtree(r); -} - -void destroy_rbtree(tree_root* root){ - __destroy_rbtree(root->root); - free(root); -} - -static void __rb_transplant(tree_root* root, tree_node* u, tree_node* v){ - if(u->parent == &RBNIL) - root->root = v; - else - if(u == u->parent->left) - u->parent->left = v; - else - u->parent->right = v; - v->parent = u->parent; -} - -static tree_node* __rb_tree_minimum(tree_node* z){ - for(; z->left != &RBNIL; z = z->left); - return z; -} - -static void __rb_tree_delete_fixup(tree_root* root, tree_node* x){ - tree_node* w; - while( x != root->root && x->color == BLACK){ - if(x == x->parent->left){ - w = x->parent->right; - if(w->color == RED){ - w->color = BLACK; - x->parent->color = RED; - left_rbrotate(root, x->parent); - w = x->parent->right; - } - if(w->left->color == BLACK && w->right->color == BLACK){ - w->color = RED; - x = x->parent; - } - else{ - if(w->right->color == BLACK){ - w->left->color = BLACK; - w->color = RED; - right_rbrotate(root, w); - w = w->parent->right; - } - w->color = x->parent->color; - x->parent->color = BLACK; - w->right->color = BLACK; - left_rbrotate(root, x->parent); - x = root->root; - } - } - else{ - w = x->parent->left; - if(w->color == RED){ - w->color = BLACK; - x->parent->color = RED; - right_rbrotate(root, x->parent); - w = x->parent->left; - } - if(w->right->color == BLACK && w->left->color == BLACK){ - w->color = RED; - x = x->parent; - } - else{ - if(w->left->color == BLACK){ - w->right->color = BLACK; - w->color = RED; - left_rbrotate(root, w); - w = w->parent->left; - } - w->color = x->parent->color; - x->parent->color = BLACK; - w->left->color = BLACK; - right_rbrotate(root, x->parent); - x = root->root; - } - } - } - x->color = BLACK; - return; -} - -void* rb_tree_delete(tree_root* root, void* key){ - tree_node *y, *z, *x, *hold_node_to_delete; - uint8_t y_original_color; - void* node_to_return; - - hold_node_to_delete = y = z = __search_rbtree_node(root, key); - - if(y == NULL){ - log(W, "Trying to remove a node from tree that does not exist."); - return NULL; - } - - node_to_return = y->node; - - y_original_color = y->color; - if(z->left == &RBNIL){ - x = z->right; - __rb_transplant(root, z, z->right); - } - else - if(z->right == &RBNIL){ - x = z->left; - __rb_transplant(root, z, z->left); - } - else{ - y = __rb_tree_minimum(z->right); - y_original_color = y->color; - x = y->right; - if(y->parent == z) - x->parent = y; - else{ - __rb_transplant(root, y, y->right); - y->right = z->right; - y->right->parent = y; - } - __rb_transplant(root, z, y); - y->left = z->left; - y->left->parent = y; - y->color = z->color; - } - if(y_original_color == BLACK) - __rb_tree_delete_fixup(root, x); - - free(hold_node_to_delete); - return node_to_return; -} - -tree_iterator* new_tree_iterator(tree_root* root){ - tree_node* aux = root->root; - tree_iterator* it = alloc(tree_iterator, 1); - - while(aux->left != &RBNIL || aux->right != &RBNIL){ - while(aux->left != &RBNIL) - aux = aux->left; - - if(aux->right != &RBNIL) - aux = aux->right; - } - it->current = aux; - return it; -} - -uint8_t tree_iterator_has_next(tree_iterator* it){ - if(it->current != &RBNIL) - return 1; - return 0; -} - -void* tree_iterator_next(tree_iterator* it){ - tree_node* aux; - tree_node* tn = it->current; - - if(tn->parent != &RBNIL && - tn->parent->right != &RBNIL && - tn->parent->right != tn){ - aux = tn->parent->right; - while(aux->left != &RBNIL || aux->right != &RBNIL){ - while(aux->left != &RBNIL) - aux = aux->left; - - if(aux->right != &RBNIL) - aux = aux->right; - } - it->current = aux; - } - else - it->current = it->current->parent; - return tn->node; -} - -void destroy_iterator(tree_iterator* it){ - free(it); -} - diff --git a/data_structures/stack.c b/data_structures/stack.c deleted file mode 100644 index a6ac7c1..0000000 --- a/data_structures/stack.c +++ /dev/null @@ -1,614 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include "../include/macros.h" -#include "../include/stack.h" - -struct generic_list_s *_new_generic_list(int32_t initial, int8_t with_type) -{ - if(initial <= 0){ - log(F, "New generic list initial capacity must be greater than 0, %d given.", initial); - exit(1); - } - - struct generic_list_s* l = alloc(struct generic_list_s, 1); - l->start = 0; - l->count = 0; - l->capacity = initial; - l->with_type = with_type; - - l->array = alloc(void*, initial); - memset(l->array, 0, initial * sizeof(void**)); - return l; -} - -struct generic_list_s* new_generic_list(int32_t initial){ - return _new_generic_list(initial, 0); -} - -struct generic_list_s* new_generic_list_with_type(int32_t initial){ - return _new_generic_list(initial, 1); -} - -uint8_t generic_list_is_empty(struct generic_list_s* l){ - return l->count == 0; -} - -int32_t generic_list_get_count(struct generic_list_s* l){ - return l->count; -} - -/* -static void rebase_generic_list(list* l){ - if(l->start == 0){ return ; } - void** tmp; - //apparently this function is never called !!!! - //printf("[%d] + %d of %d\n", l->start, l->count, l->capacity); - - int cpy = l->count - l->capacity + l->start; - - if(cpy > 0){ - tmp = alloc(void*, cpy) - - memcpy(tmp, l->array, sizeof(void*)*cpy); - } - else{ cpy = 0; } - - //printf("mv %d + %d to 0\n", l->start, l->count - cpy); - memcpy(l->array, l->array + l->start, sizeof(void*)*(l->count - cpy)); - - if(cpy > 0){ - printf("mv + %d to %d\n", cpy, l->count - cpy); - memcpy(l->array + l->count - cpy, tmp, sizeof(void*)*cpy); - free(tmp); - } - - l->start = 0; -} -*/ - -static void refactor_generic_list(list* l){ - int32_t cpy; - - l->array = realloc(l->array, sizeof(void*) * l->capacity * 2); - if(l->array == NULL){ - log(F, "Realloc failed."); - exit(1); - } - - //number of items behind start (circular!) - cpy = l->count - l->capacity + l->start; - - if(cpy > 0){ - memcpy(l->array + l->capacity, l->array, cpy); - memset(l->array, 0, cpy); - } - - l->capacity *= 2; -} - -stack* new_stack(int32_t initial) -{ - return new_generic_list(initial); -} -queue* new_queue(int32_t initial) -{ - return new_generic_list(initial); -} - -void* set_element_with_type_at(list *l, void* obj, int16_t type, int32_t pos) -{ - void* r = NULL; - - if(!l->with_type && type != 0){ log(W, "Setting list element with type %d in a list without type, type will be lost.", type);} - - if(!(pos < l->count && pos >= 0)){ - log(E, "Tried to set element the a list at an invalid position, list-size: %d, position requested: %d.", l->count, pos); - exit(-1); - } - - - if(l->with_type){ - struct list_bucket *b = l->array[(l->start + pos) % l->capacity]; - if(b != NULL) { r = b->element; } - else { - b = alloc(struct list_bucket, 1); - l->array[(l->start + pos) % l->capacity] = b; - } - - b->type = type; - b->element = obj; - } - else{ - r = l->array[(l->start + pos) % l->capacity]; - l->array[(l->start + pos) % l->capacity] = obj; - } - - return r; -} - -void* set_element_at(list* l, void* obj, int32_t pos) -{ - return set_element_with_type_at(l, obj, -1, pos); -} - -void insert_element_with_type_at(list* l, void* obj, int16_t type, int32_t pos){ - int32_t i; - - if(!l->with_type && type != 0){ log(W, "Inserting element with type %d in a list without type, type will be lost.", type);} - - - if(!(pos <= l->count && pos >= 0)){ - log(E, "Tried to insert an element to list at invalid position, list-size: %d, position requested: %d.", l->count, pos); - exit(1); - } - - if(l->count >= l->capacity){ - refactor_generic_list(l); - } - - for(i = l->count - 1; i >= pos; i--){ - int32_t d = (l->start + i) % l->capacity; - int32_t dn = (d+1) % l->capacity; - l->array[dn] = l->array[d]; - } - - if(l->with_type){ - struct list_bucket* b = alloc(struct list_bucket, 1); - b->type = type; - b->element = obj; - l->array[(l->start + pos) % l->capacity] = b; - } - else{ - l->array[(l->start + pos) % l->capacity] = obj; - } - - l->count++; -} - -void insert_element_at(list* l, void* obj, int32_t pos){ - insert_element_with_type_at(l, obj, 0, pos); -} - -void sorted_insert_element_with_type(list* l, void* obj, int16_t type, int(*compare)(void* o1, int16_t type1, void* o2, int16_t type2)){ - int32_t i; - int16_t type_v; - - for(i = 0; i < l->count; i++){ - void* v = get_element_with_type_at(l, i, &type_v); - //printf("%d:%d <> %d:%d => %d\n", ((bc*)obj)->byte, ((bc*)obj)->count, ((bc*)v)->byte, ((bc*)v)->count, compare(obj, type, v, type_v)); - if(compare(obj, type, v, type_v) < 0) break; - } - - insert_element_with_type_at(l, obj, type, i); -} - -void append_element_with_type(list* l, void* obj, int16_t type) -{ - insert_element_with_type_at(l, obj, type, l->count); -} - -void prepend_element_with_type(list* l, void* obj, int16_t type) -{ - if(!l->with_type && type != 0){ log(W, "Inserting element with type %d in a list without type, type will be lost.", type);} - - if(l->count >= l->capacity){ refactor_generic_list(l); } - if(--l->start < 0){ l->start = l->capacity + l->start; }; - - if(l->with_type){ - struct list_bucket *b = alloc(struct list_bucket, 1); - l->array[l->start] = b; - b->type = type; - b->element = obj; - } - else{ - l->array[l->start] = obj; - } - - l->count++; -} - - -void add_element_with_type(list* l, void* obj, int16_t type) -{ - append_element_with_type(l, obj, type); -} - -void add_element(list* l, void* obj) -{ - append_element_with_type(l, obj, 0); -} - -int32_t _remove_element(list* l, void* obj) -{ - int32_t i, d; - - for(i = 0;i < l->count; i++) - { - d = (i + l->start) % l->capacity; - - if(get_element_at(l, i) == obj){ - if(l->with_type){ - free(l->array[d]); - } - l->array[d] = NULL; - - if(d == l->start) { l->start = ++l->start % l->capacity; l->count--; } - else if(i == l->count-1){ l->count--; } - - return i; - } - } - return -1; -} - -static void collapse_generic_list(list* l){ - int32_t i = 0, c = 0, d, e; - for(; i < l->count; i++){ - d = (l->start + i) % l->capacity; - if(l->array[d] == NULL){ - c++; - } - else if(c > 0){ - e = d-c; - if(e < 0) e = l->capacity - e; - l->array[e] = l->array[d]; - } - } - l->count -= c; -} - -int32_t remove_element(list* l, void* obj) -{ - int32_t p = _remove_element(l, obj); - if(p > 0 && p != l->count){ - collapse_generic_list(l); - } - return p; -} - -int32_t remove_all(list* l, void* obj) -{ - int32_t c = 0; - while(_remove_element(l, obj) == -1){ c++; } - if(c > 0){ collapse_generic_list(l); } - - return c; -} - -void* remove_element_at(list* l, int32_t pos) -{ - if(pos >= l->count){ log(W, "Trying to remove object on position (%d) greater than element count (%d).", pos, l->count); return NULL; } - int32_t d = (l->start + pos) % l->capacity; - - void* r; - - if(l->with_type){ - r = ((struct list_bucket*)l->array[d])->element; - - free(l->array[d]); - l->array[d] = NULL; - } - else{ - r = l->array[d]; - } - - if(pos == 0) { - l->start = ++l->start % l->capacity; - l->count--; - } - else if(pos == l->count-1){ - l->count--; - } - else{ - collapse_generic_list(l); - } - - return r; -} - -void* get_element_with_type_at(const list* l, int32_t pos, int16_t* type) -{ - if(pos < 0 || pos >= l->count){ log(W, "Trying to access object on position (%d) outside range (0 to %d).", pos, l->count-1); return NULL; } - - int32_t d = (l->start + pos) % l->capacity; - - void* r; - - if(l->with_type){ - r = ((struct list_bucket*)l->array[d])->element; - if(type != NULL){ *type = ((struct list_bucket*)l->array[d])->type; } - } - else{ - if(type != NULL){ log(W, "Accessing type on a list without type, returned type is undefined.");} - r = l->array[d]; - } - return r; -} - -void* get_element_at(const list* l, int32_t pos){ - return get_element_with_type_at(l, pos, NULL); -} - -int get_element_pos(const list* l, void* el){ - int i; - if(l == NULL) return -1; - - for(i = 0; i < l->count; i++){ - if(get_element_at(l, i) == el) return i; - } - - return -1; -} - -void enqueue_with_type(queue* q, void* obj, int16_t type) -{ - add_element_with_type(q, obj, type); -} - -void enqueue(queue* q, void* obj) -{ - add_element(q, obj); -} - -void* dequeue(queue* q) -{ - return remove_element_at(q, 0); -} - -void push_stack_type(stack* s, void* obj, int16_t type) -{ - add_element_with_type(s, obj, type); -} - -void push_stack(stack* s, void* obj) -{ - add_element(s, obj); -} - -void* pop_stack(stack* s) -{ - return remove_element_at(s, s->count-1); -} - -int16_t peek_element_type_at(list* l, int32_t pos) -{ - if(!l->with_type) { log(W, "Peeking type on a list without type, returned type is ALWAYS 0."); return 0; } - if(pos < 0 || pos >= l->count){ log(W, "Trying to access object on position (%d) outside range (0 to %d).", pos, l->count-1); exit(1); } - int d = (l->start + pos) % l->capacity; - return ((struct list_bucket*)l->array[d])->type; -} - -int16_t peek_stack_type(stack *s) -{ - if(!s->with_type) { log(W, "Peeking type on a stack without type, returned type is ALWAYS 0."); return 0; } - if(s == NULL) - { - log(F, "Stack is not initialized."); - exit(1); - } - - if(s->count == 0) - { - log(F, "Stack is empty."); - exit(1); - } - return ((struct list_bucket*)s->array[s->count-1])->type; -} - -int16_t peek_queue_type(queue *s) -{ - if(!s->with_type) { log(W, "Peeking type on a queue without type, returned type is ALWAYS 0."); return 0; } - if(s == NULL) - { - log(F, "Queue is not initialized."); - exit(1); - } - - if(s->count == 0) - { - log(F, "Queue is empty"); - exit(1); - } - return ((struct list_bucket*)s->array[s->start])->type; -} - -struct generic_list_s *merge_lists(struct generic_list_s *l1, struct generic_list_s *l2) -{ - if(!l2) return l1; - if(!l1) return l2; - - if(l1->with_type && !l2->with_type){ log(F, "List 1 has type information and list 2 does not, cannot merge."); exit(1); } - if(!l1->with_type && l2->with_type){ log(F, "List 2 has type information and list 1 does not, cannot merge."); exit(1); } - - if(l1->count == 0){ - destroy_generic_list(l1); - return l2; - } - else if(l2->count == 0){ - destroy_generic_list(l2); - return l1; - } - - int32_t i; - int32_t new_count = l1->count + l2->count; - - struct generic_list_s *r = new_generic_list(new_count); - - int32_t n_d = 0, d; - for(i = 0; i < l1->count; i++){ - d = (l1->start + i) % l1->capacity; - r->array[n_d++] = l1->array[d]; - } - - for(i = 0; i < l2->count; i++){ - d = (l2->start + i) % l2->capacity; - r->array[n_d++] = l2->array[d]; - } - r->count = l1->count + l2->count; - - //current merge_list implementation depends on the containers of the source lists - //therefor: - l1->count = 0; - l2->count = 0; - - //by placing count at 0 the destroy does not free those containers - destroy_generic_list(l1); - destroy_generic_list(l2); - return r; -} - -/*void __quicksort_generic_list_aux(struct list_bucket** arr, int start, int end) { - if (start < end) { - struct list_bucket* pivot = arr[end]; - int i = start; - int j = end; - while (i != j) { - if ((arr[i]->element) < (pivot->element)) { - i = i + 1; - } - else { - arr[j] = arr[i]; - arr[i] = arr[j-1]; - j = j - 1; - } - } - arr[j] = pivot; - __quicksort_generic_list_aux(arr, start, j-1); - __quicksort_generic_list_aux(arr, j+1, end); - } -} - -void __quicksort_generic_list(list* l) { - __quicksort_generic_list_aux(l->array, 0, l->count - 1); - } - -list* remove_duplicates(list* l){ - if(l == NULL) - return NULL; - if(l->count <= 1) - return l; - - int i; - list* r = new_generic_list(l->capacity); - rebase_generic_list(l); - __quicksort_generic_list(l); - add_element(r, get_element_at(l, 0)); - for(i = 1; i < l->count; i++){ - if(get_element_at(l, i-1) != get_element_at(l, i)){ - add_element(r, get_element_at(l, i)); - } - } - - destroy_generic_list(l); - return r; -}*/ - -list* duplicate_generic_list(const list *l){ - if(!l) return NULL; - list* new; - if(l->with_type){ - new = new_generic_list_with_type(l->capacity); - } - else{ - new = new_generic_list(l->capacity); - } - - int i; - int16_t type; - for(i = 0; i < l->count; i++) - if(l->with_type){ - insert_element_with_type_at(new, get_element_with_type_at(l, i, &type), type, i); - } - else{ - insert_element_at(new, get_element_at(l, i), i); - } - - return new; -} - - -list* exclude_list_from_list(const list* l1, const list* l2){ - if(l2 == NULL || l2->count == 0) return NULL; - if(l1 == NULL || l1->count == 0) return duplicate_generic_list(l2); - - int32_t i; - - list* r = new_generic_list(l2->capacity + l1->capacity); - - int32_t pos; - int16_t _type; - int16_t* type = (l2->with_type)? &_type : NULL; - - void* obj; - - for(i = 0; i < l2->count; i++){ - obj = get_element_with_type_at(l2, i, type); - pos = get_element_pos(l1, obj); - if(pos > 0) append_element_with_type(r, obj, (l2->with_type)? *type : 0); - } - - return r; -} - - -void destroy_generic_list(struct generic_list_s *s) -{ - int32_t i, d; - if(s == NULL) - return; - - if(s->with_type){ - for(i = 0; i < s->count; i++) - { - d = (s->start + i) % s->capacity; - free(s->array[d]); - } - } - - free(s->array); - free(s); -} - -generic_list_iterator* new_generic_list_iterator(struct generic_list_s* l){ - generic_list_iterator* i = alloc(generic_list_iterator, 1); - i->pos = 0; - i->list = l; - return i; -} - -uint8_t generic_list_iterator_has_next(generic_list_iterator* i){ - return (i->list == NULL)? 0 : (i->pos < i->list->count); -} - -void* generic_list_iterator_next(generic_list_iterator* i){ - return get_element_at(i->list, (i->pos)++); -} - -void destroy_generic_list_iterator(generic_list_iterator* i){ - free(i); -} - diff --git a/documentation/Makefile b/documentation/Makefile deleted file mode 100644 index b388161..0000000 --- a/documentation/Makefile +++ /dev/null @@ -1,138 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -gh_pages: html - mv $(BUILDDIR)/html/_static $(BUILDDIR)/html/lxq_static - mv $(BUILDDIR)/html/_sources $(BUILDDIR)/html/lxq_sources - find $(BUILDDIR)/html -type f | xargs sed -ri 's/"(\.\.\/)*_static/"\1lxq_static/' - find $(BUILDDIR)/html -type f | xargs sed -ri 's/"(\.\.\/)*_sources/"\1lxq_sources/' - ./commit.sh - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/libxmlquery.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/libxmlquery.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/libxmlquery" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/libxmlquery" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - diff --git a/documentation/_theme/nature/theme.conf b/documentation/_theme/nature/theme.conf deleted file mode 100644 index 1cc4004..0000000 --- a/documentation/_theme/nature/theme.conf +++ /dev/null @@ -1,4 +0,0 @@ -[theme] -inherit = basic -stylesheet = nature.css -pygments_style = tango diff --git a/documentation/commit.sh b/documentation/commit.sh deleted file mode 100755 index 3220f5d..0000000 --- a/documentation/commit.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -BUILDDIR=_build - -git clone -b gh-pages git@github.com:nullable/libxmlquery.git /tmp/gh_pages -cp -r $BUILDDIR/html/* /tmp/gh_pages/ -pushd /tmp/gh_pages -git add . -git commit -m 'Auto-commit by make gh_pages target' -git push origin gh-pages:gh-pages -popd -rm -rf /tmp/gh_pages \ No newline at end of file diff --git a/documentation/conf.py b/documentation/conf.py deleted file mode 100644 index 03d0565..0000000 --- a/documentation/conf.py +++ /dev/null @@ -1,257 +0,0 @@ -# -*- coding: utf-8 -*- -# -# libxmlquery documentation build configuration file, created by -# sphinx-quickstart on Fri Nov 5 15:13:45 2010. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'libxmlquery' -copyright = u'2010, Frederico Gonçalves, Vasco Fernandes' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.1' -# The full version, including alpha/beta/rc tags. -release = '0.1.4' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'nature' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ['_theme'] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'libxmlquerydoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'libxmlquery.tex', u'libxmlquery Documentation', - u'Frederico Gonçalves, Vasco Fernandes', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'libxmlquery', u'libxmlquery Documentation', - [u'Frederico Gonçalves, Vasco Fernandes'], 1) -] - - -# -- Options for Epub output --------------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = u'libxmlquery' -epub_author = u'Frederico Gonçalves, Vasco Fernandes' -epub_publisher = u'Frederico Gonçalves, Vasco Fernandes' -epub_copyright = u'2010, Frederico Gonçalves, Vasco Fernandes' - -# The language of the text. It defaults to the language option -# or en if the language is not set. -#epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -#epub_identifier = '' - -# A unique identification for the text. -#epub_uid = '' - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_pre_files = [] - -# HTML files shat should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_post_files = [] - -# A list of files that should not be packed into the epub file. -#epub_exclude_files = [] - -# The depth of the table of contents in toc.ncx. -#epub_tocdepth = 3 - -# Allow duplicate toc entries. -#epub_tocdup = True - diff --git a/dom.html b/dom.html new file mode 100644 index 0000000..8006d82 --- /dev/null +++ b/dom.html @@ -0,0 +1,510 @@ + + + + + + + + Document Object Model — libxmlquery v0.1.4 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

Document Object Model

+
+

DOM

+

After the parsing of the xml is done, a DOM structure is created and +can be accessed through a global variable denominated lxq_document. +Bear in mind that this variable is dependent of the current parser. +In other words, if the parser module changes, then the variable name +may also change.

+

The DOM structure is a tree, where each node is an xml element. Since +the input xml has already been validated we know it has only one root +, so the document variable will point to a single node in the dom +tree, the root node (This can be accessed through document->root, but we really recommend the use of get_doc_root()).

+

The dom structure provides flexible and extendable xml document +handling. It has the capability to add, remove and modify elements in +the xml.

+
+

Data types

+
+
+dom_node
+
+ +
+
+struct snode
+
+ +

The structure definition for a dom node is in the file node.h.

+
typedef struct snode{
+ enum node_type type;
+ struct snode* parent;
+ union{
+    struct sroot* attributes;
+    char* value;
+ };
+
+ char* name;
+ char* namespace;
+
+ struct generic_list_s* children;
+}dom_node;
+
+
+

This structure is used to store any kind of entity in an xml file. It can be an element, attribute, cdata or text node. In order to control these different kind of entities, the dom_node has an enumerate field. This field is called node_type .

+
+
+node_type
+
+ +

This enum is defined as:

+
enum node_type {
+  ATTRIBUTE,
+  ELEMENT,
+  TEXT_NODE,
+  CDATA
+};
+
+
+

Each enum represents a different kind of xml entity.

+
+
+doc
+
+ +
+
+struct sdoc
+
+ +

Finally, a document is a structure that points to two dom nodes - The root of the dom tree and a list of xml declarations. Lets look at its definition.

+
+
::
+
+
typedef struct sdoc{
+
struct snode* root; +list* xml_declarations;
+
+

}doc;

+
+
+

Suppose we have the following xml file

+
<?xml version="1.0" ?>
+<x>
+  ...
+</x>
+
+
+

When this xml is parsed, a doc is created with the field xml_declaration pointing to a list that corresponds to ‘<?xml version=”1.0” ?>’ and the root field pointing to a tree that corresponds to the rest of the document.

+
+
+

Function description

+
+
+char* set_namespace(dom_node* node, char* namespace)
+

node The node whose namespace will be set.

+

namespace The namespace to set.

+

This function sets the namespace of the given node. If the node already contained a namespace, a pointer to it will be returned. Otherwise, NULL is returned.

+
+ +
+
+char* set_name(dom_node* node, char* name)
+

node The node whose name will be set.

+

name The name to set.

+

This function sets the name of the given node. If the node already contained a name, a pointer to it will be returned. Otherwise, NULL is returned.

+
+ +
+
+char* set_value(dom_node* node, char* value)
+

node The node whose value will be set.

+

value The value to set.

+

This function sets the value of the given node. If the node already contained a value, a pointer to it will be returned. Otherwise, NULL is returned.

+
+ +
+
+dom_node* set_doc_root(doc* document, struct snode* root)
+

doc The document whose root will be set.

+

root The root to set.

+

This function sets the root of the given document. If the document already contained a root, a pointer to it will be returned. Otherwise, NULL is returned.

+
+ +
+
+dom_node* set_xml_declarations(doc* document, list declarations)
+

doc The document whose xml declarations will be set.

+

declarations The xml declarations to set.

+

This function sets the xml declarations of the given document. If the document already contained xml declarations, a pointer to that list will be returned. Otherwise, NULL is returned.

+
+ +
+
+void set_parent(dom_node* node, dom_node* parent)
+

node The node whose parent will be set.

+

parent The parent to set.

+

This function sets the parent of the given node. If the node already contained a parent, a pointer to it will be returned. Otherwise, NULL is returned.

+
+ +
+
+char* get_namespace(dom_node* node)
+

node The node from which the namespace will be returned.

+

This functions returns the namespace of the given node, or NULL if the node doesn’t contain any.

+
+ +
+
+char* get_name(dom_node* node)
+

node The node from which the names will be returned.

+

This functions returns the names of the given node, or NULL if the node doesn’t contain any.

+
+ +
+
+char* get_value(dom_node* node)
+

node The node from which the value will be returned.

+

This functions returns the value of the given node, or NULL if the node doesn’t contain any.

+
+ +
+
+list* get_xml_declarations(doc* document)
+

document The document from which the xml declarations list will be returned.

+

This functions returns the list of the xml declarations, or NULL if there isn’t any.

+
+ +
+
+dom_node* get_doc_root(doc* document)
+

document The document from which the dom tree will be returned.

+

This functions returns the dom node at the root of the dom tree, or NULL if there isn’t any.

+
+ +
+
+void prepend_child(dom_node* parent, dom_node* child)
+

parent The parent node to whom the child will be prepended.

+

child The child to be prepended.

+

This function inserts a dom node at the head of the children’s list of the dom node given as first argument.

+
+ +
+
+void append_child(dom_node* parent, dom_node* child)
+

parent The parent node to whom the child will be appended.

+

child The child to be appended.

+

This function inserts a dom node at the end of the children’s list of the dom node given as first argument.

+
+ +
+
+void append_children(dom_node* parent, struct generic_list_s* children)
+

parent The parent node to whom the children list will be appended.

+

children The children list to be appended.

+

This functions calls append_child() for each node in the children’s list, passed as the second argument.

+
+ +
+
+void add_attribute(dom_node* node, dom_node* attribute)
+

node The node to whom the attribute will be added.

+

attribute The attribute to add to the node.

+

This function adds an attribute to the node given as the first argument.

+
+ +
+
+doc* new_document(struct snode* xml_declaration)
+

xml_declaration The declaration tree of the document. Can be NULL.

+

This function creates a new document with the given xml declaration.

+
+ +
+
+dom_node* new_element_node(char* name)
+

name The name of the new element node.

+

This function creates a new element node with the given name. The name should correspond to an xml tag.

+
+ +
+
+dom_node* new_text_node(char* text)
+

text The text in the xml document.

+

This function creates a new text node and stores the given text in the value field of the dom node.

+
+ +
+
+dom_node* new_attribute(char* name, char* value)
+

name The name of the attribute.

+

value The value of the attribute.

+

This function creates a new attribute with the given name and value.

+
+ +
+
+dom_node* new_cdata(char* cdata_text)
+

cdata_text The cdata text in the xml document.

+

This function creates a new cdata node and stores the text in the value field.

+
+ +
+
+dom_node* get_child_at(dom_node* parent, int index)
+

parent The node from which the child will be returned.

+

index The index of the child beggining at 0.

+

This function returns the nth child of the parent node. If no child is found, NULL will be returned.

+
+ +
+
+struct generic_list_s* get_children(dom_node* node)
+

node The node from which the children will be returned.

+

This function returns a pointer to the node’s children. Be aware that this function only returns nodes directly below the given argument. If you want the other ones too, consider using get_descedants().

+
+ +
+
+struct generic_list_s* get_descendants(dom_node* node)
+

node The node from which the descedants will be returned.

+

This function returns the descendants of the node. This differs from get_children() because it returns all nodes below the given argument.

+
+ +
+
+struct generic_list_s* get_text_nodes(doc* root)
+

root The document root of the xml.

+

This function traverses the entire dom tree and returns all text nodes in it.

+
+ +
+
+dom_node* get_attribute_by_name(dom_node* node, char* attr_name)
+

node The node from whom the attribute will be returned.

+

attr_name The name of the attribute.

+

This function returns the attribute with the given name, or NULL if there isn’t any.

+
+ +
+
+struct generic_list_s* get_elements_by_name(doc* root, char* name)
+

root The document root of the xml.

+

name The name of the elements to search.

+

This function traverses the entire dom tree and returns all element with the given name.

+
+ +
+
+dom_node* delete_attribute(dom_node* node, char* name)
+

node The node from whom the attribute will be removed.

+

name The name of the attribute to remove.

+

This function deletes the attribute with the given name from the given node. If the node doesn’t contain an attribute with the given name, then nothing will happen.

+
+ +
+
+void remove_node(doc* root, dom_node* node)
+

root The root of the xml document.

+

node The node to remove from the dom tree.

+

This function removes the given node from the given dom tree. Be carefull because it also removes all nodes below the given node. This doesn’t free the given node, so you should keep the pointer to it and free it yourself.

+
+ +
+
+void destroy_dom_node(dom_node* n)
+

n The dom node to be destroyed.

+

This function should be used with caution. This frees the space associated with the given dom node, but it also frees all nodes below it. A simple way to clean the dom tree keeping only the document structure is to pass the root node to this function as follows:

+
#include "node.h"
+#include "lxq_parser.h"
+
+int main(){
+  doc* document = parse_dom("xml_file.xml");
+  //clean the tree but keep my doc structure and xml declaration intact.
+  destroy_dom_node(get_doc_root(document));
+  return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where node.h and lxq_parser.h are kept>
+
+
+
+ +
+
+void destroy_dom_tree(doc* root)
+

root The document to be destroyed.

+

This function does exactly the same thing as destroy_dom_node() but it also frees the space associated with the document structure. As an example consider:

+
#include "node.h"
+#include "lxq_parser.h"
+
+int main(){
+  doc* document = parse_dom("xml_file.xml");
+  destroy_dom_tree(document);
+  return 0;
+}
+
+
+

You may compile it with

+
gcc -o test <above_source_file> -I<folder path where node.h and lxq_parser.h are kept>
+
+
+

If you use a memory leak checker you’ll notice that there are no leaks, so this actually destroys all nodes.

+
+ +
+
+
+
+

Serialize DOM

+

This section explains how to serialize a DOM tree into a string. Currently we support three different types of output format:

+
    +
  • XML - print the DOM tree as XML format.
  • +
  • JSON - print the DOM tree as JavaScript Object Notation format.
  • +
  • YAML - print the DOM tree as YAML Ain’t Markup Language format.
  • +
+

To do this we’ve defined an enumerate as:

+
typedef enum{
+  XML=0,
+  JSON=1,
+  YAML=2
+} serialization_type;
+
+
+

The serializarion is done throw the function:

+
+
+char* node_to_string(dom_node* root, serialization_type t)
+

root The root of the tree to serialize onto a string. Can be any part of the DOM tree.

+

t The type of serialization to do. Must be one of XML, JSON, YAML.

+

The following example shows how to serialize a document onto JSON format. If another one is desired you can change the type of serialization:

+
#include <stdio.h>
+#include "include/node.h"
+#include "include/serialize.h"
+#include "include/lxq_parser.h"
+
+int main(int argc, char** argv){
+  doc* document = parse_xml("some.xml");
+  char* json;
+  json = node_to_string(get_doc_root(document), JSON);
+  printf("%s", json);
+  free(json);
+  return 0;
+}
+
+
+
+ +
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

Parser Module

+

Next topic

+

Querying

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/dom/Makefile b/dom/Makefile deleted file mode 100644 index cc90c13..0000000 --- a/dom/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include ../Makefile.inc - - -OBJS = node.o numbers.o serialize.o huffman.o -includes = ../include/node.h ../include/serializer.h ../include/bitbuffer.h ../includes/huffman.h ../include/byte_buffer.h - - -all: $(OBJS) - -%.o: %.c $(includes) - $(CC) $(CFLAGS) -c $< - -clean: - rm -rf *~ *.out $(OBJS) - diff --git a/dom/README.rst b/dom/README.rst deleted file mode 100644 index a1784a1..0000000 --- a/dom/README.rst +++ /dev/null @@ -1,4 +0,0 @@ -DOM -=== - -This is the source for our DOM tree. diff --git a/dom/huffman.c b/dom/huffman.c deleted file mode 100644 index a9f5569..0000000 --- a/dom/huffman.c +++ /dev/null @@ -1,223 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include "../include/huffman.h" -#include "../include/btree.h" -#include "../include/bitbuffer.h" -#include "../include/stack.h" -#include "../include/byte_buffer.h" - -int compare_bc(void* o1, int16_t t1, void* o2, int16_t t2){ - return ((bc*)o2)->count - ((bc*)o1)->count; -} - -void print_btree(btree* node, int depth){ - int i; - for(i = 0; i++ < depth; printf(" ")); - if(node->left == NULL){ - printf("%c:%d\n", ((bc*)(node->value))->byte, ((bc*)(node->value))->count); - } - else{ - printf("| 0\n"); - print_btree(node->left, depth+1); - } - - for(i = 0; i++ < depth; printf(" ")); - if(node->right == NULL){ - printf("%c:%d\n", ((bc*)(node->value))->byte, ((bc*)(node->value))->count); - } - else{ - printf("| 1\n"); - print_btree(node->right, depth+1); - } -} - - - -void pack_huffman_tree(btree* tree, bitbuffer* bb){ - if(tree->left != NULL && tree->right != NULL){ - append_bit_to_buffer(0, bb); - pack_huffman_tree(tree->left, bb); - append_bit_to_buffer(0, bb); - pack_huffman_tree(tree->right, bb); - append_bit_to_buffer(1, bb); - } - else{ - append_bit_to_buffer(1, bb); - bc* node_bc = (bc*)tree->value; - append_bits_to_buffer(node_bc->byte, 8, bb); - } -} - -btree* unpack_huffman_tree(bitbuffer* packed_tree, int* i){ - btree* tree = new_btree(); - - char bit = get_bit_from_buffer(packed_tree, (*i)++); - if(bit == 0){ - tree->left = unpack_huffman_tree(packed_tree, i); - bit = get_bit_from_buffer(packed_tree, (*i)++); - if(bit == 0) tree->right = unpack_huffman_tree(packed_tree, i); - (*i)++; //next value must be 1 - } - else{ - char value = get_byte_from_buffer(packed_tree, *i); - (*i) += 8; - tree->value = alloc(char, 1); - *((char*)tree->value) = value; - } - - return tree; -} - -void set_translation(btree* node){ - bc* node_bc = (bc*)node->value; - bc *left_bc, *right_bc; - - if(node->left != NULL){ - left_bc = (bc*)node->left->value; - left_bc->bb = duplicate_bitbuffer(node_bc->bb); - append_bit_to_buffer(0, left_bc->bb); - set_translation(node->left); - } - - if(node->right != NULL){ - right_bc = (bc*)node->right->value; - right_bc->bb = duplicate_bitbuffer(node_bc->bb); - append_bit_to_buffer(1, right_bc->bb);; - set_translation(node->right); - } -} - -void print_simple_btree(btree* bt, int depth){ - int i; - if(bt->left != NULL){ - for(i = 0; i++ < depth; printf(" ")); - printf("|\n"); - print_simple_btree(bt->left, depth+1); - } - if(bt->right != NULL){ - for(i = 0; i++ < depth; printf(" ")); - printf("|\n"); - print_simple_btree(bt->right, depth+1); - } - if(bt->value != NULL){ - for(i = 0; i++ < depth; printf(" ")); - printf("'%c'\n", *((char*)bt->value)); - } -} - -char* huffman_decode(bitbuffer* bit_string){ - int* offset = alloc(int, 1); - *offset = 0; - btree* ut = unpack_huffman_tree(bit_string, offset); - - int i = *offset; - - btree* ct = ut; - byte_buffer* bb = new_byte_buffer(bit_string->size / 8); - - for(; i < bit_string->size; i++){ - char b = get_bit_from_buffer(bit_string, i); - if(b == 0) ct = ct->left; - else ct = ct->right; - - if(ct->left == NULL && ct->right == NULL){ - append_bytes_to_buffer(ct->value, bb, 1); - ct = ut; - } - } - - char end = 0; - append_bytes_to_buffer(&end, bb, 1); - return bb->buffer; -} - -bitbuffer* huffman_encode(char* byte_string, int size){ - bc* table = alloc(bc, 256); - int i; - - //initialize - for(i = 0; i < 256; i++){ - table[i].count = 0; - table[i].byte = i; - table[i].bt = NULL; - table[i].bb = NULL; - } - - //count - for(i = 0; i < size; i++){ - table[(int)(byte_string[i])].count++; - } - - //sort - list* l = new_generic_list(256); - for(i = 0; i < 256; i++){ - if(table[i].count == 0) continue; - - sorted_insert_element_with_type(l, table+i, 0, &compare_bc); - } - - - while(l->count > 1){ - int16_t t1 = peek_stack_type(l); - bc* c1 = pop_stack(l); - - int16_t t2 = peek_stack_type(l); - bc* c2 = pop_stack(l); - - bc* parent = alloc(bc, 1); - parent->byte = 0; - parent->count = c1->count + c2->count; - parent->bt = new_btree(); - parent->bt->value = parent; - - if(t1 == 0){ - parent->bt->left = new_btree(); - parent->bt->left->value = c1; - } - else {parent->bt->left = c1->bt; } - - if(t2 == 0){ - parent->bt->right = new_btree(); - parent->bt->right->value = c2; - } - else {parent->bt->right = c2->bt; } - - sorted_insert_element_with_type(l, parent, 1, &compare_bc); - } - - bc* root = pop_stack(l); - root->bb = new_bitbuffer(256); - set_translation(root->bt); - bitbuffer* packed_data = new_bitbuffer(256); - pack_huffman_tree(root->bt, packed_data); - - for(i = 0; i < size; i++){ - append_bitbuffer_to_bitbuffer(table[(int)byte_string[i]].bb, packed_data); - } - - - return packed_data; -} - diff --git a/dom/node.c b/dom/node.c deleted file mode 100644 index 8d4ec40..0000000 --- a/dom/node.c +++ /dev/null @@ -1,414 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include "../include/macros.h" -#include "../include/node.h" - -#define USE_DICT 1 - - - -struct sroot* dictionary = NULL; - -void initialize_dictionary(){ - dictionary = new_rbtree(&ident, &compare_string); -} - -char* get_string_pointer(const char* string){ - char* value = NULL; - if(string == NULL){ return NULL; } - if(USE_DICT){ - if(!dictionary){ initialize_dictionary(); } - value = search_rbtree(dictionary, (const void*)string); - if(value == NULL){ - value = strdup(string); - rb_tree_insert(dictionary, value); - } - } - else{ - value = strdup(string); - } - - //log(I, "%p: '%s' | '%s'", value, value, string); - return value; -} - -char* set_namespace(dom_node* node, const char* namespace){ - char* old; - - if(!namespace) - return NULL; - old = node->namespace; - node->namespace = get_string_pointer(namespace); - - return old; -} - -char* set_name(dom_node* node, char* name){ - char* old; - - if(!name) - return NULL; - - old = node->name; - node->name = get_string_pointer(name); - return (USE_DICT)? NULL: old; -} - -char* set_value(dom_node* node, char* value){ - char* old; - - if(!value) - return NULL; - - if(node->type == ELEMENT){ log(F, "Element node does not support the value attribute."); exit(1); } - - old = node->value; - node->value = get_string_pointer(value); - return (USE_DICT)? NULL: old; -} - -dom_node* set_doc_root(doc* document, struct snode* root){ - dom_node* old; - if(!document) - return NULL; - old = document->root; - document->root = root; - return old; -} - -list* set_xml_declaration(doc* document, list* declarations){ - list* old; - if(!document) - return NULL; - old = document->xml_declarations; - document->xml_declarations = declarations; - return old; -} - -void set_parent(dom_node* node, dom_node* parent){ - node->parent = parent; -} - -char* get_namespace(dom_node* node){ - return node->namespace; -} - -char* get_name(dom_node* node){ - return node->name; -} - -char* get_value(dom_node* node){ - return node->value; -} - -dom_node* get_doc_root(doc* document){ - return document->root; -} - -list* get_xml_declarations(doc* document){ - return document->xml_declarations; -} - -void prepend_child(dom_node* parent, dom_node* child){ - if(child == NULL) { - log(W, "Trying to prepend a NULL child."); - return; - } - if(child->type == ATTRIBUTE){ - log(W, "Trying to prepend attribute %s as child of node %s.", child->name, parent->name); - return; - } - if(parent->children == NULL) - parent->children = new_generic_list(1); - - //log(W, "prepend_child needs to be implemented."); - - prepend_element_with_type(parent->children, child, 0); - child->parent = parent; -} - -void append_child(dom_node* parent, dom_node* child){ - if(child == NULL) { - log(W, "Trying to append a NULL child."); - return; - } - if(child->type == ATTRIBUTE){ - log(W, "Trying to append attribute %s as child of node %s.", child->name, parent->name); - return; - } - /*if(child->parent != NULL){ - remove_element(child->parent->children, child); - }*/ - - if(parent->children == NULL) - parent->children = new_generic_list(1); - add_element(parent->children, child); - child->parent = parent; -} - -const void* dom_node_key(const struct stree_node* node){ - return ((dom_node*) node->node)->name; -} - -void add_attribute(dom_node* node, dom_node* attribute){ - if(attribute == NULL) { - log(W, "Trying to add a NULL attrubute."); - return; - } - if(attribute->type == ATTRIBUTE){ - if(node->attributes == NULL) - node->attributes = new_rbtree(&dom_node_key, &compare_string); - dom_node* older = (dom_node*) rb_tree_insert(node->attributes, attribute); - if(older != NULL) - destroy_dom_node(older); - return; - } - log(W, "Trying to add node %s as attribute of node %s", attribute->name, node->name); - return; -} - -void append_children(dom_node* parent, struct generic_list_s* children){ - int i; - if(children == NULL){ - log(W, "Trying to append NULL children."); - return; - } - if(parent->children == NULL) - parent->children = new_generic_list(16); - - for(i = 0; i < children->count; i++){ - append_child(parent, get_element_at(children, i)); - } - //destroy_generic_list(children); - return; -} - -doc* new_document(list* xml_declarations){ - doc* document = alloc(doc, 1); - set_xml_declaration(document, xml_declarations); - return document; -} - -dom_node* new_element_node(const char* name){ - dom_node* node = alloc(dom_node, 1); - - node->value = NULL; - node->namespace = NULL; - node->attributes = NULL; - node->children = NULL; - node->parent = NULL; - - node->type = ELEMENT; - node->name = get_string_pointer(name); - return node; -} - -dom_node* new_text_node(char* text){ - //dangerous memory optimization - textnode_dom_node* node = alloc(textnode_dom_node, 1); - - //node->namespace = NULL; - //node->attributes = NULL; - //node->children = NULL; - //node->name = NULL; - - node->parent = NULL; - node->type = TEXT_NODE; - node->value = get_string_pointer(text); - return (dom_node*)node; -} - -dom_node* new_attribute(char* name, char* value){ - dom_node* node = alloc(dom_node, 1); - - node->namespace = NULL; - node->attributes = NULL; - node->children = NULL; - - node->type = ATTRIBUTE; - node->name = get_string_pointer(name); - node->value = get_string_pointer(value); - return node; -} - -dom_node* new_cdata(char* cdata_text){ - dom_node* node = alloc(dom_node, 1); - - node->name = NULL; - node->namespace = NULL; - node->attributes = NULL; - node->children = NULL; - - node->type = CDATA; - node->value = get_string_pointer(cdata_text); - return node; -} - -dom_node* get_attribute_by_name(dom_node* node, char* attr_name){ - if(node->attributes == NULL) - return NULL; - - return (dom_node*) search_rbtree(node->attributes, attr_name); -} - -dom_node* get_child_at(dom_node* parent, int index){ - if(parent->children == NULL) - return NULL; - return (dom_node*) get_element_at(parent->children, index); -} - -static void __get_elements_by_name(dom_node* root, char* name, list* lk){ - int it; - - if(root == NULL) - return; - - if(root->type == ELEMENT && strcmp(root->name, name) == 0) - append_element_with_type(lk, root, 0); - - if(root->children != NULL) - for(it = 0; it < root->children->count; it++) - __get_elements_by_name((dom_node*) get_element_at(root->children, it), name, lk); -} - -struct generic_list_s* get_elements_by_name(doc* root, char* name){ - list* lk = new_generic_list(16); - __get_elements_by_name(root->root, name, lk); - return lk; -} - -static void __get_text_nodes(dom_node* root, list* lk){ - int it; - - if(root == NULL) - return; - - if(root->type == TEXT_NODE) - append_element_with_type(lk, root, 0); - - if(root->children != NULL) - for(it = 0; it < root->children->count; it++) - __get_text_nodes((dom_node*) get_element_at(root->children, it), lk); -} - -struct generic_list_s* get_text_nodes(doc* root){ - list* lk = new_generic_list(16); - __get_text_nodes(root->root, lk); - return lk; -} - -list* get_children(dom_node* node){ - return node->children; -} - -list* get_descendants(dom_node* node) -{ - int i; - if(node == NULL) return NULL; - - list* children = get_children(node); - if(children == NULL) return NULL; - - list* descendants = new_generic_list(1); - for(i = 0; i < children->count; i++) - { - dom_node* n = get_element_at(children, i); - if(n->type != ELEMENT) continue; - - list* nd = get_descendants(n); - descendants = merge_lists(descendants, nd); - add_element(descendants, n); - } - - return descendants; -} - -void destroy_dom_node(dom_node* n){ - struct siterator* ti; - int it; - - if( n == NULL) return; - if((n->type == ELEMENT || n->type == ATTRIBUTE) && n->namespace != NULL) - if(!USE_DICT) free(n->namespace); - if((n->type == ELEMENT || n->type == ATTRIBUTE) && n->name != NULL) - if(!USE_DICT) free(n->name); - if((n->type == TEXT_NODE || n->type == CDATA || n->type == ATTRIBUTE) && n->value != NULL) - if(!USE_DICT) free(n->value); - if(n->type == ELEMENT && n->attributes != NULL){ - ti = new_tree_iterator(n->attributes); - while(tree_iterator_has_next(ti)) - destroy_dom_node(tree_iterator_next(ti)); - destroy_iterator(ti); - destroy_rbtree(n->attributes); - } - if(n->type == ELEMENT && n->children != NULL){ - for(it = 0; it < n->children->count; it++) - destroy_dom_node((dom_node*) get_element_at(n->children, it)); - destroy_generic_list(n->children); - } - free(n); -} - -void destroy_dictionary(){ - if(dictionary != NULL){ - struct siterator* ti = new_tree_iterator(dictionary); - while(tree_iterator_has_next(ti)) - free(tree_iterator_next(ti)); - destroy_iterator(ti); - destroy_rbtree(dictionary); - dictionary = NULL; - } -} - -void destroy_dom_tree(doc* root){ - destroy_dom_node(root->root); - if(root->xml_declarations){ - int i; - for(i = 0; i < root->xml_declarations->count; i++){ - destroy_dom_node(get_element_at(root->xml_declarations, i)); - } - destroy_generic_list(root->xml_declarations); - } - - free(root); -} - -dom_node* delete_attribute(dom_node* node, char* name){ - return (dom_node*) rb_tree_delete(node->attributes, name); -} - -void remove_node(doc* root, dom_node* node){ - if(node == root->root){ - root->root = NULL; - return; - } - - remove_element(node->parent->children, node); - return; -} - diff --git a/dom/numbers.c b/dom/numbers.c deleted file mode 100644 index 6b07f43..0000000 --- a/dom/numbers.c +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -/* Copyright 2009 10gen Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* all the numbers that fit in a 4 byte string */ -const char bson_numstrs[1000][4] = { - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", - "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", - "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", - "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", - "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", - "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", - "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", - "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", - "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", - - "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", - "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", - "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", - "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", - "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", - "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", - "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", - "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", - "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", - "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", - - "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", - "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", - "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", - "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", - "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", - "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", - "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", - "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", - "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", - "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", - - "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", - "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", - "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", - "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", - "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", - "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", - "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", - "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", - "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", - "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", - - "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", - "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", - "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", - "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", - "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", - "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", - "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", - "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", - "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", - "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", - - "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", - "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", - "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", - "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", - "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", - "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", - "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", - "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", - "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", - "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", - - "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", - "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", - "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", - "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", - "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", - "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", - "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", - "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", - "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", - "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", - - "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", - "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", - "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", - "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", - "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", - "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", - "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", - "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", - "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", - "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", - - "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", - "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", - "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", - "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", - "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", - "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", - "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", - "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", - "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", - "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", - - "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", - "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", - "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", - "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", - "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", - "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", - "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", - "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", - "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", - "990", "991", "992", "993", "994", "995", "996", "997", "998", "999", -}; diff --git a/dom/serialize.c b/dom/serialize.c deleted file mode 100644 index 8cb6dab..0000000 --- a/dom/serialize.c +++ /dev/null @@ -1,363 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include "../include/byte_buffer.h" -#include "../include/serialize.h" -#include "../include/rbtree.h" - -byte_buffer* __node_list_to_xml(list* l, int depth); -byte_buffer* __node_list_to_json(list* l, int depth); - -byte_buffer* __element_list_to_yaml(list* l, int depth); -byte_buffer* __text_list_to_yaml(list* l, int depth); - -byte_buffer* __attribute_to_xml(dom_node* attr); -byte_buffer* __attribute_to_json(dom_node* attr, int depth); -byte_buffer* __attribute_to_yaml(dom_node* attr, int depth); - -byte_buffer* __dom_node_to_xml(dom_node* n, int depth){ - int i; - byte_buffer* b = new_byte_buffer(16); - - if(!n) - return b; - - switch(n->type){ - case CDATA: - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("value, b); - append_string_to_buffer("]]>\n", b); - break; - case TEXT_NODE: - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer(n->value, b); - append_string_to_buffer("\n", b); - break; - case ELEMENT: - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("<", b); - if(n->namespace != NULL) - { append_string_to_buffer(n->namespace, b); append_string_to_buffer(":", b); } - - append_string_to_buffer(n->name, b); - if(n->attributes != NULL){ - struct siterator *it = new_tree_iterator(n->attributes); - while(tree_iterator_has_next(it)){ - byte_buffer* attr = __attribute_to_xml((dom_node*) tree_iterator_next(it)); - append_buffer_to_buffer(attr, b); - destroy_byte_buffer(attr); - } - destroy_iterator(it); - } - if(n->children != NULL && n->children->count > 0){ - append_string_to_buffer(">\n", b); - byte_buffer* children_xml = __node_list_to_xml(n->children, depth+1); - append_buffer_to_buffer(children_xml, b); - destroy_byte_buffer(children_xml); - - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("namespace != NULL){ append_string_to_buffer(n->namespace, b); append_string_to_buffer(":", b); } - append_string_to_buffer(n->name, b); - append_string_to_buffer(">\n", b); - } - else{ - append_string_to_buffer(" />\n", b); - } - break; - case ATTRIBUTE: - break; - } - return b; -} - -byte_buffer* __dom_element_to_json(dom_node* n, int depth){ - byte_buffer* b = new_byte_buffer(16); - int i; - - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer(n->name, b); - - - if(n->attributes == NULL && n->children == NULL && n->namespace == NULL){ - append_string_to_buffer(": null,\n", b); - return b; - } - else{ - append_string_to_buffer(": {\n", b); - } - - if(n->attributes != NULL){ - struct siterator *it = new_tree_iterator(n->attributes); - while(tree_iterator_has_next(it)){ - byte_buffer* attr = __attribute_to_json((dom_node*) tree_iterator_next(it), depth+1); - append_buffer_to_buffer(attr, b); - destroy_byte_buffer(attr); - } - destroy_iterator(it); - } - - if(n->children != NULL && n->children->count > 0){ - byte_buffer* children_xml = __node_list_to_json(n->children, depth+1); - append_buffer_to_buffer(children_xml, b); - destroy_byte_buffer(children_xml); - } - - if(n->namespace != NULL){ - for(i = 0; i < depth+1; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("#ns: \"", b); - append_string_to_buffer(n->namespace, b); - append_string_to_buffer("\",\n", b); - } - - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("},\n", b); - - return b; -} - -byte_buffer* __dom_element_to_yaml(dom_node* n, int depth){ - byte_buffer* b = new_byte_buffer(16); - int i; - - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer(n->name, b); - - - if(n->attributes == NULL && n->children == NULL && n->namespace == NULL){ - append_string_to_buffer(": null\n", b); - return b; - } - else{ - append_string_to_buffer(":\n", b); - } - - if(n->attributes != NULL){ - for(i = 0; i < depth+1; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("- !attributes\n", b); - struct siterator *it = new_tree_iterator(n->attributes); - i = 0; - while(tree_iterator_has_next(it)){ - byte_buffer* attr = __attribute_to_yaml((dom_node*) tree_iterator_next(it), depth+2); - append_buffer_to_buffer(attr, b); - destroy_byte_buffer(attr); - } - destroy_iterator(it); - } - - if(n->children != NULL && n->children->count > 0){ - for(i = 0; i < depth+1; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("- !children\n", b); - byte_buffer* children_xml = __element_list_to_yaml(n->children, depth+2); - append_buffer_to_buffer(children_xml, b); - destroy_byte_buffer(children_xml); - } - - if(n->children != NULL && n->children->count > 0){ - for(i = 0; i < depth+1; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("- !text >\n", b); - byte_buffer* children_xml = __text_list_to_yaml(n->children, depth+2); - append_buffer_to_buffer(children_xml, b); - destroy_byte_buffer(children_xml); - } - - if(n->namespace != NULL){ - for(i = 0; i < depth+1; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("- !ns ", b); - append_string_to_buffer(n->namespace, b); - append_string_to_buffer("\n", b); - } - - return b; -} - -byte_buffer* __dom_node_to_json(dom_node* n, int depth){ - int i; - byte_buffer* b = new_byte_buffer(16); - byte_buffer* node_json; - - if(!n) - return b; - - switch(n->type){ - case CDATA: - case TEXT_NODE: - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer("\"#text\": \"", b); - append_string_to_buffer(n->value, b); - append_string_to_buffer("\",\n", b); - break; - case ELEMENT: - node_json = __dom_element_to_json(n, depth); - append_buffer_to_buffer(node_json, b); - destroy_byte_buffer(node_json); - break; - case ATTRIBUTE: - break; - } - return b; -} - -byte_buffer* __dom_node_to_yaml(dom_node* n, int depth){ - int i; - byte_buffer* b = new_byte_buffer(16); - - if(!n) - return b; - - byte_buffer* node_yaml; - switch(n->type){ - case CDATA: - case TEXT_NODE: - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer(n->value, b); - append_string_to_buffer("\n", b); - break; - case ELEMENT: - node_yaml = __dom_element_to_yaml(n, depth); - append_buffer_to_buffer(node_yaml, b); - destroy_byte_buffer(node_yaml); - break; - case ATTRIBUTE: - break; - } - return b; -} - -byte_buffer* __node_list_to_xml(list* l, int depth){ - byte_buffer* b = new_byte_buffer(16); - byte_buffer* element_buffer; - int i; - for(i = 0; i < l->count; i++){ - element_buffer = __dom_node_to_xml(get_element_at(l, i), depth); - append_buffer_to_buffer(element_buffer, b); - destroy_byte_buffer(element_buffer); - } - return b; -} - -byte_buffer* __node_list_to_json(list* l, int depth){ - byte_buffer* b = new_byte_buffer(16); - byte_buffer* element_buffer; - int i; - for(i = 0; i < l->count; i++){ - element_buffer = __dom_node_to_json(get_element_at(l, i), depth); - append_buffer_to_buffer(element_buffer, b); - destroy_byte_buffer(element_buffer); - } - return b; -} - -byte_buffer* __element_list_to_yaml(list* l, int depth){ - byte_buffer* b = new_byte_buffer(16); - int i; - byte_buffer* element_buffer; - for(i = 0; i < l->count; i++){ - if(((dom_node*)get_element_at(l, i))->type == ELEMENT){ - element_buffer = __dom_node_to_yaml(get_element_at(l, i), depth); - append_buffer_to_buffer(element_buffer, b); - destroy_byte_buffer(element_buffer); - } - } - return b; -} - -byte_buffer* __text_list_to_yaml(list* l, int depth){ - byte_buffer* b = new_byte_buffer(16); - int i; - byte_buffer* element_buffer; - for(i = 0; i < l->count; i++){ - if(((dom_node*)get_element_at(l, i))->type == TEXT_NODE){ - element_buffer = __dom_node_to_yaml(get_element_at(l, i), depth); - append_buffer_to_buffer(element_buffer, b); - destroy_byte_buffer(element_buffer); - } - } - return b; -} -//char* __node_list_to_yaml(list* l, char* buffer, int depth); - -byte_buffer* __attribute_to_xml(dom_node* attr){ - byte_buffer* b = new_byte_buffer(16); - - append_string_to_buffer(" ", b); - if(attr->namespace != NULL){ - append_string_to_buffer(attr->namespace, b); - append_string_to_buffer(":", b); - } - append_string_to_buffer(attr->name, b); - append_string_to_buffer("=\"", b); - append_string_to_buffer(attr->value, b); - append_string_to_buffer("\"", b); - return b; -} - -byte_buffer* __attribute_to_json(dom_node* attr, int depth){ - byte_buffer* b = new_byte_buffer(16); - int i; - - for(i = 0; i < depth; i++){ - append_string_to_buffer(" ", b); - } - append_string_to_buffer(attr->name, b); - append_string_to_buffer(": \"", b); - append_string_to_buffer(attr->value, b); - append_string_to_buffer("\",\n", b); - return b; -} - -byte_buffer* __attribute_to_yaml(dom_node* attr, int depth){ - byte_buffer* b = new_byte_buffer(16); - int i; - - for(i = 0; i < depth; i++){ append_string_to_buffer(" ", b); } - append_string_to_buffer(attr->name, b); - append_string_to_buffer(": \"", b); - append_string_to_buffer(attr->value, b); - append_string_to_buffer("\"\n", b); - return b; -} - -char* node_to_string(dom_node* root, serialization_type t){ - byte_buffer* b; - char* buff; - switch(t){ - case XML: - b = __dom_node_to_xml(root, 0); - break; - case JSON: - b = __dom_node_to_json(root, 0); - break; - case YAML: - b = __dom_node_to_yaml(root, 0); - break; - } - append_bytes_to_buffer("\0", b, 1); - buff = b->buffer; - free(b); - return buff; -} - diff --git a/genindex.html b/genindex.html new file mode 100644 index 0000000..e00f04a --- /dev/null +++ b/genindex.html @@ -0,0 +1,297 @@ + + + + + + + + Index — libxmlquery v0.1.4 documentation + + + + + + + + + + + +
+
+
+
+ + +

Index

+ +
+ _ | A | D | E | G | I | L | M | N | P | R | S | T | X +
+

_

+ + +
+
__alloc (C function)
+
+ +

A

+ + + +
+
add_attribute (C function)
+
add_element (C function)
+
add_element_with_type (C function)
+
alloc (C macro)
+
+
append_child (C function)
+
append_children (C function)
+
append_element_with_type (C function)
+
+ +

D

+ + + +
+
delete_attribute (C function)
+
dequeue (C function)
+
destroy_dom_node (C function)
+
destroy_dom_tree (C function)
+
destroy_generic_list (C function)
+
destroy_generic_list_iterator (C function)
+
+
destroy_iterator (C function)
+
destroy_rbtree (C function)
+
doc (C type)
+
dom_node (C type)
+
duplicate_generic_list (C function)
+
+ +

E

+ + + +
+
enqueue (C function)
+
+
enqueue_with_type (C function)
+
+ +

G

+ + + +
+
generic_list_get_count (C function)
+
generic_list_is_empty (C function)
+
generic_list_iterator_has_next (C function)
+
generic_list_iterator_next (C function)
+
generic_list_s (C type)
+
get_attribute_by_name (C function)
+
get_child_at (C function)
+
get_children (C function)
+
get_descendants (C function)
+
get_doc_root (C function)
+
+
get_element_at (C function)
+
get_element_pos (C function)
+
get_element_with_type_at (C function)
+
get_elements_by_name (C function)
+
get_name (C function)
+
get_namespace (C function)
+
get_text_nodes (C function)
+
get_value (C function)
+
get_xml_declarations (C function)
+
+ +

I

+ + + +
+
insert_element_at (C function)
+
+
insert_element_with_type_at (C function)
+
+ +

L

+ + + +
+
list (C type)
+
list_bucket (C type)
+
+
log (C macro)
+
+ +

M

+ + +
+
merge_lists (C function)
+
+ +

N

+ + + +
+
new_attribute (C function)
+
new_cdata (C function)
+
new_document (C function)
+
new_element_node (C function)
+
new_generic_list (C function)
+
new_generic_list_iterator (C function)
+
new_queue (C function)
+
+
new_rbtree (C function)
+
new_simple_rbtree (C function)
+
new_stack (C function)
+
new_text_node (C function)
+
new_tree_iterator (C function)
+
node_to_string (C function)
+
node_type (C type)
+
+ +

P

+ + + +
+
parse_file (C function)
+
parse_string (C function)
+
parse_xml (C function)
+
parse_xml_from_string (C function)
+
peek_element_type_at (C function)
+
peek_queue_type (C function)
+
+
peek_stack_type (C function)
+
pop_stack (C function)
+
prepend_child (C function)
+
prepend_element_with_type (C function)
+
push_stack (C function)
+
push_stack_type (C function)
+
+ +

R

+ + + +
+
rb_tree_delete (C function)
+
rb_tree_insert (C function)
+
register_custom_filter (C function)
+
register_simple_custom_filter (C function)
+
remove_all (C function)
+
+
remove_duplicates (C function)
+
remove_element (C function)
+
remove_element_at (C function)
+
remove_node (C function)
+
+ +

S

+ + + +
+
sdoc (C type)
+
search_rbtree (C function)
+
set_doc_root (C function)
+
set_element_at (C function)
+
set_element_with_type_at (C function)
+
set_name (C function)
+
set_namespace (C function)
+
set_parent (C function)
+
+
set_value (C function)
+
set_xml_declarations (C function)
+
siterator (C type)
+
snode (C type)
+
sorted_insert_element_with_type (C function)
+
sroot (C type)
+
stree_node (C type)
+
+ +

T

+ + + +
+
tree_iterator (C type)
+
tree_iterator_has_next (C function)
+
tree_iterator_next (C function)
+
+
tree_node (C type)
+
tree_root (C type)
+
+ +

X

+ + +
+
xmlquery_query (C function)
+
+ + + +
+
+
+
+
+ + + + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/include/bitbuffer.h b/include/bitbuffer.h deleted file mode 100644 index b6aa798..0000000 --- a/include/bitbuffer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __BITBUFFER_H__ -#define __BITBUFFER_H__ - - -typedef struct bitbuffer_s{ - char* buffer; - //in bytes - int capacity; - - //in bits - int size; -} bitbuffer; - -extern bitbuffer* new_bitbuffer(int byte_size); -extern bitbuffer* duplicate_bitbuffer(bitbuffer* bb); -extern void append_bit_to_buffer(char c, bitbuffer* bb); -extern void append_bits_to_buffer(char c, int bit_count, bitbuffer* bb); -extern void append_bitbuffer_to_bitbuffer(const bitbuffer* from, bitbuffer* to); -extern char get_bit_from_buffer(const bitbuffer* bb, int offset); -extern char get_byte_from_buffer(const bitbuffer* bb, int offset); - -#endif - diff --git a/include/btree.h b/include/btree.h deleted file mode 100644 index abff8b2..0000000 --- a/include/btree.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __BTREE_H__ -#define __BTREE_H__ - -#include "macros.h" -#include "stdlib.h" - -typedef struct btree_s{ - void* value; - struct btree_s* left; - struct btree_s* right; -} btree; - -//typedef struct btree_iterator_s{ -// btree* cur; -// int pos; -//} btree_iterator; - -btree* new_btree(); - -#endif - diff --git a/include/byte_buffer.h b/include/byte_buffer.h deleted file mode 100644 index 3ff9c35..0000000 --- a/include/byte_buffer.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __BYTE_BUFFER_H__ -#define __BYTE_BUFFER_H__ -typedef struct bb_s{ - char* buffer; - int capacity; - int size; -} byte_buffer; - -extern void destroy_byte_buffer(byte_buffer* bb); -extern byte_buffer* new_byte_buffer(int initial); -extern void append_string_to_buffer(const char* s, byte_buffer* b); -extern void append_bytes_to_buffer(const char* bytes, byte_buffer* b, size_t size); -extern void append_buffer_to_buffer(byte_buffer* b2, byte_buffer* b); - -#endif diff --git a/include/custom_selectors.h b/include/custom_selectors.h deleted file mode 100644 index 8348f8a..0000000 --- a/include/custom_selectors.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __CUSTOM_SELECTORS_H__ -#define __CUSTOM_SELECTORS_H__ - -#include "stack.h" -#include "node.h" - - -typedef struct custom_filter_s{ - char* name; - struct{ - int (*simple)(dom_node* node); - int (*complex)(dom_node* node, list* args); - } function; -} custom_filter; - -typedef struct custom_operator_s{ - char* name; - struct{ - list* (*simple)(list* nodes); - list* (*complex)(list* nodes, list* args); - } function; -} custom_operator; - -/* registers */ - -extern void register_simple_custom_filter(const char* name, int (*filter)(dom_node* node)); -extern void register_custom_filter(const char* name, int (*filter)(dom_node* node, list* args)); -extern void register_simple_custom_operator(const char* name, list* (*operator)(list* nodes)); - -/* getters */ - -extern int (*get_simple_custom_filter_by_name(const char* name))(dom_node*); -extern int (*get_custom_filter_by_name(const char* name))(dom_node*, list* args); -extern list* (*get_simple_custom_operator_by_name(const char* name))(list*); - -/* destroys*/ - -extern void destroy_custom_filters(); -extern void destroy_custom_operators(); - -/* extend operators */ - -extern void register_extended_operators(); - -#endif - diff --git a/include/eregex.h b/include/eregex.h deleted file mode 100644 index 7aedee7..0000000 --- a/include/eregex.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __EREGEX_H__ -#define __EREGEX_H__ -extern int match(const char *string, char *pattern, int ignore_case); -#endif diff --git a/include/huffman.h b/include/huffman.h deleted file mode 100644 index 98d4528..0000000 --- a/include/huffman.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __HUFFMAN_H__ -#define __HUFFMAN_H__ - -#include "btree.h" -#include "bitbuffer.h" - -typedef struct byte_count{ - int count; - char byte; - btree* bt; - bitbuffer* bb; -} bc; - -extern bitbuffer* huffman_encode(char* byte_string, int size); -extern char* huffman_decode(bitbuffer* bit_string); - -#endif - diff --git a/include/lxq_parser.h b/include/lxq_parser.h deleted file mode 100644 index 4bfc641..0000000 --- a/include/lxq_parser.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __DOM_PARSER_H__ -#define __DOM_PARSER_H__ - -#include "node.h" - -extern doc* parse_xml(char* filename); -extern list* parse_query(const char* query); -extern doc* parse_xml_from_string(const char* xmlstring); -#endif diff --git a/include/macros.h b/include/macros.h deleted file mode 100644 index aa1bf83..0000000 --- a/include/macros.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __MACROS_H__ -#define __MACROS_H__ - -#include - -#ifdef DEBUG -#include -#define log(level, format, ...) \ - do{ \ - fprintf(stderr, "%s %s:%d: ", level, __FILE__, __LINE__); \ - fprintf(stderr, format, ## __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - }while(0) -#else -#define log(level, str, ...) -#endif - -#define I "\x1B[1;34;34m[INFO]\x1B[0;0;0m" -#define W "\x1B[1;33;33m[WARNNING]\x1B[0;0;0m" -#define E "\x1B[1;31;31m[ERROR]\x1B[0;0;0m" -#define F "\x1B[1;31;31m[FATAL ERROR]\x1B[0;0;0m" - -#define alloc(type, how_many) \ - (type *) __alloc(malloc(how_many * sizeof(type))); - -static inline void* __alloc(void* x){ - if(x) - return x; - log(F,"malloc failed."); - exit(1); - return 0; -} - -#endif - diff --git a/include/node.h b/include/node.h deleted file mode 100644 index ca6350a..0000000 --- a/include/node.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __NODE_H__ -#define __NODE_H__ - -#include "rbtree.h" -#include "stack.h" - -enum node_type { - ATTRIBUTE, - ELEMENT, - TEXT_NODE, - CDATA -}; - -typedef struct textnode_s{ - enum node_type type; - struct snode* parent; - char* value; -} textnode_dom_node; - - -typedef struct snode{ - enum node_type type; - struct snode* parent; - union{ - struct sroot* attributes; - char* value; - }; - - char* name; - char* namespace; - - struct generic_list_s* children; -}dom_node; - -typedef struct sdoc{ - struct snode* root; - list* xml_declarations; -}doc; - -extern char* set_namespace(dom_node* node, const char* namespace); -extern char* set_name(dom_node* node, char* name); -extern char* set_value(dom_node* node, char* value); -extern dom_node* set_doc_root(doc* document, struct snode* root); -extern list* set_xml_declarations(doc* document, list* declarations); -extern void set_parent(dom_node* node, dom_node* parent); - -extern char* get_namespace(dom_node* node); -extern char* get_name(dom_node* node); -extern char* get_value(dom_node* node); -extern list* get_xml_declarations(doc* document); -extern dom_node* get_doc_root(doc* document); - -extern void prepend_child(dom_node* parent, dom_node* child); -extern void append_child(dom_node* parent, dom_node* child); -extern void append_children(dom_node* parent, struct generic_list_s* children); -extern void add_attribute(dom_node* node, dom_node* attribute); - -extern doc* new_document(list* xml_declarations); -extern dom_node* new_element_node(const char* name); -extern dom_node* new_text_node(char* text); -extern dom_node* new_attribute(char* name, char* value); -extern dom_node* new_cdata(char* cdata_text); - -extern dom_node* get_child_at(dom_node* parent, int index); -extern struct generic_list_s* get_children(dom_node* node); -extern struct generic_list_s* get_descendants(dom_node* node); -extern struct generic_list_s* get_text_nodes(doc* root); -extern dom_node* get_attribute_by_name(dom_node* node, char* attr_name); -extern struct generic_list_s* get_elements_by_name(doc* root, char* name); - -extern dom_node* delete_attribute(dom_node* node, char* name); -extern void remove_node(doc* root, dom_node* node); - -extern void destroy_dom_node(dom_node* n); -extern void destroy_dom_tree(doc* root); -extern void destroy_dictionary(); -#endif - diff --git a/include/query_parser.h b/include/query_parser.h deleted file mode 100644 index 618990b..0000000 --- a/include/query_parser.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __QUERY_PARSER_H__ -#define __QUERY_PARSER_H__ - -#define LXQ_RELATION_TYPE 0 -#define LXQ_SELECTOR_TYPE 1 - -#include "stack.h" - -struct selector_s; - -typedef struct match_value_s{ - char* value; - int op; -} match_value; - -typedef struct attr_selector_s{ - match_value* name; - match_value* value; -} attr_selector; - -typedef struct step_s{ int multiplier; int offset; } step; - -typedef struct filter_selector_s{ - int op; - char* name; - list* args; - struct { - step* s; - struct generic_list_s* selector; - } value; -} filter_selector; - -typedef struct selector_s{ - match_value* id; - stack* attrs; - stack* filters; -} selector; - -extern selector* new_selector(match_value* id); -extern attr_selector* new_attr_value_selector(match_value* name, match_value* value); -extern filter_selector* new_filter(int filter); -extern match_value* new_match_value(const char* value, int op); -extern match_value* new_match_value_no_strdup(char* value, int op); - -extern void destroy_selector(selector* s); -extern void destroy_filter_selector(filter_selector* fs); -extern void destroy_attr_selector(attr_selector* as); - -extern match_value* make_operators(char* str, int op); -#endif - diff --git a/include/query_runner.h b/include/query_runner.h deleted file mode 100644 index c1b35e0..0000000 --- a/include/query_runner.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __QUERY_RUNNER_H__ -#define __QUERY_RUNNER_H__ - -#include "stack.h" -#include "node.h" - -extern list* query(const char*, dom_node*); - -#endif - diff --git a/include/rbtree.h b/include/rbtree.h deleted file mode 100644 index c9f0f02..0000000 --- a/include/rbtree.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __RBTREE_H__ -#define __RBTREE_H__ - -#define RED 1 -#define BLACK 2 - -#include -#include "macros.h" - -typedef struct stree_node{ - void* node; - - uint8_t color; - - struct stree_node* parent; - struct stree_node* left; - struct stree_node* right; -}tree_node; - -typedef struct sroot{ - struct stree_node* root; - const void* (*key)(const struct stree_node* node); - int64_t (*compare)(const void* keyA, const void* keyB); -}tree_root; - -typedef struct siterator{ - struct stree_node* current; -}tree_iterator; - -extern tree_root* new_simple_rbtree(); -extern tree_root* new_rbtree(const void* (*key_function_pointer)(const struct stree_node* node), - int64_t (*compare_function_pointer)(const void* keyA, const void* keyB)); -extern void* rb_tree_insert(tree_root* root, void* node); -extern void* rb_tree_delete(tree_root* root, void* key); -extern void* search_rbtree(const tree_root* root, const void* key); -extern void destroy_rbtree(tree_root* root); - -extern tree_iterator* new_tree_iterator(tree_root* root); -extern uint8_t tree_iterator_has_next(tree_iterator* it); -extern void* tree_iterator_next(tree_iterator* it); -extern void destroy_iterator(tree_iterator* it); - -extern const void* ident(const struct stree_node* o); -extern int64_t compare_string(const void* keyA, const void* keyB); -#endif - diff --git a/include/serialize.h b/include/serialize.h deleted file mode 100644 index 5148bc8..0000000 --- a/include/serialize.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef _LXQ_SERIALIZE_H_ -#define _LXQ_SERIALIZE_H_ - -#include -#include -#include "node.h" - -typedef enum{ - XML=0, - JSON=1, - YAML=2 -} serialization_type; - -extern char* node_to_string(dom_node* root, serialization_type t); -#endif - diff --git a/include/stack.h b/include/stack.h deleted file mode 100644 index 2272377..0000000 --- a/include/stack.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -Copyright (c) 2010 Frederico Gonçalves, Vasco Fernandes - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#ifndef __STACK_H__ -#define __STACK_H__ - -#include - -struct list_bucket -{ - int16_t type; - void* element; -}; - -typedef struct generic_list_s{ - void** array; - int8_t with_type; - int32_t start; - int32_t count; - int32_t capacity; -} list; - -typedef struct generic_list_iterator_s{ - uint32_t pos; - struct generic_list_s* list; -} generic_list_iterator; - -typedef struct generic_list_s stack; -typedef struct generic_list_s queue; - -extern uint8_t generic_list_is_empty(struct generic_list_s* l); -extern int32_t generic_list_get_count(struct generic_list_s* l); - -extern struct generic_list_s *new_generic_list(int32_t initial); -extern struct generic_list_s *new_generic_list_with_type(int32_t initial); -extern stack* new_stack(int32_t initial); -extern queue* new_queue(int32_t initial); - -extern void* set_element_with_type_at(list *l, void* obj, int16_t type, int32_t pos); -extern void* set_element_at(list *l, void* obj, int32_t pos); - -extern void insert_element_with_type_at(list* l, void* obj, int16_t type, int32_t pos); -extern void insert_element_at(list* l, void* obj, int32_t pos); - -extern void sorted_insert_element_with_type(list* l, void* obj, int16_t type, int(*compare)(void* o1, int16_t type1, void* o2, int16_t type2)); - -extern void append_element_with_type(list* l, void* obj, int16_t type); -extern void prepend_element_with_type(list* l, void* obj, int16_t type); - -extern void add_element_with_type(list* l, void* obj, int16_t type); -extern void add_element(list* l, void* obj); - -extern void* get_element_at(const list* l, int32_t pos); -extern void* get_element_with_type_at(const list* l, int32_t pos, int16_t* type); - -extern int get_element_pos(const list* l, void* el); - -extern int32_t remove_element(list *l, void* obj); -extern int32_t remove_all(list *l, void* obj); -extern void* remove_element_at(list* l, int32_t pos); - -extern void enqueue_with_type(queue* q, void* obj, int16_t type); -extern void enqueue(queue* q, void* obj); -extern void* dequeue(queue* q); - -extern void push_stack_type(stack* s, void* obj, int16_t type); -extern void push_stack(stack* s, void* obj); -extern void* pop_stack(stack* s); - -extern list* remove_duplicates(list* l); - -extern int16_t peek_element_type_at(list* l, int32_t pos); -extern int16_t peek_stack_type(stack *s); -extern int16_t peek_queue_type(queue *s); - -extern struct generic_list_s *merge_lists(struct generic_list_s *l1, struct generic_list_s *l2); - -extern struct generic_list_s *duplicate_generic_list(const struct generic_list_s*); -extern void destroy_generic_list(struct generic_list_s *s); - -extern generic_list_iterator* new_generic_list_iterator(struct generic_list_s*); -extern uint8_t generic_list_iterator_has_next(generic_list_iterator* i); -extern void* generic_list_iterator_next(generic_list_iterator* i); -extern void destroy_generic_list_iterator(generic_list_iterator* i); -#endif - diff --git a/include/y.tab.h b/include/y.tab.h deleted file mode 100644 index 7af958b..0000000 --- a/include/y.tab.h +++ /dev/null @@ -1,147 +0,0 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - START_EL = 258, - END_EL = 259, - SLASH = 260, - SCUSTOM_FILTER = 261, - WORD = 262, - TEXT = 263, - CDATA_TOK = 264, - REGEX = 265, - CUSTOM_FILTER = 266, - CUSTOM_OPERATOR = 267, - CUSTOM_RELATION_OPERATOR = 268, - ALL = 269, - SPACE = 270, - END_REGEXI = 271, - NO_OP = 272, - EQUAL_OP = 273, - WSSV_OP = 274, - STARTSW_OP = 275, - ENDSW_OP = 276, - CONTAINS_OP = 277, - REGEX_OP = 278, - REGEXI_OP = 279, - DSV_OP = 280, - NOTEQUAL_OP = 281, - EVEN = 282, - ODD = 283, - NTH_CHILD_FILTER = 284, - NTH_LAST_CHILD_FILTER = 285, - FIRST_CHILD_FILTER = 286, - LAST_CHILD_FILTER = 287, - ONLY_CHILD_FILTER = 288, - EMPTY_FILTER = 289, - NOT_FILTER = 290, - DIGITS = 291 - }; -#endif -/* Tokens. */ -#define START_EL 258 -#define END_EL 259 -#define SLASH 260 -#define SCUSTOM_FILTER 261 -#define WORD 262 -#define TEXT 263 -#define CDATA_TOK 264 -#define REGEX 265 -#define CUSTOM_FILTER 266 -#define CUSTOM_OPERATOR 267 -#define CUSTOM_RELATION_OPERATOR 268 -#define ALL 269 -#define SPACE 270 -#define END_REGEXI 271 -#define NO_OP 272 -#define EQUAL_OP 273 -#define WSSV_OP 274 -#define STARTSW_OP 275 -#define ENDSW_OP 276 -#define CONTAINS_OP 277 -#define REGEX_OP 278 -#define REGEXI_OP 279 -#define DSV_OP 280 -#define NOTEQUAL_OP 281 -#define EVEN 282 -#define ODD 283 -#define NTH_CHILD_FILTER 284 -#define NTH_LAST_CHILD_FILTER 285 -#define FIRST_CHILD_FILTER 286 -#define LAST_CHILD_FILTER 287 -#define ONLY_CHILD_FILTER 288 -#define EMPTY_FILTER 289 -#define NOT_FILTER 290 -#define DIGITS 291 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 1676 of yacc.c */ -#line 104 "parser.y" - - char * string; - struct snode* dn; - int digits; - struct attr_selector_s* attrselector; - struct step_s* s; - int token; - struct filter_selector_s* fa; - struct generic_list_s* q; - struct selector_s* sel; - struct match_value_s* mv; - - - -/* Line 1676 of yacc.c */ -#line 139 "y.tab.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -extern YYSTYPE yylval; - - diff --git a/index.html b/index.html new file mode 100644 index 0000000..f6c6b44 --- /dev/null +++ b/index.html @@ -0,0 +1,137 @@ + + + + + + + + libxmlquery documentation — libxmlquery v0.1.4 documentation + + + + + + + + + + + + +
+
+
+
+ +
+

libxmlquery documentation

+

libxmlquery is a colection of C functions to help parse, create and +query xml documents.

+

If you are new to libxmlquery start by reading the +Tutorial.

+ +

You may also find specific object documentation in the Index.

+
+ + +
+
+
+
+
+

Next topic

+

Tutorial

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/install.sh b/install.sh deleted file mode 100755 index 2fef04a..0000000 --- a/install.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash - -if [ "$(id -u)" != "0" ] -then - echo "You must run install as super user" - exit 1 -fi - -function install { - if [ -d include/ -a -f libxmlquery.so ] - then - if [ -d /etc/ld.so.conf.d/ ] - then - echo "/usr/lib" > /etc/ld.so.conf.d/libxmlquery.conf - fi - - cp libxmlquery.so /usr/lib/ - cp xmlquery /usr/bin/ - chmod -x /usr/lib/libxmlquery.so - - if [ ! -e /usr/include/xmlquery ] - then - mkdir /usr/include/xmlquery - fi - cp -r include/* /usr/include/xmlquery - else - echo "Unable to find libxmlquery header files or libxmlquery.so. Header files should be in ./include dir and libxmlquery.so in ./ ." - fi -} - -function uninstall { - if [ -d /etc/ld.so.conf.d/ ] - then - rm -f /etc/ld.so.conf.d/libxmlquery.conf - fi - - rm -f /usr/lib/libxmlquery.so - rm -rf /usr/include/xmlquery/ -} - -if [ $# -eq 0 ] -then - install -else - if [ "$1" == "-u" ] - then - uninstall - else - echo "Unrecognized options: $*" - fi -fi - diff --git a/documentation/index.rst b/lxq_sources/_sources/index.txt similarity index 100% rename from documentation/index.rst rename to lxq_sources/_sources/index.txt diff --git a/lxq_sources/_sources/querying.txt b/lxq_sources/_sources/querying.txt new file mode 100644 index 0000000..a78943d --- /dev/null +++ b/lxq_sources/_sources/querying.txt @@ -0,0 +1,102 @@ +.. highlight:: c + +======== +Querying +======== + +Querying xml nodes to provide quick *random* access to inner nodes is +implemented through `CSS3 selectors `_. + +.. note:: + `CSS `_ stands for + cascading style sheets, it is primarily used for styling (x)html documents + as method to separate content from presentation. + +The CSS3 selectors specification is a `W3C `_ proposed +recomendation widely implemented by most modern browsers, it has also been used, +in its current and earlier forms (CSS and CSS2), by web developers for over 13 +years. + +The W3C recomendation does not tie CSS rules to the presentation of of (x)html +documents, in fact it does define it as a query language capable of selecting +xml/html nodes. With the rise in popularity of AJAX technologies several +javascript libraries became widely used, these libraries (most notabily +`JQuery `_) first proposed the utilization of CSS rules +not only for presentation but also to help manipulation and transversion of the +DOM. + +This library embraces CSS rules as a better/simpler alternative to manual +transversion as well as other W3C recomendations such as +`XPath `_ and +`XQuery `_. + + +Selectors +--------- + +The function `xmlquery_query` is defined to help filter and match nodes in the +:doc:`DOM tree `: + +.. c:function:: generic_list* xmlquery_query(const char* pattern, dom_node* root) + + :c:member:`pattern` Query pattern to apply to XML document. + + :c:member:`root` A root of a DOM tree where to begin the query. + + This function applies a query to a given DOM tree and returns a list of elements. + +Introduction +^^^^^^^^^^^^ + +Node selection is implemented as a **pattern string** to be matched against a +:doc:`DOM tree `. The pattern string matches some number of nodes that are +then returned as a flat list. + +A pattern example: + +.. code-block:: css + + foo + +this simple pattern matches all nodes named `foo`. Upon matching the DOM tree +with this pattern, a reference to every node named `foo` would be returned. +Independent of their position in the tree. Returned references may be +manipulated, rearanged or deleted. + + +Pattern strings match dom nodes in three different realms, according to the node +name (as we've seen), according to the node attributes and according to +*pseudo-filters*, a special kind of selectors aware of the node context. + +.. code-block:: css + + foo[attr='bar']:only-child + +A more complex selector, this selector will match nodes with the name *foo*, +with an attribute named *attr* with the value *bar*, and the node must also be +the *only child* of its parent node. + + +Custom pseudo-filters +^^^^^^^^^^^^^^^^^^^^^ + +We've created some new features. We added the possibility of making *custom pseudo-filters*. +*Custom pseudo-filters* provide a way for the user to define their own filters, which can be +chained with other query operators. + +To create a *custom pseudo-filter* you just need to define a function with the one of the following signatures:: + + int simple_filter(dom_node* node); + int complex_filter(dom_node* node, list* args); + +The first one creates a filter that doesn't take any arguments. If you want to design a filter that takes arguments, you must use the second signature. + +After defining your filter you need to register them. You do this by calling:: + +.. c:function:: void register_simple_custom_filter(const char* name, int (*filter)(dom_node* node)) + +.. c:function:: void register_custom_filter(const char* name, int (*filter)(dom_node* node, list* args)) + +The first function registers a simple filter, while the second registers a complex one. + +When you're done with this you can call your filters just like a CSS3 *pseudo-filter*. diff --git a/documentation/applications/shell.rst b/lxq_sources/applications/shell.txt similarity index 100% rename from documentation/applications/shell.rst rename to lxq_sources/applications/shell.txt diff --git a/documentation/data_structures/datastructures.rst b/lxq_sources/data_structures/datastructures.txt similarity index 100% rename from documentation/data_structures/datastructures.rst rename to lxq_sources/data_structures/datastructures.txt diff --git a/documentation/dom.rst b/lxq_sources/dom.txt similarity index 100% rename from documentation/dom.rst rename to lxq_sources/dom.txt diff --git a/lxq_sources/index.txt b/lxq_sources/index.txt new file mode 100644 index 0000000..3b0527c --- /dev/null +++ b/lxq_sources/index.txt @@ -0,0 +1,30 @@ +.. libxmlquery documentation master file, created by + sphinx-quickstart on Fri Nov 5 15:13:45 2010. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +.. highlight:: c + +libxmlquery documentation +========================= + +**libxmlquery** is a colection of C functions to help **parse**, **create** and +**query** xml documents. + +If you are new to **libxmlquery** start by reading the +:doc:`Tutorial `. + +.. toctree:: + :maxdepth: 2 + + tutorial/tutorial + parser/parser + dom + querying + data_structures/datastructures + macros.h + bindings + applications/shell + +You may also find specific object documentation in the :ref:`genindex`. + diff --git a/documentation/macros.h.rst b/lxq_sources/macros.h.txt similarity index 100% rename from documentation/macros.h.rst rename to lxq_sources/macros.h.txt diff --git a/documentation/parser/parser.rst b/lxq_sources/parser/parser.txt similarity index 100% rename from documentation/parser/parser.rst rename to lxq_sources/parser/parser.txt diff --git a/documentation/querying.rst b/lxq_sources/querying.txt similarity index 100% rename from documentation/querying.rst rename to lxq_sources/querying.txt diff --git a/lxq_sources/tutorial.txt b/lxq_sources/tutorial.txt new file mode 100644 index 0000000..afd702b --- /dev/null +++ b/lxq_sources/tutorial.txt @@ -0,0 +1,47 @@ +.. highlight:: c + +======== +Tutorial +======== + +The following code shows how to use the library to rename a node in a xml file:: + + #include + #include + #include + #include + + dom_node* node = xmlquery_parsefile("test.xml"); + node_list* q_result = xmlquery_query("@hi[foo=bar]"); + dom_node* n_result = xmlquery_pop_node(q_result); + xmlquery_set_node_name(n_result, "bye"); + + printf("%s\n", xmlquery_dom_node_to_string(node, XML); + +if ``test.xml`` contains: + +.. code-block:: xml + + + + + + +the resulting output would change the node: + +.. code-block:: xml + + + +to: + +.. code-block:: xml + + + + +this code will read an xml file in ``test.xml`` into our abstract representation +of the DOM (\ **D**\ ocument **O**\ bject **M**\ odel) tree:: + + dom_node* node = xmlquery_parsefile("test.xml"); + diff --git a/documentation/tutorial/tutorial.rst b/lxq_sources/tutorial/tutorial.txt similarity index 100% rename from documentation/tutorial/tutorial.rst rename to lxq_sources/tutorial/tutorial.txt diff --git a/lxq_static/_static/basic.css b/lxq_static/_static/basic.css new file mode 100644 index 0000000..69f30d4 --- /dev/null +++ b/lxq_static/_static/basic.css @@ -0,0 +1,509 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +.align-left { + text-align: left; +} + +.align-center { + clear: both; + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} diff --git a/lxq_static/_static/doctools.js b/lxq_static/_static/doctools.js new file mode 100644 index 0000000..eeea95e --- /dev/null +++ b/lxq_static/_static/doctools.js @@ -0,0 +1,247 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for all documentation. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +} + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * small function to check if an array contains + * a given item. + */ +jQuery.contains = function(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == item) + return true; + } + return false; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('.sidebar .this-page-menu')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('.sidebar .this-page-menu li.highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/lxq_static/_static/file.png b/lxq_static/_static/file.png new file mode 100644 index 0000000..d18082e Binary files /dev/null and b/lxq_static/_static/file.png differ diff --git a/lxq_static/_static/jquery.js b/lxq_static/_static/jquery.js new file mode 100644 index 0000000..7c24308 --- /dev/null +++ b/lxq_static/_static/jquery.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/lxq_static/_static/minus.png b/lxq_static/_static/minus.png new file mode 100644 index 0000000..da1c562 Binary files /dev/null and b/lxq_static/_static/minus.png differ diff --git a/documentation/_theme/nature/static/nature.css_t b/lxq_static/_static/nature.css similarity index 99% rename from documentation/_theme/nature/static/nature.css_t rename to lxq_static/_static/nature.css index 4252a8d..ac9c45e 100644 --- a/documentation/_theme/nature/static/nature.css_t +++ b/lxq_static/_static/nature.css @@ -235,4 +235,3 @@ tt { #table-of-contents ul { padding-left: 2em; } - diff --git a/lxq_static/_static/plus.png b/lxq_static/_static/plus.png new file mode 100644 index 0000000..b3cb374 Binary files /dev/null and b/lxq_static/_static/plus.png differ diff --git a/documentation/_theme/nature/static/pygments.css b/lxq_static/_static/pygments.css similarity index 100% rename from documentation/_theme/nature/static/pygments.css rename to lxq_static/_static/pygments.css diff --git a/lxq_static/_static/searchtools.js b/lxq_static/_static/searchtools.js new file mode 100644 index 0000000..5cbfe00 --- /dev/null +++ b/lxq_static/_static/searchtools.js @@ -0,0 +1,518 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurance, the + * latter for highlighting it. + */ + +jQuery.makeSearchSummary = function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('
').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; +} + +/** + * Porter Stemmer + */ +var PorterStemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, success: null, + dataType: "script", cache: true}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (var i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

' + _('Searching') + '

').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

').appendTo(this.out); + this.output = $('