shithub: misc

ref: f54501c2592bd7cee283a243391d07f2dd131373
dir: /9legacy/abaco_fix_relative_urls.diff/

View raw version
--- sys/src/cmd/abaco/urls.c	Wed Jul 29 17:23:32 2009
+++ /sys/src/cmd/abaco/urls.c	Fri Jul 16 16:19:54 2021
@@ -127,55 +127,74 @@
 
 void
 urlcanon(Rune *name){
-	Rune *s, *t;
+	Rune *s, *e, *tail, tailr;
 	Rune **comp, **p, **q;
-	int rooted;
+	int n;
+
+	name = runestrstr(name, L"://");
+	if(name == nil)
+		return;
+	name = runestrchr(name+3, '/');
+	if(name == nil)
+		return;
+	if(*name == L'/')
+		name++;
+
+	n = 0;
+	for(e = name; *e != 0; e++)
+		if(*e == L'/')
+			n++;
+	comp = emalloc((n+2)*sizeof *comp);
 
-	name = runestrchr(name, L'/')+2;
-	rooted=name[0]==L'/';
 	/*
 	 * Break the name into a list of components
 	 */
-	comp=emalloc(runestrlen(name)*sizeof(char *));
 	p=comp;
 	*p++=name;
-	for(s=name;;s++){
-		if(*s==L'/'){
-			*p++=s+1;
-			*s='\0';
-		}
-		else if(*s=='\0')
+	tail = nil;
+	tailr = L'☺';   /* silence compiler */
+	for(s = name; *s != 0; s++){
+		 if(*s == '?' || *s == '#'){
+			tail = s+1;
+			tailr = *s;
+			*s = 0;
 			break;
+		}
+		else if(*s == L'/'){
+			*p++ = s+1;
+			*s = 0;
+		}
 	}
-	*p=0;
+
 	/*
 	 * go through the component list, deleting components that are empty (except
-	 * the last component) or ., and any .. and its non-.. predecessor.
+	 * the last component) or ., and any .. and its predecessor.
 	 */
-	p=q=comp;
-	while(*p){
-		if(runestrcmp(*p, L"")==0 && p[1]!=0
-		|| runestrcmp(*p, L".")==0)
-			p++;
-		else if(runestrcmp(*p, L"..")==0 && q!=comp && runestrcmp(q[-1], L"..")!=0){
-			--q;
-			p++;
-		}
+	for(p = q = comp; *p != nil; p++){
+		if(runestrcmp(*p, L"") == 0 && p[1] != nil
+		|| runestrcmp(*p, L".") == 0)
+			continue;
+		else if(q>comp && runestrcmp(*p, L"..") == 0 && runestrcmp(q[-1], L"..") != 0)
+			q--;
 		else
-			*q++=*p++;
+			*q++=*p;
 	}
-	*q=0;
+	*q = nil;
+
 	/*
 	 * rebuild the path name
 	 */
 	s=name;
-	if(rooted) *s++='/';
-	for(p=comp;*p;p++){
-		t=*p;
-		while(*t) *s++=*t++;
-		if(p[1]!=0) *s++='/';
+	for(p = comp; p<q; p++){
+		n = runestrlen(*p);
+		memmove(s, *p, sizeof(Rune)*n);
+		s += n;
+		if(p[1] != nil)
+			*s++ = '/';
 	}
-	*s='\0';
+	*s = 0;
+	if(tail)
+		runeseprint(s, e+1, "%C%S", tailr, tail);
 	free(comp);
 }