emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] Changes to emacs/lisp/progmodes/cc-engine.el,v


From: Alan Mackenzie
Subject: [Emacs-diffs] Changes to emacs/lisp/progmodes/cc-engine.el,v
Date: Sat, 20 Jan 2007 19:29:30 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Alan Mackenzie <acmacm> 07/01/20 19:29:30

Index: cc-engine.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/progmodes/cc-engine.el,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- cc-engine.el        20 Jan 2007 18:33:10 -0000      1.50
+++ cc-engine.el        20 Jan 2007 19:29:30 -0000      1.51
@@ -6221,65 +6221,101 @@
   ;; `c-recognize-knr-p' is not checked.  If LIM is non-nil, it's a
   ;; position that bounds the backward search for the argument list.
   ;;
-  ;; Note: A declaration level context is assumed; the test can return
-  ;; false positives for statements.
+  ;; Point must be within a possible K&R region, e.g. just before a top-level
+  ;; "{".  It must be outside of parens and brackets.  The test can return
+  ;; false positives otherwise.
   ;;
   ;; This function might do hidden buffer changes.
 
   (save-excursion
     (save-restriction
+      ;; If we're in a macro, our search range is restricted to it.  Narrow to
+      ;; the searchable range.
+      (let* ((macro-start (c-query-macro-start))
+            (lim (max (or lim (point-min)) (or macro-start (point-min))))
+            before-lparen after-rparen)
+       (narrow-to-region lim (c-point 'eol))
+
+       ;; Search backwards for the defun's argument list.  We give up if we
+       ;; encounter a "}" (end of a previous defun) or BOB.
+       ;;
+       ;; The criterion for a paren structure being the arg list is:
+       ;; o - there is non-WS stuff after it but before any "{"; AND
+       ;; o - the token after it isn't a ";" AND
+       ;; o - it is preceded by either an identifier (the function name) or
+       ;;   a macro expansion like "DEFUN (...)"; AND
+       ;; o - its content is a non-empty comma-separated list of identifiers
+       ;;   (an empty arg list won't have a knr region).
+       ;;
+       ;; The following snippet illustrates these rules:
+       ;; int foo (bar, baz, yuk)
+       ;;     int bar [] ;
+       ;;     int (*baz) (my_type) ;
+       ;;     int (*) (void) (*yuk) (void) ;
+       ;; {
+
+       (catch 'knr
+         (while t ; go round one paren/bracket construct each time round.
+           (or (c-syntactic-skip-backward "^)]}")
+               (throw 'knr nil))       ; no more bpb pairs left.
+           (cond ((eq (char-before) ?\))
+                  (setq after-rparen (point)))
+                 ((eq (char-before) ?\})
+                  (throw 'knr nil))
+                 (t (setq after-rparen nil))) ; "]"
+
+           (if after-rparen
+           ;; We're inside a paren.  Could it be our argument list....?
+             (if
+                 (and
+                  (progn
+                    (goto-char after-rparen)
+                    (unless (c-go-list-backward) (throw 'knr nil)) ;
+               ;; FIXME!!!  What about macros between the parens?  2007/01/20
+                    (setq before-lparen (point)))
 
-      ;; Go back to the closest preceding normal parenthesis sexp.  We
-      ;; take that as the argument list in the function header.  Then
-      ;; check that it's followed by some symbol before the next ';'
-      ;; or '{'.  If it does, it's the header of the K&R argdecl we're
-      ;; in.
-      (if lim (narrow-to-region lim (c-point 'eol)))
-      (let ((outside-macro (not (c-query-macro-start)))
-           paren-end)
-
-       (catch 'done
-         (while (if (and (setq paren-end (c-down-list-backward (point)))
-                         (eq (char-after paren-end) ?\)))
-                    (progn
-                      (goto-char (1+ paren-end))
-                      (if outside-macro
-                          (c-beginning-of-macro)))
-                  (throw 'done nil))))
-
-       (and (progn
+                  ;; It can't be the arg list if next token is ; or {
+                  (progn (goto-char after-rparen)
               (c-forward-syntactic-ws)
-              (looking-at "\\w\\|\\s_"))
+                         (not (memq (char-after) '(?\; ?\{))))
 
-            (save-excursion
-              ;; The function header in a K&R declaration should only
-              ;; contain identifiers separated by comma.  It should
-              ;; also contain at least one identifier since there
-              ;; wouldn't be anything to declare in the K&R region
-              ;; otherwise.
-              (when (c-go-up-list-backward paren-end)
-                (forward-char)
-                (catch 'knr-ok
-                  (while t
-                    (c-forward-syntactic-ws)
-                    (if (or (looking-at c-known-type-key)
-                            (looking-at c-keywords-regexp))
-                        (throw 'knr-ok nil))
+                  ;; Is the thing preceding the list an identifier (the
+                  ;; function name), or a macro expansion?
+                  (progn
+                    (goto-char before-lparen)
+                    (eq (c-backward-token-2) 0)
+                    (or (c-on-identifier)
+                        (and (eq (char-after) ?\))
+                             (c-go-up-list-backward)
+                             (eq (c-backward-token-2) 0)
+                             (c-on-identifier))))
+
+                  ;; Have we got a non-empty list of comma-separated
+                  ;; identifiers?
+                  (progn
+                    (goto-char before-lparen)
+                    (c-forward-token-2) ; to first token inside parens
+                    (and
+                     (c-on-identifier)
                     (c-forward-token-2)
-                    (if (eq (char-after) ?,)
-                        (forward-char)
-                      (throw 'knr-ok (and (eq (char-after) ?\))
-                                          (= (point) paren-end))))))))
+                     (catch 'id-list
+                       (while (eq (char-after) ?\,)
+                         (c-forward-token-2)
+                         (unless (c-on-identifier) (throw 'id-list nil))
+                         (c-forward-token-2))
+                       (eq (char-after) ?\))))))
+
+                 ;; ...Yes.  We've identified the function's argument list.
+                 (throw 'knr
+                      (progn (goto-char after-rparen)
+                             (c-forward-syntactic-ws)
+                             (point)))
 
-            (save-excursion
-              ;; If it's a K&R declaration then we're now at the
-              ;; beginning of the function arglist.  Check that there
-              ;; isn't a '=' before it in this statement since that
-              ;; means it some kind of initialization instead.
-              (c-syntactic-skip-backward "^;=}{")
-              (not (eq (char-before) ?=)))
+               ;; ...No.  The current parens aren't the function's arg list.
+               (goto-char before-lparen))
 
-            (point))))))
+             (or (c-go-list-backward)  ; backwards over [ .... ]
+                 (throw 'knr nil)))))))))
 
 (defun c-skip-conditional ()
   ;; skip forward over conditional at point, including any predicate




reply via email to

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