• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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