Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
path.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2010 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * helper functions for path strings.
25  */
26 
27 #include "precompiled.h"
28 #include "lib/path.h"
29 
30 #include <cstring>
31 #include <cerrno>
32 
34  { ERR::PATH_CHARACTER_ILLEGAL, L"illegal path character" },
35  { ERR::PATH_CHARACTER_UNSAFE, L"unsafe path character" },
36  { ERR::PATH_NOT_FOUND, L"path not found" },
37  { ERR::PATH_MIXED_SEPARATORS, L"path contains both slash and backslash separators" }
38 };
39 STATUS_ADD_DEFINITIONS(pathStatusDefinitions);
40 
41 
42 static bool path_is_dir_sep(wchar_t c)
43 {
44  if(c == '/' || c == '\\')
45  return true;
46  return false;
47 }
48 
49 // is s2 a subpath of s1, or vice versa?
50 // (equal counts as subpath)
51 bool path_is_subpath(const wchar_t* s1, const wchar_t* s2)
52 {
53  // make sure s1 is the shorter string
54  if(wcslen(s1) > wcslen(s2))
55  std::swap(s1, s2);
56 
57  wchar_t c1 = 0, last_c1, c2;
58  for(;;)
59  {
60  last_c1 = c1;
61  c1 = *s1++, c2 = *s2++;
62 
63  // end of s1 reached:
64  if(c1 == '\0')
65  {
66  // s1 matched s2 up until:
67  if((c2 == '\0') || // its end (i.e. they're equal length) OR
68  path_is_dir_sep(c2) || // start of next component OR
69  path_is_dir_sep(last_c1)) // ", but both have a trailing slash
70  // => is subpath
71  return true;
72  }
73 
74  // mismatch => is not subpath
75  if(c1 != c2)
76  return false;
77  }
78 }
79 
80 
81 //-----------------------------------------------------------------------------
82 
83 // return pointer to the name component within path (i.e. skips over all
84 // characters up to the last dir separator, if any).
85 const wchar_t* path_name_only(const wchar_t* path)
86 {
87  const wchar_t* slash1 = wcsrchr(path, '/');
88  const wchar_t* slash2 = wcsrchr(path, '\\');
89  // neither present, it's a filename only
90  if(!slash1 && !slash2)
91  return path;
92 
93  // return name, i.e. component after the last slash
94  const wchar_t* name = std::max(slash1, slash2)+1;
95  return name;
96 }
97 
98 
99 /*static*/ Status Path::Validate(String::value_type c)
100 {
101  if(c < 32)
103 
104 #if !OS_WIN
105  if(c >= UCHAR_MAX)
107 #endif
108 
109  switch(c)
110  {
111  case '\\':
112  case '/':
113  case ':':
114  case '"':
115  case '?':
116  case '*':
117  case '<':
118  case '>':
119  case '|':
120  case '^':
122 
123  default:
124  return INFO::OK;
125  }
126 }
const Status OK
Definition: status.h:386
static bool path_is_dir_sep(wchar_t c)
Definition: path.cpp:42
const Status PATH_CHARACTER_ILLEGAL
Definition: path.h:48
static void swap(UniqueRange &p1, UniqueRange &p2)
Definition: unique_range.h:176
const Status PATH_CHARACTER_UNSAFE
Definition: path.h:49
i64 Status
Error handling system.
Definition: status.h:171
const Status PATH_MIXED_SEPARATORS
Definition: path.h:51
#define STATUS_ADD_DEFINITIONS(definitions)
add a module&#39;s array of StatusDefinition to the list.
Definition: status.h:216
bool path_is_subpath(const wchar_t *s1, const wchar_t *s2)
is s2 a subpath of s1, or vice versa? (equal counts as subpath)
Definition: path.cpp:51
static Status Validate(String::value_type c)
Definition: path.cpp:99
const wchar_t * path_name_only(const wchar_t *path)
Get the path component of a path.
Definition: path.cpp:85
static const StatusDefinition pathStatusDefinitions[]
Definition: path.cpp:33
const Status PATH_NOT_FOUND
Definition: path.h:50