Index: /trunk/ChangeLog
===================================================================
--- /trunk/ChangeLog	(revision 600)
+++ /trunk/ChangeLog	(revision 601)
@@ -1,3 +1,9 @@
 /* $Id$ */
+
+2006-11-25:
+    - kmk, kBuild:
+        o Added rmdir as builtin and external command.
+        o Made mkdir not modify the argument strings.
+        o Made mkdir deal properly with DOS slashes on OS/2 and Windows.
 
 2006-11-24:
Index: /trunk/kBuild/header.kmk
===================================================================
--- /trunk/kBuild/header.kmk	(revision 600)
+++ /trunk/kBuild/header.kmk	(revision 601)
@@ -406,4 +406,11 @@
 endif
 
+RMDIR_EXT   := $(PATH_KBUILD_BIN)/kmk_rmdir$(HOSTSUFF_EXE)
+ifeq ($(filter rmdir,$(KMK_BUILTIN)),rmdir)
+RMDIR       := kmk_builtin_rmdir
+else
+RMDIR       := $(RMDIR_EXT)
+endif
+
 SED_EXT     := $(PATH_KBUILD_BIN)/kmk_sed$(HOSTSUFF_EXE)
 ifeq ($(filter sed,$(KMK_BUILTIN)),sed)
Index: /trunk/src/gmake/Makefile.kmk
===================================================================
--- /trunk/src/gmake/Makefile.kmk	(revision 600)
+++ /trunk/src/gmake/Makefile.kmk	(revision 601)
@@ -104,4 +104,5 @@
 	kmkbuiltin/ln.c \
 	kmkbuiltin/rm.c \
+	kmkbuiltin/rmdir.c \
 	\
 	kmkbuiltin/err.c \
@@ -123,5 +124,5 @@
 # Standalone kmkbuiltin commands.
 #
-PROGRAMS += kmk_append kmk_cp kmk_echo kmk_mkdir kmk_install kmk_ln kmk_rm
+PROGRAMS += kmk_append kmk_cp kmk_echo kmk_mkdir kmk_install kmk_ln kmk_rm kmk_rmdir
 
 kmk_append_TEMPLATE = BIN
@@ -218,4 +219,19 @@
 kmk_rm_SOURCES += \
 	kmkbuiltin/mscfakes.c\
+	getopt.c \
+	getopt1.c
+endif
+
+kmk_rmdir_TEMPLATE = BIN
+kmk_rmdir_DEFS = kmk_builtin_rmdir=main
+kmk_rmdir_SOURCES = \
+	kmkbuiltin/rmdir.c \
+	kmkbuiltin/err.c \
+	kmkbuiltin/setmode.c
+ifeq ($(filter-out win32 win64 win nt,$(BUILD_TARGET)),)
+kmk_rmdir_INCS += $(PATH_TARGET) .
+kmk_rmdir_DEFS += HAVE_CONFIG_H
+kmk_rmdir_SOURCES += \
+	kmkbuiltin/mscfakes.c \
 	getopt.c \
 	getopt1.c
Index: /trunk/src/gmake/kmkbuiltin.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin.c	(revision 600)
+++ /trunk/src/gmake/kmkbuiltin.c	(revision 601)
@@ -196,6 +196,6 @@
     else if (!strcmp(pszCmd, "rm"))
         rc = kmk_builtin_rm(argc, argv, environ);
-    //else if (!strcmp(pszCmd, "rmdir"))
-    //    rc = kmk_builtin_rmdir(argc, argv, environ);
+    else if (!strcmp(pszCmd, "rmdir"))
+        rc = kmk_builtin_rmdir(argc, argv, environ);
     /* obsolete */
     else if (!strcmp(pszCmd, "cp"))
Index: /trunk/src/gmake/kmkbuiltin/mkdir.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin/mkdir.c	(revision 600)
+++ /trunk/src/gmake/kmkbuiltin/mkdir.c	(revision 601)
@@ -58,4 +58,5 @@
 #else
 #include "mscfakes.h"
+#include <malloc.h>
 #endif
 
@@ -161,22 +162,34 @@
 	char *p;
 
+	const size_t len = strlen(path);
+	p = alloca(len + 1);
+	path = memcpy(p, path, len + 1);
+
+#if defined(_MSC_VER) || defined(__EMX__)
+	p = strchr(path, '\\');
+	while (p) {
+		*p++ = '/';
+		p = strchr(p, '\\');
+	}
+#endif 
+
 	p = path;
 	oumask = 0;
 	retval = 0;
 #if defined(_MSC_VER) || defined(__EMX__)
