emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r106674: Large brace-block initialisa


From: Alan Mackenzie
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106674: Large brace-block initialisation makes CC Mode slow: Fix.
Date: Tue, 13 Dec 2011 18:47:08 +0000
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106674
committer: Alan Mackenzie <address@hidden>
branch nick: trunk
timestamp: Tue 2011-12-13 18:47:08 +0000
message:
  Large brace-block initialisation makes CC Mode slow: Fix.
  Tidy up and accelerate c-in-literal, etc. by using the c-parse-state
  routines.  Limit backward searching in c-font-lock-enclosing.decl.
  
  cc-engine.el (c-state-pp-to-literal): Return the pp-state and literal
  type in addition to the limits.
  (c-state-safe-place): New defun, extracted from c-state-literal-at.
  (c-state-literal-at): Use the above new defun.
  (c-slow-in-literal, c-fast-in-literal): Removed.
  (c-in-literal, c-literal-limits): Amended to use c-state-pp-to-literal.
  
  cc-fonts.el (c-font-lock-enclosing-decls): Check for being in a literal.
  Add a limit for backward searching.
  
  cc-mode.el (awk-mode): Don't alias c-in-literal to c-slow-in-literal.
modified:
  lisp/ChangeLog
  lisp/progmodes/cc-engine.el
  lisp/progmodes/cc-fonts.el
  lisp/progmodes/cc-mode.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2011-12-13 15:33:25 +0000
+++ b/lisp/ChangeLog    2011-12-13 18:47:08 +0000
@@ -1,3 +1,25 @@
+2011-12-13  Alan Mackenzie  <address@hidden>
+
+       Large brace-block initialisation makes CC Mode slow: Fix.
+       Tidy up and accelerate c-in-literal, etc. by using the
+       c-parse-state
+       routines.  Limit backward searching in c-font-lock-enclosing.decl.
+
+       * progmodes/cc-engine.el (c-state-pp-to-literal): Return the
+       pp-state and literal type in addition to the limits.
+       (c-state-safe-place): New defun, extracted from
+       c-state-literal-at.
+       (c-state-literal-at): Use the above new defun.
+       (c-slow-in-literal, c-fast-in-literal): Removed.
+       (c-in-literal, c-literal-limits): Amended to use
+       c-state-pp-to-literal.
+
+       * progmodes/cc-fonts.el (c-font-lock-enclosing-decls): Check for
+       being in a literal.  Add a limit for backward searching.
+
+       * progmodes/cc-mode.el (awk-mode): Don't alias c-in-literal to
+       c-slow-in-literal.
+
 2011-12-13  Stefan Monnier  <address@hidden>
 
        * progmodes/pascal.el: Declare `ind' as dyn-bound (bug#10264).

=== modified file 'lisp/progmodes/cc-engine.el'
--- a/lisp/progmodes/cc-engine.el       2011-12-12 05:32:49 +0000
+++ b/lisp/progmodes/cc-engine.el       2011-12-13 18:47:08 +0000
@@ -195,9 +195,6 @@
       (not prevstate)
     (> arg 0)))
 
-;; Dynamically bound cache for `c-in-literal'.
-(defvar c-in-literal-cache t)
-
 
 ;; Basic handling of preprocessor directives.
 
