Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <iostream>
16 : : #include <algorithm>
17 : : #include <string>
18 : :
19 : : #include <ctype.h>
20 : :
21 : : #include <util/filename.h>
22 : :
23 : : using namespace std;
24 : :
25 : :
26 : : namespace isc {
27 : : namespace util {
28 : :
29 : : // Split string into components. Any backslashes are assumed to have
30 : : // been replaced by forward slashes.
31 : :
32 : : void
33 : 495 : Filename::split(const string& full_name, string& directory,
34 : : string& name, string& extension) const
35 : : {
36 : 990 : directory = name = extension = "";
37 : 495 : bool dir_present = false;
38 [ + + ]: 495 : if (!full_name.empty()) {
39 : :
40 : : // Find the directory.
41 : 485 : size_t last_slash = full_name.find_last_of('/');
42 [ + + ]: 485 : if (last_slash != string::npos) {
43 : :
44 : : // Found the last slash, so extract directory component and
45 : : // set where the scan for the last_dot should terminate.
46 : 938 : directory = full_name.substr(0, last_slash + 1);
47 [ + - ]: 469 : if (last_slash == full_name.size()) {
48 : :
49 : : // The entire string was a directory, so exit not and don't
50 : : // do any more searching.
51 : : return;
52 : : }
53 : :
54 : : // Found a directory so note the fact.
55 : : dir_present = true;
56 : : }
57 : :
58 : : // Now search backwards for the last ".".
59 : 485 : size_t last_dot = full_name.find_last_of('.');
60 [ + + ][ + + ]: 485 : if ((last_dot == string::npos) ||
[ - + ]
61 : : (dir_present && (last_dot < last_slash))) {
62 : :
63 : : // Last "." either not found or it occurs to the left of the last
64 : : // slash if a directory was present (so it is part of a directory
65 : : // name). In this case, the remainder of the string after the slash
66 : : // is the name part.
67 : 28 : name = full_name.substr(last_slash + 1);
68 : 14 : return;
69 : : }
70 : :
71 : : // Did find a valid dot, so it and everything to the right is the
72 : : // extension...
73 : 942 : extension = full_name.substr(last_dot);
74 : :
75 : : // ... and the name of the file is everything in between.
76 [ + + ]: 471 : if ((last_dot - last_slash) > 1) {
77 : 959 : name = full_name.substr(last_slash + 1, last_dot - last_slash - 1);
78 : : }
79 : : }
80 : :
81 : : }
82 : :
83 : : // Expand the stored filename with the default.
84 : :
85 : : string
86 : 15 : Filename::expandWithDefault(const string& defname) const {
87 : :
88 : 30 : string def_directory("");
89 [ + - ]: 30 : string def_name("");
90 [ + - ]: 30 : string def_extension("");
91 : :
92 : : // Normalize the input string.
93 [ + - ]: 30 : string copy_defname = isc::util::str::trim(defname);
94 : : #ifdef WIN32
95 : : isc::util::str::normalizeSlash(copy_defname);
96 : : #endif
97 : :
98 : : // Split into the components
99 [ + - ]: 15 : split(copy_defname, def_directory, def_name, def_extension);
100 : :
101 : : // Now construct the result.
102 : : string retstring =
103 : 15 : (directory_.empty() ? def_directory : directory_) +
104 : 15 : (name_.empty() ? def_name : name_) +
105 [ + + ][ + + ]: 15 : (extension_.empty() ? def_extension : extension_);
[ + + ][ + - ]
[ + - ]
106 : 15 : return (retstring);
107 : : }
108 : :
109 : : // Use the stored name as default for a given name
110 : :
111 : : string
112 : 8 : Filename::useAsDefault(const string& name) const {
113 : :
114 : 16 : string name_directory("");
115 [ + - ]: 16 : string name_name("");
116 [ + - ]: 16 : string name_extension("");
117 : :
118 : : // Normalize the input string.
119 [ + - ]: 16 : string copy_name = isc::util::str::trim(name);
120 : : #ifdef WIN32
121 : : isc::util::str::normalizeSlash(copy_name);
122 : : #endif
123 : :
124 : : // Split into the components
125 [ + - ]: 8 : split(copy_name, name_directory, name_name, name_extension);
126 : :
127 : : // Now construct the result.
128 : : string retstring =
129 : : (name_directory.empty() ? directory_ : name_directory) +
130 : 8 : (name_name.empty() ? name_ : name_name) +
131 [ + + ][ + + ]: 8 : (name_extension.empty() ? extension_ : name_extension);
[ + + ][ + - ]
[ + - ]
132 : 8 : return (retstring);
133 : : }
134 : :
135 : : void
136 : 5 : Filename::setDirectory(const std::string& new_directory) {
137 : 10 : std::string directory(new_directory);
138 : :
139 [ + + ]: 5 : if (directory.length() > 0) {
140 : : // append '/' if necessary
141 [ + - ]: 4 : size_t sep = directory.rfind('/');
142 [ + - ][ + + ]: 4 : if (sep == std::string::npos || sep < directory.size() - 1) {
[ + + ]
143 : : directory += "/";
144 : : }
145 : : }
146 : : // and regenerate the full name
147 [ + - ][ + - ]: 10 : std::string full_name = directory + name_ + extension_;
148 : :
149 [ + - ]: 5 : directory_.swap(directory);
150 [ + - ]: 5 : full_name_.swap(full_name);
151 : 5 : }
152 : :
153 : :
154 : : } // namespace log
155 : 169 : } // namespace isc
|