Function: c-forward-over-illiterals
c-forward-over-illiterals is a byte-compiled function defined in
cc-cmds.el.gz.
Signature
(c-forward-over-illiterals MACRO-END ALLOW-EARLY-STOP)
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/cc-cmds.el.gz
(defun c-forward-over-illiterals (macro-end allow-early-stop)
;; Move forwards over code, stopping before reaching EOB or a literal
;; (i.e. a comment/string) or the boundary of a preprocessor statement or
;; the "end of a statement". MACRO-END is the position of the EOL/EOB which
;; terminates the current preprocessor directive, or NIL if we're not in
;; such.
;;
;; ALLOW-EARLY-STOP is non-nil if it is permissible to return without moving
;; forward at all, should we encounter a `{'. This is an ugly kludge, but
;; seems unavoidable. Depending on the context this function is called
;; from, we _sometimes_ need to stop there. Currently (2004/4/3),
;; ALLOW-EARLY-STOP is applied only to open braces, not to virtual
;; semicolons, or anything else.
;;
;; Return a cons (A.B), where
;; A is NIL if we moved forward to an EOS, or stay at one (when
;; ALLOW-EARLY-STOP is set), T otherwise (we hit a literal).
;; B is 'MACRO-BOUNDARY if we are about to cross the boundary out of or
;; into a macro, otherwise 'LITERAL if we've hit a literal, otherwise NIL
;;
;; Point is left either after the end-of-statement, or at the last non-ws
;; code before encountering the literal, or the # of the preprocessor
;; statement, or at EOB [or just after last non-WS stuff??].
;;
;; As a clarification of "after the end-of-statement", if a comment or
;; whitespace follows a completed AWK statement, that statement is treated
;; as ending just after the last non-ws character before the comment.
;;
;; Note that this function moves within either preprocessor commands
;; (macros) or normal code, but not both within the same invocation.
;;
;; Stop before `{', `}', and `#' when it's at boi on a line, but on the
;; other side of the syntactic ws, and after `;', `}' and `};'. Only
;; stop before `{' if at top level or inside braces, though. Move by
;; sexps and move into parens. Also stop at eol of lines with `#' at
;; the boi.
;;
;; This function might do hidden buffer changes.
(let ((here (point))
last)
(catch 'done
(while t ;; We go one "token" forward each time round this loop.
(setq last (point))
;; If we've moved forward to a virtual semicolon, we're done.
(if (and (> last here) ; Should we check ALLOW-EARLY-STOP, here? 2004/4/3
(c-at-vsemi-p))
(throw 'done '(nil . nil)))
(c-skip-ws-forward)
(cond
;; Gone past the end of a macro?
((and macro-end (> (point) macro-end))
(goto-char last)
(throw 'done (cons (eq (point) here) 'macro-boundary)))
;; About to hit a comment?
((save-excursion (c-forward-single-comment))
(goto-char last)
(throw 'done '(t . literal)))
;; End of buffer?
((eobp)
(if (/= here last)
(goto-char last))
(throw 'done '(nil . nil)))
;; If we encounter a '{', stop just after the previous token.
((and (eq (char-after) ?{)
(not (and c-special-brace-lists
(c-looking-at-special-brace-list)))
(or allow-early-stop (/= here last))
(save-excursion ; Is this a check that we're NOT at top level?
;;;; NO! This seems to check that (i) EITHER we're at the top level;
;;;; OR (ii) The next enclosing level of bracketing is a '{'. HMM.
;;;; Doesn't seem to make sense.
;;;; 2003/8/8 This might have something to do with the GCC extension
;;;; "Statement Expressions", e.g.
;;;; while ({stmt1 ; stmt2 ; exp ;}).
;;;; This form excludes such Statement Expressions.
(or (not (c-safe (up-list -1) t))
(= (char-after) ?{))))
(goto-char last)
(throw 'done '(nil . nil)))
;; End of a PIKE special brace list? If so, step over it and continue.
((and c-special-brace-lists
(eq (char-after) ?})
(save-excursion
(and (c-safe (up-list -1) t)
(c-looking-at-special-brace-list))))
(forward-char)
(skip-syntax-forward "w_")) ; Speedup only.
;; Have we got a '}' after having moved? If so, stop after the
;; previous token.
((and (eq (char-after) ?})
(/= here last))
(goto-char last)
(throw 'done '(nil . nil)))
;; Stop if we encounter a preprocessor line. Continue if we
;; hit a naked #
((and c-opt-cpp-prefix
(not macro-end)
(eq (char-after) ?#)
(= (point) (c-point 'boi)))
(if (= (point) here) ; Not a macro, therefore naked #.
(forward-char)
(throw 'done '(t . macro-boundary))))
;; Stop after a ';', '}', or "};"
((looking-at ";\\|};?")
(goto-char (match-end 0))
(throw 'done '(nil . nil)))
;; Found a string (this subsumes AWK regexps)?
((looking-at c-string-limit-regexp)
(goto-char last)
(throw 'done '(t . literal)))
(t
(forward-char) ; Can't fail - we checked (eobp) earlier on.
(skip-syntax-forward "w_") ; Speedup only.
(when (and macro-end (> (point) macro-end))
(goto-char last)
(throw 'done (cons (eq (point) here) 'macro-boundary))))
)))))