Skip to content
Snippets Groups Projects
Commit c8fbe016 authored by Mirar (Pontus Hagland)'s avatar Mirar (Pontus Hagland)
Browse files

sed added

Rev: lib/modules/Tools.pmod/sed.pmod:1.1
parent a1bb1366
No related branches found
No related tags found
No related merge requests found
// 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"));
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment