english
version "1.0"
identify "xyz"

# Copyright (c) 1998 by Wayne C. Gramlich.
# All rights reserved.
#
# Permission to use, copy, modify, distribute, and sell this software
# for any purpose is hereby granted without fee provided that the above
# copyright notice and this permission are retained.  The author makes
# no representations about the suitability of this software for any purpose.
# It is provided "as is" without express or implied warranty.

module xml

#: This module is used to represent an XML (eXtensible Markup Language)
#, document.

define xml				#: A parsed XML document
    record
	components vector[xml_component] #: Components that make up document
    generate address_get, allocate, erase, print

define xml_attribute			#: Attribute
    record
	name string			#: Attribute Name
	preceeding string		#: Preceeding white space
	quote_type xml_quote_type	#: Kind of attribute quote
	value string			#: Attribute value
    generate address_get, allocate, erase, identical, print

define xml_component			#: Element, enity, or text
    variant type xml_component_type
	comment string			#: "<!-- COMMENT -->"
	element xml_element		#: "<ELEMENT>" or "</ELEMENT>"
	entity string			#: "&ENTITY;"
	error string			#: An entity/comment/element parse err.
	text string			#: Some text
    generate address_get, allocate, erase, print

define xml_element			#: Element "<NAME>", "</NAME>", etc.
    record
	attributes vector[xml_attribute] #: Attribute list
	name string			#: Element name
	type xml_element_type		#: Element type
    generate address_get, allocate, erase, identical, print

define xml_element_type			#: Element type
    enumeration
	end				#: End element </NAME>
	start				#: Start element <NAME...>
    generate equal, print

define xml_quote_type			#: Quotation type
    enumeration
	double				#: Double quote -- NAME="..."
	single				#: Single quote -- NAME='...'
	no_quotes			#: No quotes -- NAME=...
	no_value			#: No value -- NAME
    generate equal, print

define xml_resources			#: XML resources
    record
	attributes vector[xml_attribute] #: Free {xml_attribute} objects
	attributes_count unsigned	#: Max. {xml_attribute}'s allocated
	components vector[xml_component] #: Free {xml_component} objects
	components_count unsigned	#: Max. {xml_component}'s allocated
	elements vector[xml_element]	#: Free {xml_element} objects
	elements_count unsigned		#: Max. {xml_element}'s allocated
	strings vector[string]		#: Free {string} objects
	strings_count unsigned		#: Max. {string}'s allocated
	xmls vector[xml]		#: Free {xml} objects
	xmls_count unsigned		#: Max. {xml}'s allocated
    generate address_get, allocate, erase, print


#: {xml} procedures:

procedure buffer_append@xml
    takes
	xml xml
	buffer string
    returns_nothing

    #: This procedure will append {xml} to {buffer}.


procedure create@xml
    takes
	resources xml_resources
    returns xml

    #: This procedure will create an return a new {xml} object allocated
    #, from {xml_resources}.


procedure error_count_get@xml
    takes
	xml xml
    returns unsigned

    #: This procedure will return the number of parse errors
    #, encounterd in {xml}.


procedure parse@xml
    takes
	text string
	resources xml_resources
    returns xml

    #: This procedure will parse {text} into an {xml} object allocated
    #, from {xml_resources}.


procedure release@xml
    takes
	xml xml
	resources xml_resources
    returns_nothing

    #, with {xml}.


procedure show@xml
    takes
	xml xml
	out_stream out_stream
    returns_nothing

    #: This procedure will show the contents of {xml} with a little
    #, more structure.


procedure size_get@xml
    takes
	xml xml
    returns unsigned

    #: This procedure will return the number of characters in {xml}.


#: {xml_attribute} procedures:

procedure buffer_append@xml_attribute
    takes
	attribute xml_attribute
	buffer string
    returns_nothing

    #: This procedure will append {attribute} onto {buffer}.


procedure create@xml_attribute
    takes_nothing
    returns xml_attribute

    #: This procedure will create and return an {xml_attribute} object
    #, allocating {strings} from {resources}.


procedure parse_into@xml_attribute
    takes
	attribute xml_attribute
	text string
	offset unsigned
	resources xml_resources
    returns unsigned

    #: This procedure will parse an element attribute from {text}
    #, starting at {offset}.  The next character to parse after
    #, the attribute is returned.  If no attribute is parsed,
    #, the original value of {offset} is returned.


procedure release@xml_attribute
    takes
	attribute xml_attribute
	resources xml_resources
    returns_nothing

    #: This procedure will release any storage associated with
    #, {attribute} back to {resources}.


procedure show@xml_attribute
    takes
	attribute xml_attribute
	out_stream out_stream
    returns_nothing

    #: This procedure will show {attribute} to {out_stream}.


procedure size_get@xml_attribute
    takes
	attribute xml_attribute
    returns unsigned

    #: This procedure will return the number of chracters in {attribute}.


