1 //----------------------------------------------------------------------------
2 //  EDGE Path Handling Methods for Win32
3 //----------------------------------------------------------------------------
4 //
5 //  Copyright (c) 2003-2008  The EDGE Team.
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU General Public License
9 //  as published by the Free Software Foundation; either version 2
10 //  of the License, or (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //----------------------------------------------------------------------------
18 //
19 #include "epi.h"
20 #include "path.h"
21 
22 namespace epi
23 {
24 
25 // Path Manipulation Functions
PATH_GetDir(const char * path)26 std::string PATH_GetDir(const char *path)
27 {
28 	SYS_ASSERT(path);
29 
30 	const char *p = path + strlen(path) - 1;
31 
32 	// back up until a slash or the start
33 	for (; p > path; p--)
34 		if (PATH_IsDirSep(*p))
35 			return std::string(path, (p - path));
36 
37     return std::string();  // nothing
38 }
39 
40 
PATH_GetFilename(const char * path)41 std::string PATH_GetFilename(const char *path)
42 {
43 	SYS_ASSERT(path);
44 
45 	const char *p = path + strlen(path) - 1;
46 
47 	// back up until a slash or the start
48 	for (; p >= path; p--)
49 		if (PATH_IsDirSep(*p))
50 			return std::string(p + 1);
51 
52     return std::string(path);
53 }
54 
55 
PATH_GetExtension(const char * path)56 std::string PATH_GetExtension(const char *path)
57 {
58 	SYS_ASSERT(path);
59 
60 	const char *p = path + strlen(path) - 1;
61 
62 	// back up until a dot
63 	for (; p >= path; p--)
64 	{
65 		if (PATH_IsDirSep(*p))
66 			break;
67 
68 		if (*p == '.')
69 		{
70             // handle filenames that being with a dot
71             // (un*x style hidden files)
72             if (p == path || PATH_IsDirSep(p[-1]))
73 				break;
74 
75 			return std::string(p + 1);
76 		}
77 	}
78 
79     return std::string();  // nothing
80 }
81 
82 
PATH_GetBasename(const char * path)83 std::string PATH_GetBasename(const char *path)
84 {
85 	SYS_ASSERT(path);
86 
87 	const char *p = path + strlen(path) - 1;
88 	const char *r = p;
89 
90 	// back up until a slash or the start
91 	for (; p > path; p--)
92 	{
93 		if (PATH_IsDirSep(*p))
94 		{
95 			p++; break;
96 		}
97 	}
98 
99 	SYS_ASSERT(p >= path);
100 
101 	// back up until a dot
102 	for (; r >= p; r--)
103 	{
104 		if (*r == '.')
105 		{
106             // handle filenames that being with a dot
107             // (un*x style hidden files)
108             if (r == p || PATH_IsDirSep(r[-1]))
109 				break;
110 
111 			return std::string(p, r - p);
112 		}
113 	}
114 
115     return std::string(p);
116 }
117 
118 
119 
PATH_IsAbsolute(const char * path)120 bool PATH_IsAbsolute(const char *path)
121 {
122 	SYS_ASSERT(path);
123 
124 #ifdef WIN32
125     // Check for Drive letter, colon and slash...
126     if (strlen(path) > 2 && path[1] == ':' &&
127         (path[2] == '\\' || path[2] == '/') &&
128         isalpha(path[0]))
129     {
130         return true;
131     }
132 
133     // Check for share name...
134     if (strlen(path) > 1 && path[0] == '\\' && path[1] == '\\')
135         return true;
136 
137 #else // LINUX
138 
139 	if (PATH_IsDirSep(path[0]))
140 		return true;
141 #endif
142 
143     return false;
144 }
145 
146 
PATH_IsDirSep(const char c)147 bool PATH_IsDirSep(const char c)
148 {
149 #ifdef WIN32
150     return (c == '\\' || c == '/' || c == ':'); // Kester added ':'
151 #else // LINUX
152     return (c == '\\' || c == '/');
153 #endif
154 }
155 
156 
PATH_Join(const char * lhs,const char * rhs)157 std::string PATH_Join(const char *lhs, const char *rhs)
158 {
159 	SYS_ASSERT(lhs && rhs);
160 
161 	if (PATH_IsAbsolute(rhs))
162 		return std::string(rhs);
163 
164     std::string result(lhs);
165 
166 	if (result.size() > 0)
167 	{
168 		const char c = result[result.size()-1];
169 
170 #ifdef WIN32
171 		if (c != '\\' && c != '/')
172 			result += DIRSEPARATOR;
173 #else // LINUX
174 		if (c != '/')
175 			result += DIRSEPARATOR;
176 #endif
177 	}
178 
179 	result += rhs;
180 
181     return result;
182 }
183 
184 
185 } // namespace epi
186 
187 //--- editor settings ---
188 // vi:ts=4:sw=4:noexpandtab
189