oops
[supertux.git] / src / file_system.cpp
1 #include <config.h>
2
3 #include "file_system.hpp"
4
5 #include <string>
6 #include <vector>
7 #include <iostream>
8 #include <sstream>
9
10 namespace FileSystem
11 {
12
13 std::string dirname(const std::string& filename)
14 {
15   std::string::size_type p = filename.find_last_of('/');
16   if(p == std::string::npos)                              
17     return "";
18   
19   return filename.substr(0, p+1);
20 }
21
22 std::string basename(const std::string& filename)
23 {
24   std::string::size_type p = filename.find_last_of('/');
25   if(p == std::string::npos)
26     return filename;
27
28   return filename.substr(p, filename.size()-p);
29 }
30
31 std::string normalize(const std::string& filename)
32 {
33   std::vector<std::string> path_stack;
34
35   const char* p = filename.c_str();
36
37   while(true) {
38     while(*p == '/') {
39       p++;
40       continue;
41     }
42
43     const char* pstart = p;
44     while(*p != '/' && *p != 0) {
45       ++p;
46     }
47
48     size_t len = p - pstart;
49     if(len == 0)
50       break;
51     
52     std::string pathelem(pstart, p-pstart);
53     if(pathelem == ".")
54       continue;
55     
56     if(pathelem == "..") {
57       if(path_stack.empty()) {
58         std::cout << "Invalid '..' in path '" << filename << "'.\n";
59         // push it into the result path so that the users sees his error...
60         path_stack.push_back(pathelem);
61       } else {
62         path_stack.pop_back();
63       }
64     } else {
65       path_stack.push_back(pathelem);
66     }
67   }
68
69   // construct path
70   std::ostringstream result;
71   for(std::vector<std::string>::iterator i = path_stack.begin();
72       i != path_stack.end(); ++i) {
73     result << '/' << *i;
74   }
75   if(path_stack.empty())
76     result << '/';
77
78   return result.str();
79 }
80
81 }
82