| 228 | |
| 229 | |
| 230 | std::string cleanPath(const std::string &path) |
| 231 | { |
| 232 | if (path.empty()) |
| 233 | return path; |
| 234 | std::string name = path; |
| 235 | char dir_separator = separator(); |
| 236 | if (dir_separator != '/') { |
| 237 | std::replace( name.begin(), name.end(), dir_separator, '/'); |
| 238 | } |
| 239 | |
| 240 | int used = 0, levels = 0; |
| 241 | const int len = name.length(); |
| 242 | std::vector<char> outVector(len); |
| 243 | char *out = &outVector[0]; |
| 244 | |
| 245 | const char *p = name.c_str(); |
| 246 | for (int i = 0, last = -1, iwrite = 0; i < len; ++i) { |
| 247 | if (p[i] == '/') { |
| 248 | while (i+1 < len && p[i+1] == '/') { |
| 249 | #if defined(__NATRON_WIN32__) //allow unc paths |
| 250 | if (!i) |
| 251 | break; |
| 252 | #endif |
| 253 | i++; |
| 254 | } |
| 255 | bool eaten = false; |
| 256 | if (i+1 < len && p[i+1] == '.') { |
| 257 | int dotcount = 1; |
| 258 | if (i+2 < len && p[i+2] == '.') |
| 259 | dotcount++; |
| 260 | if (i == len - dotcount - 1) { |
| 261 | if (dotcount == 1) { |
| 262 | break; |
| 263 | } else if (levels) { |
| 264 | if (last == -1) { |
| 265 | for (int i2 = iwrite-1; i2 >= 0; i2--) { |
| 266 | if (out[i2] == '/') { |
| 267 | last = i2; |
| 268 | break; |
| 269 | } |
| 270 | } |
| 271 | } |
| 272 | used -= iwrite - last - 1; |
| 273 | break; |
| 274 | } |
| 275 | } else if (p[i+dotcount+1] == '/') { |
| 276 | if (dotcount == 2 && levels) { |
| 277 | if (last == -1 || iwrite - last == 1) { |
| 278 | for (int i2 = (last == -1) ? (iwrite-1) : (last-1); i2 >= 0; i2--) { |
| 279 | if (out[i2] == '/') { |
| 280 | eaten = true; |
| 281 | last = i2; |
| 282 | break; |
| 283 | } |
| 284 | } |
| 285 | } else { |
| 286 | eaten = true; |
| 287 | } |
no test coverage detected