This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: cpplib: adjust column counter for tabs
Zack Weinberg wrote:-
> That's not quite correct. The effect of a tab is to move right one
> space unconditionally, then continue right until the column number is
> divisible by some value. That value is normally 8, but needs to be
> adjustable by command-line option - some people insist on 4-space
> tabs, for example. I'd suggest -ftabstop=<N> for the option name.
OK, implemented. Patch below also updates online and texinfo docs,
and removes ptrdiff_t that was preventing some bootstrap somewhere.
I image I need to update the specs, too? If so, I'll patch that
later.
Neil.
* cppinit.c (cpp_reader_init): Initialise col_adjust and
default tab stop size.
(no_num, OPT_ftabstop): New.
(handle_option): Handle "ftabstop=" command-line option.
(print_help): Document it.
* cpplex.c (COLUMN): Remove.
(handle_newline): Reset col_adjust.
(expand_name_space): Don't use ptrdiff_t.
(skip_whitespace): Update col_adjust as tabs encountered.
(_cpp_lex_line): Update to use col_adjust. Call
skip_whitespace for all whitespace.
* cpplib.h (struct cpp_options): New member tabstop.
(struct cpp_reader): New member col_adjust.
(CPP_BUF_COL): Update.
(CPP_BUF_COLUMN): New.
* cpp.texi: Document "-ftabstop=" command line option.
Index: cppinit.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cppinit.c,v
retrieving revision 1.80
diff -u -p -r1.80 cppinit.c
--- cppinit.c 2000/05/04 04:38:00 1.80
+++ cppinit.c 2000/05/16 11:08:55
@@ -540,11 +540,15 @@ cpp_reader_init (pfile)
pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size);
CPP_SET_WRITTEN (pfile, 0);
+ /* FIXME: Remove after transition to new lexer. Only set there. */
+ pfile->col_adjust = 0;
+
CPP_OPTION (pfile, dollars_in_ident) = 1;
CPP_OPTION (pfile, cplusplus_comments) = 1;
CPP_OPTION (pfile, warn_import) = 1;
CPP_OPTION (pfile, discard_comments) = 1;
CPP_OPTION (pfile, show_column) = 1;
+ CPP_OPTION (pfile, tabstop) = 8;
CPP_OPTION (pfile, pending) =
(struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
@@ -1079,6 +1083,7 @@ new_pending_directive (pend, text, handl
#define no_fil N_("File name missing after %s")
#define no_mac N_("Macro name missing after %s")
#define no_pth N_("Path name missing after %s")
+#define no_num N_("Number missing after %s")
/* This is the list of all command line options, with the leading
"-" removed. It must be sorted in ASCII collating order. */
@@ -1108,6 +1113,7 @@ new_pending_directive (pend, text, handl
DEF_OPT("fno-show-column", 0, OPT_fno_show_column) \
DEF_OPT("fpreprocessed", 0, OPT_fpreprocessed) \
DEF_OPT("fshow-column", 0, OPT_fshow_column) \
+ DEF_OPT("ftabstop=", no_num, OPT_ftabstop) \
DEF_OPT("g", no_arg, OPT_g) /* arg optional */ \
DEF_OPT("h", 0, OPT_h) \
DEF_OPT("idirafter", no_dir, OPT_idirafter) \
@@ -1312,6 +1318,15 @@ handle_option (pfile, argc, argv)
case OPT_fno_show_column:
CPP_OPTION (pfile, show_column) = 0;
break;
+ case OPT_ftabstop:
+ {
+ char *endptr;
+ long tabstop = strtol (arg, &endptr, 10);
+ /* Silently ignore silly values. */
+ if (tabstop >= 1 && tabstop <= 100)
+ CPP_OPTION (pfile, tabstop) = tabstop;
+ }
+ break;
case OPT_w:
CPP_OPTION (pfile, inhibit_warnings) = 1;
break;
@@ -1833,6 +1848,7 @@ Switches:\n\
-dD Preserve macro definitions in output\n\
-dN As -dD except that only the names are preserved\n\
-dI Include #include directives in the output\n\
+ -ftabstop=<number> Distance between tab stops for column reporting\n\
-P Do not generate #line directives\n\
-$ Do not allow '$' in identifiers\n\
-remap Remap file names when including files.\n\
Index: cpplex.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpplex.c,v
retrieving revision 1.42
diff -u -p -r1.42 cpplex.c
--- cpplex.c 2000/05/15 22:44:20 1.42
+++ cpplex.c 2000/05/16 11:09:00
@@ -96,7 +97,6 @@ typedef unsigned int (* speller) PARAMS
(name).text = (list)->namebuf + (list)->name_used;} while (0)
#define IS_DIRECTIVE(list) (TOK_TYPE (list, 0) == CPP_HASH)
-#define COLUMN(cur) ((cur) - buffer->line_base)
/* Maybe put these in the ISTABLE eventually. */
#define IS_HSPACE(c) ((c) == ' ' || (c) == '\t')
@@ -109,6 +109,7 @@ typedef unsigned int (* speller) PARAMS
if ((cur) < (limit) && *(cur) == '\r' + '\n' - c) \
(cur)++; \
CPP_BUMP_LINE_CUR (pfile, (cur)); \
+ pfile->col_adjust = 0; \
} while (0)
#define IMMED_TOKEN() (!(cur_token->flags & PREV_WHITESPACE))
@@ -526,21 +533,19 @@ expand_name_space (list, len)
unsigned int len;
{
const U_CHAR *old_namebuf;
- ptrdiff_t delta;
old_namebuf = list->namebuf;
list->name_cap += len;
list->namebuf = (unsigned char *) xrealloc (list->namebuf, list->name_cap);
/* Fix up token text pointers. */
- delta = list->namebuf - old_namebuf;
- if (delta)
+ if (list->namebuf != old_namebuf)
{
unsigned int i;
for (i = 0; i < list->tokens_used; i++)
if (token_spellings[list->tokens[i].type].type > SPELL_NONE)
- list->tokens[i].val.name.text += delta;
+ list->tokens[i].val.name.text += (list->namebuf - old_namebuf);
}
}
@@ -2508,7 +2513,9 @@ skip_line_comment2 (pfile)
return multiline;
}
-/* Skips whitespace, stopping at next non-whitespace character. */
+/* Skips whitespace, stopping at next non-whitespace character.
+ Adjusts pfile->col_adjust to account for tabs. This enables tokens
+ to be assigned the correct column. */
static void
skip_whitespace (pfile, in_directive)
cpp_reader *pfile;
@@ -2522,6 +2529,12 @@ skip_whitespace (pfile, in_directive)
{
unsigned char c = *cur++;
+ if (c == '\t')
+ {
+ unsigned int col = CPP_BUF_COLUMN (buffer, cur - 1);
+ pfile->col_adjust += (CPP_OPTION (pfile, tabstop) - 1
+ - col % CPP_OPTION(pfile, tabstop));
+ }
if (IS_HSPACE(c)) /* FIXME: Fix ISTABLE. */
continue;
if (!is_space(c) || IS_NEWLINE (c)) /* Main loop handles newlines. */
@@ -2849,6 +2862,7 @@ _cpp_lex_line (pfile, list)
register const unsigned char *cur = buffer->cur;
unsigned char flags = 0;
+ pfile->col_adjust = 0;
expanded:
token_limit = list->tokens + list->tokens_cap;
cur_token = list->tokens + list->tokens_used;
@@ -2857,17 +2871,16 @@ _cpp_lex_line (pfile, list)
{
unsigned char c = *cur++;
- /* Optimize whitespace skipping, in particular the case of a
- single whitespace character, as every other token is probably
- whitespace. (' ' '\t' '\v' '\f' '\0'). */
+ /* Optimize whitespace skipping, as most tokens are probably
+ separated by whitespace. (' ' '\t' '\v' '\f' '\0'). */
+
if (is_hspace ((unsigned int) c))
{
- if (c == '\0' || (cur < buffer->rlimit && is_hspace (*cur)))
- {
- buffer->cur = cur - (c == '\0'); /* Get the null warning. */
- skip_whitespace (pfile, IS_DIRECTIVE (list));
- cur = buffer->cur;
- }
+ /* Step back to get the null warning and tab correction. */
+ buffer->cur = cur - 1;
+ skip_whitespace (pfile, IS_DIRECTIVE (list));
+ cur = buffer->cur;
+
flags = PREV_WHITESPACE;
if (cur == buffer->rlimit)
break;
@@ -2875,7 +2888,7 @@ _cpp_lex_line (pfile, list)
}
/* Initialize current token. Its type is set in the switch. */
- cur_token->col = COLUMN (cur);
+ cur_token->col = CPP_BUF_COLUMN (buffer, cur);
cur_token->flags = flags;
flags = 0;
@@ -2949,7 +2962,7 @@ _cpp_lex_line (pfile, list)
}
do_parse_string:
- /* Here c is one of ' " > or ). */
+ /* Here c is one of ' " or >. */
INIT_NAME (list, cur_token->val.name);
buffer->cur = cur;
parse_string2 (pfile, list, &cur_token->val.name, c);
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpplib.h,v
retrieving revision 1.93
diff -u -p -r1.93 cpplib.h
--- cpplib.h 2000/05/15 22:44:22 1.93
+++ cpplib.h 2000/05/16 11:09:05
@@ -302,6 +302,9 @@ struct cpp_options
const char *in_fname;
const char *out_fname;
+ /* Characters between tab stops. */
+ unsigned int tabstop;
+
/* Pending options - -D, -U, -A, -I, -ixxx. */
struct cpp_pending *pending;
@@ -510,6 +513,9 @@ struct cpp_reader
struct if_stack *if_stack;
const unsigned char *potential_control_macro;
+ /* Token column position adjustment owing to tabs in whitespace. */
+ unsigned int col_adjust;
+
/* Buffer of -M output. */
struct deps *deps;
@@ -586,7 +592,8 @@ struct cpp_printer
#define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
#define CPP_BUF_LINE(BUF) ((BUF)->lineno)
-#define CPP_BUF_COL(BUF) ((BUF)->cur - (BUF)->line_base)
+#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + pfile->col_adjust)
+#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
/* Name under which this program was invoked. */
extern const char *progname;
Index: cpp.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpp.texi,v
retrieving revision 1.19
diff -u -p -r1.19 cpp.texi
--- cpp.texi 2000/04/11 07:20:47 1.19
+++ cpp.texi 2000/05/16 11:09:10
@@ -3107,6 +3107,13 @@ Because of the clash with @samp{-l}, you
above. In a future release, this option will be replaced by
@samp{-flint} or @samp{-Wlint}; we are not sure which yet.
+@item -ftabstop=NUMBER
+@findex -ftabstop
+Indicates the distance between tabstops. This helps the preprocessor
+report correct column numbers in warnings or errors, even if tabs appear
+on the line. Values less than 1 or greater than 100 are ignored. The
+default is 8.
+
@item -$
@findex -$
Forbid the use of @samp{$} in identifiers. The C standard does not