Function: c-forward-sws
c-forward-sws is a byte-compiled function defined in cc-engine.el.gz.
Signature
(c-forward-sws)
Documentation
This function has :around advice: No documentation
Aliases
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-forward-sws ()
;; Used by `c-forward-syntactic-ws' to implement the unbounded search.
;;
;; This function might do hidden buffer changes.
(let (;; `rung-pos' is set to a position as early as possible in the
;; unmarked part of the simple ws region.
(rung-pos (point)) next-rung-pos rung-end-pos last-put-in-sws-pos
rung-is-marked next-rung-is-marked simple-ws-end macro-start macro-end
;; `safe-start' is set when it's safe to cache the start position.
;; This is the case except when we have an unterminated block comment
;; within a macro.
safe-start)
;; Skip simple ws and do a quick check on the following character to see
;; if it's anything that can't start syntactic ws, so we can bail out
;; early in the majority of cases when there just are a few ws chars.
(c-skip-ws-chars-forward " \t\n\r\f\v ")
(when (or (looking-at c-syntactic-ws-start)
(and c-opt-cpp-prefix
(looking-at c-noise-macro-name-re))
(and (c-major-mode-is '(c-mode c++-mode))
(looking-at "\\[\\["))
(looking-at c-doc-line-join-re))
(setq rung-end-pos (min (1+ (point)) (point-max)))
(if (setq rung-is-marked (text-property-any rung-pos rung-end-pos
'c-is-sws t))
;; Find the last rung position to avoid setting properties in all
;; the cases when the marked rung is complete.
;; (`c-next-single-property-change' is certain to move at least one
;; step forward.)
(setq rung-pos (1- (c-next-single-property-change
rung-is-marked 'c-is-sws nil rung-end-pos)))
;; Got no marked rung here. Since the simple ws might have started
;; inside a line comment or cpp directive we must set `rung-pos' as
;; high as possible.
(setq rung-pos (point)))
(with-silent-modifications
(while
(progn
;; In the following while form, we move over a "ladder" and
;; following simple WS each time round the loop, appending the WS
;; onto the ladder, joining adjacent ladders, and terminating when
;; there is no more WS or we reach EOB.
(while
(when (and rung-is-marked
(get-text-property (point) 'c-in-sws))
;; The following search is the main reason that `c-in-sws'
;; and `c-is-sws' aren't combined to one property.
(goto-char (c-next-single-property-change
(point) 'c-in-sws nil (point-max)))
(unless (get-text-property (point) 'c-is-sws)
;; If the `c-in-sws' region extended past the last
;; `c-is-sws' char we have to go back a bit.
(or (get-text-property (1- (point)) 'c-is-sws)
(goto-char (c-previous-single-property-change
(point) 'c-is-sws)))
(backward-char))
(c-debug-sws-msg
"c-forward-sws cached move %s -> %s (max %s)"
rung-pos (point) (point-max))
(setq rung-pos (point))
(and (> (c-skip-ws-chars-forward " \t\n\r\f\v ") 0)
(not (eobp))))
;; We'll loop here if there is simple ws after the last rung.
;; That means that there's been some change in it and it's
;; possible that we've stepped into another ladder, so extend
;; the previous one to join with it if there is one, and try to
;; use the cache again.
(c-debug-sws-msg
"c-forward-sws extending rung with [%s..%s] (max %s)"
(1+ rung-pos) (1+ (point)) (point-max))
(unless (get-text-property (point) 'c-is-sws)
;; Remove any `c-in-sws' property from the last char of
;; the rung before we mark it with `c-is-sws', so that we
;; won't connect with the remains of a broken "ladder".
(c-remove-in-sws (point) (1+ (point))))
(c-put-is-sws (1+ rung-pos)
(1+ (point)))
(c-put-in-sws rung-pos
(point))
(setq rung-pos (point)
last-put-in-sws-pos rung-pos))
;; Now move over any comments (x)or a CPP construct.
(setq simple-ws-end (point))
(setq safe-start t)
;; Take elaborate precautions to detect an open block comment at
;; the end of a macro. If we find one, we set `safe-start' to nil
;; and break off any further scanning of comments.
;;
;; (2019-05-02): `c-end-of-macro' now moves completely over block
;; comments, even multiline ones lacking \s at their EOLs. So a
;; lot of the following is probably redundant now.
(let ((com-begin (point)) com-end in-macro)
(when (and (c-forward-single-comment)
(setq com-end (point))
(save-excursion
(goto-char com-begin)
(c-beginning-of-macro)))
(setq in-macro t)
(goto-char com-begin)
(if (progn (c-end-of-macro com-end)
(< (point) com-end))
(setq safe-start nil)))
(if in-macro
(while (and safe-start
com-end (> com-end com-begin)
(setq com-begin (point))
(when (and (c-forward-single-comment)
(setq com-end (point)))
(goto-char com-begin)
(if (progn (c-end-of-macro com-end)
(< (point) com-end))
(setq safe-start nil))
safe-start)))
(c-forward-comments)))
(cond
((/= (point) simple-ws-end)
;; Skipped over comments. Don't cache at eob in case the buffer
;; is narrowed.
(not (eobp)))
((save-excursion
(and c-opt-cpp-prefix
(looking-at c-opt-cpp-start)
(setq macro-start (point))
(progn (c-skip-ws-chars-backward " \t ")
(bolp))
(or (bobp)
(progn (backward-char)
(not (eq (char-before) ?\\))))))
;; Skip a preprocessor directive.
(end-of-line)
(while (and (eq (char-before) ?\\)
(= (forward-line 1) 0))
(end-of-line))
(setq macro-end (point))
;; Check for an open block comment at the end of the macro.
(let ((s (parse-partial-sexp macro-start macro-end)))
(if (and (elt s 4) ; in a comment
(null (elt s 7))) ; a block comment
(setq safe-start nil)))
(forward-line 1)
;; Don't cache at eob in case the buffer is narrowed.
(not (eobp)))
((and c-opt-cpp-prefix
(looking-at c-noise-macro-name-re))
;; Skip over a noise macro without parens.
(goto-char (match-end 1))
(not (eobp)))
((setq next-rung-pos (c-looking-at-c++-attribute))
(goto-char next-rung-pos)
(not (eobp)))
((looking-at c-doc-line-join-re)
;; Skip over a line join in (e.g.) Pike autodoc.
(goto-char (match-end 0))
(setq safe-start nil) ; Never cache this; the doc style could be
; changed at any time.
(not (eobp)))))
;; We've searched over a piece of non-white syntactic ws. See if this
;; can be cached.
(setq next-rung-pos (point))
(c-skip-ws-chars-forward " \t\n\r\f\v ")
(setq rung-end-pos (min (1+ (point)) (point-max)))
(if (or
;; Cache if we haven't skipped comments only, and if we started
;; either from a marked rung or from a completely uncached
;; position.
(and safe-start
(or rung-is-marked
(not (get-text-property simple-ws-end 'c-in-sws))))
;; See if there's a marked rung in the encountered simple ws. If
;; so then we can cache, unless `safe-start' is nil. Even then
;; we need to do this to check if the cache can be used for the
;; next step.
(and (setq next-rung-is-marked
(text-property-any next-rung-pos rung-end-pos
'c-is-sws t))
safe-start))
(progn
(c-debug-sws-msg
"c-forward-sws caching [%s..%s] - [%s..%s] (max %s)"
rung-pos (1+ simple-ws-end) next-rung-pos rung-end-pos
(point-max))
;; Remove the properties for any nested ws that might be cached.
;; Only necessary for `c-is-sws' since `c-in-sws' will be set
;; anyway.
(c-remove-is-sws (1+ simple-ws-end) next-rung-pos)
(unless (and rung-is-marked (= rung-pos simple-ws-end))
(c-put-is-sws rung-pos
(1+ simple-ws-end))
(setq rung-is-marked t))
(c-put-in-sws rung-pos
(setq rung-pos (point)
last-put-in-sws-pos rung-pos))
(unless (get-text-property (1- rung-end-pos) 'c-is-sws)
;; Remove any `c-in-sws' property from the last char of
;; the rung before we mark it with `c-is-sws', so that we
;; won't connect with the remains of a broken "ladder".
(c-remove-in-sws (1- rung-end-pos) rung-end-pos))
(c-put-is-sws next-rung-pos
rung-end-pos))
(c-debug-sws-msg
"c-forward-sws not caching [%s..%s] - [%s..%s] (max %s)"
rung-pos (1+ simple-ws-end) next-rung-pos rung-end-pos
(point-max))
;; Set `rung-pos' for the next rung. It's the same thing here as
;; initially, except that the rung position is set as early as
;; possible since we can't be in the ending ws of a line comment or
;; cpp directive now.
(if (setq rung-is-marked next-rung-is-marked)
(setq rung-pos (1- (c-next-single-property-change
rung-is-marked 'c-is-sws nil rung-end-pos)))
(setq rung-pos next-rung-pos))))
;; Make sure that the newly marked `c-in-sws' region doesn't connect to
;; another one after the point (which might occur when editing inside a
;; comment or macro).
(when (eq last-put-in-sws-pos (point))
(cond ((< last-put-in-sws-pos (point-max))
(c-debug-sws-msg
"c-forward-sws clearing at %s for cache separation"
last-put-in-sws-pos)
(c-remove-in-sws last-put-in-sws-pos
(1+ last-put-in-sws-pos)))
(t
;; If at eob we have to clear the last character before the end
;; instead since the buffer might be narrowed and there might
;; be a `c-in-sws' after (point-max). In this case it's
;; necessary to clear both properties.
(c-debug-sws-msg
"c-forward-sws clearing thoroughly at %s for cache separation"
(1- last-put-in-sws-pos))
(c-remove-is-and-in-sws (1- last-put-in-sws-pos)
last-put-in-sws-pos))))))))