Subject: Re: bug#18749: 24.3.94; CC Mode 5.32.5 (C/l); cc-mode state cache failure leading to bad indentation

From: Alan Mackenzie <[email-masked]>
Date: 17 Oct 2014 18:19:50 -0000

Hello, Michael.

It's been a fun day.  ;-)

In article <[email-masked]> you wrote:
> [-- text/plain, encoding 7bit, charset: US-ASCII, 6 lines --]

> A consistent c-mode indentation error that causes bad indentation, much
> cursing, and gnashing of teeth.  This occurs in the latest emacs-24
> branch (and trunk).

> From emacs -Q, using the attached file:

> [-- text/plain, encoding 7bit, charset: US-ASCII, 2434 lines, name: rwuniqsetup.c.before.2 --]

[ .... ]

> [-- text/plain, encoding quoted-printable, charset: utf-8, 291 lines --]

>     M-x c-toggle-parse-state-debug
>     C-x C-f rwuniqsetup.c.before.2
>     C-s ipaddr_rec_to_bin RET
>     C-v

> At this point you should see the following in *Messages*:

[ The following has been altered from the original to show the correct
  first inconsistency which occurred.]
> Mark saved where search started
> c-parse-state inconsistency at 46719: using cache: ((46217 . 46572) 45454 (43406 . 45002)), from scratch: (45454 (43406 . 45002))
> Old state:
> (setq c-state-cache '((46217 . 46572) 45454 (43406 . 45002))  c-state-cache-good-pos 46747  c-state-nonlit-pos-cache '(76939 73939 70939 67939 64939 61939 58939 55939 52939 49939 46939 43114 39291 36291 33291 30291 27178 24178 21178 18178 15145 12046 9013 6002 3002)  c-state-nonlit-pos-cache-limit 76939  c-state-semi-nonlit-pos-cache '(45291 42291 39291 36291 33291 30291 27094 24058 21058 18058 15058 12046 9013 6001 3001)  c-state-semi-nonlit-pos-cache-limit 45291 c-state-brace-pair-desert '(1 . 45935)  c-state-point-min 1  c-state-point-min-lit-type nil  c-state-point-min-lit-start nil  c-state-min-scan-pos 1  c-state-old-cpp-beg #<marker at 45006 in rwuniqsetup.c.before.2>  c-state-old-cpp-end #<marker at 46938 in rwuniqsetup.c.before.2>  c-parse-state-point 46793)

> At this point, indentation is having problems.  Try hitting TAB on line
> 1371, for example.  Or line 1374 for a complete failure to indent at
> all.

OK, for once c-parse-state seems to be blameless.

What seems to be happening is that during the display fontification,
operations are done at buffer offset 46793.  This is the spot after the
indentation on L1360.

CC Mode puts a backwards search limit on many operations, and this is
often implemented by temporarily narrowing the buffer (narrow-to-region
(- (point) n) (point-max)), where n is sometimes 1000.

1000 bytes before 46793 is 45793.  This spot is in the middle of the "##"
operator on L1346.  Thus the buffer is getting narrowed such that the
first character, ostensibly at BOL (to the Emacs regexp matcher), is "#".

A `c-beginning-of-macro' operation is thus spuriously finding point
45793, in the middle of this operator.  This spot is then getting
permanently marked as a beginning-of-CPP.  (Technically, this is done
with the 'category property, giving it a value 'c-cpp-delimiter.)

When c-parse-state later tries to scan this part of the code, it trips up
on this spurious beginning-of-CPP, terminating its scanning.  If you look
at the two inconsistent values for c-parse-state above, the "from
scratch" value is actually the false one, where it fails to find the
brace pair (46217 . 46572) which is after 45793.

I think what I'm going to do is insert an extra check into
c-beginning-of-macro, such that if there seems to be a match at
(point-min) of a narrowed buffer (or possibly even on the top line of
one), it will be widened and tested again.

Look forward to a patch soon!

> -- 
> Michael Welsh Duggan
> ([email-masked])

-- 
Alan Mackenzie (Nuremberg, Germany).