diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2009-04-02 12:22:38 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2009-04-02 12:22:38 +0200 |
commit | 8336dd4c16d4885989a6d8f0c83a4b401f5cb63b (patch) | |
tree | 26ca613e7f3a3fe9fb75bf5bb3b65503661e0ebf | |
parent | e4c22d3686da0e973e21eae0561c1169c0eeff36 (diff) |
Add support for attributes with default and fixed values.
tests/cxx/hybrid/default: new test
tests/cxx/hybrid/binary: update to test default and fixed values
37 files changed, 2942 insertions, 173 deletions
@@ -22,6 +22,11 @@ Version 3.1.0 Started Guide as well as examples in the examples/cxx/hybrid/binary/ directory. + * Support for attributes with default and fixed values. For details see + Section 4.3, "Attributes and Elements" in the Getting Started Guide. + Use the new --omit-default-attributes option to omit the attributes + with default and fixed values from serialized XML documents. + * New option, --custom-type, allows customization of the object model classes. You have the option of either basing your custom implementation on the generated version or providing your own implementation from diff --git a/documentation/cxx/hybrid/guide/index.xhtml b/documentation/cxx/hybrid/guide/index.xhtml index 5871593..d497a14 100644 --- a/documentation/cxx/hybrid/guide/index.xhtml +++ b/documentation/cxx/hybrid/guide/index.xhtml @@ -2031,7 +2031,143 @@ if (p.middle_name_present ()) } </pre> - <p>Finally, the <em>sequence</em> cardinality class covers all elements + <p>There are two cases in the <em>optional</em> cardinality class that + are handled differently. These are optional attributes with default + and fixed values. When an optional attribute declaration in XML Schema + specifies a default or fixed value and such an attribute is not present + in the XML document, the attribute is assumed to have the default or + fixed value, respectively. Furthermore, if an attribute with the + fixed value is set in the XML document, then the attribute value + should be the same as its fixed value.</p> + + <p>For an optional attribute with a default value, the functions for + querying and modifying the attribute's presence status are replaced + with functions that allow you to determine whether the attribute has + the default value. The accessor functions can be called at any time + since an optional attribute with a default value always has some + value. Also an extra static function is provided to allow you to + obtain the default value. Consider the following modification to + the <code>person</code> type which adds the <code>verified</code> + attribute with the default value:</p> + + <pre class="xml"> +<xs:complexType name="person"> + <xs:sequence> + <xs:element name="first-name" type="xs:string"/> + ... + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + <xs:attribute name="verified" type="xs:boolean" default="false"/> +</xs:complexType> + </pre> + + <p>The code fragment below shows the accessor and modifier functions + that are generated for this new attribute in the <code>person</code> + class:</p> + + <pre class="c++"> +class person +{ + // verified + // + bool + verified_default () const; + + void + verified_default (bool); + + bool + verified () const; + + bool& + verified (); + + void + verified (bool); + + static bool + verified_default_value (); +}; + </pre> + + <p>When we create an object of the <code>person</code> class, the + <code>verified</code> member is automatically initialized to the + default value. The following example shows how we can manipulate + the <code>verified</code> attribute value:</p> + + <pre class="c++"> +person p; // verified is set to the default value (false). + +if (p.verified_default ()) + p.verified (true); +else + p.verified_default (true); // Revert to the default value. + +bool v = p.verified (); // Ok, can always be called. +bool vd = person::verified_default_value (); + </pre> + + <p>Note that modifying an attribute of a variable-length type via + the reference when the attribute is set to the default value is + illegal since this will modify the default value shared by all + instances. For example:</p> + + <pre class="c++"> +type& x = ... + +if (x.foo_default ()) +{ + foo& f = x.foo (); // foo is variable-length, for example NMTOKENS + f.push_back ("aaa"); // Illegal. +} + +if (x.foo_default ()) +{ + foo* f = new foo; + f->push_back ("aaa"); + x.foo (f); // Ok. +} + </pre> + + <p>Because an attribute with a fixed value can only be set to that + value, only the read-only (constant) accessor and the static + function for obtaining the fixed value are provided for such + attributes. Similar to the default values, members with fixed + values of a newly created object are automatically initialized + to their respective fixed values. Consider the following + modification to the <code>verified</code> attribute from the + schema above:</p> + + <pre class="xml"> +<xs:complexType name="person"> + ... + <xs:attribute name="verified" type="xs:boolean" fixed="true"/> +</xs:complexType> + </pre> + + <p>The code fragment below shows the accessor functions that are + generated for this attribute in the <code>person</code> + class:</p> + + <pre class="c++"> +class person +{ + // verified + // + bool + verified () const; + + static bool + verified_fixed_value (); +}; + </pre> + + <p>During serialization, attributes that are set to default and fixed + values are explicitly specified in the resulting XML document. + You can use the <code>--omit-default-attributes</code> XSD/e + compiler option to omit such attributes from the serialized XML.</p> + + <p>The <em>sequence</em> cardinality class covers all elements that can occur more than once. In our example, the <code>person</code> element in the <code>people</code> type belongs to this cardinality class. The following code fragment shows diff --git a/documentation/xsde.1 b/documentation/xsde.1 index 62cc55d..874a4de 100644 --- a/documentation/xsde.1 +++ b/documentation/xsde.1 @@ -944,6 +944,10 @@ Suppress the generation of validation code in parser. .IP "\fB\--suppress-serializer-val\fR" Suppress the generation of validation code in serializer. +.IP "\fB\--omit-default-attributes\fR" +Omit attributes with default and fixed values from serialized XML +documents. + .IP "\fB\--generate-detach\fR" Generate detach functions for elements and attributes of variable-length types. These functions, for example, allow you to move sub-trees in the diff --git a/documentation/xsde.xhtml b/documentation/xsde.xhtml index c8f602a..697c751 100644 --- a/documentation/xsde.xhtml +++ b/documentation/xsde.xhtml @@ -816,6 +816,10 @@ <dt><code><b>--suppress-serializer-val</b></code></dt> <dd>Suppress the generation of validation code in serializer.</dd> + <dt><code><b>--omit-default-attributes</b></code></dt> + <dd>Omit attributes with default and fixed values from serialized + XML documents.</dd> + <dt><code><b>--generate-detach</b></code></dt> <dd>Generate detach functions for elements and attributes of variable-length types. These functions, for example, allow diff --git a/libxsde/xsde/cxx/hybrid/any-type.hxx b/libxsde/xsde/cxx/hybrid/any-type.hxx index f94f007..5042115 100644 --- a/libxsde/xsde/cxx/hybrid/any-type.hxx +++ b/libxsde/xsde/cxx/hybrid/any-type.hxx @@ -47,6 +47,18 @@ namespace xsde struct any_simple_type { }; + + inline bool + operator== (const any_simple_type&, const any_simple_type&) + { + return true; + } + + inline bool + operator!= (const any_simple_type&, const any_simple_type&) + { + return false; + } } } } diff --git a/libxsde/xsde/cxx/hybrid/base.hxx b/libxsde/xsde/cxx/hybrid/base.hxx index ba5090d..fdfdeac 100644 --- a/libxsde/xsde/cxx/hybrid/base.hxx +++ b/libxsde/xsde/cxx/hybrid/base.hxx @@ -8,6 +8,10 @@ #include <xsde/cxx/config.hxx> +#ifndef XSDE_STL +# include <string.h> // strcmp +#endif + namespace xsde { namespace cxx @@ -31,6 +35,18 @@ namespace xsde bool x_; }; + inline bool + operator== (const boolean_base& x, const boolean_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const boolean_base& x, const boolean_base& y) + { + return !(x == y); + } + // byte // struct byte_base @@ -48,6 +64,18 @@ namespace xsde signed char x_; }; + inline bool + operator== (const byte_base& x, const byte_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const byte_base& x, const byte_base& y) + { + return !(x == y); + } + // unsigned_byte // struct unsigned_byte_base @@ -66,6 +94,18 @@ namespace xsde unsigned char x_; }; + inline bool + operator== (const unsigned_byte_base& x, const unsigned_byte_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const unsigned_byte_base& x, const unsigned_byte_base& y) + { + return !(x == y); + } + // short // struct short_base @@ -83,6 +123,18 @@ namespace xsde short x_; }; + inline bool + operator== (const short_base& x, const short_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const short_base& x, const short_base& y) + { + return !(x == y); + } + // unsigned_short // struct unsigned_short_base @@ -101,6 +153,18 @@ namespace xsde unsigned short x_; }; + inline bool + operator== (const unsigned_short_base& x, const unsigned_short_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const unsigned_short_base& x, const unsigned_short_base& y) + { + return !(x == y); + } + // int // struct int_base @@ -118,6 +182,18 @@ namespace xsde int x_; }; + inline bool + operator== (const int_base& x, const int_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const int_base& x, const int_base& y) + { + return !(x == y); + } + // unsigned_int // struct unsigned_int_base @@ -135,6 +211,18 @@ namespace xsde unsigned int x_; }; + inline bool + operator== (const unsigned_int_base& x, const unsigned_int_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const unsigned_int_base& x, const unsigned_int_base& y) + { + return !(x == y); + } + // long // #ifdef XSDE_LONGLONG @@ -169,6 +257,18 @@ namespace xsde }; #endif + inline bool + operator== (const long_base& x, const long_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const long_base& x, const long_base& y) + { + return !(x == y); + } + // unsigned_long // @@ -206,6 +306,18 @@ namespace xsde }; #endif + inline bool + operator== (const unsigned_long_base& x, const unsigned_long_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const unsigned_long_base& x, const unsigned_long_base& y) + { + return !(x == y); + } + // integer // struct integer_base @@ -223,6 +335,18 @@ namespace xsde long x_; }; + inline bool + operator== (const integer_base& x, const integer_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const integer_base& x, const integer_base& y) + { + return !(x == y); + } + // negative_integer // struct negative_integer_base @@ -240,6 +364,20 @@ namespace xsde long x_; }; + inline bool + operator== (const negative_integer_base& x, + const negative_integer_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const negative_integer_base& x, + const negative_integer_base& y) + { + return !(x == y); + } + // non_positive_integer // struct non_positive_integer_base @@ -257,6 +395,20 @@ namespace xsde long x_; }; + inline bool + operator== (const non_positive_integer_base& x, + const non_positive_integer_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const non_positive_integer_base& x, + const non_positive_integer_base& y) + { + return !(x == y); + } + // positive_integer // struct positive_integer_base @@ -275,6 +427,20 @@ namespace xsde unsigned long x_; }; + inline bool + operator== (const positive_integer_base& x, + const positive_integer_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const positive_integer_base& x, + const positive_integer_base& y) + { + return !(x == y); + } + // non_negative_integer // struct non_negative_integer_base @@ -293,6 +459,20 @@ namespace xsde unsigned long x_; }; + inline bool + operator== (const non_negative_integer_base& x, + const non_negative_integer_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const non_negative_integer_base& x, + const non_negative_integer_base& y) + { + return !(x == y); + } + // float // struct float_base @@ -310,6 +490,18 @@ namespace xsde float x_; }; + inline bool + operator== (const float_base& x, const float_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const float_base& x, const float_base& y) + { + return !(x == y); + } + // double // struct double_base @@ -327,6 +519,18 @@ namespace xsde double x_; }; + inline bool + operator== (const double_base& x, const double_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const double_base& x, const double_base& y) + { + return !(x == y); + } + // decimal // struct decimal_base @@ -344,6 +548,19 @@ namespace xsde double x_; }; + inline bool + operator== (const decimal_base& x, const decimal_base& y) + { + return x.base_value () == y.base_value (); + } + + inline bool + operator!= (const decimal_base& x, const decimal_base& y) + { + return !(x == y); + } + +#ifndef XSDE_STL // string // struct string_base @@ -364,6 +581,19 @@ namespace xsde protected: char* x_; }; + + inline bool + operator== (const string_base& x, const string_base& y) + { + return strcmp (x.base_value (), y.base_value ()) == 0; + } + + inline bool + operator!= (const string_base& x, const string_base& y) + { + return !(x == y); + } +#endif } } } diff --git a/tests/cxx/hybrid/binary/cdr/output.xml b/tests/cxx/hybrid/binary/cdr/output.xml index a484661..f36f755 100644 --- a/tests/cxx/hybrid/binary/cdr/output.xml +++ b/tests/cxx/hybrid/binary/cdr/output.xml @@ -1,2 +1,2 @@ -<t:root xmlns:t="test"><list>1 2 3</list><union>abc</union><enumeration>left</enumeration><complex x="1"><a>aaa</a></complex><complex x="1" y="2"><a>aaa</a><b>bbb</b><c>c</c><c>cc</c><c>ccc</c></complex><choice></choice><choice><a>123</a></choice><choice><b>ab</b><b>cd</b><b>ef</b></choice><choice><c>12.34</c><d>false</d></choice><byte>65</byte><unsigned_byte>66</unsigned_byte><short>-222</short><unsigned_short>57005</unsigned_short><int>-57005</int><unsigned_int>3735928559</unsigned_int><long>-2147483648</long><unsigned_long>2147483647</unsigned_long><integer>-2147483648</integer><non_positive_integer>-2147483648</non_positive_integer><non_negative_integer>2147483647</non_negative_integer><positive_integer>2147483647</positive_integer><negative_integer>-2147483648</negative_integer><boolean>true</boolean><float>1234.12</float><double>12345678.1234568</double><decimal>1234567812345678</decimal><string>string</string><normalized_string>normalized string</normalized_string><token>one two three</token><name>name</name><name_token>name-token</name_token><name_tokens>name tokens</name_tokens><ncname>ncname</ncname><language>en-us</language><qname>xsi:schemaLocation</qname><id>elements1</id><id>elements2</id><id_ref>elements1</id_ref><id_refs>elements1 elements2</id_refs><any_uri>http://www.codesynthesis.com</any_uri><base64_binary>YmFzZTY0IGJpbmFyeQ== +<t:root xmlns:t="test"><list>1 2 3</list><union>abc</union><enumeration>left</enumeration><complex df1="123" df2="456" dv1="aaa bbb ccc" dv2="mmm nnn" ff1="123" ff2="123" fv1="aaa bbb ccc" fv2="aaa bbb ccc" x="1"><a>aaa</a></complex><complex df1="123" df2="123" dv1="aaa bbb ccc" dv2="aaa bbb ccc" ff1="123" ff2="123" fv1="aaa bbb ccc" fv2="aaa bbb ccc" x="1" y="2"><a>aaa</a><b>bbb</b><c>c</c><c>cc</c><c>ccc</c></complex><choice></choice><choice><a>123</a></choice><choice><b>ab</b><b>cd</b><b>ef</b></choice><choice><c>12.34</c><d>false</d></choice><byte>65</byte><unsigned_byte>66</unsigned_byte><short>-222</short><unsigned_short>57005</unsigned_short><int>-57005</int><unsigned_int>3735928559</unsigned_int><long>-2147483648</long><unsigned_long>2147483647</unsigned_long><integer>-2147483648</integer><non_positive_integer>-2147483648</non_positive_integer><non_negative_integer>2147483647</non_negative_integer><positive_integer>2147483647</positive_integer><negative_integer>-2147483648</negative_integer><boolean>true</boolean><float>1234.12</float><double>12345678.1234568</double><decimal>1234567812345678</decimal><string>string</string><normalized_string>normalized string</normalized_string><token>one two three</token><name>name</name><name_token>name-token</name_token><name_tokens>name tokens</name_tokens><ncname>ncname</ncname><language>en-us</language><qname>xsi:schemaLocation</qname><id>elements1</id><id>elements2</id><id_ref>elements1</id_ref><id_refs>elements1 elements2</id_refs><any_uri>http://www.codesynthesis.com</any_uri><base64_binary>YmFzZTY0IGJpbmFyeQ== </base64_binary><hex_binary>6865782052696E617279</hex_binary><date>2001-10-26+02:00</date><date_time>2001-10-26T21:32:52+02:00</date_time><duration>P1Y2M3DT5H20M30S</duration><day>---01+02:00</day><month>--11+02:00</month><month_day>--02-11+02:00</month_day><year>2001+02:00</year><year_month>2001-11+02:00</year_month><time>21:32:52+02:00</time></t:root>
\ No newline at end of file diff --git a/tests/cxx/hybrid/binary/cdr/test.xml b/tests/cxx/hybrid/binary/cdr/test.xml index acd75d2..1218c37 100644 --- a/tests/cxx/hybrid/binary/cdr/test.xml +++ b/tests/cxx/hybrid/binary/cdr/test.xml @@ -6,10 +6,10 @@ <enumeration>left</enumeration> - <complex x="1"> + <complex x="1" df2="456" ff2="123" dv2="mmm nnn" fv2="aaa bbb ccc"> <a>aaa</a> </complex> - <complex x="1" y="2"> + <complex x="1" y="2" ff2="123" fv2="aaa bbb ccc"> <a>aaa</a> <b>bbb</b> <c>c</c> diff --git a/tests/cxx/hybrid/binary/cdr/test.xsd b/tests/cxx/hybrid/binary/cdr/test.xsd index 7a92c7e..5a2ea34 100644 --- a/tests/cxx/hybrid/binary/cdr/test.xsd +++ b/tests/cxx/hybrid/binary/cdr/test.xsd @@ -35,6 +35,18 @@ <element name="c" type="string" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="y" type="int"/> + + <!-- test default/fixed values --> + + <attribute name="df1" type="int" default="123"/> + <attribute name="df2" type="int" default="123"/> + <attribute name="ff1" type="int" fixed="123"/> + <attribute name="ff2" type="int" fixed="123" use="required"/> + + <attribute name="dv1" type="NMTOKENS" default="aaa bbb ccc"/> + <attribute name="dv2" type="NMTOKENS" default="aaa bbb ccc"/> + <attribute name="fv1" type="NMTOKENS" fixed="aaa bbb ccc"/> + <attribute name="fv2" type="NMTOKENS" fixed="aaa bbb ccc" use="required"/> </extension> </complexContent> </complexType> diff --git a/tests/cxx/hybrid/binary/custom/output.xml b/tests/cxx/hybrid/binary/custom/output.xml index a484661..f36f755 100644 --- a/tests/cxx/hybrid/binary/custom/output.xml +++ b/tests/cxx/hybrid/binary/custom/output.xml @@ -1,2 +1,2 @@ -<t:root xmlns:t="test"><list>1 2 3</list><union>abc</union><enumeration>left</enumeration><complex x="1"><a>aaa</a></complex><complex x="1" y="2"><a>aaa</a><b>bbb</b><c>c</c><c>cc</c><c>ccc</c></complex><choice></choice><choice><a>123</a></choice><choice><b>ab</b><b>cd</b><b>ef</b></choice><choice><c>12.34</c><d>false</d></choice><byte>65</byte><unsigned_byte>66</unsigned_byte><short>-222</short><unsigned_short>57005</unsigned_short><int>-57005</int><unsigned_int>3735928559</unsigned_int><long>-2147483648</long><unsigned_long>2147483647</unsigned_long><integer>-2147483648</integer><non_positive_integer>-2147483648</non_positive_integer><non_negative_integer>2147483647</non_negative_integer><positive_integer>2147483647</positive_integer><negative_integer>-2147483648</negative_integer><boolean>true</boolean><float>1234.12</float><double>12345678.1234568</double><decimal>1234567812345678</decimal><string>string</string><normalized_string>normalized string</normalized_string><token>one two three</token><name>name</name><name_token>name-token</name_token><name_tokens>name tokens</name_tokens><ncname>ncname</ncname><language>en-us</language><qname>xsi:schemaLocation</qname><id>elements1</id><id>elements2</id><id_ref>elements1</id_ref><id_refs>elements1 elements2</id_refs><any_uri>http://www.codesynthesis.com</any_uri><base64_binary>YmFzZTY0IGJpbmFyeQ== +<t:root xmlns:t="test"><list>1 2 3</list><union>abc</union><enumeration>left</enumeration><complex df1="123" df2="456" dv1="aaa bbb ccc" dv2="mmm nnn" ff1="123" ff2="123" fv1="aaa bbb ccc" fv2="aaa bbb ccc" x="1"><a>aaa</a></complex><complex df1="123" df2="123" dv1="aaa bbb ccc" dv2="aaa bbb ccc" ff1="123" ff2="123" fv1="aaa bbb ccc" fv2="aaa bbb ccc" x="1" y="2"><a>aaa</a><b>bbb</b><c>c</c><c>cc</c><c>ccc</c></complex><choice></choice><choice><a>123</a></choice><choice><b>ab</b><b>cd</b><b>ef</b></choice><choice><c>12.34</c><d>false</d></choice><byte>65</byte><unsigned_byte>66</unsigned_byte><short>-222</short><unsigned_short>57005</unsigned_short><int>-57005</int><unsigned_int>3735928559</unsigned_int><long>-2147483648</long><unsigned_long>2147483647</unsigned_long><integer>-2147483648</integer><non_positive_integer>-2147483648</non_positive_integer><non_negative_integer>2147483647</non_negative_integer><positive_integer>2147483647</positive_integer><negative_integer>-2147483648</negative_integer><boolean>true</boolean><float>1234.12</float><double>12345678.1234568</double><decimal>1234567812345678</decimal><string>string</string><normalized_string>normalized string</normalized_string><token>one two three</token><name>name</name><name_token>name-token</name_token><name_tokens>name tokens</name_tokens><ncname>ncname</ncname><language>en-us</language><qname>xsi:schemaLocation</qname><id>elements1</id><id>elements2</id><id_ref>elements1</id_ref><id_refs>elements1 elements2</id_refs><any_uri>http://www.codesynthesis.com</any_uri><base64_binary>YmFzZTY0IGJpbmFyeQ== </base64_binary><hex_binary>6865782052696E617279</hex_binary><date>2001-10-26+02:00</date><date_time>2001-10-26T21:32:52+02:00</date_time><duration>P1Y2M3DT5H20M30S</duration><day>---01+02:00</day><month>--11+02:00</month><month_day>--02-11+02:00</month_day><year>2001+02:00</year><year_month>2001-11+02:00</year_month><time>21:32:52+02:00</time></t:root>
\ No newline at end of file diff --git a/tests/cxx/hybrid/binary/custom/test.xml b/tests/cxx/hybrid/binary/custom/test.xml index acd75d2..1218c37 100644 --- a/tests/cxx/hybrid/binary/custom/test.xml +++ b/tests/cxx/hybrid/binary/custom/test.xml @@ -6,10 +6,10 @@ <enumeration>left</enumeration> - <complex x="1"> + <complex x="1" df2="456" ff2="123" dv2="mmm nnn" fv2="aaa bbb ccc"> <a>aaa</a> </complex> - <complex x="1" y="2"> + <complex x="1" y="2" ff2="123" fv2="aaa bbb ccc"> <a>aaa</a> <b>bbb</b> <c>c</c> diff --git a/tests/cxx/hybrid/binary/custom/test.xsd b/tests/cxx/hybrid/binary/custom/test.xsd index 7a92c7e..5a2ea34 100644 --- a/tests/cxx/hybrid/binary/custom/test.xsd +++ b/tests/cxx/hybrid/binary/custom/test.xsd @@ -35,6 +35,18 @@ <element name="c" type="string" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="y" type="int"/> + + <!-- test default/fixed values --> + + <attribute name="df1" type="int" default="123"/> + <attribute name="df2" type="int" default="123"/> + <attribute name="ff1" type="int" fixed="123"/> + <attribute name="ff2" type="int" fixed="123" use="required"/> + + <attribute name="dv1" type="NMTOKENS" default="aaa bbb ccc"/> + <attribute name="dv2" type="NMTOKENS" default="aaa bbb ccc"/> + <attribute name="fv1" type="NMTOKENS" fixed="aaa bbb ccc"/> + <attribute name="fv2" type="NMTOKENS" fixed="aaa bbb ccc" use="required"/> </extension> </complexContent> </complexType> diff --git a/tests/cxx/hybrid/binary/xdr/output.xml b/tests/cxx/hybrid/binary/xdr/output.xml index a484661..f36f755 100644 --- a/tests/cxx/hybrid/binary/xdr/output.xml +++ b/tests/cxx/hybrid/binary/xdr/output.xml @@ -1,2 +1,2 @@ -<t:root xmlns:t="test"><list>1 2 3</list><union>abc</union><enumeration>left</enumeration><complex x="1"><a>aaa</a></complex><complex x="1" y="2"><a>aaa</a><b>bbb</b><c>c</c><c>cc</c><c>ccc</c></complex><choice></choice><choice><a>123</a></choice><choice><b>ab</b><b>cd</b><b>ef</b></choice><choice><c>12.34</c><d>false</d></choice><byte>65</byte><unsigned_byte>66</unsigned_byte><short>-222</short><unsigned_short>57005</unsigned_short><int>-57005</int><unsigned_int>3735928559</unsigned_int><long>-2147483648</long><unsigned_long>2147483647</unsigned_long><integer>-2147483648</integer><non_positive_integer>-2147483648</non_positive_integer><non_negative_integer>2147483647</non_negative_integer><positive_integer>2147483647</positive_integer><negative_integer>-2147483648</negative_integer><boolean>true</boolean><float>1234.12</float><double>12345678.1234568</double><decimal>1234567812345678</decimal><string>string</string><normalized_string>normalized string</normalized_string><token>one two three</token><name>name</name><name_token>name-token</name_token><name_tokens>name tokens</name_tokens><ncname>ncname</ncname><language>en-us</language><qname>xsi:schemaLocation</qname><id>elements1</id><id>elements2</id><id_ref>elements1</id_ref><id_refs>elements1 elements2</id_refs><any_uri>http://www.codesynthesis.com</any_uri><base64_binary>YmFzZTY0IGJpbmFyeQ== +<t:root xmlns:t="test"><list>1 2 3</list><union>abc</union><enumeration>left</enumeration><complex df1="123" df2="456" dv1="aaa bbb ccc" dv2="mmm nnn" ff1="123" ff2="123" fv1="aaa bbb ccc" fv2="aaa bbb ccc" x="1"><a>aaa</a></complex><complex df1="123" df2="123" dv1="aaa bbb ccc" dv2="aaa bbb ccc" ff1="123" ff2="123" fv1="aaa bbb ccc" fv2="aaa bbb ccc" x="1" y="2"><a>aaa</a><b>bbb</b><c>c</c><c>cc</c><c>ccc</c></complex><choice></choice><choice><a>123</a></choice><choice><b>ab</b><b>cd</b><b>ef</b></choice><choice><c>12.34</c><d>false</d></choice><byte>65</byte><unsigned_byte>66</unsigned_byte><short>-222</short><unsigned_short>57005</unsigned_short><int>-57005</int><unsigned_int>3735928559</unsigned_int><long>-2147483648</long><unsigned_long>2147483647</unsigned_long><integer>-2147483648</integer><non_positive_integer>-2147483648</non_positive_integer><non_negative_integer>2147483647</non_negative_integer><positive_integer>2147483647</positive_integer><negative_integer>-2147483648</negative_integer><boolean>true</boolean><float>1234.12</float><double>12345678.1234568</double><decimal>1234567812345678</decimal><string>string</string><normalized_string>normalized string</normalized_string><token>one two three</token><name>name</name><name_token>name-token</name_token><name_tokens>name tokens</name_tokens><ncname>ncname</ncname><language>en-us</language><qname>xsi:schemaLocation</qname><id>elements1</id><id>elements2</id><id_ref>elements1</id_ref><id_refs>elements1 elements2</id_refs><any_uri>http://www.codesynthesis.com</any_uri><base64_binary>YmFzZTY0IGJpbmFyeQ== </base64_binary><hex_binary>6865782052696E617279</hex_binary><date>2001-10-26+02:00</date><date_time>2001-10-26T21:32:52+02:00</date_time><duration>P1Y2M3DT5H20M30S</duration><day>---01+02:00</day><month>--11+02:00</month><month_day>--02-11+02:00</month_day><year>2001+02:00</year><year_month>2001-11+02:00</year_month><time>21:32:52+02:00</time></t:root>
\ No newline at end of file diff --git a/tests/cxx/hybrid/binary/xdr/test.xml b/tests/cxx/hybrid/binary/xdr/test.xml index acd75d2..1218c37 100644 --- a/tests/cxx/hybrid/binary/xdr/test.xml +++ b/tests/cxx/hybrid/binary/xdr/test.xml @@ -6,10 +6,10 @@ <enumeration>left</enumeration> - <complex x="1"> + <complex x="1" df2="456" ff2="123" dv2="mmm nnn" fv2="aaa bbb ccc"> <a>aaa</a> </complex> - <complex x="1" y="2"> + <complex x="1" y="2" ff2="123" fv2="aaa bbb ccc"> <a>aaa</a> <b>bbb</b> <c>c</c> diff --git a/tests/cxx/hybrid/binary/xdr/test.xsd b/tests/cxx/hybrid/binary/xdr/test.xsd index 7a92c7e..5a2ea34 100644 --- a/tests/cxx/hybrid/binary/xdr/test.xsd +++ b/tests/cxx/hybrid/binary/xdr/test.xsd @@ -35,6 +35,18 @@ <element name="c" type="string" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="y" type="int"/> + + <!-- test default/fixed values --> + + <attribute name="df1" type="int" default="123"/> + <attribute name="df2" type="int" default="123"/> + <attribute name="ff1" type="int" fixed="123"/> + <attribute name="ff2" type="int" fixed="123" use="required"/> + + <attribute name="dv1" type="NMTOKENS" default="aaa bbb ccc"/> + <attribute name="dv2" type="NMTOKENS" default="aaa bbb ccc"/> + <attribute name="fv1" type="NMTOKENS" fixed="aaa bbb ccc"/> + <attribute name="fv2" type="NMTOKENS" fixed="aaa bbb ccc" use="required"/> </extension> </complexContent> </complexType> diff --git a/tests/cxx/hybrid/default/driver.cxx b/tests/cxx/hybrid/default/driver.cxx new file mode 100644 index 0000000..1ab379f --- /dev/null +++ b/tests/cxx/hybrid/default/driver.cxx @@ -0,0 +1,56 @@ +// file : tests/cxx/hybrid/default/driver.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// Test default attribute values. +// + +#include <iostream> + +#include "test.hxx" +#include "test-pimpl.hxx" +#include "test-simpl.hxx" + +using namespace std; +using namespace test; + +int +main (int argc, char* argv[]) +{ + if (argc != 2) + { + cerr << "usage: " << argv[0] << " test.xml" << endl; + return 1; + } + + // Parse. + // + root_paggr root_p; + + xml_schema::document_pimpl doc_p ( + root_p.root_parser (), + root_p.root_namespace (), + root_p.root_name ()); + + root_p.pre (); + doc_p.parse (argv[1]); + type* r = root_p.post (); + + // Serialize. + // + root_saggr root_s; + + xml_schema::document_simpl doc_s ( + root_s.root_serializer (), + root_s.root_namespace (), + root_s.root_name ()); + + doc_s.add_prefix ("t", "test"); + + root_s.pre (*r); + doc_s.serialize (cout); + root_s.post (); + + delete r; +} diff --git a/tests/cxx/hybrid/default/makefile b/tests/cxx/hybrid/default/makefile new file mode 100644 index 0000000..a13db85 --- /dev/null +++ b/tests/cxx/hybrid/default/makefile @@ -0,0 +1,98 @@ +# file : tests/cxx/hybrid/default/makefile +# author : Boris Kolpackov <boris@codesynthesis.com> +# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make + +xsd := test.xsd +cxx := driver.cxx + +obj := $(addprefix $(out_base)/,\ +$(cxx:.cxx=.o) \ +$(xsd:.xsd=.o) \ +$(xsd:.xsd=-pskel.o) \ +$(xsd:.xsd=-pimpl.o) \ +$(xsd:.xsd=-sskel.o) \ +$(xsd:.xsd=-simpl.o)) + +dep := $(obj:.o=.o.d) + +xsde.l := $(out_root)/libxsde/xsde/xsde.l +xsde.l.cpp-options := $(out_root)/libxsde/xsde/xsde.l.cpp-options + +driver := $(out_base)/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + + +# Build. +# +$(driver): $(obj) $(xsde.l) + +$(obj) $(dep): $(xsde.l.cpp-options) + +genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.cxx) \ + $(xsd:.xsd=-pskel.hxx) $(xsd:.xsd=-pskel.cxx) \ + $(xsd:.xsd=-pimpl.hxx) $(xsd:.xsd=-pimpl.cxx) \ + $(xsd:.xsd=-sskel.hxx) $(xsd:.xsd=-sskel.cxx) \ + $(xsd:.xsd=-simpl.hxx) $(xsd:.xsd=-simpl.cxx) + +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): $(out_root)/xsde/xsde +$(gen): xsde := $(out_root)/xsde/xsde +$(gen): xsde_options += --generate-parser --generate-serializer \ +--generate-aggregate + +$(call include-dep,$(dep)) + +# Convenience alias for default target. +# +.PHONY: $(out_base)/ +$(out_base)/: $(driver) + + +# Test. +# +.PHONY: $(test) + +$(test): driver := $(driver) +$(test): $(driver) $(src_base)/test.xml $(src_base)/output + $(call message,test $$1,$$1 $(src_base)/test.xml | diff -ubB $(src_base)/output -,$(driver)) + +# Clean. +# +.PHONY: $(clean) + +$(clean): $(driver).o.clean \ + $(addsuffix .cxx.clean,$(obj)) \ + $(addsuffix .cxx.clean,$(dep)) \ + $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) + + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(gen): | $(out_base)/.gitignore +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(scf_root)/xsde/hybrid/xsd-cxx.make) + + +# Dependencies. +# +$(call import,$(src_root)/xsde/makefile) +$(call import,$(src_root)/libxsde/xsde/makefile) diff --git a/tests/cxx/hybrid/default/output b/tests/cxx/hybrid/default/output new file mode 100644 index 0000000..8d41894 --- /dev/null +++ b/tests/cxx/hybrid/default/output @@ -0,0 +1 @@ +<t:root xmlns:t="test" any="" bool1="true" bool2="true" bool3="false" bool4="false" byte="-99" decimal1="1.12345" decimal2="-0.456" double1="1.12345" double2="1123.45" double3="-0.00012345" double4="NaN" double5="-INF" fix1="123" fix2="123" fix3="abc" fix4="abc" fix5="aaa bbb ccc" fix6="aaa bbb ccc" float1="1.123" float2="1123" float3="-0.000123" float4="NaN" float5="-INF" id="this" idref="this" idrefs="this" int="-99999" integer="-99999" language="en-us" long="-99999" ncname="abcd" ninteger="-99999" nmtoken="ab:cd" nmtokens1="a:b efg aaa" nmtokens2="abc" nninteger="99999" npinteger="-99999" nstring=" a b " pinteger="99999" qname1="foo" qname2="t:bar" short="-999" string1="" string2=" a b " token="a b" ubyte="99" uint="99999" ulong="99999" uri="http://example.com" ushort="999"><union a="abc"></union><list a="123 345 678" b="ab cd ef" c="abc" d="abc def"></list><simple a="123" b="abc" c="123" d="abc" e="abc" f="abc 123"></simple><date a="2009-03-31" b="2009-03-31Z" c="2009-03-31Z" d="2009-03-31Z" e="2009-03-31+12:30" f="2009-03-31-12:30" g="2002009-03-31-12:30"></date><time a="12:03:45" b="12:03:45.123Z" c="12:03:05.123Z" d="12:03:45.123Z" e="12:03:45.123+12:30" f="12:03:45-12:30"></time><date-time a="2009-03-31T12:03:45" b="2009-03-31T12:03:45.123Z" c="2002009-03-31T12:03:05.123-12:30"></date-time><duration a="P100Y" b="P100M" c="P100D" d="PT12H" e="PT12M" f="PT12.123S" g="-P100Y10M20DT12H12M1.123S"></duration><day a="---02" b="---22Z" c="---22-12:30"></day><month a="--02" b="--12Z" c="--12+12:30"></month><year a="2009" b="-2002009Z" c="2009-12:30"></year><month-day a="--02-02" b="--12-22Z" c="--12-22+12:30"></month-day><year-month a="2009-02" b="-2002009-12Z" c="2009-12-12:30"></year-month></t:root>
\ No newline at end of file diff --git a/tests/cxx/hybrid/default/test.xml b/tests/cxx/hybrid/default/test.xml new file mode 100644 index 0000000..11bd0a7 --- /dev/null +++ b/tests/cxx/hybrid/default/test.xml @@ -0,0 +1,16 @@ +<t:root xmlns:t="test" id="this" fix2="123" fix4="abc" fix6="aaa bbb ccc"> + + <union/> + <list/> + <simple/> + <date/> + <time/> + <date-time/> + <duration/> + <day/> + <month/> + <year/> + <month-day/> + <year-month/> + +</t:root> diff --git a/tests/cxx/hybrid/default/test.xsd b/tests/cxx/hybrid/default/test.xsd new file mode 100644 index 0000000..366b37e --- /dev/null +++ b/tests/cxx/hybrid/default/test.xsd @@ -0,0 +1,228 @@ +<?xml version="1.0"?> +<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test"> + + <!-- union --> + + <simpleType name="union"> + <union memberTypes="int string"/> + </simpleType> + + <complexType name="union-test"> + <attribute default="abc" name="a" type="t:union"/> + </complexType> + + <!-- list --> + + <simpleType name="fix-list"> + <list itemType="int"/> + </simpleType> + + <simpleType name="var-list"> + <list itemType="string"/> + </simpleType> + + <simpleType name="list-item"> + <restriction base="string"/> + </simpleType> + + <simpleType name="usr-list"> + <list itemType="t:list-item"/> + </simpleType> + + <simpleType name="union-list"> + <list itemType="t:union"/> + </simpleType> + + <complexType name="list-test"> + <attribute default="123 345 678" name="a" type="t:fix-list"/> + <attribute default=" ab cd ef " name="b" type="t:var-list"/> + <attribute default="abc" name="c" type="t:usr-list"/> + <attribute default="abc def" name="d" type="t:union-list"/> + </complexType> + + <!-- simple type --> + + <simpleType name="int-base"> + <restriction base="int"/> + </simpleType> + + <simpleType name="str-base"> + <restriction base="string"/> + </simpleType> + + <simpleType name="int"> + <restriction base="t:int-base"/> + </simpleType> + + <simpleType name="str"> + <restriction base="t:str-base"/> + </simpleType> + + <simpleType name="union-derived"> + <restriction base="t:union"/> + </simpleType> + + <simpleType name="list-derived"> + <restriction base="t:usr-list"/> + </simpleType> + + <complexType name="simple-test"> + <attribute default="123" name="a" type="t:int-base"/> + <attribute default="abc" name="b" type="t:str-base"/> + <attribute default="123" name="c" type="t:int"/> + <attribute default="abc" name="d" type="t:str"/> + <attribute default="abc" name="e" type="t:union-derived"/> + <attribute default="abc 123" name="f" type="t:list-derived"/> + </complexType> + + <!-- date/time types --> + + <complexType name="date-test"> + <attribute default="2009-03-31" name="a" type="date"/> + <attribute default="2009-03-31Z" name="b" type="date"/> + <attribute default="2009-03-31+00:00" name="c" type="date"/> + <attribute default="2009-03-31-00:00" name="d" type="date"/> + <attribute default="2009-03-31+12:30" name="e" type="date"/> + <attribute default="2009-03-31-12:30" name="f" type="date"/> + <attribute default="2002009-03-31-12:30" name="g" type="date"/> + </complexType> + + <complexType name="time-test"> + <attribute default="12:03:45" name="a" type="time"/> + <attribute default="12:03:45.123Z" name="b" type="time"/> + <attribute default="12:03:05.123+00:00" name="c" type="time"/> + <attribute default="12:03:45.123-00:00" name="d" type="time"/> + <attribute default="12:03:45.123+12:30" name="e" type="time"/> + <attribute default="12:03:45-12:30" name="f" type="time"/> + </complexType> + + <complexType name="date-time-test"> + <attribute default="2009-03-31T12:03:45" name="a" type="dateTime"/> + <attribute default="2009-03-31T12:03:45.123Z" name="b" type="dateTime"/> + <attribute default="2002009-03-31T12:03:05.123-12:30" name="c" type="dateTime"/> + </complexType> + + <complexType name="duration-test"> + <attribute default="P100Y" name="a" type="duration"/> + <attribute default="P100M" name="b" type="duration"/> + <attribute default="P100D" name="c" type="duration"/> + <attribute default="PT12H" name="d" type="duration"/> + <attribute default="PT12M" name="e" type="duration"/> + <attribute default="PT12.123S" name="f" type="duration"/> + <attribute default="-P100Y10M20DT12H12M1.123S" name="g" type="duration"/> + </complexType> + + <complexType name="day-test"> + <attribute default="---02" name="a" type="gDay"/> + <attribute default="---22Z" name="b" type="gDay"/> + <attribute default="---22-12:30" name="c" type="gDay"/> + </complexType> + + <complexType name="month-test"> + <attribute default="--02" name="a" type="gMonth"/> + <attribute default="--12Z" name="b" type="gMonth"/> + <attribute default="--12+12:30" name="c" type="gMonth"/> + </complexType> + + <complexType name="year-test"> + <attribute default="2009" name="a" type="gYear"/> + <attribute default="-2002009Z" name="b" type="gYear"/> + <attribute default="2009-12:30" name="c" type="gYear"/> + </complexType> + + <complexType name="month-day-test"> + <attribute default="--02-02" name="a" type="gMonthDay"/> + <attribute default="--12-22Z" name="b" type="gMonthDay"/> + <attribute default="--12-22+12:30" name="c" type="gMonthDay"/> + </complexType> + + <complexType name="year-month-test"> + <attribute default="2009-02" name="a" type="gYearMonth"/> + <attribute default="-2002009-12Z" name="b" type="gYearMonth"/> + <attribute default="2009-12-12:30" name="c" type="gYearMonth"/> + </complexType> + + + <complexType name="type"> + <sequence> + <element name="union" type="t:union-test"/> + <element name="list" type="t:list-test"/> + <element name="simple" type="t:simple-test"/> + <element name="date" type="t:date-test"/> + <element name="time" type="t:time-test"/> + <element name="date-time" type="t:date-time-test"/> + <element name="duration" type="t:duration-test"/> + <element name="day" type="t:day-test"/> + <element name="month" type="t:month-test"/> + <element name="year" type="t:year-test"/> + <element name="month-day" type="t:month-day-test"/> + <element name="year-month" type="t:year-month-test"/> + </sequence> + <attribute name="any" type="anySimpleType" default=""/> + + <attribute name="bool1" type="boolean" default="true"/> + <attribute name="bool2" type="boolean" default="1"/> + <attribute name="bool3" type="boolean" default="false"/> + <attribute name="bool4" type="boolean" default="0"/> + + <attribute name="byte" type="byte" default="-99"/> + <attribute name="ubyte" type="unsignedByte" default="99"/> + <attribute name="short" type="short" default="-999"/> + <attribute name="ushort" type="unsignedShort" default="999"/> + <attribute name="int" type="int" default="-99999"/> + <attribute name="uint" type="unsignedInt" default="99999"/> + <attribute name="long" type="long" default="-99999"/> + <attribute name="ulong" type="unsignedLong" default="99999"/> + + <attribute name="integer" type="integer" default="-99999"/> + <attribute name="npinteger" type="nonPositiveInteger" default="-99999"/> + <attribute name="nninteger" type="nonNegativeInteger" default="99999"/> + <attribute name="pinteger" type="positiveInteger" default="99999"/> + <attribute name="ninteger" type="negativeInteger" default="-99999"/> + + <attribute name="float1" type="float" default="1.123"/> + <attribute name="float2" type="float" default="1.123e3"/> + <attribute name="float3" type="float" default="-.123E-3"/> + <attribute name="float4" type="float" default="NaN"/> + <attribute name="float5" type="float" default="-INF"/> + + <attribute name="double1" type="double" default="1.12345"/> + <attribute name="double2" type="double" default="1.12345e3"/> + <attribute name="double3" type="double" default="-.12345E-3"/> + <attribute name="double4" type="double" default="NaN"/> + <attribute name="double5" type="double" default="-INF"/> + + <attribute name="decimal1" type="decimal" default="1.12345"/> + <attribute name="decimal2" type="decimal" default="-.456"/> + + <attribute name="string1" type="string" default=""/> + <attribute name="string2" type="string" default=" a b "/> + <attribute name="nstring" type="normalizedString" default=" a b "/> + <attribute name="token" type="token" default=" a b "/> + <attribute name="nmtoken" type="NMTOKEN" default="ab:cd"/> + <attribute name="nmtokens1" type="NMTOKENS" default=" a:b efg aaa "/> + <attribute name="nmtokens2" type="NMTOKENS" default="abc"/> + <attribute name="ncname" type="NCName" default=" abcd "/> + <attribute name="language" type="language" default=" en-us "/> + <attribute name="id" type="ID"/> + <attribute name="idref" type="IDREF" default="this"/> + <attribute name="idrefs" type="IDREFS" default=" this "/> + <attribute name="uri" type="anyURI" default=" http://example.com "/> + + <attribute name="qname1" type="QName" default="foo"/> + <attribute name="qname2" type="QName" default="t:bar"/> + + <!-- fixed --> + + <attribute name="fix1" type="int" fixed="123"/> + <attribute name="fix2" type="int" fixed="123" use="required"/> + <attribute name="fix3" type="string" fixed="abc"/> + <attribute name="fix4" type="string" fixed="abc" use="required"/> + <attribute name="fix5" type="NMTOKENS" fixed="aaa bbb ccc"/> + <attribute name="fix6" type="NMTOKENS" fixed="aaa bbb ccc" use="required"/> + + </complexType> + + <element name="root" type="t:type"/> + +</schema> diff --git a/tests/cxx/hybrid/makefile b/tests/cxx/hybrid/makefile index 24ed1f0..46fc06c 100644 --- a/tests/cxx/hybrid/makefile +++ b/tests/cxx/hybrid/makefile @@ -8,7 +8,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make tests := polymorphism sequences ifeq ($(xsde_iostream),y) -tests += built-in list recursive test-template union +tests += built-in default list recursive test-template union ifeq ($(xsde_cdr),y) tests += binary/cdr diff --git a/xsde/cxx/hybrid/cli.hxx b/xsde/cxx/hybrid/cli.hxx index 80b91bc..509005a 100644 --- a/xsde/cxx/hybrid/cli.hxx +++ b/xsde/cxx/hybrid/cli.hxx @@ -33,6 +33,7 @@ namespace CXX extern Key suppress_validation; extern Key suppress_parser_val; extern Key suppress_serializer_val; + extern Key omit_default_attributes; extern Key generate_detach; extern Key generate_insertion; extern Key generate_extraction; @@ -120,6 +121,7 @@ namespace CXX suppress_validation, Boolean, suppress_parser_val, Boolean, suppress_serializer_val, Boolean, + omit_default_attributes, Boolean, generate_detach, Boolean, generate_insertion, Cult::Containers::Vector<NarrowString>, generate_extraction, Cult::Containers::Vector<NarrowString>, diff --git a/xsde/cxx/hybrid/default-value.cxx b/xsde/cxx/hybrid/default-value.cxx new file mode 100644 index 0000000..895c764 --- /dev/null +++ b/xsde/cxx/hybrid/default-value.cxx @@ -0,0 +1,1210 @@ +// file : xsde/cxx/hybrid/default-value.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cxx/hybrid/default-value.hxx> + +namespace CXX +{ + namespace Hybrid + { + namespace + { + Void + normalize (String& s) + { + Size n (s.size ()); + + for (Size i (0); i < n; ++i) + { + WideChar& c (s[i]); + + if (c == 0x0D || // carriage return + c == 0x09 || // tab + c == 0x0A) + c = 0x20; + } + } + + Void + collapse (String& s) + { + Size n (s.size ()), j (0); + Boolean subs (false), trim (true); + + for (Size i (0); i < n; ++i) + { + WideChar c (s[i]); + + if (c == 0x20 || c == 0x09 || c == 0x0A) + subs = true; + else + { + if (subs) + { + subs = false; + + if (!trim) + s[j++] = 0x20; + } + + if (trim) + trim = false; + + s[j++] = c; + } + } + + s.resize (j); + } + + Void + strip_zeros (String& s) + { + Size n (s.size ()), i (0); + + if (n > 0 && s[i] == '-' || s[i] == '+') + i++; + + Size j (i); + + Boolean strip (true); + + for (; i < n; ++i) + { + WideChar c (s[i]); + + if (c == '0') + { + if (!strip) + s[j++] = c; + } + else + { + s[j++] = c; + + if (strip) + strip = false; + } + } + + if (strip && j < n) + s[j++] = '0'; // There was nothing except zeros so add one back. + + s.resize (j); + } + } + + // + // LiteralValue + // + LiteralValue:: + LiteralValue (Context& c) + : Context (c), str_ (!stl) + { + } + + LiteralValue:: + LiteralValue (Context& c, Boolean str) + : Context (c), str_ (str) + { + } + + String LiteralValue:: + dispatch (SemanticGraph::Node& type, String const& value) + { + literal_.clear (); + value_ = value; + Traversal::NodeBase::dispatch (type); + return literal_; + } + + // Boolean. + // + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Boolean&) + { + collapse (value_); + literal_ = (value_ == L"true" || value_ == L"1") ? "true" : "false"; + } + + // Integral types. + // + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Byte&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::UnsignedByte&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Short&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::UnsignedShort&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Int&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::UnsignedInt&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Long&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + literal_ += options.value<CLI::no_long_long> () ? L"L" : L"LL"; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::UnsignedLong&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + literal_ += options.value<CLI::no_long_long> () ? L"UL" : L"ULL"; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Integer&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_ + L"L"; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::NonPositiveInteger&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_ + L"L"; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::NonNegativeInteger&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_ + L"UL"; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::PositiveInteger&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_ + L"UL"; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::NegativeInteger&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_ + L"L"; + } + + // Floats. + // + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Float&) + { + collapse (value_); + + if (value_ == L"NaN") + { + literal_ = "static_cast< float > (strtod (\"NAN\", 0))"; + } + else if (value_ == L"INF") + { + literal_ = "static_cast< float > (strtod (\"INF\", 0))"; + } + else if (value_ == L"-INF") + { + literal_ = "static_cast< float > (strtod (\"-INF\", 0))"; + } + else + { + strip_zeros (value_); + literal_ = value_ + L"F"; + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Double&) + { + collapse (value_); + + if (value_ == L"NaN") + { + literal_ = "strtod (\"NAN\", 0)"; + } + else if (value_ == L"INF") + { + literal_ = "strtod (\"INF\", 0)"; + } + else if (value_ == L"-INF") + { + literal_ = "strtod (\"-INF\", 0)"; + } + else + { + strip_zeros (value_); + literal_ = value_; + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Decimal&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + } + + // Strings. + // + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::String&) + { + if (str_) + literal_ = strlit (value_); + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::NormalizedString&) + { + if (str_) + { + normalize (value_); + literal_ = strlit (value_); + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Token&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::NameToken&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Name&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::NCName&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Language&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + + // ID/IDREF. + // + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Id&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::IdRef&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + // URI. + // + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::AnyURI&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + // Entity. + // + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::Entity&) + { + if (str_) + { + collapse (value_); + literal_ = strlit (value_); + } + } + + // + // InitValue + // + + InitValue:: + InitValue (Context& c) + : Context (c), + member_ ("this->value_."), + var_ (c, TypeName::var), + var_value_ (c, TypeName::var_value), + literal_value_ (c, true), + literal_value_list_ (c) + { + } + + Void InitValue:: + dispatch (SemanticGraph::Node& type, String const& value) + { + value_ = value; + Traversal::NodeBase::dispatch (type); + } + + Void InitValue:: + traverse (SemanticGraph::List& l) + { + SemanticGraph::Type& t (l.argumented ().type ()); + Boolean fl (fixed_length (t)); + + collapse (value_); + + if (!value_) + return; + + String ov (value_); + String om (member_); + + Size b (0); + + for (Size e (ov.find (' ')); ; e = ov.find (' ', b)) + { + String v (ov, b, e != String::npos ? e - b : e); + + os << "{"; + var_.dispatch (t); + os << " tmp;"; + + String literal (literal_value_list_.dispatch (t, v)); + + if (literal) + { + // Variable-length literal is a string. + // + if (fl) + os << "tmp = " << literal << ";"; + else + { + os << "tmp = ::xsde::cxx::strdupx (" << literal << ");"; + + if (!exceptions) + { + os << endl + << "if (!tmp)" + << "{" + << "assert (false);" + << "exit (1);" + << "}"; + } + } + } + else + { + if (fl) + member_ = "tmp."; + else + { + os << "tmp = new " << fq_name (t) << ";"; + + if (!exceptions) + { + os << endl + << "if (!tmp)" + << "{" + << "assert (false);" + << "exit (1);" + << "}"; + } + + member_ = "tmp->"; + } + + value_ = v; + Traversal::NodeBase::dispatch (t); + } + + if (exceptions) + os << om << "push_back (tmp);"; + else + os << "if (" << om << "push_back (tmp))" + << "{" + << "assert (false);" + << "exit (1);" + << "}"; + + os << "}"; + + if (e == String::npos) + break; + + b = e + 1; + } + + member_ = om; + value_ = ov; + } + + Void InitValue:: + traverse (SemanticGraph::Union& u) + { + String const& value (u.context ().get<String> ("value")); + + if (stl) + os << member_ << value << " (" << strlit (value_) << ");"; + else + { + if (exceptions) + os << member_ << value << " ("; + else + os << "char* v = "; + + os << "::xsde::cxx::strdupx (" << strlit (value_) << ")"; + + if (exceptions) + os << ");"; + else + { + os << ";" + << endl + << "if (!v)" + << "{" + << "assert (false);" + << "exit (1);" + << "}" + << member_ << value << " (v);"; + } + } + } + + Void InitValue:: + traverse (SemanticGraph::Complex& c) + { + Traversal::NodeBase::dispatch (ultimate_base (c)); + } + + Void InitValue:: + traverse (SemanticGraph::Type& t) + { + // This is a fall-back case where we handle all other (literal) + // types. + // + os << member_ << "base_value (" << + literal_value_.dispatch (t, value_) << ");"; + } + + // anySimpleType. + // + Void InitValue:: + traverse (SemanticGraph::AnySimpleType&) + { + } + + // Strings. + // + Void InitValue:: + traverse (SemanticGraph::Fundamental::String& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::NormalizedString& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Token& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::NameToken& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::NameTokens&) + { + string_sequence_type (); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Name& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::NCName& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Language& t) + { + string_type (t); + } + + // Qualified name. + // + Void InitValue:: + traverse (SemanticGraph::Fundamental::QName&) + { + collapse (value_); + + String prefix, name; + Size p (value_.find (':')); + + if (p != String::npos) + { + prefix.assign (value_, 0, p); + name.assign (value_, p + 1, String::npos); + } + else + name = value_; + + if (stl) + { + os << member_ << "prefix (" << strlit (prefix) << ");" + << member_ << "name (" << strlit (name) << ");"; + } + else + { + if (exceptions) + os << member_ << "prefix_copy (" << strlit (prefix) << ");" + << member_ << "name_copy (" << strlit (name) << ");"; + else + os << "if (" << member_ << "prefix_copy (" << strlit (prefix) << + ") || " << member_ << "name_copy (" << strlit (name) << "))" + << "{" + << "assert (false);" + << "exit (1);" + << "}"; + } + } + + // ID/IDREF. + // + Void InitValue:: + traverse (SemanticGraph::Fundamental::Id& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::IdRef& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::IdRefs&) + { + string_sequence_type (); + } + + // URI. + // + Void InitValue:: + traverse (SemanticGraph::Fundamental::AnyURI& t) + { + string_type (t); + } + + // Binary. + // + Void InitValue:: + traverse (SemanticGraph::Fundamental::Base64Binary&) + { + collapse (value_); + + if (value_) + os << "#error base64Binary default values are not yet supported" + << endl; + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::HexBinary&) + { + collapse (value_); + + if (value_) + os << "#error hexBinary default values are not yet supported" + << endl; + } + + + // Date/time. + // + Void InitValue:: + traverse (SemanticGraph::Fundamental::Date&) + { + // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM] + // + collapse (value_); + + Size b (0); + Size e (value_.find ('-', value_[0] == '-' ? 5 : 4)); + String year (value_, 0, e); + + b = e + 1; + String month (value_, b, 2); + + b += 3; + String day (value_, b, 2); + + strip_zeros (year); + strip_zeros (month); + strip_zeros (day); + + os << member_ << "year (" << year << ");" + << member_ << "month (" << month << ");" + << member_ << "day (" << day << ");"; + + time_zone (b + 2); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::DateTime&) + { + // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM] + // + collapse (value_); + + Size b (0); + Size e (value_.find ('-', value_[0] == '-' ? 5 : 4)); + String year (value_, 0, e); + b = e + 1; + + String month (value_, b, 2); + b += 3; + + String day (value_, b, 2); + b += 3; + + String hours (value_, b, 2); + b += 3; + + String minutes (value_, b, 2); + b += 3; + + e = b + 2; + for (; e < value_.size (); ++e) + { + WideChar c (value_[e]); + + if (c == 'Z' || c == '+' || c == '-') + break; + } + + String seconds (value_, b, e - b); + + strip_zeros (year); + strip_zeros (month); + strip_zeros (day); + strip_zeros (hours); + strip_zeros (minutes); + strip_zeros (seconds); + + os << member_ << "year (" << year << ");" + << member_ << "month (" << month << ");" + << member_ << "day (" << day << ");" + << member_ << "hours (" << hours << ");" + << member_ << "minutes (" << minutes << ");" + << member_ << "seconds (" << seconds << ");"; + + time_zone (e); + } + + namespace + { + Size + find_delim (String const& s, Size pos) + { + for (; pos < s.size (); ++pos) + { + WideChar c (s[pos]); + + if (c == 'Y' || c == 'D' || c == 'M' || c == 'H' || + c == 'M' || c == 'S' || c == 'T') + break; + } + + return pos; + } + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Duration&) + { + // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S] + // + collapse (value_); + + Size b (1), e, n (value_.size ()); + + if (value_[0] == '-') + { + os << member_ << "negative (true);"; + b++; + } + + e = find_delim (value_, b); + + if (e < n && value_[e] == 'Y') + { + String v (value_, b, e - b); + strip_zeros (v); + os << member_ << "years (" << v << ");"; + + b = e + 1; + e = find_delim (value_, b); + } + + if (e < n && value_[e] == 'M') + { + String v (value_, b, e - b); + strip_zeros (v); + os << member_ << "months (" << v << ");"; + + b = e + 1; + e = find_delim (value_, b); + } + + if (e < n && value_[e] == 'D') + { + String v (value_, b, e - b); + strip_zeros (v); + os << member_ << "days (" << v << ");"; + + b = e + 1; + e = find_delim (value_, b); + } + + if (e < n && value_[e] == 'T') + { + b = e + 1; + e = find_delim (value_, b); + } + + if (e < n && value_[e] == 'H') + { + String v (value_, b, e - b); + strip_zeros (v); + os << member_ << "hours (" << v << ");"; + + b = e + 1; + e = find_delim (value_, b); + } + + if (e < n && value_[e] == 'M') + { + String v (value_, b, e - b); + strip_zeros (v); + os << member_ << "minutes (" << v << ");"; + + b = e + 1; + e = find_delim (value_, b); + } + + if (e < n && value_[e] == 'S') + { + String v (value_, b, e - b); + strip_zeros (v); + os << member_ << "seconds (" << v << ");"; + + b = e + 1; + e = find_delim (value_, b); + } + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Day&) + { + // gday := ---DD[Z|(+|-)HH:MM] + // + collapse (value_); + + String day (value_, 3, 2); + strip_zeros (day); + + os << member_ << "day (" << day << ");"; + + time_zone (5); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Month&) + { + // gmonth := --MM[Z|(+|-)HH:MM] + // + collapse (value_); + + String month (value_, 2, 2); + strip_zeros (month); + + os << member_ << "month (" << month << ");"; + + time_zone (4); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::MonthDay&) + { + // gmonth_day := --MM-DD[Z|(+|-)HH:MM] + // + collapse (value_); + + String month (value_, 2, 2); + String day (value_, 5, 2); + + strip_zeros (month); + strip_zeros (day); + + os << member_ << "month (" << month << ");"; + os << member_ << "day (" << day << ");"; + + time_zone (7); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Year&) + { + // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM] + // + collapse (value_); + + Size pos (value_[0] == '-' ? 5 : 4); + for (; pos < value_.size (); ++pos) + { + WideChar c (value_[pos]); + + if (c == 'Z' || c == '+' || c == '-') + break; + } + + String year (value_, 0, pos); + strip_zeros (year); + + os << member_ << "year (" << year << ");"; + + time_zone (pos); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::YearMonth&) + { + // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM] + // + collapse (value_); + + Size pos (value_.find ('-', value_[0] == '-' ? 5 : 4)); + + String year (value_, 0, pos); + String month (value_, pos + 1, 2); + + strip_zeros (year); + strip_zeros (month); + + os << member_ << "year (" << year << ");"; + os << member_ << "month (" << month << ");"; + + time_zone (pos + 3); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Time&) + { + // time := HH:MM:SS[.S+][Z|(+|-)HH:MM] + // + collapse (value_); + + String hours (value_, 0, 2); + String minutes (value_, 3, 2); + + Size e (8); + for (; e < value_.size (); ++e) + { + WideChar c (value_[e]); + + if (c == 'Z' || c == '+' || c == '-') + break; + } + + String seconds (value_, 6, e - 6); + + strip_zeros (hours); + strip_zeros (minutes); + strip_zeros (seconds); + + os << member_ << "hours (" << hours << ");" + << member_ << "minutes (" << minutes << ");" + << member_ << "seconds (" << seconds << ");"; + + time_zone (e); + } + + Void InitValue:: + time_zone (Size pos) + { + // time_zone := Z|(+|-)HH:MM + // + if (pos < value_.size ()) + { + String h, m; + + if (value_[pos] == 'Z') + { + h = "0"; + m = "0"; + } + else + { + if (value_[pos] == '-') + { + h = "-"; + m = "-"; + } + + h.append (value_, pos + 1, 2); + m.append (value_, pos + 4, 2); + + strip_zeros (h); + strip_zeros (m); + } + + os << member_ << "zone_hours (" << h << ");" + << member_ << "zone_minutes (" << m << ");"; + } + } + + // Entity. + // + Void InitValue:: + traverse (SemanticGraph::Fundamental::Entity& t) + { + string_type (t); + } + + Void InitValue:: + traverse (SemanticGraph::Fundamental::Entities&) + { + string_sequence_type (); + } + + Void InitValue:: + string_type (SemanticGraph::Fundamental::Type& t) + { + // In case STL is disabled, strings are returned as literals + // so we end up here only if the type is derived from a string. + // Otherwise, use assign() which handles both derivations as + // well as the straight std::string value. + // + if (stl) + os << member_ << "assign (" << literal_value_.dispatch (t, value_) << + ");"; + else + { + if (exceptions) + os << member_ << "base_value ("; + else + os << "char* v = "; + + os << "::xsde::cxx::strdupx (" << + literal_value_.dispatch (t, value_) << ")"; + + if (exceptions) + os << ");"; + else + { + os << ";" + << endl + << "if (!v)" + << "{" + << "assert (false);" + << "exit (1);" + << "}" + << member_ << "base_value (v);"; + } + } + } + + Void InitValue:: + string_sequence_type () + { + collapse (value_); + + if (!value_) + return; + + Size b (0); + + for (Size e (value_.find (' ')); ; e = value_.find (' ', b)) + { + String v (value_, b, e != String::npos ? e - b : e); + + os << "{"; + + if (stl) + os << "::std::string tmp ("; + else + os << "char* tmp = ::xsde::cxx::strdupx ("; + + os << strlit (v) << ");"; + + if (!exceptions && !stl) + { + os << endl + << "if (!tmp)" + << "{" + << "assert (false);" + << "exit (1);" + << "}"; + } + + if (exceptions) + os << member_ << "push_back (tmp);"; + else + os << "if (" << member_ << "push_back (tmp))" + << "{" + << "assert (false);" + << "exit (1);" + << "}"; + + os << "}"; + + if (e == String::npos) + break; + + b = e + 1; + } + } + + // + // CompareValue + // + + CompareValue:: + CompareValue (Context& c) + : Context (c) + { + } + + Void CompareValue:: + dispatch (SemanticGraph::Node& type, String const& lhs, String const& rhs) + { + lhs_ = &lhs; + rhs_ = &rhs; + Traversal::NodeBase::dispatch (type); + } + + Void CompareValue:: + traverse (SemanticGraph::Union& u) + { + String const& value (u.context ().get<String> ("value")); + + os << *lhs_ << "." << value << " () == " << *rhs_ << "." << value << + " ()"; + } + + Void CompareValue:: + traverse (SemanticGraph::Complex& c) + { + Traversal::NodeBase::dispatch (ultimate_base (c)); + } + + Void CompareValue:: + traverse (SemanticGraph::Type& t) + { + // This is a fall-back case where we handle all other types. + // + os << *lhs_ << " == " << *rhs_; + } + } +} diff --git a/xsde/cxx/hybrid/default-value.hxx b/xsde/cxx/hybrid/default-value.hxx new file mode 100644 index 0000000..b9f902c --- /dev/null +++ b/xsde/cxx/hybrid/default-value.hxx @@ -0,0 +1,366 @@ +// file : xsde/cxx/hybrid/default-value.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_HYBRID_DEFAULT_VALUE_HXX +#define CXX_HYBRID_DEFAULT_VALUE_HXX + +#include <xsd-frontend/semantic-graph.hxx> +#include <xsd-frontend/traversal.hxx> + +#include <cxx/hybrid/elements.hxx> + +namespace CXX +{ + namespace Hybrid + { + struct LiteralValue: Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::AnyURI, + Traversal::Fundamental::Entity, + + Context + { + LiteralValue (Context&); + LiteralValue (Context&, Boolean str); + + String + dispatch (SemanticGraph::Node& type, String const& value); + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean&); + + // Integral types. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte&); + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte&); + + virtual Void + traverse (SemanticGraph::Fundamental::Short&); + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort&); + + virtual Void + traverse (SemanticGraph::Fundamental::Int&); + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt&); + + virtual Void + traverse (SemanticGraph::Fundamental::Long&); + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong&); + + virtual Void + traverse (SemanticGraph::Fundamental::Integer&); + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger&); + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger&); + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger&); + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger&); + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float&); + + virtual Void + traverse (SemanticGraph::Fundamental::Double&); + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal&); + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String&); + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&); + + virtual Void + traverse (SemanticGraph::Fundamental::Token&); + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken&); + + virtual Void + traverse (SemanticGraph::Fundamental::Name&); + + virtual Void + traverse (SemanticGraph::Fundamental::NCName&); + + virtual Void + traverse (SemanticGraph::Fundamental::Language&); + + // ID/IDREF. + // + virtual Void + traverse (SemanticGraph::Fundamental::Id&); + + virtual Void + traverse (SemanticGraph::Fundamental::IdRef&); + + // URI. + // + virtual Void + traverse (SemanticGraph::Fundamental::AnyURI&); + + // Entity. + // + virtual Void + traverse (SemanticGraph::Fundamental::Entity&); + + private: + Boolean str_; + String value_; + String literal_; + }; + + struct InitValue: Traversal::List, + Traversal::Union, + Traversal::Complex, + Traversal::Type, + + Traversal::AnySimpleType, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + + Traversal::Fundamental::QName, + + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::IdRefs, + + Traversal::Fundamental::AnyURI, + + Traversal::Fundamental::Base64Binary, + Traversal::Fundamental::HexBinary, + + Traversal::Fundamental::Date, + Traversal::Fundamental::DateTime, + Traversal::Fundamental::Duration, + Traversal::Fundamental::Day, + Traversal::Fundamental::Month, + Traversal::Fundamental::MonthDay, + Traversal::Fundamental::Year, + Traversal::Fundamental::YearMonth, + Traversal::Fundamental::Time, + + Traversal::Fundamental::Entity, + Traversal::Fundamental::Entities, + + Context + { + InitValue (Context&); + + Void + dispatch (SemanticGraph::Node& type, String const& value); + + virtual Void + traverse (SemanticGraph::List&); + + virtual Void + traverse (SemanticGraph::Union&); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Type& t); + + // anySimpleType. + // + virtual Void + traverse (SemanticGraph::AnySimpleType&); + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String&); + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&); + + virtual Void + traverse (SemanticGraph::Fundamental::Token&); + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken&); + + virtual Void + traverse (SemanticGraph::Fundamental::NameTokens&); + + virtual Void + traverse (SemanticGraph::Fundamental::Name&); + + virtual Void + traverse (SemanticGraph::Fundamental::NCName&); + + virtual Void + traverse (SemanticGraph::Fundamental::Language&); + + // Qualified name. + // + virtual Void + traverse (SemanticGraph::Fundamental::QName&); + + // ID/IDREF. + // + virtual Void + traverse (SemanticGraph::Fundamental::Id&); + + virtual Void + traverse (SemanticGraph::Fundamental::IdRef&); + + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs&); + + // URI. + // + virtual Void + traverse (SemanticGraph::Fundamental::AnyURI&); + + // Binary. + // + virtual Void + traverse (SemanticGraph::Fundamental::Base64Binary&); + + virtual Void + traverse (SemanticGraph::Fundamental::HexBinary&); + + // Date/time. + // + virtual Void + traverse (SemanticGraph::Fundamental::Date&); + + virtual Void + traverse (SemanticGraph::Fundamental::DateTime&); + + virtual Void + traverse (SemanticGraph::Fundamental::Duration&); + + virtual Void + traverse (SemanticGraph::Fundamental::Day&); + + virtual Void + traverse (SemanticGraph::Fundamental::Month&); + + virtual Void + traverse (SemanticGraph::Fundamental::MonthDay&); + + virtual Void + traverse (SemanticGraph::Fundamental::Year&); + + virtual Void + traverse (SemanticGraph::Fundamental::YearMonth&); + + virtual Void + traverse (SemanticGraph::Fundamental::Time&); + + // Entity. + // + virtual Void + traverse (SemanticGraph::Fundamental::Entity&); + + virtual Void + traverse (SemanticGraph::Fundamental::Entities&); + + private: + Void + string_type (SemanticGraph::Fundamental::Type&); + + Void + string_sequence_type (); + + Void + time_zone (Size pos); + + private: + String member_; + String value_; + TypeName var_; + TypeName var_value_; + LiteralValue literal_value_; + LiteralValue literal_value_list_; + }; + + struct CompareValue: Traversal::Union, + Traversal::Complex, + Traversal::Type, + Context + { + CompareValue (Context&); + + Void + dispatch (SemanticGraph::Node& type, + String const& lhs, + String const& rhs); + + virtual Void + traverse (SemanticGraph::Union&); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Type& t); + + private: + String const* lhs_; + String const* rhs_; + }; + } +} + +#endif // CXX_HYBRID_DEFAULT_VALUE_HXX diff --git a/xsde/cxx/hybrid/elements.hxx b/xsde/cxx/hybrid/elements.hxx index 8452976..9faeb8d 100644 --- a/xsde/cxx/hybrid/elements.hxx +++ b/xsde/cxx/hybrid/elements.hxx @@ -161,6 +161,18 @@ namespace CXX } static String const& + edefault (SemanticGraph::Attribute& a) + { + return a.context ().get<String> ("default"); + } + + static String const& + edefault_value (SemanticGraph::Attribute& a) + { + return a.context ().get<String> ("default-value"); + } + + static String const& epresent_member (SemanticGraph::Particle& p) { return p.context ().get<String> ("present-member"); @@ -922,6 +934,7 @@ namespace CXX ret, arg, var, + var_value, seq }; @@ -1368,6 +1381,11 @@ namespace CXX break; } + case var_value: + { + os << fq; + break; + } case seq: { os << (fixed_length (t) ? fix_seq : var_seq) << "< " << @@ -1437,6 +1455,7 @@ namespace CXX break; } case var: + case var_value: { if (stl) os << "::std::string"; diff --git a/xsde/cxx/hybrid/extraction-source.cxx b/xsde/cxx/hybrid/extraction-source.cxx index 5945ce3..5460740 100644 --- a/xsde/cxx/hybrid/extraction-source.cxx +++ b/xsde/cxx/hybrid/extraction-source.cxx @@ -108,6 +108,11 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { + // Nothing is serialized for fixed attributes. + // + if (a.fixed ()) + return; + SemanticGraph::Type& t (a.type ()); Boolean fl (fixed_length (t)); @@ -125,21 +130,39 @@ namespace CXX if (a.optional ()) { - os << "bool p;"; + if (!a.default_ ()) + { + os << "bool p;"; + + if (exceptions) + os << "s >> p;"; + else + os << endl + << "if (!(s >> p))" << endl + << "return false;"; - if (exceptions) - os << "s >> p;"; - else os << endl - << "if (!(s >> p))" << endl - << "return false;"; + << "if (p)" + << "{"; - os << endl - << "if (p)" - << "{"; + if (fl) + os << "x." << epresent (a) << " (true);"; + } + else + { + os << "bool d;"; - if (fl) - os << "x." << epresent (a) << " (true);"; + if (exceptions) + os << "s >> d;"; + else + os << endl + << "if (!(s >> d))" << endl + << "return false;"; + + os << endl + << "if (!d)" + << "{"; + } } if (st) @@ -181,9 +204,20 @@ namespace CXX } if (a.optional ()) - os << "}" - << "else" << endl - << "x." << epresent (a) << " (false);"; + { + if (!a.default_ ()) + { + os << "}" + << "else" << endl + << "x." << epresent (a) << " (false);"; + } + else + { + os << "}" + << "else" << endl + << "x." << edefault (a) << " (true);"; + } + } os << "}"; } diff --git a/xsde/cxx/hybrid/generator.cxx b/xsde/cxx/hybrid/generator.cxx index 3eba4ba..78b9142 100644 --- a/xsde/cxx/hybrid/generator.cxx +++ b/xsde/cxx/hybrid/generator.cxx @@ -121,6 +121,7 @@ namespace CXX extern Key suppress_validation = "suppress-validation"; extern Key suppress_parser_val = "suppress-parser-val"; extern Key suppress_serializer_val = "suppress-serializer-val"; + extern Key omit_default_attributes = "omit-default-attributes"; extern Key generate_detach = "generate-detach"; extern Key generate_insertion = "generate-insertion"; extern Key generate_extraction = "generate-extraction"; @@ -251,6 +252,11 @@ namespace CXX << " serializer." << endl; + e << "--omit-default-attributes" << endl + << " Omit attributes with default and fixed values\n" + << " from serialized XML documents." + << endl; + e << "--generate-detach" << endl << " Generate detach functions for elements and\n" << " attributes of variable-length types." diff --git a/xsde/cxx/hybrid/insertion-source.cxx b/xsde/cxx/hybrid/insertion-source.cxx index b0b89c9..7dc6fcb 100644 --- a/xsde/cxx/hybrid/insertion-source.cxx +++ b/xsde/cxx/hybrid/insertion-source.cxx @@ -100,19 +100,41 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { + // Don't waste space on fixed attributes. + // + if (a.fixed ()) + return; + if (a.optional ()) { - String const& present (epresent (a)); + if (!a.default_ ()) + { + String const& present (epresent (a)); - if (exceptions) - os << "s << x." << present << " ();"; + if (exceptions) + os << "s << x." << present << " ();"; + else + os << "if (!(s << x." << present << " ()))" << endl + << "return false;"; + + os << endl + << "if (x." << present << " ())" + << "{"; + } else - os << "if (!(s << x." << present << " ()))" << endl - << "return false;"; + { + String const& default_ (edefault (a)); - os << endl - << "if (x." << present << " ())" - << "{"; + if (exceptions) + os << "s << x." << default_ << " ();"; + else + os << "if (!(s << x." << default_ << " ()))" << endl + << "return false;"; + + os << endl + << "if (!x." << default_ << " ())" + << "{"; + } } String const& name (ename (a)); diff --git a/xsde/cxx/hybrid/parser-header.cxx b/xsde/cxx/hybrid/parser-header.cxx index 6a893c5..c174df4 100644 --- a/xsde/cxx/hybrid/parser-header.cxx +++ b/xsde/cxx/hybrid/parser-header.cxx @@ -334,6 +334,9 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { + if (a.fixed ()) + return; + String const& arg (parg_type (a.type ())); os << "virtual void" << endl diff --git a/xsde/cxx/hybrid/parser-source.cxx b/xsde/cxx/hybrid/parser-source.cxx index 505d661..bfeb129 100644 --- a/xsde/cxx/hybrid/parser-source.cxx +++ b/xsde/cxx/hybrid/parser-source.cxx @@ -879,6 +879,9 @@ namespace CXX { using SemanticGraph::Complex; + if (a.fixed ()) + return; + String const& name (epname (a)); String const& arg (parg_type (a.type ())); Complex& c (dynamic_cast<Complex&> (a.scope ())); diff --git a/xsde/cxx/hybrid/serializer-source.cxx b/xsde/cxx/hybrid/serializer-source.cxx index 540d742..b0c194e 100644 --- a/xsde/cxx/hybrid/serializer-source.cxx +++ b/xsde/cxx/hybrid/serializer-source.cxx @@ -886,9 +886,26 @@ namespace CXX { os << "bool " << s << "::" << endl << espresent (a) << " ()" - << "{" - << "return " << access << epresent (a) << " ();" - << "}"; + << "{"; + + if (a.default_ ()) + { + Boolean omit (options.value<CLI::omit_default_attributes> ()); + + if (a.fixed ()) + os << "return " << (omit ? "false" : "true") << ";"; + else + { + if (omit) + os << "return !" << access << edefault (a) << " ();"; + else + os << "return true;"; + } + } + else + os << "return " << access << epresent (a) << " ();"; + + os << "}"; } SemanticGraph::Type& t (a.type ()); diff --git a/xsde/cxx/hybrid/tree-forward.cxx b/xsde/cxx/hybrid/tree-forward.cxx index 7b2cae6..9bcb6f5 100644 --- a/xsde/cxx/hybrid/tree-forward.cxx +++ b/xsde/cxx/hybrid/tree-forward.cxx @@ -350,7 +350,10 @@ namespace CXX traverse (SemanticGraph::Fundamental::String&) { gen_typedef ("string", string_type_); - gen_using ("::xsde::cxx::hybrid::string_base"); + + if (!stl) + gen_using ("::xsde::cxx::hybrid::string_base"); + os << endl; } diff --git a/xsde/cxx/hybrid/tree-header.cxx b/xsde/cxx/hybrid/tree-header.cxx index 3003e4c..77a1c71 100644 --- a/xsde/cxx/hybrid/tree-header.cxx +++ b/xsde/cxx/hybrid/tree-header.cxx @@ -369,6 +369,7 @@ namespace CXX Traversal::Fundamental::Token, Traversal::Fundamental::Name, Traversal::Fundamental::NameToken, + Traversal::Fundamental::NameTokens, Traversal::Fundamental::NCName, Traversal::Fundamental::Language, @@ -376,6 +377,7 @@ namespace CXX Traversal::Fundamental::Id, Traversal::Fundamental::IdRef, + Traversal::Fundamental::IdRefs, Traversal::Fundamental::AnyURI, @@ -390,6 +392,7 @@ namespace CXX Traversal::Fundamental::Time, Traversal::Fundamental::Entity, + Traversal::Fundamental::Entities, Context { @@ -636,6 +639,12 @@ namespace CXX } virtual Void + traverse (SemanticGraph::Fundamental::NameTokens&) + { + align_type ("size_t"); + } + + virtual Void traverse (SemanticGraph::Fundamental::Name&) { align_type ("size_t"); // std::string @@ -676,6 +685,12 @@ namespace CXX align_type ("size_t"); // std::string } + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs&) + { + align_type ("size_t"); + } + // URI. // virtual Void @@ -749,6 +764,12 @@ namespace CXX align_type ("size_t"); // std::string } + virtual Void + traverse (SemanticGraph::Fundamental::Entities&) + { + align_type ("size_t"); + } + private: Void align_type (Char const* t) @@ -767,7 +788,17 @@ namespace CXX private: Traversal::Inherits inherits_; - Traversal::Attribute attribute_; + struct Attribute: Traversal::Attribute + { + virtual Void + traverse (Type& a) + { + if (!a.fixed ()) + Traversal::Attribute::traverse (a); + } + }; + + Attribute attribute_; Traversal::Names attribute_names_; Traversal::Element particle_; @@ -787,13 +818,16 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { - SemanticGraph::Type& t (a.type ()); + if (!a.fixed ()) + { + SemanticGraph::Type& t (a.type ()); - var_.dispatch (t); - os << " " << emember (a) << ";"; + var_.dispatch (t); + os << " " << emember (a) << ";"; - if (a.optional () && fixed_length (t)) - os << "bool " << epresent_member (a) << ";"; + if (a.optional () && !a.default_ () && fixed_length (t)) + os << "bool " << epresent_member (a) << ";"; + } } private: @@ -1105,19 +1139,23 @@ namespace CXX os << "// " << comment (a.name ()) << endl << "// " << endl; + Boolean def (a.default_ ()); + Boolean fix (a.fixed ()); + String const& name (ename (a)); SemanticGraph::Type& t (a.type ()); - if (a.optional ()) + + if (a.optional () && !fix) { - String const& present (epresent (a)); + String const& name (def ? edefault (a) : epresent (a)); os << "bool" << endl - << present << " () const;" + << name << " () const;" << endl; os << "void" << endl - << present << " (bool);" + << name << " (bool);" << endl; } @@ -1129,32 +1167,49 @@ namespace CXX << name << " () const;" << endl; - // type& - // name () + // Do not generate modifiers for fixed attributes. // - ret_.dispatch (t); - os << endl - << name << " ();" - << endl; + if (!fix) + { + // type& + // name () + // + ret_.dispatch (t); + os << endl + << name << " ();" + << endl; - // void - // name (const type& | type*) - // - os << "void" << endl - << name << " ("; - arg_.dispatch (t); - os << ");" - << endl; + // void + // name (const type& | type*) + // + os << "void" << endl + << name << " ("; + arg_.dispatch (t); + os << ");" + << endl; - // type* - // detach () - // - if (detach && !fixed_length (t)) + // type* + // detach () + // + if (detach && !fixed_length (t)) + { + arg_.dispatch (t); + os << endl + << edetach (a) << " ();" + << endl; + } + } + + if (def) { - arg_.dispatch (t); + // static const type& + // name_{default|fixed}_value () + // + os << "static "; + ro_ret_.dispatch (t); os << endl - << edetach (a) << " ();" + << edefault_value (a) << " ();" << endl; } } diff --git a/xsde/cxx/hybrid/tree-inline.cxx b/xsde/cxx/hybrid/tree-inline.cxx index 7cb4b2c..2783b5c 100644 --- a/xsde/cxx/hybrid/tree-inline.cxx +++ b/xsde/cxx/hybrid/tree-inline.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include <cxx/hybrid/tree-inline.hxx> +#include <cxx/hybrid/default-value.hxx> #include <xsd-frontend/semantic-graph.hxx> #include <xsd-frontend/traversal.hxx> @@ -239,36 +240,58 @@ namespace CXX ret_ (c, TypeName::ret), arg_ (c, TypeName::arg), deref_ (c, TypeOps::deref), - delete_ (c, TypeOps::delete_) + delete_ (c, TypeOps::delete_), + compare_value_ (c) { } virtual Void traverse (SemanticGraph::Attribute& a) { + Boolean def (a.default_ ()); + Boolean fix (a.fixed ()); + String const& name (ename (a)); - String const& member (emember (a)); + String member; + + if (!fix) + member = emember (a); SemanticGraph::Type& t (a.type ()); Boolean fl (fixed_length (t)); String scope (Context::scope (a)); - if (a.optional ()) + if (a.optional () && !fix) { - String const& present (epresent (a)); + String const& name (def ? edefault (a) : epresent (a)); // bool // preset () const; // os << inl << "bool " << scope << "::" << endl - << present << " () const" + << name << " () const" << "{"; - if (fl) - os << "return this->" << epresent_member (a) << ";"; + if (def) + { + if (fl) + { + os << "return "; + compare_value_.dispatch ( + t, L"this->" + member, edefault_value (a) + L" ()"); + os << ";"; + } + else + os << "return this->" << member << " == 0;"; + } else - os << "return this->" << member << " != 0;"; + { + if (fl) + os << "return this->" << epresent_member (a) << ";"; + else + os << "return this->" << member << " != 0;"; + } os << "}"; @@ -277,19 +300,41 @@ namespace CXX // os << inl << "void " << scope << "::" << endl - << present << " (bool x)" + << name << " (bool x)" << "{"; - if (fl) - os << "this->" << epresent_member (a) << " = x;"; + if (def) + { + os << "if (x)"; + + if (fl) + { + os << endl + << "this->" << member << " = " << edefault_value (a) << + " ();"; + } + else + { + os << "{"; + delete_.dispatch (t); + os << " this->" << member << ";" + << "this->" << member << " = 0;" + << "}"; + } + } else { - os << "if (!x)" - << "{"; - delete_.dispatch (t); - os << " this->" << member << ";" - << "this->" << member << " = 0;" - << "}"; + if (fl) + os << "this->" << epresent_member (a) << " = x;"; + else + { + os << "if (!x)" + << "{"; + delete_.dispatch (t); + os << " this->" << member << ";" + << "this->" << member << " = 0;" + << "}"; + } } os << "}"; @@ -302,65 +347,109 @@ namespace CXX ro_ret_.dispatch (t); os << " " << scope << "::" << endl << name << " () const" - << "{" - << "return "; - deref_.dispatch (t); - os << "this->" << member << ";" - << "}"; - - // type& - // name () - // - os << inl; - ret_.dispatch (t); - os << " " << scope << "::" << endl - << name << " ()" - << "{" - << "return "; - deref_.dispatch (t); - os << "this->" << member << ";" - << "}"; - - - // void - // name (const type& | type*) - // - os << inl - << "void " << scope << "::" << endl - << name << " ("; - arg_.dispatch (t); - os << " x)" << "{"; - if (!fl) + if (fix) { - delete_.dispatch (t); - os << " this->" << member << ";"; + os << "return " << edefault_value (a) << " ();"; + } + else if (def) + { + if (fl) + os << "return this->" << member << ";"; + else + { + os << "return this->" << member << " ? "; + deref_.dispatch (t); + os << "this->" << member << " : " << + edefault_value (a) << " ();"; + } + } + else + { + os << "return "; + deref_.dispatch (t); + os << "this->" << member << ";"; } - - os << "this->" << member << " = x;"; - - if (fl && a.optional ()) - os << "this->" << epresent_member (a) << " = true;"; os << "}"; - - // type* - // detach () + // Do not generate modifiers for fixed attributes. // - if (detach && !fl) + if (!fix) { + // type& + // name () + // os << inl; - arg_.dispatch (t); + ret_.dispatch (t); os << " " << scope << "::" << endl - << edetach (a) << " ()" + << name << " ()" << "{"; + + if (def) + { + if (fl) + os << "return this->" << member << ";"; + else + { + os << "return this->" << member << " ? "; + deref_.dispatch (t); + os << "this->" << member << " : const_cast< "; + ret_.dispatch (t); + os << " > (" << edefault_value (a) << " ());"; + } + } + else + { + os << "return "; + deref_.dispatch (t); + os << "this->" << member << ";"; + } + + os << "}"; + + + // void + // name (const type& | type*) + // + os << inl + << "void " << scope << "::" << endl + << name << " ("; arg_.dispatch (t); - os << " r = this->" << member << ";" - << "this->" << member << " = 0;" - << "return r;" - << "}"; + os << " x)" + << "{"; + + if (!fl) + { + delete_.dispatch (t); + os << " this->" << member << ";"; + } + + os << "this->" << member << " = x;"; + + if (fl && !def && a.optional ()) + os << "this->" << epresent_member (a) << " = true;"; + + os << "}"; + + + // type* + // detach () + // + if (detach && !fl) + { + os << inl; + arg_.dispatch (t); + os << " " << scope << "::" << endl + << edetach (a) << " ()" + << "{"; + arg_.dispatch (t); + os << " r = this->" << member << ";" + << "this->" << member << " = 0;" + << "return r;" + << "}"; + } } } @@ -370,6 +459,7 @@ namespace CXX TypeName arg_; TypeOps deref_; TypeOps delete_; + CompareValue compare_value_; }; struct ElementFunc: Traversal::Element, Context diff --git a/xsde/cxx/hybrid/tree-name-processor.cxx b/xsde/cxx/hybrid/tree-name-processor.cxx index 9308598..da128c0 100644 --- a/xsde/cxx/hybrid/tree-name-processor.cxx +++ b/xsde/cxx/hybrid/tree-name-processor.cxx @@ -546,28 +546,41 @@ namespace CXX { SemanticGraph::Context& ac (a.context ()); + Boolean def (a.default_ ()); + Boolean fix (a.fixed ()); + + String const& base (ac.get<String> ("name")); + if (!data_members_) { - if (a.optional ()) - ac.set ( - "present", - find_name (ac.get<String> ("name") + L"_present", set_)); + if (a.optional () && !fix) + { + String n; + if (def) + n = find_name (base + L"_default", set_); + else + n = find_name (base + L"_present", set_); - if (detach && !fixed_length (a.type ())) - ac.set ( - "detach", - find_name (ac.get<String> ("name") + L"_detach", set_)); + ac.set (def ? "default" : "present", n); + } + + if (detach && !fix && !fixed_length (a.type ())) + ac.set ("detach", find_name (base + L"_detach", set_)); + if (def) + { + ac.set ( + "default-value", + find_name (base + (fix ? L"_fixed_value" : L"_default_value"), + set_)); + } } - else + else if (!fix) { - String const& base (ac.get<String> ("name")); - - if (a.optional ()) + if (a.optional () && !a.default_ () && fixed_length (a.type ())) { - if (fixed_length (a.type ())) - ac.set ("present-member", - find_name (ac.get<String> ("present") + L"_", set_)); + ac.set ("present-member", + find_name (ac.get<String> ("present") + L"_", set_)); } ac.set ("member", find_name (base + L"_", set_)); diff --git a/xsde/cxx/hybrid/tree-source.cxx b/xsde/cxx/hybrid/tree-source.cxx index 2723046..eb83658 100644 --- a/xsde/cxx/hybrid/tree-source.cxx +++ b/xsde/cxx/hybrid/tree-source.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include <cxx/hybrid/tree-source.hxx> +#include <cxx/hybrid/default-value.hxx> #include <xsd-frontend/semantic-graph.hxx> #include <xsd-frontend/traversal.hxx> @@ -169,6 +170,73 @@ namespace CXX } }; + + struct AttributeFunc: Traversal::Attribute, Context + { + AttributeFunc (Context& c) + : Context (c), + var_ (c, TypeName::var_value), + ro_ret_ (c, TypeName::ro_ret), + literal_value_ (c), + init_value_ (c) + { + } + + virtual Void + traverse (SemanticGraph::Attribute& a) + { + if (a.default_ ()) + { + SemanticGraph::Type& t (a.type ()); + + String literal (literal_value_.dispatch (t, a.value ())); + String init; + + if (!literal) + { + String const& name (ename (a)); + String const& scope_name (ename (a.scope ())); + + init = L"_xsde_" + scope_name + L"_" + name + L"_default_value"; + + os << "struct " << init + << "{" + << init << " ()" + << "{"; + init_value_.dispatch (t, a.value ()); + os << "}"; + + var_.dispatch (t); + os << " value_;" + << "};" + << "static const " << init << " " << init << "_;" + << endl; + } + + // static const type& + // name_{default|fixed}_value () + // + ro_ret_.dispatch (t); + os << " " << scope (a) << "::" << endl + << edefault_value (a) << " ()" + << "{"; + + if (literal) + os << "return " << literal << ";"; + else + os << "return " << init << "_.value_;"; + + os << "}"; + } + } + + private: + TypeName var_; + TypeName ro_ret_; + LiteralValue literal_value_; + InitValue init_value_; + }; + struct ChoiceParticle: Traversal::Element, Traversal::Compositor, Context @@ -600,13 +668,24 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { - Boolean fl (fixed_length (a.type ())); + if (!a.fixed ()) + { + Boolean def (a.default_ ()); + Boolean fl (fixed_length (a.type ())); - if (!fl) - os << "this->" << emember (a) << " = 0;"; + if (!fl) + { + os << "this->" << emember (a) << " = 0;"; + } + else if (def) + { + os << "this->" << emember (a) << " = " << + edefault_value (a) << " ();"; + } - if (fl && a.optional ()) - os << "this->" << epresent_member (a) << " = false;"; + if (fl && !def && a.optional ()) + os << "this->" << epresent_member (a) << " = false;"; + } } }; @@ -726,12 +805,15 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { - SemanticGraph::Type& t (a.type ()); - - if (!fixed_length (t)) + if (!a.fixed ()) { - delete_.dispatch (t); - os << " this->" << emember (a) << ";"; + SemanticGraph::Type& t (a.type ()); + + if (!fixed_length (t)) + { + delete_.dispatch (t); + os << " this->" << emember (a) << ";"; + } } } @@ -852,17 +934,20 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { - String const& member (emember (a)); - - if (a.optional ()) + if (!a.fixed ()) { - String const& present_member (epresent_member (a)); + String const& member (emember (a)); - os << "this->" << present_member << " = x." << present_member << ";" - << "if (this->" << present_member << ")" << endl; - } + if (a.optional () && !a.default_ ()) + { + String const& present (epresent_member (a)); - os << "this->" << member << " = x." << member << ";"; + os << "this->" << present << " = x." << present << ";" + << "if (this->" << present << ")" << endl; + } + + os << "this->" << member << " = x." << member << ";"; + } } }; @@ -993,17 +1078,20 @@ namespace CXX virtual Void traverse (SemanticGraph::Attribute& a) { - String const& member (emember (a)); - - if (a.optional ()) + if (!a.fixed ()) { - String const& present_member (epresent_member (a)); + String const& member (emember (a)); - os << "this->" << present_member << " = x." << present_member << ";" - << "if (this->" << present_member << ")" << endl; - } + if (a.optional () && !a.default_ ()) + { + String const& present (epresent_member (a)); - os << "this->" << member << " = x." << member << ";"; + os << "this->" << present << " = x." << present << ";" + << "if (this->" << present << ")" << endl; + } + + os << "this->" << member << " = x." << member << ";"; + } } }; @@ -1451,6 +1539,7 @@ namespace CXX // Functions. // + attribute_func_ (c), choice_in_choice_func_ (c, true), choice_in_sequence_func_ (c, false), sequence_in_choice_func_ (c, true), @@ -1516,6 +1605,8 @@ namespace CXX { // Functions. // + attribute_names_func_ >> attribute_func_; + sequence_in_choice_func_ >> sequence_contains_func_; sequence_in_sequence_func_ >> sequence_contains_func_; sequence_contains_func_ >> choice_in_sequence_func_; @@ -1713,6 +1804,8 @@ namespace CXX // Functions. // + Complex::names (c, attribute_names_func_); + if (c.contains_compositor_p ()) Complex::contains_compositor (c, contains_compositor_func_); } @@ -1770,6 +1863,9 @@ namespace CXX // Functions. // + AttributeFunc attribute_func_; + Traversal::Names attribute_names_func_; + ChoiceFunc choice_in_choice_func_; ChoiceFunc choice_in_sequence_func_; SequenceFunc sequence_in_choice_func_; @@ -1855,6 +1951,11 @@ namespace CXX { // Needed for placement new. // + ctx.os << "#include <stdlib.h>" << endl; // strtod, exit + + if (!ctx.exceptions) + ctx.os << "#include <assert.h>" << endl; + ctx.os << "#include <new>" << endl << endl; diff --git a/xsde/makefile b/xsde/makefile index a8a4928..75a55a4 100644 --- a/xsde/makefile +++ b/xsde/makefile @@ -53,6 +53,7 @@ cxx_tun += cxx/serializer/elements.cxx \ cxx_tun += cxx/hybrid/elements.cxx \ cxx/hybrid/validator.cxx \ cxx/hybrid/generator.cxx \ + cxx/hybrid/default-value.cxx \ cxx/hybrid/tree-size-processor.cxx \ cxx/hybrid/tree-name-processor.cxx \ cxx/hybrid/tree-forward.cxx \ @@ -75,13 +76,11 @@ cxx_tun += cxx/hybrid/elements.cxx \ cxx/hybrid/serializer-aggregate-header.cxx \ cxx/hybrid/serializer-aggregate-source.cxx - # Type map # cxx_tun += type-map/lexer.cxx \ type-map/parser.cxx - # Processing # cxx_tun += processing/inheritance/processor.cxx |