@@ -2093,28 +2090,35 @@
 ;; `c-state-literal-at'.
 
 (defsubst c-state-pp-to-literal (from to)
-  ;; Do a parse-partial-sexp from FROM to TO, returning the bounds of any
-  ;; literal at TO as a cons, otherwise NIL.
-  ;; FROM must not be in a literal, and the buffer should already be wide
-  ;; enough.
+  ;; Do a parse-partial-sexp from FROM to TO, returning either
+  ;;     (STATE TYPE (BEG . END))     if TO is in a literal; or
+  ;;     (STATE)                      otherwise,
+  ;; where STATE is the parsing state at TO, TYPE is the type of the literal
+  ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the 
literal.
+  ;;
+  ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote),
+  ;; 7 (comment type) and 8 (start of comment/string) (and possibly 9) of
+  ;; STATE are valid.
   (save-excursion
-    (let ((s (parse-partial-sexp from to)))
+    (let ((s (parse-partial-sexp from to))
+         ty)
       (when (or (nth 3 s) (nth 4 s))   ; in a string or comment
+       (setq ty (cond
+                 ((nth 3 s) 'string)
+                 ((eq (nth 7 s) t) 'c++)
+                 (t 'c)))
        (parse-partial-sexp (point) (point-max)
                            nil                  ; TARGETDEPTH
                            nil                  ; STOPBEFORE
                            s                    ; OLDSTATE
-                           'syntax-table)       ; stop at end of literal
-       (cons (nth 8 s) (point))))))
+                           'syntax-table))      ; stop at end of literal
+      (if ty
+         `(,s ,ty (,(nth 8 s) . ,(point)))
+       `(,s)))))
 
-(defun c-state-literal-at (here)
-  ;; If position HERE is inside a literal, return (START . END), the
-  ;; boundaries of the literal (which may be outside the accessible bit of the
-  ;; buffer).  Otherwise, return nil.
-  ;;
-  ;; This function is almost the same as `c-literal-limits'.  It differs in
-  ;; that it is a lower level function, and that it rigorously follows the
-  ;; syntax from BOB, whereas `c-literal-limits' uses a "local" safe position.
+(defun c-state-safe-place (here)
+  ;; Return a buffer position before HERE which is "safe", i.e. outside any
+  ;; string, comment, or macro.
   ;;
   ;; NOTE: This function manipulates `c-state-nonlit-pos-cache'.  This cache
   ;; MAY NOT contain any positions within macros, since macros are frequently
