+(defun c-in-comment-line-prefix-p ()
+ ;; Point is within a comment. Is it also within a comment-prefix?
+ ;; Space at BOL which precedes a comment-prefix counts as part of it.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (let ((here (point)))
+ (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward " \t")
+ (and (looking-at c-current-comment-prefix)
+ (/= (match-beginning 0) (match-end 0))
+ (< here (match-end 0))))))
+
+(defun c-narrow-to-comment-innards (range)
+ ;; Narrow to the "inside" of the comment (block) defined by range, as
+ ;; follows:
+ ;;
+ ;; A c-style block comment has its opening "/*" and its closing "*/" (if
+ ;; present) removed. A c++-style line comment retains its opening "//" but
+ ;; has any final NL removed. If POINT is currently outwith these innards,
+ ;; move it to the appropriate boundary.
+ ;;
+ ;; This narrowing simplifies the sentence movement functions, since it
+ ;; eliminates awkward things at the boundaries of the comment (block).
+ ;;
+ ;; This function might do hidden buffer changes.
+ (let* ((lit-type (c-literal-type range))
+ (beg (if (eq lit-type 'c) (+ (car range) 2) (car range)))
+ (end (if (eq lit-type 'c)
+ (if (and (eq (char-before (cdr range)) ?/)
+ (eq (char-before (1- (cdr range))) ?*))
+ (- (cdr range) 2)
+ (point-max))
+ (if (eq (cdr range) (point-max))
+ (point-max)
+ (- (cdr range) 1)))))
+ (if (> (point) end)
+ (goto-char end)) ; This would be done automatically by ...
+ (if (< (point) beg)
+ (goto-char beg)) ; ... narrow-to-region but is not documented.
+ (narrow-to-region beg end)))
+
+(defun c-beginning-of-sentence-in-comment (range)
+ ;; Move backwards to the "beginning of a sentence" within the comment
+ ;; defined by RANGE, a cons of its starting and ending positions. If we
+ ;; find a BOS, return NIL. Otherwise, move point to just before the start
+ ;; of the comment and return T.
+ ;;
+ ;; The BOS is either text which follows a regexp match of sentence-end,
+ ;; or text which is a beginning of "paragraph".
+ ;; Comment-prefixes are treated like WS when calculating BOSes or BOPs.
+ ;;
+ ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
+ ;; It is not a general function, but is intended only for calling from
+ ;; c-move-over-sentence. Not all preconditions have been explicitly stated.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-match-data
+ (let ((start-point (point)))
+ (save-restriction
+ (c-narrow-to-comment-innards range) ; This may move point back.
+ (let* ((here (point))
+ last
+ (here-filler ; matches WS and comment-prefices at point.
+ (concat "\\=\\(^[ \t]*\\(" c-current-comment-prefix "\\)"
+ "\\|[ \t\n\r\f]\\)*"))
+ (prefix-at-bol-here ; matches WS and prefix at BOL, just before point
+ (concat "^[ \t]*\\(" c-current-comment-prefix "\\)[ \t\n\r\f]*\\="))
+ ;; First, find the previous paragraph start, if any.
+ (par-beg ; point where non-WS/non-prefix text of paragraph starts.
+ (save-excursion
+ (forward-paragraph -1) ; uses cc-mode values of
+ ; paragraph-\(start\|separate\)
+ (if (> (re-search-forward here-filler nil t) here)
+ (goto-char here))
+ (when (>= (point) here)
+ (forward-paragraph -2)
+ (if (> (re-search-forward here-filler nil t) here)
+ (goto-char here)))
+ (point))))
+
+ ;; Now seek successively earlier sentence ends between PAR-BEG and
+ ;; HERE, until the "start of sentence" following it is earlier than
+ ;; HERE, or we hit PAR-BEG. Beware of comment prefices!
+ (while (and (re-search-backward (c-sentence-end) par-beg 'limit)
+ (setq last (point))
+ (goto-char (match-end 0)) ; tentative beginning of sentence
+ (or (>= (point) here)
+ (and (not (bolp)) ; Found a non-blank comment-prefix?
+ (save-excursion
+ (if (re-search-backward prefix-at-bol-here nil t)
+ (/= (match-beginning 1) (match-end 1)))))
+ (progn ; Skip the crud to find a real b-o-s.
+ (if (c-in-comment-line-prefix-p)
+ (beginning-of-line))
+ (re-search-forward here-filler) ; always succeeds.
+ (>= (point) here))))
+ (goto-char last))
+ (re-search-forward here-filler)))
+
+ (if (< (point) start-point)
+ nil
+ (goto-char (car range))
+ t))))
+
+(defun c-end-of-sentence-in-comment (range)
+ ;; Move forward to the "end of a sentence" within the comment defined by
+ ;; RANGE, a cons of its starting and ending positions (enclosing the opening
+ ;; comment delimiter and the terminating */ or newline). If we find an EOS,
+ ;; return NIL. Otherwise, move point to just after the end of the comment
+ ;; and return T.
+ ;;
+ ;; The EOS is just after the non-WS part of the next match of the regexp
+ ;; sentence-end. Typically, this is just after one of [.!?]. If there is
+ ;; no sentence-end match following point, any WS before the end of the
+ ;; comment will count as EOS, providing we're not already in it.
+ ;;
+ ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
+ ;; It is not a general function, but is intended only for calling from
+ ;; c-move-over-sentence.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-match-data
+ (let ((start-point (point))
+ ;; (lit-type (c-literal-type range)) ; Commented out, 2005/11/23, ACM
+ )
+ (save-restriction
+ (c-narrow-to-comment-innards range) ; This might move point forwards.
+ (let* ((here (point))
+ (par-end ; EOL position of last text in current/next paragraph.
+ (save-excursion
+ ;; The cc-mode values of paragraph-\(start\|separate\), set
+ ;; in c-setup-paragraph-variables, are used in the
+ ;; following.
+ (forward-paragraph 1)
+ (if (eq (preceding-char) ?\n) (forward-char -1))
+ (when (<= (point) here) ; can happen, e.g., when HERE is at EOL.
+ (goto-char here)
+ (forward-paragraph 2)
+ (if (eq (preceding-char) ?\n) (forward-char -1)))
+ (point)))
+
+ last
+ (prefix-at-bol-here
+ (concat "^[ \t]*\\(" c-current-comment-prefix "\\)\\=")))
+ ;; Go forward one "comment-prefix which looks like sentence-end"
+ ;; each time round the following:
+ (while (and (re-search-forward (c-sentence-end) par-end 'limit)
+ (progn
+ (setq last (point))
+ (skip-chars-backward " \t\n")
+ (or (and (not (bolp))
+ (re-search-backward prefix-at-bol-here nil t)
+ (/= (match-beginning 1) (match-end 1)))
+ (<= (point) here))))
+ (goto-char last))
+
+ ;; Take special action if we're up against the end of a comment (of
+ ;; either sort): Leave point just after the last non-ws text.
+ (if (eq (point) (point-max))
+ (while (or (/= (skip-chars-backward " \t\n") 0)
+ (and (re-search-backward prefix-at-bol-here nil t)
+ (/= (match-beginning 1) (match-end 1))))))))
+
+ (if (> (point) start-point)
+ nil
+ (goto-char (cdr range))
+ t))))
+
+(defun c-beginning-of-sentence-in-string (range)
+ ;; Move backwards to the "beginning of a sentence" within the string defined
+ ;; by RANGE, a cons of its starting and ending positions (enclosing the
+ ;; string quotes). If we find a BOS, return NIL. Otherwise, move point to
+ ;; just before the start of the string and return T.
+ ;;
+ ;; The BOS is either the text which follows a regexp match of sentence-end
+ ;; or text which is a beginning of "paragraph". For the purposes of
+ ;; determining paragraph boundaries, escaped newlines are treated as
+ ;; ordinary newlines.
+ ;;
+ ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
+ ;; It is not a general function, but is intended only for calling from
+ ;; c-move-over-sentence.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-match-data
+ (let* ((here (point)) last
+ (end (1- (cdr range)))
+ (here-filler ; matches WS and escaped newlines at point.
+ "\\=\\([ \t\n\r\f]\\|\\\\[\n\r]\\)*")
+ ;; Enhance paragraph-start and paragraph-separate also to recognise
+ ;; blank lines terminated by escaped EOLs. IT MAY WELL BE that
+ ;; these values should be customizable user options, or something.
+ (paragraph-start c-string-par-start)
+ (paragraph-separate c-string-par-separate)
+
+ (par-beg ; beginning of current (or previous) paragraph.
+ (save-excursion
+ (save-restriction
+ (narrow-to-region (1+ (car range)) end)
+ (forward-paragraph -1) ; uses above values of
+ ; paragraph-\(start\|separate\)
+ (if (> (re-search-forward here-filler nil t) here)
+ (goto-char here))
+ (when (>= (point) here)
+ (forward-paragraph -2)
+ (if (> (re-search-forward here-filler nil t) here)
+ (goto-char here)))
+ (point)))))
+ ;; Now see if we can find a sentence end after PAR-BEG.
+ (while (and (re-search-backward c-sentence-end-with-esc-eol par-beg 'limit)
+ (setq last (point))
+ (goto-char (match-end 0))
+ (or (> (point) end)
+ (progn
+ (re-search-forward
+ here-filler end t) ; always succeeds. Use end rather
+ ; than here, in case point starts
+ ; beyond the closing quote.
+ (>= (point) here))))
+ (goto-char last))
+ (re-search-forward here-filler here t)
+ (if (< (point) here)
+ nil
+ (goto-char (car range))
+ t))))
+
+(defun c-end-of-sentence-in-string (range)
+ ;; Move forward to the "end of a sentence" within the string defined by
+ ;; RANGE, a cons of its starting and ending positions. If we find an EOS,
+ ;; return NIL. Otherwise, move point to just after the end of the string
+ ;; and return T.
+ ;;
+ ;; The EOS is just after the non-WS part of the next match of the regexp
+ ;; sentence-end. Typically, this is just after one of [.!?]. If there is
+ ;; no sentence-end match following point, any WS before the end of the
+ ;; string will count as EOS, providing we're not already in it.
+ ;;
+ ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
+ ;; It is not a general function, but is intended only for calling from
+ ;; c-move-over-sentence.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-match-data
+ (let* ((here (point))
+ last
+ ;; Enhance paragraph-start and paragraph-separate to recognise
+ ;; blank lines terminated by escaped EOLs.
+ (paragraph-start c-string-par-start)
+ (paragraph-separate c-string-par-separate)
+
+ (par-end ; EOL position of last text in current/next paragraph.
+ (save-excursion
+ (save-restriction
+ (narrow-to-region (car range) (1- (cdr range)))
+ ;; The above values of paragraph-\(start\|separate\) are used
+ ;; in the following.
+ (forward-paragraph 1)
+ (setq last (point))
+ ;; (re-search-backward filler-here nil t) would find an empty
+ ;; string. Therefore we simulate it by the following:
+ (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
+ (re-search-backward "\\\\\\($\\)\\=" nil t)))
+ (unless (> (point) here)
+ (goto-char last)
+ (forward-paragraph 1)
+ (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
+ (re-search-backward "\\\\\\($\\)\\=" nil t))))
+ (point)))))
+ ;; Try to go forward a sentence.
+ (when (re-search-forward c-sentence-end-with-esc-eol par-end 'limit)
+ (setq last (point))
+ (while (or (/= (skip-chars-backward " \t\n") 0)
+ (re-search-backward "\\\\\\($\\)\\=" nil t))))
+ ;; Did we move a sentence, or did we hit the end of the string?
+ (if (> (point) here)
+ nil
+ (goto-char (cdr range))
+ t))))
+
+(defun c-ascertain-preceding-literal ()
+ ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
+ ;; If a literal is the next thing (aside from whitespace) to be found before
+ ;; point, return a cons of its start.end positions (enclosing the
+ ;; delimiters). Otherwise return NIL.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-excursion
+ (c-collect-line-comments
+ (let ((here (point))
+ pos)
+ (if (c-backward-single-comment)
+ (cons (point) (progn (c-forward-single-comment) (point)))
+ (save-restriction
+ ;; to prevent `looking-at' seeing a " at point.
+ (narrow-to-region (point-min) here)
+ (when
+ (or
+ ;; An EOL can act as an "open string" terminator in AWK.
+ (looking-at c-ws*-string-limit-regexp)
+ (and (not (bobp))
+ (progn (backward-char)
+ (looking-at c-string-limit-regexp))))
+ (goto-char (match-end 0)) ; just after the string terminator.
+ (setq pos (point))
+ (c-safe (c-backward-sexp 1) ; move back over the string.
+ (cons (point) pos)))))))))
+
+(defun c-ascertain-following-literal ()
+ ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
+ ;; If a literal is the next thing (aside from whitespace) following point,
+ ;; return a cons of its start.end positions (enclosing the delimiters).
+ ;; Otherwise return NIL.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-excursion
+ (c-collect-line-comments
+ (let (pos)
+ (c-skip-ws-forward)
+ (if (looking-at c-string-limit-regexp) ; string-delimiter.
+ (cons (point) (or (c-safe (progn (c-forward-sexp 1) (point)))
+ (point-max)))
+ (setq pos (point))
+ (if (c-forward-single-comment)
+ (cons pos (point))))))))
+
+(defun c-after-statement-terminator-p () ; Should we pass in LIM here?
+ ;; Does point immediately follow a statement "terminator"? A virtual
+ ;; semicolon is regarded here as such. So is a an opening brace ;-)
+ ;;
+ ;; This function might do hidden buffer changes.
+ (or (save-excursion
+ (backward-char)
+ (and (looking-at "[;{}]")
+ (not (and c-special-brace-lists ; Pike special brace lists.
+ (eq (char-after) ?{)
+ (c-looking-at-special-brace-list)))))
+ (c-at-vsemi-p)
+ ;; The following (for macros) is not strict about exactly where we are
+ ;; wrt white space at the end of the macro. Doesn't seem to matter too
+ ;; much. ACM 2004/3/29.
+ (let (eom)
+ (save-excursion
+ (if (c-beginning-of-macro)
+ (setq eom (progn (c-end-of-macro)
+ (point)))))
+ (when eom
+ (save-excursion
+ (c-forward-comments)
+ (>= (point) eom))))))
+
+(defun c-back-over-illiterals (macro-start)
+ ;; Move backwards over code which isn't a literal (i.e. comment or string),
+ ;; stopping before reaching BOB or a literal or the boundary of a
+ ;; preprocessor statement or the "beginning of a statement". MACRO-START is
+ ;; the position of the '#' beginning the current preprocessor directive, or
+ ;; NIL if we're not in such.
+ ;;
+ ;; Return a cons (A.B), where
+ ;; A is NIL if we moved back to a BOS (and know it), T otherwise (we
+ ;; didn't move, or we hit a literal, or we're not sure about BOS).
+ ;; 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
+ ;;
+ ;; The total collection of returned values is as follows:
+ ;; (nil . nil): Found a BOS whilst remaining inside the illiterals.
+ ;; (t . literal): No BOS found: only a comment/string. We _might_ be at
+ ;; a BOS - the caller must check this.
+ ;; (nil . macro-boundary): only happens with non-nil macro-start. We've
+ ;; moved and reached the opening # of the macro.
+ ;; (t . macro-boundary): Every other circumstance in which we're at a
+ ;; macro-boundary. We might be at a BOS.
+ ;;
+ ;; Point is left either at the beginning-of-statement, or at the last non-ws
+ ;; code before encountering the literal/BOB or macro-boundary.
+ ;;
+ ;; Note that this function moves within either preprocessor commands
+ ;; (macros) or normal code, but will not cross a boundary between the two,
+ ;; or between two distinct preprocessor commands.
+ ;;
+ ;; Stop before `{' and after `;', `{', `}' and `};' when not followed by `}'
+ ;; or `)', but on the other side of the syntactic ws. Move by sexps and
+ ;; move into parens. Also stop before `#' when it's at boi on a line.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-match-data
+ (let ((here (point))
+ last) ; marks the position of non-ws code, what'll be BOS if, say, a
+ ; semicolon precedes it.
+ (catch 'done
+ (while t ;; We go back one "token" each iteration of the loop.
+ (setq last (point))
+ (cond
+ ;; Stop at the token after a comment.
+ ((c-backward-single-comment) ; Also functions as backwards-ws.
+ (goto-char last)
+ (throw 'done '(t . literal)))
+
+ ;; If we've gone back over a LF, we might have moved into or out of
+ ;; a preprocessor line.
+ ((and (save-excursion
+ (beginning-of-line)
+ (re-search-forward "\\(^\\|[^\\]\\)[\n\r]" last t))
+ (if macro-start
+ (< (point) macro-start)
+ (c-beginning-of-macro)))
+ (goto-char last)
+ ;; Return a car of NIL ONLY if we've hit the opening # of a macro.
+ (throw 'done (cons (or (eq (point) here)
+ (not macro-start))
+ 'macro-boundary)))
+
+ ;; Have we found a virtual semicolon? If so, stop, unless the next
+ ;; statement is where we started from.
+ ((and (c-at-vsemi-p)
+ (< last here)
+ (not (memq (char-after last) '(?\) ?})))) ; we've moved back from ) or }
+ (goto-char last)
+ (throw 'done '(nil . nil)))
+
+ ;; Hit the beginning of the buffer/region?
+ ((bobp)
+ (if (/= here last)
+ (goto-char last))
+ (throw 'done '(nil . nil)))
+
+ ;; Move back a character.
+ ((progn (backward-char) nil))
+
+ ;; Stop at "{" (unless it's a PIKE special brace list.)
+ ((eq (char-after) ?\{)
+ (if (and c-special-brace-lists
+ (c-looking-at-special-brace-list))
+ (skip-syntax-backward "w_") ; Speedup only.
+ (if (/= here last)
+ (goto-char last))
+ (throw 'done '(nil . nil))))
+
+ ;; Have we reached the start of a macro? This always counts as
+ ;; BOS. (N.B. I don't think (eq (point) here) can ever be true
+ ;; here. FIXME!!! ACM 2004/3/29)
+ ((and macro-start (eq (point) macro-start))
+ (throw 'done (cons (eq (point) here) 'macro-boundary)))
+
+ ;; Stop at token just after "}" or ";".
+ ((looking-at "[;}]")
+ ;; If we've gone back over ;, {, or }, we're done.
+ (if (or (= here last)
+ (memq (char-after last) '(?\) ?}))) ; we've moved back from ) or }
+ (if (and (eq (char-before) ?}) ; If };, treat them as a unit.
+ (eq (char-after) ?\;))
+ (backward-char))
+ (goto-char last) ; To the statement starting after the ; or }.
+ (throw 'done '(nil . nil))))
+
+ ;; Stop at the token after a string.
+ ((looking-at c-string-limit-regexp) ; Just gone back over a string terminator?
+ (goto-char last)
+ (throw 'done '(t . literal)))
+
+ ;; Nothing special: go back word characters.
+ (t (skip-syntax-backward "w_")) ; Speedup only.
+ ))))))
+
+(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.
+ ((and (not macro-end)
+ (eq (char-after) ?#)
+ (= (point) (c-point 'boi)))
+ (goto-char last)
+ ;(throw 'done (cons (eq (point) here) 'macro-boundary))) ; Changed 2003/3/26
+ (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))))
+ )))))
+
+(defun c-one-line-string-p (range)
+ ;; Is the literal defined by RANGE a string contained in a single line?
+ ;;
+ ;; This function might do hidden buffer changes.
+ (save-excursion
+ (goto-char (car range))
+ (and (looking-at c-string-limit-regexp)
+ (progn (skip-chars-forward "^\n" (cdr range))
+ (eq (point) (cdr range))))))
+