Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
dir-util.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors: see git history
6 *
7 * Copyright (C) 2018 Authors
8 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
9 */
15#include <cerrno>
16#include <string>
17#include <cstring>
18#include <glib.h>
19#include "dir-util.h"
20
21std::string sp_relative_path_from_path( std::string const &path, std::string const &base)
22{
23 std::string result;
24 if ( !base.empty() && !path.empty() ) {
25 size_t base_len = base.length();
26 while (base_len != 0
27 && (base[base_len - 1] == G_DIR_SEPARATOR))
28 {
29 --base_len;
30 }
31
32 if ( (path.substr(0, base_len) == base.substr(0, base_len))
33 && (path[base_len] == G_DIR_SEPARATOR))
34 {
35 size_t retPos = base_len + 1;
36 while ( (retPos < path.length()) && (path[retPos] == G_DIR_SEPARATOR) ) {
37 retPos++;
38 }
39 if ( (retPos + 1) < path.length() ) {
40 result = path.substr(retPos);
41 }
42 }
43
44 }
45 if ( result.empty() ) {
46 result = path;
47 }
48 return result;
49}
50
51char const *sp_extension_from_path(char const *const path)
52{
53 if (path == nullptr) {
54 return nullptr;
55 }
56
57 char const *p = path;
58 while (*p != '\0') p++;
59
60 while ((p >= path) && (*p != G_DIR_SEPARATOR) && (*p != '.')) p--;
61 if (* p != '.') return nullptr;
62 p++;
63
64 return p;
65}
66
67
68/* current == "./", parent == "../" */
69static char const dots[] = {'.', '.', G_DIR_SEPARATOR, '\0'};
70static char const *const parent = dots;
71static char const *const current = dots + 1;
72
73char *inkscape_rel2abs(const char *path, const char *base, char *result, const size_t size)
74{
75 const char *pp, *bp;
76 /* endp points the last position which is safe in the result buffer. */
77 const char *endp = result + size - 1;
78 char *rp;
79 int length;
80 if (*path == G_DIR_SEPARATOR)
81 {
82 if (strlen (path) >= size)
83 goto erange;
84 strcpy (result, path);
85 goto finish;
86 }
87 else if (*base != G_DIR_SEPARATOR || !size)
88 {
89 errno = EINVAL;
90 return (nullptr);
91 }
92 else if (size == 1)
93 goto erange;
94 if (!strcmp (path, ".") || !strcmp (path, current))
95 {
96 if (strlen (base) >= size)
97 goto erange;
98 strcpy (result, base);
99 /* rp points the last char. */
100 rp = result + strlen (base) - 1;
101 if (*rp == G_DIR_SEPARATOR)
102 *rp = 0;
103 else
104 rp++;
105 /* rp point NULL char */
106 if (*++path == G_DIR_SEPARATOR)
107 {
108 /* Append G_DIR_SEPARATOR to the tail of path name. */
109 *rp++ = G_DIR_SEPARATOR;
110 if (rp > endp)
111 goto erange;
112 *rp = 0;
113 }
114 goto finish;
115 }
116 bp = base + strlen (base);
117 if (*(bp - 1) == G_DIR_SEPARATOR)
118 --bp;
119 /* up to root. */
120 for (pp = path; *pp && *pp == '.';)
121 {
122 if (!strncmp (pp, parent, 3))
123 {
124 pp += 3;
125 while (bp > base && *--bp != G_DIR_SEPARATOR)
126 ;
127 }
128 else if (!strncmp (pp, current, 2))
129 {
130 pp += 2;
131 }
132 else if (!strncmp (pp, "..\0", 3))
133 {
134 pp += 2;
135 while (bp > base && *--bp != G_DIR_SEPARATOR)
136 ;
137 }
138 else
139 break;
140 }
141 /* down to leaf. */
142 length = bp - base;
143 if (length >= static_cast<int>(size))
144 goto erange;
145 strncpy (result, base, length);
146 rp = result + length;
147 if (*pp || (pp > path && *(pp - 1) == G_DIR_SEPARATOR) || length == 0)
148 *rp++ = G_DIR_SEPARATOR;
149 if (rp + strlen (pp) > endp)
150 goto erange;
151 strcpy (rp, pp);
152finish:
153 return result;
154erange:
155 errno = ERANGE;
156 return (nullptr);
157}
158
159char *inkscape_abs2rel(const char *path, const char *base, char *result, const size_t size)
160{
161 const char *pp, *bp, *branch;
162 // endp points the last position which is safe in the result buffer.
163 const char *endp = result + size - 1;
164 char *rp;
165
166 if (*path != G_DIR_SEPARATOR)
167 {
168 if (strlen (path) >= size)
169 goto erange;
170 strcpy (result, path);
171 goto finish;
172 }
173 else if (*base != G_DIR_SEPARATOR || !size)
174 {
175 errno = EINVAL;
176 return (nullptr);
177 }
178 else if (size == 1)
179 goto erange;
180 /* seek to branched point. */
181 branch = path;
182 for (pp = path, bp = base; *pp && *bp && *pp == *bp; pp++, bp++)
183 if (*pp == G_DIR_SEPARATOR)
184 branch = pp;
185 if (((*pp == 0) || ((*pp == G_DIR_SEPARATOR) && (*(pp + 1) == 0))) &&
186 ((*bp == 0) || ((*bp == G_DIR_SEPARATOR) && (*(bp + 1) == 0))))
187 {
188 rp = result;
189 *rp++ = '.';
190 if (*pp == G_DIR_SEPARATOR || *(pp - 1) == G_DIR_SEPARATOR)
191 *rp++ = G_DIR_SEPARATOR;
192 if (rp > endp)
193 goto erange;
194 *rp = 0;
195 goto finish;
196 }
197 if (((*pp == 0) && (*bp == G_DIR_SEPARATOR)) || ((*pp == G_DIR_SEPARATOR) && (*bp == 0)))
198 branch = pp;
199 /* up to root. */
200 rp = result;
201 for (bp = base + (branch - path); *bp; bp++)
202 if (*bp == G_DIR_SEPARATOR && *(bp + 1) != 0)
203 {
204 if (rp + 3 > endp)
205 goto erange;
206 *rp++ = '.';
207 *rp++ = '.';
208 *rp++ = G_DIR_SEPARATOR;
209 }
210 if (rp > endp)
211 goto erange;
212 *rp = 0;
213 /* down to leaf. */
214 if (*branch)
215 {
216 if (rp + strlen (branch + 1) > endp)
217 goto erange;
218 strcpy (rp, branch + 1);
219 }
220 else
221 *--rp = 0;
222finish:
223 return result;
224erange:
225 errno = ERANGE;
226 return (nullptr);
227}
228
229char *prepend_current_dir_if_relative(gchar const *uri)
230{
231 if (!uri) {
232 return nullptr;
233 }
234
235 gchar *full_path = (gchar *) g_malloc (1001);
236 gchar *cwd = g_get_current_dir();
237
238 gsize bytesRead = 0;
239 gsize bytesWritten = 0;
240 GError* error = nullptr;
241 gchar* cwd_utf8 = g_filename_to_utf8 ( cwd,
242 -1,
243 &bytesRead,
244 &bytesWritten,
245 &error);
246
247 inkscape_rel2abs (uri, cwd_utf8, full_path, 1000);
248 gchar *ret = g_strdup (full_path);
249 g_free(cwd_utf8);
250 g_free (full_path);
251 g_free (cwd);
252 return ret;
253}
254
255/*
256 Local Variables:
257 mode:c++
258 c-file-style:"stroustrup"
259 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
260 indent-tabs-mode:nil
261 fill-column:99
262 End:
263*/
264// vi: set autoindent shiftwidth=4 tabstop=8 filetype=cpp expandtab softtabstop=4 fileencoding=utf-8 textwidth=99 :
Css & result
char const * sp_extension_from_path(char const *const path)
Definition dir-util.cpp:51
static char const *const current
Definition dir-util.cpp:71
char * inkscape_rel2abs(const char *path, const char *base, char *result, const size_t size)
Convert a relative path name into absolute.
Definition dir-util.cpp:73
static char const *const parent
Definition dir-util.cpp:70
char * inkscape_abs2rel(const char *path, const char *base, char *result, const size_t size)
Definition dir-util.cpp:159
static char const dots[]
Definition dir-util.cpp:69
std::string sp_relative_path_from_path(std::string const &path, std::string const &base)
Returns a form of path relative to base if that is easy to construct (eg if path appears to be in the...
Definition dir-util.cpp:21
char * prepend_current_dir_if_relative(gchar const *uri)
Definition dir-util.cpp:229
TODO: insert short description here.
int size