1 /* 2 * 3 * Copyright (c) 2003-7 John Maddock 4 * Copyright (c) 2007 Bjorn Roald 5 * Use, modification and distribution is subject to the 6 * Boost Software License, Version 1.0. (See accompanying file 7 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 * 9 * This file implements the following: 10 * void bcp_implementation::scan_cvs_path(const fs::path& p) 11 */ 12 13 14 15 #include "bcp_imp.hpp" 16 #include "fileview.hpp" 17 #include <boost/regex.hpp> 18 #include <boost/filesystem/operations.hpp> 19 #include <boost/detail/workaround.hpp> 20 #include <iostream> 21 scan_cvs_path(const fs::path & p)22 void bcp_implementation::scan_cvs_path(const fs::path& p) 23 { 24 // 25 // scan through the cvs admin files to build a list 26 // of all the files under cvs version control 27 // and whether they are text or binary: 28 // 29 static const char* file_list[] = { "CVS/Entries", "CVS/Entries.Log" }; 30 static const boost::regex file_expression("^(?:A\\s+)?/([^/\\n]+)/[^/\\n]*/[^/\\n]*/[^k/\\n]*(kb[^/\\n]*)?/[^/\\n]*"); 31 static const boost::regex dir_expression("^(?:A\\s+)?D/([^/\\n]+)/"); 32 static const int file_subs[] = {1,2,}; 33 34 for(std::size_t entry = 0; entry < sizeof(file_list)/sizeof(file_list[0]); ++entry) 35 { 36 fs::path entries(m_boost_path / p / file_list[entry]); 37 if(fs::exists(entries)) 38 { 39 fileview view(entries); 40 boost::regex_token_iterator<const char*> i(view.begin(), view.end(), dir_expression, 1); 41 boost::regex_token_iterator<const char*> j; 42 while(i != j) 43 { 44 fs::path recursion_dir(p / i->str()); 45 scan_cvs_path(recursion_dir); 46 ++i; 47 } 48 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)) 49 std::vector<int> v(file_subs, file_subs + 2); 50 i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), file_expression, v); 51 #else 52 i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), file_expression, file_subs); 53 #endif 54 while(i != j) 55 { 56 fs::path file = p / i->str(); 57 ++i; 58 bool binary = i->length() ? true : false; 59 ++i; 60 m_cvs_paths[file] = binary; 61 } 62 63 } 64 } 65 } 66 scan_svn_path(const fs::path & p)67 void bcp_implementation::scan_svn_path(const fs::path& p) 68 { 69 // 70 // scan through the svn entries files to build a list 71 // of all the files under svn version control 72 // and whether they are text or binary: 73 // 74 static const boost::regex entry_expression("^\\f([^\\f]*)"); 75 static const boost::regex entry_line_expression("\\n[[:blank:]]*([^\\n]*)"); 76 // static const boost::regex 77 // mime_type_expression("\\nsvn:mime-type\\nV [[digit]]*\\n([^/]*)[^\\n]*"); 78 79 fs::path entries(m_boost_path / p / ".svn" / "entries"); 80 if(fs::exists(entries)) 81 { 82 fileview view(entries); 83 boost::cregex_token_iterator 84 i(view.begin(), view.end(), entry_expression, 1), j; 85 86 while(i != j) // entries 87 { 88 std::string entr = i->str(); 89 boost::sregex_token_iterator 90 atr_it(entr.begin(), entr.end(), entry_line_expression, 1), atr_j; 91 92 if(atr_it != atr_j) 93 { 94 std::string name = atr_it->str(); // name of file or directory 95 fs::path fpath = p / name; 96 if(++atr_it != atr_j) 97 { 98 std::string kind = atr_it->str(); 99 if(kind == "file") 100 { 101 // find if binary, we asume text unless mime type is 102 // set in property file 103 bool binary = false; // 104 105 // skip some lines type | example 106 if( ++atr_it != atr_j && // revnum | 107 ++atr_it != atr_j && // url | 108 ++atr_it != atr_j && // repos | 109 ++atr_it != atr_j && // scedule attr | 110 ++atr_it != atr_j && // text timestamp | 2007-09-02T... 111 ++atr_it != atr_j && // checksum | 58f4bfa7860... 112 ++atr_it != atr_j && // cmt_date | 2007-05-09T... 113 ++atr_it != atr_j && // cmt_rev | 37654 114 ++atr_it != atr_j && // cmt_author | dgregor 115 ++atr_it != atr_j ) // has_props | has-props 116 { 117 if(atr_it->str() == "has-props") 118 { 119 // we need to check properties file for mime-type 120 // that does not start with "text/", if found file is binary 121 fs::path properties(m_boost_path / p / ".svn" / "prop-base" 122 / (name + ".svn-base") ); 123 if(fs::exists(properties)) 124 { 125 fileview prop(properties); 126 127 static const boost::regex mime_type( 128 "svn:mime-type[[:blank:]]*(?:\\n|\\r|\\r\\n)[^\\r\\n]*(?:\\n|\\r|\\r\\n)[[:blank:]]*text/"); 129 binary = regex_search(prop.begin(), prop.end(), mime_type) ? false : true; 130 } 131 } 132 } 133 m_cvs_paths[fpath] = binary; 134 } // kind == "file" 135 else if(kind == "dir") 136 { 137 scan_svn_path(fpath); // recursion for directory entries 138 } 139 // else 140 // std::cerr << "WARNING: unknown entry kind for entry " << name 141 // << "in " << entries << std::endl; 142 } 143 } 144 ++i; 145 } // while 146 } 147 } 148