1 | // long_name_check implementation ------------------------------------------// |
---|
2 | |
---|
3 | // Copyright Beman Dawes 2002. |
---|
4 | // Copyright Gennaro Prota 2006. |
---|
5 | // |
---|
6 | // Distributed under the Boost Software License, Version 1.0. |
---|
7 | // (See accompanying file LICENSE_1_0.txt or copy at |
---|
8 | // http://www.boost.org/LICENSE_1_0.txt) |
---|
9 | |
---|
10 | #include "long_name_check.hpp" |
---|
11 | |
---|
12 | #include "boost/filesystem/operations.hpp" |
---|
13 | #include "boost/lexical_cast.hpp" |
---|
14 | |
---|
15 | #include <locale> |
---|
16 | #include <algorithm> |
---|
17 | |
---|
18 | namespace { namespace aux { |
---|
19 | |
---|
20 | bool starts_with_nonalpha( path const & p ) |
---|
21 | { |
---|
22 | const string & x = p.string(); |
---|
23 | assert(!x.empty()); |
---|
24 | |
---|
25 | const string::value_type first = x[0]; |
---|
26 | |
---|
27 | return !std::isalpha( first, std::locale::classic() ) |
---|
28 | && first != '_' |
---|
29 | && x != ".cvsignore" |
---|
30 | ; |
---|
31 | } |
---|
32 | |
---|
33 | bool contains_dot( path const & p) |
---|
34 | { |
---|
35 | return p.string().find( '.' ) != std::string::npos; |
---|
36 | } |
---|
37 | |
---|
38 | // ISO 9660 |
---|
39 | path::iterator::difference_type depth( path const & p) |
---|
40 | { |
---|
41 | return std::distance( p.begin(), p.end() ); |
---|
42 | } |
---|
43 | |
---|
44 | }} |
---|
45 | |
---|
46 | |
---|
47 | namespace boost |
---|
48 | { |
---|
49 | namespace inspect |
---|
50 | { |
---|
51 | const char file_name_check::limits::name[] = "ISO 9660 Level 3"; |
---|
52 | |
---|
53 | file_name_check::file_name_check() : m_name_errors(0) {} |
---|
54 | |
---|
55 | void file_name_check::inspect( |
---|
56 | const string & library_name, |
---|
57 | const path & full_path ) |
---|
58 | { |
---|
59 | std::string const leaf( full_path.leaf() ); |
---|
60 | |
---|
61 | // checks on the leaf name ----------------------------------// |
---|
62 | { |
---|
63 | const unsigned m = filesystem::is_directory(full_path) |
---|
64 | ? limits::max_dirname_length |
---|
65 | : limits::max_filename_length; |
---|
66 | |
---|
67 | if ( leaf.size() > m ) |
---|
68 | { |
---|
69 | ++m_name_errors; |
---|
70 | error( library_name, full_path, string(name()) |
---|
71 | + " name exceeds " |
---|
72 | + boost::lexical_cast<string>(m) |
---|
73 | + " characters" ); |
---|
74 | } |
---|
75 | } |
---|
76 | |
---|
77 | if ( std::count( leaf.begin(), leaf.end(), '.' ) > 1 ) |
---|
78 | { |
---|
79 | ++m_name_errors; |
---|
80 | error( library_name, full_path, string(name()) |
---|
81 | + " name contains more than one dot character ('.')" ); |
---|
82 | } |
---|
83 | |
---|
84 | if ( *leaf.rbegin() == '.' ) |
---|
85 | { |
---|
86 | ++m_name_errors; |
---|
87 | error( library_name, full_path, string(name()) |
---|
88 | + " filename ends with the dot character ('.')" ); |
---|
89 | } |
---|
90 | |
---|
91 | path const relative_path( |
---|
92 | relative_to( full_path, filesystem::initial_path() ) |
---|
93 | , &filesystem::no_check ); |
---|
94 | |
---|
95 | |
---|
96 | // checks on the directory name --------------------------- // |
---|
97 | |
---|
98 | if( aux::starts_with_nonalpha( path(leaf)) ) |
---|
99 | { |
---|
100 | ++m_name_errors; |
---|
101 | error( library_name, full_path, string(name()) |
---|
102 | + " leading character of \"" |
---|
103 | + leaf + "\"" |
---|
104 | + " is not alphabetic" ); |
---|
105 | } |
---|
106 | |
---|
107 | if ( filesystem::is_directory( full_path ) |
---|
108 | && aux::contains_dot( relative_path ) ) |
---|
109 | { |
---|
110 | ++m_name_errors; |
---|
111 | error( library_name, full_path, string(name()) |
---|
112 | + " directory name contains the dot character ('.')" ); |
---|
113 | } |
---|
114 | |
---|
115 | { |
---|
116 | const int m = limits::max_directory_depth; |
---|
117 | if ( filesystem::is_directory( full_path ) |
---|
118 | && aux::depth( relative_path) > m ) |
---|
119 | { |
---|
120 | ++m_name_errors; |
---|
121 | error( library_name, full_path, string(name()) |
---|
122 | + " directory depth exceeds " |
---|
123 | + boost::lexical_cast<string>(m) |
---|
124 | + " (maximum for " + limits::name + " (CD-ROMs))" ); |
---|
125 | } |
---|
126 | } |
---|
127 | |
---|
128 | const unsigned max_relative_path = 100; // [gps] Explain this |
---|
129 | const string generic_root( "boost_X_XX_X/" ); |
---|
130 | if ( relative_path.string().size() > |
---|
131 | ( max_relative_path - generic_root.size() ) ) |
---|
132 | { |
---|
133 | ++m_name_errors; |
---|
134 | error( library_name, full_path, |
---|
135 | string(name()) |
---|
136 | + " file path will exceed " |
---|
137 | + boost::lexical_cast<string>(max_relative_path) |
---|
138 | + " characters in a directory tree with a root of the form " |
---|
139 | + generic_root ) |
---|
140 | ; |
---|
141 | } |
---|
142 | |
---|
143 | if (relative_path.leaf() != ".cvsignore") |
---|
144 | { |
---|
145 | try |
---|
146 | { |
---|
147 | path const check_portability( relative_path.string(), &filesystem::portable_name ); |
---|
148 | } |
---|
149 | catch ( filesystem::filesystem_error const& ) |
---|
150 | { |
---|
151 | ++m_name_errors; |
---|
152 | error( library_name, full_path, string(name()) + " nonportable path" ); |
---|
153 | } |
---|
154 | } |
---|
155 | } |
---|
156 | |
---|
157 | file_name_check::~file_name_check() |
---|
158 | { |
---|
159 | std::cout << " " << m_name_errors << " " << desc() << '\n'; |
---|
160 | } |
---|
161 | |
---|
162 | |
---|
163 | } // namespace inspect |
---|
164 | } // namespace boost |
---|