Function: c-lineup-cpp-define

c-lineup-cpp-define is a byte-compiled function defined in cc-align.el.gz.

Signature

(c-lineup-cpp-define LANGELEM)

Documentation

Line up macro continuation lines according to the indentation of the construct preceding the macro. E.g.:

v beg of preceding constr v beg of preceding constr
                             int dribble() {
const char msg[] = if (!running)
  "Some text."; error("Not running!");

#define X(A, B) \ #define X(A, B) \
do { \ <-> do { \ <- c-lineup-cpp-define
  printf (A, B); \ printf (A, B); \
} while (0) } while (0)

If c-syntactic-indentation-in-macros is non-nil, the function returns the relative indentation to the macro start line to allow accumulation with other offsets. E.g. in the following cases, cpp-define-intro is combined with the statement-block-intro that comes from the do { that hangs on the #define line:

                             int dribble() {
const char msg[] = if (!running)
  "Some text."; error("Not running!");

#define X(A, B) do { \ #define X(A, B) do { \
  printf (A, B); \ <-> printf (A, B); \ <- c-lineup-cpp-define
  this->refs++; \ this->refs++; \
} while (0) <-> } while (0) <- c-lineup-cpp-define

The relative indentation returned by c-lineup-cpp-define is zero and two, respectively, in these two examples. They are then added to the two column indentation that statement-block-intro gives in both cases here.

If the relative indentation is zero, then nil is returned instead. That is useful in a list expression to specify the default indentation on the top level.

If c-syntactic-indentation-in-macros is nil then this function keeps the current indentation, except for empty lines (ignoring the ending backslash) where it takes the indentation from the closest preceding nonempty line in the macro. If there's no such line in the macro then the indentation is taken from the construct preceding it, as described above.

Works with: cpp-define-intro.

Probably introduced at or before Emacs version 22.1.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-align.el.gz
(defun c-lineup-cpp-define (_langelem)
  "Line up macro continuation lines according to the indentation of
the construct preceding the macro.  E.g.:

v beg of preceding constr      v beg of preceding constr
                             int dribble() {
const char msg[] =             if (!running)
  \"Some text.\";	         error(\"Not running!\");

#define X(A, B)  \\           #define X(A, B)    \\
do {             \\    <->      do {             \\    <- c-lineup-cpp-define
  printf (A, B); \\               printf (A, B); \\
} while (0)                    } while (0)

If `c-syntactic-indentation-in-macros' is non-nil, the function
returns the relative indentation to the macro start line to allow
accumulation with other offsets.  E.g. in the following cases,
cpp-define-intro is combined with the statement-block-intro that comes
from the `do {' that hangs on the `#define' line:

                             int dribble() {
const char msg[] =             if (!running)
  \"Some text.\";	         error(\"Not running!\");

#define X(A, B) do { \\       #define X(A, B) do { \\
  printf (A, B);     \\  <->      printf (A, B);   \\  <- c-lineup-cpp-define
  this->refs++;      \\           this->refs++;    \\
} while (0)             <->    } while (0)           <- c-lineup-cpp-define

The relative indentation returned by `c-lineup-cpp-define' is zero and
two, respectively, in these two examples.  They are then added to the
two column indentation that statement-block-intro gives in both cases
here.

If the relative indentation is zero, then nil is returned instead.
That is useful in a list expression to specify the default indentation
on the top level.

If `c-syntactic-indentation-in-macros' is nil then this function keeps
the current indentation, except for empty lines (ignoring the ending
backslash) where it takes the indentation from the closest preceding
nonempty line in the macro.  If there's no such line in the macro then
the indentation is taken from the construct preceding it, as described
above.

Works with: cpp-define-intro."
  (let (offset)
    (if c-syntactic-indentation-in-macros
	;; Go to the macro start and do a syntactic analysis of it.
	;; Then remove the cpp-macro element it should contain and
	;; calculate the indentation it then would get.
	(save-excursion
	  (c-beginning-of-macro)
	  (setq offset (- (c-get-syntactic-indentation
			   (delete '(cpp-macro) (c-guess-basic-syntax)))
			  (save-excursion
			    (back-to-indentation)
			    (current-column))))
	  (if (zerop offset)
	      nil
	    offset))
      ;; Do not indent syntactically inside the macro.
      (save-excursion
	(let ((macro-start-line (save-excursion
				  (goto-char (c-query-macro-start))
				  (beginning-of-line)
				  (point))))
	  (beginning-of-line)
	  ;; Check every line while inside the macro.
	  (while (and (> (point) macro-start-line)
		      (looking-at "[ \t]*\\\\?$")
		      (= (forward-line -1) 0)))
	  (if (<= (point) macro-start-line)
	      ;; If we've stepped out of the macro we take the
	      ;; syntactic offset.
	      (setq offset (c-get-syntactic-indentation
			    (delete '(cpp-macro) (c-guess-basic-syntax))))
	    (setq offset (current-indentation)))
	  (if (zerop offset)
	      nil
	    (vector offset)))))))