• 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