@@ -2137,7 +2141,7 @@
 
        (while (<= (setq npos (+ pos c-state-nonlit-pos-interval))
                   here)
-         (setq lit (c-state-pp-to-literal pos npos))
+         (setq lit (car (cddr (c-state-pp-to-literal pos npos))))
          (setq pos (or (cdr lit) npos)) ; end of literal containing npos.
          (goto-char pos)
          (when (and (c-beginning-of-macro) (/= (point) pos))
@@ -2148,9 +2152,22 @@
 
        (if (> pos c-state-nonlit-pos-cache-limit)
            (setq c-state-nonlit-pos-cache-limit pos))
-       (if (< pos here)
-           (setq lit (c-state-pp-to-literal pos here)))
-       lit))))
+       pos))))
+       
+(defun c-state-literal-at (here)
+  ;; If position HERE is inside a literal, return (START . END), the
+  ;; boundaries of the literal (which may be outside the accessible bit of the
+  ;; buffer).  Otherwise, return nil.
+  ;;
+  ;; This function is almost the same as `c-literal-limits'.  Previously, it
+  ;; differed in that it was a lower level function, and that it rigourously
+  ;; followed the syntax from BOB.  `c-literal-limits' is now (2011-12)
+  ;; virtually identical to this function.
+  (save-restriction
+    (widen)
+    (save-excursion
+      (let ((pos (c-state-safe-place here)))
+           (car (cddr (c-state-pp-to-literal pos here)))))))
 
 (defsubst c-state-lit-beg (pos)
   ;; Return the start of the literal containing POS, or POS itself.
@@ -4181,7 +4198,7 @@
 
 ;; Tools for handling comments and string literals.
 
-(defun c-slow-in-literal (&optional lim detect-cpp)
+(defun c-in-literal (&optional lim detect-cpp)
   "Return the type of literal point is in, if any.
 The return value is `c' if in a C-style comment, `c++' if in a C++
 style comment, `string' if in a string literal, `pound' if DETECT-CPP
@@ -4194,67 +4211,12 @@
 
 Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
-
-  (if (and (vectorp c-in-literal-cache)
-          (= (point) (aref c-in-literal-cache 0)))
-      (aref c-in-literal-cache 1)
-    (let ((rtn (save-excursion
-                (let* ((pos (point))
-                       (lim (or lim (progn
-                                      (c-beginning-of-syntax)
-                                      (point))))
-                       (state (parse-partial-sexp lim pos)))
-                  (cond
-                   ((elt state 3) 'string)
-                   ((elt state 4) (if (elt state 7) 'c++ 'c))
-                   ((and detect-cpp (c-beginning-of-macro lim)) 'pound)
-                   (t nil))))))
-      ;; cache this result if the cache is enabled
-      (if (not c-in-literal-cache)
-         (setq c-in-literal-cache (vector (point) rtn)))
-      rtn)))
-
-;; XEmacs has a built-in function that should make this much quicker.
-;; I don't think we even need the cache, which makes our lives more
-;; complicated anyway.  In this case, lim is only used to detect
-;; cpp directives.
-;;
-;; Note that there is a bug in XEmacs's buffer-syntactic-context when used in
-;; conjunction with syntax-table-properties.  The bug is present in, e.g.,
-;; XEmacs 21.4.4.  It manifested itself thus:
-;;
-;; Starting with an empty AWK Mode buffer, type
-;; /regexp/ {<C-j>
-;; Point gets wrongly left at column 0, rather than being indented to 
tab-width.
-;;
-;; AWK Mode is designed such that when the first / is typed, it gets the
-;; syntax-table property "string fence".  When the second / is typed, BOTH /s
-;; are given the s-t property "string".  However, buffer-syntactic-context
-;; fails to take account of the change of the s-t property on the opening / to
-;; "string", and reports that the { is within a string started by the second /.
-;;
-;; The workaround for this is for the AWK Mode initialization to switch the
-;; defalias for c-in-literal to c-slow-in-literal.  This will slow down other
-;; cc-modes in XEmacs whenever an awk-buffer has been initialized.
-;;
-;; (Alan Mackenzie, 2003/4/30).
-
-(defun c-fast-in-literal (&optional lim detect-cpp)
-  ;; This function might do hidden buffer changes.
-  (let ((context (buffer-syntactic-context)))
-    (cond
-     ((eq context 'string) 'string)
-     ((eq context 'comment) 'c++)
-     ((eq context 'block-comment) 'c)
-     ((and detect-cpp (save-excursion (c-beginning-of-macro lim))) 'pound))))
-
-(defalias 'c-in-literal
-  (if (fboundp 'buffer-syntactic-context)
-    'c-fast-in-literal                  ; XEmacs
-    'c-slow-in-literal))                ; GNU Emacs
-
-;; The defalias above isn't enough to shut up the byte compiler.
-(cc-bytecomp-defun c-in-literal)
+  (let* ((safe-place (c-state-safe-place (point)))
+        (lit (c-state-pp-to-literal safe-place (point))))
+    (or (cadr lit)
+       (and detect-cpp
+            (save-excursion (c-beginning-of-macro))
+            'pound))))
 
 (defun c-literal-limits (&optional lim near not-in-delimiter)
   "Return a cons of the beginning and end positions of the comment or
@@ -4273,64 +4235,56 @@
 
   (save-excursion
     (let* ((pos (point))
-          (lim (or lim (progn
-                         (c-beginning-of-syntax)
-                         (point))))
-          (state (parse-partial-sexp lim pos)))
-
-      (cond ((elt state 3)             ; String.
-            (goto-char (elt state 8))
-            (cons (point) (or (c-safe (c-forward-sexp 1) (point))
-                              (point-max))))
-
-           ((elt state 4)              ; Comment.
-            (goto-char (elt state 8))
-            (cons (point) (progn (c-forward-single-comment) (point))))
-
-           ((and (not not-in-delimiter)
-                 (not (elt state 5))
-                 (eq (char-before) ?/)
-                 (looking-at "[/*]"))
-            ;; We're standing in a comment starter.
-            (backward-char 1)
-            (cons (point) (progn (c-forward-single-comment) (point))))
-
-           (near
-            (goto-char pos)
-
-            ;; Search forward for a literal.
-            (skip-chars-forward " \t")
-
-            (cond
-             ((looking-at c-string-limit-regexp) ; String.
-              (cons (point) (or (c-safe (c-forward-sexp 1) (point))
-                                (point-max))))
-
-             ((looking-at c-comment-start-regexp) ; Line or block comment.
-              (cons (point) (progn (c-forward-single-comment) (point))))
-
-             (t
-              ;; Search backward.
-              (skip-chars-backward " \t")
-
-              (let ((end (point)) beg)
-                (cond
-                 ((save-excursion
-                    (< (skip-syntax-backward c-string-syntax) 0)) ; String.
-                  (setq beg (c-safe (c-backward-sexp 1) (point))))
-
-                 ((and (c-safe (forward-char -2) t)
-                       (looking-at "*/"))
-                  ;; Block comment.  Due to the nature of line
-                  ;; comments, they will always be covered by the
-                  ;; normal case above.
-                  (goto-char end)
-                  (c-backward-single-comment)
-                  ;; If LIM is bogus, beg will be bogus.
-                  (setq beg (point))))
-
-                (if beg (cons beg end))))))
-           ))))
+          (lim (or lim (c-state-safe-place pos)))
+          (pp-to-lit (c-state-pp-to-literal lim pos))
+          (state (car pp-to-lit))
+          (lit-type (cadr pp-to-lit))
+          (lit-limits (car (cddr pp-to-lit))))
+
+      (cond
+       (lit-limits)
+       ((and (not not-in-delimiter)
+            (not (elt state 5))
+            (eq (char-before) ?/)
+            (looking-at "[/*]")) ; FIXME!!! use c-line/block-comment-starter.  
2008-09-28.
+       ;; We're standing in a comment starter.
+       (backward-char 1)
+       (cons (point) (progn (c-forward-single-comment) (point))))
+
+       (near
+       (goto-char pos)
+       ;; Search forward for a literal.
+       (skip-chars-forward " \t")
+       (cond
+        ((looking-at c-string-limit-regexp) ; String.
+         (cons (point) (or (c-safe (c-forward-sexp 1) (point))
+                           (point-max))))
+
+        ((looking-at c-comment-start-regexp) ; Line or block comment.
+         (cons (point) (progn (c-forward-single-comment) (point))))
+
+        (t
+         ;; Search backward.
+         (skip-chars-backward " \t")
+
+         (let ((end (point)) beg)
+           (cond
+            ((save-excursion
+               (< (skip-syntax-backward c-string-syntax) 0)) ; String.
+             (setq beg (c-safe (c-backward-sexp 1) (point))))
+
+            ((and (c-safe (forward-char -2) t)
+                  (looking-at "*/"))
+             ;; Block comment.  Due to the nature of line
+             ;; comments, they will always be covered by the
+             ;; normal case above.
+             (goto-char end)
+             (c-backward-single-comment)
+             ;; If LIM is bogus, beg will be bogus.
+             (setq beg (point))))
+
+           (if beg (cons beg end))))))
+       ))))
 
 ;; In case external callers use this; it did have a docstring.
 (defalias 'c-literal-limits-fast 'c-literal-limits)

=== modified file 'lisp/progmodes/cc-fonts.el'
--- a/lisp/progmodes/cc-fonts.el        2011-12-12 05:32:49 +0000
+++ b/lisp/progmodes/cc-fonts.el        2011-12-13 18:47:08 +0000
@@ -1539,10 +1539,11 @@
   ;; Fontification".
   (let* ((paren-state (c-parse-state))
         (start (point))
+        (bod-lim (max (- (point) 500) (point-min)))
         decl-context bo-decl in-typedef type-type ps-elt)
 
     ;; First, are we actually in a "local" declaration?
-    (setq decl-context (c-beginning-of-decl-1)
+    (setq decl-context (c-beginning-of-decl-1 bod-lim)
          bo-decl (point)
          in-typedef (looking-at c-typedef-key))
     (if in-typedef (c-forward-token-2))

=== modified file 'lisp/progmodes/cc-mode.el'
--- a/lisp/progmodes/cc-mode.el 2011-12-12 05:32:49 +0000
+++ b/lisp/progmodes/cc-mode.el 2011-12-13 18:47:08 +0000
@@ -1562,10 +1562,6 @@
   (c-common-init 'awk-mode)
   (c-awk-unstick-NL-prop)
 
-  ;; Prevent XEmacs's buffer-syntactic-context being used.  See the comment
-  ;; in cc-engine.el, just before (defun c-fast-in-literal ...
-  (defalias 'c-in-literal 'c-slow-in-literal)
-
   (c-run-mode-hooks 'c-mode-common-hook 'awk-mode-hook)
   (c-update-modeline))
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]