mirror of git://git.suckless.org/sbase
Compare commits
13 Commits
d3a877d171
...
e24228e062
Author | SHA1 | Date |
---|---|---|
Jules Maselbas | e24228e062 | |
Roberto E. Vargas Caballero | 6a557314b9 | |
Roberto E. Vargas Caballero | bbdd7bedc4 | |
Roberto E. Vargas Caballero | 137f0917e4 | |
Roberto E. Vargas Caballero | 2d4d7dc6d4 | |
Roberto E. Vargas Caballero | 516e7fec92 | |
Roberto E. Vargas Caballero | 54a0fc3ecc | |
Roberto E. Vargas Caballero | 09dc00f995 | |
Roberto E. Vargas Caballero | 890f6c2c05 | |
Roberto E. Vargas Caballero | aacfa18b79 | |
Roberto E. Vargas Caballero | b089261c3a | |
Roberto E. Vargas Caballero | 1e10bf6069 | |
Roberto E. Vargas Caballero | b710ee81fc |
25
TODO
25
TODO
|
@ -28,10 +28,6 @@ Bugs
|
|||
|
||||
ed
|
||||
--
|
||||
* Multi-line commands don't work in global commands:
|
||||
g/^line/a \
|
||||
line1
|
||||
.
|
||||
* cat <<EOF | ed
|
||||
0a
|
||||
int radix = 16;
|
||||
|
@ -54,19 +50,16 @@ ed
|
|||
line
|
||||
.
|
||||
1g/^$/p
|
||||
* cat <<EOF | ed
|
||||
i
|
||||
foobar1
|
||||
foobar2
|
||||
.
|
||||
1,2s/foo/&\
|
||||
&/
|
||||
,n
|
||||
|
||||
* Editing huge files doesn't work well.
|
||||
* Escaping newlines in replacement doesn't work well:
|
||||
% /bin/ed
|
||||
i
|
||||
foobar
|
||||
.
|
||||
s/foo/&\
|
||||
->
|
||||
->bar
|
||||
,p
|
||||
foo
|
||||
->bar
|
||||
Q
|
||||
|
||||
|
||||
printf
|
||||
|
|
274
ed.c
274
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);
|
||||
}
|
||||
|
@ -121,6 +105,24 @@ prevln(int line)
|
|||
return (line < 0) ? lastln : line;
|
||||
}
|
||||
|
||||
static String *
|
||||
copystring(String *s, char *from)
|
||||
{
|
||||
size_t len;
|
||||
char *t;
|
||||
|
||||
if ((t = strdup(from)) == NULL)
|
||||
error("out of memory");
|
||||
len = strlen(t);
|
||||
|
||||
free(s->str);
|
||||
s->str = t;
|
||||
s->siz = len;
|
||||
s->cap = len;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static String *
|
||||
string(String *s)
|
||||
{
|
||||
|
@ -154,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
|
||||
|
@ -185,25 +179,27 @@ 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;
|
||||
if (idxsize <= SIZE_MAX - NUMLINES)
|
||||
lp = reallocarray(zero, idxsize + NUMLINES, sizeof(*lp));
|
||||
lp = reallocarray(zero, idxsize + NUMLINES, sizeof(*lp));
|
||||
if (!lp)
|
||||
error("out of memory");
|
||||
idxsize += NUMLINES;
|
||||
zero = lp;
|
||||
}
|
||||
lp = zero + lastidx;
|
||||
lp->global = 0;
|
||||
|
||||
if (!s) {
|
||||
lp->seek = -1;
|
||||
len = 0;
|
||||
} else {
|
||||
while ((c = *s++) != '\n')
|
||||
/* nothing */;
|
||||
while ((c = *s++) && c != '\n')
|
||||
;
|
||||
len = s - begin;
|
||||
if ((lp->seek = lseek(scratch, 0, SEEK_END)) < 0 ||
|
||||
write(scratch, begin, len) < 0) {
|
||||
|
@ -408,18 +404,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 == '[') {
|
||||
|
@ -490,7 +482,7 @@ skipblank(void)
|
|||
char c;
|
||||
|
||||
while ((c = input()) == ' ' || c == '\t')
|
||||
/* nothing */;
|
||||
;
|
||||
back(c);
|
||||
}
|
||||
|
||||
|
@ -503,9 +495,8 @@ ensureblank(void)
|
|||
case ' ':
|
||||
case '\t':
|
||||
skipblank();
|
||||
case '\n':
|
||||
case '\0':
|
||||
back(c);
|
||||
case EOF:
|
||||
break;
|
||||
default:
|
||||
error("unknown command");
|
||||
|
@ -663,6 +654,55 @@ 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 int
|
||||
moreinput(void)
|
||||
{
|
||||
if (!uflag)
|
||||
return cmdline.str[inputidx] != '\0';
|
||||
|
||||
getinput();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void dowrite(const char *, int);
|
||||
|
||||
static void
|
||||
|
@ -670,6 +710,9 @@ dump(void)
|
|||
{
|
||||
char *home;
|
||||
|
||||
if (modflag)
|
||||
return;
|
||||
|
||||
line1 = nextln(0);
|
||||
line2 = lastln;
|
||||
|
||||
|
@ -690,14 +733,14 @@ static void
|
|||
chksignals(void)
|
||||
{
|
||||
if (hup) {
|
||||
if (modflag)
|
||||
dump();
|
||||
exstatus = 1;
|
||||
dump();
|
||||
quit();
|
||||
}
|
||||
|
||||
if (intr) {
|
||||
intr = 0;
|
||||
newcmd = 1;
|
||||
clearerr(stdin);
|
||||
error("Interrupt");
|
||||
}
|
||||
|
@ -846,7 +889,7 @@ dohelp(void)
|
|||
static void
|
||||
chkprint(int flag)
|
||||
{
|
||||
char c;
|
||||
int c;
|
||||
|
||||
if (flag) {
|
||||
if ((c = input()) == 'p' || c == 'l' || c == 'n')
|
||||
|
@ -854,12 +897,12 @@ chkprint(int flag)
|
|||
else
|
||||
back(c);
|
||||
}
|
||||
if (input() != '\n')
|
||||
if ((c = input()) != '\0' && c != '\n')
|
||||
error("invalid command suffix");
|
||||
}
|
||||
|
||||
static char *
|
||||
getfname(char comm)
|
||||
getfname(int comm)
|
||||
{
|
||||
int c;
|
||||
char *bp;
|
||||
|
@ -867,7 +910,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) {
|
||||
|
@ -889,16 +932,21 @@ getfname(char comm)
|
|||
static void
|
||||
append(int num)
|
||||
{
|
||||
char *s = NULL;
|
||||
size_t len = 0;
|
||||
int ch;
|
||||
static String line;
|
||||
|
||||
curln = num;
|
||||
while (getline(&s, &len, stdin) > 0) {
|
||||
if (*s == '.' && s[1] == '\n')
|
||||
while (moreinput()) {
|
||||
string(&line);
|
||||
while ((ch = input()) != '\n' && ch != '\0')
|
||||
addchar(ch, &line);
|
||||
addchar('\n', &line);
|
||||
addchar('\0', &line);
|
||||
|
||||
if (!strcmp(line.str, ".\n") || !strcmp(line.str, "."))
|
||||
break;
|
||||
inject(s, AFTER);
|
||||
inject(line.str, AFTER);
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1022,14 +1070,22 @@ execsh(void)
|
|||
error("no previous command");
|
||||
}
|
||||
|
||||
while ((c = input()) != EOF && c != '\n') {
|
||||
if (c == '%' && (cmd.siz == 0 || cmd.str[cmd.siz - 1] != '\\')) {
|
||||
while ((c = input()) != '\0') {
|
||||
switch (c) {
|
||||
case '%':
|
||||
if (savfname[0] == '\0')
|
||||
error("no current filename");
|
||||
repl = 1;
|
||||
for (p = savfname; *p; ++p)
|
||||
addchar(*p, &cmd);
|
||||
} else {
|
||||
break;
|
||||
case '\\':
|
||||
c = input();
|
||||
if (c != '%') {
|
||||
back(c);
|
||||
c = '\\';
|
||||
}
|
||||
default:
|
||||
addchar(c, &cmd);
|
||||
}
|
||||
}
|
||||
|
@ -1049,20 +1105,18 @@ 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);
|
||||
}
|
||||
|
||||
if (!strcmp("%", s.str)) {
|
||||
free(s.str);
|
||||
if (!rhs)
|
||||
error("no previous substitution");
|
||||
free(s.str);
|
||||
} else {
|
||||
free(rhs);
|
||||
rhs = s.str;
|
||||
|
@ -1183,8 +1237,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();
|
||||
|
@ -1196,21 +1249,16 @@ repeat:
|
|||
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':
|
||||
if (gflag && uflag)
|
||||
return;
|
||||
case '\0':
|
||||
num = gflag ? curln : curln+1;
|
||||
deflines(num, num);
|
||||
line1 = line2;
|
||||
pflag = 'p';
|
||||
goto print;
|
||||
case 'l':
|
||||
|
@ -1360,7 +1408,7 @@ repeat:
|
|||
ensureblank();
|
||||
if (nlines > 0)
|
||||
goto unexpected;
|
||||
if (back(input()) != '\n')
|
||||
if (back(input()) != '\0')
|
||||
getfname(cmd);
|
||||
else
|
||||
puts(savfname);
|
||||
|
@ -1392,21 +1440,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
|
||||
|
@ -1451,12 +1489,26 @@ chkglobal(void)
|
|||
}
|
||||
|
||||
static void
|
||||
doglobal(void)
|
||||
savecmd(void)
|
||||
{
|
||||
int cnt, ln, k;
|
||||
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, idx;
|
||||
|
||||
skipblank();
|
||||
string(&cmdline);
|
||||
gflag = 1;
|
||||
if (uflag)
|
||||
chkprint(0);
|
||||
|
@ -1469,19 +1521,33 @@ doglobal(void)
|
|||
zero[k].global = 0;
|
||||
curln = ln;
|
||||
nlines = 0;
|
||||
if (uflag) {
|
||||
line1 = line2 = ln;
|
||||
pflag = 0;
|
||||
doprint();
|
||||
|
||||
if (!uflag) {
|
||||
idx = inputidx;
|
||||
getlst();
|
||||
docmd();
|
||||
inputidx = idx;
|
||||
continue;
|
||||
}
|
||||
getlst();
|
||||
docmd();
|
||||
|
||||
line1 = line2 = ln;
|
||||
pflag = 0;
|
||||
doprint();
|
||||
|
||||
for (;;) {
|
||||
getinput();
|
||||
if (strcmp(cmdline.str, "") == 0)
|
||||
break;
|
||||
savecmd();
|
||||
getlst();
|
||||
docmd();
|
||||
}
|
||||
|
||||
} else {
|
||||
cnt++;
|
||||
ln = nextln(ln);
|
||||
}
|
||||
}
|
||||
discard(); /* cover the case of not matching anything */
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1509,12 +1575,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();
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ main(int argc, char *argv[])
|
|||
char *s = basename(argv[0]);
|
||||
struct cmd *bp;
|
||||
|
||||
if(!strcmp(s,"sbase-box")) {
|
||||
if (!strcmp(s, "sbase-box") && argc > 1) {
|
||||
argc--; argv++;
|
||||
if (strcmp(argv[0], "-i") == 0) {
|
||||
install(argv[1]);
|
||||
|
|
Loading…
Reference in New Issue