Commits

steve  committed ccabf68

Created

  • Participants
  • Tags xemacs

Comments (0)

Files changed (5)

+1998-01-12  SL Baur  <steve@altair.xemacs.org>
+
+	* Makefile: Update to newer package interface.
+
+1998-01-03  SL Baur  <steve@altair.xemacs.org>
+
+	* Makefile: Update to newer package interface.
+
+1997-12-24  SL Baur  <steve@altair.xemacs.org>
+
+	* Makefile: Created.
+# Makefile for Ada mode lisp code
+
+# This file is part of XEmacs.
+
+# XEmacs is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+
+# XEmacs is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with XEmacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+VERSION = 1.02
+PACKAGE = ada
+PKG_TYPE = regular
+REQUIRES =
+CATEGORY = prog
+
+ELCS = ada-mode.elc ada-stmt.elc
+
+include ../../XEmacs.rules
+
+all:: $(ELCS) auto-autoloads.elc custom-load.elc
+
+srckit: srckit-std
+
+binkit: binkit-sourceonly
+;;; ada-mode.el --- An Emacs major-mode for editing Ada source.
+
+;; Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+
+;; Authors: Rolf Ebert      <ebert@inf.enst.fr>
+;;          Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de>
+;; Keywords: languages oop ada
+;; Rolf Ebert's version: 2.27
+
+;; This file is part of XEmacs
+
+;; XEmacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; This mode is a complete rewrite of a major mode for editing Ada 83
+;;; and Ada 95 source code under Emacs-19.  It contains completely new
+;;; indenting code and support for code browsing (see ada-xref).
+
+;;; Synched up with: FSF 20.1
+
+;;; USAGE
+;;; =====
+;;; Emacs should enter Ada mode when you load an Ada source (*.ad[abs]).
+;;;
+;;; When you have entered ada-mode, you may get more info by pressing
+;;; C-h m. You may also get online help describing various functions by:
+;;; C-h d <Name of function you want described>
+
+
+;;; HISTORY
+;;; =======
+;;; The first Ada mode for GNU Emacs was written by V. Broman in
+;;; 1985. He based his work on the already existing Modula-2 mode.
+;;; This was distributed as ada.el in versions of Emacs prior to 19.29.
+;;;
+;;; Lynn Slater wrote an extensive Ada mode in 1989. It consisted of
+;;; several files with support for dired commands and other nice
+;;; things. It is currently available from the PAL
+;;; (wuarchive.wustl.edu:/languages/ada) as ada-mode-1.06a.tar.Z.
+;;;
+;;; The probably very first Ada mode (called electric-ada.el) was
+;;; written by Steven D. Litvintchouk and Steven M. Rosen for the
+;;; Gosling Emacs. L. Slater based his development on ada.el and
+;;; electric-ada.el.
+;;;
+;;; The current Ada mode is a complete rewrite by M. Heritsch and
+;;; R. Ebert.  Some ideas from the Ada mode mailing list have been
+;;; added.  Some of the functionality of L. Slater's mode has not
+;;; (yet) been recoded in this new mode.  Perhaps you prefer sticking
+;;; to his version.
+
+
+;;; KNOWN BUGS
+;;; ==========
+;;;
+;;; In the presence of comments and/or incorrect syntax
+;;; ada-format-paramlist produces weird results.
+;;; -------------------
+;;; Character constants with otherwise syntactic relevant characters
+;;; like `(' or `"' throw indentation off the track.  Fontification
+;;; should work now in Emacs-19.35
+;;; C : constant Character := Character'('"');
+;;; -------------------
+
+
+;;; TODO
+;;; ====
+;;;
+;;; o bodify-single-subprogram
+;;; o make a function "separate" and put it in the corresponding file.
+
+
+
+;;; CREDITS
+;;; =======
+;;;
+;;; Many thanks to
+;;;    Philippe Waroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular,
+;;;    woodruff@stc.llnl.gov (John Woodruff)
+;;;    jj@ddci.dk (Jesper Joergensen)
+;;;    gse@ocsystems.com (Scott Evans)
+;;;    comar@LANG8.CS.NYU.EDU (Cyrille Comar)
+;;;    and others for their valuable hints.
+
+;;;--------------------
+;;;    USER OPTIONS
+;;;--------------------
+
+
+;; ---- customize support
+
+(defgroup ada nil
+  "Major mode for editing Ada source in Emacs"
+  :group 'languages)
+
+;; ---- configure indentation
+
+(defcustom ada-indent 3
+  "*Defines the size of Ada indentation."
+  :type 'integer
+  :group 'ada)
+
+(defcustom ada-broken-indent 2
+  "*# of columns to indent the continuation of a broken line."
+  :type 'integer
+  :group 'ada)
+
+(defcustom ada-label-indent -4
+  "*# of columns to indent a label."
+  :type 'integer
+  :group 'ada)
+
+(defcustom ada-stmt-end-indent 0
+  "*# of columns to indent a statement end keyword in a separate line.
+Examples are 'is', 'loop', 'record', ..."
+  :type 'integer
+  :group 'ada)
+
+(defcustom ada-when-indent 3
+  "*Defines the indentation for 'when' relative to 'exception' or 'case'."
+  :type 'integer
+  :group 'ada)
+
+(defcustom ada-indent-record-rel-type 3
+  "*Defines the indentation for 'record' relative to 'type' or 'use'."
+  :type 'integer
+  :group 'ada)
+
+(defcustom ada-indent-comment-as-code t
+  "*If non-nil, comment-lines get indented as Ada code."
+  :type 'boolean
+  :group 'ada)
+
+(defcustom ada-indent-is-separate t
+  "*If non-nil, 'is separate' or 'is abstract' on a single line are indented."
+  :type 'boolean
+  :group 'ada)
+
+(defcustom ada-indent-to-open-paren t
+  "*If non-nil, indent according to the innermost open parenthesis."
+  :type 'boolean
+  :group 'ada)
+
+(defcustom ada-search-paren-char-count-limit 3000
+  "*Search that many characters for an open parenthesis."
+  :type 'integer
+  :group 'ada)
+
+
+;; ---- other user options
+
+(defcustom ada-tab-policy 'indent-auto
+  "*Control behaviour of the TAB key.
+Must be one of `indent-rigidly', `indent-auto', `gei', `indent-af'
+or `always-tab'.
+
+`indent-rigidly' : always adds ada-indent blanks at the beginning of the line.
+`indent-auto'    : use indentation functions in this file.
+`gei'            : use David K�gedal's Generic Indentation Engine.
+`indent-af'      : use Gary E. Barnes' ada-format.el
+`always-tab'     : do indent-relative."
+  :type '(choice (const indent-auto)
+                 (const indent-rigidly)
+                 (const gei)
+                 (const indent-af)
+                 (const always-tab))
+  :group 'ada)
+
+(defcustom ada-move-to-declaration nil
+  "*If non-nil, `ada-move-to-start' moves point to the subprog declaration,
+not to 'begin'."
+  :type 'boolean
+  :group 'ada)
+
+(defcustom ada-spec-suffix ".ads"
+  "*Suffix of Ada specification files."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-body-suffix ".adb"
+  "*Suffix of Ada body files."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-spec-suffix-as-regexp "\\.ads$"
+  "*Regexp to find Ada specification files."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-body-suffix-as-regexp "\\.adb$"
+  "*Regexp to find Ada body files."
+  :type 'string
+  :group 'ada)
+
+(defvar ada-other-file-alist
+  (list
+   (list ada-spec-suffix-as-regexp (list ada-body-suffix))
+   (list ada-body-suffix-as-regexp (list ada-spec-suffix))
+   )
+  "*Alist of extensions to find given the current file's extension.
+
+This list should contain the most used extensions before the others,
+since the search algorithm searches sequentially through each directory
+specified in `ada-search-directories'.  If a file is not found, a new one
+is created with the first matching extension (`.adb' yields `.ads').")
+
+(defcustom ada-search-directories
+  '("." "/usr/adainclude" "/usr/local/adainclude" "/opt/gnu/adainclude")
+  "*List of directories to search for Ada files.
+See the description for the `ff-search-directories' variable."
+  :type '(repeat (choice :tag "Directory"
+                         (const :tag "default" nil)
+                         (directory :format "%v")))
+  :group 'ada)
+
+(defcustom ada-language-version 'ada95
+  "*Do we program in `ada83' or `ada95'?"
+  :type '(choice (const ada83)
+                 (const ada95))
+  :group 'ada)
+
+(defcustom ada-case-keyword 'downcase-word
+  "*Function to call to adjust the case of Ada keywords.
+It may be `downcase-word', `upcase-word', `ada-loose-case-word' or 
+`capitalize-word'."
+  :type '(choice (const downcase-word)
+                 (const upcase-word)
+                 (const capitalize-word)
+                 (const ada-loose-case-word))
+  :group 'ada)
+
+(defcustom ada-case-identifier 'ada-loose-case-word
+  "*Function to call to adjust the case of an Ada identifier.
+It may be `downcase-word', `upcase-word', `ada-loose-case-word' or 
+`capitalize-word'."
+  :type '(choice (const downcase-word)
+                 (const upcase-word)
+                 (const capitalize-word)
+                 (const ada-loose-case-word))
+  :group 'ada)
+
+(defcustom ada-case-attribute 'capitalize-word
+  "*Function to call to adjust the case of Ada attributes.
+It may be `downcase-word', `upcase-word', `ada-loose-case-word' or 
+`capitalize-word'."
+  :type '(choice (const downcase-word)
+                 (const upcase-word)
+                 (const capitalize-word)
+                 (const ada-loose-case-word))
+  :group 'ada)
+
+(defcustom ada-auto-case t
+  "*Non-nil automatically changes case of preceding word while typing.
+Casing is done according to `ada-case-keyword', `ada-case-identifier'
+and `ada-case-attribute'."
+  :type 'boolean
+  :group 'ada)
+
+(defcustom ada-clean-buffer-before-saving t
+  "*If non-nil, `remove-trailing-spaces' and `untabify' buffer before saving."
+  :type 'boolean
+  :group 'ada)
+
+(defvar ada-mode-hook nil
+  "*List of functions to call when Ada mode is invoked.
+This is a good place to add Ada environment specific bindings.")
+
+(defcustom ada-external-pretty-print-program "aimap"
+  "*External pretty printer to call from within Ada mode."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-tmp-directory "/tmp/"
+  "*Directory to store the temporary file for the Ada pretty printer."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-compile-options "-c"
+  "*Buffer local options passed to the Ada compiler.
+These options are used when the compiler is invoked on the current buffer."
+  :type 'string
+  :group 'ada)
+(make-variable-buffer-local 'ada-compile-options)
+
+(defcustom ada-make-options "-c"
+  "*Buffer local options passed to `ada-compiler-make' (usually `gnatmake').
+These options are used when `gnatmake' is invoked on the current buffer."
+  :type 'string
+  :group 'ada)
+(make-variable-buffer-local 'ada-make-options)
+
+(defcustom ada-compiler-syntax-check "gcc -c -gnats"
+  "*Compiler command with options for syntax checking."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-compiler-make "gnatmake"
+  "*The `make' command for the given compiler."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-fill-comment-prefix "-- "
+  "*This is inserted in the first columns when filling a comment paragraph."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-fill-comment-postfix " --"
+  "*This is inserted at the end of each line when filling a comment paragraph.
+with `ada-fill-comment-paragraph-postfix'."
+  :type 'string
+  :group 'ada)
+
+(defcustom ada-krunch-args "0"
+  "*Argument of gnatkr, a string containing the max number of characters.
+Set to 0, if you don't use crunched filenames."
+  :type 'string
+  :group 'ada)
+
+;;; ---- end of user configurable variables
+
+
+(defvar ada-mode-abbrev-table nil
+  "Abbrev table used in Ada mode.")
+(define-abbrev-table 'ada-mode-abbrev-table ())
+
+(defvar ada-mode-map ()
+  "Local keymap used for Ada mode.")
+
+(defvar ada-mode-syntax-table nil
+  "Syntax table to be used for editing Ada source code.")
+
+(defvar ada-mode-symbol-syntax-table nil
+  "Syntax table for Ada, where `_' is a word constituent.")
+
+(defconst ada-83-keywords
+  "\\<\\(abort\\|abs\\|accept\\|access\\|all\\|and\\|array\\|\
+at\\|begin\\|body\\|case\\|constant\\|declare\\|delay\\|delta\\|\
+digits\\|do\\|else\\|elsif\\|end\\|entry\\|exception\\|exit\\|for\\|\
+function\\|generic\\|goto\\|if\\|in\\|is\\|limited\\|loop\\|mod\\|\
+new\\|not\\|null\\|of\\|or\\|others\\|out\\|package\\|pragma\\|\
+private\\|procedure\\|raise\\|range\\|record\\|rem\\|renames\\|\
+return\\|reverse\\|select\\|separate\\|subtype\\|task\\|terminate\\|\
+then\\|type\\|use\\|when\\|while\\|with\\|xor\\)\\>"
+;  "\\<\\(a\\(b\\(ort\\|s\\)\\|cce\\(pt\\|ss\\)\\|ll\\|nd\\|rray\\|t\\)\\|\
+;b\\(egin\\|ody\\)\\|c\\(ase\\|onstant\\)\\|\
+;d\\(e\\(clare\\|l\\(ay\\|ta\\)\\)\\|igits\\|o\\)\\|\
+;e\\(ls\\(e\\|if\\)\\|n\\(d\\|try\\)\\|x\\(ception\\|it\\)\\)\\|\
+;f\\(or\\|unction\\)\\|g\\(eneric\\|oto\\)\\|i[fns]\\|l\\(imited\\|oop\\)\\|\
+;mod\\|n\\(ew\\|ot\\|ull\\)\\|o\\([fr]\\|thers\\|ut\\)\\|\
+;p\\(ackage\\|r\\(agma\\|ivate\\|ocedure\\)\\)\\|\
+;r\\(a\\(ise\\|nge\\)\\|e\\(cord\\|m\\|names\\|turn\\|verse\\)\\)\\|\
+;s\\(e\\(lect\\|parate\\)\\|ubtype\\)\\|use\\|
+;t\\(ask\\|erminate\\|hen\\|ype\\)\\|w\\(h\\(en\\|ile\\)\\|ith\\)\\|xor\\)\\>"
+  "Regular expression for looking at Ada83 keywords.")
+
+(defconst ada-95-keywords
+  "\\<\\(abort\\|abs\\|abstract\\|accept\\|access\\|aliased\\|\
+all\\|and\\|array\\|at\\|begin\\|body\\|case\\|constant\\|declare\\|\
+delay\\|delta\\|digits\\|do\\|else\\|elsif\\|end\\|entry\\|\
+exception\\|exit\\|for\\|function\\|generic\\|goto\\|if\\|in\\|\
+is\\|limited\\|loop\\|mod\\|new\\|not\\|null\\|of\\|or\\|others\\|\
+out\\|package\\|pragma\\|private\\|procedure\\|protected\\|raise\\|\
+range\\|record\\|rem\\|renames\\|requeue\\|return\\|reverse\\|\
+select\\|separate\\|subtype\\|tagged\\|task\\|terminate\\|then\\|\
+type\\|until\\|use\\|when\\|while\\|with\\|xor\\)\\>"
+  "Regular expression for looking at Ada95 keywords.")
+
+(defvar ada-keywords ada-95-keywords
+  "Regular expression for looking at Ada keywords.")
+
+(defvar ada-ret-binding nil
+  "Variable to save key binding of RET when casing is activated.")
+
+(defvar ada-lfd-binding nil
+  "Variable to save key binding of LFD when casing is activated.")
+
+;;; ---- Regexps to find procedures/functions/packages
+
+(defconst ada-ident-re 
+  "[a-zA-Z0-9_\\.]+"
+  "Regexp matching Ada (qualified) identifiers.")
+
+(defvar ada-procedure-start-regexp
+  "^[ \t]*\\(procedure\\|function\\|task\\)[ \t\n]+\\([a-zA-Z0-9_\\.]+\\)"
+  "Regexp used to find Ada procedures/functions.")
+
+(defvar ada-package-start-regexp
+  "^[ \t]*\\(package\\)"
+  "Regexp used to find Ada packages")
+
+
+;;; ---- regexps for indentation functions
+
+(defvar ada-block-start-re
+  "\\<\\(begin\\|select\\|declare\\|private\\|or\\|generic\\|\
+exception\\|loop\\|else\\|\
+\\(\\(limited\\|abstract\\|tagged\\)[ \t]+\\)*record\\)\\>"
+  "Regexp for keywords starting Ada blocks.")
+
+(defvar ada-end-stmt-re
+  "\\(;\\|=>\\|^[ \t]*separate[ \t]+([a-zA-Z0-9_\\.]+)\\|\
+\\<\\(begin\\|else\\|record\\|loop\\|select\\|do\\|then\\|\
+declare\\|generic\\|private\\)\\>\\|\
+^[ \t]*\\(package\\|procedure\\|function\\)\\>[ \ta-zA-Z0-9_\\.]+\\<is\\>\\|\
+^[ \t]*exception\\>\\)"
+  "Regexp of possible ends for a non-broken statement.
+A new statement starts after these.")
+
+(defvar ada-loop-start-re
+  "\\<\\(for\\|while\\|loop\\)\\>"
+  "Regexp for the start of a loop.")
+
+(defvar ada-subprog-start-re
+  "\\<\\(procedure\\|protected\\|package\\|function\\|\
+task\\|accept\\|entry\\)\\>"
+  "Regexp for the start of a subprogram.")
+
+(defvar ada-named-block-re
+  "[ \t]*[a-zA-Z_0-9]+ *:[^=]"
+  "Regexp of the name of a block or loop.")
+
+
+;; Written by Christian Egli <Christian.Egli@hcsd.hac.com>
+;;
+(defvar ada-imenu-generic-expression
+      '((nil "^\\s-*\\(procedure\\|function\\)\\s-+\\([A-Za-z0-9_]+\\)" 2)
+	("Type Defs" "^\\s-*\\(sub\\)?type\\s-+\\([A-Za-z0-9_]+\\)" 2))
+
+  "Imenu generic expression for Ada mode.  See `imenu-generic-expression'.")
+
+;;;-------------
+;;;  functions
+;;;-------------
+
+(defun ada-xemacs ()
+  (or (string-match "Lucid"  emacs-version)
+      (string-match "XEmacs" emacs-version)))
+
+(defun ada-create-syntax-table ()
+  "Create the syntax table for Ada mode."
+  ;; There are two different syntax-tables.  The standard one declares
+  ;; `_' as a symbol constituent, in the second one, it is a word
+  ;; constituent.  For some search and replacing routines we
+  ;; temporarily switch between the two.
+  (setq ada-mode-syntax-table (make-syntax-table))
+  (set-syntax-table  ada-mode-syntax-table)
+
+  ;; define string brackets (`%' is alternative string bracket, but
+  ;; almost never used as such and throws font-lock and indentation
+  ;; off the track.)
+  (modify-syntax-entry ?%  "$" ada-mode-syntax-table)
+  (modify-syntax-entry ?\" "\"" ada-mode-syntax-table)
+
+  (modify-syntax-entry ?\#  "$" ada-mode-syntax-table)
+
+  (modify-syntax-entry ?:  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\; "." ada-mode-syntax-table)
+  (modify-syntax-entry ?&  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\|  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?+  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?*  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?/  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?=  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?<  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?>  "." ada-mode-syntax-table)
+  (modify-syntax-entry ?$ "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\[ "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\] "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\{ "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\} "." ada-mode-syntax-table)
+  (modify-syntax-entry ?. "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\\ "." ada-mode-syntax-table)
+  (modify-syntax-entry ?\' "." ada-mode-syntax-table)
+
+  ;; a single hyphen is punctuation, but a double hyphen starts a comment
+  (modify-syntax-entry ?-  ". 12" ada-mode-syntax-table)
+
+  ;; and \f and \n end a comment
+  (modify-syntax-entry ?\f  ">   " ada-mode-syntax-table)
+  (modify-syntax-entry ?\n  ">   " ada-mode-syntax-table)
+
+  ;; define what belongs in Ada symbols
+  (modify-syntax-entry ?_ "_" ada-mode-syntax-table)
+
+  ;; define parentheses to match
+  (modify-syntax-entry ?\( "()" ada-mode-syntax-table)
+  (modify-syntax-entry ?\) ")(" ada-mode-syntax-table)
+
+  (setq ada-mode-symbol-syntax-table (copy-syntax-table ada-mode-syntax-table))
+  (modify-syntax-entry ?_ "w" ada-mode-symbol-syntax-table)
+  )
+
+
+;;;###autoload
+(defun ada-mode ()
+  "Ada mode is the major mode for editing Ada code.
+
+Bindings are as follows: (Note: 'LFD' is control-j.)
+
+ Indent line                                          '\\[ada-tab]'
+ Indent line, insert newline and indent the new line. '\\[newline-and-indent]'
+
+ Re-format the parameter-list point is in             '\\[ada-format-paramlist]'
+ Indent all lines in region                           '\\[ada-indent-region]'
+ Call external pretty printer program                 '\\[ada-call-pretty-printer]'
+
+ Adjust case of identifiers and keywords in region    '\\[ada-adjust-case-region]'
+ Adjust case of identifiers and keywords in buffer    '\\[ada-adjust-case-buffer]'
+
+ Call EXTERNAL pretty printer (if you have one)       '\\[ada-call-pretty-printer]'
+
+ Fill comment paragraph                               '\\[ada-fill-comment-paragraph]'
+ Fill comment paragraph and justify each line         '\\[ada-fill-comment-paragraph-justify]'
+ Fill comment paragraph, justify and append postfix   '\\[ada-fill-comment-paragraph-postfix]'
+
+ Next func/proc/task '\\[ada-next-procedure]'  Previous func/proc/task '\\[ada-previous-procedure]'
+ Next package        '\\[ada-next-package]'  Previous package        '\\[ada-previous-package]'
+
+ Goto matching start of current 'end ...;'            '\\[ada-move-to-start]'
+ Goto end of current block                            '\\[ada-move-to-end]'
+
+Comments are handled using standard GNU Emacs conventions, including:
+ Start a comment                                      '\\[indent-for-comment]'
+ Comment region                                       '\\[comment-region]'
+ Uncomment region                                     '\\[ada-uncomment-region]'
+ Continue comment on next line                        '\\[indent-new-comment-line]'
+
+If you use imenu.el:
+ Display index-menu of functions & procedures         '\\[imenu]'
+
+If you use find-file.el:
+ Switch to other file (Body <-> Spec)                 '\\[ff-find-other-file]'
+                                                   or '\\[ff-mouse-find-other-file]
+ Switch to other file in other window                 '\\[ada-ff-other-window]'
+                                                   or '\\[ff-mouse-find-other-file-other-window]
+ If you use this function in a spec and no body is available, it gets created
+ with body stubs.
+
+If you use ada-xref.el:
+ Goto declaration:          '\\[ada-point-and-xref]' on the identifier
+                         or '\\[ada-goto-declaration]' with point on the identifier
+ Complete identifier:       '\\[ada-complete-identifier]'
+ Execute Gnatf:             '\\[ada-gnatf-current]'"
+
+  (interactive)
+  (kill-all-local-variables)
+
+  (make-local-variable 'require-final-newline)
+  (setq require-final-newline t)
+
+  (make-local-variable 'comment-start)
+  (setq comment-start "-- ")
+
+  ;; comment end must be set because it may hold a wrong value if
+  ;; this buffer had been in another mode before. RE
+  (make-local-variable 'comment-end)
+  (setq comment-end "")
+
+  (make-local-variable 'comment-start-skip) ;; used by autofill
+  (setq comment-start-skip "--+[ \t]*")
+
+  (make-local-variable 'indent-line-function)
+  (setq indent-line-function 'ada-indent-current-function)
+
+  (make-local-variable 'fill-column)
+  (setq fill-column 75)
+
+  (make-local-variable 'comment-column)
+  (setq comment-column 40)
+
+  (make-local-variable 'parse-sexp-ignore-comments)
+  (setq parse-sexp-ignore-comments t)
+
+  (make-local-variable 'case-fold-search)
+  (setq case-fold-search t)
+
+  (make-local-variable 'outline-regexp)
+  (setq outline-regexp "[^\n\^M]")
+  (make-local-variable 'outline-level)
+  (setq outline-level 'ada-outline-level)
+
+  (make-local-variable 'fill-paragraph-function)
+  (setq fill-paragraph-function 'ada-fill-comment-paragraph)
+  ;;(make-local-variable 'adaptive-fill-regexp)
+
+  (make-local-variable 'imenu-generic-expression)
+  (setq imenu-generic-expression ada-imenu-generic-expression)
+
+  (if (ada-xemacs) nil ; XEmacs uses properties 
+    (make-local-variable 'font-lock-defaults)
+    (setq font-lock-defaults
+          '((ada-font-lock-keywords
+             ada-font-lock-keywords-1 ada-font-lock-keywords-2)
+            nil t
+            ((?\_ . "w")(?\. . "w"))
+            beginning-of-line
+            (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords)))
+
+    ;; Set up support for find-file.el.
+    (make-variable-buffer-local 'ff-other-file-alist)
+    (make-variable-buffer-local 'ff-search-directories)
+    (setq ff-other-file-alist   'ada-other-file-alist
+          ff-search-directories 'ada-search-directories
+          ff-pre-load-hooks     'ff-which-function-are-we-in
+          ff-post-load-hooks    'ff-set-point-accordingly
+          ff-file-created-hooks 'ada-make-body))
+
+  (setq major-mode 'ada-mode)
+  (setq mode-name "Ada")
+
+  (use-local-map ada-mode-map)
+
+  (if ada-mode-syntax-table
+      (set-syntax-table ada-mode-syntax-table)
+    (ada-create-syntax-table))
+
+  (if ada-clean-buffer-before-saving
+      (progn
+	;; remove all spaces at the end of lines in the whole buffer.
+	(add-hook 'local-write-file-hooks 'ada-remove-trailing-spaces)
+	;; convert all tabs to the correct number of spaces.
+	(add-hook 'local-write-file-hooks 'ada-untabify-buffer)))
+
+
+  ;; add menu 'Ada' to the menu bar
+  (ada-add-ada-menu)
+
+  (run-hooks 'ada-mode-hook)
+
+  ;; the following has to be done after running the ada-mode-hook
+  ;; because users might want to set the values of these variable
+  ;; inside the hook (MH)
+
+  (cond ((eq ada-language-version 'ada83)
+         (setq ada-keywords ada-83-keywords))
+        ((eq ada-language-version 'ada95)
+         (setq ada-keywords ada-95-keywords)))
+
+  (if ada-auto-case
+      (ada-activate-keys-for-case)))
+
+
+;;;--------------------------
+;;;  Compile support
+;;;--------------------------
+
+(defun ada-check-syntax ()
+  "Check syntax of the current buffer. 
+Uses the function `compile' to execute `ada-compiler-syntax-check'."
+  (interactive)
+  (let ((old-compile-command compile-command))
+    (setq compile-command (concat ada-compiler-syntax-check
+                                  (if (eq ada-language-version 'ada83)
+                                      "-gnat83 ")
+                                  " " ada-compile-options " "
+                                  (buffer-name)))
+    (setq compile-command (read-from-minibuffer
+                           "enter command for syntax check: "
+                           compile-command))
+    (compile compile-command)
+    ;; restore old compile-command
+    (setq compile-command old-compile-command)))
+
+(defun ada-make-local ()
+  "Bring current Ada unit up-to-date. 
+Uses the function `compile' to execute `ada-compile-make'."
+  (interactive)
+  (let ((old-compile-command compile-command))
+    (setq compile-command (concat ada-compiler-make
+                                  " " ada-make-options " "
+                                  (buffer-name)))
+    (setq compile-command (read-from-minibuffer
+                           "enter command for local make: "
+                           compile-command))
+    (compile compile-command)
+    ;; restore old compile-command
+    (setq compile-command old-compile-command)))
+
+
+
+
+;;;--------------------------
+;;;  Fill Comment Paragraph
+;;;--------------------------
+
+(defun ada-fill-comment-paragraph-justify ()
+  "Fills current comment paragraph and justifies each line as well."
+  (interactive)
+  (ada-fill-comment-paragraph t))
+
+
+(defun ada-fill-comment-paragraph-postfix ()
+  "Fills current comment paragraph and justifies each line as well.
+Prompts for a postfix to be appended to each line."
+  (interactive)
+  (ada-fill-comment-paragraph t t))
+
+
+(defun ada-fill-comment-paragraph (&optional justify postfix)
+  "Fills the current comment paragraph.
+If JUSTIFY is non-nil, each line is justified as well.
+If POSTFIX and JUSTIFY are  non-nil, `ada-fill-comment-postfix' is appended
+to each filled and justified line.
+If `ada-indent-comment-as-code' is non-nil, the paragraph is idented."
+  (interactive "P")
+  (let ((opos (point-marker))
+        (begin nil)
+        (end nil)
+        (end-2 nil)
+        (indent nil)
+        (ada-fill-comment-old-postfix "")
+        (fill-prefix nil))
+
+    ;; check if inside comment
+    (if (not (ada-in-comment-p))
+        (error "not inside comment"))
+
+    ;; prompt for postfix if wanted
+    (if (and justify
+             postfix)
+        (setq ada-fill-comment-postfix
+              (read-from-minibuffer "enter new postfix string: "
+                                    ada-fill-comment-postfix)))
+
+    ;; prompt for old postfix to remove if necessary
+    (if (and justify
+             postfix)
+        (setq ada-fill-comment-old-postfix
+              (read-from-minibuffer "enter already existing postfix string: "
+                                    ada-fill-comment-postfix)))
+
+    ;;
+    ;; find limits of paragraph
+    ;;
+    (message "filling comment paragraph ...")
+    (save-excursion
+      (back-to-indentation)
+      ;; find end of paragraph
+      (while (and (looking-at "--.*$")
+                  (not (looking-at "--[ \t]*$")))
+        (forward-line 1)
+        (back-to-indentation))
+      (beginning-of-line)
+      (setq end (point-marker))
+      (goto-char opos)
+      ;; find begin of paragraph
+      (back-to-indentation)
+      (while (and (looking-at "--.*$")
+                  (not (looking-at "--[ \t]*$")))
+        (forward-line -1)
+        (back-to-indentation))
+      (forward-line 1)
+      ;; get indentation to calculate width for filling
+      (ada-indent-current)
+      (back-to-indentation)
+      (setq indent (current-column))
+      (setq begin (point-marker)))
+
+    ;; delete old postfix if necessary
+    (if (and justify
+             postfix)
+        (save-excursion
+          (goto-char begin)
+          (while (re-search-forward (concat ada-fill-comment-old-postfix
+                                            "\n")
+                                    end t)
+            (replace-match "\n"))))
+
+    ;; delete leading whitespace and uncomment
+    (save-excursion
+      (goto-char begin)
+      (beginning-of-line)
+      (while (re-search-forward "^[ \t]*--[ \t]*" end t)
+        (replace-match "")))
+
+    ;; calculate fill width
+    (setq fill-column (- fill-column indent
+                         (length ada-fill-comment-prefix)
+                         (if postfix
+                             (length ada-fill-comment-postfix)
+                           0)))
+    ;; fill paragraph
+    (fill-region begin (1- end) justify)
+    (setq fill-column (+ fill-column indent
+                         (length ada-fill-comment-prefix)
+                         (if postfix
+                             (length ada-fill-comment-postfix)
+                           0)))
+   ;; find end of second last line
+    (save-excursion
+      (goto-char end)
+      (forward-line -2)
+      (end-of-line)
+      (setq end-2 (point-marker)))
+
+    ;; re-comment and re-indent region
+    (save-excursion
+      (goto-char begin)
+      (indent-to indent)
+      (insert ada-fill-comment-prefix)
+      (while (re-search-forward "\n" (1- end-2) t)
+        (replace-match (concat "\n" ada-fill-comment-prefix))
+        (beginning-of-line)
+        (indent-to indent)))
+
+    ;; append postfix if wanted
+    (if (and justify
+             postfix
+             ada-fill-comment-postfix)
+        (progn
+          ;; append postfix up to there
+          (save-excursion
+            (goto-char begin)
+            (while (re-search-forward "\n" (1- end-2) t)
+              (replace-match (concat ada-fill-comment-postfix "\n")))
+
+            ;; fill last line and append postfix
+            (end-of-line)
+            (insert-char ?
+                         (- fill-column
+                            (current-column)
+                            (length ada-fill-comment-postfix)))
+            (insert ada-fill-comment-postfix))))
+
+    ;; delete the extra line that gets inserted somehow(??)
+    (save-excursion
+      (goto-char (1- end))
+      (end-of-line)
+      (delete-char 1))
+
+     (message "filling comment paragraph ... done")
+    (goto-char opos))
+  t)
+
+
+;;;--------------------------------;;;
+;;;  Call External Pretty Printer  ;;;
+;;;--------------------------------;;;
+
+(defun ada-call-pretty-printer ()
+  "Calls the external Pretty Printer.
+The name is specified in `ada-external-pretty-print-program'.  Saves the
+current buffer in a directory specified by `ada-tmp-directory',
+starts the pretty printer as external process on that file and then
+reloads the beautified program in the buffer and cleans up
+`ada-tmp-directory'."
+  (interactive)
+  (let ((filename-with-path buffer-file-name)
+        (curbuf (current-buffer))
+        (orgpos (point))
+        (mesgbuf nil) ;; for byte-compiling
+        (file-path (file-name-directory buffer-file-name))
+        (filename-without-path (file-name-nondirectory buffer-file-name))
+        (tmp-file-with-directory
+         (concat ada-tmp-directory
+                 (file-name-nondirectory buffer-file-name))))
+    ;;
+    ;; save buffer in temporary file
+    ;;
+    (message "saving current buffer to temporary file ...")
+    (write-file tmp-file-with-directory)
+    (auto-save-mode nil)
+    (message "saving current buffer to temporary file ... done")
+    ;;
+    ;; call external pretty printer program
+    ;;
+
+    (message "running external pretty printer ...")
+    ;; create a temporary buffer for messages of pretty printer
+    (setq mesgbuf (get-buffer-create "Pretty Printer Messages"))
+    ;; execute pretty printer on temporary file
+    (call-process ada-external-pretty-print-program
+                  nil mesgbuf t
+                  tmp-file-with-directory)
+    ;; display messages if there are some
+    (if (buffer-modified-p mesgbuf)
+        ;; show the message buffer
+        (display-buffer mesgbuf t)
+      ;; kill the message buffer
+      (kill-buffer mesgbuf))
+    (message "running external pretty printer ... done")
+    ;;
+    ;; kill current buffer and load pretty printer output
+    ;; or restore old buffer
+    ;;
+    (if (y-or-n-p
+         "Really replace current buffer with pretty printer output ? ")
+        (progn
+          (set-buffer-modified-p nil)
+          (kill-buffer curbuf)
+          (find-file tmp-file-with-directory))
+      (message "old buffer contents restored"))
+    ;;
+    ;; delete temporary file and restore information of current buffer
+    ;;
+    (delete-file tmp-file-with-directory)
+    (set-visited-file-name filename-with-path)
+    (auto-save-mode t)
+    (goto-char orgpos)))
+
+
+;;;---------------
+;;;  auto-casing
+;;;---------------
+
+;; from Philippe Waroquiers <philippe@cfmu.eurocontrol.be>
+;; modified by RE and MH
+
+(defun ada-after-keyword-p ()
+  ;; returns t if cursor is after a keyword.
+  (save-excursion
+    (forward-word -1)
+    (and (save-excursion
+           (or
+            (= (point) (point-min))
+            (backward-char 1))
+           (not (looking-at "_")))     ; (MH)
+         (looking-at (concat ada-keywords "[^_]")))))
+
+(defun ada-in-char-const-p ()
+  ;; Returns t if point is inside a character constant.
+  ;; We assume to be in a constant if the previous and the next character
+  ;; are "'". 
+  (save-excursion
+    (if (> (point) 1)
+        (and
+         (progn
+           (forward-char 1)
+           (looking-at "'"))
+         (progn
+           (forward-char -2)
+           (looking-at "'")))
+      nil)))
+
+
+(defun ada-adjust-case (&optional force-identifier)
+  "Adjust the case of the word before the just typed character.
+Respect options `ada-case-keyword', `ada-case-identifier', and 
+`ada-case-attribute'.
+If FORCE-IDENTIFIER is non-nil then also adjust keyword as identifier." ; (MH)
+  (forward-char -1)
+  (if (and (> (point) 1) (not (or (ada-in-string-p)
+                                  (ada-in-comment-p)
+                                  (ada-in-char-const-p))))
+      (if (eq (char-syntax (char-after (1- (point)))) ?w)
+	  (if (save-excursion
+		(forward-word -1)
+		(or (= (point) (point-min))
+		    (backward-char 1))
+		(looking-at "'"))
+	      (funcall ada-case-attribute -1)
+	    (if (and
+		 (not force-identifier) ; (MH)
+		 (ada-after-keyword-p))
+		(funcall ada-case-keyword -1)
+	      (funcall ada-case-identifier -1)))))
+  (forward-char 1))
+
+
+(defun ada-adjust-case-interactive (arg)
+  (interactive "P")
+  (let ((lastk last-command-char))
+    (cond ((or (eq lastk ?\n)
+               (eq lastk ?\r))
+           ;; horrible kludge
+           (insert " ")
+           (ada-adjust-case)
+           ;; horrible dekludge
+           (delete-backward-char 1)
+           ;; some special keys and their bindings
+           (cond
+            ((eq lastk ?\n)
+             (funcall ada-lfd-binding))
+            ((eq lastk ?\r)
+             (funcall ada-ret-binding))))
+          ((eq lastk ?\C-i) (ada-tab))
+          ((self-insert-command (prefix-numeric-value arg))))
+    ;; if there is a keyword in front of the underscore
+    ;; then it should be part of an identifier (MH)
+    (if (eq lastk ?_)
+        (ada-adjust-case t)
+      (ada-adjust-case))))
+
+
+(defun ada-activate-keys-for-case ()
+  ;; save original keybindings to allow swapping ret/lfd
+  ;; when casing is activated
+  ;; the 'or ...' is there to be sure that the value will not
+  ;; be changed again when Ada mode is called more than once (MH)
+  (or ada-ret-binding
+      (setq ada-ret-binding (key-binding "\C-M")))
+  (or ada-lfd-binding
+      (setq ada-lfd-binding (key-binding "\C-j")))
+  ;; call case modifying function after certain keys.
+  (mapcar (function (lambda(key) (define-key
+                                   ada-mode-map
+                                   (char-to-string key)
+                                   'ada-adjust-case-interactive)))
+          '( ?` ?~ ?! ?@ ?# ?$ ?% ?^ ?& ?* ?( ?)  ?- ?= ?+ ?[ ?{ ?] ?}
+                ?_ ?\\ ?| ?\; ?: ?' ?\" ?< ?, ?. ?> ?? ?/ ?\n 32 ?\r )))
+;; deleted ?\t from above list
+
+;;
+;; added by MH
+;;
+(defun ada-loose-case-word (&optional arg)
+  "Capitalizes the first letter and the letters following `_'.
+ARG is ignored, it's there to fit the standard casing functions' style."
+  (let ((pos (point))
+        (first t))
+    (skip-chars-backward "a-zA-Z0-9_")
+    (while (or first
+               (search-forward "_" pos t))
+      (and first
+           (setq first nil))
+      (insert-char (upcase (following-char)) 1)
+      (delete-char 1))
+    (goto-char pos)))
+
+
+;;
+;; added by MH
+;; modified by JSH to handle attributes
+;;
+(defun ada-adjust-case-region (from to)
+  "Adjusts the case of all words in the region.
+Attention: This function might take very long for big regions !"
+  (interactive "*r")
+  (let ((begin nil)
+        (end nil)
+        (keywordp nil)
+        (attribp nil))
+    (unwind-protect
+	(save-excursion
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+	  (goto-char to)
+	  ;;
+	  ;; loop: look for all identifiers, keywords, and attributes
+	  ;;
+	  (while (re-search-backward
+		  "[^a-zA-Z0-9_]\\([a-zA-Z0-9_]+\\)[^a-zA-Z0-9_]"
+		  from
+		  t)
+	    ;;
+	    ;; print status message
+	    ;;
+	    (message "adjusting case ... %5d characters left" (- (point) from))
+	    (setq attribp (looking-at "'[a-zA-Z0-9_]+[^']"))
+	    (forward-char 1)
+	    (or
+	     ;; do nothing if it is a string or comment
+	     (ada-in-string-or-comment-p)
+	     (progn
+	       ;;
+	       ;; get the identifier or keyword or attribute
+	       ;;
+	       (setq begin (point))
+	       (setq keywordp (looking-at (concat ada-keywords "[^_]")))
+	       (skip-chars-forward "a-zA-Z0-9_")
+	       ;;
+	       ;; casing according to user-option
+	       ;;
+	       (if keywordp
+		   (funcall ada-case-keyword -1)
+		 (if attribp
+		     (funcall ada-case-attribute -1)
+		   (funcall ada-case-identifier -1)))
+	       (goto-char begin))))
+	  (message "adjusting case ... done"))
+      (set-syntax-table ada-mode-syntax-table))))
+
+
+;;
+;; added by MH
+;;
+(defun ada-adjust-case-buffer ()
+  "Adjusts the case of all words in the whole buffer.
+ATTENTION: This function might take very long for big buffers !"
+  (interactive "*")
+  (ada-adjust-case-region (point-min) (point-max)))
+
+
+;;;------------------------;;;
+;;; Format Parameter Lists ;;;
+;;;------------------------;;;
+
+(defun ada-format-paramlist ()
+  "Reformats a parameter list.
+ATTENTION:  1) Comments inside the list are killed !
+            2) If the syntax is not correct (especially, if there are
+               semicolons missing), it can get totally confused !
+In such a case, use `undo', correct the syntax and try again."
+
+  (interactive)
+  (let ((begin nil)
+        (end nil)
+        (delend nil)
+        (paramlist nil))
+    (unwind-protect
+	(progn 
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+
+	  ;; check if really inside parameter list
+	  (or (ada-in-paramlist-p)
+	      (error "not in parameter list"))
+	  ;;
+	  ;; find start of current parameter-list
+	  ;;
+	  (ada-search-ignore-string-comment
+           (concat ada-subprog-start-re "\\|\\<body\\>" ) t nil)
+	  (ada-search-ignore-string-comment "(" nil nil t)
+	  (backward-char 1)
+	  (setq begin (point))
+
+	  ;;
+	  ;; find end of parameter-list
+	  ;;
+	  (forward-sexp 1)
+	  (setq delend (point))
+	  (delete-char -1)
+
+	  ;;
+	  ;; find end of last parameter-declaration
+	  ;;
+	  (ada-search-ignore-string-comment "[^ \t\n]" t nil t)
+	  (forward-char 1)
+	  (setq end (point))
+
+	  ;;
+	  ;; build a list of all elements of the parameter-list
+	  ;;
+	  (setq paramlist (ada-scan-paramlist (1+ begin) end))
+
+	  ;;
+	  ;; delete the original parameter-list
+	  ;;
+	  (delete-region begin (1- delend))
+
+	  ;;
+	  ;; insert the new parameter-list
+	  ;;
+	  (goto-char begin)
+	  (ada-insert-paramlist paramlist))
+
+      ;;
+      ;; restore syntax-table
+      ;;
+      (set-syntax-table ada-mode-syntax-table)
+      )))
+
+
+(defun ada-scan-paramlist (begin end)
+  ;; Scans a parameter-list  between BEGIN and END and returns a list
+  ;; of its contents.
+  ;; The list has the following format:
+  ;;
+  ;;   Name of Param  in? out? access?  Name of Type   Default-Exp or nil
+  ;;
+  ;; ( ('Name_Param_1' t   nil    t      Type_Param_1   ':= expression')
+  ;;   ('Name_Param_2' nil nil    t      Type_Param_2    nil) )
+
+  (let ((paramlist (list))
+        (param (list))
+        (notend t)
+        (apos nil)
+        (epos nil)
+        (semipos nil)
+        (match-cons nil))
+
+    (goto-char begin)
+    ;;
+    ;; loop until end of last parameter
+    ;;
+    (while notend
+
+      ;;
+      ;; find first character of parameter-declaration
+      ;;
+      (ada-goto-next-non-ws)
+      (setq apos (point))
+
+      ;;
+      ;; find last character of parameter-declaration
+      ;;
+      (if (setq match-cons
+                (ada-search-ignore-string-comment "[ \t\n]*;" nil end t))
+          (progn
+            (setq epos (car match-cons))
+            (setq semipos (cdr match-cons)))
+        (setq epos end))
+
+      ;;
+      ;; read name(s) of parameter(s)
+      ;;
+      (goto-char apos)
+      (looking-at "\\([a-zA-Z0-9_, \t\n]*[a-zA-Z0-9_]\\)[ \t\n]*:[^=]")
+
+      (setq param (list (buffer-substring (match-beginning 1)
+                                          (match-end 1))))
+      (ada-search-ignore-string-comment ":" nil epos t)
+
+      ;;
+      ;; look for 'in'
+      ;;
+      (setq apos (point))
+      (setq param
+            (append param
+                    (list
+                     (consp
+                      (ada-search-ignore-string-comment "\\<in\\>"
+                                                        nil
+                                                        epos
+                                                        t)))))
+
+      ;;
+      ;; look for 'out'
+      ;;
+      (goto-char apos)
+      (setq param
+            (append param
+                    (list
+                     (consp
+                      (ada-search-ignore-string-comment "\\<out\\>"
+                                                        nil
+                                                        epos
+                                                        t)))))
+
+      ;;
+      ;; look for 'access'
+      ;;
+      (goto-char apos)
+      (setq param
+            (append param
+                    (list
+                     (consp
+                      (ada-search-ignore-string-comment "\\<access\\>"
+                                                        nil
+                                                        epos
+                                                        t)))))
+
+      ;;
+      ;; skip 'in'/'out'/'access'
+      ;;
+      (goto-char apos)
+      (ada-goto-next-non-ws)
+      (while (looking-at "\\<\\(in\\|out\\|access\\)\\>")
+        (forward-word 1)
+        (ada-goto-next-non-ws))
+
+      ;;
+      ;; read type of parameter 
+      ;;
+      (looking-at "\\<[a-zA-Z0-9_\\.\\']+\\>")
+      (setq param
+            (append param
+                    (list
+                     (buffer-substring (match-beginning 0)
+                                       (match-end 0)))))
+
+      ;;
+      ;; read default-expression, if there is one
+      ;;
+      (goto-char (setq apos (match-end 0)))
+      (setq param
+            (append param
+                    (list
+                     (if (setq match-cons
+                               (ada-search-ignore-string-comment ":="
+                                                                 nil
+                                                                 epos
+                                                                 t))
+                         (buffer-substring (car match-cons)
+                                           epos)
+                       nil))))
+      ;;
+      ;; add this parameter-declaration to the list
+      ;;
+      (setq paramlist (append paramlist (list param)))
+
+      ;;
+      ;; check if it was the last parameter
+      ;;
+      (if (eq epos end)
+          (setq notend nil)
+        (goto-char semipos))
+
+      ) ; end of loop
+
+    (reverse paramlist)))
+
+
+(defun ada-insert-paramlist (paramlist)
+  ;; Inserts a formatted PARAMLIST in the buffer.
+  ;; See doc of `ada-scan-paramlist' for the format.
+  (let ((i (length paramlist))
+        (parlen 0)
+        (typlen 0)
+        (temp 0)
+        (inp nil)
+        (outp nil)
+        (accessp nil)
+        (column nil)
+        (orgpoint 0)
+        (firstcol nil))
+
+    ;;
+    ;; loop until last parameter
+    ;;
+    (while (not (zerop i))
+      (setq i (1- i))
+
+      ;;
+      ;; get max length of parameter-name
+      ;;
+      (setq parlen
+            (if (<= parlen (setq temp
+                              (length (nth 0 (nth i paramlist)))))
+                temp
+              parlen))
+
+      ;;
+      ;; get max length of type-name
+      ;;
+      (setq typlen
+            (if (<= typlen (setq temp
+                              (length (nth 4 (nth i paramlist)))))
+                temp
+              typlen))
+
+      ;;
+      ;; is there any 'in' ?
+      ;;
+      (setq inp
+            (or inp
+                (nth 1 (nth i paramlist))))
+
+      ;;
+      ;; is there any 'out' ?
+      ;;
+      (setq outp
+            (or outp
+                (nth 2 (nth i paramlist))))
+
+      ;;
+      ;; is there any 'access' ?
+      ;;
+      (setq accessp
+            (or accessp
+                (nth 3 (nth i paramlist))))) ; end of loop
+
+    ;;
+    ;; does paramlist already start on a separate line ?
+    ;;
+    (if (save-excursion
+          (re-search-backward "^.\\|[^ \t]" nil t)
+          (looking-at "^."))
+        ;; yes => re-indent it
+        (ada-indent-current)
+      ;;
+      ;; no => insert newline and indent it
+      ;;
+      (progn
+        (ada-indent-current)
+        (newline)
+        (delete-horizontal-space)
+        (setq orgpoint (point))
+        (setq column (save-excursion
+                       (funcall (ada-indent-function) orgpoint)))
+        (indent-to column)
+        ))
+
+    (insert "(")
+
+    (setq firstcol (current-column))
+    (setq i (length paramlist))
+
+    ;;
+    ;; loop until last parameter
+    ;;
+    (while (not (zerop i))
+      (setq i (1- i))
+      (setq column firstcol)
+
+      ;;
+      ;; insert parameter-name, space and colon
+      ;;
+      (insert (nth 0 (nth i paramlist)))
+      (indent-to (+ column parlen 1))
+      (insert ": ")
+      (setq column (current-column))
+
+      ;;
+      ;; insert 'in' or space
+      ;;
+      (if (nth 1 (nth i paramlist))
+          (insert "in ")
+        (if (and
+             (or inp
+                 accessp)
+             (not (nth 3 (nth i paramlist))))
+            (insert "   ")))
+
+      ;;
+      ;; insert 'out' or space
+      ;;
+      (if (nth 2 (nth i paramlist))
+          (insert "out ")
+        (if (and
+             (or outp
+                 accessp)
+             (not (nth 3 (nth i paramlist))))
+            (insert "    ")))
+
+      ;;
+      ;; insert 'access'
+      ;;
+      (if (nth 3 (nth i paramlist))
+          (insert "access "))
+
+      (setq column (current-column))
+
+      ;;
+      ;; insert type-name and, if necessary, space and default-expression
+      ;;
+      (insert (nth 4 (nth i paramlist)))
+      (if (nth 5 (nth i paramlist))
+          (progn
+            (indent-to (+ column typlen 1))
+            (insert (nth 5 (nth i paramlist)))))
+
+      ;;
+      ;; check if it was the last parameter
+      ;;
+      (if (not (zerop i))
+          ;; no => insert ';' and newline and indent
+          (progn
+            (insert ";")
+            (newline)
+            (indent-to firstcol))
+        ;; yes
+        (insert ")"))
+
+      ) ; end of loop
+
+    ;;
+    ;; if anything follows, except semicolon:
+    ;; put it in a new line and indent it
+    ;;
+    (if (not (looking-at "[ \t]*[;\n]"))
+        (ada-indent-newline-indent))
+
+    ))
+
+
+;;;----------------------------;;;
+;;; Move To Matching Start/End ;;;
+;;;----------------------------;;;
+
+(defun ada-move-to-start ()
+  "Moves point to the matching start of the current Ada structure."
+  (interactive)
+  (let ((pos (point)))
+    (unwind-protect
+	(progn
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+
+	  (message "searching for block start ...")
+	  (save-excursion
+	    ;;
+	    ;; do nothing if in string or comment or not on 'end ...;'
+	    ;;            or if an error occurs during processing
+	    ;;
+	    (or
+	     (ada-in-string-or-comment-p)
+	     (and (progn
+		    (or (looking-at "[ \t]*\\<end\\>")
+			(backward-word 1))
+		    (or (looking-at "[ \t]*\\<end\\>")
+			(backward-word 1))
+		    (or (looking-at "[ \t]*\\<end\\>")
+			(error "not on end ...;")))
+		  (ada-goto-matching-start 1)
+		  (setq pos (point))
+
+		  ;;
+		  ;; on 'begin' => go on, according to user option
+		  ;;
+		  ada-move-to-declaration
+		  (looking-at "\\<begin\\>")
+		  (ada-goto-matching-decl-start)
+		  (setq pos (point))))
+
+	    ) ; end of save-excursion
+
+	  ;; now really move to the found position
+	  (goto-char pos)
+	  (message "searching for block start ... done"))
+
+      ;;
+      ;; restore syntax-table
+      ;;
+      (set-syntax-table ada-mode-syntax-table))))
+
+
+(defun ada-move-to-end ()
+  "Moves point to the matching end of the current block around point.
+Moves to 'begin' if in a declarative part."
+  (interactive)
+  (let ((pos (point))
+        (decstart nil)
+        (packdecl nil))
+    (unwind-protect
+	(progn
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+
+	  (message "searching for block end ...")
+	  (save-excursion
+
+	    (forward-char 1)
+	    (cond
+	     ;; directly on 'begin'
+	     ((save-excursion
+		(ada-goto-previous-word)
+		(looking-at "\\<begin\\>"))
+	      (ada-goto-matching-end 1))
+	     ;; on first line of defun declaration
+	     ((save-excursion
+		(and (ada-goto-stmt-start)
+		     (looking-at "\\<function\\>\\|\\<procedure\\>" )))
+	      (ada-search-ignore-string-comment "\\<begin\\>"))
+	     ;; on first line of task declaration
+	     ((save-excursion
+		(and (ada-goto-stmt-start)
+		     (looking-at "\\<task\\>" )
+		     (forward-word 1)
+		     (ada-search-ignore-string-comment "[^ \n\t]")
+		     (not (backward-char 1))
+		     (looking-at "\\<body\\>")))
+	      (ada-search-ignore-string-comment "\\<begin\\>"))
+	     ;; accept block start
+	     ((save-excursion
+		(and (ada-goto-stmt-start)
+		     (looking-at "\\<accept\\>" )))
+	      (ada-goto-matching-end 0))
+	     ;; package start
+	     ((save-excursion
+		(and (ada-goto-matching-decl-start t)
+		     (looking-at "\\<package\\>")))
+	      (ada-goto-matching-end 1))
+	     ;; inside a 'begin' ... 'end' block
+	     ((save-excursion
+		(ada-goto-matching-decl-start t))
+	      (ada-search-ignore-string-comment "\\<begin\\>"))
+	     ;; (hopefully ;-) everything else
+	     (t
+	      (ada-goto-matching-end 1)))
+	    (setq pos (point))
+
+	    ) ; end of save-excursion
+
+	  ;; now really move to the found position
+	  (goto-char pos)
+	  (message "searching for block end ... done"))
+      
+      ;;
+      ;; restore syntax-table
+      ;;
+      (set-syntax-table ada-mode-syntax-table))))
+
+
+;;;-----------------------------;;;
+;;;  Functions For Indentation  ;;;
+;;;-----------------------------;;;
+
+;; ---- main functions for indentation
+
+(defun ada-indent-region (beg end)
+  "Indents the region using `ada-indent-current' on each line."
+  (interactive "*r")
+  (goto-char beg)
+  (let ((block-done 0)
+	(lines-remaining (count-lines beg end))
+	(msg (format "indenting %4d lines %%4d lines remaining ..."
+		     (count-lines beg end)))
+        (endmark (copy-marker end)))
+    ;; catch errors while indenting
+    (condition-case err
+        (while (< (point) endmark)
+          (if (> block-done 9)
+              (progn (message msg lines-remaining)
+                     (setq block-done 0)))
+	  (if (looking-at "^$") nil
+	    (ada-indent-current))
+          (forward-line 1)
+	  (setq block-done (1+ block-done))
+	  (setq lines-remaining (1- lines-remaining)))
+      ;; show line number where the error occurred
+      (error
+       (error "line %d: %s" (1+ (count-lines (point-min) (point))) err) nil))
+    (message "indenting ... done")))
+
+
+(defun ada-indent-newline-indent ()
+  "Indents the current line, inserts a newline and then indents the new line."
+  (interactive "*")
+  (ada-indent-current)
+  (newline)
+  (ada-indent-current))
+
+
+(defun ada-indent-current ()
+  "Indents current line as Ada code.
+This works by two steps:
+ 1) It moves point to the end of the previous code line.
+    Then it calls the function to calculate the indentation for the
+    following line as if a newline would be inserted there.
+    The calculated column # is saved and the old position of point
+    is restored.
+ 2) Then another function is called to calculate the indentation for
+    the current line, based on the previously calculated column #."
+
+  (interactive)
+
+  (unwind-protect
+      (progn
+	(set-syntax-table ada-mode-symbol-syntax-table)
+
+	(let ((line-end)
+	      (orgpoint (point-marker))
+	      (cur-indent)
+	      (prev-indent)
+	      (prevline t))
+
+	  ;;
+	  ;; first step
+	  ;;
+	  (save-excursion
+	    (if (ada-goto-prev-nonblank-line t)
+		;;
+		;; we are not in the first accessible line in the buffer
+		;;
+		(progn
+		  ;;(end-of-line)
+		  ;;(forward-char 1)
+		  ;; we are already at the BOL
+		  (forward-line 1)
+		  (setq line-end (point))
+		  (setq prev-indent
+			(save-excursion
+			  (funcall (ada-indent-function) line-end))))
+              (progn                    ; first line of buffer -> set indent
+                (beginning-of-line)     ; to 0
+                (delete-horizontal-space)
+                (setq prevline nil))))
+
+	  (if prevline
+	      ;;
+	      ;; we are not in the first accessible line in the buffer
+	      ;;
+	      (progn
+		;;
+		;; second step
+		;;
+		(back-to-indentation)
+		(setq cur-indent (ada-get-current-indent prev-indent))
+                ;; only reindent if indentation is different then the current
+                (if (= (current-column) cur-indent)
+                    nil
+		  (delete-horizontal-space)
+                  (indent-to cur-indent))
+		;;
+		;; restore position of point
+		;;
+		(goto-char orgpoint)
+		(if (< (current-column) (current-indentation))
+		    (back-to-indentation))))))
+
+    ;;
+    ;; restore syntax-table
+    ;;
+    (set-syntax-table ada-mode-syntax-table)))
+
+
+(defun ada-get-current-indent (prev-indent)
+  ;; Returns the column # to indent the current line to.
+  ;; PREV-INDENT is the indentation resulting from the previous lines.
+  (let ((column nil)
+        (pos nil)
+        (match-cons nil))
+
+    (cond
+     ;;
+     ;; in open parenthesis, but not in parameter-list
+     ;;
+     ((and
+       ada-indent-to-open-paren
+       (not (ada-in-paramlist-p))
+       (setq column (ada-in-open-paren-p)))
+      ;; check if we have something like this  (Table_Component_Type =>
+      ;;                                          Source_File_Record,)
+      (save-excursion
+        (if (and (ada-search-ignore-string-comment "[^ \t]" t nil)
+                 (looking-at "\n")
+                 (ada-search-ignore-string-comment "[^ \t\n]" t nil)
+                 (looking-at ">"))
+            (setq column (+ ada-broken-indent column))))
+      column)
+
+     ;;
+     ;; end
+     ;;
+     ((looking-at "\\<end\\>")
+      (let ((label 0))
+        (save-excursion
+          (ada-goto-matching-start 1)
+
+          ;;
+          ;; found 'loop' => skip back to 'while' or 'for'
+          ;;                 if 'loop' is not on a separate line
+          ;;
+          (if (and
+               (looking-at "\\<loop\\>")
+               (save-excursion
+                 (back-to-indentation)
+                 (not (looking-at "\\<loop\\>"))))
+              (if (save-excursion
+                    (and
+                     (setq match-cons
+                           (ada-search-ignore-string-comment
+                            ada-loop-start-re t nil))
+                     (not (looking-at "\\<loop\\>"))))
+                  (progn
+                    (goto-char (car match-cons))
+                    (save-excursion
+                      (beginning-of-line)
+                      (if (looking-at ada-named-block-re)
+                          (setq label (- ada-label-indent)))))))
+
+          (+ (current-indentation) label))))
+     ;;
+     ;; exception
+     ;;
+     ((looking-at "\\<exception\\>")
+      (save-excursion
+        (ada-goto-matching-start 1)
+        (current-indentation)))
+     ;;
+     ;; when
+     ;;
+     ((looking-at "\\<when\\>")
+      (save-excursion
+        (ada-goto-matching-start 1)
+        (+ (current-indentation) ada-when-indent)))
+     ;;
+     ;; else
+     ;;
+     ((looking-at "\\<else\\>")
+      (if (save-excursion
+            (ada-goto-previous-word)
+            (looking-at "\\<or\\>"))
+          prev-indent
+        (save-excursion
+          (ada-goto-matching-start 1 nil t)
+          (current-indentation))))
+     ;;
+     ;; elsif
+     ;;
+     ((looking-at "\\<elsif\\>")
+      (save-excursion
+        (ada-goto-matching-start 1 nil t)
+        (current-indentation)))
+     ;;
+     ;; then
+     ;;
+     ((looking-at "\\<then\\>")
+      (if (save-excursion
+            (ada-goto-previous-word)
+            (looking-at "\\<and\\>"))
+          prev-indent
+        (save-excursion
+          (ada-search-ignore-string-comment "\\<elsif\\>\\|\\<if\\>" t nil)
+          (+ (current-indentation) ada-stmt-end-indent))))
+     ;;
+     ;; loop
+     ;;
+     ((looking-at "\\<loop\\>")
+      (setq pos (point))
+      (save-excursion
+        (goto-char (match-end 0))
+        (ada-goto-stmt-start)
+        (if (looking-at "\\<loop\\>\\|\\<if\\>")
+            prev-indent
+          (progn
+            (if (not (looking-at ada-loop-start-re))
+                (ada-search-ignore-string-comment ada-loop-start-re
+                                                  nil pos))
+            (if (looking-at "\\<loop\\>")
+                prev-indent
+              (+ (current-indentation) ada-stmt-end-indent))))))
+     ;;
+     ;; begin
+     ;;
+     ((looking-at "\\<begin\\>")
+      (save-excursion
+        (if (ada-goto-matching-decl-start t)
+            (current-indentation)
+          prev-indent)))
+     ;;
+     ;; is
+     ;;
+     ((looking-at "\\<is\\>")
+      (if (and
+           ada-indent-is-separate
+           (save-excursion
+             (goto-char (match-end 0))
+             (ada-goto-next-non-ws (save-excursion
+                                     (end-of-line)
+                                     (point)))
+             (looking-at "\\<abstract\\>\\|\\<separate\\>")))
+          (save-excursion
+            (ada-goto-stmt-start)
+            (+ (current-indentation) ada-indent))
+        (save-excursion
+          (ada-goto-stmt-start)
+          (+ (current-indentation) ada-stmt-end-indent))))
+     ;;
+     ;; record
+     ;;
+     ((looking-at "\\<record\\>")
+      (save-excursion
+        (ada-search-ignore-string-comment
+         "\\<\\(type\\|use\\)\\>" t nil)
+        (if (looking-at "\\<use\\>")
+            (ada-search-ignore-string-comment "\\<for\\>" t nil))
+        (+ (current-indentation) ada-indent-record-rel-type)))
+     ;;
+     ;; or as statement-start
+     ;;
+     ((ada-looking-at-semi-or)
+      (save-excursion
+        (ada-goto-matching-start 1)
+        (current-indentation)))
+     ;;
+     ;; private as statement-start
+     ;;
+     ((ada-looking-at-semi-private)
+      (save-excursion
+        (ada-goto-matching-decl-start)
+        (current-indentation)))
+     ;;
+     ;; new/abstract/separate
+     ;;
+     ((looking-at "\\<\\(new\\|abstract\\|separate\\)\\>")
+      (- prev-indent ada-indent (- ada-broken-indent)))
+     ;;
+     ;; return
+     ;;
+     ((looking-at "\\<return\\>")
+      (save-excursion
+        (forward-sexp -1)
+        (if (and (looking-at "(")
+                 (save-excursion
+                   (backward-sexp 2)
+                   (looking-at "\\<function\\>")))
+            (1+ (current-column))
+          prev-indent)))
+     ;;
+     ;; do
+     ;;
+     ((looking-at "\\<do\\>")
+      (save-excursion
+        (ada-goto-stmt-start)
+        (+ (current-indentation) ada-stmt-end-indent)))
+     ;;
+     ;; package/function/procedure
+     ;;
+     ((and (looking-at "\\<\\(package\\|function\\|procedure\\)\\>")
+           (save-excursion
+             (forward-char 1)
+             (ada-goto-stmt-start)
+             (looking-at "\\<\\(package\\|function\\|procedure\\)\\>")))
+      (save-excursion
+        ;; look for 'generic'
+        (if (and (ada-goto-matching-decl-start t)
+                 (looking-at "generic"))
+            (current-column)
+          prev-indent)))
+     ;;
+     ;; label
+     ;;
+     ((looking-at "\\<[a-zA-Z0-9_]+[ \t\n]*:[^=]")
+      (if (ada-in-decl-p)
+          prev-indent
+        (+ prev-indent ada-label-indent)))
+     ;;
+     ;; identifier and other noindent-statements
+     ;;
+     ((looking-at "\\<[a-zA-Z0-9_]+[ \t\n]*")
+      prev-indent)
+     ;;
+     ;; beginning of a parameter list
+     ;;
+     ((looking-at "(")
+      prev-indent)
+     ;;
+     ;; end of a parameter list
+     ;;
+     ((looking-at ")")
+      (save-excursion
+        (forward-char 1)
+        (backward-sexp 1)
+        (current-column)))
+     ;;
+     ;; comment
+     ;;
+     ((looking-at "--")
+      (if ada-indent-comment-as-code
+          prev-indent
+        (current-indentation)))
+     ;;
+     ;; unknown syntax - maybe this should signal an error ?
+     ;;
+     (t
+      prev-indent))))
+
+
+(defun ada-indent-function (&optional nomove)
+  ;; Returns the function to calculate the indentation for the current
+  ;; line according to the previous statement, ignoring the contents
+  ;; of the current line after point.  Moves point to the beginning of
+  ;; the current statement, if NOMOVE is nil.
+
+  (let ((orgpoint (point))
+        (func nil))
+    ;;
+    ;; inside a parameter-list
+    ;;
+    (if (ada-in-paramlist-p)
+        (setq func 'ada-get-indent-paramlist)
+      (progn
+        ;;
+        ;; move to beginning of current statement
+        ;;
+        (if (not nomove)
+            (ada-goto-stmt-start))
+        ;;
+        ;; no beginning found => don't change indentation
+        ;;
+        (if (and
+             (eq orgpoint (point))
+             (not nomove))
+            (setq func 'ada-get-indent-nochange)
+
+          (cond
+           ;;
+           ((and
+             ada-indent-to-open-paren
+             (ada-in-open-paren-p))
+            (setq func 'ada-get-indent-open-paren))
+           ;;
+           ((looking-at "\\<end\\>")
+            (setq func 'ada-get-indent-end))
+           ;;
+           ((looking-at ada-loop-start-re)
+            (setq func 'ada-get-indent-loop))
+           ;;
+           ((looking-at ada-subprog-start-re)
+            (setq func 'ada-get-indent-subprog))
+           ;;
+           ((looking-at ada-block-start-re)
+            (setq func 'ada-get-indent-block-start))
+           ;;
+           ((looking-at "\\<type\\>")
+            (setq func 'ada-get-indent-type))
+           ;;
+           ((looking-at "\\<\\(els\\)?if\\>")
+            (setq func 'ada-get-indent-if))
+           ;;
+           ((looking-at "\\<case\\>")
+            (setq func 'ada-get-indent-case))
+           ;;
+           ((looking-at "\\<when\\>")
+            (setq func 'ada-get-indent-when))
+           ;;
+           ((looking-at "--")
+            (setq func 'ada-get-indent-comment))
+           ;;
+           ((looking-at "[a-zA-Z0-9_]+[ \t\n]*:[^=]")
+            (setq func 'ada-get-indent-label))
+           ;;
+	   ((looking-at "\\<separate\\>")
+	    (setq func 'ada-get-indent-nochange))
+           (t
+            (setq func 'ada-get-indent-noindent))))))
+
+    func))
+
+
+;; ---- functions to return indentation for special cases
+
+(defun ada-get-indent-open-paren (orgpoint)
+  ;; Returns the indentation (column #) for the new line after ORGPOINT.
+  ;; Assumes point to be behind an open parenthesis not yet closed.
+  (ada-in-open-paren-p))
+
+
+(defun ada-get-indent-nochange (orgpoint)
+  ;; Returns the indentation (column #) of the current line.
+  (save-excursion
+    (forward-line -1)
+    (current-indentation)))
+
+
+(defun ada-get-indent-paramlist (orgpoint)
+  ;; Returns the indentation (column #) for the new line after ORGPOINT.
+  ;; Assumes point to be inside a parameter-list.
+  (save-excursion
+    (ada-search-ignore-string-comment "[^ \t\n]" t nil t)
+    (cond
+     ;;
+     ;; in front of the first parameter
+     ;;
+     ((looking-at "(")
+      (goto-char (match-end 0))
+      (current-column))
+     ;;
+     ;; in front of another parameter
+     ;;
+     ((looking-at ";")
+      (goto-char (cdr (ada-search-ignore-string-comment "(\\|;" t nil t)))
+      (ada-goto-next-non-ws)
+      (current-column))
+     ;;
+     ;; inside a parameter declaration
+     ;;
+     (t
+      (goto-char (cdr (ada-search-ignore-string-comment "(\\|;" t nil t)))
+      (ada-goto-next-non-ws)
+      (+ (current-column) ada-broken-indent)))))
+
+
+(defun ada-get-indent-end (orgpoint)
+  ;; Returns the indentation (column #) for the new line after ORGPOINT.
+  ;; Assumes point to be at the beginning of an end-statement.
+  ;; Therefore it has to find the corresponding start. This can be a little
+  ;; slow, if it has to search through big files with many nested blocks.
+  ;; Signals an error if the corresponding block-start doesn't match.
+  (let ((defun-name nil)
+        (label 0)
+        (indent nil))
+    ;;
+    ;; is the line already terminated by ';' ?
+    ;;
+    (if (save-excursion
+          (ada-search-ignore-string-comment ";" nil orgpoint))
+        ;;
+        ;; yes, look what's following 'end'
+        ;;
+        (progn
+          (forward-word 1)
+          (ada-goto-next-non-ws)
+          (cond
+           ;;
+           ;; loop/select/if/case/record/select
+           ;;
+           ((looking-at "\\<\\(loop\\|select\\|if\\|case\\|record\\)\\>")
+            (save-excursion
+              (ada-check-matching-start
+               (buffer-substring (match-beginning 0)
+                                 (match-end 0)))
+              (if (looking-at "\\<\\(loop\\|record\\)\\>")
+                  (progn
+                    (forward-word 1)
+                    (ada-goto-stmt-start)))
+              ;; a label ? => skip it
+              (if (looking-at ada-named-block-re)
+                  (progn
+                    (setq label (- ada-label-indent))
+                    (goto-char (match-end 0))
+                    (ada-goto-next-non-ws)))
+              ;; really looking-at the right thing ?
+              (or (looking-at (concat "\\<\\("
+                                      "loop\\|select\\|if\\|case\\|"
+                                      "record\\|while\\|type\\)\\>"))
+                  (progn
+                    (ada-search-ignore-string-comment
+                     (concat "\\<\\("
+                             "loop\\|select\\|if\\|case\\|"
+                             "record\\|while\\|type\\)\\>")))
+                  (backward-word 1))
+              (+ (current-indentation) label)))
+           ;;
+           ;; a named block end
+           ;;
+           ((looking-at ada-ident-re)
+            (setq defun-name (buffer-substring (match-beginning 0)
+                                               (match-end 0)))
+            (save-excursion
+              (ada-goto-matching-start 0)
+              (ada-check-defun-name defun-name)
+              (current-indentation)))
+           ;;
+           ;; a block-end without name
+           ;;
+           ((looking-at ";")
+            (save-excursion
+              (ada-goto-matching-start 0)
+              (if (looking-at "\\<begin\\>")
+                  (progn
+                    (setq indent (current-column))
+                    (if (ada-goto-matching-decl-start t)
+                        (current-indentation)
+                      indent)))))
+           ;;
+           ;; anything else - should maybe signal an error ?
+           ;;
+           (t
+            (+ (current-indentation) ada-broken-indent))))
+
+      (+ (current-indentation) ada-broken-indent))))
+
+
+(defun ada-get-indent-case (orgpoint)
+  ;; Returns the indentation (column #) for the new line after ORGPOINT.
+  ;; Assumes point to be at the beginning of a case-statement.
+  (let ((cur-indent (current-indentation))
+        (match-cons nil)
+        (opos (point)))
+    (cond
+     ;;
+     ;; case..is..when..=>
+     ;;
+     ((save-excursion
+        (setq match-cons (and
+                          ;; the `=>' must be after the keyword `is'.
+                          (ada-search-ignore-string-comment
+                           "\\<is\\>" nil orgpoint)
+                          (ada-search-ignore-string-comment
+                           "[ \t\n]+=>" nil orgpoint))))
+      (save-excursion
+        (goto-char (car match-cons))
+        (if (not (ada-search-ignore-string-comment "\\<when\\>" t opos))
+            (error "missing 'when' between 'case' and '=>'"))
+        (+ (current-indentation) ada-indent)))
+     ;;
+     ;; case..is..when
+     ;;
+     ((save-excursion
+       (setq match-cons (ada-search-ignore-string-comment
+                         "\\<when\\>" nil orgpoint)))
+      (goto-char (cdr match-cons))
+      (+ (current-indentation) ada-broken-indent))
+     ;;
+     ;; case..is
+     ;;
+     ((save-excursion
+       (setq match-cons (ada-search-ignore-string-comment
+                         "\\<is\\>" nil orgpoint)))
+      (+ (current-indentation) ada-when-indent))
+     ;;
+     ;; incomplete case
+     ;;
+     (t
+      (+ (current-indentation) ada-broken-indent)))))
+
+
+(defun ada-get-indent-when (orgpoint)
+  ;; Returns the indentation (column #) for the new line after ORGPOINT.
+  ;; Assumes point to be at the beginning of an when-statement.
+  (let ((cur-indent (current-indentation)))
+    (if (ada-search-ignore-string-comment
+         "[ \t\n]+=>" nil orgpoint)
+        (+ cur-indent  ada-indent)
+      (+ cur-indent ada-broken-indent))))
+
+
+(defun ada-get-indent-if (orgpoint)
+  ;; Returns the indentation (column #) for the new line after ORGPOINT.
+  ;; Assumes point to be at the beginning of an if-statement.
+  (let ((cur-indent (current-indentation))
+        (match-cons nil))
+    ;;
+    ;; if..then ?
+    ;;
+    (if (ada-search-but-not
+         "\\<then\\>" "\\<and\\>[ \t\n]+\\<then\\>" nil orgpoint)
+
+        (progn
+          ;;