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>
This commit is contained in:
Brand Huntsman 2019-05-13 17:43:53 -06:00 committed by Benno Schulenberg
parent 9e182722cc
commit 0e29c2a24a
3 changed files with 36 additions and 13 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);
}