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