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