]> git.lyx.org Git - lyx.git/blob - src/support/filename.C
whitespace cleanup
[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)
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 }
50
51
52 void FileName::erase()
53 {
54         name_.erase();
55 }
56
57
58 string const FileName::relFilename(string const & path) const
59 {
60         return MakeRelPath(name_, path);
61 }
62
63
64 string const FileName::outputFilename(string const & path) const
65 {
66         return save_abs_path_ ? name_ : MakeRelPath(name_, path);
67 }
68
69
70 string const FileName::mangledFilename(std::string const & dir) const
71 {
72         // We need to make sure that every FileName instance for a given
73         // filename returns the same mangled name.
74         typedef map<string, string> MangledMap;
75         static MangledMap mangledNames;
76         MangledMap::const_iterator const it = mangledNames.find(name_);
77         if (it != mangledNames.end())
78                 return (*it).second;
79
80         // Now the real work
81         string mname = os::internal_path(name_);
82         // Remove the extension.
83         mname = ChangeExtension(name_, string());
84         // Replace '/' in the file name with '_'
85         mname = subst(mname, "/", "_");
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         // Add the extension back on
93         mname = ChangeExtension(mname, GetExtension(name_));
94
95         // Prepend a counter to the filename. This is necessary to make
96         // the mangled name unique.
97         static int counter = 0;
98         std::ostringstream s;
99         s << counter++ << mname;
100         mname = s.str();
101
102         // MiKTeX's YAP (version 2.4.1803) crashes if the file name
103         // is longer than about 160 characters. MiKTeX's pdflatex
104         // is even pickier. A maximum length of 100 has been proven to work.
105         // If dir.size() > max length, all bets are off for YAP. We truncate
106         // the filename nevertheless, keeping a minimum of 10 chars.
107
108         string::size_type max_length = std::max(100 - ((int)dir.size() + 1), 10);
109
110         // If the mangled file name is too long, hack it to fit.
111         // We know we're guaranteed to have a unique file name because
112         // of the counter.
113         if (mname.size() > max_length) {
114                 int const half = (int(max_length) / 2) - 2;
115                 if (half > 0) {
116                         mname = mname.substr(0, half) + "___" +
117                                 mname.substr(mname.size() - half);
118                 }
119         }
120
121         mangledNames[name_] = mname;
122         return mname;
123 }
124
125
126 bool FileName::isZipped() const
127 {
128         return zippedFile(name_);
129 }
130
131
132 string const FileName::unzippedFilename() const
133 {
134         return unzippedFileName(name_);
135 }
136
137
138 bool operator==(FileName const & lhs, FileName const & rhs)
139 {
140         return lhs.absFilename() == rhs.absFilename() &&
141                 lhs.saveAbsPath() == rhs.saveAbsPath();
142 }
143
144
145 bool operator!=(FileName const & lhs, FileName const & rhs)
146 {
147         return !(lhs == rhs);
148 }
149
150 } // namespace support
151 } // namespace lyx