Function: c-do-declarators

c-do-declarators is a byte-compiled function defined in cc-engine.el.gz.

Signature

(c-do-declarators CDD-LIMIT CDD-LIST CDD-NOT-TOP CDD-COMMA-PROP CDD-FUNCTION &optional CDD-ACCEPT-ANON)

Documentation

Assuming point is at the start of a comma separated list of declarators, apply CDD-FUNCTION to each declarator (when CDD-LIST is non-nil) or just the first declarator (when CDD-LIST is nil). When CDD-FUNCTION is nil, no function is applied.

CDD-FUNCTION is supplied with 6 arguments:
0. The start position of the declarator's identifier;
1. The end position of this identifier;
[Note: if there is no identifier, as in int (*);, both of these are nil.]
2. The position of the next token after the declarator (CLARIFY!!!).
3. CDD-NOT-TOP;
4. Non-nil if the identifier is of a function.
5. When there is an initialization following the declarator (such as "=
...." or "( ....".), the character which introduces this initialization,
otherwise nil.

Additionally, if CDD-COMMA-PROP is non-nil, mark the separating commas with this value of the c-type property, when CDD-LIST is non-nil.

Stop at or before CDD-LIMIT (which may NOT be nil).

If CDD-NOT-TOP is non-nil, we are not at the top-level ("top-level" includes being directly inside a class or namespace, etc.).

If CDD-ACCEPT-ANON is non-nil, we also process declarators without names, e.g. "int (*)(int)" in a function prototype.

Return non-nil if we've reached the token after the last declarator (often a semicolon, or a comma when CDD-LIST is nil); otherwise (when we hit CDD-LIMIT, or fail otherwise) return nil, leaving point at the beginning of the putative declarator that could not be processed.

This function might do hidden buffer changes.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-do-declarators
    (cdd-limit cdd-list cdd-not-top cdd-comma-prop cdd-function
	       &optional cdd-accept-anon)
  "Assuming point is at the start of a comma separated list of declarators,
apply CDD-FUNCTION to each declarator (when CDD-LIST is non-nil) or just the
first declarator (when CDD-LIST is nil).  When CDD-FUNCTION is nil, no
function is applied.

CDD-FUNCTION is supplied with 6 arguments:
0. The start position of the declarator's identifier;
1. The end position of this identifier;
\[Note: if there is no identifier, as in int (*);, both of these are nil.]
2. The position of the next token after the declarator (CLARIFY!!!).
3. CDD-NOT-TOP;
4. Non-nil if the identifier is of a function.
5. When there is an initialization following the declarator (such as \"=
....\" or \"( ....\".), the character which introduces this initialization,
otherwise nil.

Additionally, if CDD-COMMA-PROP is non-nil, mark the separating commas with
this value of the c-type property, when CDD-LIST is non-nil.

Stop at or before CDD-LIMIT (which may NOT be nil).

If CDD-NOT-TOP is non-nil, we are not at the top-level (\"top-level\" includes
being directly inside a class or namespace, etc.).

If CDD-ACCEPT-ANON is non-nil, we also process declarators without names,
e.g. \"int (*)(int)\" in a function prototype.

Return non-nil if we've reached the token after the last declarator (often a
semicolon, or a comma when CDD-LIST is nil); otherwise (when we hit CDD-LIMIT,
or fail otherwise) return nil, leaving point at the beginning of the putative
declarator that could not be processed.

This function might do hidden buffer changes."
  ;; N.B.: We use the "cdd-" prefix in this routine to try to prevent
  ;; confusion with possible reference to common variable names from within
  ;; CDD-FUNCTION.
  (let
      ((cdd-pos (point)) cdd-next-pos cdd-id-start cdd-id-end
       cdd-decl-res cdd-got-func cdd-got-init
       c-last-identifier-range cdd-exhausted cdd-after-block)

    ;; The following `while' applies `cdd-function' to a single declarator id
    ;; each time round.  It loops only when CDD-LIST is non-nil.
    (while
	(and (not cdd-exhausted)
	     (setq cdd-decl-res (c-forward-declarator
				 cdd-limit cdd-accept-anon cdd-not-top)))

      (setq cdd-next-pos (point)
	    cdd-id-start (car cdd-decl-res)
	    cdd-id-end (cadr cdd-decl-res)
	    cdd-got-func (cadr (cddr (cddr cdd-decl-res)))
	    cdd-got-init (and (cadr (cddr cdd-decl-res)) (char-after)))

      ;; Jump past any initializer or function prototype to see if
      ;; there's a ',' to continue at.
      (cond (cdd-got-init		; "=" sign OR opening "(", "[", or "("
	     ;; Skip an initializer expression in braces, whether or not (in
	     ;; C++ Mode) preceded by an "=".  Be careful that the brace list
	     ;; isn't a code block or a struct (etc.) block.
	     (cond
	      ((and (eq cdd-got-init ?=)
		    (zerop (c-forward-token-2 1 nil  cdd-limit))
		    (eq (char-after) ?{)
		    (c-go-list-forward (point) cdd-limit)))
	      ((and (eq cdd-got-init ?{)
		    c-recognize-bare-brace-inits
		    (setq cdd-after-block
			  (save-excursion
			    (c-go-list-forward (point) cdd-limit)))
		    (not (c-looking-at-statement-block)))
	       (goto-char cdd-after-block)))
	     (if (c-syntactic-re-search-forward "[;,{]" cdd-limit 'move t)
		 (backward-char)
	       (setq cdd-exhausted t)))

	    (t (c-forward-syntactic-ws cdd-limit)))

      (if cdd-function
	  (save-excursion
	    (funcall cdd-function cdd-id-start cdd-id-end cdd-next-pos
		     cdd-not-top cdd-got-func cdd-got-init)))

      ;; If a ',' is found we set cdd-pos to the next declarator and iterate.
      (if (and cdd-list (< (point) cdd-limit) (looking-at ","))
	  (progn
	    (when cdd-comma-prop
	      (c-put-char-property (point) 'c-type cdd-comma-prop))
	    (forward-char)
	    (c-forward-syntactic-ws cdd-limit)
	    (setq cdd-pos (point)))
	(setq cdd-exhausted t)))

    (if (> (point) cdd-pos)
	t
      (goto-char cdd-pos)
      nil)))