| 1119 | } |
| 1120 | |
| 1121 | int normalize_path_copy_len(char *dst, const char *src, int *prefix_len) |
| 1122 | { |
| 1123 | char *dst0; |
| 1124 | const char *end; |
| 1125 | |
| 1126 | /* |
| 1127 | * Copy initial part of absolute path: "/", "C:/", "//server/share/". |
| 1128 | */ |
| 1129 | end = src + offset_1st_component(src); |
| 1130 | while (src < end) { |
| 1131 | char c = *src++; |
| 1132 | if (is_dir_sep(c)) |
| 1133 | c = '/'; |
| 1134 | *dst++ = c; |
| 1135 | } |
| 1136 | dst0 = dst; |
| 1137 | |
| 1138 | src = skip_slashes(src); |
| 1139 | |
| 1140 | for (;;) { |
| 1141 | char c = *src; |
| 1142 | |
| 1143 | /* |
| 1144 | * A path component that begins with . could be |
| 1145 | * special: |
| 1146 | * (1) "." and ends -- ignore and terminate. |
| 1147 | * (2) "./" -- ignore them, eat slash and continue. |
| 1148 | * (3) ".." and ends -- strip one and terminate. |
| 1149 | * (4) "../" -- strip one, eat slash and continue. |
| 1150 | */ |
| 1151 | if (c == '.') { |
| 1152 | if (!src[1]) { |
| 1153 | /* (1) */ |
| 1154 | src++; |
| 1155 | } else if (is_dir_sep(src[1])) { |
| 1156 | /* (2) */ |
| 1157 | src += 2; |
| 1158 | src = skip_slashes(src); |
| 1159 | continue; |
| 1160 | } else if (src[1] == '.') { |
| 1161 | if (!src[2]) { |
| 1162 | /* (3) */ |
| 1163 | src += 2; |
| 1164 | goto up_one; |
| 1165 | } else if (is_dir_sep(src[2])) { |
| 1166 | /* (4) */ |
| 1167 | src += 3; |
| 1168 | src = skip_slashes(src); |
| 1169 | goto up_one; |
| 1170 | } |
| 1171 | } |
| 1172 | } |
| 1173 | |
| 1174 | /* copy up to the next '/', and eat all '/' */ |
| 1175 | while ((c = *src++) != '\0' && !is_dir_sep(c)) |
| 1176 | *dst++ = c; |
| 1177 | if (is_dir_sep(c)) { |
| 1178 | *dst++ = '/'; |
no test coverage detected