Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/coreutils/src/src/relpath.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* relpath - print the relative path | - | ||||||||||||
2 | Copyright (C) 2012-2018 Free Software Foundation, Inc. | - | ||||||||||||
3 | - | |||||||||||||
4 | This program is free software: you can redistribute it and/or modify | - | ||||||||||||
5 | it under the terms of the GNU General Public License as published by | - | ||||||||||||
6 | the Free Software Foundation, either version 3 of the License, or | - | ||||||||||||
7 | (at your option) any later version. | - | ||||||||||||
8 | - | |||||||||||||
9 | This program is distributed in the hope that it will be useful, | - | ||||||||||||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | ||||||||||||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | ||||||||||||
12 | GNU General Public License for more details. | - | ||||||||||||
13 | - | |||||||||||||
14 | You should have received a copy of the GNU General Public License | - | ||||||||||||
15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | - | ||||||||||||
16 | - | |||||||||||||
17 | /* Written by Pádraig Brady. */ | - | ||||||||||||
18 | - | |||||||||||||
19 | #include <config.h> | - | ||||||||||||
20 | - | |||||||||||||
21 | #include "error.h" | - | ||||||||||||
22 | #include "system.h" | - | ||||||||||||
23 | #include "relpath.h" | - | ||||||||||||
24 | - | |||||||||||||
25 | - | |||||||||||||
26 | /* Return the length of the longest common prefix | - | ||||||||||||
27 | of canonical PATH1 and PATH2, ensuring only full path components | - | ||||||||||||
28 | are matched. Return 0 on no match. */ | - | ||||||||||||
29 | static int _GL_ATTRIBUTE_PURE | - | ||||||||||||
30 | path_common_prefix (const char *path1, const char *path2) | - | ||||||||||||
31 | { | - | ||||||||||||
32 | int i = 0; | - | ||||||||||||
33 | int ret = 0; | - | ||||||||||||
34 | - | |||||||||||||
35 | /* We already know path1[0] and path2[0] are '/'. Special case | - | ||||||||||||
36 | '//', which is only present in a canonical name on platforms | - | ||||||||||||
37 | where it is distinct. */ | - | ||||||||||||
38 | if ((path1[1] == '/') != (path2[1] == '/'))
| 0-26 | ||||||||||||
39 | return 0; never executed: return 0; | 0 | ||||||||||||
40 | - | |||||||||||||
41 | while (*path1 && *path2)
| 2-702 | ||||||||||||
42 | { | - | ||||||||||||
43 | if (*path1 != *path2)
| 3-697 | ||||||||||||
44 | break; executed 3 times by 2 tests: break; Executed by:
| 3 | ||||||||||||
45 | if (*path1 == '/')
| 83-614 | ||||||||||||
46 | ret = i + 1; executed 83 times by 2 tests: ret = i + 1; Executed by:
| 83 | ||||||||||||
47 | path1++; | - | ||||||||||||
48 | path2++; | - | ||||||||||||
49 | i++; | - | ||||||||||||
50 | } executed 697 times by 2 tests: end of block Executed by:
| 697 | ||||||||||||
51 | - | |||||||||||||
52 | if ((!*path1 && !*path2)
| 5-21 | ||||||||||||
53 | || (!*path1 && *path2 == '/')
| 3-11 | ||||||||||||
54 | || (!*path2 && *path1 == '/'))
| 1-11 | ||||||||||||
55 | ret = i; executed 14 times by 2 tests: ret = i; Executed by:
| 14 | ||||||||||||
56 | - | |||||||||||||
57 | return ret; executed 26 times by 2 tests: return ret; Executed by:
| 26 | ||||||||||||
58 | } | - | ||||||||||||
59 | - | |||||||||||||
60 | /* Either output STR to stdout or | - | ||||||||||||
61 | if *PBUF is not NULL then append STR to *PBUF | - | ||||||||||||
62 | and update *PBUF to point to the end of the buffer | - | ||||||||||||
63 | and adjust *PLEN to reflect the remaining space. | - | ||||||||||||
64 | Return TRUE on failure. */ | - | ||||||||||||
65 | static bool | - | ||||||||||||
66 | buffer_or_output (const char* str, char **pbuf, size_t *plen) | - | ||||||||||||
67 | { | - | ||||||||||||
68 | if (*pbuf)
| 8-26 | ||||||||||||
69 | { | - | ||||||||||||
70 | size_t slen = strlen (str); | - | ||||||||||||
71 | if (slen >= *plen)
| 0-8 | ||||||||||||
72 | return true; never executed: return 1 ; | 0 | ||||||||||||
73 | memcpy (*pbuf, str, slen + 1); | - | ||||||||||||
74 | *pbuf += slen; | - | ||||||||||||
75 | *plen -= slen; | - | ||||||||||||
76 | } executed 8 times by 1 test: end of block Executed by:
| 8 | ||||||||||||
77 | else | - | ||||||||||||
78 | { | - | ||||||||||||
79 | fputs (str, stdout); | - | ||||||||||||
80 | } executed 26 times by 1 test: end of block Executed by:
| 26 | ||||||||||||
81 | - | |||||||||||||
82 | return false; executed 34 times by 2 tests: return 0 ; Executed by:
| 34 | ||||||||||||
83 | } | - | ||||||||||||
84 | - | |||||||||||||
85 | /* Output the relative representation if possible. | - | ||||||||||||
86 | If BUF is non-NULL, write to that buffer rather than to stdout. */ | - | ||||||||||||
87 | bool | - | ||||||||||||
88 | relpath (const char *can_fname, const char *can_reldir, char *buf, size_t len) | - | ||||||||||||
89 | { | - | ||||||||||||
90 | bool buf_err = false; | - | ||||||||||||
91 | - | |||||||||||||
92 | /* Skip the prefix common to --relative-to and path. */ | - | ||||||||||||
93 | int common_index = path_common_prefix (can_reldir, can_fname); | - | ||||||||||||
94 | if (!common_index)
| 0-26 | ||||||||||||
95 | return false; never executed: return 0 ; | 0 | ||||||||||||
96 | - | |||||||||||||
97 | const char *relto_suffix = can_reldir + common_index; | - | ||||||||||||
98 | const char *fname_suffix = can_fname + common_index; | - | ||||||||||||
99 | - | |||||||||||||
100 | /* Skip over extraneous '/'. */ | - | ||||||||||||
101 | if (*relto_suffix == '/')
| 1-25 | ||||||||||||
102 | relto_suffix++; executed 1 time by 1 test: relto_suffix++; Executed by:
| 1 | ||||||||||||
103 | if (*fname_suffix == '/')
| 3-23 | ||||||||||||
104 | fname_suffix++; executed 3 times by 2 tests: fname_suffix++; Executed by:
| 3 | ||||||||||||
105 | - | |||||||||||||
106 | /* Replace remaining components of --relative-to with '..', to get | - | ||||||||||||
107 | to a common directory. Then output the remainder of fname. */ | - | ||||||||||||
108 | if (*relto_suffix)
| 6-20 | ||||||||||||
109 | { | - | ||||||||||||
110 | buf_err |= buffer_or_output ("..", &buf, &len); | - | ||||||||||||
111 | for (; *relto_suffix; ++relto_suffix)
| 6-27 | ||||||||||||
112 | { | - | ||||||||||||
113 | if (*relto_suffix == '/')
| 0-27 | ||||||||||||
114 | buf_err |= buffer_or_output ("/..", &buf, &len); never executed: buf_err |= buffer_or_output ("/..", &buf, &len); | 0 | ||||||||||||
115 | } executed 27 times by 2 tests: end of block Executed by:
| 27 | ||||||||||||
116 | - | |||||||||||||
117 | if (*fname_suffix)
| 2-4 | ||||||||||||
118 | { | - | ||||||||||||
119 | buf_err |= buffer_or_output ("/", &buf, &len); | - | ||||||||||||
120 | buf_err |= buffer_or_output (fname_suffix, &buf, &len); | - | ||||||||||||
121 | } executed 4 times by 2 tests: end of block Executed by:
| 4 | ||||||||||||
122 | } executed 6 times by 2 tests: end of block Executed by:
| 6 | ||||||||||||
123 | else | - | ||||||||||||
124 | { | - | ||||||||||||
125 | buf_err |= buffer_or_output (*fname_suffix ? fname_suffix : ".", | - | ||||||||||||
126 | &buf, &len); | - | ||||||||||||
127 | } executed 20 times by 2 tests: end of block Executed by:
| 20 | ||||||||||||
128 | - | |||||||||||||
129 | if (buf_err)
| 0-26 | ||||||||||||
130 | error (0, ENAMETOOLONG, "%s", _("generating relative path")); never executed: error (0, 36 , "%s", dcgettext (((void *)0), "generating relative path" , 5) ); | 0 | ||||||||||||
131 | - | |||||||||||||
132 | return !buf_err; executed 26 times by 2 tests: return !buf_err; Executed by:
| 26 | ||||||||||||
133 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |