From 6ddde92a3a45e970b05770633dc6a337d5d013c5 Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor@ghostscript.com>
Date: Mon, 27 Sep 2004 02:15:04 +0200
Subject: Initial import

---
 util/cleanname.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 util/cleanname.c

(limited to 'util/cleanname.c')

diff --git a/util/cleanname.c b/util/cleanname.c
new file mode 100644
index 00000000..e8a8ed86
--- /dev/null
+++ b/util/cleanname.c
@@ -0,0 +1,63 @@
+/*
+ * In place, rewrite name to compress multiple /, eliminate ., and process ..
+ */
+
+#define SEP(x)	((x)=='/' || (x) == 0)
+
+char *
+cleanname(char *name)
+{
+	char *p, *q, *dotdot;
+	int rooted;
+
+	rooted = name[0] == '/';
+
+	/*
+	 * invariants:
+	 *	p points at beginning of path element we're considering.
+	 *	q points just past the last path element we wrote (no slash).
+	 *	dotdot points just past the point where .. cannot backtrack
+	 *		any further (no slash).
+	 */
+
+	p = q = dotdot = name + rooted;
+
+	while (*p)
+	{
+		if (p[0] == '/')	/* null element */
+			p++;
+
+		else if (p[0] == '.' && SEP(p[1]))
+			p += 1;	/* don't count the separator in case it is nul */
+
+		else if (p[0] == '.' && p[1] == '.' && SEP(p[2]))
+		{
+			p += 2;
+			if (q > dotdot) {	/* can backtrack */
+				while (--q > dotdot && *q != '/')
+					;
+			} else if (!rooted) {	/* /.. is / but ./../ is .. */
+				if (q != name)
+					*q++ = '/';
+				*q++ = '.';
+				*q++ = '.';
+				dotdot = q;
+			}
+		}
+
+		else {	/* real path element */
+			if (q != name + rooted)
+				*q++ = '/';
+			while ((*q = *p) != '/' && *q != 0)
+				p++, q++;
+		}
+	}
+
+	if (q == name)	/* empty string is really ``.'' */
+		*q++ = '.';
+
+	*q = '\0';
+
+	return name;
+}
+
-- 
cgit v1.2.3