]> git.tdb.fi Git - libs/core.git/blob - source/utils.cpp
5c8c8d4cdd08e899336b2bf8d15b3f0170a5be2b
[libs/core.git] / source / utils.cpp
1 /* $Id$
2
3 This file is part of libmspfs
4 Copyright © 2006-2008  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <cerrno>
9 #include <msp/core/except.h>
10 #ifndef WIN32
11 #include <fnmatch.h>
12 #else
13 #include <msp/strings/glob.h>
14 #endif
15 #include <msp/strings/utils.h>
16 #include "dir.h"
17 #include "path.h"
18 #include "utils.h"
19
20 using namespace std;
21
22 namespace Msp {
23 namespace FS {
24
25 /**
26 Fixes the case of the given path to match files / directories on the
27 filesystem.  Intended to be used in programs that need to interact with
28 emulated Windows programs.
29 */
30 Path fix_case(const Path &path)
31 {
32         bool found=true;
33         Path result;
34         for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
35         {
36                 if(!found || *i=="/")
37                         result/=*i;
38                 else
39                 {
40                         list<string> files;
41                         if(result.size())
42                                 files=list_files(result);
43                         else
44                                 files=list_files(".");
45
46                         found=false;
47                         for(list<string>::iterator j=files.begin(); (j!=files.end() && !found); ++j)
48                                 if(!strcasecmp(*j,*i))
49                                 {
50                                         result/=*j;
51                                         found=true;
52                                 }
53
54                         if(!found)
55                                 result/=*i;
56                 }
57         }
58
59         return result;
60 }
61
62 void unlink(const Path &path)
63 {
64         if(::unlink(path.str().c_str())==-1)
65                 throw SystemError("unlink failed", errno);
66 }
67
68 Filename splitext(const string &fn)
69 {
70         Filename result;
71         unsigned dot=fn.rfind('.');
72         result.base=fn.substr(0, dot);
73         if(dot!=string::npos)
74                 result.ext=fn.substr(dot);
75         return result;
76 }
77
78 int fnmatch(const string &pat, const Path &fn)
79 {
80 #ifdef WIN32
81         return globcasematch(pat, fn.str());
82 #else
83         return ::fnmatch(pat.c_str(), fn.str().c_str(), FNM_PATHNAME);
84 #endif
85 }
86
87 Path relative(const Path &path, const Path &base)
88 {
89         Path::Iterator i=path.begin();
90         Path::Iterator j=base.begin();
91         for(; (i!=path.end() && j!=base.end() && *i==*j); ++i, ++j) ;
92
93         Path result;
94         for(; j!=base.end(); ++j)
95                 result/="..";
96         for(; i!=path.end(); ++i)
97                 result/=*i;
98
99         return result;
100 }
101
102 /**
103 Extracts the basename from the given path.  Same thing as Path::Path(p)[-1],
104 but faster.
105 */
106 string basename(const std::string &p)
107 {
108         unsigned slash=p.rfind(DIRCHAR);
109         if(slash==string::npos)
110                 return p;
111         else
112                 return p.substr(slash+1);
113 }
114
115 } // namespace FS
116 } // namespace Msp