-/* $OpenBSD: extend.c,v 1.74 2021/03/25 12:46:11 lum Exp $ */
+/* $OpenBSD: extend.c,v 1.75 2021/05/06 14:16:12 lum Exp $ */
/* This file is in the public domain. */
/*
return (FALSE);
llen = strlen(bufp);
- return (excline(exbuf, llen));
+ return (excline(exbuf, llen, 1));
}
/*
{
struct line *lp;
struct buffer *bp = curbp;
- int s, llen;
+ int s, llen, lnum = 0;
static char excbuf[BUFSIZE];
for (lp = bfirstlp(bp); lp != bp->b_headp; lp = lforw(lp)) {
+ lnum++;
llen = llength(lp);
if (llen >= BUFSIZE)
return (FALSE);
/* make sure the line is terminated */
excbuf[llen] = '\0';
- if ((s = excline(excbuf, llen)) != TRUE) {
+ if ((s = excline(excbuf, llen, lnum)) != TRUE) {
cleanup();
return (s);
}
== FIOSUC) {
line++;
excbuf[nbytes] = '\0';
- if (excline(excbuf, nbytes) != TRUE) {
+ if (excline(excbuf, nbytes, line) != TRUE) {
s = FIOERR;
dobeep();
ewprintf("Error loading file %s at line %d", fncpy, line);
}
(void)ffclose(ffp, NULL);
excbuf[nbytes] = '\0';
- if (s != FIOEOF || (nbytes && excline(excbuf, nbytes) != TRUE))
+ if (s != FIOEOF || (nbytes && excline(excbuf, nbytes, ++line) != TRUE))
return (FALSE);
return (TRUE);
}
* excline - run a line from a load file or eval-expression.
*/
int
-excline(char *line, int llen)
+excline(char *line, int llen, int lnum)
{
PF fp;
struct line *lp, *np;
if (*funcp == '\0')
return (TRUE); /* No error on blank lines */
if (*funcp == '(')
- return (foundparen(funcp, llen));
+ return (foundparen(funcp, llen, lnum));
line = parsetoken(funcp);
if (*line != '\0') {
*line++ = '\0';
-/* $OpenBSD: interpreter.c,v 1.26 2021/05/06 07:16:24 lum Exp $ */
+/* $OpenBSD: interpreter.c,v 1.27 2021/05/06 14:16:12 lum Exp $ */
/*
* This file is in the public domain.
*
* n. implement user definable functions.
*
* Notes:
- * - Currently calls to excline() from this file have the line length set to
- * zero. That's because excline() uses '\0' as the end of line indicator
+ * - Currently calls to excline() from this file have the line length and
+ * line number set to zero.
+ * That's because excline() uses '\0' as the end of line indicator
* and only the call to foundparen() within excline() uses excline's 2nd
- * argument. Importantly, any lines sent to there from here will not be
+ * and 3rd arguments.
+ * Importantly, any lines sent to there from here will not be
* coming back here.
*/
#include <sys/queue.h>
"lambda"
};
-const char lp = '(';
-const char rp = ')';
-char *defnam = NULL;
+static const char lp = '(';
+static const char rp = ')';
+static char *defnam = NULL;
+static int lnm;
/*
* Line has a '(' as the first non-white char.
* Multi-line not supported at the moment, To do.
*/
int
-foundparen(char *funstr, int llen)
+foundparen(char *funstr, int llen, int lnum)
{
const char *lrp = NULL;
char *p, *begp = NULL, *endp = NULL, *regs, *prechr;
pctr = expctr = inquote = esc = 0;
blkid = 1;
+ lnm = lnum;
/*
* Currently can't do () or (( at the moment,
*/
regs = "[(]+[\t ]*[)]+";
if (doregex(regs, funstr))
- return(dobeep_msg("Empty lists not supported at moment"));
+ return(dobeep_num("Empty lists not supported at moment line",
+ lnm));
regs = "[(]+[\t ]*[(]+";
if (doregex(regs, funstr))
- return(dobeep_msg("Multiple consecutive left parantheses "\
- "found."));
+ return(dobeep_num("Multiple consecutive left parantheses "\
+ "found line:", lnm));
/*
* load expressions into a list called 'expentry', to be processd
* when all are obtained.
for (i = 0; i < llen; ++i, p++) {
if (pctr == 0 && *p != ' ' && *p != '\t' && *p != '(') {
if (*p == ')')
- return(dobeep_msg("Extra ')' found"));
- return(dobeep_msg("parse error"));
+ return(dobeep_num("Extra ')' found on line:",
+ lnm));
+ return(dobeep_num("Error line:", lnm));
}
if (*p == '\\') {
esc = 1;
pctr++;
} else if (inquote != 1) {
cleanup();
- return(dobeep_msg("Opening and closing quote "\
- "char error"));
+ return(dobeep_num("Opening and closing quote "\
+ "char error line:", lnm));
}
esc = 0;
} else if (*p == ')') {
pctr--;
} else if (inquote != 1) {
cleanup();
- return(dobeep_msg("Opening and closing quote "\
- "char error"));
+ return(dobeep_num("Opening and closing quote "\
+ "char error line:", lnm));
}
esc = 0;
} else if (*p != ' ' && *p != '\t') {
if (*p == '"') {
if (inquote == 0 && esc == 0) {
if (*prechr != ' ' && *prechr != '\t')
- return(dobeep_msg("parse err"));
+ return(dobeep_num("Parse error"\
+ " line:", lnm));
inquote++;
} else if (inquote > 0 && esc == 1)
esc = 0;
else
inquote--;
} else if (*prechr == '"' && inquote == 0) {
- return(dobeep_msg("parse err"));
+ return(dobeep_num("Parse error line:", lnm));
}
endp = NULL;
} else if (endp == NULL && (*p == ' ' || *p == '\t')) {
if (pctr != 0) {
cleanup();
- return(dobeep_msg("Opening and closing parentheses error"));
+ return(dobeep_num("Opening and closing parentheses error line:",
+ lnm));
}
if (ret == FALSE)
cleanup();
/* mg function name regex */
regs = "^[A-Za-z-]+$";
if (doregex(regs, begp))
- return(excline(begp, 0));
+ return(excline(begp, 0, 0));
/* Corner case 1 */
if (strncmp(begp, "global-set-key ", 15) == 0)
/* function name as 2nd param screws up multiarg. */
- return(excline(begp, 0));
+ return(excline(begp, 0, 0));
/* Corner case 2 */
if (strncmp(begp, "define-key ", 11) == 0)
/* function name as 3rd param screws up multiarg. */
- return(excline(begp, 0));
+ return(excline(begp, 0, 0));
return (parsexp(begp, par1, par2, blkid, expctr));
}
char *regs;
if ((defnam == NULL) && (expctr != 1))
- return(dobeep_msg("'define' incorrectly used"));
+ return(dobeep_num("'define' incorrectly used line:", lnm));
/* Does the line have a incorrect variable 'define' like: */
/* (define i y z) */
regs = "^define[ ]+[A-Za-z][.0-9_A-Z+a-z-]*[ ]+.+[ ]+.+$";
if (doregex(regs, begp))
- return(dobeep_msg("Invalid use of define"));
+ return(dobeep_num("Invalid use of define line:", lnm));
/* Does the line have a single variable 'define' like: */
/* (define i 0) */
if (doregex(regs, begp)) {
if (par1 == &lp && par2 == &rp && expctr == 1)
return(founddef(begp, blkid, expctr, 1));
- return(dobeep_msg("Invalid use of define."));
+ return(dobeep_num("Invalid use of define line:", lnm));
}
/* Does the line have '(define i(' */
regs = "^define[ ]+[A-Za-z][.0-9_A-Z+a-z-]*[ ]*$";
if (doregex(regs, begp)) {
if (par1 == &lp && par2 == &lp && expctr == 1)
return(founddef(begp, blkid, expctr, 0));
- return(dobeep_msg("Invalid use of 'define'"));
+ return(dobeep_num("Invalid use of 'define' line:", lnm));
}
/* Does the line have '(define (' */
regs = "^define$";
if (doregex(regs, begp)) {
if (par1 == &lp && par2 == &lp && expctr == 1)
return(foundfun(begp, expctr));
- return(dobeep_msg("Invalid use of 'define'."));
+ return(dobeep_num("Invalid use of 'define' line:", lnm));
}
return (ABORT);
/* Does the line have 'list' */
regs = "^list$";
if (doregex(regs, begp))
- return(dobeep_msg("Invalid use of list"));
+ return(dobeep_num("Invalid use of list line:", lnm));
/* Does the line have a 'list' like: */
/* (list "a" "b") */
regs = "^list[ ]+.*$";
if (doregex(regs, begp)) {
if (expctr == 1)
- return(dobeep_msg("list with no-where to go."));
+ return(dobeep_num("list with no-where to go.", lnm));
if (par1 == &lp && expctr > 1)
return(foundlst(begp, blkid, expctr));
- return(dobeep_msg("Invalid use of list."));
+ return(dobeep_num("Invalid use of list line:", lnm));
}
return (FALSE);
}
>= sizeof(excbuf))
return (dobeep_msg("strlcat error"));
- excline(excbuf, 0);
+ excline(excbuf, 0, 0);
if (fin)
break;
if (regcomp(®ex_buff, r, REG_EXTENDED)) {
regfree(®ex_buff);
- return(dobeep_msg("Regex compilation error"));
+ return(dobeep_num("Regex compilation error line:", lnm));
}
if (!regexec(®ex_buff, e, 0, NULL, 0)) {
regfree(®ex_buff);