Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/unix/drawterm/libc/cleanname.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
 
4
/*
5
 * In place, rewrite name to compress multiple /, eliminate ., and process ..
6
 */
7
#define SEP(x)	((x)=='/' || (x) == 0)
8
char*
9
cleanname(char *name)
10
{
11
	char *p, *q, *dotdot;
12
	int rooted;
13
 
14
	rooted = name[0] == '/';
15
 
16
	/*
17
	 * invariants:
18
	 *	p points at beginning of path element we're considering.
19
	 *	q points just past the last path element we wrote (no slash).
20
	 *	dotdot points just past the point where .. cannot backtrack
21
	 *		any further (no slash).
22
	 */
23
	p = q = dotdot = name+rooted;
24
	while(*p) {
25
		if(p[0] == '/')	/* null element */
26
			p++;
27
		else if(p[0] == '.' && SEP(p[1]))
28
			p += 1;	/* don't count the separator in case it is nul */
29
		else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
30
			p += 2;
31
			if(q > dotdot) {	/* can backtrack */
32
				while(--q > dotdot && *q != '/')
33
					;
34
			} else if(!rooted) {	/* /.. is / but ./../ is .. */
35
				if(q != name)
36
					*q++ = '/';
37
				*q++ = '.';
38
				*q++ = '.';
39
				dotdot = q;
40
			}
41
		} else {	/* real path element */
42
			if(q != name+rooted)
43
				*q++ = '/';
44
			while((*q = *p) != '/' && *q != 0)
45
				p++, q++;
46
		}
47
	}
48
	if(q == name)	/* empty string is really ``.'' */
49
		*q++ = '.';
50
	*q = '\0';
51
	return name;
52
}