commit bd64e1205e3f2bb3dd69c8471b6b735286303edf
parent f3783089b8859be798df289b9cd75b604d8050a8
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 10 Dec 2015 18:09:53 +0100
Add repetion of last command
This is needed for global commands, where '&' has
an special meaning, because in interactive commands
it means repeat last command, but it is also used
in non interactive commands to indicate the repetion
of the last command.
Diffstat:
M | ed.c | | | 53 | +++++++++++++++++++++++++++++++++-------------------- |
1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/ed.c b/ed.c
@@ -42,8 +42,10 @@ size_t sizetxt, memtxt;
int scratch;
int pflag, modflag, uflag;
size_t csize;
-char *cmd;
+char *cmdline;
+char *ocmdline;
size_t cmdsiz, cmdcap;
+int repidx;
static void
error(char *msg)
@@ -90,16 +92,23 @@ input(void)
{
int c;
+ if (repidx >= 0)
+ return ocmdline[repidx++];
+
if ((c = getchar()) != EOF)
- cmd = addchar(c, cmd, &cmdcap, &cmdsiz);
+ cmdline = addchar(c, cmdline, &cmdcap, &cmdsiz);
return c;
}
static int
back(int c)
{
- ungetc(c, stdin);
- --cmdsiz;
+ if (repidx > 0) {
+ --repidx;
+ } else {
+ ungetc(c, stdin);
+ --cmdsiz;
+ }
return c;
}
@@ -739,24 +748,24 @@ execsh(void)
}
static void
-docmd(char c)
+docmd(char cmd)
{
char *s;
- int cmd, num, trunc, lline1, lline2;
- static int ocmd, oline1, oline2, line3;
+ int rep = 0, c, line3, num, trunc;
- lline1 = line1;
- lline2 = line2;
- cmd = c;
repeat:
+ skipblank();
trunc = pflag = 0;
switch (cmd) {
case '&':
skipblank();
chkprint(0);
- cmd = ocmd;
- line1 = oline1;
- line2 = oline2;
+ if (!ocmdline)
+ error("no previous command");
+ rep = 1;
+ repidx = 0;
+ getlst();
+ cmd = input();
goto repeat;
case '!':
execsh();
@@ -828,7 +837,7 @@ repeat:
break;
case 'm':
deflines(curln, curln);
- if (c != '&' && !address(&line3))
+ if (!address(&line3))
line3 = curln;
chkprint(1);
move(line3);
@@ -921,16 +930,19 @@ repeat:
}
if (!pflag)
- goto update_last_cmd;
+ goto save_last_cmd;
line1 = line2 = curln;
print:
doprint();
-update_last_cmd:
- oline1 = lline1;
- oline2 = lline2;
- ocmd = cmd;
+save_last_cmd:
+ if (rep)
+ return;
+ free(ocmdline);
+ cmdline = addchar('\0', cmdline, &cmdcap, &cmdsiz);
+ if ((ocmdline = strdup(cmdline)) == NULL)
+ error("out of memory");
}
static int
@@ -972,6 +984,7 @@ doglobal(void)
int i, k;
char *s, c;
+ skipblank();
if (uflag)
chkprint(0);
@@ -1066,10 +1079,10 @@ main(int argc, char *argv[])
for (;;) {
cmdsiz = 0;
+ repidx = -1;
if (optprompt)
fputs(prompt, stdout);
getlst();
- skipblank();
chkglobal() ? doglobal() : docmd(input());
}