[hackers] [sbase] Improve doglobal()

2018-03-06 Thread Roberto E. Vargas Caballero
Don't use directly the line numbers and call to getlst()
when a line is matched.
---
 ed.c | 30 ++
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/ed.c b/ed.c
index 13c41c6..e6d92e2 100644
--- a/ed.c
+++ b/ed.c
@@ -1318,7 +1318,7 @@ chkglobal(void)
 static void
 doglobal(void)
 {
-   int i, k;
+   int cnt, ln, k;
 
skipblank();
cmdline.siz = 0;
@@ -1326,18 +1326,24 @@ doglobal(void)
if (uflag)
chkprint(0);
 
-   for (i = 1; i <= lastln; i++) {
-   k = getindex(i);
-   if (!zero[k].global)
-   continue;
-   curln = i;
-   nlines = 0;
-   if (uflag) {
-   line1 = line2 = i;
-   pflag = 0;
-   doprint();
+   ln = line1;
+   for (cnt = 0; cnt < lastln;) {
+   k = getindex(ln);
+   if (zero[k].global) {
+   zero[k].global = 0;
+   curln = ln;
+   nlines = 0;
+   if (uflag) {
+   line1 = line2 = ln;
+   pflag = 0;
+   doprint();
+   }
+   getlst();
+   docmd();
+   } else {
+   cnt++;
+   ln = nextln(ln);
}
-   docmd();
}
discard();   /* cover the case of not matching anything */
 }
-- 
2.16.2




[hackers] [PATCH 17/17] Add TODO

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/ed.c b/ed.c
index fe68197..bf66f8b 100644
--- a/ed.c
+++ b/ed.c
@@ -1,4 +1,12 @@
 /* See LICENSE file for copyright and license details. */
+
+/*
+ * TODO: Multi-line commands don't work in global commands:
+ * o  g/^line/a \
+ *line1
+ *.
+ * o  Signal handling is broken
+ */
 #include 
 #include 
 #include 
-- 
2.14.2




[hackers] [PATCH 14/17] Improve doglobal()

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

Don't use directly the line numbers and call to getlst()
when a line is matched.
---
 ed.c | 30 ++
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/ed.c b/ed.c
index 13c41c6..1e814e9 100644
--- a/ed.c
+++ b/ed.c
@@ -1318,7 +1318,7 @@ chkglobal(void)
 static void
 doglobal(void)
 {
-   int i, k;
+   int cnt, ln, k;
 
skipblank();
cmdline.siz = 0;
@@ -1326,18 +1326,24 @@ doglobal(void)
if (uflag)
chkprint(0);
 
-   for (i = 1; i <= lastln; i++) {
-   k = getindex(i);
-   if (!zero[k].global)
-   continue;
-   curln = i;
-   nlines = 0;
-   if (uflag) {
-   line1 = line2 = i;
-   pflag = 0;
-   doprint();
+   ln = line1;
+   for (cnt = 0; cnt < lastln; cnt++) {
+   k = getindex(ln);
+   if (zero[k].global) {
+   zero[k].global = 0;
+   curln = ln;
+   nlines = 0;
+   if (uflag) {
+   line1 = line2 = ln;
+   pflag = 0;
+   doprint();
+   }
+   getlst();
+   docmd();
+   } else {
+   cnt++;
+   ln = nextln(ln);
}
-   docmd();
}
discard();   /* cover the case of not matching anything */
 }
-- 
2.14.2




[hackers] [PATCH 06/17] Move join() to use String type

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/ed.c b/ed.c
index 5d85b52..8951d4b 100644
--- a/ed.c
+++ b/ed.c
@@ -833,22 +833,22 @@ join(void)
 {
int i;
char *t, c;
-   size_t len = 0, cap = 0;
-   static char *s;
+   static String s;
 
-   free(s);
-   for (s = NULL, i = line1;; i = nextln(i)) {
+   free(s.str);
+   s.siz = s.cap = 0;
+   for (i = line1;; i = nextln(i)) {
for (t = gettxt(i); (c = *t) != '\n'; ++t)
-   s = addchar(*t, s, , );
+   addchar_(*t, );
if (i == line2)
break;
}
 
-   s = addchar('\n', s, , );
-   s = addchar('\0', s, , );
+   addchar_('\n', );
+   addchar_('\0', );
delete(line1, line2);
-   inject(s, 1);
-   free(s);
+   inject(s.str, 1);
+   free(s.str);
 }
 
 static void
-- 
2.14.2




[hackers] [PATCH 09/17] Fix type of c in getrhs()

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

C is compared against EOF, so it cannot be char.
---
 ed.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/ed.c b/ed.c
index fb4faf9..0f86759 100644
--- a/ed.c
+++ b/ed.c
@@ -926,15 +926,14 @@ static void
 getrhs(int delim)
 {
int c;
-   size_t siz, cap;
-   static char *s;
+   static String s;
 
-   free(s);
-   s = NULL;
-   siz = cap = 0;
+   free(s.str);
+   s.str = NULL;
+   s.siz = s.cap = 0;
while ((c = input()) != '\n' && c != EOF && c != delim)
-   s = addchar(c, s, , );
-   s = addchar('\0', s, , );
+   addchar_(c, );
+   addchar_('\0', );
if (c == EOF)
error("invalid pattern delimiter");
if (c == '\n') {
@@ -942,15 +941,15 @@ getrhs(int delim)
back(c);
}
 
-   if (!strcmp("%", s)) {
-   free(s);
+   if (!strcmp("%", s.str)) {
+   free(s.str);
if (!rhs)
error("no previous substitution");
} else {
free(rhs);
-   rhs = s;
+   rhs = s.str;
}
-   s = NULL;
+   s.str = NULL;
 }
 
 static int
-- 
2.14.2




[hackers] [PATCH 02/17] Define new String type

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

Current handling of strings is a bit messy. This type is copied
from the sed implementation. Addchar_ is added to be able to live
with String and old style chars based in 3 different variables.
---
 ed.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/ed.c b/ed.c
index 5511a9e..97fa5e8 100644
--- a/ed.c
+++ b/ed.c
@@ -20,6 +20,12 @@
 #define NUMLINES32
 #define CACHESIZ  4096
 
+typedef struct {
+   char *str;
+   size_t cap;
+   size_t siz;
+} String;
+
 struct hline {
off_t seek;
char  global;
@@ -111,6 +117,23 @@ prevln(int line)
return (line < 0) ? lastln : line;
 }
 
+static char *
+addchar_(char c, String *s)
+{
+   size_t cap = s->cap, siz = s->siz;
+   char *t = s->str;
+
+   if (siz >= cap &&
+   (cap > SIZE_MAX - LINESIZE ||
+(t = realloc(t, cap += LINESIZE)) == NULL))
+   error("out of memory");
+   t[siz++] = c;
+   s->siz = siz;
+   s->cap = cap;
+   s->str = t;
+   return t;
+}
+
 static char *
 addchar(char c, char *t, size_t *capacity, size_t *size)
 {
-- 
2.14.2




[hackers] [sbase] ed patches

2018-03-06 Thread quinq
Hi,

Here are some ed patches I send on the behalf of Roberto as he is having
mailing problems.




[hackers] [PATCH 16/17] Fix undo

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

Avoid incorrect values in the number of undo elements and restore lastln
value after an undo operation.
---
 ed.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/ed.c b/ed.c
index dbdfe60..fe68197 100644
--- a/ed.c
+++ b/ed.c
@@ -35,7 +35,7 @@ struct hline {
 };
 
 struct undo {
-   int curln;
+   int curln, lastln;
size_t nr, cap;
struct link {
int to1, from1;
@@ -51,7 +51,7 @@ static String lastre;
 static int optverbose, optprompt, exstatus, optdiag = 1;
 static int marks['z' - 'a'];
 static int nlines, line1, line2;
-static int curln, lastln, ocurln;
+static int curln, lastln, ocurln, olastln;
 static jmp_buf savesp;
 static char *lasterr;
 static size_t idxsize, lastidx;
@@ -266,13 +266,14 @@ clearundo(void)
 }
 
 static void
-relink(int to1, int from1, int from2, int to2)
+newundo(int from1, int from2)
 {
struct link *p;
 
if (newcmd) {
clearundo();
udata.curln = ocurln;
+   udata.lastln = olastln;
}
if (udata.nr >= udata.cap) {
size_t siz = (udata.cap + 10) * sizeof(struct link);
@@ -286,7 +287,16 @@ relink(int to1, int from1, int from2, int to2)
p->to1 = zero[from1].next;
p->from2 = from2;
p->to2 = zero[from2].prev;
+}
 
+/*
+ * relink: to1   <- from1
+ * from2 -> to2
+ */
+static void
+relink(int to1, int from1, int from2, int to2)
+{
+   newundo(from1, from2);
zero[from1].next = to1;
zero[from2].prev = to2;
modflag = 1;
@@ -299,7 +309,8 @@ undo(void)
 
if (udata.nr == 0)
return;
-   for (p = [udata.nr-1]; udata.nr--; --p) {
+   for (p = [udata.nr-1]; udata.nr > 0; --p) {
+   --udata.nr;
zero[p->from1].next = p->to1;
zero[p->from2].prev = p->to2;
}
@@ -307,6 +318,7 @@ undo(void)
udata.vec = NULL;
udata.cap = 0;
curln = udata.curln;
+   lastln = udata.lastln;
 }
 
 static void
@@ -1395,6 +1407,7 @@ edit(void)
for (;;) {
newcmd = 1;
ocurln = curln;
+   olastln = lastln;
cmdline.siz = 0;
repidx = -1;
if (optprompt) {
-- 
2.14.2




[hackers] [PATCH 01/17] Set restore point before seeting signal handlers

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/ed.c b/ed.c
index 2a84b60..5511a9e 100644
--- a/ed.c
+++ b/ed.c
@@ -1368,7 +1368,6 @@ sighup(int dummy)
 static void
 edit(void)
 {
-   setjmp(savesp);
for (;;) {
newcmd = 1;
ocurln = curln;
@@ -1388,8 +1387,6 @@ init(char *fname)
 {
size_t len;
 
-   if (setjmp(savesp))
-   return;
setscratch();
if (!fname)
return;
@@ -1418,11 +1415,12 @@ main(int argc, char *argv[])
if (argc > 1)
usage();
 
-   signal(SIGINT, sigintr);
-   signal(SIGHUP, sighup);
-   signal(SIGQUIT, SIG_IGN);
-
-   init(*argv);
+   if (!setjmp(savesp)) {
+   signal(SIGINT, sigintr);
+   signal(SIGHUP, sighup);
+   signal(SIGQUIT, SIG_IGN);
+   init(*argv);
+   }
edit();
 
/* not reached */
-- 
2.14.2




[hackers] [PATCH 07/17] Move execsh() to use String type

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/ed.c b/ed.c
index 8951d4b..dcd91d1 100644
--- a/ed.c
+++ b/ed.c
@@ -887,38 +887,37 @@ quit(void)
 static void
 execsh(void)
 {
-   static char *cmd;
-   static size_t siz, cap;
+   static String cmd;
char c, *p;
int repl = 0;
 
skipblank();
if ((c = input()) != '!') {
back(c);
-   siz = 0;
-   } else if (cmd) {
-   --siz;
+   cmd.siz = 0;
+   } else if (cmd.siz) {
+   --cmd.siz;
repl = 1;
} else {
error("no previous command");
}
 
while ((c = input()) != EOF && c != '\n') {
-   if (c == '%' && (siz == 0 || cmd[siz - 1] != '\\')) {
+   if (c == '%' && (cmd.siz == 0 || cmd.str[cmd.siz - 1] != '\\')) 
{
if (savfname[0] == '\0')
error("no current filename");
repl = 1;
for (p = savfname; *p; ++p)
-   cmd = addchar(*p, cmd, , );
+   addchar_(*p, );
} else {
-   cmd = addchar(c, cmd, , );
+   addchar_(c, );
}
}
-   cmd = addchar('\0', cmd, , );
+   addchar_('\0', );
 
if (repl)
-   puts(cmd);
-   system(cmd);
+   puts(cmd.str);
+   system(cmd.str);
if (optdiag)
puts("!");
 }
-- 
2.14.2




[hackers] [PATCH 10/17] Move subline() to use String type

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 31 +++
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/ed.c b/ed.c
index 0f86759..2a66184 100644
--- a/ed.c
+++ b/ed.c
@@ -970,26 +970,26 @@ getnth(void)
 }
 
 static void
-addpre(char **s, size_t *cap, size_t *siz)
+addpre(String *s)
 {
char *p;
 
for (p = lastmatch; p < lastmatch + matchs[0].rm_so; ++p)
-   *s = addchar(*p, *s, cap, siz);
+   addchar_(*p, s);
 }
 
 static void
-addpost(char **s, size_t *cap, size_t *siz)
+addpost(String *s)
 {
char c, *p;
 
for (p = lastmatch + matchs[0].rm_eo; (c = *p); ++p)
-   *s = addchar(c, *s, cap, siz);
-   *s = addchar('\0', *s, cap, siz);
+   addchar_(c, s);
+   addchar_('\0', s);
 }
 
 static int
-addsub(char **s, size_t *cap, size_t *siz, int nth, int nmatch)
+addsub(String *s, int nth, int nmatch)
 {
char *end, *q, *p, c;
int sub;
@@ -998,7 +998,7 @@ addsub(char **s, size_t *cap, size_t *siz, int nth, int 
nmatch)
q   = lastmatch + matchs[0].rm_so;
end = lastmatch + matchs[0].rm_eo;
while (q < end)
-   *s = addchar(*q++, *s, cap, siz);
+   addchar_(*q++, s);
return 0;
}
 
@@ -1017,11 +1017,11 @@ addsub(char **s, size_t *cap, size_t *siz, int nth, int 
nmatch)
q   = lastmatch + matchs[sub].rm_so;
end = lastmatch + matchs[sub].rm_eo;
while (q < end)
-   *s = addchar(*q++, *s, cap, siz);
+   addchar_(*q++, s);
break;
default:
copy_char:
-   *s = addchar(c, *s, cap, siz);
+   addchar_(c, s);
break;
}
}
@@ -1032,22 +1032,21 @@ static void
 subline(int num, int nth)
 {
int i, m, changed;
-   static char *s;
-   static size_t siz, cap;
+   static String s;
 
-   i = changed = siz = 0;
+   i = changed = s.siz = 0;
for (m = match(num); m; m = rematch(num)) {
-   addpre(, , );
-   changed |= addsub(, , , nth, ++i);
+   addpre();
+   changed |= addsub(, nth, ++i);
if (eol || bol)
break;
}
if (!changed)
return;
-   addpost(, , );
+   addpost();
delete(num, num);
curln = prevln(num);
-   inject(s, 0);
+   inject(s.str, 0);
 }
 
 static void
-- 
2.14.2




[hackers] [PATCH 12/17] Allow overlapping transfer

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/ed.c b/ed.c
index 58bdb45..70dd2a5 100644
--- a/ed.c
+++ b/ed.c
@@ -19,6 +19,8 @@
 #define LINESIZE80
 #define NUMLINES32
 #define CACHESIZ  4096
+#define AFTER 0
+#define BEFORE1
 
 typedef struct {
char *str;
@@ -308,11 +310,11 @@ undo(void)
 }
 
 static void
-inject(char *s, int j)
+inject(char *s, int where)
 {
int off, k, begin, end;
 
-   if (j) {
+   if (where == BEFORE) {
begin = getindex(curln-1);
end = getindex(nextln(curln-1));
} else {
@@ -649,7 +651,7 @@ doread(const char *fname)
s[n-1] = '\n';
s[n] = '\0';
}
-   inject(s, 0);
+   inject(s, AFTER);
}
if (optdiag)
printf("%zu\n", cnt);
@@ -767,7 +769,7 @@ append(int num)
while (getline(, , stdin) > 0) {
if (*s == '.' && s[1] == '\n')
break;
-   inject(s, 0);
+   inject(s, AFTER);
}
free(s);
 }
@@ -832,7 +834,7 @@ join(void)
addchar('\n', );
addchar('\0', );
delete(line1, line2);
-   inject(s.str, 1);
+   inject(s.str, BEFORE);
free(s.str);
 }
 
@@ -854,12 +856,12 @@ copy(int where)
 {
int i;
 
-   if (!line1 || (where >= line1 && where <= line2))
+   if (!line1)
error("incorrect address");
curln = where;
 
for (i = line1; i <= line2; ++i)
-   inject(gettxt(i), 0);
+   inject(gettxt(i), AFTER);
 }
 
 static void
@@ -1031,7 +1033,7 @@ subline(int num, int nth)
addpost();
delete(num, num);
curln = prevln(num);
-   inject(s.str, 0);
+   inject(s.str, AFTER);
 }
 
 static void
-- 
2.14.2




[hackers] [PATCH 03/17] Move cmdline to String type

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 32 +---
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/ed.c b/ed.c
index 97fa5e8..ca55c61 100644
--- a/ed.c
+++ b/ed.c
@@ -61,9 +61,8 @@ static size_t sizetxt, memtxt;
 static int scratch;
 static int pflag, modflag, uflag, gflag;
 static size_t csize;
-static char *cmdline;
+static String cmdline;
 static char *ocmdline;
-static size_t cmdsiz, cmdcap;
 static int repidx;
 static char *rhs;
 static char *lastmatch;
@@ -76,12 +75,15 @@ discard(void)
 {
int c;
 
-   /* discard until end of line */
-   if (repidx < 0  &&
-   ((cmdsiz > 0 && cmdline[cmdsiz-1] != '\n') || cmdsiz == 0)) {
-   while ((c = getchar()) != '\n' && c != EOF)
-   /* nothing */;
-   }
+   if (repidx >= 0)
+   return;
+
+   /* discard until the end of the line */
+   if (cmdline.siz > 0 && cmdline.str[cmdline.siz-1] == '\n')
+   return;
+
+   while ((c = getchar()) != '\n' && c != EOF)
+   ;
 }
 
 static void undo(void);
@@ -158,7 +160,7 @@ input(void)
return ocmdline[repidx++];
 
if ((c = getchar()) != EOF)
-   cmdline = addchar(c, cmdline, , );
+   addchar_(c, );
return c;
 }
 
@@ -170,7 +172,7 @@ back(int c)
} else {
ungetc(c, stdin);
if (c != EOF)
-   --cmdsiz;
+   --cmdline.siz;
}
return c;
 }
@@ -1085,7 +1087,7 @@ repeat:
execsh();
break;
case EOF:
-   if (cmdsiz == 0)
+   if (cmdline.siz == 0)
quit();
case '\n':
if (gflag && uflag)
@@ -1281,8 +1283,8 @@ save_last_cmd:
if (rep)
return;
free(ocmdline);
-   cmdline = addchar('\0', cmdline, , );
-   if ((ocmdline = strdup(cmdline)) == NULL)
+   addchar_('\0', );
+   if ((ocmdline = strdup(cmdline.str)) == NULL)
error("out of memory");
 }
 
@@ -1332,7 +1334,7 @@ doglobal(void)
int i, k;
 
skipblank();
-   cmdsiz = 0;
+   cmdline.siz = 0;
gflag = 1;
if (uflag)
chkprint(0);
@@ -1394,7 +1396,7 @@ edit(void)
for (;;) {
newcmd = 1;
ocurln = curln;
-   cmdsiz = 0;
+   cmdline.siz = 0;
repidx = -1;
if (optprompt) {
fputs(prompt, stdout);
-- 
2.14.2




[hackers] [PATCH 13/17] Fix copy()

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

Copy was using directly the line numbers and incrementing them
without calling to nextln(). It also didn't worried about how
line numbers are modified when we insert new lines.
---
 ed.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/ed.c b/ed.c
index 70dd2a5..13c41c6 100644
--- a/ed.c
+++ b/ed.c
@@ -854,14 +854,19 @@ scroll(int num)
 static void
 copy(int where)
 {
-   int i;
 
if (!line1)
error("incorrect address");
curln = where;
 
-   for (i = line1; i <= line2; ++i)
-   inject(gettxt(i), AFTER);
+   while (line1 <= line2) {
+   inject(gettxt(line1), AFTER);
+   if (line2 >= curln)
+   line2 = nextln(line2);
+   line1 = nextln(line1);
+   if (line1 >= curln)
+   line1 = nextln(line1);
+   }
 }
 
 static void
-- 
2.14.2




[hackers] [PATCH 04/17] Move text to String type

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/ed.c b/ed.c
index ca55c61..2cf2708 100644
--- a/ed.c
+++ b/ed.c
@@ -54,10 +54,9 @@ static jmp_buf savesp;
 static char *lasterr;
 static size_t idxsize, lastidx;
 static struct hline *zero;
-static char *text;
+static String text;
 static char savfname[FILENAME_MAX];
 static char tmpname[FILENAME_MAX];
-static size_t sizetxt, memtxt;
 static int scratch;
 static int pflag, modflag, uflag, gflag;
 static size_t csize;
@@ -236,11 +235,11 @@ gettxt(int line)
char *p;
 
lp = zero + getindex(line);
-   sizetxt = 0;
+   text.siz = 0;
off = lp->seek;
 
if (off == (off_t) -1)
-   return text = addchar('\0', text, , );
+   return addchar_('\0', );
 
 repeat:
if (!csize || off < lasto || off - lasto >= csize) {
@@ -254,14 +253,14 @@ repeat:
}
for (p = buf + off - lasto; p < buf + csize && *p != '\n'; ++p) {
++off;
-   text = addchar(*p, text, , );
+   addchar_(*p, );
}
if (csize && p == buf + csize)
goto repeat;
 
-   text = addchar('\n', text, , );
-   text = addchar('\0', text, , );
-   return text;
+   addchar_('\n', );
+   addchar_('\0', );
+   return text.str;
 }
 
 static void
-- 
2.14.2




[hackers] [PATCH 05/17] Move lastre to String type

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/ed.c b/ed.c
index 2cf2708..5d85b52 100644
--- a/ed.c
+++ b/ed.c
@@ -44,7 +44,7 @@ struct undo {
 static char *prompt = "*";
 static regex_t *pattern;
 static regmatch_t matchs[10];
-static char *lastre;
+static String lastre;
 
 static int optverbose, optprompt, exstatus, optdiag = 1;
 static int marks['z' - 'a'];
@@ -383,13 +383,12 @@ static void
 compile(int delim)
 {
int n, ret, c,bracket;
-   static size_t siz, cap;
static char buf[BUFSIZ];
 
if (!isgraph(delim))
error("invalid pattern delimiter");
 
-   eol = bol = bracket = siz = 0;
+   eol = bol = bracket = lastre.siz = 0;
for (n = 0;; ++n) {
if ((c = input()) == delim && !bracket)
break;
@@ -403,27 +402,27 @@ compile(int delim)
}
 
if (c == '\\') {
-   lastre = addchar(c, lastre, , );
+   addchar_(c, );
c = input();
} else if (c == '[') {
bracket = 1;
} else if (c == ']') {
bracket = 0;
}
-   lastre = addchar(c, lastre, , );
+   addchar_(c, );
}
if (n == 0) {
if (!pattern)
error("no previous pattern");
return;
}
-   lastre = addchar('\0', lastre, , );
+   addchar_('\0', );
 
if (pattern)
regfree(pattern);
if (!pattern && (!(pattern = malloc(sizeof(*pattern)
error("out of memory");
-   if ((ret = regcomp(pattern, lastre, REG_NEWLINE))) {
+   if ((ret = regcomp(pattern, lastre.str, REG_NEWLINE))) {
regerror(ret, pattern, buf, sizeof(buf));
error(buf);
}
-- 
2.14.2




[hackers] [PATCH 15/17] Use nextln() in scroll()

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

---
 ed.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/ed.c b/ed.c
index 1e814e9..dbdfe60 100644
--- a/ed.c
+++ b/ed.c
@@ -841,14 +841,20 @@ join(void)
 static void
 scroll(int num)
 {
-   int i;
+   int max, ln, cnt;
 
if (!line1 || line1 == lastln)
error("incorrect address");
 
-   for (i = line1; i <= line1 + num && i <= lastln; ++i)
-   fputs(gettxt(i), stdout);
-   curln = i;
+   ln = line1;
+   max = line1 + num;
+   if (max > lastln)
+   max = lastln;
+   for (cnt = line1; cnt < max; cnt++) {
+   fputs(gettxt(ln), stdout);
+   ln = nextln(ln);
+   }
+   curln = ln;
 }
 
 static void
-- 
2.14.2




[hackers] [PATCH 11/17] Rename addchar_() to addchar()

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

All the ocurrences of addchar() were moved to addchar_(),
so we can rename addchar_() and remove the old definition.
---
 ed.c | 63 ---
 1 file changed, 24 insertions(+), 39 deletions(-)

diff --git a/ed.c b/ed.c
index 2a66184..58bdb45 100644
--- a/ed.c
+++ b/ed.c
@@ -119,7 +119,7 @@ prevln(int line)
 }
 
 static char *
-addchar_(char c, String *s)
+addchar(char c, String *s)
 {
size_t cap = s->cap, siz = s->siz;
char *t = s->str;
@@ -135,21 +135,6 @@ addchar_(char c, String *s)
return t;
 }
 
-static char *
-addchar(char c, char *t, size_t *capacity, size_t *size)
-{
-   size_t cap = *capacity, siz = *size;
-
-   if (siz >= cap &&
-   (cap > SIZE_MAX - LINESIZE ||
-(t = realloc(t, cap += LINESIZE)) == NULL))
-   error("out of memory");
-   t[siz++] = c;
-   *size = siz;
-   *capacity = cap;
-   return t;
-}
-
 static int
 input(void)
 {
@@ -159,7 +144,7 @@ input(void)
return ocmdline[repidx++];
 
if ((c = getchar()) != EOF)
-   addchar_(c, );
+   addchar(c, );
return c;
 }
 
@@ -239,7 +224,7 @@ gettxt(int line)
off = lp->seek;
 
if (off == (off_t) -1)
-   return addchar_('\0', );
+   return addchar('\0', );
 
 repeat:
if (!csize || off < lasto || off - lasto >= csize) {
@@ -253,13 +238,13 @@ repeat:
}
for (p = buf + off - lasto; p < buf + csize && *p != '\n'; ++p) {
++off;
-   addchar_(*p, );
+   addchar(*p, );
}
if (csize && p == buf + csize)
goto repeat;
 
-   addchar_('\n', );
-   addchar_('\0', );
+   addchar('\n', );
+   addchar('\0', );
return text.str;
 }
 
@@ -402,21 +387,21 @@ compile(int delim)
}
 
if (c == '\\') {
-   addchar_(c, );
+   addchar(c, );
c = input();
} else if (c == '[') {
bracket = 1;
} else if (c == ']') {
bracket = 0;
}
-   addchar_(c, );
+   addchar(c, );
}
if (n == 0) {
if (!pattern)
error("no previous pattern");
return;
}
-   addchar_('\0', );
+   addchar('\0', );
 
if (pattern)
regfree(pattern);
@@ -839,13 +824,13 @@ join(void)
s.siz = s.cap = 0;
for (i = line1;; i = nextln(i)) {
for (t = gettxt(i); (c = *t) != '\n'; ++t)
-   addchar_(*t, );
+   addchar(*t, );
if (i == line2)
break;
}
 
-   addchar_('\n', );
-   addchar_('\0', );
+   addchar('\n', );
+   addchar('\0', );
delete(line1, line2);
inject(s.str, 1);
free(s.str);
@@ -908,12 +893,12 @@ execsh(void)
error("no current filename");
repl = 1;
for (p = savfname; *p; ++p)
-   addchar_(*p, );
+   addchar(*p, );
} else {
-   addchar_(c, );
+   addchar(c, );
}
}
-   addchar_('\0', );
+   addchar('\0', );
 
if (repl)
puts(cmd.str);
@@ -932,8 +917,8 @@ getrhs(int delim)
s.str = NULL;
s.siz = s.cap = 0;
while ((c = input()) != '\n' && c != EOF && c != delim)
-   addchar_(c, );
-   addchar_('\0', );
+   addchar(c, );
+   addchar('\0', );
if (c == EOF)
error("invalid pattern delimiter");
if (c == '\n') {
@@ -975,7 +960,7 @@ addpre(String *s)
char *p;
 
for (p = lastmatch; p < lastmatch + matchs[0].rm_so; ++p)
-   addchar_(*p, s);
+   addchar(*p, s);
 }
 
 static void
@@ -984,8 +969,8 @@ addpost(String *s)
char c, *p;
 
for (p = lastmatch + matchs[0].rm_eo; (c = *p); ++p)
-   addchar_(c, s);
-   addchar_('\0', s);
+   addchar(c, s);
+   addchar('\0', s);
 }
 
 static int
@@ -998,7 +983,7 @@ addsub(String *s, int nth, int nmatch)
q   = lastmatch + matchs[0].rm_so;
end = lastmatch + matchs[0].rm_eo;
while (q < end)
-   addchar_(*q++, s);
+   addchar(*q++, s);
return 0;
}
 
@@ -1017,11 +1002,11 @@ addsub(String *s, int nth, int nmatch)
q   = lastmatch + matchs[sub].rm_so;
end = lastmatch + matchs[sub].rm_eo;
while (q < end)
-

[hackers] [PATCH 08/17] Fix type of c in execsh()

2018-03-06 Thread quinq
From: "Roberto E. Vargas Caballero" 

C is compared against EOF, so it cannot be char.
---
 ed.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ed.c b/ed.c
index dcd91d1..fb4faf9 100644
--- a/ed.c
+++ b/ed.c
@@ -888,8 +888,8 @@ static void
 execsh(void)
 {
static String cmd;
-   char c, *p;
-   int repl = 0;
+   char *p;
+   int c, repl = 0;
 
skipblank();
if ((c = input()) != '!') {
-- 
2.14.2