## initially generated by c2l# implement Mk; include "draw.m"; Mk: module{ init: fn(nil: ref Draw->Context, argl: list of string);}; include "sys.m"; sys: Sys;include "bufio.m"; bufio: Bufio; Iobuf: import bufio;include "libc0.m"; libc0: Libc0;include "regex.m"; regex: Regex;include "ar.m"; ARMAG, SARMAG, ARFMAG, SARNAME, ar_hdr, SAR_HDR: import Ar;include "daytime.m"; daytime: Daytime;include "sh.m"; init(nil: ref Draw->Context, argl: list of string){ sys = load Sys Sys->PATH; bufio = load Bufio Bufio->PATH; libc0 = load Libc0 Libc0->PATH; regex = load Regex Regex->PATH; daytime = load Daytime Daytime->PATH; sys->pctl(Sys->FORKNS, nil); main(len argl, libc0->ls2aab(argl));} NAMELEN: con 28;ERRLEN: con 64;PNPROC, PNGROUP : con iota; # function pointer enum for symtraverseECOPY, PRINT1: con iota; Bufblock: adt{ next: cyclic ref Bufblock; start: array of byte; end: int; current: int;}; Word: adt{ s: array of byte; next: cyclic ref Word;}; Envy: adt{ name: array of byte; values: ref Word;}; Resub: adt{ sp: array of byte; ep: array of byte;}; Rule: adt{ target: array of byte; # one target tail: ref Word; # constituents of targets recipe: array of byte; # do it ! attr: int; # attributes line: int; # source line file: array of byte; # source file alltargets: ref Word; # all the targets rule: int; # rule number pat: Regex->Re; # reg exp goo prog: array of byte; # to use in out of date chain: cyclic ref Rule; # hashed per target next: cyclic ref Rule;}; # Rule.attr META, SEQ, UPD, QUIET, VIR, REGEXP, NOREC, DEL, NOVIRT: con 1<<iota;NREGEXP: con 10; Arc: adt{ flag: int; n: cyclic ref Node; r: ref Rule; stem: array of byte; prog: array of byte; match: array of array of byte; next: cyclic ref Arc;}; # Arc.flag TOGO: con 1; Node: adt{ name: array of byte; time: int; flags: int; prereqs: cyclic ref Arc; next: cyclic ref Node; # list for a rule }; # Node.flags VIRTUAL, CYCLE, READY, CANPRETEND, PRETENDING, NOTMADE, BEINGMADE, MADE, PROBABLE, VACUOUS, NORECIPE, DELETE, NOMINUSE: con 1<<iota; Job: adt{ r: ref Rule; # master rule for job n: ref Node; # list of node targets stem: array of byte; match: array of array of byte; p: ref Word; # prerequistes np: ref Word; # new prerequistes t: ref Word; # targets at: ref Word; # all targets nproc: int; # slot number next: cyclic ref Job;}; Symtab: adt{ space: int; name: array of byte; svalue: array of byte; ivalue: int; nvalue: ref Node; rvalue: ref Rule; wvalue: ref Word; next: cyclic ref Symtab;}; S_VAR # variable -> value , S_TARGET # target -> rule , S_TIME # file -> time , S_PID # pid -> products , S_NODE # target name -> node , S_AGG # aggregate -> time , S_BITCH # bitched about aggregate not there , S_NOEXPORT # var -> noexport , S_OVERRIDE # can't override , S_OUTOFDATE # n1\377n2 -> 2(outofdate) or 1(not outofdate) , S_MAKEFILE # target -> node , S_MAKEVAR # dumpable mk variable , S_EXPORTED # var -> current exported value , S_BULKED # we have bulked this dir , S_WESET # variable; we set in the mkfile # an internal mk variable (e.g., stem, target) , S_INTERNAL: con iota;NAMEBLOCK: con 1000;BIGBLOCK: con 20000;D_PARSE, D_GRAPH, D_EXEC: con 1<<iota; MKFILE: con "mkfile"; version := array[] of { byte '@', byte '(', byte '#', byte ')', byte 'm', byte 'k', byte ' ', byte 'g', byte 'e', byte 'n', byte 'e', byte 'r', byte 'a', byte 'l', byte ' ', byte 'r', byte 'e', byte 'l', byte 'e', byte 'a', byte 's', byte 'e', byte ' ', byte '4', byte ' ', byte '(', byte 'p', byte 'l', byte 'a', byte 'n', byte ' ', byte '9', byte ')', byte '\0' };debug: int;rules, metarules: ref Rule;nflag: int = 0;tflag: int = 0;iflag: int = 0;kflag: int = 0;aflag: int = 0;uflag: int = 0;explain: array of byte = nil;target1: ref Word;nreps: int = 1;jobs: ref Job;bout: ref Iobuf;patrule: ref Rule; main(argc: int, argv: array of array of byte){ w: ref Word; s: array of byte; files := array[256] of array of byte; f: array of array of byte = files; ff: int; sflag: int = 1; i: int; tfd: ref Sys->FD = sys->fildes(-1); tb: ref Iobuf; buf, whatif: ref Bufblock; # # * start with a copy of the current environment variables # * instead of sharing them # bout = bufio->fopen(sys->fildes(1), Sys->OWRITE); buf = newbuf(); whatif = nil; if(argc) ; for(argv = argv[1: ]; argv[0] != nil && argv[0][0] == byte '-'; argv = argv[1: ]){ bufcpy(buf, argv[0], libc0->strlen(argv[0])); insert(buf, ' '); case(int argv[0][1]){ 'a' => aflag = 1; 'd' => if(int (s = argv[0][2: ])[0]) while(int s[0]){ case(int s[0]){ 'p' => debug |= D_PARSE; 'g' => debug |= D_GRAPH; 'e' => debug |= D_EXEC; } s = s[1: ]; } else debug = 16rffff; 'e' => explain = argv[0][2: ]; 'f' => argv = argv[1: ]; if(argv[0] == nil) badusage(); f[0] = argv[0]; f = f[1: ]; bufcpy(buf, argv[0], libc0->strlen(argv[0])); insert(buf, ' '); 'i' => iflag = 1; 'k' => kflag = 1; 'n' => nflag = 1; 's' => sflag = 1; 't' => tflag = 1; 'u' => uflag = 1; 'w' => if(whatif == nil) whatif = newbuf(); else insert(whatif, ' '); if(int argv[0][2]) bufcpy(whatif, argv[0][2: ], libc0->strlen(argv[0][2: ])); else{ argv = argv[1: ]; if(argv[0] == nil) badusage(); bufcpy(whatif, argv[0][0: ], libc0->strlen(argv[0][0: ])); } * => badusage(); } } if(aflag) iflag = 1; usage(); syminit(); initenv(); initbind(); openwait(); usage(); # # assignment args become null strings # temp: string; for(i = 0; argv[i] != nil; i++) if(libc0->strchr(argv[i], '=') != nil){ bufcpy(buf, argv[i], libc0->strlen(argv[i])); insert(buf, ' '); if(tfd == nil){ (temp, tfd) = tmpfile("/tmp/mkarg"); if(tfd == nil){ perror(array of byte temp); Exit(); } tb = bufio->fopen(tfd, Sys->OWRITE); } tb.puts(sys->sprint("%s\n", libc0->ab2s(argv[i]))); argv[i][0] = byte 0; } if(tfd != nil){ tb.flush(); sys->seek(tfd, big 0, 0); parse(libc0->s2ab("command line args"), tfd, 1); sys->remove(temp); } if(buf.current != 0){ buf.current--; insert(buf, 0); } symlookw(libc0->s2ab("MKFLAGS"), S_VAR, stow(buf.start)); buf.current = 0; for(i = 0; argv[i] != nil; i++){ if(argv[i][0] == byte 0) continue; if(i) insert(buf, ' '); bufcpy(buf, argv[i], libc0->strlen(argv[i])); } insert(buf, 0); symlookw(libc0->s2ab("MKARGS"), S_VAR, stow(buf.start)); freebuf(buf); if(f == files){ if(access(libc0->s2ab(MKFILE), Sys->OREAD) == 0) parse(libc0->s2ab(MKFILE), sys->open(MKFILE, 0), 0); } else for(ff = 0; ff < len files && files[ff] != nil; ff++) parse(files[ff], sys->open(libc0->ab2s(files[ff]), 0), 0); if(debug&D_PARSE){ dumpw(libc0->s2ab("default targets"), target1); dumpr(libc0->s2ab("rules"), rules); dumpr(libc0->s2ab("metarules"), metarules); dumpv(libc0->s2ab("variables")); } if(whatif != nil){ insert(whatif, 0); timeinit(whatif.start); freebuf(whatif); } execinit(); # skip assignment args while(argv[0] != nil && argv[0][0] == byte 0) argv = argv[1: ]; catchnotes(); if(argv[0] == nil){ if(target1 != nil) for(w = target1; w != nil; w = w.next) mk(w.s); else{ sys->fprint(sys->fildes(2), "mk: nothing to mk\n"); Exit(); } } else{ if(sflag){ for(; argv[0] != nil; argv = argv[1: ]) if(int argv[0][0]) mk(argv[0]); } else{ head, tail, t: ref Word; # fake a new rule with all the args as prereqs tail = nil; t = nil; for(; argv[0] != nil; argv = argv[1: ]) if(int argv[0][0]){ if(tail == nil) tail = t = newword(argv[0]); else{ t.next = newword(argv[0]); t = t.next; } } if(tail.next == nil) mk(tail.s); else{ head = newword(libc0->s2ab("command line arguments")); addrules(head, tail, libc0->strdup(libc0->s2ab("")), VIR, mkinline, nil); mk(head.s); } } } if(uflag) prusage(); bout.flush();} badusage(){ sys->fprint(sys->fildes(2), "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n"); Exit();} assert(s: array of byte, n: int){ if(!n){ sys->fprint(sys->fildes(2), "mk: Assertion ``%s'' failed.\n", libc0->ab2s(s)); Exit(); }} regerror(s: array of byte){ if(patrule != nil) sys->fprint(sys->fildes(2), "mk: %s:%d: regular expression error; %s\n", libc0->ab2s(patrule.file), patrule.line, libc0->ab2s(s)); else sys->fprint(sys->fildes(2), "mk: %s:%d: regular expression error; %s\n", libc0->ab2s(infile), mkinline, libc0->ab2s(s)); Exit();} perror(s: array of byte){ perrors(libc0->ab2s(s));} perrors(s: string){ sys->fprint(sys->fildes(2), "mk: %s: %r\n", s);} access(s: array of byte, mode: int): int{ fd := sys->open(libc0->ab2s(s), mode); if (fd == nil) return -1; fd = nil; return 0;} stob(buf: array of byte, s: string){ b := libc0->s2ab(s); libc0->strncpy(buf, b, len buf);} tmpfile(basename: string): (string, ref Sys->FD){ pid := sys->pctl(0, nil); for(i := 0; i < 100; i++){ t := basename+sys->sprint("%8.8d.%.2d", pid, i); fd := sys->create(t, Sys->OEXCL|Sys->ORDWR, 8r600); if(fd != nil) return (t, fd); } return (nil, nil);} postnote(t: int, pid: int, note: array of byte){ if(pid == 0) return; fd := sys->open("#p/" + string pid + "/ctl", Sys->OWRITE); if(fd == nil) return; s := libc0->ab2s(note); if(t == PNGROUP) s += "grp"; sys->fprint(fd, "%s", s); fd = nil;} map(s: array of byte, n: int): int{ i := j := 0; ls := libc0->strlen(s); while(i < ls){ if(j == n) return i; (nil, l, nil) := sys->byte2char(s, i); i += l; j++; } return -1;} regadd(s: array of byte, m: array of (int, int), rm: array of Resub, n: int){ k := len m; for(i := 0; i < n; i++) rm[i].sp = rm[i].ep= nil; for(i = 0; i < k && i < n; i++){ (a, b) := m[i]; if(a >= 0 && b >= 0){ a = map(s, a); b = map(s, b); if(a >= 0 && b >= 0){ rm[i].sp = s[a: ]; rm[i].ep = s[b: ]; } } }} scopy(d: array of byte, j: int, m: array of Resub, k: int, n: int): int{ if(k >= n) return 0; sp := m[k].sp; ep := m[k].ep; if(sp == nil || ep == nil) return 0; c := ep[0]; ep[0] = byte 0; libc0->strcpy(d[j: ], sp); ep[0] = c; return libc0->strlen(sp)-libc0->strlen(ep);} regsub(s: array of byte, d: array of byte, m: array of Resub, n: int){ # libc0->strncpy(d, s, libc0->strlen(d)); ls := libc0->strlen(s); j := 0; for(i := 0; i < ls; i++){ case(int s[i]){Lines 1–500 of 4190. Load more
# # initially generated by c2l # implement Mk; include "draw.m"; Mk: module { init: fn(nil: ref Draw->Context, argl: list of string); }; include "sys.m"; sys: Sys; include "bufio.m"; bufio: Bufio; Iobuf: import bufio; include "libc0.m"; libc0: Libc0; include "regex.m"; regex: Regex; include "ar.m"; ARMAG, SARMAG, ARFMAG, SARNAME, ar_hdr, SAR_HDR: import Ar; include "daytime.m"; daytime: Daytime; include "sh.m"; init(nil: ref Draw->Context, argl: list of string) { sys = load Sys Sys->PATH; bufio = load Bufio Bufio->PATH; libc0 = load Libc0 Libc0->PATH; regex = load Regex Regex->PATH; daytime = load Daytime Daytime->PATH; sys->pctl(Sys->FORKNS, nil); main(len argl, libc0->ls2aab(argl)); } NAMELEN: con 28; ERRLEN: con 64; PNPROC, PNGROUP : con iota; # function pointer enum for symtraverse ECOPY, PRINT1: con iota; Bufblock: adt{ next: cyclic ref Bufblock; start: array of byte; end: int; current: int; }; Word: adt{ s: array of byte; next: cyclic ref Word; }; Envy: adt{ name: array of byte; values: ref Word; }; Resub: adt{ sp: array of byte; ep: array of byte; }; Rule: adt{ target: array of byte; # one target tail: ref Word; # constituents of targets recipe: array of byte; # do it ! attr: int; # attributes line: int; # source line file: array of byte; # source file alltargets: ref Word; # all the targets rule: int; # rule number pat: Regex->Re; # reg exp goo prog: array of byte; # to use in out of date chain: cyclic ref Rule; # hashed per target next: cyclic ref Rule; }; # Rule.attr META, SEQ, UPD, QUIET, VIR, REGEXP, NOREC, DEL, NOVIRT: con 1<<iota; NREGEXP: con 10; Arc: adt{ flag: int; n: cyclic ref Node; r: ref Rule; stem: array of byte; prog: array of byte; match: array of array of byte; next: cyclic ref Arc; }; # Arc.flag TOGO: con 1; Node: adt{ name: array of byte; time: int; flags: int; prereqs: cyclic ref Arc; next: cyclic ref Node; # list for a rule }; # Node.flags VIRTUAL, CYCLE, READY, CANPRETEND, PRETENDING, NOTMADE, BEINGMADE, MADE, PROBABLE, VACUOUS, NORECIPE, DELETE, NOMINUSE: con 1<<iota; Job: adt{ r: ref Rule; # master rule for job n: ref Node; # list of node targets stem: array of byte; match: array of array of byte; p: ref Word; # prerequistes np: ref Word; # new prerequistes t: ref Word; # targets at: ref Word; # all targets nproc: int; # slot number next: cyclic ref Job; }; Symtab: adt{ space: int; name: array of byte; svalue: array of byte; ivalue: int; nvalue: ref Node; rvalue: ref Rule; wvalue: ref Word; next: cyclic ref Symtab; }; S_VAR # variable -> value , S_TARGET # target -> rule , S_TIME # file -> time , S_PID # pid -> products , S_NODE # target name -> node , S_AGG # aggregate -> time , S_BITCH # bitched about aggregate not there , S_NOEXPORT # var -> noexport , S_OVERRIDE # can't override , S_OUTOFDATE # n1\377n2 -> 2(outofdate) or 1(not outofdate) , S_MAKEFILE # target -> node , S_MAKEVAR # dumpable mk variable , S_EXPORTED # var -> current exported value , S_BULKED # we have bulked this dir , S_WESET # variable; we set in the mkfile # an internal mk variable (e.g., stem, target) , S_INTERNAL: con iota; NAMEBLOCK: con 1000; BIGBLOCK: con 20000; D_PARSE, D_GRAPH, D_EXEC: con 1<<iota; MKFILE: con "mkfile"; version := array[] of { byte '@', byte '(', byte '#', byte ')', byte 'm', byte 'k', byte ' ', byte 'g', byte 'e', byte 'n', byte 'e', byte 'r', byte 'a', byte 'l', byte ' ', byte 'r', byte 'e', byte 'l', byte 'e', byte 'a', byte 's', byte 'e', byte ' ', byte '4', byte ' ', byte '(', byte 'p', byte 'l', byte 'a', byte 'n', byte ' ', byte '9', byte ')', byte '\0' }; debug: int; rules, metarules: ref Rule; nflag: int = 0; tflag: int = 0; iflag: int = 0; kflag: int = 0; aflag: int = 0; uflag: int = 0; explain: array of byte = nil; target1: ref Word; nreps: int = 1; jobs: ref Job; bout: ref Iobuf; patrule: ref Rule; main(argc: int, argv: array of array of byte) { w: ref Word; s: array of byte; files := array[256] of array of byte; f: array of array of byte = files; ff: int; sflag: int = 1; i: int; tfd: ref Sys->FD = sys->fildes(-1); tb: ref Iobuf; buf, whatif: ref Bufblock; # # * start with a copy of the current environment variables # * instead of sharing them # bout = bufio->fopen(sys->fildes(1), Sys->OWRITE); buf = newbuf(); whatif = nil; if(argc) ; for(argv = argv[1: ]; argv[0] != nil && argv[0][0] == byte '-'; argv = argv[1: ]){ bufcpy(buf, argv[0], libc0->strlen(argv[0])); insert(buf, ' '); case(int argv[0][1]){ 'a' => aflag = 1; 'd' => if(int (s = argv[0][2: ])[0]) while(int s[0]){ case(int s[0]){ 'p' => debug |= D_PARSE; 'g' => debug |= D_GRAPH; 'e' => debug |= D_EXEC; } s = s[1: ]; } else debug = 16rffff; 'e' => explain = argv[0][2: ]; 'f' => argv = argv[1: ]; if(argv[0] == nil) badusage(); f[0] = argv[0]; f = f[1: ]; bufcpy(buf, argv[0], libc0->strlen(argv[0])); insert(buf, ' '); 'i' => iflag = 1; 'k' => kflag = 1; 'n' => nflag = 1; 's' => sflag = 1; 't' => tflag = 1; 'u' => uflag = 1; 'w' => if(whatif == nil) whatif = newbuf(); else insert(whatif, ' '); if(int argv[0][2]) bufcpy(whatif, argv[0][2: ], libc0->strlen(argv[0][2: ])); else{ argv = argv[1: ]; if(argv[0] == nil) badusage(); bufcpy(whatif, argv[0][0: ], libc0->strlen(argv[0][0: ])); } * => badusage(); } } if(aflag) iflag = 1; usage(); syminit(); initenv(); initbind(); openwait(); usage(); # # assignment args become null strings # temp: string; for(i = 0; argv[i] != nil; i++) if(libc0->strchr(argv[i], '=') != nil){ bufcpy(buf, argv[i], libc0->strlen(argv[i])); insert(buf, ' '); if(tfd == nil){ (temp, tfd) = tmpfile("/tmp/mkarg"); if(tfd == nil){ perror(array of byte temp); Exit(); } tb = bufio->fopen(tfd, Sys->OWRITE); } tb.puts(sys->sprint("%s\n", libc0->ab2s(argv[i]))); argv[i][0] = byte 0; } if(tfd != nil){ tb.flush(); sys->seek(tfd, big 0, 0); parse(libc0->s2ab("command line args"), tfd, 1); sys->remove(temp); } if(buf.current != 0){ buf.current--; insert(buf, 0); } symlookw(libc0->s2ab("MKFLAGS"), S_VAR, stow(buf.start)); buf.current = 0; for(i = 0; argv[i] != nil; i++){ if(argv[i][0] == byte 0) continue; if(i) insert(buf, ' '); bufcpy(buf, argv[i], libc0->strlen(argv[i])); } insert(buf, 0); symlookw(libc0->s2ab("MKARGS"), S_VAR, stow(buf.start)); freebuf(buf); if(f == files){ if(access(libc0->s2ab(MKFILE), Sys->OREAD) == 0) parse(libc0->s2ab(MKFILE), sys->open(MKFILE, 0), 0); } else for(ff = 0; ff < len files && files[ff] != nil; ff++) parse(files[ff], sys->open(libc0->ab2s(files[ff]), 0), 0); if(debug&D_PARSE){ dumpw(libc0->s2ab("default targets"), target1); dumpr(libc0->s2ab("rules"), rules); dumpr(libc0->s2ab("metarules"), metarules); dumpv(libc0->s2ab("variables")); } if(whatif != nil){ insert(whatif, 0); timeinit(whatif.start); freebuf(whatif); } execinit(); # skip assignment args while(argv[0] != nil && argv[0][0] == byte 0) argv = argv[1: ]; catchnotes(); if(argv[0] == nil){ if(target1 != nil) for(w = target1; w != nil; w = w.next) mk(w.s); else{ sys->fprint(sys->fildes(2), "mk: nothing to mk\n"); Exit(); } } else{ if(sflag){ for(; argv[0] != nil; argv = argv[1: ]) if(int argv[0][0]) mk(argv[0]); } else{ head, tail, t: ref Word; # fake a new rule with all the args as prereqs tail = nil; t = nil; for(; argv[0] != nil; argv = argv[1: ]) if(int argv[0][0]){ if(tail == nil) tail = t = newword(argv[0]); else{ t.next = newword(argv[0]); t = t.next; } } if(tail.next == nil) mk(tail.s); else{ head = newword(libc0->s2ab("command line arguments")); addrules(head, tail, libc0->strdup(libc0->s2ab("")), VIR, mkinline, nil); mk(head.s); } } } if(uflag) prusage(); bout.flush(); } badusage() { sys->fprint(sys->fildes(2), "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n"); Exit(); } assert(s: array of byte, n: int) { if(!n){ sys->fprint(sys->fildes(2), "mk: Assertion ``%s'' failed.\n", libc0->ab2s(s)); Exit(); } } regerror(s: array of byte) { if(patrule != nil) sys->fprint(sys->fildes(2), "mk: %s:%d: regular expression error; %s\n", libc0->ab2s(patrule.file), patrule.line, libc0->ab2s(s)); else sys->fprint(sys->fildes(2), "mk: %s:%d: regular expression error; %s\n", libc0->ab2s(infile), mkinline, libc0->ab2s(s)); Exit(); } perror(s: array of byte) { perrors(libc0->ab2s(s)); } perrors(s: string) { sys->fprint(sys->fildes(2), "mk: %s: %r\n", s); } access(s: array of byte, mode: int): int { fd := sys->open(libc0->ab2s(s), mode); if (fd == nil) return -1; fd = nil; return 0; } stob(buf: array of byte, s: string) { b := libc0->s2ab(s); libc0->strncpy(buf, b, len buf); } tmpfile(basename: string): (string, ref Sys->FD) { pid := sys->pctl(0, nil); for(i := 0; i < 100; i++){ t := basename+sys->sprint("%8.8d.%.2d", pid, i); fd := sys->create(t, Sys->OEXCL|Sys->ORDWR, 8r600); if(fd != nil) return (t, fd); } return (nil, nil); } postnote(t: int, pid: int, note: array of byte) { if(pid == 0) return; fd := sys->open("#p/" + string pid + "/ctl", Sys->OWRITE); if(fd == nil) return; s := libc0->ab2s(note); if(t == PNGROUP) s += "grp"; sys->fprint(fd, "%s", s); fd = nil; } map(s: array of byte, n: int): int { i := j := 0; ls := libc0->strlen(s); while(i < ls){ if(j == n) return i; (nil, l, nil) := sys->byte2char(s, i); i += l; j++; } return -1; } regadd(s: array of byte, m: array of (int, int), rm: array of Resub, n: int) { k := len m; for(i := 0; i < n; i++) rm[i].sp = rm[i].ep= nil; for(i = 0; i < k && i < n; i++){ (a, b) := m[i]; if(a >= 0 && b >= 0){ a = map(s, a); b = map(s, b); if(a >= 0 && b >= 0){ rm[i].sp = s[a: ]; rm[i].ep = s[b: ]; } } } } scopy(d: array of byte, j: int, m: array of Resub, k: int, n: int): int { if(k >= n) return 0; sp := m[k].sp; ep := m[k].ep; if(sp == nil || ep == nil) return 0; c := ep[0]; ep[0] = byte 0; libc0->strcpy(d[j: ], sp); ep[0] = c; return libc0->strlen(sp)-libc0->strlen(ep); } regsub(s: array of byte, d: array of byte, m: array of Resub, n: int) { # libc0->strncpy(d, s, libc0->strlen(d)); ls := libc0->strlen(s); j := 0; for(i := 0; i < ls; i++){ case(int s[i]){