Introduction
Introduction Statistics Contact Development Disclaimer Help
ed: Add getinput() and setinput() - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
commit 1e10bf6069f472637450f3f1f1933b73dff88a83
parent b710ee81fcdb077d6ff088aa5beab021f58dc3d9
Author: Roberto E. Vargas Caballero <[email protected]>
Date: Wed, 29 Nov 2023 13:25:07 +0100
ed: Add getinput() and setinput()
These functions allow to read from stdin the full next
line or seting as input a character array. These functions
avoid all the complexity about repeat commands that is very
fragile and depends on having multiple global variables with
weak relation between them.
Diffstat:
M ed.c | 171 +++++++++++++++++------------…
1 file changed, 92 insertions(+), 79 deletions(-)
---
diff --git a/ed.c b/ed.c
@@ -64,30 +64,15 @@ static int pflag, modflag, uflag, gflag;
static size_t csize;
static String cmdline;
static char *ocmdline;
-static int repidx;
+static int inputidx;
static char *rhs;
static char *lastmatch;
static struct undo udata;
static int newcmd;
-int eol, bol;
+static int eol, bol;
static sig_atomic_t intr, hup;
-static void
-discard(void)
-{
- int c;
-
- if (repidx >= 0 || cmdline.siz == 0)
- return;
-
- /* discard until the end of the line */
- if (cmdline.str[cmdline.siz-1] != '\n') {
- while ((c = getchar()) != '\n' && c != EOF)
- ;
- }
-}
-
static void undo(void);
static void
@@ -102,7 +87,6 @@ error(char *msg)
if (!newcmd)
undo();
- discard();
curln = ocurln;
longjmp(savesp, 1);
}
@@ -172,30 +156,22 @@ static void chksignals(void);
static int
input(void)
{
- int c;
-
- if (repidx >= 0)
- return ocmdline[repidx++];
-
- if ((c = getchar()) != EOF)
- addchar(c, &cmdline);
+ int ch;
chksignals();
- return c;
+ ch = cmdline.str[inputidx];
+ if (ch != '\0')
+ inputidx++;
+ return ch;
}
static int
back(int c)
{
- if (repidx > 0) {
- --repidx;
- } else {
- ungetc(c, stdin);
- if (c != EOF)
- --cmdline.siz;
- }
- return c;
+ if (c == '\0')
+ return c;
+ return cmdline.str[--inputidx] = c;
}
static int
@@ -203,7 +179,8 @@ makeline(char *s, int *off)
{
struct hline *lp;
size_t len;
- char c, *begin = s;
+ char *begin = s;
+ int c;
if (lastidx >= idxsize) {
lp = NULL;
@@ -426,18 +403,14 @@ compile(int delim)
eol = bol = bracket = lastre.siz = 0;
for (n = 0;; ++n) {
- if ((c = input()) == delim && !bracket)
+ c = input();
+ if (c == delim && !bracket || c == '\0') {
break;
- if (c == '^') {
+ } else if (c == '^') {
bol = 1;
} else if (c == '$') {
eol = 1;
- } else if (c == '\n' || c == EOF) {
- back(c);
- break;
- }
-
- if (c == '\\') {
+ } else if (c == '\\') {
addchar(c, &lastre);
c = input();
} else if (c == '[') {
@@ -521,9 +494,8 @@ ensureblank(void)
case ' ':
case '\t':
skipblank();
- case '\n':
+ case '\0':
back(c);
- case EOF:
break;
default:
error("unknown command");
@@ -681,6 +653,46 @@ quit(void)
exit(exstatus);
}
+static void
+setinput(char *s)
+{
+ copystring(&cmdline, s);
+ inputidx = 0;
+}
+
+static void
+getinput(void)
+{
+ int ch;
+
+ string(&cmdline);
+
+ while ((ch = getchar()) != '\n' && ch != EOF) {
+ if (ch == '\\') {
+ if ((ch = getchar()) == EOF)
+ break;
+ if (ch != '\n') {
+ ungetc(ch, stdin);
+ ch = '\\';
+ }
+ }
+ addchar(ch, &cmdline);
+ }
+
+ addchar('\0', &cmdline);
+ inputidx = 0;
+
+ if (ch == EOF) {
+ chksignals();
+ if (ferror(stdin)) {
+ exstatus = 1;
+ fputs("ed: error reading input\n", stderr);
+ }
+ quit();
+ }
+}
+
+
static void dowrite(const char *, int);
static void
@@ -872,12 +884,12 @@ chkprint(int flag)
else
back(c);
}
- if (input() != '\n')
+ if (input() != '\0')
error("invalid command suffix");
}
static char *
-getfname(char comm)
+getfname(int comm)
{
int c;
char *bp;
@@ -885,7 +897,7 @@ getfname(char comm)
skipblank();
for (bp = fname; bp < &fname[FILENAME_MAX]; *bp++ = c) {
- if ((c = input()) == EOF || c == '\n')
+ if ((c = input()) == '\0')
break;
}
if (bp == fname) {
@@ -1040,7 +1052,7 @@ execsh(void)
error("no previous command");
}
- while ((c = input()) != EOF && c != '\n') {
+ while ((c = input()) != '\0') {
if (c == '%' && (cmd.siz == 0 || cmd.str[cmd.siz - 1] != '\\')…
if (savfname[0] == '\0')
error("no current filename");
@@ -1067,12 +1079,10 @@ getrhs(int delim)
static String s;
string(&s);
- while ((c = input()) != '\n' && c != EOF && c != delim)
+ while ((c = input()) != '\0' && c != delim)
addchar(c, &s);
addchar('\0', &s);
- if (c == EOF)
- error("invalid pattern delimiter");
- if (c == '\n') {
+ if (c == '\0') {
pflag = 'p';
back(c);
}
@@ -1201,8 +1211,7 @@ subst(int nth)
static void
docmd(void)
{
- char cmd;
- int rep = 0, c, line3, num, trunc;
+ int cmd, c, line3, num, trunc;
repeat:
skipblank();
@@ -1210,21 +1219,18 @@ repeat:
trunc = pflag = 0;
switch (cmd) {
case '&':
+ /* This is not working now */
skipblank();
chkprint(0);
if (!ocmdline)
error("no previous command");
- rep = 1;
- repidx = 0;
+ setinput(ocmdline);
getlst();
goto repeat;
case '!':
execsh();
break;
- case EOF:
- if (cmdline.siz == 0)
- quit();
- case '\n':
+ case '\0':
if (gflag && uflag)
return;
num = gflag ? curln : curln+1;
@@ -1378,7 +1384,7 @@ repeat:
ensureblank();
if (nlines > 0)
goto unexpected;
- if (back(input()) != '\n')
+ if (back(input()) != '\0')
getfname(cmd);
else
puts(savfname);
@@ -1410,21 +1416,11 @@ repeat:
}
if (!pflag)
- goto save_last_cmd;
-
+ return;
line1 = line2 = curln;
+
print:
doprint();
-
-save_last_cmd:
- if (!uflag)
- repidx = 0;
- if (rep)
- return;
- free(ocmdline);
- addchar('\0', &cmdline);
- if ((ocmdline = strdup(cmdline.str)) == NULL)
- error("out of memory");
}
static int
@@ -1469,12 +1465,26 @@ chkglobal(void)
}
static void
+savecmd(void)
+{
+ int ch;
+
+ skipblank();
+ ch = input();
+ if (ch != '&') {
+ ocmdline = strdup(cmdline.str);
+ if (ocmdline == NULL)
+ error("out of memory");
+ }
+ back(ch);
+}
+
+static void
doglobal(void)
{
- int cnt, ln, k;
+ int cnt, ln, k, idx;
skipblank();
- string(&cmdline);
gflag = 1;
if (uflag)
chkprint(0);
@@ -1491,15 +1501,18 @@ doglobal(void)
line1 = line2 = ln;
pflag = 0;
doprint();
+ getinput();
+ savecmd();
}
+ idx = inputidx;
getlst();
docmd();
+ inputidx = idx;
} else {
cnt++;
ln = nextln(ln);
}
}
- discard(); /* cover the case of not matching anything */
}
static void
@@ -1527,12 +1540,12 @@ edit(void)
newcmd = 1;
ocurln = curln;
olastln = lastln;
- cmdline.siz = 0;
- repidx = -1;
if (optprompt) {
fputs(prompt, stdout);
fflush(stdout);
}
+
+ getinput();
getlst();
chkglobal() ? doglobal() : docmd();
}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.