Function: c-determine-limit

c-determine-limit is a byte-compiled function defined in cc-engine.el.gz.

Signature

(c-determine-limit HOW-FAR-BACK &optional START TRY-SIZE ORG-START)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-determine-limit (how-far-back &optional start try-size org-start)
  ;; Return a buffer position approximately HOW-FAR-BACK non-literal
  ;; characters from START (default point).  The starting position, either
  ;; point or START may not be in a comment or string.
  ;;
  ;; The position found will not be before POINT-MIN and won't be in a
  ;; literal.  It will also not be inside a macro, unless START/point is also
  ;; in the same macro.
  ;;
  ;; We start searching for the sought position TRY-SIZE (default
  ;; twice HOW-FAR-BACK) bytes back from START.
  ;;
  ;; This function must be fast.  :-)

  (save-excursion
    (let* ((start (or start (point)))
	   (org-start (or org-start start))
	   (try-size (or try-size (* 2 how-far-back)))
	   (base (c-determine-limit-get-base start try-size))
	   (pos base)

	   (s (parse-partial-sexp pos pos)) ; null state.
	   stack elt size
	   (count 0))
      ;; Optimization for large blocks of comments, particularly those being
      ;; created by `comment-region'.
      (goto-char pos)
      (forward-comment try-size)
      (setq pos (point))

      (while (< pos start)
	;; Move forward one literal each time round this loop.
	;; Move forward to the start of a comment or string.
	(setq s (parse-partial-sexp
		 pos
		 start
		 nil			; target-depth
		 nil			; stop-before
		 s			; state
		 'syntax-table))	; stop-comment

	;; Gather details of the non-literal-bit - starting pos and size.
	(setq size (- (if (or (and (nth 4 s) (not (eq (nth 7 s) 'syntax-table)))
			      (nth 3 s))
			  (nth 8 s)
			(point))
		      pos))
	(if (> size 0)
	    (setq stack (cons (cons pos size) stack)))

	;; Move forward to the end of the comment/string.
	(if (or (and (nth 4 s) (not (eq (nth 7 s) 'syntax-table)))
		(nth 3 s))
	    (setq s (parse-partial-sexp
		     (point)
		     start
		     nil		; target-depth
		     nil		; stop-before
		     s			; state
		     'syntax-table)))	; stop-comment
	(setq pos (point)))

      ;; Now try and find enough non-literal characters recorded on the stack.
      ;; Go back one recorded literal each time round this loop.
      (while (and (< count how-far-back)
		  stack)
	(setq elt (car stack)
	      stack (cdr stack))
	(setq count (+ count (cdr elt))))
      (cond
       ((null elt)			; No non-literal characters found.
	(cond
	 ((> pos start)			; Nothing but literals
	  base)
	 ((and
	   (> base (point-min))
	   (> (- base try-size) (point-min))) ; prevent infinite recursion.
	  (c-determine-limit how-far-back base (* 2 try-size) org-start))
	 (t base)))
       ((>= count how-far-back)
	(c-determine-limit-no-macro
	 (+ (car elt) (- count how-far-back))
	 org-start))
       ((eq base (point-min))
	(point-min))
       ((> base (- start try-size)) ; Can only happen if we hit point-min.
	(c-determine-limit-no-macro
	 (car elt)
	 org-start))
       (t
	(c-determine-limit (- how-far-back count) base (* 2 try-size)
			   org-start))))))