#: {xml_component} procedures:

procedure buffer_append@xml_component
    takes
	component xml_component
	buffer string
    returns_nothing

    #: This procedure will append {component} to {buffer}.


procedure create@xml_component
    takes
	resources xml_resources
    returns xml_component

    #: This procedure will create and return an {xml_component} object
    #, allocating {strings} from {resources}.


procedure parse_into@xml_component
    takes
	component xml_component
	text string
	offset unsigned
	resources xml_resources
    returns unsigned

    #: This procedure will parse some one components work of {text}
    #, starting at {offset} and store the result into {component}.
    #, Any objects that are allocated come from {resources}.
    #, The offset to the next character to parse is returned.


procedure release@xml_component
    takes
	component xml_component
	resources xml_resources
    returns_nothing

    #: This procedure will release the storage associated with
    #, {component} back into {resources}.


procedure show@xml_component
    takes
	component xml_component
	out_stream out_stream
    returns_nothing

    #: This procedure will output {component} to {out_stream}.


procedure size_get@xml_component
    takes
	component xml_component
    returns unsigned

    #: This procedure will the number of characters in {component}:


#: {xml_element} procedures:

procedure buffer_append@xml_element
    takes
	element xml_element
	buffer string
    returns_nothing

    #: This procedure will append {element} to {buffer}.


procedure create@xml_element
    takes_nothing
    returns xml_element

    #: This procedure will create an return a new {xml_element}.


procedure parse_into@xml_element
    takes
	element xml_element
	text string
	offset unsigned
	resources xml_resources
    returns unsigned

    #: This procedure will parse an element from {text} starting at
    #, {offset} allocating any necessary attributes from {resources}.
    #, The offset of the next character to parse is returned.  If there
    #, is any error, the value of {offset} that was passed in is returned.


procedure release@xml_element
    takes
	element xml_element
	resources xml_resources
    returns_nothing

    #: This procedure will release the storage assocated with {element}
    #, back to {resources}.


procedure show@xml_element
    takes
	element xml_element
	out_stream out_stream
    returns_nothing

    #: This procedure will show {element} to {out_stream}


procedure size_get@xml_element
    takes
	element xml_element
    returns unsigned

    #: This procedure will return the number of characters in {element}.


#: {xml_resources} proecdures:

procedure attribute_allocate@xml_resources
    takes
	resources xml_resources
    returns xml_attribute

    #: This procedure will allocate and return an {xml_attribute}
    #, object from {resources}.


procedure attribute_release@xml_resources
    takes
	resources xml_resources
	attribute xml_attribute
    returns_nothing

    #: This procedure will release the storage associated with
    #, {attribute} and put them back into {xml_resources}.  {attribute}
    #, must be `empty' prior to calling this procedure.


procedure check@xml_resources
    takes
	resources xml_resources
	error_stream out_stream
	name string
    returns logical

    #: This procedure will verify that {resources} has no outstanding
    #, objects.  If there are outstanding object, error messages are
    #, printed to {out_stream} and {true}@{logical} is returned;
    #, otherwise, {false} is returned.


procedure component_allocate@xml_resources
    takes
	resources xml_resources
    returns xml_component

    #: This procedure will allocate and return an empty {xml_component}
    #, object allocated from {resources}.


procedure component_release@xml_resources
    takes
	resources xml_resources
	component xml_component
    returns_nothing

    #: This procedure will release the storage associated with
    #, {component} and put them back into {xml_resources}.  {component}
    #, must be `empty' prior to calling this procedure.


procedure create@xml_resources
    takes_nothing
    returns xml_resources

    #: This procedure will create and return an {xml_resources} object.


procedure element_allocate@xml_resources
    takes
	resources xml_resources
    returns xml_element

    #: This procedure will allocate and return an {xml_element} from
    #, {resources}.


procedure element_release@xml_resources
    takes
	resources xml_resources
	element xml_element
    returns_nothing

    #: This procedure will release the storage associated with
    #, {element} and put them back into {xml_resources}.  {element}
    #, must be `empty' prior to calling this procedure.


procedure string_allocate@xml_resources
    takes
	resources xml_resources
    returns string

    #: This procedure will allocate and return an empty {string} object
    #, from {resources}.


procedure string_release@xml_resources
    takes
	resources xml_resources
	string string
    returns_nothing

    #: This procedure will release the storage associated with
    #, {string} and put them back into {xml_resources}.


procedure xml_allocate@xml_resources
    takes
	resources xml_resources
    returns xml

    #: This procedure will allocate and return an {xml} object
    #, from {resources}.


procedure xml_release@xml_resources
    takes
	resources xml_resources
	xml xml
    returns_nothing

    #: This procedure will release the storage associated with
    #, {xml} and put them back into {xml_resources}.  {xml}
    #, must be `empty' prior to calling this procedure.