nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit 0e29c2a24a16da897e52712ec5c127310a50618e
parent 9e182722ccd2d51592cc894692159f6feefa8a37
Author: Brand Huntsman <alpha@qzx.com>
Date:   Mon, 13 May 2019 17:43:53 -0600

rcfile: store errors and display them when nano terminates

This is needed to implement the demand loading of syntax files, as any
errors that these files may contain would otherwise overwrite things on
the screen and the messages wouldn't be on the terminal when nano exits.

It also allows nano to start up on a Linux console when there are errors.

Signed-off-by: Brand Huntsman <alpha@qzx.com>

Diffstat:
Msrc/nano.c | 8++++++++
Msrc/proto.h | 1+
Msrc/rcfile.c | 40+++++++++++++++++++++++++++-------------
3 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/src/nano.c b/src/nano.c @@ -526,6 +526,10 @@ void finish(void) /* Restore the old terminal settings. */ tcsetattr(0, TCSANOW, &oldterm); +#ifdef ENABLE_NANORC + display_rcfile_errors(); +#endif + #ifdef ENABLE_HISTORIES /* If the user wants history persistence, write the relevant files. */ if (ISSET(HISTORYLOG)) @@ -553,6 +557,10 @@ void die(const char *msg, ...) /* Restore the old terminal settings. */ tcsetattr(0, TCSANOW, &oldterm); +#ifdef ENABLE_NANORC + display_rcfile_errors(); +#endif + /* Display the dying message. */ va_start(ap, msg); vfprintf(stderr, msg, ap); diff --git a/src/proto.h b/src/proto.h @@ -464,6 +464,7 @@ int do_yesno_prompt(bool all, const char *msg); /* Most functions in rcfile.c. */ #ifdef ENABLE_NANORC +void display_rcfile_errors(); #ifdef ENABLE_COLOR void grab_and_store(const char *kind, char *ptr, regexlisttype **storage); #endif diff --git a/src/rcfile.c b/src/rcfile.c @@ -144,22 +144,46 @@ static colortype *lastcolor = NULL; /* The end of the color list for the current syntax. */ #endif +static linestruct *errors_head = NULL; +static linestruct *errors_tail = NULL; + /* Beginning and end of a list of errors in rcfiles, if any. */ + +/* Send the gathered error messages (if any) to the terminal. */ +void display_rcfile_errors() +{ + for (linestruct *error = errors_head; error != NULL; error = error->next) + fprintf(stderr, "%s\n", error->data); +} + +#define MAXSIZE (PATH_MAX + 200) + /* Report an error in an rcfile, printing it to stderr. */ void rcfile_error(const char *msg, ...) { + linestruct *error = make_new_node(errors_tail); + char textbuf[MAXSIZE]; + int length = 0; va_list ap; + if (errors_head == NULL) + errors_head = error; + else + errors_tail->next = error; + errors_tail = error; + if (rcfile_with_errors == NULL) rcfile_with_errors = strdup(nanorc); if (lineno > 0) - fprintf(stderr, _("Error in %s on line %zu: "), nanorc, lineno); + length = snprintf(textbuf, MAXSIZE, _("Error in %s on line %zu: "), + nanorc, lineno); va_start(ap, msg); - vfprintf(stderr, _(msg), ap); + length += vsnprintf(textbuf + length, MAXSIZE - length, _(msg), ap); va_end(ap); - fprintf(stderr, "\n"); + error->data = nmalloc(length + 1); + sprintf(error->data, "%s", textbuf); } #endif /* ENABLE_NANORC */ @@ -1255,16 +1279,6 @@ void do_rcfiles(void) check_vitals_mapped(); -#ifdef __linux__ - /* On a Linux console, don't start nano when there are rcfile errors, - * because otherwise these error messages get wiped. */ - if (on_a_vt && rcfile_with_errors) { - fprintf(stderr, _("If needed, use nano with the -I option " - "to adjust your nanorc settings.\n")); - exit(1); - } -#endif - free(nanorc); }