From 6a0ecb420ec4a63c7c89ff7e3df19d11f281e304 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Fri, 1 Apr 2005 09:32:40 +0000 Subject: [PATCH] Merged revisions 551:552 from branches/Exiv2-0_6_041212. Fixes bug #423 in trunk --- config/config.h.in | 9 ++++++++- src/Makefile | 6 +++++- src/path-test.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/utils.cpp | 27 ++++++++++++++++----------- src/utils.hpp | 16 +++++++++++++--- test/data/path-test.txt | 24 ++++++++++++++++++++++++ test/path-test.sh | 7 +++++++ 7 files changed, 109 insertions(+), 16 deletions(-) create mode 100644 src/path-test.cpp create mode 100644 test/data/path-test.txt create mode 100755 test/path-test.sh diff --git a/config/config.h.in b/config/config.h.in index bf70b366..d7ff7fb0 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -143,8 +143,15 @@ /* Define to `unsigned' if does not define. */ #undef size_t +#if defined __CYGWIN32__ && !defined __CYGWIN__ + /* For backwards compatibility with Cygwin b19 and + earlier, we define __CYGWIN__ here, so that + we can rely on checking just for that macro. */ +#define __CYGWIN__ __CYGWIN32__ +#endif + /* File path seperator */ -#ifdef _MSC_VER +#if defined WIN32 && !defined __CYGWIN__ #define SEPERATOR_STR "\\" #define SEPERATOR_CHR '\\' #else diff --git a/src/Makefile b/src/Makefile index 17caef95..afe5ef68 100644 --- a/src/Makefile +++ b/src/Makefile @@ -184,12 +184,15 @@ mn.cpp: ./mn.sh $(LIBTOOL): $(LIBTOOL_DEPS) $(SHELL) $(top_srcdir)/config.status --recheck -bin: lib $(BINARY) $(EXIV2BIN) $(MCBIN) +bin: lib $(BINARY) $(EXIV2BIN) $(MCBIN) path-test lib: $(OBJ) $(LIBTOOL) --mode=link $(CXX) $(LDFLAGS) $(LOBJ) -o $(LIBRARY) -rpath $(libdir) -release $(EXIV2_VERSION) @touch lib +path-test: path-test.o utils.o + $(CXX) $(CXXFLAGS) path-test.o utils.o -o $@ + $(BINARY): %: %.o lib mn.o @$(LIBTOOL) --mode=link $(CXX) $(CXXFLAGS) $(LDLIBS) $@.o $(LDFLAGS) -o $@ -rpath $(libdir) @@ -248,6 +251,7 @@ mostlyclean: clean: mostlyclean @$(LIBTOOL) --mode=clean $(RM) $(LIBRARY) @$(LIBTOOL) --mode=clean $(RM) $(EXECUTABLE) $(EXIV2EXE) $(MCEXE) + @$(LIBTOOL) --mode=clean $(RM) path-test$(EXEEXT) # Run `make distclean' from the top source directory to also remove # files created by configuring the program. diff --git a/src/path-test.cpp b/src/path-test.cpp new file mode 100644 index 00000000..622e7865 --- /dev/null +++ b/src/path-test.cpp @@ -0,0 +1,36 @@ +// ***************************************************************** -*- C++ -*- +// path-test.cpp, $Rev$ + +#include "utils.hpp" +#include +#include +#include +#include + +int main(int argc, char* const argv[]) +{ + if (argc != 2) { + std::cout << "Usage: " << argv[0] << " file\n"; + return 1; + } + std::ifstream file(argv[1]); + if (!file) { + std::cerr << *argv[1] << ": Failed to open file for reading\n"; + return 1; + } + std::string line; + while (std::getline(file, line)) { + std::string path, dir, base; + std::istringstream is(line); + is >> path >> dir >> base; + std::string d = Util::dirname(path); + std::string b = Util::basename(path); + + if (d != dir || b != base) { + std::cout << path << "\t'" << d << "'\t '" << b + << "'\t ==> Testcase failed\n"; + } + } + + return 0; +} diff --git a/src/utils.cpp b/src/utils.cpp index 741cdae5..c331069f 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -98,17 +98,20 @@ int Getopt::getopt(int argc, char* const argv[], const std::string& optstring) std::string dirname(const std::string& path) { if (path == "") return "."; - // Strip trailing slashes + // Strip trailing slashes or backslashes std::string p = path; - while (p.length() > 1 && p[p.length()-1] == EXV_SEPERATOR_CHR) { + while ( p.length() > 1 + && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) { p = p.substr(0, p.length()-1); } - if (p == EXV_SEPERATOR_STR) return EXV_SEPERATOR_STR; - std::string::size_type idx = p.rfind(EXV_SEPERATOR_CHR); + if (p == "\\" || p == "/") return p; + if (p.length() == 2 && p[1] == ':') return p; // For Windows paths + std::string::size_type idx = p.find_last_of("\\/"); if (idx == std::string::npos) return "."; - if (idx == 0) return EXV_SEPERATOR_STR; - p = p.substr(0, idx); - while (p.length() > 1 && p[p.length()-1] == EXV_SEPERATOR_CHR) { + if (idx == 1 && p[0] == '\\' && p[1] == '\\') return p; // For Windows paths + p = p.substr(0, idx == 0 ? 1 : idx); + while ( p.length() > 1 + && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) { p = p.substr(0, p.length()-1); } return p; @@ -117,13 +120,15 @@ int Getopt::getopt(int argc, char* const argv[], const std::string& optstring) std::string basename(const std::string& path, bool delsuffix) { if (path == "") return "."; - // Strip trailing slashes + // Strip trailing slashes or backslashes std::string p = path; - while (p.length() > 1 && p[p.length()-1] == EXV_SEPERATOR_CHR) { + while ( p.length() > 1 + && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) { p = p.substr(0, p.length()-1); } - if (p == EXV_SEPERATOR_STR) return p; - std::string::size_type idx = p.rfind(EXV_SEPERATOR_CHR); + if (p.length() == 2 && p[1] == ':') return ""; // For Windows paths + std::string::size_type idx = p.find_last_of("\\/"); + if (idx == 1 && p[0] == '\\' && p[1] == '\\') return ""; // For Windows paths if (idx != std::string::npos) p = p.substr(idx+1); if (delsuffix) p = p.substr(0, p.length() - suffix(p).length()); return p; diff --git a/src/utils.hpp b/src/utils.hpp index af4b5358..945e4e44 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -144,12 +144,22 @@ private: //! Get a system error message and the error code. See %strerror(2). std::string strError(); - //! Get the directory component from the path string. See %dirname(3). + /*! + @brief Get the directory component from the \em path string. + See %dirname(3). + + This function can handle Windows paths to some extent: c:\\bar should + be fine, \\\\bigsrv\\foo also, but \\\\bigsrv alone doesn't work. + */ std::string dirname(const std::string& path); /*! - @brief Get the filename component from the path string. See %basename(3). - If the delsuffix parameter is true, the suffix will be removed. + @brief Get the filename component from the \em path string. + See %basename(3). If the \em delsuffix parameter is true, + the suffix will be removed. + + This function can handle Windows paths to some extent: c:\\bar should + be fine, \\\\bigsrv\\foo also, but \\\\bigsrv alone doesn't work. */ std::string basename(const std::string& path, bool delsuffix =false); diff --git a/test/data/path-test.txt b/test/data/path-test.txt new file mode 100644 index 00000000..37da819a --- /dev/null +++ b/test/data/path-test.txt @@ -0,0 +1,24 @@ +dir/base dir base +a/b/c a/b c +a/b/c/ a/b c +/ / +/a / a +foo . foo +bar/ . bar +bar\ . bar +dir\base dir base +a\b\c a\b c +a\b\c\ a\b c +c:\ c: +c:\bar c: bar +d:\foo\bar d:\foo bar +a . a +/////////// / +\\ \ +\\srvfile00\foo\bar \\srvfile00\foo bar +\\srvfile01\foo \\srvfile01 foo +\\srvfile02 \\srvfile02 +\\srvfile03\ \\srvfile03 +//srvfile04 / srvfile04 +//srvfile03/foo //srvfile03 foo +//srvfile02/foo/bar //srvfile02/foo bar diff --git a/test/path-test.sh b/test/path-test.sh new file mode 100755 index 00000000..a232ce9e --- /dev/null +++ b/test/path-test.sh @@ -0,0 +1,7 @@ +#! /bin/sh +# Mini test-driver for path utility functions +LD_LIBRARY_PATH=../../src:$LD_LIBRARY_PATH +binpath="../../src" +cd ./tmp + +$binpath/path-test ../data/path-test.txt