Mercurial > emacs
changeset 97058:b6ac850e9d2b
Fix bug #272, and update Ada mode to version 4.0.
author | Juanma Barranquero <lekktu@gmail.com> |
---|---|
date | Mon, 28 Jul 2008 11:03:42 +0000 |
parents | 55c00acfe623 |
children | 984f2ac5a637 |
files | doc/misc/ChangeLog doc/misc/ada-mode.texi lisp/ChangeLog lisp/progmodes/ada-mode.el lisp/progmodes/ada-prj.el lisp/progmodes/ada-xref.el |
diffstat | 6 files changed, 806 insertions(+), 578 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/misc/ChangeLog Mon Jul 28 07:15:44 2008 +0000 +++ b/doc/misc/ChangeLog Mon Jul 28 11:03:42 2008 +0000 @@ -1,3 +1,7 @@ +2008-07-28 Stephen Leake <stephen_leake@stephe-leake.org> + + * ada-mode.texi: Update to Ada mode version 4.0. + 2008-07-27 Michael Albinus <michael.albinus@gmx.de> Sync with Tramp 2.1.14.
--- a/doc/misc/ada-mode.texi Mon Jul 28 07:15:44 2008 +0000 +++ b/doc/misc/ada-mode.texi Mon Jul 28 11:03:42 2008 +0000 @@ -30,7 +30,7 @@ @title{Ada Mode} @sp 2 @subtitle An Emacs major mode for programming in Ada -@subtitle Ada Mode Version 3.7 +@subtitle Ada Mode Version 4.00 @sp 2 @page @vskip 0pt plus 1filll @@ -57,7 +57,7 @@ * Automatic Casing:: Adjusting the case of words automatically * Statement Templates:: Inserting code templates * Comment Handling:: Reformatting comments easily -* GNU Free Documentation License:: The license for this documentation. +* GNU Free Documentation License:: The license for this documentation. * Index:: @end menu @@ -268,7 +268,7 @@ listed in the Ada menu. In multi-file projects, there must be one file that is the main -program. That is given by the @code{main_unit} project file variable; +program. That is given by the @code{main} project file variable; it defaults to the current file if not yet set, but is also set by the ``set main and build'' command. @@ -280,26 +280,26 @@ runs faster than full compile mode, speeding up finding and fixing compilation errors. -This sets @code{main_unit} only if it has not been set yet. +This sets @code{main} only if it has not been set yet. @item Compile file Compiles the current file, by running @code{comp_cmd} from the current project file. -This does not set @code{main_unit}. +This does not set @code{main}. @item Set main and Build -Sets @code{main_unit} to the current file, then executes the Build +Sets @code{main} to the current file, then executes the Build command. @item Show main -Display @code{main_unit} in the message buffer. +Display @code{main} in the message buffer. @item Build -Compiles all obsolete units of the current @code{main_unit}, and links -@code{main_unit}, by running @code{make_cmd} from the current project. +Compiles all obsolete units of the current @code{main}, and links +@code{main}, by running @code{make_cmd} from the current project. -This sets @code{main_unit} only if it has not been set yet. +This sets @code{main} only if it has not been set yet. @item Run Executes the main program in a shell, displayed in a separate Emacs @@ -313,7 +313,7 @@ @end table It is important when using these commands to understand how -@code{main_unit} is used and changed. +@code{main} is used and changed. Build runs 'gnatmake' on the main unit. During a typical edit/compile session, this is the only command you need to invoke, which is why it @@ -328,19 +328,19 @@ this case, @key{C-c C-m} will normally be the only command needed; it will build the current file, rather than the last-built main. -There are three ways to change @code{main_unit}: +There are three ways to change @code{main}: @enumerate @item -Invoke @key{Ada | Set main and Build}, which sets @code{main_unit} to +Invoke @key{Ada | Set main and Build}, which sets @code{main} to the current file. @item -Invoke @key{Ada | Project | Edit}, edit @code{main_unit} and +Invoke @key{Ada | Project | Edit}, edit @code{main} and @code{main}, and click @key{[save]} @item -Invoke @key{Ada | Project | Load}, and load a project file that specifies @code{main_unit} +Invoke @key{Ada | Project | Load}, and load a project file that specifies @code{main} @end enumerate @@ -372,7 +372,10 @@ and other things on a per-project basis. Note that Ada mode project files @samp{*.adp} are different than GNAT -compiler project files @samp{*.gpr}. +compiler project files @samp{*.gpr}. However, Emacs Ada mode can use a +GNAT project project file to specify the project directories. If no +other customization is needed, a GNAT project file can be used without +an Emacs Ada mode project file. @menu * Project File Overview:: @@ -436,9 +439,15 @@ To change the project file before or after the first one is found, invoke @key{Ada | Project | Load ...}. -Or, in lisp, evaluate @code{ada-set-default-project-file "/path/file.adp"}. +Or, in lisp, evaluate @code{(ada-set-default-project-file "/path/file.adp")}. This sets @code{ada-prj-default-project-file}, and reads the project file. +You can also specify a GNAT project file to @key{Ada | Project | Load +...} or @code{ada-set-default-project-file}. Emacs Ada mode checks the +file extension; if it is @code{.gpr}, the file is treated as a GNAT +project file. Any other extension is treated as an Emacs Ada mode +project file. + @node GUI Editor, Project file variables, Project File Overview, Project files @section GUI Editor @@ -465,31 +474,69 @@ @code{comp_opt} variable will be substituted when @code{comp_cmd} is used. +In addition, process environment variables can be referenced using the +same syntax, or the normal @code{$var} syntax. + Most project variables have defaults that can be changed by setting lisp variables; the table below identifies the lisp variable for each project variable. Lisp variables corresponding to project variables that are lists are lisp lists. +In general, project variables are evaluated when referenced in +Emacs Ada mode commands. Relative file paths are expanded to +absolute relative to @code{$@{build_dir@}}. + Here is the list of variables. In the default values, the current directory @code{"."} is the project file directory. -@c defined in ada-xref-set-default-prj-values; same order here @table @asis +@c defined in ada-default-prj-properties; alphabetical order + +@item @code{ada_project_path_sep} [default: @code{":" or ";"}] +Path separator for @code{ADA_PROJECT_PATH}. It defaults to the correct +value for a native implementation of GNAT for the current operating +system. The user must override this when using Windows native GNAT +with Cygwin Emacs, and perhaps in other cases. + +Lisp variable: @code{ada-prj-ada-project-path-sep}. + +@item @code{ada_project_path} [default: @code{""}] +A list of directories to search for GNAT project files. + +If set, the @code{ADA_PROJECT_PATH} process environment variable is +set to this value in the Emacs process when the Emacs Ada mode project +is selected via menu @samp{Ada | Project | Load}. + +For @code{ada_project_path}, relative file paths are expanded to +absolute when the Emacs Ada project file is read, rather than when the +project file is selected. + +For example if the project file is in the directory +@file{/home/myproject}, the environment variable @code{GDS_ROOT} is +set to @code{/home/shared}, and the project file contains: +@example +ada_project_path_sep=: +ada_project_path=$GDS_ROOT/makerules +ada_project_path=../opentoken +@end example +the environment variable @code{ADA_PROJECT_PATH} will be set to +@code{"/home/shared/makerules:/home/opentoken/"}. + +The default value is not the current value of this environment +variable, because that will typically have been set by another +project, and will therefore be incorrect for this project. + +If you have the environment variable set correctly for all of your +projects, you do not need to set this project variable. + +@item @code{bind_opt} [default: @code{""}] +Holds user binder options; used in the default build commands. + +Lisp variable: @code{ada-prj-default-bind-opt}. + @item @code{build_dir} [default: @code{"."}] The compile commands will be issued in this directory. -@item @code{src_dir} [default: @code{"."}] -A list of directories to search for source files, both for compile -commands and source navigation. - -@item @code{obj_dir} [default: @code{"."}] -A list of directories to search for library files. Ada mode searches -this list for the @samp{.ali} files generated by GNAT that contain -cross-reference information. - -The compiler commands must place the @samp{.ali} files in one of these -directories; the default commands do that. - @item @code{casing} [default: @code{("~/.emacs_case_exceptions")} List of files containing casing exceptions. See the help on @code{ada-case-exception-file} for more info. @@ -497,6 +544,18 @@ Lisp variable: @code{ada-case-exception-file}. +@item @code{check_cmd} [default: @code{"$@{cross_prefix@}gnatmake -u -c -gnatc $@{gnatmake_opt@} $@{full_current@} -cargs $@{comp_opt@}"}] +Command used to syntax check a single file. +The name of the file is substituted for @code{full_current}. + +Lisp variable: @code{ada-prj-default-check-cmd} + +@item @code{comp_cmd} [default: @code{"$@{cross_prefix@}gnatmake -u -c $@{gnatmake_opt@} $@{full_current@} -cargs $@{comp_opt@}"}] +Command used to compile a single file. +The name of the file is substituted for @code{full_current}. + +Lisp variable: @code{ada-prj-default-comp-cmd}. + @item @code{comp_opt} [default: @code{"-gnatq -gnatQ"}] Holds user compiler options; used in the default compile commands. The default value tells gnatmake to generate library files for @@ -509,69 +568,10 @@ Lisp variable: @code{ada-prj-default-comp-opt}. -@item @code{bind_opt} [default: @code{""}] -Holds user binder options; used in the default build commands. - -Lisp variable: @code{ada-prj-default-bind-opt}. - -@item @code{link_opt} [default: @code{""}] -Holds user linker options; used in the default build commands. - -Lisp variable: @code{ada-prj-default-link-opt}. - -@item @code{gnatmake_opt} [default: @code{"-g"}] -Holds user gnatmake options; used in the default build commands. - -If a GNAT project file is used (for example @file{project.gpr}), this -option should be set to @code{-Pproject.gpr}. - -Lisp variable: @code{ada-prj-default-gnatmake-opt}. - -@item @code{gnatfind_opt} [default: @code{"-rf"}] -Holds user gnatfind options; used in the default find commands. - -Lisp variable: @code{ada-prj-gnatfind-switches}. - -@item @code{main} [default: current file] -Specifies the name of the executable file for the project; used in the -default build commands. - -@item @code{main_unit} [default: current Ada unit] -Specifies the name of the main Ada unit for the project; used in the -default build commands. - @item @code{cross_prefix} [default: @code{""}] Name of target machine in a cross-compilation environment. Used in default compile and build commands. -@item @code{remote_machine} [default: @code{""}] -Name of the machine to log into before issuing the compile and build -commands. If this variable is empty, the command will be run on the -local machine. - -@item @code{comp_cmd} [default: @code{"$@{cross_prefix@}gnatmake -u -c $@{gnatmake_opt@} $@{full_current@} -cargs $@{comp_opt@}"}] -Command used to compile a single file. -The name of the file is substituted for @code{full_current}. - -Lisp variable: @code{ada-prj-default-comp-cmd}. - -@item @code{check_cmd} [default: @code{"$@{cross_prefix@}gnatmake -u -c -gnatc $@{gnatmake_opt@} $@{full_current@} -cargs $@{comp_opt@}"}] -Command used to syntax check a single file. -The name of the file is substituted for @code{full_current}. - -Lisp variable: @code{ada-prj-default-check-cmd} - -@item @code{make_cmd} [default: @code{"$@{cross_prefix@}gnatmake -o $@{main@} $@{main_unit@} $@{gnatmake_opt@} -cargs $@{comp_opt@} -bargs $@{bind_opt@} -largs $@{link_opt@}"}] -Command used to build the application. - -Lisp variable: @code{ada-prj-default-make-cmd}. - -@item @code{run_cmd} [default: @code{"./$@{main@}"}] -Command used to run the application. - -@item @code{debug_pre_cmd} [default: @code{"cd $@{build_dir@}"}] -Command executed before @code{debug_cmd}. - @item @code{debug_cmd} [default: @code{"$@{cross_prefix@}gdb $@{main@}"}] Command used to debug the application @@ -580,6 +580,70 @@ @item @code{debug_post_cmd} [default: @code{""}] Command executed after @code{debug_cmd}. +@item @code{debug_pre_cmd} [default: @code{"cd $@{build_dir@}"}] +Command executed before @code{debug_cmd}. + +@item @code{gnatfind_opt} [default: @code{"-rf"}] +Holds user gnatfind options; used in the default find commands. + +Lisp variable: @code{ada-prj-gnatfind-switches}. + +@item @code{gnatmake_opt} [default: @code{"-g"}] +Holds user gnatmake options; used in the default build commands. + +Lisp variable: @code{ada-prj-default-gnatmake-opt}. + +@item @code{gpr_file} [default: @code{""}] +Specify GNAT project file. + +If set, the source and object directories specified in the GNAT +project file are appended to @code{src_dir} and @code{obj_dir}. This +allows specifying Ada source directories with a GNAT project file, and +other source directories with the Emacs project file. + +In addition, @code{-P@{gpr_file@}} is added to the project variable +@code{gnatmake_opt} whenever it is referenced. With the default +project variables, this passes the project file to all gnatmake +commands. + +Lisp variable: @code{ada-prj-default-gpr-file}. + +@c FIXME: add gnatstub-opts + +@item @code{link_opt} [default: @code{""}] +Holds user linker options; used in the default build commands. + +Lisp variable: @code{ada-prj-default-link-opt}. + +@item @code{main} [default: current file] +Specifies the name of the executable file for the project; used in the +default build commands. + +@item @code{make_cmd} [default: @code{"$@{cross_prefix@}gnatmake -o $@{main@} $@{main@} $@{gnatmake_opt@} -cargs $@{comp_opt@} -bargs $@{bind_opt@} -largs $@{link_opt@}"}] +Command used to build the application. + +Lisp variable: @code{ada-prj-default-make-cmd}. + +@item @code{obj_dir} [default: @code{"."}] +A list of directories to search for library files. Ada mode searches +this list for the @samp{.ali} files generated by GNAT that contain +cross-reference information. + +The compiler commands must place the @samp{.ali} files in one of these +directories; the default commands do that. + +@item @code{remote_machine} [default: @code{""}] +Name of the machine to log into before issuing the compile and build +commands. If this variable is empty, the command will be run on the +local machine. + +@item @code{run_cmd} [default: @code{"./$@{main@}"}] +Command used to run the application. + +@item @code{src_dir} [default: @code{"."}] +A list of directories to search for source files, both for compile +commands and source navigation. + @end table @node Compiling Examples, Moving Through Ada Code, Project files, Top @@ -601,6 +665,7 @@ * Set compiler options:: A basic Ada mode project file * Set source search path:: Source in multiple directories * Use GNAT project file:: +* Use multiple GNAT project files:: @end menu @node No project files, Set compiler options, Compiling Examples, Compiling Examples @@ -632,6 +697,8 @@ end Hello_2; @end example +This file has no errors. + @file{hello_pkg.ads}: @example @@ -640,6 +707,8 @@ end Hello_Pkg; @end example +This file has no errors. + @file{hello_pkg.adb}: @example @@ -683,7 +752,7 @@ Ada.Text_IO.Put_Line ("hello from hello.adb"): @end example -Now invoke @key{Ada | Show main}; this displays @file{Ada mode main_unit: hello}. +Now invoke @key{Ada | Show main}; this displays @file{Ada mode main: hello}. Now (in buffer @file{hello.adb}), invoke @key{Ada | Build}. You are prompted to save the file (if you haven't already). Then the @@ -729,7 +798,7 @@ @xref{Set source search path}, or a GNAT project file; @ref{Use GNAT project file}. -Invoke @key{Ada | Show main}; this displays @file{Ada mode main_unit: hello_2}. +Invoke @key{Ada | Show main}; this displays @file{Ada mode main: hello_2}. Move to the error with @key{C-x `}, and fix the error by adding @code{body}: @@ -740,29 +809,29 @@ Now, while still in @file{hello_pkg.adb}, invoke @key{Ada | Build}. gnatmake successfully builds @file{hello_2}. This demonstrates that Emacs has remembered the main file, in the project variable -@code{main_unit}, and used it for the Build command. +@code{main}, and used it for the Build command. Finally, again while in @file{hello_pkg.adb}, invoke @key{Ada | Run}. The @code{*run*} buffer displays @code{Hello from hello_pkg.adb}. One final point. If you switch back to buffer @file{hello.adb}, and invoke @key{Ada | Run}, @file{hello_2.exe} will be run. That is -because @code{main_unit} is still set to @code{hello_2}, as you can +because @code{main} is still set to @code{hello_2}, as you can see when you invoke @key{Ada | Project | Edit}. -There are three ways to change @code{main_unit}: +There are three ways to change @code{main}: @enumerate @item -Invoke @key{Ada | Set main and Build}, which sets @code{main_unit} to +Invoke @key{Ada | Set main and Build}, which sets @code{main} to the current file. @item -Invoke @key{Ada | Project | Edit}, edit @code{main_unit} and +Invoke @key{Ada | Project | Edit}, edit @code{main} and @code{main}, and click @key{[save]} @item -Invoke @key{Ada | Project | Load}, and load a project file that specifies @code{main_unit} +Invoke @key{Ada | Project | Load}, and load a project file that specifies @code{main} @end enumerate @@ -832,8 +901,8 @@ @section Set source search path In this example, we show how to deal with files in more than one -directory. We start with the same code as in @ref{No project files}; create those -files (with the errors present) +directory. We start with the same code as in @ref{No project files}; +create those files (with the errors present) Create the directory @file{Example_3}, containing: @@ -912,10 +981,11 @@ Fixing the error, linking and running the code proceed as in @ref{No project files}. -@node Use GNAT project file, , Set source search path, Compiling Examples +@node Use GNAT project file, Use multiple GNAT project files, Set source search path, Compiling Examples @section Use GNAT project file -In this example, we show how to use a GNAT project file. +In this example, we show how to use a GNAT project file, with no Ada +mode project file. Create the directory @file{Example_4}, containing: @@ -945,7 +1015,7 @@ In addition, create a directory @file{Example_4/Gnat_Project}, containing these files: -@file{Other/hello_4.adb}: +@file{Gnat_Project/hello_4.adb}: @example with Hello_Pkg; @@ -959,13 +1029,6 @@ There are no errors in this file. -@file{Gnat_Project/hello_4.adp}: - -@example -src_dir=.. -gnatmake_opt=-Phello_4.gpr -@end example - @file{Gnat_Project/hello_4.gpr}: @example @@ -975,7 +1038,7 @@ @end example In buffer @file{hello_4.adb}, invoke @key{Ada | Project | Load...}, and -select @file{Example_4/Gnat_Project/hello_4.adp}. +select @file{Example_4/Gnat_Project/hello_4.gpr}. Then, again in @file{hello_4.adb}, invoke @key{Ada | Set main and Build}. You should get a @code{*compilation*} buffer containing @@ -997,9 +1060,72 @@ Fixing the error, linking and running the code proceed as in @ref{No project files}. +@node Use multiple GNAT project files, , Use GNAT project file, Compiling Examples +@section Use multiple GNAT project files + +In this example, we show how to use multiple GNAT project files, +specifying the GNAT project search path in an Ada mode project file. + +Create the directory @file{Example_4} as specified in @ref{Use GNAT +project file}. + +Create the directory @file{Example_5}, containing: + +@file{hello_5.adb}: + +@example +with Hello_Pkg; +with Ada.Text_IO; use Ada.Text_IO; +procedure Hello_5 +is begin + Hello_Pkg.Say_Hello; + Put_Line ("From hello_5"); +end Hello_5; +@end example + +There are no errors in this file. + +@file{hello_5.adp}: + +@example +ada_project_path=../Example_4/Gnat_Project +gpr_file=hello_5.gpr +@end example + +@file{hello_5.gpr}: + +@example +with "hello_4"; +Project Hello_5 is + for Source_Dirs use ("."); + package Compiler is + for Default_Switches ("Ada") use ("-g", "-gnatyt"); + end Compiler; +end Hello_5; +@end example + +In buffer @file{hello_5.adb}, invoke @key{Ada | Project | Load...}, and +select @file{Example_5/hello_5.adp}. + +Then, again in @file{hello_5.adb}, invoke @key{Ada | Set main and +Build}. You should get a @code{*compilation*} buffer containing +something like (the directory paths will be different): + +@example +cd c:/Examples/Example_5/ +gnatmake -o hello_5 hello_5 -Phello_5.gpr -g -cargs -gnatq -gnatQ -bargs -largs +gcc -c -g -gnatyt -g -gnatq -gnatQ -I- -gnatA c:\Examples\Example_5\hello_5.adb +gcc -c -g -gnatyt -g -gnatq -gnatQ -I- -gnatA c:\Examples\Example_4\hello_pkg.adb +hello_pkg.adb:2:08: keyword "body" expected here [see file name] +gnatmake: "c:\examples\example_4\hello_pkg.adb" compilation error +@end example + +Now type @key{C-x `}. @file{Example_4/hello_pkg.adb} is shown, +demonstrating that @file{hello_5.gpr} and @file{hello_4.gpr} are being +used to set the compilation search path. + @node Moving Through Ada Code, Identifier completion, Compiling Examples, Top @chapter Moving Through Ada Code -@c ----------------------------------------------------------------------- There are several easy to use commands to navigate through Ada code. All these functions are available through the Ada menu, and you can also
--- a/lisp/ChangeLog Mon Jul 28 07:15:44 2008 +0000 +++ b/lisp/ChangeLog Mon Jul 28 11:03:42 2008 +0000 @@ -1,3 +1,29 @@ +2008-07-28 Stephen Leake <stephen_leake@stephe-leake.org> + + * progmodes/ada-mode.el (ada-mode): Clean up XEmacs handling. + Add support for add-log. + (ada-end-stmt-re): Fix bug - allow comment after 'when'. + + * progmodes/ada-prj.el: Delete 'main_unit' project variable. + (ada-prj-save): Prompt for file name if not given. + (ada-prj-display-page): Display casing exceptions. + + * progmodes/ada-xref.el: Add support for GNAT project files as Emacs + Ada mode project files. Delete 'main_unit' project variable; + only need 'main'. Simplify handling of default project values. + Use cross-prefix consistently. + (ada-find-executable): Throw error if not found. + (ada-initialize-runtime-library): Improve error handling when + gnatls not found. + (ada-gnat-parse-gpr): New. + (ada-treat-cmd-string): Allow process environment variables. + (ada-xref-set-default-prj-values): Delete; replace with + ada-default-prj-properties. + (ada-parse-prj-file): Handle GNAT project files. + (ada-parse-prj-file-1): New, factored out of ada-parse-prj-file. + (ada-select-prj-file): New. + (ada-get-absolute-dir-list): Allow project and environment variables. + 2008-07-27 Michael Albinus <michael.albinus@gmx.de> Sync with Tramp 2.1.14.
--- a/lisp/progmodes/ada-mode.el Mon Jul 28 07:15:44 2008 +0000 +++ b/lisp/progmodes/ada-mode.el Mon Jul 28 11:03:42 2008 +0000 @@ -135,7 +135,7 @@ (defun ada-mode-version () "Return Ada mode version." (interactive) - (let ((version-string "3.7")) + (let ((version-string "4.00")) (if (interactive-p) (message version-string) version-string))) @@ -636,6 +636,7 @@ (concat "\\(" ";" "\\|" "=>[ \t]*$" "\\|" + "=>[ \t]*--.*$" "\\|" "^[ \t]*separate[ \t]*(\\(\\sw\\|[_.]\\)+)" "\\|" "\\<" (regexp-opt '("begin" "declare" "is" "do" "else" "generic" "loop" "private" "record" "select" @@ -790,13 +791,13 @@ ;; set source marker (save-excursion - (compilation-find-file (point-marker) (match-string 1) "./") - (set-buffer file) - - (if (stringp line) - (goto-line (string-to-number line))) - - (setq source (point-marker))) + (compilation-find-file (point-marker) (match-string 1) "./") + (set-buffer file) + + (if (stringp line) + (goto-line (string-to-number line))) + + (setq source (point-marker))) (compilation-goto-locus error-pos source nil) @@ -935,8 +936,7 @@ (buffer-undo-list t) (inhibit-read-only t) (inhibit-point-motion-hooks t) - (inhibit-modification-hooks t) - buffer-file-name buffer-file-truename) + (inhibit-modification-hooks t)) (remove-text-properties (point-min) (point-max) '(syntax-table nil)) (goto-char (point-min)) (while (re-search-forward @@ -1197,9 +1197,6 @@ (set (make-local-variable 'fill-paragraph-function) 'ada-fill-comment-paragraph) - (set (make-local-variable 'imenu-generic-expression) - ada-imenu-generic-expression) - ;; Support for compile.el ;; We just substitute our own functions to go to the error. (add-hook 'compilation-mode-hook @@ -1214,23 +1211,13 @@ 'ada-compile-goto-error))) ;; font-lock support : - ;; We need to set some properties for XEmacs, and define some variables - ;; for Emacs - - ;; FIXME: The Emacs code should work just fine under XEmacs AFAIK. --Stef - (if (featurep 'xemacs) - ;; XEmacs - (put 'ada-mode 'font-lock-defaults - '(ada-font-lock-keywords - nil t ((?\_ . "w") (?# . ".")) beginning-of-line)) - ;; Emacs - (set (make-local-variable 'font-lock-defaults) - '(ada-font-lock-keywords - nil t - ((?\_ . "w") (?# . ".")) - beginning-of-line - (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords))) - ) + + (set (make-local-variable 'font-lock-defaults) + '(ada-font-lock-keywords + nil t + ((?\_ . "w") (?# . ".")) + beginning-of-line + (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords))) ;; Set up support for find-file.el. (set (make-local-variable 'ff-other-file-alist) @@ -1243,34 +1230,34 @@ (make-local-variable 'ff-special-constructs) (mapc (lambda (pair) (add-to-list 'ff-special-constructs pair)) - (list - ;; Top level child package declaration; go to the parent package. - (cons (eval-when-compile - (concat "^\\(private[ \t]\\)?[ \t]*package[ \t]+" - "\\(body[ \t]+\\)?" - "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is")) - (lambda () - (ff-get-file - ada-search-directories-internal - (ada-make-filename-from-adaname (match-string 3)) - ada-spec-suffixes))) - - ;; A "separate" clause. - (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))" - (lambda () - (ff-get-file - ada-search-directories-internal - (ada-make-filename-from-adaname (match-string 1)) - ada-spec-suffixes))) - - ;; A "with" clause. - (cons "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)" - (lambda () - (ff-get-file - ada-search-directories-internal - (ada-make-filename-from-adaname (match-string 1)) - ada-spec-suffixes))) - )) + (list + ;; Top level child package declaration; go to the parent package. + (cons (eval-when-compile + (concat "^\\(private[ \t]\\)?[ \t]*package[ \t]+" + "\\(body[ \t]+\\)?" + "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is")) + (lambda () + (ff-get-file + ada-search-directories-internal + (ada-make-filename-from-adaname (match-string 3)) + ada-spec-suffixes))) + + ;; A "separate" clause. + (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))" + (lambda () + (ff-get-file + ada-search-directories-internal + (ada-make-filename-from-adaname (match-string 1)) + ada-spec-suffixes))) + + ;; A "with" clause. + (cons "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)" + (lambda () + (ff-get-file + ada-search-directories-internal + (ada-make-filename-from-adaname (match-string 1)) + ada-spec-suffixes))) + )) ;; Support for outline-minor-mode (set (make-local-variable 'outline-regexp) @@ -1278,6 +1265,8 @@ (set (make-local-variable 'outline-level) 'ada-outline-level) ;; Support for imenu : We want a sorted index + (setq imenu-generic-expression ada-imenu-generic-expression) + (setq imenu-sort-function 'imenu--sort-by-name) ;; Support for ispell : Check only comments @@ -1290,40 +1279,40 @@ ;; Exclude comments alone on line from alignment. (add-to-list 'align-exclude-rules-list - '(ada-solo-comment - (regexp . "^\\(\\s-*\\)--") - (modes . '(ada-mode)))) + '(ada-solo-comment + (regexp . "^\\(\\s-*\\)--") + (modes . '(ada-mode)))) (add-to-list 'align-exclude-rules-list - '(ada-solo-use - (regexp . "^\\(\\s-*\\)\\<use\\>") - (modes . '(ada-mode)))) + '(ada-solo-use + (regexp . "^\\(\\s-*\\)\\<use\\>") + (modes . '(ada-mode)))) (setq ada-align-modes nil) (add-to-list 'ada-align-modes - '(ada-declaration-assign - (regexp . "[^:]\\(\\s-*\\):[^:]") - (valid . (lambda() (not (ada-in-comment-p)))) - (repeat . t) - (modes . '(ada-mode)))) + '(ada-declaration-assign + (regexp . "[^:]\\(\\s-*\\):[^:]") + (valid . (lambda() (not (ada-in-comment-p)))) + (repeat . t) + (modes . '(ada-mode)))) (add-to-list 'ada-align-modes - '(ada-associate - (regexp . "[^=]\\(\\s-*\\)=>") - (valid . (lambda() (not (ada-in-comment-p)))) - (modes . '(ada-mode)))) + '(ada-associate + (regexp . "[^=]\\(\\s-*\\)=>") + (valid . (lambda() (not (ada-in-comment-p)))) + (modes . '(ada-mode)))) (add-to-list 'ada-align-modes - '(ada-comment - (regexp . "\\(\\s-*\\)--") - (modes . '(ada-mode)))) + '(ada-comment + (regexp . "\\(\\s-*\\)--") + (modes . '(ada-mode)))) (add-to-list 'ada-align-modes - '(ada-use - (regexp . "\\(\\s-*\\)\\<use\\s-") - (valid . (lambda() (not (ada-in-comment-p)))) - (modes . '(ada-mode)))) + '(ada-use + (regexp . "\\(\\s-*\\)\\<use\\s-") + (valid . (lambda() (not (ada-in-comment-p)))) + (modes . '(ada-mode)))) (add-to-list 'ada-align-modes - '(ada-at - (regexp . "\\(\\s-+\\)at\\>") - (modes . '(ada-mode)))) + '(ada-at + (regexp . "\\(\\s-+\\)at\\>") + (modes . '(ada-mode)))) (setq align-mode-rules-list ada-align-modes) @@ -1342,6 +1331,9 @@ ;; Support for indent-new-comment-line (Especially for XEmacs) (set (make-local-variable 'comment-multi-line) nil) + ;; Support for add-log + (set (make-local-variable 'add-log-current-defun-function) 'ada-which-function) + (setq major-mode 'ada-mode mode-name "Ada") @@ -3506,11 +3498,13 @@ Assumes point to be already positioned by `ada-goto-matching-start'. Moves point to the beginning of the declaration." - ;; named block without a `declare' + ;; named block without a `declare'; ada-goto-matching-start leaves + ;; point at start of 'begin' for a block. (if (save-excursion (ada-goto-previous-word) (looking-at (concat "\\<" defun-name "\\> *:"))) t ; do nothing + ;; else ;; ;; 'accept' or 'package' ? ;; @@ -3524,7 +3518,9 @@ ;; a named 'declare'-block ? => jump to the label ;; (if (looking-at "\\<declare\\>") - (backward-word 1) + (progn + (forward-comment -1) + (backward-word 1)) ;; ;; no, => 'procedure'/'function'/'task'/'protected' ;; @@ -5043,9 +5039,9 @@ (save-excursion (end-of-line);; make sure we get the complete name (or (if (re-search-backward ada-procedure-start-regexp nil t) - (setq ff-function-name (match-string 5))) - (if (re-search-backward ada-package-start-regexp nil t) - (setq ff-function-name (match-string 4)))) + (setq ff-function-name (match-string 5))) + (if (re-search-backward ada-package-start-regexp nil t) + (setq ff-function-name (match-string 4)))) )) @@ -5190,6 +5186,9 @@ ;; Mark single quotes as having string quote syntax in 'c' instances. ;; We used to explicitly avoid ''' as a special case for fear the buffer ;; be highlighted as a string, but it seems this fear is unfounded. + ;; + ;; This sets the properties of the characters, so that ada-in-string-p + ;; correctly handles '"' too... '(("[^a-zA-Z0-9)]\\('\\)[^\n]\\('\\)" (1 (7 . ?')) (2 (7 . ?'))) ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n))))) @@ -5243,7 +5242,7 @@ "null" "or" "others" "overriding" "private" "protected" "raise" "range" "record" "rem" "renames" "requeue" "return" "reverse" "select" "separate" "synchronized" "tagged" "task" "terminate" - "then" "until" "when" "while" "with" "xor") t) + "then" "until" "when" "while" "with" "xor") t) "\\>") ;; ;; Anything following end and not already fontified is a body name. @@ -5380,13 +5379,15 @@ (insert "end " procname ";") (ada-indent-newline-indent) ) - ;; else + ((looking-at "[ \t\n]*is") ;; do nothing ) + ((looking-at "[ \t\n]*rename") ;; do nothing ) + (t (message "unknown syntax")))) (t @@ -5510,7 +5511,6 @@ (autoload 'ada-point-and-xref "ada-xref" nil t) (autoload 'ada-reread-prj-file "ada-xref" nil t) (autoload 'ada-run-application "ada-xref" nil t) -(autoload 'ada-set-default-project-file "ada-xref" nil nil) (autoload 'ada-set-default-project-file "ada-xref" nil t) (autoload 'ada-xref-goto-previous-reference "ada-xref" nil t) (autoload 'ada-set-main-compile-application "ada-xref" nil t)
--- a/lisp/progmodes/ada-prj.el Mon Jul 28 07:15:44 2008 +0000 +++ b/lisp/progmodes/ada-prj.el Mon Jul 28 11:03:42 2008 +0000 @@ -122,7 +122,8 @@ (defun ada-prj-save () "Save the edited project file." (interactive) - (let ((file-name (plist-get ada-prj-current-values 'filename)) + (let ((file-name (or (plist-get ada-prj-current-values 'filename) + (read-file-name "Save project as: "))) output) (set 'output (concat @@ -141,7 +142,6 @@ ;; Always save the fields that depend on the current buffer "main=" (plist-get ada-prj-current-values 'main) "\n" - "main_unit=" (plist-get ada-prj-current-values 'main_unit) "\n" "build_dir=" (plist-get ada-prj-current-values 'build_dir) "\n" (ada-prj-set-list "check_cmd" (plist-get ada-prj-current-values 'check_cmd)) "\n" @@ -288,26 +288,22 @@ (widget-insert "Project file name:\n") (widget-insert (plist-get ada-prj-current-values 'filename)) (widget-insert "\n\n") -; (ada-prj-field 'filename "Project file name" -; "Enter the name and directory of the project -; file. The name of the file should be the -; name of the project itself. The extension -; must be .adp") -; (ada-prj-field 'casing "Casing Exceptions Dictionnaries" -; "List of files that contain casing exception -; dictionnaries. All these files contain one -; identifier per line, with a special casing. -; The first file has the highest priority." -; t) + (ada-prj-field 'casing "Casing Exceptions" +"List of files that contain casing exception +dictionaries. All these files contain one +identifier per line, with a special casing. +The first file has the highest priority." + t nil + (mapconcat (lambda(x) + (concat " " x)) + (ada-xref-get-project-field 'casing) + "\n") + ) (ada-prj-field 'main "Executable file name" "Name of the executable generated when you compile your application. This should include the full directory name, using ${build_dir} if you wish.") - (ada-prj-field 'main_unit "File name of the main unit" -"Name of the file to pass to the gnatmake command, -and that will create the executable. -This should not include any directory specification.") (ada-prj-field 'build_dir "Build directory" "Reference directory for relative paths in src_dir and obj_dir below. This is also the directory @@ -513,10 +509,8 @@ (ada-reread-prj-file ada-prj-default-project-file) (ada-reread-prj-file))) - ;; Else start the interactive editor (switch-to-buffer "*Edit Ada Mode Project*") - (ada-xref-set-default-prj-values 'ada-prj-default-values ada-buffer) (ada-prj-initialize-values 'ada-prj-current-values ada-buffer ada-prj-default-project-file)
--- a/lisp/progmodes/ada-xref.el Mon Jul 28 07:15:44 2008 +0000 +++ b/lisp/progmodes/ada-xref.el Mon Jul 28 11:03:42 2008 +0000 @@ -68,6 +68,13 @@ Set to 0, if you don't use crunched filenames. This should be a string." :type 'string :group 'ada) +(defcustom ada-gnat-cmd "gnat" + "Default GNAT project file parser. +Will be run with args \"list -v -Pfile.gpr\". +Default is standard GNAT distribution; alternate \"gnatpath\" +is faster, available from Ada mode web site." + :type 'string :group 'ada) + (defcustom ada-gnatls-args '("-v") "*Arguments to pass to `gnatls' to find location of the runtime. Typical use is to pass `--RTS=soft-floats' on some systems that support it. @@ -94,6 +101,20 @@ "Default options for `gnatmake'." :type 'string :group 'ada) +(defcustom ada-prj-default-gpr-file "" + "Default GNAT project file. +If non-empty, this file is parsed to set the source and object directories for +the Ada mode project." + :type 'string :group 'ada) + +(defcustom ada-prj-ada-project-path-sep + (if (or (equal system-type 'windows-nt) + (equal system-type 'ms-dos)) + ";" + ":") + "Default separator for ada_project_path project variable." + :type 'string :group 'ada) + (defcustom ada-prj-gnatfind-switches "-rf" "Default switches to use for `gnatfind'. You should modify this variable, for instance to add `-a', if you are working @@ -123,7 +144,7 @@ :type 'string :group 'ada) (defcustom ada-prj-default-make-cmd - (concat "${cross_prefix}gnatmake -o ${main} ${main_unit} ${gnatmake_opt} " + (concat "${cross_prefix}gnatmake -o ${main} ${main} ${gnatmake_opt} " "-cargs ${comp_opt} -bargs ${bind_opt} -largs ${link_opt}") "*Default command to be used to compile the application. This is the same syntax as in the project file." @@ -217,7 +238,7 @@ It has the format: (project project ...) A project has the format: (project-file . project-plist) \(See 'apropos plist' for operations on property lists). -See `ada-xref-set-default-prj-values' for the list of valid properties. +See `ada-default-prj-properties' for the list of valid properties. The current project is retrieved with `ada-xref-current-project'. Properties are retrieved with `ada-xref-get-project-field', set with `ada-xref-set-project-field'. If project properties are accessed with no @@ -260,68 +281,142 @@ (defun ada-find-executable (exec-name) "Find the full path to the executable file EXEC-NAME. +If not found, throw an error. On Windows systems, this will properly handle .exe extension as well" - (or (ada-find-file-in-dir exec-name exec-path) - (ada-find-file-in-dir (concat exec-name ".exe") exec-path) - exec-name)) + (let ((result (or (ada-find-file-in-dir exec-name exec-path) + (ada-find-file-in-dir (concat exec-name ".exe") exec-path)))) + (if result + result + (error "'%s' not found in path" exec-name)))) (defun ada-initialize-runtime-library (cross-prefix) "Initialize the variables for the runtime library location. CROSS-PREFIX is the prefix to use for the `gnatls' command." - (save-excursion - (setq ada-xref-runtime-library-specs-path '() - ada-xref-runtime-library-ali-path '()) - (set-buffer (get-buffer-create "*gnatls*")) - (widen) - (erase-buffer) - ;; Catch any error in the following form (i.e gnatls was not found) - (condition-case nil - ;; Even if we get an error, delete the *gnatls* buffer - (unwind-protect - (progn - (let ((gnatls - (ada-find-executable (concat cross-prefix "gnatls")))) - (apply 'call-process gnatls (append '(nil t nil) ada-gnatls-args))) - (goto-char (point-min)) + (let ((gnatls + (condition-case nil + ;; if gnatls not found, just give up (may not be using GNAT) + (ada-find-executable (concat cross-prefix "gnatls")) + (error nil)))) + (if gnatls + (save-excursion + (setq ada-xref-runtime-library-specs-path '() + ada-xref-runtime-library-ali-path '()) + (set-buffer (get-buffer-create "*gnatls*")) + (widen) + (erase-buffer) + ;; Even if we get an error, delete the *gnatls* buffer + (unwind-protect + (let ((status (apply 'call-process gnatls (append '(nil t nil) ada-gnatls-args)))) + (goto-char (point-min)) - ;; Source path + ;; Since we didn't provide all the inputs gnatls expects, it returns status 4 + (if (/= 4 status) + (error (buffer-substring (point) (line-end-position)))) + + ;; Source path - (search-forward "Source Search Path:") - (forward-line 1) - (while (not (looking-at "^$")) - (back-to-indentation) - (if (looking-at "<Current_Directory>") - (add-to-list 'ada-xref-runtime-library-specs-path ".") - (add-to-list 'ada-xref-runtime-library-specs-path - (buffer-substring-no-properties - (point) + (search-forward "Source Search Path:") + (forward-line 1) + (while (not (looking-at "^$")) + (back-to-indentation) + (if (looking-at "<Current_Directory>") + (add-to-list 'ada-xref-runtime-library-specs-path ".") + (add-to-list 'ada-xref-runtime-library-specs-path + (buffer-substring-no-properties + (point) (save-excursion (end-of-line) (point))))) - (forward-line 1)) + (forward-line 1)) - ;; Object path + ;; Object path - (search-forward "Object Search Path:") - (forward-line 1) - (while (not (looking-at "^$")) - (back-to-indentation) - (if (looking-at "<Current_Directory>") - (add-to-list 'ada-xref-runtime-library-ali-path ".") - (add-to-list 'ada-xref-runtime-library-ali-path - (buffer-substring-no-properties - (point) - (save-excursion (end-of-line) (point))))) - (forward-line 1)) - ) - (kill-buffer nil)) - (error nil)) + (search-forward "Object Search Path:") + (forward-line 1) + (while (not (looking-at "^$")) + (back-to-indentation) + (if (looking-at "<Current_Directory>") + (add-to-list 'ada-xref-runtime-library-ali-path ".") + (add-to-list 'ada-xref-runtime-library-ali-path + (buffer-substring-no-properties + (point) + (save-excursion (end-of-line) (point))))) + (forward-line 1)) + ) + (kill-buffer nil)))) + (set 'ada-xref-runtime-library-specs-path (reverse ada-xref-runtime-library-specs-path)) (set 'ada-xref-runtime-library-ali-path (reverse ada-xref-runtime-library-ali-path)) )) +(defun ada-gnat-parse-gpr (plist gpr-file) + "Set gpr_file, src_dir and obj_dir properties in PLIST by parsing GPR-FILE. +Returns new value of PLIST. +GPR_FILE must be full path to file, normalized. +src_dir, obj_dir will include compiler runtime. +Assumes environment variable ADA_PROJECT_PATH is set properly." + (save-excursion + (set-buffer (get-buffer-create "*gnatls*")) + (erase-buffer) + + ;; this can take a long time; let the user know what's up + (message "Parsing %s ..." gpr-file) + + ;; Even if we get an error, delete the *gnatls* buffer + (unwind-protect + (let* ((cross-prefix (plist-get plist 'cross_prefix)) + (gnat (concat cross-prefix ada-gnat-cmd)) + ;; Putting quotes around gpr-file confuses gnatpath on Lynx; not clear why + (gpr-opt (concat "-P" gpr-file)) + (src-dir '()) + (obj-dir '()) + (status (call-process gnat nil t nil "list" "-v" gpr-opt))) + (goto-char (point-min)) + + (if (/= 0 status) + (error (buffer-substring (point) (line-end-position)))) + + ;; Source path + + (search-forward "Source Search Path:") + (forward-line 1) ; first directory in list + (while (not (looking-at "^$")) ; terminate on blank line + (back-to-indentation) ; skip whitespace + (if (looking-at "<Current_Directory>") + (add-to-list 'src-dir (expand-file-name ".")) + (add-to-list 'src-dir + (expand-file-name + (buffer-substring-no-properties + (point) (line-end-position))))) + (forward-line 1)) + + ;; Object path + + (search-forward "Object Search Path:") + (forward-line 1) + (while (not (looking-at "^$")) + (back-to-indentation) + (if (looking-at "<Current_Directory>") + (add-to-list 'obj-dir (expand-file-name ".")) + (add-to-list 'obj-dir + (expand-file-name + (buffer-substring-no-properties + (point) (line-end-position))))) + (forward-line 1)) + + ;; Set properties + (setq plist (plist-put plist 'gpr_file gpr-file)) + (setq plist (plist-put plist 'src_dir (reverse src-dir))) + (plist-put plist 'obj_dir (reverse obj-dir)) + ) + (kill-buffer nil) + (message "Parsing %s ... done" gpr-file) + ) + )) + (defun ada-treat-cmd-string (cmd-string) - "Replace meta-sequences like ${...} in CMD-STRING with the appropriate value. + "Replace variable references ${var} in CMD-STRING with the appropriate value. +Also replace standard environment variables $var. Assumes project exists. As a special case, ${current} is replaced with the name of the current file, minus extension but with directory, and ${full_current} is @@ -355,60 +450,8 @@ (mapconcat (lambda(x) (concat prefix x)) value " ") t t cmd-string))))) )) - cmd-string) - -(defun ada-xref-set-default-prj-values (symbol ada-buffer) - "Reset the properties in SYMBOL to the default values for ADA-BUFFER." - - (let ((file (buffer-file-name ada-buffer)) - plist) - (save-excursion - (set-buffer ada-buffer) + (substitute-in-file-name cmd-string)) - (set 'plist - ;; Try hard to find a project file, even if the current - ;; buffer is not an Ada file or not associated with a file - (list 'filename (expand-file-name - (cond - (ada-prj-default-project-file - ada-prj-default-project-file) - (file (ada-prj-find-prj-file file t)) - (t - (message (concat "Not editing an Ada file," - "and no default project " - "file specified!")) - ""))) - 'build_dir (file-name-as-directory (expand-file-name ".")) - 'src_dir (list ".") - 'obj_dir (list ".") - 'casing (if (listp ada-case-exception-file) - ada-case-exception-file - (list ada-case-exception-file)) - 'comp_opt ada-prj-default-comp-opt - 'bind_opt ada-prj-default-bind-opt - 'link_opt ada-prj-default-link-opt - 'gnatmake_opt ada-prj-default-gnatmake-opt - 'gnatfind_opt ada-prj-gnatfind-switches - 'main (if file - (file-name-nondirectory - (file-name-sans-extension file)) - "") - 'main_unit (if file - (file-name-nondirectory - (file-name-sans-extension file)) - "") - 'cross_prefix "" - 'remote_machine "" - 'comp_cmd (list ada-prj-default-comp-cmd) - 'check_cmd (list ada-prj-default-check-cmd) - 'make_cmd (list ada-prj-default-make-cmd) - 'run_cmd (list (concat "./${main}" (if is-windows ".exe"))) - 'debug_pre_cmd (list (concat ada-cd-command " ${build_dir}")) - 'debug_cmd (concat ada-prj-default-debugger - " ${main}" (if is-windows ".exe")) - 'debug_post_cmd (list nil))) - ) - (set symbol plist))) (defun ada-xref-get-project-field (field) "Extract the value of FIELD from the current project file. @@ -419,12 +462,20 @@ which will in addition return the default paths." (let* ((project-plist (cdr (ada-xref-current-project))) - value) + (value (plist-get project-plist field))) - (set 'value (plist-get project-plist field)) + (cond + ((eq field 'gnatmake_opt) + (let ((gpr-file (plist-get project-plist 'gpr_file))) + (if (not (string= gpr-file "")) + (setq value (concat "-P\"" gpr-file "\" " value))))) - ;; Substitute the ${...} constructs in all the strings, including - ;; inside lists + ;; FIXME: check for src_dir, obj_dir here, rather than requiring user to do it + (t + nil)) + + ;; Substitute the ${...} constructs in all the strings, including + ;; inside lists (cond ((stringp value) (ada-treat-cmd-string value)) @@ -485,22 +536,16 @@ ["New..." ada-prj-new t] ["Edit..." ada-prj-edit t] "---" - ;; Add the new items + ;; Add the project files ,@(mapcar (lambda (x) - (let ((name (or (car x) "<default>")) - (command `(lambda () - "Change the active project file." - (interactive) - (ada-parse-prj-file ,(car x)) - (set 'ada-prj-default-project-file ,(car x)) - (ada-xref-update-project-menu)))) + (let* ((name (or (car x) "<default>")) + (command `(lambda () + "Select the current project file." + (interactive) + (ada-select-prj-file ,name)))) (vector - (if (string= (file-name-extension name) - ada-prj-file-extension) - (file-name-sans-extension - (file-name-nondirectory name)) - (file-name-nondirectory name)) + (file-name-nondirectory name) command :button (cons :toggle @@ -508,9 +553,6 @@ (car x)) )))) - ;; Parses all the known project files, and insert at - ;; least the default one (in case - ;; ada-xref-project-files is nil) (or ada-xref-project-files '(nil)))))) (easy-menu-add-item ada-mode-menu '() submenu))) @@ -570,22 +612,20 @@ (defun ada-require-project-file () "If the current project does not exist, load or create a default one. Should only be called from interactive functions." - (if (not (ada-xref-current-project t)) - (ada-reread-prj-file))) + (if (string= "" ada-prj-default-project-file) + (ada-reread-prj-file (ada-prj-find-prj-file t)))) -(defun ada-xref-current-project-file (&optional no-user-question) - "Return the current project file name; never nil unless NO-USER-QUESTION. -If NO-USER-QUESTION, don't prompt user for file. Call -`ada-require-project-file' first if a project must exist." +(defun ada-xref-current-project-file () + "Return the current project file name; never nil. +Call `ada-require-project-file' first if a project must exist." (if (not (string= "" ada-prj-default-project-file)) ada-prj-default-project-file - (ada-prj-find-prj-file nil no-user-question))) + (ada-prj-find-prj-file t))) -(defun ada-xref-current-project (&optional no-user-question) - "Return the current project; nil if none. -If NO-USER-QUESTION, don't prompt user for file. Call -`ada-require-project-file' first if a project must exist." - (let* ((file-name (ada-xref-current-project-file no-user-question))) +(defun ada-xref-current-project () + "Return the current project. +Call `ada-require-project-file' first to ensure a project exists." + (let* ((file-name (ada-xref-current-project-file))) (assoc file-name ada-xref-project-files))) (defun ada-show-current-project () @@ -594,9 +634,9 @@ (message (ada-xref-current-project-file))) (defun ada-show-current-main () - "Display current main unit name in message buffer." + "Display current main file name in message buffer." (interactive) - (message "ada-mode main_unit: %s" (ada-xref-get-project-field 'main_unit))) + (message "ada-mode main: %s" (ada-xref-get-project-field 'main))) (defun ada-xref-push-pos (filename position) "Push (FILENAME, POSITION) on the position ring for cross-references." @@ -619,23 +659,16 @@ name) ;; FIXME: use convert-standard-filename instead -(defun ada-set-default-project-file (name &optional keep-existing) - "Set the file whose name is NAME as the default project file. -If KEEP-EXISTING is true and a project file has already been loaded, nothing -is done. This is meant to be used from `ada-mode-hook', for instance, to force -a project file unless the user has already loaded one." +(defun ada-set-default-project-file (file) + "Set FILE as the current project file." (interactive "fProject file:") - (if (or (not keep-existing) - (not ada-prj-default-project-file) - (equal ada-prj-default-project-file "")) - (progn - (setq ada-prj-default-project-file name) - (ada-reread-prj-file name)))) + (ada-parse-prj-file file) + (ada-select-prj-file file)) ;; ------ Handling the project file ----------------------------- -(defun ada-prj-find-prj-file (&optional file no-user-question) - "Find the project file associated with FILE (or the current buffer if nil). +(defun ada-prj-find-prj-file (&optional no-user-question) + "Find the project file associated with the current buffer. If the buffer is not in Ada mode, or not associated with a file, return `ada-prj-default-project-file'. Otherwise, search for a file with the same base name as the Ada file, but extension given by @@ -647,19 +680,15 @@ (let (selected) (if (not (and (derived-mode-p 'ada-mode) - buffer-file-name)) + buffer-file-name)) ;; Not in an Ada buffer, or current buffer not associated ;; with a file (for instance an emerge buffer) - - (if (and ada-prj-default-project-file - (not (string= ada-prj-default-project-file ""))) - (setq selected ada-prj-default-project-file) - (setq selected nil)) + (setq selected nil) ;; other cases: use a more complex algorithm - (let* ((current-file (or file (buffer-file-name))) + (let* ((current-file (buffer-file-name)) (first-choice (concat (file-name-sans-extension current-file) ada-prj-file-extension)) @@ -721,155 +750,220 @@ (or selected "default.adp") )) +(defun ada-default-prj-properties () + "Return the default project properties list with the current buffer as main." + + (let ((file (buffer-file-name nil))) + (list + ;; variable name alphabetical order + 'ada_project_path "" + 'ada_project_path_sep ada-prj-ada-project-path-sep + 'bind_opt ada-prj-default-bind-opt + 'build_dir default-directory + 'casing (if (listp ada-case-exception-file) + ada-case-exception-file + (list ada-case-exception-file)) + 'check_cmd (list ada-prj-default-check-cmd) ;; FIXME: should not a list + 'comp_cmd (list ada-prj-default-comp-cmd) ;; FIXME: should not a list + 'comp_opt ada-prj-default-comp-opt + 'cross_prefix "" + 'debug_cmd (concat ada-prj-default-debugger + " ${main}" (if is-windows ".exe")) ;; FIXME: don't need .exe? + 'debug_post_cmd (list nil) + 'debug_pre_cmd (list (concat ada-cd-command " ${build_dir}")) + 'gnatmake_opt ada-prj-default-gnatmake-opt + 'gnatfind_opt ada-prj-gnatfind-switches + 'gpr_file ada-prj-default-gpr-file + 'link_opt ada-prj-default-link-opt + 'main (if file + (file-name-nondirectory + (file-name-sans-extension file)) + "") + 'make_cmd (list ada-prj-default-make-cmd) ;; FIXME: should not a list + 'obj_dir (list ".") + 'remote_machine "" + 'run_cmd (list (concat "./${main}" (if is-windows ".exe"))) + ;; FIXME: should not a list + ;; FIXME: don't need .exe? + 'src_dir (list ".") + ))) (defun ada-parse-prj-file (prj-file) - "Read PRJ-FILE, set it as the active project." - ;; FIXME: doc nil, search, etc. - (if prj-file - (let (project src_dir obj_dir make_cmd comp_cmd check_cmd casing - run_cmd debug_pre_cmd debug_post_cmd - (ada-buffer (current-buffer))) - (setq prj-file (expand-file-name prj-file)) - - ;; Set the project file as the active one. - (setq ada-prj-default-project-file prj-file) - - ;; Initialize the project with the default values - (ada-xref-set-default-prj-values 'project (current-buffer)) - - ;; Do not use find-file below, since we don't want to show this - ;; buffer. If the file is open through speedbar, we can't use - ;; find-file anyway, since the speedbar frame is special and does not - ;; allow the selection of a file in it. - - (if (file-exists-p prj-file) - (progn - (let* ((buffer (run-hook-with-args-until-success - 'ada-load-project-hook prj-file))) - (unless buffer - (setq buffer (find-file-noselect prj-file nil))) - (set-buffer buffer)) - - (widen) - (goto-char (point-min)) + "Read PRJ-FILE, set project properties in `ada-xref-project-files'." + (let ((project (ada-default-prj-properties))) - ;; Now overrides these values with the project file - (while (not (eobp)) - (if (looking-at "^\\([^=]+\\)=\\(.*\\)") - (cond - ;; fields that are lists or paths require special processing - ;; FIXME: strip trailing spaces - ((string= (match-string 1) "src_dir") - (add-to-list 'src_dir - (file-name-as-directory (match-string 2)))) - ((string= (match-string 1) "obj_dir") - (add-to-list 'obj_dir - (file-name-as-directory (match-string 2)))) - ((string= (match-string 1) "casing") - (set 'casing (cons (match-string 2) casing))) - ((string= (match-string 1) "build_dir") - (set 'project - (plist-put project 'build_dir - (file-name-as-directory (match-string 2))))) - ((string= (match-string 1) "make_cmd") - (add-to-list 'make_cmd (match-string 2))) - ((string= (match-string 1) "comp_cmd") - (add-to-list 'comp_cmd (match-string 2))) - ((string= (match-string 1) "check_cmd") - (add-to-list 'check_cmd (match-string 2))) - ((string= (match-string 1) "run_cmd") - (add-to-list 'run_cmd (match-string 2))) - ((string= (match-string 1) "debug_pre_cmd") - (add-to-list 'debug_pre_cmd (match-string 2))) - ((string= (match-string 1) "debug_post_cmd") - (add-to-list 'debug_post_cmd (match-string 2))) - (t - ;; any other field in the file is just copied - (set 'project (plist-put project (intern (match-string 1)) - (match-string 2)))))) - (forward-line 1)) + (setq prj-file (expand-file-name prj-file)) + (if (string= (file-name-extension prj-file) "gpr") + (set 'project (ada-gnat-parse-gpr project prj-file)) - (if src_dir (set 'project (plist-put project 'src_dir - (reverse src_dir)))) - (if obj_dir (set 'project (plist-put project 'obj_dir - (reverse obj_dir)))) - (if casing (set 'project (plist-put project 'casing - (reverse casing)))) - (if make_cmd (set 'project (plist-put project 'make_cmd - (reverse make_cmd)))) - (if comp_cmd (set 'project (plist-put project 'comp_cmd - (reverse comp_cmd)))) - (if check_cmd (set 'project (plist-put project 'check_cmd - (reverse check_cmd)))) - (if run_cmd (set 'project (plist-put project 'run_cmd - (reverse run_cmd)))) - (if debug_post_cmd (set 'project (plist-put project 'debug_post_cmd - (reverse debug_post_cmd)))) - (if debug_pre_cmd (set 'project (plist-put project 'debug_pre_cmd - (reverse debug_pre_cmd)))) - - (set-buffer ada-buffer) - ) + (set 'project (ada-parse-prj-file-1 prj-file project)) + ) - ;; Else the file wasn't readable (probably the default project). - ;; We initialize it with the current environment variables. - ;; We need to add the startup directory in front so that - ;; files locally redefined are properly found. We cannot - ;; add ".", which varies too much depending on what the - ;; current buffer is. - (set 'project - (plist-put project 'src_dir - (append - (list command-line-default-directory) - (split-string (or (getenv "ADA_INCLUDE_PATH") "") ":") - (list "." default-directory)))) - (set 'project - (plist-put project 'obj_dir - (append - (list command-line-default-directory) - (split-string (or (getenv "ADA_OBJECTS_PATH") "") ":") - (list "." default-directory)))) - ) - - - ;; Delete the default project file from the list, if it is there. - ;; Note that in that case, this default project is the only one in - ;; the list - (if (assoc nil ada-xref-project-files) - (setq ada-xref-project-files nil)) + ;; Store the project properties + (if (assoc prj-file ada-xref-project-files) + (setcdr (assoc prj-file ada-xref-project-files) project) + (add-to-list 'ada-xref-project-files (cons prj-file project))) - ;; Memorize the newly read project file - (if (assoc prj-file ada-xref-project-files) - (setcdr (assoc prj-file ada-xref-project-files) project) - (add-to-list 'ada-xref-project-files (cons prj-file project))) - - ;; Sets up the compilation-search-path so that Emacs is able to - ;; go to the source of the errors in a compilation buffer - (setq compilation-search-path (ada-xref-get-src-dir-field)) - - ;; Set the casing exceptions file list - (if casing - (progn - (setq ada-case-exception-file (reverse casing)) - (ada-case-read-exceptions))) - - ;; Add the directories to the search path for ff-find-other-file - ;; Do not add the '/' or '\' at the end - (setq ada-search-directories-internal - (append (mapcar 'directory-file-name compilation-search-path) - ada-search-directories)) - - (ada-xref-update-project-menu) - ) - - ;; No prj file ? => Setup default values - ;; Note that nil means that all compilation modes will first look in the - ;; current directory, and only then in the current file's directory. This - ;; current file is assumed at this point to be in the common source - ;; directory. - (setq compilation-search-path (list nil default-directory)) + (ada-xref-update-project-menu) )) +(defun ada-parse-prj-file-1 (prj-file project) + "Parse the Ada mode project file PRJ-FILE, set project properties in PROJECT. +Return new value of PROJECT." + (let ((ada-buffer (current-buffer)) + ;; fields that are lists or otherwise require special processing + ada_project_path casing comp_cmd check_cmd + debug_pre_cmd debug_post_cmd gpr_file make_cmd obj_dir src_dir run_cmd) + + ;; Give users a chance to use compiler-specific project file formats + (let ((buffer (run-hook-with-args-until-success + 'ada-load-project-hook prj-file))) + (unless buffer + ;; we load the project file with no warnings; if it does not + ;; exist, we stay in the Ada buffer; no project variable + ;; settings will be found. That works for the default + ;; "default.adp", which does not exist as a file. + (setq buffer (find-file-noselect prj-file nil))) + (set-buffer buffer)) + + (widen) + (goto-char (point-min)) + + ;; process each line + (while (not (eobp)) + + ;; ignore lines that don't have the format "name=value", put + ;; 'name', 'value' in match-string. + (if (looking-at "^\\([^=\n]+\\)=\\(.*\\)") + (cond + ;; FIXME: strip trailing spaces + ;; variable name alphabetical order + ((string= (match-string 1) "ada_project_path") + (add-to-list 'ada_project_path + (expand-file-name + (substitute-in-file-name (match-string 2))))) + + ((string= (match-string 1) "build_dir") + (set 'project + (plist-put project 'build_dir + (file-name-as-directory (match-string 2))))) + + ((string= (match-string 1) "casing") + (add-to-list 'casing + (expand-file-name (substitute-in-file-name (match-string 2))))) + + ((string= (match-string 1) "check_cmd") + (add-to-list 'check_cmd (match-string 2))) + + ((string= (match-string 1) "comp_cmd") + (add-to-list 'comp_cmd (match-string 2))) + + ((string= (match-string 1) "debug_post_cmd") + (add-to-list 'debug_post_cmd (match-string 2))) + + ((string= (match-string 1) "debug_pre_cmd") + (add-to-list 'debug_pre_cmd (match-string 2))) + + ((string= (match-string 1) "gpr_file") + ;; expand now; path is relative to Emacs project file + (setq gpr_file (expand-file-name (match-string 2)))) + + ((string= (match-string 1) "make_cmd") + (add-to-list 'make_cmd (match-string 2))) + + ((string= (match-string 1) "obj_dir") + (add-to-list 'obj_dir + (file-name-as-directory + (expand-file-name (match-string 2))))) + + ((string= (match-string 1) "run_cmd") + (add-to-list 'run_cmd (match-string 2))) + + ((string= (match-string 1) "src_dir") + (add-to-list 'src_dir + (file-name-as-directory + (expand-file-name (match-string 2))))) + + (t + ;; any other field in the file is just copied + (set 'project (plist-put project + (intern (match-string 1)) + (match-string 2)))))) + + (forward-line 1)) + + ;; done reading file + + ;; back to the user buffer + (set-buffer ada-buffer) + + ;; process accumulated lists + (if ada_project_path + (let ((sep (plist-get project 'ada_project_path_sep))) + (setq ada_project_path (reverse ada_project_path)) + (setq ada_project_path (mapconcat 'identity ada_project_path sep)) + (set 'project (plist-put project 'ada_project_path ada_project_path)) + ;; env var needed now for ada-gnat-parse-gpr + (setenv "ADA_PROJECT_PATH" ada_project_path))) + + (if debug_post_cmd (set 'project (plist-put project 'debug_post_cmd (reverse debug_post_cmd)))) + (if debug_pre_cmd (set 'project (plist-put project 'debug_pre_cmd (reverse debug_pre_cmd)))) + (if casing (set 'project (plist-put project 'casing (reverse casing)))) + (if check_cmd (set 'project (plist-put project 'check_cmd (reverse check_cmd)))) + (if comp_cmd (set 'project (plist-put project 'comp_cmd (reverse comp_cmd)))) + (if make_cmd (set 'project (plist-put project 'make_cmd (reverse make_cmd)))) + (if run_cmd (set 'project (plist-put project 'run_cmd (reverse run_cmd)))) + + (if gpr_file + (progn + (set 'project (ada-gnat-parse-gpr project gpr_file)) + ;; append Ada source and object directories to others from Emacs project file + (setq src_dir (append (plist-get project 'src_dir) src_dir)) + (setq obj_dir (append (plist-get project 'obj_dir) obj_dir)) + (setq ada-xref-runtime-library-specs-path '() + ada-xref-runtime-library-ali-path '())) + ) + + ;; FIXME: gnatpath.exe doesn't output the runtime libraries, so always call ada-initialize-runtime-library + ;; if using a gpr_file, the runtime library directories are + ;; included in src_dir and obj_dir; otherwise they are in the + ;; 'runtime-library' variables. + ;; FIXME: always append to src_dir, obj_dir + (ada-initialize-runtime-library (or (ada-xref-get-project-field 'cross_prefix) "")) + ;;) + + (if obj_dir (set 'project (plist-put project 'obj_dir (reverse obj_dir)))) + (if src_dir (set 'project (plist-put project 'src_dir (reverse src_dir)))) + + project + )) + +(defun ada-select-prj-file (file) + "Select FILE as the current project file." + (interactive) + (setq ada-prj-default-project-file (expand-file-name file)) + + (let ((casing (ada-xref-get-project-field 'casing))) + (if casing + (progn + ;; FIXME: use ada-get-absolute-dir here + (setq ada-case-exception-file casing) + (ada-case-read-exceptions)))) + + (let ((ada_project_path (ada-xref-get-project-field 'ada_project_path))) + (if ada_project_path + ;; FIXME: use ada-get-absolute-dir, mapconcat here + (setenv "ADA_PROJECT_PATH" ada_project_path))) + + (setq compilation-search-path (ada-xref-get-src-dir-field)) + + (setq ada-search-directories-internal + ;; FIXME: why do we need directory-file-name here? + (append (mapcar 'directory-file-name compilation-search-path) + ada-search-directories)) + + ;; return 't', for decent display in message buffer when called interactively + t) (defun ada-find-references (&optional pos arg local-only) "Find all references to the entity under POS. @@ -927,7 +1021,9 @@ (concat "'\"" (substring entity 1 -1) "\"'")) entity)) (switches (ada-xref-get-project-field 'gnatfind_opt)) - (command (concat "gnat find " switches " " + ;; FIXME: use gpr_file + (cross-prefix (ada-xref-get-project-field 'cross_prefix)) + (command (concat cross-prefix "gnat find " switches " " quote-entity (if file (concat ":" (file-name-nondirectory file))) (if line (concat ":" line)) @@ -941,8 +1037,8 @@ (not (string= ada-prj-default-project-file ""))) (if (string-equal (file-name-extension ada-prj-default-project-file) "gpr") - (setq command (concat command " -P" ada-prj-default-project-file)) - (setq command (concat command " -p" ada-prj-default-project-file)))) + (setq command (concat command " -P\"" ada-prj-default-project-file "\"")) + (setq command (concat command " -p\"" ada-prj-default-project-file "\"")))) (if (and append (get-buffer ada-gnatfind-buffer-name)) (save-excursion @@ -1087,8 +1183,9 @@ (defun ada-get-absolute-dir-list (dir-list root-dir) "Return the list of absolute directories found in DIR-LIST. -If a directory is a relative directory, ROOT-DIR is prepended." - (mapcar (lambda (x) (expand-file-name x root-dir)) dir-list)) +If a directory is a relative directory, ROOT-DIR is prepended. +Project and environment variables are substituted." + (mapcar (lambda (x) (expand-file-name x (ada-treat-cmd-string root-dir))) dir-list)) (defun ada-set-environment () "Prepare an environment for Ada compilation. @@ -1148,7 +1245,7 @@ (compile (ada-quote-cmd cmd)))) (defun ada-set-main-compile-application () - "Set main_unit and main project variables to current buffer, build main." + "Set main project variable to current buffer, build main." (interactive) (ada-require-project-file) (let* ((file (buffer-file-name (current-buffer))) @@ -1162,7 +1259,6 @@ (file-name-sans-extension file)) "")) (ada-xref-set-project-field 'main main) - (ada-xref-set-project-field 'main_unit main) (ada-compile-application)))) (defun ada-compile-current (&optional arg prj-field) @@ -1177,8 +1273,6 @@ (process-environment (ada-set-environment)) (compilation-scroll-output t)) - (setq compilation-search-path (ada-xref-get-src-dir-field)) - (unless cmd (setq cmd '("") arg t)) @@ -1354,16 +1448,13 @@ ))) (defun ada-reread-prj-file (&optional filename) - "Reread either the current project, or FILENAME if non-nil." + "Reread either the current project, or FILENAME if non-nil. +If FILENAME is non-nil, set it as current project." (interactive "P") - (if filename - (ada-parse-prj-file filename) - (ada-parse-prj-file (ada-prj-find-prj-file))) - - ;; Reread the location of the standard runtime library - (ada-initialize-runtime-library - (or (ada-xref-get-project-field 'cross_prefix) "")) - ) + (if (not filename) + (setq filename ada-prj-default-project-file)) + (ada-parse-prj-file filename) + (ada-select-prj-file filename)) ;; ------ Private routines @@ -2184,8 +2275,8 @@ (defun ada-make-filename-from-adaname (adaname) "Determine the filename in which ADANAME is found. This is a GNAT specific function that uses gnatkrunch." - (let (krunch-buf) - (setq krunch-buf (generate-new-buffer "*gkrunch*")) + (let ((krunch-buf (generate-new-buffer "*gkrunch*")) + (cross-prefix (plist-get plist 'cross_prefix))) (save-excursion (set-buffer krunch-buf) ;; send adaname to external process `gnatkr'. @@ -2193,7 +2284,7 @@ ;; behaviors depending on the version: ;; Up to 3.15: "AA.BB.CC" => aa-bb-cc ;; After: "AA.BB.CC" => aa-bb.cc - (call-process "gnatkr" nil krunch-buf nil + (call-process (concat cross-prefix "gnatkr") nil krunch-buf nil (concat adaname ".adb") ada-krunch-args) ;; fetch output of that process (setq adaname (buffer-substring @@ -2211,33 +2302,40 @@ (defun ada-make-body-gnatstub (&optional interactive) "Create an Ada package body in the current buffer. -This function uses the `gnatstub' program to create the body. -If INTERACTIVE is nil, kill the current buffer. -This function typically is to be hooked into `ff-file-created-hook'." +This function uses the `gnat stub' program to create the body. +This function typically is to be hooked into `ff-file-created-hook'. +If INTERACTIVE is nil, assume this is called from `ff-file-created-hook'." (interactive "p") (ada-require-project-file) - (save-some-buffers nil nil) - - ;; If the current buffer is the body (as is the case when calling this - ;; function from ff-file-created-hook), then kill this temporary buffer + ;; If not interactive, assume we are being called from + ;; ff-file-created-hook. Then the current buffer is for the body + ;; file, but we will create a new one after gnat stub runs (unless interactive (set-buffer-modified-p nil) (kill-buffer (current-buffer))) + (save-some-buffers nil nil) - ;; Make sure the current buffer is the spec (this might not be the case - ;; if for instance the user was asked for a project file) + ;; Make sure the current buffer is the spec, so gnat stub gets the + ;; right package parameter (this might not be the case if for + ;; instance the user was asked for a project file) (unless (buffer-file-name (car (buffer-list))) (set-buffer (cadr (buffer-list)))) - ;; Call the external process gnatstub - (let* ((gnatstub-opts (ada-treat-cmd-string ada-gnatstub-opts)) + ;; Call the external process + (let* ((project-plist (cdr (ada-xref-current-project))) + (gnatstub-opts (ada-treat-cmd-string ada-gnatstub-opts)) + (gpr-file (plist-get project-plist 'gpr_file)) (filename (buffer-file-name (car (buffer-list)))) (output (concat (file-name-sans-extension filename) ".adb")) - (gnatstub-cmd (concat "gnatstub " gnatstub-opts " " filename)) - (buffer (get-buffer-create "*gnatstub*"))) + (cross-prefix (plist-get project-plist 'cross_prefix)) + (gnatstub-cmd (concat cross-prefix "gnat stub" + (if (not (string= gpr-file "")) + (concat " -P\"" gpr-file "\"")) + " " gnatstub-opts " " filename)) + (buffer (get-buffer-create "*gnat stub*"))) (save-excursion (set-buffer buffer) @@ -2246,30 +2344,18 @@ (insert gnatstub-cmd) (newline) ) - ;; call gnatstub to create the body file + (call-process shell-file-name nil buffer nil "-c" gnatstub-cmd) - (if (save-excursion - (set-buffer buffer) - (goto-char (point-min)) - (search-forward "command not found" nil t)) - (progn - (message "gnatstub was not found -- using the basic algorithm") - (sleep-for 2) - (kill-buffer buffer) - (ada-make-body)) + ;; clean up the output - ;; Else clean up the output + (if (file-exists-p output) + (progn + (find-file output) + (kill-buffer buffer)) - (if (file-exists-p output) - (progn - (find-file output) - (kill-buffer buffer)) - - ;; display the error buffer - (display-buffer buffer) - ) - ))) + ;; file not created; display the error message + (display-buffer buffer)))) (defun ada-xref-initialize () "Function called by `ada-mode-hook' to initialize the ada-xref.el package. @@ -2298,14 +2384,6 @@ 'error-message "File not found in src-dir (check project file): ") -;; Initializes the cross references to the runtime library -(ada-initialize-runtime-library "") - -;; Add these standard directories to the search path -(set 'ada-search-directories-internal - (append (mapcar 'directory-file-name ada-xref-runtime-library-specs-path) - ada-search-directories)) - (provide 'ada-xref) ;; arch-tag: 415a39fe-577b-4676-b3b1-6ff6db7ca24e