[fyba] 19/77: New, fully free FULLPATH.cpp
Ruben Undheim
rubund-guest at moszumanska.debian.org
Mon Sep 22 15:11:24 UTC 2014
This is an automated email from the git hooks/post-receive script.
rubund-guest pushed a commit to branch master
in repository fyba.
commit 7417e292a72bda66a9ca3689536d24a2b14323ff
Author: Anders Einar Hilden <hildenae at gmail.com>
Date: Sat Oct 19 17:42:00 2013 +0200
New, fully free FULLPATH.cpp
---
src/UT/FULLPATH.cpp | 230 ++++++++++++++++++++++++++--------------------------
1 file changed, 113 insertions(+), 117 deletions(-)
diff --git a/src/UT/FULLPATH.cpp b/src/UT/FULLPATH.cpp
index cd56ec9..679bcf3 100644
--- a/src/UT/FULLPATH.cpp
+++ b/src/UT/FULLPATH.cpp
@@ -8,6 +8,7 @@
#ifdef LINUX
# include <unistd.h>
+# include <new>
#endif
#ifdef UNIX
@@ -36,127 +37,122 @@
#define wchar_t char
#define wcschr strchr
-///////////////////////////////////////////////////////////////////////////////////////
-// FULLPATH.cpp
+/*
+CH _fullpath
+CD ==============================================================
+CD Makes a complete path from a non-complete path. Handles "..",
+CD "." and will prepend the path with current working directory
+CD if it is relative (does not start with slash)
+CD
+CD The function returns buffer, pointer to memory area containing
+CD full path if buffer was NULL, or NULL if a error occured
+CD (e.g. full path was longer than maxlen and a buffer
+CD was supplied.) The pointer should be free'd by calling code.
+CD
+CD Parameters:
+CD Type Name I/O Explanation
+CD -------------------------------------------------------------
+CD char *buffer i/o Buffer to put full path into or NULL.
+CD const char *pathname i Pathname to expand
+CD size_t maxlen i Size of buffer.
+CD char * r buffer, pointer to char[] or NULL
+CD ==============================================================
+*/
+char * _fullpath(char *buffer, const char *pathname, size_t maxlen) {
+ if(maxlen < _MAX_PATH) {
+ return NULL;
+ }
+ char * wpath;
+ wpath = new (std::nothrow) char[_MAX_PATH];
+ if (wpath == NULL) { // could not allocate memory
+ return NULL;
+ }
+
+ char * wpath2;
+ wpath2 = new (std::nothrow) char[_MAX_PATH];
+ if (wpath2 == NULL) {
+ delete [] wpath;
+ return NULL;
+ }
-///////////////////////////////////////////////////////////////////////////////////////
-// ErSlash()
-int ErSlash (int chr)
-{
- return (chr == '\\' || chr == '/');
-}
+ strncpy(wpath, pathname, _MAX_PATH);
+ strncpy(wpath2, pathname, _MAX_PATH);
-///////////////////////////////////////////////////////////////////////////////////////
-// FullPath()
-wchar_t * FullPath(wchar_t *Buffer,
- const wchar_t *PathName,
- size_t nMaxlen
- )
-{
- wchar_t *TempBuf;
- wchar_t *dst, *src;
- int c, Drive;
- size_t nLen;
-
-
- /* Allocate a temporary buffer to hold the fully qualified path.
- */
- if ((TempBuf = (wchar_t*)malloc(_MAX_PATH*2+1)) == NULL)
- return (NULL);
-
-
- Drive = 7;
- src = (wchar_t *)PathName;
-
-
- /* If supplied path is relative, append it to the drivename
- * and its current directory. Otherwise append it to the
- * drivename only.
- */
- if (!ErSlash(src[0])) { /* path is relative? */
- /* Get drivename and its current directory.
- */
- if (getcwd(TempBuf,_MAX_PATH*2+1) == NULL) {
- free(TempBuf);
- return (NULL);
- }
- dst = &TempBuf[strlen(TempBuf)];
- if (!ErSlash(*(dst-1))) /* if directory doesn't end in slash */
- *dst++ = UT_SLASH; /* append one */
-
- } else {
- /* Path is absolute. Store the drivename only.*/
- dst = TempBuf;
- }
- strcpy(dst,src); /* concatenate supplied path */
-
- /* Scan the path, squeezing out "../" and "./", and
- * squeezing out the previous directory when "../" is found.
- */
- src = dst = TempBuf;
-
- for (;;) {
- /* If this the end of the path, or end of a directory,
- * we must check for "." or ".."
- */
- if ((c = *src++) == '\0' || ErSlash(c)) {
- /* If last directory copied was "/.", back up over it.
- * Skip test if we are still at the beginning of TempBuf.
- */
- if (src != (TempBuf+1)) {
- if (*(dst-1) == '.' && ErSlash(*(dst-2))) {
- dst -= 2;
-
- /* If last directory copied was "/..", back up over it
- * AND the previous directory.
- */
- } else if (*(dst-1) == '.' && *(dst-2) == '.' && ErSlash(*(dst-3))) {
- dst -= 3; /* back up over "/.." */
- if (*(dst-1) == ':') { /* can't back up over drivename */
- free(TempBuf);
- return(NULL);
- }
- while (!ErSlash(*--dst))
- ; /* back up to start of prev. dir. */
- }
-
- if (c == '\0') { /* end of path? */
- if (ErSlash(*(dst-1))) /* if last wchar_t is slash */
- dst--; /* back up over it */
- if (*(dst-1) == ':') /* if path is just a drivename */
- *dst++ = '/'; /* append a slash */
- *dst = '\0'; /* append null terminator */
- break;
-
- } else {
- *dst++ = c; /* copy the slash */
- }
- }
-
- } else {
- *dst++ = c; /* copy the character */
- }
+ /* Make relativer paths of ./foo-paths */
+ if(pathname[0] == '.' && pathname[1] == UT_SLASH) {
+ strncpy(wpath, pathname+2, _MAX_PATH);
+ strncpy(wpath, pathname+2, _MAX_PATH);
+ }
+
+ char * prevPos = NULL;
+
+ char same[4] = { UT_SLASH, '.', UT_SLASH, '\0' }; // e.g. "/./"
+ /* replace /./ with nothing */
+ while ((prevPos = strstr(wpath, same)) != NULL) {
+ prevPos[1] = '\0';
+ UT_StrCopy(wpath2, wpath, _MAX_PATH);
+ strncat(wpath2, (prevPos+strlen(same)), _MAX_PATH);
+ UT_StrCopy(wpath, wpath2, _MAX_PATH);
}
+ char prev[5] = { UT_SLASH, '.', '.', UT_SLASH, '\0' }; // e.g "/../"
+
+ int i = -1;
+ /* Remove /../ and parent folder */
+ while ((prevPos = strstr(wpath, prev)) != NULL) {
+ /* Walk forward in the string until first slash or start of string */
+ while((prevPos + i) >= wpath && prevPos[i] != UT_SLASH) {
+ prevPos[i--] = '\0';
+ }
+ UT_StrCopy(wpath2, wpath, _MAX_PATH);
+ strncat(wpath2, (prevPos+strlen(prev)), _MAX_PATH);
+ UT_StrCopy(wpath, wpath2, _MAX_PATH);
+ i = -1;
+ }
+
+ /* prepend cwd on relative paths */
+ if(wpath[0] != UT_SLASH) {
+ if(getcwd(wpath2, _MAX_PATH) == NULL) {
+ delete [] wpath;
+ delete [] wpath2;
+ return NULL;
+ }
+ /* getcwd gives ut the path w/o ending slash */
+ strncat(wpath2, UT_STR_SLASH, _MAX_PATH-(strlen(wpath2)+1));
+ strncat(wpath2, wpath, _MAX_PATH)-(strlen(wpath2)+1);
+ UT_StrCopy(wpath, wpath2, _MAX_PATH);
+ }
- /* Copy the temp buffer to the user's buffer, if present.
- * Otherwise shrink the temp buffer and return a pointer to it.
- */
- nLen = strlen(TempBuf) + 1; /* length of path and null */
- if (Buffer != NULL) {
- if (nLen > nMaxlen) { /* user buffer too small? */
- free(TempBuf);
- return (NULL);
-
- } else {
- strcpy(Buffer,TempBuf);
- free(TempBuf);
- return (Buffer);
- }
-
- } else {
- return (wchar_t*)(realloc(TempBuf,nLen)); /* shrink the buffer */
- }
+ int endLen = strlen(wpath);
+ int startAt = 0;
+ if(wpath[0] == UT_SLASH) {
+ endLen--;
+ startAt = 1;
+ }
+ if(wpath[endLen] == UT_SLASH) {
+ wpath[endLen] = '\0';
+ endLen--;
+ }
+ delete [] wpath2;
+ if (endLen < maxlen && buffer != NULL) { /* we have a buffer, and we have room in buffer */
+ UT_StrCopy(buffer, (wpath+startAt), maxlen);
+ delete [] wpath;
+ return buffer;
+ } else if (buffer == NULL) { /* we have no buffer */
+ char * tempbuf;
+ if ((tempbuf = (char*)UT_MALLOC(endLen+1)) != NULL) {
+ UT_StrCopy(tempbuf, (wpath+startAt), (endLen+1));
+ delete [] wpath;
+ return tempbuf;
+ } else { /* failed to alloc memory*/
+ delete [] wpath;
+ return NULL;
+ }
+ } else { /* not room in buffer and we were supposed to use the buffer */
+ delete [] wpath;
+ return NULL;
+ }
}
+
#endif
@@ -225,7 +221,7 @@ SK_EntPnt_UT short UT_FullPath(wchar_t *pszBuffer, const wchar_t *pszPath, size
/* Hent filopplysninger */
#ifdef UNIX
- return (short)(FullPath(pszBuffer,szFilnavn,maxlen) != NULL)? 0 : 1;
+ return (short)(_fullpath(pszBuffer,szFilnavn,maxlen) != NULL)? 0 : 1;
#endif
#ifdef OS232
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/fyba.git
More information about the Pkg-grass-devel
mailing list