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))))
	 )))))