summaryrefslogtreecommitdiff
path: root/tools/inspect/path_name_check.cpp
blob: 87bc6842c99a7f13533e562eb68d50c3ebb78e54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//  path_name_check implementation  ------------------------------------------//

//  Copyright Beman Dawes 2002.
//  Copyright Gennaro Prota 2006.
//
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#include "path_name_check.hpp"

#include "boost/filesystem/operations.hpp"
#include "boost/lexical_cast.hpp"

#include <string>
#include <algorithm>
#include <cctype>
#include <cstring>

using std::string;

namespace
{
  const char allowable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.";
  const char initial_char[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
}

namespace boost
{
  namespace inspect
  {


    file_name_check::file_name_check() : m_name_errors(0) {}

    void file_name_check::inspect(
      const string & library_name,
      const path & full_path )
    {
      string::size_type pos;
      
      //  called for each file and directory, so only the leaf need be tested
      string const leaf( full_path.leaf().string() );

      //  includes only allowable characters
      if ( (pos = leaf.find_first_not_of( allowable )) != string::npos )
      {
        ++m_name_errors;
        error( library_name, full_path, string(name())
            + " file or directory name contains unacceptable character '"
            + leaf[pos] + "'" );
      }

      //  allowable initial character
      if ( std::strchr( initial_char, leaf[0] ) == 0 )
      {
        ++m_name_errors;
        error( library_name, full_path, string(name())
            + " file or directory name begins with an unacceptable character" );
      }

      //  rules for dot characters differ slightly for directories and files
      if ( filesystem::is_directory( full_path ) )
      {
        if ( std::strchr( leaf.c_str(), '.' ) )
        {
          ++m_name_errors;
          error( library_name, full_path, string(name())
              + " directory name contains a dot character ('.')" );
        }
      }
      //else // not a directory
      //{
      //  //  includes at most one dot character
      //  const char * first_dot = std::strchr( leaf.c_str(), '.' );
      //  if ( first_dot && std::strchr( first_dot+1, '.' ) )
      //  {
      //    ++m_name_errors;
      //    error( library_name, full_path, string(name())
      //        + " file name with more than one dot character ('.')" );
      //  }
      //}

      //  the path, including a presumed root, does not exceed the maximum size
      path const relative_path( relative_to( full_path, filesystem::initial_path() ) );
      const unsigned max_relative_path = 207; // ISO 9660:1999 sets this limit
      const string generic_root( "boost_X_XX_X/" );
      if ( relative_path.string().size() >
          ( max_relative_path - generic_root.size() ) )
      {
        ++m_name_errors;
        error( library_name, full_path,
            string(name())
            + " path will exceed "
            + boost::lexical_cast<string>(max_relative_path)
            + " characters in a directory tree with a root in the form "
            + generic_root + ", and this exceeds ISO 9660:1999 limit of 207"  )
            ;
      }

    }

    file_name_check::~file_name_check()
    {
      std::cout << "  " << m_name_errors << " " << desc() << line_break();
    }


  } // namespace inspect
} // namespace boost