Index: synopsis_trunk/Synopsis/Parsers/C/Makefile.in =================================================================== --- synopsis_trunk/Synopsis/Parsers/C/Makefile.in (revision 1815) +++ synopsis_trunk/Synopsis/Parsers/C/Makefile.in (working copy) @@ -21,7 +21,8 @@ CPPFLAGS+= @SYN_CPP@ -I @PYTHON_INCLUDE@ CXXFLAGS:= @CXXFLAGS@ LDFLAGS := @LDFLAGS@ -LIBS := @SYN_LIBS@ @LIBS@ +LIBS := -lboost_filesystem +LIBS += @SYN_LIBS@ @LIBS@ LIBRARY_EXT := @LIBEXT@ SRC := TypeTranslator.cc ASTTranslator.cc ParserImpl.cc Index: synopsis_trunk/Synopsis/Parsers/C/ASTTranslator.cc =================================================================== --- synopsis_trunk/Synopsis/Parsers/C/ASTTranslator.cc (revision 1815) +++ synopsis_trunk/Synopsis/Parsers/C/ASTTranslator.cc (working copy) @@ -9,11 +9,12 @@ #include "TypeTranslator.hh" #include #include // for PTree::reify -#include +#include using Synopsis::Token; using Synopsis::Trace; namespace PT = Synopsis::PTree; +namespace fs = boost::filesystem; ASTTranslator::ASTTranslator(std::string const &filename, std::string const &base_path, bool primary_file_only, @@ -31,10 +32,11 @@ { Trace trace("ASTTranslator::ASTTranslator", Trace::TRANSLATION); // determine canonical filenames - Path path = Path(raw_filename_).abs(); - std::string long_filename = path.str(); - path.strip(base_path_); - std::string short_filename = path.str(); + fs::path path = fs::system_complete(fs::path(raw_filename_, fs::native)).normalize(); + std::string long_filename = path.native_file_string(); + std::string short_filename = path.native_file_string(); + if (base_path_.size() && base_path_ == short_filename.substr(0, base_path_.size())) + short_filename.erase(0, base_path_.size()); AST::SourceFile file = ast_.files().get(short_filename); if (file) @@ -280,10 +282,11 @@ raw_filename_ = filename; // determine canonical filenames - Path path = Path(filename).abs(); - std::string long_filename = path.str(); - path.strip(base_path_); - std::string short_filename = path.str(); + fs::path path = fs::system_complete(fs::path(filename, fs::native)).normalize(); + std::string long_filename = path.native_file_string(); + std::string short_filename = path.native_file_string(); + if (base_path_.size() && base_path_ == short_filename.substr(0, base_path_.size())) + short_filename.erase(0, base_path_.size()); AST::SourceFile file = ast_.files().get(short_filename); if (file) Index: synopsis_trunk/Synopsis/Parsers/Cpp/ASTTranslator.cc =================================================================== --- synopsis_trunk/Synopsis/Parsers/Cpp/ASTTranslator.cc (revision 1815) +++ synopsis_trunk/Synopsis/Parsers/Cpp/ASTTranslator.cc (working copy) @@ -7,10 +7,11 @@ #include "ASTTranslator.hh" #include -#include +#include using namespace Synopsis; namespace wave = boost::wave; +namespace fs = boost::filesystem; ASTTranslator::ASTTranslator(std::string const &language, std::string const &filename, @@ -133,7 +134,7 @@ // The following confusing naming indicates something needs // to be cleared up ! - std::string abs_filename = Path(relname).abs().str(); + std::string abs_filename = fs::system_complete(fs::path(relname, fs::native)).normalize().native_file_string(); // Only keep the first level of includes starting from the last unmasked file. if (primary_file_only_ || (base_path_.size() && @@ -200,10 +201,12 @@ { Trace trace("ASTTranslator::lookup_source_file", Trace::TRANSLATION); trace << filename << ' ' << primary; - Path path = Path(filename).abs(); - path.strip(base_path_); - std::string short_name = path.str(); + fs::path path = fs::system_complete(fs::path(filename, fs::native)).normalize(); + std::string short_name = path.native_file_string(); + if (base_path_.size() && base_path_ == short_name.substr(0, base_path_.size())) + short_name.erase(0, base_path_.size()); + Python::Dict files = ast_.files(); AST::SourceFile sf = files.get(short_name); if (!sf) Index: synopsis_trunk/Synopsis/Parsers/Cxx/Makefile.in =================================================================== --- synopsis_trunk/Synopsis/Parsers/Cxx/Makefile.in (revision 1815) +++ synopsis_trunk/Synopsis/Parsers/Cxx/Makefile.in (working copy) @@ -20,7 +20,8 @@ CPPFLAGS+= @SYN_CPP@ -I @PYTHON_INCLUDE@ CXXFLAGS:= @CXXFLAGS@ LDFLAGS := @LDFLAGS@ -LIBS := @SYN_LIBS@ @LIBS@ +LIBS := -lboost_filesystem +LIBS += @SYN_LIBS@ @LIBS@ LIBRARY_EXT := @LIBEXT@ SRC := TypeTranslator.cc ASTTranslator.cc SXRGenerator.cc ParserImpl.cc Index: synopsis_trunk/Synopsis/Parsers/Cxx/ParserImpl.cc =================================================================== --- synopsis_trunk/Synopsis/Parsers/Cxx/ParserImpl.cc (revision 1815) +++ synopsis_trunk/Synopsis/Parsers/Cxx/ParserImpl.cc (working copy) @@ -17,13 +17,14 @@ #include #include #include -#include +#include +#include #include "ASTTranslator.hh" #include "SXRGenerator.hh" #include using namespace Synopsis; - +namespace fs = boost::filesystem; namespace { PyObject *error; @@ -93,14 +94,13 @@ if (syntax_prefix) { timer.reset(); - Path path(src); - path.abs(); - std::string long_filename = path.str(); - Path base(base_path); - base.abs(); - path.strip(base.str()); - std::string short_filename = path.str(); - AST::SourceFile file = ast.files().get(short_filename); + fs::path path = fs::system_complete(fs::path(src, fs::native)).normalize(); + std::string long_filename = path.native_file_string(); + fs::path base = fs::system_complete(fs::path(base_path, fs::native)).normalize(); + std::string short_filename = path.native_file_string(); + if (base.native_file_string().size() && base.native_file_string() == short_filename.substr(0, base.native_file_string().size())) + short_filename.erase(0, base.native_file_string().size()); + AST::SourceFile file = ast.files().get(short_filename); // Undo the preprocesser's macro expansions. Python::Dict macro_calls = file.macro_calls(); for (Python::Dict::iterator l = macro_calls.begin(); l != macro_calls.end(); ++l) @@ -115,7 +115,7 @@ } } std::string sxr = std::string(syntax_prefix) + "/" + short_filename + ".sxr"; - makedirs(Path(sxr).dirname()); + create_directories(fs::path(sxr).branch_path()); std::ofstream ofs(sxr.c_str()); SXRGenerator generator(buffer, symbols.current_scope(), ofs); generator.process(ptree); Index: synopsis_trunk/Synopsis/Parsers/Cxx/ASTTranslator.cc =================================================================== --- synopsis_trunk/Synopsis/Parsers/Cxx/ASTTranslator.cc (revision 1815) +++ synopsis_trunk/Synopsis/Parsers/Cxx/ASTTranslator.cc (working copy) @@ -12,12 +12,13 @@ #include // for PTree::display (debugging...) #include // for SymbolTable::display (debugging...) #include -#include +#include using Synopsis::Token; using Synopsis::Trace; namespace PT = Synopsis::PTree; namespace ST = Synopsis::SymbolTable; +namespace fs = boost::filesystem; namespace { @@ -83,10 +84,11 @@ Trace trace("ASTTranslator::ASTTranslator", Trace::TRANSLATION); // determine canonical filenames - Path path = Path(my_raw_filename).abs(); - std::string long_filename = path.str(); - path.strip(my_base_path); - std::string short_filename = path.str(); + fs::path path = fs::system_complete(fs::path(my_raw_filename, fs::native)).normalize(); + std::string long_filename = path.native_file_string(); + std::string short_filename = path.native_file_string(); + if (my_base_path.size() && my_base_path == short_filename.substr(0, my_base_path.size())) + short_filename.erase(0, my_base_path.size()); AST::SourceFile file = my_ast.files().get(short_filename); if (file) @@ -514,10 +516,11 @@ my_raw_filename = filename; // determine canonical filenames - Path path = Path(filename).abs(); - std::string long_filename = path.str(); - path.strip(my_base_path); - std::string short_filename = path.str(); + fs::path path = fs::system_complete(fs::path(filename, fs::native)).normalize(); + std::string long_filename = path.native_file_string(); + std::string short_filename = path.native_file_string(); + if (my_base_path.size() && my_base_path == short_filename.substr(0, my_base_path.size())) + short_filename.erase(0, my_base_path.size()); AST::SourceFile file = my_ast.files().get(short_filename); if (file) Index: synopsis_trunk/src/Makefile.in =================================================================== --- synopsis_trunk/src/Makefile.in (revision 1815) +++ synopsis_trunk/src/Makefile.in (working copy) @@ -81,7 +81,7 @@ TSRC := $(patsubst %, tools/%.cc, $(TOOLS)) -SUP := $(patsubst %, Support/%.cc, Path ErrorHandler) +SUP := $(patsubst %, Support/%.cc, ErrorHandler) HDR := $(patsubst $(srcdir)/%, %, $(wildcard $(srcdir)/Synopsis/*.hh)) HDR += $(patsubst $(srcdir)/%, %, $(wildcard $(srcdir)/Synopsis/PTree/*.hh)) Index: synopsis_trunk/src/Synopsis/Parser.cc =================================================================== --- synopsis_trunk/src/Synopsis/Parser.cc (revision 1815) +++ synopsis_trunk/src/Synopsis/Parser.cc (working copy) @@ -13,6 +13,7 @@ #include "Synopsis/Lexer.hh" #include #include +#include namespace PT = Synopsis::PTree; namespace ST = Synopsis::SymbolTable; Index: synopsis_trunk/src/Synopsis/SymbolFactory.cc =================================================================== --- synopsis_trunk/src/Synopsis/SymbolFactory.cc (revision 1815) +++ synopsis_trunk/src/Synopsis/SymbolFactory.cc (working copy) @@ -16,6 +16,7 @@ #include #include #include +#include using namespace Synopsis; namespace PT = Synopsis::PTree; Index: synopsis_trunk/src/Synopsis/SymbolTable/Scope.cc =================================================================== --- synopsis_trunk/src/Synopsis/SymbolTable/Scope.cc (revision 1815) +++ synopsis_trunk/src/Synopsis/SymbolTable/Scope.cc (working copy) @@ -10,6 +10,7 @@ #include #include #include +#include using namespace Synopsis; using namespace PTree; Index: synopsis_trunk/src/Support/Path-posix.cc =================================================================== --- synopsis_trunk/src/Support/Path-posix.cc (revision 1815) +++ synopsis_trunk/src/Support/Path-posix.cc (working copy) @@ -1,110 +0,0 @@ -// -// Copyright (C) 2004 Stefan Seefeld -// All rights reserved. -// Licensed to the public under the terms of the GNU LGPL (>= 2), -// see the file COPYING for details. -// - -#include "Path.hh" -#include -#include -#include -#include -#include -#include - -using namespace Synopsis; - -const char Path::SEPARATOR = '/'; - -std::string Path::cwd() -{ - static std::string path; - if (path.empty()) - for (long path_max = 32;; path_max *= 2) - { - char *buf = new char[path_max]; - if (::getcwd(buf, path_max) == 0) - { - if (errno != ERANGE) - { - delete [] buf; - throw std::runtime_error(strerror(errno)); - } - } - else - { - path = buf; - delete [] buf; - return path; - } - delete [] buf; - } - return path; -} - -std::string Path::normalize(const std::string &filename) -{ - std::string value = filename; - char separator = '/'; - const char *pat1 = "/./"; - const char *pat2 = "/../"; - if (value[0] != separator) - value.insert(0, Path::cwd() + separator); - - // nothing to do... - if (value.find(pat1) == std::string::npos && - value.find(pat2) == std::string::npos) return value; - - // for the rest we'll operate on a decomposition of the filename... - typedef std::vector Components; - Components components; - - std::string::size_type b = 0; - while (b < value.size()) - { - std::string::size_type e = value.find(separator, b); - components.push_back(value.substr(b, e-b)); - b = e == std::string::npos ? std::string::npos : e + 1; - } - - // remove all '.' and '' components - components.erase(std::remove(components.begin(), components.end(), "."), components.end()); - components.erase(std::remove(components.begin(), components.end(), ""), components.end()); - // now collapse '..' components with the preceding one - while (true) - { - Components::iterator i = std::find(components.begin(), components.end(), ".."); - if (i == components.end()) break; - if (i == components.begin()) throw std::invalid_argument("invalid path"); - components.erase(i - 1, i + 1); // remove two components - } - - // now rebuild the path as a string - std::string retn = '/' + components.front(); - for (Components::iterator i = components.begin() + 1; i != components.end(); ++i) - retn += '/' + *i; - return retn; -} - -namespace Synopsis -{ - -void makedirs(const Path &path) -{ - const std::string &dir = path.str(); - if (dir.empty()) throw std::runtime_error("empty path in 'makedirs'"); - std::string::size_type cursor = 0; - while (cursor != std::string::npos) - { - cursor = dir.find(Path::SEPARATOR, cursor + 1); - struct stat st; - int error; - if ((error = stat(dir.substr(0, cursor).c_str(), &st)) == -1 && - errno == ENOENT) - mkdir(dir.substr(0, cursor).c_str(), 0755); - else if (error) throw std::runtime_error(strerror(errno)); - } -} - -} Index: synopsis_trunk/src/Support/Path-win32.cc =================================================================== --- synopsis_trunk/src/Support/Path-win32.cc (revision 1815) +++ synopsis_trunk/src/Support/Path-win32.cc (working copy) @@ -1,110 +0,0 @@ -// -// Copyright (C) 2004 Stefan Seefeld -// All rights reserved. -// Licensed to the public under the terms of the GNU LGPL (>= 2), -// see the file COPYING for details. -// - -#include "Path.hh" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Synopsis; - -const char Path::SEPARATOR = '\\'; - -std::string Path::cwd() -{ - static std::string path; - if (path.empty()) - { - DWORD size; - if ((size = ::GetCurrentDirectoryA(0, 0)) == 0) - { - throw std::runtime_error("error accessing current working directory"); - } - char *buf = new char[size]; - if (::GetCurrentDirectoryA(size, buf) == 0) - { - delete [] buf; - throw std::runtime_error("error accessing current working directory"); - } - path = buf; - delete [] buf; - } - return path; -} - -std::string Path::normalize(const std::string &filename) -{ - std::string value = filename; - char separator = '\\'; - const char *pat1 = "\\.\\"; - const char *pat2 = "\\..\\"; - if (value[0] != separator && - value.size() > 2 && value[1] != ':' && value[2] != '\\') - value.insert(0, cwd() + separator); - // nothing to do... - if (value.find(pat1) == std::string::npos && - value.find(pat2) == std::string::npos) return value; - - // for the rest we'll operate on a decomposition of the filename... - typedef std::vector Components; - Components components; - - std::string::size_type b = 0; - while (b < value.size()) - { - std::string::size_type e = value.find(separator, b); - components.push_back(value.substr(b, e-b)); - b = e == std::string::npos ? std::string::npos : e + 1; - } - - // remove all '.' and '' components - components.erase(std::remove(components.begin(), components.end(), "."), components.end()); - components.erase(std::remove(components.begin(), components.end(), ""), components.end()); - // now collapse '..' components with the preceding one - while (true) - { - Components::iterator i = std::find(components.begin(), components.end(), ".."); - if (i == components.end()) break; - if (i == components.begin()) throw std::invalid_argument("invalid path"); - components.erase(i - 1, i + 1); // remove two components - } - - // now rebuild the path as a string - std::string retn = '/' + components.front(); - for (Components::iterator i = components.begin() + 1; i != components.end(); ++i) - retn += '/' + *i; - return retn; -} - -namespace Synopsis -{ - -void makedirs(const Path &path) -{ - const std::string &dir = path.str(); - if (dir.empty()) throw std::runtime_error("empty path in 'makedirs'"); - std::string::size_type cursor = 0; - while (cursor != std::string::npos) - { - cursor = dir.find(Path::SEPARATOR, cursor + 1); - struct stat st; - int error; - if ((error = stat(dir.substr(0, cursor).c_str(), &st)) == -1 && - errno == ENOENT) - _mkdir(dir.substr(0, cursor).c_str()); - else if (error) throw std::runtime_error(strerror(errno)); - } -} - -} Index: synopsis_trunk/src/Support/Path.cc =================================================================== --- synopsis_trunk/src/Support/Path.cc (revision 1815) +++ synopsis_trunk/src/Support/Path.cc (working copy) @@ -1,38 +0,0 @@ -// -// Copyright (C) 2004 Stefan Seefeld -// All rights reserved. -// Licensed to the public under the terms of the GNU LGPL (>= 2), -// see the file COPYING for details. -// - -#include "Path.hh" - -#ifdef _WIN32 -# include "Path-win32.cc" -#else -# include "Path-posix.cc" -#endif - -using namespace Synopsis; - -std::string Path::basename() const -{ - if (my_impl.empty()) return ""; - std::string::size_type i = my_impl.rfind(Path::SEPARATOR); - return i == std::string::npos ? my_impl : my_impl.substr(i + 1); -} - -Path Path::dirname() const -{ - if (my_impl.empty()) return Path(""); - std::string::size_type i = my_impl.rfind(Path::SEPARATOR); - return i == std::string::npos ? Path("") : Path(my_impl.substr(0, i)); -} - -void Path::strip(const std::string &prefix) -{ - if (prefix.empty()) return; - if (prefix == my_impl.substr(0, prefix.size())) - my_impl = my_impl.substr(prefix.size()); -} - Index: synopsis_trunk/src/Support/Path.hh =================================================================== --- synopsis_trunk/src/Support/Path.hh (revision 1815) +++ synopsis_trunk/src/Support/Path.hh (working copy) @@ -1,49 +0,0 @@ -// -// Copyright (C) 2004 Stefan Seefeld -// All rights reserved. -// Licensed to the public under the terms of the GNU LGPL (>= 2), -// see the file COPYING for details. -// - -#ifndef Synopsis_Path_hh_ -#define Synopsis_Path_hh_ - -#include -#include - -namespace Synopsis -{ - -class Path -{ -public: - static const char SEPARATOR; - //. take a possibly relative path - //. and turn it into an absolute one. - Path(const std::string &from) : my_impl(from) {} - - //. return the file component in the path - std::string basename() const; - //. return the directory component in the path - Path dirname() const; - //. return absolute path - Path abs() const { return Path(normalize(my_impl));} - //. strip prefix - void strip(const std::string &prefix); - //. return the path as a string - std::string str() const { return my_impl;} - //. return the current working directory - static std::string cwd(); -private: - //. return the normalized and absolutized path - static std::string normalize(const std::string &); - std::string my_impl; -}; - -//. create directory, makes all intermediate-level directories -//. needed to contain the leaf directory. -void makedirs(const Path &); - -} - -#endif