-        if (    (    (p[0] >= 'A' && p[0] <= 'Z')
-                 ||  (p[0] >= 'a' && p[0] <= 'z'))
-            && p[1] == ':')
-            p += 2;
-        else if (   (p[0] == '/' || p[0] == '\\')
-                 && (p[1] == '/' || p[1] == '\\')
-                 && (p[2] != '/' && p[2] != '\\'))
-        {
-            char *p2;
-            p += 2;
-            p2 = strpbrk(p, "\\/");
-            if (p2)
-                p = p2 + 1;
-        }
+	if (    (    (p[0] >= 'A' && p[0] <= 'Z')
+	         ||  (p[0] >= 'a' && p[0] <= 'z'))
+	    && p[1] == ':')
+		p += 2;
+	else if (   p[0] == '/'
+	         && p[1] == '/'
+	         && p[2] != '/')
+	{
+		char *p2;
+		p += 2;
+		p2 = strchr(p, '/');
+		if (p2)
+			p = p2 + 1;
+	}
 #endif
 	if (p[0] == '/')		/* Skip leading '/'. */
Index: /trunk/src/gmake/kmkbuiltin/rmdir.c
===================================================================
--- /trunk/src/gmake/kmkbuiltin/rmdir.c	(revision 600)
+++ /trunk/src/gmake/kmkbuiltin/rmdir.c	(revision 601)
@@ -39,15 +39,22 @@
 #endif /* not lint */
 #endif
+#if 0
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/bin/rmdir/rmdir.c,v 1.20 2005/01/26 06:51:28 ssouhlal Exp $");
+#endif
 
-#include <err.h>
+#include "err.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifndef _MSC_VER
 #include <unistd.h>
+#else
+#include <malloc.h>
+#include "mscfakes.h"
+#endif 
 
-static int rm_path(char *);
-static void usage(void);
+static int rm_path(const char *);
+static int usage(void);
 
 static int pflag;
@@ -55,8 +62,22 @@
 
 int
-main(int argc, char *argv[])
+kmk_builtin_rmdir(int argc, char *argv[])
 {
 	int ch, errors;
 
+	/* reinitialize globals */
+	vflag = 0;
+	
+	/* kmk: reset getopt and set progname */
+	g_progname = argv[0];
+	opterr = 1;
+	optarg = NULL;
+	optopt = 0;
+#if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__)
+	optreset = 1;
+	optind = 1;
+#else
+	optind = 0; /* init */
+#endif
 	while ((ch = getopt(argc, argv, "pv")) != -1)
 		switch(ch) {
@@ -69,5 +90,5 @@
 		case '?':
 		default:
-			usage();
+			return usage();
 		}
 	argc -= optind;
@@ -75,5 +96,5 @@
 
 	if (argc == 0)
-		usage();
+		return usage();
 
 	for (errors = 0; *argv; argv++) {
@@ -89,5 +110,5 @@
 	}
 
-	exit(errors);
+	return errors;
 }
 
@@ -96,6 +117,17 @@
 {
 	char *p;
+	const size_t len = strlen(path);
+	p = alloca(len + 1);
+	path = memcpy(p, path, len + 1);
 
-	p = path + strlen(path);
+#if defined(_MSC_VER) || defined(__EMX__)
+	p = strchr(path, '\\');
+	while (p) {
+		*p++ = '/';
+		p = strchr(p, '\\');
+	}
+#endif 
+
+	p = path + len;
 	while (--p > path && *p == '/')
 		;
@@ -108,4 +140,8 @@
 		if (p == path)
 			break;
+#if defined(_MSC_VER) || defined(__EMX__)
+		if (p[-1] == ':' && p - 2 == path)
+			break;
+#endif 
 
 		if (rmdir(path) < 0) {
@@ -120,9 +156,9 @@
 }
 
-static void
+static int
 usage(void)
 {
 
 	(void)fprintf(stderr, "usage: rmdir [-pv] directory ...\n");
-	exit(1);
+	return 1;
 }
Index: /trunk/src/gmake/variable.c
===================================================================
--- /trunk/src/gmake/variable.c	(revision 600)
+++ /trunk/src/gmake/variable.c	(revision 601)
@@ -1062,5 +1062,5 @@
 #ifdef CONFIG_WITH_KMK_BUILTIN
   /* The supported kMk Builtin commands. */
-  (void) define_variable ("KMK_BUILTIN", 11, "append cp echo install ln mkdir rm", o_default, 0);
+  (void) define_variable ("KMK_BUILTIN", 11, "append cp echo install ln mkdir rm rmdir", o_default, 0);
 #endif
 
