| 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 blockExecuted 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 blockExecuted by:
| 8 | ||||||||||||
| 77 | else | - | ||||||||||||
| 78 | { | - | ||||||||||||
| 79 | fputs (str, stdout); | - | ||||||||||||
| 80 | } executed 26 times by 1 test: end of blockExecuted 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 blockExecuted 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 blockExecuted by:
| 4 | ||||||||||||
| 122 | } executed 6 times by 2 tests: end of blockExecuted 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 blockExecuted 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 |