home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-19.28-src.tgz / tar.out / fsf / emacs / lisp / cc-mode.el < prev    next >
Lisp/Scheme  |  1996-09-28  |  135KB  |  3,724 lines

  1. ;;; cc-mode.el --- major mode for editing C++ and C code
  2.  
  3. ;; Authors: 1992 Barry A. Warsaw, Century Computing Inc. <bwarsaw@cen.com>
  4. ;;          1987 Dave Detlefs and Stewart Clamen
  5. ;;          1985 Richard M. Stallman
  6. ;; Maintainer: cc-mode-help@anthem.nlm.nih.gov
  7. ;; Created: a long, long, time ago. adapted from the original c-mode.el
  8. ;; Version:         3.349
  9. ;; Last Modified:   1994/05/24 22:04:15
  10. ;; Keywords: C++ C editing major-mode
  11.  
  12. ;; Copyright (C) 1992, 1993, 1994 Barry A. Warsaw
  13. ;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
  14.  
  15. ;; This file is part of GNU Emacs.
  16.  
  17. ;; GNU Emacs is free software; you can redistribute it and/or modify
  18. ;; it under the terms of the GNU General Public License as published by
  19. ;; the Free Software Foundation; either version 2, or (at your option)
  20. ;; any later version.
  21.  
  22. ;; GNU Emacs is distributed in the hope that it will be useful,
  23. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. ;; GNU General Public License for more details.
  26.  
  27. ;; You should have received a copy of the GNU General Public License
  28. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  29. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  
  31. ;;; Commentary:
  32.  
  33. ;; This package is intended to be a nearly interchangeable replacement
  34. ;; for standard c-mode (a.k.a. BOCM -- "Boring Old C-Mode" :-).  There
  35. ;; are some important differences.  Briefly: complete K&R C, ANSI C,
  36. ;; and C++ support with consistent indentation across all modes, more
  37. ;; intuitive indentation controlling variables, compatibility across
  38. ;; all known Emacsen, nice new features, and tons of bug fixes.  This
  39. ;; package is called CC-MODE to distinguish it from BOCM and its
  40. ;; ancestor C++-MODE, but there really is no top-level CC-MODE (see
  41. ;; below).  cc-mode.el is not compatible with c-mode.el or
  42. ;; c++-mode.el.  You should use this file to edit all your C and C++
  43. ;; code. 
  44.  
  45. ;; Details on CC-MODE are now (or will soon be) contained in an
  46. ;; accompanying texinfo manual (cc-mode.texi).  To submit bug reports,
  47. ;; hit "C-c C-b", and please try to include a code sample so I can
  48. ;; reproduce your problem.  If you have other questions contact me at
  49. ;; the following address: cc-mode-help@anthem.nlm.nih.gov.  Please
  50. ;; don't send bug reports to my personal account, I may not get it for
  51. ;; a long time.
  52.  
  53. ;; YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS. They are the result of
  54. ;; the multi-Emacsen support.  Emacs 19, Lucid Emacs 19, and Emacs
  55. ;; 18 all do things differently and there's no way to shut the
  56. ;; byte-compiler up at the necessary granularity.
  57.  
  58. ;; If your Emacs is dumped with either c-mode.el or c++-mode.el, you
  59. ;; will need to add the following to your .emacs file before any other
  60. ;; reference to c-mode or c++-mode:
  61. ;;
  62. ;; (fmakunbound 'c-mode)
  63. ;; (makunbound 'c-mode-map)
  64. ;; (fmakunbound 'c++-mode)
  65. ;; (makunbound 'c++-mode-map)
  66. ;; (makunbound 'c-style-alist)
  67.  
  68. ;; There are two major mode entry points provided by this package, one
  69. ;; for editing C++ code and the other for editing C code (both K&R and
  70. ;; ANSI).  To use CC-MODE, add the following to your .emacs file.
  71. ;; This assumes you will use .cc or .C extensions for your C++ source,
  72. ;; and .c for your C code:
  73. ;;
  74. ;; (autoload 'c++-mode "cc-mode" "C++ Editing Mode" t)
  75. ;; (autoload 'c-mode   "cc-mode" "C Editing Mode" t)
  76. ;; (setq auto-mode-alist
  77. ;;   (append '(("\\.C$"  . c++-mode)
  78. ;;             ("\\.cc$" . c++-mode)
  79. ;;             ("\\.c$"  . c-mode)   ; to edit C code
  80. ;;             ("\\.h$"  . c-mode)   ; to edit C code
  81. ;;            ) auto-mode-alist))
  82. ;;
  83. ;; If you would like to join the beta testers list, send add/drop
  84. ;; requests to cc-mode-victims-request@anthem.nlm.nih.gov.
  85. ;; Discussions go to cc-mode-victims@anthem.nlm.nih.gov, but bug
  86. ;; reports and such should still be sent to cc-mode-help only (see
  87. ;; above).
  88. ;;
  89. ;; Many, many thanks go out to all the folks on the beta test list.
  90. ;; Without their patience, testing, insight, and code contributions,
  91. ;; and encouragement cc-mode.el would be a far inferior package.
  92.  
  93. ;; LCD Archive Entry:
  94. ;; cc-mode.el|Barry A. Warsaw|cc-mode-help@anthem.nlm.nih.gov
  95. ;; |Major mode for editing C++, and ANSI/K&R C code
  96. ;; |1994/05/24 22:04:15|3.349|
  97.  
  98. ;;; Code:
  99.  
  100.  
  101. ;; user definable variables
  102. ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  103.  
  104. (defvar c-inhibit-startup-warnings-p nil
  105.   "*If non-nil, inhibits start up compatibility warnings.")
  106. (defvar c-strict-semantics-p nil
  107.   "*If non-nil, all semantic symbols must be found in `c-offsets-alist'.
  108. If the semantic symbol for a particular line does not match a symbol
  109. in the offsets alist, an error is generated, otherwise no error is
  110. reported and the semantic symbol is ignored.")
  111. (defvar c-echo-semantic-information-p nil
  112.   "*If non-nil, semantic info is echoed when the line is indented.")
  113. (defvar c-basic-offset 4
  114.   "*Amount of basic offset used by + and - symbols in `c-offsets-alist'.")
  115.  
  116. (defconst c-offsets-alist-default
  117.   '((string                . -1000)
  118.     (c                     . c-lineup-C-comments)
  119.     (defun-open            . 0)
  120.     (defun-close           . 0)
  121.     (defun-block-intro     . +)
  122.     (class-open            . 0)
  123.     (class-close           . 0)
  124.     (inline-open           . +)
  125.     (inline-close          . 0)
  126.     (c++-funcdecl-cont     . -)
  127.     (knr-argdecl-intro     . +)
  128.     (knr-argdecl           . 0)
  129.     (topmost-intro         . 0)
  130.     (topmost-intro-cont    . 0)
  131.     (member-init-intro     . +)
  132.     (member-init-cont      . 0)
  133.     (inher-intro           . +)
  134.     (inher-cont            . c-lineup-multi-inher)
  135.     (block-open            . 0)
  136.     (block-close           . 0)
  137.     (brace-list-open       . 0)
  138.     (brace-list-close      . 0)
  139.     (brace-list-intro      . +)
  140.     (brace-list-entry      . 0)
  141.     (statement             . 0)
  142.     ;; some people might prefer
  143.     ;;(statement             . c-lineup-runin-statements)
  144.     (statement-cont        . +)
  145.     ;; some people might prefer
  146.     ;;(statement-cont        . c-lineup-math)
  147.     (statement-block-intro . +)
  148.     (statement-case-intro  . +)
  149.     (substatement          . +)
  150.     (substatement-open     . +)
  151.     (case-label            . 0)
  152.     (access-label          . -)
  153.     (label                 . 2)
  154.     (do-while-closure      . 0)
  155.     (else-clause           . 0)
  156.     (comment-intro         . c-lineup-comment)
  157.     (arglist-intro         . +)
  158.     (arglist-cont          . 0)
  159.     (arglist-cont-nonempty . c-lineup-arglist)
  160.     (arglist-close         . +)
  161.     (stream-op             . c-lineup-streamop)
  162.     (inclass               . +)
  163.     (cpp-macro             . -1000)
  164.     (friend                . 0)
  165.     )
  166.   "Default settings for offsets of syntactic elements.
  167. Do not change this constant!  See the variable `c-offsets-alist' for
  168. more information.")
  169.  
  170. (defvar c-offsets-alist (copy-alist c-offsets-alist-default)
  171.   "*Association list of syntactic element symbols and indentation offsets.
  172. As described below, each cons cell in this list has the form:
  173.  
  174.     (SYNTACTIC-SYMBOL . OFFSET)
  175.  
  176. When a line is indented, cc-mode first determines the syntactic
  177. context of the line by generating a list of symbols called syntactic
  178. elements.  This list can contain more than one syntactic element and
  179. the global variable `c-semantics' contains the context list for the
  180. line being indented.  Each element in this list is actually a cons
  181. cell of the syntactic symbol and a buffer position.  This buffer
  182. position is call the relative indent point for the line.  Some
  183. syntactic symbols may not have a relative indent point associated with
  184. them.
  185.  
  186. After the syntactic context list for a line is generated, cc-mode
  187. calculates the absolute indentation for the line by looking at each
  188. syntactic element in the list.  First, it compares the syntactic
  189. element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'.  When it
  190. finds a match, it adds the OFFSET to the column of the relative indent
  191. point.  The sum of this calculation for each element in the syntactic
  192. list is the absolute offset for line being indented.
  193.  
  194. If the syntactic element does not match any in the `c-offsets-alist',
  195. an error is generated if `c-strict-semantics-p' is non-nil, otherwise
  196. the element is ignored.
  197.  
  198. Actually, OFFSET can be an integer, a function, or the symbol `+' or
  199. `-', the latter designating positive or negative values of
  200. `c-basic-offset'. If OFFSET is a function, it is called with a single
  201. argument containing the cons of the syntactic element symbol and the
  202. relative indent point.  The function should return an integer offset.
  203.  
  204. Here is the current list of valid semantic element symbols:
  205.  
  206.  string                 -- inside multi-line string
  207.  c                      -- inside a multi-line C style block comment
  208.  defun-open             -- brace that opens a function definition
  209.  defun-close            -- brace that closes a function definition
  210.  defun-block-intro      -- the first line in a top-level defun
  211.  class-open             -- brace that opens a class definition
  212.  class-close            -- brace that closes a class definition
  213.  inline-open            -- brace that opens an in-class inline method
  214.  inline-close           -- brace that closes an in-class inline method
  215.  c++-funcdecl-cont      -- the nether region between a C++ function
  216.                            declaration and the defun opening brace
  217.  knr-argdecl-intro      -- first line of a K&R C argument declaration
  218.  knr-argdecl            -- subsequent lines in a K&R C argument declaration
  219.  topmost-intro          -- the first line in a topmost construct definition
  220.  topmost-intro-cont     -- topmost definition continuation lines
  221.  member-init-intro      -- first line in a member initialization list
  222.  member-init-cont       -- subsequent member initialization list lines
  223.  inher-intro            -- first line of a multiple inheritance list
  224.  inher-cont             -- subsequent multiple inheritance lines
  225.  block-open             -- statement block open brace
  226.  block-close            -- statement block close brace
  227.  brace-list-open        -- open brace of an enum or static array list
  228.  brace-list-close       -- close brace of an enum or static array list
  229.  brace-list-intro       -- first line in an enum or static array list
  230.  brace-list-entry       -- subsequent lines in an enum or static array list
  231.  statement              -- a C/C++ statement
  232.  statement-cont         -- a continuation of a C/C++ statement
  233.  statement-block-intro  -- the first line in a new statement block
  234.  statement-case-intro   -- the first line in a case `block'
  235.  substatement           -- the first line after an if/while/for/do/else
  236.  substatement-open      -- the brace that opens a substatement block
  237.  case-label             -- a case or default label
  238.  access-label           -- C++ private/protected/public access label
  239.  label                  -- any non-special C/C++ label
  240.  do-while-closure       -- the `while' that ends a do/while construct
  241.  else-clause            -- the `else' of an if/else construct
  242.  comment-intro          -- a line containing only a comment introduction
  243.  arglist-intro          -- the first line in an argument list
  244.  arglist-cont           -- subsequent argument list lines when no
  245.                            arguments follow on the same line as the
  246.                            the arglist opening paren
  247.  arglist-cont-nonempty  -- subsequent argument list lines when at
  248.                            least one argument follows on the same
  249.                            line as the arglist opening paren
  250.  arglist-close          -- the solo close paren of an argument list
  251.  stream-op              -- lines continuing a stream operator construct
  252.  inclass                -- the construct is nested inside a class definition
  253.  cpp-macro              -- the start of a cpp macro
  254.  friend                 -- a C++ friend declaration
  255. ")
  256.  
  257. (defvar c-tab-always-indent t
  258.   "*Controls the operation of the TAB key.
  259. If t, hitting TAB always just indents the current line.  If nil,
  260. hitting TAB indents the current line if point is at the left margin or
  261. in the line's indentation, otherwise it insert a real tab character.
  262. If other than nil or t, then tab is inserted only within literals
  263. -- defined as comments and strings -- and inside preprocessor
  264. directives, but line is always reindented.
  265.  
  266. Note that indentation of lines containing only comments is also
  267. controlled by the `c-comment-only-line-offset' variable.")
  268.  
  269. (defvar c-comment-only-line-offset 0
  270.   "*Extra offset for line which contains only the start of a comment.
  271. Can contain an integer or a cons cell of the form:
  272.  
  273.  (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
  274.  
  275. Where NON-ANCHORED-OFFSET is the amount of offset given to
  276. non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
  277. the amount of offset to give column-zero anchored comment-only lines.
  278. Just an integer as value is equivalent to (<val> . 0)")
  279.  
  280. (defvar c-block-comments-indent-p nil
  281.   "*Specifies how to re-indent C style block comments.
  282.  
  283. 4 styles of C block comments are supported.  If this variable is nil,
  284. then styles 1-3 are supported.  If this variable is non-nil, style 4
  285. only is supported.  Note that this currently has *no* effect on how
  286. comments are lined up or whether stars are inserted when C comments
  287. are auto-filled.  In any case, you still have to insert the stars
  288. manually.
  289.  
  290.  style 1:       style 2:       style 3:       style 4:
  291.  /*             /*             /*             /*
  292.     blah         * blah        ** blah        blah
  293.     blah         * blah        ** blah        blah
  294.     */           */            */             */")
  295.  
  296. (defvar c-cleanup-list '(scope-operator)
  297.   "*List of various C/C++ constructs to \"clean up\".
  298. These clean ups only take place when the auto-newline feature is turned
  299. on, as evidenced by the `/a' or `/ah' appearing next to the mode name.
  300. Valid symbols are:
  301.  
  302.  brace-else-brace    -- cleans up `} else {' constructs by placing entire
  303.                         construct on a single line.  This clean up only
  304.                         takes place when there is nothing but white
  305.                         space between the braces and the `else'.  Clean
  306.             up occurs when the open-brace after the `else'
  307.             is typed.
  308.  empty-defun-braces  -- cleans up empty defun braces by placing the
  309.                         braces on the same line.  Clean up occurs when
  310.             the defun closing brace is typed.
  311.  defun-close-semi    -- cleans up the terminating semi-colon on defuns
  312.             by placing the semi-colon on the same line as
  313.             the closing brace.  Clean up occurs when the
  314.             semi-colon is typed.
  315.  list-close-comma    -- cleans up commas following braces in array
  316.                         and aggregate initializers.  Clean up occurs
  317.             when the comma is typed.
  318.  scope-operator      -- cleans up double colons which may designate
  319.             a C++ scope operator split across multiple
  320.             lines. Note that certain C++ constructs can
  321.             generate ambiguous situations.  This clean up
  322.             only takes place when there is nothing but
  323.             whitespace between colons. Clean up occurs
  324.             when the second colon is typed.")
  325.  
  326. (defvar c-hanging-braces-alist '((brace-list-open)
  327.                  (substatement-open after))
  328.   "*Controls the insertion of newlines before and after braces.
  329. This variable contains an association list with elements of the
  330. following form: (SYNTACTIC-SYMBOL . (NL-LIST)).
  331.  
  332. SYNTACTIC-SYMBOL can be any of: defun-open, defun-cloase, class-open,
  333. class-close, inline-open, inline-close, block-open,
  334. block-close, substatement-open, brace-list-open, or
  335. brace-list-close. See `c-offsets-alist' for details.
  336.  
  337. NL-LIST can contain any combination of the symbols `before' or
  338. `after'. It also be nil.  When a brace is inserted, the syntactic
  339. context it defines is looked up in this list, and if found, the
  340. NL-LIST is used to determine where newlines are inserted.  If not
  341. found, the default is to insert a newline both before and after
  342. braces.")
  343.  
  344. (defvar c-hanging-colons-alist nil
  345.   "*Controls the insertion of newlines before and after certain colons.
  346. This variable contains an association list with elements of the
  347. following form: (SYNTACTIC-SYMBOL . (NL-LIST)).
  348.  
  349. SYNTACTIC-SYMBOL can be any of: member-init-intro, inher-intro,
  350. case-label, label, and access-label. See `c-offsets-alist' for
  351. details.
  352.  
  353. NL-LIST can contain any combination of the symbols `before' or
  354. `after'. It also be nil.  When a colon is inserted, the language
  355. element that it defines is looked up in this list, and if found, the
  356. NL-LIST is used to determine where newlines are inserted.  If the
  357. language element for the colon is not found in this list, the default
  358. behavior is to not insert any newlines.")
  359.  
  360. (defvar c-backslash-column 48
  361.   "*Column to insert backslashes when macroizing a region.")
  362. (defvar c-special-indent-hook nil
  363.   "*Hook for user defined special indentation adjustments.
  364. This hook gets called after a line is indented by the mode.")
  365. (defvar c-delete-function 'backward-delete-char-untabify
  366.   "*Function called by `c-electric-delete' when deleting a single char.")
  367. (defvar c-electric-pound-behavior nil
  368.   "*List of behaviors for electric pound insertion.
  369. Only currently supported behavior is `alignleft'.")
  370.  
  371. (defvar c-style-alist
  372.   '(("GNU"
  373.      (c-basic-offset . 2)
  374.      (c-comment-only-line-offset . 0)
  375.      (c-offsets-alist . ((statement-block-intro . +)
  376.              (knr-argdecl-intro . 5)
  377.              (substatement-open . +)
  378.              (label . -)
  379.              (statement-cont . +)
  380.              ))
  381.      )
  382.     ("K&R"
  383.      (c-basic-offset . 5)
  384.      (c-comment-only-line-offset . 0)
  385.      (c-offsets-alist . ((statement-block-intro . +)
  386.              (knr-argdecl-intro . 0)
  387.              (substatement-open . 0)
  388.              (label . -)
  389.              (statement-cont . +)
  390.              ))
  391.      )
  392.     ("BSD"
  393.      (c-basic-offset . 4)
  394.      (c-comment-only-line-offset . 0)
  395.      (c-offsets-alist . ((statement-block-intro . +)
  396.              (knr-argdecl-intro . +)
  397.              (substatement-open . 0)
  398.              (label . -)
  399.              (statement-cont . +)
  400.              ))
  401.      )
  402.     ("Stroustrup"
  403.      (c-basic-offset . 4)
  404.      (c-comment-only-line-offset . 0)
  405.      (c-offsets-alist . ((statement-block-intro . +)
  406.              (substatement-open . 0)
  407.              (label . -)
  408.              (statement-cont . +)
  409.              ))
  410.      )
  411.     ("Whitesmith"
  412.      (c-basic-offset . 4)
  413.      (c-comment-only-line-offset . 0)
  414.      (c-offsets-alist . ((statement-block-intro . +)
  415.              (knr-argdecl-intro . +)
  416.              (substatement-open . 0)
  417.              (label . -)
  418.              (statement-cont . +)
  419.              ))
  420.  
  421.      )
  422.     ("Ellemtel"
  423.      (c-basic-offset . 3)
  424.      (c-comment-only-line-offset . 0)
  425.      (c-hanging-braces-alist     . ((substatement-open before)))
  426.      (c-offsets-alist . ((topmost-intro      . 0)
  427.                          (topmost-intro-cont . 0)
  428.                          (substatement       . 3)
  429.              (substatement-open  . 0)
  430.                          (case-label         . +)
  431.                          (access-label       . -3)
  432.                          (inclass            . 6)
  433.                          (inline-open        . 0)
  434.                          ))
  435.      ))
  436.   "Styles of Indentation.
  437. Elements of this alist are of the form:
  438.  
  439.   (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
  440.  
  441. where STYLE-STRING is a short descriptive string used to select a
  442. style, VARIABLE is any cc-mode variable, and VALUE is the intended
  443. value for that variable when using the selected style.
  444.  
  445. There is one special case when VARIABLE is `c-offsets-alist'.  In this
  446. case, the VALUE is a list containing elements of the form:
  447.  
  448.   (SYNTACTIC-SYMBOL . VALUE)
  449.  
  450. as described in `c-offsets-alist'.  These are passed directly to
  451. `c-set-offset' so there is no need to set every syntactic symbol in
  452. your style, only those that are different from the default.")
  453.  
  454. ;; dynamically append the default value of most variables
  455. (or (assoc "Default" c-style-alist)
  456.     (let* ((varlist '(c-inhibit-startup-warnings-p
  457.               c-strict-semantics-p
  458.               c-echo-semantic-information-p
  459.               c-basic-offset
  460.               c-offsets-alist
  461.               c-tab-always-indent
  462.               c-comment-only-line-offset
  463.               c-block-comments-indent-p
  464.               c-cleanup-list
  465.               c-hanging-braces-alist
  466.               c-hanging-colons-alist
  467.               c-backslash-column
  468.               c-electric-pound-behavior))
  469.        (default (cons "Default"
  470.               (mapcar
  471.                (function
  472.                 (lambda (var)
  473.                   (cons var (symbol-value var))
  474.                   ))
  475.                varlist))))
  476.       (setq c-style-alist (cons default c-style-alist))))
  477.  
  478. (defvar c-mode-hook nil
  479.   "*Hook called by `c-mode'.")
  480. (defvar c++-mode-hook nil
  481.   "*Hook called by `c++-mode'.")
  482. (defvar c-mode-common-hook nil
  483.   "*Hook called by both `c-mode' and `c++-mode' during common init path.")
  484.  
  485. (defvar c-mode-menu
  486.   '(["Comment Out Region"     comment-region (mark)]
  487.     ["Macro Expand Region"    c-macro-expand (mark)]
  488.     ["Backslashify"           c-backslash-region (mark)]
  489.     ["Indent Expression"      c-indent-exp
  490.      (memq (following-char) '(?\( ?\[ ?\{))]
  491.     ["Indent Line"            c-indent-command t]
  492.     ["Fill Comment Paragraph" c-fill-paragraph t]
  493.     ["Up Conditional"         c-up-conditional t]
  494.     ["Backward Conditional"   c-backward-conditional t]
  495.     ["Forward Conditional"    c-forward-conditional t]
  496.     ["Backward Statement"     c-beginning-of-statement t]
  497.     ["Forward Statement"      c-end-of-statement t]
  498.     )
  499.   "Lucid Emacs menu for C/C++ modes.")
  500.  
  501.  
  502. ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  503. ;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
  504.  
  505. (defconst c-emacs-features
  506.   (let ((major (and (boundp 'emacs-major-version)
  507.             emacs-major-version))
  508.     (minor (and (boundp 'emacs-minor-version)
  509.             emacs-minor-version))
  510.     flavor comments)
  511.     ;; figure out version numbers if not already discovered
  512.     (and (or (not major) (not minor))
  513.      (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
  514.      (setq major (string-to-int (substring emacs-version
  515.                            (match-beginning 1)
  516.                            (match-end 1)))
  517.            minor (string-to-int (substring emacs-version
  518.                            (match-beginning 2)
  519.                            (match-end 2)))))
  520.     (if (not (and major minor))
  521.     (error "Cannot figure out the major and minor version numbers."))
  522.     ;; calculate the major version
  523.     (cond
  524.      ((= major 18) (setq major 'v18))    ;Emacs 18
  525.      ((= major 4)  (setq major 'v18))    ;Epoch 4
  526.      ((= major 19) (setq major 'v19    ;Emacs 19
  527.              flavor (if (string-match "Lucid" emacs-version)
  528.                     'Lucid 'FSF)))
  529.      ;; I don't know
  530.      (t (error "Cannot recognize major version number: %s" major)))
  531.     ;; All Lucid versions use 8-bit modify-syntax-entry flags, as do all
  532.     ;; patched (obsolete) Emacs 19, Emacs 18, Epoch 4's.  Only
  533.     ;; vanilla Emacs 19 uses 1-bit flag.  Lets be as smart as we
  534.     ;; can about figuring this out.
  535.     (if (eq major 'v19)
  536.     (let ((table (copy-syntax-table)))
  537.       (modify-syntax-entry ?a ". 12345678" table)
  538.       (if (= (logand (lsh (aref table ?a) -16) 255) 255)
  539.           (setq comments '8-bit)
  540.         (setq comments '1-bit)))
  541.       (setq comments 'no-dual-comments))
  542.     ;; lets do some minimal sanity checking.
  543.     (if (and (or
  544.           ;; Lemacs before 19.6 had bugs
  545.           (and (eq major 'v19) (eq flavor 'Lucid) (< minor 6))
  546.           ;; Emacs 19 before 19.21 has known bugs
  547.           (and (eq major 'v19) (eq flavor 'FSF) (< minor 21)))
  548.          (not c-inhibit-startup-warnings-p))
  549.     (with-output-to-temp-buffer "*cc-mode warnings*"
  550.       (print (format
  551. "The version of Emacs that you are running, %s,
  552. has known bugs in its syntax.c parsing routines which will affect the
  553. performance of cc-mode. You should strongly consider upgrading to the
  554. latest available version.  cc-mode may continue to work, after a
  555. fashion, but strange indentation errors could be encountered."
  556.              emacs-version))))
  557.     ;; Emacs 18, with no patch is not too good
  558.     (if (and (eq major 'v18) (eq comments 'no-dual-comments)
  559.          (not c-inhibit-startup-warnings-p))
  560.     (with-output-to-temp-buffer "*cc-mode warnings*"
  561.       (print (format
  562. "The version of Emacs 18 you are running, %s,
  563. has known deficiencies in its ability to handle dual C++ comments,
  564. i.e. C++ line style comments and C block style comments.  This will
  565. not be much of a problem for you if you are only editing C code, but
  566. if you are doing much C++ editing, you should strongly consider
  567. upgrading to one of the latest Emacs 19's.  In Emacs 18, you may also
  568. experience performance degradations. Emacs 19 has some new built-in
  569. routines which will speed things up for you.
  570.  
  571. Because of these inherent problems, cc-mode is no longer being
  572. actively maintained for Emacs 18, although patch contributions will be
  573. folded into the main release. "
  574.                 emacs-version))))
  575.     ;; Emacs 18 with the syntax patches are no longer supported
  576.     (if (and (eq major 'v18) (not (eq comments 'no-dual-comments))
  577.          (not c-inhibit-startup-warnings-p))
  578.     (with-output-to-temp-buffer "*cc-mode warnings*"
  579.       (print (format
  580. "You are running a syntax patched Emacs 18 variant.  While this should
  581. work for you, you may want to consider upgrading to Emacs 19.
  582. The syntax patches are no longer supported
  583. either for syntax.c or cc-mode."))))
  584.     (list major flavor comments))
  585.   "A list of features extant in the Emacs you are using.
  586. There are many flavors of Emacs out there, each with different
  587. features supporting those needed by cc-mode.  Here's the current
  588. supported list, along with the values for this variable:
  589.  
  590.  Emacs 19:                  (v19 FSF 1-bit)
  591.  Vanilla Emacs 18/Epoch 4:  (v18 no-dual-comments)
  592.  Emacs 18/Epoch 4 (patch2): (v18 8-bit)
  593.  Lucid Emacs 19:            (v19 Lucid 8-bit).")
  594.  
  595. (defvar c++-mode-abbrev-table nil
  596.   "Abbrev table in use in c++-mode buffers.")
  597. (define-abbrev-table 'c++-mode-abbrev-table ())
  598.  
  599. (defvar c-mode-abbrev-table nil
  600.   "Abbrev table in use in c-mode buffers.")
  601. (define-abbrev-table 'c-mode-abbrev-table ())
  602.  
  603. (defvar c-mode-map ()
  604.   "Keymap used in c-mode buffers.")
  605. (if c-mode-map
  606.     ()
  607.   ;; TBD: should we even worry about naming this keymap. My vote: no,
  608.   ;; because Emacs 19 and Lucid do it differently.
  609.   (setq c-mode-map (make-sparse-keymap))
  610.   ;; put standard keybindings into MAP
  611.   ;; the following mappings correspond more or less directly to BOCM
  612.   (define-key c-mode-map "{"         'c-electric-brace)
  613.   (define-key c-mode-map "}"         'c-electric-brace)
  614.   (define-key c-mode-map ";"         'c-electric-semi&comma)
  615.   (define-key c-mode-map "#"         'c-electric-pound)
  616.   (define-key c-mode-map ":"         'c-electric-colon)
  617.   ;; Lemacs 19.9 defines these two, the second of which is commented out
  618.   ;; (define-key c-mode-map "\e{" 'c-insert-braces)
  619.   ;; Commented out electric square brackets because nobody likes them.
  620.   ;; (define-key c-mode-map "[" 'c-insert-brackets)
  621.   (define-key c-mode-map "\e\C-h"    'c-mark-function)
  622.   (define-key c-mode-map "\e\C-q"    'c-indent-exp)
  623.   (define-key c-mode-map "\ea"       'c-beginning-of-statement)
  624.   (define-key c-mode-map "\ee"       'c-end-of-statement)
  625.   ;; I'd rather use an adaptive fill program instead of this.
  626.   (define-key c-mode-map "\eq"       'c-fill-paragraph)
  627.   (define-key c-mode-map "\C-c\C-n"  'c-forward-conditional)
  628.   (define-key c-mode-map "\C-c\C-p"  'c-backward-conditional)
  629.   (define-key c-mode-map "\C-c\C-u"  'c-up-conditional)
  630.   (define-key c-mode-map "\t"        'c-indent-command)
  631.   (define-key c-mode-map "\177"      'c-electric-delete)
  632.   ;; these are new keybindings, with no counterpart to BOCM
  633.   (define-key c-mode-map ","         'c-electric-semi&comma)
  634.   (define-key c-mode-map "/"         'c-electric-slash)
  635.   (define-key c-mode-map "*"         'c-electric-star)
  636.   (define-key c-mode-map "\C-c\C-q"  'c-indent-defun)
  637.   (define-key c-mode-map "\C-c\C-\\" 'c-backslash-region)
  638.   ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
  639.   (define-key c-mode-map "\C-c\C-a"  'c-toggle-auto-state)
  640.   (define-key c-mode-map "\C-c\C-b"  'c-submit-bug-report)
  641.   (define-key c-mode-map "\C-c\C-c"  'comment-region)
  642.   (define-key c-mode-map "\C-c\C-d"  'c-toggle-hungry-state)
  643.   (define-key c-mode-map "\C-c\C-e"  'c-macro-expand)
  644.   (define-key c-mode-map "\C-c\C-o"  'c-set-offset)
  645.   (define-key c-mode-map "\C-c\C-s"  'c-show-semantic-information)
  646.   (define-key c-mode-map "\C-c\C-t"  'c-toggle-auto-hungry-state)
  647.   (define-key c-mode-map "\C-c\C-v"  'c-version)
  648.   ;; Emacs 19 defines menus in the mode map
  649.   (if (memq 'FSF c-emacs-features)
  650.       (progn
  651.     (define-key c-mode-map [menu-bar] (make-sparse-keymap))
  652.  
  653.     (define-key c-mode-map [menu-bar c]
  654.       (cons "C/C++" (make-sparse-keymap "C/C++")))
  655.  
  656.     (define-key c-mode-map [menu-bar c comment-region]
  657.       '("Comment Out Region" . comment-region))
  658.     (define-key c-mode-map [menu-bar c c-macro-expand]
  659.       '("Macro Expand Region" . c-macro-expand))
  660.     (define-key c-mode-map [menu-bar c c-backslash-region]
  661.       '("Backslashify" . c-backslash-region))
  662.     (define-key c-mode-map [menu-bar c indent-exp]
  663.       '("Indent Expression" . c-indent-exp))
  664.     (define-key c-mode-map [menu-bar c indent-line]
  665.       '("Indent Line" . c-indent-command))
  666.     (define-key c-mode-map [menu-bar c fill]
  667.       '("Fill Comment Paragraph" . c-fill-paragraph))
  668.     (define-key c-mode-map [menu-bar c up]
  669.       '("Up Conditional" . c-up-conditional))
  670.     (define-key c-mode-map [menu-bar c backward]
  671.       '("Backward Conditional" . c-backward-conditional))
  672.     (define-key c-mode-map [menu-bar c forward]
  673.       '("Forward Conditional" . c-forward-conditional))
  674.     (define-key c-mode-map [menu-bar c backward-stmt]
  675.       '("Backward Statement" . c-beginning-of-statement))
  676.     (define-key c-mode-map [menu-bar c forward-stmt]
  677.       '("Forward Statement" . c-end-of-statement))
  678.  
  679.      ;; RMS: mouse-3 should not select this menu.  mouse-3's global
  680.      ;; definition is useful in C mode and we should not interfere
  681.      ;; with that.  The menu is mainly for beginners, and for them,
  682.      ;; the menubar requires less memory than a special click.
  683.     )
  684.     ;; in Lucid Emacs, we want the menu to popup when the 3rd button is
  685.     ;; hit.  In 19.10 and beyond this is done automatically if we put
  686.     ;; the menu on mode-popup-menu variable, see c-common-init
  687.     (if (memq 'Lucid c-emacs-features)
  688.     (if (not (boundp 'mode-popup-menu))
  689.         (define-key c-mode-map 'button3 'c-popup-menu)))
  690.     ))
  691.  
  692. (defvar c++-mode-map ()
  693.   "Keymap used in c++-mode buffers.")
  694. (if c++-mode-map
  695.     ()
  696.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  697.   (if (memq 'v19 c-emacs-features)
  698.       ;; Lucid and Emacs 19 do this differently
  699.       (if (memq 'FSF c-emacs-features)
  700.       (setq c++-mode-map (cons 'keymap c-mode-map))
  701.     (setq c++-mode-map (make-sparse-keymap))
  702.     (set-keymap-parent c++-mode-map c-mode-map))
  703.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  704.     (setq c++-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  705.   ;; add bindings which are only useful for C++
  706.   (define-key c++-mode-map "\C-c:"  'c-scope-operator)
  707.   )
  708.  
  709. (defun c-populate-syntax-table (table)
  710.   ;; Populate the syntax TABLE
  711.   ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
  712.   (modify-syntax-entry ?\\ "\\"    table)
  713.   (modify-syntax-entry ?+  "."     table)
  714.   (modify-syntax-entry ?-  "."     table)
  715.   (modify-syntax-entry ?=  "."     table)
  716.   (modify-syntax-entry ?%  "."     table)
  717.   (modify-syntax-entry ?<  "."     table)
  718.   (modify-syntax-entry ?>  "."     table)
  719.   (modify-syntax-entry ?&  "."     table)
  720.   (modify-syntax-entry ?|  "."     table)
  721.   (modify-syntax-entry ?\' "\""    table))
  722.  
  723. (defvar c-mode-syntax-table nil
  724.   "Syntax table used in c-mode buffers.")
  725. (if c-mode-syntax-table
  726.     ()
  727.   (setq c-mode-syntax-table (make-syntax-table))
  728.   (c-populate-syntax-table c-mode-syntax-table)
  729.   ;; add extra comment syntax
  730.   (modify-syntax-entry ?/  ". 14"  c-mode-syntax-table)
  731.   (modify-syntax-entry ?*  ". 23"  c-mode-syntax-table))
  732.  
  733. (defvar c++-mode-syntax-table nil
  734.   "Syntax table used in c++-mode buffers.")
  735. (if c++-mode-syntax-table
  736.     ()
  737.   (setq c++-mode-syntax-table (make-syntax-table))
  738.   (c-populate-syntax-table c++-mode-syntax-table)
  739.   ;; add extra comment syntax
  740.   (cond
  741.    ((memq '8-bit c-emacs-features)
  742.     ;; Lucid emacs has the best implementation
  743.     (modify-syntax-entry ?/  ". 1456" c++-mode-syntax-table)
  744.     (modify-syntax-entry ?*  ". 23"   c++-mode-syntax-table)
  745.     (modify-syntax-entry ?\n "> b"    c++-mode-syntax-table))
  746.    ((memq '1-bit c-emacs-features)
  747.     ;; Emacs 19 does things differently, but we can work with it
  748.     (modify-syntax-entry ?/  ". 124b" c++-mode-syntax-table)
  749.     (modify-syntax-entry ?*  ". 23"   c++-mode-syntax-table)
  750.     (modify-syntax-entry ?\n "> b"    c++-mode-syntax-table))
  751.    )
  752.   ;; TBD: does it make sense for colon to be symbol class in C++?
  753.   ;; I'm not so sure, since c-label-key is busted on lines like:
  754.   ;; Foo::bar( i );
  755.   ;; maybe c-label-key should be fixed instead of commenting this out,
  756.   ;; but it also bothers me that this only seems appropriate for C++
  757.   ;; and not C.
  758.   ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
  759.   )
  760.  
  761. (defvar c-hungry-delete-key nil
  762.   "Internal state of hungry delete key feature.")
  763. (defvar c-auto-newline nil
  764.   "Internal state of auto newline feature.")
  765. (defvar c-auto-hungry-string nil
  766.   "Internal auto-newline/hungry-delete designation string for mode line.")
  767. (defvar c-semantics nil
  768.   "Variable containing semantics list during indentation.")
  769. (defvar c-comment-start-regexp nil
  770.   "Buffer local variable describing how comment are introduced.")
  771. (defvar c-conditional-key nil
  772.   "Buffer-local language-specific conditional keyword regexp.")
  773.  
  774. (make-variable-buffer-local 'c-auto-newline)
  775. (make-variable-buffer-local 'c-hungry-delete-key)
  776. (make-variable-buffer-local 'c-auto-hungry-string)
  777. (make-variable-buffer-local 'c-comment-start-regexp)
  778. (make-variable-buffer-local 'c-conditional-key)
  779.  
  780. ;; cmacexp is lame because it uses no preprocessor symbols.
  781. ;; It isn't very extensible either -- hardcodes /lib/cpp.
  782. ;; [I add it here only because c-mode has it -- BAW]]
  783. (autoload 'c-macro-expand "cmacexp"
  784.   "Display the result of expanding all C macros occurring in the region.
  785. The expansion is entirely correct because it uses the C preprocessor."
  786.   t)
  787.  
  788.  
  789. ;; constant regular expressions for looking at various constructs
  790. (defconst c-symbol-key "\\(\\w\\|\\s_\\)+"
  791.   "Regexp describing a C/C++ symbol.
  792. We cannot use just `word' syntax class since `_' cannot be in word
  793. class.  Putting underscore in word class breaks forward word movement
  794. behavior that users are familiar with.")
  795. (defconst c-class-key
  796.   (concat
  797.    "\\(\\(extern\\|typedef\\)\\s +\\)?"
  798.    "\\(template\\s *<[^>]*>\\s *\\)?"
  799.    ;; I'd like to add \\= in the first grouping below, but 1. its not
  800.    ;; defined in v18, and 2. doesn't seem to work in v19 anyway.
  801.    "\\([^<a-zA-Z0-9_]\\|\\`\\)[ \t]*"
  802.    "\\(class\\|struct\\|union\\)\\([ \t\n]+\\|\\'\\)")
  803.   "Regexp describing a class declaration, including templates.")
  804. (defconst c-inher-key
  805.   (concat "\\(\\<static\\>\\s +\\)?"
  806.       c-class-key "[ \t]+" c-symbol-key
  807.       "\\([ \t]*:[ \t]*\\)?\\s *[^;]")
  808.   "Regexp describing a class inheritance declaration.")
  809. (defconst c-protection-key
  810.   "\\<\\(public\\|protected\\|private\\)\\>"
  811.   "Regexp describing protection keywords.")
  812. (defconst c-baseclass-key
  813.   (concat
  814.    ":?[ \t]*\\(virtual[ \t]+\\)?\\("
  815.    c-protection-key "[ \t]+\\)" c-symbol-key)
  816.   "Regexp describing base classes in a derived class definition.")
  817. (defconst c-switch-label-key
  818.   "\\(\\(case[ \t]+\\S .*\\)\\|default[ \t]*\\):"
  819.   "Regexp describing a switch's case or default label")
  820. (defconst c-access-key
  821.   (concat c-protection-key ":")
  822.   "Regexp describing access specification keywords.")
  823. (defconst c-label-key
  824.   (concat c-symbol-key ":\\([^:]\\|$\\)")
  825.   "Regexp describing any label.")
  826. (defconst c-C-conditional-key
  827.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\)\\b[^_]"
  828.   "Regexp describing a conditional control.")
  829. (defconst c-C++-conditional-key
  830.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\|try\\|catch\\)\\b[^_]"
  831.   "Regexp describing a conditional control for C++.")
  832.  
  833. ;; main entry points for the modes
  834. ;;;###autoload
  835. (defun c++-mode ()
  836.   "Major mode for editing C++ code.
  837. cc-mode Revision: 3.349
  838. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  839. c++-mode buffer.  This automatically sets up a mail buffer with
  840. version information already added.  You just need to add a description
  841. of the problem, including a reproducable test case and send the
  842. message.
  843.  
  844. Note that the details of configuring c++-mode have been moved to
  845. the accompanying texinfo manual.
  846.  
  847. The hook variable `c++-mode-hook' is run with no args, if that
  848. variable is bound and has a non-nil value.  Also the common hook
  849. c-mode-common-hook is run first,  both by this defun, and `c-mode'.
  850.  
  851. Key bindings:
  852. \\{c++-mode-map}"
  853.   (interactive)
  854.   (kill-all-local-variables)
  855.   (set-syntax-table c++-mode-syntax-table)
  856.   (setq major-mode 'c++-mode
  857.     mode-name "C++"
  858.     local-abbrev-table c++-mode-abbrev-table)
  859.   (use-local-map c++-mode-map)
  860.   (c-common-init)
  861.   (setq comment-start "// "
  862.     comment-end ""
  863.     c-conditional-key c-C++-conditional-key
  864.     c-comment-start-regexp "//\\|/\\*")
  865.   (run-hooks 'c++-mode-hook))
  866.  
  867. ;;;###autoload
  868. (defun c-mode ()
  869.   "Major mode for editing K&R and ANSI C code.
  870. cc-mode Revision: 3.349
  871. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  872. c-mode buffer.  This automatically sets up a mail buffer with version
  873. information already added.  You just need to add a description of the
  874. problem, including a reproducable test case and send the message.
  875.  
  876. Note that the details of configuring c-mode will soon be moved to the
  877. accompanying texinfo manual.  Until then, please read the README file
  878. that came with the cc-mode distribution.
  879.  
  880. The hook variable `c-mode-hook' is run with no args, if that value is
  881. bound and has a non-nil value.  Also the common hook
  882. c-mode-common-hook is run first, both by this defun and `c++-mode'.
  883.  
  884. Key bindings:
  885. \\{c-mode-map}"
  886.   (interactive)
  887.   (kill-all-local-variables)
  888.   (set-syntax-table c-mode-syntax-table)
  889.   (setq major-mode 'c-mode
  890.     mode-name "C"
  891.     local-abbrev-table c-mode-abbrev-table)
  892.   (use-local-map c-mode-map)
  893.   (c-common-init)
  894.   (setq comment-start "/* "
  895.     comment-end   " */"
  896.     c-conditional-key c-C-conditional-key
  897.     c-comment-start-regexp "/\\*")
  898.   (run-hooks 'c-mode-hook))
  899.  
  900. (defun c-common-init ()
  901.   ;; Common initializations for c++-mode and c-mode.
  902.   ;; make local variables
  903.   (make-local-variable 'paragraph-start)
  904.   (make-local-variable 'paragraph-separate)
  905.   (make-local-variable 'paragraph-ignore-fill-prefix)
  906.   (make-local-variable 'require-final-newline)
  907.   (make-local-variable 'parse-sexp-ignore-comments)
  908.   (make-local-variable 'indent-line-function)
  909.   (make-local-variable 'indent-region-function)
  910.   (make-local-variable 'comment-start)
  911.   (make-local-variable 'comment-end)
  912.   (make-local-variable 'comment-column)
  913.   (make-local-variable 'comment-start-skip)
  914.   ;; now set their values
  915.   (setq paragraph-start (concat "^$\\|" page-delimiter)
  916.     paragraph-separate paragraph-start
  917.     paragraph-ignore-fill-prefix t
  918.     require-final-newline t
  919.     parse-sexp-ignore-comments t
  920.     indent-line-function 'c-indent-line
  921.     indent-region-function 'c-indent-region
  922.     comment-column 32
  923.     comment-start-skip "/\\*+ *\\|// *")
  924.   ;; setup the comment indent variable in a Emacs version portable way
  925.   ;; ignore any byte compiler warnings you might get here
  926.   (if (boundp 'comment-indent-function)
  927.       (progn
  928.        (make-local-variable 'comment-indent-function)
  929.        (setq comment-indent-function 'c-comment-indent))
  930.     (make-local-variable 'comment-indent-hook)
  931.     (setq comment-indent-hook 'c-comment-indent))
  932.   ;; put C menu into menubar for Lucid Emacs. I think this happens
  933.   ;; automatically for Emacs 19.
  934.   (if (and (memq 'Lucid c-emacs-features)
  935.        current-menubar
  936.        (not (assoc mode-name current-menubar)))
  937.       (progn
  938.     (set-buffer-menubar (copy-sequence current-menubar))
  939.     (add-menu nil mode-name c-mode-menu)))
  940.   (if (and (memq 'Lucid c-emacs-features)
  941.        (boundp 'mode-popup-menu))
  942.       (setq mode-popup-menu
  943.         (cons (concat mode-name " Mode Commands") c-mode-menu)))
  944.   ;; put auto-hungry designators onto minor-mode-alist, but only once
  945.   (or (assq 'c-auto-hungry-string minor-mode-alist)
  946.       (setq minor-mode-alist
  947.         (cons '(c-auto-hungry-string c-auto-hungry-string)
  948.           minor-mode-alist)))
  949.   (run-hooks 'c-mode-common-hook))
  950.  
  951.  
  952. ;; macros must be defined before first use
  953. (defmacro c-point (position)
  954.   ;; Returns the value of point at certain commonly referenced POSITIONs.
  955.   ;; POSITION can be one of the following symbols:
  956.   ;; 
  957.   ;; bol  -- beginning of line
  958.   ;; eol  -- end of line
  959.   ;; bod  -- beginning of defun
  960.   ;; boi  -- back to indentation
  961.   ;; ionl -- indentation of next line
  962.   ;; iopl -- indentation of previous line
  963.   ;; bonl -- beginning of next line
  964.   ;; bopl -- beginning of previous line
  965.   ;; 
  966.   ;; This function does not modify point or mark.
  967.   (or (and (eq 'quote (car-safe position))
  968.        (null (cdr (cdr position))))
  969.       (error "bad buffer position requested: %s" position))
  970.   (setq position (nth 1 position))
  971.   (` (let ((here (point)))
  972.        (,@ (cond
  973.         ((eq position 'bol)  '((beginning-of-line)))
  974.         ((eq position 'eol)  '((end-of-line)))
  975.         ((eq position 'bod)
  976.          '((beginning-of-defun)
  977.            ;; if defun-prompt-regexp is non-nil, b-o-d won't leave
  978.            ;; us at the open brace.
  979.            (and (boundp 'defun-prompt-regexp)
  980.             defun-prompt-regexp
  981.             (looking-at defun-prompt-regexp)
  982.             (goto-char (match-end 0)))
  983.            ))
  984.         ((eq position 'boi)  '((back-to-indentation)))
  985.         ((eq position 'bonl) '((forward-line 1)))
  986.         ((eq position 'bopl) '((forward-line -1)))
  987.         ((eq position 'iopl)
  988.          '((forward-line -1)
  989.            (back-to-indentation)))
  990.         ((eq position 'ionl)
  991.          '((forward-line 1)
  992.            (back-to-indentation)))
  993.         (t (error "unknown buffer position requested: %s" position))
  994.         ))
  995.        (prog1
  996.        (point)
  997.      (goto-char here))
  998.        ;; workaround for an Emacs18 bug -- blech! Well, at least it
  999.        ;; doesn't hurt for v19
  1000.        (,@ nil)
  1001.        )))
  1002.  
  1003. (defmacro c-auto-newline ()
  1004.   ;; if auto-newline feature is turned on, insert a newline character
  1005.   ;; and return t, otherwise return nil.
  1006.   (` (and c-auto-newline
  1007.       (not (c-in-literal))
  1008.       (not (newline)))))
  1009.  
  1010. (defmacro c-safe (&rest body)
  1011.   ;; safely execute BODY, return nil if an error occurred
  1012.   (` (condition-case nil
  1013.      (progn (,@ body))
  1014.        (error nil))))
  1015.  
  1016. (defun c-insert-special-chars (arg)
  1017.   ;; simply call self-insert-command in Emacs 19
  1018.   (self-insert-command (prefix-numeric-value arg)))
  1019.  
  1020.  
  1021. ;; This is used by indent-for-comment to decide how much to indent a
  1022. ;; comment in C code based on its context.
  1023. (defun c-comment-indent ()
  1024.   (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
  1025.       0                ;Existing comment at bol stays there.
  1026.     (let ((opoint (point))
  1027.       placeholder)
  1028.       (save-excursion
  1029.     (beginning-of-line)
  1030.     (cond
  1031.      ;; CASE 1: A comment following a solitary close-brace should
  1032.      ;; have only one space.
  1033.      ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
  1034.                   c-comment-start-regexp
  1035.                   "\\)"))
  1036.       (search-forward "}")
  1037.       (1+ (current-column)))
  1038.      ;; CASE 2: 2 spaces after #endif
  1039.      ((or (looking-at "^#[ \t]*endif[ \t]*")
  1040.           (looking-at "^#[ \t]*else[ \t]*"))
  1041.       7)
  1042.      ;; CASE 3: use comment-column if previous line is a
  1043.      ;; comment-only line indented to the left of comment-column
  1044.      ((save-excursion
  1045.         (beginning-of-line)
  1046.         (and (not (bobp))
  1047.          (forward-line -1))
  1048.         (skip-chars-forward " \t")
  1049.         (prog1
  1050.         (looking-at c-comment-start-regexp)
  1051.           (setq placeholder (point))))
  1052.       (goto-char placeholder)
  1053.       (if (< (current-column) comment-column)
  1054.           comment-column
  1055.         (current-column)))
  1056.      ;; CASE 4: If comment-column is 0, and nothing but space
  1057.      ;; before the comment, align it at 0 rather than 1.
  1058.      ((progn
  1059.         (goto-char opoint)
  1060.         (skip-chars-backward " \t")
  1061.         (and (= comment-column 0) (bolp)))
  1062.       0)
  1063.      ;; CASE 5: indent at comment column except leave at least one
  1064.      ;; space.
  1065.      (t (max (1+ (current-column))
  1066.          comment-column))
  1067.      )))))
  1068.  
  1069.  
  1070. ;; active regions, and auto-newline/hungry delete key
  1071. (defun c-keep-region-active ()
  1072.   ;; do whatever is necessary to keep the region active in
  1073.   ;; Lucid. ignore byte-compiler warnings you might see
  1074.   (and (boundp 'zmacs-region-stays)
  1075.        (setq zmacs-region-stays t)))
  1076.  
  1077. (defun c-update-modeline ()
  1078.   ;; set the c-auto-hungry-string for the correct designation on the modeline
  1079.   (setq c-auto-hungry-string
  1080.     (if c-auto-newline
  1081.         (if c-hungry-delete-key "/ah" "/a")
  1082.       (if c-hungry-delete-key "/h" nil)))
  1083.   ;; updates the modeline for all Emacsen
  1084.   (if (memq 'v19 c-emacs-features)
  1085.       (force-mode-line-update)
  1086.     (set-buffer-modified-p (buffer-modified-p))))
  1087.  
  1088. (defun c-calculate-state (arg prevstate)
  1089.   ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
  1090.   ;; arg is nil or zero, toggle the state. If arg is negative, turn
  1091.   ;; the state off, and if arg is positive, turn the state on
  1092.   (if (or (not arg)
  1093.       (zerop (setq arg (prefix-numeric-value arg))))
  1094.       (not prevstate)
  1095.     (> arg 0)))
  1096.  
  1097. (defun c-toggle-auto-state (arg)
  1098.   "Toggle auto-newline feature.
  1099. Optional numeric ARG, if supplied turns on auto-newline when positive,
  1100. turns it off when negative, and just toggles it when zero.
  1101.  
  1102. When the auto-newline feature is enabled (as evidenced by the `/a' or
  1103. `/ah' on the modeline after the mode name) newlines are automatically
  1104. inserted after special characters such as brace, comma, semi-colon,
  1105. and colon."
  1106.   (interactive "P")
  1107.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1108.   (c-update-modeline)
  1109.   (c-keep-region-active))
  1110.  
  1111. (defun c-toggle-hungry-state (arg)
  1112.   "Toggle hungry-delete-key feature.
  1113. Optional numeric ARG, if supplied turns on hungry-delete when positive,
  1114. turns it off when negative, and just toggles it when zero.
  1115.  
  1116. When the hungry-delete-key feature is enabled (as evidenced by the
  1117. `/h' or `/ah' on the modeline after the mode name) the delete key
  1118. gobbles all preceding whitespace in one fell swoop."
  1119.   (interactive "P")
  1120.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1121.   (c-update-modeline)
  1122.   (c-keep-region-active))
  1123.  
  1124. (defun c-toggle-auto-hungry-state (arg)
  1125.   "Toggle auto-newline and hungry-delete-key features.
  1126. Optional numeric ARG, if supplied turns on auto-newline and
  1127. hungry-delete when positive, turns them off when negative, and just
  1128. toggles them when zero.
  1129.  
  1130. See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
  1131.   (interactive "P")
  1132.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1133.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1134.   (c-update-modeline)
  1135.   (c-keep-region-active))
  1136.  
  1137.  
  1138. ;; COMMANDS
  1139. (defun c-electric-delete (arg)
  1140.   "Deletes preceding character or whitespace.
  1141. If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
  1142. \"/ah\" string on the mode line, then all preceding whitespace is
  1143. consumed.  If however an ARG is supplied, or `c-hungry-delete-key' is
  1144. nil, or point is inside a literal then the function in the variable
  1145. `c-delete-function' is called."
  1146.   (interactive "P")
  1147.   (if (or (not c-hungry-delete-key)
  1148.       arg
  1149.       (c-in-literal))
  1150.       (funcall c-delete-function (prefix-numeric-value arg))
  1151.     (let ((here (point)))
  1152.       (skip-chars-backward " \t\n")
  1153.       (if (/= (point) here)
  1154.       (delete-region (point) here)
  1155.     (funcall c-delete-function 1)
  1156.     ))))
  1157.  
  1158. (defun c-electric-pound (arg)
  1159.   "Electric pound (`#') insertion.
  1160. Inserts a `#' character specially depending on the variable
  1161. `c-electric-pound-behavior'.  If a numeric ARG is supplied, or if
  1162. point is inside a literal, nothing special happens."
  1163.   (interactive "P")
  1164.   (if (or (c-in-literal)
  1165.       arg
  1166.       (not (memq 'alignleft c-electric-pound-behavior)))
  1167.       ;; do nothing special
  1168.       (self-insert-command (prefix-numeric-value arg))
  1169.     ;; place the pound character at the left edge
  1170.     (let ((pos (- (point-max) (point)))
  1171.       (bolp (bolp)))
  1172.       (beginning-of-line)
  1173.       (delete-horizontal-space)
  1174.       (insert-char last-command-char 1)
  1175.       (and (not bolp)
  1176.        (goto-char (- (point-max) pos)))
  1177.       )))
  1178.  
  1179. (defun c-electric-brace (arg)
  1180.   "Insert a brace.
  1181.  
  1182. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  1183. or \"/ah\" string on the mode line, newlines are inserted before and
  1184. after braces based on the value of `c-hanging-braces-alist'.
  1185.  
  1186. Also, the line is re-indented unless a numeric ARG is supplied, there
  1187. are non-whitespace characters present on the line after the brace, or
  1188. the brace is inserted inside a literal."
  1189.   (interactive "P")
  1190.   (let* ((bod (c-point 'bod))
  1191.      (literal (c-in-literal bod))
  1192.      ;; we want to inhibit blinking the paren since this will be
  1193.      ;; most disruptive. we'll blink it ourselves later on
  1194.      (old-blink-paren (if (boundp 'blink-paren-function)
  1195.                   blink-paren-function
  1196.                 blink-paren-hook))
  1197.      blink-paren-function        ; emacs19
  1198.      blink-paren-hook        ; emacs18
  1199.      semantics newlines
  1200.      delete-temp-newline
  1201.      ;; shut this up
  1202.      (c-echo-semantic-information-p nil))
  1203.     (if (or literal
  1204.         arg
  1205.         (not (looking-at "[ \t]*$")))
  1206.     (c-insert-special-chars arg)
  1207.       (setq semantics (progn
  1208.             ;; only insert a newline if there is
  1209.             ;; non-whitespace behind us
  1210.             (if (save-excursion
  1211.                   (skip-chars-backward " \t")
  1212.                   (not (bolp)))
  1213.                 (progn (newline)
  1214.                    (setq delete-temp-newline t)))
  1215.             (self-insert-command (prefix-numeric-value arg))
  1216.             (c-guess-basic-semantics))
  1217.         newlines (and
  1218.               c-auto-newline
  1219.               (or (assq (car (or (assq 'defun-open semantics)
  1220.                      (assq 'defun-close semantics)
  1221.                      (assq 'class-open semantics)
  1222.                      (assq 'class-close semantics)
  1223.                      (assq 'inline-open semantics)
  1224.                      (assq 'inline-close semantics)
  1225.                      (assq 'brace-list-open semantics)
  1226.                      (assq 'brace-list-close semantics)
  1227.                      (assq 'block-open semantics)
  1228.                      (assq 'block-close semantics)
  1229.                      (assq 'substatement-open semantics)
  1230.                      ))
  1231.                 c-hanging-braces-alist)
  1232.               '(ignore before after))))
  1233.       ;; does a newline go before the open brace?
  1234.       (if (memq 'before newlines)
  1235.       ;; we leave the newline we've put in there before,
  1236.       ;; but we need to re-indent the line above
  1237.       (let ((pos (- (point-max) (point)))
  1238.         (here (point)))
  1239.         (forward-line -1)
  1240.         (c-indent-line)
  1241.         (goto-char (- (point-max) pos))
  1242.         ;; if the buffer has changed due to the indentation, we
  1243.         ;; need to recalculate semantics for the current line
  1244.         (if (/= (point) here)
  1245.         (setq semantics (c-guess-basic-semantics))))
  1246.     ;; must remove the newline we just stuck in (if we really did it)
  1247.     (and delete-temp-newline
  1248.          (delete-region (- (point) 2) (1- (point))))
  1249.     ;; since we're hanging the brace, we need to recalculate
  1250.     ;; semantics
  1251.     (setq semantics (c-guess-basic-semantics)))
  1252.       ;; now adjust the line's indentation
  1253.       (c-indent-line semantics)
  1254.       ;; Do all appropriate clean ups
  1255.       (let ((here (point))
  1256.         (pos (- (point-max) (point)))
  1257.         mbeg mend)
  1258.     ;; clean up empty defun braces
  1259.     (if (and c-auto-newline
  1260.          (memq 'empty-defun-braces c-cleanup-list)
  1261.          (= last-command-char ?\})
  1262.          (or (assq 'defun-close semantics)
  1263.              (assq 'class-close semantics)
  1264.              (assq 'inline-close semantics))
  1265.          (progn
  1266.            (forward-char -1)
  1267.            (skip-chars-backward " \t\n")
  1268.            (= (preceding-char) ?\{))
  1269.          ;; make sure matching open brace isn't in a comment
  1270.          (not (c-in-literal)))
  1271.         (delete-region (point) (1- here)))
  1272.     ;; clean up brace-else-brace
  1273.     (if (and c-auto-newline
  1274.          (memq 'brace-else-brace c-cleanup-list)
  1275.          (= last-command-char ?\{)
  1276.          (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
  1277.          (progn
  1278.            (setq mbeg (match-beginning 0)
  1279.              mend (match-end 0))
  1280.            (= mend here))
  1281.          (not (c-in-literal)))
  1282.         (progn
  1283.           (delete-region mbeg mend)
  1284.           (insert "} else {")))
  1285.     (goto-char (- (point-max) pos))
  1286.     )
  1287.       ;; does a newline go after the brace?
  1288.       (if (memq 'after (cdr-safe newlines))
  1289.       (progn
  1290.         (newline)
  1291.         (c-indent-line)))
  1292.       ;; blink the paren
  1293.       (and (= last-command-char ?\})
  1294.        old-blink-paren
  1295.        (save-excursion
  1296.          (c-backward-syntactic-ws bod)
  1297.          (if (boundp 'blink-paren-function)
  1298.          (funcall old-blink-paren)
  1299.            (run-hooks old-blink-paren))))
  1300.       )))
  1301.       
  1302. (defun c-electric-slash (arg)
  1303.   "Insert a slash character.
  1304. If slash is second of a double-slash C++ style comment introducing
  1305. construct, and we are on a comment-only-line, indent line as comment.
  1306. If numeric ARG is supplied or point is inside a literal, indentation
  1307. is inhibited."
  1308.   (interactive "P")
  1309.   (let ((indentp (and (eq major-mode 'c++-mode)
  1310.               (not arg)
  1311.               (= (preceding-char) ?/)
  1312.               (= last-command-char ?/)
  1313.               (not (c-in-literal))))
  1314.     ;; shut this up
  1315.     (c-echo-semantic-information-p nil))
  1316.     (self-insert-command (prefix-numeric-value arg))
  1317.     (if indentp
  1318.     (c-indent-line))))
  1319.  
  1320. (defun c-electric-star (arg)
  1321.   "Insert a star character.
  1322. If the star is the second character of a C style comment introducing
  1323. construct, and we are on a comment-only-line, indent line as comment.
  1324. If numeric ARG is supplied or point is inside a literal, indentation
  1325. is inhibited."
  1326.   (interactive "P")
  1327.   (let ((indentp (and (not arg)
  1328.               (or (and (memq (c-in-literal) '(c))
  1329.                    (save-excursion
  1330.                  (skip-chars-backward "* \t")
  1331.                  (bolp)))
  1332.               (= (preceding-char) ?/))))
  1333.     ;; shut this up
  1334.     (c-echo-semantic-information-p nil))
  1335.     (self-insert-command (prefix-numeric-value arg))
  1336.     (if indentp
  1337.     (c-indent-line))))
  1338.  
  1339. (defun c-electric-semi&comma (arg)
  1340.   "Insert a comma or semicolon.
  1341. When the auto-newline feature is turned on, as evidenced by the \"/a\"
  1342. or \"/ah\" string on the mode line, a newline is inserted after
  1343. semicolons, but not commas.
  1344.  
  1345. When semicolon is inserted, the line is re-indented unless a numeric
  1346. arg is supplied, point is inside a literal, or there are
  1347. non-whitespace characters on the line following the semicolon."
  1348.   (interactive "P")
  1349.   (let* ((bod (c-point 'bod))
  1350.      (literal (c-in-literal bod))
  1351.      (here (point))
  1352.      ;; shut this up
  1353.      (c-echo-semantic-information-p nil))
  1354.     (if (or literal
  1355.         arg
  1356.         (not (looking-at "[ \t]*$")))
  1357.     (c-insert-special-chars arg)
  1358.       ;; do some special stuff with the character
  1359.       (self-insert-command (prefix-numeric-value arg))
  1360.       ;; do all cleanups, reindentations, and newline insertions, but
  1361.       ;; only if c-auto-newline is turned on
  1362.       (if (not c-auto-newline) nil
  1363.     ;; clean ups
  1364.     (let ((pos (- (point-max) (point))))
  1365.       (if (and (or (and
  1366.             (= last-command-char ?,)
  1367.             (memq 'list-close-comma c-cleanup-list))
  1368.                (and
  1369.             (= last-command-char ?\;)
  1370.             (memq 'defun-close-semi c-cleanup-list)))
  1371.            (progn
  1372.              (forward-char -1)
  1373.              (skip-chars-backward " \t\n")
  1374.              (= (preceding-char) ?}))
  1375.            ;; make sure matching open brace isn't in a comment
  1376.            (not (c-in-literal)))
  1377.           (delete-region (point) here))
  1378.       (goto-char (- (point-max) pos)))
  1379.     ;; re-indent line
  1380.     (c-indent-line)
  1381.     ;; newline only after semicolon, but only if that semicolon is
  1382.     ;; not inside a parenthesis list (e.g. a for loop statement)
  1383.     (and (= last-command-char ?\;)
  1384.          (condition-case nil
  1385.          (save-excursion
  1386.            (up-list -1)
  1387.            (/= (following-char) ?\())
  1388.            (error t))
  1389.          (progn (newline) t)
  1390.          (c-indent-line))
  1391.     ))))
  1392.  
  1393. (defun c-electric-colon (arg)
  1394.   "Insert a colon.
  1395.  
  1396. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  1397. or \"/ah\" string on the mode line, newlines are inserted before and
  1398. after colons based on the value of `c-hanging-colons-alist'.
  1399.  
  1400. Also, the line is re-indented unless a numeric ARG is supplied, there
  1401. are non-whitespace characters present on the line after the colon, or
  1402. the colon is inserted inside a literal.
  1403.  
  1404. This function cleans up double colon scope operators based on the
  1405. value of `c-cleanup-list'."
  1406.   (interactive "P")
  1407.   (let* ((bod (c-point 'bod))
  1408.      (literal (c-in-literal bod))
  1409.      semantics newlines
  1410.      ;; shut this up
  1411.      (c-echo-semantic-information-p nil))
  1412.     (if (or literal
  1413.         arg
  1414.         (not (looking-at "[ \t]*$")))
  1415.     (c-insert-special-chars arg)
  1416.       ;; insert the colon, then do any specified cleanups
  1417.       (self-insert-command (prefix-numeric-value arg))
  1418.       (let ((pos (- (point-max) (point)))
  1419.         (here (point)))
  1420.     (if (and c-auto-newline
  1421.          (memq 'scope-operator c-cleanup-list)
  1422.          (= (preceding-char) ?:)
  1423.          (progn
  1424.            (forward-char -1)
  1425.            (skip-chars-backward " \t\n")
  1426.            (= (preceding-char) ?:))
  1427.          (not (c-in-literal))
  1428.          (not (= (char-after (- (point) 2)) ?:)))
  1429.         (delete-region (point) (1- here)))
  1430.     (goto-char (- (point-max) pos)))
  1431.       ;; lets do some special stuff with the colon character
  1432.       (setq semantics (c-guess-basic-semantics)
  1433.         ;; some language elements can only be determined by
  1434.         ;; checking the following line.  Lets first look for ones
  1435.         ;; that can be found when looking on the line with the
  1436.         ;; colon
  1437.         newlines
  1438.         (and c-auto-newline
  1439.          (or
  1440.           (let ((langelem (or (assq 'case-label semantics)
  1441.                       (assq 'label semantics)
  1442.                       (assq 'access-label semantics))))
  1443.             (and langelem
  1444.              (assq (car langelem) c-hanging-colons-alist)))
  1445.           (prog2
  1446.               (insert "\n")
  1447.               (let* ((semantics (c-guess-basic-semantics))
  1448.                  (langelem
  1449.                   (or (assq 'member-init-intro semantics)
  1450.                   (assq 'inher-intro semantics))))
  1451.             (and langelem
  1452.                  (assq (car langelem) c-hanging-colons-alist)))
  1453.             (delete-char -1))
  1454.           )))
  1455.       ;; indent the current line
  1456.       (c-indent-line semantics)
  1457.       ;; does a newline go before the colon?
  1458.       (if (memq 'before newlines)
  1459.       (let ((pos (- (point-max) (point))))
  1460.         (forward-char -1)
  1461.         (newline)
  1462.         (c-indent-line)
  1463.         (goto-char (- (point-max) pos))))
  1464.       ;; does a newline go after the colon?
  1465.       (if (memq 'after (cdr-safe newlines))
  1466.       (progn
  1467.         (newline)
  1468.         (c-indent-line)))
  1469.       )))
  1470.  
  1471. (defun c-read-offset (langelem)
  1472.   ;; read new offset value for LANGELEM from minibuffer. return a
  1473.   ;; legal value only
  1474.   (let ((oldoff (format "%s" (cdr-safe (assq langelem c-offsets-alist))))
  1475.     (errmsg "Offset must be +, -, an integer, or function name: ")
  1476.     (prompt "Offset: ")
  1477.     offset input)
  1478.     (while (not offset)
  1479.       (setq input (read-string prompt oldoff)
  1480.         offset (cond ((string-equal "+" input) '+)
  1481.              ((string-equal "-" input) '-)
  1482.              ((string-match "^-?[0-9]+$" input)
  1483.               (string-to-int input))
  1484.              ((c-safe (symbol-function (intern input)))
  1485.               (intern input))
  1486.              ;; error
  1487.              (t (ding)
  1488.                 (setq prompt errmsg)
  1489.                 nil))))
  1490.     offset))
  1491.  
  1492. (defun c-set-offset (symbol offset &optional add-p)
  1493.   "Change the value of a syntactic element symbol in `c-offsets-alist'.
  1494. SYMBOL is the syntactic element symbol to change and OFFSET is the new
  1495. offset for that syntactic element.  Optional ADD says to add SYMBOL to
  1496. `c-offsets-alist' if it doesn't already appear there."
  1497.   (interactive
  1498.    (let* ((langelem
  1499.        (intern (completing-read
  1500.             (concat "Syntactic symbol to change"
  1501.                 (if current-prefix-arg " or add" "")
  1502.                 ": ")
  1503.             (mapcar
  1504.              (function
  1505.               (lambda (langelem)
  1506.             (cons (format "%s" (car langelem)) nil)))
  1507.              c-offsets-alist)
  1508.             nil (not current-prefix-arg))
  1509.            ))
  1510.       (offset (c-read-offset langelem)))
  1511.      (list langelem offset current-prefix-arg)))
  1512.   ;; sanity check offset
  1513.   (or (eq offset '+)
  1514.       (eq offset '-)
  1515.       (integerp offset)
  1516.       (c-safe (symbol-function offset))
  1517.       (error "Offset is not +, -, an integer, or a function name: %s" offset))
  1518.   (let ((entry (assq symbol c-offsets-alist)))
  1519.     (if entry
  1520.     (setcdr entry offset)
  1521.       (if add-p
  1522.       (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
  1523.     (error "%s is not a valid syntactic symbol." symbol))))
  1524.   (c-keep-region-active))
  1525.  
  1526. (defun c-set-style (style &optional local)
  1527.   "Set cc-mode variables to use one of several different indentation styles.
  1528. STYLE is a string representing the desired style and optional LOCAL is
  1529. a flag which, if non-nil, means to make the style variables being
  1530. changed buffer local, instead of the default, which is to set the
  1531. global variables.  Interactively, the flag comes from the prefix
  1532. argument.  The styles are chosen from the `c-style-alist' variable."
  1533.   (interactive (list (completing-read "Use which C indentation style? "
  1534.                                       c-style-alist nil t)
  1535.              current-prefix-arg))
  1536.   (let ((vars (cdr (assoc style c-style-alist))))
  1537.     (or vars
  1538.     (error "Invalid C indentation style `%s'" style))
  1539.     ;; set all the variables
  1540.     (mapcar
  1541.      (function
  1542.       (lambda (varentry)
  1543.     (let ((var (car varentry))
  1544.           (val (cdr varentry)))
  1545.       (and local
  1546.            (make-local-variable var))
  1547.       ;; special case for c-offsets-alist
  1548.       (if (not (eq var 'c-offsets-alist))
  1549.           (set var val)
  1550.         ;; reset c-offsets-alist to the default value first
  1551.         (setq c-offsets-alist (copy-alist c-offsets-alist-default))
  1552.         ;; now set the langelems that are different
  1553.         (mapcar
  1554.          (function
  1555.           (lambda (langentry)
  1556.         (let ((langelem (car langentry))
  1557.               (offset (cdr langentry)))
  1558.           (c-set-offset langelem offset)
  1559.           )))
  1560.          val))
  1561.       )))
  1562.      vars))
  1563.   (c-keep-region-active))
  1564.  
  1565. (defun c-fill-paragraph (&optional arg)
  1566.   "Like \\[fill-paragraph] but handles C and C++ style comments.
  1567. If any of the current line is a comment or within a comment,
  1568. fill the comment or the paragraph of it that point is in,
  1569. preserving the comment indentation or line-starting decorations."
  1570.   (interactive "P")
  1571.   (let* (comment-start-place
  1572.      (first-line
  1573.       ;; Check for obvious entry to comment.
  1574.       (save-excursion
  1575.         (beginning-of-line)
  1576.         (skip-chars-forward " \t\n")
  1577.         (and (looking-at comment-start-skip)
  1578.          (setq comment-start-place (point))))))
  1579.     (if (and (eq major-mode 'c++-mode)
  1580.          (save-excursion
  1581.            (beginning-of-line)
  1582.            (looking-at ".*//")))
  1583.     (let (fill-prefix
  1584.           (paragraph-start
  1585.            ;; Lines containing just a comment start or just an end
  1586.            ;; should not be filled into paragraphs they are next to.
  1587.            (concat 
  1588.         paragraph-start
  1589.         "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  1590.           (paragraph-separate
  1591.            (concat
  1592.         paragraph-separate
  1593.         "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$")))
  1594.       (save-excursion
  1595.         (beginning-of-line)
  1596.         ;; Move up to first line of this comment.
  1597.         (while (and (not (bobp))
  1598.             (looking-at "[ \t]*//"))
  1599.           (forward-line -1))
  1600.         (if (not (looking-at ".*//"))
  1601.         (forward-line 1))
  1602.         ;; Find the comment start in this line.
  1603.         (re-search-forward "[ \t]*//[ \t]*")
  1604.         ;; Set the fill-prefix to be what all lines except the first
  1605.         ;; should start with.
  1606.         (setq fill-prefix (buffer-substring (match-beginning 0)
  1607.                         (match-end 0)))
  1608.         (save-restriction
  1609.           ;; Narrow down to just the lines of this comment.
  1610.           (narrow-to-region (c-point 'bol)
  1611.                 (save-excursion
  1612.                   (forward-line 1)
  1613.                   (while (looking-at fill-prefix)
  1614.                     (forward-line 1))
  1615.                   (point)))
  1616.           (fill-paragraph arg)
  1617.           )))
  1618.       ;; else C style comments
  1619.       (if (or first-line
  1620.           ;; t if we enter a comment between start of function and
  1621.           ;; this line.
  1622.           (eq (c-in-literal) 'c)
  1623.           ;; t if this line contains a comment starter.
  1624.           (setq first-line
  1625.             (save-excursion
  1626.               (beginning-of-line)
  1627.               (prog1
  1628.               (re-search-forward comment-start-skip
  1629.                          (save-excursion (end-of-line)
  1630.                                  (point))
  1631.                          t)
  1632.             (setq comment-start-place (point))))))
  1633.       ;; Inside a comment: fill one comment paragraph.
  1634.       (let ((fill-prefix
  1635.          ;; The prefix for each line of this paragraph
  1636.          ;; is the appropriate part of the start of this line,
  1637.          ;; up to the column at which text should be indented.
  1638.          (save-excursion
  1639.            (beginning-of-line)
  1640.            (if (looking-at "[ \t]*/\\*.*\\*/")
  1641.                (progn (re-search-forward comment-start-skip)
  1642.                   (make-string (current-column) ?\ ))
  1643.              (if first-line (forward-line 1))
  1644.  
  1645.              (let ((line-width (progn (end-of-line) (current-column))))
  1646.                (beginning-of-line)
  1647.                (prog1
  1648.                (buffer-substring
  1649.                 (point)
  1650.  
  1651.                 ;; How shall we decide where the end of the
  1652.                 ;; fill-prefix is?
  1653.                 (progn
  1654.                   (beginning-of-line)
  1655.                   (skip-chars-forward " \t*" (c-point 'eol))
  1656.                   (point)))
  1657.  
  1658.              ;; If the comment is only one line followed
  1659.              ;; by a blank line, calling move-to-column
  1660.              ;; above may have added some spaces and tabs
  1661.              ;; to the end of the line; the fill-paragraph
  1662.              ;; function will then delete it and the
  1663.              ;; newline following it, so we'll lose a
  1664.              ;; blank line when we shouldn't.  So delete
  1665.              ;; anything move-to-column added to the end
  1666.              ;; of the line.  We record the line width
  1667.              ;; instead of the position of the old line
  1668.              ;; end because move-to-column might break a
  1669.              ;; tab into spaces, and the new characters
  1670.              ;; introduced there shouldn't be deleted.
  1671.  
  1672.              ;; If you can see a better way to do this,
  1673.              ;; please make the change.  This seems very
  1674.              ;; messy to me.
  1675.              (delete-region (progn (move-to-column line-width)
  1676.                            (point))
  1677.                     (progn (end-of-line) (point))))))))
  1678.  
  1679.         (paragraph-start
  1680.          ;; Lines containing just a comment start or just an end
  1681.          ;; should not be filled into paragraphs they are next to.
  1682.          (concat 
  1683.           paragraph-start
  1684.           "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  1685.         (paragraph-separate
  1686.          (concat
  1687.           paragraph-separate
  1688.           "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  1689.         (chars-to-delete 0))
  1690.         (save-restriction
  1691.           ;; Don't fill the comment together with the code
  1692.           ;; following it.  So temporarily exclude everything
  1693.           ;; before the comment start, and everything after the
  1694.           ;; line where the comment ends.  If comment-start-place
  1695.           ;; is non-nil, the comment starter is there.  Otherwise,
  1696.           ;; point is inside the comment.
  1697.           (narrow-to-region (save-excursion
  1698.                   (if comment-start-place
  1699.                       (goto-char comment-start-place)
  1700.                     (search-backward "/*"))
  1701.                   ;; Protect text before the comment
  1702.                   ;; start by excluding it.  Add
  1703.                   ;; spaces to bring back proper
  1704.                   ;; indentation of that point.
  1705.                   (let ((column (current-column)))
  1706.                     (prog1 (point)
  1707.                       (setq chars-to-delete column)
  1708.                       (insert-char ?\  column))))
  1709.                 (save-excursion
  1710.                   (if comment-start-place
  1711.                       (goto-char (+ comment-start-place 2)))
  1712.                   (search-forward "*/" nil 'move)
  1713.                   (forward-line 1)
  1714.                   (point)))
  1715.           (fill-paragraph arg)
  1716.           (save-excursion
  1717.         ;; Delete the chars we inserted to avoid clobbering
  1718.         ;; the stuff before the comment start.
  1719.         (goto-char (point-min))
  1720.         (if (> chars-to-delete 0)
  1721.             (delete-region (point) (+ (point) chars-to-delete)))
  1722.         ;; Find the comment ender (should be on last line of
  1723.         ;; buffer, given the narrowing) and don't leave it on
  1724.         ;; its own line.
  1725.         (goto-char (point-max))
  1726.         (forward-line -1)
  1727.         (search-forward "*/" nil 'move)
  1728.         (beginning-of-line)
  1729.         (if (looking-at "[ \t]*\\*/")
  1730.             (delete-indentation)))))
  1731.     ;; Outside of comments: do ordinary filling.
  1732.     (fill-paragraph arg)))))
  1733.  
  1734. ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
  1735. ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
  1736. (defun c-forward-into-nomenclature (&optional arg)
  1737.   "Move forward to end of a nomenclature section or word.
  1738. With arg, to it arg times."
  1739.   (interactive "p")
  1740.   (let ((case-fold-search nil))
  1741.     (if (> arg 0)
  1742.     (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
  1743.       (while (and (< arg 0)
  1744.           (re-search-backward
  1745.            "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
  1746.            (point-min) 0))
  1747.     (forward-char 1)
  1748.     (setq arg (1+ arg)))))
  1749.   (c-keep-region-active))
  1750.  
  1751. (defun c-backward-into-nomenclature (&optional arg)
  1752.   "Move backward to beginning of a nomenclature section or word.
  1753. With optional ARG, move that many times.  If ARG is negative, move
  1754. forward."
  1755.   (interactive "p")
  1756.   (c-forward-into-nomenclature (- arg))
  1757.   (c-keep-region-active))
  1758.  
  1759. (defun c-scope-operator ()
  1760.   "Insert a double colon scope operator at point.
  1761. No indentation or other \"electric\" behavior is performed."
  1762.   (interactive)
  1763.   (insert "::"))
  1764.  
  1765. ;; TBD: These are from Lucid Emacs 19.9's version of c-mode.el
  1766. ;;(defun c-insert-brackets ()
  1767. ;;  (interactive)
  1768. ;;  (insert ?[)
  1769. ;;  (save-excursion
  1770. ;;    (insert ?])))
  1771.  
  1772. ;;(defun c-insert-braces ()
  1773. ;;  (interactive)
  1774. ;;  (setq last-command-char ?{)
  1775. ;;  (electric-c-brace 1)
  1776. ;;  (newline)
  1777. ;;  (c-indent-line)
  1778. ;;  (save-excursion
  1779. ;;    (newline)
  1780. ;;    (insert ?})
  1781. ;;    (c-indent-line)))
  1782.  
  1783.  
  1784. (defun c-beginning-of-statement (&optional count lim)
  1785.   "Go to the beginning of the innermost C statement.
  1786. With prefix arg, go back N - 1 statements.  If already at the
  1787. beginning of a statement then go to the beginning of the preceding
  1788. one.  If within a string or comment, or next to a comment (only
  1789. whitespace between), move by sentences instead of statements.
  1790.  
  1791. When called from a program, this function takes 2 optional args: the
  1792. prefix arg, and a buffer position limit which is the farthest back to
  1793. search."
  1794.   (interactive "p")
  1795.   (let ((here (point))
  1796.     (count (or count 1))
  1797.     (lim (or lim (c-point 'bod)))
  1798.     state)
  1799.     (save-excursion
  1800.       (goto-char lim)
  1801.       (setq state (parse-partial-sexp (point) here nil nil)))
  1802.     (if (and (interactive-p)
  1803.          (or (nth 3 state)
  1804.          (nth 4 state)
  1805.          (looking-at (concat "[ \t]*" comment-start-skip))
  1806.          (save-excursion
  1807.            (skip-chars-backward " \t")
  1808.            (goto-char (- (point) 2))
  1809.            (looking-at "\\*/"))))
  1810.     (forward-sentence (- count))
  1811.       (while (> count 0)
  1812.     (c-beginning-of-statement-1)
  1813.     (setq count (1- count)))
  1814.       (while (< count 0)
  1815.     (c-end-of-statement-1)
  1816.     (setq count (1+ count))))
  1817.     ;; its possible we've been left up-buf of lim
  1818.     (goto-char (max (point) lim))
  1819.     )
  1820.   (c-keep-region-active))
  1821.  
  1822. (defun c-end-of-statement (&optional count lim)
  1823.   "Go to the end of the innermost C statement.
  1824.  
  1825. With prefix arg, go forward N - 1 statements.  Move forward to end of
  1826. the next statement if already at end.  If within a string or comment,
  1827. move by sentences instead of statements.
  1828.  
  1829. When called from a program, this function takes 2 optional args: the
  1830. prefix arg, and a buffer position limit which is the farthest back to
  1831. search."
  1832.   (interactive "p")
  1833.   (c-beginning-of-statement (- (or count 1)) lim)
  1834.   (c-keep-region-active))
  1835.  
  1836. (defun c-beginning-of-statement-1 ()
  1837.   ;; move to the start of the current statement, or the previous
  1838.   ;; statement if already at the beginning of one.
  1839.   (let ((firstp t)
  1840.     donep literal-cache
  1841.     (last-begin (point)))
  1842.     (while (not donep)
  1843.       ;; stop at beginning of buffer
  1844.       (if (bobp) (setq donep t)
  1845.     ;; go backwards one balanced expression, but be careful of
  1846.     ;; unbalanced paren being reached
  1847.     (if (not (c-safe (progn (backward-sexp 1) t)))
  1848.         (progn
  1849.           (if firstp
  1850.           (backward-up-list 1)
  1851.         (goto-char last-begin))
  1852.           ;; skip over any unary operators, or other special
  1853.           ;; characters appearing at front of identifier
  1854.           (save-excursion
  1855.         (c-backward-syntactic-ws)
  1856.         (skip-chars-backward "-+!*&:.~")
  1857.         (if (= (preceding-char) ?\()
  1858.             (setq last-begin (point))))
  1859.           (goto-char last-begin)
  1860.           (setq donep t)))
  1861.  
  1862.     ;; see if we're in a literal. if not, then this bufpos may be
  1863.     ;; a candidate for stopping
  1864.     (cond
  1865.      ;; CASE 0: did we hit the error condition above?
  1866.      (donep)
  1867.      ;; CASE 1: are we in a literal?
  1868.      ((eq (setq literal-cache (c-in-literal)) 'pound)
  1869.       (beginning-of-line))
  1870.      ;; CASE 2: some other kind of literal?
  1871.      (literal-cache)
  1872.      ;; CASE 3: is this the first time we're checking?
  1873.      (firstp (setq firstp nil
  1874.                last-begin (point)))
  1875.      ;; CASE 4: are we looking at a conditional keyword?
  1876.      ((looking-at c-conditional-key)
  1877.       ;; are we in the middle of an else-if clause?
  1878.       (if (save-excursion
  1879.         (c-safe (forward-sexp -1))
  1880.         (looking-at "\\<else\\>[ \t]+\\<if\\>"))
  1881.           (forward-sexp -1))
  1882.       (setq last-begin (point)
  1883.         donep t))
  1884.      ;; CASE 5: have we crossed a statement barrier?
  1885.      ((let (crossedp)
  1886.         (save-excursion
  1887.           (while (and (not crossedp)
  1888.               (< (point) last-begin))
  1889.         (skip-chars-forward "^;{}" last-begin)
  1890.         (if (and (memq (following-char) '(?\; ?{ ?}))
  1891.              (not (c-in-literal)))
  1892.             (setq crossedp t
  1893.               donep t)
  1894.           (forward-char 1))))
  1895.         crossedp))
  1896.      ;; CASE 6: nothing special
  1897.      (t (setq last-begin (point)))
  1898.      )))
  1899.     (goto-char last-begin)))
  1900.  
  1901. (defun c-end-of-statement-1 ()
  1902.   (condition-case ()
  1903.       (progn
  1904.     (while (and (not (eobp))
  1905.             (let ((beg (point)))
  1906.               (forward-sexp 1)
  1907.               (let ((end (point)))
  1908.             (save-excursion
  1909.               (goto-char beg)
  1910.               (not (re-search-forward "[;{}]" end t)))))))
  1911.     (re-search-backward "[;}]")
  1912.     (forward-char 1))
  1913.     (error 
  1914.      (let ((beg (point)))
  1915.        (backward-up-list -1)
  1916.        (let ((end (point)))
  1917.      (goto-char beg)
  1918.      (search-forward ";" end 'move))))))
  1919.  
  1920.  
  1921. ;;(defun c-beginning-of-defun (count)
  1922. ;;  "Move the the COUNTth `real' beginning-of-defun.
  1923. ;;This is defined as the first declaration line of the most enclosing
  1924. ;;top level construct; i.e. class/struct, function, enum, etc.  With
  1925. ;;negative COUNT, go forward."
  1926. ;;  (interactive "p")
  1927. ;;  )
  1928. ;;
  1929. ;;(defun c-beginning-of-defun-1 ()
  1930. ;;  ;; move to the real beginning of defun. `Real' being defined as the
  1931. ;;  ;; first C/C++ declaration line of the most enclosing top level construct.
  1932. ;;  (let* ((state (c-parse-state))
  1933. ;;     (search-start (car state)))
  1934. ;;    ;; if the last thing is a cons then start searching from the end
  1935. ;;    ;; of the previous balanced sexp
  1936. ;;    (goto-char (or (car-safe search-start)
  1937. ;;           (and (numberp search-start)
  1938. ;;            search-start)
  1939. ;;           (point)))
  1940. ;;    (c-beginning-of-statement)
  1941. ;;    (if (bobp)
  1942. ;;    (c-forward-syntactic-ws))
  1943. ;;    ))
  1944. ;;
  1945. ;;(defun c-end-of-defun-1 ()
  1946. ;;  ;; move to the end of the defun.
  1947. ;;  (let* ((state (c-parse-state))
  1948. ;;     (search-start (car state))
  1949. ;;     )))
  1950. ;;
  1951.  
  1952. (defun c-up-conditional (count)
  1953.   "Move back to the containing preprocessor conditional, leaving mark behind.
  1954. A prefix argument acts as a repeat count.  With a negative argument,
  1955. move forward to the end of the containing preprocessor conditional.
  1956. When going backwards, `#elif' is treated like `#else' followed by
  1957. `#if'.  When going forwards, `#elif' is ignored."
  1958.   (interactive "p")
  1959.   (c-forward-conditional (- count) t)
  1960.   (c-keep-region-active))
  1961.  
  1962. (defun c-backward-conditional (count &optional up-flag)
  1963.   "Move back across a preprocessor conditional, leaving mark behind.
  1964. A prefix argument acts as a repeat count.  With a negative argument,
  1965. move forward across a preprocessor conditional."
  1966.   (interactive "p")
  1967.   (c-forward-conditional (- count) up-flag)
  1968.   (c-keep-region-active))
  1969.  
  1970. (defun c-forward-conditional (count &optional up-flag)
  1971.   "Move forward across a preprocessor conditional, leaving mark behind.
  1972. A prefix argument acts as a repeat count.  With a negative argument,
  1973. move backward across a preprocessor conditional."
  1974.   (interactive "p")
  1975.   (let* ((forward (> count 0))
  1976.      (increment (if forward -1 1))
  1977.      (search-function (if forward 're-search-forward 're-search-backward))
  1978.      (new))
  1979.     (save-excursion
  1980.       (while (/= count 0)
  1981.     (let ((depth (if up-flag 0 -1)) found)
  1982.       (save-excursion
  1983.         ;; Find the "next" significant line in the proper direction.
  1984.         (while (and (not found)
  1985.             ;; Rather than searching for a # sign that
  1986.             ;; comes at the beginning of a line aside from
  1987.             ;; whitespace, search first for a string
  1988.             ;; starting with # sign.  Then verify what
  1989.             ;; precedes it.  This is faster on account of
  1990.             ;; the fastmap feature of the regexp matcher.
  1991.             (funcall search-function
  1992.                  "#[ \t]*\\(if\\|elif\\|endif\\)"
  1993.                  nil t))
  1994.           (beginning-of-line)
  1995.           ;; Now verify it is really a preproc line.
  1996.           (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
  1997.           (let ((prev depth))
  1998.             ;; Update depth according to what we found.
  1999.             (beginning-of-line)
  2000.             (cond ((looking-at "[ \t]*#[ \t]*endif")
  2001.                (setq depth (+ depth increment)))
  2002.               ((looking-at "[ \t]*#[ \t]*elif")
  2003.                (if (and forward (= depth 0))
  2004.                    (setq found (point))))
  2005.               (t (setq depth (- depth increment))))
  2006.             ;; If we are trying to move across, and we find an
  2007.             ;; end before we find a beginning, get an error.
  2008.             (if (and (< prev 0) (< depth prev))
  2009.             (error (if forward
  2010.                    "No following conditional at this level"
  2011.                  "No previous conditional at this level")))
  2012.             ;; When searching forward, start from next line so
  2013.             ;; that we don't find the same line again.
  2014.             (if forward (forward-line 1))
  2015.             ;; If this line exits a level of conditional, exit
  2016.             ;; inner loop.
  2017.             (if (< depth 0)
  2018.             (setq found (point)))))))
  2019.       (or found
  2020.           (error "No containing preprocessor conditional"))
  2021.       (goto-char (setq new found)))
  2022.     (setq count (+ count increment))))
  2023.     (push-mark)
  2024.     (goto-char new))
  2025.   (c-keep-region-active))
  2026.  
  2027.  
  2028. ;; commands to indent lines, regions, defuns, and expressions
  2029. (defun c-indent-command (&optional whole-exp)
  2030.   "Indent current line as C++ code, or in some cases insert a tab character.
  2031.  
  2032. If `c-tab-always-indent' is t, always just indent the current line.
  2033. If nil, indent the current line only if point is at the left margin or
  2034. in the line's indentation; otherwise insert a tab.  If other than nil
  2035. or t, then tab is inserted only within literals (comments and strings)
  2036. and inside preprocessor directives, but line is always reindented.
  2037.  
  2038. A numeric argument, regardless of its value, means indent rigidly all
  2039. the lines of the expression starting after point so that this line
  2040. becomes properly indented.  The relative indentation among the lines
  2041. of the expression are preserved."
  2042.   (interactive "P")
  2043.   (let ((bod (c-point 'bod)))
  2044.     (if whole-exp
  2045.     ;; If arg, always indent this line as C
  2046.     ;; and shift remaining lines of expression the same amount.
  2047.     (let ((shift-amt (c-indent-line))
  2048.           beg end)
  2049.       (save-excursion
  2050.         (if (eq c-tab-always-indent t)
  2051.         (beginning-of-line))
  2052.         (setq beg (point))
  2053.         (forward-sexp 1)
  2054.         (setq end (point))
  2055.         (goto-char beg)
  2056.         (forward-line 1)
  2057.         (setq beg (point)))
  2058.       (if (> end beg)
  2059.           (indent-code-rigidly beg end shift-amt "#")))
  2060.       ;; No arg supplied, use c-tab-always-indent to determine
  2061.       ;; behavior
  2062.       (cond
  2063.        ;; CASE 1: indent when at column zero or in lines indentation,
  2064.        ;; otherwise insert a tab
  2065.        ((not c-tab-always-indent)
  2066.     (if (save-excursion
  2067.           (skip-chars-backward " \t")
  2068.           (not (bolp)))
  2069.         (insert-tab)
  2070.       (c-indent-line)))
  2071.        ;; CASE 2: just indent the line
  2072.        ((eq c-tab-always-indent t)
  2073.     (c-indent-line))
  2074.        ;; CASE 3: if in a literal, insert a tab, but always indent the
  2075.        ;; line
  2076.        (t
  2077.     (if (c-in-literal bod)
  2078.         (insert-tab))
  2079.     (c-indent-line)
  2080.     )))))
  2081.  
  2082. (defun c-indent-exp (&optional shutup-p)
  2083.   "Indent each line in balanced expression following point.
  2084. Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
  2085.   (interactive "P")
  2086.   (let ((here (point))
  2087.     end)
  2088.     (unwind-protect
  2089.     (let ((c-echo-semantic-information-p nil) ;keep quiet for speed
  2090.           (start (progn
  2091.                ;; try to be smarter about finding the range of
  2092.                ;; lines to indent. skip all following
  2093.                ;; whitespace. failing that, try to find any
  2094.                ;; opening brace on the current line
  2095.                (skip-chars-forward " \t\n")
  2096.                (if (memq (following-char) '(?\( ?\[ ?\{))
  2097.                (point)
  2098.              (let ((state (parse-partial-sexp (point)
  2099.                               (c-point 'eol))))
  2100.                (and (nth 1 state)
  2101.                 (goto-char (nth 1 state))
  2102.                 (memq (following-char) '(?\( ?\[ ?\{))
  2103.                 (point)))))))
  2104.       ;; find balanced expression end
  2105.       (setq end (and (c-safe (progn (forward-sexp 1) t))
  2106.              (point-marker)))
  2107.       ;; sanity check
  2108.       (and (not start)
  2109.            (not shutup-p)
  2110.            (error "Cannot find start of balanced expression to indent."))
  2111.       (and (not end)
  2112.            (not shutup-p)
  2113.            (error "Cannot find end of balanced expression to indent."))
  2114.       (or shutup-p
  2115.           (message "indenting expression... (this may take a while)"))
  2116.       (goto-char start)
  2117.       (beginning-of-line)
  2118.       (while (< (point) end)
  2119.         (if (not (looking-at "[ \t]*$"))
  2120.         (c-indent-line))
  2121.         (forward-line 1)))
  2122.       ;; make sure marker is deleted
  2123.       (and end
  2124.        (set-marker end nil))
  2125.       (or shutup-p
  2126.       (message "indenting expression... done."))
  2127.       (goto-char here))))
  2128.  
  2129. (defun c-indent-defun ()
  2130.   "Re-indents the current top-level function def, struct or class declaration."
  2131.   (interactive)
  2132.   (let ((here (point-marker))
  2133.     (c-echo-semantic-information-p nil))
  2134.     (beginning-of-defun)
  2135.     ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
  2136.     ;; the open brace. I consider this an Emacs bug.
  2137.     (and (boundp 'defun-prompt-regexp)
  2138.      defun-prompt-regexp
  2139.      (looking-at defun-prompt-regexp)
  2140.      (goto-char (match-end 0)))
  2141.     ;; catch all errors in c-indent-exp so we can 1. give more
  2142.     ;; meaningful error message, and 2. restore point
  2143.     (unwind-protect
  2144.     (condition-case ()
  2145.         (c-indent-exp)
  2146.       (buffer-read-only (error))
  2147.       (error
  2148.        (error "Cannot find closed top-level defun containing point.")))
  2149.       (goto-char here)
  2150.       (set-marker here nil))))
  2151.  
  2152. (defun c-indent-region (start end)
  2153.   ;; Indent every line whose first char is between START and END inclusive.
  2154.   (message "indenting region... (this may take a while)")
  2155.   (save-excursion
  2156.     (goto-char start)
  2157.     ;; Advance to first nonblank line.
  2158.     (skip-chars-forward " \t\n")
  2159.     (beginning-of-line)
  2160.     (let (endmark)
  2161.       (unwind-protect
  2162.       (let ((c-tab-always-indent t)
  2163.         ;; shut up any echo msgs on indiv lines
  2164.         (c-echo-semantic-information-p nil))
  2165.         (setq endmark (copy-marker end))
  2166.         (while (and (bolp)
  2167.             (not (eobp))
  2168.             (< (point) endmark))
  2169.           ;; Indent one line as with TAB.
  2170.           (let (nextline sexpend sexpbeg)
  2171.         ;; skip blank lines
  2172.         (skip-chars-forward " \t\n")
  2173.         (beginning-of-line)
  2174.         ;; indent the current line
  2175.         (c-indent-line)
  2176.         (if (save-excursion
  2177.               (beginning-of-line)
  2178.               (looking-at "[ \t]*#"))
  2179.             (forward-line 1)
  2180.           (save-excursion
  2181.             ;; Find beginning of following line.
  2182.             (setq nextline (c-point 'bonl))
  2183.             ;; Find first beginning-of-sexp for sexp extending past
  2184.             ;; this line.
  2185.             (beginning-of-line)
  2186.             (while (< (point) nextline)
  2187.               (condition-case nil
  2188.               (progn
  2189.                 (forward-sexp 1)
  2190.                 (setq sexpend (point)))
  2191.             (error (setq sexpend nil)
  2192.                    (goto-char nextline)))
  2193.               (c-forward-syntactic-ws))
  2194.             (if sexpend
  2195.             (progn 
  2196.               ;; make sure the sexp we found really starts on the
  2197.               ;; current line and extends past it
  2198.               (goto-char sexpend)
  2199.               (setq sexpend (point-marker))
  2200.               (backward-sexp 1)
  2201.               (setq sexpbeg (point)))))
  2202.           ;; check to see if the next line starts a
  2203.           ;; comment-only line
  2204.           (save-excursion
  2205.             (forward-line 1)
  2206.             (skip-chars-forward " \t")
  2207.             (if (looking-at c-comment-start-regexp)
  2208.             (setq sexpbeg (c-point 'bol))))
  2209.           ;; If that sexp ends within the region, indent it all at
  2210.           ;; once, fast.
  2211.           (condition-case nil
  2212.               (if (and sexpend
  2213.                    (> sexpend nextline)
  2214.                    (<= sexpend endmark))
  2215.               (progn
  2216.                 (goto-char sexpbeg)
  2217.                 (c-indent-exp 'shutup)
  2218.                 (goto-char sexpend)))
  2219.             (error
  2220.              (goto-char sexpbeg)
  2221.              (c-indent-line)))
  2222.           ;; Move to following line and try again.
  2223.           (and sexpend
  2224.                (markerp sexpend)
  2225.                (set-marker sexpend nil))
  2226.           (forward-line 1)))))
  2227.     (set-marker endmark nil))))
  2228.   (message "indenting region... done."))
  2229.  
  2230. (defun c-mark-function ()
  2231.   "Put mark at end of a C/C++ defun, point at beginning."
  2232.   (interactive)
  2233.   (let ((here (point))
  2234.     (bod  (c-point 'bod))
  2235.     ;; there should be a c-point position for 'eod and 'bod2
  2236.     (eod  (save-excursion (end-of-defun) (point)))
  2237.     (bod2 (save-excursion (beginning-of-defun 2) (point))))
  2238.   (push-mark here)
  2239.   (push-mark eod nil t)
  2240.   (goto-char bod2)
  2241.   (end-of-defun)
  2242.   (if (>= (point) bod)
  2243.       (goto-char bod2))))
  2244.  
  2245.  
  2246. ;; Skipping of "syntactic whitespace" for Emacs 19.  Syntactic
  2247. ;; whitespace is defined as lexical whitespace, C and C++ style
  2248. ;; comments, and preprocessor directives.  Search no farther back or
  2249. ;; forward than optional LIM.  If LIM is omitted, `beginning-of-defun'
  2250. ;; is used for backward skipping, point-max is used for forward
  2251. ;; skipping.  Note that Emacs 18 support has been moved to cc-mode-18.el.
  2252.  
  2253. (defun c-forward-syntactic-ws (&optional lim)
  2254.   ;; Forward skip of syntactic whitespace for Emacs 19.
  2255.   (save-restriction
  2256.     (let* ((lim (or lim (point-max)))
  2257.        (here lim)
  2258.        (hugenum (point-max)))
  2259.       (narrow-to-region lim (point))
  2260.       (while (/= here (point))
  2261.     (setq here (point))
  2262.     (forward-comment hugenum)
  2263.     ;; skip preprocessor directives
  2264.     (if (and (= (following-char) ?#)
  2265.          (= (c-point 'boi) (point)))
  2266.         (end-of-line)
  2267.       )))))
  2268.  
  2269. (defun c-backward-syntactic-ws (&optional lim)
  2270.   ;; Backward skip over syntactic whitespace for Emacs 19.
  2271.   (save-restriction
  2272.     (let* ((lim (or lim (c-point 'bod)))
  2273.        (here lim)
  2274.        (hugenum (- (point-max))))
  2275.       (if (< lim (point))
  2276.       (progn
  2277.         (narrow-to-region lim (point))
  2278.         (while (/= here (point))
  2279.           (setq here (point))
  2280.           (forward-comment hugenum)
  2281.           (if (eq (c-in-literal lim) 'pound)
  2282.           (beginning-of-line))
  2283.           )))
  2284.       )))
  2285.  
  2286.  
  2287. ;; Return `c' if in a C-style comment, `c++' if in a C++ style
  2288. ;; comment, `string' if in a string literal, `pound' if on a
  2289. ;; preprocessor line, or nil if not in a comment at all.  Optional LIM
  2290. ;; is used as the backward limit of the search.  If omitted, or nil,
  2291. ;; `beginning-of-defun' is used."
  2292.  
  2293. ;; This is for all v19 Emacsen supporting either 1-bit or 8-bit syntax
  2294. (defun c-in-literal (&optional lim)
  2295.   ;; Determine if point is in a C++ literal
  2296.   (save-excursion
  2297.     (let* ((lim (or lim (c-point 'bod)))
  2298.        (here (point))
  2299.        (state (parse-partial-sexp lim (point))))
  2300.       (cond
  2301.        ((nth 3 state) 'string)
  2302.        ((nth 4 state) (if (nth 7 state) 'c++ 'c))
  2303.        ((progn
  2304.       (goto-char here)
  2305.       (beginning-of-line)
  2306.       (looking-at "[ \t]*#"))
  2307.     'pound)
  2308.        (t nil)))))
  2309.  
  2310. ;; utilities for moving and querying around semantic elements
  2311. (defun c-parse-state ()
  2312.   ;; Finds and records all open parens between some important point
  2313.   ;; earlier in the file and point.
  2314.   (let* (at-bob
  2315.      (pos (save-excursion
  2316.         ;; go back 2 bods, but ignore any bogus positions
  2317.         ;; returned by beginning-of-defun (i.e. open paren in
  2318.         ;; column zero)
  2319.         (let ((cnt 0))
  2320.           (while (and (not at-bob) (< cnt 2))
  2321.             (beginning-of-defun)
  2322.             (if (= (following-char) ?\{)
  2323.             (setq cnt (1+ cnt)))
  2324.             (if (bobp)
  2325.             (setq at-bob t))))
  2326.         (point)))
  2327.      (here (save-excursion
  2328.          ;;(skip-chars-forward " \t}")
  2329.          (point)))
  2330.      (last-bod pos) (last-pos pos) state sexp-end)
  2331.     ;; cache last bod position
  2332.     (while (catch 'backup-bod
  2333.          (setq state nil)
  2334.          (while (and pos (< pos here))
  2335.            (setq last-pos pos)
  2336.            (if (and (setq pos (c-safe (scan-lists pos 1 -1)))
  2337.             (<= pos here))
  2338.            (progn
  2339.              (setq sexp-end (c-safe (scan-sexps (1- pos) 1)))
  2340.              (if (and sexp-end
  2341.                   (<= sexp-end here))
  2342.              ;; we want to record both the start and end
  2343.              ;; of this sexp, but we only want to record
  2344.              ;; the last-most of any of them before here
  2345.              (progn
  2346.                (if (= (char-after (1- pos)) ?\{)
  2347.                    (setq state (cons (cons (1- pos) sexp-end)
  2348.                          (if (consp (car state))
  2349.                              (cdr state)
  2350.                            state))))
  2351.                (setq pos sexp-end))
  2352.                ;; we're contained in this sexp so put pos on
  2353.                ;; front of list
  2354.                (setq state (cons (1- pos) state))))
  2355.          ;; something bad happened. check to see if we crossed
  2356.          ;; an unbalanced close paren. if so, we didn't really
  2357.          ;; find the right `important bufpos' so lets back up
  2358.          ;; and try again
  2359.          (if (and (not pos) (not at-bob)
  2360.               (c-safe (scan-lists last-pos 1 1)))
  2361.              (save-excursion
  2362.                (let (donep)
  2363.              (goto-char last-bod)
  2364.              (while (and (not donep) (not at-bob))
  2365.                (beginning-of-defun)
  2366.                (if (= (following-char) ?\{)
  2367.                    (setq last-bod (point)
  2368.                      donep t))
  2369.                (setq at-bob (bobp)))
  2370.              (setq pos (point))
  2371.              (throw 'backup-bod t))))
  2372.          ))
  2373.          nil))
  2374.     state))
  2375.  
  2376. (defun c-beginning-of-inheritance-list (&optional lim)
  2377.   ;; Go to the first non-whitespace after the colon that starts a
  2378.   ;; multiple inheritance introduction.  Optional LIM is the farthest
  2379.   ;; back we should search.
  2380.   (let ((lim (or lim (c-point 'bod)))
  2381.     (placeholder (progn
  2382.                (back-to-indentation)
  2383.                (point))))
  2384.     (c-backward-syntactic-ws lim)
  2385.     (while (and (> (point) lim)
  2386.         (memq (preceding-char) '(?, ?:))
  2387.         (progn
  2388.           (beginning-of-line)
  2389.           (setq placeholder (point))
  2390.           (skip-chars-forward " \t")
  2391.           (not (looking-at c-class-key))
  2392.           ))
  2393.       (c-backward-syntactic-ws lim))
  2394.     (goto-char placeholder)
  2395.     (skip-chars-forward "^:" (c-point 'eol))))
  2396.  
  2397. (defun c-beginning-of-macro (&optional lim)
  2398.   ;; Go to the beginning of the macro. Right now we don't support
  2399.   ;; multi-line macros too well
  2400.   (back-to-indentation))
  2401.  
  2402. (defun c-just-after-func-arglist-p (&optional containing)
  2403.   ;; Return t if we are between a function's argument list closing
  2404.   ;; paren and its opening brace.  Note that the list close brace
  2405.   ;; could be followed by a "const" specifier or a member init hanging
  2406.   ;; colon.  Optional CONTAINING is position of containing s-exp open
  2407.   ;; brace.  If not supplied, point is used as search start.
  2408.   (save-excursion
  2409.     (c-backward-syntactic-ws)
  2410.     (let ((checkpoint (or containing (point))))
  2411.       (goto-char checkpoint)
  2412.       ;; could be looking at const specifier
  2413.       (if (and (= (preceding-char) ?t)
  2414.            (forward-word -1)
  2415.            (looking-at "\\<const\\>"))
  2416.       (c-backward-syntactic-ws)
  2417.     ;; otherwise, we could be looking at a hanging member init
  2418.     ;; colon
  2419.     (goto-char checkpoint)
  2420.     (if (and (= (preceding-char) ?:)
  2421.          (progn
  2422.            (forward-char -1)
  2423.            (c-backward-syntactic-ws)
  2424.            (looking-at "\\s *:\\([^:]+\\|$\\)")))
  2425.         nil
  2426.       (goto-char checkpoint))
  2427.     )
  2428.       (= (preceding-char) ?\))
  2429.       )))
  2430.  
  2431. ;; defuns to look backwards for things
  2432. (defun c-backward-to-start-of-do (&optional lim)
  2433.   ;; Move to the start of the last "unbalanced" do expression.
  2434.   ;; Optional LIM is the farthest back to search.
  2435.   (let ((do-level 1)
  2436.     (case-fold-search nil)
  2437.     (lim (or lim (c-point 'bod))))
  2438.     (while (not (zerop do-level))
  2439.       ;; we protect this call because trying to execute this when the
  2440.       ;; while is not associated with a do will throw an error
  2441.       (condition-case nil
  2442.       (progn
  2443.         (backward-sexp 1)
  2444.         (cond
  2445.          ((memq (c-in-literal lim) '(c c++)))
  2446.          ((looking-at "while\\b[^_]")
  2447.           (setq do-level (1+ do-level)))
  2448.          ((looking-at "do\\b[^_]")
  2449.           (setq do-level (1- do-level)))
  2450.          ((< (point) lim)
  2451.           (setq do-level 0)
  2452.           (goto-char lim))))
  2453.     (error
  2454.      (goto-char lim)
  2455.      (setq do-level 0))))))
  2456.  
  2457. (defun c-backward-to-start-of-if (&optional lim)
  2458.   ;; Move to the start of the last "unbalanced" if and return t.  If
  2459.   ;; none is found, and we are looking at an if clause, nil is
  2460.   ;; returned.  If none is found and we are looking at an else clause,
  2461.   ;; an error is thrown.
  2462.   (let ((if-level 1)
  2463.     (case-fold-search nil)
  2464.     (lim (or lim (c-point 'bod)))
  2465.     (at-if (looking-at "if\\b[^_]")))
  2466.     (catch 'orphan-if
  2467.       (while (and (not (bobp))
  2468.           (not (zerop if-level)))
  2469.     (c-backward-syntactic-ws)
  2470.     (condition-case nil
  2471.         (backward-sexp 1)
  2472.       (error
  2473.        (if at-if
  2474.            (throw 'orphan-if nil)
  2475.          (error "Orphaned `else' clause encountered."))))
  2476.     (cond
  2477.      ((looking-at "else\\b[^_]")
  2478.       (setq if-level (1+ if-level)))
  2479.      ((looking-at "if\\b[^_]")
  2480.       ;; check for else if... skip over
  2481.       (let ((here (point)))
  2482.         (c-safe (forward-sexp -1))
  2483.         (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  2484.         nil
  2485.           (setq if-level (1- if-level))
  2486.           (goto-char here))))
  2487.      ((< (point) lim)
  2488.       (setq if-level 0)
  2489.       (goto-char lim))
  2490.      ))
  2491.       t)))
  2492.  
  2493. (defun c-skip-conditional ()
  2494.   ;; skip forward over conditional at point, including any predicate
  2495.   ;; statements in parentheses. No error checking is performed.
  2496.   (forward-sexp
  2497.    ;; else if()
  2498.    (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  2499.        3
  2500.      ;; do and else aren't followed by parens
  2501.      (if (looking-at "\\<\\(do\\|else\\)\\>")
  2502.      1 2))))
  2503.  
  2504. (defun c-search-uplist-for-classkey (brace-state)
  2505.   ;; search for the containing class, returning a 2 element vector if
  2506.   ;; found. aref 0 contains the bufpos of the class key, and aref 1
  2507.   ;; contains the bufpos of the open brace.
  2508.   (if (null brace-state)
  2509.       ;; no brace-state means we cannot be inside a class
  2510.       nil
  2511.     (let ((carcache (car brace-state))
  2512.       search-start search-end)
  2513.       (if (consp carcache)
  2514.       ;; a cons cell in the first element means that there is some
  2515.       ;; balanced sexp before the current bufpos. this we can
  2516.       ;; ignore. the nth 1 and nth 2 elements define for us the
  2517.       ;; search boundaries
  2518.       (setq search-start (nth 2 brace-state)
  2519.         search-end (nth 1 brace-state))
  2520.     ;; if the car was not a cons cell then nth 0 and nth 1 define
  2521.     ;; for us the search boundaries
  2522.     (setq search-start (nth 1 brace-state)
  2523.           search-end (nth 0 brace-state)))
  2524.       ;; if search-end is nil we are definitely not in a class
  2525.       (if (not search-end)
  2526.       nil
  2527.     ;; search-end cannot be a cons cell
  2528.     (and (consp search-end)
  2529.          (error "consp search-end: %s" search-end))
  2530.     ;; now, we need to look more closely at search-start.  if
  2531.     ;; search-start is nil, then our start boundary is really
  2532.     ;; point-min.
  2533.     (if (not search-start)
  2534.         (setq search-start (point-min))
  2535.       ;; if search-start is a cons cell, then we can start
  2536.       ;; searching from the end of the balanced sexp just ahead of
  2537.       ;; us
  2538.       (if (consp search-start)
  2539.           (setq search-start (cdr search-start))))
  2540.     ;; now we can do a quick regexp search from search-start to
  2541.     ;; search-end and see if we can find a class key.  watch for
  2542.     ;; class like strings in literals
  2543.     (save-excursion
  2544.       (save-restriction
  2545.         (goto-char search-start)
  2546.         (let (foundp class match-end)
  2547.           (while (and (not foundp)
  2548.               (save-restriction
  2549.                 (c-forward-syntactic-ws)
  2550.                 ;; see c-class-key comments for why we
  2551.                 ;; need to do this.
  2552.                 (widen)
  2553.                 (narrow-to-region (point) search-end)
  2554.                 (re-search-forward c-class-key search-end t)))
  2555.         (setq class (match-beginning 0)
  2556.               match-end (match-end 0))
  2557.         (if (not (c-in-literal search-start))
  2558.             (progn
  2559.               (goto-char class)
  2560.               (skip-chars-forward " \t\n")
  2561.               (setq foundp (vector (c-point 'boi) search-end))
  2562.               ;; make sure there's no semi-colon or equal sign
  2563.               ;; between class and brace. Otherwise, we found
  2564.               ;; a forward declaration or a struct init.
  2565.               (skip-chars-forward "^;=,)" search-end)
  2566.               (if (/= (point) search-end)
  2567.               (progn
  2568.                 (setq foundp nil)
  2569.                 (goto-char match-end))
  2570.             ;; make sure we aren't looking at the `class'
  2571.             ;; keyword inside a template arg list
  2572.             (goto-char class)
  2573.             (skip-chars-backward " \t\n")
  2574.             (if (= (preceding-char) ?<)
  2575.                 (progn
  2576.                   (setq foundp nil)
  2577.                   (skip-chars-forward "^>" search-end))))
  2578.               )))
  2579.           foundp))
  2580.       )))))
  2581.  
  2582. (defun c-inside-bracelist-p (containing-sexp)
  2583.   ;; return the buffer position of the beginning of the brace list
  2584.   ;; statement if we're inside a brace list, otherwise return nil.
  2585.   ;; CONTAINING-SEXP is the buffer pos of the innermost containing
  2586.   ;; paren
  2587.   (let (donep bufpos)
  2588.     (save-excursion
  2589.       (or
  2590.        ;; this will pick up enum lists
  2591.        (progn (goto-char containing-sexp)
  2592.           (c-beginning-of-statement)
  2593.           ;; c-b-o-s could have left us at point-min
  2594.           (and (bobp)
  2595.            (c-forward-syntactic-ws))
  2596.           (setq bufpos (point))
  2597.           (and (< bufpos containing-sexp)
  2598.            (looking-at "\\(typedef[ \t]+\\)?enum[ \t\n]+")
  2599.            (save-excursion
  2600.              (skip-chars-forward "^;" containing-sexp)
  2601.              (= (point) containing-sexp))))
  2602.        ;; this will pick up array/aggregate init lists, even if they
  2603.        ;; are nested
  2604.        (progn (goto-char containing-sexp)
  2605.           (while (not donep)
  2606.         (c-backward-syntactic-ws)
  2607.         (cond
  2608.          ;; CASE 1: we've hit the beginning of the aggregate list
  2609.          ((= (preceding-char) ?=)
  2610.           (c-beginning-of-statement)
  2611.           (setq donep t
  2612.             bufpos (point)))
  2613.          ;; CASE 2: maybe we're in a nested aggregate?
  2614.          ((= (preceding-char) ?{)
  2615.           (c-safe (forward-char -1)))
  2616.          ;; CASE 3: in a nested list, after the first one
  2617.          ;; perhaps?
  2618.          ((and (= (preceding-char) ?,)
  2619.                (= (char-after (- (point) 2)) ?}))
  2620.           (forward-char -1)
  2621.           (backward-sexp 1))
  2622.          ;; CASE 4: nope, we're done
  2623.          (t (setq donep t
  2624.               bufpos nil))
  2625.          )))
  2626.        ))
  2627.     bufpos))
  2628.  
  2629.  
  2630. ;; defuns for calculating the semantic state and indenting a single
  2631. ;; line of C/C++ code
  2632. (defmacro c-add-semantics (symbol &optional relpos)
  2633.   ;; a simple macro to append the semantics in symbol to the semantics
  2634.   ;; list.  try to increase performance by using this macro
  2635.   (` (setq semantics (cons (cons (, symbol) (, relpos)) semantics))))
  2636.  
  2637. (defun c-enclosing-brace (state)
  2638.   ;; return the bufpos of the most enclosing brace that hasn't been
  2639.   ;; narrowed out by any enclosing class, or nil if none was found
  2640.   (let (enclosingp)
  2641.     (while (and state (not enclosingp))
  2642.       (setq enclosingp (car state)
  2643.         state (cdr state))
  2644.       (if (consp enclosingp)
  2645.       (setq enclosingp nil)
  2646.     (if (> (point-min) enclosingp)
  2647.         (setq enclosingp nil))
  2648.     (setq state nil)))
  2649.     enclosingp))
  2650.  
  2651. (defun c-narrow-out-enclosing-class (state lim)
  2652.   ;; narrow the buffer so that the enclosing class is hidden
  2653.   (let (inclass-p)
  2654.     (and state
  2655.      (setq inclass-p (c-search-uplist-for-classkey state))
  2656.      (narrow-to-region
  2657.       (progn
  2658.         (goto-char (1+ (aref inclass-p 1)))
  2659.         (skip-chars-forward " \t\n" lim)
  2660.         ;; if point is now left of the class opening brace, we're
  2661.         ;; hosed, so try a different tact
  2662.         (if (<= (c-point 'bol) (aref inclass-p 1))
  2663.         (progn
  2664.           (goto-char (1+ (aref inclass-p 1)))
  2665.           (c-forward-syntactic-ws lim)))
  2666.         (c-point 'bol))
  2667.       ;; end point is the end of the current line
  2668.       (progn
  2669.         (goto-char lim)
  2670.         (c-point 'eol))))
  2671.     ;; return the class vector
  2672.     inclass-p))
  2673.  
  2674. (defun c-guess-basic-semantics ()
  2675.   ;; guess the semantic description of the current line of C++ code.
  2676.   (save-excursion
  2677.     (save-restriction
  2678.       (beginning-of-line)
  2679.       (let* ((indent-point (point))
  2680.          (case-fold-search nil)
  2681.          (state (c-parse-state))
  2682.          literal containing-sexp char-before-ip char-after-ip lim
  2683.          semantics placeholder
  2684.          ;; narrow out any enclosing class
  2685.          (inclass-p (c-narrow-out-enclosing-class state indent-point))
  2686.          )
  2687.  
  2688.     ;; get the buffer position of the most nested opening brace,
  2689.     ;; if there is one, and it hasn't been narrowed out
  2690.     (save-excursion
  2691.       (goto-char indent-point)
  2692.       (skip-chars-forward " \t}")
  2693.       (skip-chars-backward " \t")
  2694.       (while (and state (not containing-sexp))
  2695.         (setq containing-sexp (car state)
  2696.           state (cdr state))
  2697.         (if (consp containing-sexp)
  2698.         ;; if cdr == point, then containing sexp is the brace
  2699.         ;; that opens the sexp we close
  2700.         (if (= (cdr containing-sexp) (point))
  2701.             (setq containing-sexp (car containing-sexp))
  2702.           ;; otherwise, ignore this element
  2703.           (setq containing-sexp nil))
  2704.           ;; ignore the bufpos if its been narrowed out by the
  2705.           ;; containing class
  2706.           (if (<= containing-sexp (point-min))
  2707.           (setq containing-sexp nil)))))
  2708.  
  2709.     ;; set the limit on the farthest back we need to search
  2710.     (setq lim (or containing-sexp (point-min)))
  2711.  
  2712.     ;; cache char before and after indent point, and move point to
  2713.     ;; the most likely position to perform the majority of tests
  2714.     (goto-char indent-point)
  2715.     (skip-chars-forward " \t")
  2716.     (setq char-after-ip (following-char))
  2717.     (c-backward-syntactic-ws lim)
  2718.     (setq char-before-ip (preceding-char))
  2719.     (goto-char indent-point)
  2720.     (skip-chars-forward " \t")
  2721.  
  2722.     ;; are we in a literal?
  2723.     (setq literal (c-in-literal lim))
  2724.  
  2725.     ;; now figure out semantic qualities of the current line
  2726.     (cond
  2727.      ;; CASE 1: in a string.
  2728.      ((memq literal '(string))
  2729.       (c-add-semantics 'string (c-point 'bopl)))
  2730.      ;; CASE 2: in a C or C++ style comment.
  2731.      ((memq literal '(c c++))
  2732.       ;; we need to catch multi-paragraph C comments
  2733.       (while (and (zerop (forward-line -1))
  2734.               (looking-at "^[ \t]*$")))
  2735.       (c-add-semantics literal (c-point 'bol)))
  2736.      ;; CASE 3: in a cpp preprocessor
  2737.      ((eq literal 'pound)
  2738.       (c-beginning-of-macro lim)
  2739.       (c-add-semantics 'cpp-macro (c-point 'boi)))
  2740.      ;; CASE 4: Line is at top level.
  2741.      ((null containing-sexp)
  2742.       (cond
  2743.        ;; CASE 4A: we are looking at a defun, class, or
  2744.        ;; inline-inclass method opening brace
  2745.        ((= char-after-ip ?{)
  2746.         (cond
  2747.          ;; CASE 4A.1: we are looking at a class opening brace
  2748.          ((save-excursion
  2749.         (goto-char indent-point)
  2750.         (skip-chars-forward " \t{")
  2751.         (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  2752.           (and decl
  2753.                (setq placeholder (aref decl 0)))
  2754.           ))
  2755.           (c-add-semantics 'class-open placeholder))
  2756.          ;; CASE 4A.2: brace list open
  2757.          ((save-excursion
  2758.         (c-beginning-of-statement nil lim)
  2759.         ;; c-b-o-s could have left us at point-min
  2760.         (and (bobp)
  2761.              (c-forward-syntactic-ws indent-point))
  2762.         (setq placeholder (point))
  2763.         (and (or (looking-at "enum[ \t\n]+")
  2764.              (= char-before-ip ?=))
  2765.              (save-excursion
  2766.                (skip-chars-forward "^;" indent-point)
  2767.                (/= (following-char) ?\;))))
  2768.           (c-add-semantics 'brace-list-open placeholder))
  2769.          ;; CASE 4A.3: inline defun open
  2770.          (inclass-p
  2771.           (c-add-semantics 'inline-open (aref inclass-p 0)))
  2772.          ;; CASE 4A.4: ordinary defun open
  2773.          (t
  2774.           (goto-char placeholder)
  2775.           (c-add-semantics 'defun-open (c-point 'bol))
  2776.           )))
  2777.        ;; CASE 4B: first K&R arg decl or member init
  2778.        ((c-just-after-func-arglist-p)
  2779.         (cond
  2780.          ;; CASE 4B.1: a member init
  2781.          ((or (= char-before-ip ?:)
  2782.           (= char-after-ip ?:))
  2783.           ;; this line should be indented relative to the beginning
  2784.           ;; of indentation for the topmost-intro line that contains
  2785.           ;; the prototype's open paren
  2786.           ;; TBD: is the following redundant?
  2787.           (if (= char-before-ip ?:)
  2788.           (forward-char -1))
  2789.           (c-backward-syntactic-ws lim)
  2790.           ;; TBD: is the preceding redundant?
  2791.           (if (= (preceding-char) ?:)
  2792.           (progn (forward-char -1)
  2793.              (c-backward-syntactic-ws lim)))
  2794.           (if (= (preceding-char) ?\))
  2795.           (backward-sexp 1))
  2796.           (c-add-semantics 'member-init-intro (c-point 'boi))
  2797.           ;; we don't need to add any class offset since this
  2798.           ;; should be relative to the ctor's indentation
  2799.           )
  2800.          ;; CASE 4B.2: nether region after a C++ func decl
  2801.          ((eq major-mode 'c++-mode)
  2802.           (c-add-semantics 'c++-funcdecl-cont (c-point 'boi))
  2803.           (and inclass-p (c-add-semantics 'inclass (aref inclass-p 0))))
  2804.          ;; CASE 4B.3: K&R arg decl intro
  2805.          (t
  2806.           (c-add-semantics 'knr-argdecl-intro (c-point 'boi))
  2807.           (and inclass-p (c-add-semantics 'inclass (aref inclass-p 0))))
  2808.          ))
  2809.        ;; CASE 4C: inheritance line. could be first inheritance
  2810.        ;; line, or continuation of a multiple inheritance
  2811.        ((looking-at c-baseclass-key)
  2812.         (cond
  2813.          ;; CASE 4C.1: non-hanging colon on an inher intro
  2814.          ((= char-after-ip ?:)
  2815.           (c-backward-syntactic-ws lim)
  2816.           (c-add-semantics 'inher-intro (c-point 'boi))
  2817.           ;; don't add inclass symbol since relative point already
  2818.           ;; contains any class offset
  2819.           )
  2820.          ;; CASE 4C.2: hanging colon on an inher intro
  2821.          ((= char-before-ip ?:)
  2822.           (c-add-semantics 'inher-intro (c-point 'boi))
  2823.           (and inclass-p (c-add-semantics 'inclass (aref inclass-p 0))))
  2824.          ;; CASE 4C.3: a continued inheritance line
  2825.          (t
  2826.           (c-beginning-of-inheritance-list lim)
  2827.           (c-add-semantics 'inher-cont (point))
  2828.           ;; don't add inclass symbol since relative point already
  2829.           ;; contains any class offset
  2830.           )))
  2831.        ;; CASE 4D: this could be a top-level compound statement or a
  2832.        ;; member init list continuation
  2833.        ((= char-before-ip ?,)
  2834.         (goto-char indent-point)
  2835.         (c-backward-syntactic-ws lim)
  2836.         (while (and (< lim (point))
  2837.             (= (preceding-char) ?,))
  2838.           ;; this will catch member inits with multiple
  2839.           ;; line arglists
  2840.           (forward-char -1)
  2841.           (c-backward-syntactic-ws (c-point 'bol))
  2842.           (if (= (preceding-char) ?\))
  2843.           (backward-sexp 1))
  2844.           ;; now continue checking
  2845.           (beginning-of-line)
  2846.           (c-backward-syntactic-ws lim))
  2847.         (cond
  2848.          ;; CASE 4D.1: hanging member init colon
  2849.          ((= (preceding-char) ?:)
  2850.           (goto-char indent-point)
  2851.           (c-backward-syntactic-ws lim)
  2852.           (c-safe (backward-sexp 1))
  2853.           (c-add-semantics 'member-init-cont (c-point 'boi))
  2854.           ;; we do not need to add class offset since relative
  2855.           ;; point is the member init above us
  2856.           )
  2857.          ;; CASE 4D.2: non-hanging member init colon
  2858.          ((progn
  2859.         (c-forward-syntactic-ws indent-point)
  2860.         (= (following-char) ?:))
  2861.           (skip-chars-forward " \t:")
  2862.           (c-add-semantics 'member-init-cont (point)))
  2863.          ;; CASE 4D.3: perhaps a multiple inheritance line?
  2864.          ((looking-at c-inher-key)
  2865.           (c-add-semantics 'inher-cont-1 (c-point 'boi)))
  2866.          ;; CASE 4D.4: perhaps a template list continuation?
  2867.          ((save-excursion
  2868.         (skip-chars-backward "^<" lim)
  2869.         (= (preceding-char) ?<))
  2870.           ;; we can probably indent it just like and arglist-cont
  2871.           (c-add-semantics 'arglist-cont (point)))
  2872.          ;; CASE 4D.5: perhaps a top-level statement-cont
  2873.          (t
  2874.           (c-beginning-of-statement nil lim)
  2875.           (c-add-semantics 'statement-cont (c-point 'boi)))
  2876.          ))
  2877.        ;; CASE 4E: we are looking at a access specifier
  2878.        ((and inclass-p
  2879.          (looking-at c-access-key))
  2880.         (c-add-semantics 'access-label (c-point 'bonl))
  2881.         (c-add-semantics 'inclass (aref inclass-p 0)))
  2882.        ;; CASE 4F: we are looking at the brace which closes the
  2883.        ;; enclosing nested class decl
  2884.        ((and inclass-p
  2885.          (= char-after-ip ?})
  2886.          (save-excursion
  2887.            (save-restriction
  2888.              (widen)
  2889.              (forward-char 1)
  2890.              (and
  2891.               (condition-case nil
  2892.               (progn (backward-sexp 1) t)
  2893.             (error nil))
  2894.               (= (point) (aref inclass-p 1))
  2895.               ))))
  2896.         (save-restriction
  2897.           (widen)
  2898.           (goto-char (aref inclass-p 0))
  2899.           (c-add-semantics 'class-close (c-point 'boi))))
  2900.        ;; CASE 4G: we could be looking at subsequent knr-argdecls
  2901.        ((and (eq major-mode 'c-mode)
  2902.          (save-excursion
  2903.            (c-backward-syntactic-ws lim)
  2904.            (while (memq (preceding-char) '(?\; ?,))
  2905.              (beginning-of-line)
  2906.              (setq placeholder (point))
  2907.              (c-backward-syntactic-ws lim))
  2908.            (= (preceding-char) ?\)))
  2909.          (save-excursion
  2910.            (c-beginning-of-statement)
  2911.            (not (looking-at "typedef[ \t\n]+"))))
  2912.         (goto-char placeholder)
  2913.         (c-add-semantics 'knr-argdecl (c-point 'boi)))
  2914.        ;; CASE 4H: we are at the topmost level, make sure we skip
  2915.        ;; back past any access specifiers
  2916.        ((progn
  2917.           (c-backward-syntactic-ws lim)
  2918.           (while (and inclass-p
  2919.               (= (preceding-char) ?:)
  2920.               (save-excursion
  2921.                 (backward-sexp 1)
  2922.                 (looking-at c-access-key)))
  2923.         (backward-sexp 1)
  2924.         (c-backward-syntactic-ws lim))
  2925.           (or (bobp)
  2926.           (memq (preceding-char) '(?\; ?\}))))
  2927.         (c-add-semantics 'topmost-intro (c-point 'bol))
  2928.         (and inclass-p (c-add-semantics 'inclass (aref inclass-p 0))))
  2929.        ;; CASE 4I: we are at a topmost continuation line
  2930.        (t
  2931.         (c-beginning-of-statement 1 lim)
  2932.         (c-add-semantics 'topmost-intro-cont (c-point 'boi)))
  2933.        ))                ; end CASE 4
  2934.      ;; CASE 5: line is an expression, not a statement.  Most
  2935.      ;; likely we are either in a function prototype or a function
  2936.      ;; call argument list
  2937.      ((/= (char-after containing-sexp) ?{)
  2938.       (c-backward-syntactic-ws containing-sexp)
  2939.       (cond
  2940.        ;; CASE 5A: we are looking at the first argument in an empty
  2941.        ;; argument list
  2942.        ((= char-before-ip ?\()
  2943.         (goto-char containing-sexp)
  2944.         (c-add-semantics 'arglist-intro (c-point 'boi)))
  2945.        ;; CASE 5B: we are looking at the arglist closing paren
  2946.        ((and (/= char-before-ip ?,)
  2947.          (= char-after-ip ?\)))
  2948.         (goto-char containing-sexp)
  2949.         (c-add-semantics 'arglist-close (c-point 'boi)))
  2950.        ;; CASE 5C: we are inside a conditional test clause. treat
  2951.        ;; these things as statements
  2952.        ((save-excursion
  2953.          (goto-char containing-sexp)
  2954.          (and (c-safe (progn (forward-sexp -1) t))
  2955.           (looking-at "\\<for\\>")))
  2956.         (c-beginning-of-statement 1 containing-sexp)
  2957.         (if (= char-before-ip ?\;)
  2958.         (c-add-semantics 'statement (point))
  2959.           (c-add-semantics 'statement-cont (point))
  2960.           ))
  2961.        ;; CASE 5D: we are looking at an arglist continuation line,
  2962.        ;; but the preceding argument is on the same line as the
  2963.        ;; opening paren.  This case includes multi-line
  2964.        ;; mathematical paren groupings, but we could be on a
  2965.        ;; for-list continuation line
  2966.        ((and (save-excursion
  2967.            (goto-char (1+ containing-sexp))
  2968.            (skip-chars-forward " \t")
  2969.            (not (eolp)))
  2970.          (save-excursion
  2971.            (c-beginning-of-statement)
  2972.            (skip-chars-backward " \t(")
  2973.            (<= (point) containing-sexp)))
  2974.         (goto-char containing-sexp)
  2975.         (c-add-semantics 'arglist-cont-nonempty (c-point 'boi)))
  2976.        ;; CASE 5E: we are looking at just a normal arglist
  2977.        ;; continuation line
  2978.        (t (c-beginning-of-statement 1 containing-sexp)
  2979.           (c-add-semantics 'arglist-cont (c-point 'boi)))
  2980.        ))
  2981.      ;; CASE 6: func-local multi-inheritance line
  2982.      ((save-excursion
  2983.         (goto-char indent-point)
  2984.         (skip-chars-forward " \t")
  2985.         (looking-at c-baseclass-key))
  2986.       (goto-char indent-point)
  2987.       (skip-chars-forward " \t")
  2988.       (cond
  2989.        ;; CASE 6A: non-hanging colon on an inher intro
  2990.        ((= char-after-ip ?:)
  2991.         (c-backward-syntactic-ws lim)
  2992.         (c-add-semantics 'inher-intro (c-point 'boi)))
  2993.        ;; CASE 6B: hanging colon on an inher intro
  2994.        ((= char-before-ip ?:)
  2995.         (c-add-semantics 'inher-intro (c-point 'boi)))
  2996.        ;; CASE 6C: a continued inheritance line
  2997.        (t
  2998.         (c-beginning-of-inheritance-list lim)
  2999.         (c-add-semantics 'inher-cont (point))
  3000.         )))
  3001.      ;; CASE 7: we are inside a brace-list
  3002.      ((setq placeholder (c-inside-bracelist-p containing-sexp))
  3003.       (cond
  3004.        ;; CASE 7A: brace-list-close brace
  3005.        ((and (= char-after-ip ?})
  3006.          (c-safe (progn (forward-char 1)
  3007.                 (backward-sexp 1)
  3008.                 t))
  3009.          (= (point) containing-sexp))
  3010.         (c-add-semantics 'brace-list-close (c-point 'boi)))
  3011.        ;; CASE 7B: we're looking at the first line in a brace-list
  3012.        ((save-excursion
  3013.           (goto-char indent-point)
  3014.           (c-backward-syntactic-ws containing-sexp)
  3015.           (= (point) (1+ containing-sexp)))
  3016.         (goto-char containing-sexp)
  3017.         (c-add-semantics 'brace-list-intro (c-point 'boi))
  3018.         (if (= char-after-ip ?{)
  3019.         (c-add-semantics 'block-open)))
  3020.        ;; CASE 7C: this is just a later brace-list-entry
  3021.        (t (goto-char (1+ containing-sexp))
  3022.           (c-forward-syntactic-ws indent-point)
  3023.           (c-add-semantics 'brace-list-entry (point))
  3024.           (if (= char-after-ip ?{)
  3025.           (c-add-semantics 'block-open)))
  3026.        ))
  3027.      ;; CASE 8: A continued statement
  3028.      ((and (not (memq char-before-ip '(?\; ?} ?:)))
  3029.            (> (point)
  3030.           (save-excursion
  3031.             (c-beginning-of-statement 1 containing-sexp)
  3032.             (setq placeholder (point))))
  3033.            (/= placeholder containing-sexp))
  3034.       (goto-char indent-point)
  3035.       (skip-chars-forward " \t")
  3036.       (cond
  3037.        ;; CASE 8A: substatement
  3038.        ((save-excursion
  3039.           (goto-char placeholder)
  3040.           (and (looking-at c-conditional-key)
  3041.            (c-safe (progn (c-skip-conditional) t))
  3042.            (progn (c-forward-syntactic-ws)
  3043.               (>= (point) indent-point))))
  3044.         (goto-char placeholder)
  3045.         (if (= char-after-ip ?{)
  3046.         (c-add-semantics 'substatement-open (c-point 'boi))
  3047.           (c-add-semantics 'substatement (c-point 'boi))))
  3048.        ;; CASE 8B: open braces for class or brace-lists
  3049.        ((= char-after-ip ?{)
  3050.         (cond
  3051.          ;; CASE 8B.1: class-open
  3052.          ((save-excursion
  3053.         (goto-char indent-point)
  3054.         (skip-chars-forward " \t{")
  3055.         (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  3056.           (and decl
  3057.                (setq placeholder (aref decl 0)))
  3058.           ))
  3059.           (c-add-semantics 'class-open placeholder))
  3060.          ;; CASE 8B.2: brace-list-open
  3061.          ((or (save-excursion
  3062.             (goto-char placeholder)
  3063.             (looking-at "\\<enum\\>"))
  3064.           (= char-before-ip ?=))
  3065.           (c-add-semantics 'brace-list-open placeholder))
  3066.          ;; CASE 8B.3: catch-all for unknown construct.
  3067.          (t
  3068.           ;; Even though this isn't right, it's the best I'm going
  3069.           ;; to do for now. Exceptions probably fall through to
  3070.           ;; here, but aren't supported yet.  Also, after the next
  3071.           ;; release, I may call a recognition hook like so:
  3072.           ;; (run-hooks 'c-recognize-hook), but I dunno.
  3073.           (c-add-semantics 'statement-cont placeholder)
  3074.           (c-add-semantics 'block-open))
  3075.          ))
  3076.        ;; CASE 8C: iostream insertion or extraction operator
  3077.        ((looking-at "<<\\|>>")
  3078.         (goto-char placeholder)
  3079.         (if (looking-at c-conditional-key)
  3080.         (c-skip-conditional))
  3081.         (while (and (re-search-forward "<<\\|>>" indent-point 'move)
  3082.             (c-in-literal)))
  3083.         ;; if we ended up at indent-point, then the first streamop
  3084.         ;; is on a separate line. Indent the line like a
  3085.         ;; statement-cont instead
  3086.         (if (/= (point) indent-point)
  3087.         (c-add-semantics 'stream-op (c-point 'boi))
  3088.           (c-backward-syntactic-ws lim)
  3089.           (c-add-semantics 'statement-cont (c-point 'boi))))
  3090.        ;; CASE 8D: continued statement. find the accurate
  3091.        ;; beginning of statement or substatement
  3092.        (t
  3093.         (c-beginning-of-statement nil
  3094.          (save-excursion
  3095.            (goto-char placeholder)
  3096.            (and (looking-at c-conditional-key)
  3097.             (c-safe (progn (c-skip-conditional) t))
  3098.             (c-forward-syntactic-ws))
  3099.            (point)))
  3100.         (c-add-semantics 'statement-cont (point)))
  3101.        ))
  3102.      ;; CASE 9: an else clause?
  3103.      ((looking-at "\\<else\\>")
  3104.       (c-backward-to-start-of-if containing-sexp)
  3105.       (c-add-semantics 'else-clause (c-point 'boi)))
  3106.      ;; CASE 10: Statement. But what kind?  Lets see if its a
  3107.      ;; while closure of a do/while construct
  3108.      ((progn
  3109.         (goto-char indent-point)
  3110.         (skip-chars-forward " \t")
  3111.         (and (looking-at "while\\b[^_]")
  3112.          (save-excursion
  3113.            (c-backward-to-start-of-do containing-sexp)
  3114.            (setq placeholder (point))
  3115.            (looking-at "do\\b[^_]"))
  3116.          ))
  3117.       (c-add-semantics 'do-while-closure placeholder))
  3118.      ;; CASE 11: A case or default label
  3119.      ((looking-at c-switch-label-key)
  3120.       (goto-char containing-sexp)
  3121.       ;; for a case label, we set relpos the first non-whitespace
  3122.       ;; char on the line containing the switch opening brace. this
  3123.       ;; should handle hanging switch opening braces correctly.
  3124.       (c-add-semantics 'case-label (c-point 'boi)))
  3125.      ;; CASE 12: any other label
  3126.      ((looking-at c-label-key)
  3127.       (goto-char containing-sexp)
  3128.       (c-add-semantics 'label (c-point 'boi)))
  3129.      ;; CASE 13: block close brace, possibly closing the defun or
  3130.      ;; the class
  3131.      ((= char-after-ip ?})
  3132.       (let ((relpos (save-excursion
  3133.               (goto-char containing-sexp)
  3134.               (if (/= (point) (c-point 'boi))
  3135.                   (c-beginning-of-statement))
  3136.               (c-point 'boi))))
  3137.         (cond
  3138.          ;; CASE 13.A: does this close an inline?
  3139.          ((progn
  3140.         (goto-char containing-sexp)
  3141.         (c-search-uplist-for-classkey state))
  3142.           (c-add-semantics 'inline-close relpos))
  3143.          ;; CASE 13.B: if there an enclosing brace that hasn't
  3144.          ;; been narrowed out by a class, then this is a
  3145.          ;; block-close
  3146.          ((c-enclosing-brace state)
  3147.           (c-add-semantics 'block-close relpos))
  3148.          ;; CASE 13.C: find out whether we're closing a top-level
  3149.          ;; class or a defun
  3150.          (t
  3151.           (save-restriction
  3152.         (narrow-to-region (point-min) indent-point)
  3153.         (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  3154.           (if decl
  3155.               (c-add-semantics 'class-close (aref decl 0))
  3156.             (c-add-semantics 'defun-close relpos)))))
  3157.          )))
  3158.      ;; CASE 14: statement catchall
  3159.      (t
  3160.       ;; we know its a statement, but we need to find out if it is
  3161.       ;; the first statement in a block
  3162.       (goto-char containing-sexp)
  3163.       (forward-char 1)
  3164.       (c-forward-syntactic-ws indent-point)
  3165.       ;; we want to ignore labels when skipping forward
  3166.       (let ((ignore-re (concat c-switch-label-key "\\|" c-label-key))
  3167.         inswitch-p)
  3168.         (while (looking-at ignore-re)
  3169.           (if (looking-at c-switch-label-key)
  3170.           (setq inswitch-p t))
  3171.           (forward-line 1)
  3172.           (c-forward-syntactic-ws indent-point))
  3173.         (cond
  3174.          ;; CASE 14.A: we saw a case/default statement so we must be
  3175.          ;; in a switch statement.  find out if we are at the
  3176.          ;; statement just after a case or default label
  3177.          ((and inswitch-p
  3178.            (save-excursion
  3179.              (goto-char indent-point)
  3180.              (c-backward-syntactic-ws containing-sexp)
  3181.              (back-to-indentation)
  3182.              (setq placeholder (point))
  3183.              (looking-at c-switch-label-key)))
  3184.           (c-add-semantics 'statement-case-intro placeholder))
  3185.          ;; CASE 14.B: continued statement
  3186.          ((= char-before-ip ?,)
  3187.           (c-add-semantics 'statement-cont (c-point 'boi)))
  3188.          ;; CASE 14.C: a question/colon construct?  But make sure
  3189.          ;; what came before was not a label, and what comes after
  3190.          ;; is not a globally scoped function call!
  3191.          ((or (and (memq char-before-ip '(?: ??))
  3192.                (save-excursion
  3193.              (goto-char indent-point)
  3194.              (c-backward-syntactic-ws lim)
  3195.              (back-to-indentation)
  3196.              (not (looking-at c-label-key))))
  3197.           (and (memq char-after-ip '(?: ??))
  3198.                (save-excursion
  3199.              (goto-char indent-point)
  3200.              (skip-chars-forward " \t")
  3201.              ;; watch out for scope operator
  3202.              (not (looking-at "::")))))
  3203.           (c-add-semantics 'statement-cont (c-point 'boi)))
  3204.          ;; CASE 14.D: any old statement
  3205.          ((< (point) indent-point)
  3206.           (c-add-semantics 'statement (c-point 'boi))
  3207.           (if (= char-after-ip ?{)
  3208.           (c-add-semantics 'block-open)))
  3209.          ;; CASE 14.E: first statement in an inline, or first
  3210.          ;; statement in a top-level defun. we can tell this is it
  3211.          ;; if there are no enclosing braces that haven't been
  3212.          ;; narrowed out by a class (i.e. don't use bod here!)
  3213.          ((save-excursion
  3214.         (save-restriction
  3215.           (widen)
  3216.           (goto-char containing-sexp)
  3217.           (c-narrow-out-enclosing-class state containing-sexp)
  3218.           (not (c-enclosing-brace state))))
  3219.           (goto-char containing-sexp)
  3220.           (c-add-semantics 'defun-block-intro (c-point 'boi)))
  3221.          ;; CASE 14.F: first statement in a block
  3222.          (t (goto-char containing-sexp)
  3223.         (if (/= (point) (c-point 'boi))
  3224.             (c-beginning-of-statement))
  3225.         (c-add-semantics 'statement-block-intro (c-point 'boi))
  3226.         (if (= char-after-ip ?{)
  3227.             (c-add-semantics 'block-open)))
  3228.          )))
  3229.      )
  3230.  
  3231.     ;; now we need to look at any modifiers
  3232.     (goto-char indent-point)
  3233.     (skip-chars-forward " \t")
  3234.     (if (looking-at c-comment-start-regexp)
  3235.         ;; we are looking at a comment. if the comment is at or to
  3236.         ;; the right of comment-column, then all we want on the
  3237.         ;; semantics list is comment-intro, otherwise, the
  3238.         ;; indentation of the comment is relative to where a
  3239.         ;; normal statement would indent
  3240.         (if (< (current-column) comment-column)
  3241.         (c-add-semantics 'comment-intro)
  3242.           ;; reset semantics kludge
  3243.           (setq semantics nil)
  3244.           (c-add-semantics 'comment-intro)))
  3245.     ;; we might want to give additional offset to friends (in C++)
  3246.     (if (and (eq major-mode 'c++-mode)
  3247.          (looking-at "friend[ \t]+"))
  3248.         (c-add-semantics 'friend))
  3249.     ;; return the semantics
  3250.     semantics))))
  3251.  
  3252.  
  3253. ;; indent via semantic language elements
  3254. (defun c-get-offset (langelem)
  3255.   ;; Get offset from LANGELEM which is a cons cell of the form:
  3256.   ;; (SYMBOL . RELPOS).  The symbol is matched against
  3257.   ;; c-offsets-alist and the offset found there is either returned,
  3258.   ;; or added to the indentation at RELPOS.  If RELPOS is nil, then
  3259.   ;; the offset is simply returned.
  3260.   (let* ((symbol (car langelem))
  3261.      (relpos (cdr langelem))
  3262.      (match  (assq symbol c-offsets-alist))
  3263.      (offset (cdr-safe match)))
  3264.     ;; offset can be a number, a function, a variable, or one of the
  3265.     ;; symbols + or -
  3266.     (cond
  3267.      ((not match)
  3268.       (if c-strict-semantics-p
  3269.       (error "don't know how to indent a %s" symbol)
  3270.     (setq offset 0
  3271.           relpos 0)))
  3272.      ((eq offset '+) (setq offset c-basic-offset))
  3273.      ((eq offset '-) (setq offset (- c-basic-offset)))
  3274.      ((and (not (numberp offset))
  3275.        (fboundp offset))
  3276.       (setq offset (funcall offset langelem)))
  3277.      ((not (numberp offset))
  3278.       (setq offset (eval offset)))
  3279.      )
  3280.     (+ (if (and relpos
  3281.         (< relpos (c-point 'bol)))
  3282.        (save-excursion
  3283.          (goto-char relpos)
  3284.          (current-column))
  3285.      0)
  3286.        offset)))
  3287.  
  3288. (defun c-indent-line (&optional semantics)
  3289.   ;; indent the curent line as C/C++ code. Optional SEMANTICS is the
  3290.   ;; semantic information for the current line. Returns the amount of
  3291.   ;; indentation change
  3292.   (let* ((c-semantics (or semantics (c-guess-basic-semantics)))
  3293.      (pos (- (point-max) (point)))
  3294.      (indent (apply '+ (mapcar 'c-get-offset c-semantics)))
  3295.      (shift-amt  (- (current-indentation) indent)))
  3296.     (and c-echo-semantic-information-p
  3297.      (message "semantics: %s, indent= %d" c-semantics indent))
  3298.     (if (zerop shift-amt)
  3299.     nil
  3300.       (delete-region (c-point 'bol) (c-point 'boi))
  3301.       (beginning-of-line)
  3302.       (indent-to indent))
  3303.     (if (< (point) (c-point 'boi))
  3304.     (back-to-indentation)
  3305.       ;; If initial point was within line's indentation, position after
  3306.       ;; the indentation.  Else stay at same point in text.
  3307.       (if (> (- (point-max) pos) (point))
  3308.       (goto-char (- (point-max) pos)))
  3309.       )
  3310.     (run-hooks 'c-special-indent-hook)
  3311.     shift-amt))
  3312.  
  3313. (defun c-show-semantic-information ()
  3314.   "Show semantic information for current line."
  3315.   (interactive)
  3316.   (message "semantics: %s" (c-guess-basic-semantics))
  3317.   (c-keep-region-active))
  3318.  
  3319.  
  3320. ;; Standard indentation line-ups
  3321. (defun c-lineup-arglist (langelem)
  3322.   ;; lineup the current arglist line with the arglist appearing just
  3323.   ;; after the containing paren which starts the arglist.
  3324.   (save-excursion
  3325.     (let* ((containing-sexp
  3326.         (save-excursion
  3327.           ;; arglist-cont-nonempty gives relpos ==
  3328.           ;; to boi of containing-sexp paren. This
  3329.           ;; is good when offset is +, but bad
  3330.           ;; when it is c-lineup-arglist, so we
  3331.           ;; have to special case a kludge here.
  3332.           (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
  3333.           (progn
  3334.             (beginning-of-line)
  3335.             (backward-up-list 1)
  3336.             (skip-chars-forward " \t" (c-point 'eol)))
  3337.         (goto-char (cdr langelem)))
  3338.           (point)))
  3339.        (cs-curcol (save-excursion
  3340.             (goto-char (cdr langelem))
  3341.             (current-column))))
  3342.       (if (save-excursion
  3343.         (beginning-of-line)
  3344.         (looking-at "[ \t]*)"))
  3345.       (progn (beginning-of-line)
  3346.          (skip-chars-forward " \t)")
  3347.          (forward-sexp -1)
  3348.          (forward-char 1)
  3349.          (c-forward-syntactic-ws)
  3350.          (- (current-column) cs-curcol))
  3351.     (goto-char containing-sexp)
  3352.     (or (eolp)
  3353.         (progn (forward-char 1)
  3354.            (c-forward-syntactic-ws (c-point 'eol))
  3355.            ))
  3356.     (- (current-column) cs-curcol)
  3357.     ))))
  3358.  
  3359. (defun c-lineup-streamop (langelem)
  3360.   ;; lineup stream operators
  3361.   (save-excursion
  3362.     (let* ((relpos (cdr langelem))
  3363.        (curcol (progn (goto-char relpos)
  3364.               (current-column))))
  3365.       (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
  3366.       (goto-char (match-beginning 0))
  3367.       (- (current-column) curcol))))
  3368.  
  3369. (defun c-lineup-multi-inher (langelem)
  3370.   ;; line up multiple inheritance lines
  3371.   (save-excursion
  3372.     (let (cs-curcol
  3373.       (eol (c-point 'eol))
  3374.       (here (point)))
  3375.       (goto-char (cdr langelem))
  3376.       (setq cs-curcol (current-column))
  3377.       (skip-chars-forward "^:" eol)
  3378.       (skip-chars-forward " \t:" eol)
  3379.       (if (or (eolp)
  3380.           (looking-at c-comment-start-regexp))
  3381.       (c-forward-syntactic-ws here))
  3382.       (- (current-column) cs-curcol)
  3383.       )))
  3384.  
  3385. (defun c-lineup-C-comments (langelem)
  3386.   ;; line up C block comment continuation lines
  3387.   (save-excursion
  3388.     (let ((stars (progn
  3389.            (beginning-of-line)
  3390.            (skip-chars-forward " \t")
  3391.            (if (looking-at "\\*\\*?")
  3392.                (- (match-end 0) (match-beginning 0))
  3393.              0)))
  3394.       (cs-curcol (progn (goto-char (cdr langelem))
  3395.                 (current-column))))
  3396.       (back-to-indentation)
  3397.       (if (re-search-forward "/\\*[ \t]*" (c-point 'eol) t)
  3398.       (goto-char (+ (match-beginning 0)
  3399.             (cond
  3400.              (c-block-comments-indent-p 0)
  3401.              ((= stars 1) 1)
  3402.              ((= stars 2) 0)
  3403.              (t (- (match-end 0) (match-beginning 0)))))))
  3404.       (- (current-column) cs-curcol))))
  3405.  
  3406. (defun c-lineup-comment (langelem)
  3407.   ;; support old behavior for comment indentation. we look at
  3408.   ;; c-comment-only-line-offset to decide how to indent comment
  3409.   ;; only-lines
  3410.   (save-excursion
  3411.     (back-to-indentation)
  3412.     ;; at or to the right of comment-column
  3413.     (if (>= (current-column) comment-column)
  3414.     (c-comment-indent)
  3415.       ;; otherwise, indent as specified by c-comment-only-line-offset
  3416.       (if (not (bolp))
  3417.       (or (car-safe c-comment-only-line-offset)
  3418.           c-comment-only-line-offset)
  3419.     (or (cdr-safe c-comment-only-line-offset)
  3420.         (car-safe c-comment-only-line-offset)
  3421.         -1000            ;jam it against the left side
  3422.         )))))
  3423.  
  3424. (defun c-lineup-runin-statements (langelem)
  3425.   ;; line up statements in coding standards which place the first
  3426.   ;; statement on the same line as the block opening brace.
  3427.   (if (= (char-after (cdr langelem)) ?{)
  3428.       (save-excursion
  3429.     (let ((curcol (progn
  3430.             (goto-char (cdr langelem))
  3431.             (current-column))))
  3432.       (forward-char 1)
  3433.       (skip-chars-forward " \t")
  3434.       (- (current-column) curcol)))
  3435.     0))
  3436.  
  3437. (defun c-lineup-math (langelem)
  3438.   ;; line up math statement-cont after the equals
  3439.   (save-excursion
  3440.     (let ((equalp (save-excursion
  3441.             (goto-char (c-point 'boi))
  3442.             (skip-chars-forward "^=" (c-point 'eol))
  3443.             (and (= (following-char) ?=)
  3444.              (- (point) (c-point 'boi)))))
  3445.       (curcol (progn
  3446.             (goto-char (cdr langelem))
  3447.             (current-column))))
  3448.       (skip-chars-forward "^=" (c-point 'eol))
  3449.       (if (/= (following-char) ?=)
  3450.       ;; there's no equal sign on the line
  3451.       c-basic-offset
  3452.     ;; calculate indentation column after equals and ws, unless
  3453.     ;; our line contains an equals sign
  3454.     (if (not equalp)
  3455.         (progn
  3456.           (forward-char 1)
  3457.           (skip-chars-forward " \t")
  3458.           (setq equalp 0)))
  3459.     (- (current-column) equalp curcol))
  3460.       )))
  3461.  
  3462.  
  3463. ;; commands for "macroizations" -- making C++ parameterized types via
  3464. ;; macros. Also commands for commentifying regions
  3465.  
  3466. (defun c-backslashify-current-line (doit)
  3467.   ;; Backslashifies current line if DOIT is non-nil, otherwise
  3468.   ;; unbackslashifies the current line.
  3469.   (end-of-line)
  3470.   (if doit
  3471.       ;; Note that "\\\\" is needed to get one backslash.
  3472.       (if (not (save-excursion
  3473.          (forward-char -1)
  3474.          (looking-at "\\\\")))
  3475.       (progn
  3476.         (if (>= (current-column) c-backslash-column)
  3477.         (insert " \\")
  3478.           (while (<= (current-column) c-backslash-column)
  3479.         (insert "\t")
  3480.         (end-of-line))
  3481.           (delete-char -1)
  3482.           (while (< (current-column) c-backslash-column)
  3483.         (insert " ")
  3484.         (end-of-line))
  3485.           (insert "\\"))))
  3486.     (if (not (bolp))
  3487.     (progn
  3488.       (forward-char -1)
  3489.       (if (looking-at "\\\\")
  3490.           (progn
  3491.         (skip-chars-backward " \t")
  3492.         (delete-region (point) (c-point 'eol))))
  3493.       ))))
  3494.  
  3495. (defun c-backslash-region (beg end arg)
  3496.   "Insert backslashes at end of every line in region.
  3497. Useful for defining cpp macros.  If called with a prefix argument,
  3498. it trailing backslashes are removed."
  3499.   (interactive "r\nP")
  3500.   (save-excursion
  3501.     (let ((do-lastline-p (progn (goto-char end) (not (bolp)))))
  3502.       (save-restriction
  3503.     (narrow-to-region beg end)
  3504.     (goto-char (point-min))
  3505.     (while (not (save-excursion
  3506.               (forward-line 1)
  3507.               (eobp)))
  3508.       (c-backslashify-current-line (null arg))
  3509.       (forward-line 1)))
  3510.       (and do-lastline-p
  3511.        (progn (goto-char end)
  3512.           (c-backslashify-current-line (null arg))))
  3513.       )))
  3514.  
  3515. ;;(defun comment-region (beg end &optional arg)
  3516. ;;  "Comment or uncomment each line in the region.
  3517. ;;With just C-u prefix arg, uncomment each line in region.
  3518. ;;Numeric prefix arg ARG means use ARG comment characters.
  3519. ;;If ARG is negative, delete that many comment characters instead.
  3520. ;;Comments are terminated on each line, even for syntax in which newline does
  3521. ;;not end the comment.  Blank lines do not get comments."
  3522. ;;  ;; if someone wants it to only put a comment-start at the beginning and
  3523. ;;  ;; comment-end at the end then typing it, C-x C-x, closing it, C-x C-x
  3524. ;;  ;; is easy enough.  No option is made here for other than commenting
  3525. ;;  ;; every line.
  3526. ;;  (interactive "r\nP")
  3527. ;;  (or comment-start (error "No comment syntax is defined"))
  3528. ;;  (if (> beg end) (let (mid) (setq mid beg beg end end mid)))
  3529. ;;  (save-excursion
  3530. ;;    (save-restriction
  3531. ;;      (let ((cs comment-start) (ce comment-end)
  3532. ;;        numarg)
  3533. ;;        (if (consp arg) (setq numarg t)
  3534. ;;      (setq numarg (prefix-numeric-value arg))
  3535. ;;      ;; For positive arg > 1, replicate the comment delims now,
  3536. ;;      ;; then insert the replicated strings just once.
  3537. ;;      (while (> numarg 1)
  3538. ;;        (setq cs (concat cs comment-start)
  3539. ;;          ce (concat ce comment-end))
  3540. ;;        (setq numarg (1- numarg))))
  3541. ;;    ;; Loop over all lines from BEG to END.
  3542. ;;        (narrow-to-region beg end)
  3543. ;;        (goto-char beg)
  3544. ;;        (while (not (eobp))
  3545. ;;          (if (or (eq numarg t) (< numarg 0))
  3546. ;;          (progn
  3547. ;;        ;; Delete comment start from beginning of line.
  3548. ;;        (if (eq numarg t)
  3549. ;;            (while (looking-at (regexp-quote cs))
  3550. ;;              (delete-char (length cs)))
  3551. ;;          (let ((count numarg))
  3552. ;;            (while (and (> 1 (setq count (1+ count)))
  3553. ;;                (looking-at (regexp-quote cs)))
  3554. ;;              (delete-char (length cs)))))
  3555. ;;        ;; Delete comment end from end of line.
  3556. ;;                (if (string= "" ce)
  3557. ;;            nil
  3558. ;;          (if (eq numarg t)
  3559. ;;              (progn
  3560. ;;            (end-of-line)
  3561. ;;            ;; This is questionable if comment-end ends in
  3562. ;;            ;; whitespace.  That is pretty brain-damaged,
  3563. ;;            ;; though.
  3564. ;;            (skip-chars-backward " \t")
  3565. ;;            (if (and (>= (- (point) (point-min)) (length ce))
  3566. ;;                 (save-excursion
  3567. ;;                   (backward-char (length ce))
  3568. ;;                   (looking-at (regexp-quote ce))))
  3569. ;;                (delete-char (- (length ce)))))
  3570. ;;            (setq count numarg)
  3571. ;;            (while (> 1 (setq count (1+ count)))
  3572. ;;              (end-of-line)
  3573. ;;              ;; this is questionable if comment-end ends in whitespace
  3574. ;;              ;; that is pretty brain-damaged though
  3575. ;;              (skip-chars-backward " \t")
  3576. ;;              (save-excursion
  3577. ;;            (backward-char (length ce))
  3578. ;;            (if (looking-at (regexp-quote ce))
  3579. ;;                (delete-char (length ce)))))))
  3580. ;;        (forward-line 1))
  3581. ;;        ;; Insert at beginning and at end.
  3582. ;;            (if (looking-at "[ \t]*$") ()
  3583. ;;              (insert cs)
  3584. ;;              (if (string= "" ce) ()
  3585. ;;                (end-of-line)
  3586. ;;                (insert ce)))
  3587. ;;            (search-forward "\n" nil 'move)))))))
  3588.  
  3589.  
  3590. ;; defuns for submitting bug reports
  3591.  
  3592. (defconst c-version "3.349"
  3593.   "cc-mode version number.")
  3594. (defconst c-mode-help-address "cc-mode-help@anthem.nlm.nih.gov"
  3595.   "Address accepting submission of bug reports.")
  3596.  
  3597. (defun c-version ()
  3598.   "Echo the current version of cc-mode in the minibuffer."
  3599.   (interactive)
  3600.   (message "Using cc-mode version %s" c-version)
  3601.   (c-keep-region-active))
  3602.  
  3603. ;; get reporter-submit-bug-report when byte-compiling
  3604. (and (fboundp 'eval-when-compile)
  3605.      (eval-when-compile
  3606.       (require 'reporter)))
  3607.  
  3608. (defun c-submit-bug-report ()
  3609.   "Submit via mail a bug report on cc-mode."
  3610.   (interactive)
  3611.   (and
  3612.    (y-or-n-p "Do you want to submit a report on cc-mode? ")
  3613.    (require 'reporter)
  3614.    (reporter-submit-bug-report
  3615.     c-mode-help-address
  3616.     (concat "cc-mode " c-version " ("
  3617.         (if (eq major-mode 'c++-mode) "C++" "C")
  3618.         ")")
  3619.     (list
  3620.      ;; report only the vars that affect indentation
  3621.      'c-emacs-features
  3622.      'c-basic-offset
  3623.      'c-offsets-alist
  3624.      'c-block-comments-indent-p
  3625.      'c-cleanup-list
  3626.      'c-comment-only-line-offset
  3627.      'c-backslash-column
  3628.      'c-delete-function
  3629.      'c-electric-pound-behavior
  3630.      'c-hanging-braces-alist
  3631.      'c-hanging-colons-alist
  3632.      'c-tab-always-indent
  3633.      'defun-prompt-regexp
  3634.      'tab-width
  3635.      )
  3636.     (function
  3637.      (lambda ()
  3638.        (insert
  3639.     (if c-special-indent-hook
  3640.         (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  3641.             "c-special-indent-hook is set to '"
  3642.             (format "%s" c-special-indent-hook)
  3643.             ".\nPerhaps this is your problem?\n"
  3644.             "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
  3645.       "\n")
  3646.     )))
  3647.     )))
  3648.  
  3649.  
  3650. ;; menus for Lucid
  3651. (defun c-popup-menu (e)
  3652.   "Pops up the C/C++ menu."
  3653.   (interactive "@e")
  3654.   (popup-menu (cons (concat mode-name " Mode Commands") c-mode-menu))
  3655.   (c-keep-region-active))
  3656.     
  3657.  
  3658. ;; fsets for compatibility with BOCM
  3659. (fset 'electric-c-brace      'c-electric-brace)
  3660. (fset 'electric-c-semi       'c-electric-semi&comma)
  3661. (fset 'electric-c-sharp-sign 'c-electric-pound)
  3662. ;; there is no cc-mode equivalent for electric-c-terminator
  3663. (fset 'mark-c-function       'c-mark-function)
  3664. (fset 'indent-c-exp          'c-indent-exp)
  3665. (fset 'set-c-style           'c-set-style)
  3666. ;; lemacs 19.9 + font-lock + cc-mode - c++-mode lossage
  3667. (fset 'c++-beginning-of-defun 'beginning-of-defun)
  3668. (fset 'c++-end-of-defun 'end-of-defun)
  3669.  
  3670. ;; set up bc warnings for obsolete variables, but for now lets not
  3671. ;; worry about obsolete functions.  maybe later some will be important
  3672. ;; to flag
  3673. (and (memq 'v19 c-emacs-features)
  3674.      (let* ((na "Nothing appropriate.")
  3675.         (vars
  3676.          (list
  3677.           (cons 'c++-c-mode-syntax-table 'c-mode-syntaxt-table)
  3678.           (cons 'c++-tab-always-indent 'c-tab-always-indent)
  3679.           (cons 'c++-always-arglist-indent-p na)
  3680.           (cons 'c++-block-close-brace-offset 'c-offsets-alist)
  3681.           (cons 'c++-paren-as-block-close-p na)
  3682.           (cons 'c++-continued-member-init-offset 'c-offsets-alist)
  3683.           (cons 'c++-member-init-indent 'c-offsets-alist)
  3684.           (cons 'c++-friend-offset na)
  3685.           (cons 'c++-access-specifier-offset 'c-offsets-alist)
  3686.           (cons 'c++-empty-arglist-indent 'c-offsets-alist)
  3687.           (cons 'c++-comment-only-line-offset 'c-comment-only-line-offset)
  3688.           (cons 'c++-C-block-comments-indent-p 'c-block-comments-indent-p)
  3689.           (cons 'c++-cleanup-list 'c-cleanup-list)
  3690.           (cons 'c++-hanging-braces 'c-hanging-braces-alist)
  3691.           (cons 'c++-hanging-member-init-colon 'c-hanging-colons-alist)
  3692.           (cons 'c++-auto-hungry-initial-state
  3693.             "Use `c-auto-newline' and `c-hungry-delete-key' instead.")
  3694.           (cons 'c++-auto-hungry-toggle na)
  3695.           (cons 'c++-relative-offset-p na)
  3696.           (cons 'c++-special-indent-hook 'c-special-indent-hook)
  3697.           (cons 'c++-delete-function 'c-delete-function)
  3698.           (cons 'c++-electric-pound-behavior 'c-electric-pound-behavior)
  3699.           (cons 'c++-hungry-delete-key 'c-hungry-delete-key)
  3700.           (cons 'c++-auto-newline 'c-auto-newline)
  3701.           (cons 'c++-match-header-strongly na)
  3702.           (cons 'c++-defun-header-strong-struct-equivs na)
  3703.           (cons 'c++-version 'c-version)
  3704.           (cons 'c++-mode-help-address 'c-mode-help-address)
  3705.           (cons 'c-indent-level 'c-basic-offset)
  3706.           (cons 'c-brace-imaginary-offset na)
  3707.           (cons 'c-brace-offset 'c-offsets-alist)
  3708.           (cons 'c-argdecl-indent 'c-offsets-alist)
  3709.           (cons 'c-label-offset 'c-offsets-alist)
  3710.           (cons 'c-continued-statement-offset 'c-offsets-alist)
  3711.           (cons 'c-continued-brace-offset 'c-offsets-alist)
  3712.           (cons 'c-default-macroize-column 'c-backslash-column)
  3713.           (cons 'c++-default-macroize-column 'c-backslash-column)
  3714.           )))
  3715.        (mapcar
  3716.     (function
  3717.      (lambda (elt)
  3718.        (make-obsolete-variable (car elt) (cdr elt))))
  3719.     vars)))
  3720.  
  3721. (provide 'cc-mode)
  3722. ;;; cc-mode.el ends here
  3723.  
  3724.