]> git.lyx.org Git - lyx.git/blob - src/support/filename.C
MacOSX compile fix.
[lyx.git] / src / support / filename.C
1 /**
2  * \file filename.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "support/filename.h"
14 #include "support/filetools.h"
15 #include "support/lstrings.h"
16 #include "support/os.h"
17
18 #include <boost/assert.hpp>
19
20 #include <map>
21 #include <sstream>
22 #include <algorithm>
23
24
25 using std::map;
26 using std::string;
27
28
29 namespace lyx {
30 namespace support {
31
32
33 FileName::FileName()
34         : save_abs_path_(true)
35 {}
36
37
38 FileName::FileName(string const & abs_filename, bool save_abs)
39         : name_(abs_filename), save_abs_path_(save_abs), zipped_valid_(false)
40 {
41         BOOST_ASSERT(absolutePath(name_));
42 }
43
44
45 void FileName::set(string const & name, string const & buffer_path)
46 {
47         save_abs_path_ = absolutePath(name);
48         name_ = save_abs_path_ ? name : makeAbsPath(name, buffer_path);
49         zipped_valid_ = false;
50 }
51
52
53 void FileName::erase()
54 {
55         name_.erase();
56         zipped_valid_ = false;
57 }
58
59
60 string const FileName::relFilename(string const & path) const
61 {
62         return makeRelPath(name_, path);
63 }
64
65
66 string const FileName::outputFilename(string const & path) const
67 {
68         return save_abs_path_ ? name_ : makeRelPath(name_, path);
69 }
70
71
72 string const FileName::mangledFilename(std::string const & dir) const
73 {
74         // We need to make sure that every FileName instance for a given
75         // filename returns the same mangled name.
76         typedef map<string, string> MangledMap;
77         static MangledMap mangledNames;
78         MangledMap::const_iterator const it = mangledNames.find(name_);
79         if (it != mangledNames.end())
80                 return (*it).second;
81
82         // Now the real work
83         string mname = os::internal_path(name_);
84         // Remove the extension.
85         mname = changeExtension(name_, string());
86         // Replace '/' in the file name with '_'
87         mname = subst(mname, "/", "_");
88         // Replace '.' in the file name with '_'
89         mname = subst(mname, ".", "_");
90         // Replace ' ' in the file name with '_'
91         mname = subst(mname, " ", "_");
92         // Replace ':' in the file name with '_'
93         mname = subst(mname, ":", "_");
94         // Add the extension back on
95         mname = changeExtension(mname, getExtension(name_));
96
97         // Prepend a counter to the filename. This is necessary to make
98         // the mangled name unique.
99         static int counter = 0;
100         std::ostringstream s;
101         s << counter++ << mname;
102         mname = s.str();
103
104         // MiKTeX's YAP (version 2.4.1803) crashes if the file name
105         // is longer than about 160 characters. MiKTeX's pdflatex
106         // is even pickier. A maximum length of 100 has been proven to work.
107         // If dir.size() > max length, all bets are off for YAP. We truncate
108         // the filename nevertheless, keeping a minimum of 10 chars.
109
110         string::size_type max_length = std::max(100 - ((int)dir.size() + 1), 10);
111
112         // If the mangled file name is too long, hack it to fit.
113         // We know we're guaranteed to have a unique file name because
114         // of the counter.
115         if (mname.size() > max_length) {
116                 int const half = (int(max_length) / 2) - 2;
117                 if (half > 0) {
118                         mname = mname.substr(0, half) + "___" +
119                                 mname.substr(mname.size() - half);
120                 }
121         }
122
123         mangledNames[name_] = mname;
124         return mname;
125 }
126
127
128 bool FileName::isZipped() const
129 {
130         if (!zipped_valid_) {
131                 zipped_ = zippedFile(name_);
132                 zipped_valid_ = true;
133         }
134         return zipped_;
135 }
136
137
138 string const FileName::unzippedFilename() const
139 {
140         return unzippedFileName(name_);
141 }
142
143
144 bool operator==(FileName const & lhs, FileName const & rhs)
145 {
146         return lhs.absFilename() == rhs.absFilename() &&
147                 lhs.saveAbsPath() == rhs.saveAbsPath();
148 }
149
150
151 bool operator!=(FileName const & lhs, FileName const & rhs)
152 {
153         return !(lhs == rhs);
154 }
155
156 } // namespace support
157 } // namespace lyx