Commit 72d8750694598fa174a2ae8993a19494b444b07b

Authored by Jürgen Knödlseder
1 parent 62fe5380

GXmlAttribute class does no longer store the hyphens.

Hyphens are now stripped in the constructor and added back by the write() method.
ChangeLog
1   -2016-05-31 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu>
  1 +2016-06-02 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu>
2 2  
3 3 * Version 1.1.0 released
4 4 =========================
... ... @@ -11,6 +11,7 @@
11 11 Add component setting methods to GModelSky (#1770).
12 12 Add GApplication::logFileClose() method.
13 13 Add GModel::read_attributes() and write_attributes() private methods (#1765).
  14 + Also write test reports in case of an exception (#1746).
14 15 Add GCTAObservation filename constructor (#1744).
15 16 Add gammalib::number() function (#1743).
16 17 Add GSkyMap::shape() and ndim() methods (#1733).
... ...
... ... @@ -2,7 +2,7 @@ New Features and Important Changes in GammaLib 1.1.0
2 2  
3 3 Author(s) : Juergen Knoedlseder
4 4  
5   -31 May 2016
  5 +2 June 2016
6 6  
7 7  
8 8 1. Introduction
... ... @@ -271,7 +271,11 @@ easy creation of a CSV file, in particular from Python lists (#1773).
271 271  
272 272 14. XML module
273 273 --------------
274   -None
  274 +The GXmlAttribute class does no longer store the hyphens of an attribute, but
  275 +the hyphens are stripped upon construction, and added back when writing the
  276 +attribute into a URL. The side effect of this new behaviour is that XML test
  277 +reports are also written in case that an exception has occured during a unit
  278 +test (#1746).
275 279  
276 280  
277 281 15. VO module
... ...
README.md
1 1 GammaLib information
2 2 ====================
3   -* Version: 1.1.0.dev1 (30 April 2016)
  3 +* Version: 1.1.0.dev1 (2 June 2016)
4 4 * Author: Juergen Knoedlseder (jurgen.knodlseder@irap.omp.eu)
5 5  
6 6 [![Build Status](https://cta-jenkins.irap.omp.eu/buildStatus/icon?job=gammalib-integrate-os)](https://cta-jenkins.irap.omp.eu/job/gammalib-integrate-os/)
... ...
include/GXmlAttribute.hpp
1 1 /***************************************************************************
2 2 * GXmlAttribute.hpp - XML attribute class definition *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2015 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2016 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -48,8 +48,9 @@
48 48 * - @p type has a value of "singleton"
49 49 * - @p name has a value of "gamma-ray"
50 50 *
51   - * The hyphens are stored together with the attribute value. Allowed hyphens
52   - * are " and '.
  51 + * The hyphens are stripped from the attribute value before storing in the
  52 + * name-value pair constructor. Hyphens are added when writing an attribute
  53 + * using the write() method. Allowed hyphens are " and '.
53 54 ***************************************************************************/
54 55 class GXmlAttribute : public GBase {
55 56  
... ... @@ -68,10 +69,10 @@ public:
68 69 GXmlAttribute* clone(void) const;
69 70 std::string classname(void) const;
70 71 void write(GUrl& url) const;
71   - const std::string& name(void) const { return m_name; }
72   - std::string value(void) const;
73   - void name(const std::string& name) { m_name=name; }
74   - void value(std::string value);
  72 + const std::string& name(void) const;
  73 + const std::string& value(void) const;
  74 + void name(const std::string& name);
  75 + void value(const std::string& value);
75 76 std::string print(const GChatter& chatter = NORMAL) const;
76 77  
77 78 protected:
... ... @@ -82,7 +83,7 @@ protected:
82 83  
83 84 // Protected data members
84 85 std::string m_name; //!< Attribute name
85   - std::string m_value; //!< Attribute value including hyphens
  86 + std::string m_value; //!< Attribute value
86 87 };
87 88  
88 89  
... ... @@ -97,4 +98,53 @@ std::string GXmlAttribute::classname(void) const
97 98 return ("GXmlAttribute");
98 99 }
99 100  
  101 +
  102 +/***********************************************************************//**
  103 + * @brief Return attribute name
  104 + *
  105 + * @return Attribute name.
  106 + ***************************************************************************/
  107 +inline
  108 +const std::string& GXmlAttribute::name(void) const
  109 +{
  110 + return (m_name);
  111 +}
  112 +
  113 +
  114 +/***********************************************************************//**
  115 + * @brief Set attribute name
  116 + *
  117 + * @param[in] name Attribute name.
  118 + ***************************************************************************/
  119 +inline
  120 +void GXmlAttribute::name(const std::string& name)
  121 +{
  122 + m_name = name;
  123 + return;
  124 +}
  125 +
  126 +
  127 +/***********************************************************************//**
  128 + * @brief Return attribute value
  129 + *
  130 + * @return Attribute value.
  131 + ***************************************************************************/
  132 +inline
  133 +const std::string& GXmlAttribute::value(void) const
  134 +{
  135 + return (m_value);
  136 +}
  137 +
  138 +/***********************************************************************//**
  139 + * @brief Set attribute value
  140 + *
  141 + * @param[in] value Attribute value.
  142 + ***************************************************************************/
  143 +inline
  144 +void GXmlAttribute::value(const std::string& value)
  145 +{
  146 + m_value = value;
  147 + return;
  148 +}
  149 +
100 150 #endif /* GXMLATTRIBUTE_HPP */
... ...
include/GXmlDocument.hpp
1 1 /***************************************************************************
2 2 * GXmlDocument.hpp - XML document node class definition *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2014 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2016 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ...
src/test/GTestSuite.cpp
... ... @@ -245,7 +245,7 @@ void GTestSuite::append(const pfunction function, const std::string&amp; name)
245 245 /***********************************************************************//**
246 246 * @brief Run all tests in test suite
247 247 *
248   - * @return True is all tests were successful, false otherwise.
  248 + * @return True if all tests were successful, false otherwise.
249 249 *
250 250 * Executes all test functions that have been appended to the test suite.
251 251 * For each test function a test case is added to the test suite.
... ... @@ -309,6 +309,7 @@ bool GTestSuite::run(void)
309 309 {
310 310 // For other exceptions
311 311 test->has_passed(false);
  312 + test->message("Non-standard C++ exception thrown");
312 313 }
313 314  
314 315 // Compute elapsed time
... ...
src/xml/GXmlAttribute.cpp
1 1 /***************************************************************************
2 2 * GXmlAttribute.cpp - XML attribute class implementation *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2014 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2016 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -28,12 +28,11 @@
28 28 #ifdef HAVE_CONFIG_H
29 29 #include <config.h>
30 30 #endif
31   -#include "GException.hpp"
  31 +//#include "GException.hpp"
32 32 #include "GTools.hpp"
33 33 #include "GXmlAttribute.hpp"
34 34  
35 35 /* __ Method name definitions ____________________________________________ */
36   -#define G_VALUE "GXmlAttribute::value(std::string)"
37 36  
38 37 /* __ Macros _____________________________________________________________ */
39 38  
... ... @@ -85,18 +84,31 @@ GXmlAttribute::GXmlAttribute(const GXmlAttribute&amp; attr)
85 84 * @param[in] name Attribute name.
86 85 * @param[in] value Attribute value.
87 86 *
88   - * Construct attribute form a p@ name and a @p value. Predefined entities
  87 + * Construct attribute form a @p name and a @p value. Predefined entities
89 88 * (e.g. &quot;) in attribute values are automatically converted into normal
90   - * characters.
  89 + * characters. The constructor strips any existing " or ' leading and
  90 + * trailing hyphens from the @p value string.
91 91 ***************************************************************************/
92 92 GXmlAttribute::GXmlAttribute(const std::string& name, const std::string& value)
93 93 {
94 94 // Initialise members
95 95 init_members();
96 96  
  97 + // Create working copy of attribute value
  98 + std::string v(value);
  99 +
  100 + // Strip any pair of leading and trailing hyphens
  101 + int n = v.length();
  102 + if (n > 2) {
  103 + if (((v[0] == '"') && (v[n-1] == '"')) ||
  104 + ((v[0] == '\'') && (v[n-1] == '\''))) {
  105 + v = v.substr(1, n-2);
  106 + }
  107 + }
  108 +
97 109 // Set attribute
98 110 this->name(name);
99   - this->value(gammalib::xml2str(value));
  111 + this->value(gammalib::xml2str(v));
100 112  
101 113 // Return
102 114 return;
... ... @@ -195,11 +207,8 @@ GXmlAttribute* GXmlAttribute::clone(void) const
195 207 ***************************************************************************/
196 208 void GXmlAttribute::write(GUrl& url) const
197 209 {
198   - // Get value without quotation marks
199   - std::string value = m_value.substr(1, m_value.length()-2);
200   -
201   - // Convert value to XML format
202   - value = "\""+gammalib::str2xml(value)+"\"";
  210 + // Convert value into XML format and add hyphens
  211 + std::string value = "\""+gammalib::str2xml(m_value)+"\"";
203 212  
204 213 // Write attribute into URL
205 214 url.printf(" %s=%s", m_name.c_str(), value.c_str());
... ... @@ -212,7 +221,7 @@ void GXmlAttribute::write(GUrl&amp; url) const
212 221 /***********************************************************************//**
213 222 * @brief Print element attribute
214 223 *
215   - * @param[in] chatter Chattiness (defaults to NORMAL).
  224 + * @param[in] chatter Chattiness.
216 225 * @return String containing element attribute.
217 226 ***************************************************************************/
218 227 std::string GXmlAttribute::print(const GChatter& chatter) const
... ... @@ -224,7 +233,7 @@ std::string GXmlAttribute::print(const GChatter&amp; chatter) const
224 233 if (chatter != SILENT) {
225 234  
226 235 // Append attribute to string
227   - result.append(" "+m_name+"="+m_value);
  236 + result.append(" "+m_name+"=\""+m_value+"\"");
228 237  
229 238 } // endif: chatter was not silent
230 239  
... ... @@ -233,104 +242,6 @@ std::string GXmlAttribute::print(const GChatter&amp; chatter) const
233 242 }
234 243  
235 244  
236   -/***********************************************************************//**
237   - * @brief Returns attribute value
238   - *
239   - * @return String containing the attribute value without hyphens.
240   - *
241   - * Returns the attribute value by stripping the hyphens.
242   - ***************************************************************************/
243   -std::string GXmlAttribute::value(void) const
244   -{
245   - // Initialise attribute value
246   - std::string value = "";
247   -
248   - // Extract value by stripping hyphens
249   - int n = m_value.length();
250   - if (n > 2) {
251   - value = m_value.substr(1, n-2);
252   - }
253   -
254   - // Return value
255   - return value;
256   -}
257   -
258   -
259   -/***********************************************************************//**
260   - * @brief Set attribute value
261   - *
262   - * @param[in] value Attribute value.
263   - *
264   - * @exception GException::xml_attribute_value
265   - * Invalid XML attribute value.
266   - *
267   - * Sets the value of the attribute. The method automatically adds the proper
268   - * hyphens to the value string if they do not exist.
269   - ***************************************************************************/
270   -void GXmlAttribute::value(std::string value)
271   -{
272   - // Get length of value string
273   - int n = value.length();
274   -
275   - // Count hyphens and signal their presence at start/end
276   - int n_hyphens1 = 0;
277   - int n_hyphens2 = 0;
278   - bool has_hyphens1 = (n >= 2 && value[0] == '\'' && value[n-1] == '\'');
279   - bool has_hyphens2 = (n >= 2 && value[0] == '"' && value[n-1] == '"');
280   - for (int i = 0; i < n; ++i) {
281   - if (value[i] == '\'') n_hyphens1++;
282   - if (value[i] == '"') n_hyphens2++;
283   - }
284   -
285   - // Case A: value has ' start and end hyphens. Keep value as is if no other
286   - // ' hyphens are found. Otherwise, if more than 2 ' but no " hyphen is found
287   - // then enclose the value in " hyphens. Finally, if more than 2 ' and at
288   - // least one " hyphen is found we have an invalid value and throw an
289   - // exception.
290   - if (has_hyphens1) {
291   - if (n_hyphens1 > 2 && n_hyphens2 == 0) {
292   - value = "\"" + value + "\"";
293   - }
294   - else if (n_hyphens1 > 2 && n_hyphens2 > 0) {
295   - throw GException::xml_attribute_value(G_VALUE, value);
296   - }
297   - }
298   -
299   - // Case B: value has " start and end hyphens. Keep value as is if no other
300   - // " hyphens are found. Otherwise, if more than 2 " but no ' hyphen is found
301   - // then enclose the value in ' hyphens. Finally, if more than 2 " and at
302   - // least one ' hyphen is found we have an invalid value and throw an
303   - // exception.
304   - else if (has_hyphens2) {
305   - if (n_hyphens1 == 0 && n_hyphens2 > 2) {
306   - value = "'" + value + "'";
307   - }
308   - else if (n_hyphens1 > 0 && n_hyphens2 > 2) {
309   - throw GException::xml_attribute_value(G_VALUE, value);
310   - }
311   - }
312   -
313   - // Case C: value has no start and end hyphens.
314   - else {
315   - if (n_hyphens1 >= 0 && n_hyphens2 == 0) {
316   - value = "\"" + value + "\"";
317   - }
318   - else if (n_hyphens1 == 0 && n_hyphens2 > 0) {
319   - value = "'" + value + "'";
320   - }
321   - else {
322   - throw GException::xml_attribute_value(G_VALUE, value);
323   - }
324   - }
325   -
326   - // Set value
327   - m_value = value;
328   -
329   - // Return
330   - return;
331   -}
332   -
333   -
334 245 /*==========================================================================
335 246 = =
336 247 = Private methods =
... ...
src/xml/GXmlDocument.cpp
1 1 /***************************************************************************
2 2 * GXmlDocument.cpp - XML document node class implementation *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2013 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2016 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -175,10 +175,11 @@ GXmlDocument* GXmlDocument::clone(void) const
175 175 void GXmlDocument::write(GUrl& url, const int& indent) const
176 176 {
177 177 // Write document header into URL
178   - url.printf("<?xml version=\"%s\" encoding=\"%s\" standalone=\"%s\"?>\n",
179   - version().c_str(),
180   - encoding().c_str(),
181   - standalone().c_str());
  178 + url.printf("<?xml");
  179 + m_version.write(url);
  180 + m_encoding.write(url);
  181 + m_standalone.write(url);
  182 + url.printf("?>\n");
182 183  
183 184 // Write children into URL
184 185 for (int i = 0; i < m_nodes.size(); ++i) {
... ... @@ -211,9 +212,9 @@ std::string GXmlDocument::print(const GChatter&amp; chatter,
211 212  
212 213 // Append document to string
213 214 result.append("GXmlDocument::");
214   - result.append("version=" + version());
215   - result.append(" encoding=" + encoding());
216   - result.append(" standalone=" + standalone());
  215 + result.append("version=\"" + version() +"\"");
  216 + result.append(" encoding=\"" + encoding() +"\"");
  217 + result.append(" standalone=\"" + standalone() +"\"");
217 218  
218 219 // Append children
219 220 for (int i = 0; i < m_nodes.size(); ++i) {
... ... @@ -244,10 +245,10 @@ void GXmlDocument::init_members(void)
244 245 m_standalone.clear();
245 246 m_version.name("version");
246 247 m_encoding.name("encoding");
247   - m_standalone.name("m_standalone");
248   - m_version.value("\"1.0\"");
249   - m_encoding.value("\"UTF-8\"");
250   - m_standalone.value("\"no\"");
  248 + m_standalone.name("standalone");
  249 + m_version.value("1.0");
  250 + m_encoding.value("UTF-8");
  251 + m_standalone.value("no");
251 252  
252 253 // Return
253 254 return;
... ...
test/test_GXml.cpp
1 1 /***************************************************************************
2 2 * test_GXml.cpp - Test xml module *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2014 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2016 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -44,11 +44,16 @@ void TestGXml::set(void)
44 44 m_xml_file = "data/test.xml";
45 45  
46 46 // Append tests
47   - append(static_cast<pfunction>(&TestGXml::test_GXml_attributes), "Test XML attributes");
48   - append(static_cast<pfunction>(&TestGXml::test_GXml_elements), "Test XML elements");
49   - append(static_cast<pfunction>(&TestGXml::test_GXml_construct),"Test XML constructors");
50   - append(static_cast<pfunction>(&TestGXml::test_GXml_load),"Test XML load");
51   - append(static_cast<pfunction>(&TestGXml::test_GXml_access), "Test XML access");
  47 + append(static_cast<pfunction>(&TestGXml::test_GXml_attributes),
  48 + "Test XML attributes");
  49 + append(static_cast<pfunction>(&TestGXml::test_GXml_elements),
  50 + "Test XML elements");
  51 + append(static_cast<pfunction>(&TestGXml::test_GXml_construct),
  52 + "Test XML constructors");
  53 + append(static_cast<pfunction>(&TestGXml::test_GXml_load),
  54 + "Test XML load");
  55 + append(static_cast<pfunction>(&TestGXml::test_GXml_access),
  56 + "Test XML access");
52 57  
53 58 // Return
54 59 return;
... ... @@ -68,94 +73,38 @@ TestGXml* TestGXml::clone(void) const
68 73  
69 74  
70 75 /***********************************************************************//**
71   - * @brief Test XML arrtibutes
  76 + * @brief Test XML attributes
72 77 **************************************************************************/
73 78 void TestGXml::test_GXml_attributes(void)
74 79 {
75   - // Test valid attributes
76   - test_try("Test valid attributes");
77   - try {
78   - GXmlAttribute attr("test", "1.0");
79   - test_assert(attr.value() == "1.0","Test if value()= 1.0","Unexpected attribute "+attr.value());
80   -
81   - attr.value("\"1.0\"");
82   - test_assert(attr.value() == "1.0","Test if value()= 1.0","Unexpected attribute "+attr.value());
83   -
84   - attr.value("'1.0'");
85   - test_assert(attr.value() == "1.0","Test if value()= 1.0","Unexpected attribute "+attr.value());
86   -
87   - attr.value("''1.0'");
88   - test_assert(attr.value() == "''1.0'",
89   - "Test if value()= ''1.0'",
90   - "Unexpected attribute "+attr.value());
91   -
92   - attr.value("'1.0");
93   - test_assert(attr.value() == "'1.0",
94   - "Test if value()= '1.0",
95   - "Unexpected attribute "+attr.value());
96   -
97   - attr.value("1.0'");
98   - test_assert(attr.value() == "1.0'",
99   - "Test if value()= 1.0'",
100   - "Unexpected attribute "+attr.value());
101   -
102   - attr.value("\"1.0");
103   - test_assert(attr.value() == "\"1.0",
104   - "Test if value()= \"1.0",
105   - "Unexpected attribute "+attr.value());
106   -
107   -
108   - attr.value("1.0\"");
109   - test_assert(attr.value() == "1.0\"",
110   - "Test if value()= 1.0\"",
111   - "Unexpected attribute "+attr.value());
112   -
113   - attr.value("\"\"1.0\"");
114   - test_assert(attr.value() == "\"\"1.0\"",
115   - "Test if value()= \"\"1.0\"",
116   - "Unexpected attribute "+attr.value());
117   - test_try_success();
118   - }
119   - catch (std::exception &e) {
120   - test_try_failure(e);
121   - }
122   -
123   - // Test invalid attributes
124   - test_try("Test invalid attributes 1");
125   - try {
126   - GXmlAttribute attr("test", "\"\"1.0'\"");
127   - test_try_failure();
128   - }
129   - catch (GException::xml_attribute_value &e) {
130   - test_try_success();
131   - }
132   - catch (std::exception &e) {
133   - test_try_failure(e);
134   - }
135   -
136   - test_try("Test invalid attributes 2");
137   - try {
138   - GXmlAttribute attr("test", "''1.0\"");
139   - test_try_failure();
140   - }
141   - catch (GException::xml_attribute_value &e) {
142   - test_try_success();
143   - }
144   - catch (std::exception &e) {
145   - test_try_failure(e);
146   - }
147   -
148   - test_try("Test invalid attributes 3");
149   - try {
150   - GXmlAttribute attr("test", "\"1.0'");
151   - test_try_failure();
152   - }
153   - catch (GException::xml_attribute_value &e) {
154   - test_try_success();
155   - }
156   - catch (std::exception &e) {
157   - test_try_failure(e);
158   - }
  80 + // Test attribute name-value constructors
  81 + GXmlAttribute attr1("test", "1.0");
  82 + test_assert(attr1.value() == "1.0", "Test if value()= 1.0",
  83 + "Unexpected attribute "+attr1.value());
  84 + GXmlAttribute attr2("test", "\"1.0\"");
  85 + test_assert(attr2.value() == "1.0", "Test if value()= 1.0",
  86 + "Unexpected attribute "+attr2.value());
  87 + GXmlAttribute attr3("test", "'1.0'");
  88 + test_assert(attr3.value() == "1.0", "Test if value()= 1.0",
  89 + "Unexpected attribute "+attr3.value());
  90 + GXmlAttribute attr4("test", "''1.0'");
  91 + test_assert(attr4.value() == "'1.0", "Test if value()= '1.0",
  92 + "Unexpected attribute "+attr4.value());
  93 + GXmlAttribute attr5("test", "'1.0");
  94 + test_assert(attr5.value() == "'1.0", "Test if value()= '1.0",
  95 + "Unexpected attribute "+attr5.value());
  96 + GXmlAttribute attr6("test", "1.0'");
  97 + test_assert(attr6.value() == "1.0'", "Test if value()= 1.0'",
  98 + "Unexpected attribute "+attr6.value());
  99 + GXmlAttribute attr7("test", "\"1.0");
  100 + test_assert(attr7.value() == "\"1.0", "Test if value()= \"1.0",
  101 + "Unexpected attribute "+attr7.value());
  102 + GXmlAttribute attr8("test", "1.0\"");
  103 + test_assert(attr8.value() == "1.0\"", "Test if value()= 1.0\"",
  104 + "Unexpected attribute "+attr8.value());
  105 + GXmlAttribute attr9("test", "\"\"1.0\"");
  106 + test_assert(attr9.value() == "\"1.0", "Test if value()= \"1.0",
  107 + "Unexpected attribute "+attr9.value());
159 108  
160 109 // Return
161 110 return;
... ...