/* * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/* Split the names in the given name sequence,
replacing slashes with nulls and filling in the given index array */
staticvoid
splitNames(char *names, char **ix)
{ char *p = names; int i = 0;
while (*p) {
ix[i++] = p++; while (*p) { if (*p == '/') {
*p++ = '\0'; break;
}
p++;
}
}
}
/* Join the names in the given name sequence, ignoring names whose index
entries have been cleared and replacing nulls with slashes as needed */
staticvoid
joinNames(char *names, int nc, char **ix)
{ int i; char *p;
for (i = 0, p = names; i < nc; i++) { if (!ix[i]) continue; if (i > 0) {
p[-1] = '/';
} if (p == ix[i]) {
p += strlen(p) + 1;
} else { char *q = ix[i]; while ((*p++ = *q++));
}
}
*p = '\0';
}
/* Collapse "." and ".." names in the given path wherever possible. A "." name may always be eliminated; a ".." name may be eliminated if it follows a name that is neither "." nor "..". This is a syntactic operation that performs no filesystem queries, so it should only be used to cleanup
after invoking the realpath() procedure. */
void
collapse(char *path)
{ char *names = (path[0] == '/') ? path + 1 : path; /* Preserve first '/' */ int nc; char **ix; int i, j;
nc = collapsible(names); if (nc < 2) return; /* Nothing to do */
ix = (char **)alloca(nc * sizeof(char *));
splitNames(names, ix);
for (i = 0; i < nc; i++) { int dots = 0;
/* Find next occurrence of "." or ".." */ do { char *p = ix[i]; if (p[0] == '.') { if (p[1] == '\0') {
dots = 1; break;
} if ((p[1] == '.') && (p[2] == '\0')) {
dots = 2; break;
}
}
i++;
} while (i < nc); if (i >= nc) break;
/* At this point i is the index of either a "." or a "..", so take the
appropriate action and then continue the outer loop */ if (dots == 1) { /* Remove this instance of "." */
ix[i] = 0;
} else { /* If there is a preceding name, remove both that name and this
instance of ".."; otherwise, leave the ".." as is */ for (j = i - 1; j >= 0; j--) { if (ix[j]) break;
} if (j < 0) continue;
ix[j] = 0;
ix[i] = 0;
} /* i will be incremented at the top of the loop */
}
joinNames(names, nc, ix);
}
¤ Dauer der Verarbeitung: 0.25 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.