;; kde-emacs-core.el - core functionality,e.g. syntax & c++-mode-hook
;;
;; Copyright (C)  2002  KDE Development Team <www.kde.org>
;;
;; This library is free software; you can redistribute it and/or
;; modify it under the terms of the GNU Lesser General Public
;; License as published by the Free Software Foundation; either
;; version 2.1 of the License, or (at your option) any later version.
;;
;; This library is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; Lesser General Public License for more details.
;;
;; You should have received a copy of the GNU Lesser General Public
;; License along with this library; if not, write to the Free Software
;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
;; 02111-1307  USA

(require 'kde-emacs-vars)
;*---------------------------------------------------------------------*/
;*    Variables ...                                                    */
;*---------------------------------------------------------------------*/

(defcustom kde-tab-behavior 'default
  "Specifies the current tab behavior"
  :group 'kde-devel
  :version "0.1"
  :type `(choice (const default) (const abbrev-indent) (const indent)))

;*---------------------------------------------------------------------*/
;*    Functions ...                                                    */
;*---------------------------------------------------------------------*/


;; -------  First part, from Arnt's "c++ stuff" - slightly modified for our needs :)

(defun agulbra-c++-tab (arg)
  "Do the right thing about tabs in c++ mode.
Try to finish the symbol, or indent the line."
  (interactive "*P")
  (cond
   ((and (not (looking-at "[A-Za-z0-9]"))
         (save-excursion 
           (forward-char -1)
           (looking-at "[A-Za-z0-9:>_\\-\\&\\.(){}\\*\\+/]")))
         (dabbrev-expand arg))
   (t
    (if (eq kde-tab-behavior 'default)
	(c-indent-command)
      (save-excursion
	(beginning-of-line)
	(c-indent-command))))))

(defun agulbra-clean-out-spaces ()
  "Remove spaces at ends of lines."
  (interactive)
  (and (not buffer-read-only)
       (save-excursion
         (goto-char (point-min))
         (let ((count 0)
               (bmp (buffer-modified-p)))
           (while (re-search-forward "[ \t]+$" nil t)
             (setq count (1+ count))
             (replace-match "" t t))
           (set-buffer-modified-p bmp)
	   nil
           ))))

; the above used to contain (untabify (point-min) (point-max)) too

(defun agulbra-c++-clean-out-spaces ()
  "Remove spaces at ends of lines, only in c++ mode."
  (interactive)
  (if (eq major-mode 'c++-mode)
      (agulbra-clean-out-spaces)
    )
  )

(defun agulbra-delete-into-nomenclature (&optional arg)
  "Delete forward until the end of a nomenclature section or word.
With arg, do it arg times."
  (interactive "p")
  (save-excursion
    (let ((b (point-marker)))
      (c-forward-into-nomenclature arg)
      (delete-region b (point-marker)))))


(if (not (fboundp 'font-lock-add-keywords))
    (defun font-lock-add-keywords (mode keywords &optional append)
      "XEmacs doesn't have font-lock-add-keywords so we provide it."
      (font-lock-set-defaults)
      (if (eq append 'set)
	  (setq font-lock-keywords keywords)
	; NOTE: write this function for XEmacs - Zack
	;(font-lock-remove-keywords nil keywords) ;to avoid duplicates
	(let ((old (if (eq (car-safe font-lock-keywords) t)
		       (cdr font-lock-keywords)
		     font-lock-keywords)))
	  (setq font-lock-keywords (if append
				       (append old keywords)
				     (append keywords old))))))
  )

(c-add-style "kde-c" '("stroustrup"
		       (c-basic-offset . 4)
		       (c-offsets-alist
			(case-label . 4)
			(access-label . -)
			(label . 0)
			(statement-cont . c-lineup-math)
			)))

;  ( we use Backquote ( '`' ) instead of "'" because we want
;    kde-access-labels to be evaluated... )
(c-add-style "kde-c++" `("kde-c"
  ;;FIXME: 1) fume functions not available on GNU/Emacs
  ;;       2) insert-tab-mode no longer present (free variable)
  ;;       3) c-hangin-commment-under-p no longer present (free variable)
			 (c-tab-always-indent . nil)
					; (insert-tab-mode nil)
			 (indent-tabs-mode . nil)
					; (fume-auto-rescan-buffer-p nil)
			 (c-access-key . ,kde-access-labels)
			 (c-opt-access-key . ,kde-access-labels)
					; (c-hanging-comment-under-p nil)
			 (c-offsets-alist (case-label . 0))
			 ))
		    
;; KDE C++ mode
;; Not a "(setq c++-mode-hook ..." because this way we would
;; prune all other hooks!
(defun kde-c++-mode-hook ()
  (font-lock-mode)
  (c-set-style kde-c++-style)
  (define-key c++-mode-map "\C-m" 'newline-and-indent)
  (when (or
	 (eq kde-tab-behavior 'default)
	 (eq kde-tab-behavior 'abbrev-indent))
    (define-key c++-mode-map "\C-i" 'agulbra-c++-tab))
  (define-key c++-mode-map "\ef" 'c-forward-into-nomenclature)
  (define-key c++-mode-map "\ed" 'agulbra-delete-into-nomenclature)
  (define-key c++-mode-map "\eb" 'c-backward-into-nomenclature)
  ;; fontify "public|protected|private slots" with one and the same face :)
  ;; NOTE: write face-at-point function to fontify those just like other
  ;; access specifiers - Zack
  (font-lock-add-keywords nil '(("\\<\\(\\(public\\|protected\\|private\\) slots\\)\\>" 
				 . font-lock-reference-face)))
  ;; Add (setq magic-keys-mode t) to your .emacs (before loading this file)
  ;; to enable the magic keys in C++ mode.
  (and (boundp 'magic-keys-mode)
       (progn
	 (define-key c++-mode-map [\(] 'insert-parens)
	 (define-key c++-mode-map [\)] 'insert-parens2)
	 (define-key c++-mode-map [,] 'insert-comma)
	 (define-key c++-mode-map [\{] 'insert-curly-brace)
	 ))
  )

(defun kde-c-mode-hook ()
  (font-lock-mode)
  (c-set-style kde-c-style))

;; NOTE : This is a completely new c-guess-basic-syntax, it's faster, 
;;        better, meaner, harder, covers more cases, more c++ syntax,
;;        and is in general cooler ;) You have to have the new cc-mode
;;        to use it ( 5.30 at least, check it with "M-x c-version")
;;        If you don't have 5.30 comment out the following c-guess-basic-syntax
;;        and uncomment the one underneath.
(if (>= (string-to-number c-version) 5.30)
    (defun c-guess-basic-syntax ()
      "Return the syntactic context of the current line."
      (save-excursion
	(save-restriction
	  (beginning-of-line)
	  (let* ((indent-point (point))
		 (case-fold-search nil)
		 (paren-state (c-parse-state))
		 literal containing-sexp char-before-ip char-after-ip lim
		 syntax placeholder c-in-literal-cache step-type
		 tmpsymbol keyword injava-inher special-brace-list
		 ;; narrow out any enclosing class or extern "C" block
		 (inclass-p (c-narrow-out-enclosing-class paren-state
							  indent-point))
		 ;; c-state-cache is shadowed here.  That means we must
		 ;; not do any changes during the execution of this
		 ;; function, since c-check-state-cache then would change
		 ;; this local variable and leave a bogus value in the
		 ;; global one.
		 (c-state-cache (if inclass-p
				    (c-whack-state-before (point-min) paren-state)
				  paren-state))
		 (c-state-cache-start (point-min))
		 inenclosing-p macro-start in-macro-expr
		 ;; There's always at most one syntactic element which got
		 ;; a relpos.  It's stored in syntactic-relpos.
		 syntactic-relpos
		 (c-stmt-delim-chars c-stmt-delim-chars))
	    ;; check for meta top-level enclosing constructs, possible
	    ;; extern language definitions, possibly (in C++) namespace
	    ;; definitions.
	    (save-excursion
	      (save-restriction
		(widen)
		(if (and inclass-p
			 (progn
			   (goto-char (aref inclass-p 0))
			   (looking-at c-other-decl-block-key)))
		    (let ((enclosing (match-string 1)))
		      (cond
		       ((string-equal enclosing "extern")
			(setq inenclosing-p 'extern))
		       ((string-equal enclosing "namespace")
			(setq inenclosing-p 'namespace))
		       )))))

	    ;; Init some position variables:
	    ;;
	    ;; containing-sexp is the open paren of the closest
	    ;; surrounding sexp or nil if there is none that hasn't been
	    ;; narrowed out.
	    ;;
	    ;; lim is the position after the closest preceding brace sexp
	    ;; (nested sexps are ignored), or the position after
	    ;; containing-sexp if there is none, or (point-min) if
	    ;; containing-sexp is nil.
	    ;;
	    ;; c-state-cache is the state from c-parse-state at
	    ;; indent-point, without any parens outside the region
	    ;; narrowed by c-narrow-out-enclosing-class.
	    ;;
	    ;; paren-state is the state from c-parse-state outside
	    ;; containing-sexp, or at indent-point if containing-sexp is
	    ;; nil.  paren-state is not limited to the narrowed region, as
	    ;; opposed to c-state-cache.
	    (if c-state-cache
		(progn
		  (setq containing-sexp (car paren-state)
			paren-state (cdr paren-state))
		  (if (consp containing-sexp)
		      (progn
			(setq lim (cdr containing-sexp))
			(if (cdr c-state-cache)
			    ;; Ignore balanced paren.  The next entry
			    ;; can't be another one.
			    (setq containing-sexp (car (cdr c-state-cache))
				  paren-state (cdr paren-state))
			  ;; If there is no surrounding open paren then
			  ;; put the last balanced pair back on paren-state.
			  (setq paren-state (cons containing-sexp paren-state)
				containing-sexp nil)))
		    (setq lim (1+ containing-sexp))))
	      (setq lim (point-min)))

	    ;; If we're in a parenthesis list then ',' delimits the
	    ;; "statements" rather than being an operator (with the
	    ;; exception of the "for" clause).  This difference is
	    ;; typically only noticeable when statements are used in macro
	    ;; arglists.
	    (when (and containing-sexp
		       (eq (char-after containing-sexp) ?\())
	      (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))

	    ;; cache char before and after indent point, and move point to
	    ;; the most likely position to perform the majority of tests
	    (goto-char indent-point)
	    (c-backward-syntactic-ws lim)
	    (setq char-before-ip (char-before))
	    (goto-char indent-point)
	    (skip-chars-forward " \t")
	    (setq char-after-ip (char-after))

	    ;; are we in a literal?
	    (setq literal (c-in-literal lim))

	    ;; now figure out syntactic qualities of the current line
	    (cond
	     ;; CASE 1: in a string.
	     ((eq literal 'string)
	      (c-add-syntax 'string (c-point 'bopl)))
	     ;; CASE 2: in a C or C++ style comment.
	     ((memq literal '(c c++))
	      (c-add-syntax literal (car (c-literal-limits lim))))
	     ;; CASE 3: in a cpp preprocessor macro continuation.
	     ((and (save-excursion
		     (when (c-beginning-of-macro)
		       (setq macro-start (point))))
		   (/= macro-start (c-point 'boi))
		   (progn
		     (setq tmpsymbol 'cpp-macro-cont)
		     (or (not c-syntactic-indentation-in-macros)
			 (save-excursion
			   (goto-char macro-start)
			   ;; If at the beginning of the body of a #define
			   ;; directive then analyze as cpp-define-intro
			   ;; only.  Go on with the syntactic analysis
			   ;; otherwise.  in-macro-expr is set if we're in a
			   ;; cpp expression, i.e. before the #define body
			   ;; or anywhere in a non-#define directive.
			   (if (c-forward-to-cpp-define-body)
			       (let ((indent-boi (c-point 'boi indent-point)))
				 (setq in-macro-expr (> (point) indent-boi)
				       tmpsymbol 'cpp-define-intro)
				 (= (point) indent-boi))
			     (setq in-macro-expr t)
			     nil)))))
	      (c-add-syntax tmpsymbol macro-start)
	      (setq macro-start nil))
	     ;; CASE 11: an else clause?
	     ((looking-at "else\\>[^_]")
	      (c-beginning-of-statement-1 containing-sexp)
	      (c-add-stmt-syntax 'else-clause t containing-sexp paren-state))
	     ;; CASE 12: while closure of a do/while construct?
	     ((and (looking-at "while\\>[^_]")
		   (save-excursion
		     (prog1 (eq (c-beginning-of-statement-1 containing-sexp)
				'beginning)
		       (setq placeholder (point)))))
	      (goto-char placeholder)
	      (c-add-stmt-syntax 'do-while-closure t containing-sexp paren-state))
	     ;; CASE 13: A catch or finally clause?  This case is simpler
	     ;; than if-else and do-while, because a block is required
	     ;; after every try, catch and finally.
	     ((save-excursion
		(and (cond ((c-major-mode-is 'c++-mode)
			    (looking-at "catch\\>[^_]"))
			   ((c-major-mode-is 'java-mode)
			    (looking-at "\\(catch\\|finally\\)\\>[^_]")))
		     (and (c-safe (c-backward-syntactic-ws)
				  (c-backward-sexp)
				  t)
			  (eq (char-after) ?{)
			  (c-safe (c-backward-syntactic-ws)
				  (c-backward-sexp)
				  t)
			  (if (eq (char-after) ?\()
			      (c-safe (c-backward-sexp) t)
			    t))
		     (looking-at "\\(try\\|catch\\)\\>[^_]")
		     (setq placeholder (point))))
	      (goto-char placeholder)
	      (c-add-stmt-syntax 'catch-clause t containing-sexp paren-state))
	     ;; CASE 18: A substatement we can recognize by keyword.
	     ((save-excursion
		(and c-opt-block-stmt-key
		     (not (eq char-before-ip ?\;))
		     (not (memq char-after-ip '(?\) ?\] ?,)))
		     (or (not (eq char-before-ip ?}))
			 (c-looking-at-inexpr-block-backward c-state-cache))
		     (> (point)
			(progn
			  ;; Ought to cache the result from the
			  ;; c-beginning-of-statement-1 calls here.
			  (setq placeholder (point))
			  (while (eq (setq step-type
					   (c-beginning-of-statement-1 lim))
				     'label))
			  (if (eq step-type 'previous)
			      (goto-char placeholder)
			    (setq placeholder (point))
			    (if (and (eq step-type 'same)
				     (not (looking-at c-opt-block-stmt-key)))
				;; Step up to the containing statement if we
				;; stayed in the same one.
				(let (step)
				  (while (eq
					  (setq step
						(c-beginning-of-statement-1 lim))
					  'label))
				  (if (eq step 'up)
				      (setq placeholder (point))
				    ;; There was no containing statement afterall.
				    (goto-char placeholder)))))
			  placeholder))
		     (if (looking-at c-block-stmt-2-key)
			 ;; Require a parenthesis after these keywords.
			 ;; Necessary to catch e.g. synchronized in Java,
			 ;; which can be used both as statement and
			 ;; modifier.
			 (and (= (c-forward-token-1 1 nil) 0)
			      (eq (char-after) ?\())
		       (looking-at c-opt-block-stmt-key))))
	      (if (eq step-type 'up)
		  ;; CASE 18A: Simple substatement.
		  (progn
		    (goto-char placeholder)
		    (cond
		     ((eq char-after-ip ?{)
		      (c-add-stmt-syntax 'substatement-open nil
					 containing-sexp paren-state))
		     ((save-excursion
			(goto-char indent-point)
			(back-to-indentation)
			(looking-at c-label-key))
		      (c-add-stmt-syntax 'substatement-label nil
					 containing-sexp paren-state))
		     (t
		      (c-add-stmt-syntax 'substatement nil
					 containing-sexp paren-state))))
		;; CASE 18B: Some other substatement.  This is shared
		;; with case 10.
		(c-guess-continued-construct indent-point
					     char-after-ip
					     placeholder
					     lim
					     paren-state)))
	     ;; CASE 4: In-expression statement.  C.f. cases 7B, 16A and
	     ;; 17E.
	     ((and (or c-opt-inexpr-class-key
		       c-opt-inexpr-block-key
		       c-opt-lambda-key)
		   (setq placeholder (c-looking-at-inexpr-block
				      (c-safe-position containing-sexp paren-state)
				      containing-sexp)))
	      (setq tmpsymbol (assq (car placeholder)
				    '((inexpr-class . class-open)
				      (inexpr-statement . block-open))))
	      (if tmpsymbol
		  ;; It's a statement block or an anonymous class.
		  (setq tmpsymbol (cdr tmpsymbol))
		;; It's a Pike lambda.  Check whether we are between the
		;; lambda keyword and the argument list or at the defun
		;; opener.
		(setq tmpsymbol (if (eq char-after-ip ?{)
				    'inline-open
				  'lambda-intro-cont)))
	      (goto-char (cdr placeholder))
	      (back-to-indentation)
	      (c-add-stmt-syntax tmpsymbol t
				 (c-most-enclosing-brace c-state-cache (point))
				 (c-whack-state-after (point) paren-state))
	      (unless (eq (point) (cdr placeholder))
		(c-add-syntax (car placeholder))))
	     ;; CASE 5: Line is at top level.
	     ((null containing-sexp)
	      (cond
	       ;; CASE 5A: we are looking at a defun, brace list, class,
	       ;; or inline-inclass method opening brace
	       ((setq special-brace-list
		      (or (and c-special-brace-lists
			       (c-looking-at-special-brace-list))
			  (eq char-after-ip ?{)))
		(cond
		 ;; CASE 5A.1: extern language or namespace construct
		 ((save-excursion
		    (goto-char indent-point)
		    (skip-chars-forward " \t")
		    (and (c-safe (progn (c-backward-sexp 2) t))
			 (looking-at c-other-decl-block-key)
			 (setq keyword (match-string 1)
			       placeholder (point))
			 (or (and (string-equal keyword "namespace")
				  (setq tmpsymbol 'namespace-open))
			     (and (string-equal keyword "extern")
				  (progn
				    (c-forward-sexp 1)
				    (c-forward-syntactic-ws)
				    (eq (char-after) ?\"))
				  (setq tmpsymbol 'extern-lang-open)))
			 ))
		  (goto-char placeholder)
		  (c-add-syntax tmpsymbol (c-point 'boi)))
		 ;; CASE 5A.2: we are looking at a class opening brace
		 ((save-excursion
		    (goto-char indent-point)
		    (skip-chars-forward " \t{")
		    (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
		      (and decl
			   (setq placeholder (aref decl 0)))
		      ))
		  (c-add-syntax 'class-open placeholder))
		 ;; CASE 5A.3: brace list open
		 ((save-excursion
		    (c-beginning-of-decl-1 lim)
		    (if (looking-at "typedef\\>[^_]")
			(progn (c-forward-sexp 1)
			       (c-forward-syntactic-ws indent-point)))
		    (setq placeholder (c-point 'boi))
		    (or (consp special-brace-list)
			(and (or (save-excursion
				   (goto-char indent-point)
				   (setq tmpsymbol nil)
				   (while (and (> (point) placeholder)
					       (= (c-backward-token-1 1 t) 0)
					       (/= (char-after) ?=))
				     (if (and (not tmpsymbol)
					      (looking-at "new\\>[^_]"))
					 (setq tmpsymbol 'topmost-intro-cont)))
				   (eq (char-after) ?=))
				 (looking-at "enum\\>[^_]"))
			     (save-excursion
			       (while (and (< (point) indent-point)
					   (= (c-forward-token-1 1 t) 0)
					   (not (memq (char-after) '(?\; ?\()))))
			       (not (memq (char-after) '(?\; ?\()))
			       ))))
		  (if (and (c-major-mode-is 'java-mode)
			   (eq tmpsymbol 'topmost-intro-cont))
		      ;; We're in Java and have found that the open brace
		      ;; belongs to a "new Foo[]" initialization list,
		      ;; which means the brace list is part of an
		      ;; expression and not a top level definition.  We
		      ;; therefore treat it as any topmost continuation
		      ;; even though the semantically correct symbol still
		      ;; is brace-list-open, on the same grounds as in
		      ;; case 10B.2.
		      (progn
			(c-beginning-of-statement-1 lim)
			(c-add-syntax 'topmost-intro-cont (c-point 'boi)))
		    (c-add-syntax 'brace-list-open placeholder)))
		 ;; CASE 5A.4: inline defun open
		 ((and inclass-p (not inenclosing-p))
		  (c-add-syntax 'inline-open)
		  (c-add-class-syntax 'inclass inclass-p paren-state))
		 ;; CASE 5A.5: ordinary defun open
		 (t
		  (goto-char placeholder)
		  (if (or inclass-p macro-start)
		      (c-add-syntax 'defun-open (c-point 'boi))
		    ;; Bogus to use bol here, but it's the legacy.
		    (c-add-syntax 'defun-open (c-point 'bol)))
		  )))
	       ;; CASE 5B: first K&R arg decl or member init
	       ((c-just-after-func-arglist-p nil lim)
		(cond
		 ;; CASE 5B.1: a member init
		 ((or (eq char-before-ip ?:)
		      (eq char-after-ip ?:))
		  ;; this line should be indented relative to the beginning
		  ;; of indentation for the topmost-intro line that contains
		  ;; the prototype's open paren
		  ;; TBD: is the following redundant?
		  (if (eq char-before-ip ?:)
		      (forward-char -1))
		  (c-backward-syntactic-ws lim)
		  ;; TBD: is the preceding redundant?
		  (if (eq (char-before) ?:)
		      (progn (forward-char -1)
			     (c-backward-syntactic-ws lim)))
		  (if (eq (char-before) ?\))
		      (c-backward-sexp 1))
		  (setq placeholder (point))
		  (save-excursion
		    (and (c-safe (c-backward-sexp 1) t)
			 (looking-at "throw[^_]")
			 (c-safe (c-backward-sexp 1) t)
			 (setq placeholder (point))))
		  (goto-char placeholder)
		  (c-add-syntax 'member-init-intro (c-point 'boi))
		  ;; we don't need to add any class offset since this
		  ;; should be relative to the ctor's indentation
		  )
		 ;; CASE 5B.2: K&R arg decl intro
		 (c-recognize-knr-p
		  (c-beginning-of-statement-1 lim)
		  (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
		  (if inclass-p
		      (c-add-class-syntax 'inclass inclass-p paren-state)))
		 ;; CASE 5B.3: Inside a member init list.
		 ((c-beginning-of-member-init-list lim)
		  (c-forward-syntactic-ws)
		  (c-add-syntax 'member-init-cont (point)))
		 ;; CASE 5B.4: Nether region after a C++ or Java func
		 ;; decl, which could include a `throws' declaration.
		 (t
		  (c-beginning-of-statement-1 lim)
		  (c-add-syntax 'func-decl-cont (c-point 'boi))
		  )))
	       ;; CASE 5C: inheritance line. could be first inheritance
	       ;; line, or continuation of a multiple inheritance
	       ((or (and (c-major-mode-is 'c++-mode)
			 (progn
			   (when (eq char-after-ip ?,)
			     (skip-chars-forward " \t")
			     (forward-char))
			   (looking-at c-opt-decl-spec-key)))
		    (and (or (eq char-before-ip ?:)
			     ;; watch out for scope operator
			     (save-excursion
			       (and (eq char-after-ip ?:)
				    (c-safe (progn (forward-char 1) t))
				    (not (eq (char-after) ?:))
				    )))
			 (save-excursion
			   (c-backward-syntactic-ws lim)
			   (if (eq char-before-ip ?:)
			       (progn
				 (forward-char -1)
				 (c-backward-syntactic-ws lim)))
			   (back-to-indentation)
			   (looking-at c-class-key)))
		    ;; for Java
		    (and (c-major-mode-is 'java-mode)
			 (let ((fence (save-excursion
					(c-beginning-of-statement-1 lim)
					(point)))
			       cont done)
			   (save-excursion
			     (while (not done)
			       (cond ((looking-at c-opt-decl-spec-key)
				      (setq injava-inher (cons cont (point))
					    done t))
				     ((or (not (c-safe (c-forward-sexp -1) t))
					  (<= (point) fence))
				      (setq done t))
				     )
			       (setq cont t)))
			   injava-inher)
			 (not (c-crosses-statement-barrier-p (cdr injava-inher)
							     (point)))
			 ))
		(cond
		 ;; CASE 5C.1: non-hanging colon on an inher intro
		 ((eq char-after-ip ?:)
		  (c-beginning-of-statement-1 lim)
		  (c-add-syntax 'inher-intro (c-point 'boi))
		  ;; don't add inclass symbol since relative point already
		  ;; contains any class offset
		  )
		 ;; CASE 5C.2: hanging colon on an inher intro
		 ((eq char-before-ip ?:)
		  (c-beginning-of-statement-1 lim)
		  (c-add-syntax 'inher-intro (c-point 'boi))
		  (if inclass-p
		      (c-add-class-syntax 'inclass inclass-p paren-state)))
		 ;; KDE Hack Start:
		 ((and inclass-p
		       c-access-key
		       (looking-at c-access-key))
		  (c-add-syntax 'access-label (c-point 'bonl))
		  (setq placeholder (c-add-class-syntax 'inclass inclass-p
							paren-state)))
		 ;;(nconc syntax (list (cons 'access-label placeholder))))
		 ;; KDE Hack End.
		 ;; CASE 5C.3: in a Java implements/extends
		 (injava-inher
		  (let ((where (cdr injava-inher))
			(cont (car injava-inher)))
		    (goto-char where)
		    (cond ((looking-at "throws\\>[^_]")
			   (c-add-syntax 'func-decl-cont
					 (progn (c-beginning-of-statement-1 lim)
						(c-point 'boi))))
			  (cont (c-add-syntax 'inher-cont where))
			  (t (c-add-syntax 'inher-intro
					   (progn (goto-char (cdr injava-inher))
						  (c-beginning-of-statement-1 lim)
						  (point))))
			  )))
		 ;; CASE 5C.4: a continued inheritance line
		 (t
		  (c-beginning-of-inheritance-list lim)
		  (c-add-syntax 'inher-cont (point))
		  ;; don't add inclass symbol since relative point already
		  ;; contains any class offset
		  )))
	       ;; CASE 5D: this could be a top-level initialization, a
	       ;; member init list continuation, or a template argument
	       ;; list continuation.
	       ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
					 c++-template-syntax-table
				       (syntax-table))
		  (save-excursion
		    ;; Note: We use the fact that lim is always after any
		    ;; preceding brace sexp.
		    (while (and (= (c-backward-token-1 1 t lim) 0)
				(not (looking-at "[;<,=]"))))
		    (or (memq (char-after) '(?, ?=))
			(and (c-major-mode-is 'c++-mode)
			     (= (c-backward-token-1 1 nil lim) 0)
			     (eq (char-after) ?<)))))
		(goto-char indent-point)
		(c-beginning-of-member-init-list lim)
		(cond
		 ;; CASE 5D.1: hanging member init colon, but watch out
		 ;; for bogus matches on access specifiers inside classes.
		 ((and (save-excursion
			 (setq placeholder (point))
			 (c-backward-token-1 1 t lim)
			 (and (eq (char-after) ?:)
			      (not (eq (char-before) ?:))))
		       (save-excursion
			 (goto-char placeholder)
			 (back-to-indentation)
			 (or
			  (/= (car (save-excursion
				     (parse-partial-sexp (point) placeholder)))
			      0)
			  (and
			   (if c-opt-access-key
			       (not (looking-at c-opt-access-key)) t)
			   (not (looking-at c-class-key))
			   (if c-opt-bitfield-key
			       (not (looking-at c-opt-bitfield-key)) t))
			  )))
		  (goto-char placeholder)
		  (c-forward-syntactic-ws)
		  (c-add-syntax 'member-init-cont (point))
		  ;; we do not need to add class offset since relative
		  ;; point is the member init above us
		  )
		 ;; CASE 5D.2: non-hanging member init colon
		 ((progn
		    (c-forward-syntactic-ws indent-point)
		    (eq (char-after) ?:))
		  (skip-chars-forward " \t:")
		  (c-add-syntax 'member-init-cont (point)))
		 ;; CASE 5D.3: perhaps a template list continuation?
		 ((and (c-major-mode-is 'c++-mode)
		       (save-excursion
			 (save-restriction
			   (c-with-syntax-table c++-template-syntax-table
			     (goto-char indent-point)
			     (setq placeholder (c-up-list-backward (point)))
			     (and placeholder
				  (eq (char-after placeholder) ?<))))))
		  ;; we can probably indent it just like an arglist-cont
		  (goto-char placeholder)
		  (c-beginning-of-statement-1 lim t)
		  (c-add-syntax 'template-args-cont (c-point 'boi)))
		 ;; CASE 5D.4: perhaps a multiple inheritance line?
		 ((and (c-major-mode-is 'c++-mode)
		       (save-excursion
			 (c-beginning-of-statement-1 lim)
			 (setq placeholder (point))
			 (if (looking-at "static\\>[^_]")
			     (c-forward-token-1 1 nil indent-point))
			 (and (looking-at c-class-key)
			      (= (c-forward-token-1 2 nil indent-point) 0)
			      (if (eq (char-after) ?<)
				  (c-with-syntax-table c++-template-syntax-table
				    (= (c-forward-token-1 1 t indent-point) 0))
				t)
			      (eq (char-after) ?:))))
		  (goto-char placeholder)
		  (c-add-syntax 'inher-cont (c-point 'boi)))
		 ;; CASE 5D.5: Continuation of the "expression part" of a
		 ;; top level construct.
		 (t
		  (while (and (eq (car (c-beginning-of-decl-1 containing-sexp))
				  'same)
			      (save-excursion
				(c-backward-syntactic-ws)
				(eq (char-before) ?}))))
		  (c-add-stmt-syntax
		   (if (eq char-before-ip ?,)
		       ;; A preceding comma at the top level means that a
		       ;; new variable declaration starts here.  Use
		       ;; topmost-intro-cont for it, for consistency with
		       ;; the first variable declaration.  C.f. case 5N.
		       'topmost-intro-cont
		     'statement-cont)
		   nil containing-sexp paren-state))
		 ))
	       ;; CASE 5E: we are looking at a access specifier
	       ((and inclass-p
		     c-opt-access-key
		     (looking-at c-opt-access-key))
		(setq placeholder (c-add-class-syntax 'inclass inclass-p
						      paren-state))
		;; Append access-label with the same anchor point as inclass gets.
		(nconc syntax (list (cons 'access-label placeholder))))
	       ;; CASE 5F: extern-lang-close or namespace-close?
	       ((and inenclosing-p
		     (eq char-after-ip ?}))
		(setq tmpsymbol (if (eq inenclosing-p 'extern)
				    'extern-lang-close
				  'namespace-close))
		(c-add-syntax tmpsymbol (aref inclass-p 0)))
	       ;; CASE 5G: we are looking at the brace which closes the
	       ;; enclosing nested class decl
	       ((and inclass-p
		     (eq char-after-ip ?})
		     (save-excursion
		       (save-restriction
			 (widen)
			 (forward-char 1)
			 (and (c-safe (progn (c-backward-sexp 1) t))
			      (= (point) (aref inclass-p 1))
			      ))))
		(c-add-class-syntax 'class-close inclass-p paren-state))
	       ;; CASE 5H: we could be looking at subsequent knr-argdecls
	       ((and c-recognize-knr-p
		     (not (eq char-before-ip ?}))
		     (save-excursion
		       (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
		       (and placeholder
			    ;; Do an extra check to avoid tripping up on
			    ;; statements that occur in invalid contexts
			    ;; (e.g. in macro bodies where we don't really
			    ;; know the context of what we're looking at).
			    (not (and c-opt-block-stmt-key
				      (looking-at c-opt-block-stmt-key)))))
		     (< placeholder indent-point))
		(goto-char placeholder)
		(c-add-syntax 'knr-argdecl (point)))
	       ;; CASE 5I: ObjC method definition.
	       ((and c-opt-method-key
		     (looking-at c-opt-method-key))
		(c-beginning-of-statement-1 lim)
		(c-add-syntax 'objc-method-intro (c-point 'boi)))
	       ;; CASE 5N: At a variable declaration that follows a class
	       ;; definition or some other block declaration that doesn't
	       ;; end at the closing '}'.  C.f. case 5D.5.
	       ((progn
		  (c-backward-syntactic-ws lim)
		  (and (eq (char-before) ?})
		       (save-excursion
			 (let ((start (point)))
			   (if paren-state
			       ;; Speed up the backward search a bit.
			       (goto-char (car (car paren-state))))
			   (c-beginning-of-decl-1 containing-sexp)
			   (setq placeholder (point))
			   (if (= start (point))
			       ;; The '}' is unbalanced.
			       nil
			     (c-end-of-decl-1)
			     (> (point) indent-point))))))
		(goto-char placeholder)
		(c-add-stmt-syntax 'topmost-intro-cont nil
				   containing-sexp paren-state))
	       ;; CASE 5J: we are at the topmost level, make
	       ;; sure we skip back past any access specifiers
	       ((progn
		  (while (and inclass-p
			      c-opt-access-key
			      (not (bobp))
			      (save-excursion
				(c-safe (progn (c-backward-sexp 1) t))
				(and (looking-at "slots:")
				   (c-backward-sexp 1))
				(looking-at c-opt-access-key)))
		    (c-backward-sexp 1)
		    (c-backward-syntactic-ws lim))
		  (or (bobp)
		      (memq (char-before) '(?\; ?}))
		      (and (c-major-mode-is 'objc-mode)
			   (progn
			     (c-beginning-of-statement-1 lim)
			     (eq (char-after) ?@)))))
		;; real beginning-of-line could be narrowed out due to
		;; enclosure in a class block
		(save-restriction
		  (widen)
		  (c-add-syntax 'topmost-intro (c-point 'bol))
		  ;; Using bol instead of boi above is highly bogus, and
		  ;; it makes our lives hard to remain compatible. :P
		  (if inclass-p
		      (progn
			(goto-char (aref inclass-p 1))
			(or (= (point) (c-point 'boi))
			    (goto-char (aref inclass-p 0)))
			(cond
			 ((eq inenclosing-p 'extern)
			  (c-add-syntax 'inextern-lang (c-point 'boi)))
			 ((eq inenclosing-p 'namespace)
			  (c-add-syntax 'innamespace (c-point 'boi)))
			 (t (c-add-class-syntax 'inclass inclass-p paren-state)))
			))
		  (when (and c-syntactic-indentation-in-macros
			     macro-start
			     (/= macro-start (c-point 'boi indent-point)))
		    (c-add-syntax 'cpp-define-intro)
		    (setq macro-start nil))
		  ))
	       ;; CASE 5K: we are at an ObjC method definition
	       ;; continuation line.
	       ((and c-opt-method-key
		     (progn
		       (c-beginning-of-statement-1 lim)
		       (beginning-of-line)
		       (looking-at c-opt-method-key)))
		(c-add-syntax 'objc-method-args-cont (point)))
	       ;; CASE 5L: we are at the first argument of a template
	       ;; arglist that begins on the previous line.
	       ((eq (char-before) ?<)
		(c-beginning-of-statement-1 (c-safe-position (point) paren-state))
		(c-add-syntax 'template-args-cont (c-point 'boi)))
	       ;; CASE 5M: we are at a topmost continuation line
	       ;; KDE Hack 2
	       ;; NOTE: is there a way to detect these sooner ? 
	       (t
		(c-beginning-of-statement-1 (c-safe-position (point) paren-state))
		(if (re-search-forward c-access-key (point-at-eol) t)
		    (progn
		      (c-add-syntax 'topmost-intro (c-point 'bol))
		      (c-add-class-syntax 'inclass inclass-p paren-state)
		      )
		  (progn
		    (c-add-syntax 'topmost-intro-cont (c-point 'boi))
		    ))
		)
	       ))
	     ;; (CASE 6 has been removed.)
	     ;; CASE 7: line is an expression, not a statement.  Most
	     ;; likely we are either in a function prototype or a function
	     ;; call argument list
	     ((not (or (and c-special-brace-lists
			    (save-excursion
			      (goto-char containing-sexp)
			      (c-looking-at-special-brace-list)))
		       (eq (char-after containing-sexp) ?{)))
	      (cond
	       ;; CASE 7A: we are looking at the arglist closing paren
	       ((memq char-after-ip '(?\) ?\]))
		(goto-char containing-sexp)
		(setq placeholder (c-point 'boi))
		(when (and (c-safe (backward-up-list 1) t)
			   (> (point) placeholder))
		  (forward-char)
		  (skip-chars-forward " \t")
		  (setq placeholder (point)))
		(c-add-syntax 'arglist-close placeholder))
	       ;; CASE 7B: Looking at the opening brace of an
	       ;; in-expression block or brace list.  C.f. cases 4, 16A
	       ;; and 17E.
	       ((and (eq char-after-ip ?{)
		     (progn
		       (setq placeholder (c-inside-bracelist-p (point)
							       c-state-cache))
		       (if placeholder
			   (setq tmpsymbol '(brace-list-open . inexpr-class))
			 (setq tmpsymbol '(block-open . inexpr-statement)
			       placeholder
			       (cdr-safe (c-looking-at-inexpr-block
					  (c-safe-position containing-sexp
							   paren-state)
					  containing-sexp)))
			 ;; placeholder is nil if it's a block directly in
			 ;; a function arglist.  That makes us skip out of
			 ;; this case.
			 )))
		(goto-char placeholder)
		(back-to-indentation)
		(c-add-stmt-syntax (car tmpsymbol) t
				   (c-most-enclosing-brace paren-state (point))
				   (c-whack-state-after (point) paren-state))
		(if (/= (point) placeholder)
		    (c-add-syntax (cdr tmpsymbol))))
	       ;; CASE 7C: we are looking at the first argument in an empty
	       ;; argument list. Use arglist-close if we're actually
	       ;; looking at a close paren or bracket.
	       ((memq char-before-ip '(?\( ?\[))
		(goto-char containing-sexp)
		(setq placeholder (c-point 'boi))
		(when (and (c-safe (backward-up-list 1) t)
			   (> (point) placeholder))
		  (forward-char)
		  (skip-chars-forward " \t")
		  (setq placeholder (point)))
		(c-add-syntax 'arglist-intro placeholder))
	       ;; CASE 7D: we are inside a conditional test clause. treat
	       ;; these things as statements
	       ((progn
		  (goto-char containing-sexp)
		  (and (c-safe (progn (c-forward-sexp -1) t))
		       (looking-at "\\<for\\>[^_]")))
		(goto-char (1+ containing-sexp))
		(c-forward-syntactic-ws indent-point)
		(if (eq char-before-ip ?\;)
		    (c-add-syntax 'statement (point))
		  (c-add-syntax 'statement-cont (point))
		  ))
	       ;; CASE 7E: maybe a continued ObjC method call. This is the
	       ;; case when we are inside a [] bracketed exp, and what
	       ;; precede the opening bracket is not an identifier.
	       ((and c-opt-method-key
		     (eq (char-after containing-sexp) ?\[)
		     (progn
		       (goto-char (1- containing-sexp))
		       (c-backward-syntactic-ws (c-point 'bod))
		       (if (not (looking-at c-symbol-key))
			   (c-add-syntax 'objc-method-call-cont containing-sexp))
		       )))
	       ;; CASE 7F: we are looking at an arglist continuation line,
	       ;; but the preceding argument is on the same line as the
	       ;; opening paren.  This case includes multi-line
	       ;; mathematical paren groupings, but we could be on a
	       ;; for-list continuation line
	       ((progn
		  (goto-char (1+ containing-sexp))
		  (skip-chars-forward " \t")
		  (and (not (eolp))
		       (not (looking-at "\\\\$"))))
		(goto-char containing-sexp)
		(setq placeholder (c-point 'boi))
		(when (and (c-safe (backward-up-list 1) t)
			   (> (point) placeholder))
		  (forward-char)
		  (skip-chars-forward " \t")
		  (setq placeholder (point)))
		(c-add-syntax 'arglist-cont-nonempty placeholder))
	       ;; CASE 7G: we are looking at just a normal arglist
	       ;; continuation line
	       (t (c-forward-syntactic-ws indent-point)
		  (c-add-syntax 'arglist-cont (c-point 'boi)))
	       ))
	     ;; CASE 8: func-local multi-inheritance line
	     ((and (c-major-mode-is 'c++-mode)
		   (save-excursion
		     (goto-char indent-point)
		     (skip-chars-forward " \t")
		     (looking-at c-opt-decl-spec-key)))
	      (goto-char indent-point)
	      (skip-chars-forward " \t")
	      (cond
	       ;; CASE 8A: non-hanging colon on an inher intro
	       ((eq char-after-ip ?:)
		(c-backward-syntactic-ws lim)
		(c-add-syntax 'inher-intro (c-point 'boi)))
	       ;; CASE 8B: hanging colon on an inher intro
	       ((eq char-before-ip ?:)
		(c-add-syntax 'inher-intro (c-point 'boi)))
	       ;; CASE 8C: a continued inheritance line
	       (t
		(c-beginning-of-inheritance-list lim)
		(c-add-syntax 'inher-cont (point))
		)))
	     ;; CASE 9: we are inside a brace-list
	     ((setq special-brace-list
		    (or (and c-special-brace-lists
			     (save-excursion
			       (goto-char containing-sexp)
			       (c-looking-at-special-brace-list)))
			(c-inside-bracelist-p containing-sexp paren-state)))
	      (cond
	       ;; CASE 9A: In the middle of a special brace list opener.
	       ((and (consp special-brace-list)
		     (save-excursion
		       (goto-char containing-sexp)
		       (eq (char-after) ?\())
		     (eq char-after-ip (car (cdr special-brace-list))))
		(goto-char (car (car special-brace-list)))
		(skip-chars-backward " \t")
		(if (and (bolp)
			 (assoc 'statement-cont
				(setq placeholder (c-guess-basic-syntax))))
		    (setq syntax placeholder)
		  (c-beginning-of-statement-1
		   (c-safe-position (1- containing-sexp) paren-state))
		  (c-forward-token-1 0)
		  (if (looking-at "typedef\\>[^_]") (c-forward-token-1 1))
		  (c-add-syntax 'brace-list-open (c-point 'boi))))
	       ;; CASE 9B: brace-list-close brace
	       ((if (consp special-brace-list)
		    ;; Check special brace list closer.
		    (progn
		      (goto-char (car (car special-brace-list)))
		      (save-excursion
			(goto-char indent-point)
			(back-to-indentation)
			(or
			 ;; We were between the special close char and the `)'.
			 (and (eq (char-after) ?\))
			      (eq (1+ (point)) (cdr (car special-brace-list))))
			 ;; We were before the special close char.
			 (and (eq (char-after) (cdr (cdr special-brace-list)))
			      (= (c-forward-token-1) 0)
			      (eq (1+ (point)) (cdr (car special-brace-list)))))))
		  ;; Normal brace list check.
		  (and (eq char-after-ip ?})
		       (c-safe (progn (goto-char (c-up-list-backward (point)))
				      t))
		       (= (point) containing-sexp)))
		(if (eq (point) (c-point 'boi))
		    (c-add-syntax 'brace-list-close (point))
		  (setq lim (c-most-enclosing-brace c-state-cache (point)))
		  (c-beginning-of-statement-1 lim)
		  (c-add-stmt-syntax 'brace-list-close t lim
				     (c-whack-state-after (point) paren-state)
				     t)))
	       (t
		;; Prepare for the rest of the cases below by going to the
		;; token following the opening brace
		(if (consp special-brace-list)
		    (progn
		      (goto-char (car (car special-brace-list)))
		      (c-forward-token-1 1 nil indent-point))
		  (goto-char containing-sexp))
		(forward-char)
		(let ((start (point)))
		  (c-forward-syntactic-ws indent-point)
		  (goto-char (max start (c-point 'bol))))
		(c-skip-ws-forward indent-point)
		(cond
		 ;; CASE 9C: we're looking at the first line in a brace-list
		 ((= (point) indent-point)
		  (if (consp special-brace-list)
		      (goto-char (car (car special-brace-list)))
		    (goto-char containing-sexp))
		  (if (eq (point) (c-point 'boi))
		      (c-add-syntax 'brace-list-intro (point))
		    (setq lim (c-most-enclosing-brace c-state-cache (point)))
		    (c-beginning-of-statement-1 lim)
		    (c-add-stmt-syntax 'brace-list-intro t lim
				       (c-whack-state-after (point) paren-state)
				       t)))
		 ;; CASE 9D: this is just a later brace-list-entry or
		 ;; brace-entry-open
		 (t (if (or (eq char-after-ip ?{)
			    (and c-special-brace-lists
				 (save-excursion
				   (goto-char indent-point)
				   (c-forward-syntactic-ws (c-point 'eol))
				   (c-looking-at-special-brace-list (point)))))
			(c-add-syntax 'brace-entry-open (point))
		      (c-add-syntax 'brace-list-entry (point))
		      ))
		 ))))
	     ;; CASE 10: A continued statement or top level construct.
	     ((and (not (memq char-before-ip '(?\; ?:)))
		   (or (not (eq char-before-ip ?}))
		       (c-looking-at-inexpr-block-backward c-state-cache))
		   (> (point)
		      (save-excursion
			(c-beginning-of-statement-1 containing-sexp)
			(setq placeholder (point))))
		   (/= placeholder containing-sexp))
	      ;; This is shared with case 18.
	      (c-guess-continued-construct indent-point
					   char-after-ip
					   placeholder
					   containing-sexp
					   paren-state))
	     ;; CASE 14: A case or default label
	     ((looking-at c-label-kwds-regexp)
	      (goto-char containing-sexp)
	      (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
	      (c-backward-to-block-anchor lim)
	      (c-add-stmt-syntax 'case-label t lim paren-state))
	     ;; CASE 15: any other label
	     ((looking-at c-label-key)
	      (goto-char containing-sexp)
	      (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
	      (save-excursion
		(setq tmpsymbol
		      (if (and (eq (c-beginning-of-statement-1 lim) 'up)
			       (looking-at "switch\\>[^_]"))
			  ;; If the surrounding statement is a switch then
			  ;; let's analyze all labels as switch labels, so
			  ;; that they get lined up consistently.
			  'case-label
			'label)))
	      (c-backward-to-block-anchor lim)
	      (c-add-stmt-syntax tmpsymbol t lim paren-state))
	     ;; CASE 16: block close brace, possibly closing the defun or
	     ;; the class
	     ((eq char-after-ip ?})
	      ;; From here on we have the next containing sexp in lim.
	      (setq lim (c-most-enclosing-brace paren-state))
	      (goto-char containing-sexp)
	      (cond
	       ;; CASE 16E: Closing a statement block?  This catches
	       ;; cases where it's preceded by a statement keyword,
	       ;; which works even when used in an "invalid" context,
	       ;; e.g. a macro argument.
	       ((c-after-conditional)
		(c-backward-to-block-anchor lim)
		(c-add-stmt-syntax 'block-close t lim paren-state))
	       ;; CASE 16A: closing a lambda defun or an in-expression
	       ;; block?  C.f. cases 4, 7B and 17E.
	       ((setq placeholder (c-looking-at-inexpr-block
				   (c-safe-position containing-sexp paren-state)
				   nil))
		(setq tmpsymbol (if (eq (car placeholder) 'inlambda)
				    'inline-close
				  'block-close))
		(goto-char containing-sexp)
		(back-to-indentation)
		(if (= containing-sexp (point))
		    (c-add-syntax tmpsymbol (point))
		  (goto-char (cdr placeholder))
		  (back-to-indentation)
		  (c-add-stmt-syntax tmpsymbol t
				     (c-most-enclosing-brace paren-state (point))
				     (c-whack-state-after (point) paren-state))
		  (if (/= (point) (cdr placeholder))
		      (c-add-syntax (car placeholder)))))
	       ;; CASE 16B: does this close an inline or a function in
	       ;; an extern block or namespace?
	       ((setq placeholder (c-search-uplist-for-classkey paren-state))
		(c-backward-to-decl-anchor lim)
		(back-to-indentation)
		(if (save-excursion
		      (goto-char (aref placeholder 0))
		      (looking-at c-other-decl-block-key))
		    (c-add-syntax 'defun-close (point))
		  (c-add-syntax 'inline-close (point))))
	       ;; CASE 16F: Can be a defun-close of a function declared
	       ;; in a statement block, e.g. in Pike or when using gcc
	       ;; extensions.  Might also trigger it with some macros
	       ;; followed by blocks, and this gives sane indentation
	       ;; then too.  Let it through to be handled below.
	       ;; C.f. cases B.3 and 17G.
	       ((and (not inenclosing-p)
		     lim
		     (save-excursion
		       (and (not (c-looking-at-bos))
			    (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
			    (setq placeholder (point)))))
		(back-to-indentation)
		(if (/= (point) containing-sexp)
		    (goto-char placeholder))
		(c-add-stmt-syntax 'defun-close t lim paren-state))
	       ;; CASE 16C: if there an enclosing brace that hasn't
	       ;; been narrowed out by a class, then this is a
	       ;; block-close.  C.f. case 17H.
	       ((and (not inenclosing-p) lim)
		;; If the block is preceded by a case/switch label on
		;; the same line, we anchor at the first preceding label
		;; at boi.  The default handling in c-add-stmt-syntax is
		;; really fixes it better, but we do like this to keep
		;; the indentation compatible with version 5.28 and
		;; earlier.
		(while (and (/= (setq placeholder (point)) (c-point 'boi))
			    (eq (c-beginning-of-statement-1 lim) 'label)))
		(goto-char placeholder)
		(if (looking-at c-label-kwds-regexp)
		    (c-add-syntax 'block-close (point))
		  (goto-char containing-sexp)
		  ;; c-backward-to-block-anchor not necessary here; those
		  ;; situations are handled in case 16E above.
		  (c-add-stmt-syntax 'block-close t lim paren-state)))
	       ;; CASE 16D: find out whether we're closing a top-level
	       ;; class or a defun
	       (t
		(save-restriction
		  (narrow-to-region (point-min) indent-point)
		  (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
		    (if decl
			(c-add-class-syntax 'class-close decl paren-state)
		      (goto-char containing-sexp)
		      (c-backward-to-decl-anchor lim)
		      (back-to-indentation)
		      (c-add-syntax 'defun-close (point)))))
		)))
	     ;; CASE 17: Statement or defun catchall.
	     (t
	      (goto-char indent-point)
	      ;; Back up statements until we find one that starts at boi.
	      (while (let* ((prev-point (point))
			    (last-step-type (c-beginning-of-statement-1
					     containing-sexp)))
		       (if (= (point) prev-point)
			   (progn
			     (setq step-type (or step-type last-step-type))
			     nil)
			 (setq step-type last-step-type)
			 (/= (point) (c-point 'boi)))))
	      (cond
	       ;; CASE 17B: continued statement
	       ((and (eq step-type 'same)
		     (/= (point) indent-point))
		(c-add-stmt-syntax 'statement-cont nil
				   containing-sexp paren-state))
	       ;; CASE 17A: After a case/default label?
	       ((progn
		  (while (and (eq step-type 'label)
			      (not (looking-at c-label-kwds-regexp)))
		    (setq step-type
			  (c-beginning-of-statement-1 containing-sexp)))
		  (eq step-type 'label))
		(c-add-stmt-syntax (if (eq char-after-ip ?{)
				       'statement-case-open
				     'statement-case-intro)
				   t containing-sexp paren-state))
	       ;; CASE 17D: any old statement
	       ((progn
		  (while (eq step-type 'label)
		    (setq step-type
			  (c-beginning-of-statement-1 containing-sexp)))
		  (eq step-type 'previous))
		(c-add-stmt-syntax 'statement t containing-sexp paren-state)
		(if (eq char-after-ip ?{)
		    (c-add-syntax 'block-open)))
	       ;; CASE 17I: Inside a substatement block.
	       ((progn
		  ;; The following tests are all based on containing-sexp.
		  (goto-char containing-sexp)
		  ;; From here on we have the next containing sexp in lim.
		  (setq lim (c-most-enclosing-brace paren-state containing-sexp))
		  (c-after-conditional))
		(c-backward-to-block-anchor lim)
		(c-add-stmt-syntax 'statement-block-intro t lim paren-state)
		(if (eq char-after-ip ?{)
		    (c-add-syntax 'block-open)))
	       ;; CASE 17E: first statement in an in-expression block.
	       ;; C.f. cases 4, 7B and 16A.
	       ((setq placeholder (c-looking-at-inexpr-block
				   (c-safe-position containing-sexp paren-state)
				   nil))
		(setq tmpsymbol (if (eq (car placeholder) 'inlambda)
				    'defun-block-intro
				  'statement-block-intro))
		(back-to-indentation)
		(if (= containing-sexp (point))
		    (c-add-syntax tmpsymbol (point))
		  (goto-char (cdr placeholder))
		  (back-to-indentation)
		  (c-add-stmt-syntax tmpsymbol t
				     (c-most-enclosing-brace c-state-cache (point))
				     (c-whack-state-after (point) paren-state))
		  (if (/= (point) (cdr placeholder))
		      (c-add-syntax (car placeholder))))
		(if (eq char-after-ip ?{)
		    (c-add-syntax 'block-open)))
	       ;; CASE 17F: first statement in an inline, or first
	       ;; statement in a top-level defun. we can tell this is it
	       ;; if there are no enclosing braces that haven't been
	       ;; narrowed out by a class (i.e. don't use bod here).
	       ;; However, we first check for statements that we can
	       ;; recognize by keywords.  That increases the robustness in
	       ;; cases where statements are used on the top level,
	       ;; e.g. in macro definitions.
	       ((save-excursion
		  (save-restriction
		    (widen)
		    (c-narrow-out-enclosing-class paren-state containing-sexp)
		    (not (c-most-enclosing-brace paren-state))))
		(c-backward-to-decl-anchor lim)
		(back-to-indentation)
		(c-add-syntax 'defun-block-intro (point)))
	       ;; CASE 17G: First statement in a function declared inside
	       ;; a normal block.  This can occur in Pike and with
	       ;; e.g. the gcc extensions.  Might also trigger it with
	       ;; some macros followed by blocks, and this gives sane
	       ;; indentation then too.  C.f. cases B.3 and 16F.
	       ((save-excursion
		  (and (not (c-looking-at-bos))
		       (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
		       (setq placeholder (point))))
		(back-to-indentation)
		(if (/= (point) containing-sexp)
		    (goto-char placeholder))
		(c-add-stmt-syntax 'defun-block-intro t lim paren-state))
	       ;; CASE 17H: First statement in a block.  C.f. case 16C.
	       (t
		;; If the block is preceded by a case/switch label on the
		;; same line, we anchor at the first preceding label at
		;; boi.  The default handling in c-add-stmt-syntax is
		;; really fixes it better, but we do like this to keep the
		;; indentation compatible with version 5.28 and earlier.
		(while (and (/= (setq placeholder (point)) (c-point 'boi))
			    (eq (c-beginning-of-statement-1 lim) 'label)))
		(goto-char placeholder)
		(if (looking-at c-label-kwds-regexp)
		    (c-add-syntax 'statement-block-intro (point))
		  (goto-char containing-sexp)
		  ;; c-backward-to-block-anchor not necessary here; those
		  ;; situations are handled in case 17I above.
		  (c-add-stmt-syntax 'statement-block-intro t lim paren-state))
		(if (eq char-after-ip ?{)
		    (c-add-syntax 'block-open)))
	       ))
	     )
	    ;; now we need to look at any modifiers
	    (goto-char indent-point)
	    (skip-chars-forward " \t")
	    ;; are we looking at a comment only line?
	    (when (and (looking-at c-comment-start-regexp)
		       (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
	      (c-add-syntax 'comment-intro))
	    ;; we might want to give additional offset to friends (in C++).
	    (when (and c-opt-friend-key
		       (looking-at c-opt-friend-key))
	      (c-add-syntax 'friend))
	    ;; Start of or a continuation of a preprocessor directive?
	    (if (and macro-start
		     (eq macro-start (c-point 'boi))
		     (not (and (c-major-mode-is 'pike-mode)
			       (eq (char-after (1+ macro-start)) ?\"))))
		(c-add-syntax 'cpp-macro)
	      (when (and c-syntactic-indentation-in-macros macro-start)
		(if in-macro-expr
		    (when (or (< syntactic-relpos macro-start)
			      (not (or (assq 'arglist-intro syntax)
				       (assq 'arglist-cont syntax)
				       (assq 'arglist-cont-nonempty syntax)
				       (assq 'arglist-close syntax))))
		      ;; If inside a cpp expression, i.e. anywhere in a
		      ;; cpp directive except a #define body, we only let
		      ;; through the syntactic analysis that is internal
		      ;; in the expression.  That means the arglist
		      ;; elements, if they are anchored inside the cpp
		      ;; expression.
		      (setq syntax `((cpp-macro-cont . ,macro-start))))
		  (when (and (eq macro-start syntactic-relpos)
			     (not (assq 'cpp-define-intro syntax))
			     (save-excursion
			       (goto-char macro-start)
			       (or (not (c-forward-to-cpp-define-body))
				   (<= (point) (c-point 'boi indent-point)))))
		    ;; Inside a #define body and the syntactic analysis is
		    ;; anchored on the start of the #define.  In this case
		    ;; we add cpp-define-intro to get the extra
		    ;; indentation of the #define body.
		    (c-add-syntax 'cpp-define-intro)))))
	    ;; return the syntax
	    syntax))))
  (defun c-guess-basic-syntax ()
    (save-excursion
      (save-restriction
	(beginning-of-line)
	(let* ((indent-point (point))
	       (case-fold-search nil)
	       (fullstate (c-parse-state))
	       (state fullstate)
	       literal containing-sexp char-before-ip char-after-ip lim
	       syntax placeholder c-in-literal-cache inswitch-p
	       tmpsymbol keyword injava-inher special-brace-list
	       ;; narrow out any enclosing class or extern "C" block
	       (inclass-p (c-narrow-out-enclosing-class state indent-point))
	       inenclosing-p)
	  ;; check for meta top-level enclosing constructs, possible
	  ;; extern language definitions, possibly (in C++) namespace
	  ;; definitions.
	  (save-excursion
	    (save-restriction
	      (widen)
	      (if (and inclass-p
		       (progn
			 (goto-char (aref inclass-p 0))
			 (looking-at (concat c-extra-toplevel-key "[^_]"))))
		  (let ((enclosing (match-string 1)))
		    (cond
		     ((string-equal enclosing "extern")
		      (setq inenclosing-p 'extern))
		     ((string-equal enclosing "namespace")
		      (setq inenclosing-p 'namespace))
		     )))))
	  ;; get the buffer position of the most nested opening brace,
	  ;; if there is one, and it hasn't been narrowed out
	  (save-excursion
	    (goto-char indent-point)
	    (skip-chars-forward " \t}")
	    (skip-chars-backward " \t")
	    (while (and state
			(not containing-sexp))
	      (setq containing-sexp (car state)
		    state (cdr state))
	      (if (consp containing-sexp)
		  ;; if cdr == point, then containing sexp is the brace
		  ;; that opens the sexp we close
		  (if (= (cdr containing-sexp) (point))
		      (setq containing-sexp (car containing-sexp))
		    ;; otherwise, ignore this element
		    (setq containing-sexp nil))
		;; ignore the bufpos if its been narrowed out by the
		;; containing class or does not contain the indent point
		(if (or (<= containing-sexp (point-min))
			(>= containing-sexp indent-point))
		    (setq containing-sexp nil)))))
	  ;; (imenu "agulbra-c++-tab")
	  ;; set the limit on the farthest back we need to search
	  (setq lim (or containing-sexp
			(if (consp (car fullstate))
			    (cdr (car fullstate))
			  nil)
			(point-min)))

	  ;; cache char before and after indent point, and move point to
	  ;; the most likely position to perform the majority of tests
	  (goto-char indent-point)
	  (skip-chars-forward " \t")
	  (setq char-after-ip (char-after))
	  (c-backward-syntactic-ws lim)
	  (setq char-before-ip (char-before))
	  (goto-char indent-point)
	  (skip-chars-forward " \t")

	  ;; are we in a literal?
	  (setq literal (c-in-literal lim))

	  ;; now figure out syntactic qualities of the current line
	  (cond
	   ;; CASE 1: in a string.
	   ((memq literal '(string))
	    (c-add-syntax 'string (c-point 'bopl)))
	   ;; CASE 2: in a C or C++ style comment.
	   ((memq literal '(c c++))
	    (c-add-syntax literal (car (c-literal-limits lim))))
	   ;; CASE 3: in a cpp preprocessor macro continuation.
	   ((and (eq literal 'pound)
		 (/= (save-excursion
		       (c-beginning-of-macro lim)
		       (setq placeholder (point)))
		     (c-point 'boi)))
	    (c-add-syntax 'cpp-macro-cont placeholder))
	   ;; CASE 4: In-expression statement.
	   ((and (or c-inexpr-class-key c-inexpr-block-key c-lambda-key)
		 (setq placeholder (c-looking-at-inexpr-block)))
	    (setq tmpsymbol (assq (car placeholder)
				  '((inexpr-class . class-open)
				    (inexpr-statement . block-open))))
	    (if tmpsymbol
		;; It's a statement block or an anonymous class.
		(setq tmpsymbol (cdr tmpsymbol))
	      ;; It's a Pike lambda.  Check whether we are between the
	      ;; lambda keyword and the argument list or at the defun
	      ;; opener.
	      (setq tmpsymbol (if (eq char-after-ip ?{)
				  'inline-open
				'lambda-intro-cont)))
	    (goto-char (cdr placeholder))
	    (back-to-indentation)
	    (c-add-syntax tmpsymbol (point))
	    (unless (eq (point) (cdr placeholder))
	      (c-add-syntax (car placeholder))))
	   ;; CASE 5: Line is at top level.
	   ((null containing-sexp)
	    (cond
	     ;; CASE 5A: we are looking at a defun, brace list, class,
	     ;; or inline-inclass method opening brace
	     ((setq special-brace-list
		    (or (and c-special-brace-lists
			     (c-looking-at-special-brace-list))
			(eq char-after-ip ?{)))
	      (cond
	       ;; CASE 5A.1: extern language or namespace construct
	       ((save-excursion
		  (goto-char indent-point)
		  (skip-chars-forward " \t")
		  (and (c-safe (progn (c-backward-sexp 2) t))
		       (looking-at (concat c-extra-toplevel-key "[^_]"))
		       (setq keyword (match-string 1)
			     placeholder (point))
		       (or (and (string-equal keyword "namespace")
				(setq tmpsymbol 'namespace-open))
			   (and (string-equal keyword "extern")
				(progn
				  (c-forward-sexp 1)
				  (c-forward-syntactic-ws)
				  (eq (char-after) ?\"))
				(setq tmpsymbol 'extern-lang-open)))
		       ))
		(goto-char placeholder)
		(c-add-syntax tmpsymbol (c-point 'boi)))
	       ;; CASE 5A.2: we are looking at a class opening brace
	       ((save-excursion
		  (goto-char indent-point)
		  (skip-chars-forward " \t{")
		  ;; TBD: watch out! there could be a bogus
		  ;; c-state-cache in place when we get here.  we have
		  ;; to go through much chicanery to ignore the cache.
		  ;; But of course, there may not be!  BLECH!  BOGUS!
		  (let ((decl
			 (let ((c-state-cache nil))
			   (c-search-uplist-for-classkey (c-parse-state))
			   )))
		    (and decl
			 (setq placeholder (aref decl 0)))
		    ))
		(c-add-syntax 'class-open placeholder))
	       ;; CASE 5A.3: brace list open
	       ((save-excursion
		  (c-beginning-of-statement-1 lim)
		  ;; c-b-o-s could have left us at point-min
		  (and (bobp)
		       (c-forward-syntactic-ws indent-point))
		  (if (looking-at "typedef[^_]")
		      (progn (c-forward-sexp 1)
			     (c-forward-syntactic-ws indent-point)))
		  (setq placeholder (c-point 'boi))
		  (or (consp special-brace-list)
		      (and (or (save-excursion
				 (goto-char indent-point)
				 (setq tmpsymbol nil)
				 (while (and (> (point) placeholder)
					     (= (c-backward-token-1 1 t) 0)
					     (/= (char-after) ?=))
				   (if (and (not tmpsymbol)
					    (looking-at "new\\>[^_]"))
				       (setq tmpsymbol 'topmost-intro-cont)))
				 (eq (char-after) ?=))
			       (looking-at "enum[ \t\n]+"))
			   (save-excursion
			     (while (and (< (point) indent-point)
					 (= (c-forward-token-1 1 t) 0)
					 (not (memq (char-after) '(?\; ?\()))))
			     (not (memq (char-after) '(?\; ?\()))
			     ))))
		(if (and (c-major-mode-is 'java-mode)
			 (eq tmpsymbol 'topmost-intro-cont))
		    ;; We're in Java and have found that the open brace
		    ;; belongs to a "new Foo[]" initialization list,
		    ;; which means the brace list is part of an
		    ;; expression and not a top level definition.  We
		    ;; therefore treat it as any topmost continuation
		    ;; even though the semantically correct symbol still
		    ;; is brace-list-open, on the same grounds as in
		    ;; case 10B.2.
		    (progn
		      (c-beginning-of-statement-1 lim)
		      (c-forward-syntactic-ws)
		      (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
		  (c-add-syntax 'brace-list-open placeholder)))
	       ;; CASE 5A.4: inline defun open
	       ((and inclass-p (not inenclosing-p))
		(c-add-syntax 'inline-open)
		(c-add-class-syntax 'inclass inclass-p))
	       ;; CASE 5A.5: ordinary defun open
	       (t
		(goto-char placeholder)
		(if inclass-p
		    (c-add-syntax 'defun-open (c-point 'boi))
		  (c-add-syntax 'defun-open (c-point 'bol)))
		)))
	     ;; CASE 5B: first K&R arg decl or member init
	     ((c-just-after-func-arglist-p)
	      (cond
	       ;; CASE 5B.1: a member init
	       ((or (eq char-before-ip ?:)
		    (eq char-after-ip ?:))
		;; this line should be indented relative to the beginning
		;; of indentation for the topmost-intro line that contains
		;; the prototype's open paren
		;; TBD: is the following redundant?
		(if (eq char-before-ip ?:)
		    (forward-char -1))
		(c-backward-syntactic-ws lim)
		;; TBD: is the preceding redundant?
		(if (eq (char-before) ?:)
		    (progn (forward-char -1)
			   (c-backward-syntactic-ws lim)))
		(if (eq (char-before) ?\))
		    (c-backward-sexp 1))
		(setq placeholder (point))
		(save-excursion
		  (and (c-safe (c-backward-sexp 1) t)
		       (looking-at "throw[^_]")
		       (c-safe (c-backward-sexp 1) t)
		       (setq placeholder (point))))
		(goto-char placeholder)
		(c-add-syntax 'member-init-intro (c-point 'boi))
		;; we don't need to add any class offset since this
		;; should be relative to the ctor's indentation
		)
	       ;; CASE 5B.2: K&R arg decl intro
	       (c-recognize-knr-p
		(c-add-syntax 'knr-argdecl-intro (c-point 'boi))
		(if inclass-p (c-add-class-syntax 'inclass inclass-p)))
	       ;; CASE 5B.3: Inside a member init list.
	       ((c-beginning-of-member-init-list lim)
		(c-forward-syntactic-ws)
		(c-add-syntax 'member-init-cont (point)))
	       ;; CASE 5B.4: Nether region after a C++ or Java func
	       ;; decl, which could include a `throws' declaration.
	       (t
		(c-beginning-of-statement-1 lim)
		(c-add-syntax 'func-decl-cont (c-point 'boi))
		)))
	     ;; CASE 5C: inheritance line. could be first inheritance
	     ;; line, or continuation of a multiple inheritance
	     ((or (and c-baseclass-key
		       (progn
			 (when (eq char-after-ip ?,)
			   (skip-chars-forward " \t")
			   (forward-char))
			 (looking-at c-baseclass-key)))
		  (and (or (eq char-before-ip ?:)
			   ;; watch out for scope operator
			   (save-excursion
			     (and (eq char-after-ip ?:)
				  (c-safe (progn (forward-char 1) t))
				  (not (eq (char-after) ?:))
				  )))
		       (save-excursion
			 (c-backward-syntactic-ws lim)
			 (if (eq char-before-ip ?:)
			     (progn
			       (forward-char -1)
			       (c-backward-syntactic-ws lim)))
			 (back-to-indentation)
			 (looking-at c-class-key)))
		  ;; for Java
		  (and (c-major-mode-is 'java-mode)
		       (let ((fence (save-excursion
				      (c-beginning-of-statement-1 lim)
				      (point)))
			     cont done)
			 (save-excursion
			   (while (not done)
			     (cond ((looking-at c-Java-special-key)
				    (setq injava-inher (cons cont (point))
					  done t))
				   ((or (not (c-safe (c-forward-sexp -1) t))
					(<= (point) fence))
				    (setq done t))
				   )
			     (setq cont t)))
			 injava-inher)
		       (not (c-crosses-statement-barrier-p (cdr injava-inher)
							   (point)))
		       ))
	      (cond
	       ;; CASE 5C.1: non-hanging colon on an inher intro
	       ((eq char-after-ip ?:)
		(c-backward-syntactic-ws lim)
		(c-add-syntax 'inher-intro (c-point 'boi))
		;; don't add inclass symbol since relative point already
		;; contains any class offset
		)
	       ;; CASE 5C.2: hanging colon on an inher intro
	       ((eq char-before-ip ?:)
		(c-add-syntax 'inher-intro (c-point 'boi))
		(if inclass-p (c-add-class-syntax 'inclass inclass-p)))
	       ;; CASE agulbrahack.1:
	       ((and inclass-p
		     c-access-key
		     (looking-at c-access-key))
		(c-add-syntax 'access-label (c-point 'bonl))
		(c-add-class-syntax 'inclass inclass-p)
		)
	       ;; CASE 5C.3: in a Java implements/extends
	       (injava-inher
		(let ((where (cdr injava-inher))
		      (cont (car injava-inher)))
		  (goto-char where)
		  (cond ((looking-at "throws[ \t\n]")
			 (c-add-syntax 'func-decl-cont
				       (progn (c-beginning-of-statement-1 lim)
					      (c-point 'boi))))
			(cont (c-add-syntax 'inher-cont where))
			(t (c-add-syntax 'inher-intro
					 (progn (goto-char (cdr injava-inher))
						(c-beginning-of-statement-1 lim)
						(point))))
			)))
	       ;; CASE 5C.4: a continued inheritance line
	       (t
		(c-beginning-of-inheritance-list lim)
		(c-add-syntax 'inher-cont (point))
		;; don't add inclass symbol since relative point already
		;; contains any class offset
		)))
	     ;; CASE 5D: this could be a top-level compound statement, a
	     ;; member init list continuation, or a template argument
	     ;; list continuation.
	     ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
				       c++-template-syntax-table
				     (syntax-table))
		(save-excursion
		  (while (and (= (c-backward-token-1 1 t lim) 0)
			      (not (looking-at "[;{<,]"))))
		  (eq (char-after) ?,)))
	      (goto-char indent-point)
	      (c-beginning-of-member-init-list lim)
	      (cond
	       ;; CASE 5D.1: hanging member init colon, but watch out
	       ;; for bogus matches on access specifiers inside classes.
	       ((and (save-excursion
		       (setq plaaceholder (point))
		       (c-backward-token-1 1 t lim)
		       (and (eq (char-after) ?:)
			    (not (eq (char-before) ?:))))
		     (save-excursion
		       (goto-char placeholder)
		       (back-to-indentation)
		       (or
			(/= (car (save-excursion
				   (parse-partial-sexp (point) placeholder)))
			    0)
			(and
			 (if c-access-key (not (looking-at c-access-key)) t)
			 (not (looking-at c-class-key))
			 (if c-bitfield-key (not (looking-at c-bitfield-key)) t))
			)))
		(goto-char placeholder)
		(c-forward-syntactic-ws)
		(c-add-syntax 'member-init-cont (point))
		;; we do not need to add class offset since relative
		;; point is the member init above us
		)
	       ;; CASE 5D.2: non-hanging member init colon
	       ((progn
		  (c-forward-syntactic-ws indent-point)
		  (eq (char-after) ?:))
		(skip-chars-forward " \t:")
		(c-add-syntax 'member-init-cont (point)))
	       ;; CASE 5D.3: perhaps a multiple inheritance line?
	       ((save-excursion
		  (c-beginning-of-statement-1 lim)
		  (setq placeholder (point))
		  (looking-at c-inher-key))
		(goto-char placeholder)
		(c-add-syntax 'inher-cont (c-point 'boi)))
	       ;; CASE 5D.4: perhaps a template list continuation?
	       ((save-excursion
		  (goto-char indent-point)
		  (skip-chars-backward "^<" lim)
		  ;; not sure if this is the right test, but it should
		  ;; be fast and mostly accurate.
		  (setq placeholder (point))
		  (and (eq (char-before) ?<)
		       (not (c-in-literal lim))))
		;; we can probably indent it just like an arglist-cont
		(goto-char placeholder)
		(c-beginning-of-statement-1 lim)
		(c-add-syntax 'template-args-cont (c-point 'boi)))
	       ;; CASE 5D.5: perhaps a top-level statement-cont
	       (t
		(c-beginning-of-statement-1 lim)
		;; skip over any access-specifiers
		(and inclass-p c-access-key
		     (while (looking-at c-access-key)
		       (forward-line 1)))
		;; skip over comments, whitespace
		(c-forward-syntactic-ws indent-point)
		(c-add-syntax 'statement-cont (c-point 'boi)))
	       ))
	     ;; CASE 5E: we are looking at a access specifier
	     ((and inclass-p
		   c-access-key
		   (looking-at c-access-key))
	      (c-add-syntax 'access-label (c-point 'bonl))
	      (c-add-class-syntax 'inclass inclass-p))
	     ;; CASE 5F: extern-lang-close or namespace-close?
	     ((and inenclosing-p
		   (eq char-after-ip ?}))
	      (setq tmpsymbol (if (eq inenclosing-p 'extern)
				  'extern-lang-close
				'namespace-close))
	      (c-add-syntax tmpsymbol (aref inclass-p 0)))
	     ;; CASE 5G: we are looking at the brace which closes the
	     ;; enclosing nested class decl
	     ((and inclass-p
		   (eq char-after-ip ?})
		   (save-excursion
		     (save-restriction
		       (widen)
		       (forward-char 1)
		       (and (c-safe (progn (c-backward-sexp 1) t))
			    (= (point) (aref inclass-p 1))
			    ))))
	      (c-add-class-syntax 'class-close inclass-p))
	     ;; CASE 5H: we could be looking at subsequent knr-argdecls
	     ((and c-recognize-knr-p
		   ;; here we essentially use the hack that is used in
		   ;; Emacs' c-mode.el to limit how far back we should
		   ;; look.  The assumption is made that argdecls are
		   ;; indented at least one space and that function
		   ;; headers are not indented.
		   (let ((limit (save-excursion
				  (re-search-backward "^[^ \^L\t\n#]" nil 'move)
				  (point))))
		     (save-excursion
		       (c-backward-syntactic-ws limit)
		       (setq placeholder (point))
		       (while (and (memq (char-before) '(?\; ?,))
				   (> (point) limit))
			 (beginning-of-line)
			 (setq placeholder (point))
			 (c-backward-syntactic-ws limit))
		       (and (eq (char-before) ?\))
			    (or (not c-method-key)
				(progn
				  (c-forward-sexp -1)
				  (forward-char -1)
				  (c-backward-syntactic-ws)
				  (not (or (memq (char-before) '(?- ?+))
					   ;; or a class category
					   (progn
					     (c-forward-sexp -2)
					     (looking-at c-class-key))
					   )))))
		       ))
		   (save-excursion
		     (c-beginning-of-statement-1)
		     (not (looking-at "typedef[ \t\n]+"))))
	      (goto-char placeholder)
	      (c-add-syntax 'knr-argdecl (c-point 'boi)))
	     ;; CASE 5I: ObjC method definition.
	     ((and c-method-key
		   (looking-at c-method-key))
	      (c-add-syntax 'objc-method-intro (c-point 'boi)))
	     ;; CASE 5J: we are at the topmost level, make sure we skip
	     ;; back past any access specifiers
	     ((progn
		(c-backward-syntactic-ws lim)
		(while (and inclass-p
			    c-access-key
			    (not (bobp))
			    (save-excursion
			      (c-safe (progn (c-backward-sexp 1) t))
			      ;; agulbrahack 2
			      (and (looking-at "slots:")
				   (c-backward-sexp 1))
			      (looking-at c-access-key)))
		  (c-backward-sexp 1)
		  (c-backward-syntactic-ws lim))
		(or (bobp)
		    (memq (char-before) '(?\; ?\}))))
	      ;; real beginning-of-line could be narrowed out due to
	      ;; enclosure in a class block
	      (save-restriction
		(widen)
		(c-add-syntax 'topmost-intro (c-point 'bol))
		(if inclass-p
		    (progn
		      (goto-char (aref inclass-p 1))
		      (or (= (point) (c-point 'boi))
			  (goto-char (aref inclass-p 0)))
		      (cond
		       ((eq inenclosing-p 'extern)
			(c-add-syntax 'inextern-lang (c-point 'boi)))
		       ((eq inenclosing-p 'namespace)
			(c-add-syntax 'innamespace (c-point 'boi)))
		       (t (c-add-class-syntax 'inclass inclass-p)))
		      ))
		))
	     ;; CASE 5K: we are at an ObjC or Java method definition
	     ;; continuation line.
	     ((and c-method-key
		   (progn
		     (c-beginning-of-statement-1 lim)
		     (beginning-of-line)
		     (looking-at c-method-key)))
	      (c-add-syntax 'objc-method-args-cont (point)))
	     ;; CASE 5L: we are at the first argument of a template
	     ;; arglist that begins on the previous line.
	     ((eq (char-before) ?<)
	      (c-beginning-of-statement-1 lim)
	      (c-forward-syntactic-ws)
	      (c-add-syntax 'template-args-cont (c-point 'boi)))
	     ;; CASE 5M: we are at a topmost continuation line
	     (t
	      (c-beginning-of-statement-1 lim)
	      (c-forward-syntactic-ws)
	      (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
	     ))				; end CASE 5
	   ;; (CASE 6 has been removed.)
	   ;; CASE 7: line is an expression, not a statement.  Most
	   ;; likely we are either in a function prototype or a function
	   ;; call argument list
	   ((not (or (and c-special-brace-lists
			  (save-excursion
			    (goto-char containing-sexp)
			    (c-looking-at-special-brace-list)))
		     (eq (char-after containing-sexp) ?{)))
	    (c-backward-syntactic-ws containing-sexp)
	    (cond
	     ;; CASE 7A: we are looking at the arglist closing paren
	     ((and (or (c-major-mode-is 'pike-mode)
		       ;; Don't check this in Pike since it allows a
		       ;; comma after the last arg.
		       (not (eq char-before-ip ?,)))
		   (memq char-after-ip '(?\) ?\])))
	      (goto-char containing-sexp)
	      (setq placeholder (c-point 'boi))
	      (when (and (c-safe (backward-up-list 1) t)
			 (> (point) placeholder))
		(forward-char)
		(skip-chars-forward " \t")
		(setq placeholder (point)))
	      (c-add-syntax 'arglist-close placeholder))
	     ;; CASE 7B: Looking at the opening brace of an
	     ;; in-expression block or brace list.
	     ((eq char-after-ip ?{)
	      (goto-char indent-point)
	      (setq placeholder (c-point 'boi))
	      (goto-char containing-sexp)
	      (if (c-inside-bracelist-p placeholder
					(cons containing-sexp state))
		  (progn
		    (c-add-syntax 'brace-list-open (c-point 'boi))
		    (c-add-syntax 'inexpr-class))
		(c-add-syntax 'block-open (c-point 'boi))
		(c-add-syntax 'inexpr-statement)))
	     ;; CASE 7C: we are looking at the first argument in an empty
	     ;; argument list. Use arglist-close if we're actually
	     ;; looking at a close paren or bracket.
	     ((memq char-before-ip '(?\( ?\[))
	      (goto-char containing-sexp)
	      (setq placeholder (c-point 'boi))
	      (when (and (c-safe (backward-up-list 1) t)
			 (> (point) placeholder))
		(forward-char)
		(skip-chars-forward " \t")
		(setq placeholder (point)))
	      (c-add-syntax 'arglist-intro placeholder))
	     ;; CASE 7D: we are inside a conditional test clause. treat
	     ;; these things as statements
	     ((save-excursion
		(goto-char containing-sexp)
		(and (c-safe (progn (c-forward-sexp -1) t))
		     (looking-at "\\<for\\>[^_]")))
	      (goto-char (1+ containing-sexp))
	      (c-forward-syntactic-ws indent-point)
	      (c-beginning-of-statement-1 containing-sexp)
	      (if (eq char-before-ip ?\;)
		  (c-add-syntax 'statement (point))
		(c-add-syntax 'statement-cont (point))
		))
	     ;; CASE 7E: maybe a continued method call. This is the case
	     ;; when we are inside a [] bracketed exp, and what precede
	     ;; the opening bracket is not an identifier.
	     ((and c-method-key
		   (eq (char-after containing-sexp) ?\[)
		   (save-excursion
		     (goto-char (1- containing-sexp))
		     (c-backward-syntactic-ws (c-point 'bod))
		     (if (not (looking-at c-symbol-key))
			 (c-add-syntax 'objc-method-call-cont containing-sexp))
		     )))
	     ;; CASE 7F: we are looking at an arglist continuation line,
	     ;; but the preceding argument is on the same line as the
	     ;; opening paren.  This case includes multi-line
	     ;; mathematical paren groupings, but we could be on a
	     ;; for-list continuation line
	     ((save-excursion
		(goto-char (1+ containing-sexp))
		(skip-chars-forward " \t")
		(not (eolp)))
	      (goto-char containing-sexp)
	      (setq placeholder (c-point 'boi))
	      (when (and (c-safe (backward-up-list 1) t)
			 (> (point) placeholder))
		(forward-char)
		(skip-chars-forward " \t")
		(setq placeholder (point)))
	      (c-add-syntax 'arglist-cont-nonempty placeholder))
	     ;; CASE 7G: we are looking at just a normal arglist
	     ;; continuation line
	     (t (c-beginning-of-statement-1 containing-sexp)
		(forward-char 1)
		(c-forward-syntactic-ws indent-point)
		(c-add-syntax 'arglist-cont (c-point 'boi)))
	     ))
	   ;; CASE 8: func-local multi-inheritance line
	   ((and c-baseclass-key
		 (save-excursion
		   (goto-char indent-point)
		   (skip-chars-forward " \t")
		   (looking-at c-baseclass-key)))
	    (goto-char indent-point)
	    (skip-chars-forward " \t")
	    (cond
	     ;; CASE 8A: non-hanging colon on an inher intro
	     ((eq char-after-ip ?:)
	      (c-backward-syntactic-ws lim)
	      (c-add-syntax 'inher-intro (c-point 'boi)))
	     ;; CASE 8B: hanging colon on an inher intro
	     ((eq char-before-ip ?:)
	      (c-add-syntax 'inher-intro (c-point 'boi)))
	     ;; CASE 8C: a continued inheritance line
	     (t
	      (c-beginning-of-inheritance-list lim)
	      (c-add-syntax 'inher-cont (point))
	      )))
	   ;; CASE 9: we are inside a brace-list
	   ((setq special-brace-list
		  (or (and c-special-brace-lists
			   (save-excursion
			     (goto-char containing-sexp)
			     (c-looking-at-special-brace-list)))
		      (c-inside-bracelist-p containing-sexp state)))
	    (cond
	     ;; CASE 9A: In the middle of a special brace list opener.
	     ((and (consp special-brace-list)
		   (save-excursion
		     (goto-char containing-sexp)
		     (eq (char-after) ?\())
		   (eq char-after-ip (car (cdr special-brace-list))))
	      (goto-char (car (car special-brace-list)))
	      (skip-chars-backward " \t")
	      (if (and (bolp)
		       (assoc 'statement-cont
			      (setq placeholder (c-guess-basic-syntax))))
		  (setq syntax placeholder)
		(c-beginning-of-statement-1 lim)
		(c-forward-token-1 0)
		(if (looking-at "typedef\\>") (c-forward-token-1 1))
		(c-add-syntax 'brace-list-open (c-point 'boi))))
	     ;; CASE 9B: brace-list-close brace
	     ((if (consp special-brace-list)
		  ;; Check special brace list closer.
		  (progn
		    (goto-char (car (car special-brace-list)))
		    (save-excursion
		      (goto-char indent-point)
		      (back-to-indentation)
		      (or
		       ;; We were between the special close char and the `)'.
		       (and (eq (char-after) ?\))
			    (eq (1+ (point)) (cdr (car special-brace-list))))
		       ;; We were before the special close char.
		       (and (eq (char-after) (cdr (cdr special-brace-list)))
			    (= (c-forward-token-1) 0)
			    (eq (1+ (point)) (cdr (car special-brace-list)))))))
		;; Normal brace list check.
		(and (eq char-after-ip ?})
		     (c-safe (progn (forward-char 1)
				    (c-backward-sexp 1)
				    t))
		     (= (point) containing-sexp)))
	      (c-add-syntax 'brace-list-close (c-point 'boi)))
	     (t
	      ;; Prepare for the rest of the cases below by going to the
	      ;; token following the opening brace
	      (if (consp special-brace-list)
		  (progn
		    (goto-char (car (car special-brace-list)))
		    (c-forward-token-1 1 nil indent-point))
		(goto-char containing-sexp))
	      (forward-char)
	      (let ((start (point)))
		(c-forward-syntactic-ws indent-point)
		(goto-char (max start (c-point 'bol))))
	      (skip-chars-forward " \t\n\r" indent-point)
	      (cond
	       ;; CASE 9C: we're looking at the first line in a brace-list
	       ((= (point) indent-point)
		(goto-char containing-sexp)
		(c-add-syntax 'brace-list-intro (c-point 'boi))
		)			; end CASE 9C
	       ;; CASE 9D: this is just a later brace-list-entry or
	       ;; brace-entry-open
	       (t (if (or (eq char-after-ip ?{)
			  (and c-special-brace-lists
			       (save-excursion
				 (goto-char indent-point)
				 (c-forward-syntactic-ws (c-point 'eol))
				 (c-looking-at-special-brace-list (point)))))
		      (c-add-syntax 'brace-entry-open (point))
		    (c-add-syntax 'brace-list-entry (point))
		    ))			; end CASE 9D
	       ))))			; end CASE 9
	   ;; CASE 10: A continued statement
	   ((and (not (memq char-before-ip '(?\; ?:)))
		 (or (not (eq char-before-ip ?}))
		     (c-looking-at-inexpr-block-backward containing-sexp))
		 (> (point)
		    (save-excursion
		      (c-beginning-of-statement-1 containing-sexp)
		      (c-forward-syntactic-ws)
		      (setq placeholder (point))))
		 (/= placeholder containing-sexp))
	    (goto-char indent-point)
	    (skip-chars-forward " \t")
	    (let ((after-cond-placeholder
		   (save-excursion
		     (goto-char placeholder)
		     (if (and c-conditional-key (looking-at c-conditional-key))
			 (progn
			   (c-safe (c-skip-conditional))
			   (c-forward-syntactic-ws)
			   (if (eq (char-after) ?\;)
			       (progn
				 (forward-char 1)
				 (c-forward-syntactic-ws)))
			   (point))
		       nil))))
	      (cond
	       ;; CASE 10A: substatement
	       ((and after-cond-placeholder
		     (>= after-cond-placeholder indent-point))
		(goto-char placeholder)
		(if (eq char-after-ip ?{)
		    (c-add-syntax 'substatement-open (c-point 'boi))
		  (c-add-syntax 'substatement (c-point 'boi))))
	       ;; CASE 10B: open braces for class or brace-lists
	       ((setq special-brace-list
		      (or (and c-special-brace-lists
			       (c-looking-at-special-brace-list))
			  (eq char-after-ip ?{)))
		(cond
		 ;; CASE 10B.1: class-open
		 ((save-excursion
		    (goto-char indent-point)
		    (skip-chars-forward " \t{")
		    (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
		      (and decl
			   (setq placeholder (aref decl 0)))
		      ))
		  (c-add-syntax 'class-open placeholder))
		 ;; CASE 10B.2: brace-list-open
		 ((or (consp special-brace-list)
		      (save-excursion
			(goto-char placeholder)
			(looking-at "\\<enum\\>"))
		      (save-excursion
			(goto-char indent-point)
			(while (and (> (point) placeholder)
				    (= (c-backward-token-1 1 t) 0)
				    (/= (char-after) ?=)))
			(eq (char-after) ?=)))
		  ;; The most semantically accurate symbol here is
		  ;; brace-list-open, but we report it simply as a
		  ;; statement-cont.  The reason is that one normally
		  ;; adjusts brace-list-open for brace lists as
		  ;; top-level constructs, and brace lists inside
		  ;; statements is a completely different context.
		  (goto-char indent-point)
		  (c-beginning-of-closest-statement)
		  (c-add-syntax 'statement-cont (c-point 'boi)))
		 ;; CASE 10B.3: The body of a function declared inside a
		 ;; normal block.  This can only occur in Pike.
		 ((and (c-major-mode-is 'pike-mode)
		       (progn
			 (goto-char indent-point)
			 (not (c-looking-at-bos))))
		  (c-beginning-of-closest-statement)
		  (c-add-syntax 'defun-open (c-point 'boi)))
		 ;; CASE 10B.4: catch-all for unknown construct.
		 (t
		  ;; Can and should I add an extensibility hook here?
		  ;; Something like c-recognize-hook so support for
		  ;; unknown constructs could be added.  It's probably a
		  ;; losing proposition, so I dunno.
		  (goto-char placeholder)
		  (c-add-syntax 'statement-cont (c-point 'boi))
		  (c-add-syntax 'block-open))
		 ))
	       ;; CASE 10C: iostream insertion or extraction operator
	       ((looking-at "<<\\|>>")
		(goto-char placeholder)
		(and after-cond-placeholder
		     (goto-char after-cond-placeholder))
		(while (and (re-search-forward "<<\\|>>" indent-point 'move)
			    (c-in-literal placeholder)))
		;; if we ended up at indent-point, then the first
		;; streamop is on a separate line. Indent the line like
		;; a statement-cont instead
		(if (/= (point) indent-point)
		    (c-add-syntax 'stream-op (c-point 'boi))
		  (c-backward-syntactic-ws lim)
		  (c-add-syntax 'statement-cont (c-point 'boi))))
	       ;; CASE 10D: continued statement. find the accurate
	       ;; beginning of statement or substatement
	       (t
		(c-beginning-of-statement-1 after-cond-placeholder)
		;; KLUDGE ALERT!  c-beginning-of-statement-1 can leave
		;; us before the lim we're passing in.  It should be
		;; fixed, but I'm worried about side-effects at this
		;; late date.  Fix for v5.
		(goto-char (or (and after-cond-placeholder
				    (max after-cond-placeholder (point)))
			       (point)))
		(c-add-syntax 'statement-cont (point)))
	       )))
	   ;; CASE 11: an else clause?
	   ((looking-at "\\<else\\>[^_]")
	    (c-backward-to-start-of-if containing-sexp)
	    (c-add-syntax 'else-clause (c-point 'boi)))
	   ;; CASE 12: Statement. But what kind?  Lets see if its a
	   ;; while closure of a do/while construct
	   ((progn
	      (goto-char indent-point)
	      (skip-chars-forward " \t")
	      (and (looking-at "while\\b[^_]")
		   (save-excursion
		     (c-backward-to-start-of-do containing-sexp)
		     (setq placeholder (point))
		     (looking-at "do\\b[^_]"))
		   ))
	    (goto-char placeholder)
	    (c-add-syntax 'do-while-closure (c-point 'boi)))
	   ;; CASE 13: A catch or finally clause?  This case is simpler
	   ;; than if-else and do-while, because a block is required
	   ;; after every try, catch and finally.
	   ((save-excursion
	      (and (cond ((c-major-mode-is 'c++-mode)
			  (looking-at "\\<catch\\>[^_]"))
			 ((c-major-mode-is 'java-mode)
			  (looking-at "\\<\\(catch\\|finally\\)\\>[^_]")))
		   (c-safe (c-backward-sexp) t)
		   (eq (char-after) ?{)
		   (c-safe (c-backward-sexp) t)
		   (if (eq (char-after) ?\()
		       (c-safe (c-backward-sexp) t)
		     t)
		   (looking-at "\\<\\(try\\|catch\\)\\>[^_]")
		   (setq placeholder (c-point 'boi))))
	    (c-add-syntax 'catch-clause placeholder))
	   ;; CASE 14: A case or default label
	   ((looking-at c-switch-label-key)
	    (goto-char containing-sexp)
	    ;; check for hanging braces
	    (if (/= (point) (c-point 'boi))
		(c-forward-sexp -1))
	    (c-add-syntax 'case-label (c-point 'boi)))
	   ;; CASE 15: any other label
	   ((looking-at c-label-key)
	    (goto-char containing-sexp)
	    ;; check for hanging braces
	    (if (/= (point) (c-point 'boi))
		(c-forward-sexp -1))
	    (c-add-syntax 'label (c-point 'boi)))
	   ;; CASE 16: block close brace, possibly closing the defun or
	   ;; the class
	   ((eq char-after-ip ?})
	    (let* ((lim (c-safe-position containing-sexp fullstate))
		   (relpos (save-excursion
			     (goto-char containing-sexp)
			     (if (/= (point) (c-point 'boi))
				 (c-beginning-of-statement-1 lim))
			     (c-point 'boi))))
	      (cond
	       ;; CASE 16A: closing a lambda defun or an in-expression
	       ;; block?
	       ((save-excursion
		  (goto-char containing-sexp)
		  (setq placeholder (c-looking-at-inexpr-block)))
		(setq tmpsymbol (if (eq (car placeholder) 'inlambda)
				    'inline-close
				  'block-close))
		(goto-char containing-sexp)
		(back-to-indentation)
		(if (= containing-sexp (point))
		    (c-add-syntax tmpsymbol (point))
		  (goto-char (cdr placeholder))
		  (back-to-indentation)
		  (c-add-syntax tmpsymbol (point))
		  (if (/= (point) (cdr placeholder))
		      (c-add-syntax (car placeholder)))))
	       ;; CASE 16B: does this close an inline or a function in
	       ;; an extern block or namespace?
	       ((progn
		  (goto-char containing-sexp)
		  (setq placeholder (c-search-uplist-for-classkey state)))
		(goto-char (aref placeholder 0))
		(if (looking-at (concat c-extra-toplevel-key "[^_]"))
		    (c-add-syntax 'defun-close relpos)
		  (c-add-syntax 'inline-close relpos)))
	       ;; CASE 16C: if there an enclosing brace that hasn't
	       ;; been narrowed out by a class, then this is a
	       ;; block-close
	       ((and (not inenclosing-p)
		     (c-most-enclosing-brace state)
		     (or (not (c-major-mode-is 'pike-mode))
			 ;; In Pike it can be a defun-close of a
			 ;; function declared in a statement block.  Let
			 ;; it through to be handled below.
			 (or (c-looking-at-bos)
			     (progn
			       (c-beginning-of-statement-1)
			       (looking-at c-conditional-key)))))
		(c-add-syntax 'block-close relpos))
	       ;; CASE 16D: find out whether we're closing a top-level
	       ;; class or a defun
	       (t
		(save-restriction
		  (narrow-to-region (point-min) indent-point)
		  (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
		    (if decl
			(c-add-class-syntax 'class-close decl)
		      (c-add-syntax 'defun-close relpos)))))
	       )))
	   ;; CASE 17: statement catchall
	   (t
	    ;; we know its a statement, but we need to find out if it is
	    ;; the first statement in a block
	    (goto-char containing-sexp)
	    (forward-char 1)
	    (c-forward-syntactic-ws indent-point)
	    ;; now skip forward past any case/default clauses we might find.
	    (while (or (c-skip-case-statement-forward fullstate indent-point)
		       (and (looking-at c-switch-label-key)
			    (not inswitch-p)))
	      (setq inswitch-p t))
	    ;; we want to ignore non-case labels when skipping forward
	    (while (and (looking-at c-label-key)
			(goto-char (match-end 0)))
	      (c-forward-syntactic-ws indent-point))
	    (cond
	     ;; CASE 17A: we are inside a case/default clause inside a
	     ;; switch statement.  find out if we are at the statement
	     ;; just after the case/default label.
	     ((and inswitch-p
		   (progn
		     (goto-char indent-point)
		     (c-beginning-of-statement-1 containing-sexp)
		     (setq placeholder (point))
		     (beginning-of-line)
		     (when (re-search-forward c-switch-label-key
					      (max placeholder (c-point 'eol)) t)
		       (setq placeholder (match-beginning 0)))))
	      (goto-char indent-point)
	      (skip-chars-forward " \t")
	      (if (eq (char-after) ?{)
		  (c-add-syntax 'statement-case-open placeholder)
		(c-add-syntax 'statement-case-intro placeholder)))
	     ;; CASE 17B: continued statement
	     ((eq char-before-ip ?,)
	      (goto-char indent-point)
	      (c-beginning-of-closest-statement)
	      (c-add-syntax 'statement-cont (c-point 'boi)))
	     ;; CASE 17C: a question/colon construct?  But make sure
	     ;; what came before was not a label, and what comes after
	     ;; is not a globally scoped function call!
	     ((or (and (memq char-before-ip '(?: ??))
		       (save-excursion
			 (goto-char indent-point)
			 (c-backward-syntactic-ws lim)
			 (back-to-indentation)
			 (not (looking-at c-label-key))))
		  (and (memq char-after-ip '(?: ??))
		       (save-excursion
			 (goto-char indent-point)
			 (skip-chars-forward " \t")
			 ;; watch out for scope operator
			 (not (looking-at "::")))))
	      (goto-char indent-point)
	      (c-beginning-of-closest-statement)
	      (c-add-syntax 'statement-cont (c-point 'boi)))
	     ;; CASE 17D: any old statement
	     ((< (point) indent-point)
	      (let ((safepos (c-most-enclosing-brace fullstate))
		    relpos done)
		(goto-char indent-point)
		(c-beginning-of-statement-1 safepos)
		;; It is possible we're on the brace that opens a nested
		;; function.
		(if (and (eq (char-after) ?{)
			 (save-excursion
			   (c-backward-syntactic-ws safepos)
			   (not (eq (char-before) ?\;))))
		    (c-beginning-of-statement-1 safepos))
		(if (and inswitch-p
			 (looking-at c-switch-label-key))
		    (progn
		      (goto-char (match-end 0))
		      (c-forward-syntactic-ws)))
		(setq relpos (c-point 'boi))
		(while (and (not done)
			    (<= safepos (point))
			    (/= relpos (point)))
		  (c-beginning-of-statement-1 safepos)
		  (if (= relpos (c-point 'boi))
		      (setq done t))
		  (setq relpos (c-point 'boi)))
		(c-add-syntax 'statement relpos)
		(if (eq char-after-ip ?{)
		    (c-add-syntax 'block-open))))
	     ;; CASE 17E: first statement in an in-expression block
	     ((setq placeholder
		    (save-excursion
		      (goto-char containing-sexp)
		      (c-looking-at-inexpr-block)))
	      (goto-char containing-sexp)
	      (back-to-indentation)
	      (let ((block-intro (if (eq (car placeholder) 'inlambda)
				     'defun-block-intro
				   'statement-block-intro)))
		(if (= containing-sexp (point))
		    (c-add-syntax block-intro (point))
		  (goto-char (cdr placeholder))
		  (back-to-indentation)
		  (c-add-syntax block-intro (point))
		  (if (/= (point) (cdr placeholder))
		      (c-add-syntax (car placeholder)))))
	      (if (eq char-after-ip ?{)
		  (c-add-syntax 'block-open)))
	     ;; CASE 17F: first statement in an inline, or first
	     ;; statement in a top-level defun. we can tell this is it
	     ;; if there are no enclosing braces that haven't been
	     ;; narrowed out by a class (i.e. don't use bod here!)
	     ((save-excursion
		(save-restriction
		  (widen)
		  (goto-char containing-sexp)
		  (c-narrow-out-enclosing-class state containing-sexp)
		  (not (c-most-enclosing-brace state))))
	      (goto-char containing-sexp)
	      ;; if not at boi, then defun-opening braces are hung on
	      ;; right side, so we need a different relpos
	      (if (/= (point) (c-point 'boi))
		  (progn
		    (c-backward-syntactic-ws)
		    (c-safe (c-forward-sexp (if (eq (char-before) ?\))
						-1 -2)))
		    ;; looking at a Java throws clause following a
		    ;; method's parameter list
		    (c-beginning-of-statement-1)
		    ))
	      (c-add-syntax 'defun-block-intro (c-point 'boi)))
	     ;; CASE 17G: First statement in a function declared inside
	     ;; a normal block.  This can only occur in Pike.
	     ((and (c-major-mode-is 'pike-mode)
		   (progn
		     (goto-char containing-sexp)
		     (and (not (c-looking-at-bos))
			  (progn
			    (c-beginning-of-statement-1)
			    (not (looking-at c-conditional-key))))))
	      (c-add-syntax 'defun-block-intro (c-point 'boi)))
	     ;; CASE 17H: first statement in a block
	     (t (goto-char containing-sexp)
		(if (/= (point) (c-point 'boi))
		    (c-beginning-of-statement-1
		     (if (= (point) lim)
			 (c-safe-position (point) state) lim)))
		(c-add-syntax 'statement-block-intro (c-point 'boi))
		(if (eq char-after-ip ?{)
		    (c-add-syntax 'block-open)))
	     ))
	   )
	  ;; now we need to look at any modifiers
	  (goto-char indent-point)
	  (skip-chars-forward " \t")
	  (cond
	   ;; are we looking at a comment only line?
	   ((and (looking-at c-comment-start-regexp)
		 (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
	    (c-add-syntax 'comment-intro))
	   ;; we might want to give additional offset to friends (in C++).
	   ((and (c-major-mode-is 'c++-mode)
		 (looking-at c-C++-friend-key))
	    (c-add-syntax 'friend))
	   ;; Start of a preprocessor directive?
	   ((and (eq literal 'pound)
		 (= (save-excursion
		      (c-beginning-of-macro lim)
		      (setq placeholder (point)))
		    (c-point 'boi))
		 (not (and (c-major-mode-is 'pike-mode)
			   (eq (char-after (1+ placeholder)) ?\"))))
	    (c-add-syntax 'cpp-macro)))
	  ;; return the syntax
	  syntax)))))

(add-hook 'find-file-hooks 'agulbra-c++-clean-out-spaces)
(add-hook 'write-file-hooks 'agulbra-c++-clean-out-spaces)

(add-hook 'c++-mode-hook 'kde-c++-mode-hook)
(add-hook 'c-mode-hook 'kde-c-mode-hook)
; always end a file with a newline
(setq-default require-final-newline t)
; 'next-line won't be adding newlines
(setq-default next-line-add-newlines nil)
(setq compilation-error-regexp-systems-list '(gnu of comma 4bsd)
      compilation-ask-about-save nil)

(provide 'kde-emacs-core)
