summaryrefslogtreecommitdiff
path: root/dmake/path.c
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2007-01-18 08:31:57 +0000
committerVladimir Glazounov <vg@openoffice.org>2007-01-18 08:31:57 +0000
commit9856a85296257ed8c2c924b5ad1a553cd5e3c7d6 (patch)
treed1859f5feaed7479b6e7a5e6e94bdb8080fda759 /dmake/path.c
parentb033f6d86cecb0bd3a9be6f83ee6d6c420e1f1e9 (diff)
INTEGRATION: CWS dmake47 (1.1.1.1.156); FILE MERGED
2006/11/09 22:33:22 vq 1.1.1.1.156.4: #i69821# Fix/improve $(TMD) handling. 2006/10/03 00:46:38 vq 1.1.1.1.156.3: #i69742# Fix problem when removing multiple '/'. 2006/10/01 19:18:27 vq 1.1.1.1.156.2: #i69742# Create Clean_path() function. 2006/10/01 16:23:32 vq 1.1.1.1.156.1: #i69742# Clean up/speed up Build_path().
Diffstat (limited to 'dmake/path.c')
-rw-r--r--dmake/path.c119
1 files changed, 93 insertions, 26 deletions
diff --git a/dmake/path.c b/dmake/path.c
index a4c2f9af7031..d49e40a90fbe 100644
--- a/dmake/path.c
+++ b/dmake/path.c
@@ -1,4 +1,4 @@
-/* RCS $Id: path.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $
+/* RCS $Id: path.c,v 1.2 2007-01-18 09:31:57 vg Exp $
--
-- SYNOPSIS
-- Pathname manipulation code
@@ -87,21 +87,23 @@ char *path;
-/*
-** Take dir and name, and return a path which has dir as the directory
-** and name afterwards.
-**
-** N.B. Assumes that the dir separator string is in DirSepStr.
-** Return path is built in a static buffer, if you need to use it
-** again you must strdup the result returned by Build_path.
-*/
PUBLIC char *
-Build_path(dir, name)
+Build_path(dir, name)/*
+=======================
+ Return a path that is created by concatenating dir and name. A directory
+ separater is added between them if needed. If dir is empty name is stripped
+ of leading slashes (if there) and returned.
+
+ The returned path is also cleaned from unneeded './' and 'foo/../'
+ elements and also multiple consequtive '/' are removed.
+
+ Note, the returned path is built in a static buffer, if it is to be used
+ later strdup should be used on the result returned by Build_path to create
+ a copy. */
+
char *dir;
char *name;
{
- register char *p;
- register char *q;
static char *path = NIL(char);
static unsigned buflen = 0;
int plen = 0;
@@ -110,7 +112,7 @@ char *name;
if( dir != NIL(char) ) dlen = strlen( dir );
if( name != NIL(char) ) plen = strlen( name );
- len = plen+dlen+strlen(DirSepStr)+1;
+ len = plen+dlen+1+1; /* Reserve space for extra path separator. */
if( len > buflen ) {
buflen = (len+16) & ~0xf; /* buf is always multiple of 16 */
@@ -134,28 +136,93 @@ char *name;
strcat( path, name );
}
- q=path;
+ DB_PRINT( "path", ("dir: %s name: %s", dir, name ));
+
+ Clean_path( path );
+
+ return( path );
+}
+
+
+void
+Clean_path(path)/*
+==================
+ Clean the path from irregular directory separators (if more than one are
+ allowed), remove unneeded './' and 'foo/../' elements and also multiple
+ consequtive '/'.
+
+ The resulting string is shorter than the original, therefore this function
+ works on the original string. */
+
+char *path;
+{
+ register char *p;
+ register char *q;
+ char *tpath;
+
+ /* Skip the root part. */
+ tpath=path;
+#ifdef HAVE_DRIVE_LETTERS
+ if( *tpath && tpath[1] == ':' && isalpha(*tpath) )
+ tpath+=2;
+
+ /* Change all occurences from DirBrkStr to *DirSepStr. */
+#if __CYGWIN__
+ for( q = tpath; (q = strchr(q, '\\')) != NIL(char); )
+ *q = *DirSepStr;
+#else
+ for( q = tpath; (q = strchr(q, '/')) != NIL(char); )
+ *q = *DirSepStr;
+#endif
+#endif
+ for( ; *tpath == *DirSepStr ; ++tpath )
+ ;
+ q = tpath;
+
while( *q ) {
char *t;
- p=DmStrPbrk(q,DirBrkStr);
- t=DmStrPbrk(p+1,DirBrkStr);
- if( !*p || !*t ) break;
+ p=strchr(q, *DirSepStr);
+ if( !p ) break;
+
+ /* Remove multiple consequtive DirSepStr. */
+ if( p[1] == *DirSepStr ) {
+ t = p++; /* t points to first, p to second DirStrSep. */
+ /* Move p after the second (or possible more) DirSepStr. */
+ do {
+ p++;
+ }
+ while( *p == *DirSepStr);
+ strcpy(t+1,p);
+ continue;
+ }
+ /* Remove './' */
if ( p-q == 1 && *q == '.' ) {
- strcpy(q,DmStrSpn(p,DirBrkStr));
- q = path;
+ strcpy(q,p+1);
+ q = tpath;
+ continue;
}
- else if (
- !(p-q == 2 && strncmp(q,"..",2) == 0)
- && (t-p-1 == 2 && strncmp(p+1,"..",2) == 0)
- ) {
- strcpy(q,DmStrSpn(t,DirBrkStr));
- q = path;
+
+ /* If two '/' are in path check/remove 'foo/../' elements. */
+ t=strchr(p+1, *DirSepStr);
+ if( !t ) break;
+
+ if ( !(p-q == 2 && strncmp(q,"..",2) == 0)
+ && (t-p-1 == 2 && strncmp(p+1,"..",2) == 0) ) {
+ /* Skip one (or possible more) DirSepStr. */
+ do {
+ t++;
+ }
+ while( *t == *DirSepStr);
+ /* q points to first letter of the current directory/file. */
+ strcpy(q,t);
+ q = tpath;
}
else
q = p+1;
}
- return( path );
+ DB_PRINT( "path", ("path: %s", path ));
+ return;
}