[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 08/12] diagnostics: update the grammar file
From: |
Akim Demaille |
Subject: |
[PATCH 08/12] diagnostics: update the grammar file |
Date: |
Sun, 13 Jan 2019 15:24:03 +0100 |
Let's use the fixits to actually update the grammar files.
* src/getargs.h, src/getargs.c (update_flag): New.
* src/fixits.h, src/fixits.c (fixits_run): New.
* src/main.c (main): Invoke fixits_run when --update is passed.
* tests/input.at (Deprecated directives): Check --update.
---
bootstrap.conf | 1 +
lib/.gitignore | 3 ++
src/files.h | 2 +-
src/fixits.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++-
src/fixits.h | 3 ++
src/getargs.c | 22 ++++++++----
src/getargs.h | 2 +-
src/main.c | 7 +++-
tests/input.at | 89 +++++++++++++++++++++++++++++++++------------
9 files changed, 194 insertions(+), 32 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index 1b1dd00c..2450ff07 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -38,6 +38,7 @@ gnulib_modules='
readme-release
realloc-posix
relocatable-prog relocatable-script
+ rename
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
timevar
unistd unistd-safer unlink unlocked-io
diff --git a/lib/.gitignore b/lib/.gitignore
index d2ac6986..919f23c4 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -315,3 +315,6 @@
/xstrndup.h
/xtime.c
/xtime.h
+/rename.c
+/rmdir.c
+/same-inode.h
diff --git a/src/files.h b/src/files.h
index 2ec10c95..9c60dcd5 100644
--- a/src/files.h
+++ b/src/files.h
@@ -55,7 +55,7 @@ extern char *dir_prefix;
and therefore GCC warns about a name clash. */
extern uniqstr grammar_file;
-/* The current file name. Might change with %include, or with #line. */
+/* The current file name. Might change with #line. */
extern uniqstr current_file;
/* The computed base for output file names. */
diff --git a/src/fixits.c b/src/fixits.c
index d1001280..769b8508 100644
--- a/src/fixits.c
+++ b/src/fixits.c
@@ -23,10 +23,17 @@
#include "system.h"
+#include "error.h"
+#include "get-errno.h"
#include "getargs.h"
-#include "gl_xlist.h"
#include "gl_array_list.h"
+#include "gl_xlist.h"
+#include "progname.h"
+#include "quote.h"
#include "quotearg.h"
+#include "vasnprintf.h"
+
+#include "files.h"
typedef struct
{
@@ -84,6 +91,94 @@ fixits_register (location const *loc, char const* fix)
}
+void
+fixits_run (void)
+{
+ if (!fixits)
+ return;
+
+ /* This is not unlike what is done in location_caret. */
+ uniqstr input = ((fixit *) gl_list_get_at (fixits, 0))->location.start.file;
+ /* Backup the file. */
+ char buf[256];
+ size_t len = sizeof (buf);
+ char *backup = asnprintf (buf, &len, "%s~", input);
+ if (!backup)
+ xalloc_die ();
+ if (rename (input, backup))
+ error (EXIT_FAILURE, get_errno (),
+ _("%s: cannot backup"), quotearg_colon (input));
+ FILE *in = xfopen (backup, "r");
+ FILE *out = xfopen (input, "w");
+ size_t line = 1;
+ size_t offset = 1;
+ fixit const *f = NULL;
+ gl_list_iterator_t iter = gl_list_iterator (fixits);
+ while (gl_list_iterator_next (&iter, (const void**) &f, NULL))
+ {
+ /* Look for the correct line. */
+ while (line < f->location.start.line)
+ {
+ int c = getc (in);
+ if (c == EOF)
+ break;
+ if (c == '\n')
+ {
+ ++line;
+ offset = 1;
+ }
+ putc (c, out);
+ }
+ /* Look for the right offset. */
+ while (offset < f->location.start.column)
+ {
+ int c = getc (in);
+ if (c == EOF)
+ break;
+ ++offset;
+ putc (c, out);
+ }
+
+ /* Paste the fix instead. */
+ fputs (f->fix, out);
+
+ /* Skip the bad input. */
+ while (line < f->location.end.line)
+ {
+ int c = getc (in);
+ if (c == EOF)
+ break;
+ if (c == '\n')
+ {
+ ++line;
+ offset = 1;
+ }
+ }
+ while (offset < f->location.end.column)
+ {
+ int c = getc (in);
+ if (c == EOF)
+ break;
+ ++offset;
+ }
+ }
+ /* Paste the rest of the file. */
+ {
+ int c;
+ while ((c = getc (in)) != EOF)
+ putc (c, out);
+ }
+
+ gl_list_iterator_free (&iter);
+ xfclose (out);
+ xfclose (in);
+ fprintf (stderr, "%s: file %s was updated (backup: %s)\n",
+ program_name, quote_n (0, input), quote_n (1, backup));
+ if (backup != buf)
+ free (backup);
+}
+
+
/* Free the registered fixits. */
void fixits_free (void)
{
diff --git a/src/fixits.h b/src/fixits.h
index 0c531ab4..5adaf685 100644
--- a/src/fixits.h
+++ b/src/fixits.h
@@ -23,6 +23,9 @@
/* Declare a fix to apply. */
void fixits_register (location const *loc, char const* update);
+/* Apply the fixits: update the source file. */
+void fixits_run (void);
+
/* Free the registered fixits. */
void fixits_free (void);
diff --git a/src/getargs.c b/src/getargs.c
index 9874c429..83ebcb09 100644
--- a/src/getargs.c
+++ b/src/getargs.c
@@ -36,12 +36,13 @@
#include "quote.h"
#include "uniqstr.h"
-bool defines_flag;
-bool graph_flag;
-bool xml_flag;
-bool no_lines_flag;
-bool token_table_flag;
-bool yacc_flag; /* for -y */
+bool defines_flag = false;
+bool graph_flag = false;
+bool xml_flag = false;
+bool no_lines_flag = false;
+bool token_table_flag = false;
+bool yacc_flag = false; /* for -y */
+bool update_flag = false; /* for -u */
bool nondeterministic_parser = false;
bool glr_parser = false;
@@ -283,7 +284,10 @@ Operation modes:\n\
-h, --help display this help and exit\n\
-V, --version output version information and exit\n\
--print-localedir output directory containing locale-dependent
data\n\
+ and exit\n\
--print-datadir output directory containing skeletons and XSLT\n\
+ and exit\n\
+ -u, --update apply fixes to the source grammar file\n\
-y, --yacc emulate POSIX Yacc\n\
-W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
-f, --feature[=FEATURE] activate miscellaneous features\n\
@@ -478,6 +482,7 @@ static char const short_options[] =
"p:"
"r:"
"t"
+ "u" /* --update */
"v"
"x::"
"y"
@@ -499,6 +504,7 @@ static struct option const long_options[] =
{ "version", no_argument, 0, 'V' },
{ "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
{ "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
+ { "update", no_argument, 0, 'u' },
{ "warnings", optional_argument, 0, 'W' },
/* Parser. */
@@ -684,6 +690,10 @@ getargs (int argc, char *argv[])
MUSCLE_PERCENT_DEFINE_D);
break;
+ case 'u':
+ update_flag = true;
+ break;
+
case 'v':
report_flag |= report_states;
break;
diff --git a/src/getargs.h b/src/getargs.h
index 925ef58e..f44f2183 100644
--- a/src/getargs.h
+++ b/src/getargs.h
@@ -40,7 +40,7 @@ extern bool xml_flag; /* for -x */
extern bool no_lines_flag; /* for -l */
extern bool token_table_flag; /* for -k */
extern bool yacc_flag; /* for -y */
-
+extern bool update_flag; /* for -u */
/* GLR_PARSER is true if the input file says to use the GLR
(Generalized LR) parser, and to output some additional information
diff --git a/src/main.c b/src/main.c
index f728e727..94782573 100644
--- a/src/main.c
+++ b/src/main.c
@@ -103,6 +103,12 @@ main (int argc, char *argv[])
reader ();
timevar_pop (tv_reader);
+ /* Fix input file now, even if there are errors: that's less
+ warnings in the following runs. */
+ if (update_flag)
+ fixits_run ();
+ fixits_free ();
+
if (complaint_status == status_complaint)
goto finish;
@@ -206,7 +212,6 @@ main (int argc, char *argv[])
conflicts_free ();
grammar_free ();
output_file_names_free ();
- fixits_free ();
/* The scanner memory cannot be released right after parsing, as it
contains things such as user actions, prologue, epilogue etc. */
diff --git a/tests/input.at b/tests/input.at
index 522eda54..ea30991c 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -2508,28 +2508,7 @@ AT_DATA_GRAMMAR([[input.y]],
exp : '0'
]])
-AT_BISON_CHECK([[input.y]], [[1]], [[]],
-[[input.y:10.1-13: warning: deprecated directive: '%default_prec', use
'%default-prec' [-Wdeprecated]
-input.y:11.1-14: warning: deprecated directive: '%error_verbose', use '%define
parse.error verbose' [-Wdeprecated]
-input.y:12.1-10: warning: deprecated directive: '%expect_rr', use '%expect-rr'
[-Wdeprecated]
-input.y:13.1-14: warning: deprecated directive: '%file-prefix =', use
'%file-prefix' [-Wdeprecated]
-input.y:14.1-15.2: warning: deprecated directive: '%file-prefix\n =', use
'%file-prefix' [-Wdeprecated]
-input.y:17.1-19: warning: deprecated directive: '%fixed-output_files', use
'%fixed-output-files' [-Wdeprecated]
-input.y:18.1-19: warning: deprecated directive: '%fixed_output-files', use
'%fixed-output-files' [-Wdeprecated]
-input.y:20.1-19: warning: deprecated directive: '%name-prefix= "foo"', use
'%define api.prefix {foo}' [-Wdeprecated]
-input.y:21.1-16: warning: deprecated directive: '%no-default_prec', use
'%no-default-prec' [-Wdeprecated]
-input.y:22.1-16: warning: deprecated directive: '%no_default-prec', use
'%no-default-prec' [-Wdeprecated]
-input.y:23.1-9: warning: deprecated directive: '%no_lines', use '%no-lines'
[-Wdeprecated]
-input.y:24.1-9: warning: deprecated directive: '%output =', use '%output'
[-Wdeprecated]
-input.y:25.1-12: warning: deprecated directive: '%pure_parser', use
'%pure-parser' [-Wdeprecated]
-input.y:26.1-12: warning: deprecated directive: '%token_table', use
'%token-table' [-Wdeprecated]
-input.y:27.1-14: warning: deprecated directive: '%error-verbose', use '%define
parse.error verbose' [-Wdeprecated]
-input.y:27-14: error: %define variable 'parse.error' redefined
-input.y:11-14: previous definition
-input.y:29.1-18: warning: deprecated directive: '%name-prefix "bar"', use
'%define api.prefix {bar}' [-Wdeprecated]
-]])
-
-AT_BISON_CHECK([[-ffixit input.y]], [[1]], [[]],
+AT_DATA([errors-all],
[[input.y:10.1-13: warning: deprecated directive: '%default_prec', use
'%default-prec' [-Wdeprecated]
fix-it:"input.y":{10:1-10:14}:"%default-prec"
input.y:11.1-14: warning: deprecated directive: '%error_verbose', use '%define
parse.error verbose' [-Wdeprecated]
@@ -2566,6 +2545,72 @@ input.y:29.1-18: warning: deprecated directive:
'%name-prefix "bar"', use '%defi
fix-it:"input.y":{29:1-29:19}:"%define api.prefix {bar}"
]])
+AT_CHECK([[sed -e '/^fix-it:/d' errors-all >experr]])
+AT_BISON_CHECK([[input.y]], [[1]], [[]], [experr])
+
+AT_CHECK([cp errors-all experr])
+AT_BISON_CHECK([[-ffixit input.y]], [[1]], [[]], [experr])
+
+# Update the input file.
+AT_CHECK([cp input.y input.y.orig])
+AT_CHECK([sed -e '/fix-it/d' <errors-all >experr])
+AT_CHECK([echo "bison: file 'input.y' was updated (backup: 'input.y~')"
>>experr])
+AT_BISON_CHECK([[--update input.y]], [[1]], [[]], [experr])
+
+# Check the backup.
+AT_CHECK([diff input.y.orig input.y~])
+
+# Check the update.
+AT_CHECK([cat input.y], [],
+[[%code top {
+/* Load config.h, and adjust to the compiler.
+ We used to do it here, but each time we add a new line,
+ we have to adjust all the line numbers in error messages.
+ It's simpler to use a constant include to a varying file. */
+#include <testsuite.h>
+}
+
+
+%default-prec
+%define parse.error verbose
+%expect-rr 0
+%file-prefix "foo"
+%file-prefix
+"bar"
+%fixed-output-files
+%fixed-output-files
+%fixed-output-files
+%define api.prefix {foo}
+%no-default-prec
+%no-default-prec
+%no-lines
+%output "foo"
+%pure-parser
+%token-table
+%define parse.error verbose
+%glr-parser
+%define api.prefix {bar}
+%%
+exp : '0'
+]])
+
+# Unfortunately so far we don't remove duplicate definitions,
+# so there are still warnings.
+AT_BISON_CHECK([[-fcaret input.y]], [[1]], [],
+[[input.y:26.1-27: error: %define variable 'parse.error' redefined
+ %define parse.error verbose
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~
+input.y:11.1-27: previous definition
+ %define parse.error verbose
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~
+input.y:28.1-24: error: %define variable 'api.prefix' redefined
+ %define api.prefix {bar}
+ ^~~~~~~~~~~~~~~~~~~~~~~~
+input.y:19.1-24: previous definition
+ %define api.prefix {foo}
+ ^~~~~~~~~~~~~~~~~~~~~~~~
+]])
+
AT_CLEANUP
--
2.20.1
- [PATCH 00/12] RFC: fixits and --update, Akim Demaille, 2019/01/13
- [PATCH 12/12] diagnostics: add fixit support for duplicate removal, Akim Demaille, 2019/01/13
- [PATCH 01/12] diagnostics: style: avoid allocating memory when not needed, Akim Demaille, 2019/01/13
- [PATCH 02/12] diagnostics: improve them for %name-prefix, Akim Demaille, 2019/01/13
- [PATCH 09/12] diagnostics: avoid duplicate warnings for deprecated directives, Akim Demaille, 2019/01/13
- [PATCH 10/12] diagnostics: improve the accuracy for %error-verbose, Akim Demaille, 2019/01/13
- [PATCH 06/12] diagnostics: keep the fixits, Akim Demaille, 2019/01/13
- [PATCH 04/12] diagnostics: prefer ^~~~ to ^^^^ to underline code, Akim Demaille, 2019/01/13
- [PATCH 05/12] diagnostics: add -ffixit support for deprecated features, Akim Demaille, 2019/01/13
- [PATCH 08/12] diagnostics: update the grammar file,
Akim Demaille <=
- [PATCH 07/12] diagnostics: improve accuracy for deprecated %define variables, Akim Demaille, 2019/01/13