void urlcanon(Rune *name){ Rune *s, *t; Rune **comp, **p, **q; int rooted; 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') break; } *p=0; /* * go through the component list, deleting components that are empty (except * the last component) or ., and any .. and its non-.. 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++; } else *q++=*p++; } *q=0; /* * 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++='/'; } *s='\0'; free(comp); }
void renraw(Rune *from, Rune *to) { int i; delraw(to); for(i=0; i<nraw; i++) if(runestrcmp(raw[i].name, from) == 0){ free(raw[i].name); raw[i].name = erunestrdup(to); return; } }
/* define macro - .de, .am, .ig */ void r_de(int argc, Rune **argv) { Rune *end, *p; Fmt fmt; int ignore, len; delreq(argv[1]); delraw(argv[1]); ignore = runestrcmp(argv[0], L("ig")) == 0; if(!ignore) runefmtstrinit(&fmt); end = L(".."); if(argc >= 3) end = argv[2]; if(runestrcmp(argv[0], L("am")) == 0 && (p=getds(argv[1])) != nil) fmtrunestrcpy(&fmt, p); len = runestrlen(end); while((p = readline(CopyMode)) != nil){ if(runestrncmp(p, end, len) == 0 && (p[len]==' ' || p[len]==0 || p[len]=='\t' || (p[len]=='\\' && p[len+1]=='}'))){ free(p); goto done; } if(!ignore) fmtprint(&fmt, "%S\n", p); free(p); } warn("eof in %C%S %S - looking for %#Q", dot, argv[0], argv[1], end); done: if(ignore) return; p = runefmtstrflush(&fmt); if(p == nil) sysfatal("out of memory"); ds(argv[1], p); free(p); }
static Cimage * findimg(Rune *s) { Cimage *ci; qlock(&cimagelock); for(ci=cimages; ci!=nil; ci=ci->next) if(runestrcmp(ci->url->src.r, s) == 0) break; qunlock(&cimagelock); return ci; }
void delraw(Rune *name) { int i; for(i=0; i<nraw; i++){ if(runestrcmp(raw[i].name, name) == 0){ if(i != --nraw){ free(raw[i].name); raw[i] = raw[nraw]; } return; } } }
void delreq(Rune *name) { int i; for(i=0; i<nreq; i++){ if(runestrcmp(req[i].name, name) == 0){ if(i != --nreq){ free(req[i].name); req[i] = req[nreq]; } return; } } }
void r_pm(int argc, Rune **argv) { int i; if(argc == 1){ printds(0); return; } if(runestrcmp(argv[1], L("t")) == 0){ printds(1); return; } for(i=1; i<argc; i++) fprint(2, "%S: %S\n", argv[i], getds(argv[i])); }
void r_if(Rune *name) { int n; n = ifeval(); if(runestrcmp(name, L("ie")) == 0){ if(niftrue >= nelem(iftrue)) sysfatal("%Cie overflow", dot); iftrue[niftrue++] = n; } if(n) startbody(); else skipbody(); }
void r_ch(int argc, Rune **argv) { int i; if(argc == 2){ if(trap0 && runestrcmp(argv[1], trap0) == 0){ free(trap0); trap0 = nil; }else if(verbose) warn("not removing %S trap", argv[1]); return; } if(argc >= 3){ i = eval(argv[2]); if(i == 0){ free(trap0); trap0 = erunestrdup(argv[1]); }else if(verbose) warn("not moving %S trap to %d", argv[1], i); } }
/* * Process a dot line. The dot has been read. */ void dotline(int dot) { int argc, i; Rune *a, *argv[1+MAXARG]; /* * Read request/macro name */ a = copyarg(); if(a == nil || a[0] == 0){ free(a); getrune(); /* \n */ return; } argv[0] = a; /* * Check for .if, .ie, and others with special parsing. */ for(i=0; i<nraw; i++){ if(runestrcmp(raw[i].name, a) == 0){ raw[i].f(raw[i].name); free(a); return; } } /* * Read rest of line in copy mode, invoke regular request. */ a = readline(ArgMode); if(a == nil){ free(argv[0]); return; } argc = 1+parseargs(a, argv+1); for(i=0; i<nreq; i++){ if(runestrcmp(req[i].name, argv[0]) == 0){ if(req[i].argc != -1){ if(argc < 1+req[i].argc){ warn("not enough arguments for %C%S", dot, req[i].name); free(argv[0]); free(a); return; } if(argc > 1+req[i].argc) warn("too many arguments for %C%S", dot, req[i].name); } req[i].f(argc, argv); free(argv[0]); free(a); return; } } /* * Invoke user-defined macros. */ runmacro(dot, argc, argv); free(argv[0]); free(a); }
void urlcanon(Rune *name) { Rune *s, *e, *tail, tailr; Rune **comp, **p, **q; 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); /* * Break the name into a list of components */ p = comp; *p++ = name; 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; } } /* * go through the component list, deleting components that are empty (except * the last component) or ., and any .. and its predecessor. */ 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 = nil; /* * rebuild the path name */ s = name; for(p = comp; p<q; p++){ n = runestrlen(*p); memmove(s, *p, sizeof(Rune)*n); s += n; if(p[1] != nil) *s++ = '/'; } *s = 0; if(tail) runeseprint(s, e+1, "%C%S", tailr, tail); free(comp); }