aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Marshall <keithmarshall@@users.sf.net>2006-12-31 18:03:33 +0000
committerKeith Marshall <keithmarshall@@users.sf.net>2006-12-31 18:03:33 +0000
commit724dbeea36fd72b07123431c3c2c3fd1c059c5ec (patch)
tree6bad59ec3669c3ba121002fbe4897cd049c9d160
parent75ea5758cdc6e9d86a2c9005b8117d24cceeb8c7 (diff)
downloadnewlib-724dbeea36fd72b07123431c3c2c3fd1c059c5ec.zip
newlib-724dbeea36fd72b07123431c3c2c3fd1c059c5ec.tar.gz
newlib-724dbeea36fd72b07123431c3c2c3fd1c059c5ec.tar.bz2
* include/libgen.h: New file; required by...
* mingwex/basename.c, mingwex/dirname.c: New files. * mingwex/Makefile.in (DISTFILES): Add them... (POSIX_OBJS): ...with corresponding basename.o, dirname.o (Dependencies): Typo; s/Dependancies/Dependencies/
-rw-r--r--winsup/mingw/ChangeLog8
-rwxr-xr-xwinsup/mingw/include/libgen.h31
-rw-r--r--winsup/mingw/mingwex/Makefile.in8
-rwxr-xr-xwinsup/mingw/mingwex/basename.c103
-rwxr-xr-xwinsup/mingw/mingwex/dirname.c174
5 files changed, 321 insertions, 3 deletions
diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog
index 0b5685b..4d5c0e0 100644
--- a/winsup/mingw/ChangeLog
+++ b/winsup/mingw/ChangeLog
@@ -1,3 +1,11 @@
+2006-12-31 Keith Marshall <keithmarshall@users.sourceforge.net>
+
+ * include/libgen.h: New file; required by...
+ * mingwex/basename.c, mingwex/dirname.c: New files.
+ * mingwex/Makefile.in (DISTFILES): Add them...
+ (POSIX_OBJS): ...with corresponding basename.o, dirname.o
+ (Dependencies): Typo; s/Dependancies/Dependencies/
+
2006-11-25 Keith Marshall <keithmarshall@users.sourceforge.net>
* Makefile.in (VERSION): Let configure define it.
diff --git a/winsup/mingw/include/libgen.h b/winsup/mingw/include/libgen.h
new file mode 100755
index 0000000..cf4793b
--- /dev/null
+++ b/winsup/mingw/include/libgen.h
@@ -0,0 +1,31 @@
+#ifndef _LIBGEN_H_
+/*
+ * libgen.h
+ *
+ * $Id$
+ *
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Functions for splitting pathnames into dirname and basename components.
+ *
+ */
+#define _LIBGEN_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern __cdecl char *basename (char *);
+extern __cdecl char *dirname (char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBGEN_H_: end of file */
+
diff --git a/winsup/mingw/mingwex/Makefile.in b/winsup/mingw/mingwex/Makefile.in
index 8775c32..a8e007d 100644
--- a/winsup/mingw/mingwex/Makefile.in
+++ b/winsup/mingw/mingwex/Makefile.in
@@ -36,7 +36,8 @@ DISTFILES = Makefile.in configure configure.in aclocal.m4 \
wcstoimax.c wcstold.c wcstoumax.c wctrans.c wctype.c \
wdirent.c wmemchr.c wmemcmp.c wmemcpy.c wmemmove.c wmemset.c wtoll.c \
wcrtomb.c wctob.c mbrtowc.c btowc.c mb_wc_common.h \
- gettimeofday.c isblank.c iswblank.c
+ gettimeofday.c isblank.c iswblank.c \
+ basename.c dirname.c
MATH_DISTFILES = \
acosf.c acosl.c asinf.c asinl.c atan2f.c atan2l.c \
@@ -172,7 +173,8 @@ FENV_OBJS = fesetround.o fegetround.o \
feclearexcept.o feholdexcept.o fegetexceptflag.o \
feraiseexcept.o fetestexcept.o fesetexceptflag.o
POSIX_OBJS = \
- dirent.o wdirent.o getopt.o ftruncate.o gettimeofday.o
+ dirent.o wdirent.o getopt.o ftruncate.o gettimeofday.o \
+ basename.o dirname.o
REPLACE_OBJS = \
mingw-aligned-malloc.o mingw-fseek.o
COMPLEX_OBJS = \
@@ -238,7 +240,7 @@ distclean:
#
-# Dependancies
+# Dependencies
#
wdirent.o: $(srcdir)/dirent.c $(srcdir)/wdirent.c
diff --git a/winsup/mingw/mingwex/basename.c b/winsup/mingw/mingwex/basename.c
new file mode 100755
index 0000000..768b9a0
--- /dev/null
+++ b/winsup/mingw/mingwex/basename.c
@@ -0,0 +1,103 @@
+/* basename.c
+ *
+ * $Id$
+ *
+ * Provides an implementation of the "basename" function, conforming
+ * to SUSv3, with extensions to accommodate Win32 drive designators,
+ * and suitable for use on native Microsoft(R) Win32 platforms.
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ *
+ * This is free software. You may redistribute and/or modify it as you
+ * see fit, without restriction of copyright.
+ *
+ * This software is provided "as is", in the hope that it may be useful,
+ * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
+ * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
+ * time will the author accept any form of liability for any damages,
+ * however caused, resulting from the use of this software.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <libgen.h>
+
+#ifndef __cdecl /* If compiling on any non-Win32 platform ... */
+#define __cdecl /* this may not be defined. */
+#endif
+
+__cdecl char *basename( char *path )
+{
+ char *retname;
+ static char retfail[] = ".";
+
+ if( path && *path )
+ {
+ /* step over the drive designator, if present ...
+ * (FIXME: maybe should confirm *path is a valid drive designator).
+ */
+
+ if( path[1] == ':' )
+ path += 2;
+
+ /* check again, just to ensure we still have a non-empty path name ... */
+
+ if( *path )
+ {
+ /* and, when we do ...
+ * scan from left to right, to the char after the final dir separator
+ */
+
+ for( retname = path ; *path ; ++path )
+ {
+ if( (*path == '/') || (*path == '\\') )
+ {
+ /* we found a dir separator ...
+ * step over it, and any others which immediately follow it
+ */
+
+ while( (*path == '/') || (*path == '\\') )
+ ++path;
+
+ /* if we didn't reach the end of the path string ... */
+
+ if( *path )
+
+ /* then we have a new candidate for the base name */
+
+ retname = path;
+
+ /* otherwise ...
+ * strip off any trailing dir separators which we found
+ */
+
+ else while( (path > retname) && ((*--path == '/') || (*path == '\\')) )
+ *path = '\0';
+ }
+ }
+
+ /* retname now points at the resolved base name ...
+ * if it's not empty, then we return it as it is, otherwise ...
+ * we must have had only dir separators in the original path name,
+ * so we return "/".
+ */
+
+ return *retname ? retname : strcpy( retfail, "/" );
+ }
+
+ /* or we had an empty residual path name, after the drive designator,
+ * in which case we simply fall through ...
+ */
+ }
+
+ /* and, if we get to here ...
+ * the path name is either NULL, or it decomposes to an empty string;
+ * in either case, we return the default value of "." in our static buffer,
+ * (but strcpy it, just in case the caller trashed it after a previous call).
+ */
+
+ return strcpy( retfail, "." );
+}
+
+/* $RCSfile$: end of file */
diff --git a/winsup/mingw/mingwex/dirname.c b/winsup/mingw/mingwex/dirname.c
new file mode 100755
index 0000000..44256b1
--- /dev/null
+++ b/winsup/mingw/mingwex/dirname.c
@@ -0,0 +1,174 @@
+/* dirname.c
+ *
+ * $Id$
+ *
+ * Provides an implementation of the "dirname" function, conforming
+ * to SUSv3, with extensions to accommodate Win32 drive designators,
+ * and suitable for use on native Microsoft(R) Win32 platforms.
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ *
+ * This is free software. You may redistribute and/or modify it as you
+ * see fit, without restriction of copyright.
+ *
+ * This software is provided "as is", in the hope that it may be useful,
+ * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
+ * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
+ * time will the author accept any form of liability for any damages,
+ * however caused, resulting from the use of this software.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <libgen.h>
+
+#ifndef __cdecl /* If compiling on any non-Win32 platform ... */
+#define __cdecl /* this may not be defined. */
+#endif
+
+__cdecl char *dirname( char *path )
+{
+ static char retfail[] = "?:.";
+ char *retname, *basename, *copyptr = retfail;
+
+ if( path && *path )
+ {
+ retname = path;
+
+ /* SUSv3 identifies a special case, where path is exactly equal to "//";
+ * (we will also accept "\\" in the Win32 context, but not "/\" or "\/",
+ * and neither will we consider paths with an initial drive designator).
+ * For this special case, SUSv3 allows the implementation to choose to
+ * return "/" or "//", (or "\" or "\\", since this is Win32); we will
+ * simply return the path unchanged, (i.e. "//" or "\\").
+ */
+
+ if( (*path == '/') || (*path == '\\') )
+ {
+ if( (path[1] == *retname) && (path[2] == '\0') )
+ return retname;
+ }
+
+ /* For all other cases ...
+ * step over the drive designator, if present, copying it to retfail ...
+ * (FIXME: maybe should confirm *path is a valid drive designator).
+ */
+
+ else if( *path && (path[1] == ':') )
+ {
+ *copyptr++ = *path++;
+ *copyptr++ = *path++;
+ }
+
+ if( *path )
+ {
+ /* reproduce the scanning logic of the "basename" function
+ * to locate the basename component of the current path string,
+ * (but also remember where the dirname component starts).
+ */
+
+ for( retname = basename = path ; *path ; ++path )
+ {
+ if( (*path == '/') || (*path == '\\') )
+ {
+ /* we found a dir separator ...
+ * step over it, and any others which immediately follow it
+ */
+
+ while( (*path == '/') || (*path == '\\') )
+ ++path;
+
+ /* if we didn't reach the end of the path string ... */
+
+ if( *path )
+
+ /* then we have a new candidate for the base name */
+
+ basename = path;
+
+ else
+
+ /* we struck an early termination of the path string,
+ * with trailing dir separators following the base name,
+ * so break out of the for loop, to avoid overrun.
+ */
+
+ break;
+ }
+ }
+
+ /* now check,
+ * to confirm that we have distinct dirname and basename components
+ */
+
+ if( basename > retname )
+ {
+ /* and, when we do ...
+ * backtrack over all trailing separators on the dirname component,
+ * (but preserve exactly two initial dirname separators, if identical),
+ * and add a NULL terminator in their place.
+ */
+
+ --basename;
+ while( (basename > retname) && ((*basename == '/') || (*basename == '\\')) )
+ --basename;
+ if( (basename == retname) && ((*retname == '/') || (*retname == '\\'))
+ && (retname[1] == *retname) && (retname[2] != '/') && (retname[2] != '\\') )
+ ++basename;
+ *++basename = '\0';
+
+ /* adjust the start point of the dirname,
+ * to accommodate the Win32 drive designator, if it was present.
+ */
+
+ if( copyptr > retfail )
+ retname -= 2;
+
+ /* if the resultant dirname begins with EXACTLY two dir separators,
+ * AND both are identical, then we preserve them.
+ */
+
+ path = copyptr = retname;
+ while( ((*path == '/') || (*path == '\\')) )
+ ++path;
+ if( ((path - retname) == 2) && (*++copyptr == *retname) )
+ ++copyptr;
+
+ /* and finally ...
+ * we remove any residual, redundantly duplicated separators from the dirname,
+ * reterminate, and return it.
+ */
+
+ path = copyptr;
+ while( *path )
+ {
+ if( ((*copyptr++ = *path) == '/') || (*path++ == '\\') )
+ {
+ while( (*path == '/') || (*path == '\\') )
+ ++path;
+ }
+ }
+ *copyptr = '\0';
+ return retname;
+ }
+
+ else if( (*retname == '/') || (*retname == '\\') )
+ {
+ *copyptr++ = *retname;
+ *copyptr = '\0';
+ return retfail;
+ }
+ }
+ }
+
+ /* path is NULL, or an empty string; default return value is "." ...
+ * return this in our own static buffer, but strcpy it, just in case
+ * the caller trashed it after a previous call.
+ */
+
+ strcpy( copyptr, "." );
+ return retfail;
+}
+
+/* $RCSfile$: end of file */