ref: bb85d99a02ba60bebcd8509fb1bfec8476ef0047
dir: /9legacy/abaco_fix_relative_urls.diff/
--- 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); }