Commit c095e55aa166327ea86ef53aa5b457ab33d41a66

Authored by Jürgen Knödlseder
1 parent 078bffa5

Allow for relative paths in an XML files.

The gammalib::xml_file_expand and gammalib::xml_file_reduce methods were modified to accomodate also for relative file paths in an XML file. Now the files towards which the XML file points can also reside in a subdirectory relative to the XML file.
Showing 1 changed file with 58 additions and 17 deletions
src/support/GTools.cpp
... ... @@ -1813,10 +1813,10 @@ void gammalib::xml_check_par(const std::string& origin,
1813 1813 * @param[in] filename File name.
1814 1814 * @return Expanded file name.
1815 1815 *
1816   - * Expands file name provided as XML attribute for loading. If the file name
1817   - * is not empty and has no path it is assumed that the file is located in the
1818   - * same directory as the XML file, and the XML file access path is prepended
1819   - * to the file name.
  1816 + * Expands file name provided as XML attribute for loading. The XML file
  1817 + * access path will be prepended to the file name access path if the file
  1818 + * name has not an absolute path and if the file name access path does not
  1819 + * start with the XML file access path.
1820 1820 ***************************************************************************/
1821 1821 GFilename gammalib::xml_file_expand(const GXmlElement& xml,
1822 1822 const std::string& filename)
... ... @@ -1824,11 +1824,39 @@ GFilename gammalib::xml_file_expand(const GXmlElement& xml,
1824 1824 // Set file name
1825 1825 GFilename fname(filename);
1826 1826  
1827   - // If the file name is not empty and has no path we assume that the file
1828   - // name is a relative file name with respect to the XML file access path
1829   - // and we therefore prepend the XML file access path to the file name
1830   - if (!fname.is_empty() && fname.path().length() == 0) {
1831   - fname = xml.filename().path() + fname;
  1827 + // If the file name is not empty and is not an absolute path then we
  1828 + // assume that the filename is a relative file name with respect to the
  1829 + // XML file access path and we therefore prepend the XML file access path
  1830 + // to the file name
  1831 + if (!fname.is_empty()) {
  1832 + size_t access_length = fname.path().length();
  1833 + size_t xml_length = xml.filename().path().length();
  1834 +
  1835 + // If filename has no access path and the XML file has an access path
  1836 + // then preprend the XML file access path
  1837 + if (access_length == 0) {
  1838 + if (xml_length > 0) {
  1839 + fname = xml.filename().path() + fname;
  1840 + }
  1841 + }
  1842 +
  1843 + // If filename assess path is not absolute then continue ...
  1844 + else if (fname.path()[0] != '/') {
  1845 +
  1846 + // If XML file access path is not contained in file name access
  1847 + // path then prepend the XML file access path
  1848 + if (access_length >= xml_length) {
  1849 + if (fname.path().compare(0, xml_length, xml.filename().path()) != 0) {
  1850 + fname = xml.filename().path() + fname;
  1851 + }
  1852 + }
  1853 +
  1854 + // If file name access pass is shorter than XML file access path
  1855 + // then prepend the XML file access path
  1856 + else {
  1857 + fname = xml.filename().path() + fname;
  1858 + }
  1859 + }
1832 1860 }
1833 1861  
1834 1862 // Return file name
... ... @@ -1844,9 +1872,8 @@ GFilename gammalib::xml_file_expand(const GXmlElement& xml,
1844 1872 * @return Reduced file name.
1845 1873 *
1846 1874 * Reduces file name provided for writing as XML attribute. If the file name
1847   - * is not empty and has the same access path as the XML file it is assumed
1848   - * that both files are located in the same directory, and the access path is
1849   - * stripped from the file name.
  1875 + * is not empty and its access path starts has the same access path as the
  1876 + * XML file the XML file access path is stripped from the file name.
1850 1877 ***************************************************************************/
1851 1878 GFilename gammalib::xml_file_reduce(const GXmlElement& xml,
1852 1879 const std::string& filename)
... ... @@ -1854,11 +1881,25 @@ GFilename gammalib::xml_file_reduce(const GXmlElement& xml,
1854 1881 // Set file name
1855 1882 GFilename fname(filename);
1856 1883  
1857   - // If the file name is not empty and has the same access path as the XML
1858   - // file it is assumed that both files are located in the same directory,
1859   - // and the access path is stripped from the file name.
1860   - if (!fname.is_empty() && fname.path() == xml.filename().path()) {
1861   - fname = fname.file();
  1884 + // If the file name is not empty and the access path starts with the
  1885 + // same characters as the XML file access path then we assume that the
  1886 + // access path has been added and hence we strip it now
  1887 + if (!fname.is_empty()) {
  1888 + size_t access_length = fname.path().length();
  1889 + size_t xml_length = xml.filename().path().length();
  1890 + if (xml_length > 0) {
  1891 + if (access_length == xml_length) {
  1892 + if (fname.path() == xml.filename().path()) {
  1893 + fname = fname.file();
  1894 + }
  1895 + }
  1896 + else if (access_length > xml_length) {
  1897 + if (fname.path().compare(0, xml_length, xml.filename().path()) == 0) {
  1898 + std::string relpath = fname.path().substr(xml_length, access_length-xml_length);
  1899 + fname = GFilename(relpath + fname.file());
  1900 + }
  1901 + }
  1902 + }
1862 1903 }
1863 1904  
1864 1905 // Return file name
... ...