From c8fbe01662c95e1f0a1af0e767ef565f1efdefbc Mon Sep 17 00:00:00 2001 From: "Mirar (Pontus Hagland)" <pike@sort.mirar.org> Date: Fri, 3 Apr 1998 03:06:58 +0200 Subject: [PATCH] sed added Rev: lib/modules/Tools.pmod/sed.pmod:1.1 --- lib/modules/Tools.pmod/sed.pmod | 282 ++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 lib/modules/Tools.pmod/sed.pmod diff --git a/lib/modules/Tools.pmod/sed.pmod b/lib/modules/Tools.pmod/sed.pmod new file mode 100644 index 0000000000..14e63277cb --- /dev/null +++ b/lib/modules/Tools.pmod/sed.pmod @@ -0,0 +1,282 @@ +// edit commands supported: +// <firstline>,<lastline><edit command> +// ^^ numeral (17) ^^ +// or relative (+17, -17) +// or a search regexp (/regexp/) +// or multiple (17/regexp//regexp/+2) +// +// D - delete first line in space +// G - insert hold space +// H - append current space to hold space +// P - print current data +// a<string> - insert +// c<string> - change current space +// d - delete current space +// h - copy current space to hold space +// i<string> - print string +// l - print current space +// p - print first line in data +// q - quit evaluating +// s/regexp/with/x - replace +// y/chars/chars/ - replace chars +// +// where line is numeral, first 'line'==0 + +static array sedreplace(string s,object re,string with, + array whatin,int first,int lastmod, + multiset flags) +{ + array a; + string w=0; + array pr=({}); + + if (!(a=re->split(s))) + return 0; + + if (first) + { + array wa; + wa=sedreplace(a[0],re,with,whatin,first,lastmod,flags); + if (wa) + if (!flags["g"]) + return ({wa[0],wa[1]+s[strlen(a[0])..]}); + else + pr=wa[0],w=wa[1]; + else + w=a[0]; + } + + string t= + replace(with,whatin[..sizeof(a)-first+lastmod-1], + a[first..sizeof(a)+lastmod-1]); + + if (flags["p"]) pr+=({t}); + + s=(w||"")+t; + if (flags["g"]) + { + if (lastmod) + { + array wa; + wa=sedreplace(a[-1],re,with,whatin,first,lastmod,flags); + if (wa) + { + pr+=wa[0]; + s+=wa[1]; + } + else + s+=a[-1]; + } + } + else + s+=a[-1]; + + return ({pr,s}); +}; + +static array scan_for_linenumber(string cmd, + array(string) in, + int n) +{ + int x; + string what; + object re; + + while (cmd!="" && ((cmd[0]>='0' && cmd[0]<='9') + || cmd[0]=='/' || cmd[0]=='+' || cmd[0]=='-')) + { + if (cmd[0]>='0' && cmd[0]<='9') + { + sscanf(cmd,"%d%s",n,cmd); + // n--; if first line==1 + } + else if (cmd[0]=='+') + { + sscanf(cmd,"+%d%s",x,cmd); + n+=x; + } + else if (cmd[0]=='-') + { + sscanf(cmd,"-%d%s",x,cmd); + n-=x; + } + else if (sscanf(cmd,"/%s/%s",what,cmd)==2) + { + re=Regexp(what); + while (n<sizeof(in)) + { + if (re->match(in[n])) break; + n++; + } + } + else break; + } + if (n<0) n=0; else if (n>=sizeof(in)) n=sizeof(in)-1; + return ({n,cmd}); +} + +string|array `()(string|array(string) commands, + string|array(string) data, + void|int suppress) +{ + int start,stop; + string div,what,with,inflags; + multiset flags; + array whatin=({"\\1","\\2","\\3","\\4","\\5","\\6","\\7","\\8","\\9"}); + array print=({}); + array hold=({}); + object re; + array a1,a2; + array in,e; + + if (arrayp(data)) in=copy_value(data); + else in=data/"\n"; + + if (arrayp(commands)) e=commands; + else e=commands/"\n"; + + start=0; + stop=sizeof(in)-1; + + foreach (e, string cmd) + { + if (cmd!="" && ((cmd[0]>='0' && cmd[0]<='9') + || cmd[0]=='/' || cmd[0]=='+' || cmd[0]=='-')) + { + a1=scan_for_linenumber(cmd,in,start); + stop=start=a1[0]; + cmd=a1[1]; + } + + if (cmd[0..1]==",$") { cmd=cmd[2..]; stop=sizeof(in)-1; } + else if (sscanf(cmd,",%s",cmd)) + { + a1=scan_for_linenumber(cmd,in,start); + stop=a1[0]; + cmd=a1[1]; + } + + if (stop>sizeof(in)-1) stop=sizeof(in)-1; + if (start<0) start=0; + + if (cmd=="") continue; + switch (cmd[0]) + { + case 's': + div=cmd[1..1]; + if (div=="%") div="%%"; + inflags=""; + if (sscanf(cmd,"%*c"+div+"%s"+div+"%s"+div+"%s", + what,with,inflags)<3) continue; + flags=aggregate_multiset(@(inflags/"")); + + int first=0,lastmod=0; + if (what!="") // fix the regexp for working split + { + if (what[0]!='^') what="^(.*)"+what,first=1; + if (what[-1]!='$') what=what+"(.*)$",lastmod=-1; + } + re=Regexp(what); + + while (start<=stop) + { + array sa=sedreplace(in[start],re,with,whatin, + first,lastmod,flags); + + if (sa) + { + in[start]=sa[1]; + print+=sa[0]; + if (!flags["g"]) break; + } + start++; + } + + break; + + case 'y': + div=cmd[1..1]; + if (div=="%") div="%%"; + inflags=""; + if (sscanf(cmd,"%*c"+div+"%s"+div+"%s"+div+"%s", + what,with,inflags)<3) continue; + if (strlen(what)!=strlen(with)) + { + what=what[0..strlen(with)-1]; + with=with[0..strlen(what)-1]; + } + + a1=what/"",a2=with/""; + + while (start<=stop) + { + in[start]=replace(in[start],a1,a2); + start++; + } + break; + + case 'G': // insert hold space + in=in[..start-1]+hold+in[start..]; + if (stop>=start) stop+=sizeof(hold); + break; + + case 'a': // insert line + in=in[..start-1]+({cmd[1..]})+in[start..]; + if (stop>=start) stop++; + break; + + case 'c': // change + in=in[..start-1]+({cmd[1..]})+in[stop+1..]; + stop=start; + break; + + case 'd': // delete + in=in[..start-1]+in[stop+1..]; + stop=start; + break; + + case 'D': // delete first line + in=in[..start-1]+in[start+1..]; + stop=start; + break; + + case 'h': // copy + hold=in[start..stop]; + break; + + case 'H': // appending copy + hold+=in[start..stop]; + break; + + case 'i': // print text + print+=({cmd[1..]}); + break; + + case 'l': // print space + print+=in[start..stop]; + break; + + case 'P': // print all + print+=in; + break; + + case 'p': // print first + print+=in[..0]; + break; + + case 'q': // quit + if (!suppress) + return (arrayp(data)?(print+in):((print+in)*"\n")); + return (arrayp(data)?(print):(print*"\n")); + + default: + // error? just ignore for now + } + } + if (!suppress) + return (arrayp(data)?(print+in):(print+in)*"\n"); + return (arrayp(data)?(print):(print*"\n")); +} + + + -- GitLab