gprbuild-gpl-2014-src/0000755000076700001450000000000012323721732014134 5ustar gnatmailgnatgprbuild-gpl-2014-src/known-problems-1300000644000076700001450000001072611267625216017351 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.3.0 ======================================== Copyright (c) 2009, AdaCore The following is a listing of known problems in release 1.3.0. Except where specifically noted, all these problems have been corrected in the development tree of the 1.4 technology. This means they are corrected in any 1.3.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-130-IA09-020 Wrong run path option for shared libs on Darwin Problem: On Darwin, where there should be one run path option per directory, a single run path option for all the directory is issued when linking a shared library. Status: This was fixed in 1.4.0 on 2009-10-09 Workaround: Use static libraries KP-130-IA01-027 Incorrect linking of shared library on Windows Problem: When gprbuild is invoked with --unchecked-shared-lib-imports and a shared library imports a static ibrary, the linking of the shared library may fail in Windows with undefined references. Status: This was fixed in 1.4.0 on 2009-10-02 Workaround: Add the necessary Library_Options KP-130-I904-011 Incorrect compilation in extending projects Problem: gprbuild incorrectly compiles up to date inherited sources in extending projects and does not recompile non up-to-date sources in projects extending externally built projects. Status: This was fixed in 1.4.0 on 2009-09-05 Workaround: Make the project being extended not externally built. KP-130-I828-007 Crash when using attribute Included_Switches Problem: When there are several languages in a project files and for one of these languages attribute Included_Switches is declared, gprbuild may crash. Status: This was fixed in 1.4.0 on 2009-08-29 Workaround: Use one project file for each language KP-130-I828-004 Failure to bind with a cross with no prefix Problem: When a cross-compiler with no prefix is used, gprbind fails as it does not recognize "gnatbind_prefix=" as a special option. Status: This was fixed in 1.4.0 on 2009-09-01 Workaround: Remove the lines in package Binder of the configuration project file that specify the option "gnatbind_prefix=". KP-130-I722-017 Systematic binding and linking when using extending projects Problem: If you are using extending projects, gprbuild will systematically bind and link your application, even when everything is up to date. Status: This was fixed in 1.4.0 on 2009-07-21 Workaround: The compilation still performs correctly, and is just a bit slower KP-130-I713-011 gprclean does not remove binder files Problem: When the main unit's name is less than 3 characters long, gprclean does not remove the binder generated files (b__*.ads, b__*.adb and *.bexch files) Status: This was fixed in 1.4.0 on 2009-07-13 Workaround: Remove the files manually. KP-130-I525-017 gprbuild incompatible with option -r of gnatbind Problem: When a binder option such as -r that adds output to the invocation of gnatbind is used, linking fails. Status: This was fixed in 1.4.0 on 2009-08-12 Workaround: Remove binder option -r KP-130-I507-019 Spec not compiled when body has been excluded Problem: When the body of a spec has been locally removed, the spec that does not need a completion is not compiled. Status: This was fixed in 1.4.0 on 2009-05-19 Workaround: Use a spec with a dummy completion and a dummy body KP-130-I505-015 Extending library project not built Problem: When gprbuild is invoked for a library project that extends another one, the library may not be built. Status: This was fixed in 1.4.0 on 2009-05-06 Workaround: Use only non extending library projects KP-130-I421-020 First compiler on the path not automatically used Problem: If the directory where gprbuild resides is not first on the path, compilers that are in front of this directory in the path will not be chosen in autoconfiguration. Status: This was fixed in 1.4.0 on 2009-09-08 Workaround: Create a configuration project file using gprconfig before invoking gprbuild. gprbuild-gpl-2014-src/obj-debug/0000755000076700001450000000000012317234544015775 5ustar gnatmailgnatgprbuild-gpl-2014-src/share/0000755000076700001450000000000012317234545015242 5ustar gnatmailgnatgprbuild-gpl-2014-src/share/_default.gpr0000644000076700001450000000005112323721731017526 0ustar gnatmailgnatstandard project Default is end Default; gprbuild-gpl-2014-src/share/gprconfig/0000755000076700001450000000000012317234545017220 5ustar gnatmailgnatgprbuild-gpl-2014-src/share/gprconfig/asm.xml0000644000076700001450000000340611452363313020520 0ustar gnatmailgnat package Naming is for Body_Suffix ("Asm_Cpp") use ".S"; end Naming; package Compiler is for Driver ("Asm_Cpp") use "${PATH(asm_cpp)}${PREFIX(asm_cpp)}gcc"; for Leading_Required_Switches ("Asm_Cpp") use Compiler'Leading_Required_Switches ("Asm_Cpp") & ("-c", "-x", "assembler-with-cpp"); for Include_Path ("Asm_Cpp") use "CPATH"; end Compiler; package Naming is for Body_Suffix ("Asm") use ".s"; end Naming; package Compiler is for Driver ("Asm") use "${PATH(asm)}${PREFIX(asm)}gcc"; for Leading_Required_Switches ("Asm") use Compiler'Leading_Required_Switches ("Asm") & ("-c", "-x", "assembler"); for Include_Path ("Asm") use "CPATH"; end Compiler; package Naming is for Body_Suffix ("Asm2") use ".asm"; end Naming; package Compiler is for Driver ("Asm2") use "${PATH(asm2)}${PREFIX(asm2)}gcc"; for Leading_Required_Switches ("Asm2") use Compiler'Leading_Required_Switches ("Asm2") & ("-c", "-x", "assembler"); for Include_Path ("Asm2") use "CPATH"; end Compiler; gprbuild-gpl-2014-src/share/gprconfig/linker.xml0000644000076700001450000011137712277050514021235 0ustar gnatmailgnat for Archive_Builder use ("lmp-elf-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("lmp-elf-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-elf-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-elf-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("ar", "crs"); for Archive_Builder_Append_Option use ("q"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-xcoff-lynxos178-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-xcoff-lynxos178-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-eabispe-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-eabispe-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("i686-elinos-linux-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("i686-elinos-linux-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("i686-pc-mingw32-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("i686-pc-mingw32-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("x86_64-pc-mingw32-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("x86_64-pc-mingw32-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-elinos-linux-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-elinos-linux-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("arm-linux-androideabi-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("arm-linux-androideabi-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("arm-linux-gnueabi-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("arm-linux-gnueabi-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("erc32-elf-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("erc32-elf-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("leon-elf-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("leon-elf-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("leon3-elf-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("leon3-elf-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("arm-eabi-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("arm-eabi-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("avr-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("avr-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("i586-sysgo-pikeos-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("i586-sysgo-pikeos-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Suffix use ".a"; package Linker is for Max_Command_Line_Length use "15000"; for Response_File_Format use "object_list"; for Response_File_Switches use ("-Wl,-f,"); for Map_File_Option use "-Wl,-b,map:"; end Linker; for Archive_Builder use ("e500v2-wrs-vxworks-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("e500v2-wrs-vxworks-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("e500v2-wrs-vxworksae-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("e500v2-wrs-vxworksae-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("e500v2-wrs-vxworksmils-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("e500v2-wrs-vxworksmils-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("i586-wrs-vxworks-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("i586-wrs-vxworks-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("i586-wrs-vxworksae-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("i586-wrs-vxworksae-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("arm-wrs-vxworks-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("arm-wrs-vxworks-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-wrs-vxworks-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-wrs-vxworks-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("leon-wrs-vxworks-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("leon-wrs-vxworks-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-wrs-vxworksae-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-wrs-vxworksae-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-wrs-vxworksmils-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-wrs-vxworksmils-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Suffix use ".a"; for Archive_Builder use ("ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("powerpc-wrs-linux-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("powerpc-wrs-linux-ranlib"); for Archive_Suffix use ".a"; for Archive_Builder use ("e500v2-wrs-linux-ar", "cr"); for Archive_Builder_Append_Option use ("q"); for Archive_Indexer use ("e500v2-wrs-linux-ranlib"); for Archive_Suffix use ".a"; package Linker is for Driver use Compiler'Driver ("Ada"); end Linker; for Library_Support use "static_only"; for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "none"; package Linker is for Driver use "aa_link"; end Linker; for Library_Support use "none"; package Linker is for Driver use "dotnet-ld"; end Linker; for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "full"; for Shared_Library_Prefix use "lib"; for Symbolic_Link_Supported use "true"; for Library_Major_Minor_Id_Supported use "true"; for Run_Path_Option use ("-Wl,-rpath,"); for Separate_Run_Path_Options use "true"; for Run_Path_Origin use "@executable_path"; for Library_Install_Name_Option use "-Wl,-install_name,@rpath"; for Shared_Library_Suffix use ".dylib"; for Library_Auto_Init_Supported use "true"; for Archive_Indexer use project'Archive_Indexer & ("-c"); for Shared_Library_Minimum_Switches use ("-dynamiclib", "-shared-libgcc"); for Library_Encapsulated_Options use ("-shared", "-static-libgcc"); package Linker is for Map_File_Option use "-Wl,-map,"; end Linker; for Library_Rpath_Options ("C++") use ("-print-file-name=libstdc++.dylib"); for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "full"; for Shared_Library_Prefix use "lib"; for Symbolic_Link_Supported use "true"; for Library_Major_Minor_Id_Supported use "true"; for Shared_Library_Minimum_Switches use ("-shared", "-fPIC"); for Library_Version_Switches use ("-Wl,-soname,"); for Shared_Library_Suffix use ".sl"; for Library_Auto_Init_Supported use "true"; for Run_Path_Option use ("-Wl,+b,"); for Library_Partial_Linker use ("gcc", "-nostdlib", "-Wl,-r", "-o"); package Linker is for Max_Command_Line_Length use "5000"; for Response_File_Format use "object_list"; for Response_File_Switches use ("-Wl,-c,"); end Linker; for Shared_Library_Suffix use ".so"; for Library_Version_Switches use ("-Wl,+h,"); for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "full"; for Shared_Library_Prefix use "lib"; for Symbolic_Link_Supported use "true"; for Library_Major_Minor_Id_Supported use "true"; for Shared_Library_Minimum_Switches use ("-shared"); for Library_Version_Switches use ("-Wl,-soname,"); for Shared_Library_Suffix use ".so"; for Library_Auto_Init_Supported use "true"; for Run_Path_Option use ("-Wl,-z,origin,-rpath,"); for Run_Path_Origin use "$$ORIGIN"; for Library_Encapsulated_Options use ("-shared", "-static-libgcc"); package Linker is for Map_File_Option use "-Wl,-Map,"; end Linker; for Library_Partial_Linker use ("${PATH(ada)}${PREFIX(ada)}gcc", "-nostdlib", "-Wl,-r", "-o"); for Library_Partial_Linker use ("${PATH(ada)}${PREFIX(c)}gcc", "-nostdlib", "-Wl,-r", "-o"); for Library_Rpath_Options ("C++") use ("-print-file-name=libstdc++.so"); for Run_Path_Option use ("-Wl,-rpath,"); for Run_Path_Option use ("-Wl,-rpath,"); package Linker is for Max_Command_Line_Length use "5000"; for Response_File_Format use "object_list"; for Response_File_Switches use ("-Wl,-objectlist,"); end Linker; for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "full"; for Shared_Library_Prefix use "lib"; for Symbolic_Link_Supported use "true"; for Library_Major_Minor_Id_Supported use "true"; for Shared_Library_Minimum_Switches use ("-shared"); for Library_Version_Switches use ("-Wl,-h,"); for Shared_Library_Suffix use ".so"; for Library_Auto_Init_Supported use "true"; for Library_Encapsulated_Options use ("-shared", "-static-libgcc", "-mimpure-text"); for Run_Path_Option use ("-Wl,-z,origin,-R,"); for Run_Path_Origin use "$$ORIGIN"; for Library_Partial_Linker use ("gcc", "-nostdlib", "-Wl,-r", "-o"); for Library_Rpath_Options ("C++") use ("-print-file-name=libstdc++.so"); for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "full"; for Shared_Library_Prefix use "lib"; for Symbolic_Link_Supported use "false"; for Library_Major_Minor_Id_Supported use "false"; for Shared_Library_Minimum_Switches use ("-shared", "-shared-libgcc"); for Library_Version_Switches use ("-Wl,-soname,"); for Shared_Library_Suffix use ".dll"; for Library_Encapsulated_Options use ("-shared", "-static-libgcc"); for Library_Auto_Init_Supported use "true"; for Library_Partial_Linker use ("gcc", "-nostdlib", "-Wl,-r", "-o"); package Linker is for Map_File_Option use "-Wl,-Map,"; end Linker; for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "full"; for Shared_Library_Prefix use "lib"; for Symbolic_Link_Supported use "true"; for Library_Major_Minor_Id_Supported use "true"; for Shared_Library_Minimum_Switches use ("-shared", "-Wl,-expect_unresolved,*"); for Library_Version_Switches use ("-Wl,-soname,"); for Shared_Library_Suffix use ".so"; for Library_Auto_Init_Supported use "true"; for Run_Path_Option use ("-Wl,-rpath,"); package Linker is for Max_Command_Line_Length use "10000"; for Response_File_Format use "object_list"; for Response_File_Switches use ("-Wl,-input,"); end Linker; for Library_Builder use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprlib"; for Library_Support use "full"; for Shared_Library_Prefix use "lib"; for Shared_Library_Suffix use ".exe"; for Symbolic_Link_Supported use "false"; for Library_Major_Minor_Id_Supported use "false"; for Shared_Library_Minimum_Switches use ("-shared", "-shared-libgcc"); for Library_Auto_Init_Supported use "true"; package Linker is for Required_Switches use ("-mno-cygwin"); end Linker; package Linker is for Driver use Compiler'Driver ("C++"); end Linker; package Linker is for Driver use Compiler'Driver ("C++"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-shared-libgcc"); end Linker; package Linker is for Driver use Compiler'Driver ("Fortran"); end Linker; package Linker is for Driver use Compiler'Driver ("Ada"); end Linker; package Linker is for Driver use Compiler'Driver ("C"); end Linker; package Linker is for Driver use Compiler'Driver ("Ada"); end Linker; package Linker is for Driver use Compiler'Driver ("Ada"); end Linker; package Linker is for Driver use Compiler'Driver ("C"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-L" & Wind_Base & "/target/lib/usr/lib/ppc/PPC32/common", "-L" & Wind_Base & "/target/usr/lib/ppc/PPC32/common"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-L" & Wind_Base & "/target/lib_smp/usr/lib/ppc/PPC32/common"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-L" & Wind_Base & "/target/lib_smp/usr/lib/arm/ARMARCH7/common"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-L" & Wind_Base & "/target/lib/usr/lib/ppc/PPC32/e500v2common", "-L" & Wind_Base & "/target/usr/lib/ppc/PPC32/e500v2common"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-L" & Wind_Base & "/target/lib_smp/usr/lib/ppc/PPC32/e500v2common"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-L" & Wind_Base & "/target/usr/lib_cert_rtp/ppc/PPC32/common"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-L" & Wind_Base & "/target/usr/lib_cert_rtp/ppc/PPC32/e500v2common"); end Linker; package Linker is for Driver use Compiler'Driver ("C"); end Linker; package Linker is for Response_File_Format use "GCC_GNU"; for Max_Command_Line_Length use "8192"; end Linker; package Linker is for Response_File_Format use "GNU"; for Max_Command_Line_Length use "8192"; end Linker; package Linker is for Response_File_Format use "GNU"; for Max_Command_Line_Length use "8192"; end Linker; package Linker is for Response_File_Format use "GCC_Object_List"; end Linker; for Default_Language use "Ada"; for Default_Language use "C"; for Default_Language use "Fortran"; for Default_Language use "C++"; gprbuild-gpl-2014-src/share/gprconfig/fortran.xml0000644000076700001450000000450411452321006021404 0ustar gnatmailgnat package Naming is for Body_Suffix ("Fortran") use ".f"; end Naming; package Compiler is for Driver ("Fortran") use "${PATH(fortran)}g77"; for Leading_Required_Switches ("Fortran") use Compiler'Leading_Required_Switches ("Fortran") & ("-c", "-fno-underscoring"); for Include_Path ("Fortran") use "CPATH"; end Compiler; package Compiler is for Leading_Required_Switches ("Fortran") use Compiler'Leading_Required_Switches ("Fortran") & ("-mno-cygwin"); end Compiler; package Naming is for Body_Suffix ("Fortran") use ".f"; end Naming; package Compiler is for Driver ("Fortran") use "${PATH(fortran)}gfortran${PREFIX(fortran)}"; for Leading_Required_Switches ("Fortran") use Compiler'Leading_Required_Switches ("Fortran") & ("-c", "-fno-underscoring"); for Include_Path ("Fortran") use "CPATH"; end Compiler; package Compiler is for PIC_Option ("Fortran") use ("-fPIC"); end Compiler; gprbuild-gpl-2014-src/share/gprconfig/nocompiler.xml0000644000076700001450000000056710774202155022116 0ustar gnatmailgnat package Compiler is for Driver ("Project File") use ""; end Compiler; package Naming is for Spec_Suffix ("Project File") use ".gpr"; end Naming; gprbuild-gpl-2014-src/share/gprconfig/cpp.xml0000644000076700001450000001327312247666154020541 0ustar gnatmailgnat package Naming is for Spec_Suffix ("C++") use ".hh"; for Body_Suffix ("C++") use ".cpp"; end Naming; for Inherit_Source_Path ("C++") use ("C"); package Compiler is for Driver ("C++") use "${PATH(c++)}g++${PREFIX(c++)}"; end Compiler; package Clean is for Source_Artifact_Extensions ("C++") use (".gli"); for Object_Artifact_Extensions ("C++") use (".s", "ci", ".gcno"); end Clean; package Compiler is for Driver ("C++") use "${PATH(c++)}c++${PREFIX(c++)}"; end Compiler; package Compiler is for Leading_Required_Switches ("C++") use ("-c", "-x", "c++") & Compiler'Leading_Required_Switches ("C++"); for Dependency_Switches ("C++") use ("-MMD", "-MF", ""); for Include_Path ("C++") use "CPATH"; end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-fdump-xref"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-c", "-x", "c++"); for Dependency_Switches ("C++") use ("-Wp,-MMD,"); for Include_Path ("C++") use "CPATH"; end Compiler; package Compiler is for PIC_Option ("C++") use ("-fPIC"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-mno-cygwin"); end Compiler; gprbuild-gpl-2014-src/share/gprconfig/gnat.xml0000644000076700001450000002417112215621730020671 0ustar gnatmailgnat '> ] > package Naming is for Spec_Suffix ("Ada") use ".ads"; for Body_Suffix ("Ada") use ".adb"; for Casing use "lowercase"; for Dot_Replacement use "-"; end Naming; package Compiler is for Driver ("Ada") use "gnaamp"; for Language_Kind ("Ada") use "unit_based"; for Dependency_Kind ("Ada") use "ALI_File"; for Required_Switches ("Ada") use Compiler'Required_Switches ("Ada") & ("-gnatA"); for Object_File_Suffix ("Ada") use ".obj"; for Mapping_File_Switches ("Ada") use ("-gnatem="); for Mapping_Spec_Suffix ("Ada") use "%s"; for Mapping_Body_Suffix ("Ada") use "%b"; for Config_File_Switches ("Ada") use ("-gnatec="); for Include_Path_File ("Ada") use "ADA_PRJ_INCLUDE_FILE"; for Config_Body_File_Name ("Ada") use "pragma Source_File_Name_Project (%u, Body_File_Name => ""%f"");"; for Config_Spec_File_Name ("Ada") use "pragma Source_File_Name_Project (%u, Spec_File_Name => ""%f"");"; for Config_Body_File_Name_Pattern ("Ada") use "pragma Source_File_Name_Project " & " (Body_File_Name => ""*%b""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_Spec_File_Name_Pattern ("Ada") use "pragma Source_File_Name_Project " & " (Spec_File_Name => ""*%s""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_File_Unique ("Ada") use "False"; end Compiler; package Binder is for Objects_Path_File ("Ada") use "ADA_PRJ_OBJECTS_FILE"; for Required_Switches ("Ada") use Binder'Required_Switches ("Ada") & ("ada_binder=gnaampbind"); for Driver ("Ada") use "${GPRCONFIG_PREFIX}/libexec/gprbuild/gprbind"; end Binder; for Toolchain_Version ("Ada") use "GNAT ${VERSION(ada)}"; for Runtime_Library_Dir ("Ada") use "${RUNTIME_DIR(ada)}/adalib/"; for Runtime_Source_Dir ("Ada") use "${RUNTIME_DIR(ada)}/adainclude/"; &filter_gnat; package Naming is for Spec_Suffix ("Ada") use ".ads"; for Body_Suffix ("Ada") use ".adb"; for Casing use "lowercase"; for Dot_Replacement use "-"; end Naming; package Compiler is for Driver ("Ada") use "${PATH(ada)}${PREFIX(ada)}gcc"; for Language_Kind ("Ada") use "unit_based"; for Dependency_Kind ("Ada") use "ALI_File"; for Leading_Required_Switches ("Ada") use ("-c", "-x", "ada", "-gnatA") & Compiler'Leading_Required_Switches ("Ada"); for Mapping_File_Switches ("Ada") use ("-gnatem="); for Mapping_Spec_Suffix ("Ada") use "%s"; for Mapping_Body_Suffix ("Ada") use "%b"; for Config_File_Switches ("Ada") use ("-gnatec="); for Include_Path_File ("Ada") use "ADA_PRJ_INCLUDE_FILE"; end Compiler; package Binder is for Objects_Path_File ("Ada") use "ADA_PRJ_OBJECTS_FILE"; for Driver ("Ada") use "${GPRCONFIG_PREFIX}libexec/gprbuild/gprbind"; end Binder; package Clean is for Source_Artifact_Extensions ("Ada") use (".dg", ".rep"); for Object_Artifact_Extensions ("Ada") use (".s", "ci", ".gcno"); end Clean; for Toolchain_Version ("Ada") use "GNAT ${VERSION(ada)}"; for Runtime_Library_Dir ("Ada") use "${RUNTIME_DIR(ada)}/adalib/"; for Runtime_Source_Dir ("Ada") use "${RUNTIME_DIR(ada)}/adainclude/"; package Compiler is for Object_File_Suffix ("Ada") use ".il"; for Driver ("Ada") use "${PATH(ada)}${PREFIX(ada)}gnatcompile"; end Compiler; &filter_gnat; package Compiler is for Multi_Unit_Switches ("Ada") use ("-gnateI"); for Multi_Unit_Object_Separator ("Ada") use "~"; for Config_Body_File_Name ("Ada") use "pragma Source_File_Name_Project (%u, Body_File_Name => ""%f"");"; for Config_Spec_File_Name ("Ada") use "pragma Source_File_Name_Project (%u, Spec_File_Name => ""%f"");"; for Config_Body_File_Name_Index ("Ada") use "pragma Source_File_Name_Project (%u, Body_File_Name => ""%f"", Index => %i);"; for Config_Spec_File_Name_Index ("Ada") use "pragma Source_File_Name_Project (%u, Spec_File_Name => ""%f"", Index => %i);"; for Config_Body_File_Name_Pattern ("Ada") use "pragma Source_File_Name_Project " & " (Body_File_Name => ""*%b""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_Spec_File_Name_Pattern ("Ada") use "pragma Source_File_Name_Project " & " (Spec_File_Name => ""*%s""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_File_Unique ("Ada") use "False"; end Compiler; &filter_gnat; package Compiler is for Config_Body_File_Name ("Ada") use "pragma Source_File_Name (%u, Body_File_Name => ""%f"");"; for Config_Spec_File_Name ("Ada") use "pragma Source_File_Name (%u, Spec_File_Name => ""%f"");"; for Config_Body_File_Name_Pattern ("Ada") use "pragma Source_File_Name " & " (Body_File_Name => ""*%b""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_Spec_File_Name_Pattern ("Ada") use "pragma Source_File_Name " & " (Spec_File_Name => ""*%s""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_File_Unique ("Ada") use "True"; end Compiler; &filter_gnat; package Compiler is for Config_Body_File_Name ("Ada") use "pragma Source_File_Name_Project (%u, Body_File_Name => ""%f"");"; for Config_Spec_File_Name ("Ada") use "pragma Source_File_Name_Project (%u, Spec_File_Name => ""%f"");"; for Config_Body_File_Name_Pattern ("Ada") use "pragma Source_File_Name_Project " & " (Body_File_Name => ""*%b""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_Spec_File_Name_Pattern ("Ada") use "pragma Source_File_Name_Project " & " (Spec_File_Name => ""*%s""," & " Casing => %c," & " Dot_Replacement => ""%d"");"; for Config_File_Unique ("Ada") use "False"; end Compiler; &filter_gnat; package Compiler is for PIC_Option ("Ada") use ("-fPIC"); end Compiler; &filter_gnat; for Library_Encapsulated_Supported use "true"; package Compiler is for Leading_Required_Switches ("Ada") use Compiler'Leading_Required_Switches ("Ada") & ("--RTS=${RUNTIME(ada)}"); end Compiler; package Binder is for Required_Switches ("Ada") use Binder'Required_Switches ("Ada") & ("--RTS=${RUNTIME(ada)}"); end Binder; package Compiler is for Leading_Required_Switches ("Ada") use Compiler'Leading_Required_Switches ("Ada") & ("--RTS=${RUNTIME(ada)}/.."); end Compiler; package Binder is for Required_Switches ("Ada") use Binder'Required_Switches ("Ada") & ("--RTS=${RUNTIME(ada)}/.."); end Binder; package Compiler is for Leading_Required_Switches ("Ada") use Compiler'Leading_Required_Switches ("Ada") & ("-msoft-float"); end Compiler; gprbuild-gpl-2014-src/share/gprconfig/gprconfig.xsd0000644000076700001450000001447412267650363021734 0ustar gnatmailgnat gprbuild-gpl-2014-src/share/gprconfig/compilers.xml0000644000076700001450000006452112313013502021727 0ustar gnatmailgnat PRJFILE Project File GCC (.*(-wrs-|-sysgo|-elf-|-eabi-|-eabispe-|avr-|-elinos-linux|-pc-mingw32|-xcoff-|arm-linux-androideabi-|arm-linux-gnueabi-).*)?gcc ${PREFIX}gcc -v C ${PREFIX}gcc -dumpmachine GCC_Pro (.*(-wrs-|-sysgo|-elf-|-eabi-|-eabispe-|avr-|-elinos-linux|-pc-mingw32|-xcoff-|arm-linux-androideabi-|arm-linux-gnueabi-).*)?gcc ${PREFIX}gcc -v C ${PREFIX}gcc -dumpmachine GCC-WRS6 cc(arm|pentium|sh|mips|ppc) vxworks-6.* C kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp cc${PREFIX} -dumpmachine GCC-WRS6LEON cc(sparc) vxworks-6.* C kernel leon-wrs-vxworks GCC-WRS6E500V2 cc(ppc) vxworks-6.* C kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp e500v2-wrs-vxworks GCC-WRS7 cc(arm|pentium|sh|mips|ppc) vxworks-7.* C kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp cc${PREFIX} -dumpmachine GCC-WRS7LEON cc(sparc) vxworks-6.* C kernel leon-wrs-vxworks GCC-WRS7E500V2 cc(ppc) vxworks-7.* C kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp e500v2-wrs-vxworks GCC-WRS6CERT cc(arm|pentium|sh|mips|ppc|sparc) vxworks-cert-6.* C kernel,ravenscar-cert,zfp,rtp,ravenscar-cert-rtp cc${PREFIX} -dumpmachine GCC-WRS6CERTE500V2 cc(ppc) vxworks-cert-6.* C kernel,ravenscar-cert,zfp,rtp,ravenscar-cert-rtp e500v2-wrs-vxworks GCC-WRS5 cc(arm|pentium|sh|mips|ppc|sparc) cc${PREFIX} -v (tornado 2|VxWorks 5) C cc${PREFIX} -dumpmachine GCC-WRS653 cc(ppc|pentium) vxworks653.* C full,cert,ravenscar-cert,zfp cc${PREFIX} -dumpmachine GCC-WRS653-E500V2 cc(ppc) vxworks653.* C full,cert,ravenscar-cert,zfp e500v2-wrs-vxworksae GCC-WRSMILS cc(ppc) cc${PREFIX} -v vxworksae C full,cert,ravenscar-cert,zfp powerpc-wrs-vxworksmils GCC-WRSMILS-E500V2 cc(ppc) cc${PREFIX} -v vxworksae C full,cert,ravenscar-cert,zfp e500v2-wrs-vxworksmils GCC-WRSMILSHAE c\+\+(ppc) vxworks-mils-hae-1.* C zfp powerpc-wrs-vxworksmils GCC-WRSMILSHAE-E500V2 c\+\+(ppc) vxworks-mils-hae-1.* C zfp e500v2-wrs-vxworksmils GCC-SYSGO (x86_i586-)gcc C i586-sysgo-pikeos GCC-28 gcc gcc -v 2\.8\. C gcc -dumpmachine GNAAMP gnaampmake gnaampls -v Ada aamp G++ g\+\+ g++ -v C++ g++ -dumpmachine G++_Pro g\+\+ g++ -v C++ g++ -dumpmachine G++-WRS5 c\+\+(arm|pentium|sh|mips|ppc|sparc) c++${PREFIX} -v tornado 2|VxWorks 5 C++ c++${PREFIX} -dumpmachine G++-WRS6 c\+\+(arm|pentium|sh|mips|ppc|sparc) vxworks-6.* C++ kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp c++${PREFIX} -dumpmachine G++-WRS6LEON c\+\+(sparc) vxworks-6.* C++ kernel leon-wrs-vxworks G++-WRS6E500V2 c\+\+(ppc) vxworks-6.* C++ kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp e500v2-wrs-vxworks G++-WRS7 c\+\+(arm|pentium|sh|mips|ppc|sparc) vxworks-7.* C++ kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp c++${PREFIX} -dumpmachine G++-WRS7LEON c\+\+(sparc) vxworks-7.* C++ kernel leon-wrs-vxworks G++-WRS7E500V2 c\+\+(ppc) vxworks-7.* C++ kernel,kernel-smp,kernel-sjlj,rtp,rtp-smp e500v2-wrs-vxworks G++-WRS6CERT c\+\+(arm|pentium|sh|mips|ppc|sparc) vxworks-cert-6.* C++ kernel,ravenscar-cert,zfp,rtp,ravenscar-cert-rtp c++${PREFIX} -dumpmachine G++-WRS6CERTE500V2 c\+\+(ppc) vxworks-cert-6.* C++ kernel,ravenscar-cert,zfp,rtp,ravenscar-cert-rtp e500v2-wrs-vxworks G++-WRS653 c\+\+(ppc|pentium) vxworks653.* C++ full,cert,ravenscar-cert,zfp c++${PREFIX} -dumpmachine G++-WRS653-E500V2 c\+\+(ppc) vxworks653.* C++ full,cert,ravenscar-cert,zfp e500v2-wrs-vxworksae G++-WRSMILS c\+\+(ppc) c++${PREFIX} -v vxworksae C++ full,cert,ravenscar-cert,zfp powerpc-wrs-vxworksmils G++-WRSMILS-E500V2 c\+\+(ppc) c++${PREFIX} -v vxworksae C++ full,cert,ravenscar-cert,zfp e500v2-wrs-vxworksmils G++-WRSLINUX (powerpc-wrs-linux-gnu)-cpp ${PREFIX}-cpp -v C++ full ${PREFIX}-cpp -dumpmachine G++-WRSLINUXE500V2 (powerpc-wrs-linux-gnu)-cpp ${PREFIX}-cpp -v C++ full e500v2-wrs-linux GCC-WRSLINUX (powerpc-wrs-linux-gnu)-gcc ${PREFIX}-cpp -v C full ${PREFIX} -dumpmachine GCC-WRSLINUXE500V2 (powerpc-wrs-linux-gnu)-gcc ${PREFIX}-cpp -v C full e500v2-wrs-linux G++-WRSMILSHAE c\+\+(ppc) vxworks-mils-hae-1.* C++ zfp powerpc-wrs-vxworksmils G++-WRSMILSHAE-E500V2 c\+\+(ppc) vxworks-mils-hae-1.* C++ zfp e500v2-wrs-vxworksmils GCC-ASM (.*(-wrs-|-elf-|-eabi-|-eabispe-|avr-|elinos-linux|-pc-mingw32).*)?gcc ${PREFIX}gcc -v Asm,Asm_Cpp,Asm2 ${PREFIX}gcc -dumpmachine GNAT (.*(-wrs-|-sysgo|-elf-|-eabi-|-eabispe-|avr-|elinos-linux|-pc-mingw32|-xcoff-|-pikeos-|arm-linux-androideabi-|arm-linux-gnueabi-).*)?gnatmake ${PREFIX}gnatls -v Ada ${PREFIX}gcc -v \.\./lib/gcc(-lib)?/$TARGET/$gcc_version/adalib/ \.\./lib/gcc(-lib)?/$TARGET/$gcc_version/ada_object_path \.\./lib/gcc(-lib)?/$TARGET/$gcc_version/rts-(.*)/adalib/ ${PREFIX}gcc -dumpmachine GNAT_CODEPEER (.*codepeer-)gnatmake ${PREFIX}gnatls -v Ada ${PREFIX}gcc -v \.\./lib/gcc/.*/$gcc_version/adalib/ codepeer GNAT_DOTNET (.*dotnet-)gnatmake ${PREFIX}gnatls -v Ada \.\./lib/dotgnat/adalib/ \.\./lib/dotgnat/rts-(.*)/adalib/ dotnet G77 g77 g77 --version Fortran g77 -dumpmachine GFORTRAN gfortran gfortran -v Fortran gfortran -dumpmachine GCC-CYGMING gcc gcc --version C,C++,Fortran gcc -mno-cygwin -dumpmachine GCC-MINGW32 gcc(-sjlj|) gcc${PREFIX} --version C,C++,Fortran gcc${PREFIX} -dumpmachine DIABC-PPC dcc dcc -V C powerpc-elf LYNXWORKS-C gcc gcc -v C gcc -dumpmachine .*xcoff-lynxos.* LYNXWORKS-C++ c\+\+ c++ -v C++ c++ -dumpmachine .*xcoff-lynxos.* LLVM clang clang -v C clang -dumpmachine gprbuild-gpl-2014-src/share/gprconfig/c.xml0000644000076700001450000001706012313013502020150 0ustar gnatmailgnat package Naming is for Spec_Suffix ("C") use ".h"; for Body_Suffix ("C") use ".c"; end Naming; package Compiler is for Driver ("C") use "${PATH(c)}${PREFIX(c)}gcc"; end Compiler; package Clean is for Source_Artifact_Extensions ("C") use (".gli"); for Object_Artifact_Extensions ("C") use (".s", "ci", ".gcno"); end Clean; package Compiler is for Driver ("C") use "${PATH(c)}gcc${PREFIX(c)}"; end Compiler; package Clean is for Source_Artifact_Extensions ("C") use (".gli"); for Object_Artifact_Extensions ("C") use (".s", "ci", ".gcno"); end Clean; package Compiler is for Driver ("C") use "${PATH(c)}cc${PREFIX(c)}"; end Compiler; package Compiler is for Driver ("C") use "${PATH(c)}dcc"; end Compiler; package Compiler is for Driver ("C") use "${PATH(c)}clang"; end Compiler; package Compiler is for Leading_Required_Switches ("C") use ("-c", "-x", "c") & Compiler'Leading_Required_Switches ("C"); for Include_Path ("C") use "CPATH"; end Compiler; package Compiler is for Dependency_Switches ("C") use ("-Wp,-MMD,"); end Compiler; package Compiler is for Dependency_Switches ("C") use ("-MMD", "-MF", ""); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-tPPC750EH:cross", "-c"); for Dependency_Switches ("C") use ("-Xmake-dependency=6", "-Xmake-dependency-savefile="); for Include_Path ("C") use "CPATH"; end Compiler; package Compiler is for PIC_Option ("C") use ("-fPIC"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-fdump-xref"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-mno-cygwin"); end Compiler; gprbuild-gpl-2014-src/share/gprconfig/gnat_runtime.mapping0000644000076700001450000012257110520412162023264 0ustar gnatmailgnata-astaco.adb body Ada.Asynchronous_Task_Control a-calari.adb body Ada.Calendar.Arithmetic a-caldel.adb body Ada.Calendar.Delays a-calend.adb body Ada.Calendar a-calfor.adb body Ada.Calendar.Formatting a-catizo.adb body Ada.Calendar.Time_Zones a-cbdlli.adb body Ada.Containers.Bounded_Doubly_Linked_Lists a-cdlili.adb body Ada.Containers.Doubly_Linked_Lists a-cgaaso.adb body Ada.Containers.Generic_Anonymous_Array_Sort a-cgarso.adb body Ada.Containers.Generic_Array_Sort a-cgcaso.adb body Ada.Containers.Generic_Constrained_Array_Sort a-chacon.adb body Ada.Characters.Conversions a-chahan.adb body Ada.Characters.Handling a-chtgke.adb body Ada.Containers.Hash_Tables.Generic_Keys a-chtgop.adb body Ada.Containers.Hash_Tables.Generic_Operations a-cidlli.adb body Ada.Containers.Indefinite_Doubly_Linked_Lists a-cihama.adb body Ada.Containers.Indefinite_Hashed_Maps a-cihase.adb body Ada.Containers.Indefinite_Hashed_Sets a-ciorma.adb body Ada.Containers.Indefinite_Ordered_Maps a-ciormu.adb body Ada.Containers.Indefinite_Ordered_Multisets a-ciorse.adb body Ada.Containers.Indefinite_Ordered_Sets a-cohama.adb body Ada.Containers.Hashed_Maps a-cohase.adb body Ada.Containers.Hashed_Sets a-coinve.adb body Ada.Containers.Indefinite_Vectors a-colien.adb body Ada.Command_Line.Environment a-colire.adb body Ada.Command_Line.Remove a-comlin.adb body Ada.Command_Line a-convec.adb body Ada.Containers.Vectors a-coorma.adb body Ada.Containers.Ordered_Maps a-coormu.adb body Ada.Containers.Ordered_Multisets a-coorse.adb body Ada.Containers.Ordered_Sets a-coprnu.adb body Ada.Containers.Prime_Numbers a-crbtgk.adb body Ada.Containers.Red_Black_Trees.Generic_Keys a-crbtgo.adb body Ada.Containers.Red_Black_Trees.Generic_Operations a-crdlli.adb body Ada.Containers.Restricted_Doubly_Linked_Lists a-decima.adb body Ada.Decimal a-diocst.adb body Ada.Direct_Io.C_Streams a-direct.adb body Ada.Directories a-direio.adb body Ada.Direct_Io a-diroro.adb body Ada.Dispatching.Round_Robin a-dirval.adb body Ada.Directories.Validity a-dynpri.adb body Ada.Dynamic_Priorities a-einuoc.adb body Ada.Exceptions.Is_Null_Occurrence a-elchha.adb body Ada.Exceptions.Last_Chance_Handler a-envvar.adb body Ada.Environment_Variables a-excpol.adb body Ada.Exceptions.Poll a-exctra.adb body Ada.Exceptions.Traceback a-exexda.adb body Ada.Exceptions.Exception_Data a-exexpr.adb body Ada.Exceptions.Exception_Propagation a-exextr.adb body Ada.Exceptions.Exception_Traces a-filico.adb body Ada.Finalization.List_Controller a-finali.adb body Ada.Finalization a-interr.adb body Ada.Interrupts a-intsig.adb body Ada.Interrupts.Signal a-ngcefu.adb body Ada.Numerics.Generic_Complex_Elementary_Functions a-ngcoar.adb body Ada.Numerics.Generic_Complex_Arrays a-ngcoty.adb body Ada.Numerics.Generic_Complex_Types a-ngelfu.adb body Ada.Numerics.Generic_Elementary_Functions a-ngrear.adb body Ada.Numerics.Generic_Real_Arrays a-nudira.adb body Ada.Numerics.Discrete_Random a-nuflra.adb body Ada.Numerics.Float_Random a-numaux.adb body Ada.Numerics.Aux a-rbtgso.adb body Ada.Containers.Red_Black_Trees.Generic_Set_Operations a-reatim.adb body Ada.Real_Time a-retide.adb body Ada.Real_Time.Delays a-rttiev.adb body Ada.Real_Time.Timing_Events a-secain.adb body Ada.Strings.Equal_Case_Insensitive a-sequio.adb body Ada.Sequential_Io a-shcain.adb body Ada.Strings.Hash_Case_Insensitive a-siocst.adb body Ada.Sequential_Io.C_Streams a-slcain.adb body Ada.Strings.Less_Case_Insensitive a-ssicst.adb body Ada.Streams.Stream_Io.C_Streams a-stboha.adb body Ada.Strings.Bounded.Hash a-storio.adb body Ada.Storage_Io a-strbou.adb body Ada.Strings.Bounded a-strfix.adb body Ada.Strings.Fixed a-strhas.adb body Ada.Strings.Hash a-strmap.adb body Ada.Strings.Maps a-strsea.adb body Ada.Strings.Search a-strsup.adb body Ada.Strings.Superbounded a-strunb.adb body Ada.Strings.Unbounded a-ststio.adb body Ada.Streams.Stream_Io a-stunau.adb body Ada.Strings.Unbounded.Aux a-stunha.adb body Ada.Strings.Unbounded.Hash a-stwibo.adb body Ada.Strings.Wide_Bounded a-stwifi.adb body Ada.Strings.Wide_Fixed a-stwiha.adb body Ada.Strings.Wide_Hash a-stwima.adb body Ada.Strings.Wide_Maps a-stwise.adb body Ada.Strings.Wide_Search a-stwisu.adb body Ada.Strings.Wide_Superbounded a-stwiun.adb body Ada.Strings.Wide_Unbounded a-stzbou.adb body Ada.Strings.Wide_Wide_Bounded a-stzfix.adb body Ada.Strings.Wide_Wide_Fixed a-stzhas.adb body Ada.Strings.Wide_Wide_Hash a-stzmap.adb body Ada.Strings.Wide_Wide_Maps a-stzsea.adb body Ada.Strings.Wide_Wide_Search a-stzsup.adb body Ada.Strings.Wide_Wide_Superbounded a-stzunb.adb body Ada.Strings.Wide_Wide_Unbounded a-suteio.adb body Ada.Strings.Unbounded.Text_Io a-swbwha.adb body Ada.Strings.Wide_Bounded.Wide_Hash a-swunau.adb body Ada.Strings.Wide_Unbounded.Aux a-swuwha.adb body Ada.Strings.Wide_Unbounded.Wide_Hash a-swuwti.adb body Ada.Strings.Wide_Unbounded.Wide_Text_Io a-swwibo.adb body Ada.Strings.Wide_Wide_Bounded a-swwifi.adb body Ada.Strings.Wide_Wide_Fixed a-swwima.adb body Ada.Strings.Wide_Wide_Maps a-swwise.adb body Ada.Strings.Wide_Wide_Search a-swwisu.adb body Ada.Strings.Wide_Wide_Superbounded a-sytaco.adb body Ada.Synchronous_Task_Control a-szbzha.adb body Ada.Strings.Wide_Wide_Bounded.Wide_Wide_Hash a-szunau.adb body Ada.Strings.Wide_Wide_Unbounded.Aux a-szuzha.adb body Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Hash a-szuzti.adb body Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_Io a-tags.adb body Ada.Tags a-tasatt.adb body Ada.Task_Attributes a-taside.adb body Ada.Task_Identification a-taster.adb body Ada.Task_Termination a-teioed.adb body Ada.Text_Io.Editing a-textio.adb body Ada.Text_Io a-tiboio.adb body Ada.Text_Io.Bounded_Io a-ticoau.adb body Ada.Text_Io.Complex_Aux a-ticoio.adb body Ada.Text_Io.Complex_Io a-tideau.adb body Ada.Text_Io.Decimal_Aux a-tideio.adb body Ada.Text_Io.Decimal_Io a-tienau.adb body Ada.Text_Io.Enumeration_Aux a-tienio.adb body Ada.Text_Io.Enumeration_Io a-tifiio.adb body Ada.Text_Io.Fixed_Io a-tiflau.adb body Ada.Text_Io.Float_Aux a-tiflio.adb body Ada.Text_Io.Float_Io a-tigeau.adb body Ada.Text_Io.Generic_Aux a-tiinau.adb body Ada.Text_Io.Integer_Aux a-tiinio.adb body Ada.Text_Io.Integer_Io a-timoau.adb body Ada.Text_Io.Modular_Aux a-timoio.adb body Ada.Text_Io.Modular_Io a-tiocst.adb body Ada.Text_Io.C_Streams a-titest.adb body Ada.Text_Io.Text_Streams a-wichun.adb body Ada.Wide_Characters.Unicode a-witeio.adb body Ada.Wide_Text_Io a-wtcoau.adb body Ada.Wide_Text_Io.Complex_Aux a-wtcoio.adb body Ada.Wide_Text_Io.Complex_Io a-wtcstr.adb body Ada.Wide_Text_Io.C_Streams a-wtdeau.adb body Ada.Wide_Text_Io.Decimal_Aux a-wtdeio.adb body Ada.Wide_Text_Io.Decimal_Io a-wtedit.adb body Ada.Wide_Text_Io.Editing a-wtenau.adb body Ada.Wide_Text_Io.Enumeration_Aux a-wtenio.adb body Ada.Wide_Text_Io.Enumeration_Io a-wtfiio.adb body Ada.Wide_Text_Io.Fixed_Io a-wtflau.adb body Ada.Wide_Text_Io.Float_Aux a-wtflio.adb body Ada.Wide_Text_Io.Float_Io a-wtgeau.adb body Ada.Wide_Text_Io.Generic_Aux a-wtinau.adb body Ada.Wide_Text_Io.Integer_Aux a-wtinio.adb body Ada.Wide_Text_Io.Integer_Io a-wtmoau.adb body Ada.Wide_Text_Io.Modular_Aux a-wtmoio.adb body Ada.Wide_Text_Io.Modular_Io a-wttest.adb body Ada.Wide_Text_Io.Text_Streams a-wwboio.adb body Ada.Wide_Text_Io.Wide_Bounded_Io a-zchuni.adb body Ada.Wide_Wide_Characters.Unicode a-ztcoau.adb body Ada.Wide_Wide_Text_Io.Complex_Aux a-ztcoio.adb body Ada.Wide_Wide_Text_Io.Complex_Io a-ztcstr.adb body Ada.Wide_Wide_Text_Io.C_Streams a-ztdeau.adb body Ada.Wide_Wide_Text_Io.Decimal_Aux a-ztdeio.adb body Ada.Wide_Wide_Text_Io.Decimal_Io a-ztedit.adb body Ada.Wide_Wide_Text_Io.Editing a-ztenau.adb body Ada.Wide_Wide_Text_Io.Enumeration_Aux a-ztenio.adb body Ada.Wide_Wide_Text_Io.Enumeration_Io a-ztexio.adb body Ada.Wide_Wide_Text_Io a-ztfiio.adb body Ada.Wide_Wide_Text_Io.Fixed_Io a-ztflau.adb body Ada.Wide_Wide_Text_Io.Float_Aux a-ztflio.adb body Ada.Wide_Wide_Text_Io.Float_Io a-ztgeau.adb body Ada.Wide_Wide_Text_Io.Generic_Aux a-ztinau.adb body Ada.Wide_Wide_Text_Io.Integer_Aux a-ztinio.adb body Ada.Wide_Wide_Text_Io.Integer_Io a-ztmoau.adb body Ada.Wide_Wide_Text_Io.Modular_Aux a-ztmoio.adb body Ada.Wide_Wide_Text_Io.Modular_Io a-zttest.adb body Ada.Wide_Wide_Text_Io.Text_Streams a-zzboio.adb body Ada.Wide_Wide_Text_Io.Wide_Wide_Bounded_Io g-alleve.adb body GNAT.ALTIVEC.LOW_LEVEL_VECTORS g-altcon.adb body GNAT.ALTIVEC.CONVERSIONS g-alveop.adb body GNAT.ALTIVEC.VECTOR_OPERATIONS g-arrspl.adb body GNAT.ARRAY_SPLIT g-boubuf.adb body GNAT.BOUNDED_BUFFERS g-bubsor.adb body GNAT.BUBBLE_SORT g-busora.adb body GNAT.BUBBLE_SORT_A g-busorg.adb body GNAT.BUBBLE_SORT_G g-bytswa.adb body GNAT.BYTE_SWAPPING g-calend.adb body GNAT.CALENDAR g-casuti.adb body GNAT.CASE_UTIL g-catiio.adb body GNAT.CALENDAR.TIME_IO g-cgi.adb body GNAT.CGI g-cgicoo.adb body GNAT.CGI.COOKIE g-cgideb.adb body GNAT.CGI.DEBUG g-comlin.adb body GNAT.COMMAND_LINE g-comver.adb body GNAT.COMPILER_VERSION g-crc32.adb body GNAT.CRC32 g-debpoo.adb body GNAT.DEBUG_POOLS g-debuti.adb body GNAT.DEBUG_UTILITIES g-diopit.adb body GNAT.DIRECTORY_OPERATIONS.ITERATION g-dirope.adb body GNAT.DIRECTORY_OPERATIONS g-dynhta.adb body GNAT.DYNAMIC_HTABLES g-dyntab.adb body GNAT.DYNAMIC_TABLES g-eacodu.adb body Gnat.Exception_Actions.Core_Dump g-excact.adb body GNAT.EXCEPTION_ACTIONS g-exctra.adb body GNAT.EXCEPTION_TRACES g-expect.adb body GNAT.EXPECT g-heasor.adb body GNAT.HEAP_SORT g-hesora.adb body GNAT.HEAP_SORT_A g-hesorg.adb body GNAT.HEAP_SORT_G g-htable.adb body GNAT.HTABLE g-io.adb body GNAT.IO g-io_aux.adb body GNAT.IO_AUX g-locfil.adb body GNAT.LOCK_FILES g-md5.adb body GNAT.MD5 g-memdum.adb body GNAT.MEMORY_DUMP g-moreex.adb body GNAT.MOST_RECENT_EXCEPTION g-os_lib.adb body GNAT.OS_LIB g-pehage.adb body GNAT.PERFECT_HASH_GENERATORS g-regexp.adb body GNAT.REGEXP g-regist.adb body GNAT.REGISTRY g-regpat.adb body GNAT.REGPAT g-semaph.adb body GNAT.SEMAPHORES g-sha1.adb body GNAT.SHA1 g-signal.adb body GNAT.SIGNALS g-socket.adb body GNAT.SOCKETS g-socthi.adb body GNAT.SOCKETS.THIN g-speche.adb body GNAT.SPELLING_CHECKER g-spipat.adb body GNAT.SPITBOL.PATTERNS g-spitbo.adb body GNAT.SPITBOL g-string.adb body GNAT.STRINGS g-table.adb body GNAT.TABLE g-tasloc.adb body GNAT.TASK_LOCK g-thread.adb body GNAT.THREADS g-traceb.adb body GNAT.TRACEBACK g-trasym.adb body GNAT.TRACEBACK.SYMBOLIC i-c.adb body Interfaces.C i-cobol.adb body Interfaces.Cobol i-cpoint.adb body Interfaces.C.Pointers i-cpp.adb body Interfaces.Cpp i-cstrea.adb body Interfaces.C_Streams i-cstrin.adb body Interfaces.C.Strings i-fortra.adb body Interfaces.Fortran i-pacdec.adb body Interfaces.Packed_Decimal i-vxwoio.adb body Interfaces.Vxworks.Io s-addima.adb body System.Address_Image s-addope.adb body System.Address_Operations s-arit64.adb body System.Arith_64 s-assert.adb body System.Assertions s-asthan.adb body System.Ast_Handling s-atacco.adb body System.Address_To_Access_Conversions s-bbinte.adb body System.Bb.Interrupts s-bbprot.adb body System.Bb.Protection s-bbseou.adb body System.Bb.Serial_Output s-bbthqu.adb body System.Bb.Threads.Queues s-bbthre.adb body System.Bb.Threads s-bbtime.adb body System.Bb.Time s-bitops.adb body System.Bit_Ops s-carsi8.adb body System.Compare_Array_Signed_8 s-carun8.adb body System.Compare_Array_Unsigned_8 s-casi16.adb body System.Compare_Array_Signed_16 s-casi32.adb body System.Compare_Array_Signed_32 s-casi64.adb body System.Compare_Array_Signed_64 s-casuti.adb body System.Case_Util s-caun16.adb body System.Compare_Array_Unsigned_16 s-caun32.adb body System.Compare_Array_Unsigned_32 s-caun64.adb body System.Compare_Array_Unsigned_64 s-crc32.adb body System.Crc32 s-direio.adb body System.Direct_Io s-errrep.adb body System.Error_Reporting s-exctab.adb body System.Exception_Table s-exnint.adb body System.Exn_Int s-exnllf.adb body System.Exn_Llf s-exnlli.adb body System.Exn_Lli s-expint.adb body System.Exp_Int s-explli.adb body System.Exp_Lli s-expllu.adb body System.Exp_Llu s-expmod.adb body System.Exp_Mod s-expuns.adb body System.Exp_Uns s-fatgen.adb body System.Fat_Gen s-fileio.adb body System.File_Io s-finimp.adb body System.Finalization_Implementation s-finroo.adb body System.Finalization_Root s-fore.adb body System.Fore s-gearop.adb body System.Generic_Array_Operations s-gecobl.adb body System.Generic_Complex_Blas s-gecola.adb body System.Generic_Complex_Lapack s-gerebl.adb body System.Generic_Real_Blas s-gerela.adb body System.Generic_Real_Lapack s-geveop.adb body System.Generic_Vector_Operations s-gloloc.adb body System.Global_Locks s-htable.adb body System.Htable s-imgbiu.adb body System.Img_Biu s-imgboo.adb body System.Img_Bool s-imgcha.adb body System.Img_Char s-imgdec.adb body System.Img_Dec s-imgenu.adb body System.Img_Enum s-imgint.adb body System.Img_Int s-imgllb.adb body System.Img_Llb s-imglld.adb body System.Img_Lld s-imglli.adb body System.Img_Lli s-imgllu.adb body System.Img_Llu s-imgllw.adb body System.Img_Llw s-imgrea.adb body System.Img_Real s-imguns.adb body System.Img_Uns s-imgwch.adb body System.Img_Wchar s-imgwiu.adb body System.Img_Wiu s-inmaop.adb body System.Interrupt_Management.Operations s-interr.adb body System.Interrupts s-intman.adb body System.Interrupt_Management s-io.adb body System.Io s-mantis.adb body System.Mantissa s-mastop.adb body System.Machine_State_Operations s-memory.adb body System.Memory s-osprim.adb body System.Os_Primitives s-pack03.adb body System.Pack_03 s-pack05.adb body System.Pack_05 s-pack06.adb body System.Pack_06 s-pack07.adb body System.Pack_07 s-pack09.adb body System.Pack_09 s-pack10.adb body System.Pack_10 s-pack11.adb body System.Pack_11 s-pack12.adb body System.Pack_12 s-pack13.adb body System.Pack_13 s-pack14.adb body System.Pack_14 s-pack15.adb body System.Pack_15 s-pack17.adb body System.Pack_17 s-pack18.adb body System.Pack_18 s-pack19.adb body System.Pack_19 s-pack20.adb body System.Pack_20 s-pack21.adb body System.Pack_21 s-pack22.adb body System.Pack_22 s-pack23.adb body System.Pack_23 s-pack24.adb body System.Pack_24 s-pack25.adb body System.Pack_25 s-pack26.adb body System.Pack_26 s-pack27.adb body System.Pack_27 s-pack28.adb body System.Pack_28 s-pack29.adb body System.Pack_29 s-pack30.adb body System.Pack_30 s-pack31.adb body System.Pack_31 s-pack33.adb body System.Pack_33 s-pack34.adb body System.Pack_34 s-pack35.adb body System.Pack_35 s-pack36.adb body System.Pack_36 s-pack37.adb body System.Pack_37 s-pack38.adb body System.Pack_38 s-pack39.adb body System.Pack_39 s-pack40.adb body System.Pack_40 s-pack41.adb body System.Pack_41 s-pack42.adb body System.Pack_42 s-pack43.adb body System.Pack_43 s-pack44.adb body System.Pack_44 s-pack45.adb body System.Pack_45 s-pack46.adb body System.Pack_46 s-pack47.adb body System.Pack_47 s-pack48.adb body System.Pack_48 s-pack49.adb body System.Pack_49 s-pack50.adb body System.Pack_50 s-pack51.adb body System.Pack_51 s-pack52.adb body System.Pack_52 s-pack53.adb body System.Pack_53 s-pack54.adb body System.Pack_54 s-pack55.adb body System.Pack_55 s-pack56.adb body System.Pack_56 s-pack57.adb body System.Pack_57 s-pack58.adb body System.Pack_58 s-pack59.adb body System.Pack_59 s-pack60.adb body System.Pack_60 s-pack61.adb body System.Pack_61 s-pack62.adb body System.Pack_62 s-pack63.adb body System.Pack_63 s-parame.adb body System.Parameters s-parint.adb body System.Partition_Interface s-pooglo.adb body System.Pool_Global s-pooloc.adb body System.Pool_Local s-poosiz.adb body System.Pool_Size s-proinf.adb body System.Program_Info s-restri.adb body System.Restrictions s-rpc.adb body System.Rpc s-scaval.adb body System.Scalar_Values s-secsta.adb body System.Secondary_Stack s-sequio.adb body System.Sequential_Io s-shasto.adb body System.Shared_Storage s-sopco3.adb body System.String_Ops_Concat_3 s-sopco4.adb body System.String_Ops_Concat_4 s-sopco5.adb body System.String_Ops_Concat_5 s-stache.adb body System.Stack_Checking s-stausa.adb body System.Stack_Usage s-stoele.adb body System.Storage_Elements s-stopoo.adb body System.Storage_Pools s-stratt.adb body System.Stream_Attributes s-strcom.adb body System.String_Compare s-strops.adb body System.String_Ops s-strxdr.adb body System.Stream_Attributes s-tadeca.adb body System.Tasking.Async_Delays.Enqueue_Calendar s-tadert.adb body System.Tasking.Async_Delays.Enqueue_Rt s-taenca.adb body System.Tasking.Entry_Calls s-tasdeb.adb body System.Tasking.Debug s-tasinf.adb body System.Task_Info s-tasque.adb body System.Tasking.Queuing s-tasren.adb body System.Tasking.Rendezvous s-tataat.adb body System.Tasking.Task_Attributes s-tpinop.adb body System.Task_Primitives.Interrupt_Operations s-tpoben.adb body System.Tasking.Protected_Objects.Entries s-tpobop.adb body System.Tasking.Protected_Objects.Operations s-tpopsp.adb body System.Task_Primitives.Operations.Specific s-tporft.adb body System.Task_Primitives.Operations.Register_Foreign_Thread s-traceb.adb body System.Traceback s-traces.adb body System.Traces s-traent.adb body System.Traceback_Entries s-tratas.adb body System.Traces.Tasking s-vaflop.adb body System.Vax_Float_Operations s-valboo.adb body System.Val_Bool s-valcha.adb body System.Val_Char s-valdec.adb body System.Val_Dec s-valenu.adb body System.Val_Enum s-valint.adb body System.Val_Int s-vallld.adb body System.Val_Lld s-vallli.adb body System.Val_Lli s-valllu.adb body System.Val_Llu s-valrea.adb body System.Val_Real s-valuns.adb body System.Val_Uns s-valuti.adb body System.Val_Util s-valwch.adb body System.Val_Wchar s-veboop.adb body System.Vectors.Boolean_Operations s-vercon.adb body System.Version_Control s-vmexta.adb body System.Vms_Exception_Table s-vxwexc.adb body System.Vxworks_Exceptions s-wchcnv.adb body System.Wch_Cnv s-wchcon.adb body System.Wch_Con s-wchjis.adb body System.Wch_Jis s-wchstw.adb body System.Wch_Stw s-wchwts.adb body System.Wch_Wts s-widboo.adb body System.Wid_Bool s-widcha.adb body System.Wid_Char s-widenu.adb body System.Wid_Enum s-widlli.adb body System.Wid_Lli s-widllu.adb body System.Wid_Llu s-widwch.adb body System.Wid_Wchar s-wwdcha.adb body System.Wwd_Char s-wwdenu.adb body System.Wwd_Enum s-wwdwch.adb body System.Wwd_Wchar a-astaco.ads spec Ada.Asynchronous_Task_Control a-calari.ads spec Ada.Calendar.Arithmetic a-caldel.ads spec Ada.Calendar.Delays a-calend.ads spec Ada.Calendar a-calfor.ads spec Ada.Calendar.Formatting a-catizo.ads spec Ada.Calendar.Time_Zones a-cbdlli.ads spec Ada.Containers.Bounded_Doubly_Linked_Lists a-cdlili.ads spec Ada.Containers.Doubly_Linked_Lists a-cgaaso.ads spec Ada.Containers.Generic_Anonymous_Array_Sort a-cgarso.ads spec Ada.Containers.Generic_Array_Sort a-cgcaso.ads spec Ada.Containers.Generic_Constrained_Array_Sort a-chacon.ads spec Ada.Characters.Conversions a-chahan.ads spec Ada.Characters.Handling a-charac.ads spec Ada.Characters a-chlat1.ads spec Ada.Characters.Latin_1 a-chlat9.ads spec Ada.Characters.Latin_9 a-chtgke.ads spec Ada.Containers.Hash_Tables.Generic_Keys a-chtgop.ads spec Ada.Containers.Hash_Tables.Generic_Operations a-chzla1.ads spec Ada.Characters.Wide_Wide_Latin_1 a-chzla9.ads spec Ada.Characters.Wide_Wide_Latin_9 a-cidlli.ads spec Ada.Containers.Indefinite_Doubly_Linked_Lists a-cihama.ads spec Ada.Containers.Indefinite_Hashed_Maps a-cihase.ads spec Ada.Containers.Indefinite_Hashed_Sets a-ciorma.ads spec Ada.Containers.Indefinite_Ordered_Maps a-ciormu.ads spec Ada.Containers.Indefinite_Ordered_Multisets a-ciorse.ads spec Ada.Containers.Indefinite_Ordered_Sets a-cohama.ads spec Ada.Containers.Hashed_Maps a-cohase.ads spec Ada.Containers.Hashed_Sets a-cohata.ads spec Ada.Containers.Hash_Tables a-coinve.ads spec Ada.Containers.Indefinite_Vectors a-colien.ads spec Ada.Command_Line.Environment a-colire.ads spec Ada.Command_Line.Remove a-comlin.ads spec Ada.Command_Line a-contai.ads spec Ada.Containers a-convec.ads spec Ada.Containers.Vectors a-coorma.ads spec Ada.Containers.Ordered_Maps a-coormu.ads spec Ada.Containers.Ordered_Multisets a-coorse.ads spec Ada.Containers.Ordered_Sets a-coprnu.ads spec Ada.Containers.Prime_Numbers a-coteio.ads spec Ada.Complex_Text_Io a-crbltr.ads spec Ada.Containers.Red_Black_Trees a-crbtgk.ads spec Ada.Containers.Red_Black_Trees.Generic_Keys a-crbtgo.ads spec Ada.Containers.Red_Black_Trees.Generic_Operations a-crdlli.ads spec Ada.Containers.Restricted_Doubly_Linked_Lists a-cwila1.ads spec Ada.Characters.Wide_Latin_1 a-cwila9.ads spec Ada.Characters.Wide_Latin_9 a-decima.ads spec Ada.Decimal a-diocst.ads spec Ada.Direct_Io.C_Streams a-direct.ads spec Ada.Directories a-direio.ads spec Ada.Direct_Io a-diroro.ads spec Ada.Dispatching.Round_Robin a-dirval.ads spec Ada.Directories.Validity a-disedf.ads spec Ada.Dispatching.Edf a-dispat.ads spec Ada.Dispatching a-dynpri.ads spec Ada.Dynamic_Priorities a-einuoc.ads spec Ada.Exceptions.Is_Null_Occurrence a-elchha.ads spec Ada.Exceptions.Last_Chance_Handler a-envvar.ads spec Ada.Environment_Variables a-etgrbu.ads spec Ada.Execution_Time.Group_Budgets a-exctra.ads spec Ada.Exceptions.Traceback a-exetim.ads spec Ada.Execution_Time a-extiti.ads spec Ada.Execution_Time.Timers a-filico.ads spec Ada.Finalization.List_Controller a-finali.ads spec Ada.Finalization a-flteio.ads spec Ada.Float_Text_Io a-fwteio.ads spec Ada.Float_Wide_Text_Io a-fzteio.ads spec Ada.Float_Wide_Wide_Text_Io a-inteio.ads spec Ada.Integer_Text_Io a-interr.ads spec Ada.Interrupts a-intnam.ads spec Ada.Interrupts.Names a-intsig.ads spec Ada.Interrupts.Signal a-ioexce.ads spec Ada.Io_Exceptions a-iwteio.ads spec Ada.Integer_Wide_Text_Io a-izteio.ads spec Ada.Integer_Wide_Wide_Text_Io a-lcteio.ads spec Ada.Long_Complex_Text_Io a-lfteio.ads spec Ada.Long_Float_Text_Io a-lfwtio.ads spec Ada.Long_Float_Wide_Text_Io a-lfztio.ads spec Ada.Long_Float_Wide_Wide_Text_Io a-liteio.ads spec Ada.Long_Integer_Text_Io a-liwtio.ads spec Ada.Long_Integer_Wide_Text_Io a-liztio.ads spec Ada.Long_Integer_Wide_Wide_Text_Io a-llctio.ads spec Ada.Long_Long_Complex_Text_Io a-llftio.ads spec Ada.Long_Long_Float_Text_Io a-llfwti.ads spec Ada.Long_Long_Float_Wide_Text_Io a-llfzti.ads spec Ada.Long_Long_Float_Wide_Wide_Text_Io a-llitio.ads spec Ada.Long_Long_Integer_Text_Io a-lliwti.ads spec Ada.Long_Long_Integer_Wide_Text_Io a-llizti.ads spec Ada.Long_Long_Integer_Wide_Wide_Text_Io a-ncelfu.ads spec Ada.Numerics.Complex_Elementary_Functions a-ngcefu.ads spec Ada.Numerics.Generic_Complex_Elementary_Functions a-ngcoar.ads spec Ada.Numerics.Generic_Complex_Arrays a-ngcoty.ads spec Ada.Numerics.Generic_Complex_Types a-ngelfu.ads spec Ada.Numerics.Generic_Elementary_Functions a-ngrear.ads spec Ada.Numerics.Generic_Real_Arrays a-nlcefu.ads spec Ada.Numerics.Long_Complex_Elementary_Functions a-nlcoar.ads spec Ada.Numerics.Long_Complex_Arrays a-nlcoty.ads spec Ada.Numerics.Long_Complex_Types a-nlelfu.ads spec Ada.Numerics.Long_Elementary_Functions a-nllcar.ads spec Ada.Numerics.Long_Long_Complex_Arrays a-nllcef.ads spec Ada.Numerics.Long_Long_Complex_Elementary_Functions a-nllcty.ads spec Ada.Numerics.Long_Long_Complex_Types a-nllefu.ads spec Ada.Numerics.Long_Long_Elementary_Functions a-nllrar.ads spec Ada.Numerics.Long_Long_Real_Arrays a-nlrear.ads spec Ada.Numerics.Long_Real_Arrays a-nscefu.ads spec Ada.Numerics.Short_Complex_Elementary_Functions a-nscoty.ads spec Ada.Numerics.Short_Complex_Types a-nselfu.ads spec Ada.Numerics.Short_Elementary_Functions a-nucoar.ads spec Ada.Numerics.Complex_Arrays a-nucoty.ads spec Ada.Numerics.Complex_Types a-nudira.ads spec Ada.Numerics.Discrete_Random a-nuelfu.ads spec Ada.Numerics.Elementary_Functions a-nuflra.ads spec Ada.Numerics.Float_Random a-numaux.ads spec Ada.Numerics.Aux a-numeri.ads spec Ada.Numerics a-nurear.ads spec Ada.Numerics.Real_Arrays a-rbtgso.ads spec Ada.Containers.Red_Black_Trees.Generic_Set_Operations a-reatim.ads spec Ada.Real_Time a-retide.ads spec Ada.Real_Time.Delays a-rttiev.ads spec Ada.Real_Time.Timing_Events a-scteio.ads spec Ada.Short_Complex_Text_Io a-secain.ads spec Ada.Strings.Equal_Case_Insensitive a-sequio.ads spec Ada.Sequential_Io a-sfteio.ads spec Ada.Short_Float_Text_Io a-sfwtio.ads spec Ada.Short_Float_Wide_Text_Io a-sfztio.ads spec Ada.Short_Float_Wide_Wide_Text_Io a-shcain.ads spec Ada.Strings.Hash_Case_Insensitive a-siocst.ads spec Ada.Sequential_Io.C_Streams a-siteio.ads spec Ada.Short_Integer_Text_Io a-siwtio.ads spec Ada.Short_Integer_Wide_Text_Io a-siztio.ads spec Ada.Short_Integer_Wide_Wide_Text_Io a-slcain.ads spec Ada.Strings.Less_Case_Insensitive a-ssicst.ads spec Ada.Streams.Stream_Io.C_Streams a-ssitio.ads spec Ada.Short_Short_Integer_Text_Io a-ssiwti.ads spec Ada.Short_Short_Integer_Wide_Text_Io a-ssizti.ads spec Ada.Short_Short_Integer_Wide_Wide_Text_Io a-stboha.ads spec Ada.Strings.Bounded.Hash a-stfiha.ads spec Ada.Strings.Fixed.Hash a-stmaco.ads spec Ada.Strings.Maps.Constants a-storio.ads spec Ada.Storage_Io a-strbou.ads spec Ada.Strings.Bounded a-stream.ads spec Ada.Streams a-strfix.ads spec Ada.Strings.Fixed a-strhas.ads spec Ada.Strings.Hash a-string.ads spec Ada.Strings a-strmap.ads spec Ada.Strings.Maps a-strsea.ads spec Ada.Strings.Search a-strsup.ads spec Ada.Strings.Superbounded a-strunb.ads spec Ada.Strings.Unbounded a-ststio.ads spec Ada.Streams.Stream_Io ada.ads spec Ada a-stunau.ads spec Ada.Strings.Unbounded.Aux a-stunha.ads spec Ada.Strings.Unbounded.Hash a-stwibo.ads spec Ada.Strings.Wide_Bounded a-stwifi.ads spec Ada.Strings.Wide_Fixed a-stwiha.ads spec Ada.Strings.Wide_Hash a-stwima.ads spec Ada.Strings.Wide_Maps a-stwise.ads spec Ada.Strings.Wide_Search a-stwisu.ads spec Ada.Strings.Wide_Superbounded a-stwiun.ads spec Ada.Strings.Wide_Unbounded a-stzbou.ads spec Ada.Strings.Wide_Wide_Bounded a-stzfix.ads spec Ada.Strings.Wide_Wide_Fixed a-stzhas.ads spec Ada.Strings.Wide_Wide_Hash a-stzmap.ads spec Ada.Strings.Wide_Wide_Maps a-stzsea.ads spec Ada.Strings.Wide_Wide_Search a-stzsup.ads spec Ada.Strings.Wide_Wide_Superbounded a-stzunb.ads spec Ada.Strings.Wide_Wide_Unbounded a-suteio.ads spec Ada.Strings.Unbounded.Text_Io a-swbwha.ads spec Ada.Strings.Wide_Bounded.Wide_Hash a-swfwha.ads spec Ada.Strings.Wide_Fixed.Wide_Hash a-swmwco.ads spec Ada.Strings.Wide_Maps.Wide_Constants a-swunau.ads spec Ada.Strings.Wide_Unbounded.Aux a-swuwha.ads spec Ada.Strings.Wide_Unbounded.Wide_Hash a-swuwti.ads spec Ada.Strings.Wide_Unbounded.Wide_Text_Io a-sytaco.ads spec Ada.Synchronous_Task_Control a-szbzha.ads spec Ada.Strings.Wide_Wide_Bounded.Wide_Wide_Hash a-szfzha.ads spec Ada.Strings.Wide_Wide_Fixed.Wide_Wide_Hash a-szmzco.ads spec Ada.Strings.Wide_Wide_Maps.Wide_Wide_Constants a-szunau.ads spec Ada.Strings.Wide_Wide_Unbounded.Aux a-szuzha.ads spec Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Hash a-szuzti.ads spec Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_Io a-tags.ads spec Ada.Tags a-tasatt.ads spec Ada.Task_Attributes a-taside.ads spec Ada.Task_Identification a-taster.ads spec Ada.Task_Termination a-teioed.ads spec Ada.Text_Io.Editing a-textio.ads spec Ada.Text_Io a-tiboio.ads spec Ada.Text_Io.Bounded_Io a-ticoau.ads spec Ada.Text_Io.Complex_Aux a-ticoio.ads spec Ada.Text_Io.Complex_Io a-tideau.ads spec Ada.Text_Io.Decimal_Aux a-tideio.ads spec Ada.Text_Io.Decimal_Io a-tienau.ads spec Ada.Text_Io.Enumeration_Aux a-tienio.ads spec Ada.Text_Io.Enumeration_Io a-tifiau.ads spec Ada.Text_Io.Fixed_Aux a-tifiio.ads spec Ada.Text_Io.Fixed_Io a-tiflau.ads spec Ada.Text_Io.Float_Aux a-tiflio.ads spec Ada.Text_Io.Float_Io a-tigeau.ads spec Ada.Text_Io.Generic_Aux a-tiinau.ads spec Ada.Text_Io.Integer_Aux a-tiinio.ads spec Ada.Text_Io.Integer_Io a-timoau.ads spec Ada.Text_Io.Modular_Aux a-timoio.ads spec Ada.Text_Io.Modular_Io a-tiocst.ads spec Ada.Text_Io.C_Streams a-titest.ads spec Ada.Text_Io.Text_Streams a-tiunio.ads spec Ada.Text_Io.Unbounded_Io a-unccon.ads spec Ada.Unchecked_Conversion a-uncdea.ads spec Ada.Unchecked_Deallocation a-wichun.ads spec Ada.Wide_Characters.Unicode a-widcha.ads spec Ada.Wide_Characters a-witeio.ads spec Ada.Wide_Text_Io a-wtcoau.ads spec Ada.Wide_Text_Io.Complex_Aux a-wtcoio.ads spec Ada.Wide_Text_Io.Complex_Io a-wtcstr.ads spec Ada.Wide_Text_Io.C_Streams a-wtdeau.ads spec Ada.Wide_Text_Io.Decimal_Aux a-wtdeio.ads spec Ada.Wide_Text_Io.Decimal_Io a-wtedit.ads spec Ada.Wide_Text_Io.Editing a-wtenau.ads spec Ada.Wide_Text_Io.Enumeration_Aux a-wtenio.ads spec Ada.Wide_Text_Io.Enumeration_Io a-wtfiio.ads spec Ada.Wide_Text_Io.Fixed_Io a-wtflau.ads spec Ada.Wide_Text_Io.Float_Aux a-wtflio.ads spec Ada.Wide_Text_Io.Float_Io a-wtgeau.ads spec Ada.Wide_Text_Io.Generic_Aux a-wtinau.ads spec Ada.Wide_Text_Io.Integer_Aux a-wtinio.ads spec Ada.Wide_Text_Io.Integer_Io a-wtmoau.ads spec Ada.Wide_Text_Io.Modular_Aux a-wtmoio.ads spec Ada.Wide_Text_Io.Modular_Io a-wttest.ads spec Ada.Wide_Text_Io.Text_Streams a-wwboio.ads spec Ada.Wide_Text_Io.Wide_Bounded_Io a-wwunio.ads spec Ada.Wide_Text_Io.Wide_Unbounded_Io a-zchara.ads spec Ada.Wide_Wide_Characters a-zchuni.ads spec Ada.Wide_Wide_Characters.Unicode a-ztcoau.ads spec Ada.Wide_Wide_Text_Io.Complex_Aux a-ztcoio.ads spec Ada.Wide_Wide_Text_Io.Complex_Io a-ztcstr.ads spec Ada.Wide_Wide_Text_Io.C_Streams a-ztdeau.ads spec Ada.Wide_Wide_Text_Io.Decimal_Aux a-ztdeio.ads spec Ada.Wide_Wide_Text_Io.Decimal_Io a-ztedit.ads spec Ada.Wide_Wide_Text_Io.Editing a-ztenau.ads spec Ada.Wide_Wide_Text_Io.Enumeration_Aux a-ztenio.ads spec Ada.Wide_Wide_Text_Io.Enumeration_Io a-ztexio.ads spec Ada.Wide_Wide_Text_Io a-ztfiio.ads spec Ada.Wide_Wide_Text_Io.Fixed_Io a-ztflau.ads spec Ada.Wide_Wide_Text_Io.Float_Aux a-ztflio.ads spec Ada.Wide_Wide_Text_Io.Float_Io a-ztgeau.ads spec Ada.Wide_Wide_Text_Io.Generic_Aux a-ztinau.ads spec Ada.Wide_Wide_Text_Io.Integer_Aux a-ztinio.ads spec Ada.Wide_Wide_Text_Io.Integer_Io a-ztmoau.ads spec Ada.Wide_Wide_Text_Io.Modular_Aux a-ztmoio.ads spec Ada.Wide_Wide_Text_Io.Modular_Io a-zttest.ads spec Ada.Wide_Wide_Text_Io.Text_Streams a-zzboio.ads spec Ada.Wide_Wide_Text_Io.Wide_Wide_Bounded_Io a-zzunio.ads spec Ada.Wide_Wide_Text_Io.Wide_Wide_Unbounded_Io calendar.ads spec Calendar g-allein.ads spec GNAT.ALTIVEC.LOW_LEVEL_INTERFACE g-alleve.ads spec GNAT.ALTIVEC.LOW_LEVEL_VECTORS g-altcon.ads spec GNAT.ALTIVEC.CONVERSIONS g-altdes.ads spec GNAT.ALTIVEC.DESIGN g-altive.ads spec GNAT.ALTIVEC g-alveop.ads spec GNAT.ALTIVEC.VECTOR_OPERATIONS g-alvety.ads spec GNAT.ALTIVEC.VECTOR_TYPES g-alvevi.ads spec GNAT.ALTIVEC.VECTOR_VIEWS g-arrspl.ads spec Gnat.Array_Split g-awk.ads spec GNAT.AWK g-boubuf.ads spec GNAT.BOUNDED_BUFFERS g-boumai.ads spec GNAT.BOUNDED_MAILBOXES g-bubsor.ads spec GNAT.BUBBLE_SORT g-busora.ads spec GNAT.BUBBLE_SORT_A g-busorg.ads spec Gnat.Bubble_Sort_G g-bytswa.ads spec GNAT.BYTE_SWAPPING g-calend.ads spec GNAT.CALENDAR g-casuti.ads spec GNAT.CASE_UTIL g-catiio.ads spec GNAT.CALENDAR.TIME_IO g-cgi.ads spec GNAT.CGI g-cgicoo.ads spec GNAT.CGI.COOKIE g-cgideb.ads spec GNAT.CGI.DEBUG g-comlin.ads spec GNAT.COMMAND_LINE g-comver.ads spec GNAT.COMPILER_VERSION g-crc32.ads spec GNAT.CRC32 g-ctrl_c.ads spec GNAT.CTRL_C g-curexc.ads spec GNAT.CURRENT_EXCEPTION g-debpoo.ads spec GNAT.DEBUG_POOLS g-debuti.ads spec GNAT.DEBUG_UTILITIES g-diopit.ads spec GNAT.DIRECTORY_OPERATIONS.ITERATION g-dirope.ads spec GNAT.DIRECTORY_OPERATIONS g-dynhta.ads spec GNAT.DYNAMIC_HTABLES g-dyntab.ads spec GNAT.DYNAMIC_TABLES g-excact.ads spec GNAT.EXCEPTION_ACTIONS g-except.ads spec GNAT.EXCEPTIONS g-exctra.ads spec GNAT.EXCEPTION_TRACES g-expect.ads spec GNAT.EXPECT g-flocon.ads spec GNAT.FLOAT_CONTROL g-heasor.ads spec GNAT.HEAP_SORT g-hesora.ads spec GNAT.HEAP_SORT_A g-hesorg.ads spec Gnat.Heap_Sort_G g-htable.ads spec GNAT.HTABLE g-io.ads spec GNAT.IO g-io_aux.ads spec GNAT.IO_AUX g-locfil.ads spec GNAT.LOCK_FILES g-md5.ads spec GNAT.MD5 g-memdum.ads spec GNAT.MEMORY_DUMP g-moreex.ads spec GNAT.MOST_RECENT_EXCEPTION g-os_lib.ads spec GNAT.OS_LIB g-pehage.ads spec GNAT.PERFECT_HASH_GENERATORS g-regexp.ads spec GNAT.REGEXP g-regist.ads spec GNAT.REGISTRY g-regpat.ads spec GNAT.REGPAT g-semaph.ads spec GNAT.SEMAPHORES g-sestin.ads spec GNAT.SECONDARY_STACK_INFO g-sha1.ads spec GNAT.SHA1 g-signal.ads spec GNAT.SIGNALS g-soccon.ads spec GNAT.SOCKETS.CONSTANTS g-socket.ads spec GNAT.SOCKETS g-socthi.ads spec GNAT.SOCKETS.THIN g-soliop.ads spec GNAT.SOCKETS.LINKER_OPTIONS g-souinf.ads spec GNAT.SOURCE_INFO g-speche.ads spec GNAT.SPELLING_CHECKER g-spipat.ads spec GNAT.SPITBOL.PATTERNS g-spitbo.ads spec GNAT.SPITBOL g-sptabo.ads spec GNAT.SPITBOL.TABLE_BOOLEAN g-sptain.ads spec GNAT.SPITBOL.TABLE_INTEGER g-sptavs.ads spec GNAT.SPITBOL.TABLE_VSTRING g-string.ads spec GNAT.STRINGS g-strspl.ads spec GNAT.STRING_SPLIT g-table.ads spec GNAT.TABLE g-tasloc.ads spec GNAT.TASK_LOCK g-thread.ads spec GNAT.THREADS g-traceb.ads spec GNAT.TRACEBACK g-trasym.ads spec GNAT.TRACEBACK.SYMBOLIC g-utf_32.ads spec GNAT.UTF_32 g-wistsp.ads spec GNAT.WIDE_STRING_SPLIT g-zstspl.ads spec GNAT.WIDE_WIDE_STRING_SPLIT gnat.ads spec GNAT i-c.ads spec Interfaces.C i-cexten.ads spec Interfaces.C.Extensions i-cobol.ads spec Interfaces.Cobol i-cpoint.ads spec Interfaces.C.Pointers i-cpp.ads spec Interfaces.Cpp i-cstrea.ads spec Interfaces.C_Streams i-cstrin.ads spec Interfaces.C.Strings i-forbla.ads spec Interfaces.Fortran.Blas i-forlap.ads spec Interfaces.Fortran.Lapack i-fortra.ads spec Interfaces.Fortran i-jalaob.ads spec Interfaces.Java.Lang.Object i-jalasy.ads spec Interfaces.Java.Lang.System i-jalath.ads spec Interfaces.Java.Lang.Thread i-java.ads spec Interfaces.Java i-javlan.ads spec Interfaces.Java.Lang i-pacdec.ads spec Interfaces.Packed_Decimal i-vxwoio.ads spec Interfaces.Vxworks.Io i-vxwork.ads spec Interfaces.Vxworks interfac.ads spec Interfaces machcode.ads spec Machine_Code s-addima.ads spec System.Address_Image s-addope.ads spec System.Address_Operations s-arit64.ads spec System.Arith_64 s-assert.ads spec System.Assertions s-asthan.ads spec System.Ast_Handling s-atacco.ads spec System.Address_To_Access_Conversions s-auxdec.ads spec System.Aux_Dec s-auxvad.ads spec System.Aux_Vads_Sgi s-bb.ads spec System.Bb s-bbinte.ads spec System.Bb.Interrupts s-bbprot.ads spec System.Bb.Protection s-bbseou.ads spec System.Bb.Serial_Output s-bbthqu.ads spec System.Bb.Threads.Queues s-bbthre.ads spec System.Bb.Threads s-bbtime.ads spec System.Bb.Time s-bitops.ads spec System.Bit_Ops s-boarop.ads spec System.Boolean_Array_Operations s-carsi8.ads spec System.Compare_Array_Signed_8 s-carun8.ads spec System.Compare_Array_Unsigned_8 s-casi16.ads spec System.Compare_Array_Signed_16 s-casi32.ads spec System.Compare_Array_Signed_32 s-casi64.ads spec System.Compare_Array_Signed_64 s-casuti.ads spec System.Case_Util s-caun16.ads spec System.Compare_Array_Unsigned_16 s-caun32.ads spec System.Compare_Array_Unsigned_32 s-caun64.ads spec System.Compare_Array_Unsigned_64 s-chepoo.ads spec System.Checked_Pools s-crc32.ads spec System.Crc32 s-crtl.ads spec System.Crtl s-direio.ads spec System.Direct_Io s-dsaser.ads spec System.Dsa_Services s-errrep.ads spec System.Error_Reporting s-exctab.ads spec System.Exception_Table s-exnint.ads spec System.Exn_Int s-exnllf.ads spec System.Exn_Llf s-exnlli.ads spec System.Exn_Lli s-expint.ads spec System.Exp_Int s-explli.ads spec System.Exp_Lli s-expllu.ads spec System.Exp_Llu s-expmod.ads spec System.Exp_Mod s-expuns.ads spec System.Exp_Uns s-fatflt.ads spec System.Fat_Flt s-fatgen.ads spec System.Fat_Gen s-fatlfl.ads spec System.Fat_Lflt s-fatllf.ads spec System.Fat_Llf s-fatsfl.ads spec System.Fat_Sflt s-ficobl.ads spec System.File_Control_Block s-fileio.ads spec System.File_Io s-filofl.ads spec System.Fat_Ieee_Long_Float s-finimp.ads spec System.Finalization_Implementation s-finroo.ads spec System.Finalization_Root s-fishfl.ads spec System.Fat_Ieee_Short_Float s-fore.ads spec System.Fore s-fvadfl.ads spec System.Fat_Vax_D_Float s-fvaffl.ads spec System.Fat_Vax_F_Float s-fvagfl.ads spec System.Fat_Vax_G_Float s-gearop.ads spec System.Generic_Array_Operations s-gecobl.ads spec System.Generic_Complex_Blas s-gecola.ads spec System.Generic_Complex_Lapack s-gerebl.ads spec System.Generic_Real_Blas s-gerela.ads spec System.Generic_Real_Lapack s-geveop.ads spec System.Generic_Vector_Operations s-gloloc.ads spec System.Global_Locks s-hibaen.ads spec System.Hie_Back_End s-htable.ads spec System.Htable s-imgbiu.ads spec System.Img_Biu s-imgboo.ads spec System.Img_Bool s-imgcha.ads spec System.Img_Char s-imgdec.ads spec System.Img_Dec s-imgenu.ads spec System.Img_Enum s-imgint.ads spec System.Img_Int s-imgllb.ads spec System.Img_Llb s-imglld.ads spec System.Img_Lld s-imglli.ads spec System.Img_Lli s-imgllu.ads spec System.Img_Llu s-imgllw.ads spec System.Img_Llw s-imgrea.ads spec System.Img_Real s-imguns.ads spec System.Img_Uns s-imgwch.ads spec System.Img_Wchar s-imgwiu.ads spec System.Img_Wiu s-inmaop.ads spec System.Interrupt_Management.Operations s-interr.ads spec System.Interrupts s-intman.ads spec System.Interrupt_Management s-io.ads spec System.Io s-maccod.ads spec System.Machine_Code s-mantis.ads spec System.Mantissa s-memcop.ads spec System.Memory_Copy s-memory.ads spec System.Memory s-osinte.ads spec System.Os_Interface s-osprim.ads spec System.Os_Primitives s-pack03.ads spec System.Pack_03 s-pack05.ads spec System.Pack_05 s-pack06.ads spec System.Pack_06 s-pack07.ads spec System.Pack_07 s-pack09.ads spec System.Pack_09 s-pack10.ads spec System.Pack_10 s-pack11.ads spec System.Pack_11 s-pack12.ads spec System.Pack_12 s-pack13.ads spec System.Pack_13 s-pack14.ads spec System.Pack_14 s-pack15.ads spec System.Pack_15 s-pack17.ads spec System.Pack_17 s-pack18.ads spec System.Pack_18 s-pack19.ads spec System.Pack_19 s-pack20.ads spec System.Pack_20 s-pack21.ads spec System.Pack_21 s-pack22.ads spec System.Pack_22 s-pack23.ads spec System.Pack_23 s-pack24.ads spec System.Pack_24 s-pack25.ads spec System.Pack_25 s-pack26.ads spec System.Pack_26 s-pack27.ads spec System.Pack_27 s-pack28.ads spec System.Pack_28 s-pack29.ads spec System.Pack_29 s-pack30.ads spec System.Pack_30 s-pack31.ads spec System.Pack_31 s-pack33.ads spec System.Pack_33 s-pack34.ads spec System.Pack_34 s-pack35.ads spec System.Pack_35 s-pack36.ads spec System.Pack_36 s-pack37.ads spec System.Pack_37 s-pack38.ads spec System.Pack_38 s-pack39.ads spec System.Pack_39 s-pack40.ads spec System.Pack_40 s-pack41.ads spec System.Pack_41 s-pack42.ads spec System.Pack_42 s-pack43.ads spec System.Pack_43 s-pack44.ads spec System.Pack_44 s-pack45.ads spec System.Pack_45 s-pack46.ads spec System.Pack_46 s-pack47.ads spec System.Pack_47 s-pack48.ads spec System.Pack_48 s-pack49.ads spec System.Pack_49 s-pack50.ads spec System.Pack_50 s-pack51.ads spec System.Pack_51 s-pack52.ads spec System.Pack_52 s-pack53.ads spec System.Pack_53 s-pack54.ads spec System.Pack_54 s-pack55.ads spec System.Pack_55 s-pack56.ads spec System.Pack_56 s-pack57.ads spec System.Pack_57 s-pack58.ads spec System.Pack_58 s-pack59.ads spec System.Pack_59 s-pack60.ads spec System.Pack_60 s-pack61.ads spec System.Pack_61 s-pack62.ads spec System.Pack_62 s-pack63.ads spec System.Pack_63 s-parame.ads spec System.Parameters s-parint.ads spec System.Partition_Interface s-pooglo.ads spec System.Pool_Global s-pooloc.ads spec System.Pool_Local s-poosiz.ads spec System.Pool_Size s-powtab.ads spec System.Powten_Table s-proinf.ads spec System.Program_Info s-purexc.ads spec System.Pure_Exceptions s-restri.ads spec System.Restrictions s-rident.ads spec System.Rident s-rpc.ads spec System.Rpc s-scaval.ads spec System.Scalar_Values s-secsta.ads spec System.Secondary_Stack s-sequio.ads spec System.Sequential_Io s-shasto.ads spec System.Shared_Storage s-soflin.ads spec System.Soft_Links s-solita.ads spec System.Soft_Links.Tasking s-sopco3.ads spec System.String_Ops_Concat_3 s-sopco4.ads spec System.String_Ops_Concat_4 s-sopco5.ads spec System.String_Ops_Concat_5 s-stache.ads spec System.Stack_Checking s-stausa.ads spec System.Stack_Usage s-stoele.ads spec System.Storage_Elements s-stopoo.ads spec System.Storage_Pools s-stratt.ads spec System.Stream_Attributes s-strcom.ads spec System.String_Compare s-strops.ads spec System.String_Ops s-taasde.ads spec System.Tasking.Async_Delays s-tadeca.ads spec System.Tasking.Async_Delays.Enqueue_Calendar s-tadert.ads spec System.Tasking.Async_Delays.Enqueue_Rt s-taenca.ads spec System.Tasking.Entry_Calls s-taprob.ads spec System.Tasking.Protected_Objects s-taprop.ads spec System.Task_Primitives.Operations s-tarest.ads spec System.Tasking.Restricted.Stages s-tasdeb.ads spec System.Tasking.Debug s-tasinf.ads spec System.Task_Info s-tasini.ads spec System.Tasking.Initialization s-taskin.ads spec System.Tasking s-tasque.ads spec System.Tasking.Queuing s-tasren.ads spec System.Tasking.Rendezvous s-tasres.ads spec System.Tasking.Restricted s-tassta.ads spec System.Tasking.Stages s-tasuti.ads spec System.Tasking.Utilities s-tataat.ads spec System.Tasking.Task_Attributes s-thread.ads spec System.Threads s-tpinop.ads spec System.Task_Primitives.Interrupt_Operations s-tpoben.ads spec System.Tasking.Protected_Objects.Entries s-tpobop.ads spec System.Tasking.Protected_Objects.Operations s-tposen.ads spec System.Tasking.Protected_Objects.Single_Entry s-traces.ads spec System.Traces s-traent.ads spec System.Traceback_Entries s-tratas.ads spec System.Traces.Tasking s-unstyp.ads spec System.Unsigned_Types s-vaflop.ads spec System.Vax_Float_Operations s-valboo.ads spec System.Val_Bool s-valcha.ads spec System.Val_Char s-valdec.ads spec System.Val_Dec s-valenu.ads spec System.Val_Enum s-valint.ads spec System.Val_Int s-vallld.ads spec System.Val_Lld s-vallli.ads spec System.Val_Lli s-valllu.ads spec System.Val_Llu s-valrea.ads spec System.Val_Real s-valuns.ads spec System.Val_Uns s-valuti.ads spec System.Val_Util s-valwch.ads spec System.Val_Wchar s-veboop.ads spec System.Vectors.Boolean_Operations s-vector.ads spec System.Vectors s-vercon.ads spec System.Version_Control s-vmexta.ads spec System.Vms_Exception_Table s-vxwexc.ads spec System.Vxworks_Exceptions s-wchcnv.ads spec System.Wch_Cnv s-wchcon.ads spec System.Wch_Con s-wchjis.ads spec System.Wch_Jis s-wchstw.ads spec System.Wch_Stw s-wchwts.ads spec System.Wch_Wts s-widboo.ads spec System.Wid_Bool s-widcha.ads spec System.Wid_Char s-widenu.ads spec System.Wid_Enum s-widlli.ads spec System.Wid_Lli s-widllu.ads spec System.Wid_Llu s-widwch.ads spec System.Wid_Wchar s-wwdcha.ads spec System.Wwd_Char s-wwdenu.ads spec System.Wwd_Enum s-wwdwch.ads spec System.Wwd_Wchar system.ads spec System unchconv.ads spec Unchecked_Conversion unchdeal.ads spec Unchecked_Deallocation gprbuild-gpl-2014-src/share/gprconfig/cross.xml0000644000076700001450000006347512203444510021077 0ustar gnatmailgnat package Builder is for Executable_Suffix use ".axe"; end Builder; package Builder is for Executable_Suffix use ".exe"; end Builder; package Builder is for Executable_Suffix use ""; end Builder; Wind_Base := external ("WIND_BASE"); Wind_Usr := external ("WIND_USR", Wind_Base & "/target/usr/"); Pikeos_Target_Files := external ("PIKEOS_TARGET_FILES"); WRS_RTP_Base := external ("WRS_RTP_BASE", "0x40000000"); package Builder is for Executable_Suffix use ".out"; end Builder; package Builder is for Executable_Suffix use ".vxe"; end Builder; package Linker is for Required_Switches use Linker'Required_Switches & ("-mrtp"); end Linker; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-mlongcall"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-mlongcall"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-mlong-calls"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-mlong-calls"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-fno-builtin"); end Compiler; -- Traditionally the entry point of a native application is _p4_entry. For -- an APEX application, it is _begin. -- In order to use the same link options for both personalities, _begin is -- used for native as well. package Linker is for Required_Switches use Linker'Required_Switches & ("-u_begin", "-e_begin", "-nostdlib", "-Tapp-ld-script", "-lvm", "-lp4", "-lstand", "-lgcc", "-L" & Pikeos_Target_Files & "/scripts", "-L" & Pikeos_Target_Files & "/lib"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-Wl,--defsym,__wrs_rtp_base=" & WRS_RTP_Base, "-mrtp"); end Linker; package Linker is for Required_Switches use Linker'Required_Switches & ("-Wl,--defsym,__wrs_rtp_base=" & WRS_RTP_Base, "-mrtp"); end Linker; package Compiler is for Leading_Required_Switches ("Ada") use Compiler'Leading_Required_Switches ("Ada") & ("-mrtp"); end Compiler; package Linker is for Required_Switches use Linker'Required_Switches & ("-mrtp"); end Linker; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-mrtp") & ("-I" & Wind_Base & "/target/usr/h", "-I" & Wind_Base & "/target/usr/h/wrn/coreip"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-DVTHREADS", "-I" & Wind_Base & "/target/vThreads/h", "-I" & Wind_Base & "/target/val/h"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-I" & Wind_Base & "/target/include"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-I" & Wind_Base & "/target/h", "-I" & Wind_Base & "/target/h/wrn/coreip"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-I" & Wind_Base & "/target/h", "-msoft-float"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-I" & Wind_Base & "/target/h"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-mrtp") & ("-I" & Wind_Base & "/target/usr/h", "-I" & Wind_Base & "/target/usr/h/wrn/coreip"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-I" & Wind_Base & "/target/h", "-I" & Wind_Base & "/target/h/wrn/coreip"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-te500v2", "-fno-implicit-fp"); for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-te500v2", "-fno-implicit-fp"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-DVTHREADS", "-I" & Wind_Base & "/target/vThreads/h", "-I" & Wind_Base & "/target/val/h"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-I" & Wind_Base & "/target/include"); end Compiler; package Compiler is for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-fno-builtin"); end Compiler; package Compiler is for Leading_Required_Switches ("C++") use Compiler'Leading_Required_Switches ("C++") & ("-fno-builtin"); end Compiler; package Builder is for Executable_Suffix use ".out"; end Builder; package Binder is for Required_Switches ("Ada") use Binder'Required_Switches ("Ada") & ("gnatbind_prefix=${PREFIX(ada)}"); end Binder; gprbuild-gpl-2014-src/share/gprconfig/targetset.xml0000644000076700001450000001607012277050514021745 0ustar gnatmailgnat x86-elinos-linux i686-elinos-linux ppc-elinos-linux powerpc-elinos-linux e500v2-wrs-linux e500v2-wrs-linux ppc-wrs-linux powerpc-wrs-linux x86-linux i.86-.*linux.* x86_64-linux x86_64-.*linux.* ia64-hp_linux ia64-sgi_linux ia64-.*linux.* sparc-solaris sparc-.*solaris.* sparc64-solaris sparc64-.*solaris.* x86-solaris i.86-(pc-)?solaris.* x86-windows mingw32 i.86-.*mingw32.* pentium-.*mingw32.* x86_64-windows x86_64-.*mingw32.* ppc-darwin powerpc.*darwin.* x86-darwin i.86-.*-darwin.* x86_64-darwin x86_64-.*-darwin.* pa-hpux hppa.*-hpux.* ia64-hpux ia64-.*hpux.* alpha-tru64 alpha.*osf.* alpha-openvms alpha64-dec-openvms.* mips-irix mips-.*irix.* ppc-aix powerpc.*-aix.* x86-lynx i.86-.*-lynxos i.*-cygwin.* pent.*-cygwin.* x86-freebsd i.86-.*freebsd.* x86_64-freebsd x86_64-.*freebsd.* amd64-.*freebsd.* aamp .*aamp.* ppc-lynx5.* powerpc-elf-lynxos5.* ppc-lynx-solaris ppc-lynx-.* powerpc-elf-lynxos.* ppc-xcoff-lynxos ppc-xcoff-lynxos178.* powerpc-xcoff-lynxos178.* x86-lynx5.* i386-elf-lynxos5.* x86-wrs-vxworks x86-vx6-windows x86-vx6-linux i.86-wrs-vxworks powerpc-wrs-vxworks ppc-vxw-solaris ppc-vxw-windows ppc-vx178b-solaris ppc-vx178b-windows ppc-vx6-solaris ppc-vx6-windows ppc-vx6-linux e500v2-wrs-vxworks e500v2-vx6-solaris e500v2-vx6-windows e500v2-vx6-linux leon-wrs-vxworks leon-vx6-linux ppc-vx653-solaris ppc-vx653-windows powerpc-wrs-vxworksae e500v2-vx653-windows e500v2-wrs-vxworksae ppc-vxmils-windows powerpc-wrs-vxworksmils e500v2-vxmils-windows e500v2-wrs-vxworksmils x86-vx653-windows i.86-wrs-vxworksae ppc-elf-solaris ppc-elf-windows powerpc-elf p55-elf-windows powerpc-eabispe erc32-elf-solaris erc32-elf-linux erc32-elf.* leon-elf-solaris leon-elf-linux leon-elf.* leon3-elf-linux leon3-elf.* arm-elf-linux arm-eabi avr-elf-windows avr gprbuild-gpl-2014-src/share/gprconfig/windres.xml0000644000076700001450000000210512033260115021376 0ustar gnatmailgnat WINDRES (i686-pc-mingw32-|x86_64-pc-mingw32-)?windres ${PREFIX}windres --version WinRes ${PREFIX}gcc -dumpmachine package Compiler is for Driver ("WinRes") use "${PREFIX(WinRes)}windres"; for Leading_Required_Switches ("WinRes") use ("-i"); for Object_File_Suffix ("WinRes") use ".coff"; for Object_File_Switches ("WinRes") use ("-o", ""); end Compiler; package Naming is for Body_Suffix ("WinRes") use ".rc"; end Naming; gprbuild-gpl-2014-src/share/gprconfig/clean.xml0000644000076700001450000000051412160011421021002 0ustar gnatmailgnat package Clean is -- Remove the files generated by gnatinspect (in the context of GPS) for Artifacts_In_Object_Dir use Clean'Artifacts_In_Object_Dir & ("gnatinspect.*"); end Clean; gprbuild-gpl-2014-src/share/share.gpr0000644000076700001450000000014312323721731017047 0ustar gnatmailgnatproject Share is for Languages use ("XML"); for Source_Dirs use ("gprconfig"); end Share; gprbuild-gpl-2014-src/config.sub0000755000076700001450000006710010517620563016126 0ustar gnatmailgnat#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. timestamp='2001-09-07' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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 of the License, or # (at your option) any later version. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dsp16xx \ | fr30 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | m32r | m68000 | m68k | m88k | mcore \ | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el | mips64vr4300 \ | mips64vr4300el | mips64vr5000 | mips64vr5000el \ | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ | mipsisa32 \ | mn10200 | mn10300 \ | ns16k | ns32k \ | openrisc \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | s390 | s390x \ | sh | sh[34] | sh[34]eb | shbe | shle \ | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \ | stormy16 | strongarm \ | tahoe | thumb | tic80 | tron \ | v850 \ | we32k \ | x86 | xscale \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alphapca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armv*-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c54x-* \ | clipper-* | cray2-* | cydra-* \ | d10v-* | d30v-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | m32r-* \ | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | s390-* | s390x-* \ | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \ | sparc-* | sparc64-* | sparc86x-* | sparclite-* \ | sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \ | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ | v850-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; [cjt]90) basic_machine=${basic_machine}-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mipsel*-linux*) basic_machine=mipsel-unknown os=-linux-gnu ;; mips*-linux*) basic_machine=mips-unknown os=-linux-gnu ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i686-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sparclite-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=t3e-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; windows32) basic_machine=i386-pc os=-windows32-msvcrt ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; mips) if [ x$os = x-linux-gnu ]; then basic_machine=mips-unknown else basic_machine=mips-mips fi ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh3eb | sh4eb) basic_machine=sh-unknown ;; sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; c4x*) basic_machine=c4x-none os=-coff ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto*) os=-nto-qnx ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: gprbuild-gpl-2014-src/known-problems-1630000644000076700001450000001234412115157055017347 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.6.3 ======================================== Copyright (C) 2012-2013, AdaCore The following is a listing of known problems in release 1.6.3. Except where specifically noted, all these problems have been corrected in the development tree of the 2.0 technology. This means they are corrected in any 1.7.0w/2.0.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-163-M214-016 VxWorks: incompatible system headers in RTP Problem: When compiling a C file for a RTP on VxWorks, path to incompatible system headers are added to the configuration and can provoke a compilation error. Status: This was fixed in 2.0 on 2012-07-10 Workaround: Remove the following lines from the .cgpr file: for Leading_Required_Switches ("C") use Compiler'Leading_Required_Switches ("C") & ("-I" & Wind_Base & "/target/h", "-I" & Wind_Base & "/target/h/wrn/coreip"); KP-163-L921-007 Resolve --RTS relative pathes Problem: The behaviour of --RTS switch using a relative path is different when the switch appears on the gprbuild command line and when the switch appears in the Builder package. Status: This was fixed in 2.1 on 2012-12-23 Workaround: Specify the switch on the command line KP-163-L717-025 gprconfig crashes with exception Expression_Error Problem: If a query for the target of a compiler, such as "gcc -dumpmachine", returns a string that includes special characters or sequence of characters in regular expressions, gprconfig may crash with exception Expression_error. Status: This was fixed in 2.0 on 2012-07-18 Workaround: Remove from the path the compilers that returns such malformed targets. KP-163-L713-021 Exception DIRECTORY_ERROR raised when missing obj directory Problem: The exception DIRECTORY_ERROR is raised when an externally build project defines an object directory which does not exists. Status: This was fixed in 2.0 on 2012-07-13 Workaround: Create the missing object directory manually KP-163-L624-002 Knowledge base must_match node may not have desired effect Problem: In some cases, the toolchain that should have been ignored by gprconfig because it doesn't satisfy must_match criterion is added to the list of candidates anyway. Status: This was fixed in 2.0 on 2012-06-28 Workaround: Describe a toolchain in a way that doesn't use must_match criterion, or simply do not select a candidate that is incorrect. KP-163-L530-060 Allow the same library project in multiple tree Problem: An error message is reported when the same library project is found in different aggregated projects. Status: This was fixed in 2.0 on 2012-06-06 Workaround: Compile aggregated projects separately KP-163-L503-024 gprbuild crashes with exception names in virtual project Problem: gprbuild crashes if a project that is virtually extended has one or several sources with exception names specified in its package Naming. Status: This was fixed in 2.0 on 2012-07-05 Workaround: Use only names that follows the naming scheme of the project. KP-163-L321-006 Extra recompilation when using gprbuild -s -m Problem: When gprbuild is invoked with both -s and -m and the timestamp of a source (or the comments, but not the code) has changed, gprbuild still recompiles the source because the switches file is older than the source. Status: This was fixed in 2.0 on 2012-03-21 Workaround: Use only -m. KP-163-L320-047 gprbuild --no-indirect-imports and generic instantiations Problem: When --no-indirect-imports is used and an imported units is instantiated or contains an instantiation, there may be units imported by the generic body that are sources of a project that is not imported. In this case, gprbuild reports an error. Status: This was fixed in 2.0 on 2012-03-27 Workaround: Import the additional projects. KP-163-L315-021 gprbuild --no-object-check and main in project file Problem: When gprbuild is called with --no-object-check and no main on the command line, and there is one or several mains specified in the project file, all sources of the project files were compiled instead of just the closure of the mains. Status: This was fixed in 2.0 on 2012-03-16 Workaround: Call gprbuild with a main on the command line. KP-163-L215-032 Remove duplicate stack size option on Windows Problem: On Windows, a stack size option such as "-XLinker --stack=" in the linker switches in the project file or on the command line is not taken into account. Status: This was fixed in 2.0 on 2012-02-16 Workaround: Make sure that the default stack size option is sufficient for the execution of the program. gprbuild-gpl-2014-src/configure0000755000076700001450000024727212046434747016072 0ustar gnatmailgnat#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for gprbuild 2.1. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='gprbuild' PACKAGE_TARNAME='gprbuild' PACKAGE_VERSION='2.1' PACKAGE_STRING='gprbuild 2.1' PACKAGE_BUGREPORT='report@adacore.com' ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os ac_prefix_program INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA objdir is_windows xmlada_build_target xmlada_prj_flags LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures gprbuild 2.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/gprbuild] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of gprbuild 2.1:";; esac cat <<\_ACEOF Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF gprbuild configure 2.1 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by gprbuild $as_me 2.1, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking target system type" >&5 echo $ECHO_N "checking target system type... $ECHO_C" >&6; } if test "${ac_cv_target+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_target" >&5 echo "${ECHO_T}$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 echo "$as_me: error: invalid value of canonical target" >&2;} { (exit 1); exit 1; }; };; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- if test "x$prefix" = xNONE; then echo $ECHO_N "checking for prefix by $ECHO_C" >&6 # Extract the first word of "gnatmake", so it can be a program name with args. set dummy gnatmake; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_ac_prefix_program+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $ac_prefix_program in [\\/]* | ?:[\\/]*) ac_cv_path_ac_prefix_program="$ac_prefix_program" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_prefix_program="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_prefix_program=$ac_cv_path_ac_prefix_program if test -n "$ac_prefix_program"; then { echo "$as_me:$LINENO: result: $ac_prefix_program" >&5 echo "${ECHO_T}$ac_prefix_program" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test -n "$ac_prefix_program"; then prefix=`$as_dirname -- "$ac_prefix_program" || $as_expr X"$ac_prefix_program" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_prefix_program" : 'X\(//\)[^/]' \| \ X"$ac_prefix_program" : 'X\(//\)$' \| \ X"$ac_prefix_program" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_prefix_program" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` prefix=`$as_dirname -- "$prefix" || $as_expr X"$prefix" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$prefix" : 'X\(//\)[^/]' \| \ X"$prefix" : 'X\(//\)$' \| \ X"$prefix" : 'X\(/\)' \| . 2>/dev/null || echo X"$prefix" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` fi fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' objdir=`pwd` case $host in *mingw*|*cygwin*) is_windows="true";; *) is_windows="false";; esac { echo "$as_me:$LINENO: checking for xmlada" >&5 echo $ECHO_N "checking for xmlada... $ECHO_C" >&6; } xmlada_build_target= xmlada_prj_flags= if test -d $srcdir/xmlada; then xmlada_build_target=build_xmlada xmlada_prj_flags="-aP$srcdir/xmlada/install/lib/gnat" { echo "$as_me:$LINENO: result: yes (sources in gprbuild tree)" >&5 echo "${ECHO_T}yes (sources in gprbuild tree)" >&6; } else # Create a temporary directory (from "info autoconf") : ${TMPDIR=/tmp} { tmp=`(umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null` \ && test -n "$tmp" && test -d "$tmp" } || { tmp=$TMPDIR/foo$$-$RANDOM (umask 077 && mkdir -p "$tmp") } || exit $? mkdir $tmp/lib cat > $tmp/conftest.gpr << EOF with "xmlada.gpr"; project Conftest is for Source_Dirs use (); end Conftest; EOF if gnatmake -P$tmp/conftest.gpr >&5 2>&1; then { echo "$as_me:$LINENO: result: yes (precompiled)" >&5 echo "${ECHO_T}yes (precompiled)" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } { { echo "$as_me:$LINENO: error: cannot find xmlada See \`config.log' for more details." >&5 echo "$as_me: error: cannot find xmlada See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi ac_config_files="$ac_config_files src/gprconfig-sdefault.ads Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by gprbuild $as_me 2.1, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ gprbuild config.status 2.1 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/gprconfig-sdefault.ads") CONFIG_FILES="$CONFIG_FILES src/gprconfig-sdefault.ads" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim target!$target$ac_delim target_cpu!$target_cpu$ac_delim target_vendor!$target_vendor$ac_delim target_os!$target_os$ac_delim ac_prefix_program!$ac_prefix_program$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim objdir!$objdir$ac_delim is_windows!$is_windows$ac_delim xmlada_build_target!$xmlada_build_target$ac_delim xmlada_prj_flags!$xmlada_prj_flags$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 59; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi gprbuild-gpl-2014-src/vms_gprbuild.gpr0000644000076700001450000000614012323721731017343 0ustar gnatmailgnatproject VMS_Gprbuild is type OS_Type is ("avms", "ivms"); OS : OS_Type := external ("OS", "ivms"); type Build_Type is ("debug", "production", "coverage", "profiling"); Bld : Build_Type := external ("BUILD", "debug"); type VCS_Type is ("Subversion", "Git", "auto"); VCS_Kind : VCS_Type := external ("PRJ_VCS", "Subversion"); for Main use ("gprbuild.adb", "gprbind.adb", "gprlib.adb", "gprclean.adb", "ccomp.adb", "forcomp.adb"); for Source_Dirs use ("src", "gnat"); case Bld is when "production" => for Object_Dir use "obj"; when "coverage" => for Object_Dir use "obj-cov"; when "profiling" => for Object_Dir use "obj-prof"; when "debug" => for Object_Dir use "obj-debug"; end case; for Exec_Dir use "."; for Languages use ("Ada", "C"); package Compiler is common_switches := ("-gnat05", "-gnaty", "-gnatQ"); case Bld is when "debug" => for Default_Switches ("Ada") use common_switches & ("-g", "-gnata", "-gnatVa", "-gnatwaCJI" -- , "-gnatwe" , "-gnatyg" ); for Local_Configuration_Pragmas use "debug.adc"; when "coverage" => for Default_Switches ("Ada") use common_switches & ("-ftest-coverage", "-fprofile-arcs"); when "profiling" => for Default_Switches ("Ada") use common_switches & ("-pg", "-g"); when "production" => for Default_Switches ("Ada") use common_switches & ("-O2", "-gnatpn", "-gnatws"); end case; end Compiler; package Binder is common_switches := ("-E", "-static"); case Bld is when "debug" => for Default_Switches ("Ada") use common_switches; when "coverage" | "profiling" | "production" => for Default_Switches ("Ada") use common_switches; end case; end Binder; package Linker is Common_Switches_VMS := (project'Object_Dir & "/gprbuild_dummies.obj", project'Object_Dir & "/link.obj"); case Bld is when "production" | "debug" | "coverage" => for Default_Switches ("Ada") use Common_Switches_VMS; when "profiling" => for Default_Switches ("Ada") use Common_Switches_VMS & ("-pg", "-g"); end case; end Linker; Common_Excluded_Source_Files := ("gprlib-build_shared_lib.adb", "gprlib-build_shared_lib-nosymbols.adb", "gprlib-build_shared_lib-vms.adb", "mlib-tgt-vms-alpha.adb", "mlib-tgt-vms-ia64.adb"); package Naming is for Body ("gprlib.build_shared_lib") use "gprlib-build_shared_lib-vms.adb"; for Body ("gpr_util.knowledge") use "gpr_util-knowledge-vms.adb"; case OS is when "avms" => for Body ("mlib.tgt.specific") use "mlib-tgt-specific-vms-alpha.adb"; when "ivms" => for Body ("mlib.tgt.specific") use "mlib-tgt-specific-vms-ia64.adb"; end case; end Naming; end VMS_Gprbuild; gprbuild-gpl-2014-src/features-140000644000076700001450000000554211370043134016117 0ustar gnatmailgnat============================== GPRBUILD 1.4 NEW FEATURES LIST ============================== Copyright (C) 2009-2010, AdaCore This file contains a complete list of new features in version 1.4 of GPRBUILD. A full description of all GPRBUILD features can be found in the GPRBUILD User's Guide. An ISO date (YYYY-MM-DD) appears in parentheses after the description line. This date shows the implementation date of the feature. Any 1.4.0w wavefront subsequent to this date will contain the indicated feature, as will any subsequent releases. NF-14-J107-014 Compilation switches and Stand-Alone Libraries (2010-01-11) The Ada leading and trailing switches are now used to compile the binder generated files of Stand-Alone Libraries. NF-14-IA01-036 No relink if non interfaces of shared SALs changed (2009-10-01) When only non interface units are modified in a shared Stand-Alone Library, the shared SAL needs to be rebuilt but the executable no longer needs to be rebound and relinked. NF-14-I930-029 Ignore Builder switches -x for Ada (2009-09-30) For better compatibility with gnatmake, switch -x is ignored when found in the Builder switches for Ada. NF-14-I928-023 Library_Interface of SALs enforced (2009-09-30) When attribute Interfaces is not declared in a Stand-Alone Library, the units declared in Library_Interface constitutes the interface of the library. If an external unit imports a unit of the library that is not in Library_Interface, its compilation will be invalidated and gprbuild will fail. NF-14-I814-016 gprbuild no longer outputs "creating auto.cgpr" (2009-08-20) When running in the default auto configuration mode, gprbuild will no longer display the message "creating auto.cgpr" NF-14-I728-026 gprclean warns when object dir does not exist (2009-08-11) When the object dir of a project does not exist, gprclean used to exit with an error. Instead, it will now display a warning, and skip this project, but continue cleaning the other projects if required. NF-14-I415-016 Binder generated file compiled with all options (2009-05-06) gprbind now compiles the binder generated file with the required trailing compilation switches specified in the configuration project file. NF-14-I401-028 Support for Ada multi-unit source files (2009-09-20) gprbuild now supports Ada multi-unit source files NF-14-HA27-001 New switch --no-split-units (2009-10-07) A new switch --no-split-units is added. When this switch is specified, the spec, body and subunits of an Ada unit must be sources of the same project or of projects extending each others. NF-14-H828-007 Compilers working on all targets (2009-09-03) It is now possible in the knowledge base for gprconfig to specify compilers that work on all targets, by omitting the node. In particular, you can add support for tools that generate code instead of object code. gprbuild-gpl-2014-src/known-problems-210000644000076700001450000001562612312367513017267 0ustar gnatmailgnat====================================== Known problems in GPRBUILD version 2.1 ====================================== Copyright (C) 2013-2014, AdaCore The following is a listing of known problems in releases 2.1.1 and 2.1.2. Each entry contains a status line stating when the problem was fixed, and on which release(s). In addition, any wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) also contains the fix. This can be used to determine if a given release or wavefront has the fix identified in the entry. Note that older releases might or might not be affected by the problems listed in this document. Known problems fixed in 2.2.1 and above --------------------------------------- KP-21-N319-020 gprbuild fails with binder switch "-s" Problem: When gprbuild is invoked with the binder switch "-s". the binding phase will fail as gnatbind is unable to find the sources. Status: This was fixed in 2.2 on 2014-03-19 Workaround: Do not use binder switch "-s" when using gprbuild. KP-21-N318-025 gprinstall does not recognized -d option Problem: The -d option (short version of --dry-run) is documented but not recognized by gprinstall. Status: This was fixed in 2.2 on 2014-03-19 Workaround: Uses --dry-run instead. KP-21-N313-008 gprinstall fails with spec naming exception Problem: When gprinstall is invoked to install a library project file that is not a Stand-Alone Library and there is a spec with a naming exception, the installation will fail. Status: This was fixed in 2.2 on 2014-03-13 Workaround: Avoid spec naming exceptions in library project file. KP-21-N310-027 gprbuild wait indefinitely for some compilation results Problem: If the Remote package Root_Dir attribute is not properly set gprbuild may not terminate. Status: This was fixed in 2.2 on 2014-03-10 Workaround: fix the Root_Dir attribute value. KP-21-N207-022 Fail to compile sources in distributed mode Problem: Top level sources (sources found at the project's root directory) will fail to compile on remote compilation slaves. Status: This was fixed in 2.2 on 2014-02-07 Workaround: do not use the distributed compilation mode KP-21-N206-041 wrong permissions set by gprinstall for binaries Problem: On UNIX, a binary installed with gprinstall will have the executable permission set only for the owner. This will prevent others to execute this binary. It is a problem when installing an application in a shared computer for example. Status: This was fixed in 2.2 on 2014-02-06 Workaround: change the permissions manually using chmod KP-21-N120-075 gprclean -r and cycles in externally built projects Problem: When there are several externally built projects in the project tree and some of them form a cycle, through limited withs, invoking gprclean with switch -r will result in a crash. Status: This was fixed in 2.2 on 2014-01-21 Workaround: Avoid circularities in externally built projects or invoke gprclean without switch -r. KP-21-N103-018 Failure to link on target powerpc-xcoff-lynxos178 Problem: For target powerpc-xcoff-lynxos178, when there are two many object files to be linked, because a response file is not used, the linking phase may fail. Status: This was fixed in 2.2 on 2014-01-06 Workaround: Add these two lines in package Linker of the main project: for Response_File_Format use "GCC_GNU"; for Max_Command_Line_Length use "8192"; KP-21-MB30-011 Garbled output from parallel invocations of gnatbind Problem: When gprbuild is invoked with -jnn and there are several mains, several invocations of gprbind may be running in parallel and their displayed gnatbind invocations may be garbled. Status: This was fixed in 2.2 on 2013-12-01 Workaround: Ignore the problem or invoke gprbuild without -jnn. KP-21-MB26-007 Dependency builder must be invoked from the object directory Problem: When gprbuild performs parallel compilations and for some language a dependency builder is invoked to build a dependency file, the dependency builder may be invoked from the object directory of another project and thus may fail if some of its arguments are relative paths. Status: This was fixed in 2.2 on 2013-11-27 Workaround: Use absolute paths for the arguments of a dependency builder. KP-21-MB05-034 gprinstall fails to install projects built with sub-dirs Problem: gprinstall is not able to install a code which has been built with gprbuild's --subdirs option. Status: This was fixed in 2.2 on 2013-11-05 Workaround: Install the code manually. KP-21-MA31-004 Aggregated libraries and externally built Problem: gprbuild was not properly dealing with externally built projects on the dependencies. First it was trying to add the object code from such libraries and failed to pass the library on to the linker. Status: This was fixed in 2.2 on 2013-11-01 Workaround: Remove the externally built projects from the dependencies if possible and pass the corresponding library to the linker. KP-21-MA30-041 Aggregated libraries and gprinstall Problem: gprinstall was not properly handling aggregate libraries. The installation was failing and/or the generated project was not usable. Status: This was fixed in 2.2 on 2013-11-02 Workaround: Install the software using a script. Known problems fixed in 2.1.2 and above --------------------------------------- Known problems fixed in 2.1.1 and above --------------------------------------- KP-21-MB06-054 gprinstall and shared library with version on windows Problem: On Windows, gprinstall fails while installing a shared library project when the attribute Library_Version is defined. Status: This was fixed in 2.2 on 2013-11-06 This was fixed in 2.1.1 on 2013-11-27 Workaround: Manually install the library. KP-21-MB06-015 gprinstall and standalone libraries Problem: gprinstall does not generate a usable project file for standalone libraries. Status: This was fixed in 2.2 on 2013-11-06 This was fixed in 2.1.1 on 2013-11-27 Workaround: Manually adds the Library_Interface and Library_Standalone attributes. KP-21-MB05-020 gprconfig does not detect non GNAT gcc C and g++ compilers Problem: gprconfig does not find all non GNAT gcc C and g++ compilers. Status: This was fixed in 2.2 on 2013-11-07 This was fixed in 2.1.1 on 2013-12-10 Workaround: Manually edit a configuration project file and use it with gprbuild. gprbuild-gpl-2014-src/known-problems-1520000644000076700001450000000343511673621721017352 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.5.2 ======================================== Copyright (C) 2011, AdaCore The following is a listing of known problems in release 1.5.2. Except where specifically noted, all these problems have been corrected in the development tree of the 1.6 technology. This means they are corrected in any 1.6.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-152-KA13-044 Crash when attempting to compile an header file Problem: gprbuild crashes when asked to compile an header file, for example with: gprbuild -u -c prj.gpr toro.h Status: This was fixed in 1.6.0 on 2011-10-14 Workaround: Do not attempt to compile header files. KP-152-KA04-012 Pragma Linker_Options not honored Problem: gprbuild does not pass libraries specified with a pragma Linker_Options to the linker. Status: This was fixed in 1.6.0 on 2011-10-06 Workaround: Pass the corresponding libraries explicitly to the linker. KP-152-K801-014 Crash for library projects with no sources Problem: gprbuild and gprclean crash with a library project with no sources that is not externally built. Status: This was fixed in 1.6.0 on 2011-08-02 Workaround: Declare the library project as externally built. KP-152-K711-032 Failure to build archive on Windows Problem: On Windows, gprbuild may fail to build an archive if the length of the command line is greater than 8192. Status: This was fixed in 1.6.0 on 2011-07-22 Workaround: Reduce the length of the object path names to reduce the length of the command line. gprbuild-gpl-2014-src/CHANGES0000644000076700001450000000014712323721732015131 0ustar gnatmailgnat{doc: 303217, gnat: 303554, gprbuild: 225341, gprbuild.anod: 7807aabc8a6be77aca4e121b12238a2da15898cd} gprbuild-gpl-2014-src/known-problems-1620000644000076700001450000000107312032613023017331 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.6.2 ======================================== Copyright (C) 2012, AdaCore The following is a listing of known problems in release 1.6.2. Except where specifically noted, all these problems have been corrected in the development tree of the 2.0 technology. This means they are corrected in any 1.7.0w/2.0.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. gprbuild-gpl-2014-src/features-120000644000076700001450000000713111265233506016120 0ustar gnatmailgnat============================== GPRBUILD 1.2 NEW FEATURES LIST ============================== Copyright (C) 2008-2009, AdaCore This file contains a complete list of new features in version 1.2 of GPRBUILD. A full description of all GPRBUILD features can be found in the GPRBUILD User's Guide. An ISO date (YYYY-MM-DD) appears in parentheses after the description line. This date shows the implementation date of the feature. Any 1.2.0w wavefront subsequent to this date will contain the indicated feature, as will any subsequent releases. NF-12-HA21-031 Support for -margs switch (2008-10-21) The -margs switch, equivalent to -gargs is now supported, for better compatibility with gnatmake. NF-12-H903-021 Better error messages for qualified lib projects (2008-09-04) When a project qualified as a "library project" is not a library project because one or both of the attributes Library_Dir and Library_Name is missing, the error message will now indicate which attribute is not declared. NF-12-H821-015 Use response files when available (2008-09-22) When supported, and when the command line is too long, gprlib now uses response files to link shared libraries. NF-12-H812-005 Support for Diab C compiler (2008-08-28) The Diab C compiler is now supported for powerpc-elf (using the ppc750 variant). NF-12-H808-006 Specifying executable name in gprconfig (2008-08-11) The --config switch parameter to gprconfig can now be used to specify the base name of the executable you want to use. This can be used to easily select a type of compiler over another type, no matter whether it appears first in the path or not. NF-12-H806-009 Switch files only created when -s is used (2008-09-10) Switch files (with the .cswi suffix) are now only created when the switch -s is used. NF-12-H712-006 Partial linker to link shared libraries (2008-07-18) The partial linker, when declared, is now used to build shared libraries, in chunks if the command line length would be too long to build the shared library in one chunk. NF-12-H518-002 New attribute Builder'Global_Compilation_Switches (2008-06-03) A new attribute Global_Compilation_Switches ("") is created in package Builder. This attribute is taken into account in the main project when attribute Default_Switches ("") is not take into account. The switches specified in Global_Compilation_Switches ("") are used when compiling a source of language "" anywhere in the project tree. NF-12-H501-004 Improve backward compatibility with gnatmake (2008-05-05) Compatibility with projects accepted by gnatmake is improved: - a main may be truncated: the body suffix may be missing - switches from Builder'Switches (
) that are not recognized by gprbuild are for the compiler of the language of the main. NF-12-H408-020 New attributes Object_Generated and Objects_Linked (2008-04-16) New attributes for languages are created: Object_Generated (when "false", it means that no object file is created by the "compiler") and Objects_Linked (when "false", it means that the object files of the languages are not linked in an executable or put in a library). NF-12-H404-015 Warning when no source of a language (2008-04-05) When a language is declared or defaulted in a project file and there is no source of the language, gprbuild now issues a warning indicating this, unless warnings are suppressed. NF-12-H116-039 Partial linking in chunks (2008-07-18) When the partial linker is declared, a static stand-alone library is linked in chunks if the command line would be too long to link it in one chunk. gprbuild-gpl-2014-src/known-problems-2000000644000076700001450000000163412072675335017347 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 2.0.0 ======================================== Copyright (C) 2013, AdaCore The following is a listing of known problems in release 2.0.0. Except where specifically noted, all these problems have been corrected in the development tree of the 2.1 technology. This means they are corrected in any 2.1.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-200-M104-032 Modified library in externally built library project Problem: When the library file of an externally built library project is modified, executables that depend on this library are not always relinked. Status: This was fixed in 2.1.0 on 2012-01-07 Workaround: Force recompilation of the executables. gprbuild-gpl-2014-src/known-problems-1610000644000076700001450000000157212032613023017334 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.6.1 ======================================== Copyright (C) 2012, AdaCore The following is a listing of known problems in release 1.6.1. Except where specifically noted, all these problems have been corrected in the development tree of the 2.0 technology. This means they are corrected in any 1.7.0w/2.0.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-161-KC01-033 gprconfig: duplicate runtimes detected on Windows Problem: On Windows, gprconfig will sometimes report the "default" runtime multiple times for a given Ada compiler. Status: This was fixed in 1.6.2 on 2012-03-28 Workaround: Selecting any of the lines has the same effect. gprbuild-gpl-2014-src/known-problems-1500000644000076700001450000000327211522317416017343 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.5.0 ======================================== Copyright (C) 2010-2011, AdaCore The following is a listing of known problems in release 1.5.0. All these problems have been corrected in the release 1.5.1 and in any wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-150-JC22-022 Duplicate rpaths when there are several mains Problem: gprbuild keeps the rpaths from the previous mains when linking another main. That may leads to reach a limit in some platforms, and the link may then fail. Status: This was fixed in 1.5.1 on 2010-12-29 Workaround: Invoke gprbuild to link one main at a time. KP-150-JC09-012 Main in mixed cases on Windows Problem: On Windows, if the mains in attributes Mains contain capital letters, linking executables may fail. Status: This was fixed in 1.5.1 on 2011-01-07 Workaround: Use only small letters in attribute Main. KP-150-JB09-027 Improper attempt to compile locally removed body Problem: gprbuild attempts to compiled the body of a package that has been "locally removed" in an extended project. Status: This was fixed in 1.5.1 on 2010-11-09 Workaround: Make sure the spec needs a body. KP-150-J512-013 gprconfig's requires a prefix Problem: In its knowledge base, gprconfig requires a valid prefix attribute for nodes. Status: This was fixed in 1.5.1 on 2010-12-01 Workaround: Add prefix="-1" to gprbuild-gpl-2014-src/features-210000644000076700001450000001125612301444157016121 0ustar gnatmailgnat============================== GPRBUILD 2.1 NEW FEATURES LIST ============================== Copyright (C) 2012-2014, AdaCore This file contains a complete list of new features in version 2.1 of GPRBUILD. A full description of all GPRBUILD features can be found in the GPRBUILD User's Guide. NF-21-MC01-007 Add support for artifacts in gprinstall (2013-12-22) It is now possible to install files or directories not part of the project (source or object). Those artifacts are described into the project's Install package and can be used to install documentation or examples. NF-21-M918-043 Attributes External and environment variables (2013-09-19) In main aggregate project, when attribute External is specified, the corresponding environment variable is set, if it is not already set in the environment. NF-21-M719-035 -b, -c and -l may be used in package Builder (2013-08-08) The switches -c, -b and -l are no longer restricted to the command line. They may be specified in package Builder of the main project. NF-21-M719-029 --no-object-check may be used in package Builder (2013-07-21) The gprbuild switch --no-object-check is no longer restricted to the command line. It may be specified in package Builder of the main project file. NF-21-M714-001 Bind and link several executables simultaneously (2013-07-17) gprbuild is now able to bind several executables simultaneously when switch -jnnn is used, with nnn other than 1. It is also able to link these executables simultaneously with the same switch -jnnn. NF-21-M529-021 Clean artifacts in object and exec directories (2013-06-18) gprclean now cleans from the object directory the files specified in new attribute Artifacts_In_Object_Dir in package Clean and for main projects cleans from the exec directory the files specified in new attribute Artifacts_In_Exec_Dir in package Clean. NF-21-M405-028 gprinstall now supports cross-environment (2013-04-05) gprinstall will work in cross-environment by using the newly added --target option. This way it is possible to install a .dll created from a Windows cross-compiler on GNU/Linux for example. NF-21-M304-056 gprinstall now preserves timestamps (2013-03-05) gprinstall now preserves timestamps when copying the source files, object files and libraries. NF-21-LC19-034 Project_Path searched before ADA_PROJECT_PATH (2013-01-04) Project_Path values are searched before ADA_PROJECT_PATH. This behavior is better as if Project_Path is defined for the aggregate project we do not want to pick a random project found in ADA_PROJECT_PATH. NF-21-LA25-026 Aggregate projects and auto-configuration (2012-01-11) gprbuild fails when the project tree includes only aggregate projects and aggregate libraries projects. When gprbuild is called with a main project that is either an aggregate project or an aggregate library project, if auto-configuration is used, the configuration project file is created in the object directory of one of the non aggregate projects in the project tree. NF-21-LA22-030 New Linker attribute Trailing_Switches (2012-12-29) A new attribute Trailing_Switches has been added in package Linker of project files. These switches are added in the linking command line after the required switches, so that they can override these switches. NF-21-LA05-034 --config= in Builder switches (2012-12-24) gprbuild now takes into account a switch --config= in package Builder of the main project. NF-21-L809-007 Non Ada sources copied to the Library_Src_Dir (2013-06-24) In a library project, when attributes Library_Src_Dir and Interfaces are declared and there are non Ada sources/templates in the Interfaces, these sources/templates are now copied to the Library_Src_Dir. NF-21-L724-003 Empty Run_Path_Origin (2013-02-05) It is now allowed to specify attribute Run_Path_Origin as an empty string. This allows the run paths to be absolute paths. Then an executable may be moved to another directory without moving the shared libraries it needs. NF-21-KB01-015 libstdc++.so directory in run path option (2013-06-26) A new configuration attribute Library_Rpath_Options is created. The main goal of this attribute is to make sure that shared libraries with C++ code are linked with a run path option that includes the directory of the correct libstdc++.so. NF-21-K826-028 Add support for distributed compilation (2012-12-19) It is now possible to use multiple computers to conduct the compilations. This can give good speed-up for large projects. NF-21-K314-016 Linking several executables simultaneously (2013-07-14) gprbuild is now able to link several executables simultaneously when switch -jnnn is used, with nnn other than 1. gprbuild-gpl-2014-src/known-problems-1410000644000076700001450000001432311403143521017332 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.4.1 ======================================== Copyright (c) 2010 AdaCore The following is a listing of known problems in release 1.4.1. Except where specifically noted, all these problems have been corrected in the development tree of the 1.5 technology. This means they are corrected in any wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-141-J513-012 Same source file name in different projects and languages Problem: gprbuild does not accept an Ada source to have the same file name as the source of another language in another project. Status: This was fixed in 1.5.0 on 2010-05-17 Workaround: Do not put the two projects in the same project tree. KP-141-J512-013 gprconfig always appends .exe on Windows Problem: On windows, gprconfig will always add ".exe" to the executable name specified in the XML files (node ), even if this extension is already specified. Status: This was fixed in 1.5.0 on 2010-05-12 Workaround: This is only a problem when trying to share the same XML file on Unix and Windows systems, and naming the executables with ".exe" on the unix platform. In such a case, use two different XML files. KP-141-J506-012 Linking command line too long on VxWorks cross platforms Problem: On VxWorks cross platforms hosted on Windows, if the linking command line is too long (>32K) because there are two many Ada object files, the linking phase will fail. Status: This was fixed in 1.5.0 on 2010-05-07 Workaround: Reduce the linking command line length by changing some project files to non shared library project files. KP-141-J504-020 Shared SAL cannot import non library project Problem: When building a shared Stand-Alone Library project that imports a non library project with switch --unchecked-shared-lib-imports, the binding of the library fails. Status: This was fixed in 1.4.2 on 2010-05-05 Workaround: Do not import a non library project in a shared SAL KP-141-J325-035 Fake object files for header files in libraries Problem: When in a library project a header file has the same base name as an Ada source in the main project and the library project has the same object directory as the main project, linking executables may fail, as the object files corresponding to the Ada source is not specified to the linker. Status: This was fixed in 1.4.2 on 2010-03-30 Workaround: Specify a different object directory for the library project. KP-141-J316-017 Recompilation with switches -I in package Compiler Problem: When switches -I are specified in package Compiler for languages other than Ada, gprbuild may recompile up-to-date sources of these languages. Status: This was fixed in 1.5.0 on 2010-03-18 Workaround: Avoid switches -I. Use sourceless auxiliary project files to specify the header directories. KP-141-J310-029 Builder'Switches (others) not taken into account Problem: When there are no mains (for example in a library project) or several mains with different languages, the switches specified in Builder'Switches (others) are not taken into account. Status: This was fixed in 1.4.2 on 2010-03-11 Workaround: Specify the switches on the command line. KP-141-J309-023 Crash with pragma Restrictions (No_Dependence => ...) Problem gprbuild may crash when an ALI file contains R lines to record pragmas Restrictions (No_Dependence => ...). Status: This was fixed in 1.5.0 on 2010-03-11 Workaround: Remove the pragmas Restrictions (No_Dependence => ...). KP-141-J305-007 gprbuild fails to scan properly ALI files Problem: When gprbuild is used with an Ada compiler with sources more recent than those of gprbuild, it may happen that the compiler put lines in the ALI files that are not known by gprbuild, and then gprbuild fails to scan properly ALI files. Status: This was fixed in 1.4.2 on 2010-03-07 Workaround: Use a new version of gprbuild. KP-141-J301-025 Builder switch -p passed to the compiler Problem: When gprbuild find the switch -p in package Builder of the main project, it invoke the compiler with this switch. Status: This was fixed in 1.5.0 on 2010-03-02 Workaround: Remove switch -p from package Builder. KP-141-J107-023 Extending project and --no-indirect-imports Problem: gprbuild fails to compile a source in a project being extended that imports from the extending project when invoked with --no-indirect-imports. Status: This was fixed in 1.4.2 on 2010-01-07 Workaround: Invoke gprbuild without --no-indirect-imports. KP-141-IC08-014 Duplicate Linker_Options for extending projects Problem: An project extending another project inherits Linker'Linker_Options which may result in failure to link because of duplicate inker options. Status: This was fixed in 1.5.0 on 2009-12-08 Workaround: Declare empty Linker_Options in the extending project KP-141-IB16-009 Language configuration redefined in extending project Problem: When the compiler of a language is defined as non existent and an existing driver is declared in an extending project, the the sources of the original project are not compiled. Status: This was fixed in 1.5.0 on 2009-11-25 Workaround: Avoid declaring non existent compiler if the project is extended. KP-141-I925-022 No language detected when extending a project with no languages Problem: A project that extends another project with no languages may not have a default language, as no languages were found during auto configuration. Status: This was fixed in 1.5.0 on 2009-10-23 Workaround: Declare the Ada language in the extending project. gprbuild-gpl-2014-src/src/0000755000076700001450000000000012317234544014726 5ustar gnatmailgnatgprbuild-gpl-2014-src/src/gprbuild-link.ads0000644000076700001450000000333212323721731020157 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . L I N K -- -- -- -- S p e c -- -- -- -- Copyright (C) 2011-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package Gprbuild.Link is procedure Run; -- Perform linking, if necessary, for all registered mains: main project, -- aggregated projects,... end Gprbuild.Link; gprbuild-gpl-2014-src/src/ccomp.adb0000644000076700001450000001734012323721731016500 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- C C O M P -- -- -- -- B o d y -- -- -- -- Copyright (C) 2010-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This program is used on VMS as a front end to invoke the DEC C compiler CC pragma Extend_System (Aux_DEC); with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with GNAT.OS_Lib; use GNAT.OS_Lib; with Osint; use Osint; with System; use System; procedure Ccomp is subtype Cond_Value_Type is System.Unsigned_Longword; Output_File_Name : String_Access; procedure Spawn (Status : out Cond_Value_Type; Command : String; Input_File : String := String'Null_Parameter; Output_File : String := String'Null_Parameter); pragma Import (External, Spawn); pragma Import_Valued_Procedure (Spawn, "LIB$SPAWN", (Cond_Value_Type, String, String, String), (Value, Descriptor (S), Descriptor (S), Descriptor (S))); -- LIB$SPAWN is used to invoke the CC compiler procedure Stop (Status : Cond_Value_Type); pragma Import (External, Stop); pragma Import_Procedure (Stop, "LIB$STOP", Mechanism => Value); -- LIB$STOP is used to set the error code when the invocation of CC fails Success : constant Cond_Value_Type := 1; Command : constant String := "cc"; Status : Cond_Value_Type; Include_Directory : constant String := "/INCLUDE_DIRECTORY="; Mms_Dependencies : constant String := "/MMS_DEPENDENCIES=FILE="; Output_File : constant String := "-o"; Verbose : Boolean := False; procedure Add (S : in out String_Access; Last : in out Natural; Value : String); -- Add string Value to string variable S, updating Last --------- -- Add -- --------- procedure Add (S : in out String_Access; Last : in out Natural; Value : String) is begin while S'Last < Last + Value'Length loop declare New_S : constant String_Access := new String (1 .. 2 * S'Last); begin New_S (1 .. Last) := S (1 .. Last); Free (S); S := New_S; end; end loop; S (Last + 1 .. Last + Value'Length) := Value; Last := Last + Value'Length; end Add; begin declare Command_String : String_Access := new String (1 .. 40); -- This is the command string that will be used to invoke CC Last_Command : Natural := 0; Includes : String_Access := new String (1 .. 40); -- As they can be only one /INCLUDE_DIRECTORY= option, we regroupe all -- directories in string Includes. Last_Include : Natural := 0; Arg_Num : Natural; begin Add (Command_String, Last_Command, Command); Arg_Num := 0; while Arg_Num < Argument_Count loop Arg_Num := Arg_Num + 1; declare Arg : constant String := Argument (Arg_Num); begin -- If this command is /INCLUDE_DIRECTORY=, add the directory to -- string Includes. if Arg'Length > Include_Directory'Length and then Arg (Arg'First .. Arg'First + Include_Directory'Length - 1) = Include_Directory then if Last_Include = 0 then Add (Includes, Last_Include, Include_Directory & "("); else Add (Includes, Last_Include, ","); end if; declare Dir : constant String := Arg (Arg'First + Include_Directory'Length .. Arg'Last); New_Dir : String_Access; begin if Is_Directory (Dir) then New_Dir := To_Host_Dir_Spec (Dir, False); Add (Includes, Last_Include, New_Dir.all); else Add (Includes, Last_Include, Dir); end if; end; elsif Arg'Length > Mms_Dependencies'Length and then Arg (Arg'First .. Arg'First + Mms_Dependencies'Length - 1) = Mms_Dependencies then Add (Command_String, Last_Command, " " & Mms_Dependencies & To_Host_File_Spec (Arg (Arg'First + Mms_Dependencies'Length .. Arg'Last)).all); -- If it is "-o", the next argument is the output file elsif Arg = Output_File then if Arg_Num < Argument_Count then Arg_Num := Arg_Num + 1; Output_File_Name := To_Host_File_Spec (Argument (Arg_Num)); end if; -- If it is "-v", skip the argument and set Verbose to True elsif Arg = "-v" then Verbose := True; -- Otherwise, add argument to the command string else declare New_Arg : String_Access; begin if Is_Regular_File (Arg) then New_Arg := To_Host_File_Spec (Arg); elsif Is_Directory (Arg) then New_Arg := To_Host_Dir_Spec (Arg, False); end if; if New_Arg /= null then Add (Command_String, Last_Command, " " & New_Arg.all); else Add (Command_String, Last_Command, " " & Arg); end if; end; end if; end; end loop; -- If there was at least one /INCLUDE_DIRECTORY= switch, add -- /INCLUDE_DIRECTORY= with all directories to the command string. if Last_Include /= 0 then Add (Command_String, Last_Command, " " & Includes (1 .. Last_Include) & ")"); end if; -- Invoke CC declare Cmd : constant String (1 .. Last_Command) := Command_String (1 .. Last_Command); begin if Verbose then Put_Line (Cmd); end if; if Output_File_Name /= null then Spawn (Status, Cmd, Output_File => Output_File_Name.all); else Spawn (Status, Cmd); end if; if (Status mod 2) /= Success then Stop (Status); end if; end; end; end Ccomp; gprbuild-gpl-2014-src/src/gprbuild-post_compile.adb0000644000076700001450000036171312323721731021710 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . P O S T _ C O M P I L E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2011-2013, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Containers.Ordered_Sets; with Ada.Text_IO; use Ada, Ada.Text_IO; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with Debug; use Debug; with Gpr_Util; use Gpr_Util; with Gprexch; use Gprexch; with Makeutl; use Makeutl; with Opt; with Osint; use Osint; with Output; use Output; with Prj.Env; with Prj.Util; use Prj.Util; with Snames; use Snames; with Tempdir; package body Gprbuild.Post_Compile is type Lang_Names is array (Positive range <>) of Language_Ptr; type Lang_Names_Ptr is access Lang_Names; Langs : Lang_Names_Ptr := new Lang_Names (1 .. 4); Last_Lang : Natural := 0; procedure Build_Library (For_Project : Project_Id; Project_Tree : Project_Tree_Ref; No_Create : Boolean); -- Build, if necessary, the library of a library project. If No_Create -- is True then the actual static or shared library is not built, yet -- the exchange file with dependencies is created. procedure Post_Compilation_Phase (Main_Project : Project_Id; Project_Tree : Project_Tree_Ref); function Is_Included_In_Global_Archive (Object_Name : File_Name_Type; Project : Project_Id) return Boolean; -- Return True if the object Object_Name is not overridden by a source -- in a project extending project Project. type Library_Object is record Path : Path_Name_Type; TS : Time_Stamp_Type; Known : Boolean; end record; package Library_Objs is new Table.Table (Table_Component_Type => Library_Object, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 10, Table_Name => "Buildgpr.Library_Objs"); -- Library objects with their time stamps package Project_File_Paths is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Boolean, No_Element => False, Key => Name_Id, Hash => Hash, Equal => "="); procedure CodePeer_Globalize; -- Call the codepeer_globalizer for each of the object directories ------------------- -- Build_Library -- ------------------- procedure Build_Library (For_Project : Project_Id; Project_Tree : Project_Tree_Ref; No_Create : Boolean) is package Lang_Set is new Containers.Ordered_Sets (Name_Id); procedure Get_Objects; -- Get the paths of the object files of the library in table -- Library_Objs. procedure Write_List (File : Text_IO.File_Type; Label : Library_Section; List : String_List_Id); -- Write values in list into section Label in the given file. Ouptut -- Label if it is not the current section. procedure Write_Name_List (File : Text_IO.File_Type; Label : Library_Section; List : Name_List_Index); -- Write name list values into the File, output Label first. Ouptut -- Label if it is not the current section. -- Procedures to write specific sections of the exchange file procedure Write_Object_Files; procedure Write_Object_Directory; procedure Write_Compilers; procedure Write_Compiler_Leading_Switches; procedure Write_Compiler_Trailing_Switches; procedure Write_Partial_Linker; procedure Write_Shared_Lib_Minimum_Options; procedure Write_Library_Version; procedure Write_Runtime_Library_Dir; procedure Write_Auto_Init; procedure Write_Run_Path_Option; procedure Write_Leading_Library_Options; procedure Write_Library_Options; procedure Write_Library_Rpath_Options; procedure Write_Imported_Libraries; procedure Write_Dependency_Files; procedure Write_Toolchain_Version; procedure Write_Interface_Dep_Files; procedure Write_Other_Interfaces; procedure Write_Sources; procedure Write_Response_Files; Object_Directory_Path : String_Access; Project_Name : constant String := Get_Name_String (For_Project.Name); Current_Dir : constant String := Get_Current_Dir; Exchange_File : Text_IO.File_Type; Exchange_File_Name : String_Access; Latest_Object_TS : Time_Stamp_Type := Empty_Time_Stamp; Library_Builder_Name : String_Access; Library_Builder : String_Access; Library_Needs_To_Be_Built : Boolean := False; Object_Path : Path_Name_Type; Object_TS : Time_Stamp_Type; Source : Source_Id; Project : Project_Id; Disregard : Boolean; Path_Found : Boolean; Iter : Source_Iterator; Current_Section : Library_Section := No_Library_Section; ----------------- -- Get_Objects -- ----------------- procedure Get_Objects is procedure Process (Proj : Project_Id; Tree : Project_Tree_Ref; S : in out Boolean); -- Get objects for corresponding project ------------- -- Process -- ------------- procedure Process (Proj : Project_Id; Tree : Project_Tree_Ref; S : in out Boolean) is pragma Unreferenced (S); Never : constant Time_Stamp_Type := (others => '9'); -- A time stamp that is greater than any real one Source : Source_Id; Iter : Source_Iterator; begin Iter := For_Each_Source (Tree, Proj); loop Source := Prj.Element (Iter); exit when Source = No_Source; Change_To_Object_Directory (Source.Project); Initialize_Source_Record (Source); if Is_Compilable (Source) and then Source.Language.Config.Objects_Linked and then ((Source.Unit = No_Unit_Index and then Source.Kind = Impl) or else (Source.Unit /= No_Unit_Index and then (Source.Kind = Impl or else Other_Part (Source) = No_Source) and then not Is_Subunit (Source))) and then (not Source.Project.Externally_Built or else Source.Project.Extended_By /= No_Project) then Library_Objs.Append ((Path => Source.Object_Path, TS => Source.Object_TS, Known => False)); if Source.Object_TS = Empty_Time_Stamp then Latest_Object_TS := Never; if not Library_Needs_To_Be_Built then Library_Needs_To_Be_Built := True; if Opt.Verbose_Mode then Write_Str (" -> missing object file: "); Get_Name_String (Source.Object); Write_Line (Name_Buffer (1 .. Name_Len)); end if; end if; elsif Source.Object_TS > Latest_Object_TS then Latest_Object_TS := Source.Object_TS; end if; end if; Next (Iter); end loop; end Process; procedure Process_Project_And_Imported is new For_Every_Project_Imported (Boolean, Process); S : Boolean := False; Proj : Project_Id := For_Project; begin Library_Objs.Init; if For_Project.Qualifier = Aggregate_Library then Process_Project_And_Imported (For_Project, Project_Tree, S, Include_Aggregated => False); else while Proj /= No_Project loop Process (Proj, Project_Tree, S); Proj := Proj.Extends; end loop; end if; end Get_Objects; ------------------------ -- Write_Object_Files -- ------------------------ procedure Write_Object_Files is begin if Library_Objs.Last > 0 then Put_Line (Exchange_File, Library_Label (Object_Files)); for J in 1 .. Library_Objs.Last loop Put_Line (Exchange_File, Get_Name_String (Library_Objs.Table (J).Path)); end loop; end if; end Write_Object_Files; ---------------------------- -- Write_Object_Directory -- ---------------------------- procedure Write_Object_Directory is begin Put_Line (Exchange_File, Library_Label (Object_Directory)); -- Do not output object directory for an aggregate library as such -- library does not have objects by themselves. if For_Project.Qualifier /= Aggregate_Library then Put_Line (Exchange_File, Object_Directory_Path.all); end if; -- Add object directory of project being extended, if any declare Proj : Project_Id := For_Project.Extends; begin while Proj /= No_Project loop if Proj.Object_Directory /= No_Path_Information then Put_Line (Exchange_File, Get_Name_String (Proj.Object_Directory.Display_Name)); end if; Proj := Proj.Extends; end loop; end; -- Add object directories of imported non library projects Process_Imported_Non_Libraries (For_Project); declare Proj : Project_Id; begin for J in 1 .. Non_Library_Projs.Last loop Proj := Non_Library_Projs.Table (J); if Proj.Object_Directory /= No_Path_Information then Put_Line (Exchange_File, Get_Name_String (Proj.Object_Directory.Display_Name)); end if; end loop; end; -- Add ALI dir directories of imported projects (only if it is not an -- externally built project or if the project has sources). This skip -- the library projects with no sources used for example to add a -- system library to the linker. declare List : Project_List := For_Project.All_Imported_Projects; begin while List /= null loop if not List.Project.Externally_Built or else List.Project.Source_Dirs /= Nil_String then if List.Project.Library_ALI_Dir /= No_Path_Information then Put_Line (Exchange_File, Get_Name_String (List.Project.Library_ALI_Dir.Display_Name)); elsif List.Project.Library_Dir /= No_Path_Information then Put_Line (Exchange_File, Get_Name_String (List.Project.Library_Dir.Display_Name)); end if; end if; List := List.Next; end loop; end; end Write_Object_Directory; --------------------- -- Write_Compilers -- --------------------- procedure Write_Compilers is procedure Compilers_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean); -- Write compilers for the given project Dummy : Boolean := True; Lang_Seen : Lang_Set.Set; ------------------- -- Compilers_For -- ------------------- procedure Compilers_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Tree, Dummy); Lang : Language_Ptr := Project.Languages; Compiler : String_Access; begin -- Exchange file, Compilers section while Lang /= No_Language_Index loop if not Lang_Seen.Contains (Lang.Name) then Lang_Seen.Insert (Lang.Name); Compiler := Get_Compiler_Driver_Path (Project_Tree, Lang); if Compiler /= null then Put_Line (Exchange_File, Get_Name_String (Lang.Name)); Put_Line (Exchange_File, Compiler.all); elsif Lang.Config.Compiler_Driver /= No_File then Put_Line (Exchange_File, Get_Name_String (Lang.Name)); Put_Line (Exchange_File, Get_Name_String (Lang.Config.Compiler_Driver)); end if; end if; Lang := Lang.Next; end loop; end Compilers_For; procedure For_Imported is new For_Every_Project_Imported (Boolean, Compilers_For); begin Put_Line (Exchange_File, Library_Label (Compilers)); Compilers_For (For_Project, Project_Tree, Dummy); if For_Project.Qualifier = Aggregate_Library then For_Imported (For_Project, Project_Tree, Dummy); end if; end Write_Compilers; ------------------------------------- -- Write_Compiler_Leading_Switches -- ------------------------------------- procedure Write_Compiler_Leading_Switches is procedure Compiler_Leading_Switches_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean); -- Write compilers for the given project Dummy : Boolean := True; Lang_Seen : Lang_Set.Set; ----------------------------------- -- Compiler_Leading_Switches_For -- ----------------------------------- procedure Compiler_Leading_Switches_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Tree, Dummy); Lang : Language_Ptr := Project.Languages; Indx : Name_List_Index; Node : Name_Node; begin while Lang /= No_Language_Index loop if not Lang_Seen.Contains (Lang.Name) then Lang_Seen.Insert (Lang.Name); Indx := Lang.Config.Compiler_Leading_Required_Switches; if Indx /= No_Name_List then Put_Line (Exchange_File, "language=" & Get_Name_String (Lang.Name)); while Indx /= No_Name_List loop Node := Project_Tree.Shared.Name_Lists.Table (Indx); Put_Line (Exchange_File, Get_Name_String (Node.Name)); Indx := Node.Next; end loop; end if; end if; Lang := Lang.Next; end loop; end Compiler_Leading_Switches_For; procedure For_Imported is new For_Every_Project_Imported (Boolean, Compiler_Leading_Switches_For); begin Put_Line (Exchange_File, Library_Label (Compiler_Leading_Switches)); Compiler_Leading_Switches_For (For_Project, Project_Tree, Dummy); if For_Project.Qualifier = Aggregate_Library then For_Imported (For_Project, Project_Tree, Dummy); end if; end Write_Compiler_Leading_Switches; -------------------------------------- -- Write_Compiler_Trailing_Switches -- -------------------------------------- procedure Write_Compiler_Trailing_Switches is procedure Compiler_Trailing_Switches_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean); -- Write compilers for the given project Dummy : Boolean := True; Lang_Seen : Lang_Set.Set; ------------------------------------ -- Compiler_Trailing_Switches_For -- ------------------------------------ procedure Compiler_Trailing_Switches_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Tree, Dummy); Lang : Language_Ptr := Project.Languages; Indx : Name_List_Index; Node : Name_Node; begin while Lang /= No_Language_Index loop if not Lang_Seen.Contains (Lang.Name) then Lang_Seen.Insert (Lang.Name); Indx := Lang.Config.Compiler_Trailing_Required_Switches; if Indx /= No_Name_List then Put_Line (Exchange_File, "language=" & Get_Name_String (Lang.Name)); while Indx /= No_Name_List loop Node := Project_Tree.Shared.Name_Lists.Table (Indx); Put_Line (Exchange_File, Get_Name_String (Node.Name)); Indx := Node.Next; end loop; end if; end if; Lang := Lang.Next; end loop; end Compiler_Trailing_Switches_For; procedure For_Imported is new For_Every_Project_Imported (Boolean, Compiler_Trailing_Switches_For); begin Put_Line (Exchange_File, Library_Label (Compiler_Trailing_Switches)); Compiler_Trailing_Switches_For (For_Project, Project_Tree, Dummy); if For_Project.Qualifier = Aggregate_Library then For_Imported (For_Project, Project_Tree, Dummy); end if; end Write_Compiler_Trailing_Switches; ---------------- -- Write_List -- ---------------- procedure Write_List (File : Text_IO.File_Type; Label : Library_Section; List : String_List_Id) is Current : String_List_Id := List; Element : String_Element; Output_Label : Boolean := True; begin while Current /= Nil_String loop Element := Project_Tree.Shared.String_Elements.Table (Current); Get_Name_String (Element.Value); if Name_Len /= 0 then if Output_Label and then Current_Section /= Label then Put_Line (File, Library_Label (Label)); Output_Label := False; Current_Section := Label; end if; Put_Line (File, Name_Buffer (1 .. Name_Len)); end if; Current := Element.Next; end loop; end Write_List; --------------------- -- Write_Name_List -- --------------------- procedure Write_Name_List (File : Text_IO.File_Type; Label : Library_Section; List : Name_List_Index) is Current : Name_List_Index := List; Nam : Name_Node; begin if List /= No_Name_List then if Current_Section /= Label then Put_Line (File, Library_Label (Label)); Current_Section := Label; end if; while Current /= No_Name_List loop Nam := Project_Tree.Shared.Name_Lists.Table (Current); Put_Line (File, Get_Name_String (Nam.Name)); Current := Nam.Next; end loop; end if; end Write_Name_List; -------------------------- -- Write_Partial_Linker -- -------------------------- procedure Write_Partial_Linker is List : constant Name_List_Index := For_Project.Config.Lib_Partial_Linker; begin if List /= No_Name_List then Write_Name_List (Exchange_File, Partial_Linker, List); end if; end Write_Partial_Linker; -------------------------------------- -- Write_Shared_Lib_Minimum_Options -- -------------------------------------- procedure Write_Shared_Lib_Minimum_Options is Library_Options : Variable_Value := Nil_Variable_Value; begin -- Output the minimal options to build a shared library (standard -- or encapsulated). if For_Project.Standalone_Library = Encapsulated then Library_Options := Value_Of (Name_Library_Encapsulated_Options, For_Project.Decl.Attributes, Project_Tree.Shared); if not Library_Options.Default then Write_List (Exchange_File, Gprexch.Shared_Lib_Minimum_Options, Library_Options.Values); end if; else Write_Name_List (Exchange_File, Shared_Lib_Minimum_Options, For_Project.Config.Shared_Lib_Min_Options); end if; end Write_Shared_Lib_Minimum_Options; --------------------------- -- Write_Library_Version -- --------------------------- procedure Write_Library_Version is List : constant Name_List_Index := For_Project.Config.Lib_Version_Options; begin if List /= No_Name_List then Write_Name_List (Exchange_File, Library_Version_Options, List); end if; end Write_Library_Version; ------------------------------- -- Write_Runtime_Library_Dir -- ------------------------------- procedure Write_Runtime_Library_Dir is use type Ada.Containers.Count_Type; procedure RTL_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean); -- Write runtime libraries for the given project Dummy : Boolean := True; Lang_Seen : Lang_Set.Set; ------------- -- RTL_For -- ------------- procedure RTL_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Tree, Dummy); List : Language_Ptr := Project.Languages; begin while List /= No_Language_Index loop if List.Config.Runtime_Library_Dir /= No_Name and then not Lang_Seen.Contains (List.Name) then if Lang_Seen.Length = 0 then Put_Line (Exchange_File, Library_Label (Runtime_Library_Dir)); end if; Lang_Seen.Insert (List.Name); Put_Line (Exchange_File, Get_Name_String (List.Name)); Put_Line (Exchange_File, Get_Name_String (List.Config.Runtime_Library_Dir)); end if; List := List.Next; end loop; end RTL_For; procedure For_Imported is new For_Every_Project_Imported (Boolean, RTL_For); begin RTL_For (For_Project, Project_Tree, Dummy); if For_Project.Qualifier = Aggregate_Library then For_Imported (For_Project, Project_Tree, Dummy); end if; end Write_Runtime_Library_Dir; --------------------- -- Write_Auto_Init -- --------------------- procedure Write_Auto_Init is begin if For_Project.Standalone_Library /= No then if For_Project.Lib_Auto_Init then Put_Line (Exchange_File, Library_Label (Auto_Init)); end if; declare Binder_Package : constant Package_Id := Value_Of (Name => Name_Binder, In_Packages => For_Project.Decl.Packages, Shared => Project_Tree.Shared); begin if Binder_Package /= No_Package then declare Defaults : constant Array_Element_Id := Value_Of (Name => Name_Default_Switches, In_Arrays => Project_Tree.Shared.Packages.Table (Binder_Package).Decl.Arrays, Shared => Project_Tree.Shared); Switches : Variable_Value := Nil_Variable_Value; begin if Defaults /= No_Array_Element then Switches := Value_Of (Index => Name_Ada, Src_Index => 0, In_Array => Defaults, Shared => Project_Tree.Shared); if not Switches.Default then Write_List (Exchange_File, Gprexch.Binding_Options, Switches.Values); end if; end if; end; end if; end; end if; end Write_Auto_Init; --------------------------- -- Write_Run_Path_Option -- --------------------------- procedure Write_Run_Path_Option is List : constant Name_List_Index := For_Project.Config.Run_Path_Option; begin if Opt.Run_Path_Option and then List /= No_Name_List then Write_Name_List (Exchange_File, Run_Path_Option, List); if For_Project.Config.Separate_Run_Path_Options then Put_Line (Exchange_File, Library_Label (Gprexch.Separate_Run_Path_Options)); end if; end if; end Write_Run_Path_Option; ----------------------------------- -- Write_Leading_Library_Options -- ----------------------------------- procedure Write_Leading_Library_Options is Leading_Library_Options : Variable_Value := Nil_Variable_Value; begin -- If attribute Leading_Library_Options was specified, add these -- additional options. Leading_Library_Options := Value_Of (Name_Leading_Library_Options, For_Project.Decl.Attributes, Project_Tree.Shared); if not Leading_Library_Options.Default then Write_List (Exchange_File, Gprexch.Leading_Library_Options, Leading_Library_Options.Values); end if; end Write_Leading_Library_Options; --------------------------- -- Write_Library_Options -- --------------------------- procedure Write_Library_Options is Library_Options : Variable_Value := Nil_Variable_Value; begin -- If attribute Library_Options was specified, add these -- additional options. Library_Options := Value_Of (Name_Library_Options, For_Project.Decl.Attributes, Project_Tree.Shared); if not Library_Options.Default then Write_List (Exchange_File, Gprexch.Library_Options, Library_Options.Values); end if; end Write_Library_Options; --------------------------------- -- Write_Library_Rpath_Options -- --------------------------------- procedure Write_Library_Rpath_Options is procedure Add_Language (Lang : Language_Ptr); -- Add language Name in array Langs if not already there procedure Find_Languages (Project : Project_Id; Tree : Project_Tree_Ref; With_State : in out Boolean); -- Find the languages of a project procedure Find_All_Languages is new For_Every_Project_Imported (Boolean, Find_Languages); procedure Get_Languages; -- Put in Langs the languages of the project tree rooted at project -- For_Project. ------------------ -- Add_Language -- ------------------ procedure Add_Language (Lang : Language_Ptr) is begin -- Only add a language if it is not already in the list for J in 1 .. Last_Lang loop if Lang.Name = Langs (J).Name then return; end if; end loop; -- Double array Langs if already full if Last_Lang = Langs'Last then declare New_Langs : constant Lang_Names_Ptr := new Lang_Names (1 .. 2 * Langs'Length); begin New_Langs (Langs'Range) := Langs.all; Langs := New_Langs; end; end if; Last_Lang := Last_Lang + 1; Langs (Last_Lang) := Lang; end Add_Language; -------------------- -- Find_Languages -- -------------------- procedure Find_Languages (Project : Project_Id; Tree : Project_Tree_Ref; With_State : in out Boolean) is pragma Unreferenced (Tree); pragma Unreferenced (With_State); Lang : Language_Ptr := Project.Languages; begin while Lang /= No_Language_Index loop Add_Language (Lang); Lang := Lang.Next; end loop; end Find_Languages; ------------------- -- Get_Languages -- ------------------- procedure Get_Languages is OK : Boolean := True; begin Last_Lang := 0; Find_Languages (For_Project, Project_Tree, OK); Find_All_Languages (By => For_Project, Tree => Project_Tree, With_State => OK, Include_Aggregated => False); end Get_Languages; List : Array_Element_Id; Elem : Array_Element; Label_Issued : Boolean := False; Lang_Index : Natural; Lang_Ptr : Language_Ptr; Opt_List : String_List_Id; Opt_Elem : String_Element; begin if Opt.Run_Path_Option and then For_Project.Config.Run_Path_Option /= No_Name_List then List := Value_Of (Name_Library_Rpath_Options, For_Project.Decl.Arrays, Project_Tree.Shared); if List /= No_Array_Element then Get_Languages; while Last_Lang /= 0 and then List /= No_Array_Element loop Elem := Project_Tree.Shared.Array_Elements.Table (List); Lang_Index := 0; for J in 1 .. Last_Lang loop if Elem.Index = Langs (J).Name then Lang_Index := J; exit; end if; end loop; if Lang_Index /= 0 then Lang_Ptr := Langs (Lang_Index); -- Remove language from the list so that rpath options -- are not looked for twice for the same language. Langs (Lang_Index .. Last_Lang - 1) := Langs (Lang_Index + 1 .. Last_Lang); Last_Lang := Last_Lang - 1; -- Invoke the compiler for the language, followed by -- the options and put the result into a temporary file. Opt_List := Elem.Value.Values; -- Nothing to do if there is no options if Opt_List /= Nil_String then declare Opt_Nmb : Natural := 0; begin -- Count the options while Opt_List /= Nil_String loop Opt_Elem := Project_Tree.Shared.String_Elements.Table (Opt_List); Opt_Nmb := Opt_Nmb + 1; Opt_List := Opt_Elem.Next; end loop; declare Args : Argument_List (1 .. Opt_Nmb); FD : File_Descriptor; Pname : Path_Name_Type; Return_Code : Integer; pragma Warnings (Off, Return_Code); File : Text_File; Line : String (1 .. 1000); Last : Natural; Disregard : Boolean; pragma Warnings (Off, Disregard); begin Opt_List := Elem.Value.Values; Opt_Nmb := 0; -- Put the options in Args while Opt_List /= Nil_String loop Opt_Elem := Project_Tree.Shared.String_Elements.Table (Opt_List); Opt_Nmb := Opt_Nmb + 1; Args (Opt_Nmb) := new String' (Get_Name_String (Opt_Elem.Value)); Opt_List := Opt_Elem.Next; end loop; -- Create a temporary file and invoke the -- compiler with the options redirecting -- the output to this temporary file. Tempdir.Create_Temp_File (FD, Pname); Spawn (Program_Name => Lang_Ptr.Config.Compiler_Driver_Path.all, Args => Args, Output_File_Descriptor => FD, Return_Code => Return_Code); Close (FD); -- Now read the temporary file and get the first -- non empty line, if any. Open (File, Get_Name_String (Pname)); if Is_Valid (File) then Last := 0; while not End_Of_File (File) loop Get_Line (File, Line, Last); exit when Last > 0; end loop; -- Get the directory name of the path if Last /= 0 then declare Dir : constant String := Dir_Name (Normalize_Pathname (Line (1 .. Last))); begin -- If it is in fact a directory, put it -- in the exchange file. if Is_Directory (Dir) then if not Label_Issued then Put_Line (Exchange_File, Library_Label (Gprexch.Library_Rpath_Options)); Label_Issued := True; end if; Put_Line (Exchange_File, Dir); end if; end; end if; end if; if Is_Valid (File) then Close (File); end if; -- Delete the temporary file, if gprbuild was -- not invoked with -dn. if not Debug_Flag_N then Delete_File (Get_Name_String (Pname), Disregard); end if; end; end; end if; end if; List := Elem.Next; end loop; end if; end if; end Write_Library_Rpath_Options; ------------------------------ -- Write_Imported_Libraries -- ------------------------------ procedure Write_Imported_Libraries is begin -- If there are imported libraries, put their data in the exchange -- file. if Library_Projs.Last > 0 then Put_Line (Exchange_File, Library_Label (Imported_Libraries)); for J in reverse 1 .. Library_Projs.Last loop if For_Project.Qualifier /= Aggregate_Library or else Library_Projs.Table (J).Proj.Externally_Built then Put_Line (Exchange_File, Get_Name_String (Library_Projs.Table (J). Proj.Library_Dir.Display_Name)); Put_Line (Exchange_File, Get_Name_String (Library_Projs.Table (J).Proj.Library_Name)); end if; end loop; end if; end Write_Imported_Libraries; ---------------------------- -- Write_Dependency_Files -- ---------------------------- procedure Write_Dependency_Files is Current_Proj : Project_Id := For_Project; Source : Source_Id; begin Put_Line (Exchange_File, Library_Label (Dependency_Files)); while Current_Proj /= No_Project loop declare Iter : Source_Iterator; begin if Current_Proj.Qualifier = Aggregate_Library then Iter := For_Each_Source (Project_Tree); else Iter := For_Each_Source (Project_Tree, Current_Proj); end if; loop Source := Prj.Element (Iter); exit when Source = No_Source; if not Source.Locally_Removed and then Source.Dep_Path /= No_Path and then (not Source.Project.Externally_Built or else Source.Project.Extended_By /= No_Project) then if Source.Kind = Spec then if Other_Part (Source) = No_Source then Put_Line (Exchange_File, Get_Name_String (Source.Dep_Path)); end if; elsif not Is_Subunit (Source) then Put_Line (Exchange_File, Get_Name_String (Source.Dep_Path)); end if; end if; Next (Iter); end loop; Current_Proj := Current_Proj.Extends; end; end loop; end Write_Dependency_Files; ----------------------------- -- Write_Toolchain_Version -- ----------------------------- procedure Write_Toolchain_Version is use type Ada.Containers.Count_Type; procedure Toolchain_Version_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean); -- Write runtime libraries for the given project Dummy : Boolean := True; Lang_Seen : Lang_Set.Set; --------------------------- -- Toolchain_Version_For -- --------------------------- procedure Toolchain_Version_For (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Tree, Dummy); List : Language_Ptr := Project.Languages; begin while List /= No_Language_Index loop if List.Config.Toolchain_Version /= No_Name and then not Lang_Seen.Contains (List.Name) then if Lang_Seen.Length = 0 then Put_Line (Exchange_File, Library_Label (Toolchain_Version)); end if; Lang_Seen.Insert (List.Name); Put_Line (Exchange_File, Get_Name_String (List.Name)); Put_Line (Exchange_File, Get_Name_String (List.Config.Toolchain_Version)); end if; List := List.Next; end loop; end Toolchain_Version_For; procedure For_Imported is new For_Every_Project_Imported (Boolean, Toolchain_Version_For); begin Toolchain_Version_For (For_Project, Project_Tree, Dummy); if For_Project.Qualifier = Aggregate_Library then For_Imported (For_Project, Project_Tree, Dummy); end if; end Write_Toolchain_Version; ------------------------------- -- Write_Interface_Dep_Files -- ------------------------------- procedure Write_Interface_Dep_Files is Interface_ALIs : String_List_Id := For_Project.Lib_Interface_ALIs; Element : String_Element; begin Put_Line (Exchange_File, Library_Label (Interface_Dep_Files)); while Interface_ALIs /= Nil_String loop Element := Project_Tree.Shared.String_Elements.Table (Interface_ALIs); -- Find the source to get the absolute path of the ALI file declare Next_Proj : Project_Id; Iter : Source_Iterator; begin Next_Proj := For_Project.Extends; if For_Project.Qualifier = Aggregate_Library then Iter := For_Each_Source (Project_Tree); else Iter := For_Each_Source (Project_Tree, For_Project); end if; loop while Prj.Element (Iter) /= No_Source and then (Prj.Element (Iter).Unit = null or else Prj.Element (Iter).Dep_Name /= File_Name_Type (Element.Value)) loop Next (Iter); end loop; Source := Prj.Element (Iter); exit when Source /= No_Source or else Next_Proj = No_Project; Iter := For_Each_Source (Project_Tree, Next_Proj); Next_Proj := Next_Proj.Extends; end loop; if Source /= No_Source then if Source.Kind = Sep then Source := No_Source; elsif Source.Kind = Spec and then Other_Part (Source) /= No_Source then Source := Other_Part (Source); end if; end if; if Source /= No_Source then if Source.Project /= Project and then not Is_Extending (For_Project, Source.Project) and then not (For_Project.Qualifier = Aggregate_Library) then Source := No_Source; end if; end if; if Source /= No_Source then Put_Line (Exchange_File, Get_Name_String (Source.Dep_Path)); end if; end; Interface_ALIs := Element.Next; end loop; end Write_Interface_Dep_Files; ---------------------------- -- Write_Other_Interfaces -- ---------------------------- procedure Write_Other_Interfaces is Interfaces : String_List_Id := For_Project.Other_Interfaces; Element : String_Element; begin Put_Line (Exchange_File, Library_Label (Other_Interfaces)); while Interfaces /= Nil_String loop Element := Project_Tree.Shared.String_Elements.Table (Interfaces); Put_Line (Exchange_File, Get_Name_String (Element.Value)); Interfaces := Element.Next; end loop; end Write_Other_Interfaces; ------------------- -- Write_Sources -- ------------------- procedure Write_Sources is begin Put_Line (Exchange_File, Library_Label (Sources)); -- Copy the path of the sources Project := For_Project; while Project /= No_Project loop Iter := For_Each_Source (Project_Tree, Project); loop Source := Prj.Element (Iter); exit when Source = No_Source; if not Source.Locally_Removed and then Source.Replaced_By = No_Source then Put_Line (Exchange_File, Get_Name_String (Source.Path.Display_Name)); end if; Next (Iter); end loop; Project := Project.Extends; end loop; end Write_Sources; -------------------------- -- Write_Response_Files -- -------------------------- procedure Write_Response_Files is begin if For_Project.Config.Max_Command_Line_Length > 0 and then For_Project.Config.Resp_File_Format /= None then Put_Line (Exchange_File, Library_Label (Max_Command_Line_Length)); Put_Line (Exchange_File, For_Project.Config.Max_Command_Line_Length'Img); Put_Line (Exchange_File, Library_Label (Gprexch.Response_File_Format)); Put_Line (Exchange_File, For_Project.Config.Resp_File_Format'Img); if For_Project.Config.Resp_File_Options /= No_Name_List then Write_Name_List (Exchange_File, Response_File_Switches, For_Project.Config.Resp_File_Options); end if; if Debug.Debug_Flag_N then Put_Line (Exchange_File, Library_Label (Keep_Response_File)); end if; end if; end Write_Response_Files; -- Start of processing for Build_Library begin -- Check if there is an object directory if For_Project.Object_Directory.Display_Name = No_Path then Fail_Program (Project_Tree, "no object directory for library project " & Get_Name_String (For_Project.Display_Name)); end if; Object_Directory_Path := new String'(Get_Name_String (For_Project.Object_Directory.Display_Name)); -- Check consistentcy and build environment if For_Project.Config.Lib_Support = None then Fail_Program (Project_Tree, "library projects not supported on this platform"); elsif For_Project.Library_Kind /= Static and then For_Project.Config.Lib_Support /= Full then Fail_Program (Project_Tree, "shared library projects not supported on this platform"); elsif not For_Project.Config.Lib_Encapsulated_Supported and then For_Project.Standalone_Library = Encapsulated then Fail_Program (Project_Tree, "encapsulated library projects not supported on this platform"); end if; if For_Project.Config.Library_Builder = No_Path then Fail_Program (Project_Tree, "no library builder specified"); else Library_Builder := Locate_Exec_On_Path (Get_Name_String (For_Project.Config.Library_Builder)); if Library_Builder = null then Fail_Program (Project_Tree, "could not locate library builder """ & Get_Name_String (For_Project.Config.Library_Builder) & '"'); else Library_Builder_Name := new String'(Base_Name (Library_Builder.all)); end if; end if; if For_Project.Library_Kind = Static then Check_Archive_Builder; end if; Library_Needs_To_Be_Built := Opt.Force_Compilations; if not Library_Needs_To_Be_Built and then Opt.Verbose_Mode then Write_Str (" Checking library "); Get_Name_String (For_Project.Library_Name); Write_Str (Name_Buffer (1 .. Name_Len)); Write_Line (" ..."); end if; Get_Objects; -- Work occurs in the object directory Change_To_Object_Directory (For_Project); -- Get the name of of the library exchange file Get_Name_String (For_Project.Library_Name); Add_Str_To_Name_Buffer (Library_Exchange_Suffix); Exchange_File_Name := new String'(Name_Buffer (1 .. Name_Len)); if not Library_Needs_To_Be_Built then declare TS : constant Time_Stamp_Type := File_Stamp (File_Name_Type'(Name_Find)); begin if String (TS) < String (Latest_Object_TS) then Library_Needs_To_Be_Built := True; if Opt.Verbose_Mode then if TS = Empty_Time_Stamp then Write_Line (" -> library exchange file " & Exchange_File_Name.all & " does not exist"); else Write_Line (" -> object files more recent than" & " library exchange file " & Exchange_File_Name.all); end if; end if; else begin Open (Exchange_File, In_File, Exchange_File_Name.all); if End_Of_File (Exchange_File) then if Opt.Verbose_Mode then Write_Str (" -> library exchange file """); Write_Str (Exchange_File_Name.all); Write_Line (""" is empty"); end if; Library_Needs_To_Be_Built := True; end if; exception when others => if Opt.Verbose_Mode then Write_Str (" -> library exchange file """); Write_Str (Exchange_File_Name.all); Write_Line (""" cannot be open"); end if; Library_Needs_To_Be_Built := True; end; end if; end; end if; if not Library_Needs_To_Be_Built then -- The exchange file is open in input -- Get the path of the library file that should be the first field Get_Line (Exchange_File, Name_Buffer, Name_Len); if Name_Buffer (1 .. Name_Len) /= Library_Label (Library_Path) then Library_Needs_To_Be_Built := True; Close (Exchange_File); if Opt.Verbose_Mode then Write_Line (" -> library exchange file " & Exchange_File_Name.all & " has wrong format"); end if; else Get_Line (Exchange_File, Name_Buffer, Name_Len); if String (File_Stamp (File_Name_Type'(Name_Find))) < String (Latest_Object_TS) then Library_Needs_To_Be_Built := True; Close (Exchange_File); if Opt.Verbose_Mode then Write_Line (" -> object file(s) more recent than library file " & Exchange_File_Name.all); end if; end if; end if; end if; if not Library_Needs_To_Be_Built then -- The next line should be the object file label, followed by the -- object paths and time stamps. Get_Line (Exchange_File, Name_Buffer, Name_Len); if Name_Buffer (1 .. Name_Len) /= Library_Label (Object_Files) then Library_Needs_To_Be_Built := True; if Opt.Verbose_Mode then Write_Line (" -> library exchange file " & Exchange_File_Name.all & " has wrong format"); end if; end if; while not Library_Needs_To_Be_Built and then not End_Of_File (Exchange_File) loop Get_Line (Exchange_File, Name_Buffer, Name_Len); exit when Name_Buffer (1) = '['; Object_Path := Name_Find; Library_Needs_To_Be_Built := True; if End_Of_File (Exchange_File) then if Opt.Verbose_Mode then Write_Line (" -> library exchange file " & Exchange_File_Name.all & " has wrong format"); end if; else Get_Line (Exchange_File, Name_Buffer, Name_Len); if Name_Len = Time_Stamp_Length then Object_TS := Time_Stamp_Type (Name_Buffer (1 .. Name_Len)); Path_Found := False; for Index in 1 .. Library_Objs.Last loop if Object_Path = Library_Objs.Table (Index).Path then Path_Found := True; Library_Needs_To_Be_Built := Object_TS /= Library_Objs.Table (Index).TS; Library_Objs.Table (Index).Known := True; exit; end if; end loop; -- If the object file is not found, it may be that the path -- in the library is the same as the path of the object -- files, but with different symbolic links. So, we try -- again resolving the symbolic links. if not Path_Found then declare Norm_Path : constant String := Normalize_Pathname (Get_Name_String (Object_Path)); begin for Index in 1 .. Library_Objs.Last loop if Norm_Path = Normalize_Pathname (Get_Name_String (Library_Objs.Table (Index).Path)) then Library_Needs_To_Be_Built := Object_TS /= Library_Objs.Table (Index).TS; Library_Objs.Table (Index).Known := True; exit; end if; end loop; end; end if; if Library_Needs_To_Be_Built and then Opt.Verbose_Mode then Write_Str (" -> object file "); Write_Str (Get_Name_String (Object_Path)); Write_Line (" does not exist or have wrong time stamp"); end if; else if Opt.Verbose_Mode then Write_Line (" -> library exchange file " & Exchange_File_Name.all & " has wrong format"); end if; end if; end if; end loop; Close (Exchange_File); if not Library_Needs_To_Be_Built then for Index in 1 .. Library_Objs.Last loop if not Library_Objs.Table (Index).Known then Library_Needs_To_Be_Built := True; if Opt.Verbose_Mode then Write_Str (" -> library was built without object file "); Write_Line (Get_Name_String (Library_Objs.Table (Index).Path)); end if; exit; end if; end loop; end if; end if; if not Library_Needs_To_Be_Built then if Opt.Verbose_Mode then Write_Line (" -> up to date"); end if; else -- Create the library exchange file begin Create (Exchange_File, Out_File, Exchange_File_Name.all); exception when others => Fail_Program (Project_Tree, "unable to create library exchange file " & Exchange_File_Name.all); end; if Opt.Quiet_Output then Put_Line (Exchange_File, Library_Label (Quiet)); elsif Opt.Verbose_Mode then Put_Line (Exchange_File, Library_Label (Verbose)); end if; Write_Object_Files; -- Library name Put_Line (Exchange_File, Library_Label (Library_Name)); Put_Line (Exchange_File, Get_Name_String (For_Project.Library_Name)); -- Library version if For_Project.Lib_Internal_Name /= No_Name then Put_Line (Exchange_File, Library_Label (Library_Version)); Put_Line (Exchange_File, Get_Name_String (For_Project.Lib_Internal_Name)); end if; -- Library directory Put_Line (Exchange_File, Library_Label (Library_Directory)); Put_Line (Exchange_File, Get_Name_String (For_Project.Library_Dir.Display_Name)); if For_Project.Library_ALI_Dir /= No_Path_Information and then For_Project.Library_ALI_Dir.Name /= For_Project.Library_Dir.Name then Put_Line (Exchange_File, Library_Label (Library_Dependency_Directory)); Put_Line (Exchange_File, Get_Name_String (For_Project.Library_ALI_Dir.Display_Name)); end if; Write_Object_Directory; Write_Compilers; Write_Compiler_Leading_Switches; Write_Compiler_Trailing_Switches; Write_Partial_Linker; if No_Create then Put_Line (Exchange_File, Library_Label (Gprexch.No_Create)); end if; if For_Project.Qualifier = Aggregate_Library then Put_Line (Exchange_File, Library_Label (Gprexch.No_Copy_ALI)); end if; if For_Project.Library_Kind = Static then Put_Line (Exchange_File, Library_Label (Static)); Put_Line (Exchange_File, Library_Label (Archive_Builder)); Put_Line (Exchange_File, Archive_Builder_Path.all); for J in 1 .. Archive_Builder_Opts.Last loop Put_Line (Exchange_File, Archive_Builder_Opts.Options (J).all); end loop; if Archive_Builder_Append_Opts.Last > 0 then Put_Line (Exchange_File, Library_Label (Archive_Builder_Append_Option)); for J in 1 .. Archive_Builder_Append_Opts.Last loop Put_Line (Exchange_File, Archive_Builder_Append_Opts.Options (J).all); end loop; end if; if For_Project.Config.Archive_Suffix /= No_File then Put_Line (Exchange_File, Library_Label (Archive_Suffix)); Put_Line (Exchange_File, Get_Name_String (For_Project.Config.Archive_Suffix)); end if; if Archive_Indexer_Path /= null then Put_Line (Exchange_File, Library_Label (Archive_Indexer)); Put_Line (Exchange_File, Archive_Indexer_Path.all); for J in 1 .. Archive_Indexer_Opts.Last loop Put_Line (Exchange_File, Archive_Indexer_Opts.Options (J).all); end loop; end if; else -- Driver_Name if For_Project.Config.Shared_Lib_Driver /= No_File then Put_Line (Exchange_File, Library_Label (Driver_Name)); Put_Line (Exchange_File, Get_Name_String (For_Project.Config.Shared_Lib_Driver)); end if; -- Shared_Lib_Prefix if For_Project.Config.Shared_Lib_Prefix /= No_File then Put_Line (Exchange_File, Library_Label (Shared_Lib_Prefix)); Put_Line (Exchange_File, Get_Name_String (For_Project.Config.Shared_Lib_Prefix)); end if; -- Shared_Lib_Suffix if For_Project.Config.Shared_Lib_Suffix /= No_File then Put_Line (Exchange_File, Library_Label (Shared_Lib_Suffix)); Put_Line (Exchange_File, Get_Name_String (For_Project.Config.Shared_Lib_Suffix)); end if; Write_Shared_Lib_Minimum_Options; Write_Library_Version; -- Symbolic_Link_Supported if For_Project.Config.Symbolic_Link_Supported then Put_Line (Exchange_File, Library_Label (Symbolic_Link_Supported)); end if; -- Major_Minor_Id_Supported if For_Project.Config.Lib_Maj_Min_Id_Supported then Put_Line (Exchange_File, Library_Label (Major_Minor_Id_Supported)); end if; Process_Imported_Libraries (For_Project, There_Are_SALs => Disregard); Write_Runtime_Library_Dir; -- Relocatable if For_Project.Library_Kind /= Static then Put_Line (Exchange_File, Library_Label (Relocatable)); end if; -- Auto_init Write_Auto_Init; -- Gprexch.Install_Name if For_Project.Config.Library_Install_Name_Option /= No_Name then Put_Line (Exchange_File, Library_Label (Gprexch.Install_Name)); Put_Line (Exchange_File, Get_Name_String (For_Project.Config.Library_Install_Name_Option)); end if; Write_Run_Path_Option; Write_Leading_Library_Options; Write_Library_Options; Write_Library_Rpath_Options; Write_Imported_Libraries; end if; Write_Dependency_Files; Write_Toolchain_Version; if For_Project.Standalone_Library /= No then if For_Project.Lib_Auto_Init then Put_Line (Exchange_File, Library_Label (Auto_Init)); end if; Write_Interface_Dep_Files; if For_Project.Other_Interfaces /= Nil_String then Write_Other_Interfaces; end if; if For_Project.Library_Src_Dir /= No_Path_Information then -- Copy_Source_Dir Put_Line (Exchange_File, Library_Label (Copy_Source_Dir)); Put_Line (Exchange_File, Get_Name_String (For_Project.Library_Src_Dir.Display_Name)); Write_Sources; end if; -- Standalone mode Put_Line (Exchange_File, Library_Label (Standalone_Mode)); Put_Line (Exchange_File, Standalone'Image (For_Project.Standalone_Library)); elsif For_Project.Other_Interfaces /= Nil_String then Write_Other_Interfaces; end if; Write_Response_Files; Close (Exchange_File); declare Arguments : constant Argument_List := (1 => Exchange_File_Name); Success : Boolean; begin if not Opt.Quiet_Output then if Opt.Verbose_Mode then Write_Str (Library_Builder.all); else Write_Str (Library_Builder_Name.all); end if; Write_Char (' '); Write_Line (Exchange_File_Name.all); end if; Spawn (Library_Builder.all, Arguments, Success); if not Success then Fail_Program (Project_Tree, "could not build library for project " & Project_Name); end if; end; end if; -- Restore the current working directory to its previous value Change_Dir (Current_Dir); end Build_Library; ------------------------ -- CodePeer_Globalize -- ------------------------ procedure CodePeer_Globalize is Globalizer : constant String := "codepeer_globalizer"; -- CodePeer globalizer executable name Globalizer_Path : constant String_Access := GNAT.OS_Lib.Locate_Exec_On_Path (Globalizer); -- Path for CodePeer globalizer Quiet_Str : aliased String := "-quiet"; Globalizer_Args : constant Argument_List := (1 => Quiet_Str'Unchecked_Access); Previous_Dir : String_Access := null; Success : Boolean; procedure Globalize_Dir (Dir : String); -- Call CodePeer globalizer on Dir ------------------- -- Globalize_Dir -- ------------------- procedure Globalize_Dir (Dir : String) is Result : Boolean; begin if Previous_Dir = null or else Dir /= Previous_Dir.all then Free (Previous_Dir); Previous_Dir := new String'(Dir); Change_Dir (Dir); GNAT.OS_Lib.Spawn (Globalizer_Path.all, Globalizer_Args, Result); Success := Success and Result; end if; end Globalize_Dir; procedure Globalize_Dirs is new Prj.Env.For_All_Object_Dirs (Globalize_Dir); begin if Globalizer_Path = null then Fail_Program (Project_Tree, "error, unable to locate " & Globalizer); elsif not Opt.Quiet_Output then Write_Str (Globalizer); Write_Char (' '); Write_Line (Quiet_Str); end if; Success := True; Globalize_Dirs (Main_Project, Project_Tree); if not Success then Fail_Program (Project_Tree, "codepeer_globalizer failed"); end if; end CodePeer_Globalize; ----------------------------------- -- Is_Included_In_Global_Archive -- ----------------------------------- function Is_Included_In_Global_Archive (Object_Name : File_Name_Type; Project : Project_Id) return Boolean is Proj : Project_Id; Source : Source_Id; Iter : Source_Iterator; begin -- If a source is overriden in an extending project, then the object -- file is not included in the global archive. Proj := Project.Extended_By; while Proj /= No_Project loop Iter := For_Each_Source (Project_Tree, Proj); loop Source := Prj.Element (Iter); exit when Source = No_Source; if Object_To_Global_Archive (Source) and then Source.Object = Object_Name then return False; end if; Next (Iter); end loop; Proj := Proj.Extended_By; end loop; Iter := For_Each_Source (Project_Tree, Project); loop Source := Prj.Element (Iter); exit when Source = No_Source; if Object_To_Global_Archive (Source) and then Source.Object = Object_Name then return Source.Language.Config.Objects_Linked; end if; Next (Iter); end loop; return True; end Is_Included_In_Global_Archive; --------- -- Run -- --------- procedure Run is Data : Process_Data; Main : Main_Info; OK : Boolean; procedure Do_Post (Project : Project_Id; Tree : Project_Tree_Ref); ------------- -- Do_Post -- ------------- procedure Do_Post (Project : Project_Id; Tree : Project_Tree_Ref) is begin if Builder_Data (Tree).Need_Binding and then not Stop_Spawning then Post_Compilation_Phase (Project, Tree); end if; end Do_Post; procedure Post_Compile_All is new For_Project_And_Aggregated (Do_Post); begin Outstanding_Processes := 0; Stop_Spawning := False; if Main_Project.Qualifier = Aggregate_Library then -- For an aggregate library we do not want to build separate -- libraries if any, this means that at this point we want to -- handle only the main aggregate library project. Post_Compilation_Phase (Main_Project, Project_Tree); else Post_Compile_All (Main_Project, Project_Tree); end if; while Outstanding_Processes > 0 loop Await_Process (Data, OK); if not OK then Record_Failure (Data.Main); end if; Display_Processes ("bind"); end loop; if Bad_Processes.Last = 1 then Main := Bad_Processes.Table (1); Fail_Program (Main.Tree, "unable to bind " & Get_Name_String (Main.File)); elsif Bad_Processes.Last > 1 then for J in 1 .. Bad_Processes.Last loop Main := Bad_Processes.Table (J); Write_Str (" binding of "); Write_Str (Get_Name_String (Main.File)); Write_Line (" failed"); end loop; Fail_Program (Main.Tree, "*** post compilation phase failed"); end if; if Opt.CodePeer_Mode then CodePeer_Globalize; end if; end Run; ---------------------------- -- Post_Compilation_Phase -- ---------------------------- procedure Post_Compilation_Phase (Main_Project : Project_Id; Project_Tree : Project_Tree_Ref) is Exchange_File : Text_IO.File_Type; Line : String (1 .. 1_000); Last : Natural; Proj_List : Project_List; Shared_Libs : Boolean := False; Bind_Exchange_TS : Time_Stamp_Type; Bind_Object_TS : Time_Stamp_Type; Binder_Driver_Needs_To_Be_Called : Boolean := False; Project_Path : Name_Id; Project_File_TS : Time_Stamp_Type; There_Are_Stand_Alone_Libraries : Boolean := False; -- Set to True if there are SALS in the project tree procedure Bind_Language (Main_Proj : Project_Id; Main : String; Main_Base_Name_Index : File_Name_Type; Main_File : Main_Info; Main_Id : File_Name_Type; B_Data : Binding_Data); -- Do the "binding" phase for the language describeb in B_Data procedure Add_Dependency_Files (For_Project : Project_Id; Language : Language_Ptr; Main_Source : Source_Id; Dep_Files : out Boolean); -- Put the dependency files of the project in the binder exchange file procedure Wait_For_Available_Slot; -------------------------- -- Add_Dependency_Files -- -------------------------- procedure Add_Dependency_Files (For_Project : Project_Id; Language : Language_Ptr; Main_Source : Source_Id; Dep_Files : out Boolean) is Config : constant Language_Config := Language.Config; Roots : Roots_Access; Iter : Source_Iterator; procedure Put_Dependency_File (Source : Source_Id); -- Put in the exchange file the dependency file path name for source -- Source, if applicable. ------------------------- -- Put_Dependency_File -- ------------------------- procedure Put_Dependency_File (Source : Source_Id) is begin if Source.Language.Name = Language.Name and then ((Config.Kind = File_Based and then Source.Kind = Impl) or else (Config.Kind = Unit_Based and then Source.Unit /= No_Unit_Index and then Source.Unit /= Main_Source.Unit and then (Source.Kind = Impl or else Other_Part (Source) = No_Source) and then not Is_Subunit (Source))) and then Is_Included_In_Global_Archive (Source.Object, Source.Project) then if Source.Project = For_Project or not Source.Project.Library or Config.Kind = File_Based then Put_Line (Exchange_File, Get_Name_String (Source.Dep_Path)); Dep_Files := True; elsif Source.Project.Standalone_Library = No then Get_Name_String (Source.Project.Library_ALI_Dir.Display_Name); Get_Name_String_And_Append (Source.Dep_Name); Put_Line (Exchange_File, Name_Buffer (1 .. Name_Len)); Dep_Files := True; end if; end if; end Put_Dependency_File; begin Dep_Files := False; Roots := Main_Source.Roots; if Roots = null then if Main_Source.Unit = No_Unit_Index then if Main_Project.Qualifier = Aggregate_Library then Iter := For_Each_Source (Project_Tree); else Iter := For_Each_Source (Project_Tree, Encapsulated_Libs => False); end if; while Prj.Element (Iter) /= No_Source loop Initialize_Source_Record (Prj.Element (Iter)); -- Do not bind the non compilable sources, such as those -- that have been locally removed. if Is_Compilable (Prj.Element (Iter)) then Put_Dependency_File (Prj.Element (Iter)); end if; Next (Iter); end loop; end if; else -- Put the Roots while Roots /= null loop Put_Dependency_File (Roots.Root); Roots := Roots.Next; end loop; end if; end Add_Dependency_Files; ------------------- -- Bind_Language -- ------------------- procedure Bind_Language (Main_Proj : Project_Id; Main : String; Main_Base_Name_Index : File_Name_Type; Main_File : Main_Info; Main_Id : File_Name_Type; B_Data : Binding_Data) is Main_Source : constant Source_Id := Main_File.Source; Bind_Exchange : String_Access; Options_Instance : Bind_Option_Table_Ref := No_Bind_Option_Table; Dep_Files : Boolean; Lang_Index : Language_Ptr; Object_File_Suffix_Label_Written : Boolean; begin Binder_Driver_Needs_To_Be_Called := Opt.Force_Compilations or Opt.CodePeer_Mode; -- First check if the binder driver needs to be called. -- It needs to be called if -- 1) there is no existing binder exchange file -- 2) there is no binder generated object file -- 3) there is a dependency file of the language that -- is more recent than any of these two files if not Binder_Driver_Needs_To_Be_Called and then Opt.Verbose_Mode then Write_Line (" Checking binder generated files for " & Main & "..."); end if; Bind_Exchange := Binder_Exchange_File_Name (Main_Base_Name_Index, B_Data.Binder_Prefix); Bind_Exchange_TS := File_Stamp (Path_Name_Type'(Create_Name (Bind_Exchange.all))); if not Binder_Driver_Needs_To_Be_Called then if Bind_Exchange_TS = Empty_Time_Stamp then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> binder exchange file " & Bind_Exchange.all & " does not exist"); end if; else begin Open (Exchange_File, In_File, Bind_Exchange.all); exception when others => Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> could not open " & "binder exchange file" & Bind_Exchange.all); end if; end; end if; end if; if not Binder_Driver_Needs_To_Be_Called then begin Get_Line (Exchange_File, Line, Last); exception when others => Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> previous gprbind failed, or " & Bind_Exchange.all & " corrupted"); end if; end; end if; -- Check the generated object file if not Binder_Driver_Needs_To_Be_Called then if Line (1 .. Last) /= Binding_Label (Generated_Object_File) or else End_Of_File (Exchange_File) then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> previous gprbind failed, or " & Bind_Exchange.all & " corrupted"); end if; else Get_Line (Exchange_File, Line, Last); Bind_Object_TS := File_Stamp (Path_Name_Type'(Create_Name (Line (1 .. Last)))); if Bind_Object_TS = Empty_Time_Stamp then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> binder generated object " & Line (1 .. Last) & " does not exist"); end if; end if; end if; end if; if not Binder_Driver_Needs_To_Be_Called then if End_Of_File (Exchange_File) then Binder_Driver_Needs_To_Be_Called := True; else Get_Line (Exchange_File, Line, Last); if Line (1 .. Last) /= Binding_Label (Project_Files) or else End_Of_File (Exchange_File) then Binder_Driver_Needs_To_Be_Called := True; end if; end if; if Binder_Driver_Needs_To_Be_Called then if Opt.Verbose_Mode then Write_Line (" -> previous gprbind failed, or " & Bind_Exchange.all & " corrupted"); end if; else -- Populate the hash table Project_File_Paths with -- the paths of all project files in the closure -- of the main project. Project_File_Paths.Reset; Project_File_Paths.Set (Name_Id (Main_Proj.Path.Display_Name), True); Proj_List := Main_Proj.All_Imported_Projects; while Proj_List /= null loop Project_File_Paths.Set (Name_Id (Proj_List.Project.Path.Display_Name), True); Proj_List := Proj_List.Next; end loop; -- Get the project file paths from the exchange -- file and check if they are the expected project -- files with the same time stamps. while not End_Of_File (Exchange_File) loop Get_Line (Exchange_File, Name_Buffer, Name_Len); exit when Name_Len > 0 and then Name_Buffer (1) = '['; if End_Of_File (Exchange_File) then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> previous gprbind failed, " & "or " & Bind_Exchange.all & " corrupted"); end if; exit; end if; Project_Path := Name_Find; if Project_File_Paths.Get (Project_Path) then Project_File_Paths.Remove (Project_Path); Get_Line (Exchange_File, Line, Last); Project_File_TS := File_Stamp (Path_Name_Type (Project_Path)); if String (Project_File_TS) /= Line (1 .. Last) then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> project file " & Get_Name_String (Project_Path) & " has been modified"); end if; exit; end if; else Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> unknown project file " & Get_Name_String (Project_Path)); end if; exit; end if; end loop; -- Check if there are still project file paths in -- the has table. if not Binder_Driver_Needs_To_Be_Called and then Project_File_Paths.Get_First then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> more project files"); end if; end if; end if; end if; if Is_Open (Exchange_File) then Close (Exchange_File); end if; if not Binder_Driver_Needs_To_Be_Called then Queue.Initialize (Opt.One_Compilation_Per_Obj_Dir, Force => True); declare Config : constant Language_Config := B_Data.Language.Config; Source_Identity : Source_Id; Roots : Roots_Access; Source : Source_Id; Iter : Source_Iterator; begin -- Put the root sources in the queue if Main_Source.Language.Name = B_Data.Language.Name then Queue.Insert (Source => (Format => Format_Gprbuild, Tree => Main_File.Tree, Id => Main_File.Source)); end if; Roots := Main_Source.Roots; while Roots /= null loop Queue.Insert (Source => (Format => Format_Gprbuild, Tree => Main_File.Tree, Id => Roots.Root)); Roots := Roots.Next; end loop; -- If main is not unit base and there is no root, -- check all sources with the language name of the -- binder, except those that are not interfaces of -- their project. if Queue.Is_Empty then Iter := For_Each_Source (Project_Tree); Loop1 : loop Source := Prj.Element (Iter); exit Loop1 when Source = No_Source; if Source.Language.Name = B_Data.Language.Name and then not Source.Locally_Removed and then Is_Compilable (Source) and then ((Config.Kind = File_Based and then Source.Kind = Impl) or else (Config.Kind = Unit_Based and then Source.Unit /= No_Unit_Index and then Source.Unit /= Main_Source.Unit and then (Source.Kind = Impl or else Other_Part (Source) = No_Source) and then not Is_Subunit (Source))) and then Source.In_Interfaces then declare Proj : Project_Id; Src : Source_Id; Iter2 : Source_Iterator; begin -- If a source is overriden in an -- extending project, then the object file -- is not included in the global archive. Proj := Source.Project.Extended_By; Loop2 : while Proj /= No_Project loop Iter2 := For_Each_Source (Project_Tree, Proj); loop Src := Prj.Element (Iter2); exit when Src = No_Source; exit Loop1 when Src.Object = Source.Object; Next (Iter2); end loop; Proj := Proj.Extended_By; end loop Loop2; end; Queue.Insert (Source => (Format => Format_Gprbuild, Tree => Main_File.Tree, Id => Source)); end if; Next (Iter); end loop Loop1; end if; -- Get each file from the queue and check its -- dependency file. declare Dep_TS : aliased File_Attributes := Unknown_Attributes; Dep_File : File_Name_Type; Dep_Path : Path_Name_Type; Stamp : Time_Stamp_Type; The_ALI : ALI.ALI_Id; Text : Text_Buffer_Ptr; Found : Boolean; Source : Queue.Source_Info; begin while not Queue.Is_Empty loop Queue.Extract (Found, Source); Source_Identity := Source.Id; Initialize_Source_Record (Source_Identity); -- Get the dependency file for this source Dep_File := Source_Identity.Dep_Name; Dep_Path := Source_Identity.Dep_Path; Dep_TS := Source_Identity.Dep_TS; -- For a library file, if there is no ALI file -- in the object directory, check in the Library -- ALI directory. if not Is_Regular_File (Get_Name_String (Dep_Path)) and then Source_Identity.Project.Library and then Source_Identity.Project.Library_ALI_Dir /= No_Path_Information then Name_Len := 0; Add_Str_To_Name_Buffer (Get_Name_String (Source_Identity.Project .Library_ALI_Dir.Display_Name)); Add_Char_To_Name_Buffer (Directory_Separator); Add_Str_To_Name_Buffer (Get_Name_String (Dep_File)); Name_Buffer (Name_Len + 1) := ASCII.NUL; Dep_TS := Unknown_Attributes; if Is_Regular_File (Name_Buffer'Address, Dep_TS'Access) then Dep_Path := Name_Find; end if; end if; declare Proj : Project_Id := Source_Identity.Project.Extended_By; begin while Proj /= No_Project loop Name_Len := 0; if Proj.Library and then Proj.Library_ALI_Dir /= No_Path_Information then Add_Str_To_Name_Buffer (Get_Name_String (Proj.Library_ALI_Dir.Display_Name)); else Add_Str_To_Name_Buffer (Get_Name_String (Proj.Object_Directory.Display_Name)); end if; Add_Char_To_Name_Buffer (Directory_Separator); Add_Str_To_Name_Buffer (Get_Name_String (Dep_File)); Name_Buffer (Name_Len + 1) := ASCII.NUL; -- Check if the dependency file exists in -- the extended project, and if it does, -- replace both Dep_Path and Dep_TS with -- the information for it. declare NDT : aliased File_Attributes := Unknown_Attributes; begin if Is_Regular_File (Name_Buffer'Address, NDT'Access) then Dep_Path := Name_Find; Dep_TS := NDT; end if; end; Proj := Proj.Extended_By; end loop; end; Stamp := File_Time_Stamp (Dep_Path, Dep_TS'Access); -- Check the time stamp against the binder -- exchange file time stamp. if Stamp = Empty_Time_Stamp then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Str (" -> cannot find "); Write_Line (Get_Name_String (Dep_Path)); end if; exit; elsif Stamp > Bind_Exchange_TS then Binder_Driver_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Str (" -> "); Write_Str (Get_Name_String (Dep_Path)); Write_Line (" is more recent that the binder " & "exchange file"); end if; exit; else Text := Read_Library_Info_From_Full (File_Name_Type (Dep_Path), Dep_TS'Access); if Text /= null then The_ALI := ALI.Scan_ALI (File_Name_Type (Dep_Path), Text, Ignore_ED => False, Err => True, Ignore_Errors => True, Read_Lines => "W"); Free (Text); Queue.Insert_Withed_Sources_For (The_ALI, Project_Tree, Excluding_Shared_SALs => True); end if; end if; end loop; end; end; end if; if not Binder_Driver_Needs_To_Be_Called then if Opt.Verbose_Mode then Write_Line (" -> up to date"); end if; else Create (Exchange_File, Out_File, Bind_Exchange.all); -- Optional line: Quiet or Verbose if Opt.Quiet_Output then Put_Line (Exchange_File, Binding_Label (Quiet)); elsif Opt.Verbose_Mode then Put_Line (Exchange_File, Binding_Label (Verbose)); end if; -- If -dn was used, indicate to gprbind that the -- temporary response file, if created, should not -- deleted. if Debug_Flag_N then Put_Line (Exchange_File, Binding_Label (Delete_Temp_Files)); Put_Line (Exchange_File, "False"); end if; -- If there are Stand-Alone Libraries, tell it to gprbind if There_Are_Stand_Alone_Libraries then Put_Line (Exchange_File, Binding_Label (Gprexch.There_Are_Stand_Alone_Libraries)); end if; -- If the language is Ada, create a binder mapping file -- and pass it to gprbind. if B_Data.Language_Name = Name_Ada then declare Mapping_Path : constant Path_Name_Type := Create_Binder_Mapping_File (Project_Tree); begin if Mapping_Path /= No_Path then Put_Line (Exchange_File, Binding_Label (Gprexch.Mapping_File)); Put_Line (Exchange_File, Get_Name_String (Mapping_Path)); end if; end; end if; -- Send the Toolchain Version if there is one for the language if B_Data.Language.Config.Toolchain_Version /= No_Name then Put_Line (Exchange_File, Binding_Label (Toolchain_Version)); Put_Line (Exchange_File, Get_Name_String (B_Data.Language.Name)); Put_Line (Exchange_File, Get_Name_String (B_Data.Language.Config.Toolchain_Version)); end if; -- Send the object file suffix for each language where it -- is declared. Lang_Index := Main_Proj.Languages; Object_File_Suffix_Label_Written := False; while Lang_Index /= No_Language_Index loop if Lang_Index.Config.Object_File_Suffix /= No_Name then if not Object_File_Suffix_Label_Written then Put_Line (Exchange_File, Binding_Label (Gprexch.Object_File_Suffix)); Object_File_Suffix_Label_Written := True; end if; Put_Line (Exchange_File, Get_Name_String (Lang_Index.Name)); Put_Line (Exchange_File, Get_Name_String (Lang_Index.Config.Object_File_Suffix)); end if; Lang_Index := Lang_Index.Next; end loop; -- Optional line: shared libs if Shared_Libs then Put_Line (Exchange_File, Binding_Label (Gprexch.Shared_Libs)); end if; -- First, the main base name Put_Line (Exchange_File, Binding_Label (Gprexch.Main_Base_Name)); Put_Line (Exchange_File, Get_Name_String (Main_Base_Name_Index)); -- Then, the compiler path and required switches declare Config : Language_Config renames B_Data.Language.Config; List : Name_List_Index; Nam_Nod : Name_Node; Previous_Was_x : Boolean := False; begin -- Compiler path Put_Line (Exchange_File, Binding_Label (Gprexch.Compiler_Path)); Put_Line (Exchange_File, Get_Compiler_Driver_Path (Project_Tree, B_Data.Language).all); -- Leading required switches, if any List := Config.Compiler_Leading_Required_Switches; if List /= No_Name_List then Put_Line (Exchange_File, Binding_Label (Gprexch.Compiler_Leading_Switches)); while List /= No_Name_List loop Nam_Nod := Project_Tree.Shared.Name_Lists.Table (List); if Opt.CodePeer_Mode and then Previous_Was_x then Put_Line (Exchange_File, "adascil"); else Put_Line (Exchange_File, Get_Name_String (Nam_Nod.Name)); end if; Previous_Was_x := Get_Name_String (Nam_Nod.Name) = "-x"; List := Nam_Nod.Next; end loop; if Opt.CodePeer_Mode then Put_Line (Exchange_File, "-gnatcC"); end if; end if; -- Trailing required switches, if any List := Config.Compiler_Trailing_Required_Switches; if List /= No_Name_List then Put_Line (Exchange_File, Binding_Label (Gprexch.Compiler_Trailing_Switches)); while List /= No_Name_List loop Nam_Nod := Project_Tree.Shared.Name_Lists.Table (List); Put_Line (Exchange_File, Get_Name_String (Nam_Nod.Name)); List := Nam_Nod.Next; end loop; end if; end; -- Then, the Dependency files if Main_Source.Unit /= No_Unit_Index then Initialize_Source_Record (Main_Source); Put_Line (Exchange_File, Binding_Label (Main_Dependency_File)); Put_Line (Exchange_File, Get_Name_String (Main_Source.Dep_Path)); end if; -- Add the relevant dependency files, either those in -- Roots (
) for the project, or all dependency -- files in the project tree, if Roots (
) is not -- specified . Put_Line (Exchange_File, Binding_Label (Dependency_Files)); Add_Dependency_Files (Main_Proj, B_Data.Language, Main_Source, Dep_Files); -- Put the options, if any declare The_Packages : constant Package_Id := Main_Proj.Decl.Packages; Binder_Package : constant Prj.Package_Id := Prj.Util.Value_Of (Name => Name_Binder, In_Packages => The_Packages, Shared => Project_Tree.Shared); Config : constant Language_Config := B_Data.Language.Config; Switches : Variable_Value; Switch_List : String_List_Id; Element : String_Element; begin -- First, check if there are binder options -- specified in the main project file. if Binder_Package /= No_Package then declare Defaults : constant Array_Element_Id := Prj.Util.Value_Of (Name => Name_Default_Switches, In_Arrays => Project_Tree.Shared.Packages.Table (Binder_Package).Decl.Arrays, Shared => Project_Tree.Shared); Switches_Array : constant Array_Element_Id := Prj.Util.Value_Of (Name => Name_Switches, In_Arrays => Project_Tree.Shared.Packages.Table (Binder_Package).Decl.Arrays, Shared => Project_Tree.Shared); begin Switches := Prj.Util.Value_Of (Index => Name_Id (Main_Id), Src_Index => 0, In_Array => Switches_Array, Shared => Project_Tree.Shared, Allow_Wildcards => True); if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => B_Data.Language_Name, Src_Index => 0, In_Array => Switches_Array, Shared => Project_Tree.Shared, Force_Lower_Case_Index => True); end if; if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => All_Other_Names, Src_Index => 0, In_Array => Switches_Array, Shared => Project_Tree.Shared, Force_Lower_Case_Index => True); end if; if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => B_Data.Language_Name, Src_Index => 0, In_Array => Defaults, Shared => Project_Tree.Shared); end if; end; end if; -- If there are binder options, either minimum -- binder options, or in the main project file or -- on the command line, put them in the exchange -- file. Options_Instance := Binder_Options_HTable.Get (B_Data.Language_Name); if Config.Binder_Required_Switches /= No_Name_List or else Switches.Kind = Prj.List or else All_Language_Binder_Options.Last > 0 or else Options_Instance /= No_Bind_Option_Table or else Opt.CodePeer_Mode then Put_Line (Exchange_File, Binding_Label (Gprexch.Binding_Options)); -- First, the required switches, if any declare List : Name_List_Index := Config.Binder_Required_Switches; Elem : Name_Node; begin while List /= No_Name_List loop Elem := Project_Tree.Shared.Name_Lists.Table (List); Get_Name_String (Elem.Name); if Name_Len > 0 then Put_Line (Exchange_File, Name_Buffer (1 .. Name_Len)); end if; List := Elem.Next; end loop; end; -- Then, the eventual options in the main -- project file. if Switches.Kind = Prj.List then declare Option : String_Access; begin Switch_List := Switches.Values; while Switch_List /= Nil_String loop Element := Project_Tree.Shared.String_Elements.Table (Switch_List); Get_Name_String (Element.Value); if Name_Len > 0 then Option := new String' (Name_Buffer (1 .. Name_Len)); Test_If_Relative_Path (Option, Main_Project_Dir.all, No_Name); Put_Line (Exchange_File, Option.all); end if; Switch_List := Element.Next; end loop; end; end if; -- Then -P if in CodePeer mode if Opt.CodePeer_Mode then Put_Line (Exchange_File, "-P"); end if; -- Then those on the command line, for all -- binder drivers, if any. for J in 1 .. All_Language_Binder_Options.Last loop Put_Line (Exchange_File, All_Language_Binder_Options.Table (J).all); end loop; -- Finally those on the command line for the -- binder driver of the language if Options_Instance /= No_Bind_Option_Table then for Index in 1 .. Binder_Options.Last (Options_Instance.all) loop Put_Line (Exchange_File, Options_Instance.Table (Index).all); end loop; end if; end if; end; -- Finally, the list of the project paths with their -- time stamps. Put_Line (Exchange_File, Binding_Label (Project_Files)); -- The main project file is always the first one, so that -- gprbind may know the main project dir. Put_Line (Exchange_File, Get_Name_String (Main_Proj.Path.Display_Name)); Put_Line (Exchange_File, String (File_Stamp (Main_Proj.Path.Display_Name))); Proj_List := Main_Proj.All_Imported_Projects; while Proj_List /= null loop if Main_Proj.Standalone_Library = Encapsulated or else not Proj_List.From_Encapsulated_Lib then Put_Line (Exchange_File, Get_Name_String (Proj_List.Project.Path.Display_Name)); Put_Line (Exchange_File, String (File_Stamp (Proj_List.Project.Path.Display_Name))); end if; Proj_List := Proj_List.Next; end loop; Close (Exchange_File); if Main_Source.Unit = No_Unit_Index and then (not Dep_Files) then if Opt.Verbose_Mode then Write_Line (" -> nothing to bind"); end if; else if B_Data.Language.Config.Objects_Path /= No_Name then declare Env_Var : constant String := Get_Name_String (B_Data.Language.Config. Objects_Path); Path_Name : String_Access := Main_Proj.Objects_Path; begin if Path_Name = null then if Current_Verbosity = High then Put_Line (Env_Var & " :"); end if; Get_Directories (Project_Tree => Project_Tree, For_Project => Main_Proj, Activity => Executable_Binding, Languages => No_Names); Path_Name := Create_Path_From_Dirs; Main_Proj.Objects_Path := Path_Name; end if; Setenv (Env_Var, Path_Name.all); if Opt.Verbose_Mode then Write_Str (Env_Var); Write_Str (" = "); Write_Line (Path_Name.all); end if; end; elsif B_Data.Language.Config.Objects_Path_File /= No_Name then declare Env_Var : constant String := Get_Name_String (B_Data.Language.Config. Objects_Path_File); Path_Name : Path_Name_Type := Main_Proj.Objects_Path_File_Without_Libs; begin if Path_Name = No_Path then if Current_Verbosity = High then Put_Line (Env_Var & " :"); end if; Get_Directories (Project_Tree => Project_Tree, For_Project => Main_Proj, Activity => Executable_Binding, Languages => No_Names); declare FD : File_Descriptor; Len : Integer; Status : Boolean; begin Prj.Env.Create_New_Path_File (Shared => Project_Tree.Shared, Path_FD => FD, Path_Name => Main_Proj. Objects_Path_File_Without_Libs); if FD = Invalid_FD then Fail_Program (Project_Tree, "could not create " & "temporary path file"); end if; Path_Name := Main_Proj. Objects_Path_File_Without_Libs; for Index in 1 .. Directories.Last loop Get_Name_String (Directories.Table (Index)); if Current_Verbosity = High then Put_Line (Name_Buffer (1 .. Name_Len)); end if; Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := ASCII.LF; Len := Write (FD, Name_Buffer (1)'Address, Name_Len); if Len /= Name_Len then Fail_Program (Project_Tree, "disk full"); end if; end loop; Close (FD, Status); if not Status then Fail_Program (Project_Tree, "disk full"); end if; end; end if; Setenv (Env_Var, Get_Name_String (Path_Name)); if Opt.Verbose_Mode then Write_Str (Env_Var); Write_Str (" = "); Write_Line (Get_Name_String (Path_Name)); end if; end; end if; if not Opt.Quiet_Output then if Opt.Verbose_Mode then Write_Str (B_Data.Binder_Driver_Path.all); else Name_Len := 0; Add_Str_To_Name_Buffer (Base_Name (Get_Name_String (B_Data.Binder_Driver_Name))); if Executable_Suffix'Length /= 0 and then Name_Len > Executable_Suffix'Length and then Name_Buffer (Name_Len - Executable_Suffix'Length + 1 .. Name_Len) = Executable_Suffix.all then Name_Len := Name_Len - Executable_Suffix'Length; end if; Write_Str (Name_Buffer (1 .. Name_Len)); end if; Write_Char (' '); Write_Line (Bind_Exchange.all); end if; declare Pid : Process_Id; begin Pid := Non_Blocking_Spawn (B_Data.Binder_Driver_Path.all, (1 => Bind_Exchange)); if Pid = Invalid_Pid then Record_Failure (Main_File); else Add_Process (Pid, (Binding, Pid, Main_File)); Display_Processes ("bind"); end if; end; end if; end if; end Bind_Language; ----------------------------- -- Wait_For_Available_Slot -- ----------------------------- procedure Wait_For_Available_Slot is Data : Process_Data; OK : Boolean; begin while Outstanding_Processes >= Opt.Maximum_Processes loop Await_Process (Data, OK); if not OK then Record_Failure (Data.Main); end if; Display_Processes ("bind"); end loop; end Wait_For_Available_Slot; -- Start of processing for Post_Compilation_Phase begin -- Build the libraries, if any -- First, get the libraries in building order in table Library_Projs if not Opt.CodePeer_Mode then Process_Imported_Libraries (Main_Project, There_Are_SALs => There_Are_Stand_Alone_Libraries, And_Project_Itself => True); if Library_Projs.Last > 0 then declare Lib_Projs : array (1 .. Library_Projs.Last) of Library_Project; Proj : Library_Project; begin -- Copy the list of library projects in local array Lib_Projs, -- as procedure Build_Library uses table Library_Projs. for J in 1 .. Library_Projs.Last loop Lib_Projs (J) := Library_Projs.Table (J); end loop; for J in Lib_Projs'Range loop Proj := Lib_Projs (J); -- Try building a library only if no errors occured in -- library project and projects it depends on. if not Project_Compilation_Failed (Proj.Proj) then if Proj.Proj.Extended_By = No_Project then if not Proj.Proj.Externally_Built then Build_Library (Proj.Proj, Project_Tree, No_Create => Proj.Is_Aggregated); end if; if Proj.Proj.Library_Kind /= Static then Shared_Libs := True; end if; end if; end if; end loop; end; end if; end if; -- If no main is specified, there is nothing else to do if Mains.Number_Of_Mains (Project_Tree) = 0 then return; end if; -- Check if there is a need to call a binder driver Find_Binding_Languages (Project_Tree, Main_Project); -- Proceed to bind (or rebind if needed) for each main Mains.Reset; loop declare Main_File : Main_Info; begin Main_File := Mains.Next_Main; exit when Main_File = No_Main_Info; if Main_File.Tree /= Project_Tree or else Project_Compilation_Failed (Main_File.Project) then -- Will be processed later, or do not need any processing in -- the case of compilation errors in the project. null; elsif not Builder_Data (Main_File.Tree).There_Are_Binder_Drivers then if Current_Verbosity = High then Debug_Output ("Post-compilation, no binding required for", Debug_Name (Main_File.Tree)); end if; else declare Main : constant String := Get_Name_String (Main_File.File); Main_Id : constant File_Name_Type := Create_Name (Base_Name (Main)); Main_Index : constant Int := Main_File.Index; B_Data : Binding_Data; Main_Base_Name_Index : File_Name_Type; Main_Proj : Project_Id; Index_Separator : Character; begin Main_Proj := Ultimate_Extending_Project_Of (Main_File.Source.Project); -- Get the main base name-index name Index_Separator := Main_File.Source.Language .Config.Multi_Unit_Object_Separator; Main_Base_Name_Index := Base_Name_Index_For (Main, Main_Index, Index_Separator); Change_To_Object_Directory (Main_Proj); B_Data := Builder_Data (Main_File.Tree).Binding; while B_Data /= null loop Wait_For_Available_Slot; exit when Stop_Spawning; Bind_Language (Main_Proj, Main, Main_Base_Name_Index, Main_File, Main_Id, B_Data); exit when Stop_Spawning; B_Data := B_Data.Next; end loop; end; end if; end; end loop; end Post_Compilation_Phase; end Gprbuild.Post_Compile; gprbuild-gpl-2014-src/src/gprlib-build_shared_lib-nosymbols.adb0000644000076700001450000003403012323721731024145 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R L I B . B U I L D _ S H A R E D _ L I B -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This is the version of the body of procedure Build_Shared_Lib for most -- non VMS platforms where shared libraries are supported. with MLib; use MLib; with Output; use Output; separate (Gprlib) procedure Build_Shared_Lib is Ofiles : constant Argument_List := Argument_List (Object_Files.Table (1 .. Object_Files.Last)); Options : constant Argument_List := Argument_List (Options_Table.Table (1 .. Options_Table.Last)); Lib_File : constant String := Shared_Lib_Prefix.all & Library_Name.all & Shared_Lib_Suffix.all; Lib_Path : constant String := Library_Directory.all & Lib_File; Maj_Version : String_Access := new String'(""); Result : Integer; pragma Unreferenced (Result); procedure Build (Output_File : String); -- Find the library builder executable and invoke it with the correct -- options to build the shared library. ----------- -- Build -- ----------- procedure Build (Output_File : String) is Success : Boolean; Out_Opt : constant String_Access := new String'("-o"); Out_V : constant String_Access := new String'(Output_File); Driver : String_Access; Lib_Index : Natural := 0; Response_File_Name : Path_Name_Type := No_Path; Response_2 : Path_Name_Type := No_Path; procedure Display_Linking_Command; -- Display the linking command, depending on verbosity and quiet output ----------------------------- -- Display_Linking_Command -- ----------------------------- procedure Display_Linking_Command is begin if not Opt.Quiet_Output then if Opt.Verbose_Mode then Write_Str (Driver.all); else Write_Str (Base_Name (Driver.all)); end if; for J in 1 .. Last_Arg loop if Opt.Verbose_Mode or else J <= Lib_Index or else J = First_Object then Write_Char (' '); Write_Str (Arguments (J).all); elsif J > First_Object then Write_Str (" ..."); exit; elsif J = Lib_Index + 1 then Write_Str (" ..."); end if; end loop; Write_Eol; end if; end Display_Linking_Command; begin -- Get the executable to use, either the specified Driver, or "gcc" if Driver_Name = No_Name then Driver := Locate_Exec_On_Path (Gcc_Name); if Driver = null then Osint.Fail (Gcc_Name & " not found in path"); end if; else Driver := Locate_Exec_On_Path (Get_Name_String (Driver_Name)); if Driver = null then Osint.Fail (Get_Name_String (Driver_Name) & " not found in path"); end if; end if; Last_Arg := 0; Argument_Length := Driver'Length; -- The minimum arguments for J in 1 .. Shared_Lib_Minimum_Options.Last loop Add_Arg (Shared_Lib_Minimum_Options.Table (J)); end loop; -- The leading library options, if any for J in 1 .. Leading_Library_Options_Table.Last loop Add_Arg (Leading_Library_Options_Table.Table (J)); end loop; -- -o Add_Arg (Out_Opt); Add_Arg (Out_V); Lib_Index := Last_Arg; -- The options for J in Options'Range loop if Options (J) /= null and then Options (J).all /= "" then Add_Arg (Options (J)); end if; end loop; -- Other options for J in 1 .. Library_Version_Options.Last loop if Library_Version_Options.Table (J).all /= "" then Add_Arg (Library_Version_Options.Table (J)); end if; end loop; -- The object files if Partial_Linker /= null then Partial_Linker_Path := Locate_Exec_On_Path (Partial_Linker.all); if Partial_Linker_Path = null then Osint.Fail ("unable to locate linker " & Partial_Linker.all); end if; end if; if Resp_File_Format = Prj.None and then Partial_Linker_Path /= null then -- If partial linker is used, do a partial link first Partial_Number := 0; First_Object := Ofiles'First; loop declare Partial : constant String_Access := new String' (Partial_Name (Library_Name.all, Partial_Number, Object_Suffix)); Size : Natural := 0; Saved_Last_PL_Option : Natural; begin Saved_Last_PL_Option := Last_PL_Option; Add (Partial, PL_Options, Last_PL_Option); Size := Size + 1 + Partial'Length; if Partial_Number > 0 then Add (Partial_Name (Library_Name.all, Partial_Number - 1, Object_Suffix), PL_Options, Last_PL_Option); end if; for J in 1 .. Last_PL_Option loop Size := Size + 1 + PL_Options (J)'Length; end loop; loop Add (Ofiles (First_Object), PL_Options, Last_PL_Option); Size := Size + 1 + PL_Options (Last_PL_Option)'Length; First_Object := First_Object + 1; exit when First_Object > Ofiles'Last or else Size >= Maximum_Size; end loop; if not Quiet_Output then if Verbose_Mode then Put (Partial_Linker_Path.all); else Put (Base_Name (Partial_Linker_Path.all)); end if; for J in 1 .. Last_PL_Option loop if (not Verbose_Mode) and then J >= 5 then Put (" ..."); exit; end if; Put (' '); Put (PL_Options (J).all); end loop; New_Line; end if; Spawn (Partial_Linker_Path.all, PL_Options (1 .. Last_PL_Option), Success); if not Success then Osint.Fail ("call to linker driver " & Partial_Linker.all & " failed"); end if; if First_Object > Ofiles'Last then Add_Arg (Partial); exit; end if; Last_PL_Option := Saved_Last_PL_Option; Partial_Number := Partial_Number + 1; end; end loop; else First_Object := Last_Arg + 1; for J in Ofiles'Range loop Add_Arg (Ofiles (J)); end loop; end if; Last_Object := Last_Arg; -- In Ofiles we can have at the end some libraries -lname, so ensure -- that the object are only taken up to Last_Object_File_Index. if Last_Object_File_Index > First_Object and then Last_Object_File_Index < Last_Object then Last_Object := Last_Object_File_Index; end if; -- Finally the library switches and the library options for J in 1 .. Library_Switches_Table.Last loop Add_Arg (Library_Switches_Table.Table (J)); end loop; for J in 1 .. Library_Options_Table.Last loop Add_Arg (Library_Options_Table.Table (J)); end loop; Display_Linking_Command; -- Check if a response file is needed if Max_Command_Line_Length > 0 and then Argument_Length > Max_Command_Line_Length and then Resp_File_Format /= Prj.None then declare -- Preserve the options, if any Options : constant String_List := Arguments (Last_Object + 1 .. Last_Arg); begin Create_Response_File (Format => Resp_File_Format, Objects => Arguments (First_Object .. Last_Object), Other_Arguments => Options, Resp_File_Options => Response_File_Switches.all, Name_1 => Response_File_Name, Name_2 => Response_2); Last_Arg := First_Object - 1; if Resp_File_Format = GCC or else Resp_File_Format = GCC_GNU or else Resp_File_Format = GCC_Object_List or else Resp_File_Format = GCC_Option_List then Add_Arg (new String'("@" & Get_Name_String (Response_File_Name))); else if Response_File_Switches'Length /= 0 then for J in Response_File_Switches'First .. Response_File_Switches'Last - 1 loop Add_Arg (Response_File_Switches (J)); end loop; Add_Arg (new String' (Response_File_Switches (Response_File_Switches'Last).all & Get_Name_String (Response_File_Name))); else Add_Arg (new String'(Get_Name_String (Response_File_Name))); end if; -- Put back the options for J in Options'Range loop Add_Arg (Options (J)); end loop; end if; end; Display_Linking_Command; end if; -- Finally spawn the library builder driver Spawn (Driver.all, Arguments (1 .. Last_Arg), Success); -- Delete response file, if any, except when asked not to if Response_File_Name /= No_Path and then Delete_Response_File then declare Dont_Care : Boolean; pragma Warnings (Off, Dont_Care); begin Delete_File (Get_Name_String (Response_File_Name), Dont_Care); if Response_2 /= No_Path then Delete_File (Get_Name_String (Response_2), Dont_Care); end if; end; end if; if not Success then if Driver_Name = No_Name then Osint.Fail (Gcc_Name & " execution error"); else Osint.Fail (Get_Name_String (Driver_Name) & " execution error"); end if; end if; end Build; -- Start of processing for Build_Shared_Lib begin if Opt.Verbose_Mode then Write_Str ("building relocatable shared library "); Write_Line (Lib_File); end if; if Library_Version.all = "" or else not Symbolic_Link_Supported then -- If no Library_Version specified, make sure the table is empty and -- call Build. Library_Version_Options.Set_Last (0); Build (Lib_Path); else -- Put the necessary options corresponding to the Library_Version in the -- table. if Major_Minor_Id_Supported then Maj_Version := new String'(Major_Id_Name (Lib_File, Library_Version.all)); end if; if Library_Version_Options.Last > 0 then if Maj_Version.all /= "" then Library_Version_Options.Table (Library_Version_Options.Last) := new String' (Library_Version_Options.Table (Library_Version_Options.Last).all & Maj_Version.all); else Library_Version_Options.Table (Library_Version_Options.Last) := new String' (Library_Version_Options.Table (Library_Version_Options.Last).all & Library_Version.all); end if; end if; if Is_Absolute_Path (Library_Version.all) then Library_Version_Path := Library_Version; else Library_Version_Path := new String' (Library_Directory.all & Library_Version.all); end if; -- Now that the table has been filled, call Build Build (Library_Version_Path.all); -- Create symbolic link, if appropriate if Library_Version.all /= Lib_Path then Create_Sym_Links (Lib_Path, Library_Version.all, Library_Directory.all, Maj_Version.all); end if; end if; end Build_Shared_Lib; gprbuild-gpl-2014-src/src/gprexch.ads0000644000076700001450000001046612323721731017062 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R E X C H -- -- -- -- S p e c -- -- -- -- Copyright (C) 2006-2013, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- These package defines sections and the corresponding labels for exchange -- files between gprmake and gprbind (binding exchange files) and gprlib -- (library exchange files). -- All labels start with '[' and end with ']' package Gprexch is -- Binding exchange file sections type Binding_Section is (No_Binding_Section, Quiet, Verbose, Shared_Libs, Main_Base_Name, Mapping_File, Compiler_Path, Compiler_Leading_Switches, Compiler_Trailing_Switches, Main_Dependency_File, Dependency_Files, Binding_Options, Generated_Object_File, Bound_Object_Files, Generated_Source_Files, Resulting_Options, Run_Path_Option, Project_Files, Toolchain_Version, Delete_Temp_Files, Object_File_Suffix, There_Are_Stand_Alone_Libraries); function Binding_Label (Section : Binding_Section) return String; -- Return the label for a section in a binder exchange file function Get_Binding_Section (Label : String) return Binding_Section; -- Get the current section from a label in a binding exchange file -- Library exchange file sections type Library_Section is (No_Library_Section, No_Create, No_Copy_ALI, Quiet, Verbose, Relocatable, Static, Object_Files, Options, Object_Directory, Library_Name, Library_Directory, Library_Dependency_Directory, Library_Version, Library_Options, Library_Rpath_Options, Library_Path, Library_Version_Options, Shared_Lib_Prefix, Shared_Lib_Suffix, Shared_Lib_Minimum_Options, Symbolic_Link_Supported, Major_Minor_Id_Supported, PIC_Option, Imported_Libraries, Runtime_Library_Dir, Driver_Name, Compilers, Compiler_Leading_Switches, Compiler_Trailing_Switches, Toolchain_Version, Archive_Builder, Archive_Builder_Append_Option, Archive_Indexer, Partial_Linker, Archive_Suffix, Run_Path_Option, Separate_Run_Path_Options, Install_Name, Auto_Init, Interface_Dep_Files, Other_Interfaces, Standalone_Mode, Dependency_Files, Binding_Options, Leading_Library_Options, Copy_Source_Dir, Sources, Generated_Object_Files, Generated_Source_Files, Max_Command_Line_Length, Response_File_Format, Response_File_Switches, Keep_Response_File); function Library_Label (Section : Library_Section) return String; -- Return the label for a section in a library exchange file function Get_Library_Section (Label : String) return Library_Section; -- Get the current section from a label in a library exchange file end Gprexch; gprbuild-gpl-2014-src/src/gpr_util-knowledge.adb0000644000076700001450000000554312323721731021203 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R _ U T I L . K N O W L E D G E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2010-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with GprConfig.Knowledge; use GprConfig.Knowledge; with GprConfig.Sdefault; use GprConfig.Sdefault; separate (Gpr_Util) package body Knowledge is Base : Knowledge_Base; ------------------------- -- Normalized_Hostname -- ------------------------- function Normalized_Hostname return String is Id : Targets_Set_Id; begin Get_Targets_Set (Base, Hostname, Id); return Normalized_Target (Base, Id); end Normalized_Hostname; -------------------------- -- Parse_Knowledge_Base -- -------------------------- procedure Parse_Knowledge_Base (Project_Tree : Project_Tree_Ref; Directory : String := "") is function Dir return String; -- Returns Directory or if empty Default_Knowledge_Base_Directory pragma Inline (Dir); --------- -- Dir -- --------- function Dir return String is begin if Directory'Length = 0 then return Default_Knowledge_Base_Directory; else return Directory; end if; end Dir; begin Parse_Knowledge_Base (Base, Dir, Parse_Compiler_Info => False); exception when Invalid_Knowledge_Base => Fail_Program (Project_Tree, "could not parse the XML files in " & Dir); end Parse_Knowledge_Base; end Knowledge; gprbuild-gpl-2014-src/src/gprbuild-post_compile.ads0000644000076700001450000000346312323721731021724 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . P O S T _ C O M P I L E -- -- -- -- S p e c -- -- -- -- Copyright (C) 2011-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package Gprbuild.Post_Compile is procedure Run; -- Build libraries, if needed, and perform binding, if needed. -- This is either for a specific project tree, or for the root project and -- all its aggregated projects. end Gprbuild.Post_Compile; gprbuild-gpl-2014-src/src/gprbuild-compilation.ads0000644000076700001450000000665712323721731021555 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N -- -- -- -- S p e c -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This is the root package for the compilation support. It handles the local -- and distributed compilation modes. with Ada.Characters.Latin_1; private with Ada.Containers.Indefinite_Vectors; with Ada.Containers.Vectors; with Ada.Strings.Unbounded; package Gprbuild.Compilation is Default_Port : constant := 8484; Opts_Sep : constant Character := Ada.Characters.Latin_1.HT; -- Command options separator, that is the separator used for options to be -- passed to the executed command. -- A simple concurrent counter type protected type Shared_Counter is function Count return Natural; -- Returns the current counter value procedure Increment; -- Increment by one procedure Decrement; -- Decrement by one procedure Reset; -- Reset counter to 0 entry Wait_Non_Zero; -- Returns when the counter is above zero private Counter : Natural := 0; end Shared_Counter; procedure Set_Env (Env : String; Fail : Boolean; Force : Boolean := False); -- Set environemnt given an Env variable containing a set of name=value -- separated with Opts_Sep. -- -- name=value[name=value] -- -- If Fail is true the program will exit if the a format error is detected. -- If Force is set to True the environement will always be set otherwise it -- will be set only if not already set. -- The set of files for a given project (associated with a synchronization -- job). type File_Data is record Path_Name : Ada.Strings.Unbounded.Unbounded_String; Timestamp : Time_Stamp_Type; -- YYYYMMDDhhmmss Prev : Time_Stamp_Type; end record; package File_Data_Set is new Ada.Containers.Vectors (Positive, File_Data); private package Str_Vect is new Ada.Containers.Indefinite_Vectors (Positive, String); end Gprbuild.Compilation; gprbuild-gpl-2014-src/src/gprinstall-install.ads0000644000076700001450000000345412323721731021244 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Prj; package Gprinstall.Install is use Prj; procedure Process (Tree : Project_Tree_Ref; Project : Project_Id); -- Install Project and possibly all imported projects depending on the -- options. end Gprinstall.Install; gprbuild-gpl-2014-src/src/gprbind.adb0000644000076700001450000013722512323721731017031 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B I N D -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- gprbind is the executable called by gprmake to bind Ada sources. It is -- the driver for gnatbind. It gets its input from gprmake through the -- binding exchange file and gives back its results through the same file. with Ada.Directories; with Ada.Text_IO; use Ada.Text_IO; with Ada.Command_Line; use Ada.Command_Line; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.OS_Lib; use GNAT.OS_Lib; with ALI; use ALI; with Gprexch; use Gprexch; with Gpr_Util; use Gpr_Util; with Hostparm; with Makeutl; use Makeutl; with Namet; use Namet; with Osint; with Switch; with Tempdir; with Table; with Types; procedure Gprbind is Shared_Libgcc_Default : Character; for Shared_Libgcc_Default'Size use Character'Size; pragma Import (C, Shared_Libgcc_Default, "__gnat_shared_libgcc_default"); Preserve : Attribute := Time_Stamps; -- Used in calls to Copy_File. Changed to None for OpenVMS, because -- Copy_Attributes always fails on VMS. Executable_Suffix : constant String_Access := Get_Executable_Suffix; -- The suffix of executables on this platforms GNATBIND : String_Access := new String'("gnatbind"); -- The file name of the gnatbind executable. May be modified by an option -- in the Minimum_Binder_Options. Gnatbind_Prefix_Equal : constant String := "gnatbind_prefix="; -- Start of the option to specify a prefix for the gnatbind executable Gnatbind_Path_Equal : constant String := "--gnatbind_path="; -- Start of the option to specify the absolute path of gnatbind Ada_Binder_Equal : constant String := "ada_binder="; -- Start of the option to specify the full name of the Ada binder -- executable. Introduced for GNAAMP, where it is gnaambind. Quiet_Output : Boolean := False; Verbose_Mode : Boolean := False; Dash_O_Specified : Boolean := False; Dash_O_File_Specified : Boolean := False; There_Are_Stand_Alone_Libraries : Boolean := False; -- Set to True if the corresponding label is in the exchange file No_Main_Option : constant String := "-n"; Dash_o : constant String := "-o"; Dash_shared : constant String := "-shared"; Dash_x : constant String := "-x"; Dash_Fequal : constant String := "-F="; Dash_OO : constant String := "-O"; -- Minimum switches to be used to compile the binder generated file Dash_c : constant String := "-c"; Dash_gnatA : constant String := "-gnatA"; Dash_gnatWb : constant String := "-gnatWb"; Dash_gnatiw : constant String := "-gnatiw"; Dash_gnatws : constant String := "-gnatws"; GCC_Version : Character := '0'; Gcc_Version_String : constant String := "gcc version "; Shared_Libgcc : constant String := "-shared-libgcc"; Static_Libgcc : constant String := "-static-libgcc"; IO_File : File_Type; -- The file to get the inputs and to put the results of the binding Line : String (1 .. 1_000); Last : Natural; Exchange_File_Name : String_Access; Ada_Compiler_Path : String_Access; FULL_GNATBIND : String_Access; Gnatbind_Path : String_Access; Gnatbind_Path_Specified : Boolean := False; Compiler_Options : String_List_Access := new String_List (1 .. 100); Last_Compiler_Option : Natural := 0; Compiler_Trailing_Options : String_List_Access := new String_List (1 .. 10); Last_Compiler_Trailing_Option : Natural := 0; Gnatbind_Options : String_List_Access := new String_List (1 .. 100); Last_Gnatbind_Option : Natural := 0; Main_ALI : String_Access := null; Main_Base_Name : String_Access := null; Binder_Generated_File : String_Access := null; BG_File : File_Type; Mapping_File : String_Access := null; Success : Boolean := False; Return_Code : Integer; Adalib_Dir : String_Access; Prefix_Path : String_Access; Lib_Path : String_Access; Static_Libs : Boolean := True; Current_Section : Binding_Section := No_Binding_Section; All_Binding_Options : Boolean; Get_Option : Boolean; Xlinker_Seen : Boolean; Stack_Equal_Seen : Boolean; GNAT_Version : String_Access := new String'("000"); -- The version of GNAT, coming from the Toolchain_Version for Ada GNAT_Version_Set : Boolean := False; -- True when the toolchain version is in the input exchange file Delete_Temp_Files : Boolean := True; FD_Objects : File_Descriptor; Objects_Path : Path_Name_Type; Objects_File : File_Type; Ada_Object_Suffix : String_Access := Get_Object_Suffix; Display_Line : String_Access := new String (1 .. 1_000); Display_Last : Natural := 0; -- A String buffer to store temporarily the displayed gnatbind command -- invoked by gprbind. procedure Add_To_Display_Line (S : String); -- Add an argument to the Display_Line package Binding_Options_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprbind.Binding_Options_Table"); Binding_Option_Dash_V_Specified : Boolean := False; -- Set to True if -v is specified in the binding options GNAT_6_Or_Higher : Boolean := False; -- Set to True when GNAT version is neither 3.xx nor 5.xx GNAT_6_4_Or_Higher : Boolean := False; -- Set to True when GNAT_6_Or_Higher is True and if GNAT version is 6.xy -- with x >= 4. package ALI_Files_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprbind.ALI_File_Table"); type Path_And_Stamp is record Path : String_Access; Stamp : String_Access; end record; package Project_Paths is new Table.Table (Table_Component_Type => Path_And_Stamp, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprbind.Project_Paths"); type Bound_File; type Bound_File_Access is access Bound_File; type Bound_File is record Name : String_Access; Next : Bound_File_Access; end record; Bound_Files : Bound_File_Access; ------------------------- -- Add_To_Display_Line -- ------------------------- procedure Add_To_Display_Line (S : String) is begin while Display_Last + 1 + S'Length > Display_Line'Last loop declare New_Buffer : constant String_Access := new String (1 .. 2 * Display_Line'Length); begin New_Buffer (1 .. Display_Last) := Display_Line (1 .. Display_Last); Free (Display_Line); Display_Line := New_Buffer; end; end loop; if Display_Last > 0 then Display_Last := Display_Last + 1; Display_Line (Display_Last) := ' '; end if; Display_Line (Display_Last + 1 .. Display_Last + S'Length) := S; Display_Last := Display_Last + S'Length; end Add_To_Display_Line; begin if Argument_Count /= 1 then Osint.Fail ("incorrect invocation"); end if; Namet.Initialize; -- Copy_Attributes always fails on VMS if Hostparm.OpenVMS then Preserve := None; end if; Exchange_File_Name := new String'(Argument (1)); -- DEBUG: save a copy of the exchange file declare Gprbind_Debug : constant String := Getenv ("GPRBIND_DEBUG").all; begin if Gprbind_Debug = "TRUE" then Copy_File (Exchange_File_Name.all, Exchange_File_Name.all & "__saved", Success, Mode => Overwrite, Preserve => Preserve); end if; end; -- Open the binding exchange file begin Open (IO_File, In_File, Exchange_File_Name.all); exception when others => Osint.Fail ("could not read " & Exchange_File_Name.all); end; -- Get the information from the binding exchange file while not End_Of_File (IO_File) loop Get_Line (IO_File, Line, Last); if Last > 0 then if Line (1) = '[' then Current_Section := Get_Binding_Section (Line (1 .. Last)); case Current_Section is when No_Binding_Section => Osint.Fail ("unknown section: " & Line (1 .. Last)); when Quiet => Quiet_Output := True; Verbose_Mode := False; when Verbose => Quiet_Output := False; Verbose_Mode := True; when Shared_Libs => Static_Libs := False; when Gprexch.There_Are_Stand_Alone_Libraries => There_Are_Stand_Alone_Libraries := True; when others => null; end case; else case Current_Section is when No_Binding_Section => Osint.Fail ("no section specified: " & Line (1 .. Last)); when Quiet => Osint.Fail ("quiet section should be empty"); when Verbose => Osint.Fail ("verbose section should be empty"); when Shared_Libs => Osint.Fail ("shared libs section should be empty"); when Gprexch.There_Are_Stand_Alone_Libraries => Osint.Fail ("stand-alone libraries section should be empty"); when Gprexch.Main_Base_Name => if Main_Base_Name /= null then Osint.Fail ("main base name specified multiple times"); end if; Main_Base_Name := new String'(Line (1 .. Last)); when Gprexch.Mapping_File => Mapping_File := new String'(Line (1 .. Last)); when Compiler_Path => if Ada_Compiler_Path /= null then Osint.Fail ("compiler path specified multiple times"); end if; Ada_Compiler_Path := new String'(Line (1 .. Last)); when Compiler_Leading_Switches => Add (Line (1 .. Last), Compiler_Options, Last_Compiler_Option); when Compiler_Trailing_Switches => Add (Line (1 .. Last), Compiler_Trailing_Options, Last_Compiler_Trailing_Option); when Main_Dependency_File => if Main_ALI /= null then Osint.Fail ("main ALI file specified multiple times"); end if; Main_ALI := new String'(Line (1 .. Last)); when Dependency_Files => ALI_Files_Table.Append (new String'(Line (1 .. Last))); when Binding_Options => -- Check if a gnatbind absolute is specified if Last > Gnatbind_Path_Equal'Length and then Line (1 .. Gnatbind_Path_Equal'Length) = Gnatbind_Path_Equal then Gnatbind_Path := new String' (Line (Gnatbind_Path_Equal'Length + 1 .. Last)); Gnatbind_Path_Specified := True; -- Check if a gnatbind prefix is specified elsif Last >= Gnatbind_Prefix_Equal'Length and then Line (1 .. Gnatbind_Prefix_Equal'Length) = Gnatbind_Prefix_Equal then -- Ignore an empty prefix if Last > Gnatbind_Prefix_Equal'Length then -- There is always a '-' between and -- "gnatbind". Add one if not already in . if Line (Last) /= '-' then Last := Last + 1; Line (Last) := '-'; end if; GNATBIND := new String' (Line (Gnatbind_Prefix_Equal'Length + 1 .. Last) & "gnatbind"); end if; elsif Last > Ada_Binder_Equal'Length and then Line (1 .. Ada_Binder_Equal'Length) = Ada_Binder_Equal then GNATBIND := new String' (Line (Ada_Binder_Equal'Length + 1 .. Last)); -- When -O is used, instead of -O=file, -v is ignored to -- avoid polluting the output. Record occurence of -v and -- check the GNAT version later. elsif Line (1 .. Last) = "-v" then Binding_Option_Dash_V_Specified := True; -- Ignore -C, as the generated sources are always in Ada elsif Line (1 .. Last) /= "-C" then Binding_Options_Table.Append (new String'(Line (1 .. Last))); end if; when Project_Files => if End_Of_File (IO_File) then Osint.Fail ("no time stamp for " & Line (1 .. Last)); else declare PS : Path_And_Stamp; begin PS.Path := new String'(Line (1 .. Last)); Get_Line (IO_File, Line, Last); PS.Stamp := new String'(Line (1 .. Last)); Project_Paths.Append (PS); end; end if; when Gprexch.Toolchain_Version => if End_Of_File (IO_File) then Osint.Fail ("no toolchain version for language " & Line (1 .. Last)); elsif Line (1 .. Last) = "ada" then Get_Line (IO_File, Line, Last); if Last > 5 and then Line (1 .. 5) = "GNAT " then GNAT_Version := new String'(Line (6 .. Last)); GNAT_Version_Set := True; end if; else Skip_Line (IO_File); end if; when Gprexch.Delete_Temp_Files => begin Delete_Temp_Files := Boolean'Value (Line (1 .. Last)); exception when Constraint_Error => null; end; when Gprexch.Object_File_Suffix => if End_Of_File (IO_File) then Osint.Fail ("no object file suffix for language " & Line (1 .. Last)); elsif Line (1 .. Last) = "ada" then Get_Line (IO_File, Line, Last); Ada_Object_Suffix := new String'(Line (1 .. Last)); else Skip_Line (IO_File); end if; when Generated_Object_File | Generated_Source_Files | Bound_Object_Files | Resulting_Options | Run_Path_Option => null; end case; end if; end if; end loop; if Main_Base_Name = null then Osint.Fail ("no main base name specified"); else Binder_Generated_File := new String'("b__" & Main_Base_Name.all & ".adb"); end if; Close (IO_File); -- Modify binding option -A= if is not an absolute path if Project_Paths.Last >= 1 then declare Project_Dir : constant String := Ada.Directories.Containing_Directory (Project_Paths.Table (1).Path.all); begin for J in 1 .. Binding_Options_Table.Last loop if Binding_Options_Table.Table (J)'Length >= 4 and then Binding_Options_Table.Table (J) (1 .. 3) = "-A=" then declare File : constant String := Binding_Options_Table.Table (J) (4 .. Binding_Options_Table.Table (J)'Length); begin if not Is_Absolute_Path (File) then declare New_File : constant String := Normalize_Pathname (File, Project_Dir); begin Binding_Options_Table.Table (J) := new String'("-A=" & New_File); end; end if; end; end if; end loop; end; end if; -- Check if GNAT version is 6.4 or higher if GNAT_Version_Set and then GNAT_Version'Length > 2 and then GNAT_Version.all /= "000" and then GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) /= "3." and then GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) /= "5." then GNAT_6_Or_Higher := True; if GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) /= "6." or else GNAT_Version.all >= "6.4" then GNAT_6_4_Or_Higher := True; end if; end if; -- Check if binding option -v was specified and issue it only if the GNAT -- version is 6.4 or higher, otherwise the output of gnatbind -O will be -- polluted. if Binding_Option_Dash_V_Specified and then GNAT_6_4_Or_Higher then Binding_Options_Table.Append (new String'("-v")); end if; if not Static_Libs then Add (Dash_shared, Gnatbind_Options, Last_Gnatbind_Option); end if; -- Specify the name of the generated file to gnatbind Add (Dash_o, Gnatbind_Options, Last_Gnatbind_Option); Add (Binder_Generated_File.all, Gnatbind_Options, Last_Gnatbind_Option); if not Is_Regular_File (Ada_Compiler_Path.all) then Osint.Fail ("could not find the Ada compiler"); end if; if Main_ALI /= null then Add (Main_ALI.all, Gnatbind_Options, Last_Gnatbind_Option); end if; -- If there are Stand-Alone Libraries, invoke gnatbind with -F (generate -- checks of elaboration flags) to avoid multiple elaborations. if There_Are_Stand_Alone_Libraries and then GNAT_Version_Set and then GNAT_Version'Length > 2 and then GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) /= "3." then Add ("-F", Gnatbind_Options, Last_Gnatbind_Option); end if; for J in 1 .. ALI_Files_Table.Last loop Add (ALI_Files_Table.Table (J), Gnatbind_Options, Last_Gnatbind_Option); end loop; for J in 1 .. Binding_Options_Table.Last loop Add (Binding_Options_Table.Table (J), Gnatbind_Options, Last_Gnatbind_Option); if Binding_Options_Table.Table (J).all = Dash_OO then Dash_O_Specified := True; elsif Binding_Options_Table.Table (J)'Length >= 4 and then Binding_Options_Table.Table (J) (1 .. 3) = Dash_OO & '=' then Dash_O_Specified := True; Dash_O_File_Specified := True; Name_Len := 0; Add_Str_To_Name_Buffer (Binding_Options_Table.Table (J) (4 .. Binding_Options_Table.Table (J)'Last)); Objects_Path := Name_Find; end if; end loop; -- Add -x at the end, so that if -s is specified in the binding options, -- gnatbind does not try to look for sources, as the binder mapping file -- specified by -F- is not for sources, but for ALI files. Add (Dash_x, Gnatbind_Options, Last_Gnatbind_Option); if Ada_Compiler_Path = null or else Is_Absolute_Path (GNATBIND.all) then FULL_GNATBIND := GNATBIND; else FULL_GNATBIND := new String' (Dir_Name (Ada_Compiler_Path.all) & Directory_Separator & GNATBIND.all); end if; if Gnatbind_Path_Specified then FULL_GNATBIND := Gnatbind_Path; end if; Gnatbind_Path := Locate_Exec_On_Path (FULL_GNATBIND.all); -- If gnatbind is not found and its full path was not specified, check for -- gnatbind on the path. if Gnatbind_Path = null and then not Gnatbind_Path_Specified then Gnatbind_Path := Locate_Exec_On_Path (GNATBIND.all); end if; if Gnatbind_Path = null then -- Make sure Namelen has a non negative value Name_Len := 0; if Gnatbind_Path_Specified then Osint.Fail ("could not locate " & FULL_GNATBIND.all); else Osint.Fail ("could not locate " & GNATBIND.all); end if; else -- Normalize the path, so that gnaampbind does not complain about not -- being in a "bin" directory. But don't resolve symbolic links, -- because in GNAT 5.01a1 and previous releases, gnatbind was a symbolic -- link for .gnat_wrapper. Gnatbind_Path := new String' (Normalize_Pathname (Gnatbind_Path.all, Resolve_Links => False)); end if; if Main_ALI = null then Add (No_Main_Option, Gnatbind_Options, Last_Gnatbind_Option); end if; -- Add the switch -F= if the mapping file was specified -- and the version of GNAT is recent enough. if Mapping_File /= null and then GNAT_Version_Set and then GNAT_Version'Length > 2 and then GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) /= "3." then Add (Dash_Fequal & Mapping_File.all, Gnatbind_Options, Last_Gnatbind_Option); end if; -- Create temporary file to get the list of objects if not Dash_O_File_Specified then Tempdir.Create_Temp_File (FD_Objects, Objects_Path); end if; if GNAT_6_4_Or_Higher then if not Dash_O_File_Specified then Add (Dash_OO & "=" & Get_Name_String (Objects_Path), Gnatbind_Options, Last_Gnatbind_Option); Close (FD_Objects); end if; elsif not Dash_O_Specified then Add (Dash_OO, Gnatbind_Options, Last_Gnatbind_Option); end if; if not Quiet_Output then Display_Last := 0; if Verbose_Mode then Add_To_Display_Line (Gnatbind_Path.all); else Add_To_Display_Line (Base_Name (GNATBIND.all)); end if; if Verbose_Mode then for Option in 1 .. Last_Gnatbind_Option loop Add_To_Display_Line (Gnatbind_Options (Option).all); end loop; else if Main_ALI /= null then Add_To_Display_Line (Base_Name (Main_ALI.all)); if ALI_Files_Table.Last > 0 then Add_To_Display_Line ("..."); end if; elsif ALI_Files_Table.Last > 0 then Add_To_Display_Line (Base_Name (ALI_Files_Table.Table (1).all)); if ALI_Files_Table.Last > 1 then Add_To_Display_Line ("..."); end if; Add_To_Display_Line (No_Main_Option); end if; end if; Put_Line (Display_Line (1 .. Display_Last)); end if; declare Size : Natural := 0; begin for J in 1 .. Last_Gnatbind_Option loop Size := Size + Gnatbind_Options (J)'Length + 1; end loop; -- Invoke gnatbind with the arguments if the size is not too large or -- if the version of GNAT is not recent enough. if not GNAT_6_Or_Higher or else Size <= Maximum_Size then if not GNAT_6_4_Or_Higher then Spawn (Gnatbind_Path.all, Gnatbind_Options (1 .. Last_Gnatbind_Option), FD_Objects, Return_Code, Err_To_Out => False); Success := Return_Code = 0; else Return_Code := Spawn (Gnatbind_Path.all, Gnatbind_Options (1 .. Last_Gnatbind_Option)); end if; else -- Otherwise create a temporary response file declare FD : File_Descriptor; Path : Path_Name_Type; Args : Argument_List (1 .. 1); EOL : constant String (1 .. 1) := (1 => ASCII.LF); Status : Integer; Quotes_Needed : Boolean; Last_Char : Natural; Ch : Character; begin Tempdir.Create_Temp_File (FD, Path); Args (1) := new String'("@" & Get_Name_String (Path)); for J in 1 .. Last_Gnatbind_Option loop -- Check if the argument should be quoted Quotes_Needed := False; Last_Char := Gnatbind_Options (J)'Length; for K in Gnatbind_Options (J)'Range loop Ch := Gnatbind_Options (J) (K); if Ch = ' ' or else Ch = ASCII.HT or else Ch = '"' then Quotes_Needed := True; exit; end if; end loop; if Quotes_Needed then -- Quote the argument, doubling '"' declare Arg : String (1 .. Gnatbind_Options (J)'Length * 2 + 2); begin Arg (1) := '"'; Last_Char := 1; for K in Gnatbind_Options (J)'Range loop Ch := Gnatbind_Options (J) (K); Last_Char := Last_Char + 1; Arg (Last_Char) := Ch; if Ch = '"' then Last_Char := Last_Char + 1; Arg (Last_Char) := '"'; end if; end loop; Last_Char := Last_Char + 1; Arg (Last_Char) := '"'; Status := Write (FD, Arg'Address, Last_Char); end; else Status := Write (FD, Gnatbind_Options (J) (Gnatbind_Options (J)'First)'Address, Last_Char); end if; if Status /= Last_Char then Osint.Fail ("disk full"); end if; Status := Write (FD, EOL (1)'Address, 1); if Status /= 1 then Osint.Fail ("disk full"); end if; end loop; Close (FD); -- And invoke gnatbind with this this response file if not GNAT_6_4_Or_Higher then Spawn (Gnatbind_Path.all, Args, FD_Objects, Return_Code, Err_To_Out => False); else Return_Code := Spawn (Gnatbind_Path.all, Args); end if; if Delete_Temp_Files then declare Succ : Boolean; pragma Warnings (Off, Succ); begin Delete_File (Get_Name_String (Path), Succ); end; end if; end; end if; end; if not GNAT_6_4_Or_Higher and then not Dash_O_File_Specified then Close (FD_Objects); end if; if Return_Code /= 0 then if Delete_Temp_Files and not Dash_O_File_Specified then Delete_File (Get_Name_String (Objects_Path), Success); end if; Osint.Fail ("invocation of gnatbind failed"); end if; Add (Dash_c, Compiler_Options, Last_Compiler_Option); Add (Dash_gnatA, Compiler_Options, Last_Compiler_Option); Add (Dash_gnatWb, Compiler_Options, Last_Compiler_Option); Add (Dash_gnatiw, Compiler_Options, Last_Compiler_Option); Add (Dash_gnatws, Compiler_Options, Last_Compiler_Option); -- Read the ALI file of the first ALI file. Fetch the back end switches -- from this ALI file and use these switches to compile the binder -- generated file. if Main_ALI /= null or else ALI_Files_Table.Last >= 1 then Initialize_ALI; Name_Len := 0; if Main_ALI /= null then Add_Str_To_Name_Buffer (Main_ALI.all); else Add_Str_To_Name_Buffer (ALI_Files_Table.Table (1).all); end if; declare use Types; F : constant File_Name_Type := Name_Find; T : Text_Buffer_Ptr; A : ALI_Id; begin -- Load the ALI file T := Osint.Read_Library_Info (F, True); -- Read it. Note that we ignore errors, since we only want very -- limited information from the ali file, and likely a slightly -- wrong version will be just fine, though in normal operation -- we don't expect this to happen. A := Scan_ALI (F, T, Ignore_ED => False, Err => False, Ignore_Errors => True, Read_Lines => "A"); if A /= No_ALI_Id then for Index in Units.Table (ALIs.Table (A).First_Unit).First_Arg .. Units.Table (ALIs.Table (A).First_Unit).Last_Arg loop -- Do not compile with the front end switches. However, --RTS -- is to be dealt with specially because the binder-generated -- file need to compiled with the same switch. declare Arg : String_Ptr renames Args.Table (Index); begin if (not Switch.Is_Front_End_Switch (Arg.all)) or else (Arg'Length > 5 and then Arg (Arg'First + 2 .. Arg'First + 5) = "RTS=") then Add (String_Access (Arg), Compiler_Options, Last_Compiler_Option); end if; end; end loop; end if; end; end if; Add (Binder_Generated_File, Compiler_Options, Last_Compiler_Option); declare Object : constant String := "b__" & Main_Base_Name.all & Ada_Object_Suffix.all; begin Add (Dash_o, Compiler_Options, Last_Compiler_Option); Add (Object, Compiler_Options, Last_Compiler_Option); if not Quiet_Output then Name_Len := 0; if Verbose_Mode then Add_Str_To_Name_Buffer (Ada_Compiler_Path.all); else Add_Str_To_Name_Buffer (Base_Name (Ada_Compiler_Path.all)); end if; -- Remove the executable suffix, if present if Executable_Suffix'Length > 0 and then Name_Len > Executable_Suffix'Length and then Name_Buffer (Name_Len - Executable_Suffix'Length + 1 .. Name_Len) = Executable_Suffix.all then Name_Len := Name_Len - Executable_Suffix'Length; end if; Display_Last := 0; Add_To_Display_Line (Name_Buffer (1 .. Name_Len)); if Verbose_Mode then for Option in 1 .. Last_Compiler_Option loop Add_To_Display_Line (Compiler_Options (Option).all); end loop; else Add_To_Display_Line (Compiler_Options (1).all); if Compiler_Options (1) /= Binder_Generated_File then Add_To_Display_Line (Binder_Generated_File.all); end if; end if; Put_Line (Display_Line (1 .. Display_Last)); end if; -- Add the trailing options, if any for J in 1 .. Last_Compiler_Trailing_Option loop Add (Compiler_Trailing_Options (J), Compiler_Options, Last_Compiler_Option); end loop; Spawn (Ada_Compiler_Path.all, Compiler_Options (1 .. Last_Compiler_Option), Success); if not Success then Osint.Fail ("compilation of binder generated file failed"); end if; -- Find the GCC version Spawn (Program_Name => Ada_Compiler_Path.all, Args => (1 => new String'("-v")), Output_File => Exchange_File_Name.all, Success => Success, Return_Code => Return_Code, Err_To_Out => True); if Success then Open (IO_File, In_File, Exchange_File_Name.all); while not End_Of_File (IO_File) loop Get_Line (IO_File, Line, Last); if Last > Gcc_Version_String'Length and then Line (1 .. Gcc_Version_String'Length) = Gcc_Version_String then GCC_Version := Line (Gcc_Version_String'Length + 1); exit; end if; end loop; Close (IO_File); end if; Create (IO_File, Out_File, Exchange_File_Name.all); -- First, the generated object file Put_Line (IO_File, Binding_Label (Generated_Object_File)); Put_Line (IO_File, Object); -- Repeat the project paths with their time stamps Put_Line (IO_File, Binding_Label (Project_Files)); for J in 1 .. Project_Paths.Last loop Put_Line (IO_File, Project_Paths.Table (J).Path.all); Put_Line (IO_File, Project_Paths.Table (J).Stamp.all); end loop; -- Get the bound object files from the Object file Open (Objects_File, In_File, Get_Name_String (Objects_Path)); Put_Line (IO_File, Binding_Label (Bound_Object_Files)); while not End_Of_File (Objects_File) loop Get_Line (Objects_File, Line, Last); -- Only put in the exchange file the path of the object files. -- Output anything else on standard output. if Is_Regular_File (Line (1 .. Last)) then Put_Line (IO_File, Line (1 .. Last)); Bound_Files := new Bound_File' (Name => new String'(Line (1 .. Last)), Next => Bound_Files); if Dash_O_Specified and then not Dash_O_File_Specified then Put_Line (Line (1 .. Last)); end if; elsif not Dash_O_File_Specified then Put_Line (Line (1 .. Last)); end if; end loop; Close (Objects_File); if Delete_Temp_Files and then not Dash_O_File_Specified then Delete_File (Get_Name_String (Objects_Path), Success); end if; -- For the benefit of gprclean, the generated files other than the -- generated object file. Put_Line (IO_File, Binding_Label (Generated_Source_Files)); Put_Line (IO_File, "b__" & Main_Base_Name.all & ".ads"); Put_Line (IO_File, Binder_Generated_File.all); Put_Line (IO_File, "b__" & Main_Base_Name.all & ".ali"); -- Get the options from the binder generated file Open (BG_File, In_File, Binder_Generated_File.all); while not End_Of_File (BG_File) loop Get_Line (BG_File, Line, Last); exit when Line (1 .. Last) = Begin_Info; end loop; if not End_Of_File (BG_File) then Put_Line (IO_File, Binding_Label (Resulting_Options)); All_Binding_Options := False; Xlinker_Seen := False; Stack_Equal_Seen := False; loop Get_Line (BG_File, Line, Last); exit when Line (1 .. Last) = End_Info; Line (1 .. Last - 8) := Line (9 .. Last); Last := Last - 8; if Line (1) = '-' then -- After the first switch, we take all options, because some -- of the options specified in pragma Linker_Options may not -- start with '-'. All_Binding_Options := True; end if; Get_Option := All_Binding_Options or else (Base_Name (Line (1 .. Last)) = "g-trasym.o") or else (Base_Name (Line (1 .. Last)) = "g-trasym.obj"); -- g-trasym is a special case as it is not included in libgnat -- Avoid duplication of object file if Get_Option then declare BF : Bound_File_Access := Bound_Files; begin while BF /= null loop if BF.Name.all = Line (1 .. Last) then Get_Option := False; exit; else BF := BF.Next; end if; end loop; end; end if; if Get_Option then if Line (1 .. Last) = "-Xlinker" then Xlinker_Seen := True; elsif Xlinker_Seen then Xlinker_Seen := False; -- Make sure that only the first switch --stack= is put in -- the exchange file. if Last > 8 and then Line (1 .. 8) = "--stack=" then if not Stack_Equal_Seen then Stack_Equal_Seen := True; Put_Line (IO_File, "-Xlinker"); Put_Line (IO_File, Line (1 .. Last)); end if; else Put_Line (IO_File, "-Xlinker"); Put_Line (IO_File, Line (1 .. Last)); end if; elsif Last > 12 and then Line (1 .. 12) = "-Wl,--stack=" then if not Stack_Equal_Seen then Stack_Equal_Seen := True; Put_Line (IO_File, Line (1 .. Last)); end if; elsif Last >= 3 and then Line (1 .. 2) = "-L" then -- Set Adalib_Dir only if libgnat is found inside. if Is_Regular_File (Line (3 .. Last) & Directory_Separator & "libgnat.a") then Adalib_Dir := new String'(Line (3 .. Last)); if Verbose_Mode then Put_Line ("Adalib_Dir = """ & Adalib_Dir.all & '"'); end if; -- Build the Prefix_Path, where to look for some -- archives: libaddr2line.a, libbfd.a, libgnatmon.a, -- libgnalasup.a and libiberty.a. It contains three -- directories: $(adalib)/.., $(adalib)/../.. and the -- subdirectory "lib" ancestor of $(adalib). declare Dir_Last : Positive; Prev_Dir_Last : Positive; First : Positive; Prev_Dir_First : Positive; Nmb : Natural; begin Name_Len := 0; Add_Str_To_Name_Buffer (Line (3 .. Last)); while Name_Buffer (Name_Len) = Directory_Separator or else Name_Buffer (Name_Len) = '/' loop Name_Len := Name_Len - 1; end loop; while Name_Buffer (Name_Len) /= Directory_Separator and then Name_Buffer (Name_Len) /= '/' loop Name_Len := Name_Len - 1; end loop; while Name_Buffer (Name_Len) = Directory_Separator or else Name_Buffer (Name_Len) = '/' loop Name_Len := Name_Len - 1; end loop; Dir_Last := Name_Len; Nmb := 0; Dir_Loop : loop Prev_Dir_Last := Dir_Last; First := Dir_Last - 1; while First > 3 and then Name_Buffer (First) /= Directory_Separator and then Name_Buffer (First) /= '/' loop First := First - 1; end loop; Prev_Dir_First := First + 1; exit Dir_Loop when First <= 3; Dir_Last := First - 1; while Name_Buffer (Dir_Last) = Directory_Separator or else Name_Buffer (Dir_Last) = '/' loop Dir_Last := Dir_Last - 1; end loop; Nmb := Nmb + 1; if Nmb <= 1 then Add_Char_To_Name_Buffer (Path_Separator); Add_Str_To_Name_Buffer (Name_Buffer (1 .. Dir_Last)); elsif Name_Buffer (Prev_Dir_First .. Prev_Dir_Last) = "lib" then Add_Char_To_Name_Buffer (Path_Separator); Add_Str_To_Name_Buffer (Name_Buffer (1 .. Prev_Dir_Last)); exit Dir_Loop; end if; end loop Dir_Loop; Prefix_Path := new String'(Name_Buffer (1 .. Name_Len)); if Verbose_Mode then Put_Line ("Prefix_Path = """ & Prefix_Path.all & '"'); end if; end; end if; Put_Line (IO_File, Line (1 .. Last)); elsif Line (1 .. Last) = "-static" then Static_Libs := True; Put_Line (IO_File, Line (1 .. Last)); if Shared_Libgcc_Default = 'T' and then GCC_Version >= '3' then Put_Line (IO_File, Static_Libgcc); end if; elsif Line (1 .. Last) = "-shared" then Static_Libs := False; Put_Line (IO_File, Line (1 .. Last)); if GCC_Version >= '3' then Put_Line (IO_File, Shared_Libgcc); end if; -- For a number of archives, we need to indicate the full -- path of the archive, if we find it, to be sure that the -- correct archive is used by the linker. elsif Line (1 .. Last) = "-lgnat" then if Adalib_Dir = null then if Verbose_Mode then Put_Line ("No Adalib_Dir"); end if; Put_Line (IO_File, "-lgnat"); elsif Static_Libs then Put_Line (IO_File, Adalib_Dir.all & "libgnat.a"); else Put_Line (IO_File, "-lgnat"); end if; elsif Line (1 .. Last) = "-lgnarl" and then Static_Libs and then Adalib_Dir /= null then Put_Line (IO_File, Adalib_Dir.all & "libgnarl.a"); elsif Line (1 .. Last) = "-laddr2line" and then Prefix_Path /= null then Lib_Path := Locate_Regular_File ("libaddr2line.a", Prefix_Path.all); if Lib_Path /= null then Put_Line (IO_File, Lib_Path.all); Free (Lib_Path); else Put_Line (IO_File, Line (1 .. Last)); end if; elsif Line (1 .. Last) = "-lbfd" and then Prefix_Path /= null then Lib_Path := Locate_Regular_File ("libbfd.a", Prefix_Path.all); if Lib_Path /= null then Put_Line (IO_File, Lib_Path.all); Free (Lib_Path); else Put_Line (IO_File, Line (1 .. Last)); end if; elsif Line (1 .. Last) = "-lgnalasup" and then Prefix_Path /= null then Lib_Path := Locate_Regular_File ("libgnalasup.a", Prefix_Path.all); if Lib_Path /= null then Put_Line (IO_File, Lib_Path.all); Free (Lib_Path); else Put_Line (IO_File, Line (1 .. Last)); end if; elsif Line (1 .. Last) = "-lgnatmon" and then Prefix_Path /= null then Lib_Path := Locate_Regular_File ("libgnatmon.a", Prefix_Path.all); if Lib_Path /= null then Put_Line (IO_File, Lib_Path.all); Free (Lib_Path); else Put_Line (IO_File, Line (1 .. Last)); end if; elsif Line (1 .. Last) = "-liberty" and then Prefix_Path /= null then Lib_Path := Locate_Regular_File ("libiberty.a", Prefix_Path.all); if Lib_Path /= null then Put_Line (IO_File, Lib_Path.all); Free (Lib_Path); else Put_Line (IO_File, Line (1 .. Last)); end if; else Put_Line (IO_File, Line (1 .. Last)); end if; end if; end loop; end if; Close (BG_File); if not Static_Libs and then Adalib_Dir /= null then Put_Line (IO_File, Binding_Label (Run_Path_Option)); Put_Line (IO_File, Adalib_Dir.all); Name_Len := Adalib_Dir'Length; Name_Buffer (1 .. Name_Len) := Adalib_Dir.all; for J in reverse 2 .. Name_Len - 4 loop if Name_Buffer (J) = Directory_Separator and then Name_Buffer (J + 4) = Directory_Separator and then Name_Buffer (J + 1 .. J + 3) = "lib" then Name_Len := J + 3; Put_Line (IO_File, Name_Buffer (1 .. Name_Len)); exit; end if; end loop; end if; Close (IO_File); end; end Gprbind; gprbuild-gpl-2014-src/src/gprconfig-knowledge.ads0000644000076700001450000005356112323721731021360 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R C O N F I G -- -- -- -- S p e c -- -- -- -- Copyright (C) 2006-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This unit is responsible for parsing the gprconfig knowledge base with Ada.Containers.Doubly_Linked_Lists; with Ada.Containers.Indefinite_Doubly_Linked_Lists; with Ada.Containers.Indefinite_Hashed_Maps; with Ada.Containers.Hashed_Maps; with Ada.Containers.Vectors; with Ada.Strings.Unbounded; with GNAT.Regpat; with Namet; package GprConfig.Knowledge is Generate_Error : exception; -- To be raised when an error occurs during generation of config files -------------------- -- Knowledge base -- -------------------- -- The following types and subprograms manipulate the knowldge base. This -- base is a set of XML files that describe how to find compilers that are -- installed on the system and that match specific criterias. type Knowledge_Base is private; function Default_Knowledge_Base_Directory return String; -- Return the default location of the knowledge database. This is based on -- the installation directory of the executable. procedure Parse_Knowledge_Base (Base : in out Knowledge_Base; Directory : String; Parse_Compiler_Info : Boolean := True; Validate : Boolean := False); -- Parse info from the knowledge base, and store it in memory. -- Only information relevant to the current host is parsed. -- If Parse_Compiler_Info is False, then only the information about -- target sets is parsed. -- This procedure will raise Invalid_Knowledge_Base if the base contains -- incorrect data. -- If Validate is True, the contents of the knowledge base is first -- validated with an XSD schema. Invalid_Knowledge_Base : exception; -- To be raised when an error occurred while parsing the knowledge base Knowledge_Base_Validation_Error : exception; -- Some files in the knowledge base are invalid. ----------------- -- Target sets -- ----------------- -- One of the information pieces contain in the database is a way to -- normalize target names, since various names are used in different -- contexts thus making it harder to write project files depending on the -- target. type Targets_Set_Id is private; -- Identify a target aliases set All_Target_Sets : constant Targets_Set_Id; -- Matches all target sets Unknown_Targets_Set : constant Targets_Set_Id; -- Special target set when a target is not known function Query_Targets_Set (Base : Knowledge_Base; Target : String) return Targets_Set_Id; -- Get the target alias set id for a target, or Unknown_Targets_Set if -- no such target is in the base. procedure Get_Targets_Set (Base : in out Knowledge_Base; Target : String; Id : out Targets_Set_Id); -- Get the target alias set id for a target. If not already in the base, -- add it. function Normalized_Target (Base : Knowledge_Base; Set : Targets_Set_Id) return String; -- Return the normalized name for a target set --------------- -- Compilers -- --------------- -- Most of the information in the database relates to compilers. However, -- you do not have direct access to the generic description that explains -- how to find compilers on the PATH and how to compute their attributes -- (version, runtimes,...) Instead, this package gives you access to the -- list of compilers that were found. The package ensures that all -- information is only computed at most once, to save on system calls and -- provide better performance. type Compiler is private; type Compiler_Access is access all Compiler; function Runtime_Dir_Of (Comp : Compiler_Access) return Namet.Name_Id; -- Return the name of the runtime directory for the compiler. Returns -- No_Name if Comp is null. package Compiler_Lists is new Ada.Containers.Indefinite_Doubly_Linked_Lists (Compiler_Access); -- A list of compilers function Is_Selected (Comp : Compiler) return Boolean; function Target (Comp : Compiler) return Namet.Name_Id; procedure Set_Selection (Compilers : in out Compiler_Lists.List; Cursor : Compiler_Lists.Cursor; Selected : Boolean); procedure Set_Selection (Comp : in out Compiler; Selected : Boolean); -- Toggle the selection status of a compiler in the list. -- This does not check that the selection is consistent though (use -- Is_Supported_Config to do this test) function To_String (Base : Knowledge_Base; Comp : Compiler; As_Config_Arg : Boolean; Show_Target : Boolean := False; Rank_In_List : Integer := -1; Parser_Friendly : Boolean := False) return String; -- Return a string representing the compiler. It is either the --config -- argument (if As_Config_Arg is true) or the string to use in the -- interactive menu otherwise. -- If Rank_In_List is specified, it is written at the beginning of the -- line. -- If Parser_Friendly is set, then the list is displayed in a way that can -- be easily parsed automatically function To_String (Base : Knowledge_Base; Compilers : Compiler_Lists.List; Selected_Only : Boolean; Show_Target : Boolean := False; Parser_Friendly : Boolean := False) return String; -- Return the list of compilers. -- Unselectable compilers are hidden. If Selected_Only is true, then only -- compilers that are currently selected are displayed. -- If Parser_Friendly is set, then the list is displayed in a way that can -- be easily parsed automatically function Display_Before (Comp1, Comp2 : Compiler_Access) return Boolean; -- Whether Comp1 should be displayed before Comp2 when displaying lists of -- compilers. This ensures that similar languages are grouped, among othe -- things. procedure Filter_Compilers_List (Base : Knowledge_Base; Compilers : in out Compiler_Lists.List; For_Target_Set : Targets_Set_Id); -- Based on the currently selected compilers, check which other compilers -- can or cannot be selected by the user. -- This is not the case if the resulting selection in Compilers is not a -- supported config (multiple compilers for the same language, set of -- compilers explicitly marked as unsupported in the knowledge base,...). ------------------ -- Command line -- ------------------ -- This package provides support for manipulating the --config command line -- parameters. The intent is that they have the same form in all the tools -- that support it. The information provides to --config might be partial -- only, and this package provides support for completing it automatically -- based on the knowledge base. procedure Parse_Config_Parameter (Base : Knowledge_Base; Config : String; Compiler : out Compiler_Access; Requires_Compiler : out Boolean); -- Parse the --config parameter, and store the (partial) information -- found in Compiler. -- When a switch matches a language that requires no compiler, -- Requires_Compiler is set to False. -- Raises Invalid_Config if Config is invalid Invalid_Config : exception; -- Raised when the user has specified an invalid --config switch procedure Complete_Command_Line_Compilers (Base : in out Knowledge_Base; On_Target : Targets_Set_Id; Filters : Compiler_Lists.List; Compilers : in out Compiler_Lists.List); -- In batch mode, the --config parameters indicate what compilers should be -- selected. Each of these switch selects the first matching compiler -- available, and all --config switch must match a compiler. -- The information provided by the user does not have to be complete, and -- this procedure completes all missing information like version, runtime, -- and so on. -- In gprconfig, it should only be called in batch mode, since otherwise -- --config only acts as a filter for the compilers that are found through -- the knowledge base. -- Filters is the list specified by the user as --config, and contains -- potentially partial information for each compiler. On output, Compilers -- is completed with the full information for all compilers in Filters. If -- at least one of the compilers in Filters cannot be found, Invalid_Config -- is raised. function Extra_Dirs_From_Filters (Filters : Compiler_Lists.List) return String; -- Compute the list of directories that should be prepended to the PATH -- when searching for compilers. These are all the directories that the -- user has explicitly specified in his filters (aka --config) ----------------------------- -- knowledge base contents -- ----------------------------- function Hash_Case_Insensitive (Name : Namet.Name_Id) return Ada.Containers.Hash_Type; package Variables_Maps is new Ada.Containers.Hashed_Maps (Key_Type => Namet.Name_Id, Element_Type => Namet.Name_Id, Hash => Hash_Case_Insensitive, Equivalent_Keys => Namet."=", "=" => Namet."="); No_Compiler : constant Compiler; -- Describes one of the compilers found on the PATH. -- Path is the directory that contains the compiler executable. -- Path_Order is used for sorting in the interactive menu: it indicates the -- index in $PATH of the directory, so that we can show first the compilers -- that are first in path. -- Any of these compilers can be selected by the user as part of a config. -- However, to prevent incompatibilities, a compiler can be marked as not -- selectable. This will be re-evaluated based on the current selection. -- Complete is set to True if all the information about the compiler was -- computed. It is set to False if the compiler was specified through a -- command line argument --config, and part of the info needs to be -- computed. -- Index_In_List is used for the interactive menu, and is initialized -- automatically. type Compiler_Iterator is abstract tagged null record; -- An iterator that searches for all known compilers in a list of -- directories. Whenever a new compiler is found, the Callback primitive -- operation is called. procedure Callback (Iterator : in out Compiler_Iterator; Base : in out Knowledge_Base; Comp : Compiler; From_Extra_Dir : Boolean; Continue : out Boolean) is abstract; -- Called whenever a new compiler is discovered. -- It might be discovered either in a path added through a --config -- parameter (in which case From_Extra_Dir is True), or in a path specified -- in the environment variable $PATH (in which case it is False). If the -- directory is both in Extra_Dirs and in $PATH, From_Extra_Dir is set to -- False. -- On exit, Continue should be set to False if there is no need to discover -- further compilers (however there will be no possibility to restart the -- search at the same point later on). procedure Foreach_Compiler_In_Path (Iterator : in out Compiler_Iterator; Base : in out Knowledge_Base; On_Target : Targets_Set_Id; Extra_Dirs : String := ""); -- Find all compilers in "Extra_Dirs & $PATH". -- Extra_Dirs should typically be the list of directories found in -- --config command line arguments. -- The only filtering done is the target, for optimization purposes (no -- need to computed all info about the compiler if we know it will not be -- uses anyway). procedure Known_Compiler_Names (Base : Knowledge_Base; List : out Ada.Strings.Unbounded.Unbounded_String); -- Set List to the comma-separated list of known compilers procedure Generate_Configuration (Base : Knowledge_Base; Compilers : Compiler_Lists.List; Output_File : String; Target : String); -- Generate the configuration file for the list of selected compilers package String_Lists is new Ada.Containers.Indefinite_Doubly_Linked_Lists (String); procedure Put_Verbose (Str : String; Indent_Delta : Integer := 0); -- Print Str if verbose mode is activated. -- Indent_Delta will increase the current indentation level for all further -- traces, which is used to highlight nested calls. Only the sign of -- Indent_Delta is taken into account. -- Nothing is printed if Str is the empty string, only the indentation is -- changed function Filter_Match (Base : Knowledge_Base; Comp : Compiler; Filter : Compiler) return Boolean; -- Returns True if Comp match Filter (the latter corresponds to a --config -- command line argument). private type Targets_Set_Id is range -1 .. Natural'Last; All_Target_Sets : constant Targets_Set_Id := -1; Unknown_Targets_Set : constant Targets_Set_Id := 0; type Compiler is record Name : Namet.Name_Id := Namet.No_Name; -- The name of the compiler, as specified in the node of the -- knowledge base. If Compiler represents a filter as defined on through -- --config switch, then name can also be the base name of the -- executable we are looking for. In such a case, it never includes the -- exec suffix (.exe on Windows) Executable : Namet.Name_Id := Namet.No_Name; Target : Namet.Name_Id := Namet.No_Name; Targets_Set : Targets_Set_Id; Path : Namet.Name_Id := Namet.No_Name; Base_Name : Namet.Name_Id := Namet.No_Name; -- Base name of the executable. This does not include the exec suffix Version : Namet.Name_Id := Namet.No_Name; Variables : Variables_Maps.Map; Prefix : Namet.Name_Id := Namet.No_Name; Runtime : Namet.Name_Id := Namet.No_Name; Alt_Runtime : Namet.Name_Id := Namet.No_Name; Runtime_Dir : Namet.Name_Id := Namet.No_Name; Path_Order : Integer; Language_Case : Namet.Name_Id := Namet.No_Name; -- The supported language, with the casing read from the compiler. This -- is for display purposes only Language_LC : Namet.Name_Id := Namet.No_Name; -- The supported language, always lower case Selectable : Boolean := True; Selected : Boolean := False; Complete : Boolean := True; end record; No_Compiler : constant Compiler := (Name => Namet.No_Name, Target => Namet.No_Name, Targets_Set => Unknown_Targets_Set, Executable => Namet.No_Name, Base_Name => Namet.No_Name, Path => Namet.No_Name, Variables => Variables_Maps.Empty_Map, Version => Namet.No_Name, Prefix => Namet.No_Name, Runtime => Namet.No_Name, Alt_Runtime => Namet.No_Name, Runtime_Dir => Namet.No_Name, Language_Case => Namet.No_Name, Language_LC => Namet.No_Name, Selectable => False, Selected => False, Complete => True, Path_Order => 0); type Pattern_Matcher_Access is access all GNAT.Regpat.Pattern_Matcher; type External_Value_Type is (Value_Constant, Value_Shell, Value_Directory, Value_Grep, Value_Nogrep, Value_Filter, Value_Must_Match, Value_Variable, Value_Done); type External_Value_Node (Typ : External_Value_Type := Value_Constant) is record case Typ is when Value_Constant => Value : Namet.Name_Id; when Value_Shell => Command : Namet.Name_Id; when Value_Directory => Directory : Namet.Name_Id; Directory_Group : Integer; Dir_If_Match : Namet.Name_Id; Contents : Pattern_Matcher_Access; when Value_Grep => Regexp_Re : Pattern_Matcher_Access; Group : Natural; when Value_Nogrep => Regexp_No : Pattern_Matcher_Access; when Value_Filter => Filter : Namet.Name_Id; when Value_Must_Match => Must_Match : Namet.Name_Id; when Value_Variable => Var_Name : Namet.Name_Id; when Value_Done => null; end case; end record; package External_Value_Nodes is new Ada.Containers.Doubly_Linked_Lists (External_Value_Node); subtype External_Value is External_Value_Nodes.List; Null_External_Value : constant External_Value := External_Value_Nodes.Empty_List; type Compiler_Description is record Name : Namet.Name_Id := Namet.No_Name; Executable : Namet.Name_Id := Namet.No_Name; Executable_Re : Pattern_Matcher_Access; Prefix_Index : Integer := -1; Target : External_Value; Version : External_Value; Variables : External_Value; Languages : External_Value; Runtimes : External_Value; Default_Runtimes : String_Lists.List; end record; -- Executable_Re is only set if the name of the must be -- taken as a regular expression. package Compiler_Description_Maps is new Ada.Containers.Indefinite_Hashed_Maps (Namet.Name_Id, Compiler_Description, Hash_Case_Insensitive, Namet."="); type Compiler_Filter is record Name : Namet.Name_Id; Version : Namet.Name_Id; Version_Re : Pattern_Matcher_Access; Runtime : Namet.Name_Id; Runtime_Re : Pattern_Matcher_Access; Language_LC : Namet.Name_Id; end record; -- Representation for a node (in ) package Compiler_Filter_Lists is new Ada.Containers.Doubly_Linked_Lists (Compiler_Filter); type Compilers_Filter is record Compiler : Compiler_Filter_Lists.List; Negate : Boolean := False; end record; No_Compilers_Filter : constant Compilers_Filter := (Compiler => Compiler_Filter_Lists.Empty_List, Negate => False); -- a filter, that matches if any of its child -- matches. package Compilers_Filter_Lists is new Ada.Containers.Doubly_Linked_Lists (Compilers_Filter); type Configuration is record Compilers_Filters : Compilers_Filter_Lists.List; Targets_Filters : String_Lists.List; -- these are regexps Negate_Targets : Boolean := False; Config : Namet.Name_Id; Supported : Boolean; -- Whether the combination of compilers is supported end record; package Configuration_Lists is new Ada.Containers.Doubly_Linked_Lists (Configuration); package Target_Lists is new Ada.Containers.Doubly_Linked_Lists (Pattern_Matcher_Access); type Target_Set_Description is record Name : Namet.Name_Id; Patterns : Target_Lists.List; end record; subtype Known_Targets_Set_Id is Targets_Set_Id range 1 .. Targets_Set_Id'Last; -- Known targets set. They are in the base package Targets_Set_Vectors is new Ada.Containers.Vectors (Known_Targets_Set_Id, Target_Set_Description, "="); type Knowledge_Base is record Compilers : Compiler_Description_Maps.Map; No_Compilers : String_Lists.List; Check_Executable_Regexp : Boolean := False; Configurations : Configuration_Lists.List; Targets_Sets : Targets_Set_Vectors.Vector; end record; -- Check_Executable_Regexp is set to True if at least some of the -- executable names are specified as regular expressions. In such a case, -- a slightly slower algorithm is used to search for compilers. -- No_Compilers is the list of languages that require no compiler, and thus -- should not be searched on the PATH. end GprConfig.Knowledge; gprbuild-gpl-2014-src/src/gprlib-build_shared_lib-vms.adb0000644000076700001450000000550712323721731022734 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R L I B . B U I L D _ S H A R E D _ L I B -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with MLib.Tgt; use MLib.Tgt; with MLib.Utl; use MLib.Utl; separate (Gprlib) procedure Build_Shared_Lib is Ofiles : Argument_List (1 .. Object_Files.Last); Options : Argument_List (1 .. Options_Table.Last); begin -- If runtime library directory is indicated, call Specify_Adalib_Dir so -- that function MLib.Libgnat returns it. If we don't know what is the -- runtime library directory, set it to the current directory so that -- MLib.Libgnat does not fail. if Runtime_Library_Dir /= null then Specify_Adalib_Dir (Runtime_Library_Dir.all); else Specify_Adalib_Dir ("."); end if; -- On VMS, use Build_Dynamic_Library to build the library as there is -- specific handling of symbols. for J in Ofiles'Range loop Ofiles (J) := Object_Files.Table (J); end loop; for J in Options'Range loop Options (J) := Options_Table.Table (J); end loop; Build_Dynamic_Library (Ofiles => Ofiles, Options => Options, Interfaces => MLib.No_Argument_List, Lib_Filename => Library_Name.all, Lib_Dir => Library_Directory.all, Symbol_Data => Prj.No_Symbols, Lib_Version => Library_Version.all, Driver_Name => Driver_Name, Auto_Init => Auto_Init); end Build_Shared_Lib; gprbuild-gpl-2014-src/src/gpr_version.ads0000644000076700001450000000375112323721731017756 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R _ V E R S I O N -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This package spec holds version information for the GPR tools. -- It is updated whenever the release number is changed. package GPR_Version is Gpr_Version : constant String := "2014"; -- Static string identifying this version function Gpr_Version_String return String; -- Version output when GPRBUILD or its related tools, including -- GPRCLEAN, are run (with appropriate verbose option switch set). end GPR_Version; gprbuild-gpl-2014-src/src/gprslave.ads0000644000076700001450000000310112323721731017231 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ procedure Gprslave; gprbuild-gpl-2014-src/src/gprbuild.adb0000644000076700001450000005035612323721731017213 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D -- -- -- -- B o d y -- -- -- -- Copyright (C) 2004-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Text_IO; use Ada.Text_IO; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with Output; use Output; with Gpr_Util; use Gpr_Util; package body Gprbuild is package Processed_Projects is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Boolean, No_Element => False, Key => Name_Id, Hash => Hash, Equal => "="); -- Projects that have already been processed ---------------- -- Add_Option -- ---------------- procedure Add_Option (Value : String; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False) is begin Name_Len := Value'Length; Name_Buffer (1 .. Name_Len) := Value; Add_Option_Internal (Get_Option (Name_Find), To, Display, Simple_Name); end Add_Option; procedure Add_Option (Value : Name_Id; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False) is begin Add_Option_Internal (Get_Option (Value), To, Display, Simple_Name); end Add_Option; ------------------------- -- Add_Option_Internal -- ------------------------- procedure Add_Option_Internal (Value : String_Access; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False) is begin -- For compatibility with gnatmake, do not consider empty options if Value'Length = 0 then return; end if; To.Last := To.Last + 1; if To.Last > To.Options'Last then declare New_Options : constant String_List_Access := new String_List (1 .. 2 * To.Options'Last); New_Visible : constant Booleans := new Boolean_Array (1 .. 2 * To.Visible'Last); New_Simple_Name : constant Booleans := new Boolean_Array (1 .. 2 * To.Visible'Last); begin New_Options (To.Options'Range) := To.Options.all; To.Options.all := (others => null); Free (To.Options); To.Options := New_Options; New_Visible (To.Visible'Range) := To.Visible.all; Free (To.Visible); To.Visible := New_Visible; New_Simple_Name (To.Simple_Name'Range) := To.Simple_Name.all; Free (To.Simple_Name); To.Simple_Name := New_Simple_Name; end; end if; To.Options (To.Last) := Value; To.Visible (To.Last) := Display; To.Simple_Name (To.Last) := Simple_Name; end Add_Option_Internal; ---------------------------------- -- Add_Option_Internal_Codepeer -- ---------------------------------- procedure Add_Option_Internal_Codepeer (Value : String_Access; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False) is begin if Value'Length <= 2 or else Value (Value'First .. Value'First + 1) /= "-m" then Add_Option_Internal (Value, To, Display, Simple_Name); end if; end Add_Option_Internal_Codepeer; ----------------- -- Add_Options -- ----------------- procedure Add_Options (Value : String_List_Id; To : in out Options_Data; Display_All : Boolean; Display_First : Boolean; Simple_Name : Boolean := False) is List : String_List_Id := Value; Element : String_Element; Option : String_Access; First_Display : Boolean := Display_First; begin while List /= Nil_String loop Element := Project_Tree.Shared.String_Elements.Table (List); -- Ignore empty options if Element.Value /= Empty_String then Option := Get_Option (Element.Value); Add_Option_Internal (Value => Option, To => To, Display => Display_All or First_Display, Simple_Name => Simple_Name); First_Display := False; end if; List := Element.Next; end loop; end Add_Options; ----------------- -- Add_Process -- ----------------- procedure Add_Process (Process : Process_Id; Data : Process_Data) is begin Process_Htable.Set (Process, Data); Outstanding_Processes := Outstanding_Processes + 1; end Add_Process; -------------------- -- Archive_Suffix -- -------------------- function Archive_Suffix (For_Project : Project_Id) return String is begin if For_Project.Config.Archive_Suffix = No_File then return ".a"; else return Get_Name_String (For_Project.Config.Archive_Suffix); end if; end Archive_Suffix; ------------------- -- Await_Process -- ------------------- procedure Await_Process (Data : out Process_Data; OK : out Boolean) is Pid : Process_Id; begin loop Data := No_Process_Data; Wait_Process (Pid, OK); if Pid = Invalid_Pid then return; end if; Data := Process_Htable.Get (Pid); if Data /= No_Process_Data then Process_Htable.Set (Pid, No_Process_Data); Outstanding_Processes := Outstanding_Processes - 1; return; end if; end loop; end Await_Process; -------------------------------- -- Change_To_Object_Directory -- -------------------------------- procedure Change_To_Object_Directory (Project : Project_Id) is begin -- Nothing to do if the current working directory is already the correct -- object directory. if Project_Of_Current_Object_Directory /= Project then Project_Of_Current_Object_Directory := Project; -- Set the working directory to the object directory of the actual -- project. Change_Dir (Get_Name_String (Project.Object_Directory.Display_Name)); if Opt.Verbose_Mode and then Opt.Verbosity_Level > Opt.Low then Write_Str ("Changing to object directory of """); Write_Name (Project.Display_Name); Write_Str (""": """); Write_Name (Project.Object_Directory.Display_Name); Write_Line (""""); end if; end if; exception -- Fail if unable to change to the object directory when Directory_Error => Fail_Program (Project_Tree, "unable to change to object directory """ & Get_Name_String (Project.Object_Directory.Display_Name) & """ of project " & Get_Name_String (Project.Display_Name)); end Change_To_Object_Directory; --------------------------- -- Check_Archive_Builder -- --------------------------- procedure Check_Archive_Builder is List : Name_List_Index; begin -- First, make sure that the archive builder (ar) is on the path if Archive_Builder_Path = null then List := Main_Project.Config.Archive_Builder; if List = No_Name_List then Fail_Program (Project_Tree, "no archive builder in configuration"); else Archive_Builder_Name := new String'(Get_Name_String (Project_Tree.Shared.Name_Lists.Table (List).Name)); Archive_Builder_Path := Locate_Exec_On_Path (Archive_Builder_Name.all); if Archive_Builder_Path = null then Fail_Program (Project_Tree, "unable to locate archive builder """ & Archive_Builder_Name.all & '"'); end if; loop List := Project_Tree.Shared.Name_Lists.Table (List).Next; exit when List = No_Name_List; Add_Option (Value => Project_Tree.Shared.Name_Lists.Table (List).Name, To => Archive_Builder_Opts, Display => True); end loop; List := Main_Project.Config.Archive_Builder_Append_Option; while List /= No_Name_List loop Add_Option (Value => Project_Tree.Shared.Name_Lists.Table (List).Name, To => Archive_Builder_Append_Opts, Display => True); List := Project_Tree.Shared.Name_Lists.Table (List).Next; end loop; -- If there is an archive indexer (ranlib), try to locate it on -- the path. Don't fail if it is not found. List := Main_Project.Config.Archive_Indexer; if List /= No_Name_List then Archive_Indexer_Name := new String'(Get_Name_String (Project_Tree.Shared.Name_Lists.Table (List).Name)); Archive_Indexer_Path := Locate_Exec_On_Path (Archive_Indexer_Name.all); if Archive_Builder_Path /= null then loop List := Project_Tree.Shared.Name_Lists.Table (List).Next; exit when List = No_Name_List; Add_Option (Value => Project_Tree.Shared.Name_Lists.Table (List).Name, To => Archive_Indexer_Opts, Display => True); end loop; end if; end if; end if; end if; end Check_Archive_Builder; --------------------------- -- Create_Path_From_Dirs -- --------------------------- function Create_Path_From_Dirs return String_Access is Result : String_Access; Tmp : String_Access; Path_Last : Natural := 0; begin for Index in 1 .. Directories.Last loop Get_Name_String (Directories.Table (Index)); while Name_Len > 1 and then (Name_Buffer (Name_Len) = Directory_Separator or else Name_Buffer (Name_Len) = '/') loop Name_Len := Name_Len - 1; end loop; if Result = null then Result := new String (1 .. Name_Len); else while Path_Last + Name_Len + 1 > Result'Last loop Tmp := new String (1 .. 2 * Result'Length); Tmp (1 .. Path_Last) := Result (1 .. Path_Last); Free (Result); Result := Tmp; end loop; Path_Last := Path_Last + 1; Result (Path_Last) := Path_Separator; end if; Result (Path_Last + 1 .. Path_Last + Name_Len) := Name_Buffer (1 .. Name_Len); Path_Last := Path_Last + Name_Len; end loop; if Current_Verbosity = High and then Result /= null then Put_Line ("Path=" & Result (1 .. Path_Last)); end if; Tmp := new String'(Result (1 .. Path_Last)); Free (Result); return Tmp; end Create_Path_From_Dirs; ----------------------- -- Display_Processes -- ----------------------- procedure Display_Processes (Name : String) is begin if Opt.Maximum_Processes > 1 and then Opt.Verbose_Mode and then Current_Verbosity = High then Write_Str (" "); Write_Str (Outstanding_Processes'Img); Write_Char (' '); Write_Str (Name); if Outstanding_Processes <= 1 then Write_Line (" process"); else Write_Line (" processes"); end if; end if; end Display_Processes; ---------------- -- Get_Option -- ---------------- function Get_Option (Option : Name_Id) return String_Access is Option_Name : constant String := Get_Name_String (Option); begin -- Look in All_Options if this option is already cached for Index in 1 .. All_Options.Last loop if All_Options.Options (Index).all = Option_Name then return All_Options.Options (Index); end if; end loop; -- Add the option to the All_Options cache, so that it will be found -- next time. Add_Option_Internal (new String'(Option_Name), To => All_Options, Display => False); return All_Options.Options (All_Options.Last); end Get_Option; ---------- -- Hash -- ---------- function Hash (Pid : Process_Id) return Header_Num is Modulo : constant Integer := Integer (Header_Num'Last) + 1; begin return Header_Num (Pid_To_Integer (Pid) mod Modulo); end Hash; -------------------------------- -- Process_Imported_Libraries -- -------------------------------- procedure Process_Imported_Libraries (For_Project : Project_Id; There_Are_SALs : out Boolean; And_Project_Itself : Boolean := False) is procedure Process_Project (Project : Project_Id; Is_Aggregate : Boolean); -- Process Project and its imported projects recursively. -- Add any library projects to table Library_Projs. --------------------- -- Process_Project -- --------------------- procedure Process_Project (Project : Project_Id; Is_Aggregate : Boolean) is Imported : Project_List := Project.Imported_Projects; begin -- Nothing to do if project has already been processed if not Processed_Projects.Get (Project.Name) then Processed_Projects.Set (Project.Name, True); -- We first process the imported projects to guarantee that -- We have a proper reverse order for the libraries. Do not add -- library for encapsulated libraries dependencies except when -- building the encapsulated library itself. if For_Project.Standalone_Library = Encapsulated or else Project.Standalone_Library /= Encapsulated then while Imported /= null loop if Imported.Project /= No_Project then Process_Project (Imported.Project, Is_Aggregate => (Project.Qualifier = Aggregate_Library) or else Is_Aggregate); end if; Imported := Imported.Next; end loop; end if; -- For an extending project, process the project being extended if Project.Extends /= No_Project then Process_Project (Project.Extends, Is_Aggregate => False); end if; -- If it is a library project, add it to Library_Projs if (And_Project_Itself or else Project /= For_Project) and then Project.Extended_By = No_Project and then Project.Library then if Project.Standalone_Library /= No then There_Are_SALs := True; end if; Library_Projs.Append (Library_Project' (Project, Is_Aggregate and then not Project.Externally_Built)); end if; end if; end Process_Project; -- Start of processing for Process_Imported_Libraries begin Processed_Projects.Reset; Library_Projs.Init; There_Are_SALs := False; Process_Project (For_Project, Is_Aggregate => False); end Process_Imported_Libraries; ------------------------------------ -- Process_Imported_Non_Libraries -- ------------------------------------ procedure Process_Imported_Non_Libraries (For_Project : Project_Id) is procedure Process_Project (Project : Project_Id); -- Process Project and its imported projects recursively. -- Add any non library project to table Non_Library_Projs. --------------------- -- Process_Project -- --------------------- procedure Process_Project (Project : Project_Id) is Imported : Project_List := Project.Imported_Projects; begin -- Nothing to do if project has already been processed if not Processed_Projects.Get (Project.Name) then Processed_Projects.Set (Project.Name, True); -- Call Process_Project recursively for any imported project. -- We first process the imported projects to guarantee that -- we have a proper reverse order for the libraries. while Imported /= null loop if Imported.Project /= No_Project then Process_Project (Imported.Project); end if; Imported := Imported.Next; end loop; -- For an extending project, process the project being extended if Project.Extends /= No_Project then Process_Project (Project.Extends); end if; -- If it is not a library project, add it to Non_Library_Projs if Project /= For_Project and then Project.Extended_By = No_Project and then not Project.Library then Non_Library_Projs.Append (Project); end if; end if; end Process_Project; -- Start of processing for Process_Imported_Non_Libraries begin Processed_Projects.Reset; Non_Library_Projs.Init; Process_Project (For_Project); end Process_Imported_Non_Libraries; -------------------- -- Record_Failure -- -------------------- procedure Record_Failure (Main : Main_Info) is begin Bad_Processes.Append (Main); if not Opt.Keep_Going then Stop_Spawning := True; end if; end Record_Failure; --------------------------- -- Test_If_Relative_Path -- --------------------------- procedure Test_If_Relative_Path (Switch : in out String_Access; Parent : String; Including_Switch : Name_Id) is Original : constant String (1 .. Switch'Length) := Switch.all; begin if Original (1) = '-' and then Including_Switch /= No_Name then declare Inc_Switch : constant String := Get_Name_String (Including_Switch); begin if Original'Last > Inc_Switch'Last and then Original (1 .. Inc_Switch'Last) = Inc_Switch and then not Is_Absolute_Path (Original (Inc_Switch'Last + 1 .. Original'Last)) then Switch := new String' (Inc_Switch & Parent & Directory_Separator & Original (Inc_Switch'Last + 1 .. Original'Last)); end if; end; end if; if Original (1) /= '-' and then not Is_Absolute_Path (Original) then Switch := new String'(Parent & Directory_Separator & Original); end if; end Test_If_Relative_Path; end Gprbuild; gprbuild-gpl-2014-src/src/gprbuild-link.adb0000644000076700001450000031123212323721731020137 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . L I N K -- -- -- -- B o d y -- -- -- -- Copyright (C) 2011-2013, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Unchecked_Deallocation; use Ada; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Ada.Text_IO; use Ada.Text_IO; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with Debug; use Debug; with Gpr_Util; use Gpr_Util; with Gprexch; use Gprexch; with Makeutl; use Makeutl; with Osint; use Osint; with Output; use Output; with Prj.Util; use Prj.Util; with Snames; use Snames; package body Gprbuild.Link is type Archive_Data is record Checked : Boolean := False; Has_Been_Built : Boolean := False; Exists : Boolean := False; end record; type Source_Index_Rec is record Project : Project_Id; Id : Source_Id; Found : Boolean := False; end record; -- Used as Source_Indexes component to check if archive needs to be rebuilt type Source_Index_Array is array (Positive range <>) of Source_Index_Rec; type Source_Indexes_Ref is access Source_Index_Array; procedure Free is new Unchecked_Deallocation (Source_Index_Array, Source_Indexes_Ref); Initial_Source_Index_Count : constant Positive := 20; Source_Indexes : Source_Indexes_Ref := new Source_Index_Array (1 .. Initial_Source_Index_Count); -- A list of the Source_Ids, with an indication that they have been found -- in the archive dependency file. procedure Build_Global_Archive (For_Project : Project_Id; Project_Tree : Project_Tree_Ref; Has_Been_Built : out Boolean; Exists : out Boolean; OK : out Boolean); -- Build, if necessary, the global archive for a main project. -- Out parameter Has_Been_Built is True iff the global archive has been -- built/rebuilt. Exists is False if there is no need for a global archive. -- OK is False when there is a problem building the global archive. procedure Link_Main (Main_File : Main_Info); -- Link a specific main unit procedure Get_Linker_Options (For_Project : Project_Id); -- Get the Linker_Options from a project procedure Add_Rpath (Path : String); -- Add a path name to Rpath procedure Rpaths_Relative_To (Exec_Dir : Path_Name_Type; Origin : Name_Id); -- Change all paths in table Rpaths to paths relative to Exec_Dir, if they -- have at least one non root directory in common. function Is_In_Library_Project (Object_Path : String) return Boolean; -- Return True if Object_Path is the path of an object file in a library -- project. procedure Display_Command (Name : String; Path : String_Access; Ellipse : Boolean := False); -- Display the command for a spawned process, if in Verbose_Mode or not in -- Quiet_Output. In non verbose mode, when Ellipse is True, display "..." -- in place of the first argument that has Display set to False. procedure Add_Argument (Arg : String_Access; Display : Boolean; Simple_Name : Boolean := False); procedure Add_Argument (Arg : String; Display : Boolean; Simple_Name : Boolean := False); -- Add an argument to Arguments. Reallocate if necessary procedure Add_Arguments (Args : Argument_List; Display : Boolean; Simple_Name : Boolean := False); -- Add a list of arguments to Arguments. Reallocate if necessary No_Archive_Data : constant Archive_Data := (Checked => False, Has_Been_Built => False, Exists => False); package Global_Archives_Built is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Archive_Data, No_Element => No_Archive_Data, Key => Name_Id, Hash => Prj.Hash, Equal => "="); -- A hash table to record what global archives have been already built package Cache_Args is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 200, Table_Increment => 100, Table_Name => "Buildgpr.Cache_Args"); -- A table to cache arguments, to avoid multiple allocation of the same -- strings. It is not possible to use a hash table, because String is -- an unconstrained type. package Rpaths is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 200, Table_Increment => 50, Table_Name => "Makegpr.Rpaths"); -- Directories to be put in the run path option package Library_Dirs is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Boolean, No_Element => False, Key => Path_Name_Type, Hash => Hash, Equal => "="); -- A hash table to store the library dirs, to avoid repeating uselessly -- the same switch when linking executables. Last_Source : Natural := 0; -- The index of the last valid component of Source_Indexes Initial_Argument_Count : constant Positive := 20; Arguments : Argument_List_Access := new Argument_List (1 .. Initial_Argument_Count); -- Used to store lists of arguments to be used when spawning a process Arguments_Displayed : Booleans := new Boolean_Array (1 .. Initial_Argument_Count); -- For each argument in Arguments, indicate if the argument should be -- displayed when procedure Display_Command is called. Arguments_Simple_Name : Booleans := new Boolean_Array (1 .. Initial_Argument_Count); -- For each argument that should be displayed, indicate that the argument -- is a path name and that only the simple name should be displayed. Last_Argument : Natural := 0; -- Index of the last valid argument in Arguments ------------------ -- Add_Argument -- ------------------ procedure Add_Argument (Arg : String_Access; Display : Boolean; Simple_Name : Boolean := False) is begin -- Nothing to do if no argument is specified or if argument is empty if Arg /= null and then Arg'Length /= 0 then -- Reallocate arrays if necessary if Last_Argument = Arguments'Last then declare New_Arguments : constant Argument_List_Access := new Argument_List (1 .. Last_Argument + Initial_Argument_Count); New_Arguments_Displayed : constant Booleans := new Boolean_Array (1 .. Last_Argument + Initial_Argument_Count); New_Arguments_Simple_Name : constant Booleans := new Boolean_Array (1 .. Last_Argument + Initial_Argument_Count); begin New_Arguments (Arguments'Range) := Arguments.all; -- To avoid deallocating the strings, nullify all components -- of Arguments before calling Free. Arguments.all := (others => null); Free (Arguments); Arguments := New_Arguments; New_Arguments_Displayed (Arguments_Displayed'Range) := Arguments_Displayed.all; Free (Arguments_Displayed); Arguments_Displayed := New_Arguments_Displayed; New_Arguments_Simple_Name (Arguments_Simple_Name'Range) := Arguments_Simple_Name.all; Free (Arguments_Simple_Name); Arguments_Simple_Name := New_Arguments_Simple_Name; end; end if; -- Add the argument and its display indication Last_Argument := Last_Argument + 1; Arguments (Last_Argument) := Arg; Arguments_Displayed (Last_Argument) := Display; Arguments_Simple_Name (Last_Argument) := Simple_Name; end if; end Add_Argument; procedure Add_Argument (Arg : String; Display : Boolean; Simple_Name : Boolean := False) is Argument : String_Access := null; begin -- Nothing to do if argument is empty if Arg'Length > 0 then -- Check if the argument is already in the Cache_Args table. If it is -- already there, reuse the allocated value. for Index in 1 .. Cache_Args.Last loop if Cache_Args.Table (Index).all = Arg then Argument := Cache_Args.Table (Index); exit; end if; end loop; -- If the argument is not in the cache, create a new entry in the -- cache. if Argument = null then Argument := new String'(Arg); Cache_Args.Increment_Last; Cache_Args.Table (Cache_Args.Last) := Argument; end if; -- And add the argument Add_Argument (Argument, Display, Simple_Name); end if; end Add_Argument; ------------------- -- Add_Arguments -- ------------------- procedure Add_Arguments (Args : Argument_List; Display : Boolean; Simple_Name : Boolean := False) is begin -- Reallocate the arrays, if necessary if Last_Argument + Args'Length > Arguments'Last then declare New_Arguments : constant Argument_List_Access := new Argument_List (1 .. Last_Argument + Args'Length + Initial_Argument_Count); New_Arguments_Displayed : constant Booleans := new Boolean_Array (1 .. Last_Argument + Args'Length + Initial_Argument_Count); begin New_Arguments (1 .. Last_Argument) := Arguments (1 .. Last_Argument); -- To avoid deallocating the strings, nullify all components -- of Arguments before calling Free. Arguments.all := (others => null); Free (Arguments); Arguments := New_Arguments; New_Arguments_Displayed (1 .. Last_Argument) := Arguments_Displayed (1 .. Last_Argument); Free (Arguments_Displayed); Arguments_Displayed := New_Arguments_Displayed; end; end if; -- Add the new arguments and the display indications Arguments (Last_Argument + 1 .. Last_Argument + Args'Length) := Args; Arguments_Displayed (Last_Argument + 1 .. Last_Argument + Args'Length) := (others => Display); Arguments_Simple_Name (Last_Argument + 1 .. Last_Argument + Args'Length) := (others => Simple_Name); Last_Argument := Last_Argument + Args'Length; end Add_Arguments; --------------- -- Add_Rpath -- --------------- procedure Add_Rpath (Path : String) is begin -- Nothing to do if Path is empty if Path'Length > 0 then -- Nothing to do if the directory is already in the Rpaths table for J in 1 .. Rpaths.Last loop if Rpaths.Table (J).all = Path then return; end if; end loop; Rpaths.Append (new String'(Path)); end if; end Add_Rpath; -------------------------- -- Build_Global_Archive -- -------------------------- procedure Build_Global_Archive (For_Project : Project_Id; Project_Tree : Project_Tree_Ref; Has_Been_Built : out Boolean; Exists : out Boolean; OK : out Boolean) is Archive_Name : constant String := "lib" & Get_Name_String (For_Project.Name) & Archive_Suffix (For_Project); -- The name of the archive file for this project Archive_Dep_Name : constant String := "lib" & Get_Name_String (For_Project.Name) & ".deps"; -- The name of the archive dependency file for this project File : Prj.Util.Text_File; Object_Path : Path_Name_Type; Time_Stamp : Time_Stamp_Type; First_Object : Natural; Discard : Boolean; Proj_List : Project_List; Src_Id : Source_Id; S_Id : Source_Id; Success : Boolean; Real_Last_Argument : Positive; Current_Object_Pos : Positive; Size : Natural; Global_Archive_Data : Archive_Data; Need_To_Build : Boolean; procedure Add_Sources (Proj : Project_Id); -- Add all the sources of project Proj to Sources_Index procedure Add_Objects (Proj : Project_Id); -- Add all the object paths of project Proj to Arguments ----------------- -- Add_Sources -- ----------------- procedure Add_Sources (Proj : Project_Id) is Project : Project_Id := Proj; Id : Source_Id; Iter : Source_Iterator; procedure Add_Source_Id (Project : Project_Id; Id : Source_Id); -- Add a source id to Source_Indexes, with Found set to False ------------------- -- Add_Source_Id -- ------------------- procedure Add_Source_Id (Project : Project_Id; Id : Source_Id) is begin -- Reallocate the array, if necessary if Last_Source = Source_Indexes'Last then declare New_Indexes : constant Source_Indexes_Ref := new Source_Index_Array (1 .. Source_Indexes'Last + Initial_Source_Index_Count); begin New_Indexes (Source_Indexes'Range) := Source_Indexes.all; Free (Source_Indexes); Source_Indexes := New_Indexes; end; end if; Last_Source := Last_Source + 1; Source_Indexes (Last_Source) := (Project, Id, False); end Add_Source_Id; begin while Project /= No_Project loop Iter := For_Each_Source (Project_Tree, Project); loop Id := Prj.Element (Iter); exit when Id = No_Source; if Is_Compilable (Id) and then Id.Kind = Impl and then Id.Unit = No_Unit_Index then Add_Source_Id (Proj, Id); end if; Next (Iter); end loop; Project := Project.Extends; end loop; end Add_Sources; ----------------- -- Add_Objects -- ----------------- procedure Add_Objects (Proj : Project_Id) is Project : Project_Id := Proj; Id : Source_Id; Iter : Source_Iterator; begin loop if Project.Object_Directory /= No_Path_Information then if Project.Externally_Built then -- If project is externally built, include all object files -- in the object directory in the global archive. declare Obj_Dir : constant String := Get_Name_String (Project.Object_Directory.Display_Name); Dir_Obj : Dir_Type; begin if Is_Regular_File (Obj_Dir) then Open (Dir_Obj, Obj_Dir); loop Read (Dir_Obj, Name_Buffer, Name_Len); exit when Name_Len = 0; Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); if Name_Len > Object_Suffix'Length and then Name_Buffer (Name_Len - Object_Suffix'Length + 1 .. Name_Len) = Object_Suffix then Add_Argument (Obj_Dir & Directory_Separator & Name_Buffer (1 .. Name_Len), Opt.Verbose_Mode, Simple_Name => not Opt.Verbose_Mode); end if; end loop; Close (Dir_Obj); end if; end; else Iter := For_Each_Source (Project_Tree, Project); loop Id := Prj.Element (Iter); exit when Id = No_Source; if Object_To_Global_Archive (Id) then -- The source record may not be initialized if -- gprbuild was called with the switch -l. Initialize_Source_Record (Id); Add_Argument (Get_Name_String (Id.Object_Path), Opt.Verbose_Mode, Simple_Name => not Opt.Verbose_Mode); end if; Next (Iter); end loop; end if; end if; Project := Project.Extends; exit when Project = No_Project; end loop; end Add_Objects; begin Exists := False; Has_Been_Built := False; OK := True; -- No need to build the global archive, if it has already been done if For_Project.Object_Directory /= No_Path_Information then Global_Archive_Data := Global_Archives_Built.Get (Name_Id (For_Project.Path.Name)); if Global_Archive_Data.Checked then Exists := Global_Archive_Data.Exists; Has_Been_Built := Global_Archive_Data.Has_Been_Built; else Change_To_Object_Directory (For_Project); -- Put all non Ada sources in the project tree in Source_Indexes Last_Source := 0; Add_Sources (For_Project); Proj_List := For_Project.All_Imported_Projects; while Proj_List /= null loop if not Proj_List.Project.Library then Add_Sources (Proj_List.Project); end if; Proj_List := Proj_List.Next; end loop; Need_To_Build := Opt.Force_Compilations; if not Need_To_Build then if Opt.Verbose_Mode then Write_Str (" Checking "); Write_Str (Archive_Name); Write_Line (" ..."); end if; -- If the archive does not exist, of course it needs to be -- built. if not Is_Regular_File (Archive_Name) then Need_To_Build := True; if Opt.Verbose_Mode then Write_Line (" -> archive does not exist"); end if; else -- Archive does exist -- Check the archive dependency file Open (File, Archive_Dep_Name); -- If the archive dependency file does not exist, we need to -- to rebuild the archive and to create its dependency file. if not Is_Valid (File) then Need_To_Build := True; if Opt.Verbose_Mode then Write_Str (" -> archive dependency file "); Write_Str (Archive_Dep_Name); Write_Line (" does not exist"); end if; else -- Read the dependency file, line by line while not End_Of_File (File) loop Get_Line (File, Name_Buffer, Name_Len); -- First line is the path of the object file Object_Path := Name_Find; Src_Id := No_Source; -- Check if this object file is for a source of this -- project. for S in 1 .. Last_Source loop S_Id := Source_Indexes (S).Id; if not Source_Indexes (S).Found and then S_Id.Object_Path = Object_Path then -- We have found the object file: get the -- source data, and mark it as found. Src_Id := S_Id; Source_Indexes (S).Found := True; exit; end if; end loop; -- If it is not for a source of this project, then the -- archive needs to be rebuilt. if Src_Id = No_Source then Need_To_Build := True; if Opt.Verbose_Mode then Write_Str (" -> "); Write_Str (Get_Name_String (Object_Path)); Write_Line (" is not an object of any project"); end if; exit; end if; -- The second line is the time stamp of the object -- file. If there is no next line, then the dependency -- file is truncated, and the archive need to be -- rebuilt. if End_Of_File (File) then Need_To_Build := True; if Opt.Verbose_Mode then Write_Str (" -> archive dependency file "); Write_Line (" is truncated"); end if; exit; end if; Get_Line (File, Name_Buffer, Name_Len); -- If the line has the wrong number of characters, -- then the dependency file is incorrectly formatted, -- and the archive needs to be rebuilt. if Name_Len /= Time_Stamp_Length then Need_To_Build := True; if Opt.Verbose_Mode then Write_Str (" -> archive dependency file "); Write_Line (" is incorrectly formatted (time stamp)"); end if; exit; end if; Time_Stamp := Time_Stamp_Type (Name_Buffer (1 .. Name_Len)); -- If the time stamp in the dependency file is -- different from the time stamp of the object file, -- then the archive needs to be rebuilt. The -- comparaison is done with String type values, -- because two values of type Time_Stamp_Type are -- equal if they differ by 2 seconds or less; here the -- check is for an exact match. if String (Time_Stamp) /= String (Src_Id.Object_TS) then Need_To_Build := True; if Opt.Verbose_Mode then Write_Str (" -> time stamp of "); Write_Str (Get_Name_String (Object_Path)); Write_Str (" is incorrect in the archive"); Write_Line (" dependency file"); Write_Str (" recorded time stamp: "); Write_Line (String (Time_Stamp)); Write_Str (" actual time stamp: "); Write_Line (String (Src_Id.Object_TS)); end if; exit; elsif Debug_Flag_T then Write_Str (" -> time stamp of "); Write_Str (Get_Name_String (Object_Path)); Write_Str (" is correct in the archive"); Write_Line (" dependency file"); Write_Str (" recorded time stamp: "); Write_Line (String (Time_Stamp)); Write_Str (" actual time stamp: "); Write_Line (String (Src_Id.Object_TS)); end if; end loop; Close (File); end if; end if; end if; if not Need_To_Build then for S in 1 .. Last_Source loop if not Source_Indexes (S).Found and then Object_To_Global_Archive (Source_Indexes (S).Id) then Need_To_Build := True; if Opt.Verbose_Mode then Write_Str (" -> object file "); Write_Str (Get_Name_String (Source_Indexes (S).Id.Object_Path)); Write_Line (" is not in the dependency file"); end if; exit; end if; end loop; end if; if not Need_To_Build then if Opt.Verbose_Mode then Write_Line (" -> up to date"); end if; Exists := True; Has_Been_Built := False; -- Archive needs to be rebuilt else Check_Archive_Builder; -- If archive already exists, first delete it, but if this is -- not possible, continue: if archive cannot be built, we will -- fail later on. if Is_Regular_File (Archive_Name) then Delete_File (Archive_Name, Discard); end if; Last_Argument := 0; -- Start with the minimal options Add_Arguments (Archive_Builder_Opts.Options (1 .. Archive_Builder_Opts.Last), True); -- Followed by the archive name Add_Argument (Archive_Name, True, Simple_Name => not Opt.Verbose_Mode); First_Object := Last_Argument + 1; -- Followed by all the object files of the non library projects Add_Objects (For_Project); Proj_List := For_Project.All_Imported_Projects; while Proj_List /= null loop if not Proj_List.Project.Library then Add_Objects (Proj_List.Project); end if; Proj_List := Proj_List.Next; end loop; -- No global archive, if there is no object file to put into if Last_Argument < First_Object then Has_Been_Built := False; Exists := False; if Opt.Verbose_Mode then Write_Line (" -> there is no global archive"); end if; else Real_Last_Argument := Last_Argument; -- If there is an Archive_Builder_Append_Option, we may have -- to build the archive in chuck. if Archive_Builder_Append_Opts.Last = 0 then Current_Object_Pos := Real_Last_Argument + 1; else Size := 0; for J in 1 .. First_Object - 1 loop Size := Size + Arguments (J)'Length + 1; end loop; Current_Object_Pos := First_Object; while Current_Object_Pos <= Real_Last_Argument loop Size := Size + Arguments (Current_Object_Pos)'Length + 1; exit when Size > Maximum_Size; Current_Object_Pos := Current_Object_Pos + 1; end loop; Last_Argument := Current_Object_Pos - 1; end if; Display_Command (Archive_Builder_Name.all, Archive_Builder_Path, Ellipse => True); Spawn (Archive_Builder_Path.all, Arguments (1 .. Last_Argument), Success); -- If the archive has not been built completely, add the -- remaining chunks. if Success and then Current_Object_Pos <= Real_Last_Argument then Last_Argument := 0; Add_Arguments (Archive_Builder_Append_Opts.Options (1 .. Archive_Builder_Append_Opts.Last), True); Add_Argument (Archive_Name, True, Simple_Name => not Opt.Verbose_Mode); First_Object := Last_Argument + 1; while Current_Object_Pos <= Real_Last_Argument loop Size := 0; for J in 1 .. First_Object - 1 loop Size := Size + Arguments (J)'Length + 1; end loop; Last_Argument := First_Object - 1; while Current_Object_Pos <= Real_Last_Argument loop Size := Size + Arguments (Current_Object_Pos)'Length + 1; exit when Size > Maximum_Size; Last_Argument := Last_Argument + 1; Arguments (Last_Argument) := Arguments (Current_Object_Pos); Current_Object_Pos := Current_Object_Pos + 1; end loop; Display_Command (Archive_Builder_Name.all, Archive_Builder_Path, Ellipse => True); Spawn (Archive_Builder_Path.all, Arguments (1 .. Last_Argument), Success); exit when not Success; end loop; end if; -- If the archive was built, run the archive indexer -- (ranlib) if there is one. if Success then -- If the archive was built, run the archive indexer -- (ranlib), if there is one. if Archive_Indexer_Path /= null then Last_Argument := 0; Add_Arguments (Archive_Indexer_Opts.Options (1 .. Archive_Indexer_Opts.Last), True); Add_Argument (Archive_Name, True, Simple_Name => not Opt.Verbose_Mode); Display_Command (Archive_Indexer_Name.all, Archive_Indexer_Path); Spawn (Archive_Indexer_Path.all, Arguments (1 .. Last_Argument), Success); if not Success then -- Running the archive indexer failed, delete the -- dependency file, if it exists. if Is_Regular_File (Archive_Dep_Name) then Delete_File (Archive_Dep_Name, Success); end if; end if; end if; end if; if Success then -- The archive was correctly built, create its dependency -- file. declare Dep_File : Text_IO.File_Type; begin -- Create the file in Append mode, to avoid automatic -- insertion of an end of line if file is empty. Create (Dep_File, Append_File, Archive_Dep_Name); for S in 1 .. Last_Source loop Src_Id := Source_Indexes (S).Id; if Object_To_Global_Archive (Src_Id) then Put_Line (Dep_File, Get_Name_String (Src_Id.Object_Path)); Put_Line (Dep_File, String (Src_Id.Object_TS)); end if; end loop; Close (Dep_File); exception when others => if Is_Open (Dep_File) then Close (Dep_File); end if; end; Has_Been_Built := True; Exists := True; else -- Building the archive failed, delete dependency file if -- one exists. if Is_Regular_File (Archive_Dep_Name) then Delete_File (Archive_Dep_Name, Success); end if; Write_Str ("global archive for project "); Write_Str (Get_Name_String (For_Project.Display_Name)); Write_Line (" could not be built"); OK := False; return; end if; end if; end if; Global_Archives_Built.Set (Name_Id (For_Project.Path.Name), (Checked => True, Has_Been_Built => Has_Been_Built, Exists => Exists)); end if; end if; end Build_Global_Archive; --------------------- -- Display_Command -- --------------------- procedure Display_Command (Name : String; Path : String_Access; Ellipse : Boolean := False) is Display_Ellipse : Boolean := Ellipse; begin -- Only display the command in Verbose Mode (-v) or when -- not in Quiet Output (no -q). if not Opt.Quiet_Output then -- In Verbose Mode output the full path of the spawned process if Opt.Verbose_Mode then Write_Str (Path.all); elsif Executable_Suffix'Length > 0 and then Name'Length > Executable_Suffix'Length then Name_Len := Name'Length; Name_Buffer (1 .. Name_Len) := Name; if Name_Buffer (Name_Len - Executable_Suffix'Length + 1 .. Name_Len) = Executable_Suffix.all then Name_Len := Name_Len - Executable_Suffix'Length; end if; Put (Base_Name (Name_Buffer (1 .. Name_Len))); else Write_Str (Base_Name (Name)); end if; -- Display only the arguments for which the display flag is set -- (in Verbose Mode, the display flag is set for all arguments) for Arg in 1 .. Last_Argument loop if Arguments_Displayed (Arg) then Write_Char (' '); if Arguments_Simple_Name (Arg) then Write_Str (Base_Name (Arguments (Arg).all)); else Write_Str (Arguments (Arg).all); end if; elsif Display_Ellipse then Write_Str (" ..."); Display_Ellipse := False; end if; end loop; Write_Eol; end if; end Display_Command; ------------------------ -- Get_Linker_Options -- ------------------------ procedure Get_Linker_Options (For_Project : Project_Id) is Linker_Lib_Dir_Option : String_Access; Linker_Lib_Name_Option : String_Access; procedure Recursive_Add (Proj : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean); -- The recursive routine used to add linker options ------------------- -- Recursive_Add -- ------------------- procedure Recursive_Add (Proj : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Dummy); Linker_Package : Package_Id; Options : Variable_Value; begin if Proj /= For_Project then Linker_Package := Prj.Util.Value_Of (Name => Name_Linker, In_Packages => Proj.Decl.Packages, Shared => Tree.Shared); Options := Prj.Util.Value_Of (Name => Name_Ada, Index => 0, Attribute_Or_Array_Name => Name_Linker_Options, In_Package => Linker_Package, Shared => Tree.Shared); -- If attribute is present, add the project with -- the attribute to table Linker_Opts. if Options /= Nil_Variable_Value then Linker_Opts.Increment_Last; Linker_Opts.Table (Linker_Opts.Last) := (Project => Proj, Options => Options.Values); end if; end if; end Recursive_Add; procedure For_All_Projects is new For_Every_Project_Imported (Boolean, Recursive_Add); Dummy : Boolean := False; -- Start of processing for Get_Linker_Options begin if For_Project.Config.Linker_Lib_Dir_Option = No_Name then Linker_Lib_Dir_Option := new String'("-L"); else Linker_Lib_Dir_Option := new String' (Get_Name_String (For_Project.Config.Linker_Lib_Dir_Option)); end if; if For_Project.Config.Linker_Lib_Name_Option = No_Name then Linker_Lib_Name_Option := new String'("-l"); else Linker_Lib_Name_Option := new String' (Get_Name_String (For_Project.Config.Linker_Lib_Name_Option)); end if; Linker_Opts.Init; For_All_Projects (For_Project, Project_Tree, Dummy, Imported_First => True); for Index in reverse 1 .. Linker_Opts.Last loop declare Options : String_List_Id := Linker_Opts.Table (Index).Options; Proj : constant Project_Id := Linker_Opts.Table (Index).Project; Option : Name_Id; Dir_Path : constant String := Get_Name_String (Proj.Directory.Display_Name); begin while Options /= Nil_String loop Option := Project_Tree.Shared.String_Elements.Table (Options).Value; Get_Name_String (Option); -- Do not consider empty linker options if Name_Len /= 0 then -- Object files and -L switches specified with relative -- paths must be converted to absolute paths. if Name_Len > Linker_Lib_Dir_Option'Length and then Name_Buffer (1 .. Linker_Lib_Dir_Option'Length) = Linker_Lib_Dir_Option.all then if Is_Absolute_Path (Name_Buffer (Linker_Lib_Dir_Option'Length + 1 .. Name_Len)) then Add_Argument (Name_Buffer (1 .. Name_Len), True); else Add_Argument (Linker_Lib_Dir_Option.all & Dir_Path & Directory_Separator & Name_Buffer (Linker_Lib_Dir_Option'Length + 1 .. Name_Len), True); end if; elsif (Name_Len > Linker_Lib_Name_Option'Length and then Name_Buffer (1 .. Linker_Lib_Name_Option'Length) = Linker_Lib_Name_Option.all) or else Name_Buffer (1) = '-' or else Is_Absolute_Path (Name_Buffer (1 .. Name_Len)) then Add_Argument (Name_Buffer (1 .. Name_Len), True); else Add_Argument (Dir_Path & Directory_Separator & Name_Buffer (1 .. Name_Len), True, Simple_Name => True); end if; end if; Options := Project_Tree.Shared.String_Elements.Table (Options).Next; end loop; end; end loop; end Get_Linker_Options; --------------------------- -- Is_In_Library_Project -- --------------------------- function Is_In_Library_Project (Object_Path : String) return Boolean is Path_Id : constant Path_Name_Type := Create_Name (Object_Path); Src : Source_Id; Iter : Source_Iterator; begin Iter := For_Each_Source (Project_Tree); loop Src := Prj.Element (Iter); exit when Src = No_Source; if Src.Object_Path = Path_Id then return Src.Project.Library; end if; Next (Iter); end loop; return False; end Is_In_Library_Project; ------------------------ -- Rpaths_Relative_To -- ------------------------ procedure Rpaths_Relative_To (Exec_Dir : Path_Name_Type; Origin : Name_Id) is Exec : String := Normalize_Pathname (Get_Name_String (Exec_Dir), Case_Sensitive => False); Last_Exec : Positive; Curr_Exec : Positive; Last_Path : Positive; Curr_Path : Positive; Nmb : Natural; Origin_Name : constant String := Get_Name_String (Origin); begin -- Replace all directory separators with '/' to ease search if Directory_Separator /= '/' then for J in Exec'Range loop if Exec (J) = Directory_Separator then Exec (J) := '/'; end if; end loop; end if; for Npath in 1 .. Rpaths.Last loop declare Insensitive_Path : String := Normalize_Pathname (Rpaths.Table (Npath).all, Case_Sensitive => False); Path : constant String := Normalize_Pathname (Rpaths.Table (Npath).all); begin -- Replace all directory separators with '/' to ease search if Directory_Separator /= '/' then for J in Insensitive_Path'Range loop if Insensitive_Path (J) = Directory_Separator then Insensitive_Path (J) := '/'; end if; end loop; end if; -- Find the number of common directories between the path and the -- exec directory. Nmb := 0; Curr_Path := Insensitive_Path'First; Curr_Exec := Exec'First; loop exit when Curr_Path > Insensitive_Path'Last or else Curr_Exec > Exec'Last or else Insensitive_Path (Curr_Path) /= Exec (Curr_Exec); if Insensitive_Path (Curr_Path) = '/' then Nmb := Nmb + 1; Last_Path := Curr_Path; Last_Exec := Curr_Exec; elsif Curr_Exec = Exec'Last and then Curr_Path > Insensitive_Path'Last then Nmb := Nmb + 1; Last_Path := Curr_Path + 1; Last_Exec := Curr_Exec + 1; exit; end if; Curr_Path := Curr_Path + 1; Curr_Exec := Curr_Exec + 1; end loop; -- If there is more than one common directories (the root -- directory does not count), then change the absolute path to a -- relative path. if Nmb > 1 then Nmb := 0; for J in Last_Exec .. Exec'Last - 1 loop if Exec (J) = '/' then Nmb := Nmb + 1; end if; end loop; if Nmb = 0 then if Last_Path >= Path'Last then -- Case of the path being the exec dir Rpaths.Table (Npath) := new String'(Origin_Name & Directory_Separator & "."); else -- Case of the path being a subdir of the exec dir Rpaths.Table (Npath) := new String' (Origin_Name & Directory_Separator & Path (Last_Path + 1 .. Path'Last)); end if; else if Last_Path >= Path'Last then -- Case of the exec dir being a subdir of the path Rpaths.Table (Npath) := new String' (Origin_Name & Directory_Separator & (Nmb - 1) * (".." & Directory_Separator) & ".."); else -- General case of path and exec dir having a common root Rpaths.Table (Npath) := new String' (Origin_Name & Directory_Separator & Nmb * (".." & Directory_Separator) & Path (Last_Path + 1 .. Path'Last)); end if; end if; end if; end; end loop; end Rpaths_Relative_To; --------------- -- Link_Main -- --------------- procedure Link_Main (Main_File : Main_Info) is function Global_Archive_Name (For_Project : Project_Id) return String; -- Returns the name of the global archive for a project Linker_Name : String_Access := null; Linker_Path : String_Access; Min_Linker_Opts : Name_List_Index; Exchange_File : Text_IO.File_Type; Line : String (1 .. 1_000); Last : Natural; -- Success : Boolean := False; Section : Binding_Section := No_Binding_Section; Linker_Needs_To_Be_Called : Boolean; Executable_TS : Time_Stamp_Type; Main_Object_TS : Time_Stamp_Type; Binder_Exchange_TS : Time_Stamp_Type; Binder_Object_TS : Time_Stamp_Type := Dummy_Time_Stamp; Global_Archive_TS : Time_Stamp_Type; Global_Archive_Has_Been_Built : Boolean; Global_Archive_Exists : Boolean; OK : Boolean; Disregard : Boolean; B_Data : Binding_Data; -- Main already has the right canonical casing Main : constant String := Get_Name_String (Main_File.File); Main_Source : constant Source_Id := Main_File.Source; Main_Id : File_Name_Type; Exec_Name : File_Name_Type; Exec_Path_Name : Path_Name_Type; Main_Proj : Project_Id; Main_Base_Name_Index : File_Name_Type; First_Object_Index : Natural := 0; Last_Object_Index : Natural := 0; Index_Separator : Character; Response_File_Name : Path_Name_Type := No_Path; Response_2 : Path_Name_Type := No_Path; ------------------------- -- Global_Archive_Name -- ------------------------- function Global_Archive_Name (For_Project : Project_Id) return String is begin return "lib" & Get_Name_String (For_Project.Name) & Archive_Suffix (For_Project); end Global_Archive_Name; begin -- Make sure that the table Rpaths is emptied after each main, so -- that the same rpaths are not duplicated. Rpaths.Set_Last (0); Linker_Needs_To_Be_Called := Opt.Force_Compilations; Main_Id := Create_Name (Base_Name (Main)); Main_Proj := Ultimate_Extending_Project_Of (Main_Source.Project); Change_To_Object_Directory (Main_Proj); -- Build the global archive for this project, if needed Build_Global_Archive (Main_Proj, Main_File.Tree, Global_Archive_Has_Been_Built, Global_Archive_Exists, OK); if not OK then Stop_Spawning := True; Bad_Processes.Append (Main_File); return; end if; -- Get the main base name Index_Separator := Main_Source.Language.Config.Multi_Unit_Object_Separator; Main_Base_Name_Index := Base_Name_Index_For (Main, Main_File.Index, Index_Separator); if not Linker_Needs_To_Be_Called and then Opt.Verbose_Mode then Write_Str (" Checking executable for "); Write_Str (Get_Name_String (Main_Source.File)); Write_Line (" ..."); end if; if Output_File_Name /= null then Name_Len := 0; Add_Str_To_Name_Buffer (Output_File_Name.all); Exec_Name := Name_Find; else Exec_Name := Executable_Of (Project => Main_Proj, Shared => Main_File.Tree.Shared, Main => Main_Id, Index => Main_Source.Index, Ada_Main => False, Language => Get_Name_String (Main_Source.Language.Name)); end if; if Main_Proj.Exec_Directory = Main_Proj.Object_Directory then Exec_Path_Name := Path_Name_Type (Exec_Name); else Get_Name_String (Main_Proj.Exec_Directory.Display_Name); Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := Directory_Separator; Add_Str_To_Name_Buffer (Get_Name_String (Exec_Name)); Exec_Path_Name := Name_Find; end if; Executable_TS := File_Stamp (Exec_Path_Name); if not Linker_Needs_To_Be_Called and then Executable_TS = Empty_Time_Stamp then Linker_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> executable does not exist"); end if; end if; -- Get the path of the linker driver if Main_Proj.Config.Linker /= No_Path then Linker_Name := new String'(Get_Name_String (Main_Proj.Config.Linker)); Linker_Path := Locate_Exec_On_Path (Linker_Name.all); if Linker_Path = null then Fail_Program (Main_File.Tree, "unable to find linker " & Linker_Name.all); end if; else Fail_Program (Main_File.Tree, "no linker specified and " & "no default linker in the configuration"); end if; Last_Argument := 0; Initialize_Source_Record (Main_Source); Main_Object_TS := File_Stamp (File_Name_Type (Main_Source.Object_Path)); if not Linker_Needs_To_Be_Called then if Main_Object_TS = Empty_Time_Stamp then if Opt.Verbose_Mode then Write_Line (" -> main object does not exist"); end if; Linker_Needs_To_Be_Called := True; elsif String (Main_Object_TS) > String (Executable_TS) then if Opt.Verbose_Mode then Write_Line (" -> main object more recent than executable"); end if; Linker_Needs_To_Be_Called := True; end if; end if; if Main_Object_TS = Empty_Time_Stamp then Write_Str ("main object for "); Write_Str (Get_Name_String (Main_Source.File)); Write_Line (" does not exist"); Record_Failure (Main_File); return; end if; if Main_Proj = Main_Source.Object_Project then Add_Argument (Get_Name_String (Main_Source.Object), True); else Add_Argument (Get_Name_String (Main_Source.Object_Path), True); end if; -- Add the Leading_Switches if there are any in package Linker declare The_Packages : constant Package_Id := Main_Proj.Decl.Packages; Linker_Package : constant Prj.Package_Id := Prj.Util.Value_Of (Name => Name_Linker, In_Packages => The_Packages, Shared => Main_File.Tree.Shared); Switches : Variable_Value; Switch_List : String_List_Id; Element : String_Element; begin if Linker_Package /= No_Package then declare Switches_Array : constant Array_Element_Id := Prj.Util.Value_Of (Name => Name_Leading_Switches, In_Arrays => Main_File.Tree.Shared.Packages.Table (Linker_Package).Decl.Arrays, Shared => Main_File.Tree.Shared); Option : String_Access; begin Switches := Prj.Util.Value_Of (Index => Name_Id (Main_Id), Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared); if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => Main_Source.Language.Name, Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared, Force_Lower_Case_Index => True); end if; if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => All_Other_Names, Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared, Force_Lower_Case_Index => True); end if; case Switches.Kind is when Undefined | Single => null; when Prj.List => Switch_List := Switches.Values; while Switch_List /= Nil_String loop Element := Main_File.Tree.Shared.String_Elements.Table (Switch_List); Get_Name_String (Element.Value); if Name_Len > 0 then Option := new String'(Name_Buffer (1 .. Name_Len)); Add_Argument (Option.all, True); end if; Switch_List := Element.Next; end loop; end case; end; end if; end; Find_Binding_Languages (Main_File.Tree, Main_File.Project); if Builder_Data (Main_File.Tree).There_Are_Binder_Drivers then First_Object_Index := Last_Argument + 1; Binding_Options.Init; B_Data := Builder_Data (Main_File.Tree).Binding; while B_Data /= null loop declare Exchange_File_Name : constant String := Binder_Exchange_File_Name (Main_Base_Name_Index, B_Data.Binder_Prefix).all; begin if Is_Regular_File (Exchange_File_Name) then Binder_Exchange_TS := File_Stamp (Path_Name_Type'(Create_Name (Exchange_File_Name))); if not Linker_Needs_To_Be_Called and then String (Binder_Exchange_TS) > String (Executable_TS) then Linker_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Str (" -> binder exchange file """); Write_Str (Exchange_File_Name); Write_Line (""" is more recent than executable"); end if; end if; Open (Exchange_File, In_File, Exchange_File_Name); while not End_Of_File (Exchange_File) loop Get_Line (Exchange_File, Line, Last); if Last > 0 then if Line (1) = '[' then Section := Get_Binding_Section (Line (1 .. Last)); else case Section is when Generated_Object_File => Binder_Object_TS := File_Stamp (Path_Name_Type' (Create_Name (Line (1 .. Last)))); Add_Argument (Line (1 .. Last), Opt.Verbose_Mode); when Bound_Object_Files => if Normalize_Pathname (Line (1 .. Last), Case_Sensitive => False) /= Normalize_Pathname (Get_Name_String (Main_Source.Object_Path), Case_Sensitive => False) and then not Is_In_Library_Project (Line (1 .. Last)) then Add_Argument (Line (1 .. Last), Opt.Verbose_Mode); end if; when Resulting_Options => if Line (1 .. Last) /= "-static" and then Line (1 .. Last) /= "-shared" then Binding_Options.Append (new String'(Line (1 .. Last))); end if; when Gprexch.Run_Path_Option => if Opt.Run_Path_Option and then Main_Proj.Config.Run_Path_Option /= No_Name_List then Add_Rpath (Line (1 .. Last)); Add_Rpath (Shared_Libgcc_Dir (Line (1 .. Last))); end if; when others => null; end case; end if; end if; end loop; Close (Exchange_File); if Binder_Object_TS = Empty_Time_Stamp then if not Linker_Needs_To_Be_Called and then Opt.Verbose_Mode then Write_Line (" -> no binder generated object file"); end if; Write_Str ("no binder generated object file for "); Write_Line (Get_Name_String (Main_File.File)); Record_Failure (Main_File); return; elsif not Linker_Needs_To_Be_Called and then String (Binder_Object_TS) > String (Executable_TS) then Linker_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> binder generated object is more " & "recent than executable"); end if; end if; else Write_Str ("binder exchange file "); Write_Str (Exchange_File_Name); Write_Line (" does not exist"); Record_Failure (Main_File); return; end if; end; B_Data := B_Data.Next; end loop; Last_Object_Index := Last_Argument; end if; -- Add the global archive, if there is one if Global_Archive_Exists then Global_Archive_TS := File_Stamp (Path_Name_Type' (Create_Name (Global_Archive_Name (Main_Proj)))); if Global_Archive_TS = Empty_Time_Stamp then if not Linker_Needs_To_Be_Called and then Opt.Verbose_Mode then Write_Line (" -> global archive does not exist"); end if; Write_Str ("global archive for project file "); Write_Str (Get_Name_String (Main_Proj.Name)); Write_Line (" does not exist"); end if; end if; if not Linker_Needs_To_Be_Called and then Global_Archive_Has_Been_Built then Linker_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> global archive has just been built"); end if; end if; if not Linker_Needs_To_Be_Called and then Global_Archive_Exists and then String (Global_Archive_TS) > String (Executable_TS) then Linker_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Line (" -> global archive is more recent than " & "executable"); end if; end if; -- Check if there are library files that are more recent than -- executable. declare List : Project_List := Main_Proj.All_Imported_Projects; Proj : Project_Id; Current_Dir : constant String := Get_Current_Dir; begin while List /= null loop Proj := List.Project; List := List.Next; if Proj.Extended_By = No_Project and then Proj.Library and then Proj.Object_Directory /= No_Path_Information and then (Proj.Library_Kind = Static or else Proj.Standalone_Library = No) then -- Put the full path name of the library file in Name_Buffer Get_Name_String (Proj.Library_Dir.Display_Name); if Proj.Library_Kind = Static then Add_Str_To_Name_Buffer ("lib"); Add_Str_To_Name_Buffer (Get_Name_String (Proj.Library_Name)); if Proj.Config.Archive_Suffix = No_File then Add_Str_To_Name_Buffer (".a"); else Add_Str_To_Name_Buffer (Get_Name_String (Proj.Config.Archive_Suffix)); end if; else -- Shared libraries if Proj.Config.Shared_Lib_Prefix = No_File then Add_Str_To_Name_Buffer ("lib"); else Add_Str_To_Name_Buffer (Get_Name_String (Proj.Config.Shared_Lib_Prefix)); end if; Add_Str_To_Name_Buffer (Get_Name_String (Proj.Library_Name)); if Proj.Config.Shared_Lib_Suffix = No_File then Add_Str_To_Name_Buffer (".so"); else Add_Str_To_Name_Buffer (Get_Name_String (Proj.Config.Shared_Lib_Suffix)); end if; end if; -- Check that library file exists and that it is not more -- recent than the executable. declare Lib_TS : constant Time_Stamp_Type := File_Stamp (File_Name_Type'(Name_Find)); begin if Lib_TS = Empty_Time_Stamp then Linker_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Str (" -> library file """); Write_Str (Name_Buffer (1 .. Name_Len)); Write_Line (""" not found"); end if; exit; elsif String (Lib_TS) > String (Executable_TS) then Linker_Needs_To_Be_Called := True; if Opt.Verbose_Mode then Write_Str (" -> library file """); Write_Str (Name_Buffer (1 .. Name_Len)); Write_Line (""" is more recent than executable"); end if; exit; end if; end; end if; end loop; Change_Dir (Current_Dir); end; if not Linker_Needs_To_Be_Called then if Opt.Verbose_Mode then Write_Line (" -> up to date"); elsif not Opt.Quiet_Output then Inform (Exec_Name, "up to date"); end if; else if Global_Archive_Exists then Add_Argument (Global_Archive_Name (Main_Proj), Opt.Verbose_Mode); end if; -- Add the library switches, if there are libraries Process_Imported_Libraries (Main_Proj, There_Are_SALs => Disregard); Library_Dirs.Reset; for J in reverse 1 .. Library_Projs.Last loop if not Library_Projs.Table (J).Is_Aggregated then if Library_Projs.Table (J).Proj.Library_Kind = Static then Add_Argument (Get_Name_String (Library_Projs.Table (J).Proj.Library_Dir.Display_Name) & "lib" & Get_Name_String (Library_Projs.Table (J).Proj.Library_Name) & Archive_Suffix (Library_Projs.Table (J).Proj), Opt.Verbose_Mode); else -- Do not issue several time the same -L switch if -- several library projects share the same library -- directory. if not Library_Dirs.Get (Library_Projs.Table (J).Proj.Library_Dir.Name) then Library_Dirs.Set (Library_Projs.Table (J).Proj.Library_Dir.Name, True); if Main_Proj.Config.Linker_Lib_Dir_Option = No_Name then Add_Argument ("-L" & Get_Name_String (Library_Projs.Table (J). Proj.Library_Dir.Display_Name), Opt.Verbose_Mode); else Add_Argument (Get_Name_String (Main_Proj.Config.Linker_Lib_Dir_Option) & Get_Name_String (Library_Projs.Table (J). Proj.Library_Dir.Display_Name), Opt.Verbose_Mode); end if; if Opt.Run_Path_Option and then Main_Proj.Config.Run_Path_Option /= No_Name_List and then Library_Projs.Table (J).Proj.Library_Kind /= Static then Add_Rpath (Get_Name_String (Library_Projs.Table (J).Proj.Library_Dir.Display_Name)); end if; end if; if Main_Proj.Config.Linker_Lib_Name_Option = No_Name then Add_Argument ("-l" & Get_Name_String (Library_Projs.Table (J).Proj.Library_Name), Opt.Verbose_Mode); else Add_Argument (Get_Name_String (Main_Proj.Config.Linker_Lib_Name_Option) & Get_Name_String (Library_Projs.Table (J).Proj.Library_Name), Opt.Verbose_Mode); end if; end if; end if; end loop; -- Put the options in the project file, if any declare The_Packages : constant Package_Id := Main_Proj.Decl.Packages; Linker_Package : constant Prj.Package_Id := Prj.Util.Value_Of (Name => Name_Linker, In_Packages => The_Packages, Shared => Main_File.Tree.Shared); Switches : Variable_Value; Switch_List : String_List_Id; Element : String_Element; begin if Linker_Package /= No_Package then declare Defaults : constant Array_Element_Id := Prj.Util.Value_Of (Name => Name_Default_Switches, In_Arrays => Main_File.Tree.Shared.Packages.Table (Linker_Package).Decl.Arrays, Shared => Main_File.Tree.Shared); Switches_Array : constant Array_Element_Id := Prj.Util.Value_Of (Name => Name_Switches, In_Arrays => Main_File.Tree.Shared.Packages.Table (Linker_Package).Decl.Arrays, Shared => Main_File.Tree.Shared); Option : String_Access; begin Switches := Prj.Util.Value_Of (Index => Name_Id (Main_Id), Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared, Allow_Wildcards => True); if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => Main_Source.Language.Name, Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared, Force_Lower_Case_Index => True); end if; if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => All_Other_Names, Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared, Force_Lower_Case_Index => True); end if; if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => Main_Source.Language.Name, Src_Index => 0, In_Array => Defaults, Shared => Main_File.Tree.Shared); end if; case Switches.Kind is when Undefined | Single => null; when Prj.List => Switch_List := Switches.Values; while Switch_List /= Nil_String loop Element := Main_File.Tree.Shared.String_Elements.Table (Switch_List); Get_Name_String (Element.Value); if Name_Len > 0 then Option := new String'(Name_Buffer (1 .. Name_Len)); Test_If_Relative_Path (Option, Main_Project_Dir.all, Dash_L); Add_Argument (Option.all, True); end if; Switch_List := Element.Next; end loop; end case; end; end if; end; -- Get the Linker_Options, if any Get_Linker_Options (For_Project => Main_Proj); -- Add the linker switches specified on the command line for J in 1 .. Command_Line_Linker_Options.Last loop Add_Argument (Command_Line_Linker_Options.Table (J), Opt.Verbose_Mode); end loop; -- Then the binding options for J in 1 .. Binding_Options.Last loop Add_Argument (Binding_Options.Table (J), Opt.Verbose_Mode); end loop; -- Then the required switches, if any. These are put here because, -- if they include -L switches for example, the link may fail because -- the wrong objects or libraries are linked in. Min_Linker_Opts := Main_Proj.Config.Trailing_Linker_Required_Switches; while Min_Linker_Opts /= No_Name_List loop Add_Argument (Get_Name_String (Main_File.Tree.Shared.Name_Lists.Table (Min_Linker_Opts).Name), Opt.Verbose_Mode); Min_Linker_Opts := Main_File.Tree.Shared.Name_Lists.Table (Min_Linker_Opts).Next; end loop; -- Finally the Trailing_Switches if there are any in package Linker. -- They are put here so that it is possible to override the required -- switches from the configuration project file. declare The_Packages : constant Package_Id := Main_Proj.Decl.Packages; Linker_Package : constant Prj.Package_Id := Prj.Util.Value_Of (Name => Name_Linker, In_Packages => The_Packages, Shared => Main_File.Tree.Shared); Switches : Variable_Value; Switch_List : String_List_Id; Element : String_Element; begin if Linker_Package /= No_Package then declare Switches_Array : constant Array_Element_Id := Prj.Util.Value_Of (Name => Name_Trailing_Switches, In_Arrays => Main_File.Tree.Shared.Packages.Table (Linker_Package).Decl.Arrays, Shared => Main_File.Tree.Shared); Option : String_Access; begin Switches := Prj.Util.Value_Of (Index => Name_Id (Main_Id), Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared); if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => Main_Source.Language.Name, Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared, Force_Lower_Case_Index => True); end if; if Switches = Nil_Variable_Value then Switches := Prj.Util.Value_Of (Index => All_Other_Names, Src_Index => 0, In_Array => Switches_Array, Shared => Main_File.Tree.Shared, Force_Lower_Case_Index => True); end if; case Switches.Kind is when Undefined | Single => null; when Prj.List => Switch_List := Switches.Values; while Switch_List /= Nil_String loop Element := Main_File.Tree.Shared.String_Elements.Table (Switch_List); Get_Name_String (Element.Value); if Name_Len > 0 then Option := new String'(Name_Buffer (1 .. Name_Len)); Add_Argument (Option.all, True); end if; Switch_List := Element.Next; end loop; end case; end; end if; end; -- Remove duplicate stack size setting coming from pragmas -- Linker_Options or Link_With and linker switches ("-Xlinker -- --stack=R,C" or "-Wl,--stack=R"). Only the first stack size -- setting option should be taken into account, because the one in -- the project file or on the command line will always be the first -- one. And any subsequent stack setting option will overwrite the -- previous one. Clean_Link_Option_Set : declare J : Natural := Last_Object_Index + 1; Stack_Op : Boolean := False; begin while J <= Last_Argument loop -- Check for two switches "-Xlinker" followed by "--stack=..." if Arguments (J).all = "-Xlinker" and then J < Last_Argument and then Arguments (J + 1)'Length > 8 and then Arguments (J + 1) (1 .. 8) = "--stack=" then if Stack_Op then Arguments (J .. Last_Argument - 2) := Arguments (J + 2 .. Last_Argument); Last_Argument := Last_Argument - 2; else Stack_Op := True; end if; end if; -- Check for single switch if (Arguments (J)'Length > 17 and then Arguments (J) (1 .. 17) = "-Xlinker --stack=") or else (Arguments (J)'Length > 12 and then Arguments (J) (1 .. 12) = "-Wl,--stack=") then if Stack_Op then Arguments (J .. Last_Argument - 1) := Arguments (J + 1 .. Last_Argument); Last_Argument := Last_Argument - 1; else Stack_Op := True; end if; end if; J := J + 1; end loop; end Clean_Link_Option_Set; -- Look for the last switch -shared-libgcc or -static-libgcc and -- remove all the others. declare Dash_Shared_Libgcc : Boolean := False; Dash_Static_Libgcc : Boolean := False; Arg : Natural; procedure Remove_Argument; -- Remove Arguments (Arg) procedure Remove_Argument is begin Arguments (Arg .. Last_Argument - 1) := Arguments (Arg + 1 .. Last_Argument); Last_Argument := Last_Argument - 1; end Remove_Argument; begin Arg := Last_Argument; loop if Arguments (Arg).all = "-shared-libgcc" then if Dash_Shared_Libgcc or Dash_Static_Libgcc then Remove_Argument; else Dash_Shared_Libgcc := True; end if; elsif Arguments (Arg).all = "-static-libgcc" then if Dash_Shared_Libgcc or Dash_Static_Libgcc then Remove_Argument; else Dash_Static_Libgcc := True; end if; end if; Arg := Arg - 1; exit when Arg = 0; end loop; -- If -shared-libgcc was the last switch, then put in the -- run path option the shared libgcc dir. if Dash_Shared_Libgcc and then Opt.Run_Path_Option and then Main_Proj.Config.Run_Path_Option /= No_Name_List then -- Look for the adalib directory in -L switches. -- If it is found, then add the shared libgcc -- directory to the run path option. for J in 1 .. Last_Argument loop declare Option : String (1 .. Arguments (J)'Length); Last : Natural := Option'Last; begin Option := Arguments (J).all; if Last > 2 and then Option (1 .. 2) = "-L" then if Option (Last) = '/' or else Option (Last) = Directory_Separator then Last := Last - 1; end if; if Last > 10 and then Option (Last - 5 .. Last) = "adalib" then Add_Rpath (Shared_Libgcc_Dir (Option (3 .. Last))); exit; end if; end if; end; end loop; end if; end; -- Add the run path option, if necessary if Opt.Run_Path_Option and then Main_Proj.Config.Run_Path_Option /= No_Name_List and then Rpaths.Last > 0 then declare Nam_Nod : Name_Node := Main_File.Tree.Shared.Name_Lists.Table (Main_Proj.Config.Run_Path_Option); Length : Natural := 0; Arg : String_Access := null; begin if Main_Proj.Config.Run_Path_Origin /= No_Name and then Get_Name_String (Main_Proj.Config.Run_Path_Origin) /= "" then Rpaths_Relative_To (Main_Proj.Exec_Directory.Display_Name, Main_Proj.Config.Run_Path_Origin); end if; if Main_Proj.Config.Separate_Run_Path_Options then for J in 1 .. Rpaths.Last loop Nam_Nod := Main_File.Tree.Shared.Name_Lists.Table (Main_Proj.Config.Run_Path_Option); while Nam_Nod.Next /= No_Name_List loop Add_Argument (Get_Name_String (Nam_Nod.Name), True); Nam_Nod := Main_File.Tree.Shared.Name_Lists.Table (Nam_Nod.Next); end loop; Get_Name_String (Nam_Nod.Name); Add_Str_To_Name_Buffer (Rpaths.Table (J).all); Add_Argument (Name_Buffer (1 .. Name_Len), Opt.Verbose_Mode); end loop; else while Nam_Nod.Next /= No_Name_List loop Add_Argument (Get_Name_String (Nam_Nod.Name), True); Nam_Nod := Main_File.Tree.Shared.Name_Lists.Table (Nam_Nod.Next); end loop; -- Compute the length of the argument Get_Name_String (Nam_Nod.Name); Length := Name_Len; for J in 1 .. Rpaths.Last loop Length := Length + Rpaths.Table (J)'Length + 1; end loop; Length := Length - 1; -- Create the argument Arg := new String (1 .. Length); Length := Name_Len; Arg (1 .. Name_Len) := Name_Buffer (1 .. Name_Len); for J in 1 .. Rpaths.Last loop if J /= 1 then Length := Length + 1; Arg (Length) := Path_Separator; end if; Arg (Length + 1 .. Length + Rpaths.Table (J)'Length) := Rpaths.Table (J).all; Length := Length + Rpaths.Table (J)'Length; end loop; Add_Argument (Arg, Opt.Verbose_Mode); end if; end; end if; -- Add the map file option, if supported and requested if Map_File /= null and then Main_Proj.Config.Map_File_Option /= No_Name then Get_Name_String (Main_Proj.Config.Map_File_Option); if Map_File'Length > 0 then Add_Str_To_Name_Buffer (Map_File.all); else Add_Str_To_Name_Buffer (Get_Name_String (Main_Base_Name_Index)); Add_Str_To_Name_Buffer (".map"); end if; Add_Argument (Name_Buffer (1 .. Name_Len), Opt.Verbose_Mode); end if; -- Add the switch(es) to specify the name of the executable declare List : Name_List_Index := Main_Proj.Config.Linker_Executable_Option; Nam : Name_Node; procedure Add_Executable_Name; -- Add the name of the executable to to current name buffer, -- then the content of the name buffer as the next argument. ------------------------- -- Add_Executable_Name -- ------------------------- procedure Add_Executable_Name is begin Add_Str_To_Name_Buffer (Get_Name_String (Exec_Path_Name)); Add_Argument (Name_Buffer (1 .. Name_Len), True, Simple_Name => not Opt.Verbose_Mode); end Add_Executable_Name; begin if List /= No_Name_List then loop Nam := Main_File.Tree.Shared.Name_Lists.Table (List); Get_Name_String (Nam.Name); if Nam.Next = No_Name_List then Add_Executable_Name; exit; else Add_Argument (Name_Buffer (1 .. Name_Len), True); end if; List := Nam.Next; end loop; else Add_Argument ("-o", True); Name_Len := 0; Add_Executable_Name; end if; end; -- If response file are supported, check the length of the -- command line and the number of object files, then create -- a response file if needed. if Main_Proj.Config.Max_Command_Line_Length > 0 and then Main_Proj.Config.Resp_File_Format /= Prj.None and then First_Object_Index > 0 then declare Arg_Length : Natural := 0; Min_Number_Of_Objects : Natural := 0; begin for J in 1 .. Last_Argument loop Arg_Length := Arg_Length + Arguments (J)'Length + 1; end loop; if Arg_Length > Main_Proj.Config.Max_Command_Line_Length then if Main_Proj.Config.Resp_File_Options = No_Name_List then Min_Number_Of_Objects := 0; else Min_Number_Of_Objects := 1; end if; -- Don't create a project file if there would not be -- a smaller number of arguments. if Last_Object_Index - First_Object_Index + 1 > Min_Number_Of_Objects then declare Resp_File_Options : String_List_Access := new String_List (1 .. 0); List : Name_List_Index := Main_Proj.Config. Resp_File_Options; Nam_Nod : Name_Node; begin while List /= No_Name_List loop Nam_Nod := Main_File.Tree.Shared.Name_Lists.Table (List); Resp_File_Options := new String_List' (Resp_File_Options.all & new String' (Get_Name_String (Nam_Nod.Name))); List := Nam_Nod.Next; end loop; Create_Response_File (Format => Main_Proj.Config.Resp_File_Format, Objects => Arguments (First_Object_Index .. Last_Object_Index), Other_Arguments => Arguments (Last_Object_Index + 1 .. Last_Argument), Resp_File_Options => Resp_File_Options.all, Name_1 => Response_File_Name, Name_2 => Response_2); if Main_Proj.Config.Resp_File_Format = GCC or else Main_Proj.Config.Resp_File_Format = GCC_GNU or else Main_Proj.Config.Resp_File_Format = GCC_Object_List or else Main_Proj.Config.Resp_File_Format = GCC_Option_List then Arguments (First_Object_Index) := new String'("@" & Get_Name_String (Response_File_Name)); Last_Argument := First_Object_Index; else -- Replace the first object file arguments -- with the argument(s) specifying the -- response file. No need to update -- Arguments_Displayed, as the values are -- already correct (= Verbose_Mode). if Resp_File_Options'Length = 0 then Arguments (First_Object_Index) := new String'(Get_Name_String (Response_File_Name)); First_Object_Index := First_Object_Index + 1; else for J in Resp_File_Options'First .. Resp_File_Options'Last - 1 loop Arguments (First_Object_Index) := Resp_File_Options (J); First_Object_Index := First_Object_Index + 1; end loop; Arguments (First_Object_Index) := new String'(Resp_File_Options (Resp_File_Options'Last).all & Get_Name_String (Response_File_Name)); First_Object_Index := First_Object_Index + 1; end if; -- And put the arguments following the object -- files immediately after the response file -- argument(s). Update Arguments_Displayed -- too. Arguments (First_Object_Index .. Last_Argument - Last_Object_Index + First_Object_Index - 1) := Arguments (Last_Object_Index + 1 .. Last_Argument); Arguments_Displayed (First_Object_Index .. Last_Argument - Last_Object_Index + First_Object_Index - 1) := Arguments_Displayed (Last_Object_Index + 1 .. Last_Argument); Last_Argument := Last_Argument - Last_Object_Index + First_Object_Index - 1; end if; end; end if; end if; end; end if; -- Delete an eventual executable, in case it is a symbolic -- link as we don't want to modify the target of the link. declare Dummy : Boolean; pragma Unreferenced (Dummy); begin Delete_File (Get_Name_String (Exec_Path_Name), Dummy); end; Display_Command (Linker_Name.all, Linker_Path); declare Pid : Process_Id; begin Pid := Non_Blocking_Spawn (Linker_Path.all, Arguments (1 .. Last_Argument)); if Pid = Invalid_Pid then Record_Failure (Main_File); else Add_Process (Pid, (Linking, Pid, Main_File, Response_File_Name, Response_2)); Display_Processes ("link"); end if; end; end if; end Link_Main; --------- -- Run -- --------- procedure Run is Main : Main_Info; procedure Do_Link (Project : Project_Id; Tree : Project_Tree_Ref); procedure Await_Link; procedure Wait_For_Available_Slot; ---------------- -- Await_Link -- ---------------- procedure Await_Link is Data : Process_Data; OK : Boolean; begin loop Await_Process (Data, OK); if Data /= No_Process_Data then if not OK then Record_Failure (Data.Main); elsif Data.Response_1 /= No_Path and then not Debug.Debug_Flag_N then declare Dont_Care : Boolean; pragma Warnings (Off, Dont_Care); begin Delete_File (Get_Name_String (Data.Response_1), Dont_Care); if Data.Response_2 /= No_Path then Delete_File (Get_Name_String (Data.Response_2), Dont_Care); end if; end; end if; Display_Processes ("link"); return; end if; end loop; end Await_Link; ------------- -- Do_Link -- ------------- procedure Do_Link (Project : Project_Id; Tree : Project_Tree_Ref) is pragma Unreferenced (Project); Main_File : Main_Info; begin if Builder_Data (Tree).Need_Linking and then not Stop_Spawning then Mains.Reset; loop Main_File := Mains.Next_Main; exit when Main_File = No_Main_Info; if Main_File.Tree = Tree and then not Project_Compilation_Failed (Main_File.Project) then Wait_For_Available_Slot; exit when Stop_Spawning; Link_Main (Main_File); exit when Stop_Spawning; end if; end loop; end if; end Do_Link; procedure Link_All is new For_Project_And_Aggregated (Do_Link); ----------------------------- -- Wait_For_Available_Slot -- ----------------------------- procedure Wait_For_Available_Slot is begin while Outstanding_Processes >= Opt.Maximum_Processes loop Await_Link; end loop; end Wait_For_Available_Slot; begin Outstanding_Processes := 0; Stop_Spawning := False; Link_All (Main_Project, Project_Tree); while Outstanding_Processes > 0 loop Await_Link; end loop; if Bad_Processes.Last = 1 then Main := Bad_Processes.Table (1); Fail_Program (Main.Tree, "link of " & Get_Name_String (Main.File) & " failed"); elsif Bad_Processes.Last > 1 then for J in 1 .. Bad_Processes.Last loop Main := Bad_Processes.Table (J); Write_Str (" link of "); Write_Str (Get_Name_String (Main.File)); Write_Line (" failed"); end loop; Fail_Program (Main.Tree, "*** link phase failed"); end if; end Run; end Gprbuild.Link; gprbuild-gpl-2014-src/src/gprinstall-main.adb0000644000076700001450000006462612323721731020511 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Command_Line; use Ada.Command_Line; with Ada.Directories; with Ada.Exceptions; use Ada.Exceptions; with GNAT.Case_Util; use GNAT.Case_Util; with GNAT.Command_Line; use GNAT.Command_Line; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.OS_Lib; use GNAT.OS_Lib; with Atree; use Atree; with Csets; with Gpr_Util; use Gpr_Util; with GPR_Version; use GPR_Version; with Hostparm; with Makeutl; use Makeutl; with Namet; use Namet; with Osint; use Osint; with Output; use Output; with Prj.Conf; use Prj.Conf; with Prj.Env; with Prj.Err; with Prj.Tree; use Prj.Tree; with Snames; use Snames; with Stringt; with Switch; use Switch; with Opt; use Opt; with Types; use Types; with Gprinstall.DB; with Gprinstall.Install; with Gprinstall.Uninstall; procedure Gprinstall.Main is use Gpr_Util.Knowledge; -- Options specific to gprinstall Build_Var_Option : constant String := "--build-var"; Build_Name_Option : constant String := "--build-name"; Install_Name_Option : constant String := "--install-name"; Uninstall_Option : constant String := "--uninstall"; Mode_Option : constant String := "--mode="; Lib_Subdir_Option : constant String := "--lib-subdir"; Link_Lib_Subdir_Option : constant String := "--link-lib-subdir"; Exec_Subdir_Option : constant String := "--exec-subdir"; Sources_Subdir_Option : constant String := "--sources-subdir"; Project_Subdir_Option : constant String := "--project-subdir"; No_Lib_Link_Option : constant String := "--no-lib-link"; List_Option : constant String := "--list"; Stat_Option : constant String := "--stat"; procedure Initialize; -- Do the necessary package intialization and process the command line -- arguments. procedure Usage; -- Display the usage procedure Scan_Arg (Arg : String; Command_Line : Boolean; Success : out Boolean); -- Process one gprinstall argument Arg. Command_Line is True if the -- argument is specified on the command line. Optional parameter Additional -- gives additional information about the origin of the argument if it is -- found illegal. procedure Copyright; -- Output the Copyright notice type Sigint_Handler is access procedure; pragma Convention (C, Sigint_Handler); procedure Install_Int_Handler (Handler : Sigint_Handler); pragma Import (C, Install_Int_Handler, "__gnat_install_int_handler"); -- Called by Gnatmake to install the SIGINT handler below procedure Sigint_Intercepted; pragma Convention (C, Sigint_Intercepted); -- Called when the program is interrupted by Ctrl-C to delete the -- temporary mapping files and configuration pragmas files. --------------- -- Copyright -- --------------- procedure Copyright is begin -- Only output the Copyright notice once if not Copyright_Output then Copyright_Output := True; Display_Version ("GPRBUILD", "2012", Version_String => Gpr_Version_String); end if; end Copyright; -------------- -- Scan_Arg -- -------------- procedure Scan_Arg (Arg : String; Command_Line : Boolean; Success : out Boolean) is function Has_Prefix (Name : String) return Boolean; -- Returns True if Arg start with Name procedure Set_Param (P : in out Param; Name : String); -- Set P with value for option Name ---------------- -- Has_Prefix -- ---------------- function Has_Prefix (Name : String) return Boolean is begin pragma Assert (Arg'First = 1); return Arg'Length >= Name'Length and then Arg (1 .. Name'Length) = Name; end Has_Prefix; --------------- -- Set_Param -- --------------- procedure Set_Param (P : in out Param; Name : String) is begin P := (new String' (Ensure_Directory (Arg (Name'Length + 2 .. Arg'Last))), False); end Set_Param; Processed : Boolean := True; begin pragma Assert (Arg'First = 1); Success := True; if Arg'Length = 0 then return; end if; -- If preceding switch was -P, a project file name need to be -- specified, not a switch. if Project_File_Name_Expected then if Arg (1) = '-' then Fail_Program (Project_Tree, "project file name missing after -P"); else Project_File_Name_Expected := False; Project_File_Name := new String'(Arg); end if; -- If preceding switch was -o, an executable name need to be -- specified, not a switch. elsif Search_Project_Dir_Expected then if Arg (1) = '-' then Fail_Program (Project_Tree, "directory name missing after -aP"); else Search_Project_Dir_Expected := False; Prj.Env.Add_Directories (Root_Environment.Project_Path, Arg); end if; elsif Db_Directory_Expected then Db_Directory_Expected := False; Parse_Knowledge_Base (Project_Tree, Arg); -- Set the processor/language for the following switches -- Switches start with '-' elsif Arg (1) = '-' then if Has_Prefix (Source_Info_Option) then Project_Tree.Source_Info_File_Name := new String'(Arg (Source_Info_Option'Length + 1 .. Arg'Last)); elsif Has_Prefix (Config_Project_Option) then if Config_Project_File_Name /= null and then (Autoconf_Specified or else Config_Project_File_Name.all /= Arg (Config_Project_Option'Length + 1 .. Arg'Last)) then Fail_Program (Project_Tree, "several different configuration switches " & "cannot be specified"); else Autoconfiguration := False; Autoconf_Specified := False; Config_Project_File_Name := new String' (Arg (Config_Project_Option'Length + 1 .. Arg'Last)); end if; elsif Has_Prefix (Autoconf_Project_Option) then if Hostparm.OpenVMS then Fail_Program (Project_Tree, Autoconf_Project_Option & " cannot be used on VMS"); end if; if Config_Project_File_Name /= null and then (not Autoconf_Specified or else Config_Project_File_Name.all /= Arg (Autoconf_Project_Option'Length + 1 .. Arg'Last)) then Fail_Program (Project_Tree, "several different configuration switches " & "cannot be specified"); else Config_Project_File_Name := new String' (Arg (Autoconf_Project_Option'Length + 1 .. Arg'Last)); Autoconf_Specified := True; end if; elsif Arg = "-h" then Usage_Needed := True; elsif Arg = "-p" or else Arg = "--create-missing-dirs" then Create_Dest_Dir := True; elsif Arg'Length >= 2 and then Arg (2) = 'P' then if Project_File_Name /= null then Fail_Program (Project_Tree, "cannot have several project files specified"); elsif Arg'Length = 2 then Project_File_Name_Expected := True; else Project_File_Name := new String'(Arg (3 .. Arg'Last)); end if; elsif Arg'Length >= 3 and then Arg (1 .. 3) = "-aP" then if Arg'Length = 3 then Search_Project_Dir_Expected := True; else Prj.Env.Add_Directories (Root_Environment.Project_Path, Arg (4 .. Arg'Last)); end if; elsif Arg = "-q" then Opt.Quiet_Output := True; Opt.Verbose_Mode := False; elsif Arg = "-r" then Recursive := True; elsif Arg = "-v" then Opt.Verbose_Mode := True; Opt.Quiet_Output := False; elsif Arg = "-f" then Force_Installations := True; elsif Arg = "-a" then All_Sources := True; elsif Arg = "-d" then Dry_Run := True; elsif Arg'Length >= 3 and then Arg (2) = 'X' and then Is_External_Assignment (Root_Environment, Arg) then -- Is_External_Assignment has side effects when it returns True null; elsif Arg'Length > 1 and then Arg (2) = '-' then if Has_Prefix (Prefix_Project_Option) then Set_Param (Global_Prefix_Dir, Prefix_Project_Option); elsif Has_Prefix (Exec_Subdir_Option) then Set_Param (Global_Exec_Subdir, Exec_Subdir_Option); elsif Has_Prefix (Lib_Subdir_Option) then Set_Param (Global_Lib_Subdir, Lib_Subdir_Option); elsif Has_Prefix (Link_Lib_Subdir_Option) then Set_Param (Global_Link_Lib_Subdir, Link_Lib_Subdir_Option); elsif Has_Prefix (Sources_Subdir_Option) then Set_Param (Global_Sources_Subdir, Sources_Subdir_Option); elsif Has_Prefix (Project_Subdir_Option) then Set_Param (Global_Project_Subdir, Project_Subdir_Option); elsif Has_Prefix (Build_Var_Option) then Build_Var := new String' (Arg (Build_Var_Option'Length + 2 .. Arg'Last)); elsif Has_Prefix (Build_Name_Option) then Free (Build_Name); Build_Name := new String' (Arg (Build_Name_Option'Length + 2 .. Arg'Last)); elsif Has_Prefix (Install_Name_Option) then Free (Install_Name); Install_Name := new String' (Arg (Install_Name_Option'Length + 2 .. Arg'Last)); Install_Name_Default := False; elsif Has_Prefix (Uninstall_Option) then Usage_Mode := Uninstall_Mode; elsif Has_Prefix (List_Option) then Usage_Mode := List_Mode; elsif Has_Prefix (Stat_Option) then Output_Stats := True; elsif Has_Prefix (Mode_Option) then declare Mode : String := Arg (Mode_Option'Length + 1 .. Arg'Last); begin To_Lower (Mode); if Mode = "dev" then For_Dev := True; elsif Mode = "usage" then For_Dev := False; else Processed := False; end if; end; elsif Has_Prefix (Dry_Run_Option) then Dry_Run := True; elsif Has_Prefix (No_Lib_Link_Option) then Add_Lib_Link := False; elsif Has_Prefix (Subdirs_Option) then Subdirs := new String'(Arg (Subdirs_Option'Length + 1 .. Arg'Last)); elsif Has_Prefix (Target_Project_Option) then if Target_Name /= null then if Target_Name.all /= Arg (Target_Project_Option'Length + 1 .. Arg'Last) then Fail_Program (Project_Tree, "several different target switches " & "cannot be specified"); end if; else Target_Name := new String' (Arg (Target_Project_Option'Length + 1 .. Arg'Last)); end if; else Processed := False; end if; else Processed := False; end if; elsif Command_Line then -- The file name of a main or a project file declare File_Name : String := Arg; begin Canonical_Case_File_Name (File_Name); if Usage_Mode = Uninstall_Mode or else (File_Name'Length > Project_File_Extension'Length and then File_Name (File_Name'Last - Project_File_Extension'Length + 1 .. File_Name'Last) = Project_File_Extension) then if Project_File_Name /= null then Fail_Program (Project_Tree, "cannot have several project files specified"); else Project_File_Name := new String'(File_Name); end if; else -- Not a project file, then it is a main Fail_Program (Project_Tree, "only project files expected"); end if; end; else Processed := False; end if; if not Processed then if Command_Line then Fail_Program (Project_Tree, "illegal option """ & Arg & """ on the command line"); end if; end if; end Scan_Arg; ------------------------ -- Sigint_Intercepted -- ------------------------ procedure Sigint_Intercepted is begin Write_Line ("*** Interrupted ***"); Delete_All_Temp_Files (Project_Tree.Shared); OS_Exit (1); end Sigint_Intercepted; ---------------- -- Initialize -- ---------------- procedure Initialize is procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage); begin -- Do some necessary package initializations Csets.Initialize; Namet.Initialize; Snames.Initialize; Stringt.Initialize; Prj.Tree.Initialize (Root_Environment, Gprbuild_Flags); Prj.Tree.Initialize (Project_Node_Tree); Prj.Initialize (Project_Tree); Mains.Delete; -- Get the command line arguments, starting with --version and --help Check_Version_And_Help ("GPRINSTALL", "2012", Version_String => Gpr_Version_String); -- Now process the other options Autoconfiguration := True; declare Do_Not_Care : Boolean; begin Scan_Args : for Next_Arg in 1 .. Argument_Count loop Scan_Arg (Argument (Next_Arg), Command_Line => True, Success => Do_Not_Care); end loop Scan_Args; end; Mains.Set_Multi_Unit_Index (Project_Tree, Main_Index); -- Target_Name has potentially been set when calling Scan_Arg, so we can -- only initialize the project path after parsing the command line -- arguments. if Target_Name = null then Prj.Env.Initialize_Default_Project_Path (Root_Environment.Project_Path, Target_Name => ""); else Prj.Env.Initialize_Default_Project_Path (Root_Environment.Project_Path, Target_Name.all); end if; if Opt.Verbose_Mode then Copyright; end if; if Usage_Needed then Usage; Usage_Needed := False; end if; -- Fail if command line ended with "-P" if Project_File_Name_Expected then Fail_Program (Project_Tree, "project file name missing after -P"); elsif Search_Project_Dir_Expected then Fail_Program (Project_Tree, "directory name missing after -aP"); end if; if Build_Name.all /= "default" and then Usage_Mode = Uninstall_Mode then Fail_Program (Project_Tree, "cannot specify --build-name in uninstall mode"); end if; if Build_Var /= null and then Usage_Mode = Uninstall_Mode then Fail_Program (Project_Tree, "cannot specify --build-var in uninstall mode"); end if; if Output_Stats and then Usage_Mode /= List_Mode then Fail_Program (Project_Tree, "cannot specify --stat in install/uninstall mode"); end if; if Load_Standard_Base then -- We need to parse the knowledge base so that we are able to -- normalize the target names. Unfortunately, if we have to spawn -- gprconfig, it will also have to parse that knowledge base on -- its own. Parse_Knowledge_Base (Project_Tree); end if; -- If no project file was specified, look first for a default if Project_File_Name = null and then Usage_Mode /= List_Mode then Try_Help; Fail_Program (Project_Tree, "no project file specified"); end if; -- Check prefix, if not specified set to default toolchain if Global_Prefix_Dir.V = null then -- Set to default for current toolchain Global_Prefix_Dir := (new String'(Executable_Prefix_Path), True); end if; end Initialize; ----------- -- Usage -- ----------- procedure Usage is begin if not Usage_Output then Usage_Output := True; Write_Str ("Usage: "); Osint.Write_Program_Name; Write_Str (" [-P] [.gpr] [opts]"); Write_Eol; Write_Eol; -- GPRINSTALL switches Write_Str ("gprinstall switches:"); Write_Eol; Display_Usage_Version_And_Help; -- Line for Config_Project_Option Write_Str (" "); Write_Str (Config_Project_Option); Write_Str ("file.cgpr"); Write_Eol; Write_Str (" Specify the main config project file name"); Write_Eol; -- Line for Autoconf_Project_Option if not Hostparm.OpenVMS then Write_Str (" "); Write_Str (Autoconf_Project_Option); Write_Str ("file.cgpr"); Write_Eol; Write_Str (" Specify/create the main config project file name"); Write_Eol; end if; -- Line for --prefix Write_Line (" --prefix="); Write_Line (" Install destination directory"); Write_Line (" --install-name="); Write_Line (" The name of the installation"); Write_Line (" --sources-subdir="); Write_Line (" The sources directory/sub-directory"); Write_Line (" --lib-subdir="); Write_Line (" The library directory/sub-directory"); Write_Line (" --link-lib-subdir="); Write_Line (" The symlib directory/sub-directory to libraries"); Write_Line (" --exec-subdir="); Write_Line (" The executbales directory/sub-directory"); Write_Line (" --project-subdir="); Write_Line (" The project directory/sub-directory"); Write_Line (" --no-lib-link"); Write_Line (" Do not copy shared lib in exec/lib directory"); -- Line for --subdirs= Write_Line (" --subdirs=dir"); Write_Line (" Real obj/lib/exec dirs are subdirs"); -- Line for Target_Project_Option Write_Str (" "); Write_Str (Target_Project_Option); Write_Str ("targetname"); Write_Eol; Write_Str (" Specify a target for cross platforms"); Write_Eol; -- Line for --dry-run Write_Line (" -d, --dry-run"); Write_Line (" Execute nothing, display commands"); -- Line for --build-var Write_Line (" --build-var="); Write_Line (" Name of the variable which identify a build"); -- Line for --build-name Write_Line (" --build-name="); Write_Line (" Build name value (default is ""Default"")"); -- Line for --mode Write_Line (" --mode=[dev|usage]"); Write_Line (" Kind of installation (default is ""dev"")"); -- Line for --uninstall Write_Line (" --uninstall"); Write_Line (" Remove all previously installed files"); -- Line for -aP Write_Line (" -aP dir Add directory dir to project search path"); -- Line for -eL Write_Line (" -eL " & "Follow symbolic links when processing project files"); -- Line for -P Write_Line (" -P proj Use Project File proj"); -- Line for -p Write_Line (" -p, --create-missing-dirs"); Write_Line (" Create missing directories"); -- Line for -q Write_Line (" -q Be quiet/terse"); -- Line for -r Write_Line (" -r Recursive"); -- Line for -a Write_Line (" -a Force copy of all sources"); -- Line for -f Write_Line (" -f Force installaion, overwrite files"); -- Line for -v Write_Line (" -v Verbose output"); -- Line for -X Write_Line (" -Xnm=val Specify an external reference for " & "Project Files"); Write_Eol; end if; end Usage; User_Project_Node : Project_Node_Id; begin -- First initialize and read the command line arguments Initialize; -- And install Ctrl-C handler Install_Int_Handler (Sigint_Intercepted'Unrestricted_Access); -- Check command line arguments. These will be overridden when looking -- for the configuration file if Target_Name = null then Target_Name := new String'(""); end if; if Config_Project_File_Name = null then Config_Project_File_Name := new String'(""); end if; -- Then, parse the user's project and the configuration file. Apply the -- configuration file to the project so that its settings are -- automatically inherited by the project. -- If either the project or the configuration file contains errors, the -- following call with call Osint.Fail and never return if Usage_Mode = Install_Mode then begin Parse_Project_And_Apply_Config (Main_Project => Main_Project, User_Project_Node => User_Project_Node, Config_File_Name => Config_Project_File_Name.all, Autoconf_Specified => Autoconf_Specified, Project_File_Name => Project_File_Name.all, Project_Tree => Project_Tree, Env => Root_Environment, Project_Node_Tree => Project_Node_Tree, Packages_To_Check => Packages_To_Check, Allow_Automatic_Generation => Autoconfiguration, Automatically_Generated => Delete_Autoconf_File, Config_File_Path => Configuration_Project_Path, Target_Name => Target_Name.all, Normalized_Hostname => Normalized_Hostname); exception when E : Prj.Conf.Invalid_Config => Osint.Fail (Exception_Message (E)); end; if Main_Project = No_Project then -- Don't flush messages in case of parsing error. This has already -- been taken care when parsing the tree. Otherwise, it results in -- the same message being displayed twice. Fail_Program (Project_Tree, """" & Project_File_Name.all & """ processing failed", Flush_Messages => User_Project_Node /= Empty_Node); end if; if Configuration_Project_Path /= null then Free (Config_Project_File_Name); Config_Project_File_Name := new String' (Base_Name (Configuration_Project_Path.all)); end if; if Total_Errors_Detected > 0 then Prj.Err.Finalize; Fail_Program (Project_Tree, "problems while getting the configuration", Flush_Messages => False); end if; Main_Project_Dir := new String'(Get_Name_String (Main_Project.Directory.Display_Name)); if Warnings_Detected > 0 then Prj.Err.Finalize; Prj.Err.Initialize; end if; Mains.Fill_From_Project (Main_Project, Project_Tree); Compute_All_Imported_Projects (Main_Project, Project_Tree); -- Source file lookups should be cached for efficiency. -- Source files are not supposed to change. Osint.Source_File_Data (Cache => True); Install.Process (Project_Tree, Main_Project); if Warnings_Detected /= 0 then Prj.Err.Finalize; end if; elsif Usage_Mode = List_Mode then DB.List; else if Install_Name = null then Install_Name := new String' (Ada.Directories.Base_Name (Project_File_Name.all)); end if; Uninstall.Process (Install_Name.all); end if; Namet.Finalize; if Usage_Mode = Install_Mode then Finish_Program (Project_Tree, E_Success); end if; end Gprinstall.Main; gprbuild-gpl-2014-src/src/gprbuild-compilation-process.ads0000644000076700001450000001062412323721731023216 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . P R O C E S S -- -- -- -- S p e c -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This package abstract out a process which can be either local or remote. -- The communication with the remote instances are done through sockets. with GNAT.OS_Lib; package Gprbuild.Compilation.Process is type Id is private; type Remote_Id is mod 2 ** 64; -- Represent a remote process id, this number is unique across all slaves. -- Such number if created by the slaves using a slave id (unique number) -- and a compilation number. Bother numbers are 32bits value: -- -- 63 32 31 0 -- | [slave id] | [compilation number] | Invalid_Process : constant Id; function Create_Local (Pid : GNAT.OS_Lib.Process_Id) return Id; -- Returns a local process for Pid function Create_Remote (Pid : Remote_Id) return Id; -- Returns a remote process (one running on a slave) for Pid procedure Record_Environment (Project : Project_Id; Language : Name_Id; Name, Value : String); -- Record an environement variable to set when spawning a compilation. This -- is for example to set CPATH if needed for the compilation of C sources. function Run (Executable : String; Options : GNAT.OS_Lib.Argument_List; Project : Project_Id; Obj_Name : String; Language : String := ""; Dep_Name : String := ""; Output_File : String := ""; Err_To_Out : Boolean := False; Force_Local : Boolean := False) return Id; -- Run Executable with the given options locally or on a remote slave. -- Dep_File name is the name of the file that is expected to be generated -- if the compilation is successful. If Force_Local is set then the -- compilation will happen on the local machine. function Get_Maximum_Processes return Positive; -- The maximum number of simultaneous compilation supported. This is the -- sum of the local parallelism and the sum of of remote slaves supported -- processes. -- For the hash table of jobs type Header_Num is range 0 .. 2047; function Hash (Process : Id) return Header_Num; function Image (Pid : Remote_Id) return String; -- Returns the string representation of Pid procedure Record_Remote_Failure (Pid : Id; Slave : String); -- This is to be able to display on which slaves a specific compilation has -- failed. function Get_Slave_For (Pid : Id) return String; -- Returns the slave for the given compilation, or the empty string if the -- compilation was successful or conducted locally. private type Process_Kind is (Local, Remote); type Id (Kind : Process_Kind := Local) is record case Kind is when Local => Pid : Process_Id; when Remote => R_Pid : Remote_Id; end case; end record; Invalid_Process : constant Id := (Local, Pid => Invalid_Pid); end Gprbuild.Compilation.Process; gprbuild-gpl-2014-src/src/gprbuild-compilation-result.ads0000644000076700001450000000404112323721731023052 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . R E S U L T -- -- -- -- S p e c -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Gprbuild.Compilation.Process; use Gprbuild.Compilation.Process; package Gprbuild.Compilation.Result is procedure Add (Process : Id; Status : Boolean; Slave : String := ""); -- Add process Id with the given status into the list of results procedure Wait (Process : out Id; Status : out Boolean); -- Wait for a process to terminate (so a compilation process result) to be -- available and returns the process Id and the corresponding status. end Gprbuild.Compilation.Result; gprbuild-gpl-2014-src/src/gprbuild-compilation-protocol.adb0000644000076700001450000006154412323721731023367 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . P R O T O C O L -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Directories; use Ada.Directories; with Ada.Streams.Stream_IO; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Ada.Strings.Maps.Constants; use Ada.Strings.Maps; with GNAT.Rewrite_Data; with GNAT.String_Split; use GNAT.String_Split; with Gnatvsn; use Gnatvsn; with Gpr_Util; use Gpr_Util; package body Gprbuild.Compilation.Protocol is Args_Sep : constant Character := '|'; -- Channel's argument separator function Image (N : Natural) return String; -- Returns string representation of N without leading space procedure Send_File_Internal (Channel : Communication_Channel; Path_Name : String; Cmd : Command_Kind); -- Send file Path_Name over the channel with rewritting if needed procedure Send_RAW_File_Content (Channel : Communication_Channel; Path_Name : String); -- Send the file content untranslated ---------- -- Args -- ---------- function Args (Cmd : Command) return Argument_List_Access is begin return Cmd.Args; end Args; ------------------- -- Clear_Rewrite -- ------------------- procedure Clear_Rewrite (Channel : in out Communication_Channel) is begin Channel.WD_From := Null_Unbounded_String; Channel.WD_To := Null_Unbounded_String; Channel.CD_From := Null_Unbounded_String; Channel.CD_To := Null_Unbounded_String; end Clear_Rewrite; ----------- -- Close -- ----------- procedure Close (Channel : in out Communication_Channel) is begin begin -- Make sure we never fail, the other end-point could have already -- closed the channel (hard ctrl-c). Shutdown_Socket (Channel.Sock); exception when others => null; end; Channel.Channel := null; Clear_Rewrite (Channel); end Close; ------------ -- Create -- ------------ function Create (Sock : Socket_Type) return Communication_Channel is begin return Communication_Channel' (Sock, Stream (Sock), Null_Unbounded_String, Null_Unbounded_String, Null_Unbounded_String, Null_Unbounded_String); end Create; ----------------- -- Get_Command -- ----------------- function Get_Command (Channel : Communication_Channel) return Command is use Ada.Streams.Stream_IO; function Handle_File (Cmd : Command) return Command; -- A file has been recieved, write it to disk function Handle_RAW_File (Cmd : Command) return Command; -- A file has been recieved, write it to disk, no rewritte taking place procedure Handle_Output (Cmd : in out Command); -- A display output is received, read it and store it into the command ----------------- -- Handle_File -- ----------------- function Handle_File (Cmd : Command) return Command is File_Name : constant String := Translate_Receive (Channel, Cmd.Args (2).all); Dir : constant String := Containing_Directory (File_Name); procedure Input (Item : out Stream_Element_Array; Last : out Stream_Element_Offset); -- Read and return some data from channel procedure Output (Item : Stream_Element_Array); -- Write data to file Size : Stream_Element_Count := Stream_Element_Count'Value (Cmd.Args (1).all); -- Number of bytes remaining to be read from channel Rewriter : Rewrite_Data.Buffer := Rewrite_Data.Create (To_String (Channel.WD_To), To_String (Channel.WD_From)); Rewriter_CD : aliased Rewrite_Data.Buffer := Rewrite_Data.Create (To_String (Channel.CD_To), To_String (Channel.CD_From)); File : File_Type; ----------- -- Input -- ----------- procedure Input (Item : out Stream_Element_Array; Last : out Stream_Element_Offset) is begin if Size = 0 then Last := 0; else Last := Stream_Element_Count'Min (Item'Length, Size); Stream_Element_Array'Read (Channel.Channel, Item (Item'First .. Last)); Size := Size - Last; end if; end Input; ------------ -- Output -- ------------ procedure Output (Item : Stream_Element_Array) is begin Write (File, Item); end Output; begin Rewrite_Data.Link (Rewriter, Rewriter_CD'Unchecked_Access); if Dir /= "" and then not Exists (Dir) then Create_Directory (Dir); end if; Create (File, Out_File, File_Name); Rewrite_Data.Rewrite (Rewriter, Input'Access, Output'Access); Close (File); return Get_Command (Channel); end Handle_File; --------------------- -- Handle_RAW_File -- --------------------- function Handle_RAW_File (Cmd : Command) return Command is File_Name : constant String := Translate_Receive (Channel, Cmd.Args (1).all); Dir : constant String := Containing_Directory (File_Name); File : File_Type; begin if Dir /= "" and then not Exists (Dir) then Create_Directory (Dir); end if; Create (File, Out_File, File_Name); loop declare Data : constant Stream_Element_Array := Get_Raw_Data (Channel); begin exit when Data'Length = 0; Write (File, Data); end; end loop; Close (File); return Get_Command (Channel); end Handle_RAW_File; ------------------- -- Handle_Output -- ------------------- procedure Handle_Output (Cmd : in out Command) is function Is_Number (Cmd : Command) return Boolean is (Is_Subset (To_Set (Cmd.Args (1).all), Constants.Decimal_Digit_Set)); begin if Cmd.Args'Length = 2 and then Is_Number (Cmd) then declare Size : constant Natural := Natural'Value (Cmd.Args (1).all); Result : String (1 .. Size); begin if Size = 0 then Cmd.Output := Null_Unbounded_String; else String'Read (Channel.Channel, Result); Cmd.Output := To_Unbounded_String (Result); end if; end; else raise Wrong_Command with "Expected DP found " & Command_Kind'Image (Cmd.Cmd); end if; end Handle_Output; Result : Command; Args : Slice_Set; begin declare Line : constant String := String'Input (Channel.Channel); C : constant String := (if Line'Length >= 2 then Line (Line'First .. Line'First + 1) else ""); begin if C in "EX" | "AK" | "TS" | "ES" | "FL" | "FR" | "OK" | "KO" | "CX" | "CU" | "DP" | "EC" then Result.Cmd := Command_Kind'Value (C); -- Slice arguments Create (Args, Line (Line'First + 2 .. Line'Last), String'(1 => Args_Sep)); Result.Args := new Argument_List (1 .. Integer (Slice_Count (Args))); for K in Result.Args'Range loop Result.Args (K) := new String'(Slice (Args, Slice_Number (K))); end loop; if Result.Cmd = FL then -- We got some file data to write return Handle_File (Result); elsif Result.Cmd = FR then return Handle_RAW_File (Result); elsif Result.Cmd = DP then -- We got an output to display Handle_Output (Result); end if; else if Line'Length > 0 then raise Wrong_Command with Line; else raise Wrong_Command with "empty command line"; end if; end if; return Result; end; exception when others => -- Any exception means that the channel has been closed Result.Cmd := EC; return Result; end Get_Command; ----------------- -- Get_Context -- ----------------- procedure Get_Context (Channel : Communication_Channel; Target : out Unbounded_String; Project_Name : out Unbounded_String; Build_Env : out Unbounded_String; Sync : out Sync_Kind; Timestamp : out Time_Stamp_Type; Version : out Unbounded_String) is Line : constant Command := Get_Command (Channel); begin if Line.Cmd = CX and then Line.Args'Length = 6 then Target := To_Unbounded_String (Line.Args (1).all); Project_Name := To_Unbounded_String (Line.Args (2).all); Build_Env := To_Unbounded_String (Line.Args (3).all); Sync := Sync_Kind'Value (Line.Args (4).all); Timestamp := Time_Stamp_Type (Line.Args (5).all); Version := To_Unbounded_String (Line.Args (6).all); else raise Wrong_Command with "Expected CX found " & Command_Kind'Image (Line.Cmd); end if; end Get_Context; ------------- -- Get_Pid -- ------------- procedure Get_Pid (Channel : Communication_Channel; Pid : out Process.Remote_Id; Success : out Boolean) is Cmd : constant Command := Get_Command (Channel); begin if Cmd.Args'Length = 1 and then Cmd.Cmd in OK | KO then Pid := Process.Remote_Id'Value (Cmd.Args (1).all); Success := (if Kind (Cmd) = KO then False); end if; end Get_Pid; ------------------ -- Get_Raw_Data -- ------------------ function Get_Raw_Data (Channel : Communication_Channel) return Stream_Element_Array is begin return Stream_Element_Array'Input (Channel.Channel); end Get_Raw_Data; ----------- -- Image -- ----------- function Image (N : Natural) return String is N_Img : constant String := Natural'Image (N); begin return N_Img (N_Img'First + 1 .. N_Img'Last); end Image; ---------- -- Kind -- ---------- function Kind (Cmd : Command) return Command_Kind is begin return Cmd.Cmd; end Kind; ------------ -- Output -- ------------ function Output (Cmd : Command) return Unbounded_String is begin return Cmd.Output; end Output; -------------- -- Send_Ack -- -------------- procedure Send_Ack (Channel : Communication_Channel; Pid : Process.Remote_Id) is begin String'Output (Channel.Channel, Command_Kind'Image (AK) & Process.Image (Pid)); end Send_Ack; ------------------- -- Send_Clean_Up -- ------------------- procedure Send_Clean_Up (Channel : Communication_Channel; Project_Name : String) is begin String'Output (Channel.Channel, Command_Kind'Image (CU) & Project_Name); end Send_Clean_Up; ------------------ -- Send_Context -- ------------------ procedure Send_Context (Channel : Communication_Channel; Target : String; Project_Name : String; Build_Env : String; Sync : Sync_Kind) is begin String'Output (Channel.Channel, Command_Kind'Image (CX) & Target & Args_Sep & Project_Name & Args_Sep & Build_Env & Args_Sep & Sync_Kind'Image (Sync) & Args_Sep & String (UTC_Time) & Args_Sep & Gnat_Static_Version_String); end Send_Context; ----------------------------- -- Send_End_Of_Compilation -- ----------------------------- procedure Send_End_Of_Compilation (Channel : Communication_Channel) is begin String'Output (Channel.Channel, Command_Kind'Image (EC)); end Send_End_Of_Compilation; --------------------------- -- Send_End_Of_File_List -- --------------------------- procedure Send_End_Of_File_List (Channel : Communication_Channel) is begin String'Output (Channel.Channel, Command_Kind'Image (ES)); end Send_End_Of_File_List; --------------- -- Send_Exec -- --------------- procedure Send_Exec (Channel : Communication_Channel; Project : String; Dir : String; Command : String; Options : Argument_List; Obj_Name : String; Dep_Name : String; Env : String; Filter : access function (Str, Sep : String) return String := null) is R_Cmd : Unbounded_String; begin -- Options are serialized into a string and separated with Opts_Sep for K in Options'Range loop if Filter /= null then R_Cmd := R_Cmd & Filter (Options (K).all, WD_Path_Tag); else R_Cmd := R_Cmd & Options (K).all; end if; if K /= Options'Last then R_Cmd := R_Cmd & Opts_Sep; end if; end loop; -- Send the command over the channel String'Output (Channel.Channel, Command_Kind'Image (EX) & Filter (Project, WD_Path_Tag) & Args_Sep & Dir & Args_Sep & Command & Args_Sep & Obj_Name & Args_Sep & Dep_Name & Args_Sep & To_String (R_Cmd) & Args_Sep & Filter (Env, WD_Path_Tag)); end Send_Exec; --------------- -- Send_File -- --------------- procedure Send_File (Channel : Communication_Channel; Path_Name : String; Rewrite : Boolean) is begin if Rewrite then Send_File_Internal (Channel, Path_Name, FL); else if Exists (Path_Name) then String'Output (Channel.Channel, Command_Kind'Image (FR) & Translate_Send (Channel, Path_Name)); Send_RAW_File_Content (Channel, Path_Name); end if; end if; end Send_File; ---------------- -- Sync_Files -- ---------------- procedure Sync_Files (Channel : Communication_Channel; Root_Dir : String; Files : File_Data_Set.Vector) is begin Create_Args : declare Args : Unbounded_String; First : Boolean := True; begin for F of Files loop if First then First := False; else Append (Args, Args_Sep); end if; Append (Args, F.Path_Name); Append (Args, Args_Sep); Append (Args, String (F.Timestamp)); end loop; String'Output (Channel.Channel, Command_Kind'Image (TS) & To_String (Args)); end Create_Args; declare use Protocol; Cmd : constant Command := Get_Command (Channel); begin if Kind (Cmd) = KO then for Filename of Args (Cmd).all loop Send_RAW_File_Content (Channel, (if Root_Dir = "" then "" else Root_Dir & Directory_Separator) & Filename.all); end loop; end if; end; end Sync_Files; ------------------------ -- Send_File_Internal -- ------------------------ procedure Send_File_Internal (Channel : Communication_Channel; Path_Name : String; Cmd : Command_Kind) is use Ada.Streams.Stream_IO; procedure Input (Item : out Stream_Element_Array; Last : out Stream_Element_Offset); -- Get input data from file procedure Output (Item : Stream_Element_Array); -- Send data to channel function File_Size return Natural; -- Compute the size of the file as rewritten File : File_Type; F_Size : Natural; Rewriter : Rewrite_Data.Buffer := Rewrite_Data.Create (To_String (Channel.WD_From), To_String (Channel.WD_To)); Rewriter_CD : aliased Rewrite_Data.Buffer := Rewrite_Data.Create (To_String (Channel.CD_From), To_String (Channel.CD_To)); --------------- -- File_Size -- --------------- function File_Size return Natural is procedure Count (Item : Stream_Element_Array); -- Count bytes Result : Natural := Natural (Size (Path_Name)); ----------- -- Count -- ----------- procedure Count (Item : Stream_Element_Array) is begin Result := Result + Item'Length; end Count; begin if Channel.WD_From /= Null_Unbounded_String and then Length (Channel.WD_From) <= Result then Result := 0; Rewrite_Data.Rewrite (Rewriter, Input'Access, Count'Access); Reset (File); end if; return Result; end File_Size; ----------- -- Input -- ----------- procedure Input (Item : out Stream_Element_Array; Last : out Stream_Element_Offset) is begin if End_Of_File (File) then Last := 0; else Read (File, Item, Last); end if; end Input; ------------ -- Output -- ------------ procedure Output (Item : Stream_Element_Array) is begin Stream_Element_Array'Write (Channel.Channel, Item); end Output; begin Rewrite_Data.Link (Rewriter, Rewriter_CD'Unchecked_Access); if Exists (Path_Name) then Open (File, In_File, Path_Name); -- First compute the file size as translated, note that this means -- that we are parsing the file twice. F_Size := File_Size; String'Output (Channel.Channel, Command_Kind'Image (Cmd) & Image (F_Size) & Args_Sep & Translate_Send (Channel, Path_Name)); if F_Size /= 0 then Rewrite_Data.Rewrite (Rewriter, Input'Access, Output'Access); end if; Close (File); else raise Constraint_Error with "File not found : " & Path_Name; end if; end Send_File_Internal; ------------- -- Send_Ko -- ------------- procedure Send_Ko (Channel : Communication_Channel; Pid : Process.Remote_Id) is begin String'Output (Channel.Channel, Command_Kind'Image (KO) & Process.Image (Pid)); end Send_Ko; procedure Send_Ko (Channel : Communication_Channel) is begin String'Output (Channel.Channel, Command_Kind'Image (KO)); end Send_Ko; procedure Send_Ko (Channel : Communication_Channel; Files : File_Data_Set.Vector) is Args : Unbounded_String; First : Boolean := True; begin for F of Files loop if First then First := False; else Append (Args, Args_Sep); end if; Append (Args, To_String (F.Path_Name)); end loop; String'Output (Channel.Channel, Command_Kind'Image (KO) & To_String (Args)); end Send_Ko; ------------- -- Send_Ok -- ------------- procedure Send_Ok (Channel : Communication_Channel; Pid : Process.Remote_Id) is begin String'Output (Channel.Channel, Command_Kind'Image (OK) & Process.Image (Pid)); end Send_Ok; procedure Send_Ok (Channel : Communication_Channel) is begin String'Output (Channel.Channel, Command_Kind'Image (OK)); end Send_Ok; ----------------- -- Send_Output -- ----------------- procedure Send_Output (Channel : Communication_Channel; File_Name : String) is begin Send_File_Internal (Channel, File_Name, DP); end Send_Output; --------------------------- -- Send_RAW_File_Content -- --------------------------- procedure Send_RAW_File_Content (Channel : Communication_Channel; Path_Name : String) is use Ada; type Buffer_Access is access Stream_Element_Array; procedure Unchecked_Free is new Unchecked_Deallocation (Stream_Element_Array, Buffer_Access); Buffer : Buffer_Access; Last : Stream_Element_Offset; File : Stream_IO.File_Type; begin Buffer := new Stream_Element_Array (1 .. 2 * 1_024 * 1_024); -- A somewhat large buffer is needed to transfer big file -- efficiently. Here we use a 2Mb buffer which should be -- large enough for read most file contents in one OS call. -- -- This is allocated on the heap to avoid too much pressure on the -- stack of the tasks. -- Open the file in shared mode as multiple tasks could have -- to send it. Stream_IO.Open (File, Stream_IO.In_File, Path_Name, Form => "shared=yes"); -- Always send an empty stream element array at the end. -- This is used as EOF tag. loop Stream_IO.Read (File, Buffer.all, Last); Stream_Element_Array'Output (Channel.Channel, Buffer (1 .. Last)); exit when Last = 0; end loop; Stream_IO.Close (File); Unchecked_Free (Buffer); end Send_RAW_File_Content; ----------------------- -- Send_Slave_Config -- ----------------------- procedure Send_Slave_Config (Channel : Communication_Channel; Max_Process : Positive; Root_Directory : String; Clock_Status : Boolean) is begin String'Output (Channel.Channel, Command_Kind'Image (OK) & Image (Max_Process) & Args_Sep & Root_Directory & Args_Sep & Boolean'Image (Clock_Status)); end Send_Slave_Config; -------------------- -- Set_Rewrite_CD -- -------------------- procedure Set_Rewrite_CD (Channel : in out Communication_Channel; Path : String) is begin Channel.CD_From := To_Unbounded_String (Normalize_Pathname (Path)); Channel.CD_To := To_Unbounded_String (CD_Path_Tag); end Set_Rewrite_CD; -------------------- -- Set_Rewrite_WD -- -------------------- procedure Set_Rewrite_WD (Channel : in out Communication_Channel; Path : String) is begin Channel.WD_From := To_Unbounded_String (Path); Channel.WD_To := To_Unbounded_String (WD_Path_Tag); end Set_Rewrite_WD; ---------- -- Sock -- ---------- function Sock (Channel : Communication_Channel) return Socket_Type is begin return Channel.Sock; end Sock; ----------------------- -- Translate_Receive -- ----------------------- function Translate_Receive (Channel : Communication_Channel; Str : String) return String is P : constant Natural := Index (Str, To_String (Channel.WD_To)); begin if P = 0 then return Str; else return To_String (Channel.WD_From) & Str (P + Length (Channel.WD_To) .. Str'Last); end if; end Translate_Receive; -------------------- -- Translate_Send -- -------------------- function Translate_Send (Channel : Communication_Channel; Str : String) return String is P : constant Natural := Index (Str, To_String (Channel.WD_From)); begin if P = 0 then return Str; else return To_String (Channel.WD_To) & Str (P + Length (Channel.WD_From) .. Str'Last); end if; end Translate_Send; end Gprbuild.Compilation.Protocol; gprbuild-gpl-2014-src/src/gprinstall.adb0000644000076700001450000000355712323721731017563 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package body Gprinstall is --------- -- Dup -- --------- function Dup (P : Param) return Param is begin return (new String'(P.V.all), P.Default); end Dup; ---------- -- Free -- ---------- procedure Free (P : in out Param) is begin Free (P.V); end Free; end Gprinstall; gprbuild-gpl-2014-src/src/gprconfig-main.adb0000644000076700001450000005212212323721731020274 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R C O N F I G -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Command_Line; with Ada.Containers; use Ada.Containers; with Ada.Exceptions; use Ada.Exceptions; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO; use Ada.Text_IO; with GNAT.Command_Line; use GNAT.Command_Line; with GNAT.OS_Lib; use GNAT.OS_Lib; with GprConfig.Knowledge; use GprConfig.Knowledge; with GprConfig.Sdefault; with GPR_Version; with Hostparm; with Namet; use Namet; with Opt; with Prj; use Prj; with Switch; procedure GprConfig.Main is Default_Output_File : constant String := "default.cgpr"; -- Name of the configuration file used by gprbuild by default -- ??? Should be shared with gprbuild Output_File : Unbounded_String := To_Unbounded_String (Default_Output_File); Selected_Target : Unbounded_String; -- Value of --target switch Target_Specified : Boolean := False; Selected_Targets_Set : Targets_Set_Id; -- Targets set id for the selected target Opt_Validate : Boolean := False; -- Whether we should validate the contents of the knowledge base use Compiler_Lists; procedure Help (Base : Knowledge_Base); -- Display list of switches procedure Usage; -- Display list of options, no specific to current invocation, to be used -- when switch --help is used. procedure Check_Version_And_Help is new Switch.Check_Version_And_Help_G (Usage); procedure Display_Compilers_For_Parser (Base : in out Knowledge_Base; Compilers : in out Compiler_Lists.List); -- Display the list of found compilers for use by an external parser procedure Select_Compilers_Interactively (Base : in out Knowledge_Base; Compilers : in out Compiler_Lists.List); -- Ask the user for compilers to be selected procedure Show_Command_Line_Config (Compilers : Compiler_Lists.List); -- Display the batch command line that would have the same effect as the -- current selection of compilers. type Boolean_Array is array (Count_Type range <>) of Boolean; type All_Iterator (Count : Count_Type) is new Compiler_Iterator with record Filter_Matched : Boolean_Array (1 .. Count) := (others => False); Filters : Compiler_Lists.List; Compilers : Compiler_Lists.List; end record; procedure Callback (Iterator : in out All_Iterator; Base : in out Knowledge_Base; Comp : Compiler; From_Extra_Dir : Boolean; Continue : out Boolean); -- Search all compilers on path, preselecting the first one matching each -- of the filters. Base : Knowledge_Base; Filters : Compiler_Lists.List; Load_Standard_Base : Boolean := True; Batch : Boolean := False; Show_Targets : Boolean := False; Show_Compilers : Boolean := False; Compilers : Compiler_Lists.List; package Compiler_Sort is new Compiler_Lists.Generic_Sorting (Display_Before); Valid_Switches : constant String := "-batch -config= -db: h o: v q -show-targets" & " -validate -mi-show-compilers -target="; -------------- -- Callback -- -------------- procedure Callback (Iterator : in out All_Iterator; Base : in out Knowledge_Base; Comp : Compiler; From_Extra_Dir : Boolean; Continue : out Boolean) is New_Comp : Compiler := Comp; C : Compiler_Lists.Cursor; Index : Count_Type := 1; begin if Iterator.Filter_Matched /= (Iterator.Filter_Matched'Range => True) then C := First (Iterator.Filters); while Has_Element (C) loop if not Iterator.Filter_Matched (Index) and then Filter_Match (Base, Comp => Comp, Filter => Element (C).all) then Set_Selection (New_Comp, True); Iterator.Filter_Matched (Index) := True; exit; end if; Index := Index + 1; Next (C); end loop; end if; -- Ignore compilers from extra directories, unless they have been -- selected because of a --config argument if Is_Selected (New_Comp) or else not From_Extra_Dir then Put_Verbose ("Adding compiler to interactive menu " & To_String (Base, Comp, True) & " selected=" & Is_Selected (New_Comp)'Img); Append (Iterator.Compilers, new Compiler'(New_Comp)); end if; Continue := True; end Callback; ---------- -- Help -- ---------- procedure Help (Base : Knowledge_Base) is Known : Unbounded_String; begin Known_Compiler_Names (Base, Known); Usage; Put_Line (" The known compilers are: " & To_String (Known)); end Help; ---------------------------------- -- Display_Compilers_For_Parser -- ---------------------------------- procedure Display_Compilers_For_Parser (Base : in out Knowledge_Base; Compilers : in out Compiler_Lists.List) is Comp : Compiler_Lists.Cursor := First (Compilers); Count : constant Integer := Integer (Length (Compilers)); Choices : array (1 .. Count) of Compiler_Lists.Cursor; begin for C in Choices'Range loop Choices (C) := Comp; Next (Comp); end loop; Filter_Compilers_List (Base, Compilers, Selected_Targets_Set); Put (To_String (Base, Compilers, Selected_Only => False, Show_Target => True, Parser_Friendly => True)); end Display_Compilers_For_Parser; ------------------------------------ -- Select_Compilers_Interactively -- ------------------------------------ procedure Select_Compilers_Interactively (Base : in out Knowledge_Base; Compilers : in out Compiler_Lists.List) is Comp : Compiler_Lists.Cursor := First (Compilers); Tmp : Natural; Choice : Natural; Line : String (1 .. 1024); Count : constant Integer := Integer (Length (Compilers)); Choices : array (1 .. Count) of Compiler_Lists.Cursor; begin for C in Choices'Range loop Choices (C) := Comp; Next (Comp); end loop; loop Filter_Compilers_List (Base, Compilers, Selected_Targets_Set); Put_Line ("--------------------------------------------------"); Put_Line ("gprconfig has found the following compilers on your PATH."); Put_Line ("Only those matching the target and the selected compilers" & " are displayed."); Put (To_String (Base, Compilers, Selected_Only => False, Show_Target => Selected_Targets_Set = All_Target_Sets)); Put ("Select or unselect the following compiler (or ""s"" to save): "); Get_Line (Line, Tmp); exit when Tmp = 1 and then Line (1) = 's'; if Tmp = 0 then Choice := 0; else begin Choice := Natural'Value (Line (1 .. Tmp)); if Choice > Choices'Last then Choice := 0; end if; exception when Constraint_Error => Choice := 0; end; end if; if Choice = 0 then Put_Line ("Unrecognized choice"); else Set_Selection (Compilers, Choices (Choice), not Is_Selected (Element (Choices (Choice)).all)); end if; end loop; end Select_Compilers_Interactively; ------------------------------ -- Show_Command_Line_Config -- ------------------------------ procedure Show_Command_Line_Config (Compilers : Compiler_Lists.List) is C : Compiler_Lists.Cursor; begin if not Is_Empty (Compilers) then New_Line; Put_Line ("You can regenerate the same config file in batch mode"); Put_Line (" with the following command line:"); Put ("gprconfig --batch"); Put (" --target="); if Selected_Target = Null_Unbounded_String then Put ("all"); else Put (To_String (Selected_Target)); end if; C := First (Compilers); while Has_Element (C) loop if Is_Selected (Element (C).all) then Put (" --config=" & To_String (Base, Element (C).all, As_Config_Arg => True)); end if; Next (C); end loop; New_Line; New_Line; end if; end Show_Command_Line_Config; ----------- -- Usage -- ----------- procedure Usage is begin Switch.Display_Usage_Version_And_Help; Put_Line (" --target=target (" & Sdefault.Hostname & " by default)"); Put_Line (" Select specified target or ""all"" for any target."); Put_Line (" --show-targets : List all compiler targets available."); Put_Line (" --mi-show-compilers : List all compilers available in a " & "parser-friendly way."); Put_Line (" --batch : batch mode, no interactive compiler selection."); Put_Line (" -v : verbose mode."); Put_Line (" -q : quiet output."); Put_Line (" -o file : Name and directory of the output file."); Put_Line (" default is " & To_String (Output_File)); Put_Line (" --db dir : Parse dir as an additional knowledge base."); Put_Line (" --db- : Do not load the standard knowledge base from:"); Put_Line (" " & Default_Knowledge_Base_Directory); Put_Line (" --validate : Validate the contents of the knowledge base"); Put_Line (" before loading."); Put_Line (" --config=language[,version[,runtime[,path[,name]]]]"); Put_Line (" Preselect a compiler."); Put_Line (" Name is either one of the names of the blocks"); Put_Line (" in the knowledge base ('GCC', 'GCC-28',...) or"); Put_Line (" the base name of an executable ('gcc',"); Put_Line (" 'gnatmake')."); Put_Line (" An empty string can be specified for any of the"); Put_Line (" optional parameters"); end Usage; Saved_Verbosity : Verbosity := Default; begin Namet.Initialize; Selected_Target := To_Unbounded_String (Sdefault.Hostname); -- First, check if --version or --help is used Check_Version_And_Help ("GPRCONFIG", "2006", Version_String => GPR_Version.Gpr_Version_String); -- Now check whether we should parse the default knownledge base. -- This needs to be done first, since that influences --config and -h -- at least. Initialize_Option_Scan; loop case Getopt (Valid_Switches) is when '-' => if Full_Switch = "-db" then if Parameter = "-" then Load_Standard_Base := False; end if; elsif Full_Switch = "-validate" then Opt_Validate := True; elsif Full_Switch = "-target" then Target_Specified := True; if Parameter = "all" then Selected_Target := Null_Unbounded_String; else Selected_Target := To_Unbounded_String (Parameter); Output_File := To_Unbounded_String (Parameter & ".cgpr"); end if; elsif Full_Switch = "-show-targets" then -- By default, display all targets available Selected_Target := Null_Unbounded_String; end if; when 'q' => Opt.Quiet_Output := True; Current_Verbosity := Default; when 'v' => case Current_Verbosity is when Default => Current_Verbosity := Medium; when others => Current_Verbosity := High; end case; Opt.Quiet_Output := False; when ASCII.NUL => exit; when others => null; end case; end loop; Saved_Verbosity := Current_Verbosity; Current_Verbosity := Default; if Load_Standard_Base then Parse_Knowledge_Base (Base, Default_Knowledge_Base_Directory, Validate => Opt_Validate); end if; -- Now check all the other command line switches Initialize_Option_Scan; loop case Getopt (Valid_Switches) is when '-' => if Full_Switch = "-config" then declare Requires_Comp : Boolean; Comp : Compiler_Access; begin Parse_Config_Parameter (Base => Base, Config => Parameter, Compiler => Comp, Requires_Compiler => Requires_Comp); if Requires_Comp then Append (Filters, Comp); else Append (Compilers, Comp); end if; end; elsif Full_Switch = "-batch" then Batch := True; elsif Full_Switch = "-mi-show-compilers" then Show_Compilers := True; elsif Full_Switch = "-show-targets" then Show_Targets := True; elsif Full_Switch = "-db" then if Parameter = "-" then null; -- already processed else Parse_Knowledge_Base (Base, Parameter, Validate => Opt_Validate); end if; end if; when 'h' => Help (Base); return; when 'o' => Output_File := To_Unbounded_String (Parameter); when 'q' | 'v' | 't' => null; -- already processed when others => exit; end case; end loop; Current_Verbosity := Saved_Verbosity; Put_Verbose ("Only compilers matching target " & To_String (Selected_Target) & " will be preserved"); Get_Targets_Set (Base, To_String (Selected_Target), Selected_Targets_Set); if Batch or Hostparm.OpenVMS then Complete_Command_Line_Compilers (Base, Selected_Targets_Set, Filters, Compilers); else declare Iter : All_Iterator (Length (Filters)); begin Iter.Filters := Filters; Foreach_Compiler_In_Path (Iterator => Iter, Base => Base, On_Target => Selected_Targets_Set, Extra_Dirs => Extra_Dirs_From_Filters (Filters)); Splice (Target => Compilers, Before => No_Element, Source => Iter.Compilers); end; if Show_Targets or else Current_Verbosity /= Default then declare use String_Lists; All_Target : String_Lists.List; C : Compiler_Lists.Cursor := First (Compilers); begin Put_Line ("List of targets supported by a compiler:"); while Has_Element (C) loop if Target (Element (C).all) /= No_Name then declare Cur_Target : constant String := Get_Name_String (Target (Element (C).all)); T : String_Lists.Cursor := First (All_Target); Dup : Boolean := False; begin while Has_Element (T) loop if Element (T) = Cur_Target then Dup := True; exit; end if; Next (T); end loop; if not Dup then Put (Cur_Target); if Cur_Target = Sdefault.Hostname then Put (" (native target)"); end if; New_Line; Append (All_Target, Cur_Target); end if; end; end if; Next (C); end loop; end; if Show_Targets then return; end if; end if; if Is_Empty (Compilers) then if Selected_Target /= Null_Unbounded_String then Put_Line (Standard_Error, "No compilers found for target " & To_String (Selected_Target)); else Put_Line (Standard_Error, "No compilers found"); end if; Ada.Command_Line.Set_Exit_Status (1); return; end if; Compiler_Sort.Sort (Compilers); if Show_Compilers then Display_Compilers_For_Parser (Base, Compilers); return; else Select_Compilers_Interactively (Base, Compilers); Show_Command_Line_Config (Compilers); end if; end if; if not Target_Specified then Get_Targets_Set (Base, GprConfig.Sdefault.Hostname, Selected_Targets_Set); Selected_Target := To_Unbounded_String (Normalized_Target (Base, Selected_Targets_Set)); end if; if Output_File /= Null_Unbounded_String then -- Look for runtime directories XML files declare Cursor : Compiler_Lists.Cursor; Comp : Compiler_Access; begin Cursor := Compiler_Lists.First (Compilers); while Compiler_Lists.Has_Element (Cursor) loop Comp := Compiler_Lists.Element (Cursor); if Runtime_Dir_Of (Comp) /= No_Name then declare RTS : constant String := Get_Name_String (Runtime_Dir_Of (Comp)); Last : Natural := RTS'Last; begin if RTS (Last) = '/' or else RTS (Last) = Directory_Separator then Last := Last - 1; end if; if Last - RTS'First > 6 and then RTS (Last - 5 .. Last) = "adalib" and then (RTS (Last - 6) = Directory_Separator or else (RTS (Last - 6) = '/')) then Last := Last - 6; else Last := RTS'Last; end if; Parse_Knowledge_Base (Base, RTS (RTS'First .. Last)); end; end if; Compiler_Lists.Next (Cursor); end loop; end; Generate_Configuration (Base, Compilers, To_String (Output_File), To_String (Selected_Target)); end if; exception when Invalid_Config => Put_Line (Standard_Error, "Invalid configuration specified with --config"); Ada.Command_Line.Set_Exit_Status (1); when Generate_Error => Put_Line (Standard_Error, "Generation of configuration files failed"); Ada.Command_Line.Set_Exit_Status (3); when E : Knowledge_Base_Validation_Error => Put_Verbose (Exception_Information (E)); Ada.Command_Line.Set_Exit_Status (4); when E : Invalid_Knowledge_Base => Put_Line (Standard_Error, "Invalid setup of the gprconfig knowledge base"); Put_Verbose (Exception_Information (E)); Ada.Command_Line.Set_Exit_Status (4); when End_Error => null; when Invalid_Switch | Invalid_Parameter => Put_Line ("Invalid command line switch: -" & Full_Switch); Try_Help; Ada.Command_Line.Set_Exit_Status (2); end GprConfig.Main; gprbuild-gpl-2014-src/src/create_ada_runtime_project.adb0000644000076700001450000003057012323721731022740 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT SYSTEM UTILITIES -- -- -- -- C R E A T E _ A D A _ R U N T I M E _ P R O J E C T -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This utility creates the Ada runtime project file ada_runtime.gpr -- This project file resides in the parent directory of adainclude (the source -- directory) and adalib (the object directory). It is "externally built". Its -- package Naming gives the mapping of the source file names to unit names. with Ada.Characters.Handling; use Ada.Characters.Handling; with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with GNAT.Command_Line; use GNAT.Command_Line; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.OS_Lib; use GNAT.OS_Lib; with GNAT.HTable; use GNAT.HTable; procedure Create_Ada_Runtime_Project is Err : exception; -- Raised to terminate execution Project_File : Ada.Text_IO.File_Type; -- The project file being created Adainclude : String_Access := new String'("adainclude"); -- The path name of the adainclude directory, given as argument of the -- utility. Dir : Dir_Type; Str : String (1 .. 1_000); Last : Natural; Gcc : constant String := "gcc"; Gcc_Path : String_Access; Args : Argument_List (1 .. 6) := (1 => new String'("-c"), 2 => new String'("-gnats"), 3 => new String'("-gnatu"), 4 => new String'("-x"), 5 => new String'("ada"), 6 => null); -- The arguments used when invoking the Ada compiler to get the name and -- kind (spec or body) of the unit contained in a source file. Success : Boolean; Return_Code : Integer; Mapping_File_Name : String_Access := new String'("gnat_runtime.mapping"); -- Location of the default mapping file. Output_File : String_Access := new String'("ada_runtime.gpr"); -- Name of the final project file being created Output_File_Name : constant String := "output.txt"; Output : Ada.Text_IO.File_Type; -- The text file where the output of the compiler invocation is stored. -- This is temporary output from gcc Line : String (1 .. 1_000); Line_Last : Natural; Spec : Boolean; Verbose_Mode : Boolean := False; -- True if switch -v is used subtype Header_Num is Natural range 0 .. 4095; function Hash (Key : String_Access) return Header_Num; function Equal (K1, K2 : String_Access) return Boolean; type Element is record Spec : Boolean := False; Unit : String_Access := null; end record; No_Element : constant Element := (False, null); package Mapping is new GNAT.HTable.Simple_HTable (Header_Num => Header_Num, Element => Element, No_Element => No_Element, Key => String_Access, Hash => Hash, Equal => Equal); -- A hash table to keep the mapping of source file names to unit names -- found in file gnat_runtime.mapping. Key : String_Access; Elem : Element; function Hash is new GNAT.HTable.Hash (Header_Num); procedure Get_Mapping (Mapping_File : String); -- Read file mapping file to get the mapping of source file names -- to unit names and populate hash table Mapping. -- If the file doesn't exist, nothing is done, but -- Create_Ada_Runtime_Project will execute more slowly procedure Fail (S : String); -- Outputs S to Standard_Error, followed by a newline and then raises the -- exception Err. procedure Help; -- Display help on using this application ----------- -- Equal -- ----------- function Equal (K1, K2 : String_Access) return Boolean is begin if K1 = null or else K2 = null then return K1 = K2; else return K1.all = K2.all; end if; end Equal; ---------- -- Fail -- ---------- procedure Fail (S : String) is begin Put_Line (Standard_Error, S); raise Err; end Fail; ----------------- -- Get_Mapping -- ----------------- procedure Get_Mapping (Mapping_File : String) is File : File_Type; Line : String (1 .. 1_000); Last : Natural; begin Open (File, In_File, Mapping_File); while not End_Of_File (File) loop Get_Line (File, Line, Last); -- Skip the line if it is a comment line if Last > 2 and then Line (1 .. 2) /= "--" then Key := new String'(Line (1 .. Last)); Get_Line (File, Line, Last); Elem.Spec := Line (1 .. Last) = "spec"; Get_Line (File, Line, Last); Elem.Unit := new String'(Line (1 .. Last)); Mapping.Set (Key, Elem); end if; end loop; Close (File); exception when others => if Is_Open (File) then Close (File); end if; if Verbose_Mode then Put_Line (Standard_Error, "Could not read " & Mapping_File); end if; end Get_Mapping; ---------- -- Hash -- ---------- function Hash (Key : String_Access) return Header_Num is begin if Key = null then return 0; else return Hash (Key.all); end if; end Hash; ---------- -- Help -- ---------- procedure Help is begin Put_Line (" -adainclude : Location of the adainclude directory"); Put_Line (" -mapping : Location of the pre-built mapping file"); Put_Line (" -o : Output file name"); Put_Line (" -v : Verbose mode"); Put_Line (" Default is " & Output_File.all); end Help; -- Start of processing for Create_Ada_Runtime_Project begin -- The utility needs to be invoked with only one argument: the path name -- of the adainclude directory. loop case Getopt ("adainclude: o: mapping: h v") is when 'a' => Free (Adainclude); Adainclude := new String'(Parameter); when 'm' => Free (Mapping_File_Name); Mapping_File_Name := new String'(Parameter); when 'o' => Free (Output_File); Output_File := new String'(Parameter); when 'h' => Help; return; when 'v' => Verbose_Mode := True; when others => exit; end case; end loop; Gcc_Path := Locate_Exec_On_Path (Gcc); if Gcc_Path = null then Fail ("cannot find " & Gcc); end if; Get_Mapping (Mapping_File_Name.all); -- Change the working directory to the adainclude directory begin Change_Dir (Adainclude.all); exception when Directory_Error => Fail ("cannot find adainclude directory " & Adainclude.all); end; -- Create the project file in the parent directory of adainclude Create (Project_File, Out_File, Output_File.all); -- Put the first lines that are always the same Put_Line (Project_File, "project Ada_Runtime is"); New_Line (Project_File); Put_Line (Project_File, " for Languages use (""Ada"");"); Put_Line (Project_File, " for Source_Dirs use (""" & Adainclude.all & """);"); Put_Line (Project_File, " for Object_Dir use """ & Adainclude.all & ".." & Directory_Separator & "adalib"";"); New_Line (Project_File); Put_Line (Project_File, " for Externally_Built use ""true"";"); New_Line (Project_File); Put_Line (Project_File, " package Naming is"); Open (Dir, "."); -- For each regular file in the adainclude directory, invoke the compiler -- to get the unit name. loop Read (Dir, Str, Last); exit when Last = 0; if Is_Regular_File (Str (1 .. Last)) then Key := new String'(Str (1 .. Last)); Elem := Mapping.Get (Key); -- Mapping found in hash table if Elem /= No_Element then if To_Lower (Elem.Unit.all) /= Str (1 .. Last - 4) then Put (Project_File, " for "); if Elem.Spec then Put (Project_File, "Spec ("""); else Put (Project_File, "Body ("""); end if; Put (Project_File, Elem.Unit.all); Put (Project_File, """) use """); Put (Project_File, Str (1 .. Last)); Put_Line (Project_File, """;"); end if; -- Case where Mapping.Get returned no element: use the compiler -- to get the unit name. else Args (Args'Last) := new String'(Str (1 .. Last)); if Verbose_Mode then Put (Gcc_Path.all); for J in Args'Range loop Put (' ' & Args (J).all); end loop; New_Line; end if; Spawn (Gcc_Path.all, Args, Output_File_Name, Success, Return_Code); if Success then Open (Output, In_File, Output_File_Name); if not End_Of_File (Output) then Get_Line (Output, Line, Line_Last); -- Find the first closing parenthesis Char_Loop : for J in 1 .. Line_Last loop if Line (J) = ')' then if J >= 13 and then Line (1 .. 4) = "Unit" then -- No need for a spec or body declaration if the -- file name is as expected. if To_Lower (Line (6 .. J - 7)) /= Str (1 .. Last - 4) then Spec := Line (J - 5 .. J) = "(spec)"; Put (Project_File, " for "); if Spec then Put (Project_File, "Spec ("""); else Put (Project_File, "Body ("""); end if; Put (Project_File, Line (6 .. J - 7)); Put (Project_File, """) use """); Put (Project_File, Str (1 .. Last)); Put_Line (Project_File, """;"); end if; end if; exit Char_Loop; end if; end loop Char_Loop; end if; Close (Output); end if; end if; end if; end loop; -- Put the closing lines and close the project file Put_Line (Project_File, " end Naming;"); New_Line (Project_File); Put_Line (Project_File, "end Ada_Runtime;"); Close (Project_File); -- Clean up: delete the output file Delete_File (Output_File_Name, Success); exception when Invalid_Switch | Invalid_Parameter => Put_Line ("Invalid switch: " & Full_Switch); Help; when Err => Set_Exit_Status (1); when others => Put_Line ("unexpected exception"); raise; end Create_Ada_Runtime_Project; gprbuild-gpl-2014-src/src/gprconfig-sdefault.ads.in0000644000076700001450000000406312323721731021606 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- G P R C O N F I G -- -- -- -- S p e c -- -- -- -- Copyright (C) 2006-2012, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 2, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING. If not, write -- -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- -- Boston, MA 02110-1301, USA. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ package GprConfig.Sdefault is pragma Warnings (Off); Hostname : constant String := "@host@"; end GprConfig.Sdefault; gprbuild-gpl-2014-src/src/forcomp.adb0000644000076700001450000001627512323721731017052 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- F O R C O M P -- -- -- -- B o d y -- -- -- -- Copyright (C) 2010-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This program is used on VMS as a front end to invoke the DEC Fortran -- compiler. pragma Extend_System (Aux_DEC); with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with GNAT.OS_Lib; use GNAT.OS_Lib; with Osint; use Osint; with System; use System; procedure Forcomp is subtype Cond_Value_Type is System.Unsigned_Longword; Output_File_Name : String_Access; procedure Spawn (Status : out Cond_Value_Type; Command : String; Input_File : String := String'Null_Parameter; Output_File : String := String'Null_Parameter); pragma Import (External, Spawn); pragma Import_Valued_Procedure (Spawn, "LIB$SPAWN", (Cond_Value_Type, String, String, String), (Value, Descriptor (S), Descriptor (S), Descriptor (S))); -- LIB$SPAWN is used to invoke the compiler procedure Stop (Status : Cond_Value_Type); pragma Import (External, Stop); pragma Import_Procedure (Stop, "LIB$STOP", Mechanism => Value); -- LIB$STOP is used to set the error code when the invocation of the -- compiler fails. Success : constant Cond_Value_Type := 1; Command : constant String := "fortran"; Status : Cond_Value_Type; Include_Directory : constant String := "/INCLUDE="; Output_File : constant String := "-o"; Verbose : Boolean := False; procedure Add (S : in out String_Access; Last : in out Natural; Value : String); -- Add string Value to string variable S, updating Last --------- -- Add -- --------- procedure Add (S : in out String_Access; Last : in out Natural; Value : String) is begin while S'Last < Last + Value'Length loop declare New_S : constant String_Access := new String (1 .. 2 * S'Last); begin New_S (1 .. Last) := S (1 .. Last); Free (S); S := New_S; end; end loop; S (Last + 1 .. Last + Value'Length) := Value; Last := Last + Value'Length; end Add; begin declare Command_String : String_Access := new String (1 .. 40); -- This is the command string that will be used to invoke the compiler Last_Command : Natural := 0; Includes : String_Access := new String (1 .. 40); -- As they can be only one /INCLUDE= option, we regroupe all directories -- in string Includes. Last_Include : Natural := 0; Arg_Num : Natural; begin Add (Command_String, Last_Command, Command); Arg_Num := 0; while Arg_Num < Argument_Count loop Arg_Num := Arg_Num + 1; declare Arg : constant String := Argument (Arg_Num); begin -- If this command is /INCLUDE=, add the directory to string -- Includes. if Arg'Length > Include_Directory'Length and then Arg (Arg'First .. Arg'First + Include_Directory'Length - 1) = Include_Directory then if Last_Include = 0 then Add (Includes, Last_Include, Include_Directory & "("); else Add (Includes, Last_Include, ","); end if; declare Dir : constant String := Arg (Arg'First + Include_Directory'Length .. Arg'Last); New_Dir : String_Access; begin if Is_Directory (Dir) then New_Dir := To_Host_Dir_Spec (Dir, False); Add (Includes, Last_Include, New_Dir.all); else Add (Includes, Last_Include, Dir); end if; end; -- If it is "-o", the next argument is the output file elsif Arg = Output_File then if Arg_Num < Argument_Count then Arg_Num := Arg_Num + 1; Output_File_Name := To_Host_File_Spec (Argument (Arg_Num)); end if; -- If it is "-v", skip the argument and set Verbose to True elsif Arg = "-v" then Verbose := True; -- Otherwise, add argument to the command string else declare New_Arg : String_Access; begin if Is_Regular_File (Arg) then New_Arg := To_Host_File_Spec (Arg); elsif Is_Directory (Arg) then New_Arg := To_Host_Dir_Spec (Arg, False); end if; if New_Arg /= null then Add (Command_String, Last_Command, " " & New_Arg.all); else Add (Command_String, Last_Command, " " & Arg); end if; end; end if; end; end loop; -- If there was at least one /INCLUDE= switch, add /INCLUDE= with all -- directories to the command string. if Last_Include /= 0 then Add (Command_String, Last_Command, " " & Includes (1 .. Last_Include) & ")"); end if; -- Invoke Fortran declare Cmd : constant String (1 .. Last_Command) := Command_String (1 .. Last_Command); begin if Verbose then Put_Line (Cmd); end if; if Output_File_Name /= null then Spawn (Status, Cmd, Output_File => Output_File_Name.all); else Spawn (Status, Cmd); end if; if (Status mod 2) /= Success then Stop (Status); end if; end; end; end Forcomp; gprbuild-gpl-2014-src/src/gprbuild-compilation-slave.adb0000644000076700001450000007431312323721731022636 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . S L A V E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Calendar; use Ada.Calendar; with Ada.Containers.Ordered_Sets; with Ada.Containers.Vectors; use Ada; with Ada.Directories; use Ada.Directories; with Ada.Exceptions; use Ada.Exceptions; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Ada.Strings.Maps.Constants; use Ada.Strings; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with GNAT.Sockets; use GNAT; use GNAT.Sockets; with GNAT.String_Split; use GNAT.String_Split; with Output; use Output; with Snames; use Snames; with Gpr_Util; use Gpr_Util; with Gprbuild.Compilation.Protocol; use Gprbuild.Compilation.Protocol; with Gprbuild.Compilation.Result; with Gprbuild.Compilation.Sync; package body Gprbuild.Compilation.Slave is type Slave_Data is record Host : Unbounded_String; User : Unbounded_String; Port : Port_Type; Sync : Sync_Kind; end record; No_Slave_Data : constant Slave_Data := (Port => Port_Type'Last, others => <>); package Slaves_N is new Containers.Vectors (Positive, Slave_Data); Slaves_Data : Slaves_N.Vector; type Slave is record Sock : Integer; Data : Slave_Data; Channel : Communication_Channel; Current : Natural := 0; Max_Processes : Positive := 1; Root_Dir : Unbounded_String; Rsync_Pid : Process_Id; Included_Artifact_Patterns : Str_Vect.Vector; end record; function "<" (K1, K2 : Slave) return Boolean is (K1.Sock < K2.Sock); function "=" (K1, K2 : Slave) return Boolean is (K1.Sock = K2.Sock); No_Slave : constant Slave := (-1, No_Slave_Data, Current => Natural'Last, others => <>); package Slave_S is new Containers.Ordered_Sets (Slave); -- The key is the C socket number function Connect_Slave (S_Data : Slave_Data; Project_Name : String) return Slave; -- Connect to the slave and return the corresponding object -- Ack transient signal stored into this variable protected Wait_Ack is procedure Set (Pid : Remote_Id); entry Get (Pid : out Remote_Id); private Is_Set : Boolean := False; Id : Remote_Id; end Wait_Ack; task type Wait_Remote; -- Wait for incoming data from all registred slaves type Wait_Remote_Ref is access Wait_Remote; WR : Wait_Remote_Ref; -- Will be initialized only if the distributed mode is activated Compiler_Path : constant OS_Lib.String_Access := Locate_Exec_On_Path ("gnatls"); Project_Name : Unbounded_String; -- Current project name being compiled Root_Dir : Unbounded_String; -- Root directory from where the sources are to be synchronized with the -- slaves. This is by default the directory containing the main project -- file. The value is changed with the Root_Dir attribute value of the -- project file's Remote package. Remote_Process : Shared_Counter; Slaves_Sockets : Socket_Set_Type; Max_Processes : Natural := 0; protected Slaves is procedure Insert (S : Slave); -- Add a slave into the pool function Find (Socket : Integer) return Slave; -- Find a slave given the socket number function Get_Free return Slave; -- Returns a slave with free compilation slot function Count return Natural; -- Returns the number of registered slaves procedure Increment_Current (S : in out Slave); -- Increment the number of processes handled by slave procedure Decrement_Current (S : in out Slave); -- Decrement the number of processes handled by slave procedure Set_Rewrite_CD (S : in out Slave; Path : String); -- Record rewriting of the compiler directory procedure Set_Rewrite_WD (S : in out Slave; Path : String); -- Record rewriting of the wording directory procedure Iterate (Proc : access procedure (S : in out Slave)); -- Iterate over all slaves in the pool and call proc procedure Clear; -- Clear the pool private Pool : Slave_S.Set; end Slaves; ---------------------------- -- Clean_Up_Remote_Slaves -- ---------------------------- procedure Clean_Up_Remote_Slaves (Tree : Project_Tree_Ref; Project : Project_Id) is pragma Unreferenced (Tree); procedure Clean_Up_Remote_Slave (S_Data : Slave_Data; Project_Name : String); -- Clean-up slave --------------------------- -- Clean_Up_Remote_Slave -- --------------------------- procedure Clean_Up_Remote_Slave (S_Data : Slave_Data; Project_Name : String) is function User_Host return String is (if S_Data.User = Null_Unbounded_String then To_String (S_Data.Host) else To_String (S_Data.User) & '@' & To_String (S_Data.Host)); S : Slave; begin -- Only clean-up when the sources are not shared if S_Data.Sync = Protocol.Rsync then S := Connect_Slave (S_Data, Project_Name); -- Send the clean-up request Protocol.Send_Clean_Up (S.Channel, Project_Name); declare Cmd : constant Command := Get_Command (S.Channel); begin if Kind (Cmd) = OK then if Opt.Verbose_Mode then Write_Line ("Clean-up done on " & To_String (S_Data.Host)); end if; elsif Kind (Cmd) = KO then Write_Line ("Slave cannot clean-up " & User_Host); OS_Exit (1); else Write_Line ("protocol error: " & Command_Kind'Image (Kind (Cmd))); OS_Exit (1); end if; end; Protocol.Send_End_Of_Compilation (S.Channel); Close (S.Channel); end if; end Clean_Up_Remote_Slave; begin for S of Slaves_Data loop Clean_Up_Remote_Slave (S, Get_Name_String (Project.Name)); end loop; end Clean_Up_Remote_Slaves; ------------------- -- Connect_Slave -- ------------------- function Connect_Slave (S_Data : Slave_Data; Project_Name : String) return Slave is Address : Sock_Addr_Type; Sock : Socket_Type; S : Slave; Status : Selector_Status; begin S.Data := S_Data; if S.Data.Host = Null_Unbounded_String then Write_Line ("A slave must have a name, aborting"); OS_Exit (1); end if; Address.Addr := Addresses (Get_Host_By_Name (To_String (S.Data.Host)), 1); Address.Port := S_Data.Port; Create_Socket (Sock); Set_Socket_Option (Sock, Socket_Level, (Reuse_Address, True)); Connect_Socket (Sock, Address, Timeout => 2.0, Status => Status); if Status in Expired .. Aborted then Write_Line ("Cannot connect to slave " & To_String (S.Data.Host) & ", aborting"); OS_Exit (1); end if; S.Channel := Create (Sock); -- Do initial handshake Protocol.Send_Context (S.Channel, Get_Target, Project_Name, Slave_Env.all, S.Data.Sync); declare Cmd : constant Command := Get_Command (S.Channel); Parameters : constant Argument_List_Access := Args (Cmd); begin if Kind (Cmd) = OK and then Parameters'Length = 3 then S.Max_Processes := Natural'Value (Parameters (1).all); S.Root_Dir := To_Unbounded_String (Parameters (2).all); if not Boolean'Value (Parameters (3).all) then Write_Line ("warning: non synchronized clock detected for " & To_String (S.Data.Host)); end if; elsif Kind (Cmd) = KO then Write_Line ("build slave is not compatible : " & To_String (S.Data.Host)); OS_Exit (1); else Write_Line ("protocol error: " & Command_Kind'Image (Kind (Cmd))); OS_Exit (1); end if; end; return S; end Connect_Slave; ----------------------- -- Get_Max_Processes -- ----------------------- function Get_Max_Processes return Natural is begin return Max_Processes; end Get_Max_Processes; ------------------- -- Record_Slaves -- ------------------- procedure Record_Slaves (Option : String) is S : Slice_Set; procedure Parse_Build_Slave (V : String); -- Parse the build slave V ----------------------- -- Parse_Build_Slave -- ----------------------- procedure Parse_Build_Slave (V : String) is User : Unbounded_String; Host : Unbounded_String; Port : Port_Type := Default_Port; Sync : Sync_Kind := Protocol.Rsync; F : Natural := V'First; I : Natural := Index (V, "://"); begin -- Check for protocol if I /= 0 then if V (F .. I - 1) = "rsync" then Sync := Protocol.Rsync; elsif V (F .. I - 1) = "gpr" then Sync := Gpr; else Write_Line ("error: unknown protocol in " & V); OS_Exit (1); end if; F := I + 3; end if; -- Check for user I := Index (V, "@", From => F); if I /= 0 then User := To_Unbounded_String (V (F .. I - 1)); F := I + 1; end if; -- Get for port I := Index (V, ":", From => F); if I = 0 then Host := To_Unbounded_String (V (F .. V'Last)); else Host := To_Unbounded_String (V (F .. I - 1)); declare Port_Str : constant String := V (I + 1 .. V'Last); begin if Strings.Maps.Is_Subset (Maps.To_Set (Port_Str), Maps.Constants.Decimal_Digit_Set) then Port := Port_Type'Value (V (I + 1 .. V'Last)); else Write_Line ("error: invalid port value in " & V); OS_Exit (1); end if; end; end if; Slaves_Data.Append (Slave_Data'(Host, User, Port, Sync)); end Parse_Build_Slave; begin Create (S, Option, ","); for K in 1 .. Slice_Count (S) loop Parse_Build_Slave (Slice (S, K)); end loop; end Record_Slaves; ---------------------------- -- Register_Remote_Slaves -- ---------------------------- procedure Register_Remote_Slaves (Tree : Project_Tree_Ref; Project : Project_Id) is use type Containers.Count_Type; procedure Register_Remote_Slave (S_Data : Slave_Data; Project_Name : String); -- Register a slave living on Host for the given project name. User is -- used when calling rsync, it is the remote machine user name, if empty -- the local user name is used. Start, Stop : Calendar.Time; procedure Insert (V : out Str_Vect.Vector; Values : String_List_Id); -- Inserts all values into the vector Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector; Included_Artifact_Patterns : Str_Vect.Vector; ------------ -- Insert -- ------------ procedure Insert (V : out Str_Vect.Vector; Values : String_List_Id) is Idx : String_List_Id := Values; begin while Idx /= Nil_String loop declare Item : constant String_Element := Tree.Shared.String_Elements.Table (Idx); begin V.Append (Get_Name_String (Item.Value)); Idx := Item.Next; end; end loop; end Insert; --------------------------- -- Register_Remote_Slave -- --------------------------- procedure Register_Remote_Slave (S_Data : Slave_Data; Project_Name : String) is function User_Host return String is (if S_Data.User = Null_Unbounded_String then To_String (S_Data.Host) else To_String (S_Data.User) & '@' & To_String (S_Data.Host)); S : Slave; begin S := Connect_Slave (S_Data, Project_Name); Set (Slaves_Sockets, Sock (S.Channel)); -- Sum the Max_Process values Max_Processes := Max_Processes + S.Max_Processes; if Opt.Verbose_Mode then Write_Str ("Register slave " & User_Host & ","); Write_Str (Integer'Image (S.Max_Processes)); Write_Line (" process(es)"); Write_Line (" location: " & To_String (S.Root_Dir)); end if; -- Let's double check that Root_Dir and Projet_Name are not empty, -- this is a safety check to avoid rsync detroying remote environment -- as rsync is using the --delete options. if Length (S.Root_Dir) = 0 then Write_Line ("error: Root_Dir cannot be empty"); OS_Exit (1); end if; if Project_Name = "" then Write_Line ("error: Project_Name cannot be empty"); OS_Exit (1); end if; Compilation.Sync.To_Slave (Sync => S_Data.Sync, Channel => S.Channel, Project_Name => Project_Name, Root_Dir => To_String (Root_Dir), Slave_Root_Dir => To_String (S.Root_Dir), Host => To_String (S_Data.Host), User => To_String (S_Data.User), Included_Patterns => Included_Patterns, Excluded_Patterns => Excluded_Patterns); -- Now that all slave's data is known and set, record it S.Sock := To_C (Sock (S.Channel)); S.Included_Artifact_Patterns := Included_Artifact_Patterns; Slaves.Insert (S); end Register_Remote_Slave; Pcks : Package_Table.Table_Ptr renames Tree.Shared.Packages.Table; Pck : Package_Id := Project.Decl.Packages; begin Project_Name := To_Unbounded_String (Get_Name_String (Project.Name)); Root_Dir := To_Unbounded_String (Containing_Directory (Get_Name_String (Project.Path.Display_Name))); -- Check for Root_Dir attribute and Excluded_Patterns Look_Remote_Package : while Pck /= No_Package loop if Pcks (Pck).Decl /= No_Declarations and then Pcks (Pck).Name = Name_Remote then declare Id : Variable_Id := Pcks (Pck).Decl.Attributes; begin while Id /= No_Variable loop declare V : constant Variable := Tree.Shared.Variable_Elements.Table (Id); begin if not V.Value.Default then if V.Name = Name_Root_Dir then declare RD : constant String := Get_Name_String (V.Value.Value); begin if Is_Absolute_Path (RD) then Root_Dir := To_Unbounded_String (RD); else Root_Dir := To_Unbounded_String (Normalize_Pathname (To_String (Root_Dir) & Directory_Separator & RD)); end if; if not Exists (To_String (Root_Dir)) or else not Is_Directory (To_String (Root_Dir)) then Write_Line ("error: " & To_String (Root_Dir) & " is not a directory" & " or does not exists"); OS_Exit (1); else Write_Line ("root dir : " & To_String (Root_Dir)); end if; end; elsif V.Name = Name_Excluded_Patterns then Insert (Excluded_Patterns, V.Value.Values); elsif V.Name = Name_Included_Patterns then Insert (Included_Patterns, V.Value.Values); elsif V.Name = Name_Included_Artifact_Patterns then Insert (Included_Artifact_Patterns, V.Value.Values); end if; end if; end; Id := Tree.Shared.Variable_Elements.Table (Id).Next; end loop; end; end if; Pck := Pcks (Pck).Next; end loop Look_Remote_Package; -- Check if Excluded_Patterns and Included_Patterns are set if Included_Patterns.Length /= 0 and then Excluded_Patterns.Length /= 0 then Write_Line ("error: Excluded_Patterns and Included_Patterns are exclusive"); OS_Exit (1); end if; -- Then registers the build slaves Start := Calendar.Clock; for S of Slaves_Data loop Register_Remote_Slave (S, To_String (Project_Name)); end loop; Sync.Wait; Stop := Calendar.Clock; if Opt.Verbose_Mode then Write_Str (" All data synchronized in "); Write_Str (Duration'Image (Stop - Start)); Write_Line (" seconds"); end if; -- We are in remote mode, the initialization was successful, start tasks -- now. if WR = null then WR := new Wait_Remote; end if; end Register_Remote_Slaves; --------- -- Run -- --------- function Run (Project : Project_Id; Language : String; Options : GNAT.OS_Lib.Argument_List; Obj_Name : String; Dep_Name : String := ""; Env : String := "") return Id is CWD : constant String := Current_Directory; -- CWD is the directory from which the command is run RD : constant String := To_String (Root_Dir); S : Slave := Slaves.Get_Free; -- Get a free slave for conducting the compilation function Filter_String (O : String; Sep : String := WD_Path_Tag) return String; -- Make O PATH relative to RD. For option -gnatec and -gnatem makes -- the specified filename absolute in the slave environment and send -- the file to the slave. ------------------- -- Filter_String -- ------------------- function Filter_String (O : String; Sep : String := WD_Path_Tag) return String is Pos : constant Natural := Index (O, RD); begin if Pos = 0 then return O; else -- Note that we transfer files only when they are under the -- project root. if O'Length > 8 and then O (O'First .. O'First + 7) in "-gnatem=" | "-gnatec=" then -- Send the corresponding file to the slave declare File_Name : constant String := O (O'First + 8 .. O'Last); begin if Exists (File_Name) then Send_File (S.Channel, File_Name, Rewrite => True); else Write_Line ("File not found " & File_Name); Write_Line ("Please check that Built_Root is properly set"); end if; return O (O'First .. O'First + 7) & Translate_Send (S.Channel, File_Name); end; end if; return O (O'First .. Pos - 1) & Sep & Filter_String (O (Pos + RD'Length + 1 .. O'Last)); end if; end Filter_String; Pid : Remote_Id; begin -- Record the rewrite information for this channel only if we are not -- using a shared directory. Slaves.Set_Rewrite_WD (S, Path => RD); if Compiler_Path /= null then Slaves.Set_Rewrite_CD (S, Path => Containing_Directory (Containing_Directory (Compiler_Path.all))); end if; Send_Exec (S.Channel, Get_Name_String (Project.Path.Display_Name), Filter_String (CWD, Sep => ""), Language, Options, Obj_Name, Dep_Name, Env, Filter_String'Access); Remote_Process.Increment; -- Wait for the Ack from the remore host, this is set by the Wait_Remote -- task. Wait_Ack.Get (Pid); return Create_Remote (Pid); exception when E : others => Write_Line ("Unexpected exception: " & Exception_Information (E)); OS_Exit (1); end Run; ------------ -- Slaves -- ------------ protected body Slaves is -------------------- -- Change_Current -- -------------------- procedure Change_Current (S : in out Slave; Value : Integer) is Position : constant Slave_S.Cursor := Pool.Find (S); begin Pool (Position).Current := Pool (Position).Current + Value; end Change_Current; ----------- -- Clear -- ----------- procedure Clear is begin Pool.Clear; end Clear; ----------- -- Count -- ----------- function Count return Natural is begin return Natural (Pool.Length); end Count; ----------------------- -- Decrement_Current -- ----------------------- procedure Decrement_Current (S : in out Slave) is begin Change_Current (S, -1); end Decrement_Current; ---------- -- Find -- ---------- function Find (Socket : Integer) return Slave is S : constant Slave := (Sock => Socket, others => <>); Position : constant Slave_S.Cursor := Pool.Find (S); begin if Slave_S.Has_Element (Position) then return Slave_S.Element (Position); else return No_Slave; end if; end Find; -------------- -- Get_Free -- -------------- function Get_Free return Slave is begin for S of Pool loop if S.Current < S.Max_Processes then return S; end if; end loop; return No_Slave; end Get_Free; ----------------------- -- Increment_Current -- ----------------------- procedure Increment_Current (S : in out Slave) is begin Change_Current (S, 1); end Increment_Current; ------------ -- Insert -- ------------ procedure Insert (S : Slave) is begin Pool.Insert (S); end Insert; ------------- -- Iterate -- ------------- procedure Iterate (Proc : access procedure (S : in out Slave)) is begin for C in Pool.Iterate loop declare S : Slave := Slave_S.Element (C); begin Proc (S); Pool (C) := S; end; end loop; end Iterate; -------------------- -- Set_Rewrite_CD -- -------------------- procedure Set_Rewrite_CD (S : in out Slave; Path : String) is Position : constant Slave_S.Cursor := Pool.Find (S); begin Set_Rewrite_CD (Pool (Position).Channel, Path => Path); S := Pool (Position); end Set_Rewrite_CD; -------------------- -- Set_Rewrite_WD -- -------------------- procedure Set_Rewrite_WD (S : in out Slave; Path : String) is Position : constant Slave_S.Cursor := Pool.Find (S); begin Set_Rewrite_WD (Pool (Position).Channel, Path => Path); S := Pool (Position); end Set_Rewrite_WD; end Slaves; ------------------------------ -- Unregister_Remote_Slaves -- ------------------------------ procedure Unregister_Remote_Slaves is procedure Unregister (S : in out Slave); -- Unregister given slave Start, Stop : Time; ---------------- -- Unregister -- ---------------- procedure Unregister (S : in out Slave) is begin Send_End_Of_Compilation (S.Channel); Close (S.Channel); -- Sync back the object code if needed Sync.From_Slave (Sync => S.Data.Sync, Project_Name => To_String (Project_Name), Root_Dir => To_String (Root_Dir), Slave_Root_Dir => To_String (S.Root_Dir), User => To_String (S.Data.User), Host => To_String (S.Data.Host), Included_Artifact_Patterns => S.Included_Artifact_Patterns); end Unregister; begin Start := Clock; Slaves.Iterate (Unregister'Access); Sync.Wait; Stop := Clock; if Opt.Verbose_Mode and then Slaves.Count > 0 then Write_Str (" All data synchronized in "); Write_Str (Duration'Image (Stop - Start)); Write_Line (" seconds"); end if; Slaves.Clear; end Unregister_Remote_Slaves; -------------- -- Wait_Ack -- -------------- protected body Wait_Ack is --------- -- Set -- --------- procedure Set (Pid : Remote_Id) is begin Id := Pid; Is_Set := True; end Set; --------- -- Get -- --------- entry Get (Pid : out Remote_Id) when Is_Set is begin Pid := Id; Is_Set := False; end Get; end Wait_Ack; ----------------- -- Wait_Remote -- ----------------- task body Wait_Remote is use type Slave_S.Cursor; Proc : Id; Pid : Remote_Id; Selector : Selector_Type; Status : Selector_Status; R_Set, W_Set : Socket_Set_Type; Sock : Socket_Type; S : Slave; begin -- In this task we are only interrested by the incoming data, so we do -- not wait on socket ready for writting. Sockets.Empty (W_Set); Create_Selector (Selector); loop -- Let's wait for at least some process to monitor Remote_Process.Wait_Non_Zero; -- Wait for response from all registered slaves Copy (Slaves_Sockets, R_Set); Check_Selector (Selector, R_Set, W_Set, Status); if Status = Completed then Get (R_Set, Sock); pragma Assert (Sock /= No_Socket, "no socket returned by selector"); S := Slaves.Find (To_C (Sock)); if S /= No_Slave then declare Cmd : constant Command := Get_Command (S.Channel); Success : Boolean; begin -- A display output if Kind (Cmd) = DP then -- Write output to the console Write_Str (To_String (Protocol.Output (Cmd))); Get_Pid (S.Channel, Pid, Success); Proc := Create_Remote (Pid); Remote_Process.Decrement; Slaves.Decrement_Current (S); Result.Add (Proc, Success, To_String (S.Data.Host)); -- An acknowledgment of an compilation job elsif Kind (Cmd) = AK then declare Pid : constant Remote_Id := Remote_Id'Value (Args (Cmd)(1).all); begin Slaves.Increment_Current (S); Wait_Ack.Set (Pid); end; elsif Kind (Cmd) = EC then null; else raise Constraint_Error with "Unexpected command: " & Command_Kind'Image (Kind (Cmd)); end if; end; end if; else if Opt.Verbose_Mode and then Opt.Verbosity_Level = Opt.High then Write_Line ("warning: selector in " & Selector_Status'Image (Status) & " state"); end if; end if; Sockets.Empty (R_Set); end loop; exception when E : others => Write_Line (Exception_Information (E)); OS_Exit (1); end Wait_Remote; end Gprbuild.Compilation.Slave; gprbuild-gpl-2014-src/src/gprinstall-uninstall.ads0000644000076700001450000000326012323721731021602 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package Gprinstall.Uninstall is procedure Process (Install_Name : String); -- Uninstall Project end Gprinstall.Uninstall; gprbuild-gpl-2014-src/src/gprmunch.sh0000755000076700001450000000323410612067551017110 0ustar gnatmailgnat#!/bin/sh if [ $# != 1 ]; then echo "Bad number of arguments"; exit 2 fi exch_file=$1 cp $exch_file $exch_file.saved # Save stdin and use exchange file as input. exec >&3 exec < $exch_file # Save and set IFS to new line. OLD_IFS=$IFS IFS=" " # Parse exchange file. section='Unknown' dep_files="" bindsec='Unknown' nm="nm-not-defined" cc="cc-not-defined" verbose="" while read line; do case $line in "[MAIN BASE NAME]") section="base name" ;; "[COMPILER PATH]") section="discard" ;; "[COMPILER OPTIONS]") section="discard" ;; "[DEPENDENCY FILES]") section="dependency" ;; "[BINDING OPTIONS]") section="options" ;; "[VERBOSE]") verbose=y; section="Unknown" ;; \[*) echo "Unknown section ($line)"; exit 1 ;; *) case $section in "discard") ;; "Unknown") echo "Malformed exchange file"; exit 1 ;; "base name") basename=$line ;; "dependency") dep_files="$dep_files $line" ;; "options") case $line in --nm=*) nm=`echo $line | sed -e "s/^--nm=//"` ;; --cc=*) cc=`echo $line | sed -e "s/^--cc=//"` ;; *) echo "Unknown binder option ($line)" ;; esac ;; *) echo "Internal error (section $section) unhandled"; exit 1 ;; esac esac done # Restore IFS and stdin. IFS=$OLD_IFS exec 3>&1 exec 3>&- # Convert dependancy files to object files. object_files=`echo $dep_files | sed -e 's/\\.d\$/.o/'` # Do the real work. $nm $object_files | munch > cpp__$basename.c $cc -c cpp__$basename.c # Generate the exchange file. cat > $1 < True); -- The project tree Force_Deletions : Boolean := False; -- Set to True by switch -f. When True, attempts to delete non writable -- files will be done. Do_Nothing : Boolean := False; -- Set to True when switch -n is specified. When True, no file is deleted. -- gnatclean only lists the files that would have been deleted if the -- switch -n had not been specified. File_Deleted : Boolean := False; -- Set to True if at least one file has been deleted Copyright_Displayed : Boolean := False; Usage_Displayed : Boolean := False; -- Flags set to True when the action is performed, to avoid duplicate -- displays. All_Projects : Boolean := False; -- Set to True when option -r is used, so that all projects in the project -- tree are cleaned. package Processed_Projects is new Table.Table (Table_Component_Type => Project_Id, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Cleangpr.Processed_Projects"); -- Table to keep track of what project files have been processed, when -- switch -r is specified. procedure Clean_Project (Project : Project_Id; Project_Tree : Project_Tree_Ref; Main : Boolean; Remove_Executables : Boolean); -- Do the cleaning work for Project. -- This procedure calls itself recursively when there are several -- project files in the tree rooted at the main project file and switch -r -- has been specified. -- Main is True iff Project is a main project. -- If Remove_Executables is true, the binder files and results of the -- linker are also removed. procedure Delete (In_Directory : String; File : String); -- Delete one file, or list the file name if switch -n is specified end Gprclean; gprbuild-gpl-2014-src/src/gpr_util.ads0000644000076700001450000002750612323721731017252 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R _ U T I L -- -- -- -- S p e c -- -- -- -- Copyright (C) 2007-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This package contains constants, variable and subprograms used by gprbuild -- and gprclean. with Ada.Calendar; use Ada; with GNAT.MD5; use GNAT.MD5; with GNAT.OS_Lib; use GNAT.OS_Lib; with ALI; with Namet; use Namet; with Prj; use Prj; with Prj.Tree; use Prj.Tree; with Types; package Gpr_Util is Partial_Prefix : constant String := "p__"; Begin_Info : constant String := "-- BEGIN Object file/option list"; End_Info : constant String := "-- END Object file/option list "; Project_Node_Tree : constant Project_Node_Tree_Ref := new Project_Node_Tree_Data; -- This is also used to hold project path and scenario variables Success : Boolean := False; -- Config project Config_Project_Option : constant String := "--config="; Autoconf_Project_Option : constant String := "--autoconf="; Target_Project_Option : constant String := "--target="; Prefix_Project_Option : constant String := "--prefix"; No_Name_Map_File_Option : constant String := "--map-file-option"; Restricted_To_Languages_Option : constant String := "--restricted-to-languages="; Distributed_Option : constant String := "--distributed="; Slave_Env_Option : constant String := "--slave-env"; Slave_Env_Auto : Boolean := False; Dry_Run_Option : constant String := "--dry-run"; Named_Map_File_Option : constant String := No_Name_Map_File_Option & '='; Config_Path : String_Access := null; Target_Name : String_Access := null; Config_Project_File_Name : String_Access := null; Configuration_Project_Path : String_Access := null; -- Base name and full path to the configuration project file Autoconfiguration : Boolean := True; -- Whether we are using an automatically config (from gprconfig) Autoconf_Specified : Boolean := False; -- Whether the user specified --autoconf on the gprbuild command line Delete_Autoconf_File : Boolean := False; -- This variable is used by gprclean to decide if the config project file -- should be cleaned. It is set to True when the config project file is -- automatically generated or --autoconf= is used. -- Default project Default_Project_File_Name : constant String := "default.gpr"; -- Implicit project Implicit_Project_File_Path : constant String := "share" & Directory_Separator & "gpr" & Directory_Separator & '_' & Default_Project_File_Name; -- User projects Project_File_Name : String_Access := null; -- The name of the project file specified with switch -P No_Project_File_Found : Boolean := False; -- True when no project file is specified and there is no .gpr file -- in the current working directory. Main_Project : Project_Id; -- The project id of the main project RTS_Option : constant String := "--RTS="; RTS_Language_Option : constant String := "--RTS:"; Db_Directory_Expected : Boolean := False; -- True when last switch was --db Distributed_Mode : Boolean := False; -- Wether the distributed compilation mode has been activated Slave_Env : String_Access; -- The name of the distributed build environment -- Packages of project files where unknown attributes are errors Naming_String : aliased String := "naming"; Builder_String : aliased String := "builder"; Compiler_String : aliased String := "compiler"; Binder_String : aliased String := "binder"; Linker_String : aliased String := "linker"; Clean_String : aliased String := "clean"; -- Name of packages to be checked when parsing/processing project files List_Of_Packages : aliased String_List := (Naming_String'Access, Builder_String'Access, Compiler_String'Access, Binder_String'Access, Linker_String'Access, Clean_String'Access); Packages_To_Check : constant String_List_Access := List_Of_Packages'Access; -- List of the packages to be checked when parsing/processing project files -- Local subprograms function Binder_Exchange_File_Name (Main_Base_Name : File_Name_Type; Prefix : Name_Id) return String_Access; -- Returns the name of the binder exchange file corresponding to an -- object file and a language. -- Main_Base_Name must have no extension specified procedure Create_Response_File (Format : Response_File_Format; Objects : String_List; Other_Arguments : String_List; Resp_File_Options : String_List; Name_1 : out Path_Name_Type; Name_2 : out Path_Name_Type); -- Create a temporary file as a response file that contains either the list -- of Objects in the correct Format, or for Format GCC the list of all -- arguments. It is the responsibility of the caller to delete this -- temporary file if needed. ---------- -- Misc -- ---------- procedure Find_Binding_Languages (Tree : Project_Tree_Ref; Root_Project : Project_Id); -- Check if in the project tree there are sources of languages that have -- a binder driver. -- Populates Tree's appdata (Binding and There_Are_Binder_Drivers). -- Nothing is done if the binding languages were already searched for -- this Tree. -- This also performs the check for aggregated project trees. function Get_Compiler_Driver_Path (Project_Tree : Project_Tree_Ref; Lang : Language_Ptr) return String_Access; -- Get, from the config, the path of the compiler driver. This is first -- looked for on the PATH if needed. -- Returns "null" if no compiler driver was specified for the language, and -- exit with an error if one was specified but not found. procedure Locate_Runtime (Project_Tree : Project_Tree_Ref; Language : Name_Id); -- Wrapper around Set_Runtime_For. If RTS_Name is a base name (a name -- without path separator), then calls Set_Runtime_For. Otherwise, convert -- it to an absolute path (possibly by searching it in the project path) procedure Look_For_Default_Project; -- Check if default.gpr exists in the current directory. If it does, use -- it. Otherwise, if there is only one file ending with .gpr, use it. function Partial_Name (Lib_Name : String; Number : Natural; Object_Suffix : String) return String; -- Returns the name of an object file created by the partial linker function Shared_Libgcc_Dir (Run_Time_Dir : String) return String; -- Returns the directory of the shared version of libgcc, if it can be -- found, otherwise returns an empty string. package Knowledge is function Normalized_Hostname return String; -- Return the normalized name of the host on which gprbuild is running. -- The knowledge base must have been parsed first. procedure Parse_Knowledge_Base (Project_Tree : Project_Tree_Ref; Directory : String := ""); end Knowledge; procedure Need_To_Compile (Source : Source_Id; Tree : Project_Tree_Ref; In_Project : Project_Id; Must_Compile : out Boolean; The_ALI : out ALI.ALI_Id; Object_Check : Boolean; Always_Compile : Boolean); -- Check if a source need to be compiled. -- A source need to be compiled if: -- - Force_Compilations is True -- - No object file generated for the language -- - Object file does not exist -- - Dependency file does not exist -- - Switches file does not exist -- - Either of these 3 files are older than the source or any source it -- depends on. -- If an ALI file had to be parsed, it is returned as The_ALI, so that the -- caller does not need to parse it again. -- -- Object_Check should be False when switch --no-object-check is used. When -- True, presence of the object file and its time stamp are checked to -- decide if a file needs to be compiled. -- -- Tree is the project tree in which Source is found (or the root tree when -- not using aggregate projects). -- -- Always_Compile should be True when gprbuid is called with -f -u and at -- least one source on the command line. function Project_Compilation_Failed (Prj : Project_Id; Recursive : Boolean := True) return Boolean; -- Returns True if all compilations for Prj (and all projects it depends on -- if Recursive is True) were successful and False otherwise. procedure Set_Failed_Compilation_Status (Prj : Project_Id); -- Record compilation failure status for the given project Maximum_Size : Integer; pragma Import (C, Maximum_Size, "__gnat_link_max"); -- Maximum number of bytes to put in an invocation of the -- Archive_Builder. function Ensure_Directory (Path : String) return String; -- Returns Path with an ending directory separator function File_MD5 (Pathname : String) return Message_Digest; -- Returns the file MD5 signature. Raises Name_Error if Pathname does not -- exists. function Relative_Path (Pathname, To : String) return String; -- Returns the relative pathname which corresponds to Pathname when -- starting from directory to. Both Pathname and To must be absolute paths. procedure Create_Sym_Link (From, To : String); -- Create a relative symlink in From pointing to To -- Architecture function Get_Target return String; -- Returns the current target for the compilation function Compute_Slave_Env (Project : Project_Tree_Ref; Auto : Boolean) return String; -- Compute a slave environment based on the command line parameter and -- the project variables. We want the same slave environment for identical -- build. Data is a string that must be taken into account in the returned -- value. function UTC_Time return Types.Time_Stamp_Type; -- Returns the UTC time function Check_Diff (Ts1, Ts2 : Types.Time_Stamp_Type; Max_Drift : Duration := 5.0) return Boolean; -- Check two time stamps, returns True if both time are in a range of -- Max_Drift seconds maximum. function To_Time_Stamp (Time : Calendar.Time) return Types.Time_Stamp_Type; -- Returns Time as a time stamp type end Gpr_Util; gprbuild-gpl-2014-src/src/gprconfig-knowledge.adb0000644000076700001450000044257312323721731021344 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R C O N F I G -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Unchecked_Deallocation; with Ada.Characters.Handling; use Ada.Characters.Handling; with Ada.Command_Line; use Ada.Command_Line; with Ada.Containers; use Ada.Containers; with Ada.Directories; use Ada.Directories; with Ada.Environment_Variables; use Ada.Environment_Variables; with Ada.Exceptions; use Ada.Exceptions; with Ada.IO_Exceptions; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Ada.Strings.Hash; with Ada.Strings.Hash_Case_Insensitive; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO; use Ada.Text_IO; with DOM.Core.Nodes; use DOM.Core, DOM.Core.Nodes; with DOM.Core.Documents; with Schema.Dom_Readers; use Schema.Dom_Readers; with Schema.Schema_Readers; use Schema.Schema_Readers; with Schema.Validators; use Schema.Validators; with Input_Sources.File; use Input_Sources.File; with GNAT.Case_Util; use GNAT.Case_Util; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.Expect; use GNAT.Expect; with GNAT.OS_Lib; use GNAT.OS_Lib; with GNAT.Regpat; use GNAT.Regpat; with GNAT.Strings; use GNAT.Strings; with GprConfig.Sdefault; use GprConfig.Sdefault; with Makeutl; use Makeutl; with Namet; use Namet; with Opt; with Prj; use Prj; with Sax.Readers; use Sax.Readers; package body GprConfig.Knowledge is package String_Maps is new Ada.Containers.Indefinite_Hashed_Maps (String, Unbounded_String, Ada.Strings.Hash_Case_Insensitive, "="); procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Pattern_Matcher, Pattern_Matcher_Access); type External_Value_Item is record Value : Name_Id; Alternate : Name_Id := No_Name; Extracted_From : Name_Id; end record; -- Value is the actual value of the node. -- Extracted_From will either be set to Value itself, or when the node is -- a to the full directory, before the regexp match. -- When the value comes from a node, Extracted_From is set to the -- full output of the shell command. package External_Value_Lists is new Ada.Containers.Doubly_Linked_Lists (External_Value_Item); package String_To_External_Value is new Ada.Containers.Indefinite_Hashed_Maps (Key_Type => String, Element_Type => External_Value_Lists.Cursor, Hash => Ada.Strings.Hash, Equivalent_Keys => "=", "=" => External_Value_Lists."="); package CDM renames Compiler_Description_Maps; package CFL renames Compiler_Filter_Lists; use Compiler_Lists, CFL, Compilers_Filter_Lists; use Configuration_Lists, String_Maps; use External_Value_Lists, String_Lists; use External_Value_Nodes; Case_Sensitive_Files : constant Boolean := Directory_Separator = '\'; On_Windows : constant Boolean := Directory_Separator = '\'; Ignore_Compiler : exception; -- Raised when the compiler should be ignored Indentation_Level : Integer := 0; -- Current indentation level for traces function Get_Variable_Value (Comp : Compiler; Name : String) return String; -- Return the value of a predefined or user-defined variable. -- If the variable is not defined a warning is emitted and an empty -- string is returned. function Get_Name_String_Or_Null (Name : Name_Id) return String; -- Return the string stored in Name (or the empty string if Name is -- No_Name) procedure Put_Verbose (Config : Configuration); -- Debug put for Config function Get_Attribute (N : Node; Attribute : String; Default : String) return String; -- Return the value of an attribute, or Default if the attribute does not -- exist function Is_Supported_Config (Base : Knowledge_Base; Compilers : Compiler_Lists.List) return Boolean; -- Whether we know how to link code compiled with all the selected -- compilers. function Is_Language_With_No_Compiler (Base : Knowledge_Base; Language_LC : String) return Boolean; -- Given a language name (lower case), returns True if that language is -- known to require no compiler function Node_Value_As_String (N : Node) return String; -- Return the value of the node, concatenating all Text children function Ends_With (Str, Suffix : String) return Boolean; -- Whether the string ends with Suffix. Always True if Suffix is the empty -- string. procedure Foreach_Compiler_In_Dir (Iterator : in out Compiler_Iterator'Class; Base : in out Knowledge_Base; Directory : String; From_Extra_Dir : Boolean; On_Target : Targets_Set_Id; Path_Order : Integer; Continue : out Boolean); -- Find all known compilers in Directory, and call Iterator.Callback as -- appropriate. procedure Get_Words (Words : String; Filter : Namet.Name_Id; Separator1 : Character; Separator2 : Character; Map : out String_Lists.List; Allow_Empty_Elements : Boolean); -- Return the list of words in Words. Splitting is done on special -- characters, so as to be compatible with a list of languages or a list of -- runtimes -- If Allow_Empty_Elements is false, then empty strings are not stored in -- the list. function Name_As_Directory (Dir : String) return String; -- Ensure that Dir ends with a directory separator function Get_String_No_Adalib (Str : String) return Namet.Name_Id; -- Return the name without "adalib" at the end function Get_String (Str : String) return Namet.Name_Id; function Get_String_Or_No_Name (Str : String) return Namet.Name_Id; -- Same as Name_Find, but does not require the user to modify -- Name_Buffer manually. -- The second version returns No_Name is the string is empty procedure Get_External_Value (Attribute : String; Value : External_Value; Comp : Compiler; Split_Into_Words : Boolean := True; Merge_Same_Dirs : Boolean := False; Processed_Value : out External_Value_Lists.List); -- Computes the value of Value, depending on its type. When an external -- command needs to be executed, Path is put first on the PATH environment -- variable. -- Raises Ignore_Compiler if the value doesn't match its -- regexp. -- The node is also taken into account. -- If Split_Into_Words is true, then the value read from or as a -- constant string is further assumed to be a comma-separated or space- -- separated string, and split. -- Comparisong with Matching is case-insensitive (this is needed for -- languages, does not matter for versions, is not used for targets) -- -- If Merge_Same_Dirs is True, then the values that come from a -- node will be merged (the last one is kept, other removed) if -- they point to the same physical directory (after normalizing names). -- -- This is only for use within a context. procedure Foreach_Language_Runtime (Iterator : in out Compiler_Iterator'Class; Base : in out Knowledge_Base; Name : Name_Id; Executable : Name_Id; Directory : String; Prefix : Name_Id; From_Extra_Dir : Boolean; On_Target : Targets_Set_Id; Descr : Compiler_Description; Path_Order : Integer; Continue : out Boolean); -- For each language/runtime parsed in Languages/Runtimes, create a new -- compiler in the list, if it matches Matching. -- If Stop_At_First_Match is true, then only the first matching compiler is -- returned, which provides a significant speedup in some cases function Is_Windows_Executable (Filename : String) return Boolean; -- Verify that a given filename is indeed an executable procedure Parse_All_Dirs (Processed_Value : out External_Value_Lists.List; Visited : in out String_To_External_Value.Map; Current_Dir : String; Path_To_Check : String; Regexp : Pattern_Matcher; Regexp_Str : String; Value_If_Match : Name_Id; Group : Integer; Group_Match : String := ""; Group_Count : Natural := 0; Contents : Pattern_Matcher_Access := null; Merge_Same_Dirs : Boolean); -- Parse all subdirectories of Current_Dir for those that match -- Path_To_Check (see description of ). When a match is found, -- the regexp is evaluated against the current directory, and the matching -- parenthesis group is appended to Append_To (comma-separated). -- If Group is -1, then Value_If_Match is used instead of the parenthesis -- group. -- Group_Match is the substring that matched Group (if it has been matched -- already). Group_Count is the number of parenthesis groups that have been -- processed so far. The idea is to compute the matching substring as we -- go, since the regexp might no longer match in the end, if for instance -- it includes ".." directories. -- -- If Merge_Same_Dirs is True, then the values that come from a -- node will be merged (the last one is kept, other removed) if -- they point to the same physical directory (after normalizing names). In -- this case, Visited contains the list of normalized directory names. -- -- Contents, if specified, is a regular expression. It indicates that any -- file matching the pattern should be parsed, and the first line matching -- that regexp should be used as the name of the file instead. This is a -- way to simulate symbolic links on platforms that do not use them. generic with function Callback (Var_Name, Index : String) return String; function Substitute_Variables (Str : String) return String; -- Substitute variables in Str (their value is computed through Callback) function Substitute_Variables_In_Compiler_Description (Str : String; Comp : Compiler) return String; function Substitute_Variables_In_Configuration (Base : Knowledge_Base; Str : String; Comps : Compiler_Lists.List) return String; -- Substitute the special "$..." names. -- Depending on the XML nodes we are in (specified by the context) the list -- of variables might be different. procedure Match (Filter : Compilers_Filter_Lists.List; Compilers : Compiler_Lists.List; Matching_Compiler : out Compiler_Access; Matched : out Boolean); procedure Match (Filter : Compilers_Filter; Compilers : Compiler_Lists.List; Matching_Compiler : out Compiler_Access; Matched : out Boolean); procedure Match (Filter : Compiler_Filter; Compilers : Compiler_Lists.List; Matching_Compiler : out Compiler_Access; Matched : out Boolean); -- Check whether Filter matches (and set Matched to the result). -- Matching_Compiler is set if there was a single node, and is -- to set the first compiler that matched in that node function Match (Target_Filter : String_Lists.List; Negate : Boolean; Compilers : Compiler_Lists.List) return Boolean; -- Return True if Filter matches the list of selected configurations procedure Merge_Config (Base : Knowledge_Base; Packages : in out String_Maps.Map; Compilers : Compiler_Lists.List; Config : String); -- Merge the contents of Config into Packages, so that each attributes ends -- up in the right package, and the packages are not duplicated. -- Selected_Compiler is the compiler that made the chunk match the filters. -- If there were several filter, No_Compiler should be passed -- in argument. procedure Skip_Spaces (Str : String; Index : in out Integer); -- Move Index from its current position to the next non-whitespace -- character in Str procedure Skip_Spaces_Backward (Str : String; Index : in out Integer); -- Same as Skip_Spaces, but goes backward function Is_Regexp (Str : String) return Boolean; -- Whether Str is a regular expression Exec_Suffix : constant GNAT.Strings.String_Access := Get_Executable_Suffix; function Unquote (Str : String; Remove_Quoted : Boolean := False) return String; -- Remove special '\' quoting characters from Str. -- As a special case, if Remove_Quoted is true, then '\' and the following -- char are simply omitted in the output. -- For instance: -- Str="A\." Remove_Quoted=False => output is "A." -- Str="A\." Remove_Quoted=False => output is "A" ------------------- -- Get_Attribute -- ------------------- function Get_Attribute (N : Node; Attribute : String; Default : String) return String is Attr : constant Node := Get_Named_Item (Attributes (N), Attribute); begin if Attr = null then return Default; else return Node_Value (Attr); end if; end Get_Attribute; -------------------------- -- Node_Value_As_String -- -------------------------- function Node_Value_As_String (N : Node) return String is Result : Unbounded_String; Child : Node := First_Child (N); begin while Child /= null loop exit when Node_Type (Child) = Element_Node; Append (Result, Node_Value (Child)); Child := Next_Sibling (Child); end loop; return To_String (Result); end Node_Value_As_String; ------------- -- Unquote -- ------------- function Unquote (Str : String; Remove_Quoted : Boolean := False) return String is Str2 : String (Str'Range); S : Integer := Str'First; Index : Integer := Str2'First; begin while S <= Str'Last loop if Str (S) = '\' then S := S + 1; if not Remove_Quoted then Str2 (Index) := Str (S); Index := Index + 1; end if; else Str2 (Index) := Str (S); Index := Index + 1; end if; S := S + 1; end loop; return Str2 (Str2'First .. Index - 1); end Unquote; --------------- -- Ends_With -- --------------- function Ends_With (Str, Suffix : String) return Boolean is begin return Suffix = "" or else (Str'Length >= Suffix'Length and then Str (Str'Last - Suffix'Length + 1 .. Str'Last) = Suffix); end Ends_With; --------------------------- -- Is_Windows_Executable -- --------------------------- function Is_Windows_Executable (Filename : String) return Boolean is type Byte is mod 256; for Byte'Size use 8; for Byte'Alignment use 1; type Bytes is array (Positive range <>) of Byte; Windows_Pattern : constant Bytes := (77, 90, 144, 0); Fd : constant File_Descriptor := Open_Read (Filename, Binary); B : Bytes (1 .. 4); N_Read : Integer; begin N_Read := Read (Fd, B'Address, 4); Close (Fd); if N_Read < 4 then return False; else if B = Windows_Pattern then return True; else return False; end if; end if; end Is_Windows_Executable; --------------- -- Is_Regexp -- --------------- function Is_Regexp (Str : String) return Boolean is -- Take into account characters quoted by '\'. We just remove them for -- now, so that when we quote the regexp it won't see these potentially -- special characters. -- The goal is that for instance "\.\." is not considered as a regexp, -- but "\.." is. Str2 : constant String := Unquote (Str, Remove_Quoted => True); begin return GNAT.Regpat.Quote (Str2) /= Str2; end Is_Regexp; ----------------- -- Put_Verbose -- ----------------- procedure Put_Verbose (Str : String; Indent_Delta : Integer := 0) is begin if Current_Verbosity /= Default then if Indent_Delta < 0 then Indentation_Level := Indentation_Level - 2; end if; if Str /= "" then Put_Line (Standard_Error, (1 .. Indentation_Level => ' ') & Str); end if; if Indent_Delta > 0 then Indentation_Level := Indentation_Level + 2; end if; end if; end Put_Verbose; ----------------------- -- Name_As_Directory -- ----------------------- function Name_As_Directory (Dir : String) return String is begin if Dir = "" or else Dir (Dir'Last) = Directory_Separator or else Dir (Dir'Last) = '/' then return Dir; else return Dir & Directory_Separator; end if; end Name_As_Directory; ---------------------------------- -- Is_Language_With_No_Compiler -- ---------------------------------- function Is_Language_With_No_Compiler (Base : Knowledge_Base; Language_LC : String) return Boolean is C : String_Lists.Cursor := First (Base.No_Compilers); begin while Has_Element (C) loop if String_Lists.Element (C) = Language_LC then return True; end if; Next (C); end loop; return False; end Is_Language_With_No_Compiler; RTS_List : GNAT.OS_Lib.String_List_Access := new GNAT.OS_Lib.String_List (1 .. 4); -- List of the knowledge base directories that hac=ve already been parsed RTS_Last : Natural := 0; -- Index of the last directory in RTS_List -------------------------- -- Parse_Knowledge_Base -- -------------------------- procedure Parse_Knowledge_Base (Base : in out Knowledge_Base; Directory : String; Parse_Compiler_Info : Boolean := True; Validate : Boolean := False) is procedure Parse_Compiler_Description (Base : in out Knowledge_Base; File : String; Description : Node); -- Parse a compiler description described by N. Appends the result to -- Base.Compilers or Base.No_Compilers procedure Parse_Configuration (Append_To : in out Configuration_Lists.List; File : String; Description : Node); -- Parse a configuration node procedure Parse_Targets_Set (Append_To : in out Targets_Set_Vectors.Vector; File : String; Description : Node); -- Parse a targets set node -------------------------------- -- Parse_Compiler_Description -- -------------------------------- procedure Parse_Compiler_Description (Base : in out Knowledge_Base; File : String; Description : Node) is procedure Parse_External_Value (Value : out External_Value; File : String; External : Node); -- Parse an XML node that describes an external value -------------------------- -- Parse_External_Value -- -------------------------- procedure Parse_External_Value (Value : out External_Value; File : String; External : Node) is Tmp : Node := First_Child (External); External_Node : External_Value_Node; Is_Done : Boolean := True; Static_Value : constant String := Node_Value_As_String (External); Has_Static : Boolean := False; begin for S in Static_Value'Range loop if Static_Value (S) /= ' ' and then Static_Value (S) /= ASCII.LF then Has_Static := True; exit; end if; end loop; -- Constant value is not within a nested node if Has_Static then External_Node := (Typ => Value_Constant, Value => Get_String (Static_Value)); Append (Value, External_Node); Is_Done := False; end if; while Tmp /= null loop if Node_Type (Tmp) /= Element_Node then null; elsif Node_Name (Tmp) = "external" then if not Is_Done then Append (Value, (Typ => Value_Done)); end if; External_Node := (Typ => Value_Shell, Command => Get_String (Node_Value_As_String (Tmp))); Append (Value, External_Node); Is_Done := False; elsif Node_Name (Tmp) = "directory" then declare C : constant String := Get_Attribute (Tmp, "contents", ""); Contents : Pattern_Matcher_Access; begin if C /= "" then Contents := new Pattern_Matcher'(Compile (C)); end if; External_Node := (Typ => Value_Directory, Directory => Get_String (Node_Value_As_String (Tmp)), Contents => Contents, Dir_If_Match => No_Name, Directory_Group => 0); end; begin External_Node.Directory_Group := Integer'Value (Get_Attribute (Tmp, "group", "0")); exception when Constraint_Error => External_Node.Directory_Group := -1; External_Node.Dir_If_Match := Get_String (Get_Attribute (Tmp, "group", "0")); end; Append (Value, External_Node); Is_Done := True; elsif Node_Name (Tmp) = "getenv" then if not Is_Done then Append (Value, (Typ => Value_Done)); end if; declare Name : constant String := Get_Attribute (Tmp, "name", ""); begin if Ada.Environment_Variables.Exists (Name) then External_Node := (Typ => Value_Constant, Value => Get_String (Ada.Environment_Variables.Value (Name))); else Put_Verbose ("warning: environment variable '" & Name & "' is not defined"); External_Node := (Typ => Value_Constant, Value => No_Name); end if; end; Append (Value, External_Node); Is_Done := False; elsif Node_Name (Tmp) = "filter" then External_Node := (Typ => Value_Filter, Filter => Get_String (Node_Value_As_String (Tmp))); Append (Value, External_Node); Is_Done := True; elsif Node_Name (Tmp) = "must_match" then External_Node := (Typ => Value_Must_Match, Must_Match => Get_String (Node_Value_As_String (Tmp))); Append (Value, External_Node); Is_Done := True; elsif Node_Name (Tmp) = "grep" then External_Node := (Typ => Value_Grep, Regexp_Re => new Pattern_Matcher' (Compile (Get_Attribute (Tmp, "regexp", ".*"), Multiple_Lines)), Group => Integer'Value (Get_Attribute (Tmp, "group", "0"))); Append (Value, External_Node); elsif Node_Name (Tmp) = "nogrep" then External_Node := (Typ => Value_Nogrep, Regexp_No => new Pattern_Matcher' (Compile (Get_Attribute (Tmp, "regexp", ".*"), Multiple_Lines))); Append (Value, External_Node); else Put_Line (Standard_Error, "Invalid XML description for " & Node_Name (External) & " in file " & File); Put_Line (Standard_Error, " Invalid tag: " & Node_Name (Tmp)); Value := Null_External_Value; end if; Tmp := Next_Sibling (Tmp); end loop; if not Is_Done then Append (Value, (Typ => Value_Done)); end if; exception when Constraint_Error => Put_Line (Standard_Error, "Invalid group number for " & Node_Name (External) & " in file " & File); Value := Null_External_Value; end Parse_External_Value; Compiler : Compiler_Description; N : Node := First_Child (Description); Lang : External_Value_Lists.List; C : External_Value_Lists.Cursor; begin while N /= null loop if Node_Type (N) /= Element_Node then null; elsif Node_Name (N) = "executable" then declare Prefix : constant String := Get_Attribute (N, "prefix", "@@"); Val : constant String := Node_Value_As_String (N); begin if Val = "" then -- A special language that requires no executable. We do -- not store it in the list of compilers, since these -- should not be detected on the PATH anyway. Compiler.Executable := No_Name; else Compiler.Executable := Get_String (Val); begin Compiler.Prefix_Index := Integer'Value (Prefix); exception when Constraint_Error => Compiler.Prefix_Index := -1; end; if not Ends_With (Val, Exec_Suffix.all) then Compiler.Executable_Re := new Pattern_Matcher' (Compile ("^" & Val & Exec_Suffix.all & "$")); else Compiler.Executable_Re := new Pattern_Matcher' (Compile ("^" & Val & "$")); end if; Base.Check_Executable_Regexp := True; end if; exception when Expression_Error => Put_Line (Standard_Error, "Invalid regular expression found in the configuration" & " files: " & Val & " while parsing " & File); Unchecked_Free (Compiler.Executable_Re); end; elsif Node_Name (N) = "name" then Compiler.Name := Get_String (Node_Value_As_String (N)); elsif Node_Name (N) = "version" then Parse_External_Value (Value => Compiler.Version, File => File, External => N); elsif Node_Name (N) = "variable" then declare Name : constant String := Get_Attribute (N, "name", "@@"); begin Append (Compiler.Variables, (Typ => Value_Variable, Var_Name => Get_String (Name))); Parse_External_Value (Value => Compiler.Variables, File => File, External => N); end; elsif Node_Name (N) = "languages" then Parse_External_Value (Value => Compiler.Languages, File => File, External => N); elsif Node_Name (N) = "runtimes" then declare Defaults : constant String := Get_Attribute (N, "default", ""); begin if Defaults /= "" then Get_Words (Defaults, No_Name, ' ', ',', Compiler.Default_Runtimes, False); end if; Parse_External_Value (Value => Compiler.Runtimes, File => File, External => N); end; elsif Node_Name (N) = "target" then Parse_External_Value (Value => Compiler.Target, File => File, External => N); else Put_Line (Standard_Error, "Unknown XML tag in " & File & ": " & Node_Name (N)); raise Invalid_Knowledge_Base; end if; N := Next_Sibling (N); end loop; if Compiler.Executable = No_Name then Get_External_Value (Attribute => "languages", Value => Compiler.Languages, Comp => No_Compiler, Split_Into_Words => True, Processed_Value => Lang); C := First (Lang); while Has_Element (C) loop String_Lists.Append (Base.No_Compilers, To_Lower (Get_Name_String (External_Value_Lists.Element (C).Value))); Next (C); end loop; elsif Compiler.Name /= No_Name then CDM.Include (Base.Compilers, Compiler.Name, Compiler); end if; end Parse_Compiler_Description; ------------------------- -- Parse_Configuration -- ------------------------- procedure Parse_Configuration (Append_To : in out Configuration_Lists.List; File : String; Description : Node) is Config : Configuration; Chunk : Unbounded_String; N : Node := First_Child (Description); N2 : Node; Compilers : Compilers_Filter; Ignore_Config : Boolean := False; Negate : Boolean; Filter : Compiler_Filter; begin Config.Supported := True; while N /= null loop if Node_Type (N) /= Element_Node then null; elsif Node_Name (N) = "compilers" then Compilers := No_Compilers_Filter; N2 := First_Child (N); while N2 /= null loop if Node_Type (N2) /= Element_Node then null; elsif Node_Name (N2) = "compiler" then declare Version : constant String := Get_Attribute (N2, "version", ""); Runtime : constant String := Get_Attribute (N2, "runtime", ""); begin Filter := Compiler_Filter' (Name => Get_String_Or_No_Name (Get_Attribute (N2, "name", "")), Version => Get_String_Or_No_Name (Version), Version_Re => null, Runtime => Get_String_Or_No_Name (Runtime), Runtime_Re => null, Language_LC => Get_String_Or_No_Name (To_Lower (Get_Attribute (N2, "language", "")))); if Version /= "" then Filter.Version_Re := new Pattern_Matcher' (Compile (Version, Case_Insensitive)); end if; if Runtime /= "" then Filter.Runtime_Re := new Pattern_Matcher' (Compile (Runtime, Case_Insensitive)); end if; end; Append (Compilers.Compiler, Filter); else Put_Line (Standard_Error, "Unknown XML tag in " & File & ": " & Node_Name (N2)); raise Invalid_Knowledge_Base; end if; N2 := Next_Sibling (N2); end loop; Compilers.Negate := Boolean'Value (Get_Attribute (N, "negate", "False")); Append (Config.Compilers_Filters, Compilers); elsif Node_Name (N) = "targets" then if not Is_Empty (Config.Targets_Filters) then Put_Line (Standard_Error, "Can have a single filter in " & File); else N2 := First_Child (N); while N2 /= null loop if Node_Type (N2) /= Element_Node then null; elsif Node_Name (N2) = "target" then Append (Config.Targets_Filters, Get_Attribute (N2, "name", "")); else Put_Line (Standard_Error, "Unknown XML tag in " & File & ": " & Node_Name (N2)); raise Invalid_Knowledge_Base; end if; N2 := Next_Sibling (N2); end loop; Config.Negate_Targets := Boolean'Value (Get_Attribute (N, "negate", "False")); end if; elsif Node_Name (N) = "hosts" then -- Resolve this filter immediately. This saves memory, since we -- don't need to store it in memory if we know it won't apply. N2 := First_Child (N); Negate := Boolean'Value (Get_Attribute (N, "negate", "False")); Ignore_Config := not Negate; while N2 /= null loop if Node_Type (N2) /= Element_Node then null; elsif Node_Name (N2) = "host" then if Match (Get_Attribute (N2, "name", ""), Sdefault.Hostname) then Ignore_Config := Negate; exit; end if; else Put_Line (Standard_Error, "Unknown XML tag in " & File & ": " & Node_Name (N2)); raise Invalid_Knowledge_Base; end if; N2 := Next_Sibling (N2); end loop; exit when Ignore_Config; elsif Node_Name (N) = "config" then if Node_Value_As_String (N) = "" then Config.Supported := False; else Append (Chunk, Node_Value_As_String (N)); end if; else Put_Line (Standard_Error, "Unknown XML tag in " & File & ": " & Node_Name (N)); raise Invalid_Knowledge_Base; end if; N := Next_Sibling (N); end loop; if not Ignore_Config then Config.Config := Get_String (To_String (Chunk)); Append (Append_To, Config); end if; end Parse_Configuration; ----------------------- -- Parse_Targets_Set -- ----------------------- procedure Parse_Targets_Set (Append_To : in out Targets_Set_Vectors.Vector; File : String; Description : Node) is Name : Name_Id := No_Name; Set : Target_Lists.List; Pattern : Pattern_Matcher_Access; N : Node := First_Child (Description); begin while N /= null loop if Node_Type (N) /= Element_Node then null; elsif Node_Name (N) = "target" then declare Val : constant String := Node_Value_As_String (N); begin Pattern := new Pattern_Matcher'(Compile ("^" & Val & "$")); Target_Lists.Append (Set, Pattern); if Name = No_Name then Name := Get_String (Val); end if; exception when Expression_Error => Put_Line ("Invalid regular expression " & Val & " found in the target-set while parsing " & File); raise Invalid_Knowledge_Base; end; else Put_Line (Standard_Error, "Unknown XML tag in " & File & ": " & Node_Name (N)); raise Invalid_Knowledge_Base; end if; N := Next_Sibling (N); end loop; if not Target_Lists.Is_Empty (Set) then Targets_Set_Vectors.Append (Append_To, (Name, Set)); end if; end Parse_Targets_Set; Search : Search_Type; File : Directory_Entry_Type; File_Node : Node; N : Node; Reader : Schema.Dom_Readers.Tree_Reader; Input : File_Input; Schema : Schema_Reader; Dir : constant String := Normalize_Pathname (Directory, Case_Sensitive => False); begin -- Do not parse several times the same database directory for J in 1 .. RTS_Last loop if RTS_List (J).all = Dir then return; end if; end loop; -- Extend RTS_List if it is full if RTS_Last = RTS_List'Last then declare New_List : constant GNAT.OS_Lib.String_List_Access := new GNAT.OS_Lib.String_List (1 .. RTS_List'Length * 2); begin New_List (1 .. RTS_Last) := RTS_List (1 .. RTS_Last); RTS_List := New_List; end; end if; RTS_Last := RTS_Last + 1; RTS_List (RTS_Last) := new String'(Dir); if Current_Verbosity = High then Standard.Schema.Set_Debug_Output (True); end if; Reader.Set_Feature (Schema_Validation_Feature, Validate); Reader.Set_Feature (Validation_Feature, False); -- Do not use DTD if Validate then -- Load the XSD file used to validate the knowledge base declare Filename : constant String := Format_Pathname (Default_Knowledge_Base_Directory & "/gprconfig.xsd"); XSD : File_Input; begin Put_Verbose ("Parsing " & Filename); Open (Filename, XSD); Parse (Schema, XSD); Close (XSD); Reader.Set_Grammar (Get_Grammar (Schema)); Free (Schema); exception when Ada.Directories.Name_Error => Put_Line (Standard_Error, "Installation error: could not find the file " & Filename); raise Knowledge_Base_Validation_Error; when XML_Validation_Error => Put_Line (Standard_Error, Get_Error_Message (Schema)); raise Knowledge_Base_Validation_Error; end; end if; Put_Verbose ("Parsing knowledge base at " & Dir); Start_Search (Search, Directory => Dir, Pattern => "*.xml", Filter => (Ordinary_File => True, others => False)); while More_Entries (Search) loop Get_Next_Entry (Search, File); Put_Verbose ("Parsing file " & Full_Name (File)); Open (Full_Name (File), Input); Parse (Reader, Input); Close (Input); File_Node := DOM.Core.Documents.Get_Element (Get_Tree (Reader)); if Node_Name (File_Node) = "gprconfig" then N := First_Child (File_Node); while N /= null loop if Node_Type (N) /= Element_Node then null; elsif Node_Name (N) = "compiler_description" then if Parse_Compiler_Info then Parse_Compiler_Description (Base => Base, File => Simple_Name (File), Description => N); end if; elsif Node_Name (N) = "configuration" then if Parse_Compiler_Info then Parse_Configuration (Append_To => Base.Configurations, File => Simple_Name (File), Description => N); end if; elsif Node_Name (N) = "targetset" then Parse_Targets_Set (Append_To => Base.Targets_Sets, File => Simple_Name (File), Description => N); else Put_Line (Standard_Error, "Unknown XML tag in " & Simple_Name (File) & ": " & Node_Name (N)); raise Invalid_Knowledge_Base; end if; N := Next_Sibling (N); end loop; else Put_Line (Standard_Error, "Invalid toplevel XML tag in " & Simple_Name (File)); end if; Free (Reader); end loop; End_Search (Search); exception when Ada.Directories.Name_Error => Put_Verbose ("Directory not found: " & Directory); when Invalid_Knowledge_Base | Knowledge_Base_Validation_Error => raise; when E : XML_Fatal_Error => Put_Line (Standard_Error, Exception_Message (E)); raise Invalid_Knowledge_Base; when XML_Validation_Error => Put_Line (Standard_Error, Get_Error_Message (Reader)); raise Knowledge_Base_Validation_Error; when E : others => Put_Line (Standard_Error, "Unexpected exception while parsing knowledge base: " & Exception_Information (E)); raise Invalid_Knowledge_Base; end Parse_Knowledge_Base; ------------------------ -- Get_Variable_Value -- ------------------------ function Get_Variable_Value (Comp : Compiler; Name : String) return String is N : constant Name_Id := Get_String (Name); begin if Variables_Maps.Contains (Comp.Variables, N) then return Get_Name_String (Variables_Maps.Element (Comp.Variables, N)); elsif Name = "HOST" then return Sdefault.Hostname; elsif Name = "TARGET" then return Get_Name_String (Comp.Target); elsif Name = "RUNTIME_DIR" then return Name_As_Directory (Get_Name_String (Comp.Runtime_Dir)); elsif Name = "EXEC" then return Get_Name_String_Or_Null (Comp.Executable); elsif Name = "VERSION" then return Get_Name_String_Or_Null (Comp.Version); elsif Name = "LANGUAGE" then return Get_Name_String_Or_Null (Comp.Language_LC); elsif Name = "RUNTIME" then return Get_Name_String_Or_Null (Comp.Runtime); elsif Name = "PREFIX" then return Get_Name_String_Or_Null (Comp.Prefix); elsif Name = "PATH" then return Get_Name_String (Comp.Path); elsif Name = "GPRCONFIG_PREFIX" then return Executable_Prefix_Path; end if; raise Invalid_Knowledge_Base with "variable '" & Name & "' is not defined"; end Get_Variable_Value; -------------------------- -- Substitute_Variables -- -------------------------- function Substitute_Variables (Str : String) return String is Str_Len : constant Natural := Str'Last; Pos : Natural := Str'First; Last : Natural := Pos; Result : Unbounded_String; Word_Start, Word_End, Tmp : Natural; Has_Index : Boolean; begin while Pos < Str_Len loop if Str (Pos) = '$' and then Str (Pos + 1) = '$' then Append (Result, Str (Last .. Pos - 1)); Append (Result, "$"); Last := Pos + 2; Pos := Last; elsif Str (Pos) = '$' then if Str (Pos + 1) = '{' then Word_Start := Pos + 2; Tmp := Pos + 2; while Tmp <= Str_Len and then Str (Tmp) /= '}' loop Tmp := Tmp + 1; end loop; Tmp := Tmp + 1; Word_End := Tmp - 2; else Word_Start := Pos + 1; Tmp := Pos + 1; while Tmp <= Str_Len and then (Is_Alphanumeric (Str (Tmp)) or else Str (Tmp) = '_') loop Tmp := Tmp + 1; end loop; Word_End := Tmp - 1; end if; Append (Result, Str (Last .. Pos - 1)); Has_Index := False; for W in Word_Start .. Word_End loop if Str (W) = '(' then Has_Index := True; if Str (Word_End) /= ')' then Put_Line (Standard_Error, "Missing closing parenthesis in variable name: " & Str (Word_Start .. Word_End)); raise Invalid_Knowledge_Base; else Append (Result, Callback (Var_Name => Str (Word_Start .. W - 1), Index => Str (W + 1 .. Word_End - 1))); end if; exit; end if; end loop; if not Has_Index then Append (Result, Callback (Str (Word_Start .. Word_End), "")); end if; Last := Tmp; Pos := Last; else Pos := Pos + 1; end if; end loop; Append (Result, Str (Last .. Str_Len)); return To_String (Result); end Substitute_Variables; -------------------------------------------------- -- Substitute_Variables_In_Compiler_Description -- -------------------------------------------------- function Substitute_Variables_In_Compiler_Description (Str : String; Comp : Compiler) return String is function Callback (Var_Name, Index : String) return String; -------------- -- Callback -- -------------- function Callback (Var_Name, Index : String) return String is begin if Index /= "" then Put_Line (Standard_Error, "Indexed variables only allowed in (in " & Var_Name & "(" & Index & ")"); raise Invalid_Knowledge_Base; end if; return Get_Variable_Value (Comp, Var_Name); end Callback; function Do_Substitute is new Substitute_Variables (Callback); begin return Do_Substitute (Str); end Substitute_Variables_In_Compiler_Description; ------------------------------------------- -- Substitute_Variables_In_Configuration -- ------------------------------------------- function Substitute_Variables_In_Configuration (Base : Knowledge_Base; Str : String; Comps : Compiler_Lists.List) return String is function Callback (Var_Name, Index : String) return String; -------------- -- Callback -- -------------- function Callback (Var_Name, Index : String) return String is C : Compiler_Lists.Cursor; Comp : Compiler_Access; Idx : constant Name_Id := Get_String_Or_No_Name (To_Lower (Index)); begin if Var_Name = "GPRCONFIG_PREFIX" then return Executable_Prefix_Path; elsif Index = "" then if Var_Name = "TARGET" and then not Is_Empty (Comps) then -- Can have an optional language index. -- If there is no index, all compilers share the same target, -- so just take that of the first compiler in the list return Normalized_Target (Base, Compiler_Lists.Element (First (Comps)).Targets_Set); else Put_Line (Standard_Error, "Ambiguous variable substitution, need to specify the" & " language (in " & Var_Name & ")"); raise Invalid_Knowledge_Base; end if; else C := First (Comps); while Has_Element (C) loop Comp := Compiler_Lists.Element (C); if Comp.Selected and then Comp.Language_LC = Idx then return Get_Variable_Value (Comp.all, Var_Name); end if; Next (C); end loop; end if; return ""; end Callback; function Do_Substitute is new Substitute_Variables (Callback); begin return Do_Substitute (Str); end Substitute_Variables_In_Configuration; -------------------- -- Parse_All_Dirs -- -------------------- procedure Parse_All_Dirs (Processed_Value : out External_Value_Lists.List; Visited : in out String_To_External_Value.Map; Current_Dir : String; Path_To_Check : String; Regexp : Pattern_Matcher; Regexp_Str : String; Value_If_Match : Name_Id; Group : Integer; Group_Match : String := ""; Group_Count : Natural := 0; Contents : Pattern_Matcher_Access := null; Merge_Same_Dirs : Boolean) is procedure Save_File (Current_Dir : String; Val : Name_Id); -- Mark the given directory as valid for the configuration. -- This takes care of removing duplicates if needed. --------------- -- Save_File -- --------------- procedure Save_File (Current_Dir : String; Val : Name_Id) is begin if not Merge_Same_Dirs then Put_Verbose (": SAVE " & Current_Dir); Append (Processed_Value, (Value => Val, Alternate => No_Name, Extracted_From => Get_String_No_Adalib (Current_Dir))); else declare use String_To_External_Value; Normalized : constant String := Normalize_Pathname (Name => Current_Dir, Directory => "", Resolve_Links => True, Case_Sensitive => True); Prev : External_Value_Lists.Cursor; Rec : External_Value_Item; begin if Visited.Contains (Normalized) then Put_Verbose (": ALREADY FOUND (" & Get_Name_String (Val) & ") " & Current_Dir); Prev := Visited.Element (Normalized); Rec := External_Value_Lists.Element (Prev); Rec.Alternate := Val; External_Value_Lists.Replace_Element (Container => Processed_Value, Position => Prev, New_Item => Rec); else Put_Verbose (": SAVE (" & Get_Name_String (Val) & ") " & Current_Dir); Append (Processed_Value, (Value => Val, Alternate => No_Name, Extracted_From => Get_String_No_Adalib (Current_Dir))); Visited.Include (Normalized, External_Value_Lists.Last (Processed_Value)); end if; end; end if; end Save_File; First : constant Integer := Path_To_Check'First; Last : Integer; Val : Name_Id; begin if Path_To_Check'Length = 0 or else Path_To_Check = "/" or else Path_To_Check = "" & Directory_Separator then if Group = -1 then Val := Value_If_Match; else Val := Get_String (Group_Match); end if; if Contents /= null and then Is_Regular_File (Current_Dir) then Put_Verbose (": Checking inside file " & Current_Dir); declare F : File_Type; begin Open (F, In_File, Current_Dir); while not End_Of_File (F) loop declare Line : constant String := Get_Line (F); begin Put_Verbose (": read line " & Line); if Match (Contents.all, Line) then Save_File (Normalize_Pathname (Name => Line, Directory => Dir_Name (Current_Dir), Resolve_Links => True), Val); exit; end if; end; end loop; Close (F); end; else Save_File (Current_Dir, Val); end if; else -- Do not split on '\', since we document we only accept UNIX paths -- anyway. This leaves \ for regexp quotes Last := First + 1; while Last <= Path_To_Check'Last and then Path_To_Check (Last) /= '/' loop Last := Last + 1; end loop; -- If we do not have a regexp. if not Is_Regexp (Path_To_Check (First .. Last - 1)) then declare Dir : constant String := Normalize_Pathname (Current_Dir, Resolve_Links => False) & Directory_Separator & Unquote (Path_To_Check (First .. Last - 1)); Remains : constant String := Path_To_Check (Last + 1 .. Path_To_Check'Last); begin if (Remains'Length = 0 or else Remains = "/" or else Remains = "" & Directory_Separator) and then Is_Regular_File (Dir) then Put_Verbose (": Found file " & Dir); -- If there is such a subdir, keep checking Parse_All_Dirs (Processed_Value => Processed_Value, Visited => Visited, Current_Dir => Dir, Path_To_Check => Remains, Regexp => Regexp, Regexp_Str => Regexp_Str, Value_If_Match => Value_If_Match, Group => Group, Group_Match => Group_Match, Group_Count => Group_Count, Contents => Contents, Merge_Same_Dirs => Merge_Same_Dirs); elsif Is_Directory (Dir) then Put_Verbose (": Recurse into " & Dir); -- If there is such a subdir, keep checking Parse_All_Dirs (Processed_Value => Processed_Value, Visited => Visited, Current_Dir => Dir & Directory_Separator, Path_To_Check => Remains, Regexp => Regexp, Regexp_Str => Regexp_Str, Value_If_Match => Value_If_Match, Group => Group, Group_Match => Group_Match, Group_Count => Group_Count, Contents => Contents, Merge_Same_Dirs => Merge_Same_Dirs); else Put_Verbose (": No such directory: " & Dir); end if; end; -- Else we have a regexp, check all files else declare File_Re : constant String := Path_To_Check (First .. Last - 1); File_Regexp : constant Pattern_Matcher := Compile (File_Re); Search : Search_Type; File : Directory_Entry_Type; Filter : Ada.Directories.Filter_Type; begin if Current_Verbosity /= Default and then File_Re = ".." then Put_Verbose ("Potential error: .. is generally not meant as a regexp," & " and should be quoted in this case, as in \.\."); end if; if Path_To_Check (Last) = '/' then Put_Verbose (": Check directories in " & Current_Dir & " that match " & File_Re); Filter := (Directory => True, others => False); else Put_Verbose (": Check files in " & Current_Dir & " that match " & File_Re); Filter := (others => True); end if; Start_Search (Search => Search, Directory => Current_Dir, Filter => Filter, Pattern => ""); while More_Entries (Search) loop Get_Next_Entry (Search, File); if Simple_Name (File) /= "." and then Simple_Name (File) /= ".." then declare Matched : Match_Array (0 .. Integer'Max (Group, 0)); Simple : constant String := Simple_Name (File); Count : constant Natural := Paren_Count (File_Regexp); begin Match (File_Regexp, Simple, Matched); if Matched (0) /= No_Match then Put_Verbose (": Matched " & Simple_Name (File)); if Group_Count < Group and then Group_Count + Count >= Group then Put_Verbose (": Found matched group: " & Simple (Matched (Group - Group_Count).First .. Matched (Group - Group_Count).Last)); Parse_All_Dirs (Processed_Value => Processed_Value, Visited => Visited, Current_Dir => Full_Name (File) & Directory_Separator, Path_To_Check => Path_To_Check (Last + 1 .. Path_To_Check'Last), Regexp => Regexp, Regexp_Str => Regexp_Str, Value_If_Match => Value_If_Match, Group => Group, Group_Match => Simple (Matched (Group - Group_Count).First .. Matched (Group - Group_Count).Last), Group_Count => Group_Count + Count, Contents => Contents, Merge_Same_Dirs => Merge_Same_Dirs); else Parse_All_Dirs (Processed_Value => Processed_Value, Visited => Visited, Current_Dir => Full_Name (File) & Directory_Separator, Path_To_Check => Path_To_Check (Last + 1 .. Path_To_Check'Last), Regexp => Regexp, Regexp_Str => Regexp_Str, Value_If_Match => Value_If_Match, Group => Group, Group_Match => Group_Match, Group_Count => Group_Count + Count, Contents => Contents, Merge_Same_Dirs => Merge_Same_Dirs); end if; end if; end; end if; end loop; end; end if; end if; end Parse_All_Dirs; ------------------------ -- Get_External_Value -- ------------------------ procedure Get_External_Value (Attribute : String; Value : External_Value; Comp : Compiler; Split_Into_Words : Boolean := True; Merge_Same_Dirs : Boolean := False; Processed_Value : out External_Value_Lists.List) is Saved_Path : constant String := Ada.Environment_Variables.Value ("PATH"); Status : aliased Integer; Extracted_From : Name_Id := No_Name; Tmp_Result : Unbounded_String; Node_Cursor : External_Value_Nodes.Cursor := First (Value); Node : External_Value_Node; From_Static : Boolean := False; Visited : String_To_External_Value.Map; begin Clear (Processed_Value); while Has_Element (Node_Cursor) loop while Has_Element (Node_Cursor) loop Node := External_Value_Nodes.Element (Node_Cursor); case Node.Typ is when Value_Variable => Extracted_From := Node.Var_Name; when Value_Constant => if Node.Value = No_Name then Tmp_Result := Null_Unbounded_String; else Tmp_Result := To_Unbounded_String (Substitute_Variables_In_Compiler_Description (Get_Name_String (Node.Value), Comp)); end if; From_Static := True; Put_Verbose (Attribute & ": constant := " & To_String (Tmp_Result)); when Value_Shell => Ada.Environment_Variables.Set ("PATH", Get_Name_String (Comp.Path) & Path_Separator & Saved_Path); declare Command : constant String := Substitute_Variables_In_Compiler_Description (Get_Name_String (Node.Command), Comp); begin Tmp_Result := Null_Unbounded_String; declare Args : Argument_List_Access := Argument_String_To_List (Command); Output : constant String := Get_Command_Output (Command => Args (Args'First).all, Arguments => Args (Args'First + 1 .. Args'Last), Input => "", Status => Status'Unchecked_Access, Err_To_Out => True); begin GNAT.Strings.Free (Args); Ada.Environment_Variables.Set ("PATH", Saved_Path); Tmp_Result := To_Unbounded_String (Output); if Current_Verbosity = High then Put_Verbose (Attribute & ": executing """ & Command & """ output=""" & Output & """"); elsif Current_Verbosity = Medium then Put_Verbose (Attribute & ": executing """ & Command & """ output= no match"); end if; end; exception when Invalid_Process => Put_Verbose ("Spawn failed for " & Command); end; when Value_Directory => declare Search : constant String := Substitute_Variables_In_Compiler_Description (Get_Name_String (Node.Directory), Comp); begin if Search (Search'First) = '/' then Put_Verbose (Attribute & ": search directories matching " & Search & ", starting from /", 1); Parse_All_Dirs (Processed_Value => Processed_Value, Visited => Visited, Current_Dir => "", Path_To_Check => Search, Contents => Node.Contents, Regexp => Compile (Search (Search'First + 1 .. Search'Last)), Regexp_Str => Search, Value_If_Match => Node.Dir_If_Match, Merge_Same_Dirs => Merge_Same_Dirs, Group => Node.Directory_Group); else if Current_Verbosity /= Default then Put_Verbose (Attribute & ": search directories matching " & Search & ", starting from " & Get_Name_String (Comp.Path), 1); end if; Parse_All_Dirs (Processed_Value => Processed_Value, Visited => Visited, Current_Dir => Get_Name_String (Comp.Path), Path_To_Check => Search, Contents => Node.Contents, Regexp => Compile (Search), Regexp_Str => Search, Value_If_Match => Node.Dir_If_Match, Merge_Same_Dirs => Merge_Same_Dirs, Group => Node.Directory_Group); end if; Put_Verbose ("Done search directories", -1); end; when Value_Grep => declare Matched : Match_Array (0 .. Node.Group); Tmp_Str : constant String := To_String (Tmp_Result); begin Match (Node.Regexp_Re.all, Tmp_Str, Matched); if Matched (0) /= No_Match then Tmp_Result := To_Unbounded_String (Tmp_Str (Matched (Node.Group).First .. Matched (Node.Group).Last)); Put_Verbose (Attribute & ": grep matched=""" & To_String (Tmp_Result) & """"); else Tmp_Result := Null_Unbounded_String; Put_Verbose (Attribute & ": grep no match"); end if; end; when Value_Nogrep => declare Matched : Match_Array (0 .. 0); Tmp_Str : constant String := To_String (Tmp_Result); begin Match (Node.Regexp_No.all, Tmp_Str, Matched); if Matched (0) /= No_Match then Put_Verbose (Attribute & ": nogrep matched=""" & Tmp_Str & """"); raise Ignore_Compiler; else Put_Verbose (Attribute & ": nogrep no match"); end if; end; when Value_Must_Match => if not Match (Expression => Get_Name_String (Node.Must_Match), Data => To_String (Tmp_Result)) then if Current_Verbosity /= Default then Put_Verbose ("Ignore compiler since external value """ & To_String (Tmp_Result) & """ must match " & Get_Name_String (Node.Must_Match)); end if; Tmp_Result := Null_Unbounded_String; raise Ignore_Compiler; end if; exit; when Value_Done | Value_Filter => exit; end case; Next (Node_Cursor); end loop; case Node.Typ is when Value_Done | Value_Filter | Value_Must_Match => if Tmp_Result = Null_Unbounded_String then -- Value could not be computed if Extracted_From /= No_Name then Append (Processed_Value, External_Value_Item' (Value => No_Name, Alternate => No_Name, Extracted_From => Extracted_From)); end if; elsif Split_Into_Words then declare Split : String_Lists.List; C : String_Lists.Cursor; Filter : Name_Id; begin if Node.Typ = Value_Filter then Filter := Node.Filter; else Filter := No_Name; end if; -- When an external value is defined as a static string, -- the only valid separator is ','. When computed -- however, we also allow space as a separator if From_Static then Get_Words (Words => To_String (Tmp_Result), Filter => Filter, Separator1 => ',', Separator2 => ',', Map => Split, Allow_Empty_Elements => False); else Get_Words (Words => To_String (Tmp_Result), Filter => Filter, Separator1 => ' ', Separator2 => ',', Map => Split, Allow_Empty_Elements => False); end if; C := First (Split); while Has_Element (C) loop Append (Processed_Value, External_Value_Item' (Value => Get_String (String_Lists.Element (C)), Alternate => No_Name, Extracted_From => Extracted_From)); Next (C); end loop; end; else Append (Processed_Value, External_Value_Item' (Value => Get_String (To_String (Tmp_Result)), Alternate => No_Name, Extracted_From => Extracted_From)); end if; when others => null; end case; Extracted_From := No_Name; Next (Node_Cursor); end loop; end Get_External_Value; --------------- -- Get_Words -- --------------- procedure Get_Words (Words : String; Filter : Namet.Name_Id; Separator1 : Character; Separator2 : Character; Map : out String_Lists.List; Allow_Empty_Elements : Boolean) is First : Integer := Words'First; Last : Integer; Filter_Set : String_Lists.List; begin if Filter /= No_Name then Get_Words (Get_Name_String (Filter), No_Name, Separator1, Separator2, Filter_Set, Allow_Empty_Elements => True); end if; if not Allow_Empty_Elements then while First <= Words'Last and then (Words (First) = Separator1 or else Words (First) = Separator2) loop First := First + 1; end loop; end if; while First <= Words'Last loop if Words (First) /= Separator1 and then Words (First) /= Separator2 then Last := First + 1; while Last <= Words'Last and then Words (Last) /= Separator1 and then Words (Last) /= Separator2 loop Last := Last + 1; end loop; else Last := First; end if; if (Allow_Empty_Elements or else First <= Last - 1) and then (Is_Empty (Filter_Set) or else Contains (Filter_Set, Words (First .. Last - 1))) then Append (Map, Words (First .. Last - 1)); end if; First := Last + 1; end loop; end Get_Words; ------------------------------ -- Foreach_Language_Runtime -- ------------------------------ procedure Foreach_Language_Runtime (Iterator : in out Compiler_Iterator'Class; Base : in out Knowledge_Base; Name : Name_Id; Executable : Name_Id; Directory : String; Prefix : Name_Id; From_Extra_Dir : Boolean; On_Target : Targets_Set_Id; Descr : Compiler_Description; Path_Order : Integer; Continue : out Boolean) is Target : External_Value_Lists.List; Version : External_Value_Lists.List; Languages : External_Value_Lists.List; Runtimes : External_Value_Lists.List; Variables : External_Value_Lists.List; Comp : Compiler; C, C2 : External_Value_Lists.Cursor; CS : String_Lists.Cursor; begin Continue := True; -- verify that the compiler is indeed a real executable -- on Windows and not a cygwin symbolic link if On_Windows and then not Is_Windows_Executable (Directory & Directory_Separator & Get_Name_String (Executable)) then Continue := True; return; end if; Comp.Name := Name; Comp.Path := Get_String (Name_As_Directory (Normalize_Pathname (Directory, Case_Sensitive => False))); Comp.Base_Name := Get_String (GNAT.Directory_Operations.Base_Name (Get_Name_String (Executable), Suffix => Exec_Suffix.all)); Comp.Path_Order := Path_Order; Comp.Prefix := Prefix; Comp.Executable := Executable; -- Check the target first, for efficiency. If it doesn't match, no need -- to compute other attributes. if Executable /= No_Name then if not Is_Empty (Descr.Target) then Get_External_Value ("target", Value => Descr.Target, Comp => Comp, Split_Into_Words => False, Processed_Value => Target); if not Is_Empty (Target) then Comp.Target := External_Value_Lists.Element (First (Target)).Value; Get_Targets_Set (Base, Get_Name_String (Comp.Target), Comp.Targets_Set); else Put_Verbose ("Target unknown for this compiler"); Comp.Targets_Set := Unknown_Targets_Set; end if; if On_Target /= All_Target_Sets and then Comp.Targets_Set /= On_Target then Put_Verbose ("Target for this compiler does not match --target"); Continue := True; return; end if; else Put_Verbose ("Target unspecified, always match"); Comp.Targets_Set := All_Target_Sets; end if; -- Then get the value of the remaining attributes. For most of them, -- we must be able to find a valid value, or the compiler is simply -- ignored Get_External_Value ("version", Value => Descr.Version, Comp => Comp, Split_Into_Words => False, Processed_Value => Version); if Is_Empty (Version) then Put_Verbose ("Ignore compiler, since couldn't guess its version"); Continue := True; return; end if; Comp.Version := External_Value_Lists.Element (First (Version)).Value; Get_External_Value ("variables", Value => Descr.Variables, Comp => Comp, Split_Into_Words => False, Processed_Value => Variables); C := First (Variables); while Has_Element (C) loop declare Ext : constant External_Value_Item := External_Value_Lists.Element (C); begin if Ext.Value = No_Name then if Current_Verbosity /= Default then Put_Verbose ("Ignore compiler since variable '" & Get_Name_String (Ext.Extracted_From) & "' is empty"); end if; Continue := True; return; end if; if Variables_Maps.Contains (Comp.Variables, Ext.Extracted_From) then Put_Line (Standard_Error, "Variable '" & Get_Name_String (Ext.Extracted_From) & "' is already defined"); else Variables_Maps.Insert (Comp.Variables, Ext.Extracted_From, Ext.Value); end if; end; Next (C); end loop; end if; Get_External_Value ("languages", Value => Descr.Languages, Comp => Comp, Split_Into_Words => True, Processed_Value => Languages); if Is_Empty (Languages) then Put_Verbose ("Ignore compiler, since no language could be computed"); Continue := True; return; end if; if Executable /= No_Name then Get_External_Value ("runtimes", Value => Descr.Runtimes, Comp => Comp, Split_Into_Words => True, Merge_Same_Dirs => True, Processed_Value => Runtimes); if not Is_Empty (Runtimes) then -- This loop makes sure that the default runtime appears first in -- the list (and thus is selected automatically when using -- --batch). This doesn't impact the interactive display, where -- the runtimes will be sorted alphabetically anyway (see -- Display_Before) CS := First (Descr.Default_Runtimes); Defaults_Loop : while Has_Element (CS) loop C2 := First (Runtimes); while Has_Element (C2) loop if Get_Name_String (External_Value_Lists.Element (C2).Value) = String_Lists.Element (CS) then Prepend (Runtimes, External_Value_Lists.Element (C2)); Delete (Runtimes, C2); exit Defaults_Loop; end if; Next (C2); end loop; Next (CS); end loop Defaults_Loop; end if; end if; C := First (Languages); while Has_Element (C) loop declare L : constant Name_Id := External_Value_Lists.Element (C).Value; begin Comp.Language_Case := L; Comp.Language_LC := Get_String (To_Lower (Get_Name_String (L))); if Is_Empty (Runtimes) then if Descr.Runtimes /= Null_External_Value then Put_Verbose ("No runtime found where one is required for: " & Get_Name_String (Comp.Path)); else Callback (Iterator => Iterator, Base => Base, Comp => Comp, From_Extra_Dir => From_Extra_Dir, Continue => Continue); if not Continue then return; end if; end if; else C2 := First (Runtimes); while Has_Element (C2) loop Comp.Runtime := External_Value_Lists.Element (C2).Value; Comp.Alt_Runtime := External_Value_Lists.Element (C2).Alternate; Comp.Runtime_Dir := External_Value_Lists.Element (C2).Extracted_From; Callback (Iterator => Iterator, Base => Base, Comp => Comp, From_Extra_Dir => From_Extra_Dir, Continue => Continue); if not Continue then return; end if; Next (C2); end loop; end if; end; Next (C); end loop; exception when Ignore_Compiler => null; end Foreach_Language_Runtime; --------------- -- To_String -- --------------- function To_String (Base : Knowledge_Base; Comp : Compiler; As_Config_Arg : Boolean; Show_Target : Boolean := False; Rank_In_List : Integer := -1; Parser_Friendly : Boolean := False) return String is function Runtime_Or_Alternate return String; function Runtime_Or_Empty return String; function Rank return String; function Target return String; -- Return various aspects of the compiler; -------------------------- -- Runtime_Or_Alternate -- -------------------------- function Runtime_Or_Alternate return String is begin if Comp.Alt_Runtime /= No_Name then return Get_Name_String (Comp.Alt_Runtime); elsif Comp.Runtime /= No_Name then return Get_Name_String (Comp.Runtime); else return ""; end if; end Runtime_Or_Alternate; ---------------------- -- Runtime_Or_Empty -- ---------------------- function Runtime_Or_Empty return String is begin if Comp.Runtime /= No_Name then if Comp.Alt_Runtime = No_Name then return " (" & Get_Name_String (Comp.Runtime) & " runtime)"; else return " (" & Get_Name_String (Comp.Runtime) & " [" & Get_Name_String (Comp.Alt_Runtime) & "] runtime)"; end if; else return ""; end if; end Runtime_Or_Empty; ---------- -- Rank -- ---------- function Rank return String is Result : String (1 .. 4) := " "; Img : constant String := Rank_In_List'Img; begin if Rank_In_List > 0 then Result (4 - Img'Length + 1 .. 4) := Img; end if; if Comp.Selected then Result (1) := '*'; end if; return Result; end Rank; ------------ -- Target -- ------------ function Target return String is begin if Show_Target then return " on " & Get_Name_String (Comp.Target); else return ""; end if; end Target; begin if As_Config_Arg then return Get_Name_String_Or_Null (Comp.Language_Case) & ',' & Get_Name_String_Or_Null (Comp.Version) & ',' & Get_Name_String_Or_Null (Comp.Runtime) & ',' & Get_Name_String_Or_Null (Comp.Path) & ',' & Get_Name_String_Or_Null (Comp.Name); elsif Parser_Friendly then return Rank & " target:" & Get_Name_String_Or_Null (Comp.Target) & ASCII.LF & Rank & " normalized_target:" & Normalized_Target (Base, Comp.Targets_Set) & ASCII.LF & Rank & " executable:" & Get_Name_String_Or_Null (Comp.Executable) & ASCII.LF & Rank & " path:" & Get_Name_String_Or_Null (Comp.Path) & ASCII.LF & Rank & " lang:" & Get_Name_String_Or_Null (Comp.Language_Case) & ASCII.LF & Rank & " name:" & Get_Name_String_Or_Null (Comp.Name) & ASCII.LF & Rank & " version:" & Get_Name_String_Or_Null (Comp.Version) & ASCII.LF & Rank & " runtime:" & Runtime_Or_Alternate & ASCII.LF & Rank & " native:" & Boolean'Image (Query_Targets_Set (Base, Hostname) = Comp.Targets_Set); elsif Comp.Executable = No_Name then -- A language that requires no compiler return Rank & ". " & Get_Name_String_Or_Null (Comp.Language_Case) & " (no compiler required)"; else return Rank & ". " & Get_Name_String_Or_Null (Comp.Name) & " for " & Get_Name_String_Or_Null (Comp.Language_Case) & " in " & Get_Name_String_Or_Null (Comp.Path) & Target & " version " & Get_Name_String_Or_Null (Comp.Version) & Runtime_Or_Empty; end if; end To_String; --------------- -- To_String -- --------------- function To_String (Base : Knowledge_Base; Compilers : Compiler_Lists.List; Selected_Only : Boolean; Show_Target : Boolean := False; Parser_Friendly : Boolean := False) return String is Comp : Compiler_Lists.Cursor := First (Compilers); Result : Unbounded_String; Rank : Natural := 1; begin while Has_Element (Comp) loop if Compiler_Lists.Element (Comp).Selected or else (not Selected_Only and then Compiler_Lists.Element (Comp).Selectable) then Append (Result, To_String (Base, Compiler_Lists.Element (Comp).all, False, Show_Target => Show_Target, Rank_In_List => Rank, Parser_Friendly => Parser_Friendly)); Append (Result, ASCII.LF); end if; Rank := Rank + 1; Next (Comp); end loop; return To_String (Result); end To_String; ----------------------------- -- Foreach_Compiler_In_Dir -- ----------------------------- procedure Foreach_Compiler_In_Dir (Iterator : in out Compiler_Iterator'Class; Base : in out Knowledge_Base; Directory : String; From_Extra_Dir : Boolean; On_Target : Targets_Set_Id; Path_Order : Integer; Continue : out Boolean) is use CDM; function Executable_Pattern return String; pragma Inline (Executable_Pattern); -- Returns a pattern which matchs executable ------------------------ -- Executable_Pattern -- ------------------------ function Executable_Pattern return String is begin if On_Windows then return "*.{exe,bat,cmd}"; else return ""; end if; end Executable_Pattern; C : CDM.Cursor; Search : Search_Type; Dir : Directory_Entry_Type; begin -- Since the name of an executable can be a regular expression, we need -- to look at all files in the directory to see if they match. This -- requires more system calls than if the name was always a simple -- string. So we first check which of the two algorithms should be used. Continue := True; if Current_Verbosity /= Default then Put_Verbose ("Foreach compiler in " & Directory & " regexp=" & Boolean'Image (Base.Check_Executable_Regexp) & " extra_dir=" & From_Extra_Dir'Img, 1); end if; if Base.Check_Executable_Regexp then begin Start_Search (Search => Search, Directory => Directory, Pattern => Executable_Pattern); exception when Ada.Directories.Name_Error => Put_Verbose ("No such directory:" & Directory, -1); Continue := True; return; when Ada.Directories.Use_Error => Put_Verbose ("Directory not readable:" & Directory, -1); Continue := True; return; end; For_All_Files_In_Dir : loop begin exit For_All_Files_In_Dir when not More_Entries (Search); Get_Next_Entry (Search, Dir); C := First (Base.Compilers); while Has_Element (C) loop declare Config : constant Compiler_Description := CDM.Element (C); Simple : constant String := Simple_Name (Dir); Matches : Match_Array (0 .. Integer'Max (0, Config.Prefix_Index)); Matched : Boolean; Prefix : Name_Id := No_Name; begin -- A language with no expected compiler => always match if Config.Executable = No_Name then Put_Verbose (Get_Name_String (Key (C)) & " requires no compiler", 1); Continue := True; Foreach_Language_Runtime (Iterator => Iterator, Base => Base, Name => Key (C), Executable => No_Name, Directory => "", On_Target => Unknown_Targets_Set, Prefix => No_Name, From_Extra_Dir => From_Extra_Dir, Descr => Config, Path_Order => Path_Order, Continue => Continue); Put_Verbose ("", -1); exit For_All_Files_In_Dir when not Continue; Matched := False; elsif Config.Executable_Re /= null then Match (Config.Executable_Re.all, Data => Simple, Matches => Matches); Matched := Matches (0) /= No_Match; else Matched := (Get_Name_String (Config.Executable) & Exec_Suffix.all) = Simple_Name (Dir); end if; if Matched then Put_Verbose (Get_Name_String (Key (C)) & " is candidate: filename=" & Simple, 1); if Config.Executable_Re /= null and then Config.Prefix_Index >= 0 and then Matches (Config.Prefix_Index) /= No_Match then Prefix := Get_String (Simple (Matches (Config.Prefix_Index).First .. Matches (Config.Prefix_Index).Last)); end if; Continue := True; Foreach_Language_Runtime (Iterator => Iterator, Base => Base, Name => Key (C), Executable => Get_String (Simple), Directory => Directory, On_Target => On_Target, Prefix => Prefix, From_Extra_Dir => From_Extra_Dir, Descr => Config, Path_Order => Path_Order, Continue => Continue); Put_Verbose ("", -1); exit For_All_Files_In_Dir when not Continue; end if; end; Next (C); end loop; exception when Ada.Directories.Name_Error | Ada.Directories.Use_Error => null; end; end loop For_All_Files_In_Dir; else -- Do not search all entries in the directory, but check explictly -- for the compilers. This results in a lot less system calls, and -- thus is faster. C := First (Base.Compilers); while Has_Element (C) loop declare Config : constant Compiler_Description := CDM.Element (C); F : constant String := Normalize_Pathname (Name => Get_Name_String (Config.Executable), Directory => Directory, Resolve_Links => False, Case_Sensitive => Case_Sensitive_Files) & Exec_Suffix.all; begin if Ada.Directories.Exists (F) then Put_Verbose ("--------------------------------------"); Put_Verbose ("Processing " & Get_Name_String (Config.Name) & " in " & Directory); Foreach_Language_Runtime (Iterator => Iterator, Base => Base, Name => Key (C), Executable => Config.Executable, Prefix => No_Name, From_Extra_Dir => From_Extra_Dir, On_Target => On_Target, Directory => Directory, Descr => Config, Path_Order => Path_Order, Continue => Continue); exit when not Continue; end if; exception when Ada.Directories.Name_Error | Ada.Directories.Use_Error => null; when Ignore_Compiler => -- Nothing to do, the compiler has not been inserted null; end; Next (C); end loop; end if; Put_Verbose ("", -1); end Foreach_Compiler_In_Dir; ------------------------------ -- Foreach_Compiler_In_Path -- ------------------------------ procedure Foreach_Compiler_In_Path (Iterator : in out Compiler_Iterator; Base : in out Knowledge_Base; On_Target : Targets_Set_Id; Extra_Dirs : String := "") is Dirs : String_Lists.List; Map : String_Lists.List; procedure Process_Path (Path : String; Prefix : Character; Prepend_To_List : Boolean); -- Add a directory to the list of directories to examine ------------------ -- Process_Path -- ------------------ procedure Process_Path (Path : String; Prefix : Character; Prepend_To_List : Boolean) is First, Last : Natural; begin First := Path'First; while First <= Path'Last loop -- Skip null entries on PATH if Path (First) = GNAT.OS_Lib.Path_Separator then First := First + 1; else Last := First + 1; while Last <= Path'Last and then Path (Last) /= GNAT.OS_Lib.Path_Separator loop Last := Last + 1; end loop; declare -- Use a hash to make sure we do not parse the same -- directory twice. This is both more efficient and avoids -- duplicates in the final result list. To handle the case -- of links (on linux for instance /usr/bin/X11 points to -- ".", ie /usr/bin, and compilers would appear duplicated), -- we resolve symbolic links. This call is also set to fold -- to lower-case when appropriate Normalized : constant String := Name_As_Directory (Normalize_Pathname (Path (First .. Last - 1), Resolve_Links => True, Case_Sensitive => False)); begin if not Contains (Map, Normalized) then Append (Map, Normalized); -- Rerun normalize_pathname without resolve_links so that -- the displayed path looks familiar to the user (no .., -- ./ or quotes, but still using the path as shown in -- $PATH) declare Final_Path : constant String := Normalize_Pathname (Path (First .. Last - 1), Resolve_Links => False, Case_Sensitive => False); begin -- Windows is somewhat slow at parsing directories, do -- not look into any directory under C:\windows as -- there is no compiler to be found there anyway. if not On_Windows or else (Final_Path'Length > 10 and then To_Lower (Final_Path (Final_Path'First .. Final_Path'First + 9)) /= "c:\windows") then Put_Verbose ("Will examine " & Prefix & " " & Final_Path); if Prepend_To_List then Prepend (Dirs, Prefix & Final_Path); else Append (Dirs, Prefix & Final_Path); end if; end if; end; end if; end; First := Last + 1; end if; end loop; end Process_Path; Dir : String_Lists.Cursor; Path_Order : Positive := 1; Continue : Boolean; begin -- Preprocess the list of directories that will be searched. When a -- directory appears both in Extra_Dirs and in Path, we prepend it to -- the PATH for optimization purposes: no need to look in all the PATH -- if the compiler(s) will match in that directory. However, this has -- the result that a command line with --config that specifies a path -- and one that doesn't might find the second compiler in the same -- path even if it is not the first one on the PATH. That's minor, and -- a workaround is for the user to specify path for all --config args. -- -- We will also need to know later whether the directory comes from -- PATH or extra_dirs. If a directory appears in both, it is said to -- come from PATH, so that all its compilers are taken into account. -- As a special convention, the first character of the directory name is -- set to 'E' if the dir comes from extra_dirs, or 'P' if it comes from -- PATH. if Ada.Environment_Variables.Exists ("PATH") then Process_Path (Ada.Environment_Variables.Value ("PATH"), 'P', False); end if; if Extra_Dirs /= "" then Process_Path (Extra_Dirs, 'E', Prepend_To_List => True); end if; Dir := First (Dirs); while Has_Element (Dir) loop declare P : constant String := String_Lists.Element (Dir); begin Foreach_Compiler_In_Dir (Iterator => Iterator, Base => Base, Directory => P (P'First + 1 .. P'Last), From_Extra_Dir => P (P'First) = 'E', Path_Order => Path_Order, On_Target => On_Target, Continue => Continue); exit when not Continue; end; Path_Order := Path_Order + 1; Next (Dir); end loop; end Foreach_Compiler_In_Path; -------------------------- -- Known_Compiler_Names -- -------------------------- procedure Known_Compiler_Names (Base : Knowledge_Base; List : out Ada.Strings.Unbounded.Unbounded_String) is use CDM; C : CDM.Cursor := First (Base.Compilers); begin List := Null_Unbounded_String; while Has_Element (C) loop if List /= Null_Unbounded_String then Append (List, ","); end if; Append (List, Get_Name_String (Key (C))); Next (C); end loop; end Known_Compiler_Names; ----------- -- Match -- ----------- procedure Match (Filter : Compilers_Filter; Compilers : Compiler_Lists.List; Matching_Compiler : out Compiler_Access; Matched : out Boolean) is C : CFL.Cursor := First (Filter.Compiler); M : Boolean; begin while Has_Element (C) loop Match (CFL.Element (C), Compilers, Matching_Compiler, M); if M then Matched := not Filter.Negate; return; end if; Next (C); end loop; Matched := Filter.Negate; end Match; ------------------ -- Filter_Match -- ------------------ function Filter_Match (Base : Knowledge_Base; Comp : Compiler; Filter : Compiler) return Boolean is begin if Filter.Name /= No_Name and then Comp.Name /= Filter.Name and then Comp.Base_Name /= Filter.Name then if Current_Verbosity /= Default then Put_Verbose ("Filter=" & To_String (Base, Filter, True) & ": name does not match"); end if; return False; end if; if Filter.Path /= No_Name and then Filter.Path /= Comp.Path then if Current_Verbosity /= Default then Put_Verbose ("Filter=" & To_String (Base, Filter, True) & ": path does not match"); end if; return False; end if; if Filter.Version /= No_Name and then Filter.Version /= Comp.Version then if Current_Verbosity /= Default then Put_Verbose ("Filter=" & To_String (Base, Filter, True) & ": version does not match"); end if; return False; end if; if Filter.Runtime /= No_Name and then not Is_Absolute_Path (Get_Name_String (Filter.Runtime)) and then Filter.Runtime /= Comp.Runtime and then Filter.Runtime /= Comp.Alt_Runtime then if Current_Verbosity /= Default then Put_Verbose ("Filter=" & To_String (Base, Filter, True) & ": runtime does not match"); end if; return False; end if; if Filter.Language_LC /= No_Name and then Filter.Language_LC /= Comp.Language_LC then if Current_Verbosity /= Default then Put_Verbose ("Filter=" & To_String (Base, Filter, True) & ": language does not match"); end if; return False; end if; return True; end Filter_Match; ----------- -- Match -- ----------- procedure Match (Filter : Compiler_Filter; Compilers : Compiler_Lists.List; Matching_Compiler : out Compiler_Access; Matched : out Boolean) is C : Compiler_Lists.Cursor := First (Compilers); Comp : Compiler_Access; begin while Has_Element (C) loop Comp := Compiler_Lists.Element (C); if Comp.Selected and then (Filter.Name = No_Name or else Filter.Name = Comp.Name or else Comp.Base_Name = Filter.Name) and then (Filter.Version_Re = null or else (Comp.Version /= No_Name and then Match (Filter.Version_Re.all, Get_Name_String (Comp.Version)))) and then (Filter.Runtime_Re = null or else (Comp.Runtime /= No_Name and then Match (Filter.Runtime_Re.all, Get_Name_String (Comp.Runtime)))) and then (Filter.Language_LC = No_Name or else Filter.Language_LC = Comp.Language_LC) then Matching_Compiler := Comp; Matched := True; return; end if; Next (C); end loop; Matched := False; end Match; ----------- -- Match -- ----------- procedure Match (Filter : Compilers_Filter_Lists.List; Compilers : Compiler_Lists.List; Matching_Compiler : out Compiler_Access; Matched : out Boolean) is C : Compilers_Filter_Lists.Cursor := First (Filter); M : Boolean; begin while Has_Element (C) loop Match (Compilers_Filter_Lists.Element (C), Compilers, Matching_Compiler, M); if not M then Matched := False; return; end if; Next (C); end loop; if Length (Filter) /= 1 then Matching_Compiler := null; end if; Matched := True; end Match; ----------- -- Match -- ----------- function Match (Target_Filter : String_Lists.List; Negate : Boolean; Compilers : Compiler_Lists.List) return Boolean is Target : String_Lists.Cursor := First (Target_Filter); Comp : Compiler_Lists.Cursor; begin if Is_Empty (Target_Filter) then return True; else while Has_Element (Target) loop declare Pattern : constant Pattern_Matcher := Compile (String_Lists.Element (Target), Case_Insensitive); begin Comp := First (Compilers); while Has_Element (Comp) loop if Compiler_Lists.Element (Comp).Selected then if Compiler_Lists.Element (Comp).Target = No_Name then if Match (Pattern, "") then return not Negate; end if; elsif Match (Pattern, Get_Name_String (Compiler_Lists.Element (Comp).Target)) then return not Negate; end if; end if; Next (Comp); end loop; end; Next (Target); end loop; return Negate; end if; end Match; ----------------- -- Skip_Spaces -- ----------------- procedure Skip_Spaces (Str : String; Index : in out Integer) is begin while Index <= Str'Last and then (Str (Index) = ' ' or else Str (Index) = ASCII.LF) loop Index := Index + 1; end loop; end Skip_Spaces; procedure Skip_Spaces_Backward (Str : String; Index : in out Integer) is begin while Index >= Str'First and then (Str (Index) = ' ' or else Str (Index) = ASCII.LF) loop Index := Index - 1; end loop; end Skip_Spaces_Backward; ------------------ -- Merge_Config -- ------------------ procedure Merge_Config (Base : Knowledge_Base; Packages : in out String_Maps.Map; Compilers : Compiler_Lists.List; Config : String) is procedure Add_Package (Name : String; Chunk : String; Prefix : String := " "); -- Add the chunk in the appropriate package ----------------- -- Add_Package -- ----------------- procedure Add_Package (Name : String; Chunk : String; Prefix : String := " ") is C : constant String_Maps.Cursor := Find (Packages, Name); Replaced : constant String := Substitute_Variables_In_Configuration (Base, Chunk, Compilers); begin if Replaced /= "" then if Has_Element (C) then Replace_Element (Packages, C, String_Maps.Element (C) & ASCII.LF & Prefix & Replaced); else Insert (Packages, Name, Prefix & To_Unbounded_String (Replaced)); end if; end if; end Add_Package; First : Integer := Config'First; Pkg_Name_First, Pkg_Name_Last : Integer; Pkg_Content_First : Integer; Last : Integer; begin while First /= 0 and then First <= Config'Last loop -- Do we have a toplevel attribute ? Skip_Spaces (Config, First); Pkg_Name_First := Index (Config (First .. Config'Last), "package "); if Pkg_Name_First = 0 then Pkg_Name_First := Config'Last + 1; end if; Last := Pkg_Name_First - 1; Skip_Spaces_Backward (Config, Last); Add_Package (Name => "", Chunk => Config (First .. Last), Prefix => " "); exit when Pkg_Name_First > Config'Last; -- Parse the current package Pkg_Name_First := Pkg_Name_First + 8; -- skip "package " Skip_Spaces (Config, Pkg_Name_First); Pkg_Name_Last := Pkg_Name_First + 1; while Pkg_Name_Last <= Config'Last and then Config (Pkg_Name_Last) /= ' ' and then Config (Pkg_Name_Last) /= ASCII.LF loop Pkg_Name_Last := Pkg_Name_Last + 1; end loop; Pkg_Content_First := Pkg_Name_Last + 1; Skip_Spaces (Config, Pkg_Content_First); Pkg_Content_First := Pkg_Content_First + 2; -- skip "is" Skip_Spaces (Config, Pkg_Content_First); Last := Index (Config (Pkg_Content_First .. Config'Last), "end " & Config (Pkg_Name_First .. Pkg_Name_Last - 1)); if Last /= 0 then First := Last - 1; Skip_Spaces_Backward (Config, First); Add_Package (Name => Config (Pkg_Name_First .. Pkg_Name_Last - 1), Chunk => Config (Pkg_Content_First .. First)); while Last <= Config'Last and then Config (Last) /= ';' loop Last := Last + 1; end loop; Last := Last + 1; end if; First := Last; end loop; end Merge_Config; ----------------- -- Put_Verbose -- ----------------- procedure Put_Verbose (Config : Configuration) is C : Compilers_Filter_Lists.Cursor := First (Config.Compilers_Filters); Comp_Filter : Compilers_Filter; Comp : Compiler_Filter_Lists.Cursor; Filter : Compiler_Filter; begin while Has_Element (C) loop Comp_Filter := Compilers_Filter_Lists.Element (C); Put_Verbose ("", 1); Comp := First (Comp_Filter.Compiler); while Has_Element (Comp) loop Filter := Compiler_Filter_Lists.Element (Comp); Put_Verbose (""); Next (Comp); end loop; Put_Verbose ("", -1); Next (C); end loop; Put_Verbose (""); end Put_Verbose; ------------------------- -- Is_Supported_Config -- ------------------------- function Is_Supported_Config (Base : Knowledge_Base; Compilers : Compiler_Lists.List) return Boolean is Config : Configuration_Lists.Cursor := First (Base.Configurations); M : Boolean; Matching_Compiler : Compiler_Access; begin while Has_Element (Config) loop Match (Configuration_Lists.Element (Config).Compilers_Filters, Compilers, Matching_Compiler, M); if M and then Match (Configuration_Lists.Element (Config).Targets_Filters, Configuration_Lists.Element (Config).Negate_Targets, Compilers) then if not Configuration_Lists.Element (Config).Supported then if Current_Verbosity /= Default then Put_Verbose ("Selected compilers are not compatible, because of:"); Put_Verbose (Configuration_Lists.Element (Config)); end if; return False; end if; end if; Next (Config); end loop; return True; end Is_Supported_Config; ---------------------------- -- Generate_Configuration -- ---------------------------- procedure Generate_Configuration (Base : Knowledge_Base; Compilers : Compiler_Lists.List; Output_File : String; Target : String) is Config : Configuration_Lists.Cursor := First (Base.Configurations); Output : File_Type; Packages : String_Maps.Map; Selected_Compiler : Compiler_Access; M : Boolean; Project_Name : String := "Default"; procedure Gen (C : String_Maps.Cursor); -- C is a cursor of the map "Packages" -- Generate the chunk of the config file corresponding to the -- given package. procedure Gen_And_Remove (Name : String); -- Generate the chunk of the config file corresponding to the -- package name and remove it from the map. --------- -- Gen -- --------- procedure Gen (C : String_Maps.Cursor) is begin if Key (C) /= "" then New_Line (Output); Put_Line (Output, " package " & Key (C) & " is"); end if; Put_Line (Output, To_String (String_Maps.Element (C))); if Key (C) /= "" then Put_Line (Output, " end " & Key (C) & ";"); end if; end Gen; -------------------- -- Gen_And_Remove -- -------------------- procedure Gen_And_Remove (Name : String) is C : String_Maps.Cursor := Find (Packages, Name); begin if Has_Element (C) then Gen (C); Delete (Packages, C); end if; end Gen_And_Remove; begin To_Mixed (Project_Name); while Has_Element (Config) loop Match (Configuration_Lists.Element (Config).Compilers_Filters, Compilers, Selected_Compiler, M); if M and then Match (Configuration_Lists.Element (Config).Targets_Filters, Configuration_Lists.Element (Config).Negate_Targets, Compilers) then if not Configuration_Lists.Element (Config).Supported then Put_Line (Standard_Error, "Code generated by these compilers cannot be linked" & " as far as we know."); return; end if; Merge_Config (Base, Packages, Compilers, Get_Name_String (Configuration_Lists.Element (Config).Config)); end if; Next (Config); end loop; if Is_Empty (Packages) then Put_Line ("No valid configuration found"); raise Generate_Error; end if; if not Opt.Quiet_Output then Put_Line ("Creating configuration file: " & Output_File); end if; Create (Output, Out_File, Output_File); Put_Line (Output, "-- This gpr configuration file was generated by gprconfig"); Put_Line (Output, "-- using this command line:"); Put (Output, "-- " & Command_Name); for I in 1 .. Argument_Count loop Put (Output, ' '); Put (Output, Argument (I)); end loop; New_Line (Output); New_Line (Output); Put_Line (Output, "configuration project " & Project_Name & " is"); if Target'Length > 0 and then Target /= "all" then Put_Line (Output, " for Target use """ & Target & """;"); end if; -- Generate known packages in order. This takes care of possible -- dependencies. Gen_And_Remove (""); Gen_And_Remove ("Builder"); Gen_And_Remove ("Compiler"); Gen_And_Remove ("Naming"); Gen_And_Remove ("Binder"); Gen_And_Remove ("Linker"); -- Generate remaining packages Iterate (Packages, Gen'Access); Put_Line (Output, "end " & Project_Name & ";"); Close (Output); exception when Ada.Directories.Name_Error | Ada.IO_Exceptions.Use_Error => Put_Line ("Could not create the file " & Output_File); raise Generate_Error; end Generate_Configuration; ----------------------- -- Query_Targets_Set -- ----------------------- function Query_Targets_Set (Base : Knowledge_Base; Target : String) return Targets_Set_Id is use Targets_Set_Vectors; use Target_Lists; begin if Target = "" then return All_Target_Sets; end if; for I in First_Index (Base.Targets_Sets) .. Last_Index (Base.Targets_Sets) loop declare Set : constant Target_Lists.List := Targets_Set_Vectors.Element (Base.Targets_Sets, I).Patterns; C : Target_Lists.Cursor := First (Set); begin while Has_Element (C) loop if GNAT.Regpat.Match (Target_Lists.Element (C).all, Target) > 0 then return I; end if; Next (C); end loop; end; end loop; return Unknown_Targets_Set; end Query_Targets_Set; ---------------------- -- Get_Targets_Set -- ---------------------- procedure Get_Targets_Set (Base : in out Knowledge_Base; Target : String; Id : out Targets_Set_Id) is begin Id := Query_Targets_Set (Base, Target); if Id /= Unknown_Targets_Set then return; end if; -- Create a new set declare Set : Target_Lists.List; begin Put_Verbose ("create a new target set for " & Target); Set.Append (new Pattern_Matcher'(Compile ("^" & Quote (Target) & "$"))); Base.Targets_Sets.Append ((Get_String (Target), Set)); Id := Base.Targets_Sets.Last_Index; end; end Get_Targets_Set; ----------------------- -- Normalized_Target -- ----------------------- function Normalized_Target (Base : Knowledge_Base; Set : Targets_Set_Id) return String is Result : constant Target_Set_Description := Targets_Set_Vectors.Element (Base.Targets_Sets, Set); begin return Get_Name_String (Result.Name); end Normalized_Target; ---------------- -- Get_String -- ---------------- function Get_String (Str : String) return Namet.Name_Id is begin Name_Len := Str'Length; Name_Buffer (1 .. Name_Len) := Str; return Name_Find; end Get_String; -------------------------- -- Get_String_No_Adalib -- -------------------------- function Get_String_No_Adalib (Str : String) return Namet.Name_Id is Name : constant String (1 .. Str'Length) := Str; Last : Natural := Name'Last; begin if Last > 7 and then (Name (Last) = Directory_Separator or else Name (Last) = '/') then Last := Last - 1; end if; if Last > 6 and then Name (Last - 5 .. Last) = "adalib" and then (Name (Last - 6) = Directory_Separator or else Name (Last - 6) = '/') then Last := Last - 6; else Last := Name'Last; end if; Name_Len := Last; Name_Buffer (1 .. Last) := Name (1 .. Last); return Name_Find; end Get_String_No_Adalib; --------------------------- -- Get_String_Or_No_Name -- --------------------------- function Get_String_Or_No_Name (Str : String) return Namet.Name_Id is begin if Str = "" then return No_Name; else Name_Len := Str'Length; Name_Buffer (1 .. Name_Len) := Str; return Name_Find; end if; end Get_String_Or_No_Name; --------------------------- -- Hash_Case_Insensitive -- --------------------------- function Hash_Case_Insensitive (Name : Namet.Name_Id) return Ada.Containers.Hash_Type is begin return Hash_Type (Name); end Hash_Case_Insensitive; ----------------------------- -- Get_Name_String_Or_Null -- ----------------------------- function Get_Name_String_Or_Null (Name : Name_Id) return String is begin if Name = No_Name then return ""; else Get_Name_String (Name); return Name_Buffer (1 .. Name_Len); end if; end Get_Name_String_Or_Null; ------------------- -- Set_Selection -- ------------------- procedure Set_Selection (Compilers : in out Compiler_Lists.List; Cursor : Compiler_Lists.Cursor; Selected : Boolean) is procedure Internal (Comp : in out Compiler_Access); -------------- -- Internal -- -------------- procedure Internal (Comp : in out Compiler_Access) is begin Set_Selection (Comp.all, Selected); end Internal; begin Update_Element (Compilers, Cursor, Internal'Access); end Set_Selection; ------------------- -- Set_Selection -- ------------------- procedure Set_Selection (Comp : in out Compiler; Selected : Boolean) is begin Comp.Selected := Selected; end Set_Selection; ----------------------------- -- Extra_Dirs_From_Filters -- ----------------------------- function Extra_Dirs_From_Filters (Filters : Compiler_Lists.List) return String is C : Compiler_Lists.Cursor := First (Filters); Extra_Dirs : Unbounded_String; Elem : Compiler_Access; begin while Has_Element (C) loop Elem := Compiler_Lists.Element (C); if Elem.Path /= No_Name then Append (Extra_Dirs, Get_Name_String (Elem.Path) & Path_Separator); end if; Next (C); end loop; return To_String (Extra_Dirs); end Extra_Dirs_From_Filters; ------------------------------------- -- Complete_Command_Line_Compilers -- ------------------------------------- procedure Complete_Command_Line_Compilers (Base : in out Knowledge_Base; On_Target : Targets_Set_Id; Filters : Compiler_Lists.List; Compilers : in out Compiler_Lists.List) is type Cursor_Array is array (Count_Type range <>) of Compiler_Lists.Cursor; type Boolean_Array is array (Count_Type range <>) of Boolean; type Batch_Iterator (Count : Count_Type) is new Compiler_Iterator with record Found : Count_Type := 0; Compilers : Compiler_Lists.List; Matched : Cursor_Array (1 .. Count) := (others => Compiler_Lists.No_Element); Filters : Compiler_Lists.List; Found_One : Boolean_Array (1 .. Count) := (others => False); -- Whether we found at least one matching compiler for each filter end record; procedure Callback (Iterator : in out Batch_Iterator; Base : in out Knowledge_Base; Comp : Compiler; From_Extra_Dir : Boolean; Continue : out Boolean); -- Search the first compiler matching each --config command line -- argument. -------------- -- Callback -- -------------- procedure Callback (Iterator : in out Batch_Iterator; Base : in out Knowledge_Base; Comp : Compiler; From_Extra_Dir : Boolean; Continue : out Boolean) is C : Compiler_Lists.Cursor := First (Iterator.Filters); Index : Count_Type := 1; Ncomp : Compiler_Access; El : Compiler_Access; begin while Has_Element (C) loop Ncomp := null; El := Compiler_Lists.Element (C); -- A compiler in an "extra_dir" (ie specified on the command line) -- can only match if that directory was explicitly specified in -- --config. We do not want to find all compilers in /dir if that -- directory is not in $PATH if (not From_Extra_Dir or else El.Path = Comp.Path) and then Filter_Match (Base, Comp => Comp, Filter => El.all) then Ncomp := new Compiler'(Comp); if El.Runtime_Dir /= No_Name then Ncomp.Runtime_Dir := El.Runtime_Dir; Ncomp.Runtime := El.Runtime; end if; Append (Iterator.Compilers, Ncomp); if Current_Verbosity /= Default then Put_Verbose ("Saving compiler for possible backtracking: " & To_String (Base, Ncomp.all, As_Config_Arg => True) & " (matches --config " & To_String (Base, El.all, As_Config_Arg => True) & ")"); end if; if Iterator.Matched (Index) = Compiler_Lists.No_Element then Iterator.Found := Iterator.Found + 1; Put_Verbose ("Selecting it since this filter was not matched yet " & Iterator.Found'Img & "/" & Iterator.Count'Img); Iterator.Matched (Index) := Last (Iterator.Compilers); Iterator.Found_One (Index) := True; Set_Selection (Iterator.Compilers, Iterator.Matched (Index), True); -- Only keep those compilers that are not incompatible -- (according to the knowledge base). It might happen that -- none is selected as a result, but appropriate action is -- taken in Complete_Command_Line_Compilers. We ignore -- incompatible sets as early as possible, in the hope to -- limit the number of system calls if another set is found -- before all directories are traversed. if not Is_Supported_Config (Base, Iterator.Compilers) then Set_Selection (Iterator.Compilers, Iterator.Matched (Index), False); Put_Verbose ("Compilers are not compatible, cancelling last" & " compiler found"); Iterator.Matched (Index) := Compiler_Lists.No_Element; Iterator.Found := Iterator.Found - 1; end if; end if; end if; Index := Index + 1; Next (C); end loop; -- Stop at first compiler Continue := Iterator.Found /= Iterator.Count; end Callback; Iter : Batch_Iterator (Length (Filters)); function Foreach_Nth_Compiler (Filter : Compiler_Lists.Cursor) return Boolean; -- For all possible compiler matching the filter, check whether we -- find a compatible set of compilers matching the next filters. -- Return True if one was found (in which case it is the current -- selection on exit). -------------------------- -- Foreach_Nth_Compiler -- -------------------------- function Foreach_Nth_Compiler (Filter : Compiler_Lists.Cursor) return Boolean is C : Compiler_Lists.Cursor := First (Iter.Compilers); Comp_Filter : constant Compiler_Access := Compiler_Lists.Element (Filter); begin while Has_Element (C) loop if Filter_Match (Base, Compiler_Lists.Element (C).all, Filter => Comp_Filter.all) then Set_Selection (Iter.Compilers, C, True); if Next (Filter) = Compiler_Lists.No_Element then if Current_Verbosity /= Default then Put_Verbose ("Testing the following compiler set:", 1); Put_Verbose (To_String (Base, Iter.Compilers, Selected_Only => True)); end if; if Is_Supported_Config (Base, Iter.Compilers) then Put_Verbose ("They are compatible", -1); return True; else Put_Verbose ("", -1); end if; else if Foreach_Nth_Compiler (Next (Filter)) then return True; end if; end if; Set_Selection (Iter.Compilers, C, False); end if; Next (C); end loop; return False; end Foreach_Nth_Compiler; C : Compiler_Lists.Cursor; Extra_Dirs : constant String := Extra_Dirs_From_Filters (Filters); Found_All : Boolean := True; begin Iter.Filters := Filters; Put_Verbose ("Completing info for --config parameters, extra_dirs=" & Extra_Dirs, 1); -- Find all the compilers in PATH and Extra_Dirs Foreach_Compiler_In_Path (Iterator => Iter, Base => Base, On_Target => On_Target, Extra_Dirs => Extra_Dirs); Put_Verbose ("", -1); -- Check that we could find at least one of each compiler C := First (Filters); for F in Iter.Found_One'Range loop if not Iter.Found_One (F) then if not Opt.Quiet_Output then Put_Line (Standard_Error, "Error: no matching compiler found for --config=" & To_String (Base, Compiler_Lists.Element (C).all, As_Config_Arg => True)); end if; Ada.Command_Line.Set_Exit_Status (1); Found_All := False; end if; Next (C); end loop; -- If we could find at least one of each compiler, but that our initial -- attempt returned incompatible sets of compiler, we do a more thorough -- attempt now if Found_All and then Iter.Found /= Iter.Count then -- If no compatible set was found, try all possible combinations, in -- the hope that we can finally find one. In the following algorithm, -- we end up checking again some set that were checked in Callback, -- but that would be hard to avoid since the compilers can be found -- in any order. Put_Verbose ("Attempting to find a supported compiler set", 1); -- Unselect all compilers C := First (Iter.Compilers); while Has_Element (C) loop Set_Selection (Iter.Compilers, C, False); Next (C); end loop; if not Foreach_Nth_Compiler (First (Iter.Filters)) then Put_Line (Standard_Error, "Error: no set of compatible compilers was found"); raise Invalid_Config; end if; Put_Verbose ("", -1); end if; Splice (Target => Compilers, Before => Compiler_Lists.No_Element, Source => Iter.Compilers); end Complete_Command_Line_Compilers; -------------------------------------- -- Default_Knowledge_Base_Directory -- -------------------------------------- function Default_Knowledge_Base_Directory return String is Prog_Dir : constant String := Executable_Prefix_Path; Suffix : constant String := "share" & Directory_Separator & "gprconfig"; begin return Prog_Dir & Suffix; end Default_Knowledge_Base_Directory; -------------------- -- Display_Before -- -------------------- function Display_Before (Comp1, Comp2 : Compiler_Access) return Boolean is type Compare_Type is (Before, Equal, After); function Compare (Name1, Name2 : Namet.Name_Id) return Compare_Type; -- Compare alphabetically two strings ------------- -- Compare -- ------------- function Compare (Name1, Name2 : Namet.Name_Id) return Compare_Type is begin if Name1 = No_Name then if Name2 = No_Name then return Equal; else return Before; end if; elsif Name2 = No_Name then return After; end if; Get_Name_String (Name1); declare Str1 : constant String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len); begin Get_Name_String (Name2); if Str1 < Name_Buffer (1 .. Name_Len) then return Before; elsif Str1 > Name_Buffer (1 .. Name_Len) then return After; else return Equal; end if; end; end Compare; begin case Compare (Comp1.Language_LC, Comp2.Language_LC) is when Before => return True; when After => return False; when Equal => if Comp1.Path_Order < Comp2.Path_Order then return True; elsif Comp2.Path_Order < Comp1.Path_Order then return False; else -- If the "default" attribute was specified for , -- this only impacts the batch mode. We still want to sort -- the runtimes alphabetically in the interactive display. case Compare (Comp1.Runtime, Comp2.Runtime) is when Before => return True; when After => return False; when Equal => return Compare (Comp1.Version, Comp2.Version) = Before; end case; end if; end case; end Display_Before; ---------------------------- -- Parse_Config_Parameter -- ---------------------------- procedure Parse_Config_Parameter (Base : Knowledge_Base; Config : String; Compiler : out Compiler_Access; Requires_Compiler : out Boolean) is Map : String_Lists.List; C : String_Lists.Cursor; begin -- Only valid separator is ',', not spaces Get_Words (Config, Filter => No_Name, Map => Map, Separator1 => ',', Separator2 => ',', Allow_Empty_Elements => True); Compiler := new GprConfig.Knowledge.Compiler; C := First (Map); declare LC : constant String := To_Lower (String_Lists.Element (C)); begin Compiler.Language_Case := Get_String_Or_No_Name (String_Lists.Element (C)); Compiler.Language_LC := Get_String_Or_No_Name (LC); if Is_Language_With_No_Compiler (Base, LC) then Put_Verbose ("Language " & LC & " requires no compiler"); Compiler.Complete := True; Compiler.Selected := True; Compiler.Targets_Set := All_Target_Sets; Requires_Compiler := False; else Requires_Compiler := True; Next (C); if Has_Element (C) then Compiler.Version := Get_String_Or_No_Name (String_Lists.Element (C)); Next (C); if Has_Element (C) then declare Rts : constant String := String_Lists.Element (C); begin -- If the runtime is a full path, set Runtime and -- Runtime_Dir to the same value. if Rts'Length > 0 and then Is_Absolute_Path (Rts) then Compiler.Runtime := Get_String_No_Adalib (Rts); Compiler.Runtime_Dir := Compiler.Runtime; else Compiler.Runtime := Get_String_Or_No_Name (Rts); end if; end; Next (C); if Has_Element (C) then Compiler.Path := Get_String_Or_No_Name (Name_As_Directory (Normalize_Pathname (String_Lists.Element (C), Case_Sensitive => False))); Next (C); if Has_Element (C) then -- the name could be either a name as defined in the -- knowledge base, or the base name of the executable -- we are looking for. It must not include the exec -- suffix. Compiler.Name := Get_String_Or_No_Name (GNAT.Directory_Operations.Base_Name (String_Lists.Element (C), Suffix => Exec_Suffix.all)); end if; end if; end if; end if; Compiler.Complete := False; -- Complete_Command_Line_Compilers will check that this is a valid -- config Put_Verbose ("Language " & LC & " requires a compiler"); end if; end; exception when E : others => Put_Verbose ("Exception raised: " & Exception_Information (E)); raise Invalid_Config; end Parse_Config_Parameter; --------------------------- -- Filter_Compilers_List -- --------------------------- procedure Filter_Compilers_List (Base : Knowledge_Base; Compilers : in out Compiler_Lists.List; For_Target_Set : Targets_Set_Id) is procedure Mark_As_Selectable (Comp : in out Compiler_Access); procedure Mark_As_Unselectable (Comp : in out Compiler_Access); ------------------------ -- Mark_As_Selectable -- ------------------------ procedure Mark_As_Selectable (Comp : in out Compiler_Access) is begin Comp.Selectable := True; end Mark_As_Selectable; -------------------------- -- Mark_As_Unselectable -- -------------------------- procedure Mark_As_Unselectable (Comp : in out Compiler_Access) is begin Comp.Selectable := False; end Mark_As_Unselectable; Comp, Comp2 : Compiler_Lists.Cursor; Selectable : Boolean; begin Put_Verbose ("Filtering the list of compilers", 1); Comp := First (Compilers); while Has_Element (Comp) loop if not Compiler_Lists.Element (Comp).Selected then Selectable := True; if For_Target_Set /= All_Target_Sets and then Compiler_Lists.Element (Comp).Targets_Set /= All_Target_Sets and then Compiler_Lists.Element (Comp).Targets_Set /= For_Target_Set then Selectable := False; if Current_Verbosity /= Default then Put_Verbose ("Incompatible target for: " & To_String (Base, Compiler_Lists.Element (Comp).all, False)); end if; end if; if Selectable then Comp2 := First (Compilers); while Has_Element (Comp2) loop if Compiler_Lists.Element (Comp2).Selected and then Compiler_Lists.Element (Comp2).Language_LC = Compiler_Lists.Element (Comp).Language_LC then Selectable := False; if Current_Verbosity /= Default then Put_Verbose ("Already selected language for " & To_String (Base, Compiler_Lists.Element (Comp).all, False)); end if; exit; end if; Next (Comp2); end loop; end if; if Selectable then -- Would adding this compiler to the current selection end -- up with an unsupported config ? Set_Selection (Compilers, Comp, True); if not Is_Supported_Config (Base, Compilers) then Selectable := False; if Current_Verbosity /= Default then Put_Verbose ("Unsupported config for: " & To_String (Base, Compiler_Lists.Element (Comp).all, False)); end if; end if; Set_Selection (Compilers, Comp, False); end if; if Selectable then Update_Element (Compilers, Comp, Mark_As_Selectable'Access); else Update_Element (Compilers, Comp, Mark_As_Unselectable'Access); end if; end if; Next (Comp); end loop; Put_Verbose ("", -1); end Filter_Compilers_List; ----------------- -- Is_Selected -- ----------------- function Is_Selected (Comp : Compiler) return Boolean is begin return Comp.Selected; end Is_Selected; ------------ -- Target -- ------------ function Target (Comp : Compiler) return Namet.Name_Id is begin return Comp.Target; end Target; -------------------- -- Runtime_Dir_Of -- -------------------- function Runtime_Dir_Of (Comp : Compiler_Access) return Namet.Name_Id is begin if Comp = null then return Namet.No_Name; else return Comp.Runtime_Dir; end if; end Runtime_Dir_Of; end GprConfig.Knowledge; gprbuild-gpl-2014-src/src/gprclean-main.adb0000644000076700001450000007202012323721731020110 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R C L E A N . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2011-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This package contains the implementation of gprclean. -- See gprclean.adb with Ada.Command_Line; use Ada.Command_Line; with Ada.Exceptions; use Ada.Exceptions; with System.Case_Util; use System.Case_Util; with GNAT.Command_Line; use GNAT.Command_Line; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.IO; use GNAT.IO; with GNAT.OS_Lib; use GNAT.OS_Lib; with Gprbuild.Compilation.Slave; use Gprbuild.Compilation.Slave; with Csets; with Gpr_Util; use Gpr_Util; with GPR_Version; use GPR_Version; with Hostparm; with Makeutl; use Makeutl; with Namet; use Namet; with Opt; use Opt; with Osint; with Prj; use Prj; with Prj.Conf; use Prj.Conf; with Prj.Env; with Prj.Err; with Prj.Ext; with Prj.Tree; use Prj.Tree; with Snames; with Stringt; with Switch; use Switch; procedure Gprclean.Main is use Knowledge; procedure Usage; -- Display the usage. -- If called several times, the usage is displayed only the first time. procedure Parse_Cmd_Line; -- Parse the command line procedure Display_Copyright; -- Display the Copyright notice. If called several times, display the -- Copyright notice only the first time. procedure Initialize; -- Call the necessary package initializations procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage); ----------------------- -- Display_Copyright -- ----------------------- procedure Display_Copyright is begin if not Copyright_Displayed then Copyright_Displayed := True; Display_Version ("GPRCLEAN", "2006", Version_String => Gpr_Version_String); end if; end Display_Copyright; ---------------- -- Initialize -- ---------------- procedure Initialize is begin if not Initialized then Initialized := True; -- Initialize some packages Csets.Initialize; Namet.Initialize; Snames.Initialize; Stringt.Initialize; Prj.Tree.Initialize (Root_Environment, Gprclean_Flags); Prj.Tree.Initialize (Project_Node_Tree); end if; -- Reset global variables Do_Nothing := False; File_Deleted := False; Copyright_Displayed := False; Usage_Displayed := False; Free (Project_File_Name); Main_Project := Prj.No_Project; All_Projects := False; Mains.Delete; end Initialize; -------------------- -- Parse_Cmd_Line -- -------------------- procedure Parse_Cmd_Line is Last : constant Natural := Argument_Count; Index : Positive := 1; begin -- First deal with --version and --help Check_Version_And_Help ("GPRCLEAN", "2006", Version_String => Gpr_Version_String); -- Now deal with the other options while Index <= Last loop declare Arg : constant String := Argument (Index); procedure Bad_Argument; -- Signal bad argument ------------------ -- Bad_Argument -- ------------------ procedure Bad_Argument is begin Osint.Fail ("invalid argument """ & Arg & '"'); end Bad_Argument; begin if Db_Directory_Expected then Db_Directory_Expected := False; Parse_Knowledge_Base (Project_Tree, Arg); Name_Len := 0; Add_Str_To_Name_Buffer (Arg); Db_Switch_Args.Append (Name_Find); elsif Arg'Length /= 0 then if Arg (1) = '-' then if Arg'Length = 1 then Bad_Argument; end if; case Arg (2) is when '-' => if not Hostparm.OpenVMS and then Arg = "--db-" then Load_Standard_Base := False; elsif not Hostparm.OpenVMS and then Arg = "--db" then Db_Directory_Expected := True; elsif Arg'Length > Config_Project_Option'Length and then Arg (1 .. Config_Project_Option'Length) = Config_Project_Option then if Config_Project_File_Name /= null and then (Autoconf_Specified or else Config_Project_File_Name.all /= Arg (Config_Project_Option'Length + 1 .. Arg'Last)) then Fail_Program (Project_Tree, "several configuration switches cannot " & "be specified"); else Autoconfiguration := False; Config_Project_File_Name := new String' (Arg (Config_Project_Option'Length + 1 .. Arg'Last)); end if; elsif Arg (1 .. Distributed_Option'Length) = Distributed_Option then Distributed_Mode := True; Gprbuild.Compilation.Slave.Record_Slaves (Arg (Distributed_Option'Length + 1 .. Arg'Last)); elsif Arg'Length >= Slave_Env_Option'Length and then Arg (1 .. Slave_Env_Option'Length) = Slave_Env_Option then if Arg = Slave_Env_Option then -- Just --slave-env, it is up to gprbuild to -- build a sensible slave environment value. Slave_Env_Auto := True; else Slave_Env := new String' (Arg (Slave_Env_Option'Length + 2 .. Arg'Last)); end if; elsif not Hostparm.OpenVMS and then Arg'Length > Autoconf_Project_Option'Length and then Arg (1 .. Autoconf_Project_Option'Length) = Autoconf_Project_Option then if Config_Project_File_Name /= null and then (not Autoconf_Specified or else Config_Project_File_Name.all /= Arg (Autoconf_Project_Option'Length + 1 .. Arg'Last)) then Fail_Program (Project_Tree, "several configuration switches cannot " & "be specified"); else Config_Project_File_Name := new String' (Arg (Autoconf_Project_Option'Length + 1 .. Arg'Last)); Autoconf_Specified := True; end if; elsif not Hostparm.OpenVMS and then Arg'Length > Target_Project_Option'Length and then Arg (1 .. Target_Project_Option'Length) = Target_Project_Option then if Target_Name /= null then if Target_Name.all /= Arg (Target_Project_Option'Length + 1 .. Arg'Last) then Fail_Program (Project_Tree, "several target switches " & "cannot be specified"); end if; else Target_Name := new String' (Arg (Target_Project_Option'Length + 1 .. Arg'Last)); end if; elsif Arg'Length > RTS_Option'Length and then Arg (1 .. RTS_Option'Length) = RTS_Option then declare Set : constant Boolean := Runtime_Name_Set_For (Snames.Name_Ada); Old : constant String := Runtime_Name_For (Snames.Name_Ada); RTS : constant String := Arg (RTS_Option'Length + 1 .. Arg'Last); begin if Set and then Old /= RTS then Fail_Program (Project_Tree, "several different run-times " & "cannot be specified"); end if; Set_Runtime_For (Snames.Name_Ada, RTS); end; elsif Arg'Length > RTS_Language_Option'Length and then Arg (1 .. RTS_Language_Option'Length) = RTS_Language_Option then declare Language_Name : Name_Id := No_Name; RTS_Start : Natural := Arg'Last + 1; begin for J in RTS_Language_Option'Length + 2 .. Arg'Last loop if Arg (J) = '=' then Name_Len := 0; Add_Str_To_Name_Buffer (Arg (RTS_Language_Option'Length + 1 .. J - 1)); To_Lower (Name_Buffer (1 .. Name_Len)); Language_Name := Name_Find; RTS_Start := J + 1; exit; end if; end loop; if Language_Name = No_Name then Fail_Program (Project_Tree, "illegal switch: " & Arg); else declare RTS : constant String := Arg (RTS_Start .. Arg'Last); Set : constant Boolean := Runtime_Name_Set_For (Language_Name); Old : constant String := Runtime_Name_For (Language_Name); begin if Set and then Old /= RTS then Fail_Program (Project_Tree, "several different run-times cannot" & " be specified for the same language"); else Set_Runtime_For (Language_Name, RTS); end if; end; end if; end; elsif Arg'Length > Subdirs_Option'Length and then Arg (1 .. Subdirs_Option'Length) = Subdirs_Option then Subdirs := new String' (Arg (Subdirs_Option'Length + 1 .. Arg'Last)); elsif Arg = Makeutl.Unchecked_Shared_Lib_Imports then Opt.Unchecked_Shared_Lib_Imports := True; else Bad_Argument; end if; when 'a' => if Arg'Length < 4 then Bad_Argument; end if; if Arg (3) = 'P' then Prj.Env.Add_Directories (Root_Environment.Project_Path, Arg (4 .. Arg'Last)); else Bad_Argument; end if; when 'c' => Compile_Only := True; when 'e' => if Arg = "-eL" then Follow_Links_For_Files := True; Follow_Links_For_Dirs := True; else Bad_Argument; end if; when 'f' => Force_Deletions := True; Opt.Directories_Must_Exist_In_Projects := False; when 'F' => Full_Path_Name_For_Brief_Errors := True; when 'h' => Display_Copyright; Usage; when 'n' => Do_Nothing := True; when 'P' => if Project_File_Name /= null then Osint.Fail ("multiple -P switches"); end if; if Arg'Length > 2 then declare Prj : constant String := Arg (3 .. Arg'Last); begin if Prj'Length > 1 and then Prj (Prj'First) = '=' then Project_File_Name := new String' (Prj (Prj'First + 1 .. Prj'Last)); else Project_File_Name := new String'(Prj); end if; end; else if Index = Last then Osint.Fail ("no project specified after -P"); end if; Index := Index + 1; Project_File_Name := new String'(Argument (Index)); end if; when 'q' => Quiet_Output := True; when 'r' => All_Projects := True; when 'v' => if Arg = "-v" then Verbose_Mode := True; elsif Arg = "-vP0" then Current_Verbosity := Prj.Default; elsif Arg = "-vP1" then Current_Verbosity := Prj.Medium; elsif Arg = "-vP2" then Current_Verbosity := Prj.High; else Bad_Argument; end if; when 'X' => if Arg'Length = 2 then Bad_Argument; end if; declare Ext_Asgn : constant String := Arg (3 .. Arg'Last); Start : Positive := Ext_Asgn'First; Stop : Natural := Ext_Asgn'Last; OK : Boolean := True; begin if Ext_Asgn (Start) = '"' then if Ext_Asgn (Stop) = '"' then Start := Start + 1; Stop := Stop - 1; else OK := False; end if; end if; if not OK or else not Prj.Ext.Check (Root_Environment.External, Declaration => Ext_Asgn (Start .. Stop)) then Osint.Fail ("illegal external assignment '" & Ext_Asgn & '''); end if; end; when others => Bad_Argument; end case; else -- The file name of a main or a project file declare File_Name : String := Arg; begin Osint.Canonical_Case_File_Name (File_Name); if File_Name'Length > Project_File_Extension'Length and then File_Name (File_Name'Last - Project_File_Extension'Length + 1 .. File_Name'Last) = Project_File_Extension then if Project_File_Name /= null then Osint.Fail ("cannot have several project files specified"); else Project_File_Name := new String'(File_Name); end if; else -- Not a project file, then it is a main Mains.Add_Main (Arg); end if; end; end if; end if; end; Index := Index + 1; end loop; end Parse_Cmd_Line; ----------- -- Usage -- ----------- procedure Usage is begin if not Usage_Displayed then Usage_Displayed := True; Put_Line ("Usage: gprclean [switches] -P {name}"); New_Line; Put_Line (" {name} is zero or more file names"); New_Line; Display_Usage_Version_And_Help; Put_Line (" --distributed=slave1[,slave2]"); Put_Line (" Activate the remote clean-up"); Put_Line (" --slave-env[=name]"); Put_Line (" Use a specific slave's environment"); Put_Line (" --config=file.cgpr"); Put_Line (" Specify the configuration project file name"); if not Hostparm.OpenVMS then Put_Line (" --autoconf=file.cgpr"); Put_Line (" Specify/create the main config project file name"); end if; if not Hostparm.OpenVMS then Put_Line (" --target=targetname"); Put_Line (" Specify a target for cross platforms"); end if; if not Hostparm.OpenVMS then Put_Line (" --db dir Parse dir as an additional knowledge base"); end if; if not Hostparm.OpenVMS then Put_Line (" --db- Do not load the standard knowledge base"); end if; Put_Line (" --RTS="); Put_Line (" Use runtime for language Ada"); Put_Line (" --RTS:="); Put_Line (" Use runtime for language "); Put_Line (" --subdirs=dir"); Put_Line (" Real obj/lib/exec dirs are subdirs"); Put_Line (" " & Makeutl.Unchecked_Shared_Lib_Imports); Put_Line (" Shared lib projects may import any project"); New_Line; Put_Line (" -aPdir Add directory dir to project search path"); Put_Line (" -c Only delete compiler generated files"); Put_Line (" -eL Follow symbolic links when processing " & "project files"); Put_Line (" -f Force deletions of unwritable files"); Put_Line (" -F Full project path name " & "in brief error messages"); Put_Line (" -h Display this message"); Put_Line (" -n Nothing to do: only list files to delete"); Put_Line (" -P Use Project File "); Put_Line (" -q Be quiet/terse"); Put_Line (" -r Clean all projects recursively"); Put_Line (" -v Verbose mode"); Put_Line (" -vPx Specify verbosity when parsing Project Files"); Put_Line (" -Xnm=val Specify an external reference " & "for Project Files"); New_Line; end if; end Usage; User_Project_Node : Project_Node_Id; begin -- Do the necessary initializations Initialize; -- Parse the command line, getting the switches and the executable names Parse_Cmd_Line; -- Once we have parsed the command line, we might know the target, and -- thus can initialize the default project path. if Target_Name = null then Prj.Env.Initialize_Default_Project_Path (Root_Environment.Project_Path, Target_Name => ""); else Prj.Env.Initialize_Default_Project_Path (Root_Environment.Project_Path, Target_Name.all); end if; if Load_Standard_Base then Parse_Knowledge_Base (Project_Tree); end if; -- If no project file was specified, look first for a default if Project_File_Name = null then Look_For_Default_Project; end if; -- Check that a project file was specified and get the configuration if Project_File_Name = null then Try_Help; Fail_Program (Project_Tree, "no project file specified and no default project file"); end if; if Verbose_Mode then Display_Copyright; end if; if Opt.Verbose_Mode then New_Line; Put ("Parsing Project File """); Put (Project_File_Name.all); Put_Line ("""."); New_Line; end if; -- Makes the Ada RTS is absolute if it is not a base name if Runtime_Name_Set_For (Snames.Name_Ada) then Locate_Runtime (Project_Tree, Snames.Name_Ada); end if; -- Check command line arguments. These will be overridden when looking -- for the configuration file if Target_Name = null then Target_Name := new String'(""); end if; if Config_Project_File_Name = null then Config_Project_File_Name := new String'(""); end if; begin Parse_Project_And_Apply_Config (Main_Project => Main_Project, User_Project_Node => User_Project_Node, Config_File_Name => Config_Project_File_Name.all, Autoconf_Specified => Autoconf_Specified, Project_File_Name => Project_File_Name.all, Project_Tree => Project_Tree, Project_Node_Tree => Project_Node_Tree, Packages_To_Check => Packages_To_Check, Env => Root_Environment, Allow_Automatic_Generation => Autoconfiguration, Automatically_Generated => Delete_Autoconf_File, Config_File_Path => Configuration_Project_Path, Target_Name => Target_Name.all, Normalized_Hostname => Normalized_Hostname, Implicit_Project => No_Project_File_Found); -- Print warnings that might have occurred while parsing the project Prj.Err.Finalize; -- But avoid duplicate warnings later on Prj.Err.Initialize; exception when E : Prj.Conf.Invalid_Config => Osint.Fail (Exception_Message (E)); end; if Main_Project = No_Project then -- Don't flush messages in case of parsing error. This has already -- been taken care when parsing the tree. Otherwise, it results in -- the same message being displayed twice. Fail_Program (Project_Tree, """" & Project_File_Name.all & """ processing failed", Flush_Messages => User_Project_Node /= Empty_Node); end if; -- Update info on all sources declare Iter : Source_Iterator; begin Iter := For_Each_Source (Project_Tree); while Prj.Element (Iter) /= No_Source loop Initialize_Source_Record (Prj.Element (Iter)); Next (Iter); end loop; end; -- Even if the config project file has not been automatically -- generated, gprclean will delete it if it was specified using -- --autoconf=. Delete_Autoconf_File := Delete_Autoconf_File or Autoconf_Specified; if Configuration_Project_Path /= null then Free (Config_Project_File_Name); Config_Project_File_Name := new String' (Base_Name (Configuration_Project_Path.all)); end if; if Opt.Verbose_Mode then New_Line; Put ("Parsing of Project File """); Put (Project_File_Name.all); Put (""" is finished."); New_Line; end if; Mains.Fill_From_Project (Main_Project, Project_Tree); Mains.Complete_Mains (Root_Environment.Flags, Main_Project, Project_Tree); if Verbose_Mode then New_Line; end if; Processed_Projects.Init; if Slave_Env = null and then Distributed_Mode then Slave_Env := new String'(Compute_Slave_Env (Project_Tree, Slave_Env_Auto)); if Slave_Env_Auto and not Opt.Quiet_Output then Put_Line ("slave environment is " & Slave_Env.all); end if; end if; -- Clean-up local build declare procedure Do_Clean (Prj : Project_Id; Tree : Project_Tree_Ref); -------------- -- Do_Clean -- -------------- procedure Do_Clean (Prj : Project_Id; Tree : Project_Tree_Ref) is begin -- For the main project and all aggregated projects, remove the -- binder and linker generated files. Clean_Project (Prj, Tree, Main => True, Remove_Executables => not Compile_Only); -- Clean-up remote slaves if Distributed_Mode then Clean_Up_Remote_Slaves (Tree, Prj); end if; end Do_Clean; procedure For_All is new For_Project_And_Aggregated (Do_Clean); begin -- For an aggregate project, we always cleanup all aggregated -- projects, whether "-r" was specified or not. But for those -- projects, we might not clean their imported projects. For_All (Main_Project, Project_Tree); end; if Delete_Autoconf_File then Delete ("", Configuration_Project_Path.all); end if; -- In verbose mode, if Delete has not been called, indicate that -- no file needs to be deleted. if Verbose_Mode and (not File_Deleted) then New_Line; if Do_Nothing then Put_Line ("No file needs to be deleted"); else Put_Line ("No file has been deleted"); end if; end if; end Gprclean.Main; gprbuild-gpl-2014-src/src/gprinstall-uninstall.adb0000644000076700001450000002100212323721731021553 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Containers.Indefinite_Ordered_Sets; use Ada; with Ada.Directories; use Ada.Directories; with Ada.Text_IO; use Ada.Text_IO; with GNAT.MD5; use GNAT.MD5; with Gpr_Util; use Gpr_Util; with Opt; with Osint; with Output; use Output; package body Gprinstall.Uninstall is package File_Set is new Containers.Indefinite_Ordered_Sets (String); ------------- -- Process -- ------------- procedure Process (Install_Name : String) is procedure Delete_File (Position : File_Set.Cursor); -- Delete file pointed to by Position, do nothing if the file is not -- found. procedure Do_Delete (Filename : String); -- Delete file or display a message if in dry-run mode procedure Delete_Empty_Directory (Dir_Name : String); -- Delete Dir_Name if empty, if removed try with parent directory function Project_Dir return String; -- Returns the full pathname to the project directory ---------------------------- -- Delete_Empty_Directory -- ---------------------------- procedure Delete_Empty_Directory (Dir_Name : String) is Prj_Dir_Len : constant Natural := Global_Prefix_Dir.V'Length - 1; Search : Search_Type; Element : Directory_Entry_Type; Empty : Boolean := True; begin -- Do not try to remove a directory past the project dir if Dir_Name'Length >= Prj_Dir_Len then -- Check whether the directory is empty or not Start_Search (Search, Dir_Name, Pattern => ""); Check_Entry : while More_Entries (Search) loop Get_Next_Entry (Search, Element); if Simple_Name (Element) /= "." and then Simple_Name (Element) /= ".." then Empty := False; exit Check_Entry; end if; end loop Check_Entry; End_Search (Search); -- If empty delete it if Empty then begin Delete_Directory (Dir_Name); exception -- This can happen if there is still some sym links into -- the directory. when Text_IO.Use_Error => null; end; -- And then try recursively with parent directory Delete_Empty_Directory (Containing_Directory (Dir_Name)); end if; end if; end Delete_Empty_Directory; ----------------- -- Delete_File -- ----------------- procedure Delete_File (Position : File_Set.Cursor) is Name : constant String := File_Set.Element (Position); begin Do_Delete (Global_Prefix_Dir.V.all & Name); end Delete_File; --------------- -- Do_Delete -- --------------- procedure Do_Delete (Filename : String) is begin if Dry_Run then Write_Line ("delete " & Filename); elsif Exists (Filename) then Delete_File (Filename); Delete_Empty_Directory (Containing_Directory (Filename)); end if; end Do_Delete; ----------------- -- Project_Dir -- ----------------- function Project_Dir return String is begin if Is_Absolute_Path (Global_Project_Subdir.V.all) then return Global_Project_Subdir.V.all; else return Global_Prefix_Dir.V.all & Global_Project_Subdir.V.all; end if; end Project_Dir; Dir : constant String := Project_Dir & "manifests"; Name : constant String := Dir & DS & Install_Name; Man : File_Type; Buffer : String (1 .. 4096); Last : Natural; Files : File_Set.Set; Changed : File_Set.Set; -- Ranges in Buffer above, we have the MD5 (32 chars) a space and then -- the filename. subtype MD5_Range is Positive range Message_Digest'Range; subtype Name_Range is Positive range MD5_Range'Last + 2 .. Buffer'Last; File_Digest : Message_Digest; Expected_Digest : Message_Digest; Removed : Boolean; begin -- Check if manifest for this project exists if not Exists (Name) then if not Opt.Quiet_Output then Osint.Fail ("Project " & Name & " not found."); end if; Osint.Exit_Program (Osint.E_Errors); end if; if not Opt.Quiet_Output then Write_Line ("Uninstall project " & Install_Name); end if; -- Check each file to be deleted Open (Man, In_File, Name); while not End_Of_File (Man) loop Get_Line (Man, Buffer, Last); -- Skip first line if it is the original project's signature if Last > MD5_Range'Last and then Buffer (1 .. 2) /= Sig_Line then declare F_Name : constant String := Buffer (Name_Range'First .. Last); begin Expected_Digest := Buffer (MD5_Range); if Exists (Global_Prefix_Dir.V.all & F_Name) then File_Digest := File_MD5 (Global_Prefix_Dir.V.all & F_Name); Removed := False; else Removed := True; end if; -- Unconditionnaly add a file to the remove list if digest is -- ok, if we are running in force mode or the file has already -- been removed. if File_Digest = Expected_Digest or else Force_Installations or else Removed then -- Make sure we always destroy the symbolic links before the -- files itself. Files.Include (F_Name); else Changed.Include (F_Name); end if; end; end if; end loop; Close (Man); -- Delete files if Changed.Is_Subset (Of_Set => Files) then Files.Iterate (Delete_File'Access); -- Then finally delete the manifest for this project Do_Delete (Name); else if not Opt.Quiet_Output then Write_Line ("Following files have been changed:"); declare procedure Display (Position : File_Set.Cursor); -- Display only if not part of Files set ------------- -- Display -- ------------- procedure Display (Position : File_Set.Cursor) is F_Name : constant String := File_Set.Element (Position); begin if not Files.Contains (F_Name) then Write_Line (F_Name); end if; end Display; begin Changed.Iterate (Display'Access); end; Write_Line ("use option -f to force file deletion."); end if; end if; end Process; end Gprinstall.Uninstall; gprbuild-gpl-2014-src/src/gprslave.adb0000644000076700001450000015153012323721731017222 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R S L A V E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Characters.Handling; use Ada.Characters.Handling; with Ada.Containers.Indefinite_Hashed_Maps; with Ada.Containers.Indefinite_Ordered_Sets; with Ada.Containers.Ordered_Sets; with Ada.Containers.Vectors; with Ada.Directories; use Ada.Directories; with Ada.Exceptions; use Ada.Exceptions; with Ada.Streams.Stream_IO; use Ada.Streams; with Ada.Strings.Equal_Case_Insensitive; with Ada.Strings.Fixed; use Ada.Strings; with Ada.Strings.Hash_Case_Insensitive; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO; use Ada.Text_IO; with Interfaces; with System.Multiprocessors; use System; with Csets; use Csets; with Gnatvsn; use Gnatvsn; with Namet; use Namet; with Prj; use Prj; with Prj.Env; use Prj.Env; with Prj.Part; use Prj.Part; with Prj.Proc; use Prj.Proc; with Prj.Tree; use Prj.Tree; with Snames; use Snames; with Types; with GNAT.Command_Line; use GNAT; with GNAT.CRC32; with GNAT.OS_Lib; use GNAT.OS_Lib; with GNAT.Sockets; use GNAT.Sockets; with GNAT.String_Split; use GNAT.String_Split; with GNAT.Strings; with Gpr_Util; use Gpr_Util; with Gprbuild.Compilation; use Gprbuild.Compilation; with Gprbuild.Compilation.Process; use Gprbuild.Compilation.Process; with Gprbuild.Compilation.Protocol; use Gprbuild.Compilation.Protocol; with GprConfig.Knowledge; use GprConfig.Knowledge; procedure Gprslave is use Ada; -- Data for a build master type Build_Master is record Channel : Communication_Channel; -- communication with build master Socket : Socket_Type; Project_Name : Unbounded_String; Target : Unbounded_String; Build_Env : Unbounded_String; Sync : Sync_Kind; end record; function "<" (B1, B2 : Build_Master) return Boolean is (To_C (B1.Socket) < To_C (B2.Socket)); function "=" (B1, B2 : Build_Master) return Boolean is (B1.Socket = B2.Socket); package Builder_Set is new Containers.Ordered_Sets (Build_Master); -- Representation of a job data type Job_Data is record Cmd : Command; Id : Remote_Id; -- job id must be uniq across all slaves Pid : Integer; -- the OS process id Dep_Dir : Unbounded_String; Dep_File : Unbounded_String; Obj_File : Unbounded_String; Output : Unbounded_String; Build_Sock : Socket_Type; -- key used to get the corresponding builder end record; No_Job : constant Job_Data := (Id => -1, others => <>); function "<" (J1, J2 : Job_Data) return Boolean is (J1.Pid < J2.Pid); function "=" (J1, J2 : Job_Data) return Boolean is (J1.Pid = J2.Pid); package Job_Data_Set is new Containers.Ordered_Sets (Job_Data); package To_Run_Set is new Containers.Vectors (Positive, Job_Data); function Get_Arg (Builder : Build_Master; Value : String) return String; pragma Inline (Get_Arg); -- Returns Value with possible translation of the local repositories function Get_Args (Builder : Build_Master; Slices : Slice_Set) return Argument_List; -- Returns an Argument_List corresponding to the Slice_Set procedure Wait_For_Master; -- Wait for a build master to connect, initialize the globval communication -- channel below. Send the slave config to the build master. function Image (Value : Long_Integer) return String; -- Return Value string representation without the leading space function Work_Directory (Builder : Build_Master) return String; -- Directory where compilation are to be done, this is the directory named -- after the project under the Root_Directory. procedure Parse_Command_Line; -- Parse the command line options, set variables below accordingly function Get_Slave_Id return Remote_Id; task Wait_Completion; -- Waiting for job completion and sending back the response to the build -- masters. task Protocol_Handler; -- Waiting for incoming requests from the masters, take corresponding -- actions. task Run_Compilation; -- Task running a maximum of Max_Process compilation simultaneously. These -- jobs are taken from the To_Run protected object. -- A mutex to avoid interweaved responses on the channel and keep the -- working directory. Indeed the tasks are moving to some working directory -- from where a compilation has to be run or where the builder environment -- has to be created. We must ensure that all those actions are atomic. protected Mutex is entry Seize; procedure Release; private Free : Boolean := True; end Mutex; -- Protected builders data set (used by environment task and the -- Protocol_Handler). protected Builders is procedure Insert (Builder : Build_Master); -- Add Builder into the set procedure Remove (Builder : Build_Master); -- Remove Builder from the set function Get (Socket : Socket_Type) return Build_Master; -- Get the builder using Socket entry Get_Socket_Set (Socket_Set : out Socket_Set_Type); -- Get a socket set for all builders private Builders : Builder_Set.Set; end Builders; -- Queue of Job to run, A FIFO list protected To_Run is procedure Push (Job : Job_Data); entry Pop (Job : out Job_Data); private Set : To_Run_Set.Vector; end To_Run; -- Set of running jobs protected Running is procedure Register (Job : Job_Data); -- Register a running Job procedure Get (Job : out Job_Data; Pid : Process_Id); -- Get Job having the given Pid procedure Set_Max (Max : Positive); -- Set the maximum running processes simultaneously entry Wait_Slot; -- Wait for a running slot to be available entry Wait; -- Wait for at least one running process private Set : Job_Data_Set.Set; Count : Natural := 0; Max : Natural := 0; end Running; Compiler_Path : constant OS_Lib.String_Access := Locate_Exec_On_Path ("gnatls"); Slave_Id : Remote_Id; -- Host Id used to compose a unique job id across all running slaves -- Command line parameters statuses Port : aliased Integer; Max_Processes : aliased Integer; Help : aliased Boolean; Verbose : aliased Boolean; Debug : aliased Boolean; Root_Directory : aliased GNAT.Strings.String_Access := new String'(Current_Directory); -- Root directoty for the gprslave environment. All projects sources and -- compilations are done under this directory. -- Running instances statuses Address : Sock_Addr_Type; Server : Socket_Type; Index : Long_Integer := 0; -- Knowledge base Base : Knowledge_Base; Selected_Targets_Set : Targets_Set_Id; -------------- -- Builders -- -------------- protected body Builders is --------- -- Get -- --------- function Get (Socket : Socket_Type) return Build_Master is Builder : Build_Master; Pos : Builder_Set.Cursor; begin Builder.Socket := Socket; Pos := Builders.Find (Builder); if Builder_Set.Has_Element (Pos) then Builder := Builder_Set.Element (Pos); end if; return Builder; end Get; -------------------- -- Get_Socket_Set -- -------------------- entry Get_Socket_Set (Socket_Set : out Socket_Set_Type) when not Builders.Is_Empty is begin Empty (Socket_Set); for B of Builders loop Set (Socket_Set, B.Socket); end loop; end Get_Socket_Set; ------------ -- Insert -- ------------ procedure Insert (Builder : Build_Master) is begin Builders.Insert (Builder); end Insert; ------------ -- Remove -- ------------ procedure Remove (Builder : Build_Master) is begin Builders.Delete (Builder); end Remove; end Builders; ------------- -- Get_Arg -- ------------- function Get_Arg (Builder : Build_Master; Value : String) return String is P : constant Natural := Fixed.Index (Value, WD_Path_Tag); begin if P = 0 then return Value; else return Value (Value'First .. P - 1) & Work_Directory (Builder) & Directory_Separator & Get_Arg (Builder, Value (P + WD_Path_Tag'Length .. Value'Last)); end if; end Get_Arg; -------------- -- Get_Args -- -------------- function Get_Args (Builder : Build_Master; Slices : Slice_Set) return Argument_List is Args : Argument_List (1 .. Integer (Slice_Count (Slices))); begin for K in Args'Range loop Args (K) := new String' (Get_Arg (Builder, Slice (Slices, Slice_Number (K)))); end loop; return Args; end Get_Args; ----------------- -- Get_Slave_Id -- ----------------- function Get_Slave_Id return Remote_Id is use GNAT.CRC32; use type Interfaces.Unsigned_32; CRC : GNAT.CRC32.CRC32; begin Initialize (CRC); Update (CRC, Host_Name); -- Set the host id as the 32 higher bits return Remote_Id (Get_Value (CRC)) * 2 ** 32; end Get_Slave_Id; ----------- -- Image -- ----------- function Image (Value : Long_Integer) return String is I : constant String := Long_Integer'Image (Value); begin return (if I (I'First) = '-' then I else I (I'First + 1 .. I'Last)); end Image; ----------- -- Mutex -- ----------- protected body Mutex is ----------- -- Seize -- ----------- entry Seize when Free is begin Free := False; end Seize; ------------- -- Release -- ------------- procedure Release is begin Free := True; end Release; end Mutex; ------------------------ -- Parse_Command_Line -- ------------------------ procedure Parse_Command_Line is use GNAT.Command_Line; Config : Command_Line_Configuration; begin Define_Switch (Config, Help'Access, "-h", Long_Switch => "--help", Help => "display this help message"); Define_Switch (Config, Max_Processes'Access, "-j:", Long_Switch => "--jobs=", Initial => Integer (Multiprocessors.Number_Of_CPUs), Default => Integer (Multiprocessors.Number_Of_CPUs), Help => "set the maximum simultaneous compilation"); Define_Switch (Config, Root_Directory'Access, "-d:", Long_Switch => "--directory=", Help => "set the root directory"); Define_Switch (Config, Port'Access, "-p:", Long_Switch => "--port=", Initial => Integer (Default_Port), Default => Integer (Default_Port), Help => "set the port the slave will listen to"); Define_Switch (Config, Verbose'Access, "-v", Long_Switch => "--verbose", Help => "activate verbose mode, display extra information"); Define_Switch (Config, Debug'Access, "-vv", Long_Switch => "--debug", Help => "activate debug mode, display lot of information (imply -v)"); Set_Usage (Config, Usage => "[switches]"); Getopt (Config); if Help then Display_Help (Config); OS_Exit (1); end if; if Debug then Verbose := True; end if; -- Ensure Root_Directory does not ends with a directory separator if Root_Directory (Root_Directory'Last) in '/' | '\' then Delete_Last : declare RD : constant String := Root_Directory (Root_Directory'First .. Root_Directory'Last - 1); begin Free (Root_Directory); Root_Directory := new String'(RD); end Delete_Last; end if; Running.Set_Max (Max_Processes); exception when Invalid_Switch => OS_Exit (1); when Exit_From_Command_Line => OS_Exit (1); end Parse_Command_Line; ---------------------- -- Protocol_Handler -- ---------------------- task body Protocol_Handler is type Job_Number is mod 2**32; -- A 32bits integer which wrap around. This is no problem as we want -- to be able to identify running process. There won't be 2**32 process -- running at the same time. So it is safe restart numbering at 0. Selector : Selector_Type; R_Socket_Set : Socket_Set_Type; Empty_Set : Socket_Set_Type; Status : Selector_Status; Builder : Build_Master; Socket : Socket_Type; Jid : Job_Number := 0; begin -- Create selector Create_Selector (Selector); Empty (Empty_Set); -- For now do not check write status Handle_Commands : loop -- Wait for some commands from one of the build master Builders.Get_Socket_Set (R_Socket_Set); Wait_Incoming_Data : loop begin Check_Selector (Selector, R_Socket_Set, Empty_Set, Status); exit Wait_Incoming_Data; exception when E : Socket_Error => if Resolve_Exception (E) /= Interrupted_System_Call then raise; end if; end; end loop Wait_Incoming_Data; Get (R_Socket_Set, Socket); if Socket /= No_Socket then Builder := Builders.Get (Socket); Mutex.Seize; declare Cmd : constant Command := Get_Command (Builder.Channel); begin if Debug then Put ("# command: " & Command_Kind'Image (Kind (Cmd))); declare List : constant Argument_List_Access := Args (Cmd); begin if List /= null then for K in List'Range loop Put (", " & List (K).all); end loop; end if; end; New_Line; end if; if Kind (Cmd) = EX then Record_Job : declare Id : constant Remote_Id := Slave_Id + Remote_Id (Jid); -- Note that the Id above should be unique across all -- running slaves. This is not the process id, but an id -- sent back to the build master to identify the actual -- job. begin Jid := Jid + 1; if Debug then Put_Line ("# register compilation " & Image (Id)); end if; To_Run.Push (Job_Data'(Cmd, Id, -1, Null_Unbounded_String, Null_Unbounded_String, Null_Unbounded_String, Null_Unbounded_String, Builder.Socket)); Send_Ack (Builder.Channel, Id); end Record_Job; elsif Kind (Cmd) = FL then null; elsif Kind (Cmd) = CU then Clean_Up_Request : begin Builder.Project_Name := To_Unbounded_String (Args (Cmd)(1).all); if Exists (Work_Directory (Builder)) then if Verbose then Put_Line ("Delete " & Work_Directory (Builder)); end if; Delete_Tree (Work_Directory (Builder)); end if; Send_Ok (Builder.Channel); exception when others => Send_Ko (Builder.Channel); end Clean_Up_Request; elsif Kind (Cmd) = EC then -- No more compilation for this project Close (Builder.Channel); Builders.Remove (Builder); if Verbose then Put_Line ("End project : " & To_String (Builder.Project_Name)); end if; else raise Constraint_Error with "unexpected command " & Command_Kind'Image (Kind (Cmd)); end if; exception when E : others => Put_Line ("Error: " & Exception_Information (E)); -- In case of an exception, communication endded -- prematurately or some wrong command received, make sure -- we clean the slave state and we listen to new commands. -- Not doing that could make the slave unresponding. Close (Builder.Channel); end; Mutex.Release; end if; end loop Handle_Commands; exception when E : others => Put_Line ("Unrecoverable error: Protocol_Handler."); Put_Line (Exception_Information (E)); OS_Exit (1); end Protocol_Handler; --------------------- -- Run_Compilation -- --------------------- task body Run_Compilation is function Get_Driver (Builder : Build_Master; Language, Project : String) return String; -- Returns the compiler driver for the given language and the current -- target as retreived from the initial handshake context exchange. function Get_Output_File (Builder : Build_Master) return String; -- Returns a unique output file procedure Output_Compilation (File : String); -- Output compilation information package Drivers_Cache is new Containers.Indefinite_Hashed_Maps (String, String, Ada.Strings.Hash_Case_Insensitive, Ada.Strings.Equal_Case_Insensitive); Cache : Drivers_Cache.Map; ---------------- -- Get_Driver -- ---------------- function Get_Driver (Builder : Build_Master; Language, Project : String) return String is procedure Look_Driver (Project_Name : String; Is_Config : Boolean); -- Set Driver with the found driver for the Language Key : constant String := To_String (Builder.Target) & '+' & Language; Position : constant Drivers_Cache.Cursor := Cache.Find (Key); Compilers, Filters : Compiler_Lists.List; Requires_Comp : Boolean; Comp : Compiler_Access; Env : Environment; Success : Boolean; Driver : Unbounded_String := To_Unbounded_String (Key); ----------------- -- Look_Driver -- ----------------- procedure Look_Driver (Project_Name : String; Is_Config : Boolean) is Project_Node_Tree : Project_Node_Tree_Ref; Project_Node : Project_Node_Id := Empty_Node; Project_Tree : Project_Tree_Ref; Project : Project_Id; begin Project_Node_Tree := new Project_Node_Tree_Data; Prj.Tree.Initialize (Project_Node_Tree); Prj.Part.Parse (Project_Node_Tree, Project_Node, Project_Name, Errout_Handling => Prj.Part.Finalize_If_Error, Packages_To_Check => null, Is_Config_File => Is_Config, Target_Name => To_String (Builder.Target), Env => Env); Project_Tree := new Project_Tree_Data; Prj.Initialize (Project_Tree); Proc.Process (Project_Tree, Project, null, Success, Project_Node, Project_Node_Tree, Env); if not Success then return; end if; declare Pcks : Package_Table.Table_Ptr renames Project_Tree.Shared.Packages.Table; Pck : Package_Id := Project.Decl.Packages; begin Look_Compiler_Package : while Pck /= No_Package loop if Pcks (Pck).Decl /= No_Declarations and then Pcks (Pck).Name = Name_Compiler then -- Look for the Driver ("") attribute declare Id : Array_Id := Pcks (Pck).Decl.Arrays; begin while Id /= No_Array loop declare V : constant Array_Data := Project_Tree.Shared.Arrays.Table (Id); begin if V.Name = Name_Driver and then V.Value /= No_Array_Element then -- Check if element is for the given -- language, and if so return the -- corresponding value. declare E : constant Array_Element := Project_Tree.Shared. Array_Elements.Table (V.Value); begin if Get_Name_String (E.Index) = To_Lower (Language) then Driver := To_Unbounded_String (Get_Name_String (E.Value.Value)); exit Look_Compiler_Package; end if; end; end if; end; Id := Project_Tree.Shared.Arrays.Table (Id).Next; end loop; end; end if; Pck := Pcks (Pck).Next; end loop Look_Compiler_Package; end; exception -- Never propagate an exception, the driver won't be set anyway when others => null; end Look_Driver; begin if Drivers_Cache.Has_Element (Position) then return Drivers_Cache.Element (Position); else -- Generate the configuration project for this language and target Parse_Config_Parameter (Base => Base, Config => Language, Compiler => Comp, Requires_Compiler => Requires_Comp); if Requires_Comp then Filters.Append (Comp); else Compilers.Append (Comp); end if; Complete_Command_Line_Compilers (Base, Selected_Targets_Set, Filters, Compilers); -- Generate configuration project file Generate_Configuration (Base, Compilers, "slave_tmp.cgpr", To_String (Builder.Target)); Prj.Tree.Initialize (Env, Prj.Gprbuild_Flags); Prj.Initialize (Prj.No_Project_Tree); Prj.Env.Initialize_Default_Project_Path (Env.Project_Path, Target_Name => To_String (Builder.Target)); -- Parse it to find the driver for this language Look_Driver ("slave_tmp.cgpr", Is_Config => True); Directories.Delete_File ("slave_tmp.cgpr"); -- Language is not found in the knowledge base, check the project -- to see if there is a definition for the language. if Driver = Key then Look_Driver (Project, Is_Config => False); -- Ensure that we have a full-path name declare Exe : OS_Lib.String_Access := Locate_Exec_On_Path (To_String (Driver)); begin Driver := To_Unbounded_String (Exe.all); Free (Exe); end; end if; -- Record this driver for the language and target into the cache Cache.Insert (Key, To_String (Driver)); -- Clean-up and free project structure if Debug then Put_Line ("# driver for " & Language & " is : " & To_String (Driver)); end if; return To_String (Driver); end if; exception when others => -- Be sure we never propagate an exception from this routine, in -- case of problem we just return the key, this will be used as an -- executable and will be reported to the master as a proper build -- failure. return Key; end Get_Driver; --------------------- -- Get_Output_File -- --------------------- function Get_Output_File (Builder : Build_Master) return String is Filename : constant String := "output.slave." & Image (Index); begin Index := Index + 1; return Compose (Work_Directory (Builder), Filename); end Get_Output_File; ------------------------ -- Output_Compilation -- ------------------------ procedure Output_Compilation (File : String) is RDL : constant Natural := Root_Directory'Length; begin if Verbose then if File'Length > RDL and then File (File'First .. File'First + RDL - 1) = Root_Directory.all then Text_IO.Put_Line ("Compiling: " & File (File'First + RDL + 1 .. File'Last)); else Text_IO.Put_Line ("Compiling: " & File); end if; end if; end Output_Compilation; Job : Job_Data; begin loop -- Launch a new compilation only if the maximum of simultaneous -- process has not yet been reached. Running.Wait_Slot; To_Run.Pop (Job); Process : declare Builder : constant Build_Master := Builders.Get (Job.Build_Sock); Dir : constant String := Args (Job.Cmd)(2).all; List : Slice_Set; Pid : Process_Id; begin -- Enter a critical section to: -- - move to directory where the command is executed -- - execute the compilation command -- - register a new job and acknowledge -- - move back to working directory Mutex.Seize; if Debug then Put_Line ("# move to work directory " & Work_Directory (Builder)); end if; Set_Directory (Work_Directory (Builder)); -- Create/Move to object dir if any, note that if we -- have an absolute path name here it is because the -- Build_Root is probably not properly set. Try to fail -- gracefully to report a proper error message to the -- build master. -- -- If we have an absolute pathname, just start the -- process into the to directory. The output file will -- be created there and will be reported to the master. -- -- Note that the following block should never fail otherwise the -- process won't be started. Even if we know the compilation will -- fail we need to move forward as the result for this compilation -- is waited for by the build master. begin if Dir /= "" then if not Is_Absolute_Path (Dir) and then not Is_Directory (Dir) then Create_Directory (Dir); end if; if Debug then Put_Line ("# move to directory " & Dir); end if; Set_Directory (Dir); end if; exception when others => if Debug then Put_Line ("# cannot move to object directory"); end if; end; Create (List, Args (Job.Cmd)(6).all, String'(1 => Opts_Sep)); Execute : declare Project : constant String := Get_Arg (Builder, Args (Job.Cmd)(1).all); Language : constant String := Args (Job.Cmd)(3).all; Out_File : constant String := Get_Output_File (Builder); Obj_File : constant String := Args (Job.Cmd)(4).all; Dep_File : constant String := Args (Job.Cmd)(5).all; Env : constant String := Get_Arg (Builder, Args (Job.Cmd) (7).all); O : Argument_List := Get_Args (Builder, List); begin Output_Compilation (O (O'Last).all); -- Set compiler environment Set_Env (Env, Fail => False, Force => True); Pid := Non_Blocking_Spawn (Get_Driver (Builder, Language, Project), O, Out_File); if Debug then Put_Line ("# pid" & Integer'Image (Pid_To_Integer (Pid))); Put_Line ("# dep_file " & Dep_File); Put_Line ("# out_file " & Out_File); Put_Line ("# obj_file " & Obj_File); end if; Job.Pid := Pid_To_Integer (Pid); Job.Dep_File := To_Unbounded_String (Dep_File); Job.Obj_File := To_Unbounded_String (Obj_File); Job.Output := To_Unbounded_String (Out_File); Job.Dep_Dir := To_Unbounded_String ((if Is_Absolute_Path (Dir) then "" else Dir)); Running.Register (Job); Mutex.Release; for K in O'Range loop Free (O (K)); end loop; end Execute; exception when E : others => Mutex.Release; if Debug then Put_Line ("# Error in Run_Compilation: " & Exception_Information (E)); end if; end Process; end loop; exception when E : others => Put_Line ("Unrecoverable error: Run_Compilation."); Put_Line (Exception_Information (E)); OS_Exit (1); end Run_Compilation; ------------- -- Running -- ------------- protected body Running is -------------- -- Register -- -------------- procedure Register (Job : Job_Data) is begin Set.Insert (Job); Count := Count + 1; end Register; --------- -- Get -- --------- procedure Get (Job : out Job_Data; Pid : Process_Id) is Pos : Job_Data_Set.Cursor; begin Job.Pid := Pid_To_Integer (Pid); Pos := Set.Find (Job); -- Not that a job could be not found here because the Pid is one of -- gprconfig runned to generate a configuration file for a specific -- language. if Job_Data_Set.Has_Element (Pos) then Job := Job_Data_Set.Element (Pos); Set.Delete (Job); Count := Count - 1; else Job := No_Job; end if; end Get; ------------- -- Set_Max -- ------------- procedure Set_Max (Max : Positive) is begin Running.Max := Max; end Set_Max; ---------- -- Wait -- ---------- entry Wait when Count > 0 is begin null; end Wait; --------------- -- Wait_Slot -- --------------- entry Wait_Slot when Count < Max is begin null; end Wait_Slot; end Running; ------------ -- To_Run -- ------------ protected body To_Run is ---------- -- Push -- ---------- procedure Push (Job : Job_Data) is begin Set.Append (Job); end Push; --------- -- Pop -- --------- entry Pop (Job : out Job_Data) when not Set.Is_Empty is begin Job := Set.First_Element; Set.Delete_First; end Pop; end To_Run; --------------------- -- Wait_Completion -- --------------------- task body Wait_Completion is Pid : Process_Id; Success : Boolean; Job : Job_Data; Builder : Build_Master; begin loop -- Wait for a job to complete only if there is job running Running.Wait; Wait_Process (Pid, Success); Mutex.Seize; Running.Get (Job, Pid); -- Note that if there is not such element it could be because the -- build master has been killed before the end of the compilation. -- In this case an EC message is received by the slave and the -- Job_Set is clear. See Main_Loop in gprslave's body. if Job /= No_Job then declare A : Argument_List_Access := Args (Job.Cmd); begin -- Free args for K in A'Range loop Free (A (K)); end loop; Free (A); end; -- Now get the corresponding build master Builder := Builders.Get (Job.Build_Sock); -- ???What to do if the builder is not found??? -- Enter a critical section to: -- - send atomic response to build master -- - make sure the current directory is the work directory begin if Debug then Put_Line ("# job " & Image (Job.Id) & " terminated"); end if; declare DS : Character renames Directory_Separator; Dep_Dir : constant String := To_String (Job.Dep_Dir); Dep_File : constant String := To_String (Job.Dep_File); Obj_File : constant String := To_String (Job.Obj_File); Out_File : constant String := To_String (Job.Output); S : Boolean; begin Send_Output (Builder.Channel, Out_File); OS_Lib.Delete_File (Out_File, S); if Success then -- No Dep_File to send back if the compilation was not -- successful. declare D_File : constant String := Work_Directory (Builder) & (if Dep_Dir /= "" then DS & Dep_Dir else "") & DS & Dep_File; begin if Exists (D_File) and then Kind (D_File) = Ordinary_File then Send_File (Builder.Channel, D_File, Rewrite => True); end if; end; declare O_File : constant String := Work_Directory (Builder) & (if Dep_Dir /= "" then DS & Dep_Dir else "") & DS & Obj_File; begin if Builder.Sync = Protocol.Gpr and then Exists (O_File) then Send_File (Builder.Channel, O_File, Rewrite => False); end if; end; end if; end; if Debug then Put_Line ("# compilation status " & Boolean'Image (Success)); end if; if Success then Send_Ok (Builder.Channel, Job.Id); else Send_Ko (Builder.Channel, Job.Id); end if; exception when E : others => -- An exception can be raised if the builder master has been -- terminated. In this case the comminication won't succeed. if Debug then Put_Line ("# cannot send response to build master " & Exception_Information (E)); end if; end; else -- This is not necessarily an error as we could get a Pid of a a -- gprconfig run launched to generate a configuration file for a -- specific language. So we do not want to fail in this case. if Debug then Put_Line ("# unknown job data for pid"); end if; end if; Mutex.Release; end loop; exception when E : others => Put_Line ("Unrecoverable error: Wait_Completion."); Put_Line (Exception_Information (E)); OS_Exit (1); end Wait_Completion; --------------------- -- Wait_For_Master -- --------------------- procedure Wait_For_Master is use Types; procedure Sync_Gpr (Builder : Build_Master); -------------- -- Sync_Gpr -- -------------- procedure Sync_Gpr (Builder : Build_Master) is use type Containers.Count_Type; procedure Set_Stamp (Path_Name : String; Time_Stamp : Time_Stamp_Type) with Inline; -- Set modification time stamp to the given file package Files is new Containers.Indefinite_Ordered_Sets (String); procedure Delete_Files (Except : Files.Set); -- Delete all files in the current working tree except those in -- Except set. --------------- -- Set_Stamp -- --------------- procedure Set_Stamp (Path_Name : String; Time_Stamp : Time_Stamp_Type) is TS : constant String := String (Time_Stamp); begin Set_File_Last_Modify_Time_Stamp (Path_Name, GM_Time_Of (Year => Year_Type'Value (TS (1 .. 4)), Month => Month_Type'Value (TS (5 .. 6)), Day => Day_Type'Value (TS (7 .. 8)), Hour => Hour_Type'Value (TS (9 .. 10)), Minute => Minute_Type'Value (TS (11 .. 12)), Second => Second_Type'Value (TS (13 .. 14)))); end Set_Stamp; ------------------ -- Delete_Files -- ------------------ procedure Delete_Files (Except : Files.Set) is procedure Process (Path : String); -- Search recursively the Path procedure Process (Path : String) is procedure Check (File : Directory_Entry_Type); -- Remove this file if not part of Except set ----------- -- Check -- ----------- procedure Check (File : Directory_Entry_Type) is S_Name : constant String := Simple_Name (File); Entry_Name : constant String := Path & Directory_Separator & S_Name; begin if Kind (File) = Directory then if S_Name not in "." | ".." and then not Is_Symbolic_Link (Entry_Name) then Process (Entry_Name); end if; else declare R_Name : constant String := (if Path = "." then "" else Path (Path'First + 2 .. Path'Last) & Directory_Separator) & S_Name; begin if not Except.Contains (R_Name) then if Debug then Put_Line ("# detele excluded '" & R_Name & '''); end if; Delete_File (R_Name); end if; end; end if; end Check; begin Search (Directory => Path, Pattern => "*", Filter => (Special_File => False, others => True), Process => Check'Access); end Process; begin Process ("."); end Delete_Files; Total_File : Natural := 0; Total_Transferred : Natural := 0; In_Master : Files.Set; begin Set_Directory (To_String (Builder.Project_Name)); Check_Time_Stamps : loop declare To_Sync : File_Data_Set.Vector; Cmd : Command; K : Positive := 1; begin Cmd := Get_Command (Builder.Channel); if Debug then Put ("# command: " & Command_Kind'Image (Kind (Cmd))); if Args (Cmd) /= null then for K in Args (Cmd)'Range loop Put (", " & Args (Cmd) (K).all); end loop; end if; New_Line; end if; if Kind (Cmd) = TS then -- Check all files in the argument of the command. This is a -- list of couple (filename and time stamp). Check_All_Files : loop Total_File := Total_File + 1; declare Path_Name : constant String := Args (Cmd) (K).all; TS : constant Time_Stamp_Type := Time_Stamp_Type (Args (Cmd) (K + 1).all); File_Stamp : Time_Stamp_Type; Exists : Boolean; begin if Directories.Exists (Path_Name) then File_Stamp := To_Time_Stamp (Modification_Time (Path_Name)); Exists := True; else Exists := False; end if; In_Master.Insert (Path_Name); if not Exists or else File_Stamp < TS then To_Sync.Append (File_Data' (To_Unbounded_String (Path_Name), TS, File_Stamp)); end if; end; K := K + 2; exit Check_All_Files when K > Args (Cmd)'Length; end loop Check_All_Files; -- If all files are up-to-data if To_Sync.Length = 0 then Send_Ok (Builder.Channel); else -- Some files are to be synchronized, send the list of -- names back to the master. Send_Ko (Builder.Channel, To_Sync); -- We then receive the files contents in the same order for W of To_Sync loop declare File : Stream_IO.File_Type; begin Create_Path (Containing_Directory (To_String (W.Path_Name))); Stream_IO.Create (File, Stream_IO.Out_File, To_String (W.Path_Name)); loop declare Data : constant Stream_Element_Array := Get_Raw_Data (Builder.Channel); begin exit when Data'Length = 0; Stream_IO.Write (File, Data); end; end loop; Stream_IO.Close (File); -- Set file time stamp Set_Stamp (To_String (W.Path_Name), W.Timestamp); end; end loop; Total_Transferred := Total_Transferred + Natural (To_Sync.Length); end if; elsif Kind (Cmd) = ES then -- Delete all files not part of the list sent by the master. -- This is needed to remove files in previous build removed -- since then on the master. Again we need to do that as we -- can't let around unnedded specs or bodies. Delete_Files (Except => In_Master); exit Check_Time_Stamps; end if; end; end loop Check_Time_Stamps; if Verbose then Put_Line ("Files total:" & Natural'Image (Total_File)); Put_Line (" transferred :" & Natural'Image (Total_Transferred)); end if; end Sync_Gpr; Builder : Build_Master; Clock_Status : Boolean; begin -- Wait for a connection Wait_Incoming_Master : loop begin Accept_Socket (Server, Builder.Socket, Address); exit Wait_Incoming_Master; exception when E : Socket_Error => if Resolve_Exception (E) /= Interrupted_System_Call then raise; end if; end; end loop Wait_Incoming_Master; Builder.Channel := Create (Builder.Socket); -- Initial handshake declare Master_Timestamp : Time_Stamp_Type; Version : Unbounded_String; begin Get_Context (Builder.Channel, Builder.Target, Builder.Project_Name, Builder.Build_Env, Builder.Sync, Master_Timestamp, Version); Clock_Status := Check_Diff (Master_Timestamp, UTC_Time); if To_String (Version) /= Gnat_Static_Version_String then if Verbose then Put_Line ("Reject non compatible build for " & To_String (Builder.Project_Name)); end if; Send_Ko (Builder.Channel); return; end if; exception when E : others => if Verbose then Put_Line (Exception_Information (E)); end if; -- Do not try to go further Send_Ko (Builder.Channel); return; end; Get_Targets_Set (Base, To_String (Builder.Target), Selected_Targets_Set); if Verbose then Put_Line ("Handling project : " & To_String (Builder.Project_Name)); Put_Line ("Compiling for : " & To_String (Builder.Target)); end if; Mutex.Seize; -- Move to root directory before creating a new project environment Set_Directory (Root_Directory.all); if not Exists (To_String (Builder.Build_Env)) then if Debug then Put_Line ("# create build environment directory '" & To_String (Builder.Build_Env) & "' in " & Current_Directory); end if; Create_Directory (To_String (Builder.Build_Env)); end if; Set_Directory (To_String (Builder.Build_Env)); if not Exists (To_String (Builder.Project_Name)) then if Debug then Put_Line ("# create project directory '" & To_String (Builder.Project_Name) & "' in " & Current_Directory); end if; Create_Directory (To_String (Builder.Project_Name)); end if; -- Configure slave, note that this does not need to be into the critical -- section has the builder is not yet known in the system. At this point -- no compilation can be received for this slave anyway. Set_Rewrite_WD (Builder.Channel, Path => Work_Directory (Builder)); -- For Ada compilers, rewrite the root directory if Debug then if Compiler_Path = null then Put_Line ("# compiler path is null."); else Put_Line ("# compiler path is : " & Containing_Directory (Containing_Directory (Compiler_Path.all))); end if; end if; if Compiler_Path /= null then Set_Rewrite_CD (Builder.Channel, Path => Containing_Directory (Containing_Directory (Compiler_Path.all))); end if; Send_Slave_Config (Builder.Channel, Max_Processes, Compose (Root_Directory.all, To_String (Builder.Build_Env)), Clock_Status); -- If we are using the Gpr synchronisation, it is time to do it here. -- Note that we want to avoid the rewriting rules below that are -- requiring some CPU cycles not needed at this stage. if Builder.Sync = Protocol.Gpr then -- Move to projet directory Sync_Gpr (Builder); end if; Mutex.Release; -- Register the new builder Builders.Insert (Builder); exception when E : others => Put_Line ("Unrecoverable error: Wait_For_Master."); Put_Line (Exception_Information (E)); OS_Exit (1); end Wait_For_Master; -------------------- -- Work_Directory -- -------------------- function Work_Directory (Builder : Build_Master) return String is begin return Compose (Compose (Root_Directory.all, To_String (Builder.Build_Env)), To_String (Builder.Project_Name)); end Work_Directory; begin Parse_Command_Line; -- Initialize the project support Namet.Initialize; Csets.Initialize; Snames.Initialize; Parse_Knowledge_Base (Base, Default_Knowledge_Base_Directory); -- Wait for a gprbuild connection on any addresses Address.Addr := Any_Inet_Addr; Address.Port := Port_Type (Port); Create_Socket (Server); Set_Socket_Option (Server, Socket_Level, (Reuse_Address, True)); Bind_Socket (Server, Address); if Port = 0 then Address := Get_Socket_Name (Server); end if; -- If verbose if Verbose then Put_Line ("gprslave on " & Host_Name & ":" & Image (Long_Integer (Address.Port))); Put_Line (" max processes :" & Integer'Image (Max_Processes)); Flush; end if; -- Initialize the host key used to create unique pid Slave_Id := Get_Slave_Id; if Debug then Put_Line ("# slave id " & Image (Slave_Id)); end if; Listen_Socket (Server); Main_Loop : loop Wait_For_Master; end loop Main_Loop; exception when E : others => Put_Line ("Unrecoverable error: GprSlave."); Put_Line (Exception_Information (E)); OS_Exit (1); end Gprslave; gprbuild-gpl-2014-src/src/gprbuild-main.adb0000644000076700001450000020530512323721731020131 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2011-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Command_Line; use Ada.Command_Line; with Ada.Directories; with Ada.Exceptions; use Ada.Exceptions; with System; with System.Case_Util; use System.Case_Util; with System.Multiprocessors; use System.Multiprocessors; with GNAT.Command_Line; use GNAT.Command_Line; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with Atree; use Atree; with Csets; with Debug; use Debug; with Gpr_Util; use Gpr_Util; with GPR_Version; use GPR_Version; with Hostparm; with Makeutl; use Makeutl; with Opt; use Opt; with Osint; use Osint; with Output; use Output; with Prj.Conf; use Prj.Conf; with Prj.Env; with Prj.Err; with Prj.Tree; use Prj.Tree; with Snames; use Snames; with Stringt; with Switch; use Switch; with Tempdir; use Tempdir; with Gprbuild.Compile; with Gprbuild.Link; with Gprbuild.Post_Compile; with Gprbuild.Compilation.Slave; procedure Gprbuild.Main is use Gpr_Util.Knowledge; There_Are_Restricted_Languages : Boolean := False; procedure Initialize; -- Do the necessary package intialization and process the command line -- arguments. procedure Usage; -- Display the usage function Add_Global_Switches (Switch : String; For_Lang : Name_Id; For_Builder : Boolean; Has_Global_Compilation_Switches : Boolean) return Boolean; -- Take into account a global switch (builder or global compilation switch) -- read from the project file. procedure Add_Mains_To_Queue; -- Check that each main is a single file name and that it is a source -- of a project from the tree. procedure Scan_Arg (Arg : String; Command_Line : Boolean; Language : Name_Id; Success : out Boolean); -- Process one gprbuild argument Arg. Command_Line is True if the argument -- is specified on the command line. Optional parameter Additional gives -- additional information about the origin of the argument if it is found -- illegal. procedure Add_Option (Arg : String; Command_Line : Boolean); -- Add a switch for a compiler or all compilers, or for the binder or for -- the linker. The table where this option is stored depends on the value -- of Current_Processor and other global variables. procedure Copyright; -- Output the Copyright notice type Sigint_Handler is access procedure; pragma Convention (C, Sigint_Handler); procedure Install_Int_Handler (Handler : Sigint_Handler); pragma Import (C, Install_Int_Handler, "__gnat_install_int_handler"); -- Called by Gnatmake to install the SIGINT handler below procedure Sigint_Intercepted; pragma Convention (C, Sigint_Intercepted); -- Called when the program is interrupted by Ctrl-C to delete the -- temporary mapping files and configuration pragmas files. No_Object_Check_Switch : constant String := "--no-object-check"; Direct_Import_Only_Switch : constant String := "--direct-import-only"; Indirect_Imports_Switch : constant String := "--indirect-imports"; No_Indirect_Imports_Switch : constant String := "--no-indirect-imports"; Current_Working_Dir : constant String := Get_Current_Dir; -- The current working directory type Processor is (None, Linker, Binder, Compiler); Current_Processor : Processor := None; -- This variable changes when switches -*args are used Current_Builder_Comp_Option_Table : Builder_Comp_Option_Table_Ref := No_Builder_Comp_Option_Table; ------------------------------------------- -- Options specified on the command line -- ------------------------------------------- package Options is type Option_Type is (Force_Compilations_Option, Keep_Going_Option, Maximum_Processes_Option, Quiet_Output_Option, Check_Switches_Option, Verbose_Mode_Option, Verbose_Low_Mode_Option, Verbose_Medium_Mode_Option, Warnings_Treat_As_Error, Warnings_Normal, Warnings_Suppress, Indirect_Imports); procedure Register_Command_Line_Option (Option : Option_Type; Value : Natural := 0); -- Record a command line option procedure Process_Command_Line_Options; -- Reprocess the recorded command line options that have priority over -- the options in package Builder of the main project. end Options; use Options; ------------------------ -- Add_Mains_To_Queue -- ------------------------ procedure Add_Mains_To_Queue is Main_Id : Main_Info; begin Mains.Reset; loop Main_Id := Mains.Next_Main; exit when Main_Id = No_Main_Info; if Main_Id.Source /= No_Source then -- Fail if any main is declared as an excluded source file if Main_Id.Source.Locally_Removed then Fail_Program (Project_Tree, "main """ & Get_Name_String (Main_Id.Source.File) & """ cannot also be an excluded file"); end if; if Is_Allowed_Language (Main_Id.Source.Language.Name) then Queue.Insert (Source => (Format => Format_Gprbuild, Tree => Main_Id.Tree, Id => Main_Id.Source), With_Roots => Builder_Data (Main_Id.Tree).Closure_Needed); -- If a non Ada main has no roots, then all sources need to be -- compiled, so no need to check for closure. if Main_Id.Source.Language.Config.Kind /= Unit_Based and then Main_Id.Source.Roots = null then Builder_Data (Main_Id.Tree).Closure_Needed := False; end if; end if; end if; end loop; if Total_Errors_Detected /= 0 then Fail_Program (Project_Tree, "cannot continue"); end if; Queue.Insert_Project_Sources (Project => Main_Project, Project_Tree => Project_Tree, Unique_Compile => Unique_Compile, All_Projects => not Unique_Compile or else (Unique_Compile_All_Projects or Recursive)); end Add_Mains_To_Queue; ------------------------- -- Add_Global_Switches -- ------------------------- function Add_Global_Switches (Switch : String; For_Lang : Name_Id; For_Builder : Boolean; Has_Global_Compilation_Switches : Boolean) return Boolean is Success : Boolean; begin if For_Builder then if Has_Global_Compilation_Switches then Builder_Switches_Lang := No_Name; else Builder_Switches_Lang := For_Lang; end if; Scan_Arg (Switch, Command_Line => False, Language => For_Lang, Success => Success); return Success; else Current_Processor := Compiler; Current_Builder_Comp_Option_Table := Builder_Compiling_Options_HTable.Get (For_Lang); if Current_Builder_Comp_Option_Table = No_Builder_Comp_Option_Table then Current_Builder_Comp_Option_Table := new Builder_Compiling_Options.Instance; Builder_Compiling_Options_HTable.Set (For_Lang, Current_Builder_Comp_Option_Table); Builder_Compiling_Options.Init (Current_Builder_Comp_Option_Table.all); end if; Add_Option (Switch, Command_Line => False); Current_Processor := None; return True; end if; end Add_Global_Switches; ---------------- -- Add_Option -- ---------------- procedure Add_Option (Arg : String; Command_Line : Boolean) is Option : String_Access := new String'(Arg); begin case Current_Processor is when None => null; when Linker => -- Add option to the linker table if Command_Line then Test_If_Relative_Path (Switch => Option, Parent => Current_Working_Dir, Including_Switch => Dash_L); else Test_If_Relative_Path (Switch => Option, Parent => Main_Project_Dir.all, Including_Switch => Dash_L); end if; Command_Line_Linker_Options.Append (Option); when Binder => if Command_Line then Test_If_Relative_Path (Switch => Option, Parent => Current_Working_Dir, Including_Switch => No_Name); else Test_If_Relative_Path (Switch => Option, Parent => Main_Project_Dir.all, Including_Switch => No_Name); end if; if Current_Bind_Option_Table = No_Bind_Option_Table then -- Option for all binder All_Language_Binder_Options.Append (Option); else -- Option for a single binder Binder_Options.Append (Current_Bind_Option_Table.all, Option); end if; when Compiler => if Command_Line then if Current_Comp_Option_Table = No_Comp_Option_Table then -- Option for all compilers All_Language_Compiling_Options.Append (Option); else -- Option for a single compiler Compiling_Options.Append (Current_Comp_Option_Table.all, Option); end if; else if Current_Builder_Comp_Option_Table = No_Builder_Comp_Option_Table then -- Option for all compilers All_Language_Builder_Compiling_Options.Append (Option); else -- Option for a single compiler Builder_Compiling_Options.Append (Current_Builder_Comp_Option_Table.all, Option); end if; end if; end case; end Add_Option; --------------- -- Copyright -- --------------- procedure Copyright is begin -- Only output the Copyright notice once if not Copyright_Output then Copyright_Output := True; Display_Version ("GPRBUILD", "2004", Version_String => Gpr_Version_String); end if; end Copyright; ------------- -- Options -- ------------- package body Options is type Option_Data is record Option : Option_Type; Value : Natural := 0; end record; package Command_Line_Options is new Table.Table (Table_Component_Type => Option_Data, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Makegpr.Opt.Command_Line_Options"); -- Table to store the command line options ---------------------------------- -- Process_Command_Line_Options -- ---------------------------------- procedure Process_Command_Line_Options is begin for Index in 1 .. Command_Line_Options.Last loop case Command_Line_Options.Table (Index).Option is when Force_Compilations_Option => Opt.Force_Compilations := True; when Keep_Going_Option => Opt.Keep_Going := True; when Maximum_Processes_Option => Opt.Maximum_Processes := Command_Line_Options.Table (Index).Value; when Quiet_Output_Option => Opt.Quiet_Output := True; Opt.Verbose_Mode := False; when Check_Switches_Option => Opt.Check_Switches := True; when Verbose_Mode_Option => Opt.Verbose_Mode := True; Opt.Verbosity_Level := Opt.High; Opt.Quiet_Output := False; when Verbose_Low_Mode_Option => Opt.Verbose_Mode := True; Opt.Verbosity_Level := Opt.Low; Opt.Quiet_Output := False; when Verbose_Medium_Mode_Option => Opt.Verbose_Mode := True; Opt.Verbosity_Level := Opt.Medium; Opt.Quiet_Output := False; when Warnings_Treat_As_Error => Opt.Warning_Mode := Opt.Treat_As_Error; when Warnings_Normal => Opt.Warning_Mode := Opt.Normal; when Warnings_Suppress => Opt.Warning_Mode := Opt.Suppress; when Indirect_Imports => Gprbuild.Indirect_Imports := Command_Line_Options.Table (Index).Value /= 0; end case; end loop; end Process_Command_Line_Options; ---------------------------------- -- Register_Command_Line_Option -- ---------------------------------- procedure Register_Command_Line_Option (Option : Option_Type; Value : Natural := 0) is begin Command_Line_Options.Increment_Last; Command_Line_Options.Table (Command_Line_Options.Last) := (Option => Option, Value => Value); end Register_Command_Line_Option; end Options; -------------- -- Scan_Arg -- -------------- procedure Scan_Arg (Arg : String; Command_Line : Boolean; Language : Name_Id; Success : out Boolean) is Processed : Boolean := True; procedure Forbidden_In_Package_Builder; -- Fail if switch Arg is found in package Builder ---------------------------------- -- Forbidden_In_Package_Builder -- ---------------------------------- procedure Forbidden_In_Package_Builder is begin if not Command_Line then Fail_Program (Project_Tree, Arg & " can only be used on the command line"); end if; end Forbidden_In_Package_Builder; begin pragma Assert (Arg'First = 1); Success := True; if Arg'Length = 0 then return; end if; -- If preceding switch was -P, a project file name need to be -- specified, not a switch. if Project_File_Name_Expected then if Arg (1) = '-' then Fail_Program (Project_Tree, "project file name missing after -P"); else Project_File_Name_Expected := False; Project_File_Name := new String'(Arg); end if; -- If preceding switch was -o, an executable name need to be -- specified, not a switch. elsif Output_File_Name_Expected then if Arg (1) = '-' then Fail_Program (Project_Tree, "output file name missing after -o"); else Output_File_Name_Expected := False; Output_File_Name := new String'(Arg); end if; elsif Search_Project_Dir_Expected then if Arg (1) = '-' then Fail_Program (Project_Tree, "directory name missing after -aP"); else Search_Project_Dir_Expected := False; Prj.Env.Add_Directories (Root_Environment.Project_Path, Arg); end if; elsif Db_Directory_Expected then Db_Directory_Expected := False; Parse_Knowledge_Base (Project_Tree, Arg); Name_Len := 0; Add_Str_To_Name_Buffer (Arg); Db_Switch_Args.Append (Name_Find); -- Set the processor/language for the following switches -- -cargs all compiler arguments elsif Arg = "-cargs" then Current_Processor := Compiler; if Command_Line then Current_Comp_Option_Table := No_Comp_Option_Table; else Current_Builder_Comp_Option_Table := No_Builder_Comp_Option_Table; end if; -- -cargs:lang arguments for compiler of language lang elsif Arg'Length > 7 and then Arg (1 .. 7) = "-cargs:" then Current_Processor := Compiler; Name_Len := 0; Add_Str_To_Name_Buffer (Arg (8 .. Arg'Last)); To_Lower (Name_Buffer (1 .. Name_Len)); declare Lang : constant Name_Id := Name_Find; begin if Command_Line then Current_Comp_Option_Table := Compiling_Options_HTable.Get (Lang); if Current_Comp_Option_Table = No_Comp_Option_Table then Current_Comp_Option_Table := new Compiling_Options.Instance; Compiling_Options_HTable.Set (Lang, Current_Comp_Option_Table); Compiling_Options.Init (Current_Comp_Option_Table.all); end if; else Current_Builder_Comp_Option_Table := Builder_Compiling_Options_HTable.Get (Lang); if Current_Builder_Comp_Option_Table = No_Builder_Comp_Option_Table then Current_Builder_Comp_Option_Table := new Builder_Compiling_Options.Instance; Builder_Compiling_Options_HTable.Set (Lang, Current_Builder_Comp_Option_Table); Builder_Compiling_Options.Init (Current_Builder_Comp_Option_Table.all); end if; end if; end; -- -bargs all binder arguments elsif Arg = "-bargs" then Current_Processor := Binder; Current_Bind_Option_Table := No_Bind_Option_Table; -- -bargs:lang arguments for binder of language lang elsif Arg'Length > 7 and then Arg (1 .. 7) = "-bargs:" then Current_Processor := Binder; Name_Len := 0; Add_Str_To_Name_Buffer (Arg (8 .. Arg'Last)); To_Lower (Name_Buffer (1 .. Name_Len)); declare Lang : constant Name_Id := Name_Find; begin Current_Bind_Option_Table := Binder_Options_HTable.Get (Lang); if Current_Bind_Option_Table = No_Bind_Option_Table then Current_Bind_Option_Table := new Binder_Options.Instance; Binder_Options_HTable.Set (Lang, Current_Bind_Option_Table); Binder_Options.Init (Current_Bind_Option_Table.all); end if; end; -- -largs linker arguments elsif Arg = "-largs" then Current_Processor := Linker; -- -gargs/margs options directly for gprbuild -- support -margs for compatibility with gnatmake elsif Arg = "-gargs" or else Arg = "-margs" then Current_Processor := None; -- A special test is needed for the -o switch within a -largs since -- that is another way to specify the name of the final executable. elsif Command_Line and then Current_Processor = Linker and then Arg = "-o" then Fail_Program (Project_Tree, "switch -o not allowed within a -largs. Use -o directly."); -- If current processor is not gprbuild directly, store the option -- in the appropriate table. elsif Current_Processor /= None then Add_Option (Arg, Command_Line); -- Switches start with '-' elsif Arg (1) = '-' then if Arg'Length > Distributed_Option'Length and then Arg (1 .. Distributed_Option'Length) = Distributed_Option then Distributed_Mode := True; -- In distributed mode we do not want to use temp directories Use_Temp_Dir (Status => False); Compilation.Slave.Record_Slaves (Arg (Distributed_Option'Length + 1 .. Arg'Last)); elsif Arg'Length >= Slave_Env_Option'Length and then Arg (1 .. Slave_Env_Option'Length) = Slave_Env_Option then if Arg = Slave_Env_Option then -- Just --slave-env, it is up to gprbuild to build a sensible -- slave environment value. Slave_Env_Auto := True; else Slave_Env := new String'(Arg (Slave_Env_Option'Length + 2 .. Arg'Last)); end if; elsif Arg = "--db-" then if Hostparm.OpenVMS then Fail_Program (Project_Tree, "--db- cannot be used on VMS"); end if; Forbidden_In_Package_Builder; Load_Standard_Base := False; elsif Arg = "--db" then if Hostparm.OpenVMS then Fail_Program (Project_Tree, "--db cannot be used on VMS"); end if; Forbidden_In_Package_Builder; Db_Directory_Expected := True; elsif Arg = "--display-paths" then Forbidden_In_Package_Builder; Display_Paths := True; elsif Arg = "--no-split-units" then Opt.No_Split_Units := True; elsif Arg = Single_Compile_Per_Obj_Dir_Switch then Opt.One_Compilation_Per_Obj_Dir := True; elsif Arg'Length > Source_Info_Option'Length and then Arg (1 .. Source_Info_Option'Length) = Source_Info_Option then Forbidden_In_Package_Builder; Project_Tree.Source_Info_File_Name := new String'(Arg (Source_Info_Option'Length + 1 .. Arg'Last)); elsif Arg'Length > Config_Project_Option'Length and then Arg (1 .. Config_Project_Option'Length) = Config_Project_Option then if Config_Project_File_Name /= null and then (Autoconf_Specified or else Config_Project_File_Name.all /= Arg (Config_Project_Option'Length + 1 .. Arg'Last)) then Fail_Program (Project_Tree, "several different configuration switches " & "cannot be specified"); else Autoconfiguration := False; Autoconf_Specified := False; Config_Project_File_Name := new String' (Arg (Config_Project_Option'Length + 1 .. Arg'Last)); end if; elsif Arg'Length > Autoconf_Project_Option'Length and then Arg (1 .. Autoconf_Project_Option'Length) = Autoconf_Project_Option then if Hostparm.OpenVMS then Fail_Program (Project_Tree, Autoconf_Project_Option & " cannot be used on VMS"); end if; Forbidden_In_Package_Builder; if Config_Project_File_Name /= null and then (not Autoconf_Specified or else Config_Project_File_Name.all /= Arg (Autoconf_Project_Option'Length + 1 .. Arg'Last)) then Fail_Program (Project_Tree, "several different configuration switches " & "cannot be specified"); else Config_Project_File_Name := new String' (Arg (Autoconf_Project_Option'Length + 1 .. Arg'Last)); Autoconf_Specified := True; end if; elsif Arg'Length > Target_Project_Option'Length and then Arg (1 .. Target_Project_Option'Length) = Target_Project_Option then if Hostparm.OpenVMS then Fail_Program (Project_Tree, Target_Project_Option & " cannot be used on VMS"); end if; Forbidden_In_Package_Builder; if Target_Name /= null then if Target_Name.all /= Arg (Target_Project_Option'Length + 1 .. Arg'Last) then Fail_Program (Project_Tree, "several different target switches cannot be specified"); end if; else Target_Name := new String' (Arg (Target_Project_Option'Length + 1 .. Arg'Last)); end if; elsif Arg'Length > RTS_Option'Length and then Arg (1 .. RTS_Option'Length) = RTS_Option then declare Set : constant Boolean := Runtime_Name_Set_For (Name_Ada); Old : constant String := Runtime_Name_For (Name_Ada); RTS : constant String := Arg (RTS_Option'Length + 1 .. Arg'Last); begin if Command_Line then if Set and then Old /= RTS then Fail_Program (Project_Tree, "several different run-times cannot be specified"); end if; Set_Runtime_For (Name_Ada, RTS); end if; -- Ignore any --RTS= switch in package Builder. These are only -- taken into account to create the config file in -- auto-configuration. end; elsif Arg'Length > RTS_Language_Option'Length and then Arg (1 .. RTS_Language_Option'Length) = RTS_Language_Option then declare Language_Name : Name_Id := No_Name; RTS_Start : Natural := Arg'Last + 1; begin for J in RTS_Language_Option'Length + 2 .. Arg'Last loop if Arg (J) = '=' then Name_Len := 0; Add_Str_To_Name_Buffer (Arg (RTS_Language_Option'Length + 1 .. J - 1)); To_Lower (Name_Buffer (1 .. Name_Len)); Language_Name := Name_Find; RTS_Start := J + 1; exit; end if; end loop; if Language_Name = No_Name then Fail_Program (Project_Tree, "illegal switch: " & Arg); elsif Command_Line then -- Ignore any --RTS:= switch in package Builder. These -- are only taken into account to create the config file in -- auto-configuration. declare RTS : constant String := Arg (RTS_Start .. Arg'Last); Set : constant Boolean := Runtime_Name_Set_For (Language_Name); Old : constant String := Runtime_Name_For (Language_Name); begin if Set and then Old /= RTS then Fail_Program (Project_Tree, "several different run-times cannot be specified" & " for the same language"); else Set_Runtime_For (Language_Name, RTS); end if; end; end if; end; elsif Arg'Length > Subdirs_Option'Length and then Arg (1 .. Subdirs_Option'Length) = Subdirs_Option then Forbidden_In_Package_Builder; Subdirs := new String'(Arg (Subdirs_Option'Length + 1 .. Arg'Last)); elsif Command_Line and then Arg'Length > Restricted_To_Languages_Option'Length and then Arg (1 .. Restricted_To_Languages_Option'Length) = Restricted_To_Languages_Option then declare Start : Positive := Restricted_To_Languages_Option'Length + 1; Finish : Positive; begin Processed := False; while Start <= Arg'Last loop Finish := Start; loop exit when Finish > Arg'Last or else Arg (Finish) = ','; Finish := Finish + 1; end loop; if Finish > Start then Add_Restricted_Language (Arg (Start .. Finish - 1)); Processed := True; There_Are_Restricted_Languages := True; end if; Start := Finish + 1; end loop; end; elsif Arg = Indirect_Imports_Switch then Indirect_Imports := True; if Command_Line then Register_Command_Line_Option (Options.Indirect_Imports, 1); end if; elsif Arg = No_Indirect_Imports_Switch or else Arg = Direct_Import_Only_Switch then Indirect_Imports := False; if Command_Line then Register_Command_Line_Option (Options.Indirect_Imports, 0); end if; elsif Arg = Makeutl.Unchecked_Shared_Lib_Imports then Forbidden_In_Package_Builder; Opt.Unchecked_Shared_Lib_Imports := True; elsif Arg = No_Object_Check_Switch then Object_Checked := False; elsif Arg = "--codepeer" then Forbidden_In_Package_Builder; if not CodePeer_Mode then CodePeer_Mode := True; Object_Checked := False; Target_Name := new String'("codepeer"); if Subdirs = null then Subdirs := new String'("codepeer"); end if; end if; elsif Arg = Create_Map_File_Switch then Map_File := new String'(""); elsif Arg'Length > Create_Map_File_Switch'Length + 1 and then Arg (1 .. Create_Map_File_Switch'Length) = Create_Map_File_Switch and then Arg (Create_Map_File_Switch'Length + 1) = '=' then Map_File := new String'(Arg (Create_Map_File_Switch'Length + 2 .. Arg'Last)); elsif Arg'Length >= 3 and then Arg (1 .. 3) = "-aP" then Forbidden_In_Package_Builder; if Arg'Length = 3 then Search_Project_Dir_Expected := True; else Prj.Env.Add_Directories (Root_Environment.Project_Path, Arg (4 .. Arg'Last)); end if; elsif Arg = "-b" then Opt.Bind_Only := True; elsif Arg = "-c" then Opt.Compile_Only := True; if Opt.Link_Only then Opt.Bind_Only := True; end if; elsif Arg = "-C" then -- This switch is only for upward compatibility null; elsif Arg = "-d" then Opt.Display_Compilation_Progress := True; elsif Arg'Length = 3 and then Arg (2) = 'd' then if Arg (3) in '1' .. '9' or else Arg (3) in 'a' .. 'z' or else Arg (3) in 'A' .. 'Z' then Set_Debug_Flag (Arg (3)); else Fail_Program (Project_Tree, "illegal debug switch " & Arg); end if; elsif Arg'Length > 3 and then Arg (1 .. 3) = "-eI" then Forbidden_In_Package_Builder; begin Main_Index := Int'Value (Arg (4 .. Arg'Last)); exception when Constraint_Error => Fail_Program (Project_Tree, "invalid switch " & Arg); end; elsif Arg = "-eL" then Forbidden_In_Package_Builder; Opt.Follow_Links_For_Files := True; Opt.Follow_Links_For_Dirs := True; elsif Arg = "-eS" then Forbidden_In_Package_Builder; -- Accept switch for compatibility with gnatmake Opt.Commands_To_Stdout := True; elsif Arg = "-f" then Opt.Force_Compilations := True; if Command_Line then Register_Command_Line_Option (Force_Compilations_Option); end if; elsif Arg = "-F" then Forbidden_In_Package_Builder; Opt.Full_Path_Name_For_Brief_Errors := True; elsif Arg = "-h" then Forbidden_In_Package_Builder; Usage_Needed := True; elsif Arg'Length > 2 and then Arg (2) = 'j' then declare Max_Proc : Natural := 0; begin for J in 3 .. Arg'Length loop if Arg (J) in '0' .. '9' then Max_Proc := (Max_Proc * 10) + Character'Pos (Arg (J)) - Character'Pos ('0'); else Processed := False; end if; end loop; if Processed then if Max_Proc = 0 then Max_Proc := Natural (Number_Of_CPUs); end if; if Max_Proc = 0 then Max_Proc := 1; end if; Opt.Maximum_Processes := Max_Proc; end if; end; if Processed and then Command_Line then Register_Command_Line_Option (Maximum_Processes_Option, Opt.Maximum_Processes); end if; elsif Arg = "-k" then Opt.Keep_Going := True; if Command_Line then Register_Command_Line_Option (Keep_Going_Option); end if; elsif Arg = "-l" then Opt.Link_Only := True; if Opt.Compile_Only then Opt.Bind_Only := True; end if; elsif Arg = "-m" then Opt.Minimal_Recompilation := True; elsif Arg = "-o" then Forbidden_In_Package_Builder; if Output_File_Name /= null then Fail_Program (Project_Tree, "cannot specify several -o switches"); else Output_File_Name_Expected := True; end if; elsif Arg = "-p" or else Arg = "--create-missing-dirs" then Forbidden_In_Package_Builder; Opt.Setup_Projects := True; elsif Arg'Length >= 2 and then Arg (2) = 'P' then Forbidden_In_Package_Builder; if Project_File_Name /= null then Fail_Program (Project_Tree, "cannot have several project files specified"); elsif Arg'Length = 2 then Project_File_Name_Expected := True; else Project_File_Name := new String'(Arg (3 .. Arg'Last)); end if; elsif Arg = "-q" then Opt.Quiet_Output := True; Opt.Verbose_Mode := False; if Command_Line then Register_Command_Line_Option (Quiet_Output_Option); end if; elsif Arg = "-r" then Forbidden_In_Package_Builder; Recursive := True; elsif Arg = "-R" then Opt.Run_Path_Option := False; elsif Arg = "-s" then Opt.Check_Switches := True; if Command_Line then Register_Command_Line_Option (Check_Switches_Option); end if; elsif Arg = "-u" then Forbidden_In_Package_Builder; Unique_Compile := True; elsif Arg = "-U" then Forbidden_In_Package_Builder; Unique_Compile_All_Projects := True; Unique_Compile := True; elsif Arg = "-v" or else Arg = "-vh" then Opt.Verbose_Mode := True; Opt.Verbosity_Level := Opt.High; Opt.Quiet_Output := False; if Command_Line then Register_Command_Line_Option (Verbose_Mode_Option); end if; elsif Arg = "-vl" then Opt.Verbose_Mode := True; Opt.Verbosity_Level := Opt.Low; Opt.Quiet_Output := False; if Command_Line then Register_Command_Line_Option (Verbose_Low_Mode_Option); end if; elsif Arg = "-vm" then Opt.Verbose_Mode := True; Opt.Verbosity_Level := Opt.Medium; Opt.Quiet_Output := False; if Command_Line then Register_Command_Line_Option (Verbose_Medium_Mode_Option); end if; elsif Arg'Length >= 3 and then Arg (1 .. 3) = "-vP" then Forbidden_In_Package_Builder; if Arg'Length = 4 and then Arg (4) in '0' .. '2' then case Arg (4) is when '0' => Current_Verbosity := Prj.Default; when '1' => Current_Verbosity := Prj.Medium; when '2' => Current_Verbosity := Prj.High; when others => null; end case; else Fail_Program (Project_Tree, "invalid verbosity level " & Arg (4 .. Arg'Last)); end if; elsif Arg = "-we" then Opt.Warning_Mode := Opt.Treat_As_Error; if Command_Line then Register_Command_Line_Option (Warnings_Treat_As_Error); end if; elsif Arg = "-wn" then Opt.Warning_Mode := Opt.Normal; if Command_Line then Register_Command_Line_Option (Warnings_Normal); end if; elsif Arg = "-ws" then Opt.Warning_Mode := Opt.Suppress; if Command_Line then Register_Command_Line_Option (Warnings_Suppress); end if; elsif Arg = "-x" then Opt.Use_Include_Path_File := True; elsif Arg'Length >= 3 and then Arg (2) = 'X' and then Is_External_Assignment (Root_Environment, Arg) then Forbidden_In_Package_Builder; -- Is_External_Assignment has side effects when it returns True null; elsif (Language = No_Name or else Language = Name_Ada) and then (not Command_Line) and then Arg = "-x" then -- For compatibility with gnatmake, ignore -x if found in the -- Builder switches. null; elsif (Language = No_Name or else Language = Name_Ada) and then (Arg = "-fstack-check" or else Arg = "-fno-inline" or else (Arg'Length >= 2 and then (Arg (2) = 'O' or else Arg (2) = 'g'))) then -- For compatibility with gnatmake, use switch to compile Ada -- code. if Command_Line then Current_Comp_Option_Table := Compiling_Options_HTable.Get (Name_Ada); if Current_Comp_Option_Table = No_Comp_Option_Table then Current_Comp_Option_Table := new Compiling_Options.Instance; Compiling_Options_HTable.Set (Name_Ada, Current_Comp_Option_Table); Compiling_Options.Init (Current_Comp_Option_Table.all); end if; else Current_Builder_Comp_Option_Table := Builder_Compiling_Options_HTable.Get (Name_Ada); if Current_Builder_Comp_Option_Table = No_Builder_Comp_Option_Table then Current_Builder_Comp_Option_Table := new Builder_Compiling_Options.Instance; Builder_Compiling_Options_HTable.Set (Name_Ada, Current_Builder_Comp_Option_Table); Builder_Compiling_Options.Init (Current_Builder_Comp_Option_Table.all); end if; end if; Current_Processor := Compiler; Add_Option (Arg, Command_Line); Current_Processor := None; elsif (Language = No_Name or else Language = Name_Ada) and then (Arg = "-nostdlib" or else Arg = "-nostdinc") then -- For compatibility with gnatmake, use switch to bind Ada code -- code and for -nostdlib to link. Current_Bind_Option_Table := Binder_Options_HTable.Get (Name_Ada); if Current_Bind_Option_Table = No_Bind_Option_Table then Current_Bind_Option_Table := new Binder_Options.Instance; Binder_Options_HTable.Set (Name_Ada, Current_Bind_Option_Table); Binder_Options.Init (Current_Bind_Option_Table.all); end if; Current_Processor := Binder; Add_Option (Arg, Command_Line); -- For -nostdlib, use the switch to link too if Arg = "-nostdlib" then Current_Processor := Linker; Add_Option (Arg, Command_Line); end if; Current_Processor := None; else Processed := False; end if; elsif Command_Line then -- The file name of a main or a project file declare File_Name : String := Arg; begin Canonical_Case_File_Name (File_Name); if File_Name'Length > Project_File_Extension'Length and then File_Name (File_Name'Last - Project_File_Extension'Length + 1 .. File_Name'Last) = Project_File_Extension then if Project_File_Name /= null then Fail_Program (Project_Tree, "cannot have several project files specified"); else Project_File_Name := new String'(File_Name); end if; else -- Not a project file, then it is a main Mains.Add_Main (Arg); Always_Compile := True; end if; end; else Processed := False; end if; if not Processed then if Command_Line then Fail_Program (Project_Tree, "illegal option """ & Arg & """ on the command line"); else -- If we have a switch and there is a Builder Switches language -- set, pass this switch to the compiler of the language. if Arg (1) = '-' and then Builder_Switches_Lang /= No_Name then Current_Builder_Comp_Option_Table := Builder_Compiling_Options_HTable.Get (Builder_Switches_Lang); if Current_Builder_Comp_Option_Table = No_Builder_Comp_Option_Table then Current_Builder_Comp_Option_Table := new Builder_Compiling_Options.Instance; Builder_Compiling_Options_HTable.Set (Builder_Switches_Lang, Current_Builder_Comp_Option_Table); Builder_Compiling_Options.Init (Current_Builder_Comp_Option_Table.all); end if; Current_Processor := Compiler; Add_Option (Arg, False); Current_Processor := None; else Success := False; end if; end if; end if; end Scan_Arg; ------------------------ -- Sigint_Intercepted -- ------------------------ procedure Sigint_Intercepted is begin Write_Line ("*** Interrupted ***"); Delete_All_Temp_Files (Project_Tree.Shared); if Distributed_Mode then Compilation.Slave.Unregister_Remote_Slaves; end if; OS_Exit (1); end Sigint_Intercepted; ---------------- -- Initialize -- ---------------- procedure Initialize is procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage); begin -- Do some necessary package initializations Csets.Initialize; Namet.Initialize; Snames.Initialize; Stringt.Initialize; Prj.Tree.Initialize (Root_Environment, Gprbuild_Flags); Prj.Tree.Initialize (Project_Node_Tree); Prj.Initialize (Project_Tree); Mains.Delete; -- Get the name id for "-L"; Name_Len := 0; Add_Str_To_Name_Buffer ("-L"); Dash_L := Name_Find; -- Get the command line arguments, starting with --version and --help Check_Version_And_Help ("GPRBUILD", "2004", Version_String => Gpr_Version_String); -- Now process the other options Autoconfiguration := True; declare Do_Not_Care : Boolean; begin Scan_Args : for Next_Arg in 1 .. Argument_Count loop Scan_Arg (Argument (Next_Arg), Command_Line => True, Language => No_Name, Success => Do_Not_Care); end loop Scan_Args; end; if CodePeer_Mode then if There_Are_Restricted_Languages then Remove_All_Restricted_Languages; end if; Add_Restricted_Language ("ada"); Opt.Link_Only := False; if not Opt.Compile_Only and not Opt.Bind_Only then Opt.Compile_Only := True; Opt.Bind_Only := True; end if; elsif There_Are_Restricted_Languages then Opt.Compile_Only := True; Opt.Bind_Only := False; Opt.Link_Only := False; end if; Mains.Set_Multi_Unit_Index (Project_Tree, Main_Index); Current_Processor := None; -- Target_Name has potentially been set when calling Scan_Arg, so we can -- only initialize the project path after parsing the command line -- arguments. if Target_Name = null then Prj.Env.Initialize_Default_Project_Path (Root_Environment.Project_Path, Target_Name => ""); else Prj.Env.Initialize_Default_Project_Path (Root_Environment.Project_Path, Target_Name.all); end if; -- If --display-paths was specified, display the config and the user -- project paths and exit. if Display_Paths then Write_Char ('.'); declare Prefix_Path : constant String := Executable_Prefix_Path; P : String_Access; begin if Prefix_Path'Length /= 0 then Write_Char (Path_Separator); Write_Str (Prefix_Path); Write_Str ("share"); Write_Char (Directory_Separator); Write_Str ("gpr"); end if; Write_Eol; Prj.Env.Get_Path (Root_Environment.Project_Path, Path => P); Write_Line (P.all); Exit_Program (E_Success); end; end if; if Opt.Verbose_Mode then Copyright; end if; if Usage_Needed then Usage; Usage_Needed := False; end if; -- Fail if command line ended with "-P" if Project_File_Name_Expected then Fail_Program (Project_Tree, "project file name missing after -P"); -- Or if it ended with "-o" elsif Output_File_Name_Expected then Fail_Program (Project_Tree, "output file name missing after -o"); -- Or if it ended with "-aP" elsif Search_Project_Dir_Expected then Fail_Program (Project_Tree, "directory name missing after -aP"); elsif Db_Directory_Expected then Fail_Program (Project_Tree, "directory name missing after --db"); elsif Slave_Env /= null and then not Distributed_Mode then Fail_Program (Project_Tree, "cannot use --slave-env in non distributed mode"); end if; -- Makes the Ada RTS is absolute if it is not a base name if Runtime_Name_Set_For (Name_Ada) then Locate_Runtime (Project_Tree, Name_Ada); end if; if Load_Standard_Base then -- We need to parse the knowledge base so that we are able to -- normalize the target names. Unfortunately, if we have to spawn -- gprconfig, it will also have to parse that knowledge base on -- its own. Parse_Knowledge_Base (Project_Tree); end if; -- If no project file is specified, look for a default if Project_File_Name = null then Look_For_Default_Project; else No_Project_File_Found := False; end if; if Project_File_Name = null then Try_Help; Fail_Program (Project_Tree, "no project file specified and no default project file"); end if; end Initialize; ----------- -- Usage -- ----------- procedure Usage is begin if not Usage_Output then Usage_Output := True; Write_Str ("Usage: "); Osint.Write_Program_Name; Write_Str (" [-P] [.gpr] [opts] [name]"); Write_Eol; Write_Str (" {[-cargs opts] [-cargs:lang opts] [-largs opts]" & " [-gargs opts]}"); Write_Eol; Write_Eol; Write_Str (" name is zero or more file names"); Write_Eol; Write_Eol; -- GPRBUILD switches Write_Str ("gprbuild switches:"); Write_Eol; Display_Usage_Version_And_Help; -- Line for --distributed Write_Str (" --distributed=slave1[,slave2]"); Write_Eol; Write_Str (" Activate the remote/distributed compilations"); Write_Eol; -- Line for --slave-env Write_Str (" --slave-env[=name]"); Write_Eol; Write_Str (" Use a specific slave's environment"); Write_Eol; -- Line for Config_Project_Option Write_Str (" "); Write_Str (Config_Project_Option); Write_Str ("file.cgpr"); Write_Eol; Write_Str (" Specify the main config project file name"); Write_Eol; -- Line for Autoconf_Project_Option if not Hostparm.OpenVMS then Write_Str (" "); Write_Str (Autoconf_Project_Option); Write_Str ("file.cgpr"); Write_Eol; Write_Str (" Specify/create the main config project file name"); Write_Eol; end if; -- Line for Target_Project_Option if not Hostparm.OpenVMS then Write_Str (" "); Write_Str (Target_Project_Option); Write_Str ("targetname"); Write_Eol; Write_Str (" Specify a target for cross platforms"); Write_Eol; end if; -- Line for --db if not Hostparm.OpenVMS then Write_Str (" --db dir Parse dir as an additional knowledge base"); Write_Eol; end if; -- Line for --db- if not Hostparm.OpenVMS then Write_Str (" --db- Do not load the standard knowledge base"); Write_Eol; end if; -- Line for --subdirs= Write_Str (" --subdirs=dir"); Write_Eol; Write_Str (" Real obj/lib/exec dirs are subdirs"); Write_Eol; -- Line for --single-compile-per-obj-dir Write_Str (" "); Write_Str (Single_Compile_Per_Obj_Dir_Switch); Write_Eol; Write_Str (" No simultaneous compilations for the same obj dir"); Write_Eol; Write_Str (" "); Write_Str (No_Indirect_Imports_Switch); Write_Eol; Write_Str (" Sources can import only from directly imported " & "projects"); Write_Eol; Write_Str (" "); Write_Str (Indirect_Imports_Switch); Write_Eol; Write_Str (" Sources can import from directly and indirectly " & "imported projects"); Write_Eol; Write_Str (" --RTS="); Write_Eol; Write_Str (" Use runtime for language Ada"); Write_Eol; Write_Str (" --RTS:="); Write_Eol; Write_Str (" Use runtime for language "); Write_Eol; Write_Str (" "); Write_Str (Makeutl.Unchecked_Shared_Lib_Imports); Write_Eol; Write_Str (" Shared lib projects may import any project"); Write_Eol; Write_Str (" "); Write_Str (No_Object_Check_Switch); Write_Eol; Write_Str (" Do not check object files"); Write_Eol; Write_Str (" "); Write_Str (Restricted_To_Languages_Option); Write_Str (""); Write_Eol; Write_Str (" Restrict the languages of the sources"); Write_Eol; Write_Eol; Write_Str (" "); Write_Str (Create_Map_File_Switch); Write_Eol; Write_Str (" Create map file mainprog.map"); Write_Eol; Write_Str (" "); Write_Str (Create_Map_File_Switch); Write_Str ("=mapfile"); Write_Eol; Write_Str (" Create map file mapfile"); Write_Eol; Write_Eol; -- Line for -aP Write_Str (" -aP dir Add directory dir to project search path"); Write_Eol; -- Line for -b Write_Str (" -b Bind only"); Write_Eol; -- Line for -c Write_Str (" -c Compile only"); Write_Eol; -- Line for -d Write_Str (" -d Display compilation progress"); Write_Eol; -- Line for -eInn Write_Str (" -eInn Index of main unit in multi-unit source file"); Write_Eol; -- Line for -eL Write_Str (" -eL " & "Follow symbolic links when processing project files"); Write_Eol; -- Line for -eS Write_Str (" -eS " & "(no action, for compatibility with gnatmake only)"); Write_Eol; -- Line for -f Write_Str (" -f Force recompilations"); Write_Eol; -- Line for -F Write_Str (" -F Full project path name in brief error messages"); Write_Eol; -- Line for -jnnn Write_Str (" -jnum Use num processes to compile"); Write_Eol; -- Line for -k Write_Str (" -k Keep going after compilation errors"); Write_Eol; -- Line for -l Write_Str (" -l Link only"); Write_Eol; -- Line for -m Write_Str (" -m Minimum Ada recompilation"); Write_Eol; -- Line for -o Write_Str (" -o name Choose an alternate executable name"); Write_Eol; -- Line for -p Write_Str (" -p Create missing obj, lib and exec dirs"); Write_Eol; -- Line for -P Write_Str (" -P proj Use Project File proj"); Write_Eol; -- Line for -q Write_Str (" -q Be quiet/terse"); Write_Eol; -- Line for -r Write_Str (" -r Recursive (default except when using -c)"); Write_Eol; -- Line for -R Write_Str (" -R Do not use run path option"); Write_Eol; -- Line for -s Write_Str (" -s Recompile if compiler switches have changed"); Write_Eol; -- Line for -u Write_Str (" -u Unique compilation, only compile the given files"); Write_Eol; -- Line for -U Write_Str (" -U Unique compilation for all sources of all projects"); Write_Eol; -- Line for -v Write_Str (" -v Verbose output"); Write_Eol; -- Line for -vl Write_Str (" -vl Verbose output (low verbosity)"); Write_Eol; -- Line for -vm Write_Str (" -vm Verbose output (medium verbosity)"); Write_Eol; -- Line for -vh Write_Str (" -vh Verbose output (high verbosity)"); Write_Eol; -- Line for -vPx Write_Str (" -vPx Specify verbosity when parsing Project Files" & " (x = 0/1/2)"); Write_Eol; -- Line for -we Write_Str (" -we Treat all warnings as errors"); Write_Eol; -- Line for -wn Write_Str (" -wn Treat warnings as warnings"); Write_Eol; -- Line for -ws Write_Str (" -ws Suppress all warnings"); Write_Eol; -- Line for -x Write_Str (" -x Always create include path file"); Write_Eol; -- Line for -X Write_Str (" -Xnm=val Specify an external reference for " & "Project Files"); Write_Eol; Write_Eol; -- Line for -cargs Write_Line (" -cargs opts opts are passed to all compilers"); -- Line for -cargs:lang Write_Line (" -cargs: opts"); Write_Line (" opts are passed to the compiler " & "for language "); -- Line for -bargs Write_Line (" -bargs opts opts are passed to all binders"); -- Line for -cargs:lang Write_Line (" -bargs: opts"); Write_Line (" opts are passed to the binder " & "for language "); -- Line for -largs Write_Str (" -largs opts opts are passed to the linker"); Write_Eol; -- Line for -gargs Write_Str (" -gargs opts opts directly interpreted by gprbuild"); Write_Eol; -- Line for -margs Write_Str (" -margs opts equivalent to -gargs opts"); Write_Eol; Write_Eol; Write_Str ("For compatibility with gnatmake, these switches are passed " & "to the Ada compiler:"); Write_Eol; Write_Str (" -nostdlib"); Write_Eol; Write_Str (" -nostdinc"); Write_Eol; Write_Str (" -fstack-check"); Write_Eol; Write_Str (" -fno-inline"); Write_Eol; Write_Str (" -gxxx"); Write_Eol; Write_Str (" -Oxx"); Write_Eol; Write_Eol; end if; end Usage; User_Project_Node : Project_Node_Id; procedure Do_Compute_Builder_Switches is new Compute_Builder_Switches (Add_Global_Switches); begin -- First initialize and read the command line arguments Initialize; -- And install Ctrl-C handler Install_Int_Handler (Sigint_Intercepted'Unrestricted_Access); -- Check command line arguments. These will be overridden when looking -- for the configuration file if Target_Name = null then Target_Name := new String'(""); end if; if Config_Project_File_Name = null then Config_Project_File_Name := new String'(""); elsif Autoconf_Specified then -- Check if path needs to be created declare Config_Path : constant String := Ada.Directories.Containing_Directory (Config_Project_File_Name.all); begin if not Ada.Directories.Exists (Config_Path) then Ada.Directories.Create_Path (Config_Path); end if; end; end if; -- Then, parse the user's project and the configuration file. Apply the -- configuration file to the project so that its settings are -- automatically inherited by the project. -- If either the project or the configuration file contains errors, the -- following call with call Osint.Fail and never return begin Parse_Project_And_Apply_Config (Main_Project => Main_Project, User_Project_Node => User_Project_Node, Config_File_Name => Config_Project_File_Name.all, Autoconf_Specified => Autoconf_Specified, Project_File_Name => Project_File_Name.all, Project_Tree => Project_Tree, Env => Root_Environment, Project_Node_Tree => Project_Node_Tree, Packages_To_Check => Packages_To_Check, Allow_Automatic_Generation => Autoconfiguration, Automatically_Generated => Delete_Autoconf_File, Config_File_Path => Configuration_Project_Path, Target_Name => Target_Name.all, Normalized_Hostname => Normalized_Hostname, Implicit_Project => No_Project_File_Found); exception when E : Prj.Conf.Invalid_Config => Osint.Fail (Exception_Message (E)); end; if Main_Project = No_Project then -- Don't flush messages in case of parsing error. This has already -- been taken care when parsing the tree. Otherwise, it results in -- the same message being displayed twice. Fail_Program (Project_Tree, """" & Project_File_Name.all & """ processing failed", Flush_Messages => User_Project_Node /= Empty_Node); end if; if Configuration_Project_Path /= null then Free (Config_Project_File_Name); Config_Project_File_Name := new String' (Base_Name (Configuration_Project_Path.all)); end if; if Total_Errors_Detected > 0 then Prj.Err.Finalize; Fail_Program (Project_Tree, "problems while getting the configuration", Flush_Messages => False); end if; Main_Project_Dir := new String'(Get_Name_String (Main_Project.Directory.Display_Name)); if Warnings_Detected > 0 then Prj.Err.Finalize; Prj.Err.Initialize; end if; Compute_All_Imported_Projects (Main_Project, Project_Tree); if Mains.Number_Of_Mains (Project_Tree) = 0 and then not Unique_Compile then -- Register the Main units from the projects. -- No need to waste time when we are going to compile all files -- anyway (Unique_Compile). Mains.Fill_From_Project (Main_Project, Project_Tree); end if; Mains.Complete_Mains (Root_Environment.Flags, Main_Project, Project_Tree); if not Unique_Compile and then Output_File_Name /= null and then Mains.Number_Of_Mains (null) > 1 then Fail_Program (Project_Tree, "cannot specify -o when there are several mains"); end if; Do_Compute_Builder_Switches (Project_Tree => Project_Tree, Env => Root_Environment, Main_Project => Main_Project); Queue.Initialize (Opt.One_Compilation_Per_Obj_Dir); Compute_Compilation_Phases (Project_Tree, Main_Project, Option_Unique_Compile => Unique_Compile, Option_Compile_Only => Opt.Compile_Only, Option_Bind_Only => Opt.Bind_Only, Option_Link_Only => Opt.Link_Only); if Mains.Number_Of_Mains (Project_Tree) > 0 and then Main_Project.Library and then Builder_Data (Project_Tree).Need_Binding then Fail_Program (Project_Tree, "cannot specify a main program " & "on the command line for a library project file"); end if; Add_Mains_To_Queue; -- If no sources to compile, then there is nothing to do if Queue.Size = 0 then if not Opt.Quiet_Output and then not Main_Project.Externally_Built then Osint.Write_Program_Name; Write_Line (": no sources to compile"); end if; Finish_Program (Project_Tree, E_Success); end if; Always_Compile := Always_Compile and then Opt.Force_Compilations and then Unique_Compile and then not Unique_Compile_All_Projects; -- Reprocess recorded command line options that have priority over -- those in the main project file. Options.Process_Command_Line_Options; if Debug.Debug_Flag_M then Write_Line ("Maximum number of simultaneous compilations =" & Opt.Maximum_Processes'Img); end if; -- Warn if --create-map-file is not supported if Map_File /= null and then Main_Project.Config.Map_File_Option = No_Name then Write_Str ("warning: option "); Write_Str (Create_Map_File_Switch); Write_Str (" is not supported in this configuration"); Write_Eol; end if; -- Source file lookups should be cached for efficiency. -- Source files are not supposed to change. Osint.Source_File_Data (Cache => True); -- If switch --no-object-check is used, then there is no check for the -- switches. if not Object_Checked then Opt.Check_Switches := False; end if; -- Set slave-env if Slave_Env = null and then Distributed_Mode then Slave_Env := new String'(Compute_Slave_Env (Project_Tree, Slave_Env_Auto)); if Slave_Env_Auto and not Opt.Quiet_Output then Write_Str ("slave environment is "); Write_Str (Slave_Env.all); Write_Eol; end if; end if; Compile.Run; Post_Compile.Run; Link.Run; if Warnings_Detected /= 0 then Prj.Err.Finalize; end if; Namet.Finalize; Finish_Program (Project_Tree, E_Success); exception when E : others => Osint.Fail (Exception_Information (E)); end Gprbuild.Main; gprbuild-gpl-2014-src/src/gprclean.adb0000644000076700001450000011560212323721731017172 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R C L E A N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Text_IO; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.IO; use GNAT.IO; with GNAT.Regexp; use GNAT.Regexp; with Gpr_Util; use Gpr_Util; with Gprexch; use Gprexch; with MLib; use MLib; with Makeutl; use Makeutl; with Namet; use Namet; with Opt; use Opt; with Osint; with Prj.Util; use Prj.Util; with Snames; with Types; use Types; package body Gprclean is use Knowledge; ----------------------------- -- Other local subprograms -- ----------------------------- function Object_Artifact (Object_File_Name : File_Name_Type; Artifact_Extension : Name_Id) return String; procedure Clean_Archive (Project : Project_Id); -- Delete a global archive and its dependency file, if they exist procedure Clean_Interface_Copy_Directory (Project : Project_Id; Project_Tree : Project_Tree_Ref); -- Delete files in an interface copy directory: any file that is a copy of -- a source of the project. procedure Clean_Library_Directory (Project : Project_Id; Project_Tree : Project_Tree_Ref); -- Delete the library file in a library directory and any ALI file -- of a source of the project in a library ALI directory. procedure Delete_Binder_Generated_Files (Main_Project : Project_Id; Project_Tree : Project_Tree_Ref; Dir : String; Source : Source_Id); -- Delete the binder generated file in directory Dir for Source function Ultimate_Extension_Of (Project : Project_Id) return Project_Id; -- Returns either Project, if it is not extended by another project, or -- the project that extends Project, directly or indirectly, and that is -- not itself extended. Returns No_Project if Project is No_Project. function Object_Artifact (Object_File_Name : File_Name_Type; Artifact_Extension : Name_Id) return String is Object : constant String := Get_Name_String (Object_File_Name); Last : Natural := Object'Last; begin while Last > 0 and then Object (Last) /= '.' loop Last := Last - 1; end loop; if Last = 0 then Last := Object'Last + 1; end if; return Object (1 .. Last - 1) & Get_Name_String (Artifact_Extension); end Object_Artifact; ------------------- -- Clean_Archive -- ------------------- procedure Clean_Archive (Project : Project_Id) is Current_Dir : constant Dir_Name_Str := Get_Current_Dir; Archive_Name : constant String := "lib" & Get_Name_String (Project.Name) & Get_Name_String (Project.Config.Archive_Suffix); -- The name of the archive file for this project Archive_Dep_Name : constant String := "lib" & Get_Name_String (Project.Name) & ".deps"; -- The name of the archive dependency file for this project Obj_Dir : constant String := Get_Name_String (Project.Object_Directory.Display_Name); begin if Is_Directory (Obj_Dir) then Change_Dir (Obj_Dir); if Is_Regular_File (Archive_Name) then Delete (Obj_Dir, Archive_Name); end if; if Is_Regular_File (Archive_Dep_Name) then Delete (Obj_Dir, Archive_Dep_Name); end if; Change_Dir (Current_Dir); end if; end Clean_Archive; ------------------------------------ -- Clean_Interface_Copy_Directory -- ------------------------------------ procedure Clean_Interface_Copy_Directory (Project : Project_Id; Project_Tree : Project_Tree_Ref) is Current : constant String := Get_Current_Dir; Direc : Dir_Type; Name : String (1 .. 200); Last : Natural; Delete_File : Boolean; Source : Prj.Source_Id; File_Name : File_Name_Type; begin if Project.Library and then Project.Library_Src_Dir /= No_Path_Information then declare Directory : constant String := Get_Name_String (Project.Library_Src_Dir.Name); Iter : Source_Iterator; begin if Is_Directory (Directory) then Change_Dir (Directory); Open (Direc, "."); -- For each regular file in the directory, if switch -n has not -- been specified, make it writable and delete the file if it -- is a copy of a source of the project. loop Read (Direc, Name, Last); exit when Last = 0; if Is_Regular_File (Name (1 .. Last)) then Osint.Canonical_Case_File_Name (Name (1 .. Last)); Name_Len := Last; Name_Buffer (1 .. Name_Len) := Name (1 .. Last); File_Name := Name_Find; Delete_File := False; Iter := For_Each_Source (Project_Tree); loop Source := Prj.Element (Iter); exit when Source = No_Source; if Ultimate_Extension_Of (Source.Project) = Project and then Source.File = File_Name then Delete_File := True; exit; end if; Next (Iter); end loop; if Delete_File then if not Do_Nothing then Set_Writable (Name (1 .. Last)); end if; Delete (Directory, Name (1 .. Last)); end if; end if; end loop; Close (Direc); -- Restore the initial working directory Change_Dir (Current); end if; end; end if; end Clean_Interface_Copy_Directory; ----------------------------- -- Clean_Library_Directory -- ----------------------------- procedure Clean_Library_Directory (Project : Project_Id; Project_Tree : Project_Tree_Ref) is Current : constant String := Get_Current_Dir; Lib_Filename : constant String := Get_Name_String (Project.Library_Name); DLL_Name : String := Get_Name_String (Project.Config.Shared_Lib_Prefix) & Lib_Filename & Get_Name_String (Project.Config.Shared_Lib_Suffix); Archive_Name : String := "lib" & Lib_Filename & Get_Name_String (Project.Config.Archive_Suffix); Library_Exchange_File_Name : constant String := Lib_Filename & Library_Exchange_Suffix; Direc : Dir_Type; Name : String (1 .. 200); Last : Natural; Delete_File : Boolean; begin if Project.Library then Osint.Canonical_Case_File_Name (DLL_Name); Osint.Canonical_Case_File_Name (Archive_Name); declare Obj_Directory : String_Access := null; Lib_Directory : constant String := Get_Name_String (Project.Library_Dir.Display_Name); Lib_ALI_Directory : constant String := Get_Name_String (Project.Library_ALI_Dir.Display_Name); Exchange_File : Ada.Text_IO.File_Type; In_Generated : Boolean; begin if Project.Object_Directory.Display_Name /= No_Path then Obj_Directory := new String' (Get_Name_String (Project.Object_Directory.Display_Name)); if Is_Directory (Obj_Directory.all) then Change_Dir (Obj_Directory.all); Open (Direc, "."); -- Look for the library exchange file in the object -- directory. loop Read (Direc, Name, Last); exit when Last = 0; if Is_Regular_File (Name (1 .. Last)) then Osint.Canonical_Case_File_Name (Name (1 .. Last)); exit when Name (1 .. Last) = Library_Exchange_File_Name; end if; end loop; Close (Direc); -- If there is a library exchange file then get the -- generated file names and delete them, then delete -- the library exchange file. if Last > 0 then Ada.Text_IO.Open (Exchange_File, Ada.Text_IO.In_File, Library_Exchange_File_Name); In_Generated := False; while not Ada.Text_IO.End_Of_File (Exchange_File) loop Ada.Text_IO.Get_Line (Exchange_File, Name, Last); if Last > 0 then if Name (1) = '[' then In_Generated := Name (1 .. Last) = Library_Label (Generated_Object_Files) or else Name (1 .. Last) = Library_Label (Generated_Source_Files); elsif In_Generated then if Is_Regular_File (Name (1 .. Last)) then if not Do_Nothing then Set_Writable (Name (1 .. Last)); end if; Delete (Obj_Directory.all, Name (1 .. Last)); end if; end if; end if; end loop; Ada.Text_IO.Close (Exchange_File); if not Do_Nothing then Set_Writable (Library_Exchange_File_Name); end if; Delete (Obj_Directory.all, Library_Exchange_File_Name); end if; Change_Dir (Current); end if; end if; if Is_Directory (Lib_Directory) then Change_Dir (Lib_Directory); Open (Direc, "."); -- For each regular file in the directory, if switch -n has not -- been specified, make it writable and delete the file if it -- is the library file. loop Read (Direc, Name, Last); exit when Last = 0; if Is_Regular_File (Name (1 .. Last)) or else Is_Symbolic_Link (Name (1 .. Last)) then Osint.Canonical_Case_File_Name (Name (1 .. Last)); if (Project.Library_Kind = Static and then Name (1 .. Last) = Archive_Name) or else ((Project.Library_Kind = Dynamic or else Project.Library_Kind = Relocatable) and then Name (1 .. Last) = DLL_Name) then if not Do_Nothing then Set_Writable (Name (1 .. Last)); end if; Delete (Lib_Directory, Name (1 .. Last)); end if; end if; end loop; Close (Direc); if Project.Config.Symbolic_Link_Supported then if (Project.Library_Kind = Dynamic or else Project.Library_Kind = Relocatable) and then Project.Lib_Internal_Name /= No_Name then declare Lib_Version : String := Get_Name_String (Project.Lib_Internal_Name); begin Osint.Canonical_Case_File_Name (Lib_Version); if Project.Config.Lib_Maj_Min_Id_Supported then declare Maj_Version : String := Major_Id_Name (DLL_Name, Lib_Version); begin if Maj_Version /= "" then Osint.Canonical_Case_File_Name (Maj_Version); Open (Direc, "."); -- For each regular file in the directory, if -- switch -n has not been specified, make it -- writable and delete the file if it is the -- library major version file. loop Read (Direc, Name, Last); exit when Last = 0; if (Is_Regular_File (Name (1 .. Last)) or else Is_Symbolic_Link (Name (1 .. Last))) and then Name (1 .. Last) = Maj_Version then if not Do_Nothing then Set_Writable (Name (1 .. Last)); end if; Delete (Lib_Directory, Name (1 .. Last)); end if; end loop; Close (Direc); end if; end; end if; Open (Direc, "."); -- For each regular file in the directory, if switch -- -n has not been specified, make it writable and -- delete the file if it is the library version file. loop Read (Direc, Name, Last); exit when Last = 0; if Is_Regular_File (Name (1 .. Last)) and then Name (1 .. Last) = Lib_Version then if not Do_Nothing then Set_Writable (Name (1 .. Last)); end if; Delete (Lib_Directory, Name (1 .. Last)); end if; end loop; Close (Direc); end; end if; end if; Change_Dir (Current); end if; if Is_Directory (Lib_ALI_Directory) then Change_Dir (Lib_ALI_Directory); Open (Direc, "."); -- For each regular file in the directory, if switch -n has not -- been specified, make it writable and delete the file if it -- is any dependency file of a source of the project. loop Read (Direc, Name, Last); exit when Last = 0; if Is_Regular_File (Name (1 .. Last)) then Osint.Canonical_Case_File_Name (Name (1 .. Last)); Delete_File := False; if Last > 4 and then Name (Last - 3 .. Last) = ".ali" then declare Source : Prj.Source_Id; Iter : Source_Iterator; Proj : Project_Id := Project; begin Project_Loop : loop Iter := For_Each_Source (Project_Tree, Proj); loop Source := Prj.Element (Iter); exit when Source = No_Source; if Source.Dep_Name /= No_File and then Get_Name_String (Source.Dep_Name) = Name (1 .. Last) then Delete_File := True; exit Project_Loop; end if; Next (Iter); end loop; exit Project_Loop when Proj.Extends = No_Project; Proj := Proj.Extends; end loop Project_Loop; end; end if; if Delete_File then if not Do_Nothing then Set_Writable (Name (1 .. Last)); end if; Delete (Lib_ALI_Directory, Name (1 .. Last)); end if; end if; end loop; Close (Direc); -- Restore the initial working directory Change_Dir (Current); end if; end; end if; end Clean_Library_Directory; -- Artifacts type Artifact_Array_Type is array (Positive range <>) of GNAT.Regexp.Regexp; type Artifact_Array_Ptr is access Artifact_Array_Type; Artifacts : Artifact_Array_Ptr := new Artifact_Array_Type (1 .. 4); -- List of regular expression file names to be deleted in procedure -- Clean_Artifacts below. Size 4 is arbitrary. Artifact_Last : Natural := 0; -- Last index of the valid artifacts in array Artifacts. ------------------- -- Clean_Project -- ------------------- procedure Clean_Project (Project : Project_Id; Project_Tree : Project_Tree_Ref; Main : Boolean; Remove_Executables : Boolean) is Executable : File_Name_Type; -- Name of the executable file Current_Dir : constant Dir_Name_Str := Get_Current_Dir; Project2 : Project_Id; Source_Id : Prj.Source_Id; Partial_Number : Natural; List : Name_List_Index := No_Name_List; Node : Name_Node; procedure Clean_Artifacts (Dir : String; List : Name_List_Index); -- Clean the artifacts specified by List in directory Dir. -- The current directory is Dir. function Is_Regexp (Name : String) return Boolean; -- Return True iff Name is a glob regexp. --------------------- -- Clean_Artifacts -- --------------------- procedure Clean_Artifacts (Dir : String; List : Name_List_Index) is Lst : Name_List_Index := List; Nod : Name_Node; begin Artifact_Last := 0; while Lst /= No_Name_List loop Nod := Project_Tree.Shared.Name_Lists.Table (Lst); declare Name : constant String := Get_Name_String (Nod.Name); begin if Is_Regexp (Name) then if Artifact_Last = Artifacts'Length then declare New_Artifacts : constant Artifact_Array_Ptr := new Artifact_Array_Type (1 .. 2 * Artifact_Last); begin New_Artifacts (1 .. Artifact_Last) := Artifacts (1 .. Artifact_Last); Artifacts := New_Artifacts; end; end if; Artifact_Last := Artifact_Last + 1; Artifacts (Artifact_Last) := Compile (Name, Glob => True); elsif Is_Regular_File (Name) then Delete (Dir, Name); end if; end; Lst := Nod.Next; end loop; if Artifact_Last > 0 then declare Directory : Dir_Type; File_Name : Dir_Name_Str (1 .. 1_000); Last : Natural; begin Open (Directory, Dir); Directory_Loop : loop Read (Directory, File_Name, Last); exit Directory_Loop when Last = 0; if Is_Regular_File (File_Name (1 .. Last)) then Artifact_Loop : for J in 1 .. Artifact_Last loop if Match (File_Name (1 .. Last), Artifacts (J)) then Delete (Dir, File_Name (1 .. Last)); exit Artifact_Loop; end if; end loop Artifact_Loop; end if; end loop Directory_Loop; Close (Directory); end; end if; end Clean_Artifacts; --------------- -- Is_Regexp -- --------------- function Is_Regexp (Name : String) return Boolean is begin for J in Name'Range loop case Name (J) is when '?' | '*' | '[' | '{' => return True; when others => null; end case; end loop; return False; end Is_Regexp; begin -- Check that we don't specify executable on the command line for -- a main library project. if Project = Main_Project and then Mains.Number_Of_Mains (null) /= 0 and then Project.Library then Osint.Fail ("Cannot specify executable(s) for a Library Project File"); end if; -- Add project to the list of processed projects Processed_Projects.Increment_Last; Processed_Projects.Table (Processed_Projects.Last) := Project; -- Nothing to clean in an externally built project if Project.Externally_Built then if Verbose_Mode then Put ("Nothing to do to clean externally built project """); Put (Get_Name_String (Project.Name)); Put_Line (""""); end if; else if Verbose_Mode then Put ("Cleaning project """); Put (Get_Name_String (Project.Name)); Put_Line (""""); end if; if Project.Object_Directory /= No_Path_Information and then Is_Directory (Get_Name_String (Project.Object_Directory.Display_Name)) then declare Obj_Dir : constant String := Get_Name_String (Project.Object_Directory.Display_Name); Iter : Source_Iterator; begin Change_Dir (Obj_Dir); -- For non library project, clean the global archive and its -- dependency file if they exist. if not Project.Library then Clean_Archive (Project); end if; -- For a library project, clean the partially link objects, if -- there are some. if Project.Library then Partial_Number := 0; loop declare Partial : constant String := Partial_Name (Get_Name_String (Project.Library_Name), Partial_Number, Object_Suffix); begin if Is_Regular_File (Partial) then Delete (Obj_Dir, Partial); Partial_Number := Partial_Number + 1; else exit; end if; end; end loop; end if; -- Check all the object file for the sources of the current -- project and all the projects it extends. Project2 := Project; while Project2 /= No_Project loop -- Delete the object files, the dependency files, the -- switches files if they exist. Also additional artifacts -- if they are any. Iter := For_Each_Source (Project_Tree, Project2); loop Source_Id := Prj.Element (Iter); exit when Source_Id = No_Source; if Source_Id.Object /= No_File and then Is_Regular_File (Get_Name_String (Source_Id.Object)) then Delete (Obj_Dir, Get_Name_String (Source_Id.Object)); -- Clean object artifacts, if any List := Source_Id.Language.Config.Clean_Object_Artifacts; while List /= No_Name_List loop Node := Project_Tree.Shared.Name_Lists.Table (List); declare Artifact : constant String := Object_Artifact (Source_Id.Object, Node.Name); begin if Is_Regular_File (Artifact) then Delete (Obj_Dir, Artifact); end if; end; List := Node.Next; end loop; end if; if Source_Id.Dep_Name /= No_File and then Is_Regular_File (Get_Name_String (Source_Id.Dep_Name)) then Delete (Obj_Dir, Get_Name_String (Source_Id.Dep_Name)); end if; if Source_Id.Switches /= No_File and then Is_Regular_File (Get_Name_String (Source_Id.Switches)) then Delete (Obj_Dir, Get_Name_String (Source_Id.Switches)); end if; -- Clean source artifacts, if any List := Source_Id.Language.Config.Clean_Source_Artifacts; while List /= No_Name_List loop Node := Project_Tree.Shared.Name_Lists.Table (List); declare Artifact : constant String := Get_Name_String (Source_Id.File) & Get_Name_String (Node.Name); begin if Is_Regular_File (Artifact) then Delete (Obj_Dir, Artifact); end if; end; List := Node.Next; end loop; Next (Iter); end loop; Project2 := Project2.Extends; end loop; -- Clean the artifacts in object directory, if any. Do this -- after cleaning the object files, to avoid checking every -- object file when the artifacts are given as a regexp. Clean_Artifacts (Obj_Dir, Project.Config.Artifacts_In_Object_Dir); end; end if; -- If this is a library project, clean the library directory, the -- interface copy dir and, for a Stand-Alone Library, the binder -- generated files of the library. -- The directories are cleaned only if switch -c is not specified if Project.Library then if not Compile_Only then Clean_Library_Directory (Project, Project_Tree); if Project.Library_Src_Dir /= No_Path_Information then Clean_Interface_Copy_Directory (Project, Project_Tree); end if; end if; end if; if Verbose_Mode then New_Line; end if; end if; -- If switch -r is specified, call Clean_Project recursively for the -- imported projects and the project being extended. if All_Projects then declare Imported : Project_List := Project.Imported_Projects; Process : Boolean; begin -- For each imported project, call Clean_Project if the project -- has not been processed already. while Imported /= null loop Process := True; for J in Processed_Projects.First .. Processed_Projects.Last loop if Imported.Project = Processed_Projects.Table (J) then Process := False; exit; end if; end loop; if Process then Clean_Project (Imported.Project, Project_Tree, False, False); end if; Imported := Imported.Next; end loop; -- If this project extends another project, call Clean_Project for -- the project being extended. It is guaranteed that it has not -- called before, because no other project may import or extend -- this project. if Project.Extends /= No_Project then Clean_Project (Project.Extends, Project_Tree, False, False); end if; end; end if; -- For the main project, delete the executables and the binder generated -- files. -- The executables are deleted only if switch -c is not specified if Main and then Project.Exec_Directory /= No_Path_Information and then Is_Directory (Get_Name_String (Project.Exec_Directory.Display_Name)) then declare Exec_Dir : constant String := Get_Name_String (Project.Exec_Directory.Display_Name); Main_File : Main_Info; begin Change_Dir (Exec_Dir); -- Clean the artifacts in the exec dir, if any Clean_Artifacts (Exec_Dir, Project.Config.Artifacts_In_Exec_Dir); Mains.Reset; loop Main_File := Mains.Next_Main; exit when Main_File = No_Main_Info; if Main_File.Tree = Project_Tree then if Remove_Executables and then Main_File.Source /= No_Source then Executable := Executable_Of (Project => Project, Shared => Project_Tree.Shared, Main => Main_File.File, Index => Main_File.Index, Ada_Main => Main_File.Source.Language.Name = Snames.Name_Ada); declare Exec_File_Name : constant String := Get_Name_String (Executable); begin if Is_Absolute_Path (Name => Exec_File_Name) then if Is_Regular_File (Exec_File_Name) then Delete ("", Exec_File_Name); end if; else if Is_Regular_File (Exec_File_Name) then Delete (Exec_Dir, Exec_File_Name); end if; end if; end; end if; -- Delete the binder generated files only if the main source -- has been found and if there is an object directory. if Main_File.Source /= No_Source and then Project.Object_Directory /= No_Path_Information and then Is_Directory (Get_Name_String (Project.Object_Directory.Display_Name)) then Delete_Binder_Generated_Files (Project, Project_Tree, Get_Name_String (Project.Object_Directory.Display_Name), Main_File.Source); end if; end if; end loop; end; end if; -- Change back to previous directory Change_Dir (Current_Dir); end Clean_Project; ------------ -- Delete -- ------------ procedure Delete (In_Directory : String; File : String) is Full_Name : String (1 .. In_Directory'Length + File'Length + 1); Last : Natural := 0; Success : Boolean; begin -- Indicate that at least one file is deleted or is to be deleted File_Deleted := True; -- Build the path name of the file to delete Last := In_Directory'Length; Full_Name (1 .. Last) := In_Directory; if Last > 0 and then Full_Name (Last) /= Directory_Separator then Last := Last + 1; Full_Name (Last) := Directory_Separator; end if; Full_Name (Last + 1 .. Last + File'Length) := File; Last := Last + File'Length; -- If switch -n was used, simply output the path name if Do_Nothing then Put_Line (Full_Name (1 .. Last)); -- Otherwise, delete the file if it is writable else if Force_Deletions or else Is_Writable_File (Full_Name (1 .. Last)) then Delete_File (Full_Name (1 .. Last), Success); else Success := False; end if; if Verbose_Mode or else not Quiet_Output then if not Success then Put ("Warning: """); Put (Full_Name (1 .. Last)); Put_Line (""" could not be deleted"); else Put (""""); Put (Full_Name (1 .. Last)); Put_Line (""" has been deleted"); end if; end if; end if; end Delete; ----------------------------------- -- Delete_Binder_Generated_Files -- ----------------------------------- procedure Delete_Binder_Generated_Files (Main_Project : Project_Id; Project_Tree : Project_Tree_Ref; Dir : String; Source : Source_Id) is Data : constant Builder_Data_Access := Builder_Data (Project_Tree); Current : constant String := Get_Current_Dir; B_Data : Binding_Data; Base_Name : File_Name_Type; begin Find_Binding_Languages (Project_Tree, Main_Project); if Data.There_Are_Binder_Drivers then -- Get the main base name Base_Name := Base_Name_Index_For (Get_Name_String (Source.File), Source.Index, '~'); -- Work in the object directory Change_Dir (Dir); B_Data := Data.Binding; while B_Data /= null loop declare File_Name : constant String := Binder_Exchange_File_Name (Base_Name, B_Data.Binder_Prefix).all; File : Ada.Text_IO.File_Type; Line : String (1 .. 1_000); Last : Natural; Section : Binding_Section := No_Binding_Section; begin if Is_Regular_File (File_Name) then Ada.Text_IO.Open (File, Ada.Text_IO.In_File, File_Name); while not Ada.Text_IO.End_Of_File (File) loop Ada.Text_IO.Get_Line (File, Line, Last); if Last > 0 then if Line (1) = '[' then Section := Get_Binding_Section (Line (1 .. Last)); else case Section is when Generated_Object_File | Generated_Source_Files => if Is_Regular_File (Line (1 .. Last)) then Delete (Dir, Line (1 .. Last)); end if; when others => null; end case; end if; end if; end loop; Ada.Text_IO.Close (File); Delete (Dir, File_Name); end if; end; B_Data := B_Data.Next; end loop; -- Change back to previous directory Change_Dir (Current); end if; end Delete_Binder_Generated_Files; --------------------------- -- Ultimate_Extension_Of -- --------------------------- function Ultimate_Extension_Of (Project : Project_Id) return Project_Id is Result : Project_Id := Project; begin if Project /= No_Project then loop exit when Result.Extended_By = No_Project; Result := Result.Extended_By; end loop; end if; return Result; end Ultimate_Extension_Of; end Gprclean; gprbuild-gpl-2014-src/src/gprinstall.ads0000644000076700001450000001311312323721731017571 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ private with GNAT.OS_Lib; private with Prj; package Gprinstall is private use Prj; use GNAT.OS_Lib; DS : constant Character := GNAT.OS_Lib.Directory_Separator; Display_Paths : Boolean := False; -- Set by switch --display-paths: config project path and user project path -- will be displayed after all command lines witches have been scanned. Project_File_Name_Expected : Boolean := False; -- True when last switch was -P Main_Project_Dir : String_Access; -- The absolute path of the project directory of the main project, -- initialized in procedure Initialize. Force_Installations : Boolean := False; -- True if gprinstall is allowed to overwrite existing files -- A Param, track if it is set on the command line or if it is the default -- value. type Param is record V : String_Access; Default : Boolean := False; end record; function Dup (P : Param) return Param; -- Return a copy of P procedure Free (P : in out Param); -- Free P Global_Prefix_Dir : Param := (null, True); -- Root installation directory Global_Exec_Subdir : Param := (new String'("bin" & DS), True); -- Subdirectory for executable Global_Lib_Subdir : Param := (new String'("lib" & DS), True); -- Subdirectory for libraries Global_Link_Lib_Subdir : Param := (new String'("lib" & DS), True); -- Subdirectory for libraries sym links (on UNIX) Global_Sources_Subdir : Param := (new String'("include" & DS), True); -- Subdirectory for sources Global_Project_Subdir : Param := (new String'("share" & DS & "gpr" & DS), True); -- Subdirectory used for the installed generated project file Build_Var : String_Access; -- Name of the build variable for installed project file Build_Name : String_Access := new String'("default"); -- Name of the current build Install_Name : String_Access; -- The installation name Install_Name_Default : Boolean := True; -- Wether the Install_Name has been specified on the command line. If -- specified then Install_Name_Default will be false. For_Dev : Boolean := True; -- True if the installation is for developers (source of the libraries -- are also installed). If set to False (for usage) only the shared -- libraries are installed and/or the main executables. Search_Project_Dir_Expected : Boolean := False; -- True when last switch was -aP Project_Tree : constant Project_Tree_Ref := new Project_Tree_Data (Is_Root_Tree => True); -- The project tree Copyright_Output : Boolean := False; Usage_Output : Boolean := False; -- Flags to avoid multiple displays of Copyright notice and of Usage Usage_Needed : Boolean := False; -- Set by swith -h: usage will be displayed after all command line -- switches have been scanned. Recursive : Boolean := False; -- Installation will recurse into all imported projects Dry_Run : Boolean := False; -- Whether the actual installation takes place or not. If Dry_Run is set to -- True then the action will be displayed on the console but actually not -- performed. type Usage_Kind is (Install_Mode, Uninstall_Mode, List_Mode); Usage_Mode : Usage_Kind := Install_Mode; -- Set to true if project is to be uninstalled Output_Stats : Boolean := False; -- Wether the stats are to be displayed when listing installed packages All_Sources : Boolean := False; -- By default install only the sources needed to use the project (the -- interface for a SAL). If All_Sources is set to True all the sources are -- copied. Add_Lib_Link : Boolean := True; -- Wether to copy the shared library into the executable directory on -- Windows or create a link into the lib directory on UNIX. Create_Dest_Dir : Boolean := False; -- Wether to create the missing directories in the destination point Sig_Line : constant String := "S "; -- The prefix of the line containing the original project's signature end Gprinstall; gprbuild-gpl-2014-src/src/gprbuild-compilation-slave.ads0000644000076700001450000000667412323721731022664 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . S L A V E -- -- -- -- S p e c -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with GNAT.OS_Lib; with Gprbuild.Compilation.Process; use Gprbuild.Compilation.Process; package Gprbuild.Compilation.Slave is procedure Record_Slaves (Option : String); -- Record the slaves as passed on the command line procedure Register_Remote_Slaves (Tree : Project_Tree_Ref; Project : Project_Id); -- Register the slaves describes in Build_Slaves attribute of project's -- Remote package. This routine also initialize the slaves sources. This -- routine must be called before any other in this unit. procedure Clean_Up_Remote_Slaves (Tree : Project_Tree_Ref; Project : Project_Id); -- Send a clean-up request to all remote slaves. The slaves are then asked -- to remove all the sources and build artifacts for the given project. function Run (Project : Project_Id; Language : String; Options : GNAT.OS_Lib.Argument_List; Obj_Name : String; Dep_Name : String := ""; Env : String := "") return Id; -- Send a compilation job to one slave that has still some free slot. There -- is also free slot when this routine is called (gprbuild ensure this). procedure Unregister_Remote_Slaves; -- Unregister all slaves, send them notification about the end of the -- current build. This routine also synchronize back the object code from -- each slave to the build master. This routine must be called after the -- compilation phase and before the bind and link ones. It is safe to call -- this routine multiple times, the first call will do the clean-up, next -- calls are just no-op. function Get_Max_Processes return Natural; -- Returns the maximum number of processes supported by the compilation -- engine. This is the sum of the parallel local builds as specified by -- the -j option and all the sum of the processes supported by each slaves. end Gprbuild.Compilation.Slave; gprbuild-gpl-2014-src/src/gprconfig.ads0000644000076700001450000000314112323721731017370 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R C O N F I G -- -- -- -- S p e c -- -- -- -- Copyright (C) 2006-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package GprConfig is pragma Pure; end GprConfig; gprbuild-gpl-2014-src/src/gprinstall-db.adb0000644000076700001450000001330612323721731020137 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . D B -- -- -- -- B o d y -- -- -- -- Copyright (C) 2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Directories; use Ada.Directories; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with Ada.Text_IO; use Ada.Text_IO; with GNAT.MD5; use GNAT.MD5; package body Gprinstall.DB is use Ada; ---------- -- List -- ---------- procedure List is type Stats is record N_Files : Natural := 0; N_Files_Not_Found : Natural := 0; Bytes : File_Size := 0; end record; function Project_Dir return String; -- Returns the install project directory function Get_Stat (Manifest : String) return Stats; -- Compute the stats for the given manifest file procedure Process (D_Entry : Directory_Entry_Type); -- Process a directory entry, this is a specific manifest file -------------- -- Get_Stat -- -------------- function Get_Stat (Manifest : String) return Stats is File : File_Type; Line : String (1 .. 2048); Last : Natural; Result : Stats; subtype MD5_Range is Positive range Message_Digest'Range; subtype Name_Range is Positive range MD5_Range'Last + 2 .. Line'Last; begin Open (File, In_File, Manifest); while not End_Of_File (File) loop Get_Line (File, Line, Last); if Line (1 .. 2) /= Sig_Line then declare Filename : constant String := Global_Prefix_Dir.V.all & Line (Name_Range'First .. Last); begin if Exists (Filename) then Result.N_Files := Result.N_Files + 1; Result.Bytes := Result.Bytes + Size (Filename); else Result.N_Files_Not_Found := Result.N_Files_Not_Found + 1; end if; end; end if; end loop; Close (File); return Result; end Get_Stat; ----------------- -- Project_Dir -- ----------------- function Project_Dir return String is begin if Is_Absolute_Path (Global_Project_Subdir.V.all) then return Global_Project_Subdir.V.all; else return Global_Prefix_Dir.V.all & Global_Project_Subdir.V.all; end if; end Project_Dir; package File_Size_IO is new Text_IO.Integer_IO (File_Size); use File_Size_IO; ------------- -- Process -- ------------- procedure Process (D_Entry : Directory_Entry_Type) is S : Stats; Unit : String (1 .. 2) := "b "; Size : File_Size; begin Put (" " & Simple_Name (D_Entry)); Set_Col (25); if Output_Stats then -- Get stats S := Get_Stat (Full_Name (D_Entry)); -- Number of files Put (S.N_Files, Width => 5); if S.N_Files > 1 then Put (" files, "); else Put (" file, "); end if; -- Sizes Size := S.Bytes; if Size > 1024 then Size := Size / 1024; Unit := "Kb"; end if; if Size > 1024 then Size := Size / 1024; Unit := "Mb"; end if; if Size > 1024 then Size := Size / 1024; Unit := "Gb"; end if; Put (Size, Width => 5); Put (' ' & Unit); -- Files not found if any if S.N_Files_Not_Found > 0 then Put (S.N_Files_Not_Found, Width => 0); Put (" files missing."); end if; end if; New_Line; end Process; Dir : constant String := Project_Dir & "manifests"; begin New_Line; if Exists (Dir) then Put_Line ("List of installed packages"); New_Line; Search (Dir, "*", (Ordinary_File => True, others => False), Process'Access); else Put_Line ("No package installed"); New_Line; end if; end List; end Gprinstall.DB; gprbuild-gpl-2014-src/src/gprexch.adb0000644000076700001450000001047212323721731017036 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R E X C H -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package body Gprexch is type String_Ptr is access String; Binding_Labels : array (Binding_Section) of String_Ptr; -- The list of labels of the different section in a binder exchange file. -- Populated in the package body. Library_Labels : array (Library_Section) of String_Ptr; -- The list of labels of the different section in a library exchange file. -- Populated in the package body. ------------------- -- Binding_Label -- ------------------- function Binding_Label (Section : Binding_Section) return String is begin if Binding_Labels (Section) = null then return ""; else return Binding_Labels (Section).all; end if; end Binding_Label; ------------------------- -- Get_Binding_Section -- ------------------------- function Get_Binding_Section (Label : String) return Binding_Section is begin for Section in Binding_Section loop if Binding_Labels (Section) /= null and then Binding_Labels (Section).all = Label then return Section; end if; end loop; return No_Binding_Section; end Get_Binding_Section; ------------------------- -- Get_Library_Section -- ------------------------- function Get_Library_Section (Label : String) return Library_Section is begin for Section in Library_Section loop if Library_Labels (Section) /= null and then Library_Labels (Section).all = Label then return Section; end if; end loop; return No_Library_Section; end Get_Library_Section; ------------------- -- Library_Label -- ------------------- function Library_Label (Section : Library_Section) return String is begin if Library_Labels (Section) = null then return ""; else return Library_Labels (Section).all; end if; end Library_Label; -- Package elaboration code (build the lists of section labels) begin for J in Binding_Labels'Range loop if J /= No_Binding_Section then Binding_Labels (J) := new String'('[' & J'Img & ']'); for K in Binding_Labels (J)'Range loop if Binding_Labels (J) (K) = '_' then Binding_Labels (J) (K) := ' '; end if; end loop; end if; end loop; Binding_Labels (No_Binding_Section) := null; for J in Library_Labels'Range loop if J /= No_Library_Section then Library_Labels (J) := new String'('[' & J'Img & ']'); for K in Library_Labels (J)'Range loop if Library_Labels (J) (K) = '_' then Library_Labels (J) (K) := ' '; end if; end loop; end if; end loop; Library_Labels (No_Library_Section) := null; end Gprexch; gprbuild-gpl-2014-src/src/gprbuild-compile.ads0000644000076700001450000000354112323721731020654 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L E -- -- -- -- S p e c -- -- -- -- Copyright (C) 2011-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package Gprbuild.Compile is procedure Run; -- The first version compilations for a specific project tree. This needs -- to be called one for each aggregated projects, too. -- The second version will process all the main root project and all -- aggregated projects. end Gprbuild.Compile; gprbuild-gpl-2014-src/src/gpr_util.adb0000644000076700001450000023210312323721731017220 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R _ U T I L -- -- -- -- B o d y -- -- -- -- Copyright (C) 2007-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Containers.Indefinite_Ordered_Sets; with Ada.Calendar.Time_Zones; use Ada.Calendar; use Ada.Calendar.Time_Zones; with Ada.Command_Line; use Ada.Command_Line; with Ada.Directories; use Ada.Directories; with Ada.Streams.Stream_IO; use Ada.Streams; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Ada.Strings.Maps; use Ada.Strings.Maps; with Interfaces.C.Strings; with System; with GNAT.Calendar.Time_IO; use GNAT.Calendar.Time_IO; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables; with GNAT.Sockets; with ALI; use ALI; with Debug; with Makeutl; use Makeutl; with Opt; use Opt; with Osint; use Osint; with Output; use Output; with Prj.Conf; with Prj.Env; with Prj.Util; use Prj.Util; with Scans; with Scng; with Sinput.C; with Sinput.P; with Snames; use Snames; with Styleg; with Table; with Tempdir; with Types; use Types; with GprConfig.Sdefault; package body Gpr_Util is -- Empty procedures needed to instantiate Scng. Error procedures are -- empty, because we don't want to report any errors when computing -- a source checksum. procedure Post_Scan; procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr); procedure Error_Msg_S (Msg : String); procedure Error_Msg_SC (Msg : String); procedure Error_Msg_SP (Msg : String); -- Instantiation of Styleg, needed to instantiate Scng package Style is new Styleg (Error_Msg, Error_Msg_S, Error_Msg_SC, Error_Msg_SP); -- A Scanner is needed to get checksum of a source (procedure -- Get_File_Checksum). package Scanner is new Scng (Post_Scan, Error_Msg, Error_Msg_S, Error_Msg_SC, Error_Msg_SP, Style); Libgcc_Subdir_Ptr : Interfaces.C.Strings.chars_ptr; pragma Import (C, Libgcc_Subdir_Ptr, "__gnat_default_libgcc_subdir"); -- Pointer to string indicating the installation subdirectory where a -- default shared libgcc might be found. GNU_Header : aliased constant String := "INPUT ("; GNU_Opening : aliased constant String := """"; GNU_Closing : aliased constant String := '"' & ASCII.LF; GNU_Footer : aliased constant String := ')' & ASCII.LF; package Project_Name_Boolean_Htable is new Simple_HTable (Header_Num => Header_Num, Element => Boolean, No_Element => False, Key => Name_Id, Hash => Hash, Equal => "="); Project_Failure : Project_Name_Boolean_Htable.Instance := Project_Name_Boolean_Htable.Nil; -- Record a boolean for project having failed to compile cleanly ------------------------------- -- Binder_Exchange_File_Name -- ------------------------------- function Binder_Exchange_File_Name (Main_Base_Name : File_Name_Type; Prefix : Name_Id) return String_Access is File_Name : constant String := Get_Name_String (Main_Base_Name); begin Get_Name_String (Prefix); Add_Str_To_Name_Buffer (File_Name); Add_Str_To_Name_Buffer (Binder_Exchange_Suffix); return new String'(Name_Buffer (1 .. Name_Len)); end Binder_Exchange_File_Name; ----------------------- -- Compute_Slave_Env -- ----------------------- function Compute_Slave_Env (Project : Project_Tree_Ref; Auto : Boolean) return String is User : String_Access := Getenv ("USER"); User_Name : String_Access := Getenv ("USERNAME"); Default : constant String := (if User = null then (if User_Name = null then "unknown" else User_Name.all) else User.all) & '@' & GNAT.Sockets.Host_Name; package S_Set is new Containers.Indefinite_Ordered_Sets (String); Set : S_Set.Set; Ctx : Context; begin Free (User); Free (User_Name); if Auto then -- In this mode the slave environment is computed based on -- the project variable value and the command line arguments. -- First adds all command line arguments for K in 1 .. Argument_Count loop -- Skip arguments that are not changing the actual compilation and -- this will ensure that the same environment will be created for -- gprclean. if Argument (K) not in "-p" | "-d" | "-c" | "-q" and then (Argument (K)'Length < 2 or else Argument (K) (1 .. 2) /= "-j") then Set.Insert (Argument (K)); end if; end loop; -- Then all the global variables for the project tree for K in 1 .. Variable_Element_Table.Last (Project.Shared.Variable_Elements) loop declare V : constant Variable := Project.Shared.Variable_Elements.Table (K); begin if V.Value.Kind = Single then Set.Include (Get_Name_String (V.Name) & "=" & Get_Name_String (V.Value.Value)); end if; end; end loop; -- Compute the MD5 sum of the sorted elements in the set for S of Set loop Update (Ctx, S); end loop; return Default & "-" & Digest (Ctx); else -- Otherwise use the default & '@' & return Default; end if; end Compute_Slave_Env; -------------------------- -- Create_Response_File -- -------------------------- procedure Create_Response_File (Format : Response_File_Format; Objects : String_List; Other_Arguments : String_List; Resp_File_Options : String_List; Name_1 : out Path_Name_Type; Name_2 : out Path_Name_Type) is Resp_File : File_Descriptor; Status : Integer; pragma Warnings (Off, Status); Closing_Status : Boolean; pragma Warnings (Off, Closing_Status); function Modified_Argument (Arg : String) return String; -- If the argument includes a space, a backslash, or a double quote, -- escape the character with a preceding backsash. ----------------------- -- Modified_Argument -- ----------------------- function Modified_Argument (Arg : String) return String is Result : String (1 .. 2 * Arg'Length); Last : Natural := 0; procedure Add (C : Character); --------- -- Add -- --------- procedure Add (C : Character) is begin Last := Last + 1; Result (Last) := C; end Add; begin for J in Arg'Range loop if Arg (J) = '\' or else Arg (J) = ' ' or else Arg (J) = '"' then Add ('\'); end if; Add (Arg (J)); end loop; return Result (1 .. Last); end Modified_Argument; begin Name_2 := No_Path; Tempdir.Create_Temp_File (Resp_File, Name => Name_1); if Format = GNU or else Format = GCC_GNU then Status := Write (Resp_File, GNU_Header'Address, GNU_Header'Length); end if; for J in Objects'Range loop if Format = GNU or else Format = GCC_GNU then Status := Write (Resp_File, GNU_Opening'Address, GNU_Opening'Length); end if; Status := Write (Resp_File, Objects (J).all'Address, Objects (J)'Length); if Format = GNU or else Format = GCC_GNU then Status := Write (Resp_File, GNU_Closing'Address, GNU_Closing'Length); else Status := Write (Resp_File, ASCII.LF'Address, 1); end if; end loop; if Format = GNU or else Format = GCC_GNU then Status := Write (Resp_File, GNU_Footer'Address, GNU_Footer'Length); end if; case Format is when GCC_GNU | GCC_Object_List | GCC_Option_List => Close (Resp_File, Closing_Status); Name_2 := Name_1; Tempdir.Create_Temp_File (Resp_File, Name => Name_1); declare Arg : constant String := Modified_Argument (Get_Name_String (Name_2)); begin for J in Resp_File_Options'Range loop Status := Write (Resp_File, Resp_File_Options (J) (1)'Address, Resp_File_Options (J)'Length); if J < Resp_File_Options'Last then Status := Write (Resp_File, ASCII.LF'Address, 1); end if; end loop; Status := Write (Resp_File, Arg (1)'Address, Arg'Length); end; Status := Write (Resp_File, ASCII.LF'Address, 1); when GCC => null; when others => Close (Resp_File, Closing_Status); end case; if Format = GCC or else Format = GCC_GNU or else Format = GCC_Object_List or else Format = GCC_Option_List then for J in Other_Arguments'Range loop declare Arg : constant String := Modified_Argument (Other_Arguments (J).all); begin Status := Write (Resp_File, Arg (1)'Address, Arg'Length); end; Status := Write (Resp_File, ASCII.LF'Address, 1); end loop; Close (Resp_File, Closing_Status); end if; end Create_Response_File; --------------------- -- Create_Sym_Link -- --------------------- procedure Create_Sym_Link (From, To : String) is function Symlink (Oldpath : System.Address; Newpath : System.Address) return Integer; pragma Import (C, Symlink, "__gnat_symlink"); C_From : constant String := From & ASCII.NUL; C_To : constant String := Relative_Path (Containing_Directory (To), Containing_Directory (From)) & Ada.Directories.Simple_Name (To) & ASCII.NUL; Result : Integer; pragma Unreferenced (Result); begin Result := Symlink (C_To'Address, C_From'Address); end Create_Sym_Link; ---------------------- -- Ensure_Directory -- ---------------------- function Ensure_Directory (Path : String) return String is begin if Path'Length = 0 or else Path (Path'Last) = Directory_Separator or else Path (Path'Last) = '/' -- on Windows check also for / then return Path; else return Path & Directory_Separator; end if; end Ensure_Directory; --------------- -- Error_Msg -- --------------- procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr) is pragma Warnings (Off, Msg); pragma Warnings (Off, Flag_Location); begin null; end Error_Msg; ----------------- -- Error_Msg_S -- ----------------- procedure Error_Msg_S (Msg : String) is pragma Warnings (Off, Msg); begin null; end Error_Msg_S; ------------------ -- Error_Msg_SC -- ------------------ procedure Error_Msg_SC (Msg : String) is pragma Warnings (Off, Msg); begin null; end Error_Msg_SC; ------------------ -- Error_Msg_SP -- ------------------ procedure Error_Msg_SP (Msg : String) is pragma Warnings (Off, Msg); begin null; end Error_Msg_SP; -------------- -- File_MD5 -- -------------- function File_MD5 (Pathname : String) return Message_Digest is use Stream_IO; C : Context; S : Stream_IO.File_Type; B : Stream_Element_Array (1 .. 100 * 1024); -- Buffer to read chunk of data L : Stream_Element_Offset; begin Open (S, In_File, Pathname); while not End_Of_File (S) loop Read (S, B, L); Update (C, B (1 .. L)); end loop; Close (S); return Digest (C); end File_MD5; ------------------------------ -- Get_Compiler_Driver_Path -- ------------------------------ function Get_Compiler_Driver_Path (Project_Tree : Project_Tree_Ref; Lang : Language_Ptr) return String_Access is begin if Lang.Config.Compiler_Driver_Path = null then declare Compiler_Name : constant String := Get_Name_String (Lang.Config.Compiler_Driver); begin if Compiler_Name = "" then return null; end if; Lang.Config.Compiler_Driver_Path := Locate_Exec_On_Path (Compiler_Name); if Lang.Config.Compiler_Driver_Path = null then Fail_Program (Project_Tree, "unable to locate """ & Compiler_Name & '"'); end if; end; end if; return Lang.Config.Compiler_Driver_Path; end Get_Compiler_Driver_Path; ---------------------------- -- Find_Binding_Languages -- ---------------------------- procedure Find_Binding_Languages (Tree : Project_Tree_Ref; Root_Project : Project_Id) is Data : constant Builder_Data_Access := Builder_Data (Tree); B_Index : Binding_Data; Language_Name : Name_Id; Binder_Driver_Name : File_Name_Type := No_File; Binder_Driver_Path : String_Access; Binder_Prefix : Name_Id; Language : Language_Ptr; Config : Language_Config; Project : Project_List; begin -- Have we already processed this tree ? if Data.There_Are_Binder_Drivers and then Data.Binding /= null then return; end if; if Current_Verbosity = High then Debug_Output ("Find_Binding_Languages for", Debug_Name (Tree)); end if; Data.There_Are_Binder_Drivers := False; Project := Tree.Projects; while Project /= null loop Language := Project.Project.Languages; while Language /= No_Language_Index loop Config := Language.Config; Binder_Driver_Name := Config.Binder_Driver; if Language.First_Source /= No_Source and then Binder_Driver_Name /= No_File then Data.There_Are_Binder_Drivers := True; Language_Name := Language.Name; B_Index := Data.Binding; while B_Index /= null and then B_Index.Language_Name /= Language_Name loop B_Index := B_Index.Next; end loop; if B_Index = null then Get_Name_String (Binder_Driver_Name); Binder_Driver_Path := Locate_Exec_On_Path (Name_Buffer (1 .. Name_Len)); if Binder_Driver_Path = null then Fail_Program (Tree, "unable to find binder driver " & Name_Buffer (1 .. Name_Len)); end if; if Current_Verbosity = High then Debug_Output ("Binder_Driver=" & Binder_Driver_Path.all & " for Lang", Language_Name); end if; if Config.Binder_Prefix = No_Name then Binder_Prefix := Empty_String; else Binder_Prefix := Config.Binder_Prefix; end if; B_Index := Data.Binding; while B_Index /= null loop if Binder_Prefix = B_Index.Binder_Prefix then Fail_Program (Tree, "binding prefix cannot be the same for" & " two languages"); end if; B_Index := B_Index.Next; end loop; Data.Binding := new Binding_Data_Record' (Language => Language, Language_Name => Language_Name, Binder_Driver_Name => Binder_Driver_Name, Binder_Driver_Path => Binder_Driver_Path, Binder_Prefix => Binder_Prefix, Next => Data.Binding); end if; end if; Language := Language.Next; end loop; Project := Project.Next; end loop; if Root_Project.Qualifier = Aggregate then declare Agg : Aggregated_Project_List := Root_Project.Aggregated_Projects; begin while Agg /= null loop Find_Binding_Languages (Agg.Tree, Agg.Project); Agg := Agg.Next; end loop; end; end if; end Find_Binding_Languages; ---------------- -- Get_Target -- ---------------- function Get_Target return String is begin if Target_Name = null or else Target_Name.all = "" then return GprConfig.Sdefault.Hostname; else return Target_Name.all; end if; end Get_Target; -------------------- -- Locate_Runtime -- -------------------- procedure Locate_Runtime (Project_Tree : Project_Tree_Ref; Language : Name_Id) is function Is_Base_Name (Path : String) return Boolean; -- Returns True if Path has no directory separator ------------------ -- Is_Base_Name -- ------------------ function Is_Base_Name (Path : String) return Boolean is begin for I in Path'Range loop if Path (I) = Directory_Separator or else Path (I) = '/' then return False; end if; end loop; return True; end Is_Base_Name; function Find_Rts_In_Path is new Prj.Env.Find_Name_In_Path (Check_Filename => Is_Directory); RTS_Name : constant String := Prj.Conf.Runtime_Name_For (Language); Full_Path : String_Access; begin if not Is_Base_Name (RTS_Name) then Full_Path := Find_Rts_In_Path (Root_Environment.Project_Path, RTS_Name); if Full_Path = null then Fail_Program (Project_Tree, "cannot find RTS " & RTS_Name); end if; Prj.Conf.Set_Runtime_For (Language, Normalize_Pathname (Full_Path.all)); Free (Full_Path); end if; end Locate_Runtime; ------------------------------ -- Look_For_Default_Project -- ------------------------------ procedure Look_For_Default_Project is begin No_Project_File_Found := False; if Is_Regular_File (Default_Project_File_Name) then Project_File_Name := new String'(Default_Project_File_Name); else -- Check if there is a single project file in the current -- directory. If there is one and only one, use it. declare Dir : Dir_Type; Str : String (1 .. 255); Last : Natural; Single : String_Access := null; begin No_Project_File_Found := True; Open (Dir, "."); loop Read (Dir, Str, Last); exit when Last = 0; if Last > Project_File_Extension'Length and then Is_Regular_File (Str (1 .. Last)) then Canonical_Case_File_Name (Str (1 .. Last)); if Str (Last - Project_File_Extension'Length + 1 .. Last) = Project_File_Extension then No_Project_File_Found := False; if Single = null then Single := new String'(Str (1 .. Last)); else -- There are several project files in the current -- directory. Reset Single to null and exit. Single := null; exit; end if; end if; end if; end loop; Close (Dir); Project_File_Name := Single; end; if No_Project_File_Found then Project_File_Name := new String'(Executable_Prefix_Path & Implicit_Project_File_Path); if not Is_Regular_File (Project_File_Name.all) then Project_File_Name := null; end if; end if; end if; if (not Quiet_Output) and then Project_File_Name /= null then Write_Str ("using project file "); Write_Line (Project_File_Name.all); end if; end Look_For_Default_Project; ------------------ -- Partial_Name -- ------------------ function Partial_Name (Lib_Name : String; Number : Natural; Object_Suffix : String) return String is Img : constant String := Number'Img; begin return Partial_Prefix & Lib_Name & '_' & Img (Img'First + 1 .. Img'Last) & Object_Suffix; end Partial_Name; -------------------------------- -- Project_Compilation_Failed -- -------------------------------- function Project_Compilation_Failed (Prj : Project_Id; Recursive : Boolean := True) return Boolean is use Project_Name_Boolean_Htable; begin if Get (Project_Failure, Prj.Name) then return True; elsif not Recursive then return False; else -- Check all imported projects directly or indirectly declare Plist : Project_List := Prj.All_Imported_Projects; begin while Plist /= null loop if Get (Project_Failure, Plist.Project.Name) then return True; else Plist := Plist.Next; end if; end loop; return False; end; end if; end Project_Compilation_Failed; ----------------------------------- -- Set_Failed_Compilation_Status -- ----------------------------------- procedure Set_Failed_Compilation_Status (Prj : Project_Id) is begin Project_Name_Boolean_Htable.Set (Project_Failure, Prj.Name, True); end Set_Failed_Compilation_Status; ----------------------- -- Shared_Libgcc_Dir -- ----------------------- function Shared_Libgcc_Dir (Run_Time_Dir : String) return String is Path : String (1 .. Run_Time_Dir'Length + 15); Path_Last : constant Natural := Run_Time_Dir'Length; GCC_Index : Natural := 0; begin Path (1 .. Path_Last) := Run_Time_Dir; GCC_Index := Index (Path (1 .. Path_Last), "gcc-lib"); if GCC_Index /= 0 then -- This is gcc 2.8.2: the shared version of libgcc is -- located in the parent directory of "gcc-lib". GCC_Index := GCC_Index - 1; else GCC_Index := Index (Path (1 .. Path_Last), "/lib/"); if GCC_Index = 0 then GCC_Index := Index (Path (1 .. Path_Last), Directory_Separator & "lib" & Directory_Separator); end if; if GCC_Index /= 0 then -- We have found "lib" as a subdirectory in the runtime dir path. -- The declare Subdir : constant String := Interfaces.C.Strings.Value (Libgcc_Subdir_Ptr); begin Path (GCC_Index + 1 .. GCC_Index + Subdir'Length) := Subdir; GCC_Index := GCC_Index + Subdir'Length; end; end if; end if; return Path (1 .. GCC_Index); end Shared_Libgcc_Dir; --------------------- -- Need_To_Compile -- --------------------- procedure Need_To_Compile (Source : Prj.Source_Id; Tree : Project_Tree_Ref; In_Project : Project_Id; Must_Compile : out Boolean; The_ALI : out ALI.ALI_Id; Object_Check : Boolean; Always_Compile : Boolean) is Source_Path : constant String := Get_Name_String (Source.Path.Display_Name); C_Source_Path : constant String := Get_Name_String (Source.Path.Name); Runtime_Source_Dir : constant Name_Id := Source.Language.Config.Runtime_Source_Dir; Start : Natural; Finish : Natural; Last_Obj : Natural; Stamp : Time_Stamp_Type; Looping : Boolean := False; -- Set to True at the end of the first Big_Loop for Makefile fragments Source_In_Dependencies : Boolean := False; -- Set True if source was found in dependency file of its object file C_Object_Name : String_Access := null; -- The canonical file name for the object file Object_Path : String_Access := null; -- The absolute path name for the object file Switches_Name : String_Access := null; -- The file name of the file that contains the switches that were used -- in the last compilation. Num_Ext : Natural; -- Number of extending projects ALI_Project : Project_Id; -- If the ALI file is in the object directory of a project, this is -- the project id. Externally_Built : constant Boolean := In_Project.Externally_Built; -- True if the project of the source is externally built function Process_Makefile_Deps (Dep_Name, Obj_Dir : String) return Boolean; function Process_ALI_Deps return Boolean; function Process_ALI_Closure_Deps return Boolean; -- Process the dependencies for the current source file for the various -- dependency modes. -- They return True if the file needs to be recompiled procedure Cleanup; -- Cleanup local variables --------------------------- -- Process_Makefile_Deps -- --------------------------- function Process_Makefile_Deps (Dep_Name, Obj_Dir : String) return Boolean is Dep_File : Prj.Util.Text_File; begin Open (Dep_File, Dep_Name); -- If dependency file cannot be open, we need to recompile -- the source. if not Is_Valid (Dep_File) then if Verbose_Mode then Write_Str (" -> could not open dependency file "); Write_Line (Dep_Name); end if; return True; end if; -- Loop Big_Loop is executed several times only when the -- dependency file contains several times -- : ... -- When there is only one of such occurence, Big_Loop is exited -- successfully at the beginning of the second loop. Big_Loop : loop declare End_Of_File_Reached : Boolean := False; Object_Found : Boolean := False; begin loop if End_Of_File (Dep_File) then End_Of_File_Reached := True; exit; end if; Get_Line (Dep_File, Name_Buffer, Name_Len); if Name_Len > 0 and then Name_Buffer (1) /= '#' then -- Skip a first line that is an empty continuation line for J in 1 .. Name_Len - 1 loop if Name_Buffer (J) /= ' ' then Object_Found := True; exit; end if; end loop; exit when Object_Found or else Name_Buffer (Name_Len) /= '\'; end if; end loop; -- If dependency file contains only empty lines or comments, -- then dependencies are unknown, and the source needs to be -- recompiled. if End_Of_File_Reached then -- If we have reached the end of file after the first -- loop, there is nothing else to do. exit Big_Loop when Looping; if Verbose_Mode then Write_Str (" -> dependency file "); Write_Str (Dep_Name); Write_Line (" is empty"); end if; Close (Dep_File); return True; end if; end; Start := 1; Finish := Index (Name_Buffer (1 .. Name_Len), ": "); if Finish = 0 then Finish := Index (Name_Buffer (1 .. Name_Len), (1 => ':', 2 => ASCII.HT)); end if; if Finish /= 0 then Last_Obj := Finish; loop Last_Obj := Last_Obj - 1; exit when Last_Obj = Start or else Name_Buffer (Last_Obj) /= ' '; end loop; while Start < Last_Obj and then Name_Buffer (Start) = ' ' loop Start := Start + 1; end loop; Canonical_Case_File_Name (Name_Buffer (Start .. Last_Obj)); end if; -- First line must start with name of object file, followed by -- colon. if Finish = 0 or else (C_Object_Name /= null and then Name_Buffer (Start .. Last_Obj) /= C_Object_Name.all) then if Verbose_Mode then Write_Str (" -> dependency file "); Write_Str (Dep_Name); Write_Line (" has wrong format"); if Finish = 0 then Write_Line (" no colon"); else Write_Str (" expected object file name "); Write_Str (C_Object_Name.all); Write_Str (", got "); Write_Line (Name_Buffer (Start .. Last_Obj)); end if; end if; Close (Dep_File); return True; else Start := Finish + 2; -- Process each line Line_Loop : loop declare Line : String := Name_Buffer (1 .. Name_Len); Last : Natural := Name_Len; begin Name_Loop : loop -- Find the beginning of the next source path name while Finish < Last and then Line (Start) = ' ' loop Start := Start + 1; end loop; -- Go to next line when there is a continuation -- character \ at the end of the line. exit Name_Loop when Start = Last and then Line (Start) = '\'; -- We should not be at the end of the line, without -- a continuation character \. if Start = Last then if Verbose_Mode then Write_Str (" -> dependency file "); Write_Str (Dep_Name); Write_Line (" has wrong format"); end if; Close (Dep_File); return True; end if; -- Look for the end of the source path name Finish := Start; while Finish < Last loop if Line (Finish) = '\' then -- On Windows, a '\' is part of the path -- name, except when it is not the first -- character followed by another '\' or by a -- space. On other platforms, when we are -- getting a '\' that is not the last -- character of the line, the next character -- is part of the path name, even if it is a -- space. if On_Windows and then Finish = Start and then Line (Finish + 1) = '\' then Finish := Finish + 2; elsif On_Windows and then Line (Finish + 1) /= '\' and then Line (Finish + 1) /= ' ' then Finish := Finish + 1; else Line (Finish .. Last - 1) := Line (Finish + 1 .. Last); Last := Last - 1; end if; else -- A space that is not preceded by '\' -- indicates the end of the path name. exit when Line (Finish + 1) = ' '; Finish := Finish + 1; end if; end loop; -- Check this source declare Src_Name : constant String := Normalize_Pathname (Name => Line (Start .. Finish), Directory => Obj_Dir, Resolve_Links => False); C_Src_Name : String := Src_Name; Src_TS : Time_Stamp_Type; Source_2 : Prj.Source_Id; begin Canonical_Case_File_Name (C_Src_Name); -- If it is original source, set -- Source_In_Dependencies. if C_Src_Name = C_Source_Path then Source_In_Dependencies := True; end if; -- Get the time stamp of the source, which is not -- necessarily a source of any project. Name_Len := 0; Add_Str_To_Name_Buffer (Src_Name); Src_TS := File_Stamp (File_Name_Type'(Name_Find)); -- If the source does not exist, we need to -- recompile. if Src_TS = Empty_Time_Stamp then if Verbose_Mode then Write_Str (" -> source "); Write_Str (Src_Name); Write_Line (" does not exist"); end if; Close (Dep_File); return True; -- If the source has been modified after the -- object file, we need to recompile. elsif Src_TS > Source.Object_TS and then Object_Check and then Source.Language.Config.Object_Generated then if Verbose_Mode then Write_Str (" -> source "); Write_Str (Src_Name); Write_Line (" has time stamp later than object file"); end if; Close (Dep_File); return True; else Name_Len := Src_Name'Length; Name_Buffer (1 .. Name_Len) := Src_Name; Source_2 := Source_Paths_Htable.Get (Tree.Source_Paths_HT, Name_Find); if Source_2 /= No_Source and then Source_2.Replaced_By /= No_Source then if Verbose_Mode then Write_Str (" -> source "); Write_Str (Src_Name); Write_Line (" has been replaced"); end if; Close (Dep_File); return True; end if; end if; end; -- If the source path name ends the line, we are -- done. exit Line_Loop when Finish = Last; -- Go get the next source on the line Start := Finish + 1; end loop Name_Loop; end; -- If we are here, we had a continuation character \ at -- the end of the line, so we continue with the next -- line. Get_Line (Dep_File, Name_Buffer, Name_Len); Start := 1; Finish := 1; end loop Line_Loop; end if; -- Set Looping at the end of the first loop Looping := True; end loop Big_Loop; Close (Dep_File); -- If the original sources were not in the dependency file, then -- we need to recompile. It may mean that we are using a different -- source (different variant) for this object file. if not Source_In_Dependencies then if Verbose_Mode then Write_Str (" -> source "); Write_Str (Source_Path); Write_Line (" is not in the dependencies"); end if; return True; end if; return False; end Process_Makefile_Deps; ---------------------- -- Process_ALI_Deps -- ---------------------- function Process_ALI_Deps return Boolean is Text : Text_Buffer_Ptr := Read_Library_Info_From_Full (File_Name_Type (Source.Dep_Path), Source.Dep_TS'Access); Sfile : File_Name_Type; Dep_Src : Prj.Source_Id; Proj : Project_Id; Found : Boolean := False; begin if Text = null then if Verbose_Mode then Write_Str (" -> cannot read "); Write_Line (Get_Name_String (Source.Dep_Path)); end if; return True; end if; -- Read only the necessary lines of the ALI file The_ALI := ALI.Scan_ALI (File_Name_Type (Source.Dep_Path), Text, Ignore_ED => False, Err => True, Ignore_Errors => True, Read_Lines => "PDW"); Free (Text); if The_ALI = ALI.No_ALI_Id then if Verbose_Mode then Write_Str (" -> "); Write_Str (Get_Name_String (Source.Dep_Path)); Write_Line (" is incorrectly formatted"); end if; return True; end if; if ALI.ALIs.Table (The_ALI).Compile_Errors then if Verbose_Mode then Write_Line (" -> last compilation had errors"); end if; return True; end if; if Object_Check and then ALI.ALIs.Table (The_ALI).No_Object then if Verbose_Mode then Write_Line (" -> no object generated during last compilation"); end if; return True; end if; if Check_Source_Info_In_ALI (The_ALI, Tree) = No_Name then return True; end if; -- We need to check that the ALI file is in the correct object -- directory. If it is in the object directory of a project -- that is extended and it depends on a source that is in one -- of its extending projects, then the ALI file is not in the -- correct object directory. ALI_Project := Source.Object_Project; -- Count the extending projects Num_Ext := 0; Proj := ALI_Project; loop Proj := Proj.Extended_By; exit when Proj = No_Project; Num_Ext := Num_Ext + 1; end loop; declare Projects : array (1 .. Num_Ext) of Project_Id; begin Proj := ALI_Project; for J in Projects'Range loop Proj := Proj.Extended_By; Projects (J) := Proj; end loop; for D in ALI.ALIs.Table (The_ALI).First_Sdep .. ALI.ALIs.Table (The_ALI).Last_Sdep loop Sfile := ALI.Sdep.Table (D).Sfile; if ALI.Sdep.Table (D).Stamp /= Empty_Time_Stamp then Dep_Src := Source_Files_Htable.Get (Tree.Source_Files_HT, Sfile); Found := False; while Dep_Src /= No_Source loop Initialize_Source_Record (Dep_Src); if not Dep_Src.Locally_Removed and then Dep_Src.Unit /= No_Unit_Index then Found := True; if Opt.Minimal_Recompilation and then ALI.Sdep.Table (D).Stamp /= Dep_Src.Source_TS then -- If minimal recompilation is in action, replace -- the stamp of the source file in the table if -- checksums match. declare Source_Index : Source_File_Index; use Scans; begin Source_Index := Sinput.C.Load_File (Get_Name_String (Dep_Src.Path.Display_Name)); if Source_Index /= No_Source_File then Scanner.Initialize_Scanner (Source_Index); -- Make sure that the project language -- reserved words are not recognized as -- reserved words, but as identifiers. Set_Name_Table_Byte (Name_Project, 0); Set_Name_Table_Byte (Name_Extends, 0); Set_Name_Table_Byte (Name_External, 0); Set_Name_Table_Byte (Name_External_As_List, 0); -- Scan the complete file to compute its -- checksum. loop Scanner.Scan; exit when Token = Tok_EOF; end loop; if Scans.Checksum = ALI.Sdep.Table (D).Checksum then if Verbose_Mode then Write_Str (" "); Write_Str (Get_Name_String (ALI.Sdep.Table (D).Sfile)); Write_Str (": up to date, " & "different timestamps " & "but same checksum"); Write_Eol; end if; ALI.Sdep.Table (D).Stamp := Dep_Src.Source_TS; end if; end if; -- To avoid using too much memory, free the -- memory allocated. Sinput.P.Clear_Source_File_Table; end; end if; if ALI.Sdep.Table (D).Stamp /= Dep_Src.Source_TS then if Verbose_Mode then Write_Str (" -> different time stamp for "); Write_Line (Get_Name_String (Sfile)); if Debug.Debug_Flag_T then Write_Str (" in ALI file: "); Write_Line (String (ALI.Sdep.Table (D).Stamp)); Write_Str (" actual file: "); Write_Line (String (Dep_Src.Source_TS)); end if; end if; return True; else for J in Projects'Range loop if Dep_Src.Project = Projects (J) then if Verbose_Mode then Write_Line (" -> wrong object directory"); end if; return True; end if; end loop; exit; end if; end if; Dep_Src := Dep_Src.Next_With_File_Name; end loop; -- If the source was not found and the runtime source -- directory is defined, check if the file exists there, and -- if it does, check its timestamp. if not Found and then (Runtime_Source_Dir /= No_Name or else Is_Absolute_Path (Get_Name_String (Sfile))) then Name_Len := 0; if not Is_Absolute_Path (Get_Name_String (Sfile)) then Get_Name_String (Runtime_Source_Dir); Add_Char_To_Name_Buffer (Directory_Separator); end if; Add_Str_To_Name_Buffer (Get_Name_String (Sfile)); declare TS : constant Time_Stamp_Type := Source_File_Stamp (Name_Find); begin if TS /= Empty_Time_Stamp and then TS /= ALI.Sdep.Table (D).Stamp then if Verbose_Mode then Write_Str (" -> different time stamp for "); Write_Line (Get_Name_String (Sfile)); if Debug.Debug_Flag_T then Write_Str (" in ALI file: "); Write_Line (String (ALI.Sdep.Table (D).Stamp)); Write_Str (" actual file: "); Write_Line (String (TS)); end if; end if; return True; end if; end; end if; end if; end loop; end; return False; end Process_ALI_Deps; package Processed_Sources is new Table.Table (Table_Component_Type => Prj.Source_Id, Table_Index_Type => Positive, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gpr_Util.Processed_ALIs"); ------------------------------ -- Process_ALI_Closure_Deps -- ------------------------------ function Process_ALI_Closure_Deps return Boolean is Text : Text_Buffer_Ptr := Read_Library_Info_From_Full (File_Name_Type (Source.Dep_Path), Source.Dep_TS'Access); Sfile : File_Name_Type; Dep_Src : Prj.Source_Id; Proj : Project_Id; TS0 : Time_Stamp_Type; Found : Boolean := False; Last_Processed_Source : Natural := 0; Next_Source : Prj.Source_Id; Insert_Source : Boolean := False; Other_ALI : ALI.ALI_Id; begin if Text = null then if Verbose_Mode then Write_Str (" -> cannot read "); Write_Line (Get_Name_String (Source.Dep_Path)); end if; return True; end if; TS0 := File_Stamp (Source.Dep_Path); -- Read only the necessary lines of the ALI file The_ALI := ALI.Scan_ALI (File_Name_Type (Source.Dep_Path), Text, Ignore_ED => False, Err => True, Ignore_Errors => True, Read_Lines => "PDW"); Free (Text); if The_ALI = ALI.No_ALI_Id then if Verbose_Mode then Write_Str (" -> "); Write_Str (Get_Name_String (Source.Dep_Path)); Write_Line (" is incorrectly formatted"); end if; return True; end if; if ALI.ALIs.Table (The_ALI).Compile_Errors then if Verbose_Mode then Write_Line (" -> last compilation had errors"); end if; return True; end if; if Object_Check and then ALI.ALIs.Table (The_ALI).No_Object then if Verbose_Mode then Write_Line (" -> no object generated during last compilation"); end if; return True; end if; if Check_Source_Info_In_ALI (The_ALI, Tree) = No_Name then return True; end if; Processed_Sources.Init; Processed_Sources.Append (Source); Last_Processed_Source := 2; -- We need to check that the ALI file is in the correct object -- directory. If it is in the object directory of a project -- that is extended and it depends on a source that is in one -- of its extending projects, then the ALI file is not in the -- correct object directory. ALI_Project := Source.Object_Project; -- Count the extending projects Num_Ext := 0; Proj := ALI_Project; loop Proj := Proj.Extended_By; exit when Proj = No_Project; Num_Ext := Num_Ext + 1; end loop; declare Projects : array (1 .. Num_Ext) of Project_Id; begin Proj := ALI_Project; for J in Projects'Range loop Proj := Proj.Extended_By; Projects (J) := Proj; end loop; for D in ALI.ALIs.Table (The_ALI).First_Sdep .. ALI.ALIs.Table (The_ALI).Last_Sdep loop Sfile := ALI.Sdep.Table (D).Sfile; if ALI.Sdep.Table (D).Stamp /= Empty_Time_Stamp then Dep_Src := Source_Files_Htable.Get (Tree.Source_Files_HT, Sfile); Found := False; if Dep_Src /= No_Source then Insert_Source := True; for J in 1 .. Processed_Sources.Last loop if Processed_Sources.Table (J) = Dep_Src then Insert_Source := False; exit; end if; end loop; if Insert_Source then Processed_Sources.Append (Dep_Src); end if; end if; while Dep_Src /= No_Source loop Initialize_Source_Record (Dep_Src); if not Dep_Src.Locally_Removed and then Dep_Src.Unit /= No_Unit_Index then Found := True; if Opt.Minimal_Recompilation and then ALI.Sdep.Table (D).Stamp /= Dep_Src.Source_TS then -- If minimal recompilation is in action, replace -- the stamp of the source file in the table if -- checksums match. declare Source_Index : Source_File_Index; use Scans; begin Source_Index := Sinput.C.Load_File (Get_Name_String (Dep_Src.Path.Display_Name)); if Source_Index /= No_Source_File then Scanner.Initialize_Scanner (Source_Index); -- Make sure that the project language -- reserved words are not recognized as -- reserved words, but as identifiers. Set_Name_Table_Byte (Name_Project, 0); Set_Name_Table_Byte (Name_Extends, 0); Set_Name_Table_Byte (Name_External, 0); Set_Name_Table_Byte (Name_External_As_List, 0); -- Scan the complete file to compute its -- checksum. loop Scanner.Scan; exit when Token = Tok_EOF; end loop; if Scans.Checksum = ALI.Sdep.Table (D).Checksum then if Verbose_Mode then Write_Str (" "); Write_Str (Get_Name_String (ALI.Sdep.Table (D).Sfile)); Write_Str (": up to date, " & "different timestamps " & "but same checksum"); Write_Eol; end if; ALI.Sdep.Table (D).Stamp := Dep_Src.Source_TS; end if; end if; -- To avoid using too much memory, free the -- memory allocated. Sinput.P.Clear_Source_File_Table; end; end if; if ALI.Sdep.Table (D).Stamp /= Dep_Src.Source_TS then if Verbose_Mode then Write_Str (" -> different time stamp for "); Write_Line (Get_Name_String (Sfile)); if Debug.Debug_Flag_T then Write_Str (" in ALI file: "); Write_Line (String (ALI.Sdep.Table (D).Stamp)); Write_Str (" actual file: "); Write_Line (String (Dep_Src.Source_TS)); end if; end if; return True; else for J in Projects'Range loop if Dep_Src.Project = Projects (J) then if Verbose_Mode then Write_Line (" -> wrong object directory"); end if; return True; end if; end loop; exit; end if; end if; Dep_Src := Dep_Src.Next_With_File_Name; end loop; -- If the source was not found and the runtime source -- directory is defined, check if the file exists there, and -- if it does, check its timestamp. if not Found and then Runtime_Source_Dir /= No_Name then Get_Name_String (Runtime_Source_Dir); Add_Char_To_Name_Buffer (Directory_Separator); Add_Str_To_Name_Buffer (Get_Name_String (Sfile)); declare TS1 : constant Time_Stamp_Type := Source_File_Stamp (Name_Find); begin if TS1 /= Empty_Time_Stamp and then TS1 /= ALI.Sdep.Table (D).Stamp then if Verbose_Mode then Write_Str (" -> different time stamp for "); Write_Line (Get_Name_String (Sfile)); if Debug.Debug_Flag_T then Write_Str (" in ALI file: "); Write_Line (String (ALI.Sdep.Table (D).Stamp)); Write_Str (" actual file: "); Write_Line (String (TS1)); end if; end if; return True; end if; end; end if; end if; end loop; end; while Last_Processed_Source <= Processed_Sources.Last loop Next_Source := Processed_Sources.Table (Last_Processed_Source); Text := Read_Library_Info_From_Full (File_Name_Type (Next_Source.Dep_Path), Next_Source.Dep_TS'Access); Last_Processed_Source := Last_Processed_Source + 1; if Text = null then if Verbose_Mode then Write_Str (" -> cannot read "); Write_Line (Get_Name_String (Next_Source.Dep_Path)); end if; return True; end if; -- Read only the necessary lines of the ALI file Other_ALI := ALI.Scan_ALI (File_Name_Type (Next_Source.Dep_Path), Text, Ignore_ED => False, Err => True, Ignore_Errors => True, Read_Lines => "PDW"); Free (Text); if Other_ALI = ALI.No_ALI_Id then if Verbose_Mode then Write_Str (" -> "); Write_Str (Get_Name_String (Next_Source.Dep_Path)); Write_Line (" is incorrectly formatted"); end if; return True; end if; if ALI.ALIs.Table (Other_ALI).Compile_Errors then if Verbose_Mode then Write_Str (" -> last compilation of "); Write_Str (Get_Name_String (Next_Source.Dep_Path)); Write_Line (" had errors"); end if; return True; end if; for D in ALI.ALIs.Table (Other_ALI).First_Sdep .. ALI.ALIs.Table (Other_ALI).Last_Sdep loop Sfile := ALI.Sdep.Table (D).Sfile; if ALI.Sdep.Table (D).Stamp /= Empty_Time_Stamp then Dep_Src := Source_Files_Htable.Get (Tree.Source_Files_HT, Sfile); Found := False; if Dep_Src /= No_Source then Insert_Source := True; for J in 1 .. Processed_Sources.Last loop if Processed_Sources.Table (J) = Dep_Src then Insert_Source := False; exit; end if; end loop; if Insert_Source then Processed_Sources.Append (Dep_Src); end if; end if; while Dep_Src /= No_Source loop Initialize_Source_Record (Dep_Src); if not Dep_Src.Locally_Removed and then Dep_Src.Unit /= No_Unit_Index then Found := True; if Opt.Minimal_Recompilation and then ALI.Sdep.Table (D).Stamp /= Dep_Src.Source_TS then -- If minimal recompilation is in action, replace -- the stamp of the source file in the table if -- checksums match. declare Source_Index : Source_File_Index; use Scans; begin Source_Index := Sinput.C.Load_File (Get_Name_String (Dep_Src.Path.Display_Name)); if Source_Index /= No_Source_File then Scanner.Initialize_Scanner (Source_Index); -- Make sure that the project language -- reserved words are not recognized as -- reserved words, but as identifiers. Set_Name_Table_Byte (Name_Project, 0); Set_Name_Table_Byte (Name_Extends, 0); Set_Name_Table_Byte (Name_External, 0); Set_Name_Table_Byte (Name_External_As_List, 0); -- Scan the complete file to compute its -- checksum. loop Scanner.Scan; exit when Token = Tok_EOF; end loop; if Scans.Checksum = ALI.Sdep.Table (D).Checksum then ALI.Sdep.Table (D).Stamp := Dep_Src.Source_TS; end if; end if; -- To avoid using too much memory, free the -- memory allocated. Sinput.P.Clear_Source_File_Table; end; end if; if ALI.Sdep.Table (D).Stamp /= Dep_Src.Source_TS then if Verbose_Mode then Write_Str (" -> different time stamp for "); Write_Line (Get_Name_String (Sfile)); if Debug.Debug_Flag_T then Write_Str (" in ALI file: "); Write_Line (String (ALI.Sdep.Table (D).Stamp)); Write_Str (" actual file: "); Write_Line (String (Dep_Src.Source_TS)); end if; end if; return True; elsif TS0 < Dep_Src.Source_TS then if Verbose_Mode then Write_Str (" -> file "); Write_Str (Get_Name_String (Dep_Src.Path.Display_Name)); Write_Line (" later than ALI file"); end if; return True; end if; end if; Dep_Src := Dep_Src.Next_With_File_Name; end loop; end if; end loop; end loop; return False; end Process_ALI_Closure_Deps; ------------- -- Cleanup -- ------------- procedure Cleanup is begin Free (C_Object_Name); Free (Object_Path); Free (Switches_Name); end Cleanup; begin The_ALI := ALI.No_ALI_Id; -- Never attempt to compile header files if Source.Language.Config.Kind = File_Based and then Source.Kind = Spec then Must_Compile := False; return; end if; if Force_Compilations then Must_Compile := Always_Compile or else (not Externally_Built); return; end if; -- No need to compile if there is no "compiler" if Length_Of_Name (Source.Language.Config.Compiler_Driver) = 0 then Must_Compile := False; return; end if; if Source.Language.Config.Object_Generated and then Object_Check then C_Object_Name := new String'(Get_Name_String (Source.Object)); Canonical_Case_File_Name (C_Object_Name.all); Object_Path := new String'(Get_Name_String (Source.Object_Path)); if Source.Switches_Path /= No_Path then Switches_Name := new String'(Get_Name_String (Source.Switches_Path)); end if; end if; if Verbose_Mode and then Verbosity_Level > Opt.Low then Write_Str (" Checking "); Write_Str (Source_Path); if Source.Index /= 0 then Write_Str (" at "); Write_Int (Source.Index); end if; Write_Line (" ... "); end if; -- No need to compile if project is externally built if Externally_Built then if Verbose_Mode then Write_Line (" project is externally built"); end if; Must_Compile := False; Cleanup; return; end if; if not Source.Language.Config.Object_Generated then -- If no object file is generated, the "compiler" need to be invoked -- if there is no dependency file. if Source.Language.Config.Dependency_Kind = None then if Verbose_Mode then Write_Line (" -> no object file generated"); end if; Must_Compile := True; Cleanup; return; end if; elsif Object_Check then -- If object file does not exist, of course source need to be -- compiled. if Source.Object_TS = Empty_Time_Stamp then if Verbose_Mode then Write_Str (" -> object file "); Write_Str (Object_Path.all); Write_Line (" does not exist"); end if; Must_Compile := True; Cleanup; return; end if; -- If the object file has been created before the last modification -- of the source, the source need to be recompiled. if (not Opt.Minimal_Recompilation) and then Source.Object_TS < Source.Source_TS then if Verbose_Mode then Write_Str (" -> object file "); Write_Str (Object_Path.all); Write_Line (" has time stamp earlier than source"); end if; Must_Compile := True; Cleanup; return; end if; if Verbose_Mode and then Debug.Debug_Flag_T then Write_Str (" object file "); Write_Str (Object_Path.all); Write_Str (": "); Write_Line (String (Source.Object_TS)); Write_Str (" source file: "); Write_Line (String (Source.Source_TS)); end if; end if; if Source.Language.Config.Dependency_Kind /= None then -- If there is no dependency file, then the source needs to be -- recompiled and the dependency file need to be created. Stamp := File_Time_Stamp (Source.Dep_Path, Source.Dep_TS'Access); if Stamp = Empty_Time_Stamp then if Verbose_Mode then Write_Str (" -> dependency file "); Write_Str (Get_Name_String (Source.Dep_Path)); Write_Line (" does not exist"); end if; Must_Compile := True; Cleanup; return; end if; -- If the ALI file has been created after the object file, we need -- to recompile. if Object_Check and then (Source.Language.Config.Dependency_Kind = ALI_File or else Source.Language.Config.Dependency_Kind = ALI_Closure) and then Source.Object_TS < Stamp then if Verbose_Mode then Write_Str (" -> ALI file "); Write_Str (Get_Name_String (Source.Dep_Path)); Write_Line (" has timestamp earlier than object file"); end if; Must_Compile := True; Cleanup; return; end if; -- The source needs to be recompiled if the source has been modified -- after the dependency file has been created. if not Opt.Minimal_Recompilation and then Stamp < Source.Source_TS then if Verbose_Mode then Write_Str (" -> dependency file "); Write_Str (Get_Name_String (Source.Dep_Path)); Write_Line (" has time stamp earlier than source"); end if; Must_Compile := True; Cleanup; return; end if; end if; -- If we are checking the switches and there is no switches file, then -- the source needs to be recompiled and the switches file need to be -- created. if Check_Switches and then Switches_Name /= null then if Source.Switches_TS = Empty_Time_Stamp then if Verbose_Mode then Write_Str (" -> switches file "); Write_Str (Switches_Name.all); Write_Line (" does not exist"); end if; Must_Compile := True; Cleanup; return; end if; -- The source needs to be recompiled if the source has been modified -- after the switches file has been created. if not Opt.Minimal_Recompilation and then Source.Switches_TS < Source.Source_TS then if Verbose_Mode then Write_Str (" -> switches file "); Write_Str (Switches_Name.all); Write_Line (" has time stamp earlier than source"); end if; Must_Compile := True; Cleanup; return; end if; end if; case Source.Language.Config.Dependency_Kind is when None => null; when Makefile => if Process_Makefile_Deps (Get_Name_String (Source.Dep_Path), Get_Name_String (Source.Project.Object_Directory.Display_Name)) then Must_Compile := True; Cleanup; return; end if; when ALI_File => if Process_ALI_Deps then Must_Compile := True; Cleanup; return; end if; when ALI_Closure => if Process_ALI_Closure_Deps then Must_Compile := True; Cleanup; return; end if; end case; -- If we are here, then everything is OK, and we don't need -- to recompile. if (not Object_Check) and then Verbose_Mode then Write_Line (" -> up to date"); end if; Must_Compile := False; Cleanup; end Need_To_Compile; --------------- -- Knowledge -- --------------- package body Knowledge is separate; --------------- -- Post_Scan -- --------------- procedure Post_Scan is begin null; end Post_Scan; ------------------- -- Relative_Path -- ------------------- function Relative_Path (Pathname, To : String) return String is Dir_Sep_Map : constant Character_Mapping := To_Mapping ("\", "/"); P : String (1 .. Pathname'Length) := Pathname; T : String (1 .. To'Length) := To; Pi : Natural; -- common prefix ending N : Natural := 0; begin pragma Assert (Is_Absolute_Path (Pathname)); pragma Assert (Is_Absolute_Path (To)); -- Use canonical directory separator Translate (Source => P, Mapping => Dir_Sep_Map); Translate (Source => T, Mapping => Dir_Sep_Map); -- First check for common prefix Pi := 1; while Pi < P'Last and then Pi < T'Last and then P (Pi) = T (Pi) loop Pi := Pi + 1; end loop; -- Cut common prefix at a directory separator while Pi > P'First and then P (Pi) /= '/' loop Pi := Pi - 1; end loop; -- Count directory under prefix in P, these will be replaced by the -- corresponding number of "..". N := Count (T (Pi + 1 .. T'Last), "/"); if T (T'Last) /= '/' then N := N + 1; end if; return N * "../" & Ensure_Directory (P (Pi + 1 .. P'Last)); end Relative_Path; -------------- -- UTC_Time -- -------------- function UTC_Time return Time_Stamp_Type is Now : constant Time := Clock - Duration (UTC_Time_Offset); begin return Time_Stamp_Type (Image (Now, "%Y%m%d%H%M%S")); end UTC_Time; ---------------- -- Check_Diff -- ---------------- function Check_Diff (Ts1, Ts2 : Time_Stamp_Type; Max_Drift : Duration := 5.0) return Boolean is use GNAT.Calendar; function Get (T : String) return Time is (Time_Of (Year => Year_Number'Value (T (T'First .. T'First + 3)), Month => Month_Number'Value (T (T'First + 4 .. T'First + 5)), Day => Day_Number'Value (T (T'First + 6 .. T'First + 7)), Hour => Hour_Number'Value (T (T'First + 8 .. T'First + 9)), Minute => Minute_Number'Value (T (T'First + 10 .. T'First + 11)), Second => Second_Number'Value (T (T'First + 12 .. T'First + 13)))); T1 : constant Time := Get (String (Ts1)); T2 : constant Time := Get (String (Ts2)); begin return abs (T1 - T2) <= Max_Drift; end Check_Diff; ------------------- -- To_Time_Stamp -- ------------------- function To_Time_Stamp (Time : Calendar.Time) return Types.Time_Stamp_Type is begin return Time_Stamp_Type (Image (Time, "%Y%m%d%H%M%S")); end To_Time_Stamp; end Gpr_Util; gprbuild-gpl-2014-src/src/gprbuild-compilation-process.adb0000644000076700001450000002044612323721731023200 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . P R O C E S S -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Containers.Indefinite_Ordered_Maps; with Ada.Exceptions; use Ada.Exceptions; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Output; use Output; with Gpr_Util; use Gpr_Util; with Gprbuild.Compilation.Result; with Gprbuild.Compilation.Slave; package body Gprbuild.Compilation.Process is use Ada; package Env_Maps is new Containers.Indefinite_Ordered_Maps (String, String); -- A set of key=value package Prj_Maps is new Containers.Indefinite_Ordered_Maps (String, Env_Maps.Map, Env_Maps."<", Env_Maps."="); -- A set of project+language=map function "<" (Left, Right : Id) return Boolean is (Left.R_Pid < Right.R_Pid); package Failures_Slave_Set is new Containers.Indefinite_Ordered_Maps (Id, String); function Get_Env (Project : Project_Id; Language : String) return String; -- Get the environment for a specific project and language task type Wait_Local; type Wait_Local_Ref is access Wait_Local; WL : Wait_Local_Ref; Local_Process : Shared_Counter; Environments : Prj_Maps.Map; Failed_Proc : Failures_Slave_Set.Map; ------------------ -- Create_Local -- ------------------ function Create_Local (Pid : Process_Id) return Id is begin return Id'(Local, Pid); end Create_Local; ------------------- -- Create_Remote -- ------------------- function Create_Remote (Pid : Remote_Id) return Id is begin return Id'(Remote, Pid); end Create_Remote; --------------------------- -- Get_Maximum_Processes -- --------------------------- function Get_Maximum_Processes return Positive is begin return Opt.Maximum_Processes + Slave.Get_Max_Processes; end Get_Maximum_Processes; ------------- -- Get_Env -- ------------- function Get_Env (Project : Project_Id; Language : String) return String is Key : constant String := Get_Name_String (Project.Name) & "+" & Language; Res : Unbounded_String; begin if Environments.Contains (Key) then for C in Environments (Key).Iterate loop if Res /= Null_Unbounded_String then Res := Res & Opts_Sep; end if; Res := Res & Env_Maps.Key (C) & '=' & Env_Maps.Element (C); end loop; end if; return To_String (Res); end Get_Env; ------------------- -- Get_Slave_For -- ------------------- function Get_Slave_For (Pid : Id) return String is use type Failures_Slave_Set.Cursor; begin if Pid.Kind = Local then return ""; else declare Pos : constant Failures_Slave_Set.Cursor := Failed_Proc.Find (Pid); begin if Pos = Failures_Slave_Set.No_Element then return ""; else return Failures_Slave_Set.Element (Pos); end if; end; end if; end Get_Slave_For; ---------- -- Hash -- ---------- function Hash (Process : Id) return Header_Num is Modulo : constant Integer := Integer (Header_Num'Last) + 1; begin if Process.Kind = Local then return Header_Num (Pid_To_Integer (Process.Pid) mod Modulo); else return Header_Num (Process.R_Pid mod Remote_Id (Modulo)); end if; end Hash; ----------- -- Image -- ----------- function Image (Pid : Remote_Id) return String is N_Img : constant String := Remote_Id'Image (Pid); begin return N_Img (N_Img'First + 1 .. N_Img'Last); end Image; ------------------------ -- Record_Environment -- ------------------------ procedure Record_Environment (Project : Project_Id; Language : Name_Id; Name, Value : String) is Lang : constant String := Get_Name_String (Language); Key : constant String := Get_Name_String (Project.Name) & "+" & Lang; New_Item : Env_Maps.Map; begin -- Create new item, variable association New_Item.Include (Name, Value); if Environments.Contains (Key) then if Environments (Key).Contains (Name) then Environments (Key).Replace (Name, Value); else Environments (Key).Insert (Name, Value); end if; else Environments.Insert (Key, New_Item); end if; end Record_Environment; --------------------------- -- Record_Remote_Failure -- --------------------------- procedure Record_Remote_Failure (Pid : Id; Slave : String) is begin Failed_Proc.Insert (Pid, Slave); end Record_Remote_Failure; --------- -- Run -- --------- function Run (Executable : String; Options : GNAT.OS_Lib.Argument_List; Project : Project_Id; Obj_Name : String; Language : String := ""; Dep_Name : String := ""; Output_File : String := ""; Err_To_Out : Boolean := False; Force_Local : Boolean := False) return Id is Env : constant String := Get_Env (Project, Language); begin -- Initialize the task waiting for local process only in distributed -- mode. In standard mode, the process are waited for in the -- Compilation.Result.Wait procedure. if Distributed_Mode and then WL = null then WL := new Wait_Local; end if; -- Run locally first, then send jobs to remote slaves. Note that to -- build remotely we need an output file and a language, if one of -- this requirement is not fulfilled we just run the process locally. if Force_Local or else not Distributed_Mode or else Local_Process.Count < Opt.Maximum_Processes or else Output_File /= "" or else Language = "" then Run_Local : declare P : Id (Local); begin Set_Env (Env, Fail => True); if Output_File = "" then P.Pid := Non_Blocking_Spawn (Executable, Options); else P.Pid := Non_Blocking_Spawn (Executable, Options, Output_File, Err_To_Out); end if; Local_Process.Increment; return P; end Run_Local; else return Slave.Run (Project, Language, Options, Obj_Name, Dep_Name, Env); end if; end Run; ---------------- -- Wait_Local -- ---------------- task body Wait_Local is Pid : Process_Id; Status : Boolean; begin loop Local_Process.Wait_Non_Zero; Wait_Process (Pid, Status); Local_Process.Decrement; Result.Add (Id'(Local, Pid), Status); end loop; exception when E : others => Write_Line (Exception_Information (E)); OS_Exit (1); end Wait_Local; end Gprbuild.Compilation.Process; gprbuild-gpl-2014-src/src/gprbuild-compilation.adb0000644000076700001450000001036712323721731021525 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2013, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Text_IO; with Ada.Environment_Variables; use Ada; with Ada.Strings.Fixed; with GNAT.MD5; use GNAT; with GNAT.String_Split; use GNAT.String_Split; package body Gprbuild.Compilation is Last_Env_MD5 : MD5.Message_Digest := (others => <>); -- Keep last environement variable set to avoid too many system calls. -- ??? Ideally, we should set them when spawning the process, in -- which case it would be less expensive to set and could be set -- every time. ------------- -- Set_Env -- ------------- procedure Set_Env (Env : String; Fail : Boolean; Force : Boolean := False) is Env_List : Slice_Set; begin Create (Env_List, Env, String'(1 => Opts_Sep)); for K in 1 .. Slice_Count (Env_List) loop declare Var : constant String := Slice (Env_List, K); I : constant Natural := Strings.Fixed.Index (Var, "="); Sum : constant MD5.Message_Digest := MD5.Digest (Var); begin if I /= 0 then if Force or else Last_Env_MD5 /= Sum then Environment_Variables.Set (Name => Var (Var'First .. I - 1), Value => Var (I + 1 .. Var'Last)); Last_Env_MD5 := Sum; end if; elsif Var'Length > 0 then -- This is a protocol error, we do not want to fail here as -- this routine is used by gprslave. This error message should -- never been displayed anyway. Text_IO.Put_Line ("wrong environment variable, missing '=' : " & Var); if Fail then OS_Exit (1); end if; end if; end; end loop; end Set_Env; -------------------- -- Shared_Counter -- -------------------- protected body Shared_Counter is ----------- -- Count -- ----------- function Count return Natural is begin return Counter; end Count; --------------- -- Decrement -- --------------- procedure Decrement is begin Counter := Counter - 1; end Decrement; --------------- -- Increment -- --------------- procedure Increment is begin Counter := Counter + 1; end Increment; ----------- -- Reset -- ----------- procedure Reset is begin Counter := 0; end Reset; ------------------- -- Wait_Non_Zero -- ------------------- entry Wait_Non_Zero when Counter /= 0 is begin null; end Wait_Non_Zero; end Shared_Counter; end Gprbuild.Compilation; gprbuild-gpl-2014-src/src/gprinstall-db.ads0000644000076700001450000000315612323721731020162 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . D B -- -- -- -- S p e c -- -- -- -- Copyright (C) 2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ package Gprinstall.DB is procedure List; end Gprinstall.DB; gprbuild-gpl-2014-src/src/gprbuild-compilation-sync.ads0000644000076700001450000000550412323721731022515 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . S L A V E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- Synchronize data to/from the slave. The usage is: -- -- 1. call To_Slave or From_Slave for every slave to be synchronise -- 2. call Wait to wait for the synchronization to be terminated with Gprbuild.Compilation.Protocol; private package Gprbuild.Compilation.Sync is procedure To_Slave (Sync : Protocol.Sync_Kind; Channel : Protocol.Communication_Channel; Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector); -- Synchronize from from the build master to the slave depending on the -- Sync method. procedure From_Slave (Sync : Protocol.Sync_Kind; Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Included_Artifact_Patterns : Str_Vect.Vector); -- Synchronize from the slave to the build master depending on the Sync -- method. procedure Wait; -- Wait for all synchronization to be terminated end Gprbuild.Compilation.Sync; gprbuild-gpl-2014-src/src/gprlib.adb0000644000076700001450000023103012323721731016650 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R L I B -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2013, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- gprlib is called by gprmake to build the library for a library project -- file. gprlib gets it parameters from a text file and give back results -- through the same text file. with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with ALI; with Csets; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.OS_Lib; use GNAT.OS_Lib; with Gpr_Util; use Gpr_Util; with Gprexch; use Gprexch; with Hostparm; with Makeutl; use Makeutl; with Namet; use Namet; with Opt; use Opt; with Osint; with Prj; use Prj; with Snames; with Switch; use Switch; with System.Case_Util; use System.Case_Util; with Table; with Tempdir; with Types; use Types; procedure Gprlib is Shared_Libgnat_Separator : Character := '-'; -- Character between "-lgnat" or "-lgnarl" and the toolchain version. -- It is not a constant because it is changed to '_' on VMS. Size : Natural; Partial_Number : Natural; First_Object : Natural; Last_Object : Natural; Gcc_Name : constant String := "gcc"; Preserve : Attribute := Time_Stamps; -- Used by Copy_ALI_Files. Changed to None for OpenVMS, because -- Copy_Attributes always fails on VMS. Object_Suffix : constant String := Get_Target_Object_Suffix.all; -- The suffix of object files on this platform -- Switches used when spawning processes No_Main_String : constant String := "-n"; No_Main : constant String_Access := new String'(No_Main_String); Output_Switch_String : constant String := "-o"; Output_Switch : constant String_Access := new String'(Output_Switch_String); No_Warning_String : constant String := "-gnatws"; No_Warning : constant String_Access := new String'(No_Warning_String); Auto_Initialize_String : constant String := "-a"; Auto_Initialize : constant String_Access := new String'(Auto_Initialize_String); IO_File : File_Type; -- The file to get the inputs and to put the results Line : String (1 .. 1_000); Last : Natural; Exchange_File_Name : String_Access; -- Name of the exchange file GNAT_Version : String_Access := new String'("000"); -- The version of GNAT, coming from the Toolchain_Version for Ada GNAT_Version_Set : Boolean := False; -- True when the toolchain version is in the input exchange file S_Osinte_Ads : File_Name_Type := No_File; -- Name_Id for "s-osinte.ads" S_Dec_Ads : File_Name_Type := No_File; -- Name_Id for "dec.ads" G_Trasym_Ads : File_Name_Type := No_File; -- Name_Id for "g-trasym.ads" Libgnat : String_Access := new String'("-lgnat"); Libgnarl : String_Access := new String'("-lgnarl"); Libgnarl_Needed : Boolean := False; -- True if libgnarl is needed Runtime_Library_Dir : String_Access := null; -- Full path name of the Ada runtime library Current_Section : Library_Section := No_Library_Section; -- The current section when reading the exchange file No_Std_Lib_String : constant String := "-nostdlib"; Use_GNAT_Lib : Boolean := True; -- Set to False when "-nostdlib" is in the library options. When False, -- a shared library is not linked with the GNAT libraries. Standalone : Prj.Standalone := No; -- True when building a stand-alone library Copy_ALI : Boolean := True; -- Set to False if the ALI (dep files) are not to be copied into the -- library directory. This is the case for aggregate libraries, the -- dependencies are stored into the ALI directory of their corresponding -- projects. Library_Path_Name : String_Access; -- Path name of the library file package Object_Files is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprlib.Object_Files"); -- A table to store the object files of the library Last_Object_File_Index : Natural := 0; -- Index of the last object file in the Object_Files table. When building -- a Stand Alone Library, the binder generated object file will be added -- in the Object_Files table. package Options_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprlib.Options_Table"); -- A table to store the options from the exchange file package Imported_Library_Directories is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprlib.Imported_Library_Directories"); -- A table to store the directories of the imported libraries package Imported_Library_Names is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprlib.Imported_Library_Names"); -- A table to store the names of the imported libraries package ALIs is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 50, Table_Increment => 100, Table_Name => "Gprlib.Alis"); -- A table to store all of the ALI files package Interface_ALIs is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 50, Table_Increment => 100, Table_Name => "Gprlib.Interface_Alis"); -- A table to store the ALI files of the interfaces of an SAL package Other_Interfaces is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 50, Table_Increment => 100, Table_Name => "Gprlib.Other_Interfaces"); -- A table to store the interface files other than the ALI files package Binding_Options_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 5, Table_Increment => 100, Table_Name => "Gprlib.Binding_Options_Table"); -- A table to store the binding options package Leading_Library_Options_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprlib.Leading_Library_Options_Table"); -- A table to store the leading library options from the exchange file package Library_Options_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 5, Table_Increment => 100, Table_Name => "Gprlib.Library_Options_Table"); -- A table to store the library options package Library_Rpath_Options_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 5, Table_Increment => 100, Table_Name => "Gprlib.Library_Rpath_Options_Table"); -- A table to store the library rpath options package Library_Switches_Table is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 5, Table_Increment => 100, Table_Name => "Gprlib.Library_Switches_Table"); -- A table to store the switches for the imported libraries package Object_Directories is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Object_Directories"); -- A table to store the object directories of the project and of all -- the projects it extends. package Sources is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Sources"); package Generated_Sources is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Generated_Sources"); package Generated_Objects is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Generated_Objects"); package Ada_Leading_Switches is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Ada_Leading_Switches"); package Ada_Trailing_Switches is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Ada_Trailing_Switches"); Current_Language : Name_Id := No_Name; Language_Equal : constant String := "language="; Auto_Init : Boolean := False; -- True when a SAL is auto initializable Static : Boolean := False; -- True if the library is an archive No_Create : Boolean := False; -- Should the library (static or dynamic) be built Archive_Builder : String_Access := null; -- Name of the archive builder AB_Options : String_List_Access := new String_List (1 .. 10); Last_AB_Option : Natural := 0; -- Options of the archive builder First_AB_Object_Pos : Natural; Next_AB_Object_Pos : Natural; Object_Pos : Natural; -- Various indexes in AB_Options used when building an archive in chunks AB_Append_Options : String_List_Access := new String_List (1 .. 10); Last_AB_Append_Option : Natural := 0; -- Options for appending to an archive Archive_Indexer : String_Access := null; -- Name of the archive indexer AI_Options : String_List_Access := new String_List (1 .. 10); Last_AI_Option : Natural := 0; -- Options of the archive indexer Partial_Linker : String_Access := null; -- Name of the library partial linker PL_Options : String_List_Access := new String_List (1 .. 10); Last_PL_Option : Natural := 0; -- Options of the library partial linker Partial_Linker_Path : String_Access; -- The path to the partial linker driver Archive_Suffix : String_Access := new String'(".a"); Bind_Options : String_List_Access := new String_List (1 .. 10); Last_Bind_Option : Natural := 0; Success : Boolean; Relocatable : Boolean := False; Library_Name : String_Access := null; Library_Directory : String_Access := null; Library_Dependency_Directory : String_Access := null; Library_Version : String_Access := new String'(""); Library_Version_Path : String_Access := new String'(""); Symbolic_Link_Supported : Boolean := False; Major_Minor_Id_Supported : Boolean := False; PIC_Option : String_Access := null; package Library_Version_Options is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Library_Version_Options"); Shared_Lib_Prefix : String_Access := new String'("lib"); Shared_Lib_Suffix : String_Access := new String'(".so"); package Shared_Lib_Minimum_Options is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 2, Table_Increment => 100, Table_Name => "Gprlib.Shared_Lib_Minimum_Options"); Copy_Source_Directory : String_Access := null; Driver_Name : Name_Id := No_Name; Gnatbind_Name : String_Access := Osint.Program_Name ("gnatbind", "gprlib"); Gnatbind_Path : String_Access; Compiler_Name : String_Access := Osint.Program_Name ("gcc", "gprlib"); Compiler_Path : String_Access; Path_Option : String_Access := null; Separate_Run_Path_Options : Boolean := False; Rpath : String_List_Access := null; -- Allocated only if Path Option is supported Initial_Rpath_Length : constant := 4; -- Initial size of Rpath, when first allocated Rpath_Last : Natural := 0; -- Index of last directory in Rpath Rpath_Length : Natural := 0; -- Length of the full run path option Install_Name : String_Access := null; Arguments : String_List_Access := new String_List (1 .. 20); Last_Arg : Natural := 0; Argument_Length : Natural := 0; -- Response Files Max_Command_Line_Length : Natural := 0; Resp_File_Format : Prj.Response_File_Format := Prj.None; Response_File_Switches : String_List_Access := new String_List (1 .. 0); Delete_Response_File : Boolean := True; procedure Add_Arg (Arg : String_Access); -- Add one argument to the Arguments list. Increase the size of the list -- if necessary. procedure Add_Rpath (Path : String); procedure Add_Rpath (Path : String_Access); -- Add a path name to Rpath procedure Copy_ALI_Files; -- Copy the ALI files. For not SALs, copy all the ALI files. For SALs, -- only copy the interface ALI files, marking them with the special -- indicator "SL" on the P line. procedure Copy_Sources; -- Copy to the Copy_Source_Directory the sources of the interfaces of -- a Stand-Alone Library. function SALs_Use_Constructors return Boolean; -- Indicate if Stand-Alone Libraries are automatically initialized using -- the constructor mechanism. procedure Build_Shared_Lib; procedure Build_Shared_Lib is separate; ------------- -- Add_Arg -- ------------- procedure Add_Arg (Arg : String_Access) is begin if Last_Arg = Arguments'Last then -- Double the size of Arguments declare New_Args : constant String_List_Access := new String_List (1 .. 2 * Last_Arg); begin New_Args (Arguments'Range) := Arguments.all; Arguments := New_Args; end; end if; Last_Arg := Last_Arg + 1; Arguments (Last_Arg) := Arg; Argument_Length := Argument_Length + Arg'Length + 1; end Add_Arg; --------------- -- Add_Rpath -- --------------- procedure Add_Rpath (Path : String) is begin if Path'Length /= 0 then Add_Rpath (new String'(Path)); end if; end Add_Rpath; procedure Add_Rpath (Path : String_Access) is procedure Double; -- Double Rpath size ------------ -- Double -- ------------ procedure Double is New_Rpath : constant String_List_Access := new String_List (1 .. 2 * Rpath'Length); begin New_Rpath (1 .. Rpath_Last) := Rpath (1 .. Rpath_Last); for J in 1 .. Rpath_Last loop Rpath (J) := null; end loop; Free (Rpath); Rpath := New_Rpath; end Double; -- Start of processing for Add_Rpath begin -- If first path, allocate initial Rpath if Rpath = null then Rpath := new String_List (1 .. Initial_Rpath_Length); Rpath_Last := 1; Rpath_Length := 0; else -- Check if the directory is already there for J in 1 .. Rpath_Last loop if Rpath (J).all = Path.all then -- Nothing to do if the directory is already in Rpath return; end if; end loop; -- Otherwise, double Rpath if it is full if Rpath_Last = Rpath'Last then Double; end if; Rpath_Last := Rpath_Last + 1; Rpath_Length := Rpath_Length + 1; end if; -- Add the path name Rpath (Rpath_Last) := Path; Rpath_Length := Rpath_Length + Path'Length; end Add_Rpath; -------------------- -- Copy_ALI_Files -- -------------------- procedure Copy_ALI_Files is Success : Boolean := False; FD : File_Descriptor; Len : Integer; Actual_Len : Integer; S : String_Access; Curr : Natural; P_Line_Found : Boolean; Status : Boolean; begin if Standalone = No then for Index in 1 .. ALIs.Last loop declare Destination : constant String := Library_Dependency_Directory.all & Directory_Separator & Base_Name (ALIs.Table (Index).all); Disregard : Boolean; pragma Warnings (Off, Disregard); begin if Is_Regular_File (Destination) then Set_Writable (Destination); Delete_File (Destination, Disregard); end if; end; if Verbose_Mode then Put ("Copying "); Put (ALIs.Table (Index).all); Put_Line (" to library dependency directory"); end if; declare ALI_File : constant String := ALIs.Table (Index).all; begin if Is_Regular_File (ALI_File) then Copy_File (ALI_File, Library_Dependency_Directory.all, Success, Mode => Overwrite, Preserve => Preserve); else Success := False; end if; end; exit when not Success; end loop; else for Index in 1 .. Interface_ALIs.Last loop declare File_Name : String := Base_Name (Interface_ALIs.Table (Index).all); Destination : constant String := Library_Dependency_Directory.all & Directory_Separator & File_Name; Disregard : Boolean; pragma Warnings (Off, Disregard); begin if Is_Regular_File (Destination) then Set_Writable (Destination); Delete_File (Destination, Disregard); end if; if Verbose_Mode then Put ("Copying "); Put (Interface_ALIs.Table (Index).all); Put_Line (" to library dependency directory"); end if; Osint.Canonical_Case_File_Name (File_Name); -- Open the file Name_Len := Interface_ALIs.Table (Index)'Length; Name_Buffer (1 .. Name_Len) := Interface_ALIs.Table (Index).all; Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := ASCII.NUL; FD := Open_Read (Name_Buffer'Address, Binary); if FD /= Invalid_FD then Len := Integer (File_Length (FD)); S := new String (1 .. Len + 3); -- Read the file. Note that the loop is not necessary -- since the whole file is read at once except on VMS. Curr := 1; Actual_Len := Len; while Actual_Len /= 0 loop Actual_Len := Read (FD, S (Curr)'Address, Len); Curr := Curr + Actual_Len; end loop; -- We are done with the input file, so we close it -- (we simply ignore any bad status on the close) Close (FD, Status); P_Line_Found := False; -- Look for the P line. When found, add marker SL at the -- beginning of the P line. for Index in 1 .. Len - 3 loop if (S (Index) = ASCII.LF or else S (Index) = ASCII.CR) and then S (Index + 1) = 'P' then S (Index + 5 .. Len + 3) := S (Index + 2 .. Len); S (Index + 2 .. Index + 4) := " SL"; P_Line_Found := True; exit; end if; end loop; if P_Line_Found then -- Create new modified ALI file Name_Len := Library_Dependency_Directory'Length; Name_Buffer (1 .. Name_Len) := Library_Dependency_Directory.all; Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := Directory_Separator; Name_Buffer (Name_Len + 1 .. Name_Len + File_Name'Length) := File_Name; Name_Len := Name_Len + File_Name'Length + 1; Name_Buffer (Name_Len) := ASCII.NUL; FD := Create_File (Name_Buffer'Address, Binary); -- Write the modified text and close the newly -- created file. if FD /= Invalid_FD then Actual_Len := Write (FD, S (1)'Address, Len + 3); Close (FD, Status); -- Set Success to True only if the newly -- created file has been correctly written. Success := Status and Actual_Len = Len + 3; if Success then Set_Read_Only (Name_Buffer (1 .. Name_Len - 1)); end if; end if; end if; end if; end; end loop; end if; if not Success then Osint.Fail ("could not copy ALI files to library directory"); end if; end Copy_ALI_Files; ------------------ -- Copy_Sources -- ------------------ procedure Copy_Sources is Text : Text_Buffer_Ptr; The_ALI : ALI.ALI_Id; Lib_File : File_Name_Type; First_Unit : ALI.Unit_Id; Second_Unit : ALI.Unit_Id; Copy_Subunits : Boolean := False; use ALI; procedure Copy (Fname : String); -- Copy one source of the project to the copy source directory ---------- -- Copy -- ---------- procedure Copy (Fname : String) is Success : Boolean := False; begin for Index in 1 .. Sources.Last loop if Base_Name (Sources.Table (Index).all) = Fname then if Verbose_Mode then Put ("Copying "); Put (Sources.Table (Index).all); Put_Line (" to copy source directory"); end if; Copy_File (Sources.Table (Index).all, Copy_Source_Directory.all, Success, Mode => Overwrite, Preserve => Preserve); exit; end if; end loop; end Copy; begin for Index in 1 .. Interface_ALIs.Last loop -- First, load the ALI file Name_Len := 0; Add_Str_To_Name_Buffer (Interface_ALIs.Table (Index).all); Lib_File := Name_Find; Text := Osint.Read_Library_Info (Lib_File); The_ALI := ALI.Scan_ALI (Lib_File, Text, Ignore_ED => False, Err => True, Read_Lines => "UD"); Free (Text); Second_Unit := ALI.No_Unit_Id; First_Unit := ALI.ALIs.Table (The_ALI).First_Unit; Copy_Subunits := True; -- If there is both a spec and a body, check if they are both needed if ALI.Units.Table (First_Unit).Utype = ALI.Is_Body then Second_Unit := ALI.ALIs.Table (The_ALI).Last_Unit; -- If the body is not needed, then reset First_Unit if not ALI.Units.Table (Second_Unit).Body_Needed_For_SAL then First_Unit := ALI.No_Unit_Id; Copy_Subunits := False; end if; elsif ALI.Units.Table (First_Unit).Utype = ALI.Is_Spec_Only then Copy_Subunits := False; end if; -- Copy the file(s) that need to be copied if First_Unit /= No_Unit_Id then Copy (Fname => Get_Name_String (ALI.Units.Table (First_Unit).Sfile)); end if; if Second_Unit /= No_Unit_Id then Copy (Fname => Get_Name_String (ALI.Units.Table (Second_Unit).Sfile)); end if; -- Copy all the separates, if any if Copy_Subunits then for Dep in ALI.ALIs.Table (The_ALI).First_Sdep .. ALI.ALIs.Table (The_ALI).Last_Sdep loop if ALI.Sdep.Table (Dep).Subunit_Name /= No_Name then Copy (Fname => Get_Name_String (Sdep.Table (Dep).Sfile)); end if; end loop; end if; end loop; for Index in 1 .. Other_Interfaces.Last loop Copy (Fname => Other_Interfaces.Table (Index).all); end loop; end Copy_Sources; --------------------------- -- SALs_Use_Constructors -- --------------------------- function SALs_Use_Constructors return Boolean is function C_SALs_Init_Using_Constructors return Integer; pragma Import (C, C_SALs_Init_Using_Constructors, "__gnat_sals_init_using_constructors"); begin return C_SALs_Init_Using_Constructors /= 0; end SALs_Use_Constructors; begin -- Initialize some packages Csets.Initialize; Namet.Initialize; Snames.Initialize; -- Copy_Attributes always fails on VMS if Hostparm.OpenVMS then Preserve := None; Shared_Libgnat_Separator := '_'; end if; if Argument_Count /= 1 then Put_Line ("usage: gprlib "); if Argument_Count /= 0 then Osint.Fail ("incorrect invocation"); end if; return; end if; Exchange_File_Name := new String'(Argument (1)); -- DEBUG: save a copy of the exchange file if Getenv ("GPRLIB_DEBUG").all = "TRUE" then Copy_File (Exchange_File_Name.all, Exchange_File_Name.all & "__saved", Success, Mode => Overwrite, Preserve => Preserve); end if; begin Open (IO_File, In_File, Exchange_File_Name.all); exception when others => Osint.Fail ("could not read " & Exchange_File_Name.all); end; while not End_Of_File (IO_File) loop Get_Line (IO_File, Line, Last); if Last > 0 and then Line (1) = '[' then Current_Section := Get_Library_Section (Line (1 .. Last)); case Current_Section is when No_Library_Section => Osint.Fail ("unknown section: " & Line (1 .. Last)); when Quiet => Quiet_Output := True; Verbose_Mode := False; when Verbose => Quiet_Output := False; Verbose_Mode := True; when Gprexch.Relocatable => Relocatable := True; Static := False; when Gprexch.Static => Static := True; Relocatable := False; when Gprexch.Archive_Builder => Archive_Builder := null; Last_AB_Option := 0; when Gprexch.Archive_Builder_Append_Option => Last_AB_Append_Option := 0; when Gprexch.Archive_Indexer => Archive_Indexer := null; Last_AI_Option := 0; when Gprexch.Partial_Linker => Partial_Linker := null; Last_PL_Option := 0; when Gprexch.Auto_Init => Auto_Init := True; when Gprexch.Symbolic_Link_Supported => Symbolic_Link_Supported := True; when Gprexch.Major_Minor_Id_Supported => Major_Minor_Id_Supported := True; when Gprexch.Keep_Response_File => Delete_Response_File := False; when Gprexch.Separate_Run_Path_Options => Separate_Run_Path_Options := True; when Gprexch.Compiler_Leading_Switches | Gprexch.Compiler_Trailing_Switches => Current_Language := No_Name; when Gprexch.No_Create => No_Create := True; when Gprexch.No_Copy_ALI => Copy_ALI := False; when others => null; end case; elsif Last > 0 or else Current_Section = Gprexch.Shared_Lib_Prefix or else Current_Section = Gprexch.Response_File_Switches then case Current_Section is when No_Library_Section => Osint.Fail ("no section specified: " & Line (1 .. Last)); when Gprexch.No_Create => Osint.Fail ("no create section should be empty"); when Gprexch.No_Copy_ALI => Osint.Fail ("no copy ALI section should be empty"); when Quiet => Osint.Fail ("quiet section should be empty"); when Verbose => Osint.Fail ("verbose section should be empty"); when Gprexch.Relocatable => Osint.Fail ("relocatable section should be empty"); when Gprexch.Static => Osint.Fail ("static section should be empty"); when Gprexch.Keep_Response_File => Osint.Fail ("keep response file section should be empty"); when Gprexch.Separate_Run_Path_Options => Osint.Fail ("separate run path options should be empty"); when Gprexch.Object_Files => Object_Files.Append (new String'(Line (1 .. Last))); when Gprexch.Options => Options_Table.Append (new String'(Line (1 .. Last))); when Gprexch.Object_Directory => Object_Directories.Append (new String'(Line (1 .. Last))); when Gprexch.Library_Name => Library_Name := new String'(Line (1 .. Last)); when Gprexch.Library_Directory => Library_Directory := new String'(Line (1 .. Last)); when Gprexch.Library_Dependency_Directory => Library_Dependency_Directory := new String'(Line (1 .. Last)); when Gprexch.Library_Version => Library_Version := new String'(Line (1 .. Last)); when Gprexch.Leading_Library_Options => if Line (1 .. Last) = No_Std_Lib_String then Use_GNAT_Lib := False; end if; Leading_Library_Options_Table.Append (new String'(Line (1 .. Last))); when Gprexch.Library_Options => if Line (1 .. Last) = No_Std_Lib_String then Use_GNAT_Lib := False; end if; Library_Options_Table.Append (new String'(Line (1 .. Last))); when Gprexch.Library_Rpath_Options => Library_Rpath_Options_Table.Append (new String'(Line (1 .. Last))); when Library_Path => Osint.Fail ("library path should not be specified"); when Gprexch.Library_Version_Options => Library_Version_Options.Append (new String'(Line (1 .. Last))); when Gprexch.Shared_Lib_Prefix => Shared_Lib_Prefix := new String'(Line (1 .. Last)); when Gprexch.Shared_Lib_Suffix => Shared_Lib_Suffix := new String'(Line (1 .. Last)); when Gprexch.Shared_Lib_Minimum_Options => Shared_Lib_Minimum_Options.Append (new String'(Line (1 .. Last))); when Gprexch.Symbolic_Link_Supported => Osint.Fail ("symbolic link supported section should be empty"); when Gprexch.Major_Minor_Id_Supported => Osint.Fail ("major minor id supported section should be empty"); when Gprexch.PIC_Option => PIC_Option := new String'(Line (1 .. Last)); when Gprexch.Imported_Libraries => if End_Of_File (IO_File) then Osint.Fail ("no library name for imported library " & Line (1 .. Last)); else Imported_Library_Directories.Append (new String'(Line (1 .. Last))); Get_Line (IO_File, Line, Last); Imported_Library_Names.Append (new String'(Line (1 .. Last))); end if; when Gprexch.Driver_Name => Name_Len := Last; Name_Buffer (1 .. Name_Len) := Line (1 .. Last); Driver_Name := Name_Find; when Gprexch.Compilers => if End_Of_File (IO_File) then Osint.Fail ("no compiler specified for language " & Line (1 .. Last)); else To_Lower (Line (1 .. Last)); if Line (1 .. Last) = "ada" then Get_Line (IO_File, Line, Last); if Last = 0 then Osint.Fail ("Ada compiler name cannot be empty"); else Compiler_Name := new String'(Line (1 .. Last)); if Last > 3 and then Line (Last - 2 .. Last) = "gcc" then Gnatbind_Name := new String'(Line (1 .. Last - 3) & "gnatbind"); elsif Last > 7 and then Line (Last - 6 .. Last) = "gcc.exe" then Gnatbind_Name := new String'(Line (1 .. Last - 7) & "gnatbind"); end if; end if; else Skip_Line (IO_File); end if; end if; when Gprexch.Compiler_Leading_Switches => if Last > Language_Equal'Length and then Line (1 .. Language_Equal'Length) = Language_Equal then Name_Len := 0; Add_Str_To_Name_Buffer (Line (Language_Equal'Length + 1 .. Last)); To_Lower (Name_Buffer (1 .. Name_Len)); Current_Language := Name_Find; elsif Current_Language = Snames.Name_Ada then Ada_Leading_Switches.Append (new String'(Line (1 .. Last))); end if; when Gprexch.Compiler_Trailing_Switches => if Last > Language_Equal'Length and then Line (1 .. Language_Equal'Length) = Language_Equal then Name_Len := 0; Add_Str_To_Name_Buffer (Line (Language_Equal'Length + 1 .. Last)); To_Lower (Name_Buffer (1 .. Name_Len)); Current_Language := Name_Find; elsif Current_Language = Snames.Name_Ada then Ada_Trailing_Switches.Append (new String'(Line (1 .. Last))); end if; when Toolchain_Version => if End_Of_File (IO_File) then Osint.Fail ("no toolchain version for language " & Line (1 .. Last)); elsif Line (1 .. Last) = "ada" then Get_Line (IO_File, Line, Last); if Last > 5 and then Line (1 .. 5) = "GNAT " then GNAT_Version := new String'(Line (6 .. Last)); GNAT_Version_Set := True; -- On VMS, replace all '.' with '_', to avoid names with -- several dots. if Hostparm.OpenVMS then for J in 6 .. Last loop if Line (J) = '.' then Line (J) := '_'; end if; end loop; end if; Libgnat := new String' ("-lgnat" & Shared_Libgnat_Separator & Line (6 .. Last)); Libgnarl := new String' ("-lgnarl" & Shared_Libgnat_Separator & Line (6 .. Last)); end if; else Skip_Line (IO_File); end if; when Gprexch.Archive_Builder => if Archive_Builder = null then Archive_Builder := new String'(Line (1 .. Last)); else Add (new String'(Line (1 .. Last)), AB_Options, Last_AB_Option); end if; when Gprexch.Archive_Builder_Append_Option => Add (new String'(Line (1 .. Last)), AB_Append_Options, Last_AB_Append_Option); when Gprexch.Archive_Indexer => if Archive_Indexer = null then Archive_Indexer := new String'(Line (1 .. Last)); else Add (new String'(Line (1 .. Last)), AI_Options, Last_AI_Option); end if; when Gprexch.Partial_Linker => if Partial_Linker = null then Partial_Linker := new String'(Line (1 .. Last)); else Add (new String'(Line (1 .. Last)), PL_Options, Last_PL_Option); end if; when Gprexch.Archive_Suffix => Archive_Suffix := new String'(Line (1 .. Last)); when Gprexch.Run_Path_Option => if Path_Option /= null then Osint.Fail ("multiple run path options"); end if; Path_Option := new String'(Line (1 .. Last)); when Gprexch.Install_Name => if Install_Name /= null then Osint.Fail ("multiple install names"); end if; Install_Name := new String'(Line (1 .. Last)); when Gprexch.Auto_Init => Osint.Fail ("auto init section should be empty"); when Interface_Dep_Files => Interface_ALIs.Append (new String'(Line (1 .. Last))); Standalone := Prj.Standard; when Gprexch.Other_Interfaces => Other_Interfaces.Append (new String'(Line (1 .. Last))); when Gprexch.Standalone_Mode => Standalone := Prj.Standalone'Value (Line (1 .. Last)); when Dependency_Files => if Last > 4 and then Line (Last - 3 .. Last) = ".ali" then ALIs.Append (new String'(Line (1 .. Last))); end if; when Binding_Options => Binding_Options_Table.Append (new String'(Line (1 .. Last))); when Copy_Source_Dir => Copy_Source_Directory := new String'(Line (1 .. Last)); when Gprexch.Sources => Sources.Append (new String'(Line (1 .. Last))); when Gprexch.Runtime_Library_Dir => if End_Of_File (IO_File) then Osint.Fail ("no runtime library dir for language " & Line (1 .. Last)); elsif Line (1 .. Last) = "ada" then Get_Line (IO_File, Line, Last); Runtime_Library_Dir := new String'(Line (1 .. Last)); else Skip_Line (IO_File); end if; when Gprexch.Generated_Object_Files | Gprexch.Generated_Source_Files => null; when Gprexch.Max_Command_Line_Length => begin Max_Command_Line_Length := Natural'Value (Line (1 .. Last)); if Max_Command_Line_Length < Maximum_Size then Maximum_Size := Max_Command_Line_Length; end if; exception when Constraint_Error => Osint.Fail ("incorrect value for max command line length: " & Line (1 .. Last)); end; when Gprexch.Response_File_Format => begin Resp_File_Format := Prj.Response_File_Format'Value (Line (1 .. Last)); exception when Constraint_Error => Osint.Fail ("incorrect value for response file format: " & Line (1 .. Last)); end; when Gprexch.Response_File_Switches => if Response_File_Switches = null then Response_File_Switches := new String_List (1 .. 1); else declare New_Switches : constant String_List_Access := new String_List (1 .. Response_File_Switches'Last + 1); begin New_Switches (Response_File_Switches'Range) := Response_File_Switches.all; Free (Response_File_Switches); Response_File_Switches := New_Switches; end; end if; Response_File_Switches (Response_File_Switches'Last) := new String'(Line (1 .. Last)); end case; end if; end loop; Close (IO_File); if Object_Files.Last = 0 then Osint.Fail ("no object files specified"); end if; Last_Object_File_Index := Object_Files.Last; if Library_Name = null then Osint.Fail ("no library name specified"); end if; if Library_Directory = null then Osint.Fail ("no library directory specified"); end if; if Object_Directories.Last = 0 then Osint.Fail ("no object directory specified"); end if; if Library_Directory.all = Object_Directories.Table (1).all then Osint.Fail ("object directory and library directory cannot be the same"); end if; if Library_Dependency_Directory = null then Library_Dependency_Directory := Library_Directory; end if; -- We work in the object directory begin Change_Dir (Object_Directories.Table (1).all); exception when others => Osint.Fail ("cannot change to object directory " & Object_Directories.Table (1).all); end; if Standalone /= No then declare Binder_Generated_File : String := "b__" & Library_Name.all & ".adb"; Binder_Generated_Object : String := "b__" & Library_Name.all & Object_Suffix; ALI_First_Index : Positive; First_ALI : File_Name_Type; T : Text_Buffer_Ptr; A : ALI.ALI_Id; Obj_Index : Natural; use ALI; begin Osint.Canonical_Case_File_Name (Binder_Generated_File); Osint.Canonical_Case_File_Name (Binder_Generated_Object); Gnatbind_Path := Locate_Exec_On_Path (Gnatbind_Name.all); if Gnatbind_Path = null then Osint.Fail ("unable to locate binder " & Gnatbind_Name.all); end if; Last_Bind_Option := 0; Add (No_Main, Bind_Options, Last_Bind_Option); Add (Output_Switch, Bind_Options, Last_Bind_Option); Add ("b__" & Library_Name.all & ".adb", Bind_Options, Last_Bind_Option); -- Make sure that the init procedure is never "adainit" if Library_Name.all = "ada" then Add ("-Lada_", Bind_Options, Last_Bind_Option); else Add ("-L" & Library_Name.all, Bind_Options, Last_Bind_Option); end if; if Auto_Init and then SALs_Use_Constructors then -- Check that pragma Linker_Constructor is supported if not GNAT_Version_Set or else (GNAT_Version'Length > 2 and then GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) = "3.") then -- GNAT version 3.xx or unknown null; elsif GNAT_Version'Length > 2 and then GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) = "5." and then GNAT_Version.all < "5.04" then -- GNAT versions 5.00, 5.01, 5.02 or 5.03 null; else -- Any other supported GNAT version should support pragma -- Linker_Constructor. So, invoke gnatbind with -a. Add (Auto_Initialize, Bind_Options, Last_Bind_Option); end if; end if; for J in 1 .. Binding_Options_Table.Last loop Add (Binding_Options_Table.Table (J).all, Bind_Options, Last_Bind_Option); end loop; -- Get an eventual --RTS from the ALI file Name_Len := 0; Add_Str_To_Name_Buffer (ALIs.Table (1).all); First_ALI := Name_Find; -- Load the ALI file T := Osint.Read_Library_Info (First_ALI, True); -- Read it A := Scan_ALI (First_ALI, T, Ignore_ED => False, Err => False, Read_Lines => "A"); if A /= No_ALI_Id then for Index in ALI.Units.Table (ALI.ALIs.Table (A).First_Unit).First_Arg .. ALI.Units.Table (ALI.ALIs.Table (A).First_Unit).Last_Arg loop -- Look for --RTS. If found, add the switch to call gnatbind declare Arg : Types.String_Ptr renames Args.Table (Index); begin if Arg'Length >= 6 and then Arg (Arg'First + 2 .. Arg'First + 5) = "RTS=" then Add (Arg.all, Bind_Options, Last_Bind_Option); exit; end if; end; end loop; end if; ALI_First_Index := Last_Bind_Option + 1; for J in 1 .. ALIs.Last loop Add (ALIs.Table (J), Bind_Options, Last_Bind_Option); end loop; if not Quiet_Output then if Verbose_Mode then Put (Gnatbind_Path.all); else Put (Base_Name (Gnatbind_Name.all)); end if; for J in 1 .. Last_Bind_Option loop if (not Verbose_Mode) and then J > ALI_First_Index then Put (" ..."); exit; end if; Put (" "); Put (Bind_Options (J).all); end loop; New_Line; end if; -- If there is more than one object directory, set ADA_OBJECTS_PATH -- for the additional object libraries, so that gnatbind may find -- all the ALI files. if Object_Directories.Last > 1 then declare Object_Path : String_Access := new String'(Object_Directories.Table (2).all); begin for J in 3 .. Object_Directories.Last loop Object_Path := new String' (Object_Path.all & Path_Separator & Object_Directories.Table (J).all); end loop; Setenv ("ADA_OBJECTS_PATH", Object_Path.all); end; end if; declare Size : Natural := 0; begin for J in 1 .. Last_Bind_Option loop Size := Size + Bind_Options (J)'Length + 1; end loop; -- Invoke gnatbind with the arguments if the size is not too large -- or if the version of GNAT is not recent enough. if Size <= Maximum_Size or else not GNAT_Version_Set or else (GNAT_Version'Length > 2 and then (GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) = "3." or else GNAT_Version (GNAT_Version'First .. GNAT_Version'First + 1) = "5.")) then Spawn (Gnatbind_Path.all, Bind_Options (1 .. Last_Bind_Option), Success); else -- Otherwise create a temporary response file declare EOL : constant String (1 .. 1) := (1 => ASCII.LF); FD : File_Descriptor; Path : Path_Name_Type; Args : Argument_List (1 .. 1); Status : Integer; Quotes_Needed : Boolean; Last_Char : Natural; Ch : Character; begin Tempdir.Create_Temp_File (FD, Path); Args (1) := new String'("@" & Get_Name_String (Path)); for J in 1 .. Last_Bind_Option loop -- Check if the argument should be quoted Quotes_Needed := False; Last_Char := Bind_Options (J)'Length; for K in Bind_Options (J)'Range loop Ch := Bind_Options (J) (K); if Ch = ' ' or else Ch = ASCII.HT or else Ch = '"' then Quotes_Needed := True; exit; end if; end loop; if Quotes_Needed then -- Quote the argument, doubling '"' declare Arg : String (1 .. Bind_Options (J)'Length * 2 + 2); begin Arg (1) := '"'; Last_Char := 1; for K in Bind_Options (J)'Range loop Ch := Bind_Options (J) (K); Last_Char := Last_Char + 1; Arg (Last_Char) := Ch; if Ch = '"' then Last_Char := Last_Char + 1; Arg (Last_Char) := '"'; end if; end loop; Last_Char := Last_Char + 1; Arg (Last_Char) := '"'; Status := Write (FD, Arg'Address, Last_Char); end; else Status := Write (FD, Bind_Options (J) (Bind_Options (J)'First)'Address, Last_Char); end if; if Status /= Last_Char then Osint.Fail ("disk full"); end if; Status := Write (FD, EOL (1)'Address, 1); if Status /= 1 then Osint.Fail ("disk full"); end if; end loop; Close (FD); -- And invoke gnatbind with this this response file Spawn (Gnatbind_Path.all, Args, Success); if Delete_Response_File then declare Succ : Boolean; pragma Warnings (Off, Succ); begin Delete_File (Get_Name_String (Path), Succ); end; end if; end; end if; end; if not Success then Osint.Fail ("invocation of " & Gnatbind_Name.all & " failed"); end if; Generated_Sources.Append (new String'("b__" & Library_Name.all & ".ads")); Generated_Sources.Append (new String'("b__" & Library_Name.all & ".adb")); Generated_Sources.Append (new String'("b__" & Library_Name.all & ".ali")); Compiler_Path := Locate_Exec_On_Path (Compiler_Name.all); if Compiler_Path = null then Osint.Fail ("unable to locate compiler " & Compiler_Name.all); end if; Last_Bind_Option := 0; for J in 1 .. Ada_Leading_Switches.Last loop Add (Ada_Leading_Switches.Table (J), Bind_Options, Last_Bind_Option); end loop; Add (No_Warning, Bind_Options, Last_Bind_Option); Add (Binder_Generated_File, Bind_Options, Last_Bind_Option); Add (Output_Switch, Bind_Options, Last_Bind_Option); Add (Binder_Generated_Object, Bind_Options, Last_Bind_Option); Obj_Index := Last_Bind_Option; if Relocatable and then PIC_Option /= null then Add (PIC_Option, Bind_Options, Last_Bind_Option); end if; -- Get the back-end switches and --RTS from the ALI file -- Load the ALI file T := Osint.Read_Library_Info (First_ALI, True); -- Read it A := Scan_ALI (First_ALI, T, Ignore_ED => False, Err => False, Read_Lines => "A"); if A /= No_ALI_Id then for Index in ALI.Units.Table (ALI.ALIs.Table (A).First_Unit).First_Arg .. ALI.Units.Table (ALI.ALIs.Table (A).First_Unit).Last_Arg loop -- Do not compile with the front end switches except -- for --RTS. declare Arg : Types.String_Ptr renames Args.Table (Index); begin if not Is_Front_End_Switch (Arg.all) or else (Arg'Length > 6 and then Arg (Arg'First + 2 .. Arg'First + 5) = "RTS=") then Add (Arg.all, Bind_Options, Last_Bind_Option); end if; end; end loop; end if; for J in 1 .. Ada_Trailing_Switches.Last loop Add (Ada_Trailing_Switches.Table (J), Bind_Options, Last_Bind_Option); end loop; if not Quiet_Output then if Verbose_Mode then Put (Compiler_Path.all); else Put (Base_Name (Compiler_Name.all)); end if; for J in 1 .. Last_Bind_Option loop if not Verbose_Mode and then J > Obj_Index then Put (" ..."); exit; else Put (" "); Put (Bind_Options (J).all); end if; end loop; New_Line; end if; Spawn (Compiler_Path.all, Bind_Options (1 .. Last_Bind_Option), Success); if not Success then Osint.Fail ("invocation of " & Compiler_Name.all & " failed"); end if; Generated_Objects.Append (new String'(Binder_Generated_Object)); Object_Files.Append (new String'(Binder_Generated_Object)); -- For shared libraries, check if libgnarl is needed if Relocatable then declare BG_File : File_Type; Line : String (1 .. 1_000); Last : Natural; begin Open (BG_File, In_File, Binder_Generated_File); while not End_Of_File (BG_File) loop Get_Line (BG_File, Line, Last); exit when Line (1 .. Last) = Begin_Info; end loop; while not End_Of_File (BG_File) loop Get_Line (BG_File, Line, Last); exit when Line (1 .. Last) = End_Info; if Use_GNAT_Lib and then Runtime_Library_Dir /= null and then Line (9 .. Last) = "-lgnarl" then Libgnarl_Needed := True; end if; if Standalone /= No and then (Partial_Linker = null or else Resp_File_Format /= Prj.None) and then Line (9 .. 10) = "-l" and then Line (9 .. Last) /= "-lgnarl" and then Line (9 .. Last) /= "-lgnat" then Object_Files.Append (new String'(Line (9 .. Last))); end if; end loop; end; end if; end; end if; -- Archives if Static and then not No_Create then if Standalone /= No and then Partial_Linker /= null then Partial_Linker_Path := Locate_Exec_On_Path (Partial_Linker.all); if Partial_Linker_Path = null then Osint.Fail ("unable to locate linker " & Partial_Linker.all); end if; end if; if Archive_Builder = null then Osint.Fail ("no archive builder specified"); end if; Library_Path_Name := new String' (Library_Directory.all & "lib" & Library_Name.all & Archive_Suffix.all); Add (Library_Path_Name, AB_Options, Last_AB_Option); First_AB_Object_Pos := Last_AB_Option + 1; if Standalone /= No and then Partial_Linker_Path /= null then -- If partial linker is used, do a partial link and put the resulting -- object file in the archive. Partial_Number := 0; First_Object := 1; loop declare Partial : constant String_Access := new String' (Partial_Name (Library_Name.all, Partial_Number, Object_Suffix)); Size : Natural := 0; Saved_Last_PL_Option : Natural; begin Saved_Last_PL_Option := Last_PL_Option; Add (Partial, PL_Options, Last_PL_Option); Size := Size + 1 + Partial'Length; if Partial_Number > 0 then Add (Partial_Name (Library_Name.all, Partial_Number - 1, Object_Suffix), PL_Options, Last_PL_Option); end if; for J in 1 .. Last_PL_Option loop Size := Size + 1 + PL_Options (J)'Length; end loop; loop Add (Object_Files.Table (First_Object), PL_Options, Last_PL_Option); Size := Size + 1 + PL_Options (Last_PL_Option)'Length; First_Object := First_Object + 1; exit when First_Object > Object_Files.Last or else Size >= Maximum_Size; end loop; if not Quiet_Output then if Verbose_Mode then Put (Partial_Linker_Path.all); else Put (Base_Name (Partial_Linker_Path.all)); end if; for J in 1 .. Last_PL_Option loop if (not Verbose_Mode) and then J >= 5 then Put (" ..."); exit; end if; Put (' '); Put (PL_Options (J).all); end loop; New_Line; end if; Spawn (Partial_Linker_Path.all, PL_Options (1 .. Last_PL_Option), Success); if not Success then Osint.Fail ("call to linker driver " & Partial_Linker.all & " failed"); end if; if First_Object > Object_Files.Last then Add (Partial, AB_Options, Last_AB_Option); exit; end if; Last_PL_Option := Saved_Last_PL_Option; Partial_Number := Partial_Number + 1; end; end loop; else -- Not a standalone library, or Partial linker is not specified. -- Put all objects in the archive. for J in 1 .. Object_Files.Last loop Add (Object_Files.Table (J), AB_Options, Last_AB_Option); end loop; end if; -- Delete the archive if it already exists, to avoid having duplicated -- object files in the archive when it is built in chunks. if Is_Regular_File (Library_Path_Name.all) then Delete_File (Library_Path_Name.all, Success); end if; if Last_AB_Append_Option = 0 then -- If there is no Archive_Builder_Append_Option, always build the -- archive in one chunk. Next_AB_Object_Pos := Last_AB_Option + 1; else -- If Archive_Builder_Append_Option is specified, for the creation of -- the archive, only put on the command line a number of character -- lower that Maximum_Size. Size := 0; for J in 1 .. First_AB_Object_Pos - 1 loop Size := Size + AB_Options (J)'Length + 1; end loop; Next_AB_Object_Pos := First_AB_Object_Pos; while Next_AB_Object_Pos <= Last_AB_Option loop Size := Size + AB_Options (Next_AB_Object_Pos)'Length + 1; exit when Size > Maximum_Size; Next_AB_Object_Pos := Next_AB_Object_Pos + 1; end loop; -- Display the invocation of the archive builder for the creation of -- the archive. if not Quiet_Output then if Verbose_Mode then Put (Archive_Builder.all); else Put (Base_Name (Archive_Builder.all)); end if; for J in 1 .. Next_AB_Object_Pos - 1 loop if (not Verbose_Mode) and then J >= 5 then Put (" ..."); exit; end if; Put (' '); Put (AB_Options (J).all); end loop; New_Line; end if; Spawn (Archive_Builder.all, AB_Options (1 .. Next_AB_Object_Pos - 1), Success); if not Success then Osint.Fail ("call to archive builder " & Archive_Builder.all & " failed"); end if; end if; -- If the archive has not been created complete, add the remaining -- chunks. if Next_AB_Object_Pos <= Last_AB_Option then First_AB_Object_Pos := Last_AB_Append_Option + 2; AB_Options (1 .. Last_AB_Append_Option) := AB_Append_Options (1 .. Last_AB_Append_Option); AB_Options (Last_AB_Append_Option + 1) := Library_Path_Name; loop Size := 0; for J in 1 .. First_AB_Object_Pos - 1 loop Size := Size + AB_Options (J)'Length + 1; end loop; Object_Pos := First_AB_Object_Pos; while Next_AB_Object_Pos <= Last_AB_Option loop Size := Size + AB_Options (Next_AB_Object_Pos)'Length + 1; exit when Size > Maximum_Size; AB_Options (Object_Pos) := AB_Options (Next_AB_Object_Pos); Object_Pos := Object_Pos + 1; Next_AB_Object_Pos := Next_AB_Object_Pos + 1; end loop; -- Display the invocation of the Archive Builder for this chunk if not Quiet_Output then if Verbose_Mode then Put (Archive_Builder.all); else Put (Base_Name (Archive_Builder.all)); end if; for J in 1 .. Object_Pos - 1 loop if (not Verbose_Mode) and then J >= 5 then Put (" ..."); exit; end if; Put (' '); Put (AB_Options (J).all); end loop; New_Line; end if; Spawn (Archive_Builder.all, AB_Options (1 .. Object_Pos - 1), Success); if not Success then Osint.Fail ("call to archive builder " & Archive_Builder.all & " failed"); end if; exit when Next_AB_Object_Pos > Last_AB_Option; end loop; end if; -- If there is an Archive Indexer, invoke it if Archive_Indexer /= null then Add (Library_Path_Name, AI_Options, Last_AI_Option); if not Quiet_Output then if Verbose_Mode then Put (Archive_Indexer.all); else Put (File_Name (Archive_Indexer.all)); end if; for J in 1 .. Last_AI_Option loop Put (' '); if J = Last_AI_Option and then (not Verbose_Mode) then Put (File_Name (AI_Options (J).all)); else Put (AI_Options (J).all); end if; end loop; New_Line; end if; Spawn (Archive_Indexer.all, AI_Options (1 .. Last_AI_Option), Success); if not Success then Osint.Fail ("call to archive indexer " & Archive_Indexer.all & " failed"); end if; end if; elsif not No_Create then -- Shared libraries Library_Path_Name := new String' (Library_Directory.all & Shared_Lib_Prefix.all & Library_Name.all & Shared_Lib_Suffix.all); if Relocatable and then PIC_Option /= null and then PIC_Option.all /= "" then Options_Table.Append (new String'(PIC_Option.all)); end if; -- Get default search directories to locate system.ads when calling -- Targparm.Get_Target_Parameters. -- Osint.Add_Default_Search_Dirs; -- Check if the platform is VMS and, if it is, change some variables -- Targparm.Get_Target_Parameters; Prj.Initialize (Prj.No_Project_Tree); if S_Osinte_Ads = No_File then Name_Len := 0; Add_Str_To_Name_Buffer ("s-osinte.ads"); S_Osinte_Ads := Name_Find; end if; if S_Dec_Ads = No_File then Name_Len := 0; Add_Str_To_Name_Buffer ("dec.ads"); S_Dec_Ads := Name_Find; end if; if G_Trasym_Ads = No_File then Name_Len := 0; Add_Str_To_Name_Buffer ("g-trasym.ads"); G_Trasym_Ads := Name_Find; end if; for J in 1 .. Imported_Library_Directories.Last loop Library_Switches_Table.Append (new String'("-L" & Imported_Library_Directories.Table (J).all)); if Path_Option /= null then Add_Rpath (Imported_Library_Directories.Table (J)); end if; Library_Switches_Table.Append (new String'("-l" & Imported_Library_Names.Table (J).all)); end loop; -- If Ada is used and we don't already know yet that libgnarl is needed, -- look for s-osinte.ads in all the ALI files. If found in at least one, -- then libgnarl is needed. if Use_GNAT_Lib and then Runtime_Library_Dir /= null and then not Libgnarl_Needed then declare Lib_File : File_Name_Type; Text : Text_Buffer_Ptr; Id : ALI.ALI_Id; use ALI; begin if Verbose_Mode then Put_Line ("Reading ALI files to decide for -lgnarl"); end if; ALI_Loop : for Index in 1 .. ALIs.Last loop if Verbose_Mode then Put_Line ("Reading " & ALIs.Table (Index).all); end if; Name_Len := 0; Add_Str_To_Name_Buffer (ALIs.Table (Index).all); Lib_File := Name_Find; Text := Osint.Read_Library_Info (Lib_File, True); Id := ALI.Scan_ALI (F => Lib_File, T => Text, Ignore_ED => False, Err => True, Read_Lines => "D"); Free (Text); if Id = No_ALI_Id then Put_Line ("warning: reading of " & ALIs.Table (Index).all & " failed"); else -- Look for s-osinte.ads in the dependencies for Index in ALI.ALIs.Table (Id).First_Sdep .. ALI.ALIs.Table (Id).Last_Sdep loop if ALI.Sdep.Table (Index).Sfile = S_Osinte_Ads then Libgnarl_Needed := True; exit ALI_Loop; end if; end loop; end if; end loop ALI_Loop; if Verbose_Mode then Put_Line ("End of ALI file reading"); end if; end; end if; if Use_GNAT_Lib and then Runtime_Library_Dir /= null then if Standalone = Encapsulated then -- For encapsulated library we want to link against the static -- GNAT runtime. Libgnat := new String'(Runtime_Library_Dir.all & "libgnat.a"); Libgnarl := new String'(Runtime_Library_Dir.all & "libgnarl.a"); if not Is_Regular_File (Libgnat.all) then Osint.Fail ("missing " & Libgnat.all & " for encapsulated library"); end if; if Libgnarl_Needed and then not Is_Regular_File (Libgnarl.all) then Osint.Fail ("missing " & Libgnarl.all & " for encapsulated library"); end if; -- Adds options into the library options table as those static -- libraries must come late in the linker command line. if Libgnarl_Needed then Library_Options_Table.Append (Libgnarl); end if; Library_Options_Table.Append (Libgnat); else Options_Table.Append (new String'("-L" & Runtime_Library_Dir.all)); if Path_Option /= null then Add_Rpath (Runtime_Library_Dir); -- Add to the Path Option the directory of the shared version -- of libgcc. Add_Rpath (Shared_Libgcc_Dir (Runtime_Library_Dir.all)); end if; if Libgnarl_Needed then Options_Table.Append (Libgnarl); end if; Options_Table.Append (Libgnat); end if; end if; if Install_Name /= null then Options_Table.Append (new String' (Install_Name.all & Directory_Separator & Shared_Lib_Prefix.all & Library_Name.all & Shared_Lib_Suffix.all)); end if; if Path_Option /= null then for Index in 1 .. Library_Rpath_Options_Table.Last loop Add_Rpath (Library_Rpath_Options_Table.Table (Index)); end loop; end if; if Path_Option /= null and then Rpath /= null then if Separate_Run_Path_Options then for J in 1 .. Rpath_Last loop Options_Table.Append (new String'(Path_Option.all & Rpath (J).all)); end loop; else declare Option : constant String_Access := new String (1 .. Path_Option'Length + Rpath_Length); Cur : Natural := 0; begin Option (Cur + 1 .. Cur + Path_Option'Length) := Path_Option.all; Cur := Cur + Path_Option'Length; Option (Cur + 1 .. Cur + Rpath (1)'Length) := Rpath (1).all; Cur := Cur + Rpath (1)'Length; for J in 2 .. Rpath_Last loop Cur := Cur + 1; Option (Cur) := Path_Separator; Option (Cur + 1 .. Cur + Rpath (J)'Length) := Rpath (J).all; Cur := Cur + Rpath (J)'Length; end loop; Options_Table.Append (Option); end; end if; end if; Build_Shared_Lib; end if; if Copy_ALI and then ALIs.Last /= 0 then Copy_ALI_Files; end if; if Copy_Source_Directory /= null then Copy_Sources; end if; -- Create new exchange files with the path of the library file and the -- paths of the object files with their time stamps. begin Create (IO_File, Out_File, Exchange_File_Name.all); exception when others => Osint.Fail ("could not create " & Exchange_File_Name.all); end; if Library_Path_Name /= null then Put_Line (IO_File, Library_Label (Library_Path)); Put_Line (IO_File, Library_Path_Name.all); end if; Put_Line (IO_File, Library_Label (Gprexch.Object_Files)); for Index in 1 .. Last_Object_File_Index loop Put_Line (IO_File, Object_Files.Table (Index).all); Name_Len := Object_Files.Table (Index)'Length; Name_Buffer (1 .. Name_Len) := Object_Files.Table (Index).all; Put_Line (IO_File, String (Osint.File_Stamp (Path_Name_Type'(Name_Find)))); end loop; if Generated_Sources.Last > 0 then Put_Line (IO_File, Library_Label (Gprexch.Generated_Source_Files)); for Index in 1 .. Generated_Sources.Last loop Put_Line (IO_File, Generated_Sources.Table (Index).all); end loop; end if; if Generated_Objects.Last > 0 then Put_Line (IO_File, Library_Label (Gprexch.Generated_Object_Files)); for Index in 1 .. Generated_Objects.Last loop Put_Line (IO_File, Generated_Objects.Table (Index).all); end loop; end if; Close (IO_File); end Gprlib; gprbuild-gpl-2014-src/src/gpr_version.adb0000644000076700001450000000630212323721731017730 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R _ V E R S I O N -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Gnatvsn; use Gnatvsn; with GprConfig.Sdefault; package body GPR_Version is ------------------------ -- Gpr_Version_String -- ------------------------ function Gpr_Version_String return String is Last : Positive; First : Positive; Date : String (1 .. 10) := "(unknown) "; Host : constant String := " (" & GprConfig.Sdefault.Hostname & ')'; begin -- Find the beginning and the end of the current date, that is the last -- string with 8 consecutive digits in Gnat_Static_Version_String. Last := Gnat_Static_Version_String'Last; Last_Loop : while Last - Gnat_Static_Version_String'First >= 9 loop if Gnat_Static_Version_String (Last) not in '0' .. '9' then Last := Last - 1; else First := Last; First_Loop : while First >= Gnat_Static_Version_String'First and then Gnat_Static_Version_String (First) in '0' .. '9' loop if Last - First = 7 then Date := '(' & Gnat_Static_Version_String (First .. Last) & ')'; exit Last_Loop; else First := First - 1; end if; end loop First_Loop; Last := First; end if; end loop Last_Loop; case Build_Type is when Gnatpro => return "Pro " & Gpr_Version & " " & Date & Host; when GPL => return "GPL " & Gpr_Version & " " & Date & Host; when FSF => return Gpr_Version & " " & Date & Host; end case; end Gpr_Version_String; end GPR_Version; gprbuild-gpl-2014-src/src/gprbuild-compile.adb0000644000076700001450000034253712323721731020646 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2011-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Containers.Indefinite_Ordered_Maps; with Ada.Strings.Fixed; use Ada, Ada.Strings.Fixed; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO; use Ada.Text_IO; with GNAT.Directory_Operations; use GNAT, GNAT.Directory_Operations; with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables; with Atree; use Atree; with ALI.Util; with Gpr_Util; use Gpr_Util; with Makeutl; use Makeutl; with Osint; use Osint; with Output; use Output; with Prj.Env; with Prj.Util; use Prj.Util; with Snames; use Snames; with Tempdir; with Gprbuild.Compilation.Process; use Gprbuild.Compilation.Process; with Gprbuild.Compilation.Result; use Gprbuild.Compilation.Result; with Gprbuild.Compilation.Slave; package body Gprbuild.Compile is procedure Add_Compilation_Switches (Source : Source_Id); -- Add to the compilation option, the switches clared in -- Compiler'Switches(), if it is defined, otherwise in -- Compiler'Default_Switches (), if it is defined. procedure Await_Compile (Source : out Queue.Source_Info; OK : out Boolean; Slave : out Unbounded_String); -- Wait for the end of a compilation and indicate that the object directory -- is free. procedure Compilation_Phase (Main_Project : Project_Id; Project_Tree : Project_Tree_Ref); procedure Recursive_Import (Project : Project_Id); -- Add to table Imports the projects imported by Project, recursively function Project_Extends (Extending : Project_Id; Extended : Project_Id) return Boolean; -- Returns True if Extending is Extended or is extending Extended directly -- or indirectly. function Directly_Imports (Project : Project_Id; Imported : Project_Id) return Boolean; -- Returns True if Project directly withs Imported or a project extending -- Imported. procedure Create_Config_File (For_Project : Project_Id; Config : Language_Config; Language : Name_Id); -- Create a new config file function Config_File_For (Project : Project_Id; Package_Name : Name_Id; Attribute_Name : Name_Id; Language : Name_Id) return Path_Name_Type; -- Returns the name of a config file. Returns No_Name if there is no -- config file. procedure Create_Object_Path_File (Project : Project_Id); -- Create a temporary file that contains the list of object directories -- in the correct order. function "<" (Left, Right : Source_Id) return Boolean is (Left.File < Right.File); package Bad_Compilations_Set is new Containers.Indefinite_Ordered_Maps (Source_Id, String); Bad_Compilations : Bad_Compilations_Set.Map; -- Records bad compilation with the given slave name if any Outstanding_Compiles : Natural := 0; -- The number of compilation jobs currently spawned Slave_Initialized : Boolean := False; -- Record wether the remote compilation slaves have been initialized when -- running in distributed mode. type Process_Purpose is (Compilation, Dependency); -- A type to distinguish between compilation jobs and dependency file -- building jobs. type Process_Data is record Process : Id := Invalid_Process; Source : Queue.Source_Info := Queue.No_Source_Info; Source_Project : Project_Id := null; Mapping_File : Path_Name_Type := No_Path; Purpose : Process_Purpose := Compilation; Options : String_List_Access := null; end record; -- Data recorded for each spawned jobs, compilation of dependency file -- building. No_Process_Data : constant Process_Data := (Process => Invalid_Process, Source => Queue.No_Source_Info, Source_Project => null, Mapping_File => No_Path, Purpose => Compilation, Options => null); package Compilation_Htable is new GNAT.HTable.Simple_HTable (Header_Num => Gprbuild.Compilation.Process.Header_Num, Element => Process_Data, No_Element => No_Process_Data, Key => Id, Hash => Hash, Equal => "="); -- Hash table to keep data for all spawned jobs package Naming_Datas is new Table.Table (Table_Component_Type => Lang_Naming_Data, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Makegpr.Naming_Datas"); -- Naming data when creating config files package Imports is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Boolean, No_Element => False, Key => Project_Id, Hash => Hash, Equal => "="); -- When --direct-import-only is used, contains the project ids a non Ada -- source is allowed to import source from. package Included_Sources is new Table.Table (Table_Component_Type => Source_Id, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Makegpr.Included_Sources"); package Subunits is new Table.Table (Table_Component_Type => GNAT.OS_Lib.String_Access, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Makegpr.Subunits"); -- A table to store the subunit names when switch --no-split-units ia used ------------------------------ -- Add_Compilation_Switches -- ------------------------------ procedure Add_Compilation_Switches (Source : Source_Id) is Options : Variable_Value; Is_Default : Boolean; begin Makeutl.Get_Switches (Source, Name_Compiler, Project_Tree, Options, Is_Default); if Options /= Nil_Variable_Value then declare List : String_List_Id := Options.Values; Element : String_Element; Option : GNAT.OS_Lib.String_Access; begin while List /= Nil_String loop Element := Project_Tree.Shared.String_Elements.Table (List); -- Ignore empty options if Element.Value /= Empty_String then Option := Get_Option (Element.Value); Add_Option_Internal_Codepeer (Value => Option, To => Compilation_Options, Display => True); end if; List := Element.Next; end loop; end; end if; end Add_Compilation_Switches; ------------------- -- Await_Compile -- ------------------- procedure Await_Compile (Source : out Queue.Source_Info; OK : out Boolean; Slave : out Unbounded_String) is Process : Id; Comp_Data : Process_Data; Language : Language_Ptr; Config : Language_Config; begin loop Source := Queue.No_Source_Info; Wait (Process, OK); if Process = Invalid_Process then return; end if; Comp_Data := Compilation_Htable.Get (Process); if Comp_Data /= No_Process_Data then Source := Comp_Data.Source; Queue.Set_Obj_Dir_Free (Source.Id.Project.Object_Directory.Name); if Comp_Data.Purpose = Compilation then if OK then -- We created a new ALI file, so reset the attributes of -- the old one. Source.Id.Dep_TS := Unknown_Attributes; if Comp_Data.Options /= null and then Source.Id.Switches_Path /= No_Path and then Opt.Check_Switches then -- First, update the time stamp of the object file -- that will be written in the switches file. Source.Id.Object_TS := File_Stamp (Source.Id.Object_Path); -- Write the switches file, now that we have the -- updated time stamp for the object file. declare File : Text_IO.File_Type; begin Create (File, Out_File, Get_Name_String (Source.Id.Switches_Path)); Put_Line (File, String (Source.Id.Object_TS)); for J in Comp_Data.Options'Range loop Put_Line (File, Comp_Data.Options (J).all); end loop; Close (File); exception when others => Fail_Program (Source.Tree, "could not create switches file """ & Get_Name_String (Source.Id.Switches_Path) & '"'); end; -- For all languages other than Ada, update the time -- stamp of the object file as it is written in the -- global archive dependency file. For all languages, -- update the time stamp of the object file if it is -- in a library project. elsif Source.Id.Language.Config.Dependency_Kind /= ALI_File or else Source.Id.Project.Library then Source.Id.Object_TS := File_Stamp (Source.Id.Object_Path); end if; else Set_Failed_Compilation_Status (Comp_Data.Source_Project); Slave := To_Unbounded_String (Get_Slave_For (Process)); end if; Language := Source.Id.Language; -- If there is a mapping file used, recycle it in the hash -- table of the language. if Comp_Data.Mapping_File /= No_Path and then Language /= No_Language_Index then Mapping_Files_Htable.Set (T => Language.Mapping_Files, K => Comp_Data.Mapping_File, E => Comp_Data.Mapping_File); end if; Config := Language.Config; if Config.Dependency_Kind = Makefile and then Config.Compute_Dependency /= No_Name_List then declare Current_Dir : constant Dir_Name_Str := Get_Current_Dir; List : Name_List_Index := Config.Compute_Dependency; Nam : Name_Node := Source.Tree.Shared.Name_Lists.Table (List); Exec_Name : constant String := Get_Name_String (Nam.Name); Exec_Path : OS_Lib.String_Access; begin Change_Dir (Get_Name_String (Source.Id.Project.Object_Directory.Display_Name)); Comp_Data.Mapping_File := No_Path; Comp_Data.Purpose := Dependency; -- ??? We search for it on the PATH for every file, -- this is very inefficient Exec_Path := Locate_Exec_On_Path (Exec_Name); if Exec_Path = null then Fail_Program (Source.Tree, "unable to find dependency builder " & Exec_Name); end if; List := Nam.Next; Compilation_Options.Last := 0; if List = No_Name_List then Name_Len := 0; else loop Nam := Source.Tree.Shared.Name_Lists.Table (List); List := Nam.Next; if List = No_Name_List then Get_Name_String (Nam.Name); exit; end if; Add_Option (Nam.Name, Compilation_Options, Opt.Verbose_Mode); end loop; end if; Add_Str_To_Name_Buffer (Get_Name_String (Source.Id.Path.Display_Name)); Add_Option (Name_Buffer (1 .. Name_Len), Compilation_Options, Opt.Verbose_Mode, Simple_Name => not Opt.Verbose_Mode); if not Opt.Quiet_Output then if Opt.Verbose_Mode then Write_Str (Exec_Path.all); else Write_Str (Exec_Name); end if; Write_Str (" "); for Option in 1 .. Compilation_Options.Last loop if Compilation_Options.Visible (Option) then Write_Str (Compilation_Options.Options (Option).all); Write_Str (" "); end if; end loop; Write_Eol; end if; Comp_Data.Process := Run (Executable => Exec_Path.all, Options => Compilation_Options.Options (1 .. Compilation_Options.Last), Project => Comp_Data.Source_Project, Obj_Name => Get_Name_String (Source.Id.Object), Output_File => Get_Name_String (Source.Id.Dep_Path), Err_To_Out => True, Force_Local => True); Compilation_Htable.Set (Comp_Data.Process, Comp_Data); Free (Exec_Path); Change_Dir (Current_Dir); end; else Outstanding_Compiles := Outstanding_Compiles - 1; return; end if; elsif Comp_Data.Purpose = Dependency then Outstanding_Compiles := Outstanding_Compiles - 1; return; end if; end if; end loop; end Await_Compile; --------------------- -- Config_File_For -- --------------------- function Config_File_For (Project : Project_Id; Package_Name : Name_Id; Attribute_Name : Name_Id; Language : Name_Id) return Path_Name_Type is function Absolute_Path (Path : Path_Name_Type; Project : Project_Id) return Path_Name_Type; -- Returns an absolute path for a config file ------------------- -- Absolute_Path -- ------------------- function Absolute_Path (Path : Path_Name_Type; Project : Project_Id) return Path_Name_Type is begin Get_Name_String (Path); if not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)) then Get_Name_String (Project.Directory.Display_Name); if Name_Buffer (Name_Len) /= Directory_Separator then Add_Char_To_Name_Buffer (Directory_Separator); end if; Add_Str_To_Name_Buffer (Get_Name_String (Path)); end if; return Name_Find; end Absolute_Path; Config_Package : constant Package_Id := Value_Of (Name => Package_Name, In_Packages => Project.Decl.Packages, Shared => Project_Tree.Shared); Config_Variable : Variable_Value := Value_Of (Name => Language, Attribute_Or_Array_Name => Attribute_Name, In_Package => Config_Package, Shared => Project_Tree.Shared); begin -- Get the config pragma attribute when the language is Ada and the -- config file attribute is not declared. if Config_Variable = Nil_Variable_Value and then Config_Package /= No_Package and then Language = Name_Ada then if Attribute_Name = Name_Global_Config_File then Config_Variable := Value_Of (Variable_Name => Name_Global_Configuration_Pragmas, In_Variables => Project_Tree.Shared.Packages.Table (Config_Package).Decl.Attributes, Shared => Project_Tree.Shared); elsif Attribute_Name = Name_Local_Config_File then Config_Variable := Value_Of (Variable_Name => Name_Local_Configuration_Pragmas, In_Variables => Project_Tree.Shared.Packages.Table (Config_Package).Decl.Attributes, Shared => Project_Tree.Shared); end if; end if; if Config_Variable = Nil_Variable_Value then return No_Path; else Get_Name_String (Config_Variable.Value); if Name_Len = 0 then return No_Path; else return Absolute_Path (Path_Name_Type (Config_Variable.Value), Config_Variable.Project); end if; end if; end Config_File_For; ------------------------ -- Create_Config_File -- ------------------------ procedure Create_Config_File (For_Project : Project_Id; Config : Language_Config; Language : Name_Id) is File_Name : Path_Name_Type := No_Path; File : File_Descriptor := Invalid_FD; Source : Source_Id; Iter : Source_Iterator; procedure Check (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean); -- Check the naming schemes of the different projects of the project -- tree. For each different naming scheme issue the pattern config -- declarations. procedure Check_Temp_File; -- Check if a temp file has been created. If not, create one procedure Copy_Config_File (Project : Project_Id; Package_Name : Name_Id; Attribute_Name : Name_Id; Language : Name_Id); -- If a specified config file exists, copy it in the temporary config -- file. procedure Put_Line (File : File_Descriptor; S : String); -- Output procedure, analogous to normal Text_IO proc of same name ----------- -- Check -- ----------- procedure Check (Project : Project_Id; Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Dummy, Tree); Lang_Id : Language_Ptr := Project.Languages; Current_Naming : Positive := 1; procedure Replace; ------------- -- Replace -- ------------- procedure Replace is Cur : Positive := 1; procedure Substitute (N : File_Name_Type); procedure Substitute (Name : String); ---------------- -- Substitute -- ---------------- procedure Substitute (N : File_Name_Type) is begin if N = No_File then Cur := Cur + 1; else Substitute (Get_Name_String (N)); end if; end Substitute; procedure Substitute (Name : String) is begin Name_Buffer (Cur + Name'Length .. Name_Len - 2 + Name'Length) := Name_Buffer (Cur + 2 .. Name_Len); Name_Buffer (Cur .. Cur + Name'Length - 1) := Name; Name_Len := Name_Len - 2 + Name'Length; Cur := Cur + Name'Length; end Substitute; begin while Cur < Name_Len loop if Name_Buffer (Cur) = '%' then case Name_Buffer (Cur + 1) is when 'b' => Substitute (Lang_Id.Config.Naming_Data.Body_Suffix); when 's' => Substitute (Lang_Id.Config.Naming_Data.Spec_Suffix); when 'd' => Substitute (Lang_Id.Config.Naming_Data.Dot_Replacement); when 'c' => Substitute (Image (Lang_Id.Config.Naming_Data.Casing)); when '%' => Name_Buffer (Cur .. Name_Len - 1) := Name_Buffer (Cur + 1 .. Name_Len); Name_Len := Name_Len - 1; Cur := Cur + 1; when others => Cur := Cur + 1; end case; else Cur := Cur + 1; end if; end loop; end Replace; begin if Current_Verbosity = High then Write_Str ("Checking project file """); Write_Str (Namet.Get_Name_String (Project.Name)); Write_Str ("""."); Write_Eol; end if; while Lang_Id /= No_Language_Index loop exit when Lang_Id.Name = Language; Lang_Id := Lang_Id.Next; end loop; if Lang_Id /= No_Language_Index then Current_Naming := Naming_Datas.First; while Current_Naming <= Naming_Datas.Last loop exit when Naming_Datas.Table (Current_Naming) = Lang_Id.Config.Naming_Data; Current_Naming := Current_Naming + 1; end loop; if Current_Naming > Naming_Datas.Last then Naming_Datas.Increment_Last; Naming_Datas.Table (Naming_Datas.Last) := Lang_Id.Config.Naming_Data; Check_Temp_File; if Lang_Id.Config.Config_Spec_Pattern /= No_Name then Get_Name_String (Lang_Id.Config.Config_Spec_Pattern); Replace; Put_Line (File, Name_Buffer (1 .. Name_Len)); end if; if Lang_Id.Config.Config_Body_Pattern /= No_Name then Get_Name_String (Lang_Id.Config.Config_Body_Pattern); Replace; Put_Line (File, Name_Buffer (1 .. Name_Len)); end if; end if; end if; end Check; --------------------- -- Check_Temp_File -- --------------------- procedure Check_Temp_File is begin if File = Invalid_FD then Tempdir.Create_Temp_File (File, Name => File_Name); if File = Invalid_FD then Fail_Program (Project_Tree, "unable to create temporary configuration pragmas file"); else Record_Temp_File (Project_Tree.Shared, File_Name); if Opt.Verbose_Mode and then Opt.Verbosity_Level > Opt.Low then Write_Str ("Creating temp file """); Write_Str (Get_Name_String (File_Name)); Write_Line (""""); end if; end if; end if; end Check_Temp_File; ---------------------- -- Copy_Config_File -- ---------------------- procedure Copy_Config_File (Project : Project_Id; Package_Name : Name_Id; Attribute_Name : Name_Id; Language : Name_Id) is Config_File_Path : constant Path_Name_Type := Config_File_For (Project, Package_Name, Attribute_Name, Language); Config_File : Text_IO.File_Type; Line : String (1 .. 1_000); Last : Natural; begin if Config_File_Path /= No_Path then begin Open (Config_File, In_File, Get_Name_String (Config_File_Path)); exception when others => Fail_Program (Project_Tree, "unable to open config file " & Get_Name_String (Config_File_Path)); end; Check_Temp_File; while not End_Of_File (Config_File) loop Get_Line (Config_File, Line, Last); Put_Line (File, Line (1 .. Last)); end loop; Close (Config_File); end if; end Copy_Config_File; -------------- -- Put_Line -- -------------- procedure Put_Line (File : File_Descriptor; S : String) is S0 : String (1 .. S'Length + 1); Last : Natural; begin -- Add an ASCII.LF to the string. As this config file is supposed to -- be used only by the compiler, we don't care about the characters -- for the end of line. In fact we could have put a space, but -- it is more convenient to be able to read gnat.adc during -- development, for which the ASCII.LF is fine. S0 (1 .. S'Length) := S; S0 (S0'Last) := ASCII.LF; Last := Write (File, S0'Address, S0'Length); if Last /= S'Length + 1 then Fail_Program (Project_Tree, "Disk full"); end if; if Current_Verbosity = High then Write_Line (S); end if; end Put_Line; procedure Check_All_Projects is new For_Every_Project_Imported (Boolean, Check); Dummy : Boolean := False; -- Start of processing for Create_Config_File begin -- Nothing to do if config has already been checked if For_Project.Config_Checked then return; end if; if Config.Config_File_Unique then -- Copy an eventual global config file Copy_Config_File (Main_Project, Name_Builder, Name_Global_Config_File, Language); -- Copy an eventual local config file Copy_Config_File (For_Project, Name_Compiler, Name_Local_Config_File, Language); end if; For_Project.Config_Checked := True; Naming_Datas.Init; Check_All_Projects (For_Project, Project_Tree, Dummy); -- Visit all the units and issue the config declarations for those that -- need one. Iter := For_Each_Source (Project_Tree); loop Source := Prj.Element (Iter); exit when Source = No_Source; if Source.Language.Name = Language and then Source.Naming_Exception /= No and then Source.Unit /= No_Unit_Index and then not Source.Locally_Removed and then Source.Replaced_By = No_Source then Name_Len := 0; if Source.Kind = Spec then if Source.Index = 0 and then Config.Config_Spec /= No_Name then Get_Name_String (Config.Config_Spec); elsif Source.Index /= 0 and then Config.Config_Spec_Index /= No_Name then Get_Name_String (Config.Config_Spec_Index); end if; else if Source.Index = 0 and then Config.Config_Body /= No_Name then Get_Name_String (Config.Config_Body); elsif Source.Index /= 0 and then Config.Config_Body_Index /= No_Name then Get_Name_String (Config.Config_Body_Index); end if; end if; if Name_Len /= 0 then declare Cur : Positive := 1; Unit : constant String := Get_Name_String (Source.Unit.Name); File_Name : constant String := Get_Name_String (Source.Display_File); begin while Cur < Name_Len loop if Name_Buffer (Cur) /= '%' then Cur := Cur + 1; else case Name_Buffer (Cur + 1) is when 'u' => Name_Buffer (Cur + Unit'Length .. Name_Len - 2 + Unit'Length) := Name_Buffer (Cur + 2 .. Name_Len); Name_Buffer (Cur .. Cur + Unit'Length - 1) := Unit; Cur := Cur + Unit'Length; Name_Len := Name_Len - 2 + Unit'Length; when 'f' => Name_Buffer (Cur + File_Name'Length .. Name_Len - 2 + File_Name'Length) := Name_Buffer (Cur + 2 .. Name_Len); Name_Buffer (Cur .. Cur + File_Name'Length - 1) := File_Name; Cur := Cur + File_Name'Length; Name_Len := Name_Len - 2 + File_Name'Length; when 'i' => declare Index_String : constant String := Source.Index'Img; begin Name_Buffer (Cur + Index_String'Length .. Name_Len - 2 + Index_String'Length) := Name_Buffer (Cur + 2 .. Name_Len); Name_Buffer (Cur .. Cur + Index_String'Length - 1) := Index_String; Cur := Cur + Index_String'Length; Name_Len := Name_Len - 2 + Index_String'Length; end; when '%' => Name_Buffer (Cur .. Name_Len - 1) := Name_Buffer (Cur + 1 .. Name_Len); Cur := Cur + 1; Name_Len := Name_Len - 1; when others => Cur := Cur + 1; end case; end if; end loop; Put_Line (File, Name_Buffer (1 .. Name_Len)); end; end if; end if; Next (Iter); end loop; if File /= Invalid_FD then Close (File); For_Project.Config_File_Name := File_Name; end if; end Create_Config_File; ----------------------------- -- Create_Object_Path_File -- ----------------------------- procedure Create_Object_Path_File (Project : Project_Id) is FD : File_Descriptor; Name : Path_Name_Type; LF : constant String := (1 => ASCII.LF); procedure Add (Project : Project_Id; In_Tree : Project_Tree_Ref; Dummy : in out Boolean); -- Add the object directory of a project to the file --------- -- Add -- --------- procedure Add (Project : Project_Id; In_Tree : Project_Tree_Ref; Dummy : in out Boolean) is pragma Unreferenced (Dummy, In_Tree); Path : constant Path_Name_Type := Get_Object_Directory (Project, Including_Libraries => True, Only_If_Ada => False); Last : Natural; pragma Unreferenced (Last); begin if Path /= No_Path then Get_Name_String (Path); Last := Write (FD, Name_Buffer (1)'Address, Name_Len); Last := Write (FD, LF (1)'Address, 1); end if; Dummy := True; end Add; procedure For_All_Projects is new For_Every_Project_Imported (Boolean, Add); Status : Boolean := False; pragma Warnings (Off, Status); begin Tempdir.Create_Temp_File (FD, Name); Project.Object_Path_File := Name; For_All_Projects (Project, Project_Tree, Status, Include_Aggregated => True); Close (FD, Status); end Create_Object_Path_File; ---------------------- -- Recursive_Import -- ---------------------- procedure Recursive_Import (Project : Project_Id) is Ext : constant Project_Id := Project.Extends; L : Project_List := Project.Imported_Projects; begin if Ext /= No_Project and then not Imports.Get (Ext) then Imports.Set (Ext, True); Recursive_Import (Ext); end if; while L /= null loop if not Imports.Get (L.Project) then Imports.Set (L.Project, True); Recursive_Import (L.Project); end if; L := L.Next; end loop; end Recursive_Import; ---------------------- -- Directly_Imports -- ---------------------- function Directly_Imports (Project : Project_Id; Imported : Project_Id) return Boolean is L : Project_List := Project.Imported_Projects; P : Project_Id; begin while L /= null loop P := L.Project; while P /= No_Project loop if Imported = P then return True; end if; P := P.Extends; end loop; L := L.Next; end loop; return False; end Directly_Imports; --------- -- Run -- --------- procedure Run is procedure Do_Compile (Project : Project_Id; Tree : Project_Tree_Ref); ---------------- -- Do_Compile -- ---------------- procedure Do_Compile (Project : Project_Id; Tree : Project_Tree_Ref) is use type Containers.Count_Type; begin if Builder_Data (Tree).Need_Compilation then Compilation_Phase (Project, Tree); if Total_Errors_Detected > 0 or else not Bad_Compilations.Is_Empty then -- If switch -k or -jnn (with nn > 1), output a summary of the -- sources that could not be compiled. if (Opt.Keep_Going or else Get_Maximum_Processes > 1) and then not Bad_Compilations.Is_Empty then Write_Eol; for Index in Bad_Compilations.Iterate loop declare Source : constant Source_Id := Bad_Compilations_Set.Key (Index); Slave : constant String := Bad_Compilations_Set.Element (Index); begin if Source /= No_Source then Write_Str (" compilation of "); Write_Str (Get_Name_String (Source.Display_File)); Write_Str (" failed"); if Slave /= "" then Write_Str (" on " & Slave); end if; Write_Eol; end if; end; end loop; Write_Eol; end if; if Opt.Keep_Going and then Project.Qualifier = Aggregate then Bad_Compilations.Clear; else if Distributed_Mode and then Slave_Initialized then Gprbuild.Compilation.Slave.Unregister_Remote_Slaves; end if; Fail_Program (Tree, "*** compilation phase failed"); end if; end if; end if; end Do_Compile; procedure Compile_All is new For_Project_And_Aggregated (Do_Compile); begin Compile_All (Main_Project, Project_Tree); -- Unregister the slaves and get back compiled object code. This is a -- nop if no compilation has been done. Gprbuild.Compilation.Slave.Unregister_Remote_Slaves; end Run; ----------------------- -- Compilation_Phase -- ----------------------- procedure Compilation_Phase (Main_Project : Project_Id; Project_Tree : Project_Tree_Ref) is type Local_Project_Data is record Include_Language : Language_Ptr := No_Language_Index; -- Prepared arguments for "include" parameters (-I or include file). -- These are specific to each language and project. Include_Path_File : Path_Name_Type; -- The path name of the of the source search directory file Imported_Dirs_Switches : Argument_List_Access; -- List of the source search switches (-I) to be used -- when compiling. Include_Path : OS_Lib.String_Access := null; -- The search source path for the project. Used as the value for an -- environment variable, specified by attribute Include_Path -- (). The names of the environment variables are in component -- Include_Path of the records Language_Config. end record; -- project-specific data required for this procedure. These are not -- stored in the Project_Data record so that projects kept in memory do -- not have to allocate space for these temporary data No_Local_Project_Data : constant Local_Project_Data := (Include_Language => No_Language_Index, Include_Path => null, Imported_Dirs_Switches => null, Include_Path_File => No_Path); package Local_Projects_HT is new Simple_HTable (Header_Num => Prj.Header_Num, Element => Local_Project_Data, No_Element => No_Local_Project_Data, Key => Project_Id, Hash => Prj.Hash, Equal => "="); Local_Projects : Local_Projects_HT.Instance; Current_Project : Project_Id := No_Project; Current_Language_Ind : Language_Ptr := No_Language_Index; -- The project for which the include path environment has been set last, -- to avoid computing it several times. Dep_File : Text_File; Start : Natural; Finish : Natural; Last_Obj : Natural; procedure Add_Config_File_Switch (Config : Language_Config; Path_Name : Path_Name_Type); procedure Record_ALI_For (Source_Identity : Queue.Source_Info; The_ALI : ALI.ALI_Id := ALI.No_ALI_Id); -- Record the Id of an ALI file in Good_ALI table. -- The_ALI can contain the pre-parsed ali file, to save time. -- Tree is the tree to which Source_Identity belongs function Phase_2_Makefile (Src_Data : Queue.Source_Info) return Boolean; function Phase_2_ALI (Src_Data : Queue.Source_Info) return Boolean; -- Process Wait_For_Available_Slot depending on Src_Data.Dependency type -- This returns whether the compilation is considered as successful or -- not. procedure Set_Options_For_File (Id : Source_Id); -- Prepare the compiler options to use when building Id procedure Process_Project_Phase_1 (Source : Queue.Source_Info); -- If some compilation is needed for this project, perform it function Must_Exit_Because_Of_Error return Boolean; -- Return True if there were errors and the user decided to exit in such -- a case. This waits for any outstanding compilation. function Check_Switches_File (Id : Source_Id) return Boolean; -- Check in its switches file where Id was compiled with the same -- switches procedure Update_Object_Path (Id : Source_Id; Source_Project : Project_Id); -- Update, if necessary, the path of the object file, of the dependency -- file and of the switches file, in the case of the compilation of a -- source in an extended project, when the source is in a project being -- extended. procedure Add_Dependency_Options (Id : Source_Id); -- Add switches to the compilation command line to create the -- dependency file procedure Add_Object_File_Switches (Id : Source_Id); -- If there are switches to specify the name of the object file, add -- them. procedure Add_Object_Path_Switches (Id : Source_Id); -- If attribute Compiler'Object_Path_Switches has been specified, create -- the temporary object path file, if not already done, and add the -- switch(es) to the invocation of the compiler. procedure Add_Config_File_Switches (Id : Source_Id; Source_Project : Project_Id); -- If Config_File_Switches is specified, check if a config file need to -- be specified. Return the path to the config file procedure Add_Trailing_Switches (Id : Source_Id); -- Add the trailing required switches, if any, so that they will be put -- in the switches file. procedure Add_Name_Of_Source_Switches (Id : Source_Id); -- Add the name of the source to be compiled function Add_Mapping_File_Switches (Source : Queue.Source_Info; Source_Project : Project_Id) return Path_Name_Type; -- If the compiler supports mapping files, add the necessary switch. -- Returns the name of the mapping file to use (or No_File) procedure Add_Multi_Unit_Switches (Id : Source_Id); -- Add, if needed, the required switches to compile a multi-unit source -- file. procedure Spawn_Compiler_And_Register (Source : Queue.Source_Info; Source_Project : Project_Id; Compiler_Path : String; Mapping_File_Path : Path_Name_Type; Last_Switches_For_File : Integer); -- Spawn the compiler with the arguments currently set in -- Compiler_Options. It registers the process we just spawned, so that -- we start monitoring it. -- This also displays on the output the command we are spawning. -- Last_Switches_For_File is the index in Compilation_Options of the -- last switch that should be written to the switches file. All -- following switches are not output in that file. function Get_Compatible_Languages (Lang : Language_Ptr) return Name_Ids; -- Return the list of languages that Id could potentially include (for -- instance "C" if Id is a "C++" file. This also includes Id's own -- language. procedure Prepare_Imported_Dirs_Switches (Data : out Local_Project_Data; Project : Project_Id; Lang : Language_Ptr); -- Add the switches for include directories to the command line (these -- are the "-I" switches in the case of C for instance). procedure Prepare_Include_Path_File (Data : out Local_Project_Data; Project : Project_Id; Lang : Language_Ptr); -- Create a file to pass the include directories to the compiler procedure Start_Compile_If_Possible; -- Checks if there is more work that we can do (ie the Queue is non -- empty). If there is, do it only if we have not yet used up all the -- available processes. procedure Wait_For_Available_Slot; -- Check if we should wait for a compilation to finish. This is the case -- if all the available processes are busy compiling sources or there is -- nothing else to do (that is the Q is empty and there are outstanding -- compilations). procedure Set_Env_For_Include_Dirs (Id : Source_Id; Source_Project : Project_Id); -- Set environment variables or switches to pass the include directories -- to the compiler ---------------------------- -- Add_Config_File_Switch -- ---------------------------- procedure Add_Config_File_Switch (Config : Language_Config; Path_Name : Path_Name_Type) is List : Name_List_Index := Config.Config_File_Switches; Nam : Name_Node; begin while List /= No_Name_List loop Nam := Project_Tree.Shared.Name_Lists.Table (List); Get_Name_String (Nam.Name); if Nam.Next = No_Name_List then Add_Str_To_Name_Buffer (Get_Name_String (Path_Name)); end if; Add_Option (Name_Buffer (1 .. Name_Len), To => Compilation_Options, Display => Opt.Verbose_Mode); List := Nam.Next; end loop; end Add_Config_File_Switch; -------------------- -- Record_ALI_For -- -------------------- procedure Record_ALI_For (Source_Identity : Queue.Source_Info; The_ALI : ALI.ALI_Id := ALI.No_ALI_Id) is Local_ALI : ALI.ALI_Id := The_ALI; Text : Text_Buffer_Ptr; begin if The_ALI = ALI.No_ALI_Id then Text := Read_Library_Info_From_Full (File_Name_Type (Source_Identity.Id.Dep_Path), Source_Identity.Id.Dep_TS'Access); if Text /= null then -- Read the ALI file but read only the necessary lines Local_ALI := ALI.Scan_ALI (File_Name_Type (Source_Identity.Id.Dep_Path), Text, Ignore_ED => False, Err => True, Ignore_Errors => True, Read_Lines => "W"); Free (Text); end if; end if; if Local_ALI /= ALI.No_ALI_Id then Queue.Insert_Withed_Sources_For (Local_ALI, Source_Identity.Tree); ALI.Initialize_ALI; ALI.Util.Initialize_ALI_Source; end if; end Record_ALI_For; ---------------------- -- Phase_2_Makefile -- ---------------------- function Phase_2_Makefile (Src_Data : Queue.Source_Info) return Boolean is Compilation_OK : Boolean := True; begin Open (Dep_File, Get_Name_String (Src_Data.Id.Dep_Path)); if Is_Valid (Dep_File) then Big_Loop : loop declare End_Of_File_Reached : Boolean := False; Object_Found : Boolean := False; begin loop if End_Of_File (Dep_File) then End_Of_File_Reached := True; exit; end if; Get_Line (Dep_File, Name_Buffer, Name_Len); if Name_Len > 0 and then Name_Buffer (1) /= '#' then -- Skip a first line that is an empty -- continuation line. for J in 1 .. Name_Len - 1 loop if Name_Buffer (J) /= ' ' then Object_Found := True; exit; end if; end loop; exit when Object_Found or else Name_Buffer (Name_Len) /= '\'; end if; end loop; exit Big_Loop when End_Of_File_Reached; end; Start := 1; Finish := Index (Name_Buffer (1 .. Name_Len), ": "); exit Big_Loop when Finish = 0; Last_Obj := Finish; loop Last_Obj := Last_Obj - 1; exit when Last_Obj = Start or else Name_Buffer (Last_Obj) /= ' '; end loop; while Start < Last_Obj and then Name_Buffer (Start) = ' ' loop Start := Start + 1; end loop; Start := Finish + 2; -- Process each line Line_Loop : loop declare Line : String := Name_Buffer (1 .. Name_Len); Last : Natural := Name_Len; begin Name_Loop : loop -- Find the beginning of the next source path -- name. while Start < Last and then Line (Start) = ' ' loop Start := Start + 1; end loop; -- Go to next line when there is a -- continuation character \ at the end of the -- line. exit Name_Loop when Start = Last and then Line (Start) = '\'; -- We should not be at the end of the line, -- without a continuation character \. exit Name_Loop when Start = Last; -- Look for the end of the source path name Finish := Start; while Finish < Last loop if Line (Finish) = '\' then -- On Windows, a '\' is part of the -- path name, except when it is not the -- first character followed by another -- '\' or by a space. On other -- platforms, when we are getting a '\' -- that is not the last character of -- the line, the next character is part -- of the path name, even if it is a -- space. if On_Windows and then Finish = Start and then Line (Finish + 1) = '\' then Finish := Finish + 2; elsif On_Windows and then Line (Finish + 1) /= '\' and then Line (Finish + 1) /= ' ' then Finish := Finish + 1; else Line (Finish .. Last - 1) := Line (Finish + 1 .. Last); Last := Last - 1; end if; else -- A space that is not preceded by '\' -- indicates the end of the path name. exit when Line (Finish + 1) = ' '; Finish := Finish + 1; end if; end loop; -- Check this source declare Src_Name : constant String := Normalize_Pathname (Name => Line (Start .. Finish), Resolve_Links => False, Case_Sensitive => False); Source_2 : Source_Id; begin Name_Len := 0; Add_Str_To_Name_Buffer (Src_Name); Source_2 := Source_Paths_Htable.Get (Src_Data.Tree.Source_Paths_HT, Name_Find); if Source_2 /= No_Source then -- It is a source of a project if not Project_Extends (Src_Data.Id.Project, Source_2.Project) and then not Project_Extends (Source_2.Project, Src_Data.Id.Project) then -- It is not a source of the same project -- as the source just compiled. Check if -- it can be imported. if not Indirect_Imports then if Directly_Imports (Src_Data.Id.Project, Source_2.Project) then -- It is a source of a directly -- imported project. Record its -- project, for later processing. Imports.Set (Source_2.Project, True); else -- It is a source of a project that -- is not directly imported. Record -- the source for later processing. Included_Sources.Append (Source_2); end if; end if; if not Source_2.In_Interfaces then -- It is not a source in the interfaces -- of its project. Report an error and -- invalidate the compilation. Write_Char ('"'); Write_Str (Get_Name_String (Src_Data.Id.Path.Display_Name)); Write_Str (""" cannot import """); Write_Str (Src_Name); Write_Line (""":"); Write_Str (" it is not part of the " & "interfaces of its project """); Write_Str (Get_Name_String (Source_2.Project.Display_Name)); Write_Line (""""); Compilation_OK := False; end if; end if; end if; end; exit Line_Loop when Finish = Last; -- Go get the next source on the line Start := Finish + 1; end loop Name_Loop; end; -- If we are here, we had a continuation character -- \ at the end of the line, so we continue with -- the next line. Get_Line (Dep_File, Name_Buffer, Name_Len); Start := 1; Finish := 1; end loop Line_Loop; end loop Big_Loop; Close (Dep_File); if Included_Sources.Last > 0 then -- Sources in project that are not directly imported -- have been found. Check if they may be imported by -- other allowed imported sources. declare L : Project_List := Src_Data.Id.Project.Imported_Projects; begin -- Put in hash table Imports the project trees -- rooted at the projects that are already in -- Imports. while L /= null loop if Imports.Get (L.Project) then Recursive_Import (L.Project); end if; L := L.Next; end loop; -- For all the imported sources from project not -- directly imported, check if their projects are -- in table imports. for J in 1 .. Included_Sources.Last loop declare Included : constant Source_Id := Included_Sources.Table (J); begin if not Imports.Get (Included.Project) then -- This source is either directly imported or -- imported from another source that should not be -- imported. Report an error and invalidate the -- compilation. Write_Char ('"'); Write_Str (Get_Name_String (Src_Data.Id.Path.Display_Name)); Write_Str (""" cannot import """); Write_Str (Get_Name_String (Included.Path.Display_Name)); Write_Line (""":"); Write_Str (" """); Write_Str (Get_Name_String (Src_Data.Id.Project.Display_Name)); Write_Str (""" does not directly import project """); Write_Str (Get_Name_String (Included.Project.Display_Name)); Write_Line (""""); Compilation_OK := False; end if; end; end loop; end; end if; end if; return Compilation_OK; end Phase_2_Makefile; ----------------- -- Phase_2_ALI -- ----------------- function Phase_2_ALI (Src_Data : Queue.Source_Info) return Boolean is Compilation_OK : Boolean := True; Text : Text_Buffer_Ptr := Read_Library_Info_From_Full (File_Name_Type (Src_Data.Id.Dep_Path), Src_Data.Id.Dep_TS'Access); The_ALI : ALI.ALI_Id := ALI.No_ALI_Id; Sfile : File_Name_Type; Afile : File_Name_Type; Source_2 : Source_Id; procedure Check_Source (Sfile : File_Name_Type); -- Check if source Sfile is in the same project file as the Src_Data -- source file. Invalidate the compilation if it is not. ------------------ -- Check_Source -- ------------------ procedure Check_Source (Sfile : File_Name_Type) is Source_3 : constant Source_Id := Find_Source (Src_Data.Tree, No_Project, Base_Name => Sfile); begin if Source_3 = No_Source then Write_Str ("source "); Write_Str (Get_Name_String (Sfile)); Write_Line (" is not a source of a project"); Compilation_OK := False; elsif Ultimate_Extending_Project_Of (Source_3.Project) /= Ultimate_Extending_Project_Of (Src_Data.Id.Project) then Write_Str ("sources "); Write_Str (Get_Name_String (Source_3.File)); Write_Str (" and "); Write_Str (Get_Name_String (Src_Data.Id.File)); Write_Str (" belong to different projects: "); Write_Str (Get_Name_String (Source_3.Project.Display_Name)); Write_Str (" and "); Write_Line (Get_Name_String (Src_Data.Id.Project.Display_Name)); Compilation_OK := False; end if; end Check_Source; begin if Text /= null then -- Read the ALI file but read only the necessary lines The_ALI := ALI.Scan_ALI (File_Name_Type (Src_Data.Id.Dep_Path), Text, Ignore_ED => False, Err => True, Ignore_Errors => True, Read_Lines => "DW"); if The_ALI /= ALI.No_ALI_Id then for J in ALI.ALIs.Table (The_ALI).First_Unit .. ALI.ALIs.Table (The_ALI).Last_Unit loop for K in ALI.Units.Table (J).First_With .. ALI.Units.Table (J).Last_With loop if not ALI.Withs.Table (K).Implicit_With_From_Instantiation then Sfile := ALI.Withs.Table (K).Sfile; -- Skip generics if Sfile /= No_File then -- Look for this source Afile := ALI.Withs.Table (K).Afile; Source_2 := Source_Files_Htable.Get (Src_Data.Tree.Source_Files_HT, Sfile); while Source_2 /= No_Source loop if Is_Compilable (Source_2) and then Source_2.Dep_Name = Afile then case Source_2.Kind is when Spec => null; when Impl => if Is_Subunit (Source_2) then Source_2 := No_Source; end if; when Sep => Source_2 := No_Source; end case; exit; end if; Source_2 := Source_2.Next_With_File_Name; end loop; -- If it is the source of a project that is not the -- project of the source just compiled, check if it -- is allowed to be imported. if Source_2 /= No_Source then if not Project_Extends (Src_Data.Id.Project, Source_2.Project) and then not Project_Extends (Source_2.Project, Src_Data.Id.Project) then if not Indirect_Imports and then not Directly_Imports (Src_Data.Id.Project, Source_2.Project) then -- It is in a project that is not directly -- imported. Report an error and -- invalidate the compilation. Write_Str ("Unit """); Write_Str (Get_Name_String (Src_Data.Id.Unit.Name)); Write_Str (""" cannot import unit """); Write_Str (Get_Name_String (Source_2.Unit.Name)); Write_Line (""":"); Write_Str (" """); Write_Str (Get_Name_String (Src_Data.Id.Project.Display_Name)); Write_Str (""" does not directly" & " import project """); Write_Str (Get_Name_String (Source_2.Project.Display_Name)); Write_Line (""""); Compilation_OK := False; elsif not Source_2.In_Interfaces then -- It is not an interface of its project. -- Report an error and invalidate the -- compilation. Write_Str ("Unit """); Write_Str (Get_Name_String (Src_Data.Id.Unit.Name)); Write_Str (""" cannot import unit """); Write_Str (Get_Name_String (Source_2.Unit.Name)); Write_Line (""":"); Write_Str (" it is not part of the " & "interfaces of its project """); Write_Str (Get_Name_String (Source_2.Project.Display_Name)); Write_Line (""""); Compilation_OK := False; end if; end if; end if; end if; end if; end loop; end loop; if Opt.No_Split_Units then -- Initialized the list of subunits with the unit name Subunits.Init; Subunits.Append (new String'(Get_Name_String (Src_Data.Id.Unit.Name))); -- First check that the spec and the body are in the same -- project. for J in ALI.ALIs.Table (The_ALI).First_Unit .. ALI.ALIs.Table (The_ALI).Last_Unit loop Check_Source (ALI.Units.Table (J).Sfile); end loop; -- Next, check the subunits, if any declare Subunit_Found : Boolean; Already_Found : Boolean; Last : Positive; begin -- Loop until we don't find new subunits loop Subunit_Found := False; for D in ALI.ALIs.Table (The_ALI).First_Sdep .. ALI.ALIs.Table (The_ALI).Last_Sdep loop if ALI.Sdep.Table (D).Subunit_Name /= No_Name then Get_Name_String (ALI.Sdep.Table (D).Subunit_Name); -- First check if we already found this subunit Already_Found := False; for K in 1 .. Subunits.Last loop if Name_Buffer (1 .. Name_Len) = Subunits.Table (K).all then Already_Found := True; exit; end if; end loop; if not Already_Found then -- Find the name of the parent Last := Name_Len - 1; while Last > 1 and then Name_Buffer (Last + 1) /= '.' loop Last := Last - 1; end loop; for J in 1 .. Subunits.Last loop if Subunits.Table (J).all = Name_Buffer (1 .. Last) then -- It is a new subunit, add it o the -- list and check if it is in the right -- project. Subunits.Append (new String' (Name_Buffer (1 .. Name_Len))); Subunit_Found := True; Check_Source (ALI.Sdep.Table (D).Sfile); exit; end if; end loop; end if; end if; end loop; exit when not Subunit_Found; end loop; end; end if; if Compilation_OK and then Builder_Data (Src_Data.Tree).Closure_Needed then Record_ALI_For (Src_Data, The_ALI); end if; end if; Free (Text); end if; return Compilation_OK; end Phase_2_ALI; -------------------------- -- Set_Options_For_File -- -------------------------- procedure Set_Options_For_File (Id : Source_Id) is Config : Language_Config renames Id.Language.Config; Builder_Options_Instance : constant Builder_Comp_Option_Table_Ref := Builder_Compiling_Options_HTable.Get (Id.Language.Name); Comp_Opt : constant Comp_Option_Table_Ref := Compiling_Options_HTable.Get (Id.Language.Name); List : Name_List_Index; Nam_Nod : Name_Node; First : Boolean; begin Compilation_Options.Last := 0; -- 1a) The leading required switches List := Config.Compiler_Leading_Required_Switches; First := True; while List /= No_Name_List loop Nam_Nod := Project_Tree.Shared.Name_Lists.Table (List); if Nam_Nod.Name /= Empty_String then Add_Option (Value => Nam_Nod.Name, To => Compilation_Options, Display => First or Opt.Verbose_Mode); First := False; end if; List := Nam_Nod.Next; end loop; -- 1b) The switches in CodePeer mode if Opt.CodePeer_Mode then -- Replace -x ada with -x adascil declare Cur : Integer := Compilation_Options.Last - 1; begin while Cur > 0 and then Compilation_Options.Options (Cur).all /= "-x" loop Cur := Cur - 1; end loop; if Cur /= 0 then Compilation_Options.Visible (Cur) := True; Compilation_Options.Options (Cur + 1) := new String'("adascil"); Compilation_Options.Visible (Cur + 1) := True; else Add_Option (Value => "-x", To => Compilation_Options, Display => True); Add_Option (Value => "adascil", To => Compilation_Options, Display => True); end if; end; Add_Option (Value => "-gnatcC", To => Compilation_Options, Display => True); end if; -- 2) the compilation switches specified in package Builder -- for all compilers, following "-cargs", if any. for Index in 1 .. All_Language_Builder_Compiling_Options.Last loop Add_Option_Internal_Codepeer (Value => All_Language_Builder_Compiling_Options.Table (Index), To => Compilation_Options, Display => True); end loop; -- 3) the compilation switches specified in package Builder -- for the compiler of the language, following -- -cargs:. if Builder_Options_Instance /= null then for Index in 1 .. Builder_Compiling_Options.Last (Builder_Options_Instance.all) loop Add_Option_Internal_Codepeer (Value => Builder_Options_Instance.Table (Index), To => Compilation_Options, Display => True); end loop; end if; -- 4) The PIC option if it exists, for shared libraries if Id.Project.Library and then Id.Project.Library_Kind /= Static then List := Config.Compilation_PIC_Option; while List /= No_Name_List loop Nam_Nod := Project_Tree.Shared.Name_Lists.Table (List); Add_Option (Value => Nam_Nod.Name, To => Compilation_Options, Display => True); List := Nam_Nod.Next; end loop; end if; -- 5) Compiler'Switches(), if it is -- defined, otherwise Compiler'Switches (), -- if defined. Add_Compilation_Switches (Id); -- 6) the switches specified on the gprbuild command line -- for all compilers, following "-cargs", if any. for Index in 1 .. All_Language_Compiling_Options.Last loop Add_Option_Internal_Codepeer (Value => All_Language_Compiling_Options.Table (Index), To => Compilation_Options, Display => True); end loop; -- 7) the switches specified on the gprbuild command line -- for the compiler of the language, following -- -cargs:. if Comp_Opt /= null then for Index in 1 .. Compiling_Options.Last (Comp_Opt.all) loop Add_Option_Internal_Codepeer (Value => Comp_Opt.Table (Index), To => Compilation_Options, Display => True); end loop; end if; end Set_Options_For_File; ------------------------- -- Check_Switches_File -- ------------------------- function Check_Switches_File (Id : Source_Id) return Boolean is File : Text_IO.File_Type; function Assert_Line (Current : String) return Boolean; -- Return False if Current is not the next line in the switches file ----------------- -- Assert_Line -- ----------------- function Assert_Line (Current : String) return Boolean is Line : String (1 .. 1_000); Last : Natural; begin if End_Of_File (File) then if Opt.Verbose_Mode then Write_Line (" -> switches file has fewer switches"); end if; Close (File); return False; end if; Get_Line (File, Line, Last); if Line (1 .. Last) /= Current then if Opt.Verbose_Mode then Write_Line (" -> switches file '" & Get_Name_String (Id.Switches_Path) & "' has different line"); Write_Line (" " & Line (1 .. Last)); Write_Line (" " & Current); end if; Close (File); return False; end if; return True; end Assert_Line; List : Name_List_Index; Nam_Nod : Name_Node; begin Open (File, In_File, Get_Name_String (Id.Switches_Path)); if not Assert_Line (String (Id.Object_TS)) then return True; end if; for Index in 1 .. Compilation_Options.Last loop if not Assert_Line (Compilation_Options.Options (Index).all) then return True; end if; end loop; List := Id.Language.Config.Compiler_Trailing_Required_Switches; while List /= No_Name_List loop Nam_Nod := Project_Tree.Shared.Name_Lists.Table (List); if not Assert_Line (Get_Name_String (Nam_Nod.Name)) then return True; end if; List := Nam_Nod.Next; end loop; if not End_Of_File (File) then if Opt.Verbose_Mode then Write_Line (" -> switches file has more switches"); end if; Close (File); return True; end if; Close (File); return False; exception when others => if Opt.Verbose_Mode then Write_Line (" -> no switches file"); end if; return True; end Check_Switches_File; ------------------------ -- Update_Object_Path -- ------------------------ procedure Update_Object_Path (Id : Source_Id; Source_Project : Project_Id) is begin Id.Object_Project := Source_Project; if Id.Object_Project /= Id.Project then if Id.Object /= No_File then Get_Name_String (Id.Object_Project.Object_Directory.Display_Name); Add_Str_To_Name_Buffer (Get_Name_String (Id.Object)); Id.Object_Path := Name_Find; end if; if Id.Dep_Name /= No_File then Get_Name_String (Id.Object_Project.Object_Directory.Display_Name); Add_Str_To_Name_Buffer (Get_Name_String (Id.Dep_Name)); Id.Dep_Path := Name_Find; end if; if Id.Switches /= No_File then Get_Name_String (Id.Object_Project.Object_Directory.Display_Name); Add_Str_To_Name_Buffer (Get_Name_String (Id.Switches)); Id.Switches_Path := Name_Find; end if; end if; end Update_Object_Path; ---------------------------- -- Add_Dependency_Options -- ---------------------------- procedure Add_Dependency_Options (Id : Source_Id) is List : Name_List_Index := Id.Language.Config.Dependency_Option; Node : Name_Node; begin if Id.Language.Config.Dependency_Kind /= None then while List /= No_Name_List loop Node := Project_Tree.Shared.Name_Lists.Table (List); List := Node.Next; if List = No_Name_List then Add_Option (Value => Get_Name_String (Node.Name) & Get_Name_String (Id.Dep_Name), To => Compilation_Options, Display => Opt.Verbose_Mode); else Add_Option (Value => Node.Name, To => Compilation_Options, Display => Opt.Verbose_Mode); end if; end loop; end if; end Add_Dependency_Options; ------------------------------ -- Add_Object_File_Switches -- ------------------------------ procedure Add_Object_File_Switches (Id : Source_Id) is List : Name_List_Index := Id.Language.Config.Object_File_Switches; Node : Name_Node; begin if List /= No_Name_List then loop Node := Project_Tree.Shared.Name_Lists.Table (List); exit when Node.Next = No_Name_List; Add_Option (Node.Name, To => Compilation_Options, Display => Opt.Verbose_Mode or else Id.Index /= 0); List := Node.Next; end loop; Get_Name_String (Node.Name); Add_Str_To_Name_Buffer (Get_Name_String (Id.Object)); Add_Option (Name_Buffer (1 .. Name_Len), To => Compilation_Options, Display => Opt.Verbose_Mode or else Id.Index /= 0); -- Always specify object-file for a multi-unit source file elsif Id.Index /= 0 then Add_Option ("-o", To => Compilation_Options, Display => True); Add_Option (Get_Name_String (Id.Object), To => Compilation_Options, Display => True); end if; end Add_Object_File_Switches; ------------------------------ -- Add_Object_Path_Switches -- ------------------------------ procedure Add_Object_Path_Switches (Id : Source_Id) is List : Name_List_Index := Id.Language.Config.Object_Path_Switches; Node : Name_Node; begin if List /= No_Name_List then if Id.Project.Object_Path_File = No_Path then Create_Object_Path_File (Id.Project); end if; while List /= No_Name_List loop Node := Project_Tree.Shared.Name_Lists.Table (List); exit when Node.Next = No_Name_List; Add_Option (Node.Name, To => Compilation_Options, Display => Opt.Verbose_Mode); List := Node.Next; end loop; Get_Name_String (Node.Name); Add_Str_To_Name_Buffer (Get_Name_String (Id.Project.Object_Path_File)); Add_Option (Name_Buffer (1 .. Name_Len), To => Compilation_Options, Display => Opt.Verbose_Mode); end if; end Add_Object_Path_Switches; ------------------------------ -- Add_Config_File_Switches -- ------------------------------ procedure Add_Config_File_Switches (Id : Source_Id; Source_Project : Project_Id) is Config : constant Language_Config := Id.Language.Config; Config_File_Path : Path_Name_Type; begin if Config.Config_File_Switches /= No_Name_List and then (Config.Config_Body /= No_Name or else Config.Config_Body_Index /= No_Name or else Config.Config_Body_Pattern /= No_Name or else Config.Config_Spec /= No_Name or else Config.Config_Spec_Index /= No_Name or else Config.Config_Spec_Pattern /= No_Name) then Create_Config_File (For_Project => Source_Project, Config => Config, Language => Id.Language.Name); if Source_Project.Config_File_Name /= No_Path then Add_Config_File_Switch (Config => Config, Path_Name => Source_Project.Config_File_Name); end if; if not Config.Config_File_Unique then Config_File_Path := Config_File_For (Project => Main_Project, Package_Name => Name_Builder, Attribute_Name => Name_Global_Config_File, Language => Id.Language.Name); if Config_File_Path /= No_Path then Add_Config_File_Switch (Config => Config, Path_Name => Config_File_Path); end if; Config_File_Path := Config_File_For (Project => Source_Project, Package_Name => Name_Compiler, Attribute_Name => Name_Local_Config_File, Language => Id.Language.Name); if Config_File_Path /= No_Path then Add_Config_File_Switch (Config => Config, Path_Name => Config_File_Path); end if; end if; end if; end Add_Config_File_Switches; ------------------------------- -- Add_Mapping_File_Switches -- ------------------------------- function Add_Mapping_File_Switches (Source : Queue.Source_Info; Source_Project : Project_Id) return Path_Name_Type is List : Name_List_Index := Source.Id.Language.Config.Mapping_File_Switches; Node : Name_Node; Mapping_File_Path : Path_Name_Type; begin if List /= No_Name_List then -- Check if there is a temporary mapping file we can use Mapping_File_Path := Mapping_Files_Htable.Get_First (Source.Id.Language.Mapping_Files); if Mapping_File_Path /= No_Path then -- Reuse this temporary mapping file and remove its -- name from the HTable so that it is not reused -- before the compilation terminates. Mapping_Files_Htable.Remove (Source.Id.Language.Mapping_Files, Mapping_File_Path); else -- Create a new temporary mapping file, as there are -- none that can be reused. Prj.Env.Create_Mapping_File (Project => Source_Project, Language => Source.Id.Language.Name, In_Tree => Source.Tree, Name => Mapping_File_Path); end if; while List /= No_Name_List loop Node := Source.Tree.Shared.Name_Lists.Table (List); List := Node.Next; if List /= No_Name_List then Add_Option (Value => Node.Name, To => Compilation_Options, Display => Opt.Verbose_Mode); else Get_Name_String (Node.Name); Add_Str_To_Name_Buffer (Get_Name_String (Mapping_File_Path)); Add_Option (Name_Buffer (1 .. Name_Len), To => Compilation_Options, Display => Opt.Verbose_Mode); end if; end loop; return Mapping_File_Path; else return No_Path; end if; end Add_Mapping_File_Switches; ----------------------------- -- Add_Multi_Unit_Switches -- ----------------------------- procedure Add_Multi_Unit_Switches (Id : Source_Id) is List : Name_List_Index := Id.Language.Config.Multi_Unit_Switches; begin if Id.Index /= 0 and then List /= No_Name_List then declare Index_Img : constant String := Id.Index'Img; Node : Name_Node; begin loop Node := Project_Tree.Shared.Name_Lists.Table (List); exit when Node.Next = No_Name_List; Add_Option (Node.Name, To => Compilation_Options, Display => True); List := Node.Next; end loop; Get_Name_String (Node.Name); Add_Str_To_Name_Buffer (Index_Img (2 .. Index_Img'Last)); Add_Option (Name_Buffer (1 .. Name_Len), To => Compilation_Options, Display => True); end; end if; end Add_Multi_Unit_Switches; --------------------------- -- Add_Trailing_Switches -- --------------------------- procedure Add_Trailing_Switches (Id : Source_Id) is List : Name_List_Index := Id.Language.Config.Compiler_Trailing_Required_Switches; Node : Name_Node; begin while List /= No_Name_List loop Node := Project_Tree.Shared.Name_Lists.Table (List); Add_Option (Node.Name, To => Compilation_Options, Display => Opt.Verbose_Mode); List := Node.Next; end loop; end Add_Trailing_Switches; --------------------------------- -- Add_Name_Of_Source_Switches -- --------------------------------- procedure Add_Name_Of_Source_Switches (Id : Source_Id) is List : Name_List_Index := Id.Language.Config.Source_File_Switches; Node : Name_Node; Source_Path : OS_Lib.String_Access; begin -- Add any source file prefix if List /= No_Name_List then loop Node := Project_Tree.Shared.Name_Lists.Table (List); exit when Node.Next = No_Name_List; Add_Option (Node.Name, To => Compilation_Options, Display => Opt.Verbose_Mode or else Id.Index /= 0); List := Node.Next; end loop; end if; -- Then handle the source file Get_Name_String (Id.Path.Display_Name); case Id.Language.Config.Path_Syntax is when Canonical => Source_Path := new String'(Name_Buffer (1 .. Name_Len)); when Host => Source_Path := To_Host_File_Spec (Name_Buffer (1 .. Name_Len)); end case; if Node.Name = No_Name then Add_Option_Internal (Source_Path, To => Compilation_Options, Display => True, Simple_Name => not Opt.Verbose_Mode); else Get_Name_String (Node.Name); Add_Option (Name_Buffer (1 .. Name_Len) & Source_Path.all, To => Compilation_Options, Display => True, Simple_Name => not Opt.Verbose_Mode); end if; end Add_Name_Of_Source_Switches; --------------------------------- -- Spawn_Compiler_And_Register -- --------------------------------- procedure Spawn_Compiler_And_Register (Source : Queue.Source_Info; Source_Project : Project_Id; Compiler_Path : String; Mapping_File_Path : Path_Name_Type; Last_Switches_For_File : Integer) is procedure Add_Process (Process : Id; Source : Queue.Source_Info; Source_Project : Project_Id; Mapping_File : Path_Name_Type; Purpose : Process_Purpose; Options : String_List_Access); -- Add compilation process and indicate that the object directory is -- busy. ----------------- -- Add_Process -- ----------------- procedure Add_Process (Process : Id; Source : Queue.Source_Info; Source_Project : Project_Id; Mapping_File : Path_Name_Type; Purpose : Process_Purpose; Options : String_List_Access) is begin Compilation_Htable.Set (Process, (Process, Source, Source_Project, Mapping_File, Purpose, Options)); Outstanding_Compiles := Outstanding_Compiles + 1; Queue.Set_Obj_Dir_Busy (Source.Id.Project.Object_Directory.Name); end Add_Process; function Get_Language return String is (if Source.Id.Language /= null then Get_Name_String (Source.Id.Language.Name) else ""); Process : Id; Options : String_List_Access; begin if not Opt.Quiet_Output then if Opt.Verbose_Mode then Write_Str (Compiler_Path); else Name_Len := 0; Add_Str_To_Name_Buffer (Base_Name (Compiler_Path)); if Executable_Suffix'Length /= 0 and then Name_Len > Executable_Suffix'Length and then Name_Buffer (Name_Len - Executable_Suffix'Length + 1 .. Name_Len) = Executable_Suffix.all then Name_Len := Name_Len - Executable_Suffix'Length; end if; Write_Str (Name_Buffer (1 .. Name_Len)); end if; for Option in 1 .. Compilation_Options.Last loop if Compilation_Options.Visible (Option) then Write_Char (' '); if Compilation_Options.Simple_Name (Option) then Write_Str (Base_Name (Compilation_Options.Options (Option).all)); else Write_Str (Compilation_Options.Options (Option).all); end if; end if; end loop; Write_Eol; end if; Process := Run (Compiler_Path, Compilation_Options.Options (1 .. Compilation_Options.Last), Source_Project, Language => Get_Language, Dep_Name => (if Source.Id.Dep_Name = No_File then "" else Get_Name_String (Source.Id.Dep_Name)), Obj_Name => (if Source.Id.Object = No_File then "" else Get_Name_String (Source.Id.Object))); if Last_Switches_For_File >= 0 then Compilation_Options.Last := Last_Switches_For_File; Add_Trailing_Switches (Source.Id); Options := new String_List' (Compilation_Options.Options (1 .. Compilation_Options.Last)); end if; Add_Process (Process => Process, Source => Source, Source_Project => Source_Project, Mapping_File => Mapping_File_Path, Purpose => Compilation, Options => Options); end Spawn_Compiler_And_Register; ------------------------------ -- Get_Compatible_Languages -- ------------------------------ function Get_Compatible_Languages (Lang : Language_Ptr) return Name_Ids is NL : Name_List_Index := Lang.Config.Include_Compatible_Languages; Languages : Name_Ids (1 .. 1 + Length (Project_Tree.Shared.Name_Lists, NL)); Index : Positive := 1; begin Languages (Index) := Lang.Name; while NL /= No_Name_List loop Index := Index + 1; Languages (Index) := Project_Tree.Shared.Name_Lists.Table (NL).Name; NL := Project_Tree.Shared.Name_Lists.Table (NL).Next; end loop; return Languages; end Get_Compatible_Languages; ------------------------------- -- Prepare_Include_Path_File -- ------------------------------- procedure Prepare_Include_Path_File (Data : out Local_Project_Data; Project : Project_Id; Lang : Language_Ptr) is FD : File_Descriptor; Status : Boolean; begin Get_Directories (Project_Tree => Project_Tree, For_Project => Project, Activity => Compilation, Languages => Get_Compatible_Languages (Lang)); Prj.Env.Create_New_Path_File (Shared => Project_Tree.Shared, Path_FD => FD, Path_Name => Data.Include_Path_File); if FD = Invalid_FD then Fail_Program (Project_Tree, "could not create temporary path file"); end if; for Index in 1 .. Directories.Last loop Get_Name_String (Directories.Table (Index)); Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := ASCII.LF; if Write (FD, Name_Buffer (1)'Address, Name_Len) /= Name_Len then Fail_Program (Project_Tree, "disk full when writing include path file"); end if; end loop; Close (FD, Status); if not Status then Fail_Program (Project_Tree, "disk full when writing include path file"); end if; end Prepare_Include_Path_File; ------------------------------------ -- Prepare_Imported_Dirs_Switches -- ------------------------------------ procedure Prepare_Imported_Dirs_Switches (Data : out Local_Project_Data; Project : Project_Id; Lang : Language_Ptr) is Len : constant Natural := Length (Project_Tree.Shared.Name_Lists, Lang.Config.Include_Option); Host_Path : OS_Lib.String_Access; Last : Natural := 0; List : Name_List_Index; Nam : Name_Node; begin Get_Directories (Project_Tree => Project_Tree, For_Project => Project, Activity => Compilation, Languages => Get_Compatible_Languages (Lang)); Free (Data.Imported_Dirs_Switches); Data.Imported_Dirs_Switches := new String_List (1 .. Directories.Last * Len); for Index in 1 .. Directories.Last loop List := Lang.Config.Include_Option; while List /= No_Name_List loop Nam := Project_Tree.Shared.Name_Lists.Table (List); exit when Nam.Next = No_Name_List; Last := Last + 1; Data.Imported_Dirs_Switches (Last) := new String'(Get_Name_String (Nam.Name)); List := Nam.Next; end loop; Get_Name_String (Directories.Table (Index)); while Name_Len > 1 and then (Name_Buffer (Name_Len) = Directory_Separator or else Name_Buffer (Name_Len) = '/') loop Name_Len := Name_Len - 1; end loop; Last := Last + 1; -- Concatenate the last switch and the path in a single option case Lang.Config.Path_Syntax is when Canonical => Data.Imported_Dirs_Switches (Last) := new String' (Get_Name_String (Nam.Name) & Name_Buffer (1 .. Name_Len)); when Host => Host_Path := To_Host_Dir_Spec (Name_Buffer (1 .. Name_Len), False); Data.Imported_Dirs_Switches (Last) := new String' (Get_Name_String (Nam.Name) & Host_Path.all); Free (Host_Path); end case; end loop; end Prepare_Imported_Dirs_Switches; ------------------------------ -- Set_Env_For_Include_Dirs -- ------------------------------ procedure Set_Env_For_Include_Dirs (Id : Source_Id; Source_Project : Project_Id) is Data : Local_Project_Data := Local_Projects_HT.Get (Local_Projects, Id.Object_Project); begin -- Prepare (if not already done) the data for Project/Lang. -- All files for a given language are processed sequentially, before -- we switch to the next language, so we are only preparing once per -- language here. if Data.Include_Language /= Id.Language then Free (Data.Include_Path); Free (Data.Imported_Dirs_Switches); Data := No_Local_Project_Data; if Id.Language.Config.Include_Option /= No_Name_List then Prepare_Imported_Dirs_Switches (Data, Id.Object_Project, Id.Language); elsif Id.Language.Config.Include_Path_File /= No_Name then if Id.Language.Config.Mapping_File_Switches = No_Name_List or else Opt.Use_Include_Path_File then Prepare_Include_Path_File (Data, Id.Object_Project, Id.Language); end if; elsif Id.Language.Config.Include_Path /= No_Name then Get_Directories (Project_Tree => Project_Tree, For_Project => Id.Object_Project, Activity => Compilation, Languages => Get_Compatible_Languages (Id.Language)); Data.Include_Path := Create_Path_From_Dirs; end if; Data.Include_Language := Id.Language; Local_Projects_HT.Set (Local_Projects, Id.Object_Project, Data); end if; -- Reset environment variables if they have changed if Id.Object_Project /= Current_Project or else Id.Language /= Current_Language_Ind then Current_Project := Id.Object_Project; Current_Language_Ind := Id.Language; if Data.Include_Path_File /= No_Path then Setenv (Get_Name_String (Id.Language.Config.Include_Path_File), Get_Name_String (Data.Include_Path_File)); elsif Data.Include_Path /= null then Gprbuild.Compilation.Process.Record_Environment (Source_Project, Id.Language.Name, Get_Name_String (Id.Language.Config.Include_Path), Data.Include_Path.all); if Opt.Verbose_Mode then Write_Str (Get_Name_String (Id.Language.Config.Include_Path)); Write_Str (" = "); Write_Line (Data.Include_Path.all); end if; end if; end if; -- But always set the switches if Data.Imported_Dirs_Switches /= null then for J in Data.Imported_Dirs_Switches'Range loop if Data.Imported_Dirs_Switches (J)'Length > 0 then Add_Option_Internal (Value => Data.Imported_Dirs_Switches (J), To => Compilation_Options, Display => Opt.Verbose_Mode); end if; end loop; end if; end Set_Env_For_Include_Dirs; ----------------------------- -- Process_Project_Phase_1 -- ----------------------------- procedure Process_Project_Phase_1 (Source : Queue.Source_Info) is Id : constant Source_Id := Source.Id; Project_Tree : constant Project_Tree_Ref := Source.Tree; Source_Project : constant Project_Id := Ultimate_Extending_Project_Of (Source.Id.Project); Compilation_Needed : Boolean := True; Last_Switches_For_File : Integer; Mapping_File : Path_Name_Type; The_ALI : ALI.ALI_Id; begin if Always_Compile or else not Source_Project.Externally_Built then Need_To_Compile (Source => Source.Id, Tree => Source.Tree, In_Project => Source_Project, Must_Compile => Compilation_Needed, The_ALI => The_ALI, Object_Check => Object_Checked, Always_Compile => Always_Compile); if Compilation_Needed and then Opt.Keep_Going then -- When in Keep_Going mode first check that we did not already -- tried to compile this source as part of another import of -- the corresponding project file. if Bad_Compilations.Contains (Source.Id) then Compilation_Needed := False; end if; end if; if Compilation_Needed or else Opt.Check_Switches then Set_Options_For_File (Source.Id); if Opt.Check_Switches and then not Compilation_Needed then Compilation_Needed := Check_Switches_File (Source.Id); end if; end if; if Compilation_Needed then -- If Distributed_Mode activated, parse Remote package to -- register and initialize the slaves. if Distributed_Mode and then not Slave_Initialized then Gprbuild.Compilation.Slave.Register_Remote_Slaves (Project_Tree, Main_Project); Slave_Initialized := True; end if; Update_Object_Path (Source.Id, Source_Project); Change_To_Object_Directory (Source_Project); -- Record the last recorded option index, to be able to -- write the switches file later. if Id.Language.Config.Object_Generated then Last_Switches_For_File := Compilation_Options.Last; else Last_Switches_For_File := -1; end if; Add_Dependency_Options (Id); Set_Env_For_Include_Dirs (Id, Source_Project); Add_Config_File_Switches (Id, Source_Project); Mapping_File := Add_Mapping_File_Switches (Source, Source_Project); Add_Trailing_Switches (Id); Add_Name_Of_Source_Switches (Id); Add_Object_File_Switches (Id); Add_Multi_Unit_Switches (Id); Add_Object_Path_Switches (Id); Spawn_Compiler_And_Register (Source => Source, Source_Project => Source_Project, Compiler_Path => Get_Compiler_Driver_Path (Project_Tree, Id.Language).all, Mapping_File_Path => Mapping_File, Last_Switches_For_File => Last_Switches_For_File); elsif Builder_Data (Source.Tree).Closure_Needed and then (Id.Language.Config.Dependency_Kind = ALI_File or else Id.Language.Config.Dependency_Kind = ALI_Closure) then Record_ALI_For (Source, The_ALI); else ALI.Initialize_ALI; ALI.Util.Initialize_ALI_Source; end if; end if; end Process_Project_Phase_1; -------------------------------- -- Must_Exit_Because_Of_Error -- -------------------------------- function Must_Exit_Because_Of_Error return Boolean is use type Containers.Count_Type; Source_Identity : Queue.Source_Info; Compilation_OK : Boolean; Slave : Unbounded_String; begin if not Bad_Compilations.Is_Empty and then not Opt.Keep_Going then while Outstanding_Compiles > 0 loop Await_Compile (Source_Identity, Compilation_OK, Slave); if not Compilation_OK then Bad_Compilations.Insert (Source_Identity.Id, To_String (Slave)); end if; end loop; return True; end if; return False; end Must_Exit_Because_Of_Error; ------------------------------- -- Start_Compile_If_Possible -- ------------------------------- procedure Start_Compile_If_Possible is Found : Boolean; Source : Queue.Source_Info; begin if not Queue.Is_Empty and then Outstanding_Compiles < Get_Maximum_Processes then Queue.Extract (Found, Source); if Found then Initialize_Source_Record (Source.Id); Process_Project_Phase_1 (Source); end if; end if; end Start_Compile_If_Possible; ----------------------------- -- Wait_For_Available_Slot -- ----------------------------- procedure Wait_For_Available_Slot is Source_Identity : Queue.Source_Info; Compilation_OK : Boolean; No_Check : Boolean; Slave : Unbounded_String; use Queue; begin if Outstanding_Compiles = Get_Maximum_Processes or else (Queue.Is_Virtually_Empty and then Outstanding_Compiles > 0) then Await_Compile (Source_Identity, Compilation_OK, Slave); if Compilation_OK and then Source_Identity /= Queue.No_Source_Info then -- Check if dependencies are on sources in Interfaces and, -- when --direct-import-only is used, the imported sources -- come from directly withed projects. Imports.Reset; Included_Sources.Set_Last (0); case Source_Identity.Id.Language.Config.Dependency_Kind is when None => null; when Makefile => Compilation_OK := Phase_2_Makefile (Source_Identity); when ALI_File | ALI_Closure => Compilation_OK := Phase_2_ALI (Source_Identity); end case; -- If the compilation was invalidated, delete the compilation -- artifacts. if not Compilation_OK then if Source_Identity.Id.Dep_Path /= No_Path then Delete_File (Get_Name_String (Source_Identity.Id.Dep_Path), No_Check); end if; if Source_Identity.Id.Object_Path /= No_Path then Delete_File (Get_Name_String (Source_Identity.Id.Object_Path), No_Check); end if; if Source_Identity.Id.Switches_Path /= No_Path then Delete_File (Get_Name_String (Source_Identity.Id.Switches_Path), No_Check); end if; end if; end if; if not Compilation_OK then Bad_Compilations.Insert (Source_Identity.Id, To_String (Slave)); end if; end if; end Wait_For_Available_Slot; -- Start of processing for Compilation_Phase begin Outstanding_Compiles := 0; -- Then process each files in the queue (new files might be added to -- the queue as a result). Compilation_Loop : while not Queue.Is_Empty or else Outstanding_Compiles > 0 loop exit Compilation_Loop when Must_Exit_Because_Of_Error; Start_Compile_If_Possible; Wait_For_Available_Slot; if Opt.Display_Compilation_Progress then Write_Str ("completed "); Write_Int (Int (Queue.Processed)); Write_Str (" out of "); Write_Int (Int (Queue.Size)); Write_Str (" ("); Write_Int (Int (((Queue.Processed) * 100) / Queue.Size)); Write_Str ("%)..."); Write_Eol; end if; end loop Compilation_Loop; -- Release local memory declare Data : Local_Project_Data := Local_Projects_HT.Get_First (Local_Projects); begin while Data /= No_Local_Project_Data loop Free (Data.Include_Path); Free (Data.Imported_Dirs_Switches); Data := Local_Projects_HT.Get_Next (Local_Projects); end loop; Local_Projects_HT.Reset (Local_Projects); end; end Compilation_Phase; --------------------- -- Project_Extends -- --------------------- function Project_Extends (Extending : Project_Id; Extended : Project_Id) return Boolean is Current : Project_Id := Extending; begin loop if Current = No_Project then return False; elsif Current = Extended then return True; end if; Current := Current.Extends; end loop; end Project_Extends; end Gprbuild.Compile; gprbuild-gpl-2014-src/src/gprbuild-compilation-protocol.ads0000644000076700001450000002365112323721731023405 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . P R O T O C O L -- -- -- -- S p e c -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Streams; use Ada.Streams; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with GNAT.OS_Lib; use GNAT; with GNAT.Sockets; use GNAT.Sockets; with Gprbuild.Compilation.Process; package Gprbuild.Compilation.Protocol is Wrong_Command : exception; -- Raised when a command cannot be parsed WD_Path_Tag : constant String := "<1>"; -- The string replacing root working diretory of full path name, see -- Set_Rewrite below. CD_Path_Tag : constant String := "<2>"; -- The string replacing the compiler root directory, see Set_Rewrite below Any_OS : constant String := "any"; -- Used when OS check is not necessary, for example gprclean does not need -- this check. It is safe to clean-up a Solaris slave from a Windows -- master. -- -- Communication -- type Communication_Channel is private; -- A communication channel, this channel is used for any communication -- between the build master and the slaves. No_Channel : constant Communication_Channel; function Create (Sock : Socket_Type) return Communication_Channel; -- Create a communication channel function Sock (Channel : Communication_Channel) return Socket_Type; pragma Inline (Sock); procedure Close (Channel : in out Communication_Channel); -- Close the channel procedure Set_Rewrite_WD (Channel : in out Communication_Channel; Path : String); -- Add rewrite information for the working directory. This is needed to -- translate paths to/from build master and slave working directories. procedure Set_Rewrite_CD (Channel : in out Communication_Channel; Path : String); -- Add rewrite information for the compiler directory. This is needed to -- translate paths to/from compilers path in build master and in slave. -- This is needed to be able to find the files from other projects -- installed with the compiler. The translated paths are in the -- gprbuild mapping file. procedure Clear_Rewrite (Channel : in out Communication_Channel); -- Remove any rewrite information from the channel function Translate_Receive (Channel : Communication_Channel; Str : String) return String; -- Translate Str using Channel rewrite function Translate_Send (Channel : Communication_Channel; Str : String) return String; -- Translate Str using Channel rewrite type Sync_Kind is (Rsync, Gpr); -- The kind of synchronization used. It is either using rsync external -- tool based or gprbuild internal protocol. -- -- Command -- type Command is private; type Command_Kind is (EX, -- execute a command AK, -- acknowledge received command (with pid) TS, -- a file timestamp ES, -- end of file timestamp FL, -- a file, content being rewritten from builder/slave PATH FR, -- a RAW file, no rewrite taking place OK, -- compilation ok (with optional pid) KO, -- compilation failed (with optional pid) CX, -- master context CU, -- clean-up request DP, -- display output EC); -- end of compilation function Kind (Cmd : Command) return Command_Kind; pragma Inline (Kind); function Args (Cmd : Command) return OS_Lib.Argument_List_Access; pragma Inline (Args); -- Returns all arguments for Cmd function Output (Cmd : Command) return Unbounded_String; pragma Inline (Output); -- Returns the output for a DP command function Get_Command (Channel : Communication_Channel) return Command; -- Wait and return a command as parsed from the communication channel Invalid_Pid : constant := -1; -- -- From gprbuild -- procedure Send_Context (Channel : Communication_Channel; Target : String; Project_Name : String; Build_Env : String; Sync : Sync_Kind); -- Send initial context to the slave procedure Send_Exec (Channel : Communication_Channel; Project : String; Dir : String; Command : String; Options : GNAT.OS_Lib.Argument_List; Obj_Name : String; Dep_Name : String; Env : String; Filter : access function (Str, Sep : String) return String := null); -- Send a compilation job to a slave. The compilation must be done on -- Dir. This directory is specified relative to the root directory of -- the sources. Dep_Name is the dependency file that is generated by this -- compilation and which must be sent back to the build master after the -- compilation. Filter is a function used to make path on the command line -- all relatives to the root directory. The build master root in full path -- is replaced by Full_Path_Tag. The slaves will change back this tag to -- the actual full path on their working environment. The Env string is a -- set of environement variables (name=value[;name=value]) to set before -- spawning the process. procedure Send_File (Channel : Communication_Channel; Path_Name : String; Rewrite : Boolean); -- Path_Name is the full path name to the local filename procedure Sync_Files (Channel : Communication_Channel; Root_Dir : String; Files : File_Data_Set.Vector); -- Send a set of filenames and associated timestamps. Will receive a OK or -- KO with the list of files to be transfered to the slave. procedure Send_End_Of_Compilation (Channel : Communication_Channel); -- Send an end of compilation signal, the slave will at this point be able -- to get jobs from another build master (Get_Context). procedure Send_End_Of_File_List (Channel : Communication_Channel); -- Send an end of file list signal, it means that all files timestamps have -- been checked. After this the compilation can be started. procedure Get_Pid (Channel : Communication_Channel; Pid : out Process.Remote_Id; Success : out Boolean); -- Get a process id, Success is set to False in case of failure procedure Send_Clean_Up (Channel : Communication_Channel; Project_Name : String); -- Send a clean-up requets to the slave -- -- From gprslave -- procedure Get_Context (Channel : Communication_Channel; Target : out Unbounded_String; Project_Name : out Unbounded_String; Build_Env : out Unbounded_String; Sync : out Sync_Kind; Timestamp : out Time_Stamp_Type; Version : out Unbounded_String); -- Wait for an initial context from a build master procedure Send_Slave_Config (Channel : Communication_Channel; Max_Process : Positive; Root_Directory : String; Clock_Status : Boolean); -- Send the slave configuration to the build master procedure Send_Ack (Channel : Communication_Channel; Pid : Process.Remote_Id); -- Send Acknoledgement of a received compilation job procedure Send_Ok (Channel : Communication_Channel; Pid : Process.Remote_Id); -- Send Pid of a successful command procedure Send_Ko (Channel : Communication_Channel; Pid : Process.Remote_Id); -- Send Pid of an un-successful command procedure Send_Ok (Channel : Communication_Channel); -- Send Ok for a successful command (clean-up for example) procedure Send_Ko (Channel : Communication_Channel); -- Send Ko to initial handshake (slave not compatible with master for -- example). procedure Send_Ko (Channel : Communication_Channel; Files : File_Data_Set.Vector); -- Send a Ko message with a list of file names procedure Send_Output (Channel : Communication_Channel; File_Name : String); -- Send an output of a command function Get_Raw_Data (Channel : Communication_Channel) return Stream_Element_Array; -- Get a Stream_Element_Array from the channel and return it private type Communication_Channel is record Sock : Socket_Type; Channel : Stream_Access; WD_From, WD_To : Unbounded_String; -- working directory CD_From, CD_To : Unbounded_String; -- compiler directory end record; No_Channel : constant Communication_Channel := (Sock => <>, Channel => null, others => Null_Unbounded_String); type Command is record Cmd : Command_Kind; Args : Argument_List_Access; Output : Unbounded_String; end record; end Gprbuild.Compilation.Protocol; gprbuild-gpl-2014-src/src/gprbuild-compilation-sync.adb0000644000076700001450000005234212323721731022476 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . S L A V E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Containers.Indefinite_Ordered_Maps; with Ada.Containers.Vectors; with Ada.Directories; use Ada.Directories; with Ada.Exceptions; use Ada.Exceptions; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with GNAT.Regexp; use GNAT.Regexp; with Gpr_Util; use Gpr_Util; with Output; use Output; package body Gprbuild.Compilation.Sync is use Ada; use type Containers.Count_Type; package Hosts_Set is new Containers.Indefinite_Ordered_Maps (Integer, String); procedure Wait_Rsync (N : Natural); -- Wait for N rsync processes. If one of the is in error exit function User_Host (User, Host : String) return String is (if User = "" then Host else User & '@' & Host); Default_Excluded_Patterns : Str_Vect.Vector; -- Default excluded patterns to use when in excluded mode as opposed to -- include mode where we describe the patterns to include specifically. Rsync_Cmd : constant GNAT.OS_Lib.String_Access := Locate_Exec_On_Path ("rsync"); Rsync_Count : Natural := 0; -- The number of rsync process started, we need to wait for them to -- terminate. Max_Gpr_Sync : constant := 10; -- The number of parallele synchronization done for the gpr protocol. This -- is currenlty fixed to 6 but could probable be a parameter. The number is -- high, as these tasks are mostly doing IO and so are not CPU demanding, -- the goal is to saturate the network bandwidth. Hosts : Hosts_Set.Map; procedure To_Slave_Rsync (Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector); -- Rsync based synchronization to the slave procedure From_Slave_Rsync (Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Included_Artifact_Patterns : Str_Vect.Vector); -- Rsync based synchronization from the slave procedure To_Slave_Gpr (Channel : Protocol.Communication_Channel; Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector); -- Gpr based synchronization to the slave -- Data for each synchronization job for the Gpr protocol type Gpr_Data is record Channel : Protocol.Communication_Channel; Project_Name : Unbounded_String; Root_Dir : Unbounded_String; Slave_Root_Dir : Unbounded_String; User, Host : Unbounded_String; Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector; end record; package Gpr_Data_Set is new Containers.Vectors (Positive, Gpr_Data); -- Queue of job to be done for the gpr protocol protected Gpr_Queue is procedure Add (Job : Gpr_Data); -- Add a new synchronization job entry Get (Job : out Gpr_Data; Files : out File_Data_Set.Vector; Stop : out Boolean); -- Get a synchronization job with the corresponding files, Stop is set -- to True if there is no more job to handle and False otherwise. procedure No_More_Job; private procedure Set_Project_Files (Job : Gpr_Data); -- Set the project files to be synchronized Jobs : Gpr_Data_Set.Vector; Project_Files : File_Data_Set.Vector; PF_Initialized : Boolean := False; No_More : Boolean := False; end Gpr_Queue; -- Synchronization job are handled by the Gpr_Sync tasks task type Gpr_Sync is entry Stop; end Gpr_Sync; type Gpr_Sync_Tasks is array (1 .. Max_Gpr_Sync) of Gpr_Sync; type Sync_Tasks_Ref is access all Gpr_Sync_Tasks; Sync_Tasks : Sync_Tasks_Ref; -- Only allocated (and so started) if a some slaves are using the gpr -- protocol. Otherwise this variable will stay null. ---------------- -- From_Slave -- ---------------- procedure From_Slave (Sync : Protocol.Sync_Kind; Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Included_Artifact_Patterns : Str_Vect.Vector) is begin case Sync is when Protocol.Gpr => -- Nothing to do as the artifacts are copied after each -- compilation. null; when Protocol.Rsync => From_Slave_Rsync (Project_Name, Root_Dir, Slave_Root_Dir, User, Host, Included_Artifact_Patterns); end case; end From_Slave; ---------------------- -- From_Slave_Rsync -- ---------------------- procedure From_Slave_Rsync (Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Included_Artifact_Patterns : Str_Vect.Vector) is Args : Argument_List (1 .. 6 + Positive'Max (4, Natural (Included_Artifact_Patterns.Length))); N : Positive range 3 .. Args'Last := 3; Pid : Process_Id; begin -- Archive mode, compression and ignore VCS Args (1) := new String'("-az"); Args (2) := new String'("--update"); -- Check all subdirectories Args (3) := new String'("--include=*/"); if Included_Artifact_Patterns.Length = 0 then -- Include known suffix (objects, dependencies) Args (4) := new String'("--include=*.o"); Args (5) := new String'("--include=*.gli"); Args (6) := new String'("--include=*.obj"); Args (7) := new String'("--include=*.coff"); N := 7; else for P of Included_Artifact_Patterns loop N := N + 1; Args (N) := new String'("--include=" & P); end loop; end if; -- Exclude everything else N := N + 1; Args (N) := new String'("--exclude=*"); -- Local and remote directory N := N + 1; Args (N) := new String' (User_Host (User, Host) & ":" & Compose (Slave_Root_Dir, Project_Name) & "/"); N := N + 1; Args (N) := new String'(Root_Dir); if Opt.Verbose_Mode then Write_Line (" synchronize back data"); Write_Line (" from: " & Args (N - 1).all); Write_Line (" to : " & Args (N).all); end if; Pid := Non_Blocking_Spawn (Rsync_Cmd.all, Args (1 .. N)); Hosts.Insert (Pid_To_Integer (Pid), Host); for A of Args loop Free (A); end loop; end From_Slave_Rsync; --------------- -- Gpr_Queue -- --------------- protected body Gpr_Queue is --------- -- Add -- --------- procedure Add (Job : Gpr_Data) is begin Jobs.Append (Job); end Add; --------- -- Get -- --------- entry Get (Job : out Gpr_Data; Files : out File_Data_Set.Vector; Stop : out Boolean) when Jobs.Length > 0 or No_More is begin if Jobs.Length = 0 and then No_More then Stop := True; else Stop := False; Job := Jobs.First_Element; Jobs.Delete_First; if not PF_Initialized then Set_Project_Files (Job); end if; Files := Project_Files; end if; end Get; ----------------- -- No_More_Job -- ----------------- procedure No_More_Job is begin No_More := True; end No_More_Job; ----------------------- -- Set_Project_Files -- ----------------------- procedure Set_Project_Files (Job : Gpr_Data) is Root_Dir : constant String := (if Job.Root_Dir = Null_Unbounded_String then "." else To_String (Job.Root_Dir)); type Regexp_Set is array (Containers.Count_Type range <>) of Regexp; I_Regexp : Regexp_Set (1 .. Job.Included_Patterns.Length); E_Regexp : Regexp_Set (1 .. Job.Excluded_Patterns.Length + Default_Excluded_Patterns.Length); procedure Process (Prefix : String); procedure Process (Prefix : String) is procedure Check (File : Directory_Entry_Type); -- Check and add this file if it passes the filters ----------- -- Check -- ----------- procedure Check (File : Directory_Entry_Type) is use GNAT; function Match (Name : String; R_Set : Regexp_Set) return Boolean with Inline; -- Returns true if Name is matched by one of the regexp in -- R_Set. ----------- -- Match -- ----------- function Match (Name : String; R_Set : Regexp_Set) return Boolean is begin for Regexp of R_Set loop if Match (Name, Regexp) then return True; end if; end loop; return False; end Match; S_Name : constant String := Simple_Name (File); Entry_Name : constant String := Prefix & S_Name; Is_File : Boolean; begin if Kind (File) = Directory then if S_Name not in "." | ".." and then (I_Regexp'Length /= 0 or else not Match (S_Name, E_Regexp)) and then not Is_Symbolic_Link (Root_Dir & Directory_Separator & Entry_Name) then Process (Entry_Name & Directory_Separator); end if; else if I_Regexp'Length = 0 then if Match (S_Name, E_Regexp) then Is_File := False; else Is_File := True; end if; else if Match (S_Name, I_Regexp) then Is_File := True; else Is_File := False; end if; end if; if Is_File then Project_Files.Append (File_Data' (To_Unbounded_String (Entry_Name), To_Time_Stamp (Modification_Time (File)), Dummy_Time_Stamp)); end if; end if; end Check; begin Search (Directory => Root_Dir & (if Prefix = "" then "" else Directory_Separator & Prefix), Pattern => "*", Filter => (Special_File => False, others => True), Process => Check'Access); end Process; begin -- Compile the patterns declare K : Containers.Count_Type := 1; begin for P of Job.Included_Patterns loop I_Regexp (K) := Compile (P, Glob => True); K := K + 1; end loop; K := 1; for P of Default_Excluded_Patterns loop E_Regexp (K) := Compile (P, Glob => True); K := K + 1; end loop; for P of Job.Excluded_Patterns loop E_Regexp (K) := Compile (P, Glob => True); K := K + 1; end loop; end; -- Check the files under the project root Process (Prefix => ""); PF_Initialized := True; end Set_Project_Files; end Gpr_Queue; -------------- -- Gpr_Sync -- -------------- task body Gpr_Sync is Job : Gpr_Data; Files : File_Data_Set.Vector; No_More_Job : Boolean; begin For_Slave : loop -- Get a new job and the associated files if any Gpr_Queue.Get (Job, Files, No_More_Job); exit For_Slave when No_More_Job; declare Chunk_Size : constant := 500; -- This constant controls the number of files sent with the sync -- command. Doing one at a time is really time consumming as -- we have for every file and send and a receive command on -- the socket. F_List : File_Data_Set.Vector; Count : Natural := 0; begin -- Synchronize each file in the list we got for F of Files loop if Count = Chunk_Size then Protocol.Sync_Files (Job.Channel, To_String (Job.Root_Dir), F_List); F_List.Clear; Count := 0; end if; F_List.Append (F); Count := Count + 1; end loop; -- Then send the last chunk if any if Count /= 0 then Protocol.Sync_Files (Job.Channel, To_String (Job.Root_Dir), F_List); end if; Protocol.Send_End_Of_File_List (Job.Channel); end; end loop For_Slave; accept Stop; exception when E : others => Write_Line (Exception_Information (E)); OS_Exit (1); end Gpr_Sync; -------------- -- To_Slave -- -------------- procedure To_Slave (Sync : Protocol.Sync_Kind; Channel : Protocol.Communication_Channel; Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector) is begin case Sync is when Protocol.Gpr => To_Slave_Gpr (Channel, Project_Name, Root_Dir, Slave_Root_Dir, User, Host, Excluded_Patterns, Included_Patterns); when Protocol.Rsync => To_Slave_Rsync (Project_Name, Root_Dir, Slave_Root_Dir, User, Host, Excluded_Patterns, Included_Patterns); end case; end To_Slave; ------------------ -- To_Slave_Gpr -- ------------------ procedure To_Slave_Gpr (Channel : Protocol.Communication_Channel; Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector) is begin -- Starts the tasks if not already done if Sync_Tasks = null then Sync_Tasks := new Gpr_Sync_Tasks; end if; Gpr_Queue.Add (Gpr_Data' (Channel, To_Unbounded_String (Project_Name), To_Unbounded_String (Root_Dir), To_Unbounded_String (Slave_Root_Dir), To_Unbounded_String (User), To_Unbounded_String (Host), Excluded_Patterns, Included_Patterns)); end To_Slave_Gpr; -------------------- -- To_Slave_Rsync -- -------------------- procedure To_Slave_Rsync (Project_Name : String; Root_Dir : String; Slave_Root_Dir : String; User : String; Host : String; Excluded_Patterns : Str_Vect.Vector; Included_Patterns : Str_Vect.Vector) is procedure Add_Arg (Str : String); -- Add new argument Args : Argument_List (1 .. 6 + Positive'Max (11 + Natural (Excluded_Patterns.Length), 2 + Natural (Included_Patterns.Length))); N : Natural range 0 .. Args'Last := 0; -------------- -- Add_Args -- -------------- procedure Add_Arg (Str : String) is begin N := N + 1; Args (N) := new String'(Str); end Add_Arg; Pid : Process_Id; begin -- Check for rsync tool if Rsync_Cmd = null then Write_Line ("error: rsync not found for " & Host); OS_Exit (1); end if; -- Archive mode, compression and ignore VCS Add_Arg ("-arz"); if Included_Patterns.Length = 0 then -- Default excluded patterns objects/ali for P of Default_Excluded_Patterns loop Add_Arg ("--exclude=" & P); end loop; -- Add any user's defined excluded patterns for P of Excluded_Patterns loop Add_Arg ("--exclude=" & P); end loop; else -- Include sub-directories Add_Arg ("--include=*/"); -- Add any user's defined included patterns for P of Included_Patterns loop Add_Arg ("--include=" & P); end loop; -- Then we exclude everything else Add_Arg ("--exclude=*"); end if; -- Delete remote files not in local directory Add_Arg ("--delete-excluded"); Add_Arg ("--delete"); Add_Arg ("--copy-links"); -- Local and remote directory Add_Arg (Root_Dir & "/"); Add_Arg (User_Host (User, Host) & ":" & Compose (Slave_Root_Dir, Project_Name)); if Opt.Verbose_Mode then Write_Line (" synchronize data"); Write_Line (" from: " & Args (N - 1).all); Write_Line (" to : " & Args (N).all); end if; Pid := Non_Blocking_Spawn (Rsync_Cmd.all, Args (1 .. N)); Hosts.Insert (Pid_To_Integer (Pid), Host); Rsync_Count := Rsync_Count + 1; for A of Args (1 .. N) loop Free (A); end loop; end To_Slave_Rsync; ---------------- -- Wait_Rsync -- ---------------- procedure Wait_Rsync (N : Natural) is Pid : Process_Id; Success : Boolean; Error : Boolean := False; Host : Hosts_Set.Cursor; begin for K in 1 .. N loop Wait_Process (Pid, Success); Host := Hosts.Find (Pid_To_Integer (Pid)); if Success then if Opt.Verbose_Mode then Write_Line (" synchronization done for " & Hosts_Set.Element (Host)); end if; else Error := True; Write_Line ("error: rsync on " & Hosts_Set.Element (Host)); end if; end loop; -- If there is any error we cannot continue, just exit now if Error then OS_Exit (1); end if; end Wait_Rsync; ---------- -- Wait -- ---------- procedure Wait is begin Gpr_Queue.No_More_Job; Wait_Rsync (Rsync_Count); if Sync_Tasks /= null then for T of Sync_Tasks.all loop if not T'Terminated then T.Stop; end if; end loop; end if; end Wait; begin Default_Excluded_Patterns.Append ("*.o"); Default_Excluded_Patterns.Append ("*.obj"); Default_Excluded_Patterns.Append ("*.ali"); Default_Excluded_Patterns.Append ("*.dll"); Default_Excluded_Patterns.Append ("*.so"); Default_Excluded_Patterns.Append ("*.so.*"); Default_Excluded_Patterns.Append ("*.exe"); Default_Excluded_Patterns.Append (".git"); Default_Excluded_Patterns.Append (".svn"); Default_Excluded_Patterns.Append ("CVS"); Default_Excluded_Patterns.Append ("gnatinspect.db*"); end Gprbuild.Compilation.Sync; gprbuild-gpl-2014-src/src/gprbuild-compilation-result.adb0000644000076700001450000000724112323721731023036 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D . C O M P I L A T I O N . R E S U L T -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Containers.Doubly_Linked_Lists; with Gpr_Util; use Gpr_Util; package body Gprbuild.Compilation.Result is use Ada; use type Containers.Count_Type; type Process_Data is record Process : Id; Status : Boolean; end record; package Endded_Process is new Containers.Doubly_Linked_Lists (Process_Data); protected Results is procedure Add (Result : Process_Data); entry Get (Result : out Process_Data); private List : Endded_Process.List; end Results; --------- -- Add -- --------- procedure Add (Process : Id; Status : Boolean; Slave : String := "") is begin Results.Add (Process_Data'(Process, Status)); -- For a compilation failure records the slave to be able to report it if not Status and then Slave /= "" then Record_Remote_Failure (Process, Slave); end if; end Add; ------------- -- Results -- ------------- protected body Results is --------- -- Add -- --------- procedure Add (Result : Process_Data) is begin List.Append (Result); end Add; --------- -- Get -- --------- entry Get (Result : out Process_Data) when List.Length /= 0 is begin Result := List.First_Element; List.Delete_First; end Get; end Results; ---------- -- Wait -- ---------- procedure Wait (Process : out Id; Status : out Boolean) is Data : Process_Data; Pid : Process_Id; begin -- In distributed mode we wait for a result to be available into the -- shared Results list. This list is filed with results from local -- process (see Compilation.Process.Wait_Local) and also with the -- remotes ones (see Compilation.Slave.Wait_Remote). if Distributed_Mode then Results.Get (Data); Process := Data.Process; Status := Data.Status; else -- In non distributed mode just wait for a compilation to terminate Wait_Process (Pid, Status); Process := Create_Local (Pid); end if; end Wait; end Gprbuild.Compilation.Result; gprbuild-gpl-2014-src/src/gpr_util-knowledge-vms.adb0000644000076700001450000000412412323721731022000 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R _ U T I L . K N O W L E D G E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2010-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This is the VMS dummy version of this package separate (Gpr_Util) package body Knowledge is ------------------------- -- Normalized_Hostname -- ------------------------- function Normalized_Hostname return String is begin return ""; end Normalized_Hostname; -------------------------- -- Parse_Knowledge_Base -- -------------------------- procedure Parse_Knowledge_Base (Directory : String := "") is pragma Unreferenced (Directory); begin null; end Parse_Knowledge_Base; end Knowledge; gprbuild-gpl-2014-src/src/gprinstall.exe.manifest0000644000076700001450000000116512064643534021422 0ustar gnatmailgnat Description of your application gprbuild-gpl-2014-src/src/gprinstall-install.adb0000644000076700001450000022560012323721731021222 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R I N S T A L L . M A I N -- -- -- -- B o d y -- -- -- -- Copyright (C) 2012-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ with Ada.Characters.Handling; use Ada.Characters.Handling; with Ada.Containers.Indefinite_Vectors; use Ada; with Ada.Containers.Indefinite_Ordered_Sets; with Ada.Containers.Ordered_Sets; with Ada.Containers.Vectors; with Ada.Directories; use Ada.Directories; with Ada.Strings.Equal_Case_Insensitive; with Ada.Strings.Less_Case_Insensitive; with Ada.Strings.Fixed; use Ada.Strings; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO; use Ada.Text_IO; with GNAT.MD5; use GNAT.MD5; with Gpr_Util; use Gpr_Util; with GPR_Version; use GPR_Version; with Namet; use Namet; with Opt; with Osint; with Output; use Output; with Prj.Util; use Prj.Util; with Snames; use Snames; package body Gprinstall.Install is package Name_Id_Set is new Containers.Ordered_Sets (Name_Id); Installed : Name_Id_Set.Set; -- Record already installed project ------------- -- Process -- ------------- procedure Process (Tree : Project_Tree_Ref; Project : Project_Id) is Windows_Target : constant Boolean := Get_Name_String (Project.Config.Shared_Lib_Suffix) = ".dll"; Pcks : Package_Table.Table_Ptr renames Tree.Shared.Packages.Table; Strs : String_Element_Table.Table_Ptr renames Tree.Shared.String_Elements.Table; -- Local values for the given project, these are initially set with the -- default values. It is updated using the Install package found in the -- project if any. Active : Boolean := True; -- Whether installation is active or not (Install package's attribute) Prefix_Dir : Param := Dup (Global_Prefix_Dir); Exec_Subdir : Param := Dup (Global_Exec_Subdir); Lib_Subdir : Param := Dup (Global_Lib_Subdir); Link_Lib_Subdir : Param := Dup (Global_Link_Lib_Subdir); Sources_Subdir : Param := Dup (Global_Sources_Subdir); Project_Subdir : Param := Dup (Global_Project_Subdir); type Items is (Source, Object, Dependency, Library, Executable); Copy : array (Items) of Boolean := (others => False); -- What should be copied from a project, this depends on the actual -- project kind and the mode (usage, dev) set for the install. Man : Text_IO.File_Type; -- File where manifest for this project is kept -- Keeping track of artifacts to install type Artifacts_Data is record Destination, Filename : Name_Id; end record; package Artifacts_Set is new Containers.Vectors (Positive, Artifacts_Data); Artifacts : Artifacts_Set.Vector; procedure Copy_File (From, To, File : String; Sym_Link : Boolean := False; Executable : Boolean := False); -- Copy file From into To, if Sym_Link is set a symbolic link is -- created. If Executable is set, the destination file exec attribute -- is set. function Dir_Name (Suffix : Boolean := True) return String; -- Returns the name of directory where project files are to be -- installed. This name is the name of the project. If Suffix is -- True then the build name is also returned. function Cat (Dir : Path_Name_Type; File : File_Name_Type) return String; pragma Inline (Cat); -- Returns the string which is the catenation of Dir and File function Sources_Dir (Build_Name : Boolean := True) return String; -- Returns the full pathname to the sources destination directory function Exec_Dir return String; -- Returns the full pathname to the executable destination directory function Lib_Dir (Build_Name : Boolean := True) return String; -- Returns the full pathname to the library destination directory function Link_Lib_Dir return String; -- Returns the full pathname to the lib symlib directory function Project_Dir return String; -- Returns the full pathname to the project destination directory procedure Check_Install_Package; -- Check Project's install package and overwrite the default values of -- the corresponding variables above. procedure Copy_Files; -- Do the file copues for the project's sources, object, library, -- executable. procedure Create_Project (Project : Project_Id); -- Create install project for the given project procedure Add_To_Manifest (Pathname : String); -- Add filename to manifest function Get_Library_Filename return File_Name_Type; -- Returns the actual file name for the library function Has_Sources (Project : Project_Id) return Boolean; pragma Inline (Has_Sources); -- Returns True if the project contains sources function Bring_Sources (Project : Project_Id) return Boolean; -- Returns True if Project gives visibility to some sources directly or -- indirectly via the with clauses. function Main_Binary (Source : Name_Id) return String; -- Give the source name found in the Main attribute, returns the actual -- binary as built by gprbuild. This routine looks into the Builder -- switches for a the Executable attribute. function Is_Install_Active (Tree : Project_Tree_Ref; Project : Project_Id) return Boolean; -- Returns True if the Project is active, that is there is no attribute -- Activer set to False in the Install package. procedure Open_Check_Manifest; -- Check that manifest file can be used --------------------- -- Add_To_Manifest -- --------------------- procedure Add_To_Manifest (Pathname : String) is Prefix_Len : constant Natural := Prefix_Dir.V'Length; begin if not Is_Open (Man) then Open_Check_Manifest; end if; -- Append entry into manifest Put_Line (Man, File_MD5 (Pathname) & " " -- Remove the prefix, we want to store the pathname relative to -- the prefix of installation. & Pathname (Pathname'First + Prefix_Len .. Pathname'Last)); end Add_To_Manifest; ------------------- -- Bring_Sources -- ------------------- function Bring_Sources (Project : Project_Id) return Boolean is begin if Has_Sources (Project) then return True; else declare List : Project_List := Project.All_Imported_Projects; begin while List /= null loop if Has_Sources (List.Project) then return True; end if; List := List.Next; end loop; end; end if; return False; end Bring_Sources; --------------------------- -- Check_Install_Package -- --------------------------- procedure Check_Install_Package is Pck : Package_Id := Project.Decl.Packages; procedure Replace (P : in out Param; Val : Name_Id); pragma Inline (Replace); -- Set Var with Value, free previous pointer ------------- -- Replace -- ------------- procedure Replace (P : in out Param; Val : Name_Id) is V : constant String := Ensure_Directory (Get_Name_String (Val)); begin if V /= "" then Free (P.V); P := (new String'(V), Default => False); end if; end Replace; begin Look_Install_Package : while Pck /= No_Package loop if Pcks (Pck).Decl /= No_Declarations and then Pcks (Pck).Name = Name_Install then -- Found Install package, check attributes declare Id : Variable_Id := Pcks (Pck).Decl.Attributes; begin while Id /= No_Variable loop declare V : constant Variable := Tree.Shared.Variable_Elements.Table (Id); begin if V.Name = Name_Prefix and then Global_Prefix_Dir.Default then Replace (Prefix_Dir, V.Value.Value); elsif V.Name = Name_Exec_Subdir and then Global_Exec_Subdir.Default then Replace (Exec_Subdir, V.Value.Value); elsif V.Name = Name_Lib_Subdir and then Global_Lib_Subdir.Default then Replace (Lib_Subdir, V.Value.Value); elsif V.Name = Name_Link_Lib_Subdir and then Global_Link_Lib_Subdir.Default then Replace (Link_Lib_Subdir, V.Value.Value); elsif V.Name = Name_Sources_Subdir and then Global_Sources_Subdir.Default then Replace (Sources_Subdir, V.Value.Value); elsif V.Name = Name_Project_Subdir and then Global_Project_Subdir.Default then Replace (Project_Subdir, V.Value.Value); elsif V.Name = Name_Active then declare Val : constant String := To_Lower (Get_Name_String (V.Value.Value)); begin if Val = "false" then Active := False; else Active := True; end if; end; end if; end; Id := Tree.Shared.Variable_Elements.Table (Id).Next; end loop; end; -- Now check arrays declare Id : Array_Id := Pcks (Pck).Decl.Arrays; begin while Id /= No_Array loop declare V : constant Array_Data := Tree.Shared.Arrays.Table (Id); begin if V.Name = Name_Artifacts then declare Eid : Array_Element_Id := V.Value; begin while Eid /= No_Array_Element loop declare E : constant Array_Element := Tree.Shared.Array_Elements.Table (Eid); S : String_List_Id := E.Value.Values; begin while S /= Nil_String loop Artifacts.Append (Artifacts_Data' (E.Index, Strs (S).Value)); S := Strs (S).Next; end loop; end; Eid := Tree.Shared.Array_Elements. Table (Eid).Next; end loop; end; end if; end; Id := Tree.Shared.Arrays.Table (Id).Next; end loop; end; exit Look_Install_Package; end if; Pck := Pcks (Pck).Next; end loop Look_Install_Package; end Check_Install_Package; -------------- -- Dir_Name -- -------------- function Dir_Name (Suffix : Boolean := True) return String is function Get_Suffix return String; -- Returns a suffix if needed ---------------- -- Get_Suffix -- ---------------- function Get_Suffix return String is begin -- .default is always ommitted from the directory name if Suffix and then Build_Name.all /= "default" then return '.' & Build_Name.all; else return ""; end if; end Get_Suffix; begin return Get_Name_String (Project.Name) & Get_Suffix; end Dir_Name; --------------------------- -- Get_Library_Filenaame -- --------------------------- function Get_Library_Filename return File_Name_Type is begin -- Library prefix Name_Len := 0; if Project.Library_Kind /= Static and then Project.Config.Shared_Lib_Prefix /= No_File then Add_Str_To_Name_Buffer (Get_Name_String (Project.Config.Shared_Lib_Prefix)); else Add_Str_To_Name_Buffer ("lib"); end if; -- Library name Add_Str_To_Name_Buffer (Get_Name_String (Project.Library_Name)); -- Library suffix if Project.Library_Kind = Static and then Project.Config.Archive_Suffix /= No_File then Add_Str_To_Name_Buffer (Get_Name_String (Project.Config.Archive_Suffix)); elsif Project.Library_Kind /= Static and then Project.Config.Shared_Lib_Suffix /= No_File then Add_Str_To_Name_Buffer (Get_Name_String (Project.Config.Shared_Lib_Suffix)); else Add_Str_To_Name_Buffer (".so"); end if; return Name_Find; end Get_Library_Filename; ----------------------- -- Is_Install_Active -- ----------------------- function Is_Install_Active (Tree : Project_Tree_Ref; Project : Project_Id) return Boolean is Pcks : Package_Table.Table_Ptr renames Tree.Shared.Packages.Table; Pck : Package_Id := Project.Decl.Packages; begin Look_Install_Package : while Pck /= No_Package loop if Pcks (Pck).Decl /= No_Declarations and then Pcks (Pck).Name = Name_Install then -- Found Install package, check attributes declare Id : Variable_Id := Pcks (Pck).Decl.Attributes; begin while Id /= No_Variable loop declare V : constant Variable := Tree.Shared.Variable_Elements.Table (Id); begin if V.Name = Name_Active then declare Val : constant String := To_Lower (Get_Name_String (V.Value.Value)); begin if Val = "false" then return False; else return True; end if; end; end if; end; Id := Tree.Shared.Variable_Elements.Table (Id).Next; end loop; end; exit Look_Install_Package; end if; Pck := Pcks (Pck).Next; end loop Look_Install_Package; -- If not defined, the default is active return True; end Is_Install_Active; ----------------- -- Main_Binary -- ----------------- function Main_Binary (Source : Name_Id) return String is function Get_Exec_Suffix return String; -- Return the target executable suffix --------------------- -- Get_Exec_Suffix -- --------------------- function Get_Exec_Suffix return String is begin if Project.Config.Executable_Suffix = No_Name then return ""; else return Get_Name_String (Project.Config.Executable_Suffix); end if; end Get_Exec_Suffix; Builder_Package : constant Package_Id := Value_Of (Name_Builder, Main_Project.Decl.Packages, Project_Tree.Shared); Value : Variable_Value; begin if Builder_Package /= No_Package then Value := Value_Of (Name => Source, Attribute_Or_Array_Name => Name_Executable, In_Package => Builder_Package, Shared => Project_Tree.Shared); if Value = Nil_Variable_Value then -- If not found and name has an extension, try without declare Name : constant String := Get_Name_String (Source); S : Name_Id; begin if Name /= Base_Name (Name) then Name_Len := 0; Add_Str_To_Name_Buffer (Base_Name (Name)); S := Name_Find; Value := Value_Of (Name => S, Attribute_Or_Array_Name => Name_Executable, In_Package => Builder_Package, Shared => Project_Tree.Shared); end if; end; end if; end if; if Value = Nil_Variable_Value then return Base_Name (Get_Name_String (Source)) & Get_Exec_Suffix; else return Get_Name_String (Value.Value) & Get_Exec_Suffix; end if; end Main_Binary; ----------------- -- Has_Sources -- ----------------- function Has_Sources (Project : Project_Id) return Boolean is begin return Project.Source_Dirs /= Nil_String or else Project.Qualifier = Aggregate_Library; end Has_Sources; -------------- -- Exec_Dir -- -------------- function Exec_Dir return String is begin if Is_Absolute_Path (Exec_Subdir.V.all) then return Exec_Subdir.V.all; else return Prefix_Dir.V.all & Exec_Subdir.V.all; end if; end Exec_Dir; ------------- -- Lib_Dir -- ------------- function Lib_Dir (Build_Name : Boolean := True) return String is begin if Is_Absolute_Path (Lib_Subdir.V.all) then return Lib_Subdir.V.all; elsif not Lib_Subdir.Default or else not Build_Name then return Prefix_Dir.V.all & Lib_Subdir.V.all; else return Ensure_Directory (Prefix_Dir.V.all & Lib_Subdir.V.all & Dir_Name); end if; end Lib_Dir; ------------------ -- Link_Lib_Dir -- ------------------ function Link_Lib_Dir return String is begin if Is_Absolute_Path (Link_Lib_Subdir.V.all) then return Link_Lib_Subdir.V.all; else return Prefix_Dir.V.all & Link_Lib_Subdir.V.all; end if; end Link_Lib_Dir; ----------------- -- Sources_Dir -- ----------------- function Sources_Dir (Build_Name : Boolean := True) return String is begin if Is_Absolute_Path (Sources_Subdir.V.all) then return Sources_Subdir.V.all; elsif not Sources_Subdir.Default or else not Build_Name then return Prefix_Dir.V.all & Sources_Subdir.V.all; else return Ensure_Directory (Prefix_Dir.V.all & Sources_Subdir.V.all & Dir_Name); end if; end Sources_Dir; ----------------- -- Project_Dir -- ----------------- function Project_Dir return String is begin if Is_Absolute_Path (Project_Subdir.V.all) then return Project_Subdir.V.all; else return Prefix_Dir.V.all & Project_Subdir.V.all; end if; end Project_Dir; --------- -- Cat -- --------- function Cat (Dir : Path_Name_Type; File : File_Name_Type) return String is begin return Get_Name_String (Dir) & Get_Name_String (File); end Cat; --------------- -- Copy_File -- --------------- procedure Copy_File (From, To, File : String; Sym_Link : Boolean := False; Executable : Boolean := False) is Dest_Filename : constant String := To & File; begin if not Sym_Link and then Exists (Dest_Filename) and then not Force_Installations then Write_Str ("file "); Write_Str (File); Write_Str (" exists, use -f to overwrite"); Write_Eol; OS_Exit (1); end if; if Dry_Run or else Opt.Verbose_Mode then if Sym_Link then Write_Str ("ln -s "); else Write_Str ("cp "); end if; Write_Str (From); Write_Str (" "); Write_Str (Dest_Filename); Write_Eol; end if; if not Dry_Run then if not Sym_Link and then not Exists (From) then Write_Str ("file "); Write_Str (From); Write_Str (" does not exist, build may not be complete"); Write_Eol; OS_Exit (1); end if; if (not Sym_Link and then not Exists (To)) or else (Sym_Link and then not Exists (From)) then if Create_Dest_Dir then if Sym_Link then Create_Path (Containing_Directory (From)); else Create_Path (To); end if; else Set_Standard_Error; Write_Line ("directory does not exist, use -p to create"); OS_Exit (1); end if; end if; -- Do copy if Sym_Link then Create_Sym_Link (From, To & File); -- Add file to manifest Add_To_Manifest (From); else begin Directories.Copy_File (Source_Name => From, Target_Name => Dest_Filename, Form => "preserve=timestamps"); exception when Text_IO.Use_Error => Write_Line ("cannot overwrite file " & Dest_Filename & " check permissions."); OS_Exit (1); end; if Executable then Set_Executable (Dest_Filename, Mode => S_Owner + S_Group + S_Others); end if; -- Add file to manifest Add_To_Manifest (Dest_Filename); end if; end if; end Copy_File; ---------------- -- Copy_Files -- ---------------- procedure Copy_Files is procedure Copy_Project_Sources (Project : Project_Id; Tree : Project_Tree_Ref); -- Copy sources from the given project procedure Copy_Source (Sid : Source_Id); procedure Copy_Artifacts (Pathname, Destination : String); -- Copy items from the artifacts attribute Source_Copied : Name_Id_Set.Set; -------------------------- -- Copy_Project_Sources -- -------------------------- procedure Copy_Project_Sources (Project : Project_Id; Tree : Project_Tree_Ref) is function Is_Ada (Sid : Source_Id) return Boolean; pragma Inline (Is_Ada); -- Returns True if Sid is an Ada source ------------ -- Is_Ada -- ------------ function Is_Ada (Sid : Source_Id) return Boolean is begin return Sid.Language /= null and then Get_Name_String (Sid.Language.Name) = "ada"; end Is_Ada; Iter : Source_Iterator; Sid : Source_Id; begin if Project.Qualifier = Aggregate_Library then Iter := For_Each_Source (Tree); else Iter := For_Each_Source (Tree, Project); end if; loop Sid := Element (Iter); exit when Sid = No_Source; -- Skip sources that are removed/excluded and sources not -- part of the interface for standalone libraries. if not Sid.Locally_Removed and then not Sid.Project.Externally_Built and then (Project.Standalone_Library = No or else Sid.Declared_In_Interfaces) then -- If the unit has a naming exception we install it -- regardless of the fact that it is part of the interface -- or not. This is because the installed project will have -- a Naming package referencing this file. The .ali is -- looked based on the name of the renamed body. if All_Sources or else Sid.Naming_Exception = Yes then Copy_Source (Sid); end if; -- Objects / Deps if Other_Part (Sid) = null or else Sid.Kind /= Spec then if Copy (Object) then Copy_File (From => Cat (Get_Object_Directory (Sid.Project, False), Sid.Object), To => Lib_Dir, File => Get_Name_String (Sid.Object)); end if; -- Only install Ada .ali files if Copy (Dependency) and then Sid.Kind /= Sep and then Is_Ada (Sid) then Copy_File (From => Cat (Get_Object_Directory (Sid.Project, False), Sid.Dep_Name), To => Lib_Dir, File => Get_Name_String (Sid.Dep_Name)); end if; end if; end if; Next (Iter); end loop; end Copy_Project_Sources; ----------------- -- Copy_Source -- ----------------- procedure Copy_Source (Sid : Source_Id) is begin if Copy (Source) then declare Prep_Filename : constant String := Cat (Get_Object_Directory (Sid.Project, False), Sid.File) & Osint.Prep_Suffix; begin if not Source_Copied.Contains (Name_Id (Sid.Path.Name)) then Source_Copied.Insert (Name_Id (Sid.Path.Name)); Copy_File (From => (if Exists (Prep_Filename) then Prep_Filename else Get_Name_String (Sid.Path.Name)), To => Sources_Dir, File => Get_Name_String (Sid.File)); end if; end; end if; end Copy_Source; -------------------- -- Copy_Artifacts -- -------------------- procedure Copy_Artifacts (Pathname, Destination : String) is procedure Copy_Entry (E : Directory_Entry_Type); -- Copy file pointed by E function Get_Directory (Fullname : String) return String; -- Returns the directory containing fullname. Note that we -- cannot use the standard Containing_Directory as filename -- can be a pattern and not be allowed in filename. function Get_Pattern return String; -- Return filename of pattern from Filename below ---------------- -- Copy_Entry -- ---------------- procedure Copy_Entry (E : Directory_Entry_Type) is Fullname : constant String := Full_Name (E); Dest_Dir : constant String := (if Is_Absolute_Path (Destination) then Destination else Prefix_Dir.V.all & Destination); begin if Kind (E) = Directory and then Simple_Name (E) /= "." and then Simple_Name (E) /= ".." then Copy_Artifacts (Fullname & "/*", Dest_Dir & Simple_Name (E) & '/'); elsif Kind (E) = Ordinary_File then Copy_File (From => Fullname, To => Dest_Dir, File => Simple_Name (Fullname)); end if; end Copy_Entry; ------------------- -- Get_Directory -- ------------------- function Get_Directory (Fullname : String) return String is K : Natural := Fullname'Last; begin while K > 0 and then not Osint.Is_Directory_Separator (Fullname (K)) loop K := K - 1; end loop; pragma Assert (K > 0); return Fullname (Fullname'First .. K); end Get_Directory; ----------------- -- Get_Pattern -- ----------------- function Get_Pattern return String is K : Natural := Pathname'Last; begin while K > 0 and then not Osint.Is_Directory_Separator (Pathname (K)) loop K := K - 1; end loop; if K = 0 then return Pathname; else return Pathname (K + 1 .. Pathname'Last); end if; end Get_Pattern; begin Directories.Search (Directory => Get_Directory (Pathname), Pattern => Get_Pattern, Process => Copy_Entry'Access); exception when Text_IO.Name_Error => Put_Line ("warning: path does not exists '" & Get_Directory (Pathname) & '''); end Copy_Artifacts; procedure Copy_Interfaces is new For_Interface_Sources (Copy_Source); begin if not All_Sources then Copy_Interfaces (Tree, Project); end if; Copy_Project_Sources (Project, Tree); -- Copy library if Copy (Library) then if Project.Library_Kind /= Static and then Project.Lib_Internal_Name /= No_Name and then Project.Library_Name /= Project.Lib_Internal_Name then if Windows_Target then -- No support for version, do a simple copy Copy_File (From => Cat (Project.Library_Dir.Display_Name, Get_Library_Filename), To => Lib_Dir, File => Get_Name_String (Get_Library_Filename), Executable => Project.Library_Kind /= Static); else Copy_File (From => Cat (Project.Library_Dir.Display_Name, File_Name_Type (Project.Lib_Internal_Name)), To => Lib_Dir, File => Get_Name_String (Project.Lib_Internal_Name), Executable => Project.Library_Kind /= Static); Copy_File (From => Lib_Dir & Get_Name_String (Get_Library_Filename), To => Lib_Dir, File => Get_Name_String (Project.Lib_Internal_Name), Sym_Link => True); end if; else Copy_File (From => Cat (Project.Library_Dir.Display_Name, Get_Library_Filename), To => Lib_Dir, File => Get_Name_String (Get_Library_Filename), Executable => Project.Library_Kind /= Static); end if; -- On Windows copy the shared libraries into the bin directory -- for it to be found in the PATH when running executable. On non -- Windows platforms add a symlink into the lib directory. if Project.Library_Kind /= Static and then Add_Lib_Link then if Windows_Target then Copy_File (From => Lib_Dir & Get_Name_String (Get_Library_Filename), To => Exec_Dir, File => Get_Name_String (Get_Library_Filename), Executable => True); else Copy_File (From => Link_Lib_Dir & Get_Name_String (Get_Library_Filename), To => Lib_Dir, File => Get_Name_String (Get_Library_Filename), Sym_Link => True); end if; end if; end if; -- Copy executable(s) if Copy (Executable) then declare M : String_List_Id := Project.Mains; begin while M /= Nil_String loop declare Bin : constant String := Main_Binary (Strs (M).Value); begin Copy_File (From => Get_Name_String (Project.Exec_Directory.Display_Name) & Bin, To => Exec_Dir, File => Bin, Executable => True); end; M := Strs (M).Next; end loop; end; end if; -- Copy artifacts for E of Artifacts loop declare Destination : constant String := Ensure_Directory (Get_Name_String (E.Destination)); Filename : constant String := Get_Name_String (E.Filename); begin Copy_Artifacts (Get_Name_String (Project.Directory.Name) & Filename, Destination); end; end loop; end Copy_Files; -------------------- -- Create_Project -- -------------------- procedure Create_Project (Project : Project_Id) is Filename : constant String := Project_Dir & Base_Name (Get_Name_String (Project.Path.Display_Name)) & ".gpr"; Gprinstall_Tag : constant String := "This project has been generated by GPRINSTALL"; package String_Vector is new Containers.Indefinite_Vectors (Positive, String); package Seen_Set is new Containers.Indefinite_Ordered_Sets (String); Content : String_Vector.Vector; -- The content of the project, this is used when creating the project -- and is needed to ease the project section merging when installing -- multiple builds. Line : Unbounded_String; function "+" (Item : String) return Unbounded_String renames To_Unbounded_String; function "-" (Item : Unbounded_String) return String renames To_String; procedure Create_Packages; -- Create packages that are needed, currently Naming and part of -- Linker is generated for the installed project. function Image (Name : Name_Id; Id : Array_Element_Id) return String; -- Returns Id image function Image (Id : Variable_Id) return String; -- Returns Id image function Image (Var : Variable_Value) return String; -- Returns Id image procedure Read_Project; -- Read project and set Content accordingly procedure Write_Project; -- Write content into project procedure Add_Empty_Line; pragma Inline (Add_Empty_Line); function Naming_Case_Alternative (Proj : Project_Id) return String_Vector.Vector; -- Returns the naming case alternative for this project configuration function Linker_Case_Alternative (Proj : Project_Id) return String_Vector.Vector; -- Returns the linker case alternative for this project configuration function Data_Attributes return String_Vector.Vector; -- Returns the attributes for the sources, objects and library function Get_Languages return String; -- Returns the list of languages function Get_Package (Project : Project_Id; Pkg_Name : Name_Id) return Package_Id; -- Returns the package Name for the given project -------------------- -- Add_Empty_Line -- -------------------- procedure Add_Empty_Line is begin if Content.Element (Content.Last_Index) /= "" then Content.Append (""); end if; end Add_Empty_Line; --------------------- -- Create_Packages -- --------------------- procedure Create_Packages is procedure Create_Naming (Proj : Project_Id); -- Create the naming package procedure Create_Linker (Proj : Project_Id); -- Create the linker package if needed ------------------- -- Create_Naming -- ------------------- procedure Create_Naming (Proj : Project_Id) is begin Content.Append (" package Naming is"); -- Attributes declare V : Variable_Id := Pcks (Get_Package (Proj, Name_Naming)).Decl.Attributes; begin while V /= No_Variable loop Content.Append (" " & Image (V)); V := Tree.Shared.Variable_Elements.Table (V).Next; end loop; end; Content.Append (" case BUILD is"); Content.Append (Naming_Case_Alternative (Proj)); Content.Append (" end case;"); Content.Append (" end Naming;"); Add_Empty_Line; end Create_Naming; ------------------- -- Create_Linker -- ------------------- procedure Create_Linker (Proj : Project_Id) is begin Content.Append (" package Linker is"); Content.Append (" case BUILD is"); -- Attribute Linker_Options only if set Content.Append (Linker_Case_Alternative (Proj)); Content.Append (" end case;"); Content.Append (" end Linker;"); Add_Empty_Line; end Create_Linker; begin Create_Naming (Project); Create_Linker (Project); end Create_Packages; --------------------- -- Data_Attributes -- --------------------- function Data_Attributes return String_Vector.Vector is procedure Gen_Dir_Name (P : Param; Line : in out Unbounded_String); -- Generate dir name ------------------ -- Gen_Dir_Name -- ------------------ procedure Gen_Dir_Name (P : Param; Line : in out Unbounded_String) is begin if P.Default then -- This is the default value, add Dir_Name Line := Line & Dir_Name (Suffix => False); -- Furthermore, if the build name is "default" do not output if Build_Name.all /= "default" then Line := Line & "." & Build_Name.all; end if; end if; end Gen_Dir_Name; V : String_Vector.Vector; Line : Unbounded_String; begin V.Append (" when """ & Build_Name.all & """ =>"); -- Project sources Line := +" for Source_Dirs use ("""; Line := Line & Relative_Path (Sources_Dir (Build_Name => False), To => Project_Dir); Gen_Dir_Name (Sources_Subdir, Line); Line := Line & """);"; V.Append (-Line); -- Project objects and/or library if Project.Library then Line := +" for Library_Dir use """; else Line := +" for Object_Dir use """; end if; Line := Line & Relative_Path (Lib_Dir (Build_Name => False), To => Project_Dir); Gen_Dir_Name (Lib_Subdir, Line); Line := Line & """;"; V.Append (-Line); if Project.Library then Line := +" for Library_Kind use """; Line := Line & To_Lower (Lib_Kind'Image (Project.Library_Kind)); Line := Line & """;"; V.Append (-Line); if Project.Standalone_Library /= No then Line := +" for Library_Standalone use """; Line := Line & To_Lower (Standalone'Image (Project.Standalone_Library)); Line := Line & """;"; V.Append (-Line); -- And then generates the interfaces Line := +" for Library_Interface use ("; declare L : String_List_Id := Project.Lib_Interface_ALIs; First : Boolean := True; begin while L /= Nil_String loop if not First then Append (Line, ", "); else First := False; end if; Append (Line, """"); -- Removes the trailing .ali extension Append (Line, Base_Name (Get_Name_String (Strs (L).Value))); Append (Line, """"); L := Strs (L).Next; end loop; end; Append (Line, ");"); V.Append (-Line); end if; end if; return V; end Data_Attributes; ------------------- -- Get_Languages -- ------------------- function Get_Languages return String is package Lang_Set is new Containers.Indefinite_Ordered_Sets (String, Strings.Less_Case_Insensitive, Strings.Equal_Case_Insensitive); Langs : Lang_Set.Set; procedure For_Project (Project : Project_Id); -- Add languages for the given project ----------------- -- For_Project -- ----------------- procedure For_Project (Project : Project_Id) is L : Language_Ptr := Project.Languages; begin while L /= null loop if L.Config.Compiler_Driver /= No_File and then Get_Name_String (L.Config.Compiler_Driver) /= "" then Langs.Include (Get_Name_String (L.Display_Name)); end if; L := L.Next; end loop; end For_Project; begin -- First adds language for the main project For_Project (Project); -- If we are dealing with an aggregate library, adds the languages -- from all aggregated projects. if Project.Qualifier = Aggregate_Library then declare Agg : Aggregated_Project_List := Project.Aggregated_Projects; begin while Agg /= null loop For_Project (Agg.Project); Agg := Agg.Next; end loop; end; end if; declare Res : Unbounded_String; First : Boolean := True; begin for V of Langs loop if not First then Res := Res & ", "; end if; Res := Res & '"' & V & '"'; First := False; end loop; return To_String (Res); end; end Get_Languages; ----------------- -- Get_Package -- ----------------- function Get_Package (Project : Project_Id; Pkg_Name : Name_Id) return Package_Id is Pck : Package_Id := Project.Decl.Packages; begin while Pck /= No_Package loop if Pcks (Pck).Decl /= No_Declarations and then Pcks (Pck).Name = Pkg_Name then return Pck; end if; Pck := Pcks (Pck).Next; end loop; return No_Package; end Get_Package; ----------- -- Image -- ----------- function Image (Name : Name_Id; Id : Array_Element_Id) return String is E : constant Array_Element := Tree.Shared.Array_Elements.Table (Id); begin return "for " & Get_Name_String (Name) & " (""" & Get_Name_String (E.Index) & """) use " & Image (E.Value); end Image; function Image (Id : Variable_Id) return String is V : constant Variable_Value := Tree.Shared.Variable_Elements.Table (Id).Value; begin if V.Default then return ""; else return "for " & Get_Name_String (Tree.Shared.Variable_Elements.Table (Id).Name) & " use " & Image (V); end if; end Image; function Image (Var : Variable_Value) return String is begin case Var.Kind is when Single => return """" & Get_Name_String (Var.Value) & """;"; when List => declare V : Unbounded_String; L : String_List_Id := Var.Values; First : Boolean := True; begin Append (V, "("); while L /= Nil_String loop if not First then Append (V, ", "); else First := False; end if; Append (V, """"); Append (V, Get_Name_String (Strs (L).Value)); Append (V, """"); L := Strs (L).Next; end loop; Append (V, ");"); return To_String (V); end; when Undefined => return ""; end case; end Image; ----------------------------- -- Linker_Case_Alternative -- ----------------------------- function Linker_Case_Alternative (Proj : Project_Id) return String_Vector.Vector is use type Ada.Containers.Count_Type; procedure Linker_For (Pck : Package_Id); -- Handle the linker options for this package Seen : Seen_Set.Set; -- Records the attribute generated to avoid duplicate when -- handling aggregated projects. R : String_Vector.Vector; Opts : String_Vector.Vector; ---------------- -- Linker_For -- ---------------- procedure Linker_For (Pck : Package_Id) is V : Variable_Id := Pcks (Pck).Decl.Attributes; begin while V /= No_Variable loop if Tree.Shared.Variable_Elements.Table (V).Name = Name_Linker_Options then declare Val : constant Variable_Value := Tree.Shared.Variable_Elements.Table (V).Value; L : String_List_Id := Val.Values; begin while L /= Nil_String loop Opts.Append (Get_Name_String (Strs (L).Value)); Seen.Include (Get_Name_String (Strs (L).Value)); L := Strs (L).Next; end loop; end; end if; V := Tree.Shared.Variable_Elements.Table (V).Next; end loop; end Linker_For; begin R.Append (" when """ & Build_Name.all & """ =>"); Linker_For (Get_Package (Proj, Name_Linker)); if Proj.Qualifier = Aggregate_Library then declare Agg : Aggregated_Project_List := Project.Aggregated_Projects; begin while Agg /= null loop Linker_For (Get_Package (Agg.Project, Name_Linker)); Agg := Agg.Next; end loop; end; end if; -- We also want to add the externally built libraries without -- sources (referencing system libraries for example). declare L : Project_List := Project.All_Imported_Projects; begin while L /= null loop if L.Project.Library and then L.Project.Externally_Built and then not Bring_Sources (L.Project) then Opts.Append ("-l" & Get_Name_String (L.Project.Library_Name)); end if; L := L.Next; end loop; end; if Opts.Length = 0 then -- No linker alternative found, add null statement R.Append (" null;"); else declare O_List : Unbounded_String; begin for O of Opts loop if O_List /= Null_Unbounded_String then Append (O_List, ", "); end if; Append (O_List, '"' & O & '"'); end loop; R.Append (" for Linker_Options use (" & To_String (O_List) & ");"); end; end if; return R; end Linker_Case_Alternative; ----------------------------- -- Naming_Case_Alternative -- ----------------------------- function Naming_Case_Alternative (Proj : Project_Id) return String_Vector.Vector is procedure Naming_For (Pck : Package_Id); -- Handle the naming scheme for this package Seen : Seen_Set.Set; -- Records the attribute generated to avoid duplicate when -- handling aggregated projects. V : String_Vector.Vector; ---------------- -- Naming_For -- ---------------- procedure Naming_For (Pck : Package_Id) is A : Array_Id := Pcks (Pck).Decl.Arrays; N : Name_Id; E : Array_Element_Id; begin -- Arrays while A /= No_Array loop N := Tree.Shared.Arrays.Table (A).Name; E := Tree.Shared.Arrays.Table (A).Value; while E /= No_Array_Element loop declare Decl : constant String := Image (N, E); begin if not Seen.Contains (Decl) then V.Append (" " & Image (N, E)); Seen.Include (Decl); end if; end; E := Tree.Shared.Array_Elements.Table (E).Next; end loop; A := Tree.Shared.Arrays.Table (A).Next; end loop; end Naming_For; begin V.Append (" when """ & Build_Name.all & """ =>"); Naming_For (Get_Package (Proj, Name_Naming)); if Proj.Qualifier = Aggregate_Library then declare Agg : Aggregated_Project_List := Project.Aggregated_Projects; begin while Agg /= null loop Naming_For (Get_Package (Agg.Project, Name_Naming)); Agg := Agg.Next; end loop; end; end if; return V; end Naming_Case_Alternative; ------------------ -- Read_Project -- ------------------ procedure Read_Project is File : File_Type; Buffer : String (1 .. 1_024); Last : Natural; begin Open (File, In_File, Filename); while not End_Of_File (File) loop Get_Line (File, Buffer, Last); Content.Append (Buffer (1 .. Last)); end loop; Close (File); end Read_Project; ------------------- -- Write_Project -- ------------------- procedure Write_Project is F : File_Access := Standard_Output; File : aliased File_Type; begin if not Dry_Run then Create (File, Out_File, Filename); F := File'Unchecked_Access; end if; for K in Content.First_Index .. Content.Last_Index loop Put_Line (F.all, Content.Element (K)); end loop; if not Dry_Run then Close (File); end if; end Write_Project; type Section_Kind is (Top, Naming, Linker); Project_Exists : constant Boolean := Exists (Filename); Current_Section : Section_Kind := Top; Pos : String_Vector.Cursor; Generated : Boolean := False; begin if Dry_Run or else Opt.Verbose_Mode then Write_Eol; Write_Str ("Project "); Write_Str (Filename); if Dry_Run then Write_Line (" would be installed"); else Write_Line (" installed"); end if; Write_Eol; end if; -- If project exists, read it and check the generated status if Project_Exists then Read_Project; -- First check that this project has been generated by gprbuild, -- if not exit with an error as we cannot modify a project created -- manually and we do not want to overwrite it. Pos := Content.First; Check_Generated_Status : while String_Vector.Has_Element (Pos) loop if Fixed.Index (String_Vector.Element (Pos), Gprinstall_Tag) /= 0 then Generated := True; exit Check_Generated_Status; end if; String_Vector.Next (Pos); end loop Check_Generated_Status; if not Generated and then not Force_Installations then Write_Str ("non gprinstall project file "); Write_Str (Filename); Write_Str (" exists, use -f to overwrite"); Write_Eol; OS_Exit (1); end if; end if; if Project_Exists and then Generated then if not Has_Sources (Project) then -- Nothing else to do in this case return; end if; if Opt.Verbose_Mode then Write_Line ("project file exists, merging new build"); end if; -- Do merging for new build, we need to add an entry into the -- BUILD_KIND type and a corresponding case entry in the naming -- and Linker package. Parse_Content : while String_Vector.Has_Element (Pos) loop declare BN : constant String := Build_Name.all; Line : constant String := String_Vector.Element (Pos); P, L : Natural; begin if Fixed.Index (Line, "type BUILD_KIND is (") /= 0 then -- This is the "type BUILD_KIND" line, add new build name -- First check if the current build name already exists if Fixed.Index (Line, """" & BN & """") = 0 then -- Get end of line P := Fixed.Index (Line, ");"); if P = 0 then Write_Line ("cannot parse the BUILD_KIND line"); OS_Exit (1); else Content.Replace_Element (Pos, Line (Line'First .. P - 1) & ", """ & BN & """);"); end if; end if; elsif Fixed.Index (Line, ":= external") /= 0 and then Build_Var /= null then -- Replace build-var with new one P := Fixed.Index (Line, """"); if P = 0 then Write_Line ("cannot parse the BUILD line"); OS_Exit (1); else L := P + 1; while L <= Line'Last and then Line (L) /= '"' loop L := L + 1; end loop; if Line (L) /= '"' then Write_Line ("cannot parse the BUILD line"); OS_Exit (1); else Content.Replace_Element (Pos, Line (Line'First .. P) & Build_Var.all & Line (L .. Line'Last)); end if; end if; elsif Fixed.Index (Line, "package Naming is") /= 0 then Current_Section := Naming; elsif Fixed.Index (Line, "package Linker is") /= 0 then Current_Section := Linker; elsif Fixed.Index (Line, "case BUILD is") /= 0 then -- Add new case section for the new build name case Current_Section is when Naming => String_Vector.Next (Pos); Content.Insert (Pos, Naming_Case_Alternative (Project)); when Linker => String_Vector.Next (Pos); Content.Insert (Pos, Linker_Case_Alternative (Project)); when Top => -- For the Sources/Lib attributes String_Vector.Next (Pos); Content.Insert (Pos, Data_Attributes); end case; elsif Fixed.Index (Line, "when """ & BN & """ =>") /= 0 then -- Found a when with the current build name, this is a -- previous install overwritten by this one. Remove this -- section. Note that this removes sections from all -- packages Naming and Linker, and from project level -- case alternative. Count_And_Delete : declare use type Containers.Count_Type; function End_When (L : String) return Boolean; -- Return True if L is the end of a when alternative -------------- -- End_When -- -------------- function End_When (L : String) return Boolean is P : constant Natural := Strings.Fixed.Index_Non_Blank (L); Len : constant Natural := L'Length; begin return P > 0 and then ((P + 4 <= Len and then L (P .. P + 4) = "when ") or else (P + 8 <= Len and then L (P .. P + 8) = "end case;")); end End_When; N : Containers.Count_Type := 0; P : String_Vector.Cursor := Pos; begin -- The number of line to delete are from Pos to the -- first line starting with a "when". loop String_Vector.Next (P); N := N + 1; exit when End_When (String_Vector.Element (P)); end loop; Content.Delete (Pos, N); end Count_And_Delete; end if; end; String_Vector.Next (Pos); end loop Parse_Content; else -- Project does not exists, or it exists, was not generated by -- gprinstall and -f used. In this case it will be overwriten by -- a generated project. Content.Clear; -- Tag project as generated by gprbuild Content.Append ("-- " & Gprinstall_Tag & ' ' & Gpr_Version_String); Add_Empty_Line; -- Handle with clauses, generate a with clauses only for project -- bringing some visibility to sources. No need for doing this for -- aggregate projects. if Project.Qualifier /= Aggregate_Library then declare L : Project_List := Project.Imported_Projects; begin while L /= null loop if Has_Sources (L.Project) and then not L.Project.Externally_Built and then Is_Install_Active (Tree, L.Project) then Content.Append ("with """ & Base_Name (Get_Name_String (L.Project.Path.Display_Name)) & """;"); end if; L := L.Next; end loop; end; end if; -- In all cases adds externally built projects declare L : Project_List := Project.All_Imported_Projects; begin while L /= null loop if Has_Sources (L.Project) and then L.Project.Externally_Built then Content.Append ("with """ & Base_Name (Get_Name_String (L.Project.Path.Display_Name)) & """;"); end if; L := L.Next; end loop; end; Add_Empty_Line; -- Project name if Has_Sources (Project) then if Project.Library then Line := +"library "; else Line := +"standard "; end if; else Line := +"abstract "; end if; Line := Line & "project "; Line := Line & Get_Name_String (Project.Display_Name); Line := Line & " is"; Content.Append (-Line); if Has_Sources (Project) then -- BUILD variable Content.Append (" type BUILD_KIND is (""" & Build_Name.all & """);"); Line := +" BUILD : BUILD_KIND := external("""; if Build_Var /= null then Line := Line & Build_Var.all; else Line := Line & To_Upper (Dir_Name (Suffix => False)); Line := Line & "_BUILD"; end if; Line := Line & """, """ & Build_Name.all & """);"; Content.Append (-Line); -- Add languages, for an aggregate library we want all unique -- languages from all aggregated libraries. Add_Empty_Line; Content.Append (" for Languages use (" & Get_Languages & ");"); -- Build_Suffix used to avoid .default as suffix Add_Empty_Line; Content.Append (" case BUILD is"); Content.Append (Data_Attributes); Content.Append (" end case;"); Add_Empty_Line; -- Library Name if Project.Library then Content.Append (" for Library_Name use """ & Get_Name_String (Project.Library_Name) & """;"); -- Issue the Library_Version only if needed if Project.Library_Kind /= Static and then Project.Lib_Internal_Name /= No_Name and then Project.Library_Name /= Project.Lib_Internal_Name then Content.Append (" for Library_Version use """ & Get_Name_String (Project.Lib_Internal_Name) & """;"); end if; end if; Add_Empty_Line; -- Packages Create_Packages; -- Externally Built Content.Append (" for Externally_Built use ""True"";"); else -- This is an abstract project Content.Append (" for Source_Dirs use ();"); end if; -- Close project Content.Append ("end " & Get_Name_String (Project.Display_Name) & ";"); end if; -- Write new project if needed Write_Project; if not Dry_Run then -- Add project file to manifest Add_To_Manifest (Filename); end if; end Create_Project; ------------------------- -- Open_Check_Manifest -- ------------------------- procedure Open_Check_Manifest is Dir : constant String := Project_Dir & "manifests"; Name : constant String := Dir & DS & Install_Name.all; Prj_Sig : constant String := File_MD5 (Get_Name_String (Project.Path.Display_Name)); Buf : String (1 .. 128); Last : Natural; begin -- Check wether the manifest does not exist in this case if Exists (Name) then Open (Man, In_File, Name); Get_Line (Man, Buf, Last); if Last >= Message_Digest'Length and then (Buf (1 .. 2) /= Sig_Line or else Buf (3 .. Message_Digest'Last + 2) /= Prj_Sig) and then Install_Name_Default then Write_Line ("Project already installed, either:"); Write_Line (" - uninstall first using --uninstall option"); Write_Line (" - install under another name, use --install-name"); Write_Line (" - force installation under the same name, " & "use --install-name=" & Install_Name.all); OS_Exit (1); end if; Reset (Man, Append_File); else Create_Path (Dir); Create (Man, Out_File, Name); Put_Line (Man, Sig_Line & Prj_Sig); end if; end Open_Check_Manifest; Install_Project : Boolean; -- Whether the project is to be installed begin -- If we have an aggregate project we just install separately all -- aggregated projects. if Project.Qualifier = Aggregate then declare L : Aggregated_Project_List := Project.Aggregated_Projects; begin while L /= null loop Process (L.Tree, L.Project); L := L.Next; end loop; end; -- Nothing more to do for an aggegate project return; end if; if not Installed.Contains (Project.Name) then Installed.Include (Project.Name); -- First look for the Install package and set up the local values -- accordingly. Check_Install_Package; -- The default install name is the name of the project without -- extension. if Install_Name = null or else Install_Name_Default then Free (Install_Name); Install_Name := new String'((Base_Name (Get_Name_String (Project.Path.Name)))); end if; -- Skip non active project and externally built ones Install_Project := Active and Bring_Sources (Project) and not Project.Externally_Built; if not Opt.Quiet_Output then if Install_Project then Write_Str ("Install"); elsif Opt.Verbose_Mode then Write_Str ("Skip"); end if; if Install_Project or Opt.Verbose_Mode then Write_Str (" project "); Write_Str (Get_Name_String (Project.Display_Name)); if Build_Name.all /= "default" then Write_Str (" - " & Build_Name.all); end if; end if; if not Install_Project and Opt.Verbose_Mode then if not Active then Write_Str (" (not active)"); elsif Project.Externally_Built then Write_Str (" (externally built)"); elsif Project.Source_Dirs = Nil_String then Write_Str (" (no sources)"); end if; end if; if Install_Project or Opt.Verbose_Mode then Write_Eol; end if; end if; -- If this is not an active project, just return now if not Install_Project then return; end if; -- What should be copied Copy := (Source => For_Dev, Object => For_Dev and then Project.Mains = Nil_String and then Project.Qualifier /= Library and then Project.Qualifier /= Aggregate_Library and then not Project.Library, Dependency => For_Dev and then Project.Mains = Nil_String, Library => Project.Library and then ((For_Dev and then Project.Library_Kind = Static) or else Project.Library_Kind /= Static), Executable => Project.Mains /= Nil_String); -- Copy all files from the project if Has_Sources (Project) then Copy_Files; end if; -- A project file is only needed in developer mode if For_Dev then Create_Project (Project); end if; -- Close manifest file if needed if Is_Open (Man) then Close (Man); end if; -- Handle all projects recursivelly if needed if Recursive then declare L : Project_List := Project.Imported_Projects; begin while L /= null loop Process (Tree, L.Project); L := L.Next; end loop; end; end if; end if; Free (Prefix_Dir); Free (Sources_Subdir); Free (Lib_Subdir); Free (Exec_Subdir); Free (Project_Subdir); end Process; end Gprinstall.Install; gprbuild-gpl-2014-src/src/gprlib-build_shared_lib.adb0000644000076700001450000000352512323721731022127 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R L I B . B U I L D _ S H A R E D _ L I B -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2012, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- This is the default body for procedure Build_Shared_Lib, used when shared -- libraries are not supported. It is an error if this procedure is called. separate (Gprlib) procedure Build_Shared_Lib is begin Osint.Fail ("Build_Shared_Lib should not have been called"); end Build_Shared_Lib; gprbuild-gpl-2014-src/src/gprbuild.ads0000644000076700001450000004171612323721731017234 0ustar gnatmailgnat------------------------------------------------------------------------------ -- GNAT COMPILER COMPONENTS -- -- -- -- G P R B U I L D -- -- -- -- S p e c -- -- -- -- Copyright (C) 2004-2014, Free Software Foundation, Inc. -- -- -- -- This is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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 distributed with this software; see file -- -- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy -- -- of the license. -- ------------------------------------------------------------------------------ -- The following package implements the facilities to compile, bind and/or -- link a set of Ada and non Ada sources, specified in Project Files. private with Ada.Unchecked_Deallocation; private with GNAT.Dynamic_Tables; private with GNAT.HTable; private with GNAT.OS_Lib; private with Makeutl; with ALI; with Namet; use Namet; with Opt; with Prj; use Prj; with Table; with Types; use Types; package Gprbuild is -- Everyting private so only accessible to child packages private use GNAT.OS_Lib; use type ALI.ALI_Id, Opt.Verbosity_Level_Type, Opt.Warning_Mode_Type; Object_Suffix : constant String := Get_Target_Object_Suffix.all; -- The suffix of object files on this platform Dash_L : Name_Id; -- "-L", initialized in procedure Initialize Main_Project_Dir : String_Access; -- The absolute path of the project directory of the main project, -- initialized in procedure Initialize. Executable_Suffix : constant String_Access := Get_Executable_Suffix; -- The suffix of executables on this platforms Main_Index : Int := 0; Project_Tree : constant Project_Tree_Ref := new Project_Tree_Data (Is_Root_Tree => True); -- The project tree Copyright_Output : Boolean := False; Usage_Output : Boolean := False; -- Flags to avoid multiple displays of Copyright notice and of Usage Usage_Needed : Boolean := False; -- Set by swith -h: usage will be displayed after all command line -- switches have been scanned. Display_Paths : Boolean := False; -- Set by switch --display-paths: config project path and user project path -- will be displayed after all command lines witches have been scanned. Output_File_Name : String_Access := null; -- The name given after a switch -o Output_File_Name_Expected : Boolean := False; -- True when last switch was -o Project_File_Name_Expected : Boolean := False; -- True when last switch was -P Search_Project_Dir_Expected : Boolean := False; -- True when last switch was -aP Object_Checked : Boolean := True; -- False when switch --no-object-check is used. When True, presence of -- the object file and its time stamp are checked to decide if a file needs -- to be compiled. Also set to False when switch --codepeer is used. Map_File : String_Access := null; -- Value of switch --create-map-file Indirect_Imports : Boolean := True; -- False when switch --no-indirect-imports is used. Sources are only -- allowed to import from the projects that are directly withed. Recursive : Boolean := False; Unique_Compile : Boolean := False; -- Set to True if -u or -U or a project file with no main is used Unique_Compile_All_Projects : Boolean := False; -- Set to True if -U is used Always_Compile : Boolean := False; -- Set to True when gprbuid is called with -f -u and at least one source -- on the command line. Builder_Switches_Lang : Name_Id := No_Name; -- Used to decide to what compiler the Builder'Default_Switches that -- are not recognized by gprbuild should be given. package All_Language_Builder_Compiling_Options is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Makegpr.All_Language_Builder_Compiling_Options"); -- Table to store the options for all compilers, that is those that -- follow the switch "-cargs" without any mention of language in the -- Builder switches. package All_Language_Compiling_Options is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Makegpr.All_Language_Compiling_Options"); -- Table to store the options for all compilers, that is those that -- follow the switch "-cargs" without any mention of language on the -- command line. package Builder_Compiling_Options is new GNAT.Dynamic_Tables (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100); -- Tables to store the options for the compilers of the different -- languages, that is those after switch "-cargs:", in the Builder -- switches. package Compiling_Options is new GNAT.Dynamic_Tables (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100); -- Tables to store the options for the compilers of the different -- languages, that is those after switch "-cargs:", on the command -- line. type Boolean_Array is array (Positive range <>) of Boolean; type Booleans is access Boolean_Array; procedure Free is new Ada.Unchecked_Deallocation (Boolean_Array, Booleans); Initial_Number_Of_Options : constant Natural := 10; type Options_Data is record Options : String_List_Access := new String_List (1 .. Initial_Number_Of_Options); Visible : Booleans := new Boolean_Array (1 .. Initial_Number_Of_Options); Simple_Name : Booleans := new Boolean_Array (1 .. Initial_Number_Of_Options); Last : Natural := 0; end record; -- A record type to keep different options with a boolean for each that -- indicates if it should be displayed. All_Options : Options_Data; -- A cache for all options, to avoid too many allocations Compilation_Options : Options_Data; -- The compilation options coming from package Compiler type Comp_Option_Table_Ref is access Compiling_Options.Instance; No_Comp_Option_Table : constant Comp_Option_Table_Ref := null; Current_Comp_Option_Table : Comp_Option_Table_Ref := No_Comp_Option_Table; type Builder_Comp_Option_Table_Ref is access Builder_Compiling_Options.Instance; No_Builder_Comp_Option_Table : constant Builder_Comp_Option_Table_Ref := null; package Compiling_Options_HTable is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Comp_Option_Table_Ref, No_Element => No_Comp_Option_Table, Key => Name_Id, Hash => Prj.Hash, Equal => "="); -- A hash table to get the command line compilation option table from the -- language name. package Builder_Compiling_Options_HTable is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Builder_Comp_Option_Table_Ref, No_Element => No_Builder_Comp_Option_Table, Key => Name_Id, Hash => Prj.Hash, Equal => "="); -- A hash table to get the builder compilation option table from the -- language name. package All_Language_Binder_Options is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Makegpr.All_Language_Binder_Options"); -- Table to store the options for all binders, that is those that -- follow the switch "-bargs" without any mention of language. package Binder_Options is new GNAT.Dynamic_Tables (Table_Component_Type => String_Access, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100); -- Tables to store the options for the binders of the different -- languages, that is those after switch "-bargs:". type Bind_Option_Table_Ref is access Binder_Options.Instance; No_Bind_Option_Table : constant Bind_Option_Table_Ref := null; Current_Bind_Option_Table : Bind_Option_Table_Ref := No_Bind_Option_Table; package Binder_Options_HTable is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Bind_Option_Table_Ref, No_Element => No_Bind_Option_Table, Key => Name_Id, Hash => Prj.Hash, Equal => "="); -- A hash table to get the compilation option table from the language name package Binding_Options is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 20, Table_Increment => 100, Table_Name => "Makegpr.Binding_Options"); -- Table to store the linking options coming from the binder package Command_Line_Linker_Options is new Table.Table (Table_Component_Type => String_Access, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 20, Table_Increment => 100, Table_Name => "Makegpr.Command_Line_Linker_Options"); -- Table to store the linking options type Linker_Options_Data is record Project : Project_Id; Options : String_List_Id; end record; package Linker_Opts is new Table.Table (Table_Component_Type => Linker_Options_Data, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 20, Table_Increment => 100, Table_Name => "Makegpr.Linker_Opts"); -- Table to store the Linker'Linker_Options in the project files Project_Of_Current_Object_Directory : Project_Id := No_Project; -- The object directory of the project for the last binding. Avoid -- calling Change_Dir if the current working directory is already this -- directory. -- Archive builder name, path and options Archive_Builder_Name : String_Access := null; Archive_Builder_Path : String_Access := null; Archive_Builder_Opts : Options_Data; Archive_Builder_Append_Opts : Options_Data; -- Archive indexer name, path and options Archive_Indexer_Name : String_Access := null; Archive_Indexer_Path : String_Access := null; Archive_Indexer_Opts : Options_Data; -- Libraries type Library_Project is record Proj : Project_Id; Is_Aggregated : Boolean; end record; package Library_Projs is new Table.Table ( Table_Component_Type => Library_Project, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 10, Table_Name => "Buildgpr.Library_Projs"); -- Library projects imported directly or indirectly package Non_Library_Projs is new Table.Table ( Table_Component_Type => Project_Id, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 10, Table_Name => "Buildgpr.Non_Library_Projs"); -- Non library projects imported directly or indirectly procedure Add_Option (Value : String; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False); procedure Add_Option (Value : Name_Id; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False); procedure Add_Options (Value : String_List_Id; To : in out Options_Data; Display_All : Boolean; Display_First : Boolean; Simple_Name : Boolean := False); -- Add one or several options to a list of options. Increase the size -- of the list, if necessary. function Get_Option (Option : Name_Id) return String_Access; -- Get a string access corresponding to Option. Either find the string -- access in the All_Options cache, or create a new entry in All_Options. procedure Test_If_Relative_Path (Switch : in out String_Access; Parent : String; Including_Switch : Name_Id); procedure Add_Option_Internal (Value : String_Access; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False); -- Add an option in a specific list of options procedure Add_Option_Internal_Codepeer (Value : String_Access; To : in out Options_Data; Display : Boolean; Simple_Name : Boolean := False); -- Similar to procedure Add_Option_Internal, except that in CodePeer -- mode, options -mxxx are not added. procedure Process_Imported_Libraries (For_Project : Project_Id; There_Are_SALs : out Boolean; And_Project_Itself : Boolean := False); -- Get the imported library project ids in table Library_Projs procedure Process_Imported_Non_Libraries (For_Project : Project_Id); -- Get the imported non library project ids in table Non_Library_Projs function Create_Path_From_Dirs return String_Access; -- Concatenate all directories in the Directories table into a path. -- Caller is responsible for freeing the result procedure Check_Archive_Builder; -- Check if the archive builder (ar) is there function Archive_Suffix (For_Project : Project_Id) return String; -- Return the archive suffix for the project, if defined, otherwise -- return ".a". procedure Change_To_Object_Directory (Project : Project_Id); -- Change to the object directory of project Project, if this is not -- already the current working directory. use Makeutl; package Bad_Processes is new Table.Table (Table_Component_Type => Main_Info, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Gprbuild.Bad_Processes"); -- Info for all the mains where binding fails Outstanding_Processes : Natural := 0; -- The number of bind jobs currently spawned Stop_Spawning : Boolean := False; -- True when one bind process failed and switch -k was not used procedure Record_Failure (Main : Main_Info); -- Add Main to table Bad_Binds and set Stop_Binding to True if switch -k is -- not used. type Process_Kind is (None, Binding, Linking); type Process_Data (Kind : Process_Kind := None) is record Process : Process_Id := Invalid_Pid; Main : Main_Info := No_Main_Info; case Kind is when Linking => Response_1 : Path_Name_Type := No_Path; Response_2 : Path_Name_Type := No_Path; when others => null; end case; end record; No_Process_Data : constant Process_Data := (None, Invalid_Pid, No_Main_Info); type Header_Num is range 0 .. 2047; function Hash (Pid : Process_Id) return Header_Num; -- Used for Process_Htable below package Process_Htable is new GNAT.HTable.Simple_HTable (Header_Num => Header_Num, Element => Process_Data, No_Element => No_Process_Data, Key => Process_Id, Hash => Hash, Equal => "="); -- Hash table to keep data for all spawned jobs procedure Add_Process (Process : Process_Id; Data : Process_Data); -- Add process in the Process_Htable procedure Await_Process (Data : out Process_Data; OK : out Boolean); -- Wait for the end of a bind job procedure Display_Processes (Name : String); -- When -jnn, -v and -vP2 are used, display the number of currently spawned -- processes. end Gprbuild; gprbuild-gpl-2014-src/src/gprbuild_dummies.c0000644000076700001450000000320412323721732020421 0ustar gnatmailgnat/**************************************************************************** * * * GNAT COMPILER COMPONENTS * * * * G P R B U I L D _ D U M M I E S * * * * C Implementation File * * * * Copyright (C) 2006-2012, Free Software Foundation, Inc. * * * This is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * * ware Foundation; either version 3, or (at your option) any later ver- * * sion. This software is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- * * TABILITY 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 distributed with this software; see file * * COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy * * of the license. * ****************************************************************************/ #include void set_std_prefix (void) { abort (); } void update_path (void) { abort (); } gprbuild-gpl-2014-src/known-problems-1000000644000076700001450000001027611260747162017344 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.0.0 ======================================== Copyright (c) 2008, 2009 AdaCore The following is a listing of known problems in release 1.0.0. Except where specifically noted, all these problems have been corrected in the development tree of the 1.1 technology. This means they are corrected in any 1.1.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-100-H115-007 gprbuild fails to build archives with many object files Problem: gprbuild may fail to build archives (for static library or the global archive) when the number of object files is too large. Status: This was fixed in 1.1.0 on 2008-01-16 Workaround: Either reduce the number of object files, using one or several static libraries, or reduce the absolute paths of the project files. KP-100-H124-002 Missing objects from externally built projects Problem: When an externally built projects does not contain sources for bodies, but only for some specs, some of the object files may be missing in the global archive. Status: This was fixed in 1.1.0 on 2008-03-06 Workaround: Convert the externally built project into an externally built static library project. KP-100-H208-029 -bargs and -largs not allowed in package Builder Problem: Switches -bargs, -bargs: and -largs are not accepted in the switch attributes of package Builder. Status: This was fixed in 1.1.0 on 2008-02-09 Workaround: Use these switches only on the command line. KP-100-H216-002 gprbuild crashes with limited with cycle Problem: gprbuild may crash if there are cycles in the project tree using limited withs. Status: This was fixed in 1.1.0 on 2008-02-17 Workaround: Do not use limited withs. KP-100-H226-027 Missing gprclean switch -eL Problem: The switch -eL, to follow symbolic links when processing project files, is missing for gprclean. Status: This was fixed in 1.1.0 on 2008-02-26 Workaround: Do not use symbolic links. KP-100-H303-021 Linker switches not relative to project directory Problem: When using switches in package Linker that include relative paths, the paths are relative to the object directory, not to the project directory as is done for gnatmake. Status: This was fixed in 1.1.0 on 2008-03-04 Workaround: Use only absolute paths. KP-100-H218-008 Wrong executable name generated Problem: When the body suffix of the main includes several dots, gprbuild does not generate the proper executable name. Status: This was fixed in 1.1.0 on 2008-02-18 Workaround: Specify the executable name in the project file. KP-100-GC29-007 Importing an externally buit library with an empty object dir Problem: Building a Stand-Alone Library that imports an externally built library where the object directory does not contain any ALI file fails. Status: This was fixed in 1.1.0 on 2007-12-29 Workaround: Copy the ALI files in the object directory. KP-100-GC29-003 SALs with capital letter names on Windows Problem: Stand-Alone Libraries with capital letters in their names are not build correctly on Windows. Status: This was fixed in 1.1.0 on 2007-12-29 Workaround: Use only library names with small letters. KP-100-GC12-012 Failure to build a library that imports other libraries Problem: When a library project imports several other library projects, gprbuild will fail to build the library. Status: This was fixed in 1.1.0 on 2007-12-16 Workaround: Reduce the number of libraries. KP-100-GC12-009 Autoconfiguration fails when object dir not present Problem: When the object dir of the main project file is not present autoconfiguration fails, even when gprbuild is called with -p. Status: This was fixed in 1.1.0 on 2007-12-18 Workaround: Create manually the object dir of the main project. gprbuild-gpl-2014-src/features-200000644000076700001450000000522012144662113016111 0ustar gnatmailgnat============================== GPRBUILD 2.0 NEW FEATURES LIST ============================== Copyright (C) 2013, AdaCore This file contains a complete list of new features in version 2.0 of GPRBUILD. A full description of all GPRBUILD features can be found in the GPRBUILD User's Guide. NF-20-M121-032 Switches --RTS for gprclean (2013-01-21) gprclean may now be called with switches --RTS= or --RTS:=. The runtimes specified with these switches are taken into account in the invocation of gprconfig in auto-configuration. This allows gprclean to have more accurate file names to delete, for example when the executable extension depends on the runtime. NF-20-LA23-043 Unconditionally create --autoconf= path (2012-10-26) gprbuild now creates unconditionally the directory of the configuration project file specified with --autoconf= when this directory does not exist. NF-20-L924-049 Add support for arbitrary runtimes for GNAT (2012-09-30) The names of the runtimes for GNAT are no longer limited to a restricted list. NF-20-L918-009 Add support for Windows resources (2012-10-03) Support for compiling Windows resources file with the binutils's windres compiler has been added. NF-20-L908-003 Add aggregate project support for gprinstall (2012-09-08) gprinstall can now be used to install aggregate projects. NF-20-L906-035 Add aggregate library project support to gprinstall (2012-09-08) gprinstall can now be used to install aggregate library projects. NF-20-L126-014 Verbosity when linking shared SALs (2012-01-26) In default mode (not verbose and not quiet), the base name of gnatbind and of the compiler when binding and compiling the binder generated file is now output, instead of the full path names. Also, when the command line is long, only the beginning is output. NF-20-KC19-034 Support for VxWorks Linux (2012-04-11) gprbuild now support VxWorks Linux targets. NF-20-K623-010 New switch --validate for gprconfig (2012-01-04) This switch can be used to validate the XML files from the gprconfig knowledge base. It should be used when you add your own XML files. NF-20-JC09-030 New package Clean in project file (2012-03-30) A new package Clean is added in project files. It can contain declarations of attributes Source_Artifact_Extensions and Object_Artifact_Extensions, that specify the extensions of files whose names are derived from source or object file names, that reside in the object directory and that are to be cleaned by gprclean. NF-20-H729-014 New tool named gprinstall (2012-05-18) A new tool named gprinstall has been implemeted and can be used to install a standard or a library project. gprbuild-gpl-2014-src/Makefile.in0000644000076700001450000001467712255333627016226 0ustar gnatmailgnatSHELL=/bin/sh INSTALL=@INSTALL@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ host=@host@ target=@target@ build=@build@ IS_WINDOWS=@is_windows@ # Relative to the gnat/ subdirectory (or absolute path) GNAT_SOURCE_DIR=../gnat_src ifeq ($(IS_WINDOWS),true) LN=cp -p EXEXT=.exe else LN=ln -s -f EXEXT= endif CP=cp -p MKDIR=mkdir -p BUILD=production prefix=@prefix@ srcdir=@srcdir@ root_objdir=@objdir@ exec_prefix=@exec_prefix@ datarootdir=@datarootdir@ datadir=@datadir@ bindir=@bindir@ libdir=@libdir@ libexecdir=@libexecdir@ docdir=${datadir}/doc/@PACKAGE_TARNAME@ # Are xmlada sources in our source tree xmlada_build_target=@xmlada_build_target@ xmlada_prj_flags=@xmlada_prj_flags@ # How do we want to use XML/Ada ? LIBRARY_TYPE=static export LIBRARY_TYPE objdir=obj ifeq ($(BUILD), debug) objdir=obj-debug endif ifeq ($(BUILD), coverage) objdir=obj-cov endif ifeq ($(BUILD), profiling) objdir=obj-prof endif dummy:=$(shell $(MKDIR) $(objdir)) PROCESSORS ?= 0 GNATMAKE=gnatmake -p -m -j${PROCESSORS} ifeq ($(strip $(filter-out %vms%,$(host))),) GNATMAKE=${GNATMAKE} -XOS=vms endif ADA_GEN_SUBDIR=gnat .PHONY: all distall gprbuild gprconfig gprclean gprinstall \ copy_gnat_src complete bootstrap all: $(xmlada_build_target) $(ADA_GEN_SUBDIR)/stamp-snames ${GNATMAKE} $(xmlada_prj_flags) -Pgprbuild -XBUILD=${BUILD} distall: make GNATMAKE="$(GNATMAKE)" BUILD="$(BUILD)" make BUILD="$(BUILD)" install if [ "$(IS_WINDOWS)" = "false" ]; then \ $(CP) $(srcdir)/doinstall $(prefix) && \ chmod a+x $(prefix)/doinstall; \ fi ifeq ($(BUILD), production) strip $(prefix)/bin/gprbuild$(EXEXT) strip $(prefix)/bin/gprclean$(EXEXT) strip $(prefix)/bin/gprconfig$(EXEXT) strip $(prefix)/bin/gprinstall$(EXEXT) strip $(prefix)/bin/gprslave$(EXEXT) strip $(prefix)/libexec/gprbuild/gprbind$(EXEXT) strip $(prefix)/libexec/gprbuild/gprlib$(EXEXT) endif all gprconfig gprbuild gprclean: $(objdir)/gprbuild_dummies.o $(objdir)/link.o force MOVE_IF_CHANGE=mv -f -include $(srcdir)/gnat/Make-generated.in copy_gnat_src: force -cd $(ADA_GEN_SUBDIR); \ $(foreach f,$(shell cat $(ADA_GEN_SUBDIR)/MANIFEST.GPRBUILD), \ $(LN) $(GNAT_SOURCE_DIR)/$(f) . ;\ ) complete: copy_gnat_src all install gprbuild: ${GNATMAKE} -Pgprbuild -XBUILD=${BUILD} gprbuild-main.adb gprinstall: ${GNATMAKE} -Pgprbuild -XBUILD=${BUILD} gprinstall-main.adb gprclean: ${GNATMAKE} -Pgprbuild -XBUILD=${BUILD} gprclean-main.adb gprconfig: ${GNATMAKE} -Pgprbuild -XBUILD=${BUILD} gprconfig-main bootstrap: gprconfig gprbuild echo echo "=== Bootstraping grpbuild" make install prefix=bootstrap/install -${MKDIR} bootstrap/${objdir} bootstrap/install/bin/gprbuild -Pgprbuild -XBUILD=${BUILD} \ -XBUILD_TOOL=gprbuild .PHONY: install clean distclean bootstrap-clean bootstrap-clean: bootstrap/install/bin/gprclean -Pgprbuild -XBUILD=${BUILD} \ -XBUILD_TOOL=gprbuild install: install.data install.bin -${MKDIR} ${datadir}/gpr $(RM) -r ${datadir}/examples/gprbuild -${MKDIR} ${datadir}/examples/gprbuild ${CP} -r examples/* ${datadir}/examples/gprbuild ${RM} -r ${datadir}/doc/gprbuild -${MKDIR} ${datadir}/doc/gprbuild for format in html txt pdf info; do \ if [ -d doc/$$format ] ; then \ ${MKDIR} ${datadir}/doc/gprbuild/$$format; \ ${CP} doc/$$format/* ${datadir}/doc/gprbuild/$$format; \ if [ $$format = html ] ; then \ ${CP} doc/*.png ${datadir}/doc/gprbuild/html; \ sed -e "s/.*//" doc/gprbuild_gps.xml \ > ${datadir}/doc/gprbuild/html/gps_index.xml; \ fi; \ fi; \ done install.data: force -${MKDIR} ${datadir}/gprconfig ${CP} share/gprconfig/*.xml ${datadir}/gprconfig ${CP} share/gprconfig/gprconfig.xsd ${datadir}/gprconfig -${MKDIR} ${datadir}/gpr ${CP} share/_default.gpr ${datadir}/gpr install.bin: force -${MKDIR} ${bindir} ${INSTALL_PROGRAM} gprconfig${EXEXT} ${bindir} ${INSTALL_PROGRAM} gprbuild${EXEXT} ${bindir} ${INSTALL_PROGRAM} gprclean${EXEXT} ${bindir} ${INSTALL_PROGRAM} gprinstall${EXEXT} ${bindir} ifeq ($(IS_WINDOWS),true) ${CP} src/gprinstall.exe.manifest ${bindir} chmod +x ${bindir}/gprinstall.exe.manifest endif ${INSTALL_PROGRAM} gprslave${EXEXT} ${bindir} -${MKDIR} ${libexecdir}/gprbuild ${INSTALL_PROGRAM} gprbind${EXEXT} ${libexecdir}/gprbuild/ ${INSTALL_PROGRAM} gprlib${EXEXT} ${libexecdir}/gprbuild/ $(objdir)/gprbuild_dummies.o: src/gprbuild_dummies.c gcc -c -o $@ $< $(objdir)/link.o: gnat/link.c gcc -c -o $@ $< .PHONY: build_xmlada build_xmlada: cd $(srcdir)/xmlada && ./configure --build=$(build) \ --prefix=$(root_objdir)/xmlada/install cd $(srcdir)/xmlada && make LIBRARY_TYPE=static static install_static clean: gnat clean -q -r -Pgprbuild distclean: gnat clean -q -r -Pgprbuild @${RM} config.log config.status src/gprconfig-sdefault.ads @${RM} Makefile @${RM} $(objdir)/* @${RM} -r bootstrap make -C doc clean make -C examples clean .PHONY: doc install-doc tests examples force doc: make -C doc install-doc: -$(MKDIR) ${docdir}/html ${CP} doc/*.html ${docdir}/html tests: force cd internal/gprtests_python; python ./run-gprconfig-test.py cd internal/gprtests_python; python ./run-gprbuild-test.py ###################### # Running tests locally # Run tests with the locally compiled gprbuild (no "make install" necessary) # You can set test_names and test_config from the command line to restrict # the tests that are run. When running all the tests, only show the failing # tests to make them more obvious. But when running a specific set of tests, # display all results. # Adds "~/.local/bin" to the PATH, in case gnatpython was installed with --user. # Adds "." to the PATH, since some of the tests expect it. ###################### test_names= test_config= ifneq (${test_config},) test_config_switch:=--config=${test_config} else test_config_switch= endif LOCAL_SETUP = cd internal/gprtests_python; PATH=${HOME}/.local/bin:${shell pwd}/install/bin:${PATH}:. LOCAL_GPRCONFIG_TEST=${LOCAL_SETUP}; python ./run-gprconfig-test.py --diffs --enable-color -j${PROCESSORS} ${test_config_switch} LOCAL_GPRBUILD_TEST=${LOCAL_SETUP}; python ./run-gprbuild-test.py --diffs --enable-color -j${PROCESSORS} ${test_config_switch} install_local: force @make prefix=${shell pwd}/install install tests_local: install_local ifeq (${test_names},) @${LOCAL_GPRCONFIG_TEST} --loglevel=ERROR @${LOCAL_GPRBUILD_TEST} --loglevel=ERROR else @${LOCAL_GPRCONFIG_TEST} --loglevel=INFO ${test_names} @${LOCAL_GPRBUILD_TEST} --loglevel=INFO ${test_names} endif examples: force make -C examples force: gprbuild-gpl-2014-src/COPYING30000644000076700001450000010451312242550044015252 0ustar gnatmailgnat GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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 3 of the License, or (at your option) any later version. This program 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 this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . gprbuild-gpl-2014-src/obj/0000755000076700001450000000000012317234553014711 5ustar gnatmailgnatgprbuild-gpl-2014-src/features-150000644000076700001450000000634011452325114016117 0ustar gnatmailgnat============================== GPRBUILD 1.5 NEW FEATURES LIST ============================== Copyright (C) 2009-2010, AdaCore This file contains a complete list of new features in version 1.5 of GPRBUILD. A full description of all GPRBUILD features can be found in the GPRBUILD User's Guide. An ISO date (YYYY-MM-DD) appears in parentheses after the description line. This date shows the implementation date of the feature. Any 1.5.0w wavefront subsequent to this date will contain the indicated feature, as will any subsequent releases. NF-15-J928-007 Indexed variables in knowledge base (2010-10-04) To avoid an ambiguity in the nodes when multiple compilers are selected, the substitution variables need to be indexed by the language of the corresponding compiler. NF-15-J915-016 No linking with GNAT libs with -nostdlib (2010-09-17) When a shared library is linked and -nostdlib is in the library options, then the GNAT libraries are not used for the link. NF-15-J614-021 New command line switch --source-info= (2010-06-29) A new command line switch is added to gprbuild, to read a source info file, instead of looking for sources. If the source info file does not exist, it is created, so that subsequent invocation of gprbuild may use it. NF-15-J614-004 Recompilation if ALI file newer than object file (2010-06-15) If the gprbuild finds that an ALI file is newer than the corresponding object file, then the corresponding source is recompiled, as the object file was not produced at the same time the ALI file was produced. NF-15-J325-005 New attributes for leading options (2010-04-12) New attributes Leading_Library_Options and Linker'Leading_Switches are added. NF-15-IC02-005 New switch -x (2009-12-07) gprbuild no longer create an include path file to the compiler, except when the new switch -x is used. This is to improve performances. NF-15-IB26-022 New switch -R (2009-11-26) gprbuid now recognizes the gnatmake switch -R. When this switch is specified, no run path option is used when linking executables and shared libraries. NF-15-IB20-033 New switch --no-object-check (2009-11-23) A new switch --no-object-check is added to gprbuild. When this switch is used, the object files are not checked, the switch files are not checked even when switch -s is used and there is no binding or linking. NF-15-IA18-001 No shared libgnat by default with C++ (2009-10-20) When Ada and C++ are used, the shared versions of the GNAT libraries are no longer used by default. However, the shared version of libgcc is always used. NF-15-I713-006 Relative paths in the run path option (2009-10-21) For platforms where the linker supports -z origin and $ORIGIN in the run path option, use paths relative to the exec directory in the run path option. NF-15-I416-017 Builder switches when there is no main (2010-06-02) When there is no main specified and there is only one compiled language in the main project, gprbuild now takes into account the builder switches for this language in package Builder of the main project. NF-15-HA09-027 Gprbuild support for GNAAMP (2010-05-07) Gprbuild has been adapted for use with GNAAMP and will now properly invoke the gnaamp compiler and related tools. gprbuild-gpl-2014-src/known-problems-2020000644000076700001450000001213312262541374017341 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 2.0.2 ======================================== Copyright (C) 2013, AdaCore The following is a listing of known problems in release 2.0.2. Except where specifically noted, all these problems have been corrected in the development tree of the 2.1 technology. This means they are corrected in any 2.1.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-202-MA30-007 Aggregated projects with same name Problem: When gprbuild is invoked with an aggregate project and some of the aggregated projects have a common name, linking some executables may fail in one or several of these aggregated projects. Status: This was fixed in 2.1 on 2013-10-30 Workaround: Use diffrent project names for the aggregated projects. KP-202-MA15-017 gprclean crashes cleaning a library project without object dir Problem: gprclean crashes with an exception when invoked to clean a library project with a specified object directory that does not exist. Status: This was fixed in 2.1 on 2013-10-15 Workaround: Make sure that all object directories exist before invoking gprclean. KP-202-MA11-007 Aggregate projects and mains with no suffix Problem: When the main project is an aggregate project, gprbuild does not recognize mains specified without suffix, including in attributes Main in aggregated projects. Status: This was fixed in 2.1 on 1013-10-11 Workaround: Use full source file names for mains. KP-202-M913-037 Several compilations of the same source with aggregated project Problem: When gprbuild is invoked with an aggregate project and the same project A belongs to several project trees rooted at the aggregated projects, sources of project A may be compiled or recompiled several times. Status: This was fixed in 2.1 on 2013-09-15 Workaround: Invoke gprbuild individually on the aggregated projects. KP-202-M910-024 None dependency kind and non empty dependency switches Problem: gprbuild may crash or behave incorrectly when the Dependency_Kind for a language is "None" and the Dependency_Switches is declared as a non empty list. Status: This was fixed in 2.1 on 2013-09-10 Workaround: Make sure that when Dependency_Kind is "None", Dependency_Switches is not declared or is declared with an empty list value, including in the configuration project file. KP-202-M903-002 Incorrect link with gprbuild -l Problem: When gprbuild is invoked with -l to link an executable and there are non Ada object files to be put in the global archive gprbuild may crash or link incorrectly the executable. Status: This was fixed in 2.1 on 2013-09-04 Workaround: Invoke gprbuild without switch -l. KP-202-M625-043 Minimal recompilation and preprocessed sources Problem: When gprbuild is invoked with -m (minimal recompilation) and a source that need preprocessing is checked for its checksum to decide if it needs to be recompiled, gprbuild may behave incorrectly, either reporting "preprocessor not active" errors or even crashing. Status: This was fixed in 2.1 on 2013-06-26 Workaround: Invoke gprbuild without switch -m. KP-202-M617-043 --single-compile-per-obj-dir in package Builder Problem: When switches --single-compile-per-obj-dir is specified in package Builder of the main project, it has no effect for simultaneous compilations. Status: This was fixed in 2.1 on 2013-08-08 Workaround: Use --single-compile-per-obj-dir on the command line. KP-202-M417-023 Deeply extended library projects Problem: When a library A project extends a project B that itself extends a project C, object files for sources that are not immediate sources of projects A or B are not included in the library file. Status: This was fixed in 2.1 on 2013-04-17 Workaround: Do not extend an already extending library project. KP-202-M116-027 aggregated projects sharing extended projects Problem: gprbuild refuses aggregate projects where several aggregated project trees share a project that is extended at least once. Status: This was fixed in 2.1 on 2013-01-18 Workaround: Do not aggregate projects that share an extended project. KP-202-KC15-051 gprconfig should not parse twice the same knowledge base Problem: gprconfig, in some circumstances, may parse several times the same knowledge base directory. This may result in an invalid configuration project file, for example the same string type may be declared several times. Status: This was fixed in 2.1 on 2013-02-04 Workaround: Avoid parsing several times the same knowledge base directory. gprbuild-gpl-2014-src/known-problems-1400000644000076700001450000000512411343556011017335 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.4.0 ======================================== Copyright (c) 2009,2010 AdaCore The following is a listing of known problems in release 1.4.0. All these problems have been corrected in the release 1.4.1 and in any wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-140-IC10-043 No switches file created when -s in Builder switches Problem: When gprbuild switch -s is specified in the Builder switches of the main project, but not on the command line, no switches fie is created, resulting in recompilation of all sources each time gprbuild is invoked. Status: This was fixed in 1.5.0 on 2009-12-10 Workaround: Specify -s on the command line. KP-140-IC09-017 Bad compilation options Problem: When there are empty compilation options, these options are replaced by random values, which may lead to compilation errors. Status: This was fixed in 1.5.0 on 2009-12-09 Workaround: Avoid empty compilation options KP-140-IC03-003 gprbind cannot bind with Binder option -C Problem: When there is an option -C in the Binder package, the binding of Ada executables fail. Status: This was fixed in 1.5.0 on 2009-12-03 Workaround: Do not specify Binder option -C. KP-140-IC02-002 Library not rebuilt when source is recompiled Problem: When in a library project a modified source is recompiled, the library is not always rebuilt. Status: This was fixed in 1.5.0 on 2009-12-02 Workaround: Invoke gprbuild twice: the library will be rebuilt for the second invocation. KP-140-IA29-033 Library built with different symbolic links Problem: When a library has been built in a setup where there are symbolic links and it is part of another setup with different or no symbolic links, gprbuild always attempts to rebuild the library. Status: This was fixed in 1.5.0 on 2009-11-04 Workaround: Always invoke gprbuild with -eL. KP-140-IA27-015 Static library built in chunks contains duplicate object files Problem: When static libraries (archives) are built in chunks and are rebuilt, they may contains duplicate object files, including old object files that should have been replaced. Status: This was fixed in 1.5.0 on 2009-10-27 Workaround: Delete the archive before rebuilding it. gprbuild-gpl-2014-src/gprbuild.gpr0000644000076700001450000001467712323721731016474 0ustar gnatmailgnatwith "xmlada"; project Gprbuild is type OS_Type is ("unix", "avms", "ivms", "Windows_NT"); OS : OS_Type := external ("OS", "unix"); type Build_Type is ("debug", "production", "coverage", "profiling"); Bld : Build_Type := external ("BUILD", "debug"); type Build_Tool_Type is ("gnatmake", "gprbuild"); Build_Tool : Build_Tool_Type := external ("BUILD_TOOL", "gnatmake"); type VCS_Type is ("Subversion", "Git", "auto"); VCS_Kind : VCS_Type := external ("PRJ_VCS", "Subversion"); Processors := external ("PROCESSORS", "1"); for Main use ("gprconfig-main.adb", "gprbuild-main.adb", "gprbind.adb", "gprlib.adb", "gprclean-main.adb", "gprinstall-main.adb", "gprslave.adb"); for Source_Dirs use ("src", "gnat"); case Build_Tool is when "gprbuild" => case Bld is when "production" => for Object_Dir use "bootstrap/obj"; when "coverage" => for Object_Dir use "bootstrap/obj-cov"; when "profiling" => for Object_Dir use "bootstrap/obj-prof"; when "debug" => for Object_Dir use "bootstrap/obj-debug"; end case; for Exec_Dir use "bootstrap"; when "gnatmake" => case Bld is when "production" => for Object_Dir use "obj"; when "coverage" => for Object_Dir use "obj-cov"; when "profiling" => for Object_Dir use "obj-prof"; when "debug" => for Object_Dir use "obj-debug"; end case; for Exec_Dir use "."; end case; case Build_Tool is when "gprbuild" => for Languages use ("Ada", "C"); when "gnatmake" => for Languages use ("Ada", "C"); -- We only build the Ada part with projects so that we do not -- have boostrap issues with gprbuild. end case; package Builder is for Executable ("gprconfig-main.adb") use "gprconfig"; for Executable ("gprbuild-main.adb") use "gprbuild"; for Executable ("gprclean-main.adb") use "gprclean"; for Executable ("gprinstall-main.adb") use "gprinstall"; for Default_Switches ("Ada") use ("-m", "-j" & Processors); for Switches ("Ada") use (); end Builder; package Compiler is common_switches := ("-gnat12", "-gnaty", "-gnatQ"); case Bld is when "debug" => for Default_Switches ("Ada") use common_switches & ("-g", "-gnata", "-gnatVa", "-gnatwaCJI" , "-gnatwe" , "-gnatyg" ); for Local_Configuration_Pragmas use "debug.adc"; when "coverage" => for Default_Switches ("Ada") use common_switches & ("-ftest-coverage", "-fprofile-arcs"); when "profiling" => for Default_Switches ("Ada") use common_switches & ("-pg", "-g"); when "production" => for Default_Switches ("Ada") use common_switches & ("-O2", "-gnatpn", "-gnatws"); end case; end Compiler; package Binder is common_switches := ("-E", "-static"); case Bld is when "debug" => for Default_Switches ("Ada") use common_switches & ("-Sin") ; when "coverage" | "profiling" | "production" => for Default_Switches ("Ada") use common_switches; end case; end Binder; package Linker is Common_Switches := (project'Object_Dir & "/gprbuild_dummies.o", project'Object_Dir & "/link.o"); -- We use project'Object_Dir here instead of GprBuild'Object_Dir -- for compatibility with GNAT Pro 6.0.2. Common_Switches_VMS := (project'Object_Dir & "/gprbuild_dummies.obj", project'Object_Dir & "/link.obj"); case Build_Tool is when "gnatmake" => -- Link manually the C part case Bld is when "production" | "debug" => case OS is when "avms" | "ivms" => for Default_Switches ("Ada") use Common_Switches_VMS; when others => for Default_Switches ("Ada") use Common_Switches; end case; when "coverage" => case OS is when "avms" | "ivms" => for Default_Switches ("Ada") use Common_Switches_VMS; when others => for Default_Switches ("Ada") use Common_Switches & ("-lgcov"); end case; when "profiling" => for Default_Switches ("Ada") use Common_Switches & ("-pg", "-g"); end case; when "gprbuild" => null; end case; end Linker; Common_Excluded_Source_Files := ("gprlib-build_shared_lib.adb", "gprlib-build_shared_lib-nosymbols.adb", "gprlib-build_shared_lib-vms.adb", "mlib-tgt-specific.adb", "mlib-tgt-vms-alpha.adb", "mlib-tgt-vms-ia64.adb"); case Build_Tool is when "gprbuild" => case OS is when "unix" | "Windows_NT" => for Locally_Removed_Files use Common_Excluded_Source_Files & ("mlib-tgt-vms.ads", "mlib-tgt-vms.adb"); -- Excluded_Source_File not supported by GNAT Pro 6.0.2 when "avms" | "ivms" => for Locally_Removed_Files use Common_Excluded_Source_Files; -- Excluded_Source_File not supported by GNAT Pro 6.0.2 end case; when "gnatmake" => null; end case; package Naming is case OS is when "unix" | "Windows_NT" => for Body ("gprlib.build_shared_lib") use "gprlib-build_shared_lib-nosymbols.adb"; for Body ("mlib.tgt.specific") use "mlib-tgt-specific.adb"; when "avms" => for Body ("gprlib.build_shared_lib") use "gprlib-build_shared_lib-vms.adb"; for Body ("mlib.tgt.specific") use "mlib-tgt-specific-vms-alpha.adb"; when "ivms" => for Body ("gprlib.build_shared_lib") use "gprlib-build_shared_lib-vms.adb"; for Body ("mlib.tgt.specific") use "mlib-tgt-specific-vms-ia64.adb"; end case; end Naming; package IDE is for VCS_Kind use VCS_Kind; end IDE; end Gprbuild; gprbuild-gpl-2014-src/obj-cov/0000755000076700001450000000000012317234553015476 5ustar gnatmailgnatgprbuild-gpl-2014-src/install-sh0000755000076700001450000001124510517620563016146 0ustar gnatmailgnat#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 gprbuild-gpl-2014-src/README0000644000076700001450000000605012313645070015014 0ustar gnatmailgnatPreliminary note for Windows users ================================== The build instructions for gprbuild may have a slight UNIX flavor but they can be used on Windows platforms with a full CYGWIN installation. The latter makes it simpler to build gprbuild but is not required to use it. Configuring =========== Configuring is usually done simply as: ./configure Two parameters may be worth specifying: --prefix for specifying the installation root and --build for specifying the build host. In particular, on Windows, when using cygwin to build, it is necessary to configure with --build=i686-pc-mingw32 if one wants to use 32 bit mingw based compilers such as GNAT Pro or GNAT GPL, and with --build=x86_64-pc-mingw32 for 64 bit compilers. Here are examples of such commands: ./configure --build=i686-pc-mingw32 --prefix=$HOME/local ./configure --build=x86_64-pc-mingw32 --prefix=$HOME/local Using alternate GNAT Sources ============================ Gprbuild uses some sources of the GNAT package. They are expected by default to be located in the gnat/ subdirectory of Gprbuild. Only some of the GNAT sources are required, but note that having all of the GNAT sources present in the gnat/ subdirectory will result in build failure. In order to use GNAT sources from another location, create a link named gnat_src and call the Makefile target copy_gnat_src: ln -s gnat_src make copy_gnat_src That will place links into the gnat/ subdirectory for each of the required GNAT source files. On Windows with Cygwin, the files must be copied because symbolic links do not work. The definition of GNAT_SOURCE_DIR in the Makefile needs to be modified so that it specifies the path to the GNAT sources. For example: GNAT_SOURCE_DIR=$(HOME)/gnat Then call the Makefile target copy_gnat_src: make copy_gnat_src The Makefile will recognize the use of Windows and will therefore place a copy of the required files into the gnat/ subdirectory. Alternatively you can specify GNAT_SOURCE_DIR on the command line when invoking the makefile target: make copy_gnat_src GNAT_SOURCE_DIR= Note that target "copy_gnat_src" is invoked automatically by target "complete". Building and Installing ======================= XML/Ada must be installed before building. Building the main executables is done simply with make all When compiling, you can choose whether you want to link statically with XML/Ada (the default), or dynamically. To compile dynamically, you should run make LIBRARY_TYPE=relocatable all instead of the above. Installation is done with make install Doc & Examples ============== The documention is provided in various formats in the doc subdirectory. It refers to concrete examples that are to be found in the examples subdirectory. Each example can be built easily using the simple attached Makefile: make all # build the example make run # run the executable(s) make clean # cleanup All the examples can be built/run/cleaned using the same targets and the toplevel examples Makefile. gprbuild-gpl-2014-src/features-220000644000076700001450000000443612313013502016111 0ustar gnatmailgnat============================== GPRBUILD 2.2 NEW FEATURES LIST ============================== Copyright (C) 2013-2014, AdaCore This file contains a complete list of new features in version 2.2 of GPRBUILD. A full description of all GPRBUILD features can be found in the GPRBUILD User's Guide. NF-22-N321-014 Add support for LLVM C compiler (2014-03-21) This adds support for compiling and linking with the LLVM C compiler (clang). NF-22-N310-033 Display slaves name for remote compilation errors (2014-03-15) When a remote compilation fails we now display on which remote computer this compilation was conducted. This can helps finding remote computers with incorrect setup for example. NF-22-N206-046 Advice to use --help for incorrectly invoked tools (2014-02-10) When a gpr tool (gprbuild, gprconfig, gprclean or gprinstall) is incorrectly invoked, with at least one argument, the usage will no longer be displayed. Instead this line will be displayed: type "gprxxx --help" for more information. NF-22-N130-015 Check distributed build consistency (2014-02-03) A check is now done to ensure that build slaves, used on a distributed compilation farm, are all of the same version as the build master. NF-22-N121-005 Check for clock drift in distributed mode (2014-01-29) A clock check is done between the slaves and the build master before starting a distributed compilation. A warning is issued if a clock drift is detected. It is important to have the clock properly synchronized to avoid unneeded recompilation. NF-22-N115-029 GPRinstall supports listing of installed packages (2014-03-13) A new mode, enabled with the option --list, can be used in GPRinstall to display the installed packages. Used with --stat a set of statistics are also displayed like the number of installed files and the total size on disk. NF-22-N108-032 Add support for grouping installs with gprinstall (2014-01-22) A new option named --install-name can be used to group installations under a single name. It makes it possible to uninstall with a single command the multiple installations. This can be handy when a library comes with some tools for example, both built with different projects files. Yet, the library and the executables are tightly related and part of the same application. gprbuild-gpl-2014-src/known-problems-2010000644000076700001450000000157212150651123017333 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 2.0.1 ======================================== Copyright (C) 2013, AdaCore The following is a listing of known problems in release 2.0.1. Except where specifically noted, all these problems have been corrected in the development tree of the 2.1 technology. This means they are corrected in any 2.1.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-201-M125-039 Library version on IA64 HP-UX Problem: On IA64 HP-UX, gprbuild fails to build a shared library when attribute Library_Version is declared. Status: This was fixed in 2.1 on 2013-01-25 This was fixed in 2.0.2 on 2013-05-27 Workaround: Do not specify Library_Version. gprbuild-gpl-2014-src/known-problems-1600000644000076700001450000000232012032613023017323 0ustar gnatmailgnat======================================== Known problems in GPRBUILD version 1.6.0 ======================================== Copyright (C) 2011-2012, AdaCore The following is a listing of known problems in release 1.6.0. Except where specifically noted, all these problems have been corrected in the development tree of the 2.0 technology. This means they are corrected in any 1.7.0w/2.0.0w wavefront issued subsequent to the date specified (in ISO format YYYY-MM-DD) in the status line. This can be used to determine if a given wavefront has the fix identified in the entry. KP-160-K917-002 Ignore compilers when variables cannot be computed Problem: In gprconfig, if a compiler description includes the computation of extra variables (like "gcc_version" for GNAT) and this variable cannot be computed, the compiler should simply be ignored. Instead, gprconfig stops working. In particular, gprconfig failed if a .NET compiler for Ada was installed on the machine. Status: This was fixed in 1.6.1 on 2011-10-24 Workaround: Use the command line switches to specify the compilers to use, rather than let gprconfig auto-detect them. gprbuild-gpl-2014-src/doinstall0000755000076700001450000000616011765654220016064 0ustar gnatmailgnat#!/bin/sh prefix='' has_gnatpro=n machine='' ggd_prefix='' if [ "x$ggd_prefix" = "x" ]; then ggd_prog="gnatmake" else ggd_prog="$ggd_prefix-gnatmake" fi if type $ggd_prog > /dev/null 2>&1 && $ggd_prog -v 2>&1 | grep GNATMAKE | grep -q Pro; then has_gnatpro=y prefix=`type $ggd_prog | cut -d' ' -f3 | sed 's%/bin.*$%%'` machine=`$prefix/bin/gcc -dumpmachine || true` fi gprbuild="gprbuild" clear cat << EOF This script is provided to simplify the installation of the $machine binary distribution of $gprbuild - the multi languages project builder. For information on commercial support, please contact sales@adacore.com. This script will ask a few questions regarding the $gprbuild installation. Confirmation is required before any write action is taken. Please press RETURN to continue. EOF read x # --------------------- Select installation option -------------------- clear cat << EOF There are 2 options for installation: EOF if [ "$has_gnatpro" = "y" ]; then cat <"), the attribute is not taken into account. Status: This was fixed in 1.6.0 on 2011-02-28 Workaround: Use language names in lower case. KP-151-K223-005 Bad handling of pragmas Linker_Options and Link_With Problem: On Windows, the stack for executables with tasking is incorrectly specified to the linker. Status: This was fixed in 1.6.0 on 2011-02-24 Workaround: Use gnatmake instead of gprbuild for linking. KP-151-K209-050 Crash when main is an excluded file Problem: When one of the main is also an excluded source file, gprbuild crashes when attempting to check if the main needs to be compiled. Status: This was fixed in 1.6.0 on 2011-02-10 Workaround: Remove the main from the list of excluded source files. KP-151-K125-041 No binding of locally removed sources Problem: When the main is not in Ada and there are no Roots specified, an attempt is made to bind locally removed Ada sources, resulting in a gprbuild crash. Status: This was fixed in 1.5.2 on 2011-02-02 Workaround: Remove the sources instead of declaring them locally removed. KP-151-JC23-006 Link time error on big projects with powerpc-elf Problem: When linking projects with a sufficiently big number of units the link phase fails with missing symbol errors. This is a command line limitation error when gprbuild calls the linker. Status: This was fixed in 1.6.0 on 2011-03-16 Workaround: force the use of a response file by using the following attributes in package Linker: for Max_Command_Line_Length use "8000"; for Response_File_Format use "GNU"; gprbuild-gpl-2014-src/debug.adc0000755000076700001450000000003312323721731015671 0ustar gnatmailgnatpragma Initialize_Scalars; gprbuild-gpl-2014-src/features-110000644000076700001450000000475511001654624016124 0ustar gnatmailgnat========================================================= GPRBUILD 1.1 NEW FEATURES LIST Current as of Mar 04, 2008 ========================================================= Copyright (c) 2008, AdaCore This file contains a complete list of new features in version 1.1 of GPRBUILD. A full description of all GPRBUILD features can be found in the GPRBUILD User's Guide. An ISO date (YYYY-MM-DD) appears in parentheses after the description line. This date shows the implementation date of the feature. Any 1.1.0w wavefront subsequent to this date will contain the indicated feature, as will any subsequent releases. NF-11-H402-020 Static lib projects may import standard projects (2008-04-02) The restriction that static library projects could only import library projects has been lifted. Shared library projects are still allowed to import only shared library projects. NF-11-H324-006 Restricted imports of sources (2008-04-01) New functionalities have been added to restrict the set of sources or header files that can be inported: - switch --direct-import-only forbid sources of a projects to imports sources or header files of a project that is not directly withed. - attribute Interfaces lists the sources and header files that are allowed to be imported from sources of an importing project. NF-11-H312-002 Languages with no compilers (2008-03-12) When the Compiler'Driver for a language is specified as the empty string, gprbuild is silently ignoring all of it sources. This is tru, by default, for language "Project File", when using automatic configuration. NF-11-H226-001 All lib projects may import project without sources (2008-02-26) All library projects, including shared library projects, are allowed to import projects without any sources, even when this is not declared explicitly. NF-11-H212-018 New attribute Inherit_Source_Path (2008-02-13) A new attribute Inherit_Source_Path allows sources of a language to import source or header file from another language. Example: for Inherit_Source_Path ("C++") use ("C"); allows C++ sources to be compiled with a source search path that include all source directories of imported projects with C declared as a language. NF-11-H117-025 Unrecognized gprbuild switches passed to compiler (2008-01-19) When gprbuild takes into account attribute Builder'Default_Switches () any switch it does not recognizes is passed to the compiler of language for all sources of language in all projects. gprbuild-gpl-2014-src/gnat/0000755000076700001450000000000012323721724015066 5ustar gnatmailgnatgprbuild-gpl-2014-src/gnat/xsnamest.adb0000644000076700001450000002377012323721731017407 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT SYSTEM UTILITIES -- -- -- -- X S N A M E S T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This utility is used to make a new version of the Snames package when new -- names are added. This version reads a template file from snames.ads-tmpl in -- which the numbers are all written as $, and generates a new version of the -- spec file snames.ads (written to snames.ns). It also reads snames.adb-tmpl -- and generates an updated body (written to snames.nb), and snames.h-tmpl and -- generates an updated C header file (written to snames.nh). with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO; with Ada.Strings.Maps; use Ada.Strings.Maps; with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants; with Ada.Text_IO; use Ada.Text_IO; with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO; with GNAT.Spitbol; use GNAT.Spitbol; with GNAT.Spitbol.Patterns; use GNAT.Spitbol.Patterns; with XUtil; use XUtil; procedure XSnamesT is subtype VString is GNAT.Spitbol.VString; InS : Ada.Text_IO.File_Type; InB : Ada.Text_IO.File_Type; InH : Ada.Text_IO.File_Type; OutS : Ada.Streams.Stream_IO.File_Type; OutB : Ada.Streams.Stream_IO.File_Type; OutH : Ada.Streams.Stream_IO.File_Type; A, B : VString := Nul; Line : VString := Nul; Name0 : VString := Nul; Name1 : VString := Nul; Oval : VString := Nul; Restl : VString := Nul; Name_Ref : constant Pattern := Span (' ') * A & Break (' ') * Name0 & Span (' ') * B & ": constant Name_Id := N + $;" & Rest * Restl; Get_Name : constant Pattern := "Name_" & Rest * Name1; Chk_Low : constant Pattern := Pos (0) & Any (Lower_Set) & Rest & Pos (1); Findu : constant Pattern := Span ('u') * A; Val : Natural; Xlate_U_Und : constant Character_Mapping := To_Mapping ("u", "_"); M : Match_Result; type Header_Symbol is (None, Name, Attr, Conv, Prag); -- A symbol in the header file procedure Output_Header_Line (S : Header_Symbol); -- Output header line Header_Name : aliased String := "Name"; Header_Attr : aliased String := "Attr"; Header_Conv : aliased String := "Convention"; Header_Prag : aliased String := "Pragma"; -- Prefixes used in the header file type String_Ptr is access all String; Header_Prefix : constant array (Header_Symbol) of String_Ptr := (null, Header_Name'Access, Header_Attr'Access, Header_Conv'Access, Header_Prag'Access); -- Patterns used in the spec file Get_Attr : constant Pattern := Span (' ') & "Attribute_" & Break (",)") * Name1; Get_Conv : constant Pattern := Span (' ') & "Convention_" & Break (",)") * Name1; Get_Prag : constant Pattern := Span (' ') & "Pragma_" & Break (",)") * Name1; type Header_Symbol_Counter is array (Header_Symbol) of Natural; Header_Counter : Header_Symbol_Counter := (0, 0, 0, 0, 0); Header_Current_Symbol : Header_Symbol := None; Header_Pending_Line : VString := Nul; ------------------------ -- Output_Header_Line -- ------------------------ procedure Output_Header_Line (S : Header_Symbol) is function Make_Value (V : Integer) return String; -- Build the definition for the current macro (Names are integers -- offset to N, while other items are enumeration values). ---------------- -- Make_Value -- ---------------- function Make_Value (V : Integer) return String is begin if S = Name then return "(First_Name_Id + 256 + " & V & ")"; else return "" & V; end if; end Make_Value; -- Start of processing for Output_Header_Line begin -- Skip all the #define for S-prefixed symbols in the header. -- Of course we are making implicit assumptions: -- (1) No newline between symbols with the same prefix. -- (2) Prefix order is the same as in snames.ads. if Header_Current_Symbol /= S then declare Name2 : VString; Pat : constant Pattern := "#define " & Header_Prefix (S).all & Break (' ') * Name2; In_Pat : Boolean := False; begin if Header_Current_Symbol /= None then Put_Line (OutH, Header_Pending_Line); end if; loop Line := Get_Line (InH); if Match (Line, Pat) then In_Pat := True; elsif In_Pat then Header_Pending_Line := Line; exit; else Put_Line (OutH, Line); end if; end loop; Header_Current_Symbol := S; end; end if; -- Now output the line -- Note that we must ensure at least one space between macro name and -- parens, otherwise the parenthesized value gets treated as an argument -- specification. Put_Line (OutH, "#define " & Header_Prefix (S).all & "_" & Name1 & (30 - Natural'Min (29, Length (Name1))) * ' ' & Make_Value (Header_Counter (S))); Header_Counter (S) := Header_Counter (S) + 1; end Output_Header_Line; -- Start of processing for XSnames begin Open (InS, In_File, "snames.ads-tmpl"); Open (InB, In_File, "snames.adb-tmpl"); Open (InH, In_File, "snames.h-tmpl"); -- Note that we do not generate snames.{ads,adb,h} directly. Instead -- we output them to snames.n{s,b,h} so that Makefiles can use -- move-if-change to not touch previously generated files if the -- new ones are identical. Create (OutS, Out_File, "snames.ns"); Create (OutB, Out_File, "snames.nb"); Create (OutH, Out_File, "snames.nh"); Put_Line (OutH, "#ifdef __cplusplus"); Put_Line (OutH, "extern ""C"" {"); Put_Line (OutH, "#endif"); Anchored_Mode := True; Val := 0; loop Line := Get_Line (InB); exit when Match (Line, " Preset_Names"); Put_Line (OutB, Line); end loop; Put_Line (OutB, Line); LoopN : while not End_Of_File (InS) loop Line := Get_Line (InS); if not Match (Line, Name_Ref) then Put_Line (OutS, Line); if Match (Line, Get_Attr) then Output_Header_Line (Attr); elsif Match (Line, Get_Conv) then Output_Header_Line (Conv); elsif Match (Line, Get_Prag) then Output_Header_Line (Prag); end if; else if Match (Name0, "Last_") then Oval := Lpad (V (Val - 1), 3, '0'); else Oval := Lpad (V (Val), 3, '0'); end if; Put_Line (OutS, A & Name0 & B & ": constant Name_Id := N + " & Oval & ';' & Restl); if Match (Name0, Get_Name) then Name0 := Name1; Val := Val + 1; if Match (Name0, Findu, M) then Replace (M, Translate (A, Xlate_U_Und)); Translate (Name0, Lower_Case_Map); elsif not Match (Name0, "Op_", "") then Translate (Name0, Lower_Case_Map); else Name0 := 'O' & Translate (Name0, Lower_Case_Map); end if; if not Match (Name0, Chk_Low) then Put_Line (OutB, " """ & Name0 & "#"" &"); end if; Output_Header_Line (Name); end if; end if; end loop LoopN; loop Line := Get_Line (InB); exit when Match (Line, " ""#"";"); end loop; Put_Line (OutB, Line); while not End_Of_File (InB) loop Line := Get_Line (InB); Put_Line (OutB, Line); end loop; Put_Line (OutH, Header_Pending_Line); while not End_Of_File (InH) loop Line := Get_Line (InH); Put_Line (OutH, Line); end loop; Put_Line (OutH, "#ifdef __cplusplus"); Put_Line (OutH, "}"); Put_Line (OutH, "#endif"); end XSnamesT; gprbuild-gpl-2014-src/gnat/atree.ads0000644000076700001450000042054412323721731016666 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- A T R E E -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Alloc; with Sinfo; use Sinfo; with Einfo; use Einfo; with Namet; use Namet; with Types; use Types; with Snames; use Snames; with System; use System; with Table; with Uintp; use Uintp; with Urealp; use Urealp; with Unchecked_Conversion; package Atree is -- This package defines the format of the tree used to represent the Ada -- program internally. Syntactic and semantic information is combined in -- this tree. There is no separate symbol table structure. -- WARNING: There is a C version of this package. Any changes to this source -- file must be properly reflected in the C header file atree.h -- Package Atree defines the basic structure of the tree and its nodes and -- provides the basic abstract interface for manipulating the tree. Two other -- packages use this interface to define the representation of Ada programs -- using this tree format. The package Sinfo defines the basic representation -- of the syntactic structure of the program, as output by the parser. The -- package Einfo defines the semantic information which is added to the tree -- nodes that represent declared entities (i.e. the information which might -- typically be described in a separate symbol table structure). -- The front end of the compiler first parses the program and generates a -- tree that is simply a syntactic representation of the program in abstract -- syntax tree format. Subsequent processing in the front end traverses the -- tree, transforming it in various ways and adding semantic information. ---------------------- -- Size of Entities -- ---------------------- -- Currently entities are composed of 6 sequentially allocated 32-byte -- nodes, considered as a single record. The following definition gives -- the number of extension nodes. Num_Extension_Nodes : Node_Id := 5; -- This value is increased by one if debug flag -gnatd.N is set. This is -- for testing performance impact of adding a new extension node. We make -- this of type Node_Id for easy reference in loops using this value. ---------------------------------------- -- Definitions of Fields in Tree Node -- ---------------------------------------- -- The representation of the tree is completely hidden, using a functional -- interface for accessing and modifying the contents of nodes. Logically -- a node contains a number of fields, much as though the nodes were -- defined as a record type. The fields in a node are as follows: -- Nkind Indicates the kind of the node. This field is present -- in all nodes. The type is Node_Kind, which is declared -- in the package Sinfo. -- Sloc Location (Source_Ptr) of the corresponding token -- in the Source buffer. The individual node definitions -- show which token is referenced by this pointer. -- In_List A flag used to indicate if the node is a member -- of a node list. -- Rewrite_Ins A flag set if a node is marked as a rewrite inserted -- node as a result of a call to Mark_Rewrite_Insertion. -- Paren_Count A 2-bit count used in sub-expression nodes to indicate -- the level of parentheses. The settings are 0,1,2 and -- 3 for many. If the value is 3, then an auxiliary table -- is used to indicate the real value. Set to zero for -- non-subexpression nodes. -- Note: the required parentheses surrounding conditional -- and quantified expressions count as a level of parens -- for this purpose, so e.g. in X := (if A then B else C); -- Paren_Count for the right side will be 1. -- Comes_From_Source -- This flag is present in all nodes. It is set if the -- node is built by the scanner or parser, and clear if -- the node is built by the analyzer or expander. It -- indicates that the node corresponds to a construct -- that appears in the original source program. -- Analyzed This flag is present in all nodes. It is set when -- a node is analyzed, and is used to avoid analyzing -- the same node twice. Analysis includes expansion if -- expansion is active, so in this case if the flag is -- set it means the node has been analyzed and expanded. -- Error_Posted This flag is present in all nodes. It is set when -- an error message is posted which is associated with -- the flagged node. This is used to avoid posting more -- than one message on the same node. -- Field1 -- Field2 -- Field3 -- Field4 -- Field5 Five fields holding Union_Id values -- ElistN Synonym for FieldN typed as Elist_Id (Empty = No_Elist) -- ListN Synonym for FieldN typed as List_Id -- NameN Synonym for FieldN typed as Name_Id -- NodeN Synonym for FieldN typed as Node_Id -- StrN Synonym for FieldN typed as String_Id -- UintN Synonym for FieldN typed as Uint (Empty = Uint_0) -- UrealN Synonym for FieldN typed as Ureal -- Note: in the case of ElistN and UintN fields, it is common that we -- end up with a value of Union_Id'(0) as the default value. This value -- is meaningless as a Uint or Elist_Id value. We have two choices here. -- We could require that all Uint and Elist fields be initialized to an -- appropriate value, but that's error prone, since it would be easy to -- miss an initialization. So instead we have the retrieval functions -- generate an appropriate default value (Uint_0 or No_Elist). Probably -- it would be cleaner to generate No_Uint in the Uint case but we got -- stuck with representing an "unset" size value as zero early on, and -- it will take a bit of fiddling to change that ??? -- Note: the actual usage of FieldN (i.e. whether it contains a Elist_Id, -- List_Id, Name_Id, Node_Id, String_Id, Uint or Ureal) depends on the -- value in Nkind. Generally the access to this field is always via the -- functional interface, so the field names ElistN, ListN, NameN, NodeN, -- StrN, UintN and UrealN are used only in the bodies of the access -- functions (i.e. in the bodies of Sinfo and Einfo). These access -- functions contain debugging code that checks that the use is -- consistent with Nkind and Ekind values. -- However, in specialized circumstances (examples are the circuit in -- generic instantiation to copy trees, and in the tree dump routine), -- it is useful to be able to do untyped traversals, and an internal -- package in Atree allows for direct untyped accesses in such cases. -- Flag0 Nineteen Boolean flags (use depends on Nkind and -- Flag1 Ekind, as described for FieldN). Again the access -- Flag2 is usually via subprograms in Sinfo and Einfo which -- Flag3 provide high-level synonyms for these flags, and -- Flag4 contain debugging code that checks that the values -- Flag5 in Nkind and Ekind are appropriate for the access. -- Flag6 -- Flag7 -- Flag8 -- Flag9 -- Flag10 -- Flag11 Note that Flag0-3 are stored separately in the Flags -- Flag12 table, but that's a detail of the implementation which -- Flag13 is entirely hidden by the funcitonal interface. -- Flag14 -- Flag15 -- Flag16 -- Flag17 -- Flag18 -- Link For a node, points to the Parent. For a list, points -- to the list header. Note that in the latter case, a -- client cannot modify the link field. This field is -- private to the Atree package (but is also modified -- by the Nlists package). -- The following additional fields are present in extended nodes used -- for entities (Nkind in N_Entity). -- Ekind Entity type. This field indicates the type of the -- entity, it is of type Entity_Kind which is defined -- in package Einfo. -- Flag19 299 additional flags -- ... -- Flag317 -- Convention Entity convention (Convention_Id value) -- Field6 Additional Union_Id value stored in tree -- Node6 Synonym for Field6 typed as Node_Id -- Elist6 Synonym for Field6 typed as Elist_Id (Empty = No_Elist) -- Uint6 Synonym for Field6 typed as Uint (Empty = Uint_0) -- Similar definitions for Field7 to Field35 (and also Node7-Node35, -- Elist7-Elist35, Uint7-Uint35, Ureal7-Ureal35). Note that not all -- these functions are defined, only the ones that are actually used. function Last_Node_Id return Node_Id; pragma Inline (Last_Node_Id); -- Returns Id of last allocated node Id function Nodes_Address return System.Address; -- Return address of Nodes table (used in Back_End for Gigi call) function Flags_Address return System.Address; -- Return address of Flags table (used in Back_End for Gigi call) function Num_Nodes return Nat; -- Total number of nodes allocated, where an entity counts as a single -- node. This count is incremented every time a node or entity is -- allocated, and decremented every time a node or entity is deleted. -- This value is used by Xref and by Treepr to allocate hash tables of -- suitable size for hashing Node_Id values. ----------------------- -- Use of Empty Node -- ----------------------- -- The special Node_Id Empty is used to mark missing fields. Whenever the -- syntax has an optional component, then the corresponding field will be -- set to Empty if the component is missing. -- Note: Empty is not used to describe an empty list. Instead in this -- case the node field contains a list which is empty, and these cases -- should be distinguished (essentially from a type point of view, Empty -- is a Node, and is thus not a list). -- Note: Empty does in fact correspond to an allocated node. Only the -- Nkind field of this node may be referenced. It contains N_Empty, which -- uniquely identifies the empty case. This allows the Nkind field to be -- dereferenced before the check for Empty which is sometimes useful. ----------------------- -- Use of Error Node -- ----------------------- -- The Error node is used during syntactic and semantic analysis to -- indicate that the corresponding piece of syntactic structure or -- semantic meaning cannot properly be represented in the tree because -- of an illegality in the program. -- If an Error node is encountered, then you know that a previous -- illegality has been detected. The proper reaction should be to -- avoid posting related cascaded error messages, and to propagate -- the error node if necessary. ------------------------ -- Current_Error_Node -- ------------------------ -- The current error node is a global location indicating the current -- node that is being processed for the purposes of placing a compiler -- abort message. This is not necessarily perfectly accurate, it is -- just a reasonably accurate best guess. It is used to output the -- source location in the abort message by Comperr, and also to -- implement the d3 debugging flag. This is also used by Rtsfind -- to generate error messages for high integrity mode. -- There are two ways this gets set. During parsing, when new source -- nodes are being constructed by calls to New_Node and New_Entity, -- either one of these calls sets Current_Error_Node to the newly -- created node. During semantic analysis, this mechanism is not -- used, and instead Current_Error_Node is set by the subprograms in -- Debug_A that mark the start and end of analysis/expansion of a -- node in the tree. Current_Error_Node : Node_Id; -- Node to place error messages ------------------ -- Error Counts -- ------------------ -- The following variables denote the count of errors of various kinds -- detected in the tree. Note that these might be more logically located -- in Err_Vars, but we put it to deal with licensing issues (we need this -- to have the GPL exception licensing, since Check_Error_Detected can -- be called from units with this licensing). Serious_Errors_Detected : Nat := 0; -- This is a count of errors that are serious enough to stop expansion, -- and hence to prevent generation of an object file even if the -- switch -gnatQ is set. Initialized to zero at the start of compilation. -- Initialized for -gnatVa use, see comment above. Total_Errors_Detected : Nat := 0; -- Number of errors detected so far. Includes count of serious errors and -- non-serious errors, so this value is always greater than or equal to the -- Serious_Errors_Detected value. Initialized to zero at the start of -- compilation. Initialized for -gnatVa use, see comment above. Warnings_Detected : Nat := 0; -- Number of warnings detected. Initialized to zero at the start of -- compilation. Initialized for -gnatVa use, see comment above. Warnings_Treated_As_Errors : Nat := 0; -- Number of warnings changed into errors as a result of matching a pattern -- given in a Warning_As_Error configuration pragma. Configurable_Run_Time_Violations : Nat := 0; -- Count of configurable run time violations so far. This is used to -- suppress certain cascaded error messages when we know that we may not -- have fully expanded some items, due to high integrity violations (e.g. -- the use of constructs not permitted by the library in use, or improper -- constructs in No_Run_Time mode). procedure Check_Error_Detected; -- When an anomaly is found in the tree, many semantic routines silently -- bail out, assuming that the anomaly was caused by a previously detected -- serious error (or configurable run time violation). This routine should -- be called in these cases, and will raise an exception if no such error -- has been detected. This ensure that the anomaly is never allowed to go -- unnoticed. ------------------------------- -- Default Setting of Fields -- ------------------------------- -- Nkind is set to N_Unused_At_Start -- Ekind is set to E_Void -- Sloc is always set, there is no default value -- Field1-5 fields are set to Empty -- Field6-35 fields in extended nodes are set to Empty -- Parent is set to Empty -- All Boolean flag fields are set to False -- Note: the value Empty is used in Field1-Field35 to indicate a null node. -- The usage varies. The common uses are to indicate absence of an optional -- clause or a completely unused Field1-35 field. ------------------------------------- -- Use of Synonyms for Node Fields -- ------------------------------------- -- A subpackage Atree.Unchecked_Access provides routines for reading and -- writing the fields defined above (Field1-35, Node1-35, Flag0-317 etc). -- These unchecked access routines can be used for untyped traversals. -- In addition they are used in the implementations of the Sinfo and -- Einfo packages. These packages both provide logical synonyms for -- the generic fields, together with an appropriate set of access routines. -- Normally access to information within tree nodes uses these synonyms, -- providing a high level typed interface to the tree information. -------------------------------------------------- -- Node Allocation and Modification Subprograms -- -------------------------------------------------- -- Generally the parser builds the tree and then it is further decorated -- (e.g. by setting the entity fields), but not fundamentally modified. -- However, there are cases in which the tree must be restructured by -- adding and rearranging nodes, as a result of disambiguating cases -- which the parser could not parse correctly, and adding additional -- semantic information (e.g. making constraint checks explicit). The -- following subprograms are used for constructing the tree in the first -- place, and then for subsequent modifications as required. procedure Initialize; -- Called at the start of compilation to initialize the allocation of -- the node and list tables and make the standard entries for Empty, -- Error and Error_List. Note that Initialize must not be called if -- Tree_Read is used. procedure Lock; -- Called before the back end is invoked to lock the nodes table -- Also called after Unlock to relock??? procedure Unlock; -- Unlocks nodes table, in cases where the back end needs to modify it procedure Tree_Read; -- Initializes internal tables from current tree file using the relevant -- Table.Tree_Read routines. Note that Initialize should not be called if -- Tree_Read is used. Tree_Read includes all necessary initialization. procedure Tree_Write; -- Writes out internal tables to current tree file using the relevant -- Table.Tree_Write routines. function New_Node (New_Node_Kind : Node_Kind; New_Sloc : Source_Ptr) return Node_Id; -- Allocates a completely new node with the given node type and source -- location values. All other fields are set to their standard defaults: -- -- Empty for all FieldN fields -- False for all FlagN fields -- -- The usual approach is to build a new node using this function and -- then, using the value returned, use the Set_xxx functions to set -- fields of the node as required. New_Node can only be used for -- non-entity nodes, i.e. it never generates an extended node. -- -- If we are currently parsing, as indicated by a previous call to -- Set_Comes_From_Source_Default (True), then this call also resets -- the value of Current_Error_Node. function New_Entity (New_Node_Kind : Node_Kind; New_Sloc : Source_Ptr) return Entity_Id; -- Similar to New_Node, except that it is used only for entity nodes -- and returns an extended node. procedure Set_Comes_From_Source_Default (Default : Boolean); -- Sets value of Comes_From_Source flag to be used in all subsequent -- New_Node and New_Entity calls until another call to this procedure -- changes the default. This value is set True during parsing and -- False during semantic analysis. This is also used to determine -- if New_Node and New_Entity should set Current_Error_Node. function Get_Comes_From_Source_Default return Boolean; pragma Inline (Get_Comes_From_Source_Default); -- Gets the current value of the Comes_From_Source flag procedure Preserve_Comes_From_Source (NewN, OldN : Node_Id); pragma Inline (Preserve_Comes_From_Source); -- When a node is rewritten, it is sometimes appropriate to preserve the -- original comes from source indication. This is true when the rewrite -- essentially corresponds to a transformation corresponding exactly to -- semantics in the reference manual. This procedure copies the setting -- of Comes_From_Source from OldN to NewN. function Has_Extension (N : Node_Id) return Boolean; pragma Inline (Has_Extension); -- Returns True if the given node has an extension (i.e. was created by -- a call to New_Entity rather than New_Node, and Nkind is in N_Entity) procedure Change_Node (N : Node_Id; New_Node_Kind : Node_Kind); -- This procedure replaces the given node by setting its Nkind field to -- the indicated value and resetting all other fields to their default -- values except for Sloc, which is unchanged, and the Parent pointer -- and list links, which are also unchanged. All other information in -- the original node is lost. The new node has an extension if the -- original node had an extension. procedure Copy_Node (Source : Node_Id; Destination : Node_Id); -- Copy the entire contents of the source node to the destination node. -- The contents of the source node is not affected. If the source node -- has an extension, then the destination must have an extension also. -- The parent pointer of the destination and its list link, if any, are -- not affected by the copy. Note that parent pointers of descendents -- are not adjusted, so the descendents of the destination node after -- the Copy_Node is completed have dubious parent pointers. Note that -- this routine does NOT copy aspect specifications, the Has_Aspects -- flag in the returned node will always be False. The caller must deal -- with copying aspect specifications where this is required. function New_Copy (Source : Node_Id) return Node_Id; -- This function allocates a completely new node, and then initializes -- it by copying the contents of the source node into it. The contents of -- the source node is not affected. The target node is always marked as -- not being in a list (even if the source is a list member), and not -- overloaded. The new node will have an extension if the source has -- an extension. New_Copy (Empty) returns Empty, and New_Copy (Error) -- returns Error. Note that, unlike Copy_Separate_Tree, New_Copy does not -- recursively copy any descendents, so in general parent pointers are not -- set correctly for the descendents of the copied node. Both normal and -- extended nodes (entities) may be copied using New_Copy. function Relocate_Node (Source : Node_Id) return Node_Id; -- Source is a non-entity node that is to be relocated. A new node is -- allocated, and the contents of Source are copied to this node, using -- New_Copy. The parent pointers of descendents of the node are then -- adjusted to point to the relocated copy. The original node is not -- modified, but the parent pointers of its descendents are no longer -- valid. The new copy is always marked as not overloaded. This routine is -- used in conjunction with the tree rewrite routines (see descriptions of -- Replace/Rewrite). -- -- Note that the resulting node has the same parent as the source node, and -- is thus still attached to the tree. It is valid for Source to be Empty, -- in which case Relocate_Node simply returns Empty as the result. function Copy_Separate_Tree (Source : Node_Id) return Node_Id; -- Given a node that is the root of a subtree, Copy_Separate_Tree copies -- the entire syntactic subtree, including recursively any descendants -- whose parent field references a copied node (descendants not linked to -- a copied node by the parent field are also copied.) The parent pointers -- in the copy are properly set. Copy_Separate_Tree (Empty/Error) returns -- Empty/Error. The new subtree does not share entities with the source, -- but has new entities with the same name. -- -- Most of the time this routine is called on an unanalyzed tree, and no -- semantic information is copied. However, to ensure that no entities -- are shared between the two when the source is already analyzed, and -- that the result looks like an unanalyzed tree from the parser, Entity -- fields and Etype fields are set to Empty, and Analyzed flags set False. -- -- In addition, Expanded_Name nodes are converted back into the original -- parser form (where they are Selected_Components), so that reanalysis -- does the right thing. function Copy_Separate_List (Source : List_Id) return List_Id; -- Applies Copy_Separate_Tree to each element of the Source list, returning -- a new list of the results of these copy operations. procedure Exchange_Entities (E1 : Entity_Id; E2 : Entity_Id); -- Exchange the contents of two entities. The parent pointers are switched -- as well as the Defining_Identifier fields in the parents, so that the -- entities point correctly to their original parents. The effect is thus -- to leave the tree completely unchanged in structure, except that the -- entity ID values of the two entities are interchanged. Neither of the -- two entities may be list members. Note that entities appear on two -- semantic chains: Homonym and Next_Entity: the corresponding links must -- be adjusted by the caller, according to context. function Extend_Node (Node : Node_Id) return Entity_Id; -- This function returns a copy of its input node with an extension added. -- The fields of the extension are set to Empty. Due to the way extensions -- are handled (as four consecutive array elements), it may be necessary -- to reallocate the node, so that the returned value is not the same as -- the input value, but where possible the returned value will be the same -- as the input value (i.e. the extension will occur in place). It is the -- caller's responsibility to ensure that any pointers to the original node -- are appropriately updated. This function is used only by Sinfo.CN to -- change nodes into their corresponding entities. type Report_Proc is access procedure (Target : Node_Id; Source : Node_Id); procedure Set_Reporting_Proc (P : Report_Proc); -- Register a procedure that is invoked when a node is allocated, replaced -- or rewritten. type Traverse_Result is (Abandon, OK, OK_Orig, Skip); -- This is the type of the result returned by the Process function passed -- to Traverse_Func and Traverse_Proc. See below for details. subtype Traverse_Final_Result is Traverse_Result range Abandon .. OK; -- This is the type of the final result returned Traverse_Func, based on -- the results of Process calls. See below for details. generic with function Process (N : Node_Id) return Traverse_Result is <>; function Traverse_Func (Node : Node_Id) return Traverse_Final_Result; -- This is a generic function that, given the parent node for a subtree, -- traverses all syntactic nodes of this tree, calling the given function -- Process on each one, in pre order (i.e. top-down). The order of -- traversing subtrees is arbitrary. The traversal is controlled as follows -- by the result returned by Process: -- OK The traversal continues normally with the syntactic -- children of the node just processed. -- OK_Orig The traversal continues normally with the syntactic -- children of the original node of the node just processed. -- Skip The children of the node just processed are skipped and -- excluded from the traversal, but otherwise processing -- continues elsewhere in the tree. -- Abandon The entire traversal is immediately abandoned, and the -- original call to Traverse returns Abandon. -- The result returned by Traverse is Abandon if processing was terminated -- by a call to Process returning Abandon, otherwise it is OK (meaning that -- all calls to process returned either OK, OK_Orig, or Skip). generic with function Process (N : Node_Id) return Traverse_Result is <>; procedure Traverse_Proc (Node : Node_Id); pragma Inline (Traverse_Proc); -- This is the same as Traverse_Func except that no result is returned, -- i.e. Traverse_Func is called and the result is simply discarded. --------------------------- -- Node Access Functions -- --------------------------- -- The following functions return the contents of the indicated field of -- the node referenced by the argument, which is a Node_Id. function Nkind (N : Node_Id) return Node_Kind; pragma Inline (Nkind); function Analyzed (N : Node_Id) return Boolean; pragma Inline (Analyzed); function Has_Aspects (N : Node_Id) return Boolean; pragma Inline (Has_Aspects); function Comes_From_Source (N : Node_Id) return Boolean; pragma Inline (Comes_From_Source); function Error_Posted (N : Node_Id) return Boolean; pragma Inline (Error_Posted); function Sloc (N : Node_Id) return Source_Ptr; pragma Inline (Sloc); function Paren_Count (N : Node_Id) return Nat; pragma Inline (Paren_Count); function Parent (N : Node_Id) return Node_Id; pragma Inline (Parent); -- Returns the parent of a node if the node is not a list member, or else -- the parent of the list containing the node if the node is a list member. function No (N : Node_Id) return Boolean; pragma Inline (No); -- Tests given Id for equality with the Empty node. This allows notations -- like "if No (Variant_Part)" as opposed to "if Variant_Part = Empty". function Present (N : Node_Id) return Boolean; pragma Inline (Present); -- Tests given Id for inequality with the Empty node. This allows notations -- like "if Present (Statement)" as opposed to "if Statement /= Empty". --------------------- -- Node_Kind Tests -- --------------------- -- These are like the functions in Sinfo, but the first argument is a -- Node_Id, and the tested field is Nkind (N). function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind) return Boolean; function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind; V3 : Node_Kind) return Boolean; function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind; V3 : Node_Kind; V4 : Node_Kind) return Boolean; function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind; V3 : Node_Kind; V4 : Node_Kind; V5 : Node_Kind) return Boolean; function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind; V3 : Node_Kind; V4 : Node_Kind; V5 : Node_Kind; V6 : Node_Kind) return Boolean; function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind; V3 : Node_Kind; V4 : Node_Kind; V5 : Node_Kind; V6 : Node_Kind; V7 : Node_Kind) return Boolean; function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind; V3 : Node_Kind; V4 : Node_Kind; V5 : Node_Kind; V6 : Node_Kind; V7 : Node_Kind; V8 : Node_Kind) return Boolean; function Nkind_In (N : Node_Id; V1 : Node_Kind; V2 : Node_Kind; V3 : Node_Kind; V4 : Node_Kind; V5 : Node_Kind; V6 : Node_Kind; V7 : Node_Kind; V8 : Node_Kind; V9 : Node_Kind) return Boolean; pragma Inline (Nkind_In); -- Inline all above functions ----------------------- -- Entity_Kind_Tests -- ----------------------- -- Utility functions to test whether an Entity_Kind value, either given -- directly as the first argument, or the Ekind field of an Entity give -- as the first argument, matches any of the given list of Entity_Kind -- values. Return True if any match, False if no match. function Ekind_In (E : Entity_Id; V1 : Entity_Kind; V2 : Entity_Kind) return Boolean; function Ekind_In (E : Entity_Id; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind) return Boolean; function Ekind_In (E : Entity_Id; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind) return Boolean; function Ekind_In (E : Entity_Id; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind) return Boolean; function Ekind_In (E : Entity_Id; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind; V6 : Entity_Kind) return Boolean; function Ekind_In (E : Entity_Id; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind; V6 : Entity_Kind; V7 : Entity_Kind) return Boolean; function Ekind_In (E : Entity_Id; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind; V6 : Entity_Kind; V7 : Entity_Kind; V8 : Entity_Kind) return Boolean; function Ekind_In (T : Entity_Kind; V1 : Entity_Kind; V2 : Entity_Kind) return Boolean; function Ekind_In (T : Entity_Kind; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind) return Boolean; function Ekind_In (T : Entity_Kind; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind) return Boolean; function Ekind_In (T : Entity_Kind; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind) return Boolean; function Ekind_In (T : Entity_Kind; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind; V6 : Entity_Kind) return Boolean; function Ekind_In (T : Entity_Kind; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind; V6 : Entity_Kind; V7 : Entity_Kind) return Boolean; function Ekind_In (T : Entity_Kind; V1 : Entity_Kind; V2 : Entity_Kind; V3 : Entity_Kind; V4 : Entity_Kind; V5 : Entity_Kind; V6 : Entity_Kind; V7 : Entity_Kind; V8 : Entity_Kind) return Boolean; pragma Inline (Ekind_In); -- Inline all above functions ----------------------------- -- Entity Access Functions -- ----------------------------- -- The following functions apply only to Entity_Id values, i.e. -- to extended nodes. function Ekind (E : Entity_Id) return Entity_Kind; pragma Inline (Ekind); function Convention (E : Entity_Id) return Convention_Id; pragma Inline (Convention); ---------------------------- -- Node Update Procedures -- ---------------------------- -- The following functions set a specified field in the node whose Id is -- passed as the first argument. The second parameter is the new value -- to be set in the specified field. Note that Set_Nkind is in the next -- section, since its use is restricted. procedure Set_Sloc (N : Node_Id; Val : Source_Ptr); pragma Inline (Set_Sloc); procedure Set_Paren_Count (N : Node_Id; Val : Nat); pragma Inline (Set_Paren_Count); procedure Set_Parent (N : Node_Id; Val : Node_Id); pragma Inline (Set_Parent); procedure Set_Analyzed (N : Node_Id; Val : Boolean := True); pragma Inline (Set_Analyzed); procedure Set_Error_Posted (N : Node_Id; Val : Boolean := True); pragma Inline (Set_Error_Posted); procedure Set_Comes_From_Source (N : Node_Id; Val : Boolean); pragma Inline (Set_Comes_From_Source); -- Note that this routine is very rarely used, since usually the -- default mechanism provided sets the right value, but in some -- unusual cases, the value needs to be reset (e.g. when a source -- node is copied, and the copy must not have Comes_From_Source set). procedure Set_Has_Aspects (N : Node_Id; Val : Boolean := True); pragma Inline (Set_Has_Aspects); procedure Set_Original_Node (N : Node_Id; Val : Node_Id); pragma Inline (Set_Original_Node); -- Note that this routine is used only in very peculiar cases. In normal -- cases, the Original_Node link is set by calls to Rewrite. We currently -- use it in ASIS mode to manually set the link from pragma expressions -- to their aspect original source expressions, so that the original source -- expressions accessed by ASIS are also semantically analyzed. ------------------------------ -- Entity Update Procedures -- ------------------------------ -- The following procedures apply only to Entity_Id values, i.e. -- to extended nodes. procedure Basic_Set_Convention (E : Entity_Id; Val : Convention_Id); pragma Inline (Basic_Set_Convention); -- Clients should use Sem_Util.Set_Convention rather than calling this -- routine directly, as Set_Convention also deals with the special -- processing required for access types. procedure Set_Ekind (E : Entity_Id; Val : Entity_Kind); pragma Inline (Set_Ekind); --------------------------- -- Tree Rewrite Routines -- --------------------------- -- During the compilation process it is necessary in a number of situations -- to rewrite the tree. In some cases, such rewrites do not affect the -- structure of the tree, for example, when an indexed component node is -- replaced by the corresponding call node (the parser cannot distinguish -- between these two cases). -- In other situations, the rewrite does affect the structure of the -- tree. Examples are the replacement of a generic instantiation by the -- instantiated spec and body, and the static evaluation of expressions. -- If such structural modifications are done by the expander, there are -- no difficulties, since the form of the tree after the expander has no -- special significance, except as input to the backend of the compiler. -- However, if these modifications are done by the semantic phase, then -- it is important that they be done in a manner which allows the original -- tree to be preserved. This is because tools like pretty printers need -- to have this original tree structure available. -- The subprograms in this section allow rewriting of the tree by either -- insertion of new nodes in an existing list, or complete replacement of -- a subtree. The resulting tree for most purposes looks as though it has -- been really changed, and there is no trace of the original. However, -- special subprograms, also defined in this section, allow the original -- tree to be reconstructed if necessary. -- For tree modifications done in the expander, it is permissible to -- destroy the original tree, although it is also allowable to use the -- tree rewrite routines where it is convenient to do so. procedure Mark_Rewrite_Insertion (New_Node : Node_Id); pragma Inline (Mark_Rewrite_Insertion); -- This procedure marks the given node as an insertion made during a tree -- rewriting operation. Only the root needs to be marked. The call does -- not do the actual insertion, which must be done using one of the normal -- list insertion routines. The node is treated normally in all respects -- except for its response to Is_Rewrite_Insertion. The function of these -- calls is to be able to get an accurate original tree. This helps the -- accuracy of Sprint.Sprint_Node, and in particular, when stubs are being -- generated, it is essential that the original tree be accurate. function Is_Rewrite_Insertion (Node : Node_Id) return Boolean; pragma Inline (Is_Rewrite_Insertion); -- Tests whether the given node was marked using Mark_Rewrite_Insertion. -- This is used in reconstructing the original tree (where such nodes are -- to be eliminated). procedure Rewrite (Old_Node, New_Node : Node_Id); -- This is used when a complete subtree is to be replaced. Old_Node is the -- root of the old subtree to be replaced, and New_Node is the root of the -- newly constructed replacement subtree. The actual mechanism is to swap -- the contents of these two nodes fixing up the parent pointers of the -- replaced node (we do not attempt to preserve parent pointers for the -- original node). Neither Old_Node nor New_Node can be extended nodes. -- -- Note: New_Node may not contain references to Old_Node, for example as -- descendents, since the rewrite would make such references invalid. If -- New_Node does need to reference Old_Node, then these references should -- be to a relocated copy of Old_Node (see Relocate_Node procedure). -- -- Note: The Original_Node function applied to Old_Node (which has now -- been replaced by the contents of New_Node), can be used to obtain the -- original node, i.e. the old contents of Old_Node. procedure Replace (Old_Node, New_Node : Node_Id); -- This is similar to Rewrite, except that the old value of Old_Node is -- not saved, and the New_Node is deleted after the replace, since it -- is assumed that it can no longer be legitimately needed. The flag -- Is_Rewrite_Substitution will be False for the resulting node, unless -- it was already true on entry, and Original_Node will not return the -- original contents of the Old_Node, but rather the New_Node value (unless -- Old_Node had already been rewritten using Rewrite). Replace also -- preserves the setting of Comes_From_Source. -- -- Note, New_Node may not contain references to Old_Node, for example as -- descendents, since the rewrite would make such references invalid. If -- New_Node does need to reference Old_Node, then these references should -- be to a relocated copy of Old_Node (see Relocate_Node procedure). -- -- Replace is used in certain circumstances where it is desirable to -- suppress any history of the rewriting operation. Notably, it is used -- when the parser has mis-classified a node (e.g. a task entry call -- that the parser has parsed as a procedure call). function Is_Rewrite_Substitution (Node : Node_Id) return Boolean; pragma Inline (Is_Rewrite_Substitution); -- Return True iff Node has been rewritten (i.e. if Node is the root -- of a subtree which was installed using Rewrite). function Original_Node (Node : Node_Id) return Node_Id; pragma Inline (Original_Node); -- If Node has not been rewritten, then returns its input argument -- unchanged, else returns the Node for the original subtree. Note that -- this is used extensively by ASIS on the trees constructed in ASIS mode -- to reconstruct the original semantic tree. See section in sinfo.ads -- for requirements on original nodes returned by this function. -- -- Note: Parents are not preserved in original tree nodes that are -- retrieved in this way (i.e. their children may have children whose -- pointers which reference some other node). This needs more details??? -- -- Note: there is no direct mechanism for deleting an original node (in -- a manner that can be reversed later). One possible approach is to use -- Rewrite to substitute a null statement for the node to be deleted. ----------------------------------- -- Generic Field Access Routines -- ----------------------------------- -- This subpackage provides the functions for accessing and procedures for -- setting fields that are normally referenced by wrapper subprograms (e.g. -- logical synonyms defined in packages Sinfo and Einfo, or specialized -- routines such as Rewrite (for Original_Node), or the node creation -- routines (for Set_Nkind). The implementations of these wrapper -- subprograms use the package Atree.Unchecked_Access as do various -- special case accesses where no wrapper applies. Documentation is always -- required for such a special case access explaining why it is needed. package Unchecked_Access is -- Functions to allow interpretation of Union_Id values as Uint and -- Ureal values. function To_Union is new Unchecked_Conversion (Uint, Union_Id); function To_Union is new Unchecked_Conversion (Ureal, Union_Id); function From_Union is new Unchecked_Conversion (Union_Id, Uint); function From_Union is new Unchecked_Conversion (Union_Id, Ureal); -- Functions to fetch contents of indicated field. It is an error to -- attempt to read the value of a field which is not present. function Field1 (N : Node_Id) return Union_Id; pragma Inline (Field1); function Field2 (N : Node_Id) return Union_Id; pragma Inline (Field2); function Field3 (N : Node_Id) return Union_Id; pragma Inline (Field3); function Field4 (N : Node_Id) return Union_Id; pragma Inline (Field4); function Field5 (N : Node_Id) return Union_Id; pragma Inline (Field5); function Field6 (N : Node_Id) return Union_Id; pragma Inline (Field6); function Field7 (N : Node_Id) return Union_Id; pragma Inline (Field7); function Field8 (N : Node_Id) return Union_Id; pragma Inline (Field8); function Field9 (N : Node_Id) return Union_Id; pragma Inline (Field9); function Field10 (N : Node_Id) return Union_Id; pragma Inline (Field10); function Field11 (N : Node_Id) return Union_Id; pragma Inline (Field11); function Field12 (N : Node_Id) return Union_Id; pragma Inline (Field12); function Field13 (N : Node_Id) return Union_Id; pragma Inline (Field13); function Field14 (N : Node_Id) return Union_Id; pragma Inline (Field14); function Field15 (N : Node_Id) return Union_Id; pragma Inline (Field15); function Field16 (N : Node_Id) return Union_Id; pragma Inline (Field16); function Field17 (N : Node_Id) return Union_Id; pragma Inline (Field17); function Field18 (N : Node_Id) return Union_Id; pragma Inline (Field18); function Field19 (N : Node_Id) return Union_Id; pragma Inline (Field19); function Field20 (N : Node_Id) return Union_Id; pragma Inline (Field20); function Field21 (N : Node_Id) return Union_Id; pragma Inline (Field21); function Field22 (N : Node_Id) return Union_Id; pragma Inline (Field22); function Field23 (N : Node_Id) return Union_Id; pragma Inline (Field23); function Field24 (N : Node_Id) return Union_Id; pragma Inline (Field24); function Field25 (N : Node_Id) return Union_Id; pragma Inline (Field25); function Field26 (N : Node_Id) return Union_Id; pragma Inline (Field26); function Field27 (N : Node_Id) return Union_Id; pragma Inline (Field27); function Field28 (N : Node_Id) return Union_Id; pragma Inline (Field28); function Field29 (N : Node_Id) return Union_Id; pragma Inline (Field29); function Field30 (N : Node_Id) return Union_Id; pragma Inline (Field30); function Field31 (N : Node_Id) return Union_Id; pragma Inline (Field31); function Field32 (N : Node_Id) return Union_Id; pragma Inline (Field32); function Field33 (N : Node_Id) return Union_Id; pragma Inline (Field33); function Field34 (N : Node_Id) return Union_Id; pragma Inline (Field34); function Field35 (N : Node_Id) return Union_Id; pragma Inline (Field35); function Node1 (N : Node_Id) return Node_Id; pragma Inline (Node1); function Node2 (N : Node_Id) return Node_Id; pragma Inline (Node2); function Node3 (N : Node_Id) return Node_Id; pragma Inline (Node3); function Node4 (N : Node_Id) return Node_Id; pragma Inline (Node4); function Node5 (N : Node_Id) return Node_Id; pragma Inline (Node5); function Node6 (N : Node_Id) return Node_Id; pragma Inline (Node6); function Node7 (N : Node_Id) return Node_Id; pragma Inline (Node7); function Node8 (N : Node_Id) return Node_Id; pragma Inline (Node8); function Node9 (N : Node_Id) return Node_Id; pragma Inline (Node9); function Node10 (N : Node_Id) return Node_Id; pragma Inline (Node10); function Node11 (N : Node_Id) return Node_Id; pragma Inline (Node11); function Node12 (N : Node_Id) return Node_Id; pragma Inline (Node12); function Node13 (N : Node_Id) return Node_Id; pragma Inline (Node13); function Node14 (N : Node_Id) return Node_Id; pragma Inline (Node14); function Node15 (N : Node_Id) return Node_Id; pragma Inline (Node15); function Node16 (N : Node_Id) return Node_Id; pragma Inline (Node16); function Node17 (N : Node_Id) return Node_Id; pragma Inline (Node17); function Node18 (N : Node_Id) return Node_Id; pragma Inline (Node18); function Node19 (N : Node_Id) return Node_Id; pragma Inline (Node19); function Node20 (N : Node_Id) return Node_Id; pragma Inline (Node20); function Node21 (N : Node_Id) return Node_Id; pragma Inline (Node21); function Node22 (N : Node_Id) return Node_Id; pragma Inline (Node22); function Node23 (N : Node_Id) return Node_Id; pragma Inline (Node23); function Node24 (N : Node_Id) return Node_Id; pragma Inline (Node24); function Node25 (N : Node_Id) return Node_Id; pragma Inline (Node25); function Node26 (N : Node_Id) return Node_Id; pragma Inline (Node26); function Node27 (N : Node_Id) return Node_Id; pragma Inline (Node27); function Node28 (N : Node_Id) return Node_Id; pragma Inline (Node28); function Node29 (N : Node_Id) return Node_Id; pragma Inline (Node29); function Node30 (N : Node_Id) return Node_Id; pragma Inline (Node30); function Node31 (N : Node_Id) return Node_Id; pragma Inline (Node31); function Node32 (N : Node_Id) return Node_Id; pragma Inline (Node32); function Node33 (N : Node_Id) return Node_Id; pragma Inline (Node33); function Node34 (N : Node_Id) return Node_Id; pragma Inline (Node34); function Node35 (N : Node_Id) return Node_Id; pragma Inline (Node35); function List1 (N : Node_Id) return List_Id; pragma Inline (List1); function List2 (N : Node_Id) return List_Id; pragma Inline (List2); function List3 (N : Node_Id) return List_Id; pragma Inline (List3); function List4 (N : Node_Id) return List_Id; pragma Inline (List4); function List5 (N : Node_Id) return List_Id; pragma Inline (List5); function List10 (N : Node_Id) return List_Id; pragma Inline (List10); function List14 (N : Node_Id) return List_Id; pragma Inline (List14); function List25 (N : Node_Id) return List_Id; pragma Inline (List25); function Elist1 (N : Node_Id) return Elist_Id; pragma Inline (Elist1); function Elist2 (N : Node_Id) return Elist_Id; pragma Inline (Elist2); function Elist3 (N : Node_Id) return Elist_Id; pragma Inline (Elist3); function Elist4 (N : Node_Id) return Elist_Id; pragma Inline (Elist4); function Elist5 (N : Node_Id) return Elist_Id; pragma Inline (Elist5); function Elist8 (N : Node_Id) return Elist_Id; pragma Inline (Elist8); function Elist9 (N : Node_Id) return Elist_Id; pragma Inline (Elist9); function Elist10 (N : Node_Id) return Elist_Id; pragma Inline (Elist10); function Elist13 (N : Node_Id) return Elist_Id; pragma Inline (Elist13); function Elist15 (N : Node_Id) return Elist_Id; pragma Inline (Elist15); function Elist16 (N : Node_Id) return Elist_Id; pragma Inline (Elist16); function Elist18 (N : Node_Id) return Elist_Id; pragma Inline (Elist18); function Elist21 (N : Node_Id) return Elist_Id; pragma Inline (Elist21); function Elist23 (N : Node_Id) return Elist_Id; pragma Inline (Elist23); function Elist24 (N : Node_Id) return Elist_Id; pragma Inline (Elist24); function Elist25 (N : Node_Id) return Elist_Id; pragma Inline (Elist25); function Elist26 (N : Node_Id) return Elist_Id; pragma Inline (Elist26); function Name1 (N : Node_Id) return Name_Id; pragma Inline (Name1); function Name2 (N : Node_Id) return Name_Id; pragma Inline (Name2); function Str3 (N : Node_Id) return String_Id; pragma Inline (Str3); -- Note: the following Uintnn functions have a special test for the -- Field value being Empty. If an Empty value is found then Uint_0 is -- returned. This avoids the rather tricky requirement of initializing -- all Uint fields in nodes and entities. function Uint2 (N : Node_Id) return Uint; pragma Inline (Uint2); function Uint3 (N : Node_Id) return Uint; pragma Inline (Uint3); function Uint4 (N : Node_Id) return Uint; pragma Inline (Uint4); function Uint5 (N : Node_Id) return Uint; pragma Inline (Uint5); function Uint8 (N : Node_Id) return Uint; pragma Inline (Uint8); function Uint9 (N : Node_Id) return Uint; pragma Inline (Uint9); function Uint10 (N : Node_Id) return Uint; pragma Inline (Uint10); function Uint11 (N : Node_Id) return Uint; pragma Inline (Uint11); function Uint12 (N : Node_Id) return Uint; pragma Inline (Uint12); function Uint13 (N : Node_Id) return Uint; pragma Inline (Uint13); function Uint14 (N : Node_Id) return Uint; pragma Inline (Uint14); function Uint15 (N : Node_Id) return Uint; pragma Inline (Uint15); function Uint16 (N : Node_Id) return Uint; pragma Inline (Uint16); function Uint17 (N : Node_Id) return Uint; pragma Inline (Uint17); function Uint22 (N : Node_Id) return Uint; pragma Inline (Uint22); function Ureal3 (N : Node_Id) return Ureal; pragma Inline (Ureal3); function Ureal18 (N : Node_Id) return Ureal; pragma Inline (Ureal18); function Ureal21 (N : Node_Id) return Ureal; pragma Inline (Ureal21); function Flag0 (N : Node_Id) return Boolean; pragma Inline (Flag0); function Flag1 (N : Node_Id) return Boolean; pragma Inline (Flag1); function Flag2 (N : Node_Id) return Boolean; pragma Inline (Flag2); function Flag3 (N : Node_Id) return Boolean; pragma Inline (Flag3); function Flag4 (N : Node_Id) return Boolean; pragma Inline (Flag4); function Flag5 (N : Node_Id) return Boolean; pragma Inline (Flag5); function Flag6 (N : Node_Id) return Boolean; pragma Inline (Flag6); function Flag7 (N : Node_Id) return Boolean; pragma Inline (Flag7); function Flag8 (N : Node_Id) return Boolean; pragma Inline (Flag8); function Flag9 (N : Node_Id) return Boolean; pragma Inline (Flag9); function Flag10 (N : Node_Id) return Boolean; pragma Inline (Flag10); function Flag11 (N : Node_Id) return Boolean; pragma Inline (Flag11); function Flag12 (N : Node_Id) return Boolean; pragma Inline (Flag12); function Flag13 (N : Node_Id) return Boolean; pragma Inline (Flag13); function Flag14 (N : Node_Id) return Boolean; pragma Inline (Flag14); function Flag15 (N : Node_Id) return Boolean; pragma Inline (Flag15); function Flag16 (N : Node_Id) return Boolean; pragma Inline (Flag16); function Flag17 (N : Node_Id) return Boolean; pragma Inline (Flag17); function Flag18 (N : Node_Id) return Boolean; pragma Inline (Flag18); function Flag19 (N : Node_Id) return Boolean; pragma Inline (Flag19); function Flag20 (N : Node_Id) return Boolean; pragma Inline (Flag20); function Flag21 (N : Node_Id) return Boolean; pragma Inline (Flag21); function Flag22 (N : Node_Id) return Boolean; pragma Inline (Flag22); function Flag23 (N : Node_Id) return Boolean; pragma Inline (Flag23); function Flag24 (N : Node_Id) return Boolean; pragma Inline (Flag24); function Flag25 (N : Node_Id) return Boolean; pragma Inline (Flag25); function Flag26 (N : Node_Id) return Boolean; pragma Inline (Flag26); function Flag27 (N : Node_Id) return Boolean; pragma Inline (Flag27); function Flag28 (N : Node_Id) return Boolean; pragma Inline (Flag28); function Flag29 (N : Node_Id) return Boolean; pragma Inline (Flag29); function Flag30 (N : Node_Id) return Boolean; pragma Inline (Flag30); function Flag31 (N : Node_Id) return Boolean; pragma Inline (Flag31); function Flag32 (N : Node_Id) return Boolean; pragma Inline (Flag32); function Flag33 (N : Node_Id) return Boolean; pragma Inline (Flag33); function Flag34 (N : Node_Id) return Boolean; pragma Inline (Flag34); function Flag35 (N : Node_Id) return Boolean; pragma Inline (Flag35); function Flag36 (N : Node_Id) return Boolean; pragma Inline (Flag36); function Flag37 (N : Node_Id) return Boolean; pragma Inline (Flag37); function Flag38 (N : Node_Id) return Boolean; pragma Inline (Flag38); function Flag39 (N : Node_Id) return Boolean; pragma Inline (Flag39); function Flag40 (N : Node_Id) return Boolean; pragma Inline (Flag40); function Flag41 (N : Node_Id) return Boolean; pragma Inline (Flag41); function Flag42 (N : Node_Id) return Boolean; pragma Inline (Flag42); function Flag43 (N : Node_Id) return Boolean; pragma Inline (Flag43); function Flag44 (N : Node_Id) return Boolean; pragma Inline (Flag44); function Flag45 (N : Node_Id) return Boolean; pragma Inline (Flag45); function Flag46 (N : Node_Id) return Boolean; pragma Inline (Flag46); function Flag47 (N : Node_Id) return Boolean; pragma Inline (Flag47); function Flag48 (N : Node_Id) return Boolean; pragma Inline (Flag48); function Flag49 (N : Node_Id) return Boolean; pragma Inline (Flag49); function Flag50 (N : Node_Id) return Boolean; pragma Inline (Flag50); function Flag51 (N : Node_Id) return Boolean; pragma Inline (Flag51); function Flag52 (N : Node_Id) return Boolean; pragma Inline (Flag52); function Flag53 (N : Node_Id) return Boolean; pragma Inline (Flag53); function Flag54 (N : Node_Id) return Boolean; pragma Inline (Flag54); function Flag55 (N : Node_Id) return Boolean; pragma Inline (Flag55); function Flag56 (N : Node_Id) return Boolean; pragma Inline (Flag56); function Flag57 (N : Node_Id) return Boolean; pragma Inline (Flag57); function Flag58 (N : Node_Id) return Boolean; pragma Inline (Flag58); function Flag59 (N : Node_Id) return Boolean; pragma Inline (Flag59); function Flag60 (N : Node_Id) return Boolean; pragma Inline (Flag60); function Flag61 (N : Node_Id) return Boolean; pragma Inline (Flag61); function Flag62 (N : Node_Id) return Boolean; pragma Inline (Flag62); function Flag63 (N : Node_Id) return Boolean; pragma Inline (Flag63); function Flag64 (N : Node_Id) return Boolean; pragma Inline (Flag64); function Flag65 (N : Node_Id) return Boolean; pragma Inline (Flag65); function Flag66 (N : Node_Id) return Boolean; pragma Inline (Flag66); function Flag67 (N : Node_Id) return Boolean; pragma Inline (Flag67); function Flag68 (N : Node_Id) return Boolean; pragma Inline (Flag68); function Flag69 (N : Node_Id) return Boolean; pragma Inline (Flag69); function Flag70 (N : Node_Id) return Boolean; pragma Inline (Flag70); function Flag71 (N : Node_Id) return Boolean; pragma Inline (Flag71); function Flag72 (N : Node_Id) return Boolean; pragma Inline (Flag72); function Flag73 (N : Node_Id) return Boolean; pragma Inline (Flag73); function Flag74 (N : Node_Id) return Boolean; pragma Inline (Flag74); function Flag75 (N : Node_Id) return Boolean; pragma Inline (Flag75); function Flag76 (N : Node_Id) return Boolean; pragma Inline (Flag76); function Flag77 (N : Node_Id) return Boolean; pragma Inline (Flag77); function Flag78 (N : Node_Id) return Boolean; pragma Inline (Flag78); function Flag79 (N : Node_Id) return Boolean; pragma Inline (Flag79); function Flag80 (N : Node_Id) return Boolean; pragma Inline (Flag80); function Flag81 (N : Node_Id) return Boolean; pragma Inline (Flag81); function Flag82 (N : Node_Id) return Boolean; pragma Inline (Flag82); function Flag83 (N : Node_Id) return Boolean; pragma Inline (Flag83); function Flag84 (N : Node_Id) return Boolean; pragma Inline (Flag84); function Flag85 (N : Node_Id) return Boolean; pragma Inline (Flag85); function Flag86 (N : Node_Id) return Boolean; pragma Inline (Flag86); function Flag87 (N : Node_Id) return Boolean; pragma Inline (Flag87); function Flag88 (N : Node_Id) return Boolean; pragma Inline (Flag88); function Flag89 (N : Node_Id) return Boolean; pragma Inline (Flag89); function Flag90 (N : Node_Id) return Boolean; pragma Inline (Flag90); function Flag91 (N : Node_Id) return Boolean; pragma Inline (Flag91); function Flag92 (N : Node_Id) return Boolean; pragma Inline (Flag92); function Flag93 (N : Node_Id) return Boolean; pragma Inline (Flag93); function Flag94 (N : Node_Id) return Boolean; pragma Inline (Flag94); function Flag95 (N : Node_Id) return Boolean; pragma Inline (Flag95); function Flag96 (N : Node_Id) return Boolean; pragma Inline (Flag96); function Flag97 (N : Node_Id) return Boolean; pragma Inline (Flag97); function Flag98 (N : Node_Id) return Boolean; pragma Inline (Flag98); function Flag99 (N : Node_Id) return Boolean; pragma Inline (Flag99); function Flag100 (N : Node_Id) return Boolean; pragma Inline (Flag100); function Flag101 (N : Node_Id) return Boolean; pragma Inline (Flag101); function Flag102 (N : Node_Id) return Boolean; pragma Inline (Flag102); function Flag103 (N : Node_Id) return Boolean; pragma Inline (Flag103); function Flag104 (N : Node_Id) return Boolean; pragma Inline (Flag104); function Flag105 (N : Node_Id) return Boolean; pragma Inline (Flag105); function Flag106 (N : Node_Id) return Boolean; pragma Inline (Flag106); function Flag107 (N : Node_Id) return Boolean; pragma Inline (Flag107); function Flag108 (N : Node_Id) return Boolean; pragma Inline (Flag108); function Flag109 (N : Node_Id) return Boolean; pragma Inline (Flag109); function Flag110 (N : Node_Id) return Boolean; pragma Inline (Flag110); function Flag111 (N : Node_Id) return Boolean; pragma Inline (Flag111); function Flag112 (N : Node_Id) return Boolean; pragma Inline (Flag112); function Flag113 (N : Node_Id) return Boolean; pragma Inline (Flag113); function Flag114 (N : Node_Id) return Boolean; pragma Inline (Flag114); function Flag115 (N : Node_Id) return Boolean; pragma Inline (Flag115); function Flag116 (N : Node_Id) return Boolean; pragma Inline (Flag116); function Flag117 (N : Node_Id) return Boolean; pragma Inline (Flag117); function Flag118 (N : Node_Id) return Boolean; pragma Inline (Flag118); function Flag119 (N : Node_Id) return Boolean; pragma Inline (Flag119); function Flag120 (N : Node_Id) return Boolean; pragma Inline (Flag120); function Flag121 (N : Node_Id) return Boolean; pragma Inline (Flag121); function Flag122 (N : Node_Id) return Boolean; pragma Inline (Flag122); function Flag123 (N : Node_Id) return Boolean; pragma Inline (Flag123); function Flag124 (N : Node_Id) return Boolean; pragma Inline (Flag124); function Flag125 (N : Node_Id) return Boolean; pragma Inline (Flag125); function Flag126 (N : Node_Id) return Boolean; pragma Inline (Flag126); function Flag127 (N : Node_Id) return Boolean; pragma Inline (Flag127); function Flag128 (N : Node_Id) return Boolean; pragma Inline (Flag128); function Flag129 (N : Node_Id) return Boolean; pragma Inline (Flag129); function Flag130 (N : Node_Id) return Boolean; pragma Inline (Flag130); function Flag131 (N : Node_Id) return Boolean; pragma Inline (Flag131); function Flag132 (N : Node_Id) return Boolean; pragma Inline (Flag132); function Flag133 (N : Node_Id) return Boolean; pragma Inline (Flag133); function Flag134 (N : Node_Id) return Boolean; pragma Inline (Flag134); function Flag135 (N : Node_Id) return Boolean; pragma Inline (Flag135); function Flag136 (N : Node_Id) return Boolean; pragma Inline (Flag136); function Flag137 (N : Node_Id) return Boolean; pragma Inline (Flag137); function Flag138 (N : Node_Id) return Boolean; pragma Inline (Flag138); function Flag139 (N : Node_Id) return Boolean; pragma Inline (Flag139); function Flag140 (N : Node_Id) return Boolean; pragma Inline (Flag140); function Flag141 (N : Node_Id) return Boolean; pragma Inline (Flag141); function Flag142 (N : Node_Id) return Boolean; pragma Inline (Flag142); function Flag143 (N : Node_Id) return Boolean; pragma Inline (Flag143); function Flag144 (N : Node_Id) return Boolean; pragma Inline (Flag144); function Flag145 (N : Node_Id) return Boolean; pragma Inline (Flag145); function Flag146 (N : Node_Id) return Boolean; pragma Inline (Flag146); function Flag147 (N : Node_Id) return Boolean; pragma Inline (Flag147); function Flag148 (N : Node_Id) return Boolean; pragma Inline (Flag148); function Flag149 (N : Node_Id) return Boolean; pragma Inline (Flag149); function Flag150 (N : Node_Id) return Boolean; pragma Inline (Flag150); function Flag151 (N : Node_Id) return Boolean; pragma Inline (Flag151); function Flag152 (N : Node_Id) return Boolean; pragma Inline (Flag152); function Flag153 (N : Node_Id) return Boolean; pragma Inline (Flag153); function Flag154 (N : Node_Id) return Boolean; pragma Inline (Flag154); function Flag155 (N : Node_Id) return Boolean; pragma Inline (Flag155); function Flag156 (N : Node_Id) return Boolean; pragma Inline (Flag156); function Flag157 (N : Node_Id) return Boolean; pragma Inline (Flag157); function Flag158 (N : Node_Id) return Boolean; pragma Inline (Flag158); function Flag159 (N : Node_Id) return Boolean; pragma Inline (Flag159); function Flag160 (N : Node_Id) return Boolean; pragma Inline (Flag160); function Flag161 (N : Node_Id) return Boolean; pragma Inline (Flag161); function Flag162 (N : Node_Id) return Boolean; pragma Inline (Flag162); function Flag163 (N : Node_Id) return Boolean; pragma Inline (Flag163); function Flag164 (N : Node_Id) return Boolean; pragma Inline (Flag164); function Flag165 (N : Node_Id) return Boolean; pragma Inline (Flag165); function Flag166 (N : Node_Id) return Boolean; pragma Inline (Flag166); function Flag167 (N : Node_Id) return Boolean; pragma Inline (Flag167); function Flag168 (N : Node_Id) return Boolean; pragma Inline (Flag168); function Flag169 (N : Node_Id) return Boolean; pragma Inline (Flag169); function Flag170 (N : Node_Id) return Boolean; pragma Inline (Flag170); function Flag171 (N : Node_Id) return Boolean; pragma Inline (Flag171); function Flag172 (N : Node_Id) return Boolean; pragma Inline (Flag172); function Flag173 (N : Node_Id) return Boolean; pragma Inline (Flag173); function Flag174 (N : Node_Id) return Boolean; pragma Inline (Flag174); function Flag175 (N : Node_Id) return Boolean; pragma Inline (Flag175); function Flag176 (N : Node_Id) return Boolean; pragma Inline (Flag176); function Flag177 (N : Node_Id) return Boolean; pragma Inline (Flag177); function Flag178 (N : Node_Id) return Boolean; pragma Inline (Flag178); function Flag179 (N : Node_Id) return Boolean; pragma Inline (Flag179); function Flag180 (N : Node_Id) return Boolean; pragma Inline (Flag180); function Flag181 (N : Node_Id) return Boolean; pragma Inline (Flag181); function Flag182 (N : Node_Id) return Boolean; pragma Inline (Flag182); function Flag183 (N : Node_Id) return Boolean; pragma Inline (Flag183); function Flag184 (N : Node_Id) return Boolean; pragma Inline (Flag184); function Flag185 (N : Node_Id) return Boolean; pragma Inline (Flag185); function Flag186 (N : Node_Id) return Boolean; pragma Inline (Flag186); function Flag187 (N : Node_Id) return Boolean; pragma Inline (Flag187); function Flag188 (N : Node_Id) return Boolean; pragma Inline (Flag188); function Flag189 (N : Node_Id) return Boolean; pragma Inline (Flag189); function Flag190 (N : Node_Id) return Boolean; pragma Inline (Flag190); function Flag191 (N : Node_Id) return Boolean; pragma Inline (Flag191); function Flag192 (N : Node_Id) return Boolean; pragma Inline (Flag192); function Flag193 (N : Node_Id) return Boolean; pragma Inline (Flag193); function Flag194 (N : Node_Id) return Boolean; pragma Inline (Flag194); function Flag195 (N : Node_Id) return Boolean; pragma Inline (Flag195); function Flag196 (N : Node_Id) return Boolean; pragma Inline (Flag196); function Flag197 (N : Node_Id) return Boolean; pragma Inline (Flag197); function Flag198 (N : Node_Id) return Boolean; pragma Inline (Flag198); function Flag199 (N : Node_Id) return Boolean; pragma Inline (Flag199); function Flag200 (N : Node_Id) return Boolean; pragma Inline (Flag200); function Flag201 (N : Node_Id) return Boolean; pragma Inline (Flag201); function Flag202 (N : Node_Id) return Boolean; pragma Inline (Flag202); function Flag203 (N : Node_Id) return Boolean; pragma Inline (Flag203); function Flag204 (N : Node_Id) return Boolean; pragma Inline (Flag204); function Flag205 (N : Node_Id) return Boolean; pragma Inline (Flag205); function Flag206 (N : Node_Id) return Boolean; pragma Inline (Flag206); function Flag207 (N : Node_Id) return Boolean; pragma Inline (Flag207); function Flag208 (N : Node_Id) return Boolean; pragma Inline (Flag208); function Flag209 (N : Node_Id) return Boolean; pragma Inline (Flag209); function Flag210 (N : Node_Id) return Boolean; pragma Inline (Flag210); function Flag211 (N : Node_Id) return Boolean; pragma Inline (Flag211); function Flag212 (N : Node_Id) return Boolean; pragma Inline (Flag212); function Flag213 (N : Node_Id) return Boolean; pragma Inline (Flag213); function Flag214 (N : Node_Id) return Boolean; pragma Inline (Flag214); function Flag215 (N : Node_Id) return Boolean; pragma Inline (Flag215); function Flag216 (N : Node_Id) return Boolean; pragma Inline (Flag216); function Flag217 (N : Node_Id) return Boolean; pragma Inline (Flag217); function Flag218 (N : Node_Id) return Boolean; pragma Inline (Flag218); function Flag219 (N : Node_Id) return Boolean; pragma Inline (Flag219); function Flag220 (N : Node_Id) return Boolean; pragma Inline (Flag220); function Flag221 (N : Node_Id) return Boolean; pragma Inline (Flag221); function Flag222 (N : Node_Id) return Boolean; pragma Inline (Flag222); function Flag223 (N : Node_Id) return Boolean; pragma Inline (Flag223); function Flag224 (N : Node_Id) return Boolean; pragma Inline (Flag224); function Flag225 (N : Node_Id) return Boolean; pragma Inline (Flag225); function Flag226 (N : Node_Id) return Boolean; pragma Inline (Flag226); function Flag227 (N : Node_Id) return Boolean; pragma Inline (Flag227); function Flag228 (N : Node_Id) return Boolean; pragma Inline (Flag228); function Flag229 (N : Node_Id) return Boolean; pragma Inline (Flag229); function Flag230 (N : Node_Id) return Boolean; pragma Inline (Flag230); function Flag231 (N : Node_Id) return Boolean; pragma Inline (Flag231); function Flag232 (N : Node_Id) return Boolean; pragma Inline (Flag232); function Flag233 (N : Node_Id) return Boolean; pragma Inline (Flag233); function Flag234 (N : Node_Id) return Boolean; pragma Inline (Flag234); function Flag235 (N : Node_Id) return Boolean; pragma Inline (Flag235); function Flag236 (N : Node_Id) return Boolean; pragma Inline (Flag236); function Flag237 (N : Node_Id) return Boolean; pragma Inline (Flag237); function Flag238 (N : Node_Id) return Boolean; pragma Inline (Flag238); function Flag239 (N : Node_Id) return Boolean; pragma Inline (Flag239); function Flag240 (N : Node_Id) return Boolean; pragma Inline (Flag240); function Flag241 (N : Node_Id) return Boolean; pragma Inline (Flag241); function Flag242 (N : Node_Id) return Boolean; pragma Inline (Flag242); function Flag243 (N : Node_Id) return Boolean; pragma Inline (Flag243); function Flag244 (N : Node_Id) return Boolean; pragma Inline (Flag244); function Flag245 (N : Node_Id) return Boolean; pragma Inline (Flag245); function Flag246 (N : Node_Id) return Boolean; pragma Inline (Flag246); function Flag247 (N : Node_Id) return Boolean; pragma Inline (Flag247); function Flag248 (N : Node_Id) return Boolean; pragma Inline (Flag248); function Flag249 (N : Node_Id) return Boolean; pragma Inline (Flag249); function Flag250 (N : Node_Id) return Boolean; pragma Inline (Flag250); function Flag251 (N : Node_Id) return Boolean; pragma Inline (Flag251); function Flag252 (N : Node_Id) return Boolean; pragma Inline (Flag252); function Flag253 (N : Node_Id) return Boolean; pragma Inline (Flag253); function Flag254 (N : Node_Id) return Boolean; pragma Inline (Flag254); function Flag255 (N : Node_Id) return Boolean; pragma Inline (Flag255); function Flag256 (N : Node_Id) return Boolean; pragma Inline (Flag256); function Flag257 (N : Node_Id) return Boolean; pragma Inline (Flag257); function Flag258 (N : Node_Id) return Boolean; pragma Inline (Flag258); function Flag259 (N : Node_Id) return Boolean; pragma Inline (Flag259); function Flag260 (N : Node_Id) return Boolean; pragma Inline (Flag260); function Flag261 (N : Node_Id) return Boolean; pragma Inline (Flag261); function Flag262 (N : Node_Id) return Boolean; pragma Inline (Flag262); function Flag263 (N : Node_Id) return Boolean; pragma Inline (Flag263); function Flag264 (N : Node_Id) return Boolean; pragma Inline (Flag264); function Flag265 (N : Node_Id) return Boolean; pragma Inline (Flag265); function Flag266 (N : Node_Id) return Boolean; pragma Inline (Flag266); function Flag267 (N : Node_Id) return Boolean; pragma Inline (Flag267); function Flag268 (N : Node_Id) return Boolean; pragma Inline (Flag268); function Flag269 (N : Node_Id) return Boolean; pragma Inline (Flag269); function Flag270 (N : Node_Id) return Boolean; pragma Inline (Flag270); function Flag271 (N : Node_Id) return Boolean; pragma Inline (Flag271); function Flag272 (N : Node_Id) return Boolean; pragma Inline (Flag272); function Flag273 (N : Node_Id) return Boolean; pragma Inline (Flag273); function Flag274 (N : Node_Id) return Boolean; pragma Inline (Flag274); function Flag275 (N : Node_Id) return Boolean; pragma Inline (Flag275); function Flag276 (N : Node_Id) return Boolean; pragma Inline (Flag276); function Flag277 (N : Node_Id) return Boolean; pragma Inline (Flag277); function Flag278 (N : Node_Id) return Boolean; pragma Inline (Flag278); function Flag279 (N : Node_Id) return Boolean; pragma Inline (Flag279); function Flag280 (N : Node_Id) return Boolean; pragma Inline (Flag280); function Flag281 (N : Node_Id) return Boolean; pragma Inline (Flag281); function Flag282 (N : Node_Id) return Boolean; pragma Inline (Flag282); function Flag283 (N : Node_Id) return Boolean; pragma Inline (Flag283); function Flag284 (N : Node_Id) return Boolean; pragma Inline (Flag284); function Flag285 (N : Node_Id) return Boolean; pragma Inline (Flag285); function Flag286 (N : Node_Id) return Boolean; pragma Inline (Flag286); function Flag287 (N : Node_Id) return Boolean; pragma Inline (Flag287); function Flag288 (N : Node_Id) return Boolean; pragma Inline (Flag288); function Flag289 (N : Node_Id) return Boolean; pragma Inline (Flag289); function Flag290 (N : Node_Id) return Boolean; pragma Inline (Flag290); function Flag291 (N : Node_Id) return Boolean; pragma Inline (Flag291); function Flag292 (N : Node_Id) return Boolean; pragma Inline (Flag292); function Flag293 (N : Node_Id) return Boolean; pragma Inline (Flag293); function Flag294 (N : Node_Id) return Boolean; pragma Inline (Flag294); function Flag295 (N : Node_Id) return Boolean; pragma Inline (Flag295); function Flag296 (N : Node_Id) return Boolean; pragma Inline (Flag296); function Flag297 (N : Node_Id) return Boolean; pragma Inline (Flag297); function Flag298 (N : Node_Id) return Boolean; pragma Inline (Flag298); function Flag299 (N : Node_Id) return Boolean; pragma Inline (Flag299); function Flag300 (N : Node_Id) return Boolean; pragma Inline (Flag300); function Flag301 (N : Node_Id) return Boolean; pragma Inline (Flag301); function Flag302 (N : Node_Id) return Boolean; pragma Inline (Flag302); function Flag303 (N : Node_Id) return Boolean; pragma Inline (Flag303); function Flag304 (N : Node_Id) return Boolean; pragma Inline (Flag304); function Flag305 (N : Node_Id) return Boolean; pragma Inline (Flag305); function Flag306 (N : Node_Id) return Boolean; pragma Inline (Flag306); function Flag307 (N : Node_Id) return Boolean; pragma Inline (Flag307); function Flag308 (N : Node_Id) return Boolean; pragma Inline (Flag308); function Flag309 (N : Node_Id) return Boolean; pragma Inline (Flag309); function Flag310 (N : Node_Id) return Boolean; pragma Inline (Flag310); function Flag311 (N : Node_Id) return Boolean; pragma Inline (Flag311); function Flag312 (N : Node_Id) return Boolean; pragma Inline (Flag312); function Flag313 (N : Node_Id) return Boolean; pragma Inline (Flag313); function Flag314 (N : Node_Id) return Boolean; pragma Inline (Flag314); function Flag315 (N : Node_Id) return Boolean; pragma Inline (Flag315); function Flag316 (N : Node_Id) return Boolean; pragma Inline (Flag316); function Flag317 (N : Node_Id) return Boolean; pragma Inline (Flag317); -- Procedures to set value of indicated field procedure Set_Nkind (N : Node_Id; Val : Node_Kind); pragma Inline (Set_Nkind); procedure Set_Field1 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field1); procedure Set_Field2 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field2); procedure Set_Field3 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field3); procedure Set_Field4 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field4); procedure Set_Field5 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field5); procedure Set_Field6 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field6); procedure Set_Field7 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field7); procedure Set_Field8 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field8); procedure Set_Field9 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field9); procedure Set_Field10 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field10); procedure Set_Field11 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field11); procedure Set_Field12 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field12); procedure Set_Field13 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field13); procedure Set_Field14 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field14); procedure Set_Field15 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field15); procedure Set_Field16 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field16); procedure Set_Field17 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field17); procedure Set_Field18 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field18); procedure Set_Field19 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field19); procedure Set_Field20 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field20); procedure Set_Field21 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field21); procedure Set_Field22 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field22); procedure Set_Field23 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field23); procedure Set_Field24 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field24); procedure Set_Field25 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field25); procedure Set_Field26 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field26); procedure Set_Field27 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field27); procedure Set_Field28 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field28); procedure Set_Field29 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field29); procedure Set_Field30 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field30); procedure Set_Field31 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field31); procedure Set_Field32 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field32); procedure Set_Field33 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field33); procedure Set_Field34 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field34); procedure Set_Field35 (N : Node_Id; Val : Union_Id); pragma Inline (Set_Field35); procedure Set_Node1 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node1); procedure Set_Node2 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node2); procedure Set_Node3 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node3); procedure Set_Node4 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node4); procedure Set_Node5 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node5); procedure Set_Node6 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node6); procedure Set_Node7 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node7); procedure Set_Node8 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node8); procedure Set_Node9 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node9); procedure Set_Node10 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node10); procedure Set_Node11 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node11); procedure Set_Node12 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node12); procedure Set_Node13 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node13); procedure Set_Node14 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node14); procedure Set_Node15 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node15); procedure Set_Node16 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node16); procedure Set_Node17 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node17); procedure Set_Node18 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node18); procedure Set_Node19 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node19); procedure Set_Node20 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node20); procedure Set_Node21 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node21); procedure Set_Node22 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node22); procedure Set_Node23 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node23); procedure Set_Node24 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node24); procedure Set_Node25 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node25); procedure Set_Node26 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node26); procedure Set_Node27 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node27); procedure Set_Node28 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node28); procedure Set_Node29 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node29); procedure Set_Node30 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node30); procedure Set_Node31 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node31); procedure Set_Node32 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node32); procedure Set_Node33 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node33); procedure Set_Node34 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node34); procedure Set_Node35 (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node35); procedure Set_List1 (N : Node_Id; Val : List_Id); pragma Inline (Set_List1); procedure Set_List2 (N : Node_Id; Val : List_Id); pragma Inline (Set_List2); procedure Set_List3 (N : Node_Id; Val : List_Id); pragma Inline (Set_List3); procedure Set_List4 (N : Node_Id; Val : List_Id); pragma Inline (Set_List4); procedure Set_List5 (N : Node_Id; Val : List_Id); pragma Inline (Set_List5); procedure Set_List10 (N : Node_Id; Val : List_Id); pragma Inline (Set_List10); procedure Set_List14 (N : Node_Id; Val : List_Id); pragma Inline (Set_List14); procedure Set_List25 (N : Node_Id; Val : List_Id); pragma Inline (Set_List25); procedure Set_Elist1 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist1); procedure Set_Elist2 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist2); procedure Set_Elist3 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist3); procedure Set_Elist4 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist4); procedure Set_Elist5 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist5); procedure Set_Elist8 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist8); procedure Set_Elist9 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist9); procedure Set_Elist10 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist10); procedure Set_Elist13 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist13); procedure Set_Elist15 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist15); procedure Set_Elist16 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist16); procedure Set_Elist18 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist18); procedure Set_Elist21 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist21); procedure Set_Elist23 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist23); procedure Set_Elist24 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist24); procedure Set_Elist25 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist25); procedure Set_Elist26 (N : Node_Id; Val : Elist_Id); pragma Inline (Set_Elist26); procedure Set_Name1 (N : Node_Id; Val : Name_Id); pragma Inline (Set_Name1); procedure Set_Name2 (N : Node_Id; Val : Name_Id); pragma Inline (Set_Name2); procedure Set_Str3 (N : Node_Id; Val : String_Id); pragma Inline (Set_Str3); procedure Set_Uint2 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint2); procedure Set_Uint3 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint3); procedure Set_Uint4 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint4); procedure Set_Uint5 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint5); procedure Set_Uint8 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint8); procedure Set_Uint9 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint9); procedure Set_Uint10 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint10); procedure Set_Uint11 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint11); procedure Set_Uint12 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint12); procedure Set_Uint13 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint13); procedure Set_Uint14 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint14); procedure Set_Uint15 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint15); procedure Set_Uint16 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint16); procedure Set_Uint17 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint17); procedure Set_Uint22 (N : Node_Id; Val : Uint); pragma Inline (Set_Uint22); procedure Set_Ureal3 (N : Node_Id; Val : Ureal); pragma Inline (Set_Ureal3); procedure Set_Ureal18 (N : Node_Id; Val : Ureal); pragma Inline (Set_Ureal18); procedure Set_Ureal21 (N : Node_Id; Val : Ureal); pragma Inline (Set_Ureal21); procedure Set_Flag0 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag0); procedure Set_Flag1 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag1); procedure Set_Flag2 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag2); procedure Set_Flag3 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag3); procedure Set_Flag4 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag4); procedure Set_Flag5 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag5); procedure Set_Flag6 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag6); procedure Set_Flag7 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag7); procedure Set_Flag8 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag8); procedure Set_Flag9 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag9); procedure Set_Flag10 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag10); procedure Set_Flag11 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag11); procedure Set_Flag12 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag12); procedure Set_Flag13 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag13); procedure Set_Flag14 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag14); procedure Set_Flag15 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag15); procedure Set_Flag16 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag16); procedure Set_Flag17 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag17); procedure Set_Flag18 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag18); procedure Set_Flag19 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag19); procedure Set_Flag20 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag20); procedure Set_Flag21 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag21); procedure Set_Flag22 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag22); procedure Set_Flag23 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag23); procedure Set_Flag24 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag24); procedure Set_Flag25 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag25); procedure Set_Flag26 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag26); procedure Set_Flag27 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag27); procedure Set_Flag28 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag28); procedure Set_Flag29 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag29); procedure Set_Flag30 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag30); procedure Set_Flag31 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag31); procedure Set_Flag32 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag32); procedure Set_Flag33 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag33); procedure Set_Flag34 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag34); procedure Set_Flag35 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag35); procedure Set_Flag36 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag36); procedure Set_Flag37 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag37); procedure Set_Flag38 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag38); procedure Set_Flag39 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag39); procedure Set_Flag40 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag40); procedure Set_Flag41 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag41); procedure Set_Flag42 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag42); procedure Set_Flag43 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag43); procedure Set_Flag44 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag44); procedure Set_Flag45 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag45); procedure Set_Flag46 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag46); procedure Set_Flag47 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag47); procedure Set_Flag48 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag48); procedure Set_Flag49 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag49); procedure Set_Flag50 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag50); procedure Set_Flag51 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag51); procedure Set_Flag52 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag52); procedure Set_Flag53 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag53); procedure Set_Flag54 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag54); procedure Set_Flag55 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag55); procedure Set_Flag56 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag56); procedure Set_Flag57 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag57); procedure Set_Flag58 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag58); procedure Set_Flag59 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag59); procedure Set_Flag60 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag60); procedure Set_Flag61 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag61); procedure Set_Flag62 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag62); procedure Set_Flag63 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag63); procedure Set_Flag64 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag64); procedure Set_Flag65 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag65); procedure Set_Flag66 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag66); procedure Set_Flag67 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag67); procedure Set_Flag68 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag68); procedure Set_Flag69 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag69); procedure Set_Flag70 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag70); procedure Set_Flag71 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag71); procedure Set_Flag72 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag72); procedure Set_Flag73 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag73); procedure Set_Flag74 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag74); procedure Set_Flag75 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag75); procedure Set_Flag76 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag76); procedure Set_Flag77 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag77); procedure Set_Flag78 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag78); procedure Set_Flag79 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag79); procedure Set_Flag80 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag80); procedure Set_Flag81 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag81); procedure Set_Flag82 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag82); procedure Set_Flag83 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag83); procedure Set_Flag84 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag84); procedure Set_Flag85 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag85); procedure Set_Flag86 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag86); procedure Set_Flag87 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag87); procedure Set_Flag88 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag88); procedure Set_Flag89 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag89); procedure Set_Flag90 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag90); procedure Set_Flag91 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag91); procedure Set_Flag92 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag92); procedure Set_Flag93 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag93); procedure Set_Flag94 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag94); procedure Set_Flag95 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag95); procedure Set_Flag96 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag96); procedure Set_Flag97 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag97); procedure Set_Flag98 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag98); procedure Set_Flag99 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag99); procedure Set_Flag100 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag100); procedure Set_Flag101 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag101); procedure Set_Flag102 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag102); procedure Set_Flag103 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag103); procedure Set_Flag104 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag104); procedure Set_Flag105 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag105); procedure Set_Flag106 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag106); procedure Set_Flag107 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag107); procedure Set_Flag108 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag108); procedure Set_Flag109 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag109); procedure Set_Flag110 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag110); procedure Set_Flag111 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag111); procedure Set_Flag112 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag112); procedure Set_Flag113 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag113); procedure Set_Flag114 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag114); procedure Set_Flag115 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag115); procedure Set_Flag116 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag116); procedure Set_Flag117 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag117); procedure Set_Flag118 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag118); procedure Set_Flag119 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag119); procedure Set_Flag120 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag120); procedure Set_Flag121 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag121); procedure Set_Flag122 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag122); procedure Set_Flag123 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag123); procedure Set_Flag124 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag124); procedure Set_Flag125 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag125); procedure Set_Flag126 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag126); procedure Set_Flag127 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag127); procedure Set_Flag128 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag128); procedure Set_Flag129 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag129); procedure Set_Flag130 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag130); procedure Set_Flag131 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag131); procedure Set_Flag132 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag132); procedure Set_Flag133 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag133); procedure Set_Flag134 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag134); procedure Set_Flag135 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag135); procedure Set_Flag136 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag136); procedure Set_Flag137 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag137); procedure Set_Flag138 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag138); procedure Set_Flag139 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag139); procedure Set_Flag140 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag140); procedure Set_Flag141 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag141); procedure Set_Flag142 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag142); procedure Set_Flag143 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag143); procedure Set_Flag144 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag144); procedure Set_Flag145 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag145); procedure Set_Flag146 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag146); procedure Set_Flag147 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag147); procedure Set_Flag148 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag148); procedure Set_Flag149 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag149); procedure Set_Flag150 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag150); procedure Set_Flag151 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag151); procedure Set_Flag152 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag152); procedure Set_Flag153 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag153); procedure Set_Flag154 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag154); procedure Set_Flag155 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag155); procedure Set_Flag156 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag156); procedure Set_Flag157 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag157); procedure Set_Flag158 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag158); procedure Set_Flag159 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag159); procedure Set_Flag160 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag160); procedure Set_Flag161 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag161); procedure Set_Flag162 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag162); procedure Set_Flag163 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag163); procedure Set_Flag164 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag164); procedure Set_Flag165 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag165); procedure Set_Flag166 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag166); procedure Set_Flag167 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag167); procedure Set_Flag168 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag168); procedure Set_Flag169 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag169); procedure Set_Flag170 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag170); procedure Set_Flag171 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag171); procedure Set_Flag172 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag172); procedure Set_Flag173 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag173); procedure Set_Flag174 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag174); procedure Set_Flag175 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag175); procedure Set_Flag176 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag176); procedure Set_Flag177 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag177); procedure Set_Flag178 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag178); procedure Set_Flag179 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag179); procedure Set_Flag180 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag180); procedure Set_Flag181 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag181); procedure Set_Flag182 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag182); procedure Set_Flag183 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag183); procedure Set_Flag184 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag184); procedure Set_Flag185 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag185); procedure Set_Flag186 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag186); procedure Set_Flag187 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag187); procedure Set_Flag188 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag188); procedure Set_Flag189 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag189); procedure Set_Flag190 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag190); procedure Set_Flag191 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag191); procedure Set_Flag192 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag192); procedure Set_Flag193 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag193); procedure Set_Flag194 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag194); procedure Set_Flag195 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag195); procedure Set_Flag196 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag196); procedure Set_Flag197 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag197); procedure Set_Flag198 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag198); procedure Set_Flag199 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag199); procedure Set_Flag200 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag200); procedure Set_Flag201 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag201); procedure Set_Flag202 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag202); procedure Set_Flag203 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag203); procedure Set_Flag204 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag204); procedure Set_Flag205 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag205); procedure Set_Flag206 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag206); procedure Set_Flag207 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag207); procedure Set_Flag208 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag208); procedure Set_Flag209 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag209); procedure Set_Flag210 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag210); procedure Set_Flag211 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag211); procedure Set_Flag212 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag212); procedure Set_Flag213 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag213); procedure Set_Flag214 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag214); procedure Set_Flag215 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag215); procedure Set_Flag216 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag216); procedure Set_Flag217 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag217); procedure Set_Flag218 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag218); procedure Set_Flag219 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag219); procedure Set_Flag220 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag220); procedure Set_Flag221 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag221); procedure Set_Flag222 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag222); procedure Set_Flag223 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag223); procedure Set_Flag224 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag224); procedure Set_Flag225 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag225); procedure Set_Flag226 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag226); procedure Set_Flag227 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag227); procedure Set_Flag228 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag228); procedure Set_Flag229 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag229); procedure Set_Flag230 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag230); procedure Set_Flag231 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag231); procedure Set_Flag232 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag232); procedure Set_Flag233 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag233); procedure Set_Flag234 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag234); procedure Set_Flag235 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag235); procedure Set_Flag236 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag236); procedure Set_Flag237 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag237); procedure Set_Flag238 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag238); procedure Set_Flag239 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag239); procedure Set_Flag240 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag240); procedure Set_Flag241 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag241); procedure Set_Flag242 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag242); procedure Set_Flag243 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag243); procedure Set_Flag244 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag244); procedure Set_Flag245 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag245); procedure Set_Flag246 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag246); procedure Set_Flag247 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag247); procedure Set_Flag248 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag248); procedure Set_Flag249 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag249); procedure Set_Flag250 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag250); procedure Set_Flag251 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag251); procedure Set_Flag252 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag252); procedure Set_Flag253 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag253); procedure Set_Flag254 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag254); procedure Set_Flag255 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag255); procedure Set_Flag256 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag256); procedure Set_Flag257 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag257); procedure Set_Flag258 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag258); procedure Set_Flag259 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag259); procedure Set_Flag260 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag260); procedure Set_Flag261 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag261); procedure Set_Flag262 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag262); procedure Set_Flag263 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag263); procedure Set_Flag264 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag264); procedure Set_Flag265 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag265); procedure Set_Flag266 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag266); procedure Set_Flag267 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag267); procedure Set_Flag268 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag268); procedure Set_Flag269 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag269); procedure Set_Flag270 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag270); procedure Set_Flag271 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag271); procedure Set_Flag272 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag272); procedure Set_Flag273 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag273); procedure Set_Flag274 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag274); procedure Set_Flag275 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag275); procedure Set_Flag276 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag276); procedure Set_Flag277 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag277); procedure Set_Flag278 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag278); procedure Set_Flag279 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag279); procedure Set_Flag280 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag280); procedure Set_Flag281 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag281); procedure Set_Flag282 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag282); procedure Set_Flag283 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag283); procedure Set_Flag284 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag284); procedure Set_Flag285 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag285); procedure Set_Flag286 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag286); procedure Set_Flag287 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag287); procedure Set_Flag288 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag288); procedure Set_Flag289 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag289); procedure Set_Flag290 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag290); procedure Set_Flag291 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag291); procedure Set_Flag292 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag292); procedure Set_Flag293 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag293); procedure Set_Flag294 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag294); procedure Set_Flag295 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag295); procedure Set_Flag296 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag296); procedure Set_Flag297 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag297); procedure Set_Flag298 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag298); procedure Set_Flag299 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag299); procedure Set_Flag300 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag300); procedure Set_Flag301 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag301); procedure Set_Flag302 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag302); procedure Set_Flag303 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag303); procedure Set_Flag304 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag304); procedure Set_Flag305 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag305); procedure Set_Flag306 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag306); procedure Set_Flag307 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag307); procedure Set_Flag308 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag308); procedure Set_Flag309 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag309); procedure Set_Flag310 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag310); procedure Set_Flag311 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag311); procedure Set_Flag312 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag312); procedure Set_Flag313 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag313); procedure Set_Flag314 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag314); procedure Set_Flag315 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag315); procedure Set_Flag316 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag316); procedure Set_Flag317 (N : Node_Id; Val : Boolean); pragma Inline (Set_Flag317); -- The following versions of Set_Noden also set the parent pointer of -- the referenced node if it is not Empty. procedure Set_Node1_With_Parent (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node1_With_Parent); procedure Set_Node2_With_Parent (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node2_With_Parent); procedure Set_Node3_With_Parent (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node3_With_Parent); procedure Set_Node4_With_Parent (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node4_With_Parent); procedure Set_Node5_With_Parent (N : Node_Id; Val : Node_Id); pragma Inline (Set_Node5_With_Parent); -- The following versions of Set_Listn also set the parent pointer of -- the referenced node if it is not Empty. procedure Set_List1_With_Parent (N : Node_Id; Val : List_Id); pragma Inline (Set_List1_With_Parent); procedure Set_List2_With_Parent (N : Node_Id; Val : List_Id); pragma Inline (Set_List2_With_Parent); procedure Set_List3_With_Parent (N : Node_Id; Val : List_Id); pragma Inline (Set_List3_With_Parent); procedure Set_List4_With_Parent (N : Node_Id; Val : List_Id); pragma Inline (Set_List4_With_Parent); procedure Set_List5_With_Parent (N : Node_Id; Val : List_Id); pragma Inline (Set_List5_With_Parent); end Unchecked_Access; ----------------------------- -- Private Part Subpackage -- ----------------------------- -- The following package contains the definition of the data structure -- used by the implementation of the Atree package. Logically it really -- corresponds to the private part, hence the name. The reason that it -- is defined as a sub-package is to allow special access from clients -- that need to see the internals of the data structures. package Atree_Private_Part is ------------------------- -- Tree Representation -- ------------------------- -- The nodes of the tree are stored in a table (i.e. an array). In the -- case of extended nodes six consecutive components in the array are -- used. There are thus two formats for array components. One is used -- for non-extended nodes, and for the first component of extended -- nodes. The other is used for the extension parts (second, third, -- fourth, fifth, and sixth components) of an extended node. A variant -- record structure is used to distinguish the two formats. type Node_Record (Is_Extension : Boolean := False) is record -- Logically, the only field in the common part is the above -- Is_Extension discriminant (a single bit). However, Gigi cannot -- yet handle such a structure, so we fill out the common part of -- the record with fields that are used in different ways for -- normal nodes and node extensions. Pflag1, Pflag2 : Boolean; -- The Paren_Count field is represented using two boolean flags, -- where Pflag1 is worth 1, and Pflag2 is worth 2. This is done -- because we need to be easily able to reuse this field for -- extra flags in the extended node case. In_List : Boolean; -- Flag used to indicate if node is a member of a list. -- This field is considered private to the Atree package. Has_Aspects : Boolean; -- Flag used to indicate that a node has aspect specifications that -- are associated with the node. See Aspects package for details. Rewrite_Ins : Boolean; -- Flag set by Mark_Rewrite_Insertion procedure. -- This field is considered private to the Atree package. Analyzed : Boolean; -- Flag to indicate the node has been analyzed (and expanded) Comes_From_Source : Boolean; -- Flag to indicate that node comes from the source program (i.e. -- was built by the parser or scanner, not the analyzer or expander). Error_Posted : Boolean; -- Flag to indicate that an error message has been posted on the -- node (to avoid duplicate flags on the same node) Flag4 : Boolean; Flag5 : Boolean; Flag6 : Boolean; Flag7 : Boolean; Flag8 : Boolean; Flag9 : Boolean; Flag10 : Boolean; Flag11 : Boolean; Flag12 : Boolean; Flag13 : Boolean; Flag14 : Boolean; Flag15 : Boolean; Flag16 : Boolean; Flag17 : Boolean; Flag18 : Boolean; -- Flags 4-18 for a normal node. Note that Flags 0-3 are stored -- separately in the Flags array. -- The above fields are used as follows in components 2-6 of -- an extended node entry. -- In_List used as Flag19,Flag40,Flag129,Flag216,Flag287 -- Has_Aspects used as Flag20,Flag41,Flag130,Flag217,Flag288 -- Rewrite_Ins used as Flag21,Flag42,Flag131,Flag218,Flag289 -- Analyzed used as Flag22,Flag43,Flag132,Flag219,Flag290 -- Comes_From_Source used as Flag23,Flag44,Flag133,Flag220,Flag291 -- Error_Posted used as Flag24,Flag45,Flag134,Flag221,Flag292 -- Flag4 used as Flag25,Flag46,Flag135,Flag222,Flag293 -- Flag5 used as Flag26,Flag47,Flag136,Flag223,Flag294 -- Flag6 used as Flag27,Flag48,Flag137,Flag224,Flag295 -- Flag7 used as Flag28,Flag49,Flag138,Flag225,Flag296 -- Flag8 used as Flag29,Flag50,Flag139,Flag226,Flag297 -- Flag9 used as Flag30,Flag51,Flag140,Flag227,Flag298 -- Flag10 used as Flag31,Flag52,Flag141,Flag228,Flag299 -- Flag11 used as Flag32,Flag53,Flag142,Flag229,Flag300 -- Flag12 used as Flag33,Flag54,Flag143,Flag230,Flag301 -- Flag13 used as Flag34,Flag55,Flag144,Flag231,Flag302 -- Flag14 used as Flag35,Flag56,Flag145,Flag232,Flag303 -- Flag15 used as Flag36,Flag57,Flag146,Flag233,Flag304 -- Flag16 used as Flag37,Flag58,Flag147,Flag234,Flag305 -- Flag17 used as Flag38,Flag59,Flag148,Flag235,Flag306 -- Flag18 used as Flag39,Flag60,Flag149,Flag236,Flag307 -- Pflag1 used as Flag61,Flag62,Flag150,Flag237,Flag308 -- Pflag2 used as Flag63,Flag64,Flag151,Flag238,Flag309 Nkind : Node_Kind; -- For a non-extended node, or the initial section of an extended -- node, this field holds the Node_Kind value. For an extended node, -- The Nkind field is used as follows: -- -- Second entry: holds the Ekind field of the entity -- Third entry: holds 8 additional flags (Flag65-Flag72) -- Fourth entry: holds 8 additional flags (Flag239-246) -- Fifth entry: holds 8 additional flags (Flag247-254) -- Sixth entry: holds 8 additional flags (Flag310-317) -- Now finally (on an 32-bit boundary) comes the variant part case Is_Extension is -- Non-extended node, or first component of extended node when False => Sloc : Source_Ptr; -- Source location for this node Link : Union_Id; -- This field is used either as the Parent pointer (if In_List -- is False), or to point to the list header (if In_List is -- True). This field is considered private and can be modified -- only by Atree or by Nlists. Field1 : Union_Id; Field2 : Union_Id; Field3 : Union_Id; Field4 : Union_Id; Field5 : Union_Id; -- Five general use fields, which can contain Node_Id, List_Id, -- Elist_Id, String_Id, or Name_Id values depending on the -- values in Nkind and (for extended nodes), in Ekind. See -- packages Sinfo and Einfo for details of their use. -- Extension (second component) of extended node when True => Field6 : Union_Id; Field7 : Union_Id; Field8 : Union_Id; Field9 : Union_Id; Field10 : Union_Id; Field11 : Union_Id; Field12 : Union_Id; -- Seven additional general fields available only for entities -- See package Einfo for details of their use (which depends -- on the value in the Ekind field). -- In the third component, the extension format as described -- above is used to hold additional general fields and flags -- as follows: -- Field6-11 Holds Field13-Field18 -- Field12 Holds Flag73-Flag96 and Convention -- In the fourth component, the extension format as described -- above is used to hold additional general fields and flags -- as follows: -- Field6-10 Holds Field19-Field23 -- Field11 Holds Flag152-Flag183 -- Field12 Holds Flag97-Flag128 -- In the fifth component, the extension format as described -- above is used to hold additional general fields and flags -- as follows: -- Field6-11 Holds Field24-Field29 -- Field12 Holds Flag184-Flag215 -- In the sixth component, the extension format as described -- above is used to hold additional general fields and flags -- as follows: -- Field6-11 Holds Field30-Field35 -- Field12 Holds Flag255-Flag286 end case; end record; pragma Pack (Node_Record); for Node_Record'Size use 8 * 32; for Node_Record'Alignment use 4; function E_To_N is new Unchecked_Conversion (Entity_Kind, Node_Kind); function N_To_E is new Unchecked_Conversion (Node_Kind, Entity_Kind); -- Default value used to initialize default nodes. Note that some of the -- fields get overwritten, and in particular, Nkind always gets reset. Default_Node : Node_Record := ( Is_Extension => False, Pflag1 => False, Pflag2 => False, In_List => False, Has_Aspects => False, Rewrite_Ins => False, Analyzed => False, Comes_From_Source => False, -- modified by Set_Comes_From_Source_Default Error_Posted => False, Flag4 => False, Flag5 => False, Flag6 => False, Flag7 => False, Flag8 => False, Flag9 => False, Flag10 => False, Flag11 => False, Flag12 => False, Flag13 => False, Flag14 => False, Flag15 => False, Flag16 => False, Flag17 => False, Flag18 => False, Nkind => N_Unused_At_Start, Sloc => No_Location, Link => Empty_List_Or_Node, Field1 => Empty_List_Or_Node, Field2 => Empty_List_Or_Node, Field3 => Empty_List_Or_Node, Field4 => Empty_List_Or_Node, Field5 => Empty_List_Or_Node); -- Default value used to initialize node extensions (i.e. the second -- through sixth components of an extended node). Note we are cheating -- a bit here when it comes to Node12, which really holds flags and (for -- the third component), the convention. But it works because Empty, -- False, Convention_Ada, all happen to be all zero bits. Default_Node_Extension : constant Node_Record := ( Is_Extension => True, Pflag1 => False, Pflag2 => False, In_List => False, Has_Aspects => False, Rewrite_Ins => False, Analyzed => False, Comes_From_Source => False, Error_Posted => False, Flag4 => False, Flag5 => False, Flag6 => False, Flag7 => False, Flag8 => False, Flag9 => False, Flag10 => False, Flag11 => False, Flag12 => False, Flag13 => False, Flag14 => False, Flag15 => False, Flag16 => False, Flag17 => False, Flag18 => False, Nkind => E_To_N (E_Void), Field6 => Empty_List_Or_Node, Field7 => Empty_List_Or_Node, Field8 => Empty_List_Or_Node, Field9 => Empty_List_Or_Node, Field10 => Empty_List_Or_Node, Field11 => Empty_List_Or_Node, Field12 => Empty_List_Or_Node); -- The following defines the extendable array used for the nodes table -- Nodes with extensions use six consecutive entries in the array package Nodes is new Table.Table ( Table_Component_Type => Node_Record, Table_Index_Type => Node_Id'Base, Table_Low_Bound => First_Node_Id, Table_Initial => Alloc.Nodes_Initial, Table_Increment => Alloc.Nodes_Increment, Table_Name => "Nodes"); -- The following is a parallel table to Nodes, which provides 8 more -- bits of space that logically belong to the corresponding node. This -- is currently used to implement Flags 0,1,2,3 for normal nodes, or -- the first component of an extended node (four bits unused). Entries -- for extending components are completely unused. type Flags_Byte is record Flag0 : Boolean; Flag1 : Boolean; Flag2 : Boolean; Flag3 : Boolean; Spare0 : Boolean; Spare1 : Boolean; Spare2 : Boolean; Spare3 : Boolean; end record; for Flags_Byte'Size use 8; pragma Pack (Flags_Byte); Default_Flags : constant Flags_Byte := (others => False); -- Default value used to initialize new entries package Flags is new Table.Table ( Table_Component_Type => Flags_Byte, Table_Index_Type => Node_Id'Base, Table_Low_Bound => First_Node_Id, Table_Initial => Alloc.Nodes_Initial, Table_Increment => Alloc.Nodes_Increment, Table_Name => "Flags"); end Atree_Private_Part; end Atree; gprbuild-gpl-2014-src/gnat/casing.ads0000644000076700001450000001114012323721731017016 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- C A S I N G -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Types; use Types; package Casing is -- This package contains data and subprograms to support the feature that -- recognizes the letter case styles used in the source program being -- compiled, and uses this information for error message formatting, and -- for recognizing reserved words that are misused as identifiers. ------------------------------- -- Case Control Declarations -- ------------------------------- -- Declaration of type for describing casing convention type Casing_Type is ( All_Upper_Case, -- All letters are upper case All_Lower_Case, -- All letters are lower case Mixed_Case, -- The initial letter, and any letters after underlines are upper case. -- All other letters are lower case Unknown -- Used if an identifier does not distinguish between the above cases, -- (e.g. X, Y_3, M4, A_B, or if it is inconsistent ABC_def). ); subtype Known_Casing is Casing_Type range All_Upper_Case .. Mixed_Case; -- Exclude Unknown casing ------------------------------ -- Case Control Subprograms -- ------------------------------ procedure Set_Casing (C : Casing_Type; D : Casing_Type := Mixed_Case); -- Takes the name stored in the first Name_Len positions of Name_Buffer -- and modifies it to be consistent with the casing given by C, or if -- C = Unknown, then with the casing given by D. The name is basically -- treated as an identifier, except that special separator characters -- other than underline are permitted and treated like underlines (this -- handles cases like minus and period in unit names, apostrophes in error -- messages, angle brackets in names like , etc). procedure Set_All_Upper_Case; pragma Inline (Set_All_Upper_Case); -- This procedure is called with an identifier name stored in Name_Buffer. -- On return, the identifier is converted to all upper case. The call is -- equivalent to Set_Casing (All_Upper_Case). function Determine_Casing (Ident : Text_Buffer) return Casing_Type; -- Determines the casing of the identifier/keyword string Ident. A special -- test is made for SPARK_Mode which is considered to be mixed case, since -- this gives a better general behavior. end Casing; gprbuild-gpl-2014-src/gnat/butil.ads0000644000076700001450000000612612323721731016701 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- B U T I L -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2007, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Namet; use Namet; package Butil is -- This package contains utility routines for the binder function Is_Predefined_Unit return Boolean; -- Given a unit name stored in Name_Buffer with length in Name_Len, -- returns True if this is the name of a predefined unit or a child of -- a predefined unit (including the obsolescent renamings). This is used -- in the preference selection (see Better_Choice in body of Binde). function Is_Internal_Unit return Boolean; -- Given a unit name stored in Name_Buffer with length in Name_Len, -- returns True if this is the name of an internal unit or a child of -- an internal. Similar in usage to Is_Predefined_Unit. -- Note: the following functions duplicate functionality in Uname, but -- we want to avoid bringing Uname into the binder since it generates -- to many unnecessary dependencies, and makes the binder too large. function Uname_Less (U1, U2 : Unit_Name_Type) return Boolean; -- Determines if the unit name U1 is alphabetically before U2 procedure Write_Unit_Name (U : Unit_Name_Type); -- Output unit name with (body) or (spec) after as required. On return -- Name_Len is set to the number of characters which were output. end Butil; gprbuild-gpl-2014-src/gnat/switch.ads0000644000076700001450000001431312323721731017060 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S W I T C H -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package together with a child package appropriate to the client tool -- scans switches. Note that the body of the appropriate Usage package must be -- coordinated with the switches that are recognized by this package. These -- Usage packages also act as the official documentation for the switches -- that are recognized. In addition, package Debug documents the otherwise -- undocumented debug switches that are also recognized. with Gnatvsn; with Types; use Types; ------------ -- Switch -- ------------ package Switch is -- Common switches for GNU tools Version_Switch : constant String := "--version"; Help_Switch : constant String := "--help"; ----------------- -- Subprograms -- ----------------- generic with procedure Usage; -- Print tool-specific part of --help message procedure Check_Version_And_Help_G (Tool_Name : String; Initial_Year : String; Version_String : String := Gnatvsn.Gnat_Version_String); -- Check if switches --version or --help is used. If one of this switch is -- used, issue the proper messages and end the process. procedure Display_Version (Tool_Name : String; Initial_Year : String; Version_String : String := Gnatvsn.Gnat_Version_String); -- Display version of a tool when switch --version is used procedure Display_Usage_Version_And_Help; -- Output the two lines of usage for switches --version and --help function Is_Switch (Switch_Chars : String) return Boolean; -- Returns True iff Switch_Chars is at least two characters long, and the -- first character is an hyphen ('-'). function Is_Front_End_Switch (Switch_Chars : String) return Boolean; -- Returns True iff Switch_Chars represents a front-end switch, i.e. it -- starts with -I, -gnat or -?RTS. function Is_Internal_GCC_Switch (Switch_Chars : String) return Boolean; -- Returns True iff Switch_Chars represents an internal GCC switch to be -- followed by a single argument, such as -dumpbase, --param or -auxbase. -- Even though passed by the "gcc" driver, these need not be stored in ALI -- files and may safely be ignored by non GCC back-ends. function Switch_Last (Switch_Chars : String) return Natural; -- Index in Switch_Chars of the last relevant character for later string -- comparison purposes. This is typically 'Last, minus one if there is a -- terminating ASCII.NUL. private -- This section contains some common routines used by the tool dependent -- child packages (there is one such child package for each tool that uses -- Switches to scan switches - Compiler/gnatbind/gnatmake/. Switch_Max_Value : constant := 999_999; -- Maximum value permitted in switches that take a value function Nat_Present (Switch_Chars : String; Max : Integer; Ptr : Integer) return Boolean; -- Returns True if an integer is at the current scan location or an equal -- sign. This is used as a guard for calling Scan_Nat. Switch_Chars is the -- string containing the switch, and Ptr points just past the switch -- character. Max is the maximum allowed value of Ptr. procedure Scan_Nat (Switch_Chars : String; Max : Integer; Ptr : in out Integer; Result : out Nat; Switch : Character); -- Scan natural integer parameter for switch. On entry, Ptr points just -- past the switch character, on exit it points past the last digit of the -- integer value. Max is the maximum allowed value of Ptr, so the scan is -- restricted to Switch_Chars (Ptr .. Max). It is possible for Ptr to be -- one greater than Max on return if the entire string is digits. Scan_Nat -- will skip an optional equal sign if it is present. Nat_Present must be -- True, or an error will be signalled. procedure Scan_Pos (Switch_Chars : String; Max : Integer; Ptr : in out Integer; Result : out Pos; Switch : Character); -- Scan positive integer parameter for switch. Identical to Scan_Nat with -- same parameters except that zero is considered out of range. procedure Bad_Switch (Switch : Character); procedure Bad_Switch (Switch : String); pragma No_Return (Bad_Switch); -- Fail with an appropriate message when a switch is not recognized end Switch; gprbuild-gpl-2014-src/gnat/stylesw.ads0000644000076700001450000003753012323721731017277 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S T Y L E S W -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains the style switches used for setting style options. -- The only clients of this package are the body of Style and the body of -- Switches. All other style checking issues are handled using the public -- interfaces in the spec of Style. with Types; use Types; package Stylesw is -------------------------- -- Style Check Switches -- -------------------------- -- These flags are used to control the details of the style checking -- options. The default values shown here correspond to no style checking. -- If any of these values is set to a non-default value, then -- Opt.Style_Check is set True to activate calls to this package. -- The actual mechanism for setting these switches to other than default -- values is via the Set_Style_Check_Options procedure or through a call to -- Set_Default_Style_Check_Options. They should not be set directly in any -- other manner. Style_Check_Array_Attribute_Index : Boolean := False; -- This can be set True by using the -gnatyA switch. If it is True then -- index numbers for array attributes (like Length) are required to be -- absent for one-dimensional arrays and present for multi-dimensional -- array attribute references. Style_Check_Attribute_Casing : Boolean := False; -- This can be set True by using the -gnatya switch. If it is True, then -- attribute names (including keywords such as digits used as attribute -- names) must be in mixed case. Style_Check_Blanks_At_End : Boolean := False; -- This can be set True by using the -gnatyb switch. If it is True, then -- spaces at the end of lines are not permitted. Style_Check_Blank_Lines : Boolean := False; -- This can be set True by using the -gnatyu switch. If it is True, then -- multiple blank lines are not permitted, and there may not be a blank -- line at the end of the file. Style_Check_Boolean_And_Or : Boolean := False; -- This can be set True by using the -gnatyB switch. If it is True, then -- the use of AND THEN/OR ELSE rather than AND/OR is required except for -- the following cases: -- -- a) Both operands are simple Boolean constants or variables -- b) Both operands are of a modular type -- c) Both operands are of an array type Style_Check_Comments : Boolean := False; -- This can be set True by using the -gnatyc switch. If it is True, then -- comments are style checked as follows: -- -- All comments must be at the start of the line, or the first minus must -- be preceded by at least one space. -- -- For a comment that is not at the start of a line, the only requirement -- is that a space follow the comment characters. -- -- For a comment that is at the start of the line, one of the following -- conditions must hold: -- -- The comment characters are the only non-blank characters on the line -- -- The comment characters are followed by an exclamation point (the -- sequence --! is used by gnatprep for marking deleted lines). -- -- The comment characters are followed by two space characters if -- Comment_Spacing = 2, else by one character if Comment_Spacing = 1. -- -- The line consists entirely of minus signs -- -- The comment characters are followed by a single space, and the last -- two characters on the line are also comment characters. -- -- Note: the reason for the last two conditions is to allow "boxed" -- comments where only a single space separates the comment characters. Style_Check_Comments_Spacing : Nat range 1 .. 2; -- Spacing required for comments, valid only if Style_Check_Comments true. Style_Check_DOS_Line_Terminator : Boolean := False; -- This can be set true by using the -gnatyd switch. If it is True, then -- the line terminator must be a single LF, without an associated CR (e.g. -- DOS line terminator sequence CR/LF not allowed). Style_Check_End_Labels : Boolean := False; -- This can be set True by using the -gnatye switch. If it is True, then -- optional END labels must always be present. Style_Check_Form_Feeds : Boolean := False; -- This can be set True by using the -gnatyf switch. If it is True, then -- form feeds and vertical tabs are not allowed in the source text. Style_Check_Horizontal_Tabs : Boolean := False; -- This can be set True by using the -gnatyh switch. If it is True, then -- horizontal tabs are not allowed in source text. Style_Check_If_Then_Layout : Boolean := False; -- This can be set True by using the -gnatyi switch. If it is True, then a -- THEN keyword must either appear on the same line as the IF, or on a line -- all on its own. -- -- This permits one of two styles for IF-THEN layout. Either the IF and -- THEN keywords are on the same line, where the condition is short enough, -- or the conditions are continued over to the lines following the IF and -- the THEN stands on its own. For example: -- -- if X > Y then -- -- if X > Y -- and then Y < Z -- then -- -- if X > Y and then Z > 0 -- then -- -- are allowed, but -- -- if X > Y -- and then B > C then -- -- is not allowed. Style_Check_Indentation : Column_Number range 0 .. 9 := 0; -- This can be set non-zero by using the -gnaty? (? a digit) switch. If -- it is non-zero it activates indentation checking with the indicated -- indentation value. A value of zero turns off checking. The requirement -- is that any new statement, line comment, declaration or keyword such -- as END, start on a column that is a multiple of the indentation value. Style_Check_Keyword_Casing : Boolean := False; -- This can be set True by using the -gnatyk switch. If it is True, then -- keywords are required to be in all lower case. This rule does not apply -- to keywords such as digits appearing as an attribute name. Style_Check_Layout : Boolean := False; -- This can be set True by using the -gnatyl switch. If it is True, it -- activates checks that constructs are indented as suggested by the -- examples in the RM syntax, e.g. that the ELSE keyword must line up -- with the IF keyword. Style_Check_Max_Line_Length : Boolean := False; -- This can be set True by using the -gnatym/M switches. If it is True, it -- activates checking for a maximum line length of Style_Max_Line_Length -- characters. Style_Check_Max_Nesting_Level : Boolean := False; -- This can be set True by using -gnatyLnnn with a value other than zero -- (a value of zero resets it to False). If True, it activates checking -- the maximum nesting level against Style_Max_Nesting_Level. Style_Check_Missing_Overriding : Boolean := False; -- This can be set True by using the -gnatyO switch. If it is True, then -- "overriding" is required in subprogram declarations and bodies where -- appropriate. Note that "not overriding" is never required. Style_Check_Mode_In : Boolean := False; -- This can be set True by using -gnatyI. If True, it activates checking -- that mode IN is not used on its own (since it is the default). Style_Check_Order_Subprograms : Boolean := False; -- This can be set True by using the -gnatyo switch. If it is True, then -- names of subprogram bodies must be in alphabetical order (not taking -- casing into account). Style_Check_Pragma_Casing : Boolean := False; -- This can be set True by using the -gnatyp switch. If it is True, then -- pragma names must use mixed case. Style_Check_References : Boolean := False; -- This can be set True by using the -gnatyr switch. If it is True, then -- all references to declared identifiers are checked. The requirement -- is that casing of the reference be the same as the casing of the -- corresponding declaration. Style_Check_Separate_Stmt_Lines : Boolean := False; -- This can be set True by using the -gnatyS switch. If it is TRUE, -- then for the case of keywords THEN (not preceded by AND) or ELSE (not -- preceded by OR) which introduce a conditionally executed statement -- sequence, there must be no tokens on the same line as the keyword, so -- that coverage testing can clearly identify execution of the statement -- sequence. A comment is permitted, as is THEN ABORT or a PRAGMA keyword -- after ELSE (a common style to specify the condition for the ELSE). Style_Check_Specs : Boolean := False; -- This can be set True by using the -gnatys switches. If it is True, then -- separate specs are required to be present for all procedures except -- parameterless library level procedures. The exception means that typical -- main programs do not require separate specs. Style_Check_Standard : Boolean := False; -- This can be set True by using the -gnatyn switch. If it is True, then -- any references to names in Standard have to be cased in a manner that -- is consistent with the Ada RM (usually Mixed case, as in Long_Integer) -- but there are some exceptions (e.g. NUL, ASCII). Style_Check_Tokens : Boolean := False; -- This can be set True by using the -gnatyt switch. If it is True, then -- the style check that requires canonical spacing between various -- punctuation tokens as follows: -- -- ABS and NOT must be followed by a space -- -- => must be surrounded by spaces -- -- <> must be preceded by a space or left paren -- -- Binary operators other than ** must be surrounded by spaces. -- -- There is no restriction on the layout of the ** binary operator. -- -- Colon must be surrounded by spaces -- -- Colon-equal (assignment) must be surrounded by spaces -- -- Comma must be the first non-blank character on the line, or be -- immediately preceded by a non-blank character, and must be followed -- by a blank. -- -- A space must precede a left paren following a digit or letter, and a -- right paren must not be followed by a space (it can be at the end of -- the line). -- -- A right paren must either be the first non-blank character on a line, -- or it must be preceded by a non-blank character. -- -- A semicolon must not be preceded by a blank, and must not be followed -- by a non-blank character. -- -- A unary plus or minus may not be followed by a space -- -- There must be one blank (and no other white space) between NOT and IN -- -- A vertical bar must be surrounded by spaces -- -- Note that a requirement that a token be preceded by a space is met by -- placing the token at the start of the line, and similarly a requirement -- that a token be followed by a space is met by placing the token at -- the end of the line. Note that in the case where horizontal tabs are -- permitted, a horizontal tab is acceptable for meeting the requirement -- for a space. Style_Check_Xtra_Parens : Boolean := False; -- This can be set True by using the -gnatyx switch. If true, then it is -- not allowed to enclose entire expressions in tests in parentheses -- (C style), e.g. if (x = y) then ... is not allowed. Style_Max_Line_Length : Int := 0; -- Value used to check maximum line length. Gets reset as a result of -- use of -gnatym or -gnatyMnnn switches. This value is only read if -- Style_Check_Max_Line_Length is True. Style_Max_Nesting_Level : Int := 0; -- Value used to check maximum nesting level. Gets reset as a result -- of use of the -gnatyLnnn switch. This value is only read if -- Style_Check_Max_Nesting_Level is True. ----------------- -- Subprograms -- ----------------- function RM_Column_Check return Boolean; -- Determines whether style checking is active and the RM column check -- mode is set requiring checking of RM format layout. procedure Set_Default_Style_Check_Options; -- This procedure is called to set the default style checking options in -- response to a -gnaty switch with no suboptions or from -gnatyy. procedure Set_GNAT_Style_Check_Options; -- This procedure is called to set the default style checking options for -- GNAT units (as set by -gnatg or -gnatyg). Style_Msg_Buf : String (1 .. 80); Style_Msg_Len : Natural; -- Used to return procedure Set_Style_Check_Options (Options : String; OK : out Boolean; Err_Col : out Natural); -- This procedure is called to set the style check options that correspond -- to the characters in the given Options string. If all options are valid, -- they are set in an additive manner: any previous options are retained -- unless overridden, unless a minus is encountered, and then subsequent -- style switches are subtracted from the current set. -- -- If all options given are valid, then OK is True, Err_Col is set to -- Options'Last + 1, and Style_Msg_Buf/Style_Msg_Len are unchanged. -- -- If an invalid character is found, then OK is False on exit, and Err_Col -- is the index in options of the bad character. In this case Style_Msg_Len -- is set and Style_Msg_Buf (1 .. Style_Msg_Len) has a detailed message -- describing the error. procedure Set_Style_Check_Options (Options : String); -- Like the above procedure, but used when the Options string is known to -- be valid. This is for example appropriate for calls where the string was -- obtained by Save_Style_Check_Options. procedure Reset_Style_Check_Options; -- Sets all style check options to off subtype Style_Check_Options is String (1 .. 64); -- Long enough string to hold all options from Save call below procedure Save_Style_Check_Options (Options : out Style_Check_Options); -- Sets Options to represent current selection of options. This set can be -- restored by first calling Reset_Style_Check_Options, and then calling -- Set_Style_Check_Options with the Options string. end Stylesw; gprbuild-gpl-2014-src/gnat/lib-list.adb0000644000076700001450000001145512323721731017261 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- L I B . L I S T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ separate (Lib) procedure List (File_Names_Only : Boolean := False) is Num_Units : constant Nat := Int (Units.Last) - Int (Units.First) + 1; -- Number of units in file table Sorted_Units : Unit_Ref_Table (1 .. Num_Units); -- Table of unit numbers that we will sort Unit_Hed : constant String := "Unit name "; Unit_Und : constant String := "--------- "; Unit_Bln : constant String := " "; File_Hed : constant String := "File name "; File_Und : constant String := "--------- "; File_Bln : constant String := " "; Time_Hed : constant String := "Time stamp"; Time_Und : constant String := "----------"; Unit_Length : constant Natural := Unit_Hed'Length; File_Length : constant Natural := File_Hed'Length; begin -- First step is to make a sorted table of units for J in 1 .. Num_Units loop Sorted_Units (J) := Unit_Number_Type (Int (Units.First) + J - 1); end loop; Sort (Sorted_Units); -- Now we can generate the unit table listing Write_Eol; if not File_Names_Only then Write_Str (Unit_Hed); Write_Str (File_Hed); Write_Str (Time_Hed); Write_Eol; Write_Str (Unit_Und); Write_Str (File_Und); Write_Str (Time_Und); Write_Eol; Write_Eol; end if; for R in Sorted_Units'Range loop if File_Names_Only then if not Is_Internal_File_Name (File_Name (Source_Index (Sorted_Units (R)))) then Write_Name (Full_File_Name (Source_Index (Sorted_Units (R)))); Write_Eol; end if; else Write_Unit_Name (Unit_Name (Sorted_Units (R))); if Name_Len > (Unit_Length - 1) then Write_Eol; Write_Str (Unit_Bln); else for J in Name_Len + 1 .. Unit_Length loop Write_Char (' '); end loop; end if; Write_Name (Full_File_Name (Source_Index (Sorted_Units (R)))); if Name_Len > (File_Length - 1) then Write_Eol; Write_Str (Unit_Bln); Write_Str (File_Bln); else for J in Name_Len + 1 .. File_Length loop Write_Char (' '); end loop; end if; Write_Str (String (Time_Stamp (Source_Index (Sorted_Units (R))))); Write_Eol; end if; end loop; Write_Eol; end List; gprbuild-gpl-2014-src/gnat/prj-env.ads0000644000076700001450000003061212323721731017140 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . E N V -- -- -- -- S p e c -- -- -- -- Copyright (C) 2001-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package implements services for Project-aware tools, mostly related -- to the environment (configuration pragma files, path files, mapping files). with GNAT.Dynamic_HTables; with GNAT.OS_Lib; package Prj.Env is procedure Initialize (In_Tree : Project_Tree_Ref); -- Initialize global components relative to environment variables procedure Print_Sources (In_Tree : Project_Tree_Ref); -- Output the list of sources after Project files have been scanned procedure Create_Mapping (In_Tree : Project_Tree_Ref); -- Create in memory mapping from the sources of all the projects (in body -- of package Fmap), so that Osint.Find_File will find the correct path -- corresponding to a source. procedure Create_Temp_File (Shared : Shared_Project_Tree_Data_Access; Path_FD : out File_Descriptor; Path_Name : out Path_Name_Type; File_Use : String); -- Create temporary file, fail with an error if it could not be created procedure Create_Mapping_File (Project : Project_Id; Language : Name_Id; In_Tree : Project_Tree_Ref; Name : out Path_Name_Type); -- Create a temporary mapping file for project Project. For each source or -- template of Language in the Project, put the mapping of its file name -- and path name in this file. See fmap for a description of the format -- of the mapping file. -- -- Implementation note: we pass a language name, not a language_index here, -- since the latter would have to match exactly the index of that language -- for the specified project, and that is not information available in -- buildgpr.adb. procedure Create_Config_Pragmas_File (For_Project : Project_Id; In_Tree : Project_Tree_Ref); -- If we need SFN pragmas, either for non standard naming schemes or for -- individual units. procedure Create_New_Path_File (Shared : Shared_Project_Tree_Data_Access; Path_FD : out File_Descriptor; Path_Name : out Path_Name_Type); -- Create a new temporary path file, placing file name in Path_Name function Ada_Include_Path (Project : Project_Id; In_Tree : Project_Tree_Ref; Recursive : Boolean := False) return String; -- Get the source search path of a Project file. If Recursive it True, get -- all the source directories of the imported and modified project files -- (recursively). If Recursive is False, just get the path for the source -- directories of Project. Note: the resulting String may be empty if there -- is no source directory in the project file. function Ada_Objects_Path (Project : Project_Id; In_Tree : Project_Tree_Ref; Including_Libraries : Boolean := True) return String_Access; -- Get the ADA_OBJECTS_PATH of a Project file. For the first call with the -- exact same parameters, compute it and cache it. When Including_Libraries -- is True, the object directory of a library project is replaced with the -- library ALI directory of this project (usually the library directory of -- the project, except when attribute Library_ALI_Dir is declared) except -- when the library ALI directory does not contain any ALI file. procedure Set_Ada_Paths (Project : Project_Id; In_Tree : Project_Tree_Ref; Including_Libraries : Boolean; Include_Path : Boolean := True; Objects_Path : Boolean := True); -- Set the environment variables for additional project path files, after -- creating the path files if necessary. function File_Name_Of_Library_Unit_Body (Name : String; Project : Project_Id; In_Tree : Project_Tree_Ref; Main_Project_Only : Boolean := True; Full_Path : Boolean := False) return String; -- Returns the file name of a library unit, in canonical case. Name may or -- may not have an extension (corresponding to the naming scheme of the -- project). If there is no body with this name, but there is a spec, the -- name of the spec is returned. -- -- If Full_Path is False (the default), the simple file name is returned. -- If Full_Path is True, the absolute path name is returned. -- -- If neither a body nor a spec can be found, an empty string is returned. -- If Main_Project_Only is True, the unit must be an immediate source of -- Project. If it is False, it may be a source of one of its imported -- projects. function Project_Of (Name : String; Main_Project : Project_Id; In_Tree : Project_Tree_Ref) return Project_Id; -- Get the project of a source. The source file name may be truncated -- (".adb" or ".ads" may be missing). If the source is in a project being -- extended, return the ultimate extending project. If it is not a source -- of any project, return No_Project. procedure Get_Reference (Source_File_Name : String; In_Tree : Project_Tree_Ref; Project : out Project_Id; Path : out Path_Name_Type); -- Returns the project of a source and its path in displayable form generic with procedure Action (Path : String); procedure For_All_Source_Dirs (Project : Project_Id; In_Tree : Project_Tree_Ref); -- Iterate through all the source directories of a project, including those -- of imported or modified projects. Only returns those directories that -- potentially contain Ada sources (ie ignore projects that have no Ada -- sources generic with procedure Action (Path : String); procedure For_All_Object_Dirs (Project : Project_Id; Tree : Project_Tree_Ref); -- Iterate through all the object directories of a project, including those -- of imported or modified projects. ------------------ -- Project Path -- ------------------ type Project_Search_Path is private; -- An abstraction of the project path. This object provides subprograms -- to search for projects on the path (and caches the results to improve -- efficiency). No_Project_Search_Path : constant Project_Search_Path; procedure Initialize_Default_Project_Path (Self : in out Project_Search_Path; Target_Name : String); -- Initialize Self. It will then contain the default project path on the -- given target (including directories specified by the environment -- variables ADA_PROJECT_PATH and GPR_PROJECT_PATH). This does nothing if -- Self has already been initialized. procedure Copy (From : Project_Search_Path; To : out Project_Search_Path); -- Copy From into To procedure Initialize_Empty (Self : in out Project_Search_Path); -- Initialize self with an empty list of directories. If Self had already -- been set, it is reset. function Is_Initialized (Self : Project_Search_Path) return Boolean; -- Whether Self has been initialized procedure Free (Self : in out Project_Search_Path); -- Free the memory used by Self procedure Add_Directories (Self : in out Project_Search_Path; Path : String; Prepend : Boolean := False); -- Add one or more directories to the path. Directories added with this -- procedure are added in order after the current directory and before the -- path given by the environment variable GPR_PROJECT_PATH. A value of "-" -- will remove the default project directory from the project path. -- -- Calls to this subprogram must be performed before the first call to -- Find_Project below, or PATH will be added at the end of the search path. procedure Get_Path (Self : Project_Search_Path; Path : out String_Access); -- Return the current value of the project path, either the value set -- during elaboration of the package or, if procedure Set_Project_Path has -- been called, the value set by the last call to Set_Project_Path. The -- returned value must not be modified. -- Self must have been initialized first. procedure Set_Path (Self : in out Project_Search_Path; Path : String); -- Override the value of the project path. This also removes the implicit -- default search directories. generic with function Check_Filename (Name : String) return Boolean; function Find_Name_In_Path (Self : Project_Search_Path; Path : String) return String_Access; -- Find a name in the project search path of Self. Check_Filename is -- the predicate to valid the search. If Path is an absolute filename, -- simply calls the predicate with Path. Otherwise, calls the predicate -- for each component of the path. Stops as soon as the predicate -- returns True and returns the name, or returns null in case of failure. procedure Find_Project (Self : in out Project_Search_Path; Project_File_Name : String; Directory : String; Path : out Namet.Path_Name_Type); -- Search for a project with the given name either in Directory (which -- often will be the directory contain the project we are currently parsing -- and which we found a reference to another project), or in the project -- path Self. Self must have been initialized first. -- -- Project_File_Name can optionally contain directories, and the extension -- (.gpr) for the file name is optional. -- -- Returns No_Name if no such project was found function Get_Runtime_Path (Self : Project_Search_Path; Name : String) return String_Access; -- Compute the full path for the project-based runtime name. It first -- checks that name is not a simple name (must has a path separator in it), -- and returns null in case of failure. This check might be removed in the -- future. The name is simply searched on the project path. private package Projects_Paths is new GNAT.Dynamic_HTables.Simple_HTable (Header_Num => Header_Num, Element => Path_Name_Type, No_Element => No_Path, Key => Name_Id, Hash => Hash, Equal => "="); type Project_Search_Path is record Path : GNAT.OS_Lib.String_Access; -- As a special case, if the first character is '#:" or this variable -- is unset, this means that the PATH has not been fully initialized -- yet (although subprograms above will properly take care of that). Cache : Projects_Paths.Instance; end record; No_Project_Search_Path : constant Project_Search_Path := (Path => null, Cache => Projects_Paths.Nil); end Prj.Env; gprbuild-gpl-2014-src/gnat/makeutl.ads0000644000076700001450000006237212323721731017231 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- M A K E U T L -- -- -- -- S p e c -- -- -- -- Copyright (C) 2004-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains various subprograms used by the builders, in -- particular those subprograms related to project management and build -- queue management. with ALI; with Namet; use Namet; with Opt; with Osint; with Prj; use Prj; with Prj.Tree; with Snames; use Snames; with Table; with Types; use Types; with GNAT.OS_Lib; use GNAT.OS_Lib; package Makeutl is type Fail_Proc is access procedure (S : String); -- Pointer to procedure which outputs a failure message Root_Environment : Prj.Tree.Environment; -- The environment coming from environment variables and command line -- switches. When we do not have an aggregate project, this is used for -- parsing the project tree. When we have an aggregate project, this is -- used to parse the aggregate project; the latter then generates another -- environment (with additional external values and project path) to parse -- the aggregated projects. Default_Config_Name : constant String := "default.cgpr"; -- Name of the configuration file used by gprbuild and generated by -- gprconfig by default. On_Windows : constant Boolean := Directory_Separator = '\'; -- True when on Windows Source_Info_Option : constant String := "--source-info="; -- Switch to indicate the source info file Subdirs_Option : constant String := "--subdirs="; -- Switch used to indicate that the real directories (object, exec, -- library, ...) are subdirectories of those in the project file. Unchecked_Shared_Lib_Imports : constant String := "--unchecked-shared-lib-imports"; -- Command line switch to allow shared library projects to import projects -- that are not shared library projects. Single_Compile_Per_Obj_Dir_Switch : constant String := "--single-compile-per-obj-dir"; -- Switch to forbid simultaneous compilations for the same object directory -- when project files are used. Create_Map_File_Switch : constant String := "--create-map-file"; -- Switch to create a map file when an executable is linked Load_Standard_Base : Boolean := True; -- False when gprbuild is called with --db- package Db_Switch_Args is new Table.Table (Table_Component_Type => Name_Id, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 200, Table_Increment => 100, Table_Name => "Makegpr.Db_Switch_Args"); -- Table of all the arguments of --db switches of gprbuild package Directories is new Table.Table (Table_Component_Type => Path_Name_Type, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => 200, Table_Increment => 100, Table_Name => "Makegpr.Directories"); -- Table of all the source or object directories, filled up by -- Get_Directories. procedure Add (Option : String_Access; To : in out String_List_Access; Last : in out Natural); procedure Add (Option : String; To : in out String_List_Access; Last : in out Natural); -- Add a string to a list of strings function Absolute_Path (Path : Path_Name_Type; Project : Project_Id) return String; -- Returns an absolute path for a configuration pragmas file function Create_Binder_Mapping_File (Project_Tree : Project_Tree_Ref) return Path_Name_Type; -- Create a binder mapping file and returns its path name function Create_Name (Name : String) return File_Name_Type; function Create_Name (Name : String) return Name_Id; function Create_Name (Name : String) return Path_Name_Type; -- Get an id for a name function Base_Name_Index_For (Main : String; Main_Index : Int; Index_Separator : Character) return File_Name_Type; -- Returns the base name of Main, without the extension, followed by the -- Index_Separator followed by the Main_Index if it is non-zero. function Executable_Prefix_Path return String; -- Return the absolute path parent directory of the directory where the -- current executable resides, if its directory is named "bin", otherwise -- return an empty string. When a directory is returned, it is guaranteed -- to end with a directory separator. procedure Inform (N : Name_Id := No_Name; Msg : String); procedure Inform (N : File_Name_Type; Msg : String); -- Prints out the program name followed by a colon, N and S function File_Not_A_Source_Of (Project_Tree : Project_Tree_Ref; Uname : Name_Id; Sfile : File_Name_Type) return Boolean; -- Check that file name Sfile is one of the source of unit Uname. Returns -- True if the unit is in one of the project file, but the file name is not -- one of its source. Returns False otherwise. function Check_Source_Info_In_ALI (The_ALI : ALI.ALI_Id; Tree : Project_Tree_Ref) return Name_Id; -- Check whether all file references in ALI are still valid (i.e. the -- source files are still associated with the same units). Return the name -- of the unit if everything is still valid. Return No_Name otherwise. procedure Ensure_Absolute_Path (Switch : in out String_Access; Parent : String; Do_Fail : Fail_Proc; For_Gnatbind : Boolean := False; Including_Non_Switch : Boolean := True; Including_RTS : Boolean := False); -- Do nothing if Switch is an absolute path switch. If relative, fail if -- Parent is the empty string, otherwise prepend the path with Parent. This -- subprogram is only used when using project files. If For_Gnatbind is -- True, consider gnatbind specific syntax for -L (not a path, left -- unchanged) and -A (path is optional, preceded with "=" if present). -- If Including_RTS is True, process also switches --RTS=. Do_Fail is -- called in case of error. Using Osint.Fail might be appropriate. function Is_Subunit (Source : Source_Id) return Boolean; -- Return True if source is a subunit procedure Initialize_Source_Record (Source : Source_Id); -- Get information either about the source file, or the object and -- dependency file, as well as their timestamps. function Is_External_Assignment (Env : Prj.Tree.Environment; Argv : String) return Boolean; -- Verify that an external assignment switch is syntactically correct -- -- Correct forms are: -- -- -Xname=value -- -X"name=other value" -- -- Assumptions: 'First = 1, Argv (1 .. 2) = "-X" -- -- When this function returns True, the external assignment has been -- entered by a call to Prj.Ext.Add, so that in a project file, External -- ("name") will return "value". type Name_Ids is array (Positive range <>) of Name_Id; No_Names : constant Name_Ids := (1 .. 0 => No_Name); -- Name_Ids is used for list of language names in procedure Get_Directories -- below. Ada_Only : constant Name_Ids := (1 => Name_Ada); -- Used to invoke Get_Directories in gnatmake type Activity_Type is (Compilation, Executable_Binding, SAL_Binding); procedure Get_Directories (Project_Tree : Project_Tree_Ref; For_Project : Project_Id; Activity : Activity_Type; Languages : Name_Ids); -- Put in table Directories the source (when Sources is True) or -- object/library (when Sources is False) directories of project -- For_Project and of all the project it imports directly or indirectly. -- The source directories of imported projects are only included if one -- of the declared languages is in the list Languages. function Aggregate_Libraries_In (Tree : Project_Tree_Ref) return Boolean; -- Return True iff there is one or more aggregate library projects in -- the project tree Tree. procedure Write_Path_File (FD : File_Descriptor); -- Write in the specified open path file the directories in table -- Directories, then closed the path file. procedure Get_Switches (Source : Source_Id; Pkg_Name : Name_Id; Project_Tree : Project_Tree_Ref; Value : out Variable_Value; Is_Default : out Boolean); procedure Get_Switches (Source_File : File_Name_Type; Source_Lang : Name_Id; Source_Prj : Project_Id; Pkg_Name : Name_Id; Project_Tree : Project_Tree_Ref; Value : out Variable_Value; Is_Default : out Boolean; Test_Without_Suffix : Boolean := False; Check_ALI_Suffix : Boolean := False); -- Compute the switches (Compilation switches for instance) for the given -- file. This checks various attributes to see if there are file specific -- switches, or else defaults on the switches for the corresponding -- language. Is_Default is set to False if there were file-specific -- switches Source_File can be set to No_File to force retrieval of the -- default switches. If Test_Without_Suffix is True, and there is no " for -- Switches(Source_File) use", then this procedure also tests without the -- extension of the filename. If Test_Without_Suffix is True and -- Check_ALI_Suffix is True, then we also replace the file extension with -- ".ali" when testing. function Linker_Options_Switches (Project : Project_Id; Do_Fail : Fail_Proc; In_Tree : Project_Tree_Ref) return String_List; -- Collect the options specified in the Linker'Linker_Options attributes -- of project Project, in project tree In_Tree, and in the projects that -- it imports directly or indirectly, and returns the result. function Path_Or_File_Name (Path : Path_Name_Type) return String; -- Returns a file name if -df is used, otherwise return a path name function Unit_Index_Of (ALI_File : File_Name_Type) return Int; -- Find the index of a unit in a source file. Return zero if the file is -- not a multi-unit source file. procedure Verbose_Msg (N1 : Name_Id; S1 : String; N2 : Name_Id := No_Name; S2 : String := ""; Prefix : String := " -> "; Minimum_Verbosity : Opt.Verbosity_Level_Type := Opt.Low); procedure Verbose_Msg (N1 : File_Name_Type; S1 : String; N2 : File_Name_Type := No_File; S2 : String := ""; Prefix : String := " -> "; Minimum_Verbosity : Opt.Verbosity_Level_Type := Opt.Low); -- If the verbose flag (Verbose_Mode) is set and the verbosity level is at -- least equal to Minimum_Verbosity, then print Prefix to standard output -- followed by N1 and S1. If N2 /= No_Name then N2 is printed after S1. S2 -- is printed last. Both N1 and N2 are printed in quotation marks. The two -- forms differ only in taking Name_Id or File_name_Type arguments. ------------------------- -- Program termination -- ------------------------- procedure Fail_Program (Project_Tree : Project_Tree_Ref; S : String; Flush_Messages : Boolean := True); -- Terminate program with a message and a fatal status code procedure Finish_Program (Project_Tree : Project_Tree_Ref; Exit_Code : Osint.Exit_Code_Type := Osint.E_Success; S : String := ""); -- Terminate program, with or without a message, setting the status code -- according to Fatal. This properly removes all temporary files. -------------- -- Switches -- -------------- generic with function Add_Switch (Switch : String; For_Lang : Name_Id; For_Builder : Boolean; Has_Global_Compilation_Switches : Boolean) return Boolean; -- For_Builder is true if we have a builder switch. This function -- should return True in case of success (the switch is valid), -- False otherwise. The error message will be displayed by -- Compute_Builder_Switches itself. -- -- Has_Global_Compilation_Switches is True if the attribute -- Global_Compilation_Switches is defined in the project. procedure Compute_Builder_Switches (Project_Tree : Project_Tree_Ref; Env : in out Prj.Tree.Environment; Main_Project : Project_Id; Only_For_Lang : Name_Id := No_Name); -- Compute the builder switches and global compilation switches. Every time -- a switch is found in the project, it is passed to Add_Switch. You can -- provide a value for Only_For_Lang so that we only look for this language -- when parsing the global compilation switches. ----------------------- -- Project_Tree data -- ----------------------- -- The following types are specific to builders, and associated with each -- of the loaded project trees. type Binding_Data_Record; type Binding_Data is access Binding_Data_Record; type Binding_Data_Record is record Language : Language_Ptr; Language_Name : Name_Id; Binder_Driver_Name : File_Name_Type; Binder_Driver_Path : String_Access; Binder_Prefix : Name_Id; Next : Binding_Data; end record; -- Data for a language that have a binder driver type Builder_Project_Tree_Data is new Project_Tree_Appdata with record Binding : Binding_Data; There_Are_Binder_Drivers : Boolean := False; -- True when there is a binder driver. Set by Get_Configuration when -- an attribute Language_Processing'Binder_Driver is declared. -- Reset to False if there are no sources of the languages with binder -- drivers. Number_Of_Mains : Natural := 0; -- Number of main units in this project tree Closure_Needed : Boolean := False; -- If True, we need to add the closure of the file we just compiled to -- the queue. If False, it is assumed that all files are already on the -- queue so we do not waste time computing the closure. Need_Compilation : Boolean := True; Need_Binding : Boolean := True; Need_Linking : Boolean := True; -- Which of the compilation phases are needed for this project tree end record; type Builder_Data_Access is access all Builder_Project_Tree_Data; procedure Free (Data : in out Builder_Project_Tree_Data); -- Free all memory allocated for Data function Builder_Data (Tree : Project_Tree_Ref) return Builder_Data_Access; -- Return (allocate if needed) tree-specific data procedure Compute_Compilation_Phases (Tree : Project_Tree_Ref; Root_Project : Project_Id; Option_Unique_Compile : Boolean := False; -- Was "-u" specified ? Option_Compile_Only : Boolean := False; -- Was "-c" specified ? Option_Bind_Only : Boolean := False; Option_Link_Only : Boolean := False); -- Compute which compilation phases will be needed for Tree. This also does -- the computation for aggregated trees. This also check whether we'll need -- to check the closure of the files we have just compiled to add them to -- the queue. ----------- -- Mains -- ----------- -- Package Mains is used to store the mains specified on the command line -- and to retrieve them when a project file is used, to verify that the -- files exist and that they belong to a project file. -- Mains are stored in a table. An index is used to retrieve the mains -- from the table. type Main_Info is record File : File_Name_Type; -- Always canonical casing Index : Int := 0; Location : Source_Ptr := No_Location; Source : Prj.Source_Id := No_Source; Project : Project_Id; Tree : Project_Tree_Ref; end record; No_Main_Info : constant Main_Info := (No_File, 0, No_Location, No_Source, No_Project, null); package Mains is procedure Add_Main (Name : String; Index : Int := 0; Location : Source_Ptr := No_Location; Project : Project_Id := No_Project; Tree : Project_Tree_Ref := null); -- Add one main to the table. This is in general used to add the main -- files specified on the command line. Index is used for multi-unit -- source files, and indicates which unit in the source is concerned. -- Location is the location within the project file (if a project file -- is used). Project and Tree indicate to which project the main should -- belong. In particular, for aggregate projects, this isn't necessarily -- the main project tree. These can be set to No_Project and null when -- not using projects. procedure Delete; -- Empty the table procedure Reset; -- Reset the cursor to the beginning of the table procedure Set_Multi_Unit_Index (Project_Tree : Project_Tree_Ref := null; Index : Int := 0); -- If a single main file was defined, this subprogram indicates which -- unit inside it is the main (case of a multi-unit source files). -- Errors are raised if zero or more than one main file was defined, -- and Index is non-zaero. This subprogram is used for the handling -- of the command line switch. function Next_Main return String; function Next_Main return Main_Info; -- Moves the cursor forward and returns the new current entry. Returns -- No_Main_Info there are no more mains in the table. function Number_Of_Mains (Tree : Project_Tree_Ref) return Natural; -- Returns the number of mains in this project tree (if Tree is null, it -- returns the total number of project trees) procedure Fill_From_Project (Root_Project : Project_Id; Project_Tree : Project_Tree_Ref); -- If no main was already added (presumably from the command line), add -- the main units from root_project (or in the case of an aggregate -- project from all the aggregated projects). procedure Complete_Mains (Flags : Processing_Flags; Root_Project : Project_Id; Project_Tree : Project_Tree_Ref); -- If some main units were already added from the command line, check -- that they all belong to the root project, and that they are full -- paths rather than (partial) base names (e.g. no body suffix was -- specified). end Mains; ----------- -- Queue -- ----------- type Source_Info_Format is (Format_Gprbuild, Format_Gnatmake); package Queue is -- The queue of sources to be checked for compilation. There can be a -- single such queue per application. type Source_Info (Format : Source_Info_Format := Format_Gprbuild) is record case Format is when Format_Gprbuild => Tree : Project_Tree_Ref := No_Project_Tree; Id : Source_Id := No_Source; when Format_Gnatmake => File : File_Name_Type := No_File; Unit : Unit_Name_Type := No_Unit_Name; Index : Int := 0; Project : Project_Id := No_Project; Sid : Source_Id := No_Source; end case; end record; -- Information about files stored in the queue. The exact information -- depends on the builder, and in particular whether it only supports -- project-based files (in which case we have a full Source_Id record). No_Source_Info : constant Source_Info := (Format_Gprbuild, null, null); procedure Initialize (Queue_Per_Obj_Dir : Boolean; Force : Boolean := False); -- Initialize the queue -- -- Queue_Per_Obj_Dir matches the --single-compile-per-obj-dir switch: -- when True, there cannot be simultaneous compilations with the object -- files in the same object directory when project files are used. -- -- Nothing is done if Force is False and the queue was already -- initialized. procedure Remove_Marks; -- Remove all marks set for the files. This means that the files will be -- handed to the compiler if they are added to the queue, and is mostly -- useful when recompiling several executables in non-project mode, as -- the switches may be different and -s may be in use. function Is_Empty return Boolean; -- Returns True if the queue is empty function Is_Virtually_Empty return Boolean; -- Returns True if queue is empty or if all object directories are busy procedure Insert (Source : Source_Info; With_Roots : Boolean := False); function Insert (Source : Source_Info; With_Roots : Boolean := False) return Boolean; -- Insert source in the queue. The second version returns False if the -- Source was already marked in the queue. If With_Roots is True and the -- source is in Format_Gprbuild mode (ie with a project), this procedure -- also includes the "Roots" for this main, ie all the other files that -- must be included in the library or binary (in particular to combine -- Ada and C files connected through pragma Export/Import). When the -- roots are computed, they are also stored in the corresponding -- Source_Id for later reuse by the binder. procedure Insert_Project_Sources (Project : Project_Id; Project_Tree : Project_Tree_Ref; All_Projects : Boolean; Unique_Compile : Boolean); -- Insert all the compilable sources of the project in the queue. If -- All_Project is true, then all sources from imported projects are also -- inserted. Unique_Compile should be true if "-u" was specified on the -- command line: if True and some files were given on the command line), -- only those files will be compiled (so Insert_Project_Sources will do -- nothing). If True and no file was specified on the command line, all -- files of the project(s) will be compiled. This procedure also -- processed aggregated projects. procedure Insert_Withed_Sources_For (The_ALI : ALI.ALI_Id; Project_Tree : Project_Tree_Ref; Excluding_Shared_SALs : Boolean := False); -- Insert in the queue those sources withed by The_ALI, if there are not -- already in the queue and Only_Interfaces is False or they are part of -- the interfaces of their project. procedure Extract (Found : out Boolean; Source : out Source_Info); -- Get the first source that can be compiled from the queue. If no -- source may be compiled, sets Found to False. In this case, the value -- for Source is undefined. function Size return Natural; -- Return the total size of the queue, including the sources already -- extracted. function Processed return Natural; -- Return the number of source in the queue that have aready been -- processed. procedure Set_Obj_Dir_Busy (Obj_Dir : Path_Name_Type); procedure Set_Obj_Dir_Free (Obj_Dir : Path_Name_Type); -- Mark Obj_Dir as busy or free (see the parameter to Initialize) function Element (Rank : Positive) return File_Name_Type; -- Get the file name for element of index Rank in the queue end Queue; end Makeutl; gprbuild-gpl-2014-src/gnat/hostparm.ads0000644000076700001450000001104512323721731017413 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- H O S T P A R M -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package defines some system dependent parameters for GNAT. These -- are parameters that are relevant to the host machine on which the -- compiler is running, and thus this package is part of the compiler. with Types; package Hostparm is --------------------- -- HOST Parameters -- --------------------- Gnat_VMSp : Integer; pragma Import (C, Gnat_VMSp, "__gnat_vmsp"); OpenVMS : Boolean := Gnat_VMSp /= 0; -- Set True for OpenVMS host. See also OpenVMS target boolean in -- system-vms.ads and system-vms_64.ads and OpenVMS_On_Target boolean in -- Targparm. This is not a constant, because it can be modified by -gnatdm. Direct_Separator : constant Character; pragma Import (C, Direct_Separator, "__gnat_dir_separator"); Normalized_CWD : constant String := "." & Direct_Separator; -- Normalized string to access current directory Max_Line_Length : constant := Types.Column_Number'Pred (Types.Column_Number'Last); -- Maximum source line length. By default we set it to the maximum -- value that can be supported, which is given by the range of the -- Column_Number type. We subtract 1 because need to be able to -- have a valid Column_Number equal to Max_Line_Length to represent -- the location of a "line too long" error. -- -- 200 is the minimum value required (RM 2.2(15)). The value set here -- can be reduced by the explicit use of the -gnatyM style switch. Max_Name_Length : constant := 1024; -- Maximum length of unit name (including all dots, and " (spec)") and -- of file names in the library, must be at least Max_Line_Length, but -- can be larger. Tag_Errors : constant Boolean := False; -- If set to true, then brief form error messages will be prefaced by -- the string "error:". Used as default for Opt.Unique_Error_Tag. Exclude_Missing_Objects : constant Boolean := True; -- If set to true, gnatbind will exclude from consideration all -- non-existent .o files. Max_Debug_Name_Length : constant := 256; -- If a generated qualified debug name exceeds this length, then it -- is automatically compressed, regardless of the setting of the -- Compress_Debug_Names switch controlled by -gnatC. end Hostparm; gprbuild-gpl-2014-src/gnat/elists.adb0000644000076700001450000003710612323721731017046 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- E L I S T S -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- WARNING: There is a C version of this package. Any changes to this -- source file must be properly reflected in the C header a-elists.h. with Alloc; with Debug; use Debug; with Output; use Output; with Table; package body Elists is ------------------------------------- -- Implementation of Element Lists -- ------------------------------------- -- Element lists are composed of three types of entities. The element -- list header, which references the first and last elements of the -- list, the elements themselves which are singly linked and also -- reference the nodes on the list, and finally the nodes themselves. -- The following diagram shows how an element list is represented: -- +----------------------------------------------------+ -- | +------------------------------------------+ | -- | | | | -- V | V | -- +-----|--+ +-------+ +-------+ +-------+ | -- | Elmt | | 1st | | 2nd | | Last | | -- | List |--->| Elmt |--->| Elmt ---...-->| Elmt ---+ -- | Header | | | | | | | | | | -- +--------+ +---|---+ +---|---+ +---|---+ -- | | | -- V V V -- +-------+ +-------+ +-------+ -- | | | | | | -- | Node1 | | Node2 | | Node3 | -- | | | | | | -- +-------+ +-------+ +-------+ -- The list header is an entry in the Elists table. The values used for -- the type Elist_Id are subscripts into this table. The First_Elmt field -- (Lfield1) points to the first element on the list, or to No_Elmt in the -- case of an empty list. Similarly the Last_Elmt field (Lfield2) points to -- the last element on the list or to No_Elmt in the case of an empty list. -- The elements themselves are entries in the Elmts table. The Next field -- of each entry points to the next element, or to the Elist header if this -- is the last item in the list. The Node field points to the node which -- is referenced by the corresponding list entry. ------------------------- -- Element List Tables -- ------------------------- type Elist_Header is record First : Elmt_Id; Last : Elmt_Id; end record; package Elists is new Table.Table ( Table_Component_Type => Elist_Header, Table_Index_Type => Elist_Id'Base, Table_Low_Bound => First_Elist_Id, Table_Initial => Alloc.Elists_Initial, Table_Increment => Alloc.Elists_Increment, Table_Name => "Elists"); type Elmt_Item is record Node : Node_Or_Entity_Id; Next : Union_Id; end record; package Elmts is new Table.Table ( Table_Component_Type => Elmt_Item, Table_Index_Type => Elmt_Id'Base, Table_Low_Bound => First_Elmt_Id, Table_Initial => Alloc.Elmts_Initial, Table_Increment => Alloc.Elmts_Increment, Table_Name => "Elmts"); ----------------- -- Append_Elmt -- ----------------- procedure Append_Elmt (N : Node_Or_Entity_Id; To : Elist_Id) is L : constant Elmt_Id := Elists.Table (To).Last; begin Elmts.Increment_Last; Elmts.Table (Elmts.Last).Node := N; Elmts.Table (Elmts.Last).Next := Union_Id (To); if L = No_Elmt then Elists.Table (To).First := Elmts.Last; else Elmts.Table (L).Next := Union_Id (Elmts.Last); end if; Elists.Table (To).Last := Elmts.Last; if Debug_Flag_N then Write_Str ("Append new element Elmt_Id = "); Write_Int (Int (Elmts.Last)); Write_Str (" to list Elist_Id = "); Write_Int (Int (To)); Write_Str (" referencing Node_Or_Entity_Id = "); Write_Int (Int (N)); Write_Eol; end if; end Append_Elmt; ------------------------ -- Append_Unique_Elmt -- ------------------------ procedure Append_Unique_Elmt (N : Node_Or_Entity_Id; To : Elist_Id) is Elmt : Elmt_Id; begin Elmt := First_Elmt (To); loop if No (Elmt) then Append_Elmt (N, To); return; elsif Node (Elmt) = N then return; else Next_Elmt (Elmt); end if; end loop; end Append_Unique_Elmt; -------------- -- Contains -- -------------- function Contains (List : Elist_Id; N : Node_Or_Entity_Id) return Boolean is Elmt : Elmt_Id; begin if Present (List) then Elmt := First_Elmt (List); while Present (Elmt) loop if Node (Elmt) = N then return True; end if; Next_Elmt (Elmt); end loop; end if; return False; end Contains; -------------------- -- Elists_Address -- -------------------- function Elists_Address return System.Address is begin return Elists.Table (First_Elist_Id)'Address; end Elists_Address; ------------------- -- Elmts_Address -- ------------------- function Elmts_Address return System.Address is begin return Elmts.Table (First_Elmt_Id)'Address; end Elmts_Address; ---------------- -- First_Elmt -- ---------------- function First_Elmt (List : Elist_Id) return Elmt_Id is begin pragma Assert (List > Elist_Low_Bound); return Elists.Table (List).First; end First_Elmt; ---------------- -- Initialize -- ---------------- procedure Initialize is begin Elists.Init; Elmts.Init; end Initialize; ----------------------- -- Insert_Elmt_After -- ----------------------- procedure Insert_Elmt_After (N : Node_Or_Entity_Id; Elmt : Elmt_Id) is Nxt : constant Union_Id := Elmts.Table (Elmt).Next; begin pragma Assert (Elmt /= No_Elmt); Elmts.Increment_Last; Elmts.Table (Elmts.Last).Node := N; Elmts.Table (Elmts.Last).Next := Nxt; Elmts.Table (Elmt).Next := Union_Id (Elmts.Last); if Nxt in Elist_Range then Elists.Table (Elist_Id (Nxt)).Last := Elmts.Last; end if; end Insert_Elmt_After; ------------------------ -- Is_Empty_Elmt_List -- ------------------------ function Is_Empty_Elmt_List (List : Elist_Id) return Boolean is begin return Elists.Table (List).First = No_Elmt; end Is_Empty_Elmt_List; ------------------- -- Last_Elist_Id -- ------------------- function Last_Elist_Id return Elist_Id is begin return Elists.Last; end Last_Elist_Id; --------------- -- Last_Elmt -- --------------- function Last_Elmt (List : Elist_Id) return Elmt_Id is begin return Elists.Table (List).Last; end Last_Elmt; ------------------ -- Last_Elmt_Id -- ------------------ function Last_Elmt_Id return Elmt_Id is begin return Elmts.Last; end Last_Elmt_Id; ---------- -- Lock -- ---------- procedure Lock is begin Elists.Locked := True; Elmts.Locked := True; Elists.Release; Elmts.Release; end Lock; -------------------- -- New_Copy_Elist -- -------------------- function New_Copy_Elist (List : Elist_Id) return Elist_Id is Result : Elist_Id; Elmt : Elmt_Id; begin if List = No_Elist then return No_Elist; -- Replicate the contents of the input list while preserving the -- original order. else Result := New_Elmt_List; Elmt := First_Elmt (List); while Present (Elmt) loop Append_Elmt (Node (Elmt), Result); Next_Elmt (Elmt); end loop; return Result; end if; end New_Copy_Elist; ------------------- -- New_Elmt_List -- ------------------- function New_Elmt_List return Elist_Id is begin Elists.Increment_Last; Elists.Table (Elists.Last).First := No_Elmt; Elists.Table (Elists.Last).Last := No_Elmt; if Debug_Flag_N then Write_Str ("Allocate new element list, returned ID = "); Write_Int (Int (Elists.Last)); Write_Eol; end if; return Elists.Last; end New_Elmt_List; --------------- -- Next_Elmt -- --------------- function Next_Elmt (Elmt : Elmt_Id) return Elmt_Id is N : constant Union_Id := Elmts.Table (Elmt).Next; begin if N in Elist_Range then return No_Elmt; else return Elmt_Id (N); end if; end Next_Elmt; procedure Next_Elmt (Elmt : in out Elmt_Id) is begin Elmt := Next_Elmt (Elmt); end Next_Elmt; -------- -- No -- -------- function No (List : Elist_Id) return Boolean is begin return List = No_Elist; end No; function No (Elmt : Elmt_Id) return Boolean is begin return Elmt = No_Elmt; end No; ---------- -- Node -- ---------- function Node (Elmt : Elmt_Id) return Node_Or_Entity_Id is begin if Elmt = No_Elmt then return Empty; else return Elmts.Table (Elmt).Node; end if; end Node; ---------------- -- Num_Elists -- ---------------- function Num_Elists return Nat is begin return Int (Elmts.Last) - Int (Elmts.First) + 1; end Num_Elists; ------------------ -- Prepend_Elmt -- ------------------ procedure Prepend_Elmt (N : Node_Or_Entity_Id; To : Elist_Id) is F : constant Elmt_Id := Elists.Table (To).First; begin Elmts.Increment_Last; Elmts.Table (Elmts.Last).Node := N; if F = No_Elmt then Elists.Table (To).Last := Elmts.Last; Elmts.Table (Elmts.Last).Next := Union_Id (To); else Elmts.Table (Elmts.Last).Next := Union_Id (F); end if; Elists.Table (To).First := Elmts.Last; end Prepend_Elmt; ------------- -- Present -- ------------- function Present (List : Elist_Id) return Boolean is begin return List /= No_Elist; end Present; function Present (Elmt : Elmt_Id) return Boolean is begin return Elmt /= No_Elmt; end Present; ------------ -- Remove -- ------------ procedure Remove (List : Elist_Id; N : Node_Or_Entity_Id) is Elmt : Elmt_Id; begin if Present (List) then Elmt := First_Elmt (List); while Present (Elmt) loop if Node (Elmt) = N then Remove_Elmt (List, Elmt); exit; end if; Next_Elmt (Elmt); end loop; end if; end Remove; ----------------- -- Remove_Elmt -- ----------------- procedure Remove_Elmt (List : Elist_Id; Elmt : Elmt_Id) is Nxt : Elmt_Id; Prv : Elmt_Id; begin Nxt := Elists.Table (List).First; -- Case of removing only element in the list if Elmts.Table (Nxt).Next in Elist_Range then pragma Assert (Nxt = Elmt); Elists.Table (List).First := No_Elmt; Elists.Table (List).Last := No_Elmt; -- Case of removing the first element in the list elsif Nxt = Elmt then Elists.Table (List).First := Elmt_Id (Elmts.Table (Nxt).Next); -- Case of removing second or later element in the list else loop Prv := Nxt; Nxt := Elmt_Id (Elmts.Table (Prv).Next); exit when Nxt = Elmt or else Elmts.Table (Nxt).Next in Elist_Range; end loop; pragma Assert (Nxt = Elmt); Elmts.Table (Prv).Next := Elmts.Table (Nxt).Next; if Elmts.Table (Prv).Next in Elist_Range then Elists.Table (List).Last := Prv; end if; end if; end Remove_Elmt; ---------------------- -- Remove_Last_Elmt -- ---------------------- procedure Remove_Last_Elmt (List : Elist_Id) is Nxt : Elmt_Id; Prv : Elmt_Id; begin Nxt := Elists.Table (List).First; -- Case of removing only element in the list if Elmts.Table (Nxt).Next in Elist_Range then Elists.Table (List).First := No_Elmt; Elists.Table (List).Last := No_Elmt; -- Case of at least two elements in list else loop Prv := Nxt; Nxt := Elmt_Id (Elmts.Table (Prv).Next); exit when Elmts.Table (Nxt).Next in Elist_Range; end loop; Elmts.Table (Prv).Next := Elmts.Table (Nxt).Next; Elists.Table (List).Last := Prv; end if; end Remove_Last_Elmt; ------------------ -- Replace_Elmt -- ------------------ procedure Replace_Elmt (Elmt : Elmt_Id; New_Node : Node_Or_Entity_Id) is begin Elmts.Table (Elmt).Node := New_Node; end Replace_Elmt; --------------- -- Tree_Read -- --------------- procedure Tree_Read is begin Elists.Tree_Read; Elmts.Tree_Read; end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is begin Elists.Tree_Write; Elmts.Tree_Write; end Tree_Write; ------------ -- Unlock -- ------------ procedure Unlock is begin Elists.Locked := False; Elmts.Locked := False; end Unlock; end Elists; gprbuild-gpl-2014-src/gnat/types.ads0000644000076700001450000012615512323721731016733 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- T Y P E S -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains host independent type definitions which are used -- in more than one unit in the compiler. They are gathered here for easy -- reference, although in some cases the full description is found in the -- relevant module which implements the definition. The main reason that they -- are not in their "natural" specs is that this would cause a lot of inter- -- spec dependencies, and in particular some awkward circular dependencies -- would have to be dealt with. -- WARNING: There is a C version of this package. Any changes to this source -- file must be properly reflected in the C header file types.h declarations. -- Note: the declarations in this package reflect an expectation that the host -- machine has an efficient integer base type with a range at least 32 bits -- 2s-complement. If there are any machines for which this is not a correct -- assumption, a significant number of changes will be required. with System; with Unchecked_Conversion; with Unchecked_Deallocation; package Types is pragma Preelaborate; ------------------------------- -- General Use Integer Types -- ------------------------------- type Int is range -2 ** 31 .. +2 ** 31 - 1; -- Signed 32-bit integer subtype Nat is Int range 0 .. Int'Last; -- Non-negative Int values subtype Pos is Int range 1 .. Int'Last; -- Positive Int values type Word is mod 2 ** 32; -- Unsigned 32-bit integer type Short is range -32768 .. +32767; for Short'Size use 16; -- 16-bit signed integer type Byte is mod 2 ** 8; for Byte'Size use 8; -- 8-bit unsigned integer type size_t is mod 2 ** Standard'Address_Size; -- Memory size value, for use in calls to C routines -------------------------------------- -- 8-Bit Character and String Types -- -------------------------------------- -- We use Standard.Character and Standard.String freely, since we are -- compiling ourselves, and we properly implement the required 8-bit -- character code as required in Ada 95. This section defines a few -- general use constants and subtypes. EOF : constant Character := ASCII.SUB; -- The character SUB (16#1A#) is used in DOS and other systems derived -- from DOS (XP, NT etc) to signal the end of a text file. Internally -- all source files are ended by an EOF character, even on Unix systems. -- An EOF character acts as the end of file only as the last character -- of a source buffer, in any other position, it is treated as a blank -- if it appears between tokens, and as an illegal character otherwise. -- This makes life easier dealing with files that originated from DOS, -- including concatenated files with interspersed EOF characters. subtype Graphic_Character is Character range ' ' .. '~'; -- Graphic characters, as defined in ARM subtype Line_Terminator is Character range ASCII.LF .. ASCII.CR; -- Line terminator characters (LF, VT, FF, CR). For further details, see -- the extensive discussion of line termination in the Sinput spec. subtype Upper_Half_Character is Character range Character'Val (16#80#) .. Character'Val (16#FF#); -- Characters with the upper bit set type Character_Ptr is access all Character; type String_Ptr is access all String; -- Standard character and string pointers procedure Free is new Unchecked_Deallocation (String, String_Ptr); -- Procedure for freeing dynamically allocated String values subtype Big_String is String (Positive); type Big_String_Ptr is access all Big_String; -- Virtual type for handling imported big strings. Note that we should -- never have any allocators for this type, but we don't give a storage -- size of zero, since there are legitimate deallocations going on. function To_Big_String_Ptr is new Unchecked_Conversion (System.Address, Big_String_Ptr); -- Used to obtain Big_String_Ptr values from external addresses subtype Word_Hex_String is String (1 .. 8); -- Type used to represent Word value as 8 hex digits, with lower case -- letters for the alphabetic cases. function Get_Hex_String (W : Word) return Word_Hex_String; -- Convert word value to 8-character hex string ----------------------------------------- -- Types Used for Text Buffer Handling -- ----------------------------------------- -- We can not use type String for text buffers, since we must use the -- standard 32-bit integer as an index value, since we count on all index -- values being the same size. type Text_Ptr is new Int; -- Type used for subscripts in text buffer type Text_Buffer is array (Text_Ptr range <>) of Character; -- Text buffer used to hold source file or library information file type Text_Buffer_Ptr is access all Text_Buffer; -- Text buffers for input files are allocated dynamically and this type -- is used to reference these text buffers. procedure Free is new Unchecked_Deallocation (Text_Buffer, Text_Buffer_Ptr); -- Procedure for freeing dynamically allocated text buffers ------------------------------------------ -- Types Used for Source Input Handling -- ------------------------------------------ type Logical_Line_Number is range 0 .. Int'Last; for Logical_Line_Number'Size use 32; -- Line number type, used for storing logical line numbers (i.e. line -- numbers that include effects of any Source_Reference pragmas in the -- source file). The value zero indicates a line containing a source -- reference pragma. No_Line_Number : constant Logical_Line_Number := 0; -- Special value used to indicate no line number type Physical_Line_Number is range 1 .. Int'Last; for Physical_Line_Number'Size use 32; -- Line number type, used for storing physical line numbers (i.e. line -- numbers in the physical file being compiled, unaffected by the presence -- of source reference pragmas). type Column_Number is range 0 .. 32767; for Column_Number'Size use 16; -- Column number (assume that 2**15 - 1 is large enough). The range for -- this type is used to compute Hostparm.Max_Line_Length. See also the -- processing for -gnatyM in Stylesw). No_Column_Number : constant Column_Number := 0; -- Special value used to indicate no column number Source_Align : constant := 2 ** 12; -- Alignment requirement for source buffers (by keeping source buffers -- aligned, we can optimize the implementation of Get_Source_File_Index. -- See this routine in Sinput for details. subtype Source_Buffer is Text_Buffer; -- Type used to store text of a source file. The buffer for the main -- source (the source specified on the command line) has a lower bound -- starting at zero. Subsequent subsidiary sources have lower bounds -- which are one greater than the previous upper bound, rounded up to -- a multiple of Source_Align. subtype Big_Source_Buffer is Text_Buffer (0 .. Text_Ptr'Last); -- This is a virtual type used as the designated type of the access type -- Source_Buffer_Ptr, see Osint.Read_Source_File for details. type Source_Buffer_Ptr is access all Big_Source_Buffer; -- Pointer to source buffer. We use virtual origin addressing for source -- buffers, with thin pointers. The pointer points to a virtual instance -- of type Big_Source_Buffer, where the actual type is in fact of type -- Source_Buffer. The address is adjusted so that the virtual origin -- addressing works correctly. See Osint.Read_Source_Buffer for further -- details. Again, as for Big_String_Ptr, we should never allocate using -- this type, but we don't give a storage size clause of zero, since we -- may end up doing deallocations of instances allocated manually. subtype Source_Ptr is Text_Ptr; -- Type used to represent a source location, which is a subscript of a -- character in the source buffer. As noted above, different source buffers -- have different ranges, so it is possible to tell from a Source_Ptr value -- which source it refers to. Note that negative numbers are allowed to -- accommodate the following special values. No_Location : constant Source_Ptr := -1; -- Value used to indicate no source position set in a node. A test for a -- Source_Ptr value being > No_Location is the approved way to test for a -- standard value that does not include No_Location or any of the following -- special definitions. One important use of No_Location is to label -- generated nodes that we don't want the debugger to see in normal mode -- (very often we conditionalize so that we set No_Location in normal mode -- and the corresponding source line in -gnatD mode). Standard_Location : constant Source_Ptr := -2; -- Used for all nodes in the representation of package Standard other than -- nodes representing the contents of Standard.ASCII. Note that testing for -- a value being <= Standard_Location tests for both Standard_Location and -- for Standard_ASCII_Location. Standard_ASCII_Location : constant Source_Ptr := -3; -- Used for all nodes in the presentation of package Standard.ASCII System_Location : constant Source_Ptr := -4; -- Used to identify locations of pragmas scanned by Targparm, where we know -- the location is in System, but we don't know exactly what line. First_Source_Ptr : constant Source_Ptr := 0; -- Starting source pointer index value for first source program ------------------------------------- -- Range Definitions for Tree Data -- ------------------------------------- -- The tree has fields that can hold any of the following types: -- Pointers to other tree nodes (type Node_Id) -- List pointers (type List_Id) -- Element list pointers (type Elist_Id) -- Names (type Name_Id) -- Strings (type String_Id) -- Universal integers (type Uint) -- Universal reals (type Ureal) -- In most contexts, the strongly typed interface determines which of these -- types is present. However, there are some situations (involving untyped -- traversals of the tree), where it is convenient to be easily able to -- distinguish these values. The underlying representation in all cases is -- an integer type Union_Id, and we ensure that the range of the various -- possible values for each of the above types is disjoint so that this -- distinction is possible. -- Note: it is also helpful for debugging purposes to make these ranges -- distinct. If a bug leads to misidentification of a value, then it will -- typically result in an out of range value and a Constraint_Error. type Union_Id is new Int; -- The type in the tree for a union of possible ID values List_Low_Bound : constant := -100_000_000; -- The List_Id values are subscripts into an array of list headers which -- has List_Low_Bound as its lower bound. This value is chosen so that all -- List_Id values are negative, and the value zero is in the range of both -- List_Id and Node_Id values (see further description below). List_High_Bound : constant := 0; -- Maximum List_Id subscript value. This allows up to 100 million list Id -- values, which is in practice infinite, and there is no need to check the -- range. The range overlaps the node range by one element (with value -- zero), which is used both for the Empty node, and for indicating no -- list. The fact that the same value is used is convenient because it -- means that the default value of Empty applies to both nodes and lists, -- and also is more efficient to test for. Node_Low_Bound : constant := 0; -- The tree Id values start at zero, because we use zero for Empty (to -- allow a zero test for Empty). Actual tree node subscripts start at 0 -- since Empty is a legitimate node value. Node_High_Bound : constant := 099_999_999; -- Maximum number of nodes that can be allocated is 100 million, which -- is in practice infinite, and there is no need to check the range. Elist_Low_Bound : constant := 100_000_000; -- The Elist_Id values are subscripts into an array of elist headers which -- has Elist_Low_Bound as its lower bound. Elist_High_Bound : constant := 199_999_999; -- Maximum Elist_Id subscript value. This allows up to 100 million Elists, -- which is in practice infinite and there is no need to check the range. Elmt_Low_Bound : constant := 200_000_000; -- Low bound of element Id values. The use of these values is internal to -- the Elists package, but the definition of the range is included here -- since it must be disjoint from other Id values. The Elmt_Id values are -- subscripts into an array of list elements which has this as lower bound. Elmt_High_Bound : constant := 299_999_999; -- Upper bound of Elmt_Id values. This allows up to 100 million element -- list members, which is in practice infinite (no range check needed). Names_Low_Bound : constant := 300_000_000; -- Low bound for name Id values Names_High_Bound : constant := 399_999_999; -- Maximum number of names that can be allocated is 100 million, which is -- in practice infinite and there is no need to check the range. Strings_Low_Bound : constant := 400_000_000; -- Low bound for string Id values Strings_High_Bound : constant := 499_999_999; -- Maximum number of strings that can be allocated is 100 million, which -- is in practice infinite and there is no need to check the range. Ureal_Low_Bound : constant := 500_000_000; -- Low bound for Ureal values Ureal_High_Bound : constant := 599_999_999; -- Maximum number of Ureal values stored is 100_000_000 which is in -- practice infinite so that no check is required. Uint_Low_Bound : constant := 600_000_000; -- Low bound for Uint values Uint_Table_Start : constant := 2_000_000_000; -- Location where table entries for universal integers start (see -- Uintp spec for details of the representation of Uint values). Uint_High_Bound : constant := 2_099_999_999; -- The range of Uint values is very large, since a substantial part -- of this range is used to store direct values, see Uintp for details. -- The following subtype definitions are used to provide convenient names -- for membership tests on Int values to see what data type range they -- lie in. Such tests appear only in the lowest level packages. subtype List_Range is Union_Id range List_Low_Bound .. List_High_Bound; subtype Node_Range is Union_Id range Node_Low_Bound .. Node_High_Bound; subtype Elist_Range is Union_Id range Elist_Low_Bound .. Elist_High_Bound; subtype Elmt_Range is Union_Id range Elmt_Low_Bound .. Elmt_High_Bound; subtype Names_Range is Union_Id range Names_Low_Bound .. Names_High_Bound; subtype Strings_Range is Union_Id range Strings_Low_Bound .. Strings_High_Bound; subtype Uint_Range is Union_Id range Uint_Low_Bound .. Uint_High_Bound; subtype Ureal_Range is Union_Id range Ureal_Low_Bound .. Ureal_High_Bound; ----------------------------- -- Types for Atree Package -- ----------------------------- -- Node_Id values are used to identify nodes in the tree. They are -- subscripts into the Nodes table declared in package Atree. Note that -- the special values Empty and Error are subscripts into this table. -- See package Atree for further details. type Node_Id is range Node_Low_Bound .. Node_High_Bound; -- Type used to identify nodes in the tree subtype Entity_Id is Node_Id; -- A synonym for node types, used in the Einfo package to refer to nodes -- that are entities (i.e. nodes with an Nkind of N_Defining_xxx). All such -- nodes are extended nodes and these are the only extended nodes, so that -- in practice entity and extended nodes are synonymous. subtype Node_Or_Entity_Id is Node_Id; -- A synonym for node types, used in cases where a given value may be used -- to represent either a node or an entity. We like to minimize such uses -- for obvious reasons of logical type consistency, but where such uses -- occur, they should be documented by use of this type. Empty : constant Node_Id := Node_Low_Bound; -- Used to indicate null node. A node is actually allocated with this -- Id value, so that Nkind (Empty) = N_Empty. Note that Node_Low_Bound -- is zero, so Empty = No_List = zero. Empty_List_Or_Node : constant := 0; -- This constant is used in situations (e.g. initializing empty fields) -- where the value set will be used to represent either an empty node or -- a non-existent list, depending on the context. Error : constant Node_Id := Node_Low_Bound + 1; -- Used to indicate an error in the source program. A node is actually -- allocated with this Id value, so that Nkind (Error) = N_Error. Empty_Or_Error : constant Node_Id := Error; -- Since Empty and Error are the first two Node_Id values, the test for -- N <= Empty_Or_Error tests to see if N is Empty or Error. This definition -- provides convenient self-documentation for such tests. First_Node_Id : constant Node_Id := Node_Low_Bound; -- Subscript of first allocated node. Note that Empty and Error are both -- allocated nodes, whose Nkind fields can be accessed without error. ------------------------------ -- Types for Nlists Package -- ------------------------------ -- List_Id values are used to identify node lists stored in the tree, so -- that each node can be on at most one such list (see package Nlists for -- further details). Note that the special value Error_List is a subscript -- in this table, but the value No_List is *not* a valid subscript, and any -- attempt to apply list operations to No_List will cause a (detected) -- error. type List_Id is range List_Low_Bound .. List_High_Bound; -- Type used to identify a node list No_List : constant List_Id := List_High_Bound; -- Used to indicate absence of a list. Note that the value is zero, which -- is the same as Empty, which is helpful in initializing nodes where a -- value of zero can represent either an empty node or an empty list. Error_List : constant List_Id := List_Low_Bound; -- Used to indicate that there was an error in the source program in a -- context which would normally require a list. This node appears to be -- an empty list to the list operations (a null list is actually allocated -- which has this Id value). First_List_Id : constant List_Id := Error_List; -- Subscript of first allocated list header ------------------------------ -- Types for Elists Package -- ------------------------------ -- Element list Id values are used to identify element lists stored outside -- of the tree, allowing nodes to be members of more than one such list -- (see package Elists for further details). type Elist_Id is range Elist_Low_Bound .. Elist_High_Bound; -- Type used to identify an element list (Elist header table subscript) No_Elist : constant Elist_Id := Elist_Low_Bound; -- Used to indicate absence of an element list. Note that this is not an -- actual Elist header, so element list operations on this value are not -- valid. First_Elist_Id : constant Elist_Id := No_Elist + 1; -- Subscript of first allocated Elist header -- Element Id values are used to identify individual elements of an element -- list (see package Elists for further details). type Elmt_Id is range Elmt_Low_Bound .. Elmt_High_Bound; -- Type used to identify an element list No_Elmt : constant Elmt_Id := Elmt_Low_Bound; -- Used to represent empty element First_Elmt_Id : constant Elmt_Id := No_Elmt + 1; -- Subscript of first allocated Elmt table entry ------------------------------- -- Types for Stringt Package -- ------------------------------- -- String_Id values are used to identify entries in the strings table. They -- are subscripts into the Strings table defined in package Stringt. -- Note that with only a few exceptions, which are clearly documented, the -- type String_Id should be regarded as a private type. In particular it is -- never appropriate to perform arithmetic operations using this type. -- Doesn't this also apply to all other *_Id types??? type String_Id is range Strings_Low_Bound .. Strings_High_Bound; -- Type used to identify entries in the strings table No_String : constant String_Id := Strings_Low_Bound; -- Used to indicate missing string Id. Note that the value zero is used -- to indicate a missing data value for all the Int types in this section. First_String_Id : constant String_Id := No_String + 1; -- First subscript allocated in string table ------------------------- -- Character Code Type -- ------------------------- -- The type Char is used for character data internally in the compiler, but -- character codes in the source are represented by the Char_Code type. -- Each character literal in the source is interpreted as being one of the -- 16#7FFF_FFFF# possible Wide_Wide_Character codes, and a unique Integer -- value is assigned, corresponding to the UTF-32 value, which also -- corresponds to the Pos value in the Wide_Wide_Character type, and also -- corresponds to the Pos value in the Wide_Character and Character types -- for values that are in appropriate range. String literals are similarly -- interpreted as a sequence of such codes. type Char_Code_Base is mod 2 ** 32; for Char_Code_Base'Size use 32; subtype Char_Code is Char_Code_Base range 0 .. 16#7FFF_FFFF#; for Char_Code'Value_Size use 32; for Char_Code'Object_Size use 32; function Get_Char_Code (C : Character) return Char_Code; pragma Inline (Get_Char_Code); -- Function to obtain internal character code from source character. For -- the moment, the internal character code is simply the Pos value of the -- input source character, but we provide this interface for possible -- later support of alternative character sets. function In_Character_Range (C : Char_Code) return Boolean; pragma Inline (In_Character_Range); -- Determines if the given character code is in range of type Character, -- and if so, returns True. If not, returns False. function In_Wide_Character_Range (C : Char_Code) return Boolean; pragma Inline (In_Wide_Character_Range); -- Determines if the given character code is in range of the type -- Wide_Character, and if so, returns True. If not, returns False. function Get_Character (C : Char_Code) return Character; pragma Inline (Get_Character); -- For a character C that is in Character range (see above function), this -- function returns the corresponding Character value. It is an error to -- call Get_Character if C is not in Character range. function Get_Wide_Character (C : Char_Code) return Wide_Character; -- For a character C that is in Wide_Character range (see above function), -- this function returns the corresponding Wide_Character value. It is an -- error to call Get_Wide_Character if C is not in Wide_Character range. --------------------------------------- -- Types used for Library Management -- --------------------------------------- type Unit_Number_Type is new Int; -- Unit number. The main source is unit 0, and subsidiary sources have -- non-zero numbers starting with 1. Unit numbers are used to index the -- Units table in package Lib. Main_Unit : constant Unit_Number_Type := 0; -- Unit number value for main unit No_Unit : constant Unit_Number_Type := -1; -- Special value used to signal no unit type Source_File_Index is new Int range -1 .. Int'Last; -- Type used to index the source file table (see package Sinput) Internal_Source_File : constant Source_File_Index := Source_File_Index'First; -- Value used to indicate the buffer for the source-code-like strings -- internally created withing the compiler (see package Sinput) No_Source_File : constant Source_File_Index := 0; -- Value used to indicate no source file present ----------------------------------- -- Representation of Time Stamps -- ----------------------------------- -- All compiled units are marked with a time stamp which is derived from -- the source file (we assume that the host system has the concept of a -- file time stamp which is modified when a file is modified). These -- time stamps are used to ensure consistency of the set of units that -- constitutes a library. Time stamps are 14-character strings with -- with the following format: -- YYYYMMDDHHMMSS -- YYYY year -- MM month (2 digits 01-12) -- DD day (2 digits 01-31) -- HH hour (2 digits 00-23) -- MM minutes (2 digits 00-59) -- SS seconds (2 digits 00-59) -- In the case of Unix systems (and other systems which keep the time in -- GMT), the time stamp is the GMT time of the file, not the local time. -- This solves problems in using libraries across networks with clients -- spread across multiple time-zones. Time_Stamp_Length : constant := 14; -- Length of time stamp value subtype Time_Stamp_Index is Natural range 1 .. Time_Stamp_Length; type Time_Stamp_Type is new String (Time_Stamp_Index); -- Type used to represent time stamp Empty_Time_Stamp : constant Time_Stamp_Type := (others => ' '); -- Value representing an empty or missing time stamp. Looks less than any -- real time stamp if two time stamps are compared. Note that although this -- is not private, clients should not rely on the exact way in which this -- string is represented, and instead should use the subprograms below. Dummy_Time_Stamp : constant Time_Stamp_Type := (others => '0'); -- This is used for dummy time stamp values used in the D lines for -- non-existent files, and is intended to be an impossible value. function "=" (Left, Right : Time_Stamp_Type) return Boolean; function "<=" (Left, Right : Time_Stamp_Type) return Boolean; function ">=" (Left, Right : Time_Stamp_Type) return Boolean; function "<" (Left, Right : Time_Stamp_Type) return Boolean; function ">" (Left, Right : Time_Stamp_Type) return Boolean; -- Comparison functions on time stamps. Note that two time stamps are -- defined as being equal if they have the same day/month/year and the -- hour/minutes/seconds values are within 2 seconds of one another. This -- deals with rounding effects in library file time stamps caused by -- copying operations during installation. We have particularly noticed -- that WinNT seems susceptible to such changes. -- -- Note : the Empty_Time_Stamp value looks equal to itself, and less than -- any non-empty time stamp value. procedure Split_Time_Stamp (TS : Time_Stamp_Type; Year : out Nat; Month : out Nat; Day : out Nat; Hour : out Nat; Minutes : out Nat; Seconds : out Nat); -- Given a time stamp, decompose it into its components procedure Make_Time_Stamp (Year : Nat; Month : Nat; Day : Nat; Hour : Nat; Minutes : Nat; Seconds : Nat; TS : out Time_Stamp_Type); -- Given the components of a time stamp, initialize the value ------------------------------------- -- Types used for Check Management -- ------------------------------------- type Check_Id is new Nat; -- Type used to represent a check id No_Check_Id : constant := 0; -- Check_Id value used to indicate no check Access_Check : constant := 1; Accessibility_Check : constant := 2; Alignment_Check : constant := 3; Allocation_Check : constant := 4; Atomic_Synchronization : constant := 5; Discriminant_Check : constant := 6; Division_Check : constant := 7; Duplicated_Tag_Check : constant := 8; Elaboration_Check : constant := 9; Index_Check : constant := 10; Length_Check : constant := 11; Overflow_Check : constant := 12; Predicate_Check : constant := 13; Range_Check : constant := 14; Storage_Check : constant := 15; Tag_Check : constant := 16; Validity_Check : constant := 17; -- Values used to represent individual predefined checks (including the -- setting of Atomic_Synchronization, which is implemented internally using -- a "check" whose name is Atomic_Synchronization). All_Checks : constant := 18; -- Value used to represent All_Checks value subtype Predefined_Check_Id is Check_Id range 1 .. All_Checks; -- Subtype for predefined checks, including All_Checks -- The following array contains an entry for each recognized check name -- for pragma Suppress. It is used to represent current settings of scope -- based suppress actions from pragma Suppress or command line settings. -- Note: when Suppress_Array (All_Checks) is True, then generally all other -- specific check entries are set True, except for the Elaboration_Check -- entry which is set only if an explicit Suppress for this check is given. -- The reason for this non-uniformity is that we do not want All_Checks to -- suppress elaboration checking when using the static elaboration model. -- We recognize only an explicit suppress of Elaboration_Check as a signal -- that the static elaboration checking should skip a compile time check. type Suppress_Array is array (Predefined_Check_Id) of Boolean; pragma Pack (Suppress_Array); -- To add a new check type to GNAT, the following steps are required: -- 1. Add an entry to Snames spec for the new name -- 2. Add an entry to the definition of Check_Id above -- 3. Add a new function to Checks to handle the new check test -- 4. Add a new Do_xxx_Check flag to Sinfo (if required) -- 5. Add appropriate checks for the new test -- The following provides precise details on the mode used to generate -- code for intermediate operations in expressions for signed integer -- arithmetic (and how to generate overflow checks if enabled). Note -- that this only affects handling of intermediate results. The final -- result must always fit within the target range, and if overflow -- checking is enabled, the check on the final result is against this -- target range. type Overflow_Mode_Type is ( Not_Set, -- Dummy value used during initialization process to show that the -- corresponding value has not yet been initialized. Strict, -- Operations are done in the base type of the subexpression. If -- overflow checks are enabled, then the check is against the range -- of this base type. Minimized, -- Where appropriate, intermediate arithmetic operations are performed -- with an extended range, using Long_Long_Integer if necessary. If -- overflow checking is enabled, then the check is against the range -- of Long_Long_Integer. Eliminated); -- In this mode arbitrary precision arithmetic is used as needed to -- ensure that it is impossible for intermediate arithmetic to cause an -- overflow. In this mode, intermediate expressions are not affected by -- the overflow checking mode, since overflows are eliminated. subtype Minimized_Or_Eliminated is Overflow_Mode_Type range Minimized .. Eliminated; -- Define subtype so that clients don't need to know ordering. Note that -- Overflow_Mode_Type is not marked as an ordered enumeration type. -- The following structure captures the state of check suppression or -- activation at a particular point in the program execution. type Suppress_Record is record Suppress : Suppress_Array; -- Indicates suppression status of each possible check Overflow_Mode_General : Overflow_Mode_Type; -- This field indicates the mode for handling code generation and -- overflow checking (if enabled) for intermediate expression values. -- This applies to general expressions outside assertions. Overflow_Mode_Assertions : Overflow_Mode_Type; -- This field indicates the mode for handling code generation and -- overflow checking (if enabled) for intermediate expression values. -- This applies to any expression occuring inside assertions. end record; ----------------------------------- -- Global Exception Declarations -- ----------------------------------- -- This section contains declarations of exceptions that are used -- throughout the compiler or in other GNAT tools. Unrecoverable_Error : exception; -- This exception is raised to immediately terminate the compilation of the -- current source program. Used in situations where things are bad enough -- that it doesn't seem worth continuing (e.g. max errors reached, or a -- required file is not found). Also raised when the compiler finds itself -- in trouble after an error (see Comperr). Terminate_Program : exception; -- This exception is raised to immediately terminate the tool being -- executed. Each tool where this exception may be raised must have a -- single exception handler that contains only a null statement and that is -- the last statement of the program. If needed, procedure Set_Exit_Status -- is called with the appropriate exit status before raising -- Terminate_Program. --------------------------------- -- Parameter Mechanism Control -- --------------------------------- -- Function and parameter entities have a field that records the passing -- mechanism. See specification of Sem_Mech for full details. The following -- subtype is used to represent values of this type: subtype Mechanism_Type is Int range -18 .. Int'Last; -- Type used to represent a mechanism value. This is a subtype rather than -- a type to avoid some annoying processing problems with certain routines -- in Einfo (processing them to create the corresponding C). The values in -- the range -18 .. 0 are used to represent mechanism types declared as -- named constants in the spec of Sem_Mech. Positive values are used for -- the case of a pragma C_Pass_By_Copy that sets a threshold value for the -- mechanism to be used. For example if pragma C_Pass_By_Copy (32) is given -- then Default_C_Record_Mechanism is set to 32, and the meaning is to use -- By_Reference if the size is greater than 32, and By_Copy otherwise. ------------------------------ -- Run-Time Exception Codes -- ------------------------------ -- When the code generator generates a run-time exception, it provides a -- reason code which is one of the following. This reason code is used to -- select the appropriate run-time routine to be called, determining both -- the exception to be raised, and the message text to be added. -- The prefix CE/PE/SE indicates the exception to be raised -- CE = Constraint_Error -- PE = Program_Error -- SE = Storage_Error -- The remaining part of the name indicates the message text to be added, -- where all letters are lower case, and underscores are converted to -- spaces (for example CE_Invalid_Data adds the text "invalid data"). -- To add a new code, you need to do the following: -- 1. Assign a new number to the reason. Do not renumber existing codes, -- since this causes compatibility/bootstrap issues, and problems in -- the CIL/JVM backends. So always add the new code at the end of the -- list. -- 2. Update the contents of the array Kind -- 3. Modify the corresponding definitions in types.h, including the -- definition of last_reason_code. -- 4. Add the name of the routines in exp_ch11.Get_RT_Exception_Name -- 5. Add a new routine in Ada.Exceptions with the appropriate call and -- static string constant. Note that there is more than one version -- of a-except.adb which must be modified. -- Note on ordering of references. For the tables in Ada.Exceptions units, -- usually the ordering does not matter, and we use the same ordering as -- is used here (note the requirement in the ordering here that CE/PE/SE -- codes be kept together, so the subtype declarations work OK). However, -- there is an important exception, which is in a-except-2005.adb, where -- ordering of the Rcheck routines must correspond to the ordering of the -- Rmsg_xx messages. This is required by the .NET scripts. type RT_Exception_Code is (CE_Access_Check_Failed, -- 00 CE_Access_Parameter_Is_Null, -- 01 CE_Discriminant_Check_Failed, -- 02 CE_Divide_By_Zero, -- 03 CE_Explicit_Raise, -- 04 CE_Index_Check_Failed, -- 05 CE_Invalid_Data, -- 06 CE_Length_Check_Failed, -- 07 CE_Null_Exception_Id, -- 08 CE_Null_Not_Allowed, -- 09 CE_Overflow_Check_Failed, -- 10 CE_Partition_Check_Failed, -- 11 CE_Range_Check_Failed, -- 12 CE_Tag_Check_Failed, -- 13 PE_Access_Before_Elaboration, -- 14 PE_Accessibility_Check_Failed, -- 15 PE_Address_Of_Intrinsic, -- 16 PE_Aliased_Parameters, -- 17 PE_All_Guards_Closed, -- 18 PE_Bad_Predicated_Generic_Type, -- 19 PE_Current_Task_In_Entry_Body, -- 20 PE_Duplicated_Entry_Address, -- 21 PE_Explicit_Raise, -- 22 PE_Finalize_Raised_Exception, -- 23 PE_Implicit_Return, -- 24 PE_Misaligned_Address_Value, -- 25 PE_Missing_Return, -- 26 PE_Overlaid_Controlled_Object, -- 27 PE_Potentially_Blocking_Operation, -- 28 PE_Stubbed_Subprogram_Called, -- 29 PE_Unchecked_Union_Restriction, -- 30 PE_Non_Transportable_Actual, -- 31 SE_Empty_Storage_Pool, -- 32 SE_Explicit_Raise, -- 33 SE_Infinite_Recursion, -- 34 SE_Object_Too_Large, -- 35 PE_Stream_Operation_Not_Allowed); -- 36 Last_Reason_Code : constant := 36; -- Last reason code type Reason_Kind is (CE_Reason, PE_Reason, SE_Reason); -- Categorization of reason codes by exception raised Rkind : array (RT_Exception_Code range <>) of Reason_Kind := (CE_Access_Check_Failed => CE_Reason, CE_Access_Parameter_Is_Null => CE_Reason, CE_Discriminant_Check_Failed => CE_Reason, CE_Divide_By_Zero => CE_Reason, CE_Explicit_Raise => CE_Reason, CE_Index_Check_Failed => CE_Reason, CE_Invalid_Data => CE_Reason, CE_Length_Check_Failed => CE_Reason, CE_Null_Exception_Id => CE_Reason, CE_Null_Not_Allowed => CE_Reason, CE_Overflow_Check_Failed => CE_Reason, CE_Partition_Check_Failed => CE_Reason, CE_Range_Check_Failed => CE_Reason, CE_Tag_Check_Failed => CE_Reason, PE_Access_Before_Elaboration => PE_Reason, PE_Accessibility_Check_Failed => PE_Reason, PE_Address_Of_Intrinsic => PE_Reason, PE_Aliased_Parameters => PE_Reason, PE_All_Guards_Closed => PE_Reason, PE_Bad_Predicated_Generic_Type => PE_Reason, PE_Current_Task_In_Entry_Body => PE_Reason, PE_Duplicated_Entry_Address => PE_Reason, PE_Explicit_Raise => PE_Reason, PE_Finalize_Raised_Exception => PE_Reason, PE_Implicit_Return => PE_Reason, PE_Misaligned_Address_Value => PE_Reason, PE_Missing_Return => PE_Reason, PE_Overlaid_Controlled_Object => PE_Reason, PE_Potentially_Blocking_Operation => PE_Reason, PE_Stubbed_Subprogram_Called => PE_Reason, PE_Unchecked_Union_Restriction => PE_Reason, PE_Non_Transportable_Actual => PE_Reason, PE_Stream_Operation_Not_Allowed => PE_Reason, SE_Empty_Storage_Pool => SE_Reason, SE_Explicit_Raise => SE_Reason, SE_Infinite_Recursion => SE_Reason, SE_Object_Too_Large => SE_Reason); end Types; gprbuild-gpl-2014-src/gnat/output.adb0000644000076700001450000002750612323721731017106 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- O U T P U T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ package body Output is Current_FD : File_Descriptor := Standout; -- File descriptor for current output Special_Output_Proc : Output_Proc := null; -- Record argument to last call to Set_Special_Output. If this is -- non-null, then we are in special output mode. Indentation_Amount : constant Positive := 3; -- Number of spaces to output for each indentation level Indentation_Limit : constant Positive := 40; -- Indentation beyond this number of spaces wraps around pragma Assert (Indentation_Limit < Buffer_Max / 2); -- Make sure this is substantially shorter than the line length Cur_Indentation : Natural := 0; -- Number of spaces to indent each line ----------------------- -- Local_Subprograms -- ----------------------- procedure Flush_Buffer; -- Flush buffer if non-empty and reset column counter --------------------------- -- Cancel_Special_Output -- --------------------------- procedure Cancel_Special_Output is begin Special_Output_Proc := null; end Cancel_Special_Output; ------------ -- Column -- ------------ function Column return Pos is begin return Pos (Next_Col); end Column; ---------------------- -- Delete_Last_Char -- ---------------------- procedure Delete_Last_Char is begin if Next_Col /= 1 then Next_Col := Next_Col - 1; end if; end Delete_Last_Char; ------------------ -- Flush_Buffer -- ------------------ procedure Flush_Buffer is Write_Error : exception; -- Raised if Write fails ------------------ -- Write_Buffer -- ------------------ procedure Write_Buffer (Buf : String); -- Write out Buf, either using Special_Output_Proc, or the normal way -- using Write. Raise Write_Error if Write fails (presumably due to disk -- full). Write_Error is not used in the case of Special_Output_Proc. procedure Write_Buffer (Buf : String) is begin -- If Special_Output_Proc has been set, then use it if Special_Output_Proc /= null then Special_Output_Proc.all (Buf); -- If output is not set, then output to either standard output -- or standard error. elsif Write (Current_FD, Buf'Address, Buf'Length) /= Buf'Length then raise Write_Error; end if; end Write_Buffer; Len : constant Natural := Next_Col - 1; -- Start of processing for Flush_Buffer begin if Len /= 0 then begin -- If there's no indentation, or if the line is too long with -- indentation, or if it's a blank line, just write the buffer. if Cur_Indentation = 0 or else Cur_Indentation + Len > Buffer_Max or else Buffer (1 .. Len) = (1 => ASCII.LF) then Write_Buffer (Buffer (1 .. Len)); -- Otherwise, construct a new buffer with preceding spaces, and -- write that. else declare Indented_Buffer : constant String := (1 .. Cur_Indentation => ' ') & Buffer (1 .. Len); begin Write_Buffer (Indented_Buffer); end; end if; exception when Write_Error => -- If there are errors with standard error just quit. Otherwise -- set the output to standard error before reporting a failure -- and quitting. if Current_FD /= Standerr then Current_FD := Standerr; Next_Col := 1; Write_Line ("fatal error: disk full"); end if; OS_Exit (2); end; -- Buffer is now empty Next_Col := 1; end if; end Flush_Buffer; ------------------- -- Ignore_Output -- ------------------- procedure Ignore_Output (S : String) is begin null; end Ignore_Output; ------------ -- Indent -- ------------ procedure Indent is begin -- The "mod" in the following assignment is to cause a wrap around in -- the case where there is too much indentation. Cur_Indentation := (Cur_Indentation + Indentation_Amount) mod Indentation_Limit; end Indent; --------------- -- Last_Char -- --------------- function Last_Char return Character is begin if Next_Col /= 1 then return Buffer (Next_Col - 1); else return ASCII.NUL; end if; end Last_Char; ------------- -- Outdent -- ------------- procedure Outdent is begin -- The "mod" here undoes the wrap around from Indent above Cur_Indentation := (Cur_Indentation - Indentation_Amount) mod Indentation_Limit; end Outdent; --------------------------- -- Restore_Output_Buffer -- --------------------------- procedure Restore_Output_Buffer (S : Saved_Output_Buffer) is begin Next_Col := S.Next_Col; Cur_Indentation := S.Cur_Indentation; Buffer (1 .. Next_Col - 1) := S.Buffer (1 .. Next_Col - 1); end Restore_Output_Buffer; ------------------------ -- Save_Output_Buffer -- ------------------------ function Save_Output_Buffer return Saved_Output_Buffer is S : Saved_Output_Buffer; begin S.Buffer (1 .. Next_Col - 1) := Buffer (1 .. Next_Col - 1); S.Next_Col := Next_Col; S.Cur_Indentation := Cur_Indentation; Next_Col := 1; Cur_Indentation := 0; return S; end Save_Output_Buffer; ------------------------ -- Set_Special_Output -- ------------------------ procedure Set_Special_Output (P : Output_Proc) is begin Special_Output_Proc := P; end Set_Special_Output; ---------------- -- Set_Output -- ---------------- procedure Set_Output (FD : File_Descriptor) is begin if Special_Output_Proc = null then Flush_Buffer; end if; Current_FD := FD; end Set_Output; ------------------------ -- Set_Standard_Error -- ------------------------ procedure Set_Standard_Error is begin Set_Output (Standerr); end Set_Standard_Error; ------------------------- -- Set_Standard_Output -- ------------------------- procedure Set_Standard_Output is begin Set_Output (Standout); end Set_Standard_Output; ------- -- w -- ------- procedure w (C : Character) is begin Write_Char ('''); Write_Char (C); Write_Char ('''); Write_Eol; end w; procedure w (S : String) is begin Write_Str (S); Write_Eol; end w; procedure w (V : Int) is begin Write_Int (V); Write_Eol; end w; procedure w (B : Boolean) is begin if B then w ("True"); else w ("False"); end if; end w; procedure w (L : String; C : Character) is begin Write_Str (L); Write_Char (' '); w (C); end w; procedure w (L : String; S : String) is begin Write_Str (L); Write_Char (' '); w (S); end w; procedure w (L : String; V : Int) is begin Write_Str (L); Write_Char (' '); w (V); end w; procedure w (L : String; B : Boolean) is begin Write_Str (L); Write_Char (' '); w (B); end w; ---------------- -- Write_Char -- ---------------- procedure Write_Char (C : Character) is begin if Next_Col = Buffer'Length then Write_Eol; end if; if C = ASCII.LF then Write_Eol; else Buffer (Next_Col) := C; Next_Col := Next_Col + 1; end if; end Write_Char; --------------- -- Write_Eol -- --------------- procedure Write_Eol is begin -- Remove any trailing spaces while Next_Col > 1 and then Buffer (Next_Col - 1) = ' ' loop Next_Col := Next_Col - 1; end loop; Buffer (Next_Col) := ASCII.LF; Next_Col := Next_Col + 1; Flush_Buffer; end Write_Eol; --------------------------- -- Write_Eol_Keep_Blanks -- --------------------------- procedure Write_Eol_Keep_Blanks is begin Buffer (Next_Col) := ASCII.LF; Next_Col := Next_Col + 1; Flush_Buffer; end Write_Eol_Keep_Blanks; ---------------------- -- Write_Erase_Char -- ---------------------- procedure Write_Erase_Char (C : Character) is begin if Next_Col /= 1 and then Buffer (Next_Col - 1) = C then Next_Col := Next_Col - 1; end if; end Write_Erase_Char; --------------- -- Write_Int -- --------------- procedure Write_Int (Val : Int) is begin if Val < 0 then Write_Char ('-'); Write_Int (-Val); else if Val > 9 then Write_Int (Val / 10); end if; Write_Char (Character'Val ((Val mod 10) + Character'Pos ('0'))); end if; end Write_Int; ---------------- -- Write_Line -- ---------------- procedure Write_Line (S : String) is begin Write_Str (S); Write_Eol; end Write_Line; ------------------ -- Write_Spaces -- ------------------ procedure Write_Spaces (N : Nat) is begin for J in 1 .. N loop Write_Char (' '); end loop; end Write_Spaces; --------------- -- Write_Str -- --------------- procedure Write_Str (S : String) is begin for J in S'Range loop Write_Char (S (J)); end loop; end Write_Str; end Output; gprbuild-gpl-2014-src/gnat/osint.adb0000644000076700001450000031667212323721731016707 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- O S I N T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Alloc; with Debug; with Fmap; use Fmap; with Gnatvsn; use Gnatvsn; with Hostparm; with Opt; use Opt; with Output; use Output; with Sdefault; use Sdefault; with Table; with Targparm; use Targparm; with Unchecked_Conversion; pragma Warnings (Off); -- This package is used also by gnatcoll with System.Case_Util; use System.Case_Util; pragma Warnings (On); with GNAT.HTable; package body Osint is Running_Program : Program_Type := Unspecified; -- comment required here ??? Program_Set : Boolean := False; -- comment required here ??? Std_Prefix : String_Ptr; -- Standard prefix, computed dynamically the first time Relocate_Path -- is called, and cached for subsequent calls. Empty : aliased String := ""; No_Dir : constant String_Ptr := Empty'Access; -- Used in Locate_File as a fake directory when Name is already an -- absolute path. ------------------------------------- -- Use of Name_Find and Name_Enter -- ------------------------------------- -- This package creates a number of source, ALI and object file names -- that are used to locate the actual file and for the purpose of message -- construction. These names need not be accessible by Name_Find, and can -- be therefore created by using routine Name_Enter. The files in question -- are file names with a prefix directory (i.e., the files not in the -- current directory). File names without a prefix directory are entered -- with Name_Find because special values might be attached to the various -- Info fields of the corresponding name table entry. ----------------------- -- Local Subprograms -- ----------------------- function Append_Suffix_To_File_Name (Name : File_Name_Type; Suffix : String) return File_Name_Type; -- Appends Suffix to Name and returns the new name function OS_Time_To_GNAT_Time (T : OS_Time) return Time_Stamp_Type; -- Convert OS format time to GNAT format time stamp. If T is Invalid_Time, -- then returns Empty_Time_Stamp. function Executable_Prefix return String_Ptr; -- Returns the name of the root directory where the executable is stored. -- The executable must be located in a directory called "bin", or under -- root/lib/gcc-lib/..., or under root/libexec/gcc/... For example, if -- executable is stored in directory "/foo/bar/bin", this routine returns -- "/foo/bar/". Return "" if location is not recognized as described above. function Update_Path (Path : String_Ptr) return String_Ptr; -- Update the specified path to replace the prefix with the location where -- GNAT is installed. See the file prefix.c in GCC for details. procedure Locate_File (N : File_Name_Type; T : File_Type; Dir : Natural; Name : String; Found : out File_Name_Type; Attr : access File_Attributes); -- See if the file N whose name is Name exists in directory Dir. Dir is an -- index into the Lib_Search_Directories table if T = Library. Otherwise -- if T = Source, Dir is an index into the Src_Search_Directories table. -- Returns the File_Name_Type of the full file name if file found, or -- No_File if not found. -- -- On exit, Found is set to the file that was found, and Attr to a cache of -- its attributes (at least those that have been computed so far). Reusing -- the cache will save some system calls. -- -- Attr is always reset in this call to Unknown_Attributes, even in case of -- failure procedure Find_File (N : File_Name_Type; T : File_Type; Found : out File_Name_Type; Attr : access File_Attributes); -- A version of Find_File that also returns a cache of the file attributes -- for later reuse procedure Smart_Find_File (N : File_Name_Type; T : File_Type; Found : out File_Name_Type; Attr : out File_Attributes); -- A version of Smart_Find_File that also returns a cache of the file -- attributes for later reuse function C_String_Length (S : Address) return Integer; -- Returns length of a C string (zero for a null address) function To_Path_String_Access (Path_Addr : Address; Path_Len : Integer) return String_Access; -- Converts a C String to an Ada String. Are we doing this to avoid withing -- Interfaces.C.Strings ??? -- Caller must free result. function Include_Dir_Default_Prefix return String_Access; -- Same as exported version, except returns a String_Access ------------------------------ -- Other Local Declarations -- ------------------------------ EOL : constant Character := ASCII.LF; -- End of line character Number_File_Names : Int := 0; -- Number of file names found on command line and placed in File_Names Look_In_Primary_Directory_For_Current_Main : Boolean := False; -- When this variable is True, Find_File only looks in Primary_Directory -- for the Current_Main file. This variable is always set to True for the -- compiler. It is also True for gnatmake, when the source name given on -- the command line has directory information. Current_Full_Source_Name : File_Name_Type := No_File; Current_Full_Source_Stamp : Time_Stamp_Type := Empty_Time_Stamp; Current_Full_Lib_Name : File_Name_Type := No_File; Current_Full_Lib_Stamp : Time_Stamp_Type := Empty_Time_Stamp; Current_Full_Obj_Name : File_Name_Type := No_File; Current_Full_Obj_Stamp : Time_Stamp_Type := Empty_Time_Stamp; -- Respectively full name (with directory info) and time stamp of the -- latest source, library and object files opened by Read_Source_File and -- Read_Library_Info. package File_Name_Chars is new Table.Table ( Table_Component_Type => Character, Table_Index_Type => Int, Table_Low_Bound => 1, Table_Initial => Alloc.File_Name_Chars_Initial, Table_Increment => Alloc.File_Name_Chars_Increment, Table_Name => "File_Name_Chars"); -- Table to store text to be printed by Dump_Source_File_Names The_Include_Dir_Default_Prefix : String_Access := null; -- Value returned by Include_Dir_Default_Prefix. We don't initialize it -- here, because that causes an elaboration cycle with Sdefault; we -- initialize it lazily instead. ------------------ -- Search Paths -- ------------------ Primary_Directory : constant := 0; -- This is index in the tables created below for the first directory to -- search in for source or library information files. This is the directory -- containing the latest main input file (a source file for the compiler or -- a library file for the binder). package Src_Search_Directories is new Table.Table ( Table_Component_Type => String_Ptr, Table_Index_Type => Integer, Table_Low_Bound => Primary_Directory, Table_Initial => 10, Table_Increment => 100, Table_Name => "Osint.Src_Search_Directories"); -- Table of names of directories in which to search for source (Compiler) -- files. This table is filled in the order in which the directories are -- to be searched, and then used in that order. package Lib_Search_Directories is new Table.Table ( Table_Component_Type => String_Ptr, Table_Index_Type => Integer, Table_Low_Bound => Primary_Directory, Table_Initial => 10, Table_Increment => 100, Table_Name => "Osint.Lib_Search_Directories"); -- Table of names of directories in which to search for library (Binder) -- files. This table is filled in the order in which the directories are -- to be searched and then used in that order. The reason for having two -- distinct tables is that we need them both in gnatmake. --------------------- -- File Hash Table -- --------------------- -- The file hash table is provided to free the programmer from any -- efficiency concern when retrieving full file names or time stamps of -- source files. If the programmer calls Source_File_Data (Cache => True) -- he is guaranteed that the price to retrieve the full name (i.e. with -- directory info) or time stamp of the file will be payed only once, the -- first time the full name is actually searched (or the first time the -- time stamp is actually retrieved). This is achieved by employing a hash -- table that stores as a key the File_Name_Type of the file and associates -- to that File_Name_Type the full file name and time stamp of the file. File_Cache_Enabled : Boolean := False; -- Set to true if you want the enable the file data caching mechanism type File_Hash_Num is range 0 .. 1020; function File_Hash (F : File_Name_Type) return File_Hash_Num; -- Compute hash index for use by Simple_HTable type File_Info_Cache is record File : File_Name_Type; Attr : aliased File_Attributes; end record; No_File_Info_Cache : constant File_Info_Cache := (No_File, Unknown_Attributes); package File_Name_Hash_Table is new GNAT.HTable.Simple_HTable ( Header_Num => File_Hash_Num, Element => File_Info_Cache, No_Element => No_File_Info_Cache, Key => File_Name_Type, Hash => File_Hash, Equal => "="); function Smart_Find_File (N : File_Name_Type; T : File_Type) return File_Name_Type; -- Exactly like Find_File except that if File_Cache_Enabled is True this -- routine looks first in the hash table to see if the full name of the -- file is already available. function Smart_File_Stamp (N : File_Name_Type; T : File_Type) return Time_Stamp_Type; -- Takes the same parameter as the routine above (N is a file name without -- any prefix directory information) and behaves like File_Stamp except -- that if File_Cache_Enabled is True this routine looks first in the hash -- table to see if the file stamp of the file is already available. ----------------------------- -- Add_Default_Search_Dirs -- ----------------------------- procedure Add_Default_Search_Dirs is Search_Dir : String_Access; Search_Path : String_Access; Path_File_Name : String_Access; procedure Add_Search_Dir (Search_Dir : String; Additional_Source_Dir : Boolean); procedure Add_Search_Dir (Search_Dir : String_Access; Additional_Source_Dir : Boolean); -- Add a source search dir or a library search dir, depending on the -- value of Additional_Source_Dir. procedure Get_Dirs_From_File (Additional_Source_Dir : Boolean); -- Open a path file and read the directory to search, one per line function Get_Libraries_From_Registry return String_Ptr; -- On Windows systems, get the list of installed standard libraries -- from the registry key: -- -- HKEY_LOCAL_MACHINE\SOFTWARE\Ada Core Technologies\ -- GNAT\Standard Libraries -- Return an empty string on other systems. -- -- Note that this is an undocumented legacy feature, and that it -- works only when using the default runtime library (i.e. no --RTS= -- command line switch). -------------------- -- Add_Search_Dir -- -------------------- procedure Add_Search_Dir (Search_Dir : String; Additional_Source_Dir : Boolean) is begin if Additional_Source_Dir then Add_Src_Search_Dir (Search_Dir); else Add_Lib_Search_Dir (Search_Dir); end if; end Add_Search_Dir; procedure Add_Search_Dir (Search_Dir : String_Access; Additional_Source_Dir : Boolean) is begin if Additional_Source_Dir then Add_Src_Search_Dir (Search_Dir.all); else Add_Lib_Search_Dir (Search_Dir.all); end if; end Add_Search_Dir; ------------------------ -- Get_Dirs_From_File -- ------------------------ procedure Get_Dirs_From_File (Additional_Source_Dir : Boolean) is File_FD : File_Descriptor; Buffer : constant String := Path_File_Name.all & ASCII.NUL; Len : Natural; Actual_Len : Natural; S : String_Access; Curr : Natural; First : Natural; Ch : Character; Status : Boolean; pragma Warnings (Off, Status); -- For the call to Close where status is ignored begin File_FD := Open_Read (Buffer'Address, Binary); -- If we cannot open the file, we ignore it, we don't fail if File_FD = Invalid_FD then return; end if; Len := Integer (File_Length (File_FD)); S := new String (1 .. Len); -- Read the file. Note that the loop is not necessary since the -- whole file is read at once except on VMS. Curr := 1; Actual_Len := Len; while Curr <= Len and then Actual_Len /= 0 loop Actual_Len := Read (File_FD, S (Curr)'Address, Len); Curr := Curr + Actual_Len; end loop; -- We are done with the file, so we close it (ignore any error on -- the close, since we have successfully read the file). Close (File_FD, Status); -- Now, we read line by line First := 1; Curr := 0; while Curr < Len loop Ch := S (Curr + 1); if Ch = ASCII.CR or else Ch = ASCII.LF or else Ch = ASCII.FF or else Ch = ASCII.VT then if First <= Curr then Add_Search_Dir (S (First .. Curr), Additional_Source_Dir); end if; First := Curr + 2; end if; Curr := Curr + 1; end loop; -- Last line is a special case, if the file does not end with -- an end of line mark. if First <= S'Last then Add_Search_Dir (S (First .. S'Last), Additional_Source_Dir); end if; end Get_Dirs_From_File; --------------------------------- -- Get_Libraries_From_Registry -- --------------------------------- function Get_Libraries_From_Registry return String_Ptr is function C_Get_Libraries_From_Registry return Address; pragma Import (C, C_Get_Libraries_From_Registry, "__gnat_get_libraries_from_registry"); function Strlen (Str : Address) return Integer; pragma Import (C, Strlen, "strlen"); procedure Strncpy (X : Address; Y : Address; Length : Integer); pragma Import (C, Strncpy, "strncpy"); procedure C_Free (Str : Address); pragma Import (C, C_Free, "free"); Result_Ptr : Address; Result_Length : Integer; Out_String : String_Ptr; begin Result_Ptr := C_Get_Libraries_From_Registry; Result_Length := Strlen (Result_Ptr); Out_String := new String (1 .. Result_Length); Strncpy (Out_String.all'Address, Result_Ptr, Result_Length); C_Free (Result_Ptr); return Out_String; end Get_Libraries_From_Registry; -- Start of processing for Add_Default_Search_Dirs begin -- If there was a -gnateO switch, add all object directories from the -- file given in argument to the library search list. if Object_Path_File_Name /= null then Path_File_Name := String_Access (Object_Path_File_Name); pragma Assert (Path_File_Name'Length > 0); Get_Dirs_From_File (Additional_Source_Dir => False); end if; -- After the locations specified on the command line, the next places -- to look for files are the directories specified by the appropriate -- environment variable. Get this value, extract the directory names -- and store in the tables. -- Check for eventual project path file env vars Path_File_Name := Getenv (Project_Include_Path_File); if Path_File_Name'Length > 0 then Get_Dirs_From_File (Additional_Source_Dir => True); end if; Path_File_Name := Getenv (Project_Objects_Path_File); if Path_File_Name'Length > 0 then Get_Dirs_From_File (Additional_Source_Dir => False); end if; -- On VMS, don't expand the logical name (e.g. environment variable), -- just put it into Unix (e.g. canonical) format. System services -- will handle the expansion as part of the file processing. for Additional_Source_Dir in False .. True loop if Additional_Source_Dir then Search_Path := Getenv (Ada_Include_Path); if Search_Path'Length > 0 then if Hostparm.OpenVMS then Search_Path := To_Canonical_Path_Spec ("ADA_INCLUDE_PATH:"); else Search_Path := To_Canonical_Path_Spec (Search_Path.all); end if; end if; else Search_Path := Getenv (Ada_Objects_Path); if Search_Path'Length > 0 then if Hostparm.OpenVMS then Search_Path := To_Canonical_Path_Spec ("ADA_OBJECTS_PATH:"); else Search_Path := To_Canonical_Path_Spec (Search_Path.all); end if; end if; end if; Get_Next_Dir_In_Path_Init (Search_Path); loop Search_Dir := Get_Next_Dir_In_Path (Search_Path); exit when Search_Dir = null; Add_Search_Dir (Search_Dir, Additional_Source_Dir); end loop; end loop; -- For the compiler, if --RTS= was specified, add the runtime -- directories. if RTS_Src_Path_Name /= null and then RTS_Lib_Path_Name /= null then Add_Search_Dirs (RTS_Src_Path_Name, Include); Add_Search_Dirs (RTS_Lib_Path_Name, Objects); else if not Opt.No_Stdinc then -- For WIN32 systems, look for any system libraries defined in -- the registry. These are added to both source and object -- directories. Search_Path := String_Access (Get_Libraries_From_Registry); Get_Next_Dir_In_Path_Init (Search_Path); loop Search_Dir := Get_Next_Dir_In_Path (Search_Path); exit when Search_Dir = null; Add_Search_Dir (Search_Dir, False); Add_Search_Dir (Search_Dir, True); end loop; -- The last place to look are the defaults Search_Path := Read_Default_Search_Dirs (String_Access (Update_Path (Search_Dir_Prefix)), Include_Search_File, String_Access (Update_Path (Include_Dir_Default_Name))); Get_Next_Dir_In_Path_Init (Search_Path); loop Search_Dir := Get_Next_Dir_In_Path (Search_Path); exit when Search_Dir = null; Add_Search_Dir (Search_Dir, True); end loop; end if; -- Even when -nostdlib is used, we still want to have visibility on -- the run-time object directory, as it is used by gnatbind to find -- the run-time ALI files in "real" ZFP set up. if not Opt.RTS_Switch then Search_Path := Read_Default_Search_Dirs (String_Access (Update_Path (Search_Dir_Prefix)), Objects_Search_File, String_Access (Update_Path (Object_Dir_Default_Name))); Get_Next_Dir_In_Path_Init (Search_Path); loop Search_Dir := Get_Next_Dir_In_Path (Search_Path); exit when Search_Dir = null; Add_Search_Dir (Search_Dir, False); end loop; end if; end if; end Add_Default_Search_Dirs; -------------- -- Add_File -- -------------- procedure Add_File (File_Name : String; Index : Int := No_Index) is begin Number_File_Names := Number_File_Names + 1; -- As Add_File may be called for mains specified inside a project file, -- File_Names may be too short and needs to be extended. if Number_File_Names > File_Names'Last then File_Names := new File_Name_Array'(File_Names.all & File_Names.all); File_Indexes := new File_Index_Array'(File_Indexes.all & File_Indexes.all); end if; File_Names (Number_File_Names) := new String'(File_Name); File_Indexes (Number_File_Names) := Index; end Add_File; ------------------------ -- Add_Lib_Search_Dir -- ------------------------ procedure Add_Lib_Search_Dir (Dir : String) is begin if Dir'Length = 0 then Fail ("missing library directory name"); end if; declare Norm : String_Ptr := Normalize_Directory_Name (Dir); begin -- Do nothing if the directory is already in the list. This saves -- system calls and avoid unneeded work for D in Lib_Search_Directories.First .. Lib_Search_Directories.Last loop if Lib_Search_Directories.Table (D).all = Norm.all then Free (Norm); return; end if; end loop; Lib_Search_Directories.Increment_Last; Lib_Search_Directories.Table (Lib_Search_Directories.Last) := Norm; end; end Add_Lib_Search_Dir; --------------------- -- Add_Search_Dirs -- --------------------- procedure Add_Search_Dirs (Search_Path : String_Ptr; Path_Type : Search_File_Type) is Current_Search_Path : String_Access; begin Get_Next_Dir_In_Path_Init (String_Access (Search_Path)); loop Current_Search_Path := Get_Next_Dir_In_Path (String_Access (Search_Path)); exit when Current_Search_Path = null; if Path_Type = Include then Add_Src_Search_Dir (Current_Search_Path.all); else Add_Lib_Search_Dir (Current_Search_Path.all); end if; end loop; end Add_Search_Dirs; ------------------------ -- Add_Src_Search_Dir -- ------------------------ procedure Add_Src_Search_Dir (Dir : String) is begin if Dir'Length = 0 then Fail ("missing source directory name"); end if; Src_Search_Directories.Increment_Last; Src_Search_Directories.Table (Src_Search_Directories.Last) := Normalize_Directory_Name (Dir); end Add_Src_Search_Dir; -------------------------------- -- Append_Suffix_To_File_Name -- -------------------------------- function Append_Suffix_To_File_Name (Name : File_Name_Type; Suffix : String) return File_Name_Type is begin Get_Name_String (Name); Name_Buffer (Name_Len + 1 .. Name_Len + Suffix'Length) := Suffix; Name_Len := Name_Len + Suffix'Length; return Name_Find; end Append_Suffix_To_File_Name; --------------------- -- C_String_Length -- --------------------- function C_String_Length (S : Address) return Integer is function Strlen (S : Address) return Integer; pragma Import (C, Strlen, "strlen"); begin if S = Null_Address then return 0; else return Strlen (S); end if; end C_String_Length; ------------------------------ -- Canonical_Case_File_Name -- ------------------------------ procedure Canonical_Case_File_Name (S : in out String) is begin if not File_Names_Case_Sensitive then To_Lower (S); end if; end Canonical_Case_File_Name; --------------------------------- -- Canonical_Case_Env_Var_Name -- --------------------------------- procedure Canonical_Case_Env_Var_Name (S : in out String) is begin if not Env_Vars_Case_Sensitive then To_Lower (S); end if; end Canonical_Case_Env_Var_Name; --------------------------- -- Create_File_And_Check -- --------------------------- procedure Create_File_And_Check (Fdesc : out File_Descriptor; Fmode : Mode) is begin Output_File_Name := Name_Enter; Fdesc := Create_File (Name_Buffer'Address, Fmode); if Fdesc = Invalid_FD then Fail ("Cannot create: " & Name_Buffer (1 .. Name_Len)); end if; end Create_File_And_Check; ------------------------ -- Current_File_Index -- ------------------------ function Current_File_Index return Int is begin return File_Indexes (Current_File_Name_Index); end Current_File_Index; -------------------------------- -- Current_Library_File_Stamp -- -------------------------------- function Current_Library_File_Stamp return Time_Stamp_Type is begin return Current_Full_Lib_Stamp; end Current_Library_File_Stamp; ------------------------------- -- Current_Object_File_Stamp -- ------------------------------- function Current_Object_File_Stamp return Time_Stamp_Type is begin return Current_Full_Obj_Stamp; end Current_Object_File_Stamp; ------------------------------- -- Current_Source_File_Stamp -- ------------------------------- function Current_Source_File_Stamp return Time_Stamp_Type is begin return Current_Full_Source_Stamp; end Current_Source_File_Stamp; ---------------------------- -- Dir_In_Obj_Search_Path -- ---------------------------- function Dir_In_Obj_Search_Path (Position : Natural) return String_Ptr is begin if Opt.Look_In_Primary_Dir then return Lib_Search_Directories.Table (Primary_Directory + Position - 1); else return Lib_Search_Directories.Table (Primary_Directory + Position); end if; end Dir_In_Obj_Search_Path; ---------------------------- -- Dir_In_Src_Search_Path -- ---------------------------- function Dir_In_Src_Search_Path (Position : Natural) return String_Ptr is begin if Opt.Look_In_Primary_Dir then return Src_Search_Directories.Table (Primary_Directory + Position - 1); else return Src_Search_Directories.Table (Primary_Directory + Position); end if; end Dir_In_Src_Search_Path; ---------------------------- -- Dump_Source_File_Names -- ---------------------------- procedure Dump_Source_File_Names is subtype Rng is Int range File_Name_Chars.First .. File_Name_Chars.Last; begin Write_Str (String (File_Name_Chars.Table (Rng))); end Dump_Source_File_Names; --------------------- -- Executable_Name -- --------------------- function Executable_Name (Name : File_Name_Type; Only_If_No_Suffix : Boolean := False) return File_Name_Type is Exec_Suffix : String_Access; Add_Suffix : Boolean; begin if Name = No_File then return No_File; end if; if Executable_Extension_On_Target = No_Name then Exec_Suffix := Get_Target_Executable_Suffix; else Get_Name_String (Executable_Extension_On_Target); Exec_Suffix := new String'(Name_Buffer (1 .. Name_Len)); end if; if Exec_Suffix'Length /= 0 then Get_Name_String (Name); Add_Suffix := True; if Only_If_No_Suffix then for J in reverse 1 .. Name_Len loop if Name_Buffer (J) = '.' then Add_Suffix := False; exit; elsif Name_Buffer (J) = '/' or else Name_Buffer (J) = Directory_Separator then exit; end if; end loop; end if; if Add_Suffix then declare Buffer : String := Name_Buffer (1 .. Name_Len); begin -- Get the file name in canonical case to accept as is names -- ending with ".EXE" on VMS and Windows. Canonical_Case_File_Name (Buffer); -- If Executable does not end with the executable suffix, add -- it. if Buffer'Length <= Exec_Suffix'Length or else Buffer (Buffer'Last - Exec_Suffix'Length + 1 .. Buffer'Last) /= Exec_Suffix.all then Name_Buffer (Name_Len + 1 .. Name_Len + Exec_Suffix'Length) := Exec_Suffix.all; Name_Len := Name_Len + Exec_Suffix'Length; Free (Exec_Suffix); return Name_Find; end if; end; end if; end if; Free (Exec_Suffix); return Name; end Executable_Name; function Executable_Name (Name : String; Only_If_No_Suffix : Boolean := False) return String is Exec_Suffix : String_Access; Add_Suffix : Boolean; Canonical_Name : String := Name; begin if Executable_Extension_On_Target = No_Name then Exec_Suffix := Get_Target_Executable_Suffix; else Get_Name_String (Executable_Extension_On_Target); Exec_Suffix := new String'(Name_Buffer (1 .. Name_Len)); end if; if Exec_Suffix'Length = 0 then Free (Exec_Suffix); return Name; else declare Suffix : constant String := Exec_Suffix.all; begin Free (Exec_Suffix); Canonical_Case_File_Name (Canonical_Name); Add_Suffix := True; if Only_If_No_Suffix then for J in reverse Canonical_Name'Range loop if Canonical_Name (J) = '.' then Add_Suffix := False; exit; elsif Canonical_Name (J) = '/' or else Canonical_Name (J) = Directory_Separator then exit; end if; end loop; end if; if Add_Suffix and then (Canonical_Name'Length <= Suffix'Length or else Canonical_Name (Canonical_Name'Last - Suffix'Length + 1 .. Canonical_Name'Last) /= Suffix) then declare Result : String (1 .. Name'Length + Suffix'Length); begin Result (1 .. Name'Length) := Name; Result (Name'Length + 1 .. Result'Last) := Suffix; return Result; end; else return Name; end if; end; end if; end Executable_Name; ----------------------- -- Executable_Prefix -- ----------------------- function Executable_Prefix return String_Ptr is function Get_Install_Dir (Exec : String) return String_Ptr; -- S is the executable name preceded by the absolute or relative -- path, e.g. "c:\usr\bin\gcc.exe" or "..\bin\gcc". --------------------- -- Get_Install_Dir -- --------------------- function Get_Install_Dir (Exec : String) return String_Ptr is Full_Path : constant String := Normalize_Pathname (Exec); -- Use the full path, so that we find "lib" or "bin", even when -- the tool has been invoked with a relative path, as in -- "./gnatls -v" invoked in the GNAT bin directory. begin for J in reverse Full_Path'Range loop if Is_Directory_Separator (Full_Path (J)) then if J < Full_Path'Last - 5 then if (To_Lower (Full_Path (J + 1)) = 'l' and then To_Lower (Full_Path (J + 2)) = 'i' and then To_Lower (Full_Path (J + 3)) = 'b') or else (To_Lower (Full_Path (J + 1)) = 'b' and then To_Lower (Full_Path (J + 2)) = 'i' and then To_Lower (Full_Path (J + 3)) = 'n') then return new String'(Full_Path (Full_Path'First .. J)); end if; end if; end if; end loop; return new String'(""); end Get_Install_Dir; -- Start of processing for Executable_Prefix begin if Exec_Name = null then Exec_Name := new String (1 .. Len_Arg (0)); Osint.Fill_Arg (Exec_Name (1)'Address, 0); end if; -- First determine if a path prefix was placed in front of the -- executable name. for J in reverse Exec_Name'Range loop if Is_Directory_Separator (Exec_Name (J)) then return Get_Install_Dir (Exec_Name.all); end if; end loop; -- If we come here, the user has typed the executable name with no -- directory prefix. return Get_Install_Dir (Locate_Exec_On_Path (Exec_Name.all).all); end Executable_Prefix; ------------------ -- Exit_Program -- ------------------ procedure Exit_Program (Exit_Code : Exit_Code_Type) is begin -- The program will exit with the following status: -- 0 if the object file has been generated (with or without warnings) -- 1 if recompilation was not needed (smart recompilation) -- 2 if gnat1 has been killed by a signal (detected by GCC) -- 4 for a fatal error -- 5 if there were errors -- 6 if no code has been generated (spec) -- Note that exit code 3 is not used and must not be used as this is -- the code returned by a program aborted via C abort() routine on -- Windows. GCC checks for that case and thinks that the child process -- has been aborted. This code (exit code 3) used to be the code used -- for E_No_Code, but E_No_Code was changed to 6 for this reason. case Exit_Code is when E_Success => OS_Exit (0); when E_Warnings => OS_Exit (0); when E_No_Compile => OS_Exit (1); when E_Fatal => OS_Exit (4); when E_Errors => OS_Exit (5); when E_No_Code => OS_Exit (6); when E_Abort => OS_Abort; end case; end Exit_Program; ---------- -- Fail -- ---------- procedure Fail (S : String) is begin -- We use Output in case there is a special output set up. In this case -- Set_Standard_Error will have no immediate effect. Set_Standard_Error; Osint.Write_Program_Name; Write_Str (": "); Write_Str (S); Write_Eol; Exit_Program (E_Fatal); end Fail; --------------- -- File_Hash -- --------------- function File_Hash (F : File_Name_Type) return File_Hash_Num is begin return File_Hash_Num (Int (F) rem File_Hash_Num'Range_Length); end File_Hash; ----------------- -- File_Length -- ----------------- function File_Length (Name : C_File_Name; Attr : access File_Attributes) return Long_Integer is function Internal (F : Integer; N : C_File_Name; A : System.Address) return Long_Integer; pragma Import (C, Internal, "__gnat_file_length_attr"); begin return Internal (-1, Name, Attr.all'Address); end File_Length; --------------------- -- File_Time_Stamp -- --------------------- function File_Time_Stamp (Name : C_File_Name; Attr : access File_Attributes) return OS_Time is function Internal (N : C_File_Name; A : System.Address) return OS_Time; pragma Import (C, Internal, "__gnat_file_time_name_attr"); begin return Internal (Name, Attr.all'Address); end File_Time_Stamp; function File_Time_Stamp (Name : Path_Name_Type; Attr : access File_Attributes) return Time_Stamp_Type is begin if Name = No_Path then return Empty_Time_Stamp; end if; Get_Name_String (Name); Name_Buffer (Name_Len + 1) := ASCII.NUL; return OS_Time_To_GNAT_Time (File_Time_Stamp (Name_Buffer'Address, Attr)); end File_Time_Stamp; ---------------- -- File_Stamp -- ---------------- function File_Stamp (Name : File_Name_Type) return Time_Stamp_Type is begin if Name = No_File then return Empty_Time_Stamp; end if; Get_Name_String (Name); -- File_Time_Stamp will always return Invalid_Time if the file does -- not exist, and OS_Time_To_GNAT_Time will convert this value to -- Empty_Time_Stamp. Therefore we do not need to first test whether -- the file actually exists, which saves a system call. return OS_Time_To_GNAT_Time (File_Time_Stamp (Name_Buffer (1 .. Name_Len))); end File_Stamp; function File_Stamp (Name : Path_Name_Type) return Time_Stamp_Type is begin return File_Stamp (File_Name_Type (Name)); end File_Stamp; --------------- -- Find_File -- --------------- function Find_File (N : File_Name_Type; T : File_Type) return File_Name_Type is Attr : aliased File_Attributes; Found : File_Name_Type; begin Find_File (N, T, Found, Attr'Access); return Found; end Find_File; --------------- -- Find_File -- --------------- procedure Find_File (N : File_Name_Type; T : File_Type; Found : out File_Name_Type; Attr : access File_Attributes) is begin Get_Name_String (N); declare File_Name : String renames Name_Buffer (1 .. Name_Len); File : File_Name_Type := No_File; Last_Dir : Natural; begin -- If we are looking for a config file, look only in the current -- directory, i.e. return input argument unchanged. Also look only in -- the current directory if we are looking for a .dg file (happens in -- -gnatD mode). if T = Config or else (Debug_Generated_Code and then Name_Len > 3 and then (Name_Buffer (Name_Len - 2 .. Name_Len) = ".dg" or else (Hostparm.OpenVMS and then Name_Buffer (Name_Len - 2 .. Name_Len) = "_dg"))) then Found := N; Attr.all := Unknown_Attributes; return; -- If we are trying to find the current main file just look in the -- directory where the user said it was. elsif Look_In_Primary_Directory_For_Current_Main and then Current_Main = N then Locate_File (N, T, Primary_Directory, File_Name, Found, Attr); return; -- Otherwise do standard search for source file else -- Check the mapping of this file name File := Mapped_Path_Name (N); -- If the file name is mapped to a path name, return the -- corresponding path name if File /= No_File then -- For locally removed file, Error_Name is returned; then -- return No_File, indicating the file is not a source. if File = Error_File_Name then Found := No_File; else Found := File; end if; Attr.all := Unknown_Attributes; return; end if; -- First place to look is in the primary directory (i.e. the same -- directory as the source) unless this has been disabled with -I- if Opt.Look_In_Primary_Dir then Locate_File (N, T, Primary_Directory, File_Name, Found, Attr); if Found /= No_File then return; end if; end if; -- Finally look in directories specified with switches -I/-aI/-aO if T = Library then Last_Dir := Lib_Search_Directories.Last; else Last_Dir := Src_Search_Directories.Last; end if; for D in Primary_Directory + 1 .. Last_Dir loop Locate_File (N, T, D, File_Name, Found, Attr); if Found /= No_File then return; end if; end loop; Attr.all := Unknown_Attributes; Found := No_File; end if; end; end Find_File; ----------------------- -- Find_Program_Name -- ----------------------- procedure Find_Program_Name is Command_Name : String (1 .. Len_Arg (0)); Cindex1 : Integer := Command_Name'First; Cindex2 : Integer := Command_Name'Last; begin Fill_Arg (Command_Name'Address, 0); if Command_Name = "" then Name_Len := 0; return; end if; -- The program name might be specified by a full path name. However, -- we don't want to print that all out in an error message, so the -- path might need to be stripped away. for J in reverse Cindex1 .. Cindex2 loop if Is_Directory_Separator (Command_Name (J)) then Cindex1 := J + 1; exit; end if; end loop; -- Command_Name(Cindex1 .. Cindex2) is now the equivalent of the -- POSIX command "basename argv[0]" -- Strip off any versioning information such as found on VMS. -- This would take the form of TOOL.exe followed by a ";" or "." -- and a sequence of one or more numbers. if Command_Name (Cindex2) in '0' .. '9' then for J in reverse Cindex1 .. Cindex2 loop if Command_Name (J) = '.' or else Command_Name (J) = ';' then Cindex2 := J - 1; exit; end if; exit when Command_Name (J) not in '0' .. '9'; end loop; end if; -- Strip off any executable extension (usually nothing or .exe) -- but formally reported by autoconf in the variable EXEEXT if Cindex2 - Cindex1 >= 4 then if To_Lower (Command_Name (Cindex2 - 3)) = '.' and then To_Lower (Command_Name (Cindex2 - 2)) = 'e' and then To_Lower (Command_Name (Cindex2 - 1)) = 'x' and then To_Lower (Command_Name (Cindex2)) = 'e' then Cindex2 := Cindex2 - 4; end if; end if; Name_Len := Cindex2 - Cindex1 + 1; Name_Buffer (1 .. Name_Len) := Command_Name (Cindex1 .. Cindex2); end Find_Program_Name; ------------------------ -- Full_Lib_File_Name -- ------------------------ procedure Full_Lib_File_Name (N : File_Name_Type; Lib_File : out File_Name_Type; Attr : out File_Attributes) is A : aliased File_Attributes; begin -- ??? seems we could use Smart_Find_File here Find_File (N, Library, Lib_File, A'Access); Attr := A; end Full_Lib_File_Name; ------------------------ -- Full_Lib_File_Name -- ------------------------ function Full_Lib_File_Name (N : File_Name_Type) return File_Name_Type is Attr : File_Attributes; File : File_Name_Type; begin Full_Lib_File_Name (N, File, Attr); return File; end Full_Lib_File_Name; ---------------------------- -- Full_Library_Info_Name -- ---------------------------- function Full_Library_Info_Name return File_Name_Type is begin return Current_Full_Lib_Name; end Full_Library_Info_Name; --------------------------- -- Full_Object_File_Name -- --------------------------- function Full_Object_File_Name return File_Name_Type is begin return Current_Full_Obj_Name; end Full_Object_File_Name; ---------------------- -- Full_Source_Name -- ---------------------- function Full_Source_Name return File_Name_Type is begin return Current_Full_Source_Name; end Full_Source_Name; ---------------------- -- Full_Source_Name -- ---------------------- function Full_Source_Name (N : File_Name_Type) return File_Name_Type is begin return Smart_Find_File (N, Source); end Full_Source_Name; ---------------------- -- Full_Source_Name -- ---------------------- procedure Full_Source_Name (N : File_Name_Type; Full_File : out File_Name_Type; Attr : access File_Attributes) is begin Smart_Find_File (N, Source, Full_File, Attr.all); end Full_Source_Name; ------------------- -- Get_Directory -- ------------------- function Get_Directory (Name : File_Name_Type) return File_Name_Type is begin Get_Name_String (Name); for J in reverse 1 .. Name_Len loop if Is_Directory_Separator (Name_Buffer (J)) then Name_Len := J; return Name_Find; end if; end loop; Name_Len := Hostparm.Normalized_CWD'Length; Name_Buffer (1 .. Name_Len) := Hostparm.Normalized_CWD; return Name_Find; end Get_Directory; -------------------------- -- Get_Next_Dir_In_Path -- -------------------------- Search_Path_Pos : Integer; -- Keeps track of current position in search path. Initialized by the -- call to Get_Next_Dir_In_Path_Init, updated by Get_Next_Dir_In_Path. function Get_Next_Dir_In_Path (Search_Path : String_Access) return String_Access is Lower_Bound : Positive := Search_Path_Pos; Upper_Bound : Positive; begin loop while Lower_Bound <= Search_Path'Last and then Search_Path.all (Lower_Bound) = Path_Separator loop Lower_Bound := Lower_Bound + 1; end loop; exit when Lower_Bound > Search_Path'Last; Upper_Bound := Lower_Bound; while Upper_Bound <= Search_Path'Last and then Search_Path.all (Upper_Bound) /= Path_Separator loop Upper_Bound := Upper_Bound + 1; end loop; Search_Path_Pos := Upper_Bound; return new String'(Search_Path.all (Lower_Bound .. Upper_Bound - 1)); end loop; return null; end Get_Next_Dir_In_Path; ------------------------------- -- Get_Next_Dir_In_Path_Init -- ------------------------------- procedure Get_Next_Dir_In_Path_Init (Search_Path : String_Access) is begin Search_Path_Pos := Search_Path'First; end Get_Next_Dir_In_Path_Init; -------------------------------------- -- Get_Primary_Src_Search_Directory -- -------------------------------------- function Get_Primary_Src_Search_Directory return String_Ptr is begin return Src_Search_Directories.Table (Primary_Directory); end Get_Primary_Src_Search_Directory; ------------------------ -- Get_RTS_Search_Dir -- ------------------------ function Get_RTS_Search_Dir (Search_Dir : String; File_Type : Search_File_Type) return String_Ptr is procedure Get_Current_Dir (Dir : System.Address; Length : System.Address); pragma Import (C, Get_Current_Dir, "__gnat_get_current_dir"); Max_Path : Integer; pragma Import (C, Max_Path, "__gnat_max_path_len"); -- Maximum length of a path name Current_Dir : String_Ptr; Default_Search_Dir : String_Access; Default_Suffix_Dir : String_Access; Local_Search_Dir : String_Access; Norm_Search_Dir : String_Access; Result_Search_Dir : String_Access; Search_File : String_Access; Temp_String : String_Ptr; begin -- Add a directory separator at the end of the directory if necessary -- so that we can directly append a file to the directory if Search_Dir (Search_Dir'Last) /= Directory_Separator then Local_Search_Dir := new String'(Search_Dir & String'(1 => Directory_Separator)); else Local_Search_Dir := new String'(Search_Dir); end if; if File_Type = Include then Search_File := Include_Search_File; Default_Suffix_Dir := new String'("adainclude"); else Search_File := Objects_Search_File; Default_Suffix_Dir := new String'("adalib"); end if; Norm_Search_Dir := To_Canonical_Path_Spec (Local_Search_Dir.all); if Is_Absolute_Path (Norm_Search_Dir.all) then -- We first verify if there is a directory Include_Search_Dir -- containing default search directories Result_Search_Dir := Read_Default_Search_Dirs (Norm_Search_Dir, Search_File, null); Default_Search_Dir := new String'(Norm_Search_Dir.all & Default_Suffix_Dir.all); Free (Norm_Search_Dir); if Result_Search_Dir /= null then return String_Ptr (Result_Search_Dir); elsif Is_Directory (Default_Search_Dir.all) then return String_Ptr (Default_Search_Dir); else return null; end if; -- Search in the current directory else -- Get the current directory declare Buffer : String (1 .. Max_Path + 2); Path_Len : Natural := Max_Path; begin Get_Current_Dir (Buffer'Address, Path_Len'Address); if Buffer (Path_Len) /= Directory_Separator then Path_Len := Path_Len + 1; Buffer (Path_Len) := Directory_Separator; end if; Current_Dir := new String'(Buffer (1 .. Path_Len)); end; Norm_Search_Dir := new String'(Current_Dir.all & Local_Search_Dir.all); Result_Search_Dir := Read_Default_Search_Dirs (Norm_Search_Dir, Search_File, null); Default_Search_Dir := new String'(Norm_Search_Dir.all & Default_Suffix_Dir.all); Free (Norm_Search_Dir); if Result_Search_Dir /= null then return String_Ptr (Result_Search_Dir); elsif Is_Directory (Default_Search_Dir.all) then return String_Ptr (Default_Search_Dir); else -- Search in Search_Dir_Prefix/Search_Dir Norm_Search_Dir := new String' (Update_Path (Search_Dir_Prefix).all & Local_Search_Dir.all); Result_Search_Dir := Read_Default_Search_Dirs (Norm_Search_Dir, Search_File, null); Default_Search_Dir := new String'(Norm_Search_Dir.all & Default_Suffix_Dir.all); Free (Norm_Search_Dir); if Result_Search_Dir /= null then return String_Ptr (Result_Search_Dir); elsif Is_Directory (Default_Search_Dir.all) then return String_Ptr (Default_Search_Dir); else -- We finally search in Search_Dir_Prefix/rts-Search_Dir Temp_String := new String'(Update_Path (Search_Dir_Prefix).all & "rts-"); Norm_Search_Dir := new String'(Temp_String.all & Local_Search_Dir.all); Result_Search_Dir := Read_Default_Search_Dirs (Norm_Search_Dir, Search_File, null); Default_Search_Dir := new String'(Norm_Search_Dir.all & Default_Suffix_Dir.all); Free (Norm_Search_Dir); if Result_Search_Dir /= null then return String_Ptr (Result_Search_Dir); elsif Is_Directory (Default_Search_Dir.all) then return String_Ptr (Default_Search_Dir); else return null; end if; end if; end if; end if; end Get_RTS_Search_Dir; -------------------------------- -- Include_Dir_Default_Prefix -- -------------------------------- function Include_Dir_Default_Prefix return String_Access is begin if The_Include_Dir_Default_Prefix = null then The_Include_Dir_Default_Prefix := String_Access (Update_Path (Include_Dir_Default_Name)); end if; return The_Include_Dir_Default_Prefix; end Include_Dir_Default_Prefix; function Include_Dir_Default_Prefix return String is begin return Include_Dir_Default_Prefix.all; end Include_Dir_Default_Prefix; ---------------- -- Initialize -- ---------------- procedure Initialize is begin Number_File_Names := 0; Current_File_Name_Index := 0; Src_Search_Directories.Init; Lib_Search_Directories.Init; -- Start off by setting all suppress options, to False. The special -- overflow fields are set to Not_Set (they will be set by -gnatp, or -- by -gnato, or, if neither of these appear, in Adjust_Global_Switches -- in Gnat1drv). Suppress_Options := ((others => False), Not_Set, Not_Set); -- Reserve the first slot in the search paths table. This is the -- directory of the main source file or main library file and is filled -- in by each call to Next_Main_Source/Next_Main_Lib_File with the -- directory specified for this main source or library file. This is the -- directory which is searched first by default. This default search is -- inhibited by the option -I- for both source and library files. Src_Search_Directories.Set_Last (Primary_Directory); Src_Search_Directories.Table (Primary_Directory) := new String'(""); Lib_Search_Directories.Set_Last (Primary_Directory); Lib_Search_Directories.Table (Primary_Directory) := new String'(""); end Initialize; ------------------ -- Is_Directory -- ------------------ function Is_Directory (Name : C_File_Name; Attr : access File_Attributes) return Boolean is function Internal (N : C_File_Name; A : System.Address) return Integer; pragma Import (C, Internal, "__gnat_is_directory_attr"); begin return Internal (Name, Attr.all'Address) /= 0; end Is_Directory; ---------------------------- -- Is_Directory_Separator -- ---------------------------- function Is_Directory_Separator (C : Character) return Boolean is begin -- In addition to the default directory_separator allow the '/' to -- act as separator since this is allowed in MS-DOS, Windows 95/NT, -- and OS2 ports. On VMS, the situation is more complicated because -- there are two characters to check for. return C = Directory_Separator or else C = '/' or else (Hostparm.OpenVMS and then (C = ']' or else C = ':')); end Is_Directory_Separator; ------------------------- -- Is_Readonly_Library -- ------------------------- function Is_Readonly_Library (File : File_Name_Type) return Boolean is begin Get_Name_String (File); pragma Assert (Name_Buffer (Name_Len - 3 .. Name_Len) = ".ali"); return not Is_Writable_File (Name_Buffer (1 .. Name_Len)); end Is_Readonly_Library; ------------------------ -- Is_Executable_File -- ------------------------ function Is_Executable_File (Name : C_File_Name; Attr : access File_Attributes) return Boolean is function Internal (N : C_File_Name; A : System.Address) return Integer; pragma Import (C, Internal, "__gnat_is_executable_file_attr"); begin return Internal (Name, Attr.all'Address) /= 0; end Is_Executable_File; ---------------------- -- Is_Readable_File -- ---------------------- function Is_Readable_File (Name : C_File_Name; Attr : access File_Attributes) return Boolean is function Internal (N : C_File_Name; A : System.Address) return Integer; pragma Import (C, Internal, "__gnat_is_readable_file_attr"); begin return Internal (Name, Attr.all'Address) /= 0; end Is_Readable_File; --------------------- -- Is_Regular_File -- --------------------- function Is_Regular_File (Name : C_File_Name; Attr : access File_Attributes) return Boolean is function Internal (N : C_File_Name; A : System.Address) return Integer; pragma Import (C, Internal, "__gnat_is_regular_file_attr"); begin return Internal (Name, Attr.all'Address) /= 0; end Is_Regular_File; ---------------------- -- Is_Symbolic_Link -- ---------------------- function Is_Symbolic_Link (Name : C_File_Name; Attr : access File_Attributes) return Boolean is function Internal (N : C_File_Name; A : System.Address) return Integer; pragma Import (C, Internal, "__gnat_is_symbolic_link_attr"); begin return Internal (Name, Attr.all'Address) /= 0; end Is_Symbolic_Link; ---------------------- -- Is_Writable_File -- ---------------------- function Is_Writable_File (Name : C_File_Name; Attr : access File_Attributes) return Boolean is function Internal (N : C_File_Name; A : System.Address) return Integer; pragma Import (C, Internal, "__gnat_is_writable_file_attr"); begin return Internal (Name, Attr.all'Address) /= 0; end Is_Writable_File; ------------------- -- Lib_File_Name -- ------------------- function Lib_File_Name (Source_File : File_Name_Type; Munit_Index : Nat := 0) return File_Name_Type is begin Get_Name_String (Source_File); for J in reverse 2 .. Name_Len loop if Name_Buffer (J) = '.' then Name_Len := J - 1; exit; end if; end loop; if Munit_Index /= 0 then Add_Char_To_Name_Buffer (Multi_Unit_Index_Character); Add_Nat_To_Name_Buffer (Munit_Index); end if; Add_Char_To_Name_Buffer ('.'); Add_Str_To_Name_Buffer (ALI_Suffix.all); return Name_Find; end Lib_File_Name; ----------------- -- Locate_File -- ----------------- procedure Locate_File (N : File_Name_Type; T : File_Type; Dir : Natural; Name : String; Found : out File_Name_Type; Attr : access File_Attributes) is Dir_Name : String_Ptr; begin -- If Name is already an absolute path, do not look for a directory if Is_Absolute_Path (Name) then Dir_Name := No_Dir; elsif T = Library then Dir_Name := Lib_Search_Directories.Table (Dir); else pragma Assert (T /= Config); Dir_Name := Src_Search_Directories.Table (Dir); end if; declare Full_Name : String (1 .. Dir_Name'Length + Name'Length + 1); begin Full_Name (1 .. Dir_Name'Length) := Dir_Name.all; Full_Name (Dir_Name'Length + 1 .. Full_Name'Last - 1) := Name; Full_Name (Full_Name'Last) := ASCII.NUL; Attr.all := Unknown_Attributes; if not Is_Regular_File (Full_Name'Address, Attr) then Found := No_File; else -- If the file is in the current directory then return N itself if Dir_Name'Length = 0 then Found := N; else Name_Len := Full_Name'Length - 1; Name_Buffer (1 .. Name_Len) := Full_Name (1 .. Full_Name'Last - 1); Found := Name_Find; -- ??? Was Name_Enter, no obvious reason end if; end if; end; end Locate_File; ------------------------------- -- Matching_Full_Source_Name -- ------------------------------- function Matching_Full_Source_Name (N : File_Name_Type; T : Time_Stamp_Type) return File_Name_Type is begin Get_Name_String (N); declare File_Name : constant String := Name_Buffer (1 .. Name_Len); File : File_Name_Type := No_File; Attr : aliased File_Attributes; Last_Dir : Natural; begin if Opt.Look_In_Primary_Dir then Locate_File (N, Source, Primary_Directory, File_Name, File, Attr'Access); if File /= No_File and then T = File_Stamp (N) then return File; end if; end if; Last_Dir := Src_Search_Directories.Last; for D in Primary_Directory + 1 .. Last_Dir loop Locate_File (N, Source, D, File_Name, File, Attr'Access); if File /= No_File and then T = File_Stamp (File) then return File; end if; end loop; return No_File; end; end Matching_Full_Source_Name; ---------------- -- More_Files -- ---------------- function More_Files return Boolean is begin return (Current_File_Name_Index < Number_File_Names); end More_Files; ------------------------------- -- Nb_Dir_In_Obj_Search_Path -- ------------------------------- function Nb_Dir_In_Obj_Search_Path return Natural is begin if Opt.Look_In_Primary_Dir then return Lib_Search_Directories.Last - Primary_Directory + 1; else return Lib_Search_Directories.Last - Primary_Directory; end if; end Nb_Dir_In_Obj_Search_Path; ------------------------------- -- Nb_Dir_In_Src_Search_Path -- ------------------------------- function Nb_Dir_In_Src_Search_Path return Natural is begin if Opt.Look_In_Primary_Dir then return Src_Search_Directories.Last - Primary_Directory + 1; else return Src_Search_Directories.Last - Primary_Directory; end if; end Nb_Dir_In_Src_Search_Path; -------------------- -- Next_Main_File -- -------------------- function Next_Main_File return File_Name_Type is File_Name : String_Ptr; Dir_Name : String_Ptr; Fptr : Natural; begin pragma Assert (More_Files); Current_File_Name_Index := Current_File_Name_Index + 1; -- Get the file and directory name File_Name := File_Names (Current_File_Name_Index); Fptr := File_Name'First; for J in reverse File_Name'Range loop if File_Name (J) = Directory_Separator or else File_Name (J) = '/' then if J = File_Name'Last then Fail ("File name missing"); end if; Fptr := J + 1; exit; end if; end loop; -- Save name of directory in which main unit resides for use in -- locating other units Dir_Name := new String'(File_Name (File_Name'First .. Fptr - 1)); case Running_Program is when Compiler => Src_Search_Directories.Table (Primary_Directory) := Dir_Name; Look_In_Primary_Directory_For_Current_Main := True; when Make => Src_Search_Directories.Table (Primary_Directory) := Dir_Name; if Fptr > File_Name'First then Look_In_Primary_Directory_For_Current_Main := True; end if; when Binder | Gnatls => Dir_Name := Normalize_Directory_Name (Dir_Name.all); Lib_Search_Directories.Table (Primary_Directory) := Dir_Name; when Unspecified => null; end case; Name_Len := File_Name'Last - Fptr + 1; Name_Buffer (1 .. Name_Len) := File_Name (Fptr .. File_Name'Last); Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); Current_Main := Name_Find; -- In the gnatmake case, the main file may have not have the -- extension. Try ".adb" first then ".ads" if Running_Program = Make then declare Orig_Main : constant File_Name_Type := Current_Main; begin if Strip_Suffix (Orig_Main) = Orig_Main then Current_Main := Append_Suffix_To_File_Name (Orig_Main, ".adb"); if Full_Source_Name (Current_Main) = No_File then Current_Main := Append_Suffix_To_File_Name (Orig_Main, ".ads"); if Full_Source_Name (Current_Main) = No_File then Current_Main := Orig_Main; end if; end if; end if; end; end if; return Current_Main; end Next_Main_File; ------------------------------ -- Normalize_Directory_Name -- ------------------------------ function Normalize_Directory_Name (Directory : String) return String_Ptr is function Is_Quoted (Path : String) return Boolean; pragma Inline (Is_Quoted); -- Returns true if Path is quoted (either double or single quotes) --------------- -- Is_Quoted -- --------------- function Is_Quoted (Path : String) return Boolean is First : constant Character := Path (Path'First); Last : constant Character := Path (Path'Last); begin if (First = ''' and then Last = ''') or else (First = '"' and then Last = '"') then return True; else return False; end if; end Is_Quoted; Result : String_Ptr; -- Start of processing for Normalize_Directory_Name begin if Directory'Length = 0 then Result := new String'(Hostparm.Normalized_CWD); elsif Is_Directory_Separator (Directory (Directory'Last)) then Result := new String'(Directory); elsif Is_Quoted (Directory) then -- This is a quoted string, it certainly means that the directory -- contains some spaces for example. We can safely remove the quotes -- here as the OS_Lib.Normalize_Arguments will be called before any -- spawn routines. This ensure that quotes will be added when needed. Result := new String (1 .. Directory'Length - 1); Result (1 .. Directory'Length - 2) := Directory (Directory'First + 1 .. Directory'Last - 1); Result (Result'Last) := Directory_Separator; else Result := new String (1 .. Directory'Length + 1); Result (1 .. Directory'Length) := Directory; Result (Directory'Length + 1) := Directory_Separator; end if; return Result; end Normalize_Directory_Name; --------------------- -- Number_Of_Files -- --------------------- function Number_Of_Files return Int is begin return Number_File_Names; end Number_Of_Files; ------------------------------- -- Object_Dir_Default_Prefix -- ------------------------------- function Object_Dir_Default_Prefix return String is Object_Dir : String_Access := String_Access (Update_Path (Object_Dir_Default_Name)); begin if Object_Dir = null then return ""; else declare Result : constant String := Object_Dir.all; begin Free (Object_Dir); return Result; end; end if; end Object_Dir_Default_Prefix; ---------------------- -- Object_File_Name -- ---------------------- function Object_File_Name (N : File_Name_Type) return File_Name_Type is begin if N = No_File then return No_File; end if; Get_Name_String (N); Name_Len := Name_Len - ALI_Suffix'Length - 1; for J in Target_Object_Suffix'Range loop Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := Target_Object_Suffix (J); end loop; return Name_Enter; end Object_File_Name; ------------------------------- -- OS_Exit_Through_Exception -- ------------------------------- procedure OS_Exit_Through_Exception (Status : Integer) is begin Current_Exit_Status := Status; raise Types.Terminate_Program; end OS_Exit_Through_Exception; -------------------------- -- OS_Time_To_GNAT_Time -- -------------------------- function OS_Time_To_GNAT_Time (T : OS_Time) return Time_Stamp_Type is GNAT_Time : Time_Stamp_Type; Y : Year_Type; Mo : Month_Type; D : Day_Type; H : Hour_Type; Mn : Minute_Type; S : Second_Type; begin if T = Invalid_Time then return Empty_Time_Stamp; end if; GM_Split (T, Y, Mo, D, H, Mn, S); Make_Time_Stamp (Year => Nat (Y), Month => Nat (Mo), Day => Nat (D), Hour => Nat (H), Minutes => Nat (Mn), Seconds => Nat (S), TS => GNAT_Time); return GNAT_Time; end OS_Time_To_GNAT_Time; ----------------- -- Prep_Suffix -- ----------------- function Prep_Suffix return String is begin if Hostparm.OpenVMS then return "_prep"; else return ".prep"; end if; end Prep_Suffix; ------------------ -- Program_Name -- ------------------ function Program_Name (Nam : String; Prog : String) return String_Access is End_Of_Prefix : Natural := 0; Start_Of_Prefix : Positive := 1; Start_Of_Suffix : Positive; begin -- GNAAMP tool names require special treatment if AAMP_On_Target then -- The name "gcc" is mapped to "gnaamp" (the compiler driver) if Nam = "gcc" then return new String'("gnaamp"); -- Tool names starting with "gnat" are mapped by substituting the -- string "gnaamp" for "gnat" (for example, "gnatpp" => "gnaamppp"). elsif Nam'Length >= 4 and then Nam (Nam'First .. Nam'First + 3) = "gnat" then return new String'("gnaamp" & Nam (Nam'First + 4 .. Nam'Last)); -- No other mapping rules, so we continue and handle any other forms -- of tool names the same as on other targets. else null; end if; end if; -- Get the name of the current program being executed Find_Program_Name; Start_Of_Suffix := Name_Len + 1; -- Find the target prefix if any, for the cross compilation case. -- For instance in "powerpc-elf-gcc" the target prefix is -- "powerpc-elf-" -- Ditto for suffix, e.g. in "gcc-4.1", the suffix is "-4.1" for J in reverse 1 .. Name_Len loop if Name_Buffer (J) = '/' or else Name_Buffer (J) = Directory_Separator or else Name_Buffer (J) = ':' then Start_Of_Prefix := J + 1; exit; end if; end loop; -- Find End_Of_Prefix for J in Start_Of_Prefix .. Name_Len - Prog'Length + 1 loop if Name_Buffer (J .. J + Prog'Length - 1) = Prog then End_Of_Prefix := J - 1; exit; end if; end loop; if End_Of_Prefix > 1 then Start_Of_Suffix := End_Of_Prefix + Prog'Length + 1; end if; -- Create the new program name return new String' (Name_Buffer (Start_Of_Prefix .. End_Of_Prefix) & Nam & Name_Buffer (Start_Of_Suffix .. Name_Len)); end Program_Name; ------------------------------ -- Read_Default_Search_Dirs -- ------------------------------ function Read_Default_Search_Dirs (Search_Dir_Prefix : String_Access; Search_File : String_Access; Search_Dir_Default_Name : String_Access) return String_Access is Prefix_Len : constant Integer := Search_Dir_Prefix.all'Length; Buffer : String (1 .. Prefix_Len + Search_File.all'Length + 1); File_FD : File_Descriptor; S, S1 : String_Access; Len : Integer; Curr : Integer; Actual_Len : Integer; J1 : Integer; Prev_Was_Separator : Boolean; Nb_Relative_Dir : Integer; function Is_Relative (S : String; K : Positive) return Boolean; pragma Inline (Is_Relative); -- Returns True if a relative directory specification is found -- in S at position K, False otherwise. ----------------- -- Is_Relative -- ----------------- function Is_Relative (S : String; K : Positive) return Boolean is begin return not Is_Absolute_Path (S (K .. S'Last)); end Is_Relative; -- Start of processing for Read_Default_Search_Dirs begin -- Construct a C compatible character string buffer Buffer (1 .. Search_Dir_Prefix.all'Length) := Search_Dir_Prefix.all; Buffer (Search_Dir_Prefix.all'Length + 1 .. Buffer'Last - 1) := Search_File.all; Buffer (Buffer'Last) := ASCII.NUL; File_FD := Open_Read (Buffer'Address, Binary); if File_FD = Invalid_FD then return Search_Dir_Default_Name; end if; Len := Integer (File_Length (File_FD)); -- An extra character for a trailing Path_Separator is allocated S := new String (1 .. Len + 1); S (Len + 1) := Path_Separator; -- Read the file. Note that the loop is not necessary since the -- whole file is read at once except on VMS. Curr := 1; Actual_Len := Len; while Actual_Len /= 0 loop Actual_Len := Read (File_FD, S (Curr)'Address, Len); Curr := Curr + Actual_Len; end loop; -- Process the file, dealing with path separators Prev_Was_Separator := True; Nb_Relative_Dir := 0; for J in 1 .. Len loop -- Treat any control character as a path separator. Note that we do -- not treat space as a path separator (we used to treat space as a -- path separator in an earlier version). That way space can appear -- as a legitimate character in a path name. -- Why do we treat all control characters as path separators??? if S (J) in ASCII.NUL .. ASCII.US then S (J) := Path_Separator; end if; -- Test for explicit path separator (or control char as above) if S (J) = Path_Separator then Prev_Was_Separator := True; -- If not path separator, register use of relative directory else if Prev_Was_Separator and then Is_Relative (S.all, J) then Nb_Relative_Dir := Nb_Relative_Dir + 1; end if; Prev_Was_Separator := False; end if; end loop; if Nb_Relative_Dir = 0 then return S; end if; -- Add the Search_Dir_Prefix to all relative paths S1 := new String (1 .. S'Length + Nb_Relative_Dir * Prefix_Len); J1 := 1; Prev_Was_Separator := True; for J in 1 .. Len + 1 loop if S (J) = Path_Separator then Prev_Was_Separator := True; else if Prev_Was_Separator and then Is_Relative (S.all, J) then S1 (J1 .. J1 + Prefix_Len - 1) := Search_Dir_Prefix.all; J1 := J1 + Prefix_Len; end if; Prev_Was_Separator := False; end if; S1 (J1) := S (J); J1 := J1 + 1; end loop; Free (S); return S1; end Read_Default_Search_Dirs; ----------------------- -- Read_Library_Info -- ----------------------- function Read_Library_Info (Lib_File : File_Name_Type; Fatal_Err : Boolean := False) return Text_Buffer_Ptr is File : File_Name_Type; Attr : aliased File_Attributes; begin Find_File (Lib_File, Library, File, Attr'Access); return Read_Library_Info_From_Full (Full_Lib_File => File, Lib_File_Attr => Attr'Access, Fatal_Err => Fatal_Err); end Read_Library_Info; --------------------------------- -- Read_Library_Info_From_Full -- --------------------------------- function Read_Library_Info_From_Full (Full_Lib_File : File_Name_Type; Lib_File_Attr : access File_Attributes; Fatal_Err : Boolean := False) return Text_Buffer_Ptr is Lib_FD : File_Descriptor; -- The file descriptor for the current library file. A negative value -- indicates failure to open the specified source file. Len : Integer; -- Length of source file text (ALI). If it doesn't fit in an integer -- we're probably stuck anyway (>2 gigs of source seems a lot, and -- there are other places in the compiler that make this assumption). Text : Text_Buffer_Ptr; -- Allocated text buffer Status : Boolean; pragma Warnings (Off, Status); -- For the calls to Close begin Current_Full_Lib_Name := Full_Lib_File; Current_Full_Obj_Name := Object_File_Name (Current_Full_Lib_Name); if Current_Full_Lib_Name = No_File then if Fatal_Err then Fail ("Cannot find: " & Name_Buffer (1 .. Name_Len)); else Current_Full_Obj_Stamp := Empty_Time_Stamp; return null; end if; end if; Get_Name_String (Current_Full_Lib_Name); Name_Buffer (Name_Len + 1) := ASCII.NUL; -- Open the library FD, note that we open in binary mode, because as -- documented in the spec, the caller is expected to handle either -- DOS or Unix mode files, and there is no point in wasting time on -- text translation when it is not required. Lib_FD := Open_Read (Name_Buffer'Address, Binary); if Lib_FD = Invalid_FD then if Fatal_Err then Fail ("Cannot open: " & Name_Buffer (1 .. Name_Len)); else Current_Full_Obj_Stamp := Empty_Time_Stamp; return null; end if; end if; -- Compute the length of the file (potentially also preparing other data -- like the timestamp and whether the file is read-only, for future use) Len := Integer (File_Length (Name_Buffer'Address, Lib_File_Attr)); -- Check for object file consistency if requested if Opt.Check_Object_Consistency then -- On most systems, this does not result in an extra system call Current_Full_Lib_Stamp := OS_Time_To_GNAT_Time (File_Time_Stamp (Name_Buffer'Address, Lib_File_Attr)); -- ??? One system call here Current_Full_Obj_Stamp := File_Stamp (Current_Full_Obj_Name); if Current_Full_Obj_Stamp (1) = ' ' then -- When the library is readonly always assume object is consistent -- The call to Is_Writable_File only results in a system call on -- some systems, but in most cases it has already been computed as -- part of the call to File_Length above. Get_Name_String (Current_Full_Lib_Name); Name_Buffer (Name_Len + 1) := ASCII.NUL; if not Is_Writable_File (Name_Buffer'Address, Lib_File_Attr) then Current_Full_Obj_Stamp := Current_Full_Lib_Stamp; elsif Fatal_Err then Get_Name_String (Current_Full_Obj_Name); Close (Lib_FD, Status); -- No need to check the status, we fail anyway Fail ("Cannot find: " & Name_Buffer (1 .. Name_Len)); else Current_Full_Obj_Stamp := Empty_Time_Stamp; Close (Lib_FD, Status); -- No need to check the status, we return null anyway return null; end if; elsif Current_Full_Obj_Stamp < Current_Full_Lib_Stamp then Close (Lib_FD, Status); -- No need to check the status, we return null anyway return null; end if; end if; -- Read data from the file declare Actual_Len : Integer := 0; Lo : constant Text_Ptr := 0; -- Low bound for allocated text buffer Hi : Text_Ptr := Text_Ptr (Len); -- High bound for allocated text buffer. Note length is Len + 1 -- which allows for extra EOF character at the end of the buffer. begin -- Allocate text buffer. Note extra character at end for EOF Text := new Text_Buffer (Lo .. Hi); -- Some systems (e.g. VMS) have file types that require one -- read per line, so read until we get the Len bytes or until -- there are no more characters. Hi := Lo; loop Actual_Len := Read (Lib_FD, Text (Hi)'Address, Len); Hi := Hi + Text_Ptr (Actual_Len); exit when Actual_Len = Len or else Actual_Len <= 0; end loop; Text (Hi) := EOF; end; -- Read is complete, close file and we are done Close (Lib_FD, Status); -- The status should never be False. But, if it is, what can we do? -- So, we don't test it. return Text; end Read_Library_Info_From_Full; ---------------------- -- Read_Source_File -- ---------------------- procedure Read_Source_File (N : File_Name_Type; Lo : Source_Ptr; Hi : out Source_Ptr; Src : out Source_Buffer_Ptr; T : File_Type := Source) is Source_File_FD : File_Descriptor; -- The file descriptor for the current source file. A negative value -- indicates failure to open the specified source file. Len : Integer; -- Length of file, assume no more than 2 gigabytes of source Actual_Len : Integer; Status : Boolean; pragma Warnings (Off, Status); -- For the call to Close begin Current_Full_Source_Name := Find_File (N, T); Current_Full_Source_Stamp := File_Stamp (Current_Full_Source_Name); if Current_Full_Source_Name = No_File then -- If we were trying to access the main file and we could not find -- it, we have an error. if N = Current_Main then Get_Name_String (N); Fail ("Cannot find: " & Name_Buffer (1 .. Name_Len)); end if; Src := null; Hi := No_Location; return; end if; Get_Name_String (Current_Full_Source_Name); Name_Buffer (Name_Len + 1) := ASCII.NUL; -- Open the source FD, note that we open in binary mode, because as -- documented in the spec, the caller is expected to handle either -- DOS or Unix mode files, and there is no point in wasting time on -- text translation when it is not required. Source_File_FD := Open_Read (Name_Buffer'Address, Binary); if Source_File_FD = Invalid_FD then Src := null; Hi := No_Location; return; end if; -- Print out the file name, if requested, and if it's not part of the -- runtimes, store it in File_Name_Chars. declare Name : String renames Name_Buffer (1 .. Name_Len); Inc : String renames Include_Dir_Default_Prefix.all; begin if Debug.Debug_Flag_Dot_N then Write_Line (Name); end if; if Inc /= "" and then Inc'Length < Name_Len and then Name_Buffer (1 .. Inc'Length) = Inc then -- Part of runtimes, so ignore it null; else File_Name_Chars.Append_All (File_Name_Chars.Table_Type (Name)); File_Name_Chars.Append (ASCII.LF); end if; end; -- Prepare to read data from the file Len := Integer (File_Length (Source_File_FD)); -- Set Hi so that length is one more than the physical length, -- allowing for the extra EOF character at the end of the buffer Hi := Lo + Source_Ptr (Len); -- Do the actual read operation declare subtype Actual_Source_Buffer is Source_Buffer (Lo .. Hi); -- Physical buffer allocated type Actual_Source_Ptr is access Actual_Source_Buffer; -- This is the pointer type for the physical buffer allocated Actual_Ptr : constant Actual_Source_Ptr := new Actual_Source_Buffer; -- And this is the actual physical buffer begin -- Allocate source buffer, allowing extra character at end for EOF -- Some systems (e.g. VMS) have file types that require one read per -- line, so read until we get the Len bytes or until there are no -- more characters. Hi := Lo; loop Actual_Len := Read (Source_File_FD, Actual_Ptr (Hi)'Address, Len); Hi := Hi + Source_Ptr (Actual_Len); exit when Actual_Len = Len or else Actual_Len <= 0; end loop; Actual_Ptr (Hi) := EOF; -- Now we need to work out the proper virtual origin pointer to -- return. This is exactly Actual_Ptr (0)'Address, but we have to -- be careful to suppress checks to compute this address. declare pragma Suppress (All_Checks); pragma Warnings (Off); -- This use of unchecked conversion is aliasing safe function To_Source_Buffer_Ptr is new Unchecked_Conversion (Address, Source_Buffer_Ptr); pragma Warnings (On); begin Src := To_Source_Buffer_Ptr (Actual_Ptr (0)'Address); end; end; -- Read is complete, get time stamp and close file and we are done Close (Source_File_FD, Status); -- The status should never be False. But, if it is, what can we do? -- So, we don't test it. end Read_Source_File; ------------------- -- Relocate_Path -- ------------------- function Relocate_Path (Prefix : String; Path : String) return String_Ptr is S : String_Ptr; procedure set_std_prefix (S : String; Len : Integer); pragma Import (C, set_std_prefix); begin if Std_Prefix = null then Std_Prefix := Executable_Prefix; if Std_Prefix.all /= "" then -- Remove trailing directory separator when calling set_std_prefix set_std_prefix (Std_Prefix.all, Std_Prefix'Length - 1); end if; end if; if Path (Prefix'Range) = Prefix then if Std_Prefix.all /= "" then S := new String (1 .. Std_Prefix'Length + Path'Last - Prefix'Last); S (1 .. Std_Prefix'Length) := Std_Prefix.all; S (Std_Prefix'Length + 1 .. S'Last) := Path (Prefix'Last + 1 .. Path'Last); return S; end if; end if; return new String'(Path); end Relocate_Path; ----------------- -- Set_Program -- ----------------- procedure Set_Program (P : Program_Type) is begin if Program_Set then Fail ("Set_Program called twice"); end if; Program_Set := True; Running_Program := P; end Set_Program; ---------------- -- Shared_Lib -- ---------------- function Shared_Lib (Name : String) return String is Library : String (1 .. Name'Length + Library_Version'Length + 3); -- 3 = 2 for "-l" + 1 for "-" before lib version begin Library (1 .. 2) := "-l"; Library (3 .. 2 + Name'Length) := Name; Library (3 + Name'Length) := '-'; Library (4 + Name'Length .. Library'Last) := Library_Version; if OpenVMS_On_Target then for K in Library'First + 2 .. Library'Last loop if Library (K) = '.' or else Library (K) = '-' then Library (K) := '_'; end if; end loop; end if; return Library; end Shared_Lib; ---------------------- -- Smart_File_Stamp -- ---------------------- function Smart_File_Stamp (N : File_Name_Type; T : File_Type) return Time_Stamp_Type is File : File_Name_Type; Attr : aliased File_Attributes; begin if not File_Cache_Enabled then Find_File (N, T, File, Attr'Access); else Smart_Find_File (N, T, File, Attr); end if; if File = No_File then return Empty_Time_Stamp; else Get_Name_String (File); Name_Buffer (Name_Len + 1) := ASCII.NUL; return OS_Time_To_GNAT_Time (File_Time_Stamp (Name_Buffer'Address, Attr'Access)); end if; end Smart_File_Stamp; --------------------- -- Smart_Find_File -- --------------------- function Smart_Find_File (N : File_Name_Type; T : File_Type) return File_Name_Type is File : File_Name_Type; Attr : File_Attributes; begin Smart_Find_File (N, T, File, Attr); return File; end Smart_Find_File; --------------------- -- Smart_Find_File -- --------------------- procedure Smart_Find_File (N : File_Name_Type; T : File_Type; Found : out File_Name_Type; Attr : out File_Attributes) is Info : File_Info_Cache; begin if not File_Cache_Enabled then Find_File (N, T, Info.File, Info.Attr'Access); else Info := File_Name_Hash_Table.Get (N); if Info.File = No_File then Find_File (N, T, Info.File, Info.Attr'Access); File_Name_Hash_Table.Set (N, Info); end if; end if; Found := Info.File; Attr := Info.Attr; end Smart_Find_File; ---------------------- -- Source_File_Data -- ---------------------- procedure Source_File_Data (Cache : Boolean) is begin File_Cache_Enabled := Cache; end Source_File_Data; ----------------------- -- Source_File_Stamp -- ----------------------- function Source_File_Stamp (N : File_Name_Type) return Time_Stamp_Type is begin return Smart_File_Stamp (N, Source); end Source_File_Stamp; --------------------- -- Strip_Directory -- --------------------- function Strip_Directory (Name : File_Name_Type) return File_Name_Type is begin Get_Name_String (Name); for J in reverse 1 .. Name_Len - 1 loop -- If we find the last directory separator if Is_Directory_Separator (Name_Buffer (J)) then -- Return part of Name that follows this last directory separator Name_Buffer (1 .. Name_Len - J) := Name_Buffer (J + 1 .. Name_Len); Name_Len := Name_Len - J; return Name_Find; end if; end loop; -- There were no directory separator, just return Name return Name; end Strip_Directory; ------------------ -- Strip_Suffix -- ------------------ function Strip_Suffix (Name : File_Name_Type) return File_Name_Type is begin Get_Name_String (Name); for J in reverse 2 .. Name_Len loop -- If we found the last '.', return part of Name that precedes it if Name_Buffer (J) = '.' then Name_Len := J - 1; return Name_Enter; end if; end loop; return Name; end Strip_Suffix; --------------------------- -- To_Canonical_Dir_Spec -- --------------------------- function To_Canonical_Dir_Spec (Host_Dir : String; Prefix_Style : Boolean) return String_Access is function To_Canonical_Dir_Spec (Host_Dir : Address; Prefix_Flag : Integer) return Address; pragma Import (C, To_Canonical_Dir_Spec, "__gnat_to_canonical_dir_spec"); C_Host_Dir : String (1 .. Host_Dir'Length + 1); Canonical_Dir_Addr : Address; Canonical_Dir_Len : Integer; begin C_Host_Dir (1 .. Host_Dir'Length) := Host_Dir; C_Host_Dir (C_Host_Dir'Last) := ASCII.NUL; if Prefix_Style then Canonical_Dir_Addr := To_Canonical_Dir_Spec (C_Host_Dir'Address, 1); else Canonical_Dir_Addr := To_Canonical_Dir_Spec (C_Host_Dir'Address, 0); end if; Canonical_Dir_Len := C_String_Length (Canonical_Dir_Addr); if Canonical_Dir_Len = 0 then return null; else return To_Path_String_Access (Canonical_Dir_Addr, Canonical_Dir_Len); end if; exception when others => Fail ("invalid directory spec: " & Host_Dir); return null; end To_Canonical_Dir_Spec; --------------------------- -- To_Canonical_File_List -- --------------------------- function To_Canonical_File_List (Wildcard_Host_File : String; Only_Dirs : Boolean) return String_Access_List_Access is function To_Canonical_File_List_Init (Host_File : Address; Only_Dirs : Integer) return Integer; pragma Import (C, To_Canonical_File_List_Init, "__gnat_to_canonical_file_list_init"); function To_Canonical_File_List_Next return Address; pragma Import (C, To_Canonical_File_List_Next, "__gnat_to_canonical_file_list_next"); procedure To_Canonical_File_List_Free; pragma Import (C, To_Canonical_File_List_Free, "__gnat_to_canonical_file_list_free"); Num_Files : Integer; C_Wildcard_Host_File : String (1 .. Wildcard_Host_File'Length + 1); begin C_Wildcard_Host_File (1 .. Wildcard_Host_File'Length) := Wildcard_Host_File; C_Wildcard_Host_File (C_Wildcard_Host_File'Last) := ASCII.NUL; -- Do the expansion and say how many there are Num_Files := To_Canonical_File_List_Init (C_Wildcard_Host_File'Address, Boolean'Pos (Only_Dirs)); declare Canonical_File_List : String_Access_List (1 .. Num_Files); Canonical_File_Addr : Address; Canonical_File_Len : Integer; begin -- Retrieve the expanded directory names and build the list for J in 1 .. Num_Files loop Canonical_File_Addr := To_Canonical_File_List_Next; Canonical_File_Len := C_String_Length (Canonical_File_Addr); Canonical_File_List (J) := To_Path_String_Access (Canonical_File_Addr, Canonical_File_Len); end loop; -- Free up the storage To_Canonical_File_List_Free; return new String_Access_List'(Canonical_File_List); end; end To_Canonical_File_List; ---------------------------- -- To_Canonical_File_Spec -- ---------------------------- function To_Canonical_File_Spec (Host_File : String) return String_Access is function To_Canonical_File_Spec (Host_File : Address) return Address; pragma Import (C, To_Canonical_File_Spec, "__gnat_to_canonical_file_spec"); C_Host_File : String (1 .. Host_File'Length + 1); Canonical_File_Addr : Address; Canonical_File_Len : Integer; begin C_Host_File (1 .. Host_File'Length) := Host_File; C_Host_File (C_Host_File'Last) := ASCII.NUL; Canonical_File_Addr := To_Canonical_File_Spec (C_Host_File'Address); Canonical_File_Len := C_String_Length (Canonical_File_Addr); if Canonical_File_Len = 0 then return null; else return To_Path_String_Access (Canonical_File_Addr, Canonical_File_Len); end if; exception when others => Fail ("invalid file spec: " & Host_File); return null; end To_Canonical_File_Spec; ---------------------------- -- To_Canonical_Path_Spec -- ---------------------------- function To_Canonical_Path_Spec (Host_Path : String) return String_Access is function To_Canonical_Path_Spec (Host_Path : Address) return Address; pragma Import (C, To_Canonical_Path_Spec, "__gnat_to_canonical_path_spec"); C_Host_Path : String (1 .. Host_Path'Length + 1); Canonical_Path_Addr : Address; Canonical_Path_Len : Integer; begin C_Host_Path (1 .. Host_Path'Length) := Host_Path; C_Host_Path (C_Host_Path'Last) := ASCII.NUL; Canonical_Path_Addr := To_Canonical_Path_Spec (C_Host_Path'Address); Canonical_Path_Len := C_String_Length (Canonical_Path_Addr); -- Return a null string (vice a null) for zero length paths, for -- compatibility with getenv(). return To_Path_String_Access (Canonical_Path_Addr, Canonical_Path_Len); exception when others => Fail ("invalid path spec: " & Host_Path); return null; end To_Canonical_Path_Spec; ---------------------- -- To_Host_Dir_Spec -- ---------------------- function To_Host_Dir_Spec (Canonical_Dir : String; Prefix_Style : Boolean) return String_Access is function To_Host_Dir_Spec (Canonical_Dir : Address; Prefix_Flag : Integer) return Address; pragma Import (C, To_Host_Dir_Spec, "__gnat_to_host_dir_spec"); C_Canonical_Dir : String (1 .. Canonical_Dir'Length + 1); Host_Dir_Addr : Address; Host_Dir_Len : Integer; begin C_Canonical_Dir (1 .. Canonical_Dir'Length) := Canonical_Dir; C_Canonical_Dir (C_Canonical_Dir'Last) := ASCII.NUL; if Prefix_Style then Host_Dir_Addr := To_Host_Dir_Spec (C_Canonical_Dir'Address, 1); else Host_Dir_Addr := To_Host_Dir_Spec (C_Canonical_Dir'Address, 0); end if; Host_Dir_Len := C_String_Length (Host_Dir_Addr); if Host_Dir_Len = 0 then return null; else return To_Path_String_Access (Host_Dir_Addr, Host_Dir_Len); end if; end To_Host_Dir_Spec; ----------------------- -- To_Host_File_Spec -- ----------------------- function To_Host_File_Spec (Canonical_File : String) return String_Access is function To_Host_File_Spec (Canonical_File : Address) return Address; pragma Import (C, To_Host_File_Spec, "__gnat_to_host_file_spec"); C_Canonical_File : String (1 .. Canonical_File'Length + 1); Host_File_Addr : Address; Host_File_Len : Integer; begin C_Canonical_File (1 .. Canonical_File'Length) := Canonical_File; C_Canonical_File (C_Canonical_File'Last) := ASCII.NUL; Host_File_Addr := To_Host_File_Spec (C_Canonical_File'Address); Host_File_Len := C_String_Length (Host_File_Addr); if Host_File_Len = 0 then return null; else return To_Path_String_Access (Host_File_Addr, Host_File_Len); end if; end To_Host_File_Spec; --------------------------- -- To_Path_String_Access -- --------------------------- function To_Path_String_Access (Path_Addr : Address; Path_Len : Integer) return String_Access is subtype Path_String is String (1 .. Path_Len); type Path_String_Access is access Path_String; function Address_To_Access is new Unchecked_Conversion (Source => Address, Target => Path_String_Access); Path_Access : constant Path_String_Access := Address_To_Access (Path_Addr); Return_Val : String_Access; begin Return_Val := new String (1 .. Path_Len); for J in 1 .. Path_Len loop Return_Val (J) := Path_Access (J); end loop; return Return_Val; end To_Path_String_Access; ----------------- -- Update_Path -- ----------------- function Update_Path (Path : String_Ptr) return String_Ptr is function C_Update_Path (Path, Component : Address) return Address; pragma Import (C, C_Update_Path, "update_path"); function Strlen (Str : Address) return Integer; pragma Import (C, Strlen, "strlen"); procedure Strncpy (X : Address; Y : Address; Length : Integer); pragma Import (C, Strncpy, "strncpy"); In_Length : constant Integer := Path'Length; In_String : String (1 .. In_Length + 1); Component_Name : aliased String := "GCC" & ASCII.NUL; Result_Ptr : Address; Result_Length : Integer; Out_String : String_Ptr; begin In_String (1 .. In_Length) := Path.all; In_String (In_Length + 1) := ASCII.NUL; Result_Ptr := C_Update_Path (In_String'Address, Component_Name'Address); Result_Length := Strlen (Result_Ptr); Out_String := new String (1 .. Result_Length); Strncpy (Out_String.all'Address, Result_Ptr, Result_Length); return Out_String; end Update_Path; ---------------- -- Write_Info -- ---------------- procedure Write_Info (Info : String) is begin Write_With_Check (Info'Address, Info'Length); Write_With_Check (EOL'Address, 1); end Write_Info; ------------------------ -- Write_Program_Name -- ------------------------ procedure Write_Program_Name is Save_Buffer : constant String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len); begin Find_Program_Name; -- Convert the name to lower case so error messages are the same on -- all systems. for J in 1 .. Name_Len loop if Name_Buffer (J) in 'A' .. 'Z' then Name_Buffer (J) := Character'Val (Character'Pos (Name_Buffer (J)) + 32); end if; end loop; Write_Str (Name_Buffer (1 .. Name_Len)); -- Restore Name_Buffer which was clobbered by the call to -- Find_Program_Name Name_Len := Save_Buffer'Last; Name_Buffer (1 .. Name_Len) := Save_Buffer; end Write_Program_Name; ---------------------- -- Write_With_Check -- ---------------------- procedure Write_With_Check (A : Address; N : Integer) is Ignore : Boolean; pragma Warnings (Off, Ignore); begin if N = Write (Output_FD, A, N) then return; else Write_Str ("error: disk full writing "); Write_Name_Decoded (Output_File_Name); Write_Eol; Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := ASCII.NUL; Delete_File (Name_Buffer'Address, Ignore); Exit_Program (E_Fatal); end if; end Write_With_Check; ---------------------------- -- Package Initialization -- ---------------------------- procedure Reset_File_Attributes (Attr : System.Address); pragma Import (C, Reset_File_Attributes, "__gnat_reset_attributes"); begin Initialization : declare function Get_Default_Identifier_Character_Set return Character; pragma Import (C, Get_Default_Identifier_Character_Set, "__gnat_get_default_identifier_character_set"); -- Function to determine the default identifier character set, -- which is system dependent. See Opt package spec for a list of -- the possible character codes and their interpretations. function Get_Maximum_File_Name_Length return Int; pragma Import (C, Get_Maximum_File_Name_Length, "__gnat_get_maximum_file_name_length"); -- Function to get maximum file name length for system Sizeof_File_Attributes : Integer; pragma Import (C, Sizeof_File_Attributes, "__gnat_size_of_file_attributes"); begin pragma Assert (Sizeof_File_Attributes <= File_Attributes_Size); Reset_File_Attributes (Unknown_Attributes'Address); Identifier_Character_Set := Get_Default_Identifier_Character_Set; Maximum_File_Name_Length := Get_Maximum_File_Name_Length; -- Following should be removed by having above function return -- Integer'Last as indication of no maximum instead of -1 ??? if Maximum_File_Name_Length = -1 then Maximum_File_Name_Length := Int'Last; end if; Src_Search_Directories.Set_Last (Primary_Directory); Src_Search_Directories.Table (Primary_Directory) := new String'(""); Lib_Search_Directories.Set_Last (Primary_Directory); Lib_Search_Directories.Table (Primary_Directory) := new String'(""); Osint.Initialize; end Initialization; end Osint; gprbuild-gpl-2014-src/gnat/xutil.ads0000644000076700001450000000467112323721731016732 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT SYSTEM UTILITIES -- -- -- -- X U T I L -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- Shared routines for the build-time code generation utilities with Ada.Streams.Stream_IO; with Ada.Strings.Unbounded; package XUtil is subtype VString is Ada.Strings.Unbounded.Unbounded_String; subtype Sfile is Ada.Streams.Stream_IO.File_Type; procedure Put (F : Sfile; S : String); procedure Put (F : Sfile; S : VString); procedure Put_Line (F : Sfile; S : String); procedure Put_Line (F : Sfile; S : VString); procedure New_Line (F : Sfile); -- Similar to the same-named Ada.Text_IO routines, but ensure UNIX line -- ending on all platforms. end XUtil; gprbuild-gpl-2014-src/gnat/krunch.adb0000644000076700001450000002164112323721731017032 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- K R U N C H -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Hostparm; procedure Krunch (Buffer : in out String; Len : in out Natural; Maxlen : Natural; No_Predef : Boolean; VMS_On_Target : Boolean := False) is pragma Assert (Buffer'First = 1); -- This is a documented requirement; the assert turns off index warnings B1 : Character renames Buffer (1); Curlen : Natural; Krlen : Natural; Num_Seps : Natural; Startloc : Natural; J : Natural; begin -- Deal with special predefined children cases. Startloc is the first -- location for the krunch, set to 1, except for the predefined children -- case, where it is set to 3, to start after the standard prefix. if No_Predef then Startloc := 1; Curlen := Len; Krlen := Maxlen; elsif Len >= 18 and then Buffer (1 .. 17) = "ada-wide_text_io-" then Startloc := 3; Buffer (2 .. 5) := "-wt-"; Buffer (6 .. Len - 12) := Buffer (18 .. Len); Curlen := Len - 12; Krlen := 8; elsif Len >= 23 and then Buffer (1 .. 22) = "ada-wide_wide_text_io-" then Startloc := 3; Buffer (2 .. 5) := "-zt-"; Buffer (6 .. Len - 17) := Buffer (23 .. Len); Curlen := Len - 17; Krlen := 8; elsif Len >= 4 and then Buffer (1 .. 4) = "ada-" then Startloc := 3; Buffer (2 .. Len - 2) := Buffer (4 .. Len); Curlen := Len - 2; Krlen := 8; elsif Len >= 5 and then Buffer (1 .. 5) = "gnat-" then Startloc := 3; Buffer (2 .. Len - 3) := Buffer (5 .. Len); Curlen := Len - 3; Krlen := 8; elsif Len >= 7 and then Buffer (1 .. 7) = "system-" then Startloc := 3; Buffer (2 .. Len - 5) := Buffer (7 .. Len); Curlen := Len - 5; Krlen := 8; elsif Len >= 11 and then Buffer (1 .. 11) = "interfaces-" then Startloc := 3; Buffer (2 .. Len - 9) := Buffer (11 .. Len); Curlen := Len - 9; Krlen := 8; -- For the renamings in the obsolescent section, we also force krunching -- to 8 characters, but no other special processing is required here. -- Note that text_io and calendar are already short enough anyway. elsif (Len = 9 and then Buffer (1 .. 9) = "direct_io") or else (Len = 10 and then Buffer (1 .. 10) = "interfaces") or else (Len = 13 and then Buffer (1 .. 13) = "io_exceptions") or else (Len = 12 and then Buffer (1 .. 12) = "machine_code") or else (Len = 13 and then Buffer (1 .. 13) = "sequential_io") or else (Len = 20 and then Buffer (1 .. 20) = "unchecked_conversion") or else (Len = 22 and then Buffer (1 .. 22) = "unchecked_deallocation") then Startloc := 1; Krlen := 8; Curlen := Len; -- Special case of a child unit whose parent unit is a single letter that -- is A, G, I, or S. In order to prevent confusion with krunched names -- of predefined units use a tilde rather than a minus as the second -- character of the file name. On VMS a tilde is an illegal character -- in a file name, two consecutive underlines ("__") are used instead. elsif Len > 1 and then Buffer (2) = '-' and then (B1 = 'a' or else B1 = 'g' or else B1 = 'i' or else B1 = 's') and then Len <= Maxlen then -- When VMS is the host, it is always also the target if Hostparm.OpenVMS or else VMS_On_Target then Len := Len + 1; Buffer (4 .. Len) := Buffer (3 .. Len - 1); Buffer (2) := '_'; Buffer (3) := '_'; else Buffer (2) := '~'; end if; if Len <= Maxlen then return; else -- Case of VMS when the buffer had exactly the length Maxlen and now -- has the length Maxlen + 1: krunching after "__" is needed. Startloc := 4; Curlen := Len; Krlen := Maxlen; end if; -- Normal case, not a predefined file else Startloc := 1; Curlen := Len; Krlen := Maxlen; end if; -- Immediate return if file name is short enough now if Curlen <= Krlen then Len := Curlen; return; end if; -- If string contains Wide_Wide, replace by a single z J := Startloc; while J <= Curlen - 8 loop if Buffer (J .. J + 8) = "wide_wide" and then (J = Startloc or else Buffer (J - 1) = '-' or else Buffer (J - 1) = '_') and then (J + 8 = Curlen or else Buffer (J + 9) = '-' or else Buffer (J + 9) = '_') then Buffer (J) := 'z'; Buffer (J + 1 .. Curlen - 8) := Buffer (J + 9 .. Curlen); Curlen := Curlen - 8; end if; J := J + 1; end loop; -- For now, refuse to krunch a name that contains an ESC character (wide -- character sequence) since it's too much trouble to do this right ??? for J in 1 .. Curlen loop if Buffer (J) = ASCII.ESC then return; end if; end loop; -- Count number of separators (minus signs and underscores) and for now -- replace them by spaces. We keep them around till the end to control -- the krunching process, and then we eliminate them as the last step Num_Seps := 0; for J in Startloc .. Curlen loop if Buffer (J) = '-' or else Buffer (J) = '_' then Buffer (J) := ' '; Num_Seps := Num_Seps + 1; end if; end loop; -- Now we do the one character at a time krunch till we are short enough while Curlen - Num_Seps > Krlen loop declare Long_Length : Natural := 0; Long_Last : Natural := 0; Piece_Start : Natural; Ptr : Natural; begin Ptr := Startloc; -- Loop through pieces to find longest piece while Ptr <= Curlen loop Piece_Start := Ptr; -- Loop through characters in one piece of name while Ptr <= Curlen and then Buffer (Ptr) /= ' ' loop Ptr := Ptr + 1; end loop; if Ptr - Piece_Start > Long_Length then Long_Length := Ptr - Piece_Start; Long_Last := Ptr - 1; end if; Ptr := Ptr + 1; end loop; -- Remove last character of longest piece if Long_Last < Curlen then Buffer (Long_Last .. Curlen - 1) := Buffer (Long_Last + 1 .. Curlen); end if; Curlen := Curlen - 1; end; end loop; -- Final step, remove the spaces Len := 0; for J in 1 .. Curlen loop if Buffer (J) /= ' ' then Len := Len + 1; Buffer (Len) := Buffer (J); end if; end loop; return; end Krunch; gprbuild-gpl-2014-src/gnat/debug.adb0000644000076700001450000014317012323721731016630 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- D E B U G -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ package body Debug is --------------------------------- -- Summary of Debug Flag Usage -- --------------------------------- -- Debug flags for compiler (GNAT1) -- da Generate messages tracking semantic analyzer progress -- db Show encoding of type names for debug output -- dc List names of units as they are compiled -- dd Dynamic allocation of tables messages generated -- de List the entity table -- df Full tree/source print (includes withed units) -- dg Print source from tree (generated code only) -- dh Generate listing showing loading of name table hash chains -- di Generate messages for visibility linking/delinking -- dj Suppress "junk null check" for access parameter values -- dk Generate GNATBUG message on abort, even if previous errors -- dl Generate unit load trace messages -- dm Allow VMS features even if not OpenVMS version -- dn Generate messages for node/list allocation -- do Print source from tree (original code only) -- dp Generate messages for parser scope stack push/pops -- dq No auto-alignment of small records -- dr Generate parser resynchronization messages -- ds Print source from tree (including original and generated stuff) -- dt Print full tree -- du Uncheck categorization pragmas -- dv Output trace of overload resolution -- dw Print trace of semantic scope stack -- dx Force expansion on, even if no code being generated -- dy Print tree of package Standard -- dz Print source of package Standard -- dA All entities included in representation information output -- dB Output debug encoding of type names and variants -- dC Output debugging information on check suppression -- dD Delete elaboration checks in inner level routines -- dE Apply elaboration checks to predefined units -- dF Front end data layout enabled -- dG Generate all warnings including those normally suppressed -- dH Hold (kill) call to gigi -- dI Inhibit internal name numbering in gnatG listing -- dJ Output debugging trace info for JGNAT (Java VM version of GNAT) -- dK Kill all error messages -- dL Output trace information on elaboration checking -- dM Assume all variables are modified (no current values) -- dN No file name information in exception messages -- dO Output immediate error messages -- dP Do not check for controlled objects in preelaborable packages -- dQ Enable inlining in GNATprove mode -- dR Bypass check for correct version of s-rpc -- dS Never convert numbers to machine numbers in Sem_Eval -- dT Convert to machine numbers only for constant declarations -- dU Enable garbage collection of unreachable entities -- dV Enable viewing of all symbols in debugger -- dW Disable warnings on calls for IN OUT parameters -- dX Display messages on reads of potentially uninitialized scalars -- dY Enable configurable run-time mode -- dZ Generate listing showing the contents of the dispatch tables -- d.a Force Target_Strict_Alignment mode to True -- d.b Dump backend types -- d.c Generate inline concatenation, do not call procedure -- d.d Disable atomic synchronization -- d.e Enable atomic synchronization -- d.f Inhibit folding of static expressions -- d.g Enable conversion of raise into goto -- d.h -- d.i Ignore Warnings pragmas -- d.j Generate listing of frontend inlined calls -- d.k Enable new support for frontend inlining -- d.l Use Ada 95 semantics for limited function returns -- d.m For -gnatl, print full source only for main unit -- d.n Print source file names -- d.o Generate .NET listing of CIL code -- d.p Enable the .NET CIL verifier -- d.q -- d.r Enable OK_To_Reorder_Components in non-variant records -- d.s Disable expansion of slice move, use memmove -- d.t Disable static allocation of library level dispatch tables -- d.u Enable Modify_Tree_For_C (update tree for c) -- d.v Enable OK_To_Reorder_Components in variant records -- d.w Do not check for infinite loops -- d.x No exception handlers -- d.y -- d.z -- d.A Read/write Aspect_Specifications hash table to tree -- d.B -- d.C Generate concatenation call, do not generate inline code -- d.D -- d.E Turn selected errors into warnings -- d.F Debug mode for GNATprove -- d.G Ignore calls through generic formal parameters for elaboration -- d.H -- d.I Do not ignore enum representation clauses in CodePeer mode -- d.J Disable parallel SCIL generation mode -- d.K -- d.L Depend on back end for limited types in if and case expressions -- d.M Relaxed RM semantics -- d.N Add node to all entities -- d.O Dump internal SCO tables -- d.P Previous (non-optimized) handling of length comparisons -- d.Q Previous (incomplete) style check for binary operators -- d.R Restrictions in ali files in positional form -- d.S Force Optimize_Alignment (Space) -- d.T Force Optimize_Alignment (Time) -- d.U Ignore indirect calls for static elaboration -- d.V View generated C code -- d.W Print out debugging information for Walk_Library_Items -- d.X -- d.Y -- d.Z -- d1 Error msgs have node numbers where possible -- d2 Eliminate error flags in verbose form error messages -- d3 Dump bad node in Comperr on an abort -- d4 Inhibit automatic krunch of predefined library unit files -- d5 Debug output for tree read/write -- d6 Default access unconstrained to thin pointers -- d7 Do not output version & file time stamp in -gnatv or -gnatl mode -- d8 Force opposite endianness in packed stuff -- d9 Allow lock free implementation -- d.1 -- d.2 -- d.3 -- d.4 -- d.5 -- d.6 -- d.7 -- d.8 -- d.9 -- Debug flags for binder (GNATBIND) -- da All links (including internal units) listed if there is a cycle -- db Output information from Better_Choice -- dc List units as they are chosen -- dd -- de Elaboration dependencies including system units -- df -- dg -- dh -- di Ignore_Errors mode for reading ali files -- dj -- dk -- dl -- dm -- dn List details of manipulation of Num_Pred values -- do Use old preference for elaboration order -- dp -- dq -- dr -- ds -- dt -- du List units as they are acquired -- dv -- dw -- dx Force binder to read xref information from ali files -- dy -- dz -- Debug flags used in package Make and its clients (e.g. GNATMAKE) -- da -- db -- dc -- dd -- de -- df Only output file names, not path names, in log -- dg -- dh Generate listing showing loading of name table hash chains -- di -- dj -- dk -- dl -- dm Display the number of maximum simultaneous compilations -- dn Do not delete temp files created by gnatmake -- do -- dp Prints the contents of the Q used by Make.Compile_Sources -- dq Prints source files as they are enqueued and dequeued -- dr -- ds -- dt Display time stamps when there is a mismatch -- du List units as their ali files are acquired -- dv -- dw Prints the list of units withed by the unit currently explored -- dx -- dy -- dz -------------------------------------------- -- Documentation for Compiler Debug Flags -- -------------------------------------------- -- da Generate messages tracking semantic analyzer progress. A message -- is output showing each node as it gets analyzed, expanded, -- resolved, or evaluated. This option is useful for finding out -- exactly where a bomb during semantic analysis is occurring. -- db In Exp_Dbug, certain type names are encoded to include debugging -- information. This debug switch causes lines to be output showing -- the encodings used. -- dc List names of units as they are compiled. One line of output will -- be generated at the start of compiling each unit (package or -- subprogram). -- dd Dynamic allocation of tables messages generated. Each time a -- table is reallocated, a line is output indicating the expansion. -- de List the entity table -- df Full tree/source print (includes withed units). Normally the tree -- output (dt) or recreated source output (dg,do,ds) includes only -- the main unit. If df is set, then the output in either case -- includes all compiled units (see also dg,do,ds,dt). Note that to -- be effective, this swich must be used in combination with one or -- more of dt, dg, do or ds. -- dg Print the source recreated from the generated tree. In the case -- where the tree has been rewritten this output includes only the -- generated code, not the original code (see also df,do,ds,dz). -- This flag differs from -gnatG in that the output also includes -- non-source generated null statements, and freeze nodes, which -- are normally omitted in -gnatG mode. -- dh Generates a table at the end of a compilation showing how the hash -- table chains built by the Namet package are loaded. This is useful -- in ensuring that the hashing algorithm (in Namet.Hash) is working -- effectively with typical sets of program identifiers. -- di Generate messages for visibility linking/delinking -- dj Suppress "junk null check" for access parameters. This flag permits -- Ada programs to pass null parameters to access parameters, and to -- explicitly check such access values against the null literal. -- Neither of these is valid Ada, but both were allowed in versions of -- GNAT before 3.10, so this switch can ease the transition process. -- dk Immediate kill on abort. Normally on an abort (i.e. a call to -- Comperr.Compiler_Abort), the GNATBUG message is not given if -- there is a previous error. This debug switch bypasses this test -- and gives the message unconditionally (useful for debugging). -- dl Generate unit load trace messages. A line of traceback output is -- generated each time a request is made to the library manager to -- load a new unit. -- dm Some features are permitted only in OpenVMS ports of GNAT (e.g. -- the specification of passing by descriptor). Normally any use -- of these features will be flagged as an error, but this debug -- flag allows acceptance of these features in non OpenVMS ports. -- Of course they may not have any useful effect, and in particular -- attempting to generate code with this flag set may blow up. -- The flag also forces the use of 64-bits for Long_Integer. -- dn Generate messages for node/list allocation. Each time a node or -- list header is allocated, a line of output is generated. Certain -- other basic tree operations also cause a line of output to be -- generated. This option is useful in seeing where the parser is -- blowing up. -- do Print the source recreated from the generated tree. In the case -- where the tree has been rewritten, this output includes only the -- original code, not the generated code (see also df,dg,ds,dz). -- dp Generate messages for parser scope stack push/pops. A line of -- output by the parser each time the parser scope stack is either -- pushed or popped. Useful in debugging situations where the -- parser scope stack ends up incorrectly synchronized -- dq In layout version 1.38, 2002/01/12, a circuit was implemented -- to give decent default alignment to short records that had no -- specific alignment set. This debug option restores the previous -- behavior of giving such records poor alignments, typically 1. -- This may be useful in dealing with transition. -- dr Generate parser resynchronization messages. Normally the parser -- resynchronizes quietly. With this debug option, two messages -- are generated, one when the parser starts a resynchronization -- skip, and another when it resumes parsing. Useful in debugging -- inadequate error recovery situations. -- ds Print the source recreated from the generated tree. In the case -- where the tree has been rewritten this output includes both the -- generated code and the original code with the generated code -- being enlosed in curly brackets (see also df,do,ds,dz) -- dt Print full tree. The generated tree is output (see also df,dy) -- du Uncheck categorization pragmas. This debug switch causes the -- categorization pragmas (Pure, Preelaborate etc) to be ignored -- so that normal checks are not made (this is particularly useful -- for adding temporary debugging code to units that have pragmas -- that are inconsistent with the debugging code added. -- dv Output trace of overload resolution. Outputs messages for -- overload attempts that involve cascaded errors, or where -- an interepretation is incompatible with the context. -- dw Write semantic scope stack messages. Each time a scope is created -- or removed, a message is output (see the Sem_Ch8.Push_Scope and -- Sem_Ch8.Pop_Scope subprograms). -- dx Force expansion on, even if no code being generated. Normally the -- expander is inhibited if no code is generated. This switch forces -- expansion to proceed normally even if the backend is not being -- called. This is particularly useful for debugging purposes when -- using the front-end only version of the compiler (which normally -- would never do any expansion). -- dy Print tree of package Standard. Normally the tree print out does -- not include package Standard, even if the -df switch is set. This -- switch forces output of the internal tree built for Standard. -- dz Print source of package Standard. Normally the source print out -- does not include package Standard, even if the -df switch is set. -- This switch forces output of the source recreated from the internal -- tree built for Standard. Note that this differs from -gnatS in -- that it prints from the actual tree using the normal Sprint -- circuitry for printing trees. -- dA Forces output of representation information, including full -- information for all internal type and object entities, as well -- as all user defined type and object entities including private -- and incomplete types. This debug switch also automatically sets -- the equivalent of -gnatR3m. -- dB Output debug encodings for types and variants. See Exp_Dbug for -- exact form of the generated output. -- dC Output trace information showing the decisions made during -- check suppression activity in unit Checks. -- dD Delete new elaboration checks. This flag causes GNAT to return -- to the 3.13a elaboration semantics, and to suppress the fixing -- of two bugs. The first is in the context of inner routines in -- dynamic elaboration mode, when the subprogram we are in was -- called at elaboration time by a unit that was also compiled with -- dynamic elaboration checks. In this case, if A calls B calls C, -- and all are in different units, we need an elaboration check at -- each call. These nested checks were only put in recently (see -- version 1.80 of Sem_Elab) and we provide this debug flag to -- revert to the previous behavior in case of regressions. The -- other behavior reverted by this flag is the treatment of the -- Elaborate_Body pragma in static elaboration mode. This used to -- be treated as not needing elaboration checking, but in fact in -- general Elaborate_All is still required because of nested calls. -- dE Apply compile time elaboration checking for with relations between -- predefined units. Normally no checks are made (it seems that at -- least on the SGI, such checks run into trouble). -- dF Front end data layout enabled. Normally front end data layout -- is only enabled if the target parameter Backend_Layout is False. -- This debugging switch enables it unconditionally. -- dG Generate all warnings. Normally Errout suppresses warnings on -- units that are not part of the main extended source, and also -- suppresses warnings on instantiations in the main extended -- source that duplicate warnings already posted on the template. -- This switch stops both kinds of deletion and causes Errout to -- post all warnings sent to it. -- dH Inhibit call to gigi. This is useful for testing front end data -- layout, and may be useful in other debugging situations where -- you do not want gigi to intefere with the testing. -- dI Inhibit internal name numbering in gnatDG listing. Any sequence of -- the form appearing in -- a name is replaced by .... This -- is used in the fixed bugs run to minimize system and version -- dependency in filed -gnatD or -gnatG output. -- dJ Generate debugging trace output for the JGNAT back end. This -- consists of symbolic Java Byte Code sequences for all generated -- classes plus additional information to indicate local variables -- and methods. -- dK Kill all error messages. This debug flag suppresses the output -- of all error messages. It is used in regression tests where the -- error messages are target dependent and irrelevant. -- dL Output trace information on elaboration checking. This debug -- switch causes output to be generated showing each call or -- instantiation as it is checked, and the progress of the recursive -- trace through calls at elaboration time. -- dM Assume all variables have been modified, and ignore current value -- indications. This debug flag disconnects the tracking of constant -- values (see Exp_Ch2.Expand_Current_Value). -- dN Do not generate file name information in exception messages -- dO Output immediate error messages. This causes error messages to -- be output as soon as they are generated (disconnecting several -- circuits for improvement of messages, deletion of duplicate -- messages etc). Useful to diagnose compiler bombs caused by -- erroneous handling of error situations -- dP Do not check for controlled objects in preelaborable packages. -- RM 10.2.1(9) forbids the use of library level controlled objects -- in preelaborable packages, but this restriction is a huge pain, -- especially in the predefined library units. -- dQ Enable inlining in GNATprove mode. Although expansion is not set in -- GNATprove mode, inlining is useful for improving the precision of -- formal verification. Under a debug flag until fully reliable. -- dR Bypass the check for a proper version of s-rpc being present -- to use the -gnatz? switch. This allows debugging of the use -- of stubs generation without needing to have GLADE (or some -- other PCS installed). -- dS Omit conversion of fpt numbers to exact machine numbers in -- non-static evaluation contexts (see Check_Non_Static_Context). -- This is intended for testing out timing problems with this -- conversion circuit. -- dT Similar to dS, but omits the conversions only in the case where -- the parent is not a constant declaration. -- dU Enable garbage collection of unreachable entities. This enables -- both the reachability analysis and changing the Is_Public and -- Is_Eliminated flags. -- dV Enable viewing of all symbols in debugger. Causes debug information -- to be generated for all symbols, including internal symbols. This -- is enabled by default for -gnatD, but this switch allows this to -- be enabled without generating modified source files. Note that the -- use of -gnatdV ensures in the dwarf/elf case that all symbols that -- are present in the elf tables are also in the dwarf tables (which -- seems to be required by some tools). Another effect of dV is to -- generate full qualified names, including internal names generated -- for blocks and loops. -- dW Disable warnings when a possibly uninitialized scalar value is -- passed to an IN OUT parameter of a procedure. This usage is a -- quite improper bounded error [erroneous in Ada 83] situation, -- and would normally generate a warning. However, to ease the -- task of transitioning incorrect legacy code, we provide this -- undocumented feature for suppressing these warnings. -- dY Enable configurable run-time mode, just as though the System file -- had Configurable_Run_Time_Mode set to True. This is useful in -- testing high integrity mode. -- dZ Generate listing showing the contents of the dispatch tables. Each -- line has an internally generated number used for references between -- tagged types and primitives. For each primitive the output has the -- following fields: -- -- - Letter 'P' or letter 's': The former indicates that this -- primitive will be located in a primary dispatch table. The -- latter indicates that it will be located in a secondary -- dispatch table. -- -- - Name of the primitive. In case of predefined Ada primitives -- the text "(predefined)" is added before the name, and these -- acronyms are used: SR (Stream_Read), SW (Stream_Write), SI -- (Stream_Input), SO (Stream_Output), DA (Deep_Adjust), DF -- (Deep_Finalize). In addition Oeq identifies the equality -- operator, and "_assign" the assignment. -- -- - If the primitive covers interface types, two extra fields -- referencing other primitives are generated: "Alias" references -- the primitive of the tagged type that covers an interface -- primitive, and "AI_Alias" references the covered interface -- primitive. -- -- - The expression "at #xx" indicates the slot of the dispatch -- table occupied by such primitive in its corresponding primary -- or secondary dispatch table. -- -- - In case of abstract subprograms the text "is abstract" is -- added at the end of the line. -- d.a Force Target_Strict_Alignment to True, even on targets where it -- would normally be false. Can be used for testing strict alignment -- circuitry in the compiler. -- d.b Dump back end types. During Create_Standard, the back end is -- queried for all available types. This option shows them. -- d.c Generate inline concatenation, instead of calling one of the -- System.Concat_n.Str_Concat_n routines in cases where the latter -- routines would normally be called. -- d.d Disable atomic synchronization for all atomic variable references. -- Pragma Enable_Atomic_Synchronization is ignored. -- d.e Enable atomic synchronization for all atomic variable references. -- Pragma Disable_Atomic_Synchronization is ignored, and also the -- compiler switch -gnated is ignored. -- d.f Suppress folding of static expressions. This of course results -- in seriously non-conforming behavior, but is useful sometimes -- when tracking down handling of complex expressions. -- d.g Enables conversion of a raise statement into a goto when the -- relevant handler is statically determinable. For now we only try -- this if this debug flag is set. Later we will enable this more -- generally by default. -- d.i Ignore all occurrences of pragma Warnings in the sources. This can -- be used in particular to disable Warnings (Off) to check if any of -- these statements are inappropriate. -- d.j Generate listing of frontend inlined calls and inline calls passed -- to the backend. This is useful to locate skipped calls that must be -- inlined by the frontend. -- d.k Enable new semantics of frontend inlining. This is useful to test -- this new feature in all the platforms. What *is* this new semantics -- which doesn't seem to be documented anywhere??? -- d.l Use Ada 95 semantics for limited function returns. This may be -- used to work around the incompatibility introduced by AI-318-2. -- It is useful only in -gnat05 mode. -- d.m When -gnatl is used, the normal output includes full listings of -- all files in the extended main source (body/spec/subunits). If this -- debug switch is used, then the full listing is given only for the -- main source (this corresponds to a previous behavior of -gnatl and -- is used for running the ACATS tests). -- d.n Print source file names as they are loaded. This is useful if the -- compiler has a bug -- these are the files that need to be included -- in a bug report. -- d.o Generate listing showing the IL instructions generated by the .NET -- compiler for each subprogram. -- d.p Enable the .NET CIL verifier. During development the verifier is -- disabled by default and this flag is used to enable it. In the -- future we will reverse this functionality. -- d.r Forces the flag OK_To_Reorder_Components to be set in all record -- base types that have no discriminants. -- d.s Normally the compiler expands slice moves into loops if overlap -- might be possible. This debug flag inhibits that expansion, and -- the back end is expected to use an appropriate routine to handle -- overlap, based on Forward_OK and Backwards_OK flags. -- d.t The compiler has been modified (a fairly extensive modification) -- to generate static dispatch tables for library level tagged types. -- This debug switch disables this modification and reverts to the -- previous dynamic construction of tables. It is there as a possible -- work around if we run into trouble with the new implementation. -- d.u Sets Modify_Tree_For_C mode in which tree is modified to make it -- easier to generate code using a C compiler. -- d.v Forces the flag OK_To_Reorder_Components to be set in all record -- base types that have at least one discriminant (v = variant). -- d.w This flag turns off the scanning of loops to detect possible -- infinite loops. -- d.x No exception handlers in generated code. This causes exception -- handlers to be eliminated from the generated code. They are still -- fully compiled and analyzed, they just get eliminated from the -- code generation step. -- d.A There seems to be a problem with ASIS if we activate the circuit -- for reading and writing the aspect specification hash table, so -- for now, this is controlled by the debug flag d.A. The hash table -- is only written and read if this flag is set. -- d.C Generate call to System.Concat_n.Str_Concat_n routines in cases -- where we would normally generate inline concatenation code. -- d.E Turn selected errors into warnings. This debug switch causes a -- specific set of error messages into warnings. Setting this switch -- causes Opt.Error_To_Warning to be set to True. The intention is -- that this be used for messages representing upwards incompatible -- changes to Ada 2012 that cause previously correct programs to be -- treated as illegal now. The following cases are affected: -- -- Errors relating to overlapping subprogram parameters for cases -- other than IN OUT parameters to functions. -- -- Errors relating to the new rules about not defining equality -- too late so that composition of equality can be assured. -- -- Errors relating to overriding indicators on protected subprogram -- bodies (not an Ada 2012 incompatibility, but might cause errors -- for existing programs assuming they were legal because GNAT -- formerly allowed them). -- d.F Sets GNATprove_Mode to True. This allows debugging the frontend in -- the special mode used by GNATprove. -- d.G Previously the compiler ignored calls via generic formal parameters -- when doing the analysis for the static elaboration model. This is -- now fixed, but we provide this debug flag to revert to the previous -- situation of ignoring such calls to aid in transition. -- d.I Do not ignore enum representation clauses in CodePeer mode. -- The default of ignoring representation clauses for enumeration -- types in CodePeer is good for the majority of Ada code, but in some -- cases being able to change this default might be useful to remove -- some false positives. -- d.J Disable parallel SCIL generation. Normally SCIL file generation is -- done in parallel to speed processing. This switch disables this -- behavior. -- d.L Normally the front end generates special expansion for conditional -- expressions of a limited type. This debug flag removes this special -- case expansion, leaving it up to the back end to handle conditional -- expressions correctly. -- d.M Relaxed RM semantics. This flag sets Opt.Relaxed_RM_Semantics -- See Opt.Relaxed_RM_Semantics for more details. -- d.N Enlarge entities by one node (but don't attempt to use this extra -- node for storage of any flags or fields). This can be used to do -- experiments on the impact of increasing entity sizes. -- d.O Dump internal SCO tables. Before outputting the SCO information to -- the ALI file, the internal SCO tables (SCO_Table/SCO_Unit_Table) -- are dumped for debugging purposes. -- d.P Previous non-optimized handling of length comparisons. Setting this -- flag inhibits the effect of Optimize_Length_Comparison in Exp_Ch4. -- This is there in case we find a situation where the optimization -- malfunctions, to provide a work around. -- d.Q Previous incomplete style checks for binary operators. Style checks -- for token separation rules were incomplete and have been made -- compliant with the documentation. For example, no warning was -- issued for expressions such as 16-One or "A"&"B". Setting this flag -- inhibits these new checks. -- d.R As documented in lib-writ.ads, restrictions in the ali file can -- have two forms, positional and named. The named notation is the -- current preferred form, but the use of this debug switch will force -- the use of the obsolescent positional form. -- d.S Force Optimize_Alignment (Space) mode as the default -- d.T Force Optimize_Alignment (Time) mode as the default -- d.U Ignore indirect calls for static elaboration. The static -- elaboration model is conservative, especially regarding indirect -- calls. If you say Proc'Access, it will assume you might call -- Proc. This can cause elaboration cycles at bind time. This flag -- reverts to the behavior of earlier compilers, which ignored -- indirect calls. -- d.V Causes routines in Cprint to be called instead of corresponding -- routines in Sprint. Used during development of Cprint. -- d.W Print out debugging information for Walk_Library_Items, including -- the order in which units are walked. This is primarily for use in -- debugging CodePeer mode. -- d1 Error messages have node numbers where possible. Normally error -- messages have only source locations. This option is useful when -- debugging errors caused by expanded code, where the source location -- does not give enough information. -- d2 Suppress output of the error position flags for verbose form error -- messages. The messages are still interspersed in the listing, but -- without any error flags or extra blank lines. Also causes an extra -- <<< to be output at the right margin. This is intended to be the -- easiest format for checking conformance of ACATS B tests. This -- flag also suppresses the additional messages explaining why a -- non-static expression is non-static (see Sem_Eval.Why_Not_Static). -- This avoids having to worry about these messages in ACATS testing. -- d3 Causes Comperr to dump the contents of the node for which an abort -- was detected (normally only the Node_Id of the node is output). -- d4 Inhibits automatic krunching of predefined library unit file names. -- Normally, as described in the spec of package Krunch, such files -- are automatically krunched to 8 characters, with special treatment -- of the prefixes Ada, System, and Interfaces. Setting this debug -- switch disables this special treatment. -- d5 Causes the tree read/write circuit to output detailed information -- tracking the data that is read and written element by element. -- d6 Normally access-to-unconstrained-array types are represented -- using fat (double) pointers. Using this debug flag causes them -- to default to thin. This can be used to test the performance -- implications of using thin pointers, and also to test that the -- compiler functions correctly with this choice. -- d7 Normally a -gnatl or -gnatv listing includes the time stamp -- of the source file. This debug flag suppresses this output, -- and also suppresses the message with the version number. -- This is useful in certain regression tests. -- d8 This forces the packed stuff to generate code assuming the -- opposite endianness from the actual correct value. Useful in -- testing out code generation from the packed routines. -- d9 This allows lock free implementation for protected objects -- (see Exp_Ch9). ------------------------------------------ -- Documentation for Binder Debug Flags -- ------------------------------------------ -- da Normally if there is an elaboration circularity, then in describing -- the cycle, links involving internal units are omitted, since they -- are irrelevant and confusing. This debug flag causes all links to -- be listed, and is useful when diagnosing circularities introduced -- by incorrect changes to the run-time library itself. -- db Output debug information from Better_Choice in Binde, which uses -- various heuristics to determine elaboration order in cases where -- multiple orders are valid. -- dc List units as they are chosen. As units are selected for addition to -- the elaboration order, a line of output is generated showing which -- unit has been selected. -- de Similar to the effect of -e (output complete list of elaboration -- dependencies) except that internal units are included in the -- listing. -- di Normally gnatbind calls Read_Ali with Ignore_Errors set to -- False, since the binder really needs correct version ALI -- files to do its job. This debug flag causes Ignore_Errors -- mode to be set for the binder (and is particularly useful -- for testing ignore errors mode). -- dn List details of manipulation of Num_Pred values during execution of -- the algorithm used to determine a correct order of elaboration. This -- is useful in diagnosing any problems in its behavior. -- do Use old elaboration order preference. The new preference rules -- prefer specs with no bodies to specs with bodies, and between two -- specs with bodies, prefers the one whose body is closer to being -- able to be elaborated. This is a clear improvement, but we provide -- this debug flag in case of regressions. -- du List unit name and file name for each unit as it is read in -- dx Force the binder to read (and then ignore) the xref information -- in ali files (used to check that read circuit is working OK). -------------------------------------------- -- Documentation for gnatmake Debug Flags -- -------------------------------------------- -- df Only output file names, not path names, in log -- dh Generate listing showing loading of name table hash chains, -- same as for the compiler. -- dm Issue a message indicating the maximum number of simultaneous -- compilations. -- dn Do not delete temporary files created by gnatmake at the end -- of execution, such as temporary config pragma files, mapping -- files or project path files. -- dp Prints the Q used by routine Make.Compile_Sources every time -- we go around the main compile loop of Make.Compile_Sources -- dq Prints source files as they are enqueued and dequeued in the Q -- used by routine Make.Compile_Sources. Useful to figure out the -- order in which sources are recompiled. -- dt When a time stamp mismatch has been found for an ALI file, -- display the source file name, the time stamp expected and -- the time stamp found. -- du List unit name and file name for each unit as it is read in -- dw Prints the list of units withed by the unit currently explored -- during the main loop of Make.Compile_Sources. --------------------------------------------- -- Documentation for gprbuild Debug Flags -- --------------------------------------------- -- dn Do not delete temporary files createed by gprbuild at the end -- of execution, such as temporary config pragma files, mapping -- files or project path files. -- dt When a time stamp mismatch has been found for an ALI file, -- display the source file name, the time stamp expected and -- the time stamp found. -------------------- -- Set_Debug_Flag -- -------------------- procedure Set_Debug_Flag (C : Character; Val : Boolean := True) is subtype Dig is Character range '1' .. '9'; subtype LLet is Character range 'a' .. 'z'; subtype ULet is Character range 'A' .. 'Z'; begin if C in Dig then case Dig (C) is when '1' => Debug_Flag_1 := Val; when '2' => Debug_Flag_2 := Val; when '3' => Debug_Flag_3 := Val; when '4' => Debug_Flag_4 := Val; when '5' => Debug_Flag_5 := Val; when '6' => Debug_Flag_6 := Val; when '7' => Debug_Flag_7 := Val; when '8' => Debug_Flag_8 := Val; when '9' => Debug_Flag_9 := Val; end case; elsif C in ULet then case ULet (C) is when 'A' => Debug_Flag_AA := Val; when 'B' => Debug_Flag_BB := Val; when 'C' => Debug_Flag_CC := Val; when 'D' => Debug_Flag_DD := Val; when 'E' => Debug_Flag_EE := Val; when 'F' => Debug_Flag_FF := Val; when 'G' => Debug_Flag_GG := Val; when 'H' => Debug_Flag_HH := Val; when 'I' => Debug_Flag_II := Val; when 'J' => Debug_Flag_JJ := Val; when 'K' => Debug_Flag_KK := Val; when 'L' => Debug_Flag_LL := Val; when 'M' => Debug_Flag_MM := Val; when 'N' => Debug_Flag_NN := Val; when 'O' => Debug_Flag_OO := Val; when 'P' => Debug_Flag_PP := Val; when 'Q' => Debug_Flag_QQ := Val; when 'R' => Debug_Flag_RR := Val; when 'S' => Debug_Flag_SS := Val; when 'T' => Debug_Flag_TT := Val; when 'U' => Debug_Flag_UU := Val; when 'V' => Debug_Flag_VV := Val; when 'W' => Debug_Flag_WW := Val; when 'X' => Debug_Flag_XX := Val; when 'Y' => Debug_Flag_YY := Val; when 'Z' => Debug_Flag_ZZ := Val; end case; else case LLet (C) is when 'a' => Debug_Flag_A := Val; when 'b' => Debug_Flag_B := Val; when 'c' => Debug_Flag_C := Val; when 'd' => Debug_Flag_D := Val; when 'e' => Debug_Flag_E := Val; when 'f' => Debug_Flag_F := Val; when 'g' => Debug_Flag_G := Val; when 'h' => Debug_Flag_H := Val; when 'i' => Debug_Flag_I := Val; when 'j' => Debug_Flag_J := Val; when 'k' => Debug_Flag_K := Val; when 'l' => Debug_Flag_L := Val; when 'm' => Debug_Flag_M := Val; when 'n' => Debug_Flag_N := Val; when 'o' => Debug_Flag_O := Val; when 'p' => Debug_Flag_P := Val; when 'q' => Debug_Flag_Q := Val; when 'r' => Debug_Flag_R := Val; when 's' => Debug_Flag_S := Val; when 't' => Debug_Flag_T := Val; when 'u' => Debug_Flag_U := Val; when 'v' => Debug_Flag_V := Val; when 'w' => Debug_Flag_W := Val; when 'x' => Debug_Flag_X := Val; when 'y' => Debug_Flag_Y := Val; when 'z' => Debug_Flag_Z := Val; end case; end if; end Set_Debug_Flag; --------------------------- -- Set_Dotted_Debug_Flag -- --------------------------- procedure Set_Dotted_Debug_Flag (C : Character; Val : Boolean := True) is subtype Dig is Character range '1' .. '9'; subtype LLet is Character range 'a' .. 'z'; subtype ULet is Character range 'A' .. 'Z'; begin if C in Dig then case Dig (C) is when '1' => Debug_Flag_Dot_1 := Val; when '2' => Debug_Flag_Dot_2 := Val; when '3' => Debug_Flag_Dot_3 := Val; when '4' => Debug_Flag_Dot_4 := Val; when '5' => Debug_Flag_Dot_5 := Val; when '6' => Debug_Flag_Dot_6 := Val; when '7' => Debug_Flag_Dot_7 := Val; when '8' => Debug_Flag_Dot_8 := Val; when '9' => Debug_Flag_Dot_9 := Val; end case; elsif C in ULet then case ULet (C) is when 'A' => Debug_Flag_Dot_AA := Val; when 'B' => Debug_Flag_Dot_BB := Val; when 'C' => Debug_Flag_Dot_CC := Val; when 'D' => Debug_Flag_Dot_DD := Val; when 'E' => Debug_Flag_Dot_EE := Val; when 'F' => Debug_Flag_Dot_FF := Val; when 'G' => Debug_Flag_Dot_GG := Val; when 'H' => Debug_Flag_Dot_HH := Val; when 'I' => Debug_Flag_Dot_II := Val; when 'J' => Debug_Flag_Dot_JJ := Val; when 'K' => Debug_Flag_Dot_KK := Val; when 'L' => Debug_Flag_Dot_LL := Val; when 'M' => Debug_Flag_Dot_MM := Val; when 'N' => Debug_Flag_Dot_NN := Val; when 'O' => Debug_Flag_Dot_OO := Val; when 'P' => Debug_Flag_Dot_PP := Val; when 'Q' => Debug_Flag_Dot_QQ := Val; when 'R' => Debug_Flag_Dot_RR := Val; when 'S' => Debug_Flag_Dot_SS := Val; when 'T' => Debug_Flag_Dot_TT := Val; when 'U' => Debug_Flag_Dot_UU := Val; when 'V' => Debug_Flag_Dot_VV := Val; when 'W' => Debug_Flag_Dot_WW := Val; when 'X' => Debug_Flag_Dot_XX := Val; when 'Y' => Debug_Flag_Dot_YY := Val; when 'Z' => Debug_Flag_Dot_ZZ := Val; end case; else case LLet (C) is when 'a' => Debug_Flag_Dot_A := Val; when 'b' => Debug_Flag_Dot_B := Val; when 'c' => Debug_Flag_Dot_C := Val; when 'd' => Debug_Flag_Dot_D := Val; when 'e' => Debug_Flag_Dot_E := Val; when 'f' => Debug_Flag_Dot_F := Val; when 'g' => Debug_Flag_Dot_G := Val; when 'h' => Debug_Flag_Dot_H := Val; when 'i' => Debug_Flag_Dot_I := Val; when 'j' => Debug_Flag_Dot_J := Val; when 'k' => Debug_Flag_Dot_K := Val; when 'l' => Debug_Flag_Dot_L := Val; when 'm' => Debug_Flag_Dot_M := Val; when 'n' => Debug_Flag_Dot_N := Val; when 'o' => Debug_Flag_Dot_O := Val; when 'p' => Debug_Flag_Dot_P := Val; when 'q' => Debug_Flag_Dot_Q := Val; when 'r' => Debug_Flag_Dot_R := Val; when 's' => Debug_Flag_Dot_S := Val; when 't' => Debug_Flag_Dot_T := Val; when 'u' => Debug_Flag_Dot_U := Val; when 'v' => Debug_Flag_Dot_V := Val; when 'w' => Debug_Flag_Dot_W := Val; when 'x' => Debug_Flag_Dot_X := Val; when 'y' => Debug_Flag_Dot_Y := Val; when 'z' => Debug_Flag_Dot_Z := Val; end case; end if; end Set_Dotted_Debug_Flag; end Debug; gprbuild-gpl-2014-src/gnat/stand.ads0000644000076700001450000004732212323721731016676 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S T A N D -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains the declarations of entities in package Standard, -- These values are initialized either by calling CStand.Create_Standard, -- or by calling Stand.Tree_Read. with Types; use Types; package Stand is -- Warning: the entities defined in this package are written out by the -- Tree_Write routine, and read back in by the Tree_Read routine, so be -- sure to modify these two routines if you add entities that are not -- part of Standard_Entity. type Standard_Entity_Type is ( -- This enumeration type contains an entry for each name in Standard -- Package names S_Standard, S_ASCII, -- Types and subtypes defined in package Standard (in the order in which -- they appear in the RM, so that the declarations are in the right -- order for the purposes of ASIS traversals S_Boolean, S_Short_Short_Integer, S_Short_Integer, S_Integer, S_Long_Integer, S_Long_Long_Integer, S_Natural, S_Positive, S_Short_Float, S_Float, S_Long_Float, S_Long_Long_Float, S_Character, S_Wide_Character, S_Wide_Wide_Character, S_String, S_Wide_String, S_Wide_Wide_String, S_Duration, -- Enumeration literals for type Boolean S_False, S_True, -- Exceptions declared in package Standard S_Constraint_Error, S_Numeric_Error, S_Program_Error, S_Storage_Error, S_Tasking_Error, -- Binary Operators declared in package Standard S_Op_Add, S_Op_And, S_Op_Concat, S_Op_Concatw, S_Op_Concatww, S_Op_Divide, S_Op_Eq, S_Op_Expon, S_Op_Ge, S_Op_Gt, S_Op_Le, S_Op_Lt, S_Op_Mod, S_Op_Multiply, S_Op_Ne, S_Op_Or, S_Op_Rem, S_Op_Subtract, S_Op_Xor, -- Unary operators declared in package Standard S_Op_Abs, S_Op_Minus, S_Op_Not, S_Op_Plus, -- Constants defined in package ASCII (with value in hex). -- First the thirty-two C0 control characters) S_NUL, -- 16#00# S_SOH, -- 16#01# S_STX, -- 16#02# S_ETX, -- 16#03# S_EOT, -- 16#04# S_ENQ, -- 16#05# S_ACK, -- 16#06# S_BEL, -- 16#07# S_BS, -- 16#08# S_HT, -- 16#09# S_LF, -- 16#0A# S_VT, -- 16#0B# S_FF, -- 16#0C# S_CR, -- 16#0D# S_SO, -- 16#0E# S_SI, -- 16#0F# S_DLE, -- 16#10# S_DC1, -- 16#11# S_DC2, -- 16#12# S_DC3, -- 16#13# S_DC4, -- 16#14# S_NAK, -- 16#15# S_SYN, -- 16#16# S_ETB, -- 16#17# S_CAN, -- 16#18# S_EM, -- 16#19# S_SUB, -- 16#1A# S_ESC, -- 16#1B# S_FS, -- 16#1C# S_GS, -- 16#1D# S_RS, -- 16#1E# S_US, -- 16#1F# -- Here are the ones for Colonel Whitaker's O26 keypunch S_Exclam, -- 16#21# S_Quotation, -- 16#22# S_Sharp, -- 16#23# S_Dollar, -- 16#24# S_Percent, -- 16#25# S_Ampersand, -- 16#26# S_Colon, -- 16#3A# S_Semicolon, -- 16#3B# S_Query, -- 16#3F# S_At_Sign, -- 16#40# S_L_Bracket, -- 16#5B# S_Back_Slash, -- 16#5C# S_R_Bracket, -- 16#5D# S_Circumflex, -- 16#5E# S_Underline, -- 16#5F# S_Grave, -- 16#60# S_LC_A, -- 16#61# S_LC_B, -- 16#62# S_LC_C, -- 16#63# S_LC_D, -- 16#64# S_LC_E, -- 16#65# S_LC_F, -- 16#66# S_LC_G, -- 16#67# S_LC_H, -- 16#68# S_LC_I, -- 16#69# S_LC_J, -- 16#6A# S_LC_K, -- 16#6B# S_LC_L, -- 16#6C# S_LC_M, -- 16#6D# S_LC_N, -- 16#6E# S_LC_O, -- 16#6F# S_LC_P, -- 16#70# S_LC_Q, -- 16#71# S_LC_R, -- 16#72# S_LC_S, -- 16#73# S_LC_T, -- 16#74# S_LC_U, -- 16#75# S_LC_V, -- 16#76# S_LC_W, -- 16#77# S_LC_X, -- 16#78# S_LC_Y, -- 16#79# S_LC_Z, -- 16#7A# S_L_BRACE, -- 16#7B# S_BAR, -- 16#7C# S_R_BRACE, -- 16#7D# S_TILDE, -- 16#7E# -- And one more control character, all on its own S_DEL); -- 16#7F# subtype S_Types is Standard_Entity_Type range S_Boolean .. S_Duration; subtype S_Exceptions is Standard_Entity_Type range S_Constraint_Error .. S_Tasking_Error; subtype S_ASCII_Names is Standard_Entity_Type range S_NUL .. S_DEL; subtype S_Binary_Ops is Standard_Entity_Type range S_Op_Add .. S_Op_Xor; subtype S_Unary_Ops is Standard_Entity_Type range S_Op_Abs .. S_Op_Plus; type Standard_Entity_Array_Type is array (Standard_Entity_Type) of Node_Id; Standard_Entity : Standard_Entity_Array_Type; -- This array contains pointers to the Defining Identifier nodes for each -- of the visible entities defined in Standard_Entities_Type. The array is -- initialized by the Create_Standard procedure. Standard_Package_Node : Node_Id; -- Points to the N_Package_Declaration node for standard. Also -- initialized by the Create_Standard procedure. -- The following Entities are the pointers to the Defining Identifier -- nodes for some visible entities defined in Standard_Entities_Type. SE : Standard_Entity_Array_Type renames Standard_Entity; Standard_Standard : Entity_Id renames SE (S_Standard); Standard_ASCII : Entity_Id renames SE (S_ASCII); Standard_Character : Entity_Id renames SE (S_Character); Standard_Wide_Character : Entity_Id renames SE (S_Wide_Character); Standard_Wide_Wide_Character : Entity_Id renames SE (S_Wide_Wide_Character); Standard_String : Entity_Id renames SE (S_String); Standard_Wide_String : Entity_Id renames SE (S_Wide_String); Standard_Wide_Wide_String : Entity_Id renames SE (S_Wide_Wide_String); Standard_Boolean : Entity_Id renames SE (S_Boolean); Standard_False : Entity_Id renames SE (S_False); Standard_True : Entity_Id renames SE (S_True); Standard_Duration : Entity_Id renames SE (S_Duration); Standard_Natural : Entity_Id renames SE (S_Natural); Standard_Positive : Entity_Id renames SE (S_Positive); Standard_Constraint_Error : Entity_Id renames SE (S_Constraint_Error); Standard_Numeric_Error : Entity_Id renames SE (S_Numeric_Error); Standard_Program_Error : Entity_Id renames SE (S_Program_Error); Standard_Storage_Error : Entity_Id renames SE (S_Storage_Error); Standard_Tasking_Error : Entity_Id renames SE (S_Tasking_Error); Standard_Short_Float : Entity_Id renames SE (S_Short_Float); Standard_Float : Entity_Id renames SE (S_Float); Standard_Long_Float : Entity_Id renames SE (S_Long_Float); Standard_Long_Long_Float : Entity_Id renames SE (S_Long_Long_Float); Standard_Short_Short_Integer : Entity_Id renames SE (S_Short_Short_Integer); Standard_Short_Integer : Entity_Id renames SE (S_Short_Integer); Standard_Integer : Entity_Id renames SE (S_Integer); Standard_Long_Integer : Entity_Id renames SE (S_Long_Integer); Standard_Long_Long_Integer : Entity_Id renames SE (S_Long_Long_Integer); Standard_Op_Add : Entity_Id renames SE (S_Op_Add); Standard_Op_And : Entity_Id renames SE (S_Op_And); Standard_Op_Concat : Entity_Id renames SE (S_Op_Concat); Standard_Op_Concatw : Entity_Id renames SE (S_Op_Concatw); Standard_Op_Concatww : Entity_Id renames SE (S_Op_Concatww); Standard_Op_Divide : Entity_Id renames SE (S_Op_Divide); Standard_Op_Eq : Entity_Id renames SE (S_Op_Eq); Standard_Op_Expon : Entity_Id renames SE (S_Op_Expon); Standard_Op_Ge : Entity_Id renames SE (S_Op_Ge); Standard_Op_Gt : Entity_Id renames SE (S_Op_Gt); Standard_Op_Le : Entity_Id renames SE (S_Op_Le); Standard_Op_Lt : Entity_Id renames SE (S_Op_Lt); Standard_Op_Mod : Entity_Id renames SE (S_Op_Mod); Standard_Op_Multiply : Entity_Id renames SE (S_Op_Multiply); Standard_Op_Ne : Entity_Id renames SE (S_Op_Ne); Standard_Op_Or : Entity_Id renames SE (S_Op_Or); Standard_Op_Rem : Entity_Id renames SE (S_Op_Rem); Standard_Op_Subtract : Entity_Id renames SE (S_Op_Subtract); Standard_Op_Xor : Entity_Id renames SE (S_Op_Xor); Standard_Op_Abs : Entity_Id renames SE (S_Op_Abs); Standard_Op_Minus : Entity_Id renames SE (S_Op_Minus); Standard_Op_Not : Entity_Id renames SE (S_Op_Not); Standard_Op_Plus : Entity_Id renames SE (S_Op_Plus); Last_Standard_Node_Id : Node_Id; -- Highest Node_Id value used by Standard Last_Standard_List_Id : List_Id; -- Highest List_Id value used by Standard (including those used by -- normal list headers, element list headers, and list elements) Boolean_Literals : array (Boolean) of Entity_Id; -- Entities for the two boolean literals, used by the expander ------------------------------------- -- Semantic Phase Special Entities -- ------------------------------------- -- The semantic phase needs a number of entities for internal processing -- that are logically at the level of Standard, and hence defined in this -- package. However, they are never visible to a program, and are not -- chained on to the Decls list of Standard. The names of all these -- types are relevant only in certain debugging and error message -- situations. They have names that are suitable for use in such -- error messages (see body for actual names used). Standard_Void_Type : Entity_Id; -- This is a type used to represent the return type of procedures Standard_Exception_Type : Entity_Id; -- This is a type used to represent the Etype of exceptions Standard_A_String : Entity_Id; -- An access to String type used for building elements of tables -- carrying the enumeration literal names. Standard_A_Char : Entity_Id; -- Access to character, used as a component of the exception type to denote -- a thin pointer component. Standard_Debug_Renaming_Type : Entity_Id; -- A zero-size subtype of Integer, used as the type of variables used to -- provide the debugger with name encodings for renaming declarations. Predefined_Float_Types : Elist_Id; -- Entities for predefined floating point types. These are used by -- the semantic phase to select appropriate types for floating point -- declarations. This list is ordered by preference. All types up to -- Long_Long_Float_Type are considered for plain "digits N" declarations, -- while selection of later types requires a range specification and -- possibly other attributes or pragmas. -- The entities labeled Any_xxx are used in situations where the full -- characteristics of an entity are not yet known, e.g. Any_Character -- is used to label a character literal before resolution is complete. -- These entities are also used to construct appropriate references in -- error messages ("expecting an integer type"). Any_Id : Entity_Id; -- Used to represent some unknown identifier. Used to label undefined -- identifier references to prevent cascaded errors. Any_Type : Entity_Id; -- Used to represent some unknown type. Any_Type is the type of an -- unresolved operator, and it is the type of a node where a type error -- has been detected. Any_Type plays an important role in avoiding cascaded -- errors, because it is compatible with all other types, and is propagated -- to any expression that has a subexpression of Any_Type. When resolving -- operators, Any_Type is the initial type of the node before any of its -- candidate interpretations has been examined. If after examining all of -- them the type is still Any_Type, the node has no possible interpretation -- and an error can be emitted (and Any_Type will be propagated upwards). Any_Access : Entity_Id; -- Used to resolve the overloaded literal NULL Any_Array : Entity_Id; -- Used to represent some unknown array type Any_Boolean : Entity_Id; -- The context type of conditions in IF and WHILE statements Any_Character : Entity_Id; -- Any_Character is used to label character literals, which in general -- will not have an explicit declaration (this is true of the predefined -- character types). Any_Composite : Entity_Id; -- The type Any_Composite is used for aggregates before type resolution. -- It is compatible with any array or non-limited record type. Any_Discrete : Entity_Id; -- Used to represent some unknown discrete type Any_Fixed : Entity_Id; -- Used to represent some unknown fixed-point type Any_Integer : Entity_Id; -- Used to represent some unknown integer type Any_Modular : Entity_Id; -- Used to represent the result type of a boolean operation on an integer -- literal. The result is not Universal_Integer, because it is only legal -- in a modular context. Any_Numeric : Entity_Id; -- Used to represent some unknown numeric type Any_Real : Entity_Id; -- Used to represent some unknown real type Any_Scalar : Entity_Id; -- Used to represent some unknown scalar type Any_String : Entity_Id; -- The type Any_String is used for string literals before type resolution. -- It corresponds to array (Positive range <>) of character where the -- component type is compatible with any character type, not just -- Standard_Character. Raise_Type : Entity_Id; -- The type Raise_Type denotes the type of a Raise_Expression. It is -- compatible with all other types, and must eventually resolve to a -- concrete type that is imposed by the context. -- -- Historical note: we used to use Any_Type for this purpose, but the -- confusion of meanings (Any_Type normally indicates an error) caused -- difficulties. In particular some needed expansions were skipped since -- the nodes in question looked like they had an error. Universal_Integer : Entity_Id; -- Entity for universal integer type. The bounds of this type correspond -- to the largest supported integer type (i.e. Long_Long_Integer). It is -- the type used for runtime calculations in type universal integer. Universal_Real : Entity_Id; -- Entity for universal real type. The bounds of this type correspond to -- to the largest supported real type (i.e. Long_Long_Float). It is the -- type used for runtime calculations in type universal real. Note that -- this type is always IEEE format, even if Long_Long_Float is Vax_Float -- (and in that case the bounds don't correspond exactly). Universal_Fixed : Entity_Id; -- Entity for universal fixed type. This is a type with arbitrary -- precision that can only appear in a context with a specific type. -- Universal_Fixed labels the result of multiplication or division of -- two fixed point numbers, and has no specified bounds (since, unlike -- universal integer and universal real, it is never used for runtime -- calculations). Standard_Integer_8 : Entity_Id; Standard_Integer_16 : Entity_Id; Standard_Integer_32 : Entity_Id; Standard_Integer_64 : Entity_Id; -- These are signed integer types with the indicated sizes. Used for the -- underlying implementation types for fixed-point and enumeration types. Standard_Short_Short_Unsigned : Entity_Id; Standard_Short_Unsigned : Entity_Id; Standard_Unsigned : Entity_Id; Standard_Long_Unsigned : Entity_Id; Standard_Long_Long_Unsigned : Entity_Id; -- Unsigned types with same Esize as corresponding signed integer types Standard_Unsigned_64 : Entity_Id; -- An unsigned type, mod 2 ** 64, size of 64 bits. Abort_Signal : Entity_Id; -- Entity for abort signal exception Standard_Op_Rotate_Left : Entity_Id; Standard_Op_Rotate_Right : Entity_Id; Standard_Op_Shift_Left : Entity_Id; Standard_Op_Shift_Right : Entity_Id; Standard_Op_Shift_Right_Arithmetic : Entity_Id; -- These entities are used for shift operators generated by the expander ----------------- -- Subprograms -- ----------------- procedure Tree_Read; -- Initializes entity values in this package from the current tree file -- using Tree_IO. Note that Tree_Read includes all the initialization that -- is carried out by Create_Standard. procedure Tree_Write; -- Writes out the entity values in this package to the current tree file -- using Tree_IO. end Stand; gprbuild-gpl-2014-src/gnat/prj.adb0000644000076700001450000017350712323721731016344 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Debug; with Opt; with Osint; use Osint; with Output; use Output; with Prj.Attr; with Prj.Com; with Prj.Err; use Prj.Err; with Snames; use Snames; with Uintp; use Uintp; with Ada.Characters.Handling; use Ada.Characters.Handling; with Ada.Containers.Ordered_Sets; with Ada.Unchecked_Deallocation; with GNAT.Case_Util; use GNAT.Case_Util; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.HTable; package body Prj is type Restricted_Lang; type Restricted_Lang_Access is access Restricted_Lang; type Restricted_Lang is record Name : Name_Id; Next : Restricted_Lang_Access; end record; Restricted_Languages : Restricted_Lang_Access := null; -- When null, all languages are allowed, otherwise only the languages in -- the list are allowed. Object_Suffix : constant String := Get_Target_Object_Suffix.all; -- File suffix for object files Initial_Buffer_Size : constant := 100; -- Initial size for extensible buffer used in Add_To_Buffer The_Empty_String : Name_Id := No_Name; Debug_Level : Integer := 0; -- Current indentation level for debug traces type Cst_String_Access is access constant String; All_Lower_Case_Image : aliased constant String := "lowercase"; All_Upper_Case_Image : aliased constant String := "UPPERCASE"; Mixed_Case_Image : aliased constant String := "MixedCase"; The_Casing_Images : constant array (Known_Casing) of Cst_String_Access := (All_Lower_Case => All_Lower_Case_Image'Access, All_Upper_Case => All_Upper_Case_Image'Access, Mixed_Case => Mixed_Case_Image'Access); procedure Free (Project : in out Project_Id); -- Free memory allocated for Project procedure Free_List (Languages : in out Language_Ptr); procedure Free_List (Source : in out Source_Id); procedure Free_List (Languages : in out Language_List); -- Free memory allocated for the list of languages or sources procedure Reset_Units_In_Table (Table : in out Units_Htable.Instance); -- Resets all Units to No_Unit_Index Unit.File_Names (Spec).Unit & -- Unit.File_Names (Impl).Unit in the given table. procedure Free_Units (Table : in out Units_Htable.Instance); -- Free memory allocated for unit information in the project procedure Language_Changed (Iter : in out Source_Iterator); procedure Project_Changed (Iter : in out Source_Iterator); -- Called when a new project or language was selected for this iterator function Contains_ALI_Files (Dir : Path_Name_Type) return Boolean; -- Return True if there is at least one ALI file in the directory Dir ----------------------------- -- Add_Restricted_Language -- ----------------------------- procedure Add_Restricted_Language (Name : String) is N : String (1 .. Name'Length) := Name; begin To_Lower (N); Name_Len := 0; Add_Str_To_Name_Buffer (N); Restricted_Languages := new Restricted_Lang'(Name => Name_Find, Next => Restricted_Languages); end Add_Restricted_Language; ------------------------------------- -- Remove_All_Restricted_Languages -- ------------------------------------- procedure Remove_All_Restricted_Languages is begin Restricted_Languages := null; end Remove_All_Restricted_Languages; ------------------- -- Add_To_Buffer -- ------------------- procedure Add_To_Buffer (S : String; To : in out String_Access; Last : in out Natural) is begin if To = null then To := new String (1 .. Initial_Buffer_Size); Last := 0; end if; -- If Buffer is too small, double its size while Last + S'Length > To'Last loop declare New_Buffer : constant String_Access := new String (1 .. 2 * To'Length); begin New_Buffer (1 .. Last) := To (1 .. Last); Free (To); To := New_Buffer; end; end loop; To (Last + 1 .. Last + S'Length) := S; Last := Last + S'Length; end Add_To_Buffer; --------------------------------- -- Current_Object_Path_File_Of -- --------------------------------- function Current_Object_Path_File_Of (Shared : Shared_Project_Tree_Data_Access) return Path_Name_Type is begin return Shared.Private_Part.Current_Object_Path_File; end Current_Object_Path_File_Of; --------------------------------- -- Current_Source_Path_File_Of -- --------------------------------- function Current_Source_Path_File_Of (Shared : Shared_Project_Tree_Data_Access) return Path_Name_Type is begin return Shared.Private_Part.Current_Source_Path_File; end Current_Source_Path_File_Of; --------------------------- -- Delete_Temporary_File -- --------------------------- procedure Delete_Temporary_File (Shared : Shared_Project_Tree_Data_Access := null; Path : Path_Name_Type) is Dont_Care : Boolean; pragma Warnings (Off, Dont_Care); begin if not Debug.Debug_Flag_N then if Current_Verbosity = High then Write_Line ("Removing temp file: " & Get_Name_String (Path)); end if; Delete_File (Get_Name_String (Path), Dont_Care); if Shared /= null then for Index in 1 .. Temp_Files_Table.Last (Shared.Private_Part.Temp_Files) loop if Shared.Private_Part.Temp_Files.Table (Index) = Path then Shared.Private_Part.Temp_Files.Table (Index) := No_Path; end if; end loop; end if; end if; end Delete_Temporary_File; ------------------------------ -- Delete_Temp_Config_Files -- ------------------------------ procedure Delete_Temp_Config_Files (Project_Tree : Project_Tree_Ref) is Success : Boolean; pragma Warnings (Off, Success); Proj : Project_List; begin if not Debug.Debug_Flag_N then if Project_Tree /= null then Proj := Project_Tree.Projects; while Proj /= null loop if Proj.Project.Config_File_Temp then Delete_Temporary_File (Project_Tree.Shared, Proj.Project.Config_File_Name); -- Make sure that we don't have a config file for this -- project, in case there are several mains. In this case, -- we will recreate another config file: we cannot reuse the -- one that we just deleted. Proj.Project.Config_Checked := False; Proj.Project.Config_File_Name := No_Path; Proj.Project.Config_File_Temp := False; end if; Proj := Proj.Next; end loop; end if; end if; end Delete_Temp_Config_Files; --------------------------- -- Delete_All_Temp_Files -- --------------------------- procedure Delete_All_Temp_Files (Shared : Shared_Project_Tree_Data_Access) is Dont_Care : Boolean; pragma Warnings (Off, Dont_Care); Path : Path_Name_Type; begin if not Debug.Debug_Flag_N then for Index in 1 .. Temp_Files_Table.Last (Shared.Private_Part.Temp_Files) loop Path := Shared.Private_Part.Temp_Files.Table (Index); if Path /= No_Path then if Current_Verbosity = High then Write_Line ("Removing temp file: " & Get_Name_String (Path)); end if; Delete_File (Get_Name_String (Path), Dont_Care); end if; end loop; Temp_Files_Table.Free (Shared.Private_Part.Temp_Files); Temp_Files_Table.Init (Shared.Private_Part.Temp_Files); end if; -- If any of the environment variables ADA_PRJ_INCLUDE_FILE or -- ADA_PRJ_OBJECTS_FILE has been set, then reset their value to -- the empty string. On VMS, this has the effect of deassigning -- the logical names. if Shared.Private_Part.Current_Source_Path_File /= No_Path then Setenv (Project_Include_Path_File, ""); end if; if Shared.Private_Part.Current_Object_Path_File /= No_Path then Setenv (Project_Objects_Path_File, ""); end if; end Delete_All_Temp_Files; --------------------- -- Dependency_Name -- --------------------- function Dependency_Name (Source_File_Name : File_Name_Type; Dependency : Dependency_File_Kind) return File_Name_Type is begin case Dependency is when None => return No_File; when Makefile => return Extend_Name (Source_File_Name, Makefile_Dependency_Suffix); when ALI_File | ALI_Closure => return Extend_Name (Source_File_Name, ALI_Dependency_Suffix); end case; end Dependency_Name; ---------------- -- Empty_File -- ---------------- function Empty_File return File_Name_Type is begin return File_Name_Type (The_Empty_String); end Empty_File; ------------------- -- Empty_Project -- ------------------- function Empty_Project (Qualifier : Project_Qualifier) return Project_Data is begin Prj.Initialize (Tree => No_Project_Tree); declare Data : Project_Data (Qualifier => Qualifier); begin -- Only the fields for which no default value could be provided in -- prj.ads are initialized below. Data.Config := Default_Project_Config; return Data; end; end Empty_Project; ------------------ -- Empty_String -- ------------------ function Empty_String return Name_Id is begin return The_Empty_String; end Empty_String; ------------ -- Expect -- ------------ procedure Expect (The_Token : Token_Type; Token_Image : String) is begin if Token /= The_Token then -- ??? Should pass user flags here instead Error_Msg (Gnatmake_Flags, Token_Image & " expected", Token_Ptr); end if; end Expect; ----------------- -- Extend_Name -- ----------------- function Extend_Name (File : File_Name_Type; With_Suffix : String) return File_Name_Type is Last : Positive; begin Get_Name_String (File); Last := Name_Len + 1; while Name_Len /= 0 and then Name_Buffer (Name_Len) /= '.' loop Name_Len := Name_Len - 1; end loop; if Name_Len <= 1 then Name_Len := Last; end if; for J in With_Suffix'Range loop Name_Buffer (Name_Len) := With_Suffix (J); Name_Len := Name_Len + 1; end loop; Name_Len := Name_Len - 1; return Name_Find; end Extend_Name; ------------------------- -- Is_Allowed_Language -- ------------------------- function Is_Allowed_Language (Name : Name_Id) return Boolean is R : Restricted_Lang_Access := Restricted_Languages; Lang : constant String := Get_Name_String (Name); begin if R = null then return True; else while R /= null loop if Get_Name_String (R.Name) = Lang then return True; end if; R := R.Next; end loop; return False; end if; end Is_Allowed_Language; --------------------- -- Project_Changed -- --------------------- procedure Project_Changed (Iter : in out Source_Iterator) is begin if Iter.Project /= null then Iter.Language := Iter.Project.Project.Languages; Language_Changed (Iter); end if; end Project_Changed; ---------------------- -- Language_Changed -- ---------------------- procedure Language_Changed (Iter : in out Source_Iterator) is begin Iter.Current := No_Source; if Iter.Language_Name /= No_Name then while Iter.Language /= null and then Iter.Language.Name /= Iter.Language_Name loop Iter.Language := Iter.Language.Next; end loop; end if; -- If there is no matching language in this project, move to next if Iter.Language = No_Language_Index then if Iter.All_Projects then loop Iter.Project := Iter.Project.Next; exit when Iter.Project = null or else Iter.Encapsulated_Libs or else not Iter.Project.From_Encapsulated_Lib; end loop; Project_Changed (Iter); else Iter.Project := null; end if; else Iter.Current := Iter.Language.First_Source; if Iter.Current = No_Source then Iter.Language := Iter.Language.Next; Language_Changed (Iter); elsif not Iter.Locally_Removed and then Iter.Current.Locally_Removed then Next (Iter); end if; end if; end Language_Changed; --------------------- -- For_Each_Source -- --------------------- function For_Each_Source (In_Tree : Project_Tree_Ref; Project : Project_Id := No_Project; Language : Name_Id := No_Name; Encapsulated_Libs : Boolean := True; Locally_Removed : Boolean := True) return Source_Iterator is Iter : Source_Iterator; begin Iter := Source_Iterator' (In_Tree => In_Tree, Project => In_Tree.Projects, All_Projects => Project = No_Project, Language_Name => Language, Language => No_Language_Index, Current => No_Source, Encapsulated_Libs => Encapsulated_Libs, Locally_Removed => Locally_Removed); if Project /= null then while Iter.Project /= null and then Iter.Project.Project /= Project loop Iter.Project := Iter.Project.Next; end loop; else while not Iter.Encapsulated_Libs and then Iter.Project.From_Encapsulated_Lib loop Iter.Project := Iter.Project.Next; end loop; end if; Project_Changed (Iter); return Iter; end For_Each_Source; ------------- -- Element -- ------------- function Element (Iter : Source_Iterator) return Source_Id is begin return Iter.Current; end Element; ---------- -- Next -- ---------- procedure Next (Iter : in out Source_Iterator) is begin loop Iter.Current := Iter.Current.Next_In_Lang; exit when Iter.Locally_Removed or else Iter.Current = No_Source or else not Iter.Current.Locally_Removed; end loop; if Iter.Current = No_Source then Iter.Language := Iter.Language.Next; Language_Changed (Iter); end if; end Next; -------------------------------- -- For_Every_Project_Imported -- -------------------------------- procedure For_Every_Project_Imported_Context (By : Project_Id; Tree : Project_Tree_Ref; With_State : in out State; Include_Aggregated : Boolean := True; Imported_First : Boolean := False) is use Project_Boolean_Htable; procedure Recursive_Check_Context (Project : Project_Id; Tree : Project_Tree_Ref; In_Aggregate_Lib : Boolean; From_Encapsulated_Lib : Boolean); -- Recursively handle the project tree creating a new context for -- keeping track about already handled projects. ----------------------------- -- Recursive_Check_Context -- ----------------------------- procedure Recursive_Check_Context (Project : Project_Id; Tree : Project_Tree_Ref; In_Aggregate_Lib : Boolean; From_Encapsulated_Lib : Boolean) is package Name_Id_Set is new Ada.Containers.Ordered_Sets (Element_Type => Name_Id); Seen_Name : Name_Id_Set.Set; -- This set is needed to ensure that we do not handle the same -- project twice in the context of aggregate libraries. procedure Recursive_Check (Project : Project_Id; Tree : Project_Tree_Ref; In_Aggregate_Lib : Boolean; From_Encapsulated_Lib : Boolean); -- Check if project has already been seen. If not, mark it as Seen, -- Call Action, and check all its imported and aggregated projects. --------------------- -- Recursive_Check -- --------------------- procedure Recursive_Check (Project : Project_Id; Tree : Project_Tree_Ref; In_Aggregate_Lib : Boolean; From_Encapsulated_Lib : Boolean) is function Has_Sources (P : Project_Id) return Boolean; -- Returns True if P has sources function Get_From_Tree (P : Project_Id) return Project_Id; -- Get project P from Tree. If P has no sources get another -- instance of this project with sources. If P has sources, -- returns it. ----------------- -- Has_Sources -- ----------------- function Has_Sources (P : Project_Id) return Boolean is Lang : Language_Ptr; begin Lang := P.Languages; while Lang /= No_Language_Index loop if Lang.First_Source /= No_Source then return True; end if; Lang := Lang.Next; end loop; return False; end Has_Sources; ------------------- -- Get_From_Tree -- ------------------- function Get_From_Tree (P : Project_Id) return Project_Id is List : Project_List := Tree.Projects; begin if not Has_Sources (P) then while List /= null loop if List.Project.Name = P.Name and then Has_Sources (List.Project) then return List.Project; end if; List := List.Next; end loop; end if; return P; end Get_From_Tree; -- Local variables List : Project_List; -- Start of processing for Recursive_Check begin if not Seen_Name.Contains (Project.Name) then -- Even if a project is aggregated multiple times in an -- aggregated library, we will only return it once. Seen_Name.Include (Project.Name); if not Imported_First then Action (Get_From_Tree (Project), Tree, Project_Context'(In_Aggregate_Lib, From_Encapsulated_Lib), With_State); end if; -- Visit all extended projects if Project.Extends /= No_Project then Recursive_Check (Project.Extends, Tree, In_Aggregate_Lib, From_Encapsulated_Lib); end if; -- Visit all imported projects List := Project.Imported_Projects; while List /= null loop Recursive_Check (List.Project, Tree, In_Aggregate_Lib, From_Encapsulated_Lib or else Project.Standalone_Library = Encapsulated); List := List.Next; end loop; -- Visit all aggregated projects if Include_Aggregated and then Project.Qualifier in Aggregate_Project then declare Agg : Aggregated_Project_List; begin Agg := Project.Aggregated_Projects; while Agg /= null loop pragma Assert (Agg.Project /= No_Project); -- For aggregated libraries, the tree must be the one -- of the aggregate library. if Project.Qualifier = Aggregate_Library then Recursive_Check (Agg.Project, Tree, True, From_Encapsulated_Lib or else Project.Standalone_Library = Encapsulated); else -- Use a new context as we want to returns the same -- project in different project tree for aggregated -- projects. Recursive_Check_Context (Agg.Project, Agg.Tree, False, False); end if; Agg := Agg.Next; end loop; end; end if; if Imported_First then Action (Get_From_Tree (Project), Tree, Project_Context'(In_Aggregate_Lib, From_Encapsulated_Lib), With_State); end if; end if; end Recursive_Check; -- Start of processing for Recursive_Check_Context begin Recursive_Check (Project, Tree, In_Aggregate_Lib, From_Encapsulated_Lib); end Recursive_Check_Context; -- Start of processing for For_Every_Project_Imported begin Recursive_Check_Context (Project => By, Tree => Tree, In_Aggregate_Lib => False, From_Encapsulated_Lib => False); end For_Every_Project_Imported_Context; procedure For_Every_Project_Imported (By : Project_Id; Tree : Project_Tree_Ref; With_State : in out State; Include_Aggregated : Boolean := True; Imported_First : Boolean := False) is procedure Internal (Project : Project_Id; Tree : Project_Tree_Ref; Context : Project_Context; With_State : in out State); -- Action wrapper for handling the context -------------- -- Internal -- -------------- procedure Internal (Project : Project_Id; Tree : Project_Tree_Ref; Context : Project_Context; With_State : in out State) is pragma Unreferenced (Context); begin Action (Project, Tree, With_State); end Internal; procedure For_Projects is new For_Every_Project_Imported_Context (State, Internal); begin For_Projects (By, Tree, With_State, Include_Aggregated, Imported_First); end For_Every_Project_Imported; ----------------- -- Find_Source -- ----------------- function Find_Source (In_Tree : Project_Tree_Ref; Project : Project_Id; In_Imported_Only : Boolean := False; In_Extended_Only : Boolean := False; Base_Name : File_Name_Type; Index : Int := 0) return Source_Id is Result : Source_Id := No_Source; procedure Look_For_Sources (Proj : Project_Id; Tree : Project_Tree_Ref; Src : in out Source_Id); -- Look for Base_Name in the sources of Proj ---------------------- -- Look_For_Sources -- ---------------------- procedure Look_For_Sources (Proj : Project_Id; Tree : Project_Tree_Ref; Src : in out Source_Id) is Iterator : Source_Iterator; begin Iterator := For_Each_Source (In_Tree => Tree, Project => Proj); while Element (Iterator) /= No_Source loop if Element (Iterator).File = Base_Name and then (Index = 0 or else Element (Iterator).Index = Index) then Src := Element (Iterator); -- If the source has been excluded, continue looking. We will -- get the excluded source only if there is no other source -- with the same base name that is not locally removed. if not Element (Iterator).Locally_Removed then return; end if; end if; Next (Iterator); end loop; end Look_For_Sources; procedure For_Imported_Projects is new For_Every_Project_Imported (State => Source_Id, Action => Look_For_Sources); Proj : Project_Id; -- Start of processing for Find_Source begin if In_Extended_Only then Proj := Project; while Proj /= No_Project loop Look_For_Sources (Proj, In_Tree, Result); exit when Result /= No_Source; Proj := Proj.Extends; end loop; elsif In_Imported_Only then Look_For_Sources (Project, In_Tree, Result); if Result = No_Source then For_Imported_Projects (By => Project, Tree => In_Tree, Include_Aggregated => False, With_State => Result); end if; else Look_For_Sources (No_Project, In_Tree, Result); end if; return Result; end Find_Source; ---------------------- -- Find_All_Sources -- ---------------------- function Find_All_Sources (In_Tree : Project_Tree_Ref; Project : Project_Id; In_Imported_Only : Boolean := False; In_Extended_Only : Boolean := False; Base_Name : File_Name_Type; Index : Int := 0) return Source_Ids is Result : Source_Ids (1 .. 1_000); Last : Natural := 0; type Empty_State is null record; No_State : Empty_State; -- This is needed for the State parameter of procedure Look_For_Sources -- below, because of the instantiation For_Imported_Projects of generic -- procedure For_Every_Project_Imported. As procedure Look_For_Sources -- does not modify parameter State, there is no need to give its type -- more than one value. procedure Look_For_Sources (Proj : Project_Id; Tree : Project_Tree_Ref; State : in out Empty_State); -- Look for Base_Name in the sources of Proj ---------------------- -- Look_For_Sources -- ---------------------- procedure Look_For_Sources (Proj : Project_Id; Tree : Project_Tree_Ref; State : in out Empty_State) is Iterator : Source_Iterator; Src : Source_Id; begin State := No_State; Iterator := For_Each_Source (In_Tree => Tree, Project => Proj); while Element (Iterator) /= No_Source loop if Element (Iterator).File = Base_Name and then (Index = 0 or else (Element (Iterator).Unit /= No_Unit_Index and then Element (Iterator).Index = Index)) then Src := Element (Iterator); -- If the source has been excluded, continue looking. We will -- get the excluded source only if there is no other source -- with the same base name that is not locally removed. if not Element (Iterator).Locally_Removed then Last := Last + 1; Result (Last) := Src; end if; end if; Next (Iterator); end loop; end Look_For_Sources; procedure For_Imported_Projects is new For_Every_Project_Imported (State => Empty_State, Action => Look_For_Sources); Proj : Project_Id; -- Start of processing for Find_All_Sources begin if In_Extended_Only then Proj := Project; while Proj /= No_Project loop Look_For_Sources (Proj, In_Tree, No_State); exit when Last > 0; Proj := Proj.Extends; end loop; elsif In_Imported_Only then Look_For_Sources (Project, In_Tree, No_State); if Last = 0 then For_Imported_Projects (By => Project, Tree => In_Tree, Include_Aggregated => False, With_State => No_State); end if; else Look_For_Sources (No_Project, In_Tree, No_State); end if; return Result (1 .. Last); end Find_All_Sources; ---------- -- Hash -- ---------- function Hash is new GNAT.HTable.Hash (Header_Num => Header_Num); -- Used in implementation of other functions Hash below ---------- -- Hash -- ---------- function Hash (Name : File_Name_Type) return Header_Num is begin return Hash (Get_Name_String (Name)); end Hash; function Hash (Name : Name_Id) return Header_Num is begin return Hash (Get_Name_String (Name)); end Hash; function Hash (Name : Path_Name_Type) return Header_Num is begin return Hash (Get_Name_String (Name)); end Hash; function Hash (Project : Project_Id) return Header_Num is begin if Project = No_Project then return Header_Num'First; else return Hash (Get_Name_String (Project.Name)); end if; end Hash; ----------- -- Image -- ----------- function Image (The_Casing : Casing_Type) return String is begin return The_Casing_Images (The_Casing).all; end Image; ----------------------------- -- Is_Standard_GNAT_Naming -- ----------------------------- function Is_Standard_GNAT_Naming (Naming : Lang_Naming_Data) return Boolean is begin return Get_Name_String (Naming.Spec_Suffix) = ".ads" and then Get_Name_String (Naming.Body_Suffix) = ".adb" and then Get_Name_String (Naming.Dot_Replacement) = "-"; end Is_Standard_GNAT_Naming; ---------------- -- Initialize -- ---------------- procedure Initialize (Tree : Project_Tree_Ref) is begin if The_Empty_String = No_Name then Uintp.Initialize; Name_Len := 0; The_Empty_String := Name_Find; Prj.Attr.Initialize; -- Make sure that new reserved words after Ada 95 may be used as -- identifiers. Opt.Ada_Version := Opt.Ada_95; Opt.Ada_Version_Pragma := Empty; Set_Name_Table_Byte (Name_Project, Token_Type'Pos (Tok_Project)); Set_Name_Table_Byte (Name_Extends, Token_Type'Pos (Tok_Extends)); Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External)); Set_Name_Table_Byte (Name_External_As_List, Token_Type'Pos (Tok_External_As_List)); end if; if Tree /= No_Project_Tree then Reset (Tree); end if; end Initialize; ------------------ -- Is_Extending -- ------------------ function Is_Extending (Extending : Project_Id; Extended : Project_Id) return Boolean is Proj : Project_Id; begin Proj := Extending; while Proj /= No_Project loop if Proj = Extended then return True; end if; Proj := Proj.Extends; end loop; return False; end Is_Extending; ----------------- -- Object_Name -- ----------------- function Object_Name (Source_File_Name : File_Name_Type; Object_File_Suffix : Name_Id := No_Name) return File_Name_Type is begin if Object_File_Suffix = No_Name then return Extend_Name (Source_File_Name, Object_Suffix); else return Extend_Name (Source_File_Name, Get_Name_String (Object_File_Suffix)); end if; end Object_Name; function Object_Name (Source_File_Name : File_Name_Type; Source_Index : Int; Index_Separator : Character; Object_File_Suffix : Name_Id := No_Name) return File_Name_Type is Index_Img : constant String := Source_Index'Img; Last : Natural; begin Get_Name_String (Source_File_Name); Last := Name_Len; while Last > 1 and then Name_Buffer (Last) /= '.' loop Last := Last - 1; end loop; if Last > 1 then Name_Len := Last - 1; end if; Add_Char_To_Name_Buffer (Index_Separator); Add_Str_To_Name_Buffer (Index_Img (2 .. Index_Img'Last)); if Object_File_Suffix = No_Name then Add_Str_To_Name_Buffer (Object_Suffix); else Add_Str_To_Name_Buffer (Get_Name_String (Object_File_Suffix)); end if; return Name_Find; end Object_Name; ---------------------- -- Record_Temp_File -- ---------------------- procedure Record_Temp_File (Shared : Shared_Project_Tree_Data_Access; Path : Path_Name_Type) is begin Temp_Files_Table.Append (Shared.Private_Part.Temp_Files, Path); end Record_Temp_File; ---------- -- Free -- ---------- procedure Free (List : in out Aggregated_Project_List) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Aggregated_Project, Aggregated_Project_List); Tmp : Aggregated_Project_List; begin while List /= null loop Tmp := List.Next; Free (List.Tree); Unchecked_Free (List); List := Tmp; end loop; end Free; ---------------------------- -- Add_Aggregated_Project -- ---------------------------- procedure Add_Aggregated_Project (Project : Project_Id; Path : Path_Name_Type) is Aggregated : Aggregated_Project_List; begin -- Check if the project is already in the aggregated project list. If it -- is, do not add it again. Aggregated := Project.Aggregated_Projects; while Aggregated /= null loop if Path = Aggregated.Path then return; else Aggregated := Aggregated.Next; end if; end loop; Project.Aggregated_Projects := new Aggregated_Project' (Path => Path, Project => No_Project, Tree => null, Next => Project.Aggregated_Projects); end Add_Aggregated_Project; ---------- -- Free -- ---------- procedure Free (Project : in out Project_Id) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Project_Data, Project_Id); begin if Project /= null then Free (Project.Ada_Include_Path); Free (Project.Objects_Path); Free (Project.Ada_Objects_Path); Free (Project.Ada_Objects_Path_No_Libs); Free_List (Project.Imported_Projects, Free_Project => False); Free_List (Project.All_Imported_Projects, Free_Project => False); Free_List (Project.Languages); case Project.Qualifier is when Aggregate | Aggregate_Library => Free (Project.Aggregated_Projects); when others => null; end case; Unchecked_Free (Project); end if; end Free; --------------- -- Free_List -- --------------- procedure Free_List (Languages : in out Language_List) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Language_List_Element, Language_List); Tmp : Language_List; begin while Languages /= null loop Tmp := Languages.Next; Unchecked_Free (Languages); Languages := Tmp; end loop; end Free_List; --------------- -- Free_List -- --------------- procedure Free_List (Source : in out Source_Id) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Source_Data, Source_Id); Tmp : Source_Id; begin while Source /= No_Source loop Tmp := Source.Next_In_Lang; Free_List (Source.Alternate_Languages); if Source.Unit /= null and then Source.Kind in Spec_Or_Body then Source.Unit.File_Names (Source.Kind) := null; end if; Unchecked_Free (Source); Source := Tmp; end loop; end Free_List; --------------- -- Free_List -- --------------- procedure Free_List (List : in out Project_List; Free_Project : Boolean) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Project_List_Element, Project_List); Tmp : Project_List; begin while List /= null loop Tmp := List.Next; if Free_Project then Free (List.Project); end if; Unchecked_Free (List); List := Tmp; end loop; end Free_List; --------------- -- Free_List -- --------------- procedure Free_List (Languages : in out Language_Ptr) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Language_Data, Language_Ptr); Tmp : Language_Ptr; begin while Languages /= null loop Tmp := Languages.Next; Free_List (Languages.First_Source); Unchecked_Free (Languages); Languages := Tmp; end loop; end Free_List; -------------------------- -- Reset_Units_In_Table -- -------------------------- procedure Reset_Units_In_Table (Table : in out Units_Htable.Instance) is Unit : Unit_Index; begin Unit := Units_Htable.Get_First (Table); while Unit /= No_Unit_Index loop if Unit.File_Names (Spec) /= null then Unit.File_Names (Spec).Unit := No_Unit_Index; end if; if Unit.File_Names (Impl) /= null then Unit.File_Names (Impl).Unit := No_Unit_Index; end if; Unit := Units_Htable.Get_Next (Table); end loop; end Reset_Units_In_Table; ---------------- -- Free_Units -- ---------------- procedure Free_Units (Table : in out Units_Htable.Instance) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Unit_Data, Unit_Index); Unit : Unit_Index; begin Unit := Units_Htable.Get_First (Table); while Unit /= No_Unit_Index loop -- We cannot reset Unit.File_Names (Impl or Spec).Unit here as -- Source_Data buffer is freed by the following instruction -- Free_List (Tree.Projects, Free_Project => True); Unchecked_Free (Unit); Unit := Units_Htable.Get_Next (Table); end loop; Units_Htable.Reset (Table); end Free_Units; ---------- -- Free -- ---------- procedure Free (Tree : in out Project_Tree_Ref) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Project_Tree_Data, Project_Tree_Ref); procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Project_Tree_Appdata'Class, Project_Tree_Appdata_Access); begin if Tree /= null then if Tree.Is_Root_Tree then Name_List_Table.Free (Tree.Shared.Name_Lists); Number_List_Table.Free (Tree.Shared.Number_Lists); String_Element_Table.Free (Tree.Shared.String_Elements); Variable_Element_Table.Free (Tree.Shared.Variable_Elements); Array_Element_Table.Free (Tree.Shared.Array_Elements); Array_Table.Free (Tree.Shared.Arrays); Package_Table.Free (Tree.Shared.Packages); Temp_Files_Table.Free (Tree.Shared.Private_Part.Temp_Files); end if; if Tree.Appdata /= null then Free (Tree.Appdata.all); Unchecked_Free (Tree.Appdata); end if; Source_Paths_Htable.Reset (Tree.Source_Paths_HT); Source_Files_Htable.Reset (Tree.Source_Files_HT); Reset_Units_In_Table (Tree.Units_HT); Free_List (Tree.Projects, Free_Project => True); Free_Units (Tree.Units_HT); Unchecked_Free (Tree); end if; end Free; ----------- -- Reset -- ----------- procedure Reset (Tree : Project_Tree_Ref) is begin -- Visible tables if Tree.Is_Root_Tree then -- We cannot use 'Access here: -- "illegal attribute for discriminant-dependent component" -- However, we know this is valid since Shared and Shared_Data have -- the same lifetime and will always exist concurrently. Tree.Shared := Tree.Shared_Data'Unrestricted_Access; Name_List_Table.Init (Tree.Shared.Name_Lists); Number_List_Table.Init (Tree.Shared.Number_Lists); String_Element_Table.Init (Tree.Shared.String_Elements); Variable_Element_Table.Init (Tree.Shared.Variable_Elements); Array_Element_Table.Init (Tree.Shared.Array_Elements); Array_Table.Init (Tree.Shared.Arrays); Package_Table.Init (Tree.Shared.Packages); -- Private part table Temp_Files_Table.Init (Tree.Shared.Private_Part.Temp_Files); Tree.Shared.Private_Part.Current_Source_Path_File := No_Path; Tree.Shared.Private_Part.Current_Object_Path_File := No_Path; end if; Source_Paths_Htable.Reset (Tree.Source_Paths_HT); Source_Files_Htable.Reset (Tree.Source_Files_HT); Replaced_Source_HTable.Reset (Tree.Replaced_Sources); Tree.Replaced_Source_Number := 0; Reset_Units_In_Table (Tree.Units_HT); Free_List (Tree.Projects, Free_Project => True); Free_Units (Tree.Units_HT); end Reset; ------------------------------------- -- Set_Current_Object_Path_File_Of -- ------------------------------------- procedure Set_Current_Object_Path_File_Of (Shared : Shared_Project_Tree_Data_Access; To : Path_Name_Type) is begin Shared.Private_Part.Current_Object_Path_File := To; end Set_Current_Object_Path_File_Of; ------------------------------------- -- Set_Current_Source_Path_File_Of -- ------------------------------------- procedure Set_Current_Source_Path_File_Of (Shared : Shared_Project_Tree_Data_Access; To : Path_Name_Type) is begin Shared.Private_Part.Current_Source_Path_File := To; end Set_Current_Source_Path_File_Of; ----------------------- -- Set_Path_File_Var -- ----------------------- procedure Set_Path_File_Var (Name : String; Value : String) is Host_Spec : String_Access := To_Host_File_Spec (Value); begin if Host_Spec = null then Prj.Com.Fail ("could not convert file name """ & Value & """ to host spec"); else Setenv (Name, Host_Spec.all); Free (Host_Spec); end if; end Set_Path_File_Var; ------------------- -- Switches_Name -- ------------------- function Switches_Name (Source_File_Name : File_Name_Type) return File_Name_Type is begin return Extend_Name (Source_File_Name, Switches_Dependency_Suffix); end Switches_Name; ----------- -- Value -- ----------- function Value (Image : String) return Casing_Type is begin for Casing in The_Casing_Images'Range loop if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then return Casing; end if; end loop; raise Constraint_Error; end Value; --------------------- -- Has_Ada_Sources -- --------------------- function Has_Ada_Sources (Data : Project_Id) return Boolean is Lang : Language_Ptr; begin Lang := Data.Languages; while Lang /= No_Language_Index loop if Lang.Name = Name_Ada then return Lang.First_Source /= No_Source; end if; Lang := Lang.Next; end loop; return False; end Has_Ada_Sources; ------------------------ -- Contains_ALI_Files -- ------------------------ function Contains_ALI_Files (Dir : Path_Name_Type) return Boolean is Dir_Name : constant String := Get_Name_String (Dir); Direct : Dir_Type; Name : String (1 .. 1_000); Last : Natural; Result : Boolean := False; begin Open (Direct, Dir_Name); -- For each file in the directory, check if it is an ALI file loop Read (Direct, Name, Last); exit when Last = 0; Canonical_Case_File_Name (Name (1 .. Last)); Result := Last >= 5 and then Name (Last - 3 .. Last) = ".ali"; exit when Result; end loop; Close (Direct); return Result; exception -- If there is any problem, close the directory if open and return True. -- The library directory will be added to the path. when others => if Is_Open (Direct) then Close (Direct); end if; return True; end Contains_ALI_Files; -------------------------- -- Get_Object_Directory -- -------------------------- function Get_Object_Directory (Project : Project_Id; Including_Libraries : Boolean; Only_If_Ada : Boolean := False) return Path_Name_Type is begin if (Project.Library and then Including_Libraries) or else (Project.Object_Directory /= No_Path_Information and then (not Including_Libraries or else not Project.Library)) then -- For a library project, add the library ALI directory if there is -- no object directory or if the library ALI directory contains ALI -- files; otherwise add the object directory. if Project.Library then if Project.Object_Directory = No_Path_Information or else (Including_Libraries and then Contains_ALI_Files (Project.Library_ALI_Dir.Display_Name)) then return Project.Library_ALI_Dir.Display_Name; else return Project.Object_Directory.Display_Name; end if; -- For a non-library project, add object directory if it is not a -- virtual project, and if there are Ada sources in the project or -- one of the projects it extends. If there are no Ada sources, -- adding the object directory could disrupt the order of the -- object dirs in the path. elsif not Project.Virtual then declare Add_Object_Dir : Boolean; Prj : Project_Id; begin Add_Object_Dir := not Only_If_Ada; Prj := Project; while not Add_Object_Dir and then Prj /= No_Project loop if Has_Ada_Sources (Prj) then Add_Object_Dir := True; else Prj := Prj.Extends; end if; end loop; if Add_Object_Dir then return Project.Object_Directory.Display_Name; end if; end; end if; end if; return No_Path; end Get_Object_Directory; ----------------------------------- -- Ultimate_Extending_Project_Of -- ----------------------------------- function Ultimate_Extending_Project_Of (Proj : Project_Id) return Project_Id is Prj : Project_Id; begin Prj := Proj; while Prj /= null and then Prj.Extended_By /= No_Project loop Prj := Prj.Extended_By; end loop; return Prj; end Ultimate_Extending_Project_Of; ----------------------------------- -- Compute_All_Imported_Projects -- ----------------------------------- procedure Compute_All_Imported_Projects (Root_Project : Project_Id; Tree : Project_Tree_Ref) is procedure Analyze_Tree (Local_Root : Project_Id; Local_Tree : Project_Tree_Ref; Context : Project_Context); -- Process Project and all its aggregated project to analyze their own -- imported projects. ------------------ -- Analyze_Tree -- ------------------ procedure Analyze_Tree (Local_Root : Project_Id; Local_Tree : Project_Tree_Ref; Context : Project_Context) is pragma Unreferenced (Local_Root); Project : Project_Id; procedure Recursive_Add (Prj : Project_Id; Tree : Project_Tree_Ref; Context : Project_Context; Dummy : in out Boolean); -- Recursively add the projects imported by project Project, but not -- those that are extended. ------------------- -- Recursive_Add -- ------------------- procedure Recursive_Add (Prj : Project_Id; Tree : Project_Tree_Ref; Context : Project_Context; Dummy : in out Boolean) is pragma Unreferenced (Dummy, Tree); List : Project_List; Prj2 : Project_Id; begin -- A project is not importing itself Prj2 := Ultimate_Extending_Project_Of (Prj); if Project /= Prj2 then -- Check that the project is not already in the list. We know -- the one passed to Recursive_Add have never been visited -- before, but the one passed it are the extended projects. List := Project.All_Imported_Projects; while List /= null loop if List.Project = Prj2 then return; end if; List := List.Next; end loop; -- Add it to the list Project.All_Imported_Projects := new Project_List_Element' (Project => Prj2, From_Encapsulated_Lib => Context.From_Encapsulated_Lib or else Analyze_Tree.Context.From_Encapsulated_Lib, Next => Project.All_Imported_Projects); end if; end Recursive_Add; procedure For_All_Projects is new For_Every_Project_Imported_Context (Boolean, Recursive_Add); Dummy : Boolean := False; List : Project_List; begin List := Local_Tree.Projects; while List /= null loop Project := List.Project; Free_List (Project.All_Imported_Projects, Free_Project => False); For_All_Projects (Project, Local_Tree, Dummy, Include_Aggregated => False); List := List.Next; end loop; end Analyze_Tree; procedure For_Aggregates is new For_Project_And_Aggregated_Context (Analyze_Tree); -- Start of processing for Compute_All_Imported_Projects begin For_Aggregates (Root_Project, Tree); end Compute_All_Imported_Projects; ------------------- -- Is_Compilable -- ------------------- function Is_Compilable (Source : Source_Id) return Boolean is begin case Source.Compilable is when Unknown => if Source.Language.Config.Compiler_Driver /= No_File and then Length_Of_Name (Source.Language.Config.Compiler_Driver) /= 0 and then not Source.Locally_Removed and then (Source.Language.Config.Kind /= File_Based or else Source.Kind /= Spec) then -- Do not modify Source.Compilable before the source record -- has been initialized. if Source.Source_TS /= Empty_Time_Stamp then Source.Compilable := Yes; end if; return True; else if Source.Source_TS /= Empty_Time_Stamp then Source.Compilable := No; end if; return False; end if; when Yes => return True; when No => return False; end case; end Is_Compilable; ------------------------------ -- Object_To_Global_Archive -- ------------------------------ function Object_To_Global_Archive (Source : Source_Id) return Boolean is begin return Source.Language.Config.Kind = File_Based and then Source.Kind = Impl and then Source.Language.Config.Objects_Linked and then Is_Compilable (Source) and then Source.Language.Config.Object_Generated; end Object_To_Global_Archive; ---------------------------- -- Get_Language_From_Name -- ---------------------------- function Get_Language_From_Name (Project : Project_Id; Name : String) return Language_Ptr is N : Name_Id; Result : Language_Ptr; begin Name_Len := Name'Length; Name_Buffer (1 .. Name_Len) := Name; To_Lower (Name_Buffer (1 .. Name_Len)); N := Name_Find; Result := Project.Languages; while Result /= No_Language_Index loop if Result.Name = N then return Result; end if; Result := Result.Next; end loop; return No_Language_Index; end Get_Language_From_Name; ---------------- -- Other_Part -- ---------------- function Other_Part (Source : Source_Id) return Source_Id is begin if Source.Unit /= No_Unit_Index then case Source.Kind is when Impl => return Source.Unit.File_Names (Spec); when Spec => return Source.Unit.File_Names (Impl); when Sep => return No_Source; end case; else return No_Source; end if; end Other_Part; ------------------ -- Create_Flags -- ------------------ function Create_Flags (Report_Error : Error_Handler; When_No_Sources : Error_Warning; Require_Sources_Other_Lang : Boolean := True; Allow_Duplicate_Basenames : Boolean := True; Compiler_Driver_Mandatory : Boolean := False; Error_On_Unknown_Language : Boolean := True; Require_Obj_Dirs : Error_Warning := Error; Allow_Invalid_External : Error_Warning := Error; Missing_Source_Files : Error_Warning := Error; Ignore_Missing_With : Boolean := False) return Processing_Flags is begin return Processing_Flags' (Report_Error => Report_Error, When_No_Sources => When_No_Sources, Require_Sources_Other_Lang => Require_Sources_Other_Lang, Allow_Duplicate_Basenames => Allow_Duplicate_Basenames, Error_On_Unknown_Language => Error_On_Unknown_Language, Compiler_Driver_Mandatory => Compiler_Driver_Mandatory, Require_Obj_Dirs => Require_Obj_Dirs, Allow_Invalid_External => Allow_Invalid_External, Missing_Source_Files => Missing_Source_Files, Ignore_Missing_With => Ignore_Missing_With); end Create_Flags; ------------ -- Length -- ------------ function Length (Table : Name_List_Table.Instance; List : Name_List_Index) return Natural is Count : Natural := 0; Tmp : Name_List_Index; begin Tmp := List; while Tmp /= No_Name_List loop Count := Count + 1; Tmp := Table.Table (Tmp).Next; end loop; return Count; end Length; ------------------ -- Debug_Output -- ------------------ procedure Debug_Output (Str : String) is begin if Current_Verbosity > Default then Set_Standard_Error; Write_Line ((1 .. Debug_Level * 2 => ' ') & Str); Set_Standard_Output; end if; end Debug_Output; ------------------ -- Debug_Indent -- ------------------ procedure Debug_Indent is begin if Current_Verbosity = High then Set_Standard_Error; Write_Str ((1 .. Debug_Level * 2 => ' ')); Set_Standard_Output; end if; end Debug_Indent; ------------------ -- Debug_Output -- ------------------ procedure Debug_Output (Str : String; Str2 : Name_Id) is begin if Current_Verbosity > Default then Debug_Indent; Set_Standard_Error; Write_Str (Str); if Str2 = No_Name then Write_Line (" "); else Write_Line (" """ & Get_Name_String (Str2) & '"'); end if; Set_Standard_Output; end if; end Debug_Output; --------------------------- -- Debug_Increase_Indent -- --------------------------- procedure Debug_Increase_Indent (Str : String := ""; Str2 : Name_Id := No_Name) is begin if Str2 /= No_Name then Debug_Output (Str, Str2); else Debug_Output (Str); end if; Debug_Level := Debug_Level + 1; end Debug_Increase_Indent; --------------------------- -- Debug_Decrease_Indent -- --------------------------- procedure Debug_Decrease_Indent (Str : String := "") is begin if Debug_Level > 0 then Debug_Level := Debug_Level - 1; end if; if Str /= "" then Debug_Output (Str); end if; end Debug_Decrease_Indent; ---------------- -- Debug_Name -- ---------------- function Debug_Name (Tree : Project_Tree_Ref) return Name_Id is P : Project_List; begin Name_Len := 0; Add_Str_To_Name_Buffer ("Tree ["); P := Tree.Projects; while P /= null loop if P /= Tree.Projects then Add_Char_To_Name_Buffer (','); end if; Add_Str_To_Name_Buffer (Get_Name_String (P.Project.Name)); P := P.Next; end loop; Add_Char_To_Name_Buffer (']'); return Name_Find; end Debug_Name; ---------- -- Free -- ---------- procedure Free (Tree : in out Project_Tree_Appdata) is pragma Unreferenced (Tree); begin null; end Free; -------------------------------- -- For_Project_And_Aggregated -- -------------------------------- procedure For_Project_And_Aggregated (Root_Project : Project_Id; Root_Tree : Project_Tree_Ref) is Agg : Aggregated_Project_List; begin Action (Root_Project, Root_Tree); if Root_Project.Qualifier in Aggregate_Project then Agg := Root_Project.Aggregated_Projects; while Agg /= null loop For_Project_And_Aggregated (Agg.Project, Agg.Tree); Agg := Agg.Next; end loop; end if; end For_Project_And_Aggregated; ---------------------------------------- -- For_Project_And_Aggregated_Context -- ---------------------------------------- procedure For_Project_And_Aggregated_Context (Root_Project : Project_Id; Root_Tree : Project_Tree_Ref) is procedure Recursive_Process (Project : Project_Id; Tree : Project_Tree_Ref; Context : Project_Context); -- Process Project and all aggregated projects recursively ----------------------- -- Recursive_Process -- ----------------------- procedure Recursive_Process (Project : Project_Id; Tree : Project_Tree_Ref; Context : Project_Context) is Agg : Aggregated_Project_List; Ctx : Project_Context; begin Action (Project, Tree, Context); if Project.Qualifier in Aggregate_Project then Ctx := (In_Aggregate_Lib => True, From_Encapsulated_Lib => Context.From_Encapsulated_Lib or else Project.Standalone_Library = Encapsulated); Agg := Project.Aggregated_Projects; while Agg /= null loop Recursive_Process (Agg.Project, Agg.Tree, Ctx); Agg := Agg.Next; end loop; end if; end Recursive_Process; -- Start of processing for For_Project_And_Aggregated_Context begin Recursive_Process (Root_Project, Root_Tree, Project_Context'(False, False)); end For_Project_And_Aggregated_Context; -- Package initialization for Prj begin -- Make sure that the standard config and user project file extensions are -- compatible with canonical case file naming. Canonical_Case_File_Name (Config_Project_File_Extension); Canonical_Case_File_Name (Project_File_Extension); end Prj; gprbuild-gpl-2014-src/gnat/Make-generated.in0000644000076700001450000002005712253553403020232 0ustar gnatmailgnat# Dependencies for compiler sources that are generated at build time # Note: can't use ?= here, not supported by older versions of GNU Make ifeq ($(origin ADA_GEN_SUBDIR), undefined) ADA_GEN_SUBDIR=ada endif ifeq ($(origin CP), undefined) CP=cp endif ifeq ($(origin MKDIR), undefined) MKDIR=mkdir -p endif ifeq ($(origin MOVE_IF_CHANGE), undefined) MOVE_IF_CHANGE=mv -f endif .PHONY: ada_extra_files ada_extra_files : $(ADA_GEN_SUBDIR)/treeprs.ads $(ADA_GEN_SUBDIR)/einfo.h $(ADA_GEN_SUBDIR)/sinfo.h $(ADA_GEN_SUBDIR)/nmake.adb \ $(ADA_GEN_SUBDIR)/nmake.ads $(ADA_GEN_SUBDIR)/snames.ads $(ADA_GEN_SUBDIR)/snames.adb $(ADA_GEN_SUBDIR)/snames.h # We delete the files before copying, below, in case they are read-only. $(ADA_GEN_SUBDIR)/treeprs.ads : $(ADA_GEN_SUBDIR)/treeprs.adt $(ADA_GEN_SUBDIR)/sinfo.ads $(ADA_GEN_SUBDIR)/xtreeprs.adb -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/treeprs $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/treeprs/,$(notdir $^)) $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/treeprs (cd $(ADA_GEN_SUBDIR)/bldtools/treeprs; gnatmake -q xtreeprs ; ./xtreeprs treeprs.ads ) $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/treeprs/treeprs.ads $(ADA_GEN_SUBDIR)/treeprs.ads $(ADA_GEN_SUBDIR)/einfo.h : $(ADA_GEN_SUBDIR)/einfo.ads $(ADA_GEN_SUBDIR)/einfo.adb $(ADA_GEN_SUBDIR)/xeinfo.adb $(ADA_GEN_SUBDIR)/ceinfo.adb -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/einfo $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/einfo/,$(notdir $^)) $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/einfo (cd $(ADA_GEN_SUBDIR)/bldtools/einfo; gnatmake -q xeinfo ; ./xeinfo einfo.h ) $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/einfo/einfo.h $(ADA_GEN_SUBDIR)/einfo.h $(ADA_GEN_SUBDIR)/sinfo.h : $(ADA_GEN_SUBDIR)/sinfo.ads $(ADA_GEN_SUBDIR)/sinfo.adb $(ADA_GEN_SUBDIR)/xsinfo.adb $(ADA_GEN_SUBDIR)/csinfo.adb -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/sinfo $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/sinfo/,$(notdir $^)) $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/sinfo (cd $(ADA_GEN_SUBDIR)/bldtools/sinfo; gnatmake -q xsinfo ; ./xsinfo sinfo.h ) $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/sinfo/sinfo.h $(ADA_GEN_SUBDIR)/sinfo.h $(ADA_GEN_SUBDIR)/snames.h $(ADA_GEN_SUBDIR)/snames.ads $(ADA_GEN_SUBDIR)/snames.adb : $(ADA_GEN_SUBDIR)/stamp-snames ; @true $(ADA_GEN_SUBDIR)/stamp-snames : $(ADA_GEN_SUBDIR)/snames.ads-tmpl $(ADA_GEN_SUBDIR)/snames.adb-tmpl $(ADA_GEN_SUBDIR)/snames.h-tmpl $(ADA_GEN_SUBDIR)/xsnamest.adb $(ADA_GEN_SUBDIR)/xutil.ads $(ADA_GEN_SUBDIR)/xutil.adb -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/snamest $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/snamest/,$(notdir $^)) $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/snamest (cd $(ADA_GEN_SUBDIR)/bldtools/snamest; gnatmake -q xsnamest ; ./xsnamest ) $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/snamest/snames.ns $(ADA_GEN_SUBDIR)/snames.ads $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/snamest/snames.nb $(ADA_GEN_SUBDIR)/snames.adb $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/snamest/snames.nh $(ADA_GEN_SUBDIR)/snames.h touch $(ADA_GEN_SUBDIR)/stamp-snames $(ADA_GEN_SUBDIR)/nmake.adb $(ADA_GEN_SUBDIR)/nmake.ads: $(ADA_GEN_SUBDIR)/stamp-nmake ; @true $(ADA_GEN_SUBDIR)/stamp-nmake: $(ADA_GEN_SUBDIR)/sinfo.ads $(ADA_GEN_SUBDIR)/nmake.adt $(ADA_GEN_SUBDIR)/xnmake.adb $(ADA_GEN_SUBDIR)/xutil.ads $(ADA_GEN_SUBDIR)/xutil.adb -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/nmake $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/nmake/,$(notdir $^)) $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/nmake (cd $(ADA_GEN_SUBDIR)/bldtools/nmake; gnatmake -q xnmake ; ./xnmake -b nmake.adb ; ./xnmake -s nmake.ads) $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/nmake/nmake.ads $(ADA_GEN_SUBDIR)/nmake.ads $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/nmake/nmake.adb $(ADA_GEN_SUBDIR)/nmake.adb touch $(ADA_GEN_SUBDIR)/stamp-nmake # GCC_FOR_TARGET has paths relative to the gcc directory, so we need to adjust # for running it from $(ADA_GEN_SUBDIR)/bldtools/oscons. OSCONS_CC=$(subst ./xgcc,../../../xgcc,$(subst -B./, -B../../../,$(GCC_FOR_TARGET))) # The main ada source directory must be on the include path for #include "..." # because s-oscons-tmplt.c requires adaint.h, gsocket.h, and any file included # by these headers. However note that we must use -iquote, not -I, so that # ada/types.h does not conflict with a same-named system header (VxWorks # has a header). OSCONS_SRCDIR=$${_oscons_srcdir} OSCONS_CPP=$(OSCONS_CC) $(GNATLIBCFLAGS) -E -C \ -DTARGET=\"$(target)\" -iquote $(OSCONS_SRCDIR) s-oscons-tmplt.c > s-oscons-tmplt.i OSCONS_EXTRACT=$(OSCONS_CC) -iquote $(OSCONS_SRCDIR) -S s-oscons-tmplt.i # Note: if you need to build with a non-GNU compiler, you could adapt the # following definitions (written for VMS DEC-C) #OSCONS_CPP=../../../$(DECC) -E /comment=as_is -DNATIVE \ # -DTARGET='""$(target)""' -I$(OSCONS_SRCDIR) s-oscons-tmplt.c # #OSCONS_EXTRACT=../../../$(DECC) -DNATIVE \ # -DTARGET='""$(target)""' -I$(OSCONS_SRCDIR) s-oscons-tmplt.c ; \ # ld -o s-oscons-tmplt.exe s-oscons-tmplt.obj; \ # ./s-oscons-tmplt.exe > s-oscons-tmplt.s # Note: the first dependency of s-oscons.ads *must* remain s-oscons-tmplt.c, as # we use $(tmp-sdefault.adb $(ECHO) "with Osint; use Osint;" >>tmp-sdefault.adb $(ECHO) "package body Sdefault is" >>tmp-sdefault.adb $(ECHO) " S0 : constant String := \"$(prefix)/\";" >>tmp-sdefault.adb $(ECHO) " S1 : constant String := \"$(ADA_INCLUDE_DIR)/\";" >>tmp-sdefault.adb $(ECHO) " S2 : constant String := \"$(ADA_RTL_OBJ_DIR)/\";" >>tmp-sdefault.adb $(ECHO) " S3 : constant String := \"$(target_noncanonical)/\";" >>tmp-sdefault.adb $(ECHO) " S4 : constant String := \"$(libsubdir)/\";" >>tmp-sdefault.adb $(ECHO) " function Include_Dir_Default_Name return String_Ptr is" >>tmp-sdefault.adb $(ECHO) " begin" >>tmp-sdefault.adb $(ECHO) " return Relocate_Path (S0, S1);" >>tmp-sdefault.adb $(ECHO) " end Include_Dir_Default_Name;" >>tmp-sdefault.adb $(ECHO) " function Object_Dir_Default_Name return String_Ptr is" >>tmp-sdefault.adb $(ECHO) " begin" >>tmp-sdefault.adb $(ECHO) " return Relocate_Path (S0, S2);" >>tmp-sdefault.adb $(ECHO) " end Object_Dir_Default_Name;" >>tmp-sdefault.adb $(ECHO) " function Target_Name return String_Ptr is" >>tmp-sdefault.adb $(ECHO) " begin" >>tmp-sdefault.adb $(ECHO) " return new String'(S3);" >>tmp-sdefault.adb $(ECHO) " end Target_Name;" >>tmp-sdefault.adb $(ECHO) " function Search_Dir_Prefix return String_Ptr is" >>tmp-sdefault.adb $(ECHO) " begin" >>tmp-sdefault.adb $(ECHO) " return Relocate_Path (S0, S4);" >>tmp-sdefault.adb $(ECHO) " end Search_Dir_Prefix;" >>tmp-sdefault.adb $(ECHO) "end Sdefault;" >> tmp-sdefault.adb $(MOVE_IF_CHANGE) tmp-sdefault.adb $(ADA_GEN_SUBDIR)/sdefault.adb touch $(ADA_GEN_SUBDIR)/stamp-sdefault $(ADA_GEN_SUBDIR)/gnat.hlp : $(ADA_GEN_SUBDIR)/vms_help.adb $(ADA_GEN_SUBDIR)/vms_cmds.ads $(ADA_GEN_SUBDIR)/gnat.help_in $(ADA_GEN_SUBDIR)/vms_data.ads -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/gnat_hlp $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/gnat_hlp/,$(notdir $^)) $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/gnat_hlp (cd $(ADA_GEN_SUBDIR)/bldtools/gnat_hlp; \ gnatmake -q vms_help; \ ./vms_help$(build_exeext) gnat.help_in vms_data.ads ../../gnat.hlp) gprbuild-gpl-2014-src/gnat/prj-attr-pm.adb0000644000076700001450000000643112323721731017715 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . A T T R . P M -- -- -- -- B o d y -- -- -- -- Copyright (C) 2004-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ package body Prj.Attr.PM is ------------------- -- Add_Attribute -- ------------------- procedure Add_Attribute (To_Package : Package_Node_Id; Attribute_Name : Name_Id; Attribute_Node : out Attribute_Node_Id) is begin -- Only add attribute if package is already defined and is not unknown if To_Package /= Empty_Package and then To_Package /= Unknown_Package then Attrs.Append ( (Name => Attribute_Name, Var_Kind => Undefined, Optional_Index => False, Attr_Kind => Unknown, Read_Only => False, Others_Allowed => False, Next => Package_Attributes.Table (To_Package.Value).First_Attribute)); Package_Attributes.Table (To_Package.Value).First_Attribute := Attrs.Last; Attribute_Node := (Value => Attrs.Last); end if; end Add_Attribute; ------------------------- -- Add_Unknown_Package -- ------------------------- procedure Add_Unknown_Package (Name : Name_Id; Id : out Package_Node_Id) is begin Package_Attributes.Increment_Last; Id := (Value => Package_Attributes.Last); Package_Attributes.Table (Id.Value) := (Name => Name, Known => False, First_Attribute => Empty_Attr); end Add_Unknown_Package; end Prj.Attr.PM; gprbuild-gpl-2014-src/gnat/prj-tree.ads0000644000076700001450000016001612323721731017311 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . T R E E -- -- -- -- S p e c -- -- -- -- Copyright (C) 2001-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package defines the structure of the Project File tree with GNAT.Dynamic_HTables; with GNAT.Dynamic_Tables; with Table; with Prj.Attr; use Prj.Attr; with Prj.Env; with Prj.Ext; package Prj.Tree is ----------------- -- Environment -- ----------------- -- The following record contains the context in which projects are parsed -- and processed (finding importing project, resolving external values,..). type Environment is record External : Prj.Ext.External_References; -- External references are stored in this hash table (and manipulated -- through subprograms in prj-ext.ads). External references are -- project-tree specific so that one can load the same tree twice but -- have two views of it, for instance. Project_Path : aliased Prj.Env.Project_Search_Path; -- The project path is tree specific, since we might want to load -- simultaneously multiple projects, each with its own search path, in -- particular when using different compilers with different default -- search directories. Flags : Prj.Processing_Flags; -- Configure errors and warnings end record; procedure Initialize (Self : out Environment; Flags : Processing_Flags); -- Initialize a new environment procedure Initialize_And_Copy (Self : out Environment; Copy_From : Environment); -- Initialize a new environment, copying its values from Copy_From procedure Free (Self : in out Environment); -- Free the memory used by Self procedure Override_Flags (Self : in out Environment; Flags : Prj.Processing_Flags); -- Override the subprogram called in case there are parsing errors. This -- is needed in applications that do their own error handling, since the -- error handler is likely to be a local subprogram in this case (which -- can't be stored when the flags are created). ------------------- -- Project nodes -- ------------------- type Project_Node_Tree_Data; type Project_Node_Tree_Ref is access all Project_Node_Tree_Data; -- Type to designate a project node tree, so that several project node -- trees can coexist in memory. Project_Nodes_Initial : constant := 1_000; Project_Nodes_Increment : constant := 100; -- Allocation parameters for initializing and extending number -- of nodes in table Tree_Private_Part.Project_Nodes Project_Node_Low_Bound : constant := 0; Project_Node_High_Bound : constant := 099_999_999; -- Range of values for project node id's (in practice infinite) type Project_Node_Id is range Project_Node_Low_Bound .. Project_Node_High_Bound; -- The index of table Tree_Private_Part.Project_Nodes Empty_Node : constant Project_Node_Id := Project_Node_Low_Bound; -- Designates no node in table Project_Nodes First_Node_Id : constant Project_Node_Id := Project_Node_Low_Bound + 1; subtype Variable_Node_Id is Project_Node_Id; -- Used to designate a node whose expected kind is one of -- N_Typed_Variable_Declaration, N_Variable_Declaration or -- N_Variable_Reference. subtype Package_Declaration_Id is Project_Node_Id; -- Used to designate a node whose expected kind is N_Project_Declaration type Project_Node_Kind is (N_Project, N_With_Clause, N_Project_Declaration, N_Declarative_Item, N_Package_Declaration, N_String_Type_Declaration, N_Literal_String, N_Attribute_Declaration, N_Typed_Variable_Declaration, N_Variable_Declaration, N_Expression, N_Term, N_Literal_String_List, N_Variable_Reference, N_External_Value, N_Attribute_Reference, N_Case_Construction, N_Case_Item, N_Comment_Zones, N_Comment); -- Each node in the tree is of a Project_Node_Kind. For the signification -- of the fields in each node of Project_Node_Kind, look at package -- Tree_Private_Part. function Present (Node : Project_Node_Id) return Boolean; pragma Inline (Present); -- Return True if Node /= Empty_Node function No (Node : Project_Node_Id) return Boolean; pragma Inline (No); -- Return True if Node = Empty_Node procedure Initialize (Tree : Project_Node_Tree_Ref); -- Initialize the Project File tree: empty the Project_Nodes table -- and reset the Projects_Htable. function Default_Project_Node (In_Tree : Project_Node_Tree_Ref; Of_Kind : Project_Node_Kind; And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id; -- Returns a Project_Node_Record with the specified Kind and Expr_Kind. All -- the other components have default nil values. -- To create a node for a project itself, see Create_Project below instead function Hash (N : Project_Node_Id) return Header_Num; -- Used for hash tables where the key is a Project_Node_Id function Imported_Or_Extended_Project_Of (Project : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; With_Name : Name_Id) return Project_Node_Id; -- Return the node of a project imported or extended by project Project and -- whose name is With_Name. Return Empty_Node if there is no such project. -------------- -- Comments -- -------------- type Comment_State is private; -- A type to store the values of several global variables related to -- comments. procedure Save (S : out Comment_State); -- Save in variable S the comment state. Called before scanning a new -- project file. procedure Restore_And_Free (S : in out Comment_State); -- Restore the comment state to a previously saved value. Called after -- scanning a project file. Frees the memory occupied by S procedure Reset_State; -- Set the comment state to its initial value. Called before scanning a -- new project file. function There_Are_Unkept_Comments return Boolean; -- Indicates that some of the comments in a project file could not be -- stored in the parse tree. procedure Set_Previous_Line_Node (To : Project_Node_Id); -- Indicate the node on the previous line. If there are comments -- immediately following this line, then they should be associated with -- this node. procedure Set_Previous_End_Node (To : Project_Node_Id); -- Indicate that on the previous line the "end" belongs to node To. -- If there are comments immediately following this "end" line, they -- should be associated with this node. procedure Set_End_Of_Line (To : Project_Node_Id); -- Indicate the node on the current line. If there is an end of line -- comment, then it should be associated with this node. procedure Set_Next_End_Node (To : Project_Node_Id); -- Put node To on the top of the end node stack. When an END line is found -- with this node on the top of the end node stack, the comments, if any, -- immediately preceding this "end" line will be associated with this node. procedure Remove_Next_End_Node; -- Remove the top of the end node stack ------------------------ -- Comment Processing -- ------------------------ type Comment_Data is record Value : Name_Id := No_Name; Follows_Empty_Line : Boolean := False; Is_Followed_By_Empty_Line : Boolean := False; end record; -- Component type for Comments Table below package Comments is new Table.Table (Table_Component_Type => Comment_Data, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Prj.Tree.Comments"); -- A table to store the comments that may be stored is the tree procedure Scan (In_Tree : Project_Node_Tree_Ref); -- Scan the tokens and accumulate comments type Comment_Location is (Before, After, Before_End, After_End, End_Of_Line); -- Used in call to Add_Comments below procedure Add_Comments (To : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; Where : Comment_Location); -- Add comments to this node ---------------------- -- Access Functions -- ---------------------- -- The following query functions are part of the abstract interface -- of the Project File tree. They provide access to fields of a project. -- The access functions should be called only with valid arguments. -- For each function the condition of validity is specified. If an access -- function is called with invalid arguments, then exception -- Assertion_Error is raised if assertions are enabled, otherwise the -- behaviour is not defined and may result in a crash. function Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id; pragma Inline (Name_Of); -- Valid for all non empty nodes. May return No_Name for nodes that have -- no names. function Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind; pragma Inline (Kind_Of); -- Valid for all non empty nodes function Location_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Source_Ptr; pragma Inline (Location_Of); -- Valid for all non empty nodes function First_Comment_After (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Valid only for N_Comment_Zones nodes function First_Comment_After_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Valid only for N_Comment_Zones nodes function First_Comment_Before (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Valid only for N_Comment_Zones nodes function First_Comment_Before_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Valid only for N_Comment_Zones nodes function Next_Comment (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Valid only for N_Comment nodes function End_Of_Line_Comment (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id; -- Valid only for non empty nodes function Follows_Empty_Line (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean; -- Valid only for N_Comment nodes function Is_Followed_By_Empty_Line (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean; -- Valid only for N_Comment nodes function Parent_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Parent_Project_Of); -- Valid only for N_Project nodes function Project_File_Includes_Unkept_Comments (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean; -- Valid only for N_Project nodes function Directory_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Path_Name_Type; pragma Inline (Directory_Of); -- Returns the directory that contains the project file. This always ends -- with a directory separator. Only valid for N_Project nodes. function Expression_Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Variable_Kind; pragma Inline (Expression_Kind_Of); -- Only valid for N_Literal_String, N_Attribute_Declaration, -- N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression, -- N_Term, N_Variable_Reference, N_Attribute_Reference nodes or -- N_External_Value. function Is_Extending_All (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean; pragma Inline (Is_Extending_All); -- Only valid for N_Project and N_With_Clause function Is_Not_Last_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean; pragma Inline (Is_Not_Last_In_List); -- Only valid for N_With_Clause function First_Variable_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Variable_Node_Id; pragma Inline (First_Variable_Of); -- Only valid for N_Project or N_Package_Declaration nodes function First_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Package_Declaration_Id; pragma Inline (First_Package_Of); -- Only valid for N_Project nodes function Package_Id_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Package_Node_Id; pragma Inline (Package_Id_Of); -- Only valid for N_Package_Declaration nodes function Path_Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Path_Name_Type; pragma Inline (Path_Name_Of); -- Only valid for N_Project and N_With_Clause nodes function String_Value_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id; pragma Inline (String_Value_Of); -- Only valid for N_With_Clause, N_Literal_String nodes or N_Comment. -- For a N_With_Clause created automatically for a virtual extending -- project, No_Name is returned. function Source_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Int; pragma Inline (Source_Index_Of); -- Only valid for N_Literal_String and N_Attribute_Declaration nodes function First_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_With_Clause_Of); -- Only valid for N_Project nodes function Project_Declaration_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Project_Declaration_Of); -- Only valid for N_Project nodes function Project_Qualifier_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Qualifier; pragma Inline (Project_Qualifier_Of); -- Only valid for N_Project nodes function Extending_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Extending_Project_Of); -- Only valid for N_Project_Declaration nodes function First_String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_String_Type_Of); -- Only valid for N_Project nodes function Extended_Project_Path_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Path_Name_Type; pragma Inline (Extended_Project_Path_Of); -- Only valid for N_With_Clause nodes function Project_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Project_Node_Of); -- Only valid for N_With_Clause, N_Variable_Reference and -- N_Attribute_Reference nodes. function Non_Limited_Project_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Non_Limited_Project_Node_Of); -- Only valid for N_With_Clause nodes. Returns Empty_Node for limited -- imported project files, otherwise returns the same result as -- Project_Node_Of. function Next_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_With_Clause_Of); -- Only valid for N_With_Clause nodes function First_Declarative_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_Declarative_Item_Of); -- Only valid for N_Project_Declaration, N_Case_Item and -- N_Package_Declaration. function Extended_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Extended_Project_Of); -- Only valid for N_Project_Declaration nodes function Current_Item_Node (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Current_Item_Node); -- Only valid for N_Declarative_Item nodes function Next_Declarative_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_Declarative_Item); -- Only valid for N_Declarative_Item node function Project_Of_Renamed_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Project_Of_Renamed_Package_Of); -- Only valid for N_Package_Declaration nodes. May return Empty_Node. function Next_Package_In_Project (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_Package_In_Project); -- Only valid for N_Package_Declaration nodes function First_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_Literal_String); -- Only valid for N_String_Type_Declaration nodes function Next_String_Type (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_String_Type); -- Only valid for N_String_Type_Declaration nodes function Next_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_Literal_String); -- Only valid for N_Literal_String nodes function Expression_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Expression_Of); -- Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration -- or N_Variable_Declaration nodes function Associative_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Associative_Project_Of); -- Only valid for N_Attribute_Declaration nodes function Associative_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Associative_Package_Of); -- Only valid for N_Attribute_Declaration nodes function Value_Is_Valid (For_Typed_Variable : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; Value : Name_Id) return Boolean; pragma Inline (Value_Is_Valid); -- Only valid for N_Typed_Variable_Declaration. Returns True if Value is -- in the list of allowed strings for For_Typed_Variable. False otherwise. function Associative_Array_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id; pragma Inline (Associative_Array_Index_Of); -- Only valid for N_Attribute_Declaration and N_Attribute_Reference. -- Returns No_Name for non associative array attributes. function Next_Variable (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_Variable); -- Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration -- nodes. function First_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_Term); -- Only valid for N_Expression nodes function Next_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_Expression_In_List); -- Only valid for N_Expression nodes function Current_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Current_Term); -- Only valid for N_Term nodes function Next_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_Term); -- Only valid for N_Term nodes function First_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_Expression_In_List); -- Only valid for N_Literal_String_List nodes function Package_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Package_Node_Of); -- Only valid for N_Variable_Reference or N_Attribute_Reference nodes. -- May return Empty_Node. function String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (String_Type_Of); -- Only valid for N_Variable_Reference or N_Typed_Variable_Declaration -- nodes. function External_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (External_Reference_Of); -- Only valid for N_External_Value nodes function External_Default_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (External_Default_Of); -- Only valid for N_External_Value nodes function Case_Variable_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Case_Variable_Reference_Of); -- Only valid for N_Case_Construction nodes function First_Case_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_Case_Item_Of); -- Only valid for N_Case_Construction nodes function First_Choice_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (First_Choice_Of); -- Only valid for N_Case_Item nodes. Return the first choice in a -- N_Case_Item, or Empty_Node if this is when others. function Next_Case_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; pragma Inline (Next_Case_Item); -- Only valid for N_Case_Item nodes function Case_Insensitive (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean; -- Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes ----------------------- -- Create procedures -- ----------------------- -- The following procedures are used to edit a project file tree. They are -- slightly higher-level than the Set_* procedures below function Create_Project (In_Tree : Project_Node_Tree_Ref; Name : Name_Id; Full_Path : Path_Name_Type; Is_Config_File : Boolean := False) return Project_Node_Id; -- Create a new node for a project and register it in the tree so that it -- can be retrieved later on. function Create_Package (Tree : Project_Node_Tree_Ref; Project : Project_Node_Id; Pkg : String) return Project_Node_Id; -- Create a new package in Project. If the package already exists, it is -- returned. The name of the package *must* be lower-cases, or none of its -- attributes will be recognized. function Create_Attribute (Tree : Project_Node_Tree_Ref; Prj_Or_Pkg : Project_Node_Id; Name : Name_Id; Index_Name : Name_Id := No_Name; Kind : Variable_Kind := List; At_Index : Integer := 0; Value : Project_Node_Id := Empty_Node) return Project_Node_Id; -- Create a new attribute. The new declaration is added at the end of the -- declarative item list for Prj_Or_Pkg (a project or a package), but -- before any package declaration). No addition is done if Prj_Or_Pkg is -- Empty_Node. If Index_Name is not "", then if creates an attribute value -- for a specific index. At_Index is used for the " at " in the naming -- exceptions. -- -- To set the value of the attribute, either provide a value for Value, or -- use Set_Expression_Of to set the value of the attribute (in which case -- Enclose_In_Expression might be useful). The former is recommended since -- it will more correctly handle cases where the index needs to be set on -- the expression rather than on the index of the attribute (i.e. 'for -- Specification ("unit") use "file" at 3', versus 'for Executable ("file" -- at 3) use "name"'). Value must be a N_String_Literal if an index will be -- added to it. function Create_Literal_String (Str : Namet.Name_Id; Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Create a literal string whose value is Str procedure Add_At_End (Tree : Project_Node_Tree_Ref; Parent : Project_Node_Id; Expr : Project_Node_Id; Add_Before_First_Pkg : Boolean := False; Add_Before_First_Case : Boolean := False); -- Add a new declarative item in the list in Parent. This new declarative -- item will contain Expr (unless Expr is already a declarative item, in -- which case it is added directly to the list). The new item is inserted -- at the end of the list, unless Add_Before_First_Pkg is True. In the -- latter case, it is added just before the first case construction is -- seen, or before the first package (this assumes that all packages are -- found at the end of the project, which isn't true in the general case -- unless you have normalized the project to match this description). function Enclose_In_Expression (Node : Project_Node_Id; Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Enclose the Node inside a N_Expression node, and return this expression. -- This does nothing if Node is already a N_Expression. -------------------- -- Set Procedures -- -------------------- -- The following procedures are part of the abstract interface of the -- Project File tree. -- Foe each Set_* procedure the condition of validity is specified. If an -- access function is called with invalid arguments, then exception -- Assertion_Error is raised if assertions are enabled, otherwise the -- behaviour is not defined and may result in a crash. -- These are very low-level, and manipulate the tree itself directly. You -- should look at the Create_* procedure instead if you want to use higher -- level constructs procedure Set_Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Name_Id); pragma Inline (Set_Name_Of); -- Valid for all non empty nodes. procedure Set_Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Kind); pragma Inline (Set_Kind_Of); -- Valid for all non empty nodes procedure Set_Location_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Source_Ptr); pragma Inline (Set_Location_Of); -- Valid for all non empty nodes procedure Set_First_Comment_After (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Comment_After); -- Valid only for N_Comment_Zones nodes procedure Set_First_Comment_After_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Comment_After_End); -- Valid only for N_Comment_Zones nodes procedure Set_First_Comment_Before (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Comment_Before); -- Valid only for N_Comment_Zones nodes procedure Set_First_Comment_Before_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Comment_Before_End); -- Valid only for N_Comment_Zones nodes procedure Set_Next_Comment (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Comment); -- Valid only for N_Comment nodes procedure Set_Parent_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); -- Valid only for N_Project nodes procedure Set_Project_File_Includes_Unkept_Comments (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Boolean); -- Valid only for N_Project nodes procedure Set_Directory_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Path_Name_Type); pragma Inline (Set_Directory_Of); -- Valid only for N_Project nodes procedure Set_Expression_Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Variable_Kind); pragma Inline (Set_Expression_Kind_Of); -- Only valid for N_Literal_String, N_Attribute_Declaration, -- N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression, -- N_Term, N_Variable_Reference, N_Attribute_Reference or N_External_Value -- nodes. procedure Set_Is_Extending_All (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref); pragma Inline (Set_Is_Extending_All); -- Only valid for N_Project and N_With_Clause procedure Set_Is_Not_Last_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref); pragma Inline (Set_Is_Not_Last_In_List); -- Only valid for N_With_Clause procedure Set_First_Variable_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Variable_Node_Id); pragma Inline (Set_First_Variable_Of); -- Only valid for N_Project or N_Package_Declaration nodes procedure Set_First_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Package_Declaration_Id); pragma Inline (Set_First_Package_Of); -- Only valid for N_Project nodes procedure Set_Package_Id_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Package_Node_Id); pragma Inline (Set_Package_Id_Of); -- Only valid for N_Package_Declaration nodes procedure Set_Path_Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Path_Name_Type); pragma Inline (Set_Path_Name_Of); -- Only valid for N_Project and N_With_Clause nodes procedure Set_String_Value_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Name_Id); pragma Inline (Set_String_Value_Of); -- Only valid for N_With_Clause, N_Literal_String nodes or N_Comment. procedure Set_Source_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Int); pragma Inline (Set_Source_Index_Of); -- Only valid for N_Literal_String and N_Attribute_Declaration nodes. For -- N_Literal_String, set the source index of the literal string. For -- N_Attribute_Declaration, set the source index of the index of the -- associative array element. procedure Set_First_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_With_Clause_Of); -- Only valid for N_Project nodes procedure Set_Project_Declaration_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Project_Declaration_Of); -- Only valid for N_Project nodes procedure Set_Project_Qualifier_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Qualifier); pragma Inline (Set_Project_Qualifier_Of); -- Only valid for N_Project nodes procedure Set_Extending_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Extending_Project_Of); -- Only valid for N_Project_Declaration nodes procedure Set_First_String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_String_Type_Of); -- Only valid for N_Project nodes procedure Set_Extended_Project_Path_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Path_Name_Type); pragma Inline (Set_Extended_Project_Path_Of); -- Only valid for N_With_Clause nodes procedure Set_Project_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id; Limited_With : Boolean := False); pragma Inline (Set_Project_Node_Of); -- Only valid for N_With_Clause, N_Variable_Reference and -- N_Attribute_Reference nodes. procedure Set_Next_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_With_Clause_Of); -- Only valid for N_With_Clause nodes procedure Set_First_Declarative_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Declarative_Item_Of); -- Only valid for N_Project_Declaration, N_Case_Item and -- N_Package_Declaration. procedure Set_Extended_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Extended_Project_Of); -- Only valid for N_Project_Declaration nodes procedure Set_Current_Item_Node (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Current_Item_Node); -- Only valid for N_Declarative_Item nodes procedure Set_Next_Declarative_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Declarative_Item); -- Only valid for N_Declarative_Item node procedure Set_Project_Of_Renamed_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Project_Of_Renamed_Package_Of); -- Only valid for N_Package_Declaration nodes. procedure Set_Next_Package_In_Project (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Package_In_Project); -- Only valid for N_Package_Declaration nodes procedure Set_First_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Literal_String); -- Only valid for N_String_Type_Declaration nodes procedure Set_Next_String_Type (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_String_Type); -- Only valid for N_String_Type_Declaration nodes procedure Set_Next_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Literal_String); -- Only valid for N_Literal_String nodes procedure Set_Expression_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Expression_Of); -- Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration -- or N_Variable_Declaration nodes procedure Set_Associative_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Associative_Project_Of); -- Only valid for N_Attribute_Declaration nodes procedure Set_Associative_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Associative_Package_Of); -- Only valid for N_Attribute_Declaration nodes procedure Set_Associative_Array_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Name_Id); pragma Inline (Set_Associative_Array_Index_Of); -- Only valid for N_Attribute_Declaration and N_Attribute_Reference. procedure Set_Next_Variable (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Variable); -- Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration -- nodes. procedure Set_First_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Term); -- Only valid for N_Expression nodes procedure Set_Next_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Expression_In_List); -- Only valid for N_Expression nodes procedure Set_Current_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Current_Term); -- Only valid for N_Term nodes procedure Set_Next_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Term); -- Only valid for N_Term nodes procedure Set_First_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Expression_In_List); -- Only valid for N_Literal_String_List nodes procedure Set_Package_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Package_Node_Of); -- Only valid for N_Variable_Reference or N_Attribute_Reference nodes. procedure Set_String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_String_Type_Of); -- Only valid for N_Variable_Reference or N_Typed_Variable_Declaration -- nodes. procedure Set_External_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_External_Reference_Of); -- Only valid for N_External_Value nodes procedure Set_External_Default_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_External_Default_Of); -- Only valid for N_External_Value nodes procedure Set_Case_Variable_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Case_Variable_Reference_Of); -- Only valid for N_Case_Construction nodes procedure Set_First_Case_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Case_Item_Of); -- Only valid for N_Case_Construction nodes procedure Set_First_Choice_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_First_Choice_Of); -- Only valid for N_Case_Item nodes. procedure Set_Next_Case_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id); pragma Inline (Set_Next_Case_Item); -- Only valid for N_Case_Item nodes. procedure Set_Case_Insensitive (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Boolean); -- Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes ------------------------------- -- Restricted Access Section -- ------------------------------- package Tree_Private_Part is -- This is conceptually in the private part. However, for efficiency, -- some packages are accessing it directly. type Project_Node_Record is record Kind : Project_Node_Kind; Qualifier : Project_Qualifier := Unspecified; Location : Source_Ptr := No_Location; Directory : Path_Name_Type := No_Path; -- Only for N_Project Expr_Kind : Variable_Kind := Undefined; -- See below for what Project_Node_Kind it is used Variables : Variable_Node_Id := Empty_Node; -- First variable in a project or a package Packages : Package_Declaration_Id := Empty_Node; -- First package declaration in a project Pkg_Id : Package_Node_Id := Empty_Package; -- Only used for N_Package_Declaration -- -- The component Pkg_Id is an entry into the table Package_Attributes -- (in Prj.Attr). It is used to indicate all the attributes of the -- package with their characteristics. -- -- The tables Prj.Attr.Attributes and Prj.Attr.Package_Attributes -- are built once and for all through a call (from Prj.Initialize) -- to procedure Prj.Attr.Initialize. It is never modified after that. Name : Name_Id := No_Name; -- See below for what Project_Node_Kind it is used Src_Index : Int := 0; -- Index of a unit in a multi-unit source. -- Only for some N_Attribute_Declaration and N_Literal_String. Path_Name : Path_Name_Type := No_Path; -- See below for what Project_Node_Kind it is used Value : Name_Id := No_Name; -- See below for what Project_Node_Kind it is used Field1 : Project_Node_Id := Empty_Node; -- See below the meaning for each Project_Node_Kind Field2 : Project_Node_Id := Empty_Node; -- See below the meaning for each Project_Node_Kind Field3 : Project_Node_Id := Empty_Node; -- See below the meaning for each Project_Node_Kind Field4 : Project_Node_Id := Empty_Node; -- See below the meaning for each Project_Node_Kind Flag1 : Boolean := False; -- This flag is significant only for: -- -- N_Attribute_Declaration and N_Attribute_Reference -- Indicates for an associative array attribute, that the -- index is case insensitive. -- -- N_Comment -- Indicates that the comment is preceded by an empty line. -- -- N_Project -- Indicates that there are comments in the project source that -- cannot be kept in the tree. -- -- N_Project_Declaration -- Indicates that there are unkept comments in the project. -- -- N_With_Clause -- Indicates that this is not the last with in a with clause. -- Set for "A", but not for "B" in with "B"; and with "A", "B"; Flag2 : Boolean := False; -- This flag is significant only for: -- -- N_Project -- Indicates that the project "extends all" another project. -- -- N_Comment -- Indicates that the comment is followed by an empty line. -- -- N_With_Clause -- Indicates that the originally imported project is an extending -- all project. Comments : Project_Node_Id := Empty_Node; -- For nodes other that N_Comment_Zones or N_Comment, designates the -- comment zones associated with the node. -- -- For N_Comment_Zones, designates the comment after the "end" of -- the construct. -- -- For N_Comment, designates the next comment, if any. end record; -- type Project_Node_Kind is -- (N_Project, -- -- Name: project name -- -- Path_Name: project path name -- -- Expr_Kind: Undefined -- -- Field1: first with clause -- -- Field2: project declaration -- -- Field3: first string type -- -- Field4: parent project, if any -- -- Value: extended project path name (if any) -- N_With_Clause, -- -- Name: imported project name -- -- Path_Name: imported project path name -- -- Expr_Kind: Undefined -- -- Field1: project node -- -- Field2: next with clause -- -- Field3: project node or empty if "limited with" -- -- Field4: not used -- -- Value: literal string withed -- N_Project_Declaration, -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: Undefined -- -- Field1: first declarative item -- -- Field2: extended project -- -- Field3: extending project -- -- Field4: not used -- -- Value: not used -- N_Declarative_Item, -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: Undefined -- -- Field1: current item node -- -- Field2: next declarative item -- -- Field3: not used -- -- Field4: not used -- -- Value: not used -- N_Package_Declaration, -- -- Name: package name -- -- Path_Name: not used -- -- Expr_Kind: Undefined -- -- Field1: project of renamed package (if any) -- -- Field2: first declarative item -- -- Field3: next package in project -- -- Field4: not used -- -- Value: not used -- N_String_Type_Declaration, -- -- Name: type name -- -- Path_Name: not used -- -- Expr_Kind: Undefined -- -- Field1: first literal string -- -- Field2: next string type -- -- Field3: not used -- -- Field4: not used -- -- Value: not used -- N_Literal_String, -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: Single -- -- Field1: next literal string -- -- Field2: not used -- -- Field3: not used -- -- Field4: not used -- -- Value: string value -- N_Attribute_Declaration, -- -- Name: attribute name -- -- Path_Name: not used -- -- Expr_Kind: attribute kind -- -- Field1: expression -- -- Field2: project of full associative array -- -- Field3: package of full associative array -- -- Field4: not used -- -- Value: associative array index -- -- (if an associative array element) -- N_Typed_Variable_Declaration, -- -- Name: variable name -- -- Path_Name: not used -- -- Expr_Kind: Single -- -- Field1: expression -- -- Field2: type of variable (N_String_Type_Declaration) -- -- Field3: next variable -- -- Field4: not used -- -- Value: not used -- N_Variable_Declaration, -- -- Name: variable name -- -- Path_Name: not used -- -- Expr_Kind: variable kind -- -- Field1: expression -- -- Field2: not used -- -- Field3 is used for next variable, instead of Field2, -- -- so that it is the same field for -- -- N_Variable_Declaration and -- -- N_Typed_Variable_Declaration -- -- Field3: next variable -- -- Field4: not used -- -- Value: not used -- N_Expression, -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: expression kind -- -- Field1: first term -- -- Field2: next expression in list -- -- Field3: not used -- -- Value: not used -- N_Term, -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: term kind -- -- Field1: current term -- -- Field2: next term in the expression -- -- Field3: not used -- -- Field4: not used -- -- Value: not used -- N_Literal_String_List, -- -- Designates a list of string expressions between brackets -- -- separated by commas. The string expressions are not necessarily -- -- literal strings. -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: List -- -- Field1: first expression -- -- Field2: not used -- -- Field3: not used -- -- Field4: not used -- -- Value: not used -- N_Variable_Reference, -- -- Name: variable name -- -- Path_Name: not used -- -- Expr_Kind: variable kind -- -- Field1: project (if specified) -- -- Field2: package (if specified) -- -- Field3: type of variable (N_String_Type_Declaration), if any -- -- Field4: not used -- -- Value: not used -- N_External_Value, -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: Single -- -- Field1: Name of the external reference (literal string) -- -- Field2: Default (literal string) -- -- Field3: not used -- -- Value: not used -- N_Attribute_Reference, -- -- Name: attribute name -- -- Path_Name: not used -- -- Expr_Kind: attribute kind -- -- Field1: project -- -- Field2: package (if attribute of a package) -- -- Field3: not used -- -- Field4: not used -- -- Value: associative array index -- -- (if an associative array element) -- N_Case_Construction, -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: Undefined -- -- Field1: case variable reference -- -- Field2: first case item -- -- Field3: not used -- -- Field4: not used -- -- Value: not used -- N_Case_Item -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: not used -- -- Field1: first choice (literal string), or Empty_Node -- -- for when others -- -- Field2: first declarative item -- -- Field3: next case item -- -- Field4: not used -- -- Value: not used -- N_Comment_zones -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: not used -- -- Field1: comment before the construct -- -- Field2: comment after the construct -- -- Field3: comment before the "end" of the construct -- -- Value: end of line comment -- -- Field4: not used -- -- Comments: comment after the "end" of the construct -- N_Comment -- -- Name: not used -- -- Path_Name: not used -- -- Expr_Kind: not used -- -- Field1: not used -- -- Field2: not used -- -- Field3: not used -- -- Field4: not used -- -- Value: comment -- -- Flag1: comment is preceded by an empty line -- -- Flag2: comment is followed by an empty line -- -- Comments: next comment package Project_Node_Table is new GNAT.Dynamic_Tables (Table_Component_Type => Project_Node_Record, Table_Index_Type => Project_Node_Id, Table_Low_Bound => First_Node_Id, Table_Initial => Project_Nodes_Initial, Table_Increment => Project_Nodes_Increment); -- Table contains the syntactic tree of project data from project files type Project_Name_And_Node is record Name : Name_Id; -- Name of the project Display_Name : Name_Id; -- The name of the project as it appears in the .gpr file Node : Project_Node_Id; -- Node of the project in table Project_Nodes Resolved_Path : Path_Name_Type; -- Resolved and canonical path of a real project file. -- No_Name in case of virtual projects. Extended : Boolean; -- True when the project is being extended by another project From_Extended : Boolean; -- True when the project is only imported by projects that are -- extended. Proj_Qualifier : Project_Qualifier; -- The project qualifier of the project, if any end record; No_Project_Name_And_Node : constant Project_Name_And_Node := (Name => No_Name, Display_Name => No_Name, Node => Empty_Node, Resolved_Path => No_Path, Extended => True, From_Extended => False, Proj_Qualifier => Unspecified); package Projects_Htable is new GNAT.Dynamic_HTables.Simple_HTable (Header_Num => Header_Num, Element => Project_Name_And_Node, No_Element => No_Project_Name_And_Node, Key => Name_Id, Hash => Hash, Equal => "="); -- This hash table contains a mapping of project names to project nodes. -- Note that this hash table contains only the nodes whose Kind is -- N_Project. It is used to find the node of a project from its name, -- and to verify if a project has already been parsed, knowing its name. end Tree_Private_Part; type Project_Node_Tree_Data is record Project_Nodes : Tree_Private_Part.Project_Node_Table.Instance; Projects_HT : Tree_Private_Part.Projects_Htable.Instance; Incomplete_With : Boolean := False; -- Set to True if the projects were loaded with the flag -- Ignore_Missing_With set to True, and there were indeed some with -- statements that could not be resolved end record; procedure Free (Proj : in out Project_Node_Tree_Ref); -- Free memory used by Prj private type Comment_Array is array (Positive range <>) of Comment_Data; type Comments_Ptr is access Comment_Array; type Comment_State is record End_Of_Line_Node : Project_Node_Id := Empty_Node; Previous_Line_Node : Project_Node_Id := Empty_Node; Previous_End_Node : Project_Node_Id := Empty_Node; Unkept_Comments : Boolean := False; Comments : Comments_Ptr := null; end record; end Prj.Tree; gprbuild-gpl-2014-src/gnat/tempdir.adb0000644000076700001450000001230012323721731017174 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- T E M P D I R -- -- -- -- B o d y -- -- -- -- Copyright (C) 2003-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with GNAT.Directory_Operations; use GNAT.Directory_Operations; with Hostparm; use Hostparm; with Opt; use Opt; with Output; use Output; package body Tempdir is Tmpdir_Needs_To_Be_Displayed : Boolean := True; Tmpdir : constant String := "TMPDIR"; Gnutmpdir : constant String := "GNUTMPDIR"; Temp_Dir : String_Access := new String'(""); ---------------------- -- Create_Temp_File -- ---------------------- procedure Create_Temp_File (FD : out File_Descriptor; Name : out Path_Name_Type) is File_Name : String_Access; Current_Dir : constant String := Get_Current_Dir; function Directory return String; -- Returns Temp_Dir.all if not empty, else return current directory --------------- -- Directory -- --------------- function Directory return String is begin if Temp_Dir'Length /= 0 then return Temp_Dir.all; else return Current_Dir; end if; end Directory; -- Start of processing Tempdir begin if Temp_Dir'Length /= 0 then -- In verbose mode, display once the value of TMPDIR, so that -- if temp files cannot be created, it is easier to understand -- where temp files are supposed to be created. if Verbose_Mode and then Tmpdir_Needs_To_Be_Displayed then Write_Str ("TMPDIR = """); Write_Str (Temp_Dir.all); Write_Line (""""); Tmpdir_Needs_To_Be_Displayed := False; end if; -- Change directory to TMPDIR before creating the temp file, -- then change back immediately to the previous directory. Change_Dir (Temp_Dir.all); Create_Temp_File (FD, File_Name); Change_Dir (Current_Dir); else Create_Temp_File (FD, File_Name); end if; if FD = Invalid_FD then Write_Line ("could not create temporary file in " & Directory); Name := No_Path; else declare Path_Name : constant String := Normalize_Pathname (Directory & Directory_Separator & File_Name.all); begin Name_Len := Path_Name'Length; Name_Buffer (1 .. Name_Len) := Path_Name; Name := Name_Find; Free (File_Name); end; end if; end Create_Temp_File; ------------------ -- Use_Temp_Dir -- ------------------ procedure Use_Temp_Dir (Status : Boolean) is Dir : String_Access; begin if Status then -- On VMS, if GNUTMPDIR is defined, use it if OpenVMS then Dir := Getenv (Gnutmpdir); -- Otherwise, if GNUTMPDIR is not defined, try TMPDIR if Dir'Length = 0 then Dir := Getenv (Tmpdir); end if; else Dir := Getenv (Tmpdir); end if; end if; Free (Temp_Dir); if Dir /= null and then Dir'Length > 0 and then Is_Absolute_Path (Dir.all) and then Is_Directory (Dir.all) then Temp_Dir := new String'(Normalize_Pathname (Dir.all)); else Temp_Dir := new String'(""); end if; Free (Dir); end Use_Temp_Dir; -- Start of elaboration for package Tempdir begin Use_Temp_Dir (Status => True); end Tempdir; gprbuild-gpl-2014-src/gnat/mlib-tgt-specific.ads0000644000076700001450000000435312323721731021064 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- M L I B . T G T . S P E C I F I C -- -- -- -- S p e c -- -- -- -- Copyright (C) 2007, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This child package of package MLib.Tgt has no interface. -- For each platform, there is a specific body that defines the subprogram -- that are different from the default defined in the body of MLib.Tgt, -- and modify the corresponding access to subprogram value in the private -- part of MLib.Tgt. package MLib.Tgt.Specific is pragma Elaborate_Body; end MLib.Tgt.Specific; gprbuild-gpl-2014-src/gnat/mlib-utl.adb0000644000076700001450000004763212323721731017275 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- M L I B . U T L -- -- -- -- B o d y -- -- -- -- Copyright (C) 2002-2013, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with MLib.Fil; use MLib.Fil; with MLib.Tgt; use MLib.Tgt; with Opt; with Osint; with Output; use Output; with Interfaces.C.Strings; use Interfaces.C.Strings; package body MLib.Utl is Adalib_Path : String_Access := null; -- Path of the GNAT adalib directory, specified in procedure -- Specify_Adalib_Dir. Used in function Lib_Directory. Gcc_Name : String_Access; -- Default value of the "gcc" executable used in procedure Gcc Gcc_Exec : String_Access; -- The full path name of the "gcc" executable Ar_Name : String_Access; -- The name of the archive builder for the platform, set when procedure Ar -- is called for the first time. Ar_Exec : String_Access; -- The full path name of the archive builder Ar_Options : String_List_Access; -- The minimum options used when invoking the archive builder Ar_Append_Options : String_List_Access; -- The options to be used when invoking the archive builder to add chunks -- of object files, when building the archive in chunks. Opt_Length : Natural := 0; -- The max number of options for the Archive_Builder Initial_Size : Natural := 0; -- The minimum number of bytes for the invocation of the Archive Builder -- (without name of the archive or object files). Ranlib_Name : String_Access; -- The name of the archive indexer for the platform, if there is one Ranlib_Exec : String_Access := null; -- The full path name of the archive indexer Ranlib_Options : String_List_Access := null; -- The options to be used when invoking the archive indexer, if any -------- -- Ar -- -------- procedure Ar (Output_File : String; Objects : Argument_List) is Full_Output_File : constant String := Ext_To (Output_File, Archive_Ext); Arguments : Argument_List_Access; Last_Arg : Natural := 0; Success : Boolean; Line_Length : Natural := 0; Maximum_Size : Integer; pragma Import (C, Maximum_Size, "__gnat_link_max"); -- Maximum number of bytes to put in an invocation of the -- Archive_Builder. Size : Integer; -- The number of bytes for the invocation of the archive builder Current_Object : Natural; procedure Display; -- Display an invocation of the Archive Builder ------------- -- Display -- ------------- procedure Display is begin if not Opt.Quiet_Output then Write_Str (Ar_Name.all); Line_Length := Ar_Name'Length; for J in 1 .. Last_Arg loop -- Make sure the Output buffer does not overflow if Line_Length + 1 + Arguments (J)'Length > Buffer_Max then Write_Eol; Line_Length := 0; end if; Write_Char (' '); -- Only output the first object files when not in verbose mode if (not Opt.Verbose_Mode) and then J = Opt_Length + 3 then Write_Str ("..."); exit; end if; Write_Str (Arguments (J).all); Line_Length := Line_Length + 1 + Arguments (J)'Length; end loop; Write_Eol; end if; end Display; begin if Ar_Exec = null then Ar_Name := Osint.Program_Name (Archive_Builder, "gnatmake"); Ar_Exec := Locate_Exec_On_Path (Ar_Name.all); if Ar_Exec = null then Free (Ar_Name); Ar_Name := new String'(Archive_Builder); Ar_Exec := Locate_Exec_On_Path (Ar_Name.all); end if; if Ar_Exec = null then Fail (Ar_Name.all & " not found in path"); elsif Opt.Verbose_Mode then Write_Str ("found "); Write_Line (Ar_Exec.all); end if; Ar_Options := Archive_Builder_Options; Initial_Size := 0; for J in Ar_Options'Range loop Initial_Size := Initial_Size + Ar_Options (J)'Length + 1; end loop; Ar_Append_Options := Archive_Builder_Append_Options; Opt_Length := Ar_Options'Length; if Ar_Append_Options /= null then Opt_Length := Natural'Max (Ar_Append_Options'Length, Opt_Length); Size := 0; for J in Ar_Append_Options'Range loop Size := Size + Ar_Append_Options (J)'Length + 1; end loop; Initial_Size := Integer'Max (Initial_Size, Size); end if; -- ranlib Ranlib_Name := Osint.Program_Name (Archive_Indexer, "gnatmake"); if Ranlib_Name'Length > 0 then Ranlib_Exec := Locate_Exec_On_Path (Ranlib_Name.all); if Ranlib_Exec = null then Free (Ranlib_Name); Ranlib_Name := new String'(Archive_Indexer); Ranlib_Exec := Locate_Exec_On_Path (Ranlib_Name.all); end if; if Ranlib_Exec /= null and then Opt.Verbose_Mode then Write_Str ("found "); Write_Line (Ranlib_Exec.all); end if; end if; Ranlib_Options := Archive_Indexer_Options; end if; Arguments := new String_List (1 .. 1 + Opt_Length + Objects'Length); Arguments (1 .. Ar_Options'Length) := Ar_Options.all; -- "ar cr ..." Arguments (Ar_Options'Length + 1) := new String'(Full_Output_File); Delete_File (Full_Output_File); Size := Initial_Size + Full_Output_File'Length + 1; -- Check the full size of a call of the archive builder with all the -- object files. for J in Objects'Range loop Size := Size + Objects (J)'Length + 1; end loop; -- If the size is not too large or if it is not possible to build the -- archive in chunks, build the archive in a single invocation. if Size <= Maximum_Size or else Ar_Append_Options = null then Last_Arg := Ar_Options'Length + 1 + Objects'Length; Arguments (Ar_Options'Length + 2 .. Last_Arg) := Objects; Display; Spawn (Ar_Exec.all, Arguments (1 .. Last_Arg), Success); else -- Build the archive in several invocation, making sure to not -- go over the maximum size for each invocation. Last_Arg := Ar_Options'Length + 1; Current_Object := Objects'First; Size := Initial_Size + Full_Output_File'Length + 1; -- First invocation while Current_Object <= Objects'Last loop Size := Size + Objects (Current_Object)'Length + 1; exit when Size > Maximum_Size; Last_Arg := Last_Arg + 1; Arguments (Last_Arg) := Objects (Current_Object); Current_Object := Current_Object + 1; end loop; Display; Spawn (Ar_Exec.all, Arguments (1 .. Last_Arg), Success); Arguments (1 .. Ar_Append_Options'Length) := Ar_Append_Options.all; Arguments (Ar_Append_Options'Length + 1) := new String'(Full_Output_File); -- Appending invocation(s) Big_Loop : while Success and then Current_Object <= Objects'Last loop Last_Arg := Ar_Append_Options'Length + 1; Size := Initial_Size + Full_Output_File'Length + 1; Inner_Loop : while Current_Object <= Objects'Last loop Size := Size + Objects (Current_Object)'Length + 1; exit Inner_Loop when Size > Maximum_Size; Last_Arg := Last_Arg + 1; Arguments (Last_Arg) := Objects (Current_Object); Current_Object := Current_Object + 1; end loop Inner_Loop; Display; Spawn (Ar_Exec.all, Arguments (1 .. Last_Arg), Success); end loop Big_Loop; end if; if not Success then Fail (Ar_Name.all & " execution error."); end if; -- If we have found ranlib, run it over the library if Ranlib_Exec /= null then if not Opt.Quiet_Output then Write_Str (Ranlib_Name.all); Write_Char (' '); Write_Line (Arguments (Ar_Options'Length + 1).all); end if; Spawn (Ranlib_Exec.all, Ranlib_Options.all & (Arguments (Ar_Options'Length + 1)), Success); if not Success then Fail (Ranlib_Name.all & " execution error."); end if; end if; end Ar; ----------------- -- Delete_File -- ----------------- procedure Delete_File (Filename : String) is File : constant String := Filename & ASCII.NUL; Success : Boolean; begin Delete_File (File'Address, Success); if Opt.Verbose_Mode then if Success then Write_Str ("deleted "); else Write_Str ("could not delete "); end if; Write_Line (Filename); end if; end Delete_File; --------- -- Gcc -- --------- procedure Gcc (Output_File : String; Objects : Argument_List; Options : Argument_List; Options_2 : Argument_List; Driver_Name : Name_Id := No_Name) is Link_Bytes : Integer := 0; -- Projected number of bytes for the linker command line Link_Max : Integer; pragma Import (C, Link_Max, "__gnat_link_max"); -- Maximum number of bytes on the command line supported by the OS -- linker. Passed this limit the response file mechanism must be used -- if supported. Object_List_File_Supported : Boolean; for Object_List_File_Supported'Size use Character'Size; pragma Import (C, Object_List_File_Supported, "__gnat_objlist_file_supported"); -- Predicate indicating whether the linker has an option whereby the -- names of object files can be passed to the linker in a file. Object_File_Option_Ptr : Interfaces.C.Strings.chars_ptr; pragma Import (C, Object_File_Option_Ptr, "__gnat_object_file_option"); -- Pointer to a string representing the linker option which specifies -- the response file. Object_File_Option : constant String := Value (Object_File_Option_Ptr); -- The linker option which specifies the response file as a string Using_GNU_response_file : constant Boolean := Object_File_Option'Length > 0 and then Object_File_Option (Object_File_Option'Last) = '@'; -- Whether a GNU response file is used Tname : String_Access; Tname_FD : File_Descriptor := Invalid_FD; -- Temporary file used by linker to pass list of object files on -- certain systems with limitations on size of arguments. Closing_Status : Boolean; -- For call to Close Arguments : Argument_List (1 .. 7 + Objects'Length + Options'Length + Options_2'Length); A : Natural := 0; Success : Boolean; Out_Opt : constant String_Access := new String'("-o"); Out_V : constant String_Access := new String'(Output_File); Lib_Dir : constant String_Access := new String'("-L" & Lib_Directory); Lib_Opt : constant String_Access := new String'(Dynamic_Option); Driver : String_Access; type Object_Position is (First, Second, Last); Position : Object_Position; procedure Write_RF (S : String); -- Write a string to the response file and check if it was successful. -- Fail the program if it was not successful (disk full). -------------- -- Write_RF -- -------------- procedure Write_RF (S : String) is Success : Boolean := True; Back_Slash : constant Character := '\'; begin -- If a GNU response file is used, space and backslash need to be -- escaped because they are interpreted as a string separator and -- an escape character respectively by the underlying mechanism. -- On the other hand, quote and double-quote are not escaped since -- they are interpreted as string delimiters on both sides. if Using_GNU_response_file then for J in S'Range loop if S (J) = ' ' or else S (J) = '\' then if Write (Tname_FD, Back_Slash'Address, 1) /= 1 then Success := False; end if; end if; if Write (Tname_FD, S (J)'Address, 1) /= 1 then Success := False; end if; end loop; else if Write (Tname_FD, S'Address, S'Length) /= S'Length then Success := False; end if; end if; if Write (Tname_FD, ASCII.LF'Address, 1) /= 1 then Success := False; end if; if not Success then Fail ("cannot generate response file to link library: disk full"); end if; end Write_RF; -- Start of processing for Gcc begin if Driver_Name = No_Name then if Gcc_Exec = null then if Gcc_Name = null then Gcc_Name := Osint.Program_Name ("gcc", "gnatmake"); end if; Gcc_Exec := Locate_Exec_On_Path (Gcc_Name.all); if Gcc_Exec = null then Fail (Gcc_Name.all & " not found in path"); end if; end if; Driver := Gcc_Exec; else Driver := Locate_Exec_On_Path (Get_Name_String (Driver_Name)); if Driver = null then Fail (Get_Name_String (Driver_Name) & " not found in path"); end if; end if; Link_Bytes := 0; if Lib_Opt'Length /= 0 then A := A + 1; Arguments (A) := Lib_Opt; Link_Bytes := Link_Bytes + Lib_Opt'Length + 1; end if; A := A + 1; Arguments (A) := Out_Opt; Link_Bytes := Link_Bytes + Out_Opt'Length + 1; A := A + 1; Arguments (A) := Out_V; Link_Bytes := Link_Bytes + Out_V'Length + 1; A := A + 1; Arguments (A) := Lib_Dir; Link_Bytes := Link_Bytes + Lib_Dir'Length + 1; A := A + Options'Length; Arguments (A - Options'Length + 1 .. A) := Options; for J in Options'Range loop Link_Bytes := Link_Bytes + Options (J)'Length + 1; end loop; if not Opt.Quiet_Output then if Opt.Verbose_Mode then Write_Str (Driver.all); elsif Driver_Name /= No_Name then Write_Str (Get_Name_String (Driver_Name)); else Write_Str (Gcc_Name.all); end if; for J in 1 .. A loop if Opt.Verbose_Mode or else J < 4 then Write_Char (' '); Write_Str (Arguments (J).all); else Write_Str (" ..."); exit; end if; end loop; -- Do not display all the object files if not in verbose mode, only -- the first one. Position := First; for J in Objects'Range loop if Opt.Verbose_Mode or else Position = First then Write_Char (' '); Write_Str (Objects (J).all); Position := Second; elsif Position = Second then Write_Str (" ..."); Position := Last; exit; end if; end loop; for J in Options_2'Range loop if not Opt.Verbose_Mode then if Position = Second then Write_Str (" ..."); end if; exit; end if; Write_Char (' '); Write_Str (Options_2 (J).all); end loop; Write_Eol; end if; for J in Objects'Range loop Link_Bytes := Link_Bytes + Objects (J)'Length + 1; end loop; for J in Options_2'Range loop Link_Bytes := Link_Bytes + Options_2 (J)'Length + 1; end loop; if Object_List_File_Supported and then Link_Bytes > Link_Max then -- Create a temporary file containing the object files, one object -- file per line for maximal compatibility with linkers supporting -- this option. Create_Temp_File (Tname_FD, Tname); for J in Objects'Range loop Write_RF (Objects (J).all); end loop; Close (Tname_FD, Closing_Status); if not Closing_Status then Fail ("cannot generate response file to link library: disk full"); end if; A := A + 1; Arguments (A) := new String'(Object_File_Option & Tname.all); else A := A + Objects'Length; Arguments (A - Objects'Length + 1 .. A) := Objects; end if; A := A + Options_2'Length; Arguments (A - Options_2'Length + 1 .. A) := Options_2; Spawn (Driver.all, Arguments (1 .. A), Success); if Success then -- Delete the temporary file used in conjunction with linking -- if one was created. if Tname_FD /= Invalid_FD then Delete_File (Tname.all); end if; else if Driver_Name = No_Name then Fail (Gcc_Name.all & " execution error"); else Fail (Get_Name_String (Driver_Name) & " execution error"); end if; end if; end Gcc; ------------------- -- Lib_Directory -- ------------------- function Lib_Directory return String is Libgnat : constant String := Tgt.Libgnat; begin -- If procedure Specify_Adalib_Dir has been called, used the specified -- value. if Adalib_Path /= null then return Adalib_Path.all; end if; Name_Len := Libgnat'Length; Name_Buffer (1 .. Name_Len) := Libgnat; Get_Name_String (Osint.Find_File (Name_Enter, Osint.Library)); -- Remove libgnat.a return Name_Buffer (1 .. Name_Len - Libgnat'Length); end Lib_Directory; ------------------------ -- Specify_Adalib_Dir -- ------------------------ procedure Specify_Adalib_Dir (Path : String) is begin if Path'Length = 0 then Adalib_Path := null; else Adalib_Path := new String'(Path); end if; end Specify_Adalib_Dir; end MLib.Utl; gprbuild-gpl-2014-src/gnat/prj-err.ads0000644000076700001450000001100712323721731017135 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . E R R -- -- -- -- S p e c -- -- -- -- Copyright (C) 2002-2010, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains the routines to output error messages and the scanner -- for the project files. It replaces Errout and Scn. It is not dependent on -- the GNAT tree packages (Atree, Sinfo, ...). It uses exactly the same global -- variables as Errout, located in package Err_Vars. Like Errout, it also uses -- the common variables and routines in package Erroutc. -- -- Parameters are set through Err_Vars.Error_Msg_File_* or -- Err_Vars.Error_Msg_Name_*, and replaced automatically in the messages -- ("{{" for files, "%%" for names). -- -- However, in this package you can configure the error messages to be sent -- to your own callback by setting Report_Error in the flags. This ensures -- that applications can control where error messages are displayed. with Scng; with Errutil; package Prj.Err is --------------------------------------------------------- -- Error Message Text and Message Insertion Characters -- --------------------------------------------------------- -- See errutil.ads ----------------------------------------------------- -- Format of Messages and Manual Quotation Control -- ----------------------------------------------------- -- See errutil.ads ------------------------------ -- Error Output Subprograms -- ------------------------------ procedure Initialize renames Errutil.Initialize; -- Initializes for output of error messages. Must be called for each -- file before using any of the other routines in the package. procedure Finalize (Source_Type : String := "project") renames Errutil.Finalize; -- Finalize processing of error messages for one file and output message -- indicating the number of detected errors. procedure Error_Msg (Flags : Processing_Flags; Msg : String; Location : Source_Ptr := No_Location; Project : Project_Id := null); -- Output an error message, either through Flags.Error_Report or through -- Errutil. The location defaults to the project's location ("project" -- in the source code). If Msg starts with "?", this is a warning, and -- Warning: is added at the beginning. If Msg starts with "<", see comment -- for Err_Vars.Error_Msg_Warn. ------------- -- Scanner -- ------------- procedure Post_Scan; -- Convert an Ada operator symbol into a standard string package Scanner is new Scng (Post_Scan => Post_Scan, Error_Msg => Errutil.Error_Msg, Error_Msg_S => Errutil.Error_Msg_S, Error_Msg_SC => Errutil.Error_Msg_SC, Error_Msg_SP => Errutil.Error_Msg_SP, Style => Errutil.Style); -- Instantiation of the generic scanner end Prj.Err; gprbuild-gpl-2014-src/gnat/prj-dect.ads0000644000076700001450000000625612323721731017276 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . D E C T -- -- -- -- S p e c -- -- -- -- Copyright (C) 2001-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- Parse a list of declarative items in a project file with Prj.Tree; private package Prj.Dect is procedure Parse (In_Tree : Prj.Tree.Project_Node_Tree_Ref; Declarations : out Prj.Tree.Project_Node_Id; Current_Project : Prj.Tree.Project_Node_Id; Extends : Prj.Tree.Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags); -- Parse project declarative items -- -- In_Tree is the project node tree -- -- Declarations is the resulting project node -- -- Current_Project is the project node of the project for which the -- declarative items are parsed. -- -- Extends is the project node of the project that project Current_Project -- extends. If project Current-Project does not extend any project, -- Extends has the value Empty_Node. -- -- Packages_To_Check is the list of packages that needs to be checked. -- For legal packages declared in project Current_Project that are not in -- Packages_To_Check, only the syntax of the declarations are checked, not -- the attribute names and kinds. -- -- Is_Config_File should be set to True if the project represents a config -- file (.cgpr) since some specific checks apply. end Prj.Dect; gprbuild-gpl-2014-src/gnat/opt.ads0000644000076700001450000027623712323721731016400 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- O P T -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains global flags set by the initialization routine from -- the command line and referenced throughout the compiler, the binder, or -- other GNAT tools. The comments indicate which options are used by which -- programs (GNAT, GNATBIND, GNATLINK, GNATMAKE, GPRMAKE, etc). -- Some flags are labelled "PROJECT MANAGER". These are used by tools that -- use the Project Manager. These tools include gnatmake, gnatname, the gnat -- driver, gnatclean, gprbuild and gprclean. with Hostparm; use Hostparm; with Types; use Types; pragma Warnings (Off); -- This package is used also by gnatcoll with System.Strings; use System.Strings; with System.WCh_Con; use System.WCh_Con; pragma Warnings (On); package Opt is ---------------------- -- Checksum Control -- ---------------------- -- Checksums are computed for sources to check for sources being the same -- from a compilation point of view (e.g. spelling of identifiers and -- white space layout do not count in this computation). -- The way the checksum is computed has evolved across the various versions -- of GNAT. When gprbuild is called with -m, the checksums must be computed -- the same way in gprbuild as it was in the GNAT version of the compiler. -- The different ways are -- Version 6.4 and later: -- The Accumulate_Token_Checksum procedure is called after each numeric -- literal and each identifier/keyword. For keywords, Tok_Identifier is -- used in the call to Accumulate_Token_Checksum. -- Versions 5.04 to 6.3: -- For keywords, the token value were used in the call to procedure -- Accumulate_Token_Checksum. Type Token_Type did not include Tok_Some. -- Versions 5.03: -- For keywords, the token value were used in the call to -- Accumulate_Token_Checksum. Type Token_Type did not include -- Tok_Interface, Tok_Overriding, Tok_Synchronized and Tok_Some. -- Versions 5.02 and before: -- No calls to procedure Accumulate_Token_Checksum (the checksum -- mechanism was introduced in version 5.03). -- To signal to the scanner whether Accumulate_Token_Checksum needs to be -- called and what versions to call, the following Boolean flags are used: Checksum_Accumulate_Token_Checksum : Boolean := True; -- GPRBUILD -- Set to False by gprbuild when the version of GNAT is 5.02 or before. If -- this switch is False, then we do not call Accumulate_Token_Checksum, so -- the setting of the following two flags is irrelevant. Checksum_GNAT_6_3 : Boolean := False; -- GPRBUILD -- Set to True by gprbuild when the version of GNAT is 6.3 or before. Checksum_GNAT_5_03 : Boolean := False; -- GPRBUILD -- Set to True by gprbuild when the version of GNAT is 5.03 or before. ---------------------------------------------- -- Settings of Modes for Current Processing -- ---------------------------------------------- -- The following mode values represent the current state of processing. -- The values set here are the default values. Unless otherwise noted, -- the value may be reset in Switch-? with an appropriate switch. In -- some cases, the values can also be modified by pragmas, and in the -- case of some binder variables, Gnatbind.Scan_Bind_Arg may modify -- the default values. type Ada_Version_Type is (Ada_83, Ada_95, Ada_2005, Ada_2012); pragma Ordered (Ada_Version_Type); -- Versions of Ada for Ada_Version below. Note that these are ordered, -- so that tests like Ada_Version >= Ada_95 are legitimate and useful. -- Think twice before using "="; Ada_Version >= Ada_2012 is more likely -- what you want, because it will apply to future versions of the language. Ada_Version_Default : constant Ada_Version_Type := Ada_2012; pragma Warnings (Off, Ada_Version_Default); -- GNAT -- Default Ada version if no switch given. The Warnings off is to kill -- constant condition warnings. Ada_Version : Ada_Version_Type := Ada_Version_Default; -- GNAT -- Current Ada version for compiler, as set by configuration pragmas, -- compiler switches, or implicitly (to Ada_Version_Runtime) when a -- predefined or internal file is compiled. Ada_Version_Pragma : Node_Id := Empty; -- Reflects the Ada_xxx pragma that resulted in setting Ada_Version. Used -- to specialize error messages complaining about the Ada version in use. Ada_Version_Explicit : Ada_Version_Type := Ada_Version_Default; -- GNAT -- Like Ada_Version, but does not get set implicitly for predefined or -- internal units, so it reflects the Ada version explicitly set using -- configuration pragmas or compiler switches (or if neither appears, it -- remains set to Ada_Version_Default). This is used in the rare cases -- (notably pragma Obsolescent) where we want the explicit version set. Ada_Version_Runtime : Ada_Version_Type := Ada_2012; -- GNAT -- Ada version used to compile the runtime. Used to set Ada_Version (but -- not Ada_Version_Explicit) when compiling predefined or internal units. Ada_Final_Suffix : constant String := "final"; Ada_Final_Name : String_Ptr := new String'("ada" & Ada_Final_Suffix); -- GNATBIND -- The name of the procedure that performs the finalization at the end of -- execution. This variable may be modified by Gnatbind.Scan_Bind_Arg. Ada_Init_Suffix : constant String := "init"; Ada_Init_Name : String_Ptr := new String'("ada" & Ada_Init_Suffix); -- GNATBIND -- The name of the procedure that performs initialization at the start -- of execution. This variable may be modified by Gnatbind.Scan_Bind_Arg. Ada_Main_Name_Suffix : constant String := "main"; -- GNATBIND -- The suffix for Ada_Main_Name. Defined as a constant here so that it -- can be referenced in a uniform manner to create either the default -- value of Ada_Main_Name (declared below), or the non-default name -- set by Gnatbind.Scan_Bind_Arg. Ada_Main_Name : String_Ptr := new String'("ada_" & Ada_Main_Name_Suffix); -- GNATBIND -- The name of the Ada package generated by the binder (when in Ada mode). -- This variable may be modified by Gnatbind.Scan_Bind_Arg. Address_Clause_Overlay_Warnings : Boolean := True; -- GNAT -- Set False to disable address clause warnings. Modified by use of -- -gnatwo/O. Address_Is_Private : Boolean := False; -- GNAT, GNATBIND -- Set True if package System has the line "type Address is private;" All_Errors_Mode : Boolean := False; -- GNAT -- Flag set to force display of multiple errors on a single line and -- also repeated error messages for references to undefined identifiers -- and certain other repeated error messages. Set by use of -gnatf. Allow_Integer_Address : Boolean := False; -- GNAT -- Allow use of integer expression in a context requiring System.Address. -- Set by the use of configuration pragma Allow_Integer_Address Also set -- in relaxed semantics mode for use by CodePeer or when -gnatd.M is used. All_Sources : Boolean := False; -- GNATBIND -- Set to True to require all source files to be present. This flag is -- directly modified by gnatmake to affect the shared binder routines. Alternate_Main_Name : String_Ptr := null; -- GNATBIND -- Set to non null when Bind_Alternate_Main_Name is True. This value -- is modified as needed by Gnatbind.Scan_Bind_Arg. ASIS_Mode : Boolean := False; -- GNAT -- Enable semantic checks and tree transformations that are important -- for ASIS but that are usually skipped if Operating_Mode is set to -- Check_Semantics. This flag does not have the corresponding option to set -- it ON. It is set ON when Tree_Output is set ON, it can also be set ON -- from the code of GNSA-based tool (a client may need to set ON the -- Back_Annotate_Rep_Info flag in this case. At the moment this does not -- make very much sense, because GNSA cannot do back annotation). Assertions_Enabled : Boolean := False; -- GNAT -- Indicates default policy (True = Check, False = Ignore) to be applied -- to all assertion aspects and pragmas, and to pragma Debug, if there is -- no overriding Assertion_Policy, Check_Policy, or Debug_Policy pragma. -- Set True by use of -gnata. Assume_No_Invalid_Values : Boolean := False; -- GNAT Normally, in accordance with (RM 13.9.1 (9-11)) the front end -- assumes that values could have invalid representations, unless it can -- clearly prove that the values are valid. If this switch is set (by -- pragma Assume_No_Invalid_Values (Off)), then the compiler assumes values -- are valid and in range of their representations. This feature is now -- fully enabled in the compiler. Back_Annotate_Rep_Info : Boolean := False; -- GNAT -- If set True, enables back annotation of representation information -- by gigi, even in -gnatc mode. This is set True by the use of -gnatR -- (list representation information) or -gnatt (generate tree). It is -- also set true if certain Unchecked_Conversion instantiations require -- checking based on annotated values. Back_End_Handles_Limited_Types : Boolean; -- This flag is set true if the back end can properly handle limited or -- other by reference types, and avoid copies. If this flag is False, then -- the front end does special expansion for if/case expressions to make -- sure that no copy occurs. If the flag is True, then the expansion for -- if and case expressions relies on the back end properly handling things. -- Currently the default is False for all cases (set in gnat1drv). The -- default can be modified using -gnatd.L (sets the flag True). This is -- used to test the possibility of having the backend handle this. Bind_Alternate_Main_Name : Boolean := False; -- GNATBIND -- True if main should be called Alternate_Main_Name.all. -- This variable may be set to True by Gnatbind.Scan_Bind_Arg. Bind_Main_Program : Boolean := True; -- GNATBIND -- Set to False if not binding main Ada program Bind_For_Library : Boolean := False; -- GNATBIND -- Set to True if the binder needs to generate a file designed for building -- a library. May be set to True by Gnatbind.Scan_Bind_Arg. Bind_Only : Boolean := False; -- GNATMAKE, GPRMAKE, GPRBUILD -- Set to True to skip compile and link steps -- (except when Compile_Only and/or Link_Only are True). Blank_Deleted_Lines : Boolean := False; -- GNAT, GNATPREP -- Output empty lines for each line of preprocessed input that is deleted -- in the output, including preprocessor lines starting with a '#'. Brief_Output : Boolean := False; -- GNAT, GNATBIND -- Force brief error messages to standard error, even if verbose mode is -- set (so that main error messages go to standard output). Build_Bind_And_Link_Full_Project : Boolean := False; -- GNATMAKE -- Set to True to build, bind and link all the sources of a project file -- (switch -B) Check_Aliasing_Of_Parameters : Boolean := False; -- GNAT -- Set to True to detect whether subprogram parameters and function results -- alias the same object(s). Check_Float_Overflow : Boolean := False; -- GNAT -- Set to True to check that operations on predefined unconstrained float -- types (e.g. Float, Long_Float) do not overflow and generate infinities -- or invalid values. Set by the Check_Float_Overflow pragma, or by use -- of the -gnateF switch. Check_Object_Consistency : Boolean := False; -- GNATBIND, GNATMAKE -- Set to True to check whether every object file is consistent with its -- corresponding ada library information (ALI) file. An object file is -- inconsistent with the corresponding ALI file if the object file does -- not exist or if it has an older time stamp than the ALI file. Default -- above is for GNATBIND. GNATMAKE overrides this default to True (see -- Make.Initialize) since we normally do need to check source consistencies -- in gnatmake. Check_Only : Boolean := False; -- GNATBIND -- Set to True to do checks only, no output of binder file Check_Policy_List : Node_Id := Empty; -- GNAT -- This points to the list of N_Pragma nodes for Check_Policy pragmas -- that are linked through the Next_Pragma fields, with the list being -- terminated by Empty. The order is most recently processed first. Note -- that Push_Scope and Pop_Scope in Sem_Ch8 save and restore the value -- of this variable, implementing the required scope control for pragmas -- appearing in a declarative part. Check_Readonly_Files : Boolean := False; -- GNATMAKE -- Set to True to check readonly files during the make process Check_Source_Files : Boolean := True; -- GNATBIND, GNATMAKE -- Set to True to enable consistency checking for any source files that -- are present (i.e. date must match the date in the library info file). -- Set to False for object file consistency check only. This flag is -- directly modified by gnatmake, to affect the shared binder routines. Check_Switches : Boolean := False; -- GNATMAKE, GPRMAKE, GPBUILD -- Set to True to check compiler options during the make process Check_Unreferenced : Boolean := False; -- GNAT -- Set to True to enable checking for unreferenced entities other -- than formal parameters (for which see Check_Unreferenced_Formals) -- Modified by use of -gnatwu/U. Check_Unreferenced_Formals : Boolean := False; -- GNAT -- Set to True to check for unreferenced formals. This is turned on by -- -gnatwa/wf/wu and turned off by -gnatwA/wF/wU. Check_Validity_Of_Parameters : Boolean := False; -- GNAT -- Set to True to check for proper scalar initialization of subprogram -- parameters on both entry and exit. Turned on by??? turned off by??? Check_Withs : Boolean := False; -- GNAT -- Set to True to enable checking for unused withs, and also the case -- of withing a package and using none of the entities in the package. -- Modified by use of -gnatwu/U. CodePeer_Mode : Boolean := False; -- GNAT, GNATBIND, GPRBUILD -- Enable full CodePeer mode (SCIL generation, disable switches that -- interact badly with it, etc...). This is turned on by -gnatC. Commands_To_Stdout : Boolean := False; -- GNATMAKE -- True if echoed commands to be written to stdout instead of stderr Comment_Deleted_Lines : Boolean := False; -- GNATPREP -- True if source lines removed by the preprocessor should be commented -- in the output file. Compile_Only : Boolean := False; -- GNATMAKE, GNATCLEAN, GPRMAKE, GPBUILD, GPRCLEAN -- GNATMAKE, GPRMAKE, GPRMAKE: -- set to True to skip bind and link steps (except when Bind_Only is -- True). -- GNATCLEAN, GPRCLEAN: -- set to True to delete only the files produced by the compiler but not -- the library files or the executable files. Compiler_Unit : Boolean := False; -- GNAT1 -- Set True by an occurrence of pragma Compiler_Unit_Warning (or of the -- obsolete pragma Compiler_Unit) in the main unit. Once set True, stays -- True, since any units that are with'ed directly or indirectly by -- a Compiler_Unit_Warning main unit are subject to the same restrictions. -- Such units really should have their own pragmas, but we do not bother to -- check for that, so this transitivity provides extra checking. Config_File : Boolean := True; -- GNAT -- Set to False to inhibit reading and processing of gnat.adc file Config_File_Names : String_List_Access := null; -- GNAT -- Names of configuration pragmas files (given by switches -gnatec) Configurable_Run_Time_Mode : Boolean := False; -- GNAT, GNATBIND -- Set True if the compiler is operating in configurable run-time mode. -- This happens if the flag Targparm.Configurable_Run_TimeMode_On_Target -- is set True, or if pragma No_Run_Time is used. See the spec of Rtsfind -- for details on the handling of the latter pragma. Constant_Condition_Warnings : Boolean := False; -- GNAT -- Set to True to activate warnings on constant conditions. Modified by -- use of -gnatwc/C. Create_Mapping_File : Boolean := False; -- GNATMAKE, GPRMAKE -- Set to True (-C switch) to indicate that the compiler will be invoked -- with a mapping file (-gnatem compiler switch). subtype Debug_Level_Value is Nat range 0 .. 3; Debugger_Level : Debug_Level_Value := 0; -- GNATBIND -- The value given to the -g parameter. The default value for -g with -- no value is 2. This is usually ignored by GNATBIND, except in the -- VMS version where it is passed as an argument to __gnat_initialize -- to trigger the activation of the remote debugging interface. -- Is this still true ??? Default_Exit_Status : Int := 0; -- GNATBIND -- Set the default exit status value. Set by the -Xnnn switch for the -- binder. Debug_Generated_Code : Boolean := False; -- GNAT -- Set True (-gnatD switch) to debug generated expanded code instead -- of the original source code. Causes debugging information to be -- written with respect to the generated code file that is written. Default_Pool : Node_Id := Empty; -- GNAT -- Used to record the storage pool name (or null literal) that is the -- argument of an applicable pragma Default_Storage_Pool. -- Empty: No pragma Default_Storage_Pool applies. -- N_Null node: "pragma Default_Storage_Pool (null);" applies. -- otherwise: "pragma Default_Storage_Pool (X);" applies, and -- this points to the name X. -- Push_Scope and Pop_Scope in Sem_Ch8 save and restore this value. Default_Stack_Size : Int := -1; -- GNATBIND -- Set to default primary stack size in units of bytes. Set by -- the -dnnn switch for the binder. A value of -1 indicates that no -- default was set by the binder. Default_Sec_Stack_Size : Int := -1; -- GNATBIND -- Set to default secondary stack size in units of bytes. Set by -- the -Dnnn switch for the binder. A value of -1 indicates that no -- default was set by the binder, and that the default should be the -- initial value of System.Secondary_Stack.Default_Secondary_Stack_Size. Default_SSO : Character := ' '; -- GNAT -- Set if a pragma Default_Scalar_Storage_Order has been given. The value -- of ' ' indicates that no default has been set, otherwise the value is -- either 'H' for High_Order_First or 'L' for Lower_Order_First. Detect_Blocking : Boolean := False; -- GNAT -- Set True to force the run time to raise Program_Error if calls to -- potentially blocking operations are detected from protected actions. Directories_Must_Exist_In_Projects : Boolean := True; -- PROJECT MANAGER -- Set to False with switch -f of gnatclean and gprclean Display_Compilation_Progress : Boolean := False; -- GNATMAKE, GPRMAKE, GPRBUILD -- Set True (-d switch) to display information on progress while compiling -- files. Internal flag to be used in conjunction with an IDE (e.g GPS). type Distribution_Stub_Mode_Type is -- GNAT (No_Stubs, -- Normal mode, no generation/compilation of distribution stubs Generate_Receiver_Stub_Body, -- The unit being compiled is the RCI body, and the compiler will -- generate the body for the receiver stubs and compile it. Generate_Caller_Stub_Body); -- The unit being compiled is the RCI spec, and the compiler will -- generate the body for the caller stubs and compile it. Distribution_Stub_Mode : Distribution_Stub_Mode_Type := No_Stubs; -- GNAT -- This enumeration variable indicates the five states of distribution -- annex stub generation/compilation. Do_Not_Execute : Boolean := False; -- GNATMAKE -- Set to True if no actual compilations should be undertaken Dump_Source_Text : Boolean := False; -- GNAT -- Set to True (by -gnatL) to dump source text intermingled with generated -- code. Effective only if either of Debug/Print_Generated_Code is true. Dynamic_Elaboration_Checks : Boolean := False; -- GNAT -- Set True for dynamic elaboration checking mode, as set by the -gnatE -- switch or by the use of pragma Elaboration_Checks (Dynamic). Dynamic_Stack_Measurement : Boolean := False; -- GNATBIND -- Set True to enable dynamic stack measurement (-u flag for gnatbind) Dynamic_Stack_Measurement_Array_Size : Nat := 100; -- GNATBIND -- Number of measurements we want to store during dynamic stack analysis. -- When the buffer is full, non-storable results will be output on the fly. -- The value is relevant only if Dynamic_Stack_Measurement is set. Set -- by processing of -u flag for gnatbind. Elab_Dependency_Output : Boolean := False; -- GNATBIND -- Set to True to output complete list of elaboration constraints Elab_Order_Output : Boolean := False; -- GNATBIND -- Set to True to output chosen elaboration order Elab_Info_Messages : Boolean := False; -- GNAT -- Set to True to output info messages for static elabmodel (-gnatel) Elab_Warnings : Boolean := False; -- GNAT -- Set to True to generate elaboration warnings (-gnatwl) Error_Msg_Line_Length : Nat := 0; -- GNAT -- Records the error message line length limit. If this is set to zero, -- then we get the old style behavior, in which each call to the error -- message routines generates one line of output as a separate message. -- If it is set to a non-zero value, then continuation lines are folded -- to make a single long message, and then this message is split up into -- multiple lines not exceeding the specified length. Set by -gnatj=nn. Error_To_Warning : Boolean := False; -- GNAT -- If True, then certain error messages (e.g. parameter overlap messages -- for procedure calls in Ada 2012 mode) are treated as warnings instead -- of errors. Set by debug flag -gnatd.E. A search for Error_To_Warning -- will identify affected messages. Exception_Handler_Encountered : Boolean := False; -- GNAT -- This flag is set true if the parser encounters an exception handler. -- It is used to set Warn_On_Exception_Propagation True if the restriction -- No_Exception_Propagation is set. Exception_Extra_Info : Boolean := False; -- GNAT -- True when switch -gnateE is used. When True, generate extra information -- associated with exception messages (in particular range and index -- checks). Exception_Locations_Suppressed : Boolean := False; -- GNAT -- Set to True if a Suppress_Exception_Locations configuration pragma is -- currently active. type Exception_Mechanism_Type is -- Determines the handling of exceptions. See Exp_Ch11 for details -- (Front_End_Setjmp_Longjmp_Exceptions, -- Exceptions use setjmp/longjmp generated explicitly by the front end -- (this includes gigi or other equivalent parts of the code generator). -- AT END handlers are converted into exception handlers by the front -- end in this mode. Back_End_Exceptions); -- Exceptions are handled by the back end. The front end simply -- generates the handlers as they appear in the source, and AT END -- handlers are left untouched (they are not converted into exception -- handlers when operating in this mode. pragma Convention (C, Exception_Mechanism_Type); Exception_Mechanism : Exception_Mechanism_Type := Front_End_Setjmp_Longjmp_Exceptions; -- GNAT -- Set to the appropriate value depending on the default as given in -- system.ads (ZCX_By_Default). The C convention is there to make this -- variable accessible to gigi. Exception_Tracebacks : Boolean := False; -- GNATBIND -- Set to True to store tracebacks in exception occurrences (-E) Extensions_Allowed : Boolean := False; -- GNAT -- Set to True by switch -gnatX if GNAT specific language extensions -- are allowed. Currently there are no such defined extensions. type External_Casing_Type is ( As_Is, -- External names cased as they appear in the Ada source Uppercase, -- External names forced to all uppercase letters Lowercase); -- External names forced to all lowercase letters External_Name_Imp_Casing : External_Casing_Type := Lowercase; -- GNAT -- The setting of this flag determines the casing of external names -- when the name is implicitly derived from an entity name (i.e. either -- no explicit External_Name or Link_Name argument is used, or, in the -- case of extended DEC pragmas, the external name is given using an -- identifier. The As_Is setting is not permitted here (since this would -- create Ada source programs that were case sensitive). External_Name_Exp_Casing : External_Casing_Type := As_Is; -- GNAT -- The setting of this flag determines the casing of an external name -- specified explicitly with a string literal. As_Is means the string -- literal is used as given with no modification to the casing. If -- Lowercase or Uppercase is set, then the string is forced to all -- lowercase or all uppercase letters as appropriate. Note that this -- setting has no effect if the external name is given using an identifier -- in the case of extended DEC import/export pragmas (in this case the -- casing is controlled by External_Name_Imp_Casing), and also has no -- effect if an explicit Link_Name is supplied (a link name is always -- used exactly as given). External_Unit_Compilation_Allowed : Boolean := False; -- GNATMAKE -- When True (set by gnatmake switch -x), allow compilation of sources -- that are not part of any project file. Fast_Math : Boolean := False; -- GNAT -- Indicates the current setting of Fast_Math mode, as set by the use -- of a Fast_Math pragma (set True by Fast_Math (On)). Float_Format : Character := ' '; -- GNAT -- A non-blank value indicates that a Float_Format pragma has been -- processed, in which case this variable is set to 'I' for IEEE or to -- 'V' for VAX. The setting of 'V' is only possible on OpenVMS versions -- of GNAT. Float_Format_Long : Character := ' '; -- GNAT -- A non-blank value indicates that a Long_Float pragma has been processed -- (this pragma is recognized only in OpenVMS versions of GNAT), in which -- case this variable is set to D or G for D_Float or G_Float. Force_ALI_Tree_File : Boolean := False; -- GNAT -- Force generation of ALI file even if errors are encountered. Also forces -- generation of tree file if -gnatt is also set. Set on by use of -gnatQ. Disable_ALI_File : Boolean := False; -- GNAT -- Disable generation of ALI file Force_Checking_Of_Elaboration_Flags : Boolean := False; -- GNATBIND -- True if binding with forced checking of the elaboration flags -- (-F switch set). Force_Compilations : Boolean := False; -- GNATMAKE, GPRMAKE, GPRBUILD -- Set to force recompilations even when the objects are up-to-date. Full_Path_Name_For_Brief_Errors : Boolean := False; -- PROJECT MANAGER -- When True, in Brief_Output mode, each error message line -- will start with the full path name of the source. -- When False, only the file name without directory information -- is used. Full_List : Boolean := False; -- GNAT -- Set True to generate full source listing with embedded errors Full_List_File_Name : String_Ptr := null; -- GNAT -- Set to file name to generate full source listing to named file (or if -- the name is of the form .xxx, then to name.xxx where name is the source -- file name with extension stripped. Generate_CodePeer_Messages : Boolean := False; -- GNAT -- Generate CodePeer messages. Ignored if CodePeer_Mode is false. -- This is turned on by -gnateC. Generate_Processed_File : Boolean := False; -- GNAT -- True when switch -gnateG is used. When True, create in a file -- .prep, if the source is preprocessed. Generate_SCO : Boolean := False; -- GNAT -- True when switch -fdump-scos (or -gnateS) is used. When True, Source -- Coverage Obligation (SCO) information is generated and output in the ALI -- file. See unit Par_SCO for full details. Generate_SCO_Instance_Table : Boolean := False; -- GNAT -- True when switch -fdebug-instances is used. When True, a table of -- instances is included in SCOs. Generating_Code : Boolean := False; -- GNAT -- True if the frontend finished its work and has called the backend to -- process the tree and generate the object file. Global_Discard_Names : Boolean := False; -- GNAT, GNATBIND -- True if a pragma Discard_Names appeared as a configuration pragma for -- the current compilation unit. GNAT_Mode : Boolean := False; -- GNAT -- True if compiling in GNAT system mode (-gnatg switch) Heap_Size : Nat := 0; -- GNATBIND -- Heap size for memory allocations. Valid values are 32 and 64. Only -- available on VMS. Identifier_Character_Set : Character; -- GNAT -- This variable indicates the character set to be used for identifiers. -- The possible settings are: -- '1' Latin-1 (ISO-8859-1) -- '2' Latin-2 (ISO-8859-2) -- '3' Latin-3 (ISO-8859-3) -- '4' Latin-4 (ISO-8859-4) -- '5' Latin-Cyrillic (ISO-8859-5) -- '9' Latin-9 (ISO-8859-15) -- 'p' PC (US, IBM page 437) -- '8' PC (European, IBM page 850) -- 'f' Full upper set (all distinct) -- 'n' No upper characters (Ada 83 rules) -- 'w' Latin-1 plus wide characters allowed in identifiers -- -- The setting affects the set of letters allowed in identifiers and the -- upper/lower case equivalences. It does not affect the interpretation of -- character and string literals, which are always stored using the actual -- coding in the source program. This variable is initialized to the -- default value appropriate to the system (in Osint.Initialize), and then -- reset if a command line switch is used to change the setting. Ignore_Rep_Clauses : Boolean := False; -- GNAT -- Set True to ignore all representation clauses. Useful when compiling -- code from foreign compilers for checking or ASIS purposes. Can be -- set True by use of -gnatI. Ignore_Style_Checks_Pragmas : Boolean := False; -- GNAT -- Set True to ignore all Style_Checks pragmas. Can be set True by use -- of -gnateY. Ignore_Unrecognized_VWY_Switches : Boolean := False; -- GNAT -- Set True to ignore unrecognized y, V, w switches. Can be set True -- by use of -gnateu, causing subsequent unrecognized switches to result -- in a warning rather than an error. Implementation_Unit_Warnings : Boolean := True; -- GNAT -- Set True to active warnings for use of implementation internal units. -- Modified by use of -gnatwi/-gnatwI. Implicit_Packing : Boolean := False; -- GNAT -- If set True, then a Size attribute clause on an array is allowed to -- cause implicit packing instead of generating an error message. Set by -- use of pragma Implicit_Packing. Ineffective_Inline_Warnings : Boolean := False; -- GNAT -- Set True to activate warnings if front-end inlining (-gnatN) is not -- able to actually inline a particular call (or all calls). Can be -- controlled by use of -gnatwp/-gnatwP. Init_Or_Norm_Scalars : Boolean := False; -- GNAT, GANTBIND -- Set True if a pragma Initialize_Scalars applies to the current unit. -- Also set True if a pragma Restriction (Normalize_Scalars) applies. Initialize_Scalars : Boolean := False; -- GNAT -- Set True if a pragma Initialize_Scalars applies to the current unit. -- Note that Init_Or_Norm_Scalars is also set to True if this is True. Initialize_Scalars_Mode1 : Character := 'I'; Initialize_Scalars_Mode2 : Character := 'N'; -- GNATBIND -- Set to two characters from -S switch (IN/LO/HI/EV/xx). The default -- is IN (invalid values), used if no -S switch is used. Inline_Active : Boolean := False; -- GNAT -- Set True to activate pragma Inline processing across modules. Default -- for now is not to inline across module boundaries. Inline_Level : Nat := 0; -- GNAT -- Set to indicate the inlining level: 0 means that an appropriate value is -- to be computed by the compiler based on the optimization level (-gnatn), -- 1 is for moderate inlining across modules (-gnatn1) and 2 for full -- inlining across modules (-gnatn2). Interface_Library_Unit : Boolean := False; -- GNATBIND -- Set to True to indicate that at least one ALI file is an interface ALI: -- then elaboration flag checks are to be generated in the binder -- generated file. Generate_SCIL : Boolean := False; -- GNAT -- Set True to activate SCIL code generation. Invalid_Value_Used : Boolean := False; -- GNAT -- Set True if a valid Invalid_Value attribute is encountered Follow_Links_For_Files : Boolean := False; -- PROJECT MANAGER -- Set to True (-eL) to process the project files in trusted mode. If -- Follow_Links is False, it is assumed that the project doesn't contain -- any file duplicated through symbolic links (although the latter are -- still valid if they point to a file which is outside of the project), -- and that no directory has a name which is a valid source name. Follow_Links_For_Dirs : Boolean := False; -- PROJECT MANAGER -- Set to True if directories can be links in this project, and therefore -- additional system calls must be performed to ensure that we always see -- the same full name for each directory. Front_End_Inlining : Boolean := False; -- GNAT -- Set True to activate inlining by front-end expansion Inline_Processing_Required : Boolean := False; -- GNAT -- Set True if inline processing is required. Inline processing is required -- if an active Inline pragma is processed. The flag is set for a pragma -- Inline or Inline_Always that is actually active. In_Place_Mode : Boolean := False; -- GNATMAKE -- Set True to store ALI and object files in place i.e. in the object -- directory if these files already exist or in the source directory -- if not. Keep_Going : Boolean := False; -- GNATMAKE, GPRMAKE, GPRBUILD -- When True signals to ignore compilation errors and keep processing -- sources until there is no more work. Keep_Temporary_Files : Boolean := False; -- GNATCMD -- When True the temporary files created by the GNAT driver are not -- deleted. Set by switch -dn or qualifier /KEEP_TEMPORARY_FILES. Leap_Seconds_Support : Boolean := False; -- GNATBIND -- Set to True to enable leap seconds support in Ada.Calendar and its -- children. Link_Only : Boolean := False; -- GNATMAKE, GPRMAKE, GPRBUILD -- Set to True to skip compile and bind steps (except when Bind_Only is -- set to True). List_Body_Required_Info : Boolean := False; -- GNATMAKE -- List info messages about why a package requires a body. Modified by use -- of -gnatw.y/.Y. List_Inherited_Aspects : Boolean := False; -- GNAT -- List inherited invariants, preconditions, and postconditions from -- Invariant'Class, Pre'Class, and Post'Class aspects. Also list inherited -- subtype predicates. Modified by use of -gnatw.l/.L. List_Restrictions : Boolean := False; -- GNATBIND -- Set to True to list restrictions pragmas that could apply to partition List_Units : Boolean := False; -- GNAT -- List units in the active library for a compilation (-gnatu switch) List_Closure : Boolean := False; -- GNATBIND -- List all sources in the closure of a main (-R or -Ra gnatbind switch) List_Closure_All : Boolean := False; -- GNATBIND -- List all sources in closure of main including run-time units (-Ra -- gnatbind switch). List_Dependencies : Boolean := False; -- GNATMAKE -- When True gnatmake verifies that the objects are up to date and -- outputs the list of object dependencies (-M switch). -- Output depends if -a switch is used or not. -- This list can be used directly in a Makefile. List_Representation_Info : Int range 0 .. 3 := 0; -- GNAT -- Set non-zero by -gnatR switch to list representation information. -- The settings are as follows: -- -- 0 = no listing of representation information (default as above) -- 1 = list rep info for user defined record and array types -- 2 = list rep info for all user defined types and objects -- 3 = like 2, but variable fields are decoded symbolically List_Representation_Info_To_File : Boolean := False; -- GNAT -- Set true by -gnatRs switch. Causes information from -gnatR/1/2/3/m to be -- written to file.rep (where file is the name of the source file) instead -- of stdout. For example, if file x.adb is compiled using -gnatR2s then -- representation info is written to x.adb.ref. List_Representation_Info_Mechanisms : Boolean := False; -- GNAT -- Set true by -gnatRm switch. Causes information on mechanisms to be -- included in the representation output information. List_Preprocessing_Symbols : Boolean := False; -- GNAT, GNATPREP -- Set to True if symbols for preprocessing a source are to be listed -- before preprocessing occurs. Set to True by switch -s of gnatprep or -- -s in preprocessing data file for the compiler. type Create_Repinfo_File_Proc is access procedure (Src : String); type Write_Repinfo_Line_Proc is access procedure (Info : String); type Close_Repinfo_File_Proc is access procedure; -- Types used for procedure addresses below Create_Repinfo_File_Access : Create_Repinfo_File_Proc := null; Write_Repinfo_Line_Access : Write_Repinfo_Line_Proc := null; Close_Repinfo_File_Access : Close_Repinfo_File_Proc := null; -- GNAT -- These three locations are left null when operating in non-compiler (e.g. -- ASIS mode), but when operating in compiler mode, they are set to point -- to the three corresponding procedures in Osint-C. The reason for this -- slightly strange interface is to stop Repinfo from dragging in Osint in -- ASIS mode, which would include lots of unwanted units in the ASIS build. type Create_List_File_Proc is access procedure (S : String); type Write_List_Info_Proc is access procedure (S : String); type Close_List_File_Proc is access procedure; -- Types used for procedure addresses below Create_List_File_Access : Create_List_File_Proc := null; Write_List_Info_Access : Write_List_Info_Proc := null; Close_List_File_Access : Close_List_File_Proc := null; -- GNAT -- These three locations are left null when operating in non-compiler -- (e.g. from the binder), but when operating in compiler mode, they are -- set to point to the three corresponding procedures in Osint-C. The -- reason for this slightly strange interface is to prevent Repinfo -- from dragging in Osint-C in the binder, which would include unwanted -- units in the binder. Locking_Policy : Character := ' '; -- GNAT, GNATBIND -- Set to ' ' for the default case (no locking policy specified). Reset to -- first character (uppercase) of locking policy name if a valid pragma -- Locking_Policy is encountered. Locking_Policy_Sloc : Source_Ptr := No_Location; -- GNAT, GNATBIND -- Remember location of previous Locking_Policy pragma. This is used for -- inconsistency error messages. A value of System_Location is used if the -- policy is set in package System. Look_In_Primary_Dir : Boolean := True; -- GNAT, GNATBIND, GNATMAKE, GNATCLEAN -- Set to False if a -I- was present on the command line. When True we are -- allowed to look in the primary directory to locate other source or -- library files. Make_Steps : Boolean := False; -- GNATMAKE -- Set to True when either Compile_Only, Bind_Only or Link_Only is -- set to True. Main_Index : Int := 0; -- GNATMAKE -- This is set to non-zero by gnatmake switch -eInnn to indicate that -- the main program is the nnn unit in a multi-unit source file. Mapping_File_Name : String_Ptr := null; -- GNAT -- File name of mapping between unit names, file names and path names. -- (given by switch -gnatem) Maximum_Messages : Int := 9999; -- GNAT, GNATBIND -- Maximum default number of errors before compilation is terminated, or in -- the case of GNAT, maximum number of warnings before further warnings are -- suppressed. Can be overridden by -gnatm (GNAT) or -m (GNATBIND) switch. Maximum_File_Name_Length : Int; -- GNAT, GNATBIND -- Maximum number of characters allowed in a file name, not counting the -- extension, as set by the appropriate switch. If no switch is given, -- then this value is initialized by Osint to the appropriate value. Maximum_Instantiations : Int := 8000; -- GNAT -- Maximum number of instantiations permitted (to stop runaway cases -- of nested instantiations). These situations probably only occur in -- specially concocted test cases. Can be modified by -gnateinn switch. Maximum_Processes : Positive := 1; -- GNATMAKE, GPRMAKE, GPRBUILD -- Maximum number of processes that should be spawned to carry out -- compilations. Minimal_Recompilation : Boolean := False; -- GNATMAKE -- Set to True if minimal recompilation mode requested Modify_Tree_For_C : Boolean := False; -- GNAT -- If this switch is set True (currently it is set only by -gnatd.V), then -- certain meaning-preserving transformations are applied to the tree to -- make it easier to interface with back ends that implement C semantics. -- There is a section in Sinfo which describes the transformations made. Multiple_Unit_Index : Int := 0; -- GNAT -- This is set non-zero if the current unit is being compiled in multiple -- unit per file mode, meaning that the current unit is selected from the -- sequence of units in the current source file, using the value stored -- in this variable (e.g. 2 = select second unit in file). A value of -- zero indicates that we are in normal (one unit per file) mode. No_Backup : Boolean := False; -- GNATNAME -- Do not create backup copies of project files. Set by switch --no-backup. No_Deletion : Boolean := False; -- GNATPREP -- Set by preprocessor switch -a. Do not eliminate any source text. Implies -- Undefined_Symbols_Are_False. Useful to perform a syntax check on all -- branches of #if constructs. No_Main_Subprogram : Boolean := False; -- GNATMAKE, GNATBIND -- Set to True if compilation/binding of a program without main -- subprogram requested. No_Run_Time_Mode : Boolean := False; -- GNAT, GNATBIND -- This flag is set True if a No_Run_Time pragma is encountered. See -- spec of Rtsfind for a full description of handling of this pragma. No_Split_Units : Boolean := False; -- GPRBUILD -- Set to True with switch --no-split-units. When True, unit sources, spec, -- body and subunits, must all be in the same project. This is checked -- after each compilation. No_Stdinc : Boolean := False; -- GNAT, GNATBIND, GNATMAKE, GNATFIND, GNATXREF -- Set to True if no default source search dirs added to search list. No_Stdlib : Boolean := False; -- GNATMAKE, GNATBIND, GNATFIND, GNATXREF -- Set to True if no default library search dirs added to search list. No_Strict_Aliasing : Boolean := False; -- GNAT -- Set True if pragma No_Strict_Aliasing with no parameters encountered. Normalize_Scalars : Boolean := False; -- GNAT, GNATBIND -- Set True if a pragma Normalize_Scalars applies to the current unit. -- Note that Init_Or_Norm_Scalars is also set to True if this is True. Object_Directory_Present : Boolean := False; -- GNATMAKE -- Set to True when an object directory is specified with option -D Object_Path_File_Name : String_Ptr := null; -- GNAT2WHY -- Path of the temporary file that contains a list of object directories -- passed by -gnateO=. One_Compilation_Per_Obj_Dir : Boolean := False; -- GNATMAKE, GPRBUILD -- Set to True with switch --single-compile-per-obj-dir. When True, there -- cannot be simultaneous compilations with the object files in the same -- object directory, if project files are used. type Operating_Mode_Type is (Check_Syntax, Check_Semantics, Generate_Code); pragma Ordered (Operating_Mode_Type); Operating_Mode : Operating_Mode_Type := Generate_Code; -- GNAT -- Indicates the operating mode of the compiler. The default is generate -- code, which runs the parser, semantics and backend. Switches can be -- used to set syntax checking only mode, or syntax and semantics checking -- only mode. Operating_Mode can also be modified as a result of detecting -- errors during the compilation process. In particular if any serious -- error is detected then this flag is reset from Generate_Code to -- Check_Semantics after generating an error message. This is an ordered -- type with the semantics that each value does more than the previous one. Optimize_Alignment : Character := 'O'; -- Setting of Optimize_Alignment, set to T/S/O for time/space/off. Can -- be modified by use of pragma Optimize_Alignment. Optimize_Alignment_Local : Boolean := False; -- Set True if Optimize_Alignment mode is set by a local configuration -- pragma that overrides the gnat.adc (or other configuration file) default -- so that the unit is not dependent on the default setting. Also always -- set True for internal units, since these always have a default setting -- of Optimize_Alignment (Off) that is enforced (essentially equivalent to -- them all having such an explicit pragma in each unit). Original_Operating_Mode : Operating_Mode_Type := Generate_Code; -- GNAT -- Indicates the original operating mode of the compiler as set by compiler -- options. This is identical to Operating_Mode except that this is not -- affected by errors. Optimization_Level : Int; pragma Import (C, Optimization_Level, "optimize"); -- Constant reflecting the optimization level (0,1,2,3 for -O0,-O1,-O2,-O3) -- See jmissing.c and aamissing.c for definitions for dotnet/jgnat and -- GNAAMP back ends. Optimize_Size : Int; pragma Import (C, Optimize_Size, "optimize_size"); -- Constant reflecting setting of -Os (optimize for size). Set to nonzero -- in -Os mode and set to zero otherwise. See jmissing.c and aamissing.c -- for definitions of "optimize_size" for dotnet/jgnat and GNAAMP backends Output_File_Name_Present : Boolean := False; -- GNATBIND, GNAT, GNATMAKE, GPRMAKE -- Set to True when the output C file name is given with option -o for -- GNATBIND, when the object file name is given with option -gnatO for GNAT -- or when the executable is given with option -o for GNATMAKE or GPRMAKE. Output_Linker_Option_List : Boolean := False; -- GNATBIND -- True if output of list of linker options is requested (-K switch set) Output_ALI_List : Boolean := False; ALI_List_Filename : String_Ptr; -- GNATBIND -- True if output of list of ALIs is requested (-A switch set). List is -- output under the given filename, or standard output if not specified. Output_Object_List : Boolean := False; Object_List_Filename : String_Ptr; -- GNATBIND -- True if output of list of objects is requested (-O switch set). List is -- output under the given filename, or standard output if not specified. Partition_Elaboration_Policy : Character := ' '; -- GNAT, GNATBIND -- Set to ' ' for the default case (no elaboration policy specified). Reset -- to first character (uppercase) of locking policy name if a valid pragma -- Partition_Elaboration_Policy is encountered. Partition_Elaboration_Policy_Sloc : Source_Ptr := No_Location; -- GNAT, GNATBIND -- Remember location of previous Partition_Elaboration_Policy pragma. This -- is used for inconsistency error messages. A value of System_Location is -- used if the policy is set in package System. Persistent_BSS_Mode : Boolean := False; -- GNAT -- True if a Persistent_BSS configuration pragma is in effect, causing -- potentially persistent data to be placed in the persistent_bss section. Pessimistic_Elab_Order : Boolean := False; -- GNATBIND -- True if pessimistic elaboration order is to be chosen (-p switch set) Polling_Required : Boolean := False; -- GNAT -- Set to True if polling for asynchronous abort is enabled by using -- the -gnatP option for GNAT. Preprocessing_Data_File : String_Ptr := null; -- GNAT -- Set by switch -gnatep=. The file name of the preprocessing data file. Preprocessing_Symbol_Defs : String_List_Access := new String_List (1 .. 4); -- An extensible array to temporarily stores symbol definitions specified -- on the command line with -gnateD switches. -- What is this magic constant 4 ??? -- What is extensible about this fixed length array ??? Preprocessing_Symbol_Last : Natural := 0; -- Index of last symbol definition in array Symbol_Definitions Print_Generated_Code : Boolean := False; -- GNAT -- Set to True to enable output of generated code in source form. This -- flag is set by the -gnatG switch. Print_Standard : Boolean := False; -- GNAT -- Set to true to enable printing of package standard in source form. -- This flag is set by the -gnatS switch type Usage is (Unknown, Not_In_Use, In_Use); Project_File_In_Use : Usage := Unknown; -- GNAT -- Indicates if a project file is used or not. Set to In_Use by the first -- SFNP pragma. Queuing_Policy : Character := ' '; -- GNAT, GNATBIND -- Set to ' ' for the default case (no queuing policy specified). Reset to -- first character (uppercase) of locking policy name if a valid -- Queuing_Policy pragma is encountered. Queuing_Policy_Sloc : Source_Ptr := No_Location; -- GNAT, GNATBIND -- Remember location of previous Queuing_Policy pragma. This is used for -- inconsistency error messages. A value of System_Location is used if the -- policy is set in package System. Quiet_Output : Boolean := False; -- GNATMAKE, GNATCLEAN, GPRMAKE, GPRBUILD, GPRCLEAN -- Set to True if the tool should not have any output if there are no -- errors or warnings. Overriding_Renamings : Boolean := False; -- GNAT -- Set to True to enable compatibility mode with Rational compiler, and -- to accept renamings of implicit operations in their own scope. Relaxed_RM_Semantics : Boolean := False; -- GNAT -- Set to True to ignore some Ada semantic error to help parse legacy -- Ada code for use in e.g. static analysis (such as CodePeer). This -- deals with cases where other compilers allow illegal constructs. Tools -- such as CodePeer are interested in analyzing code rather than enforcing -- legality rules, so as long as these illegal constructs end up with code -- that can be handled by the tool in question, there is no reason to -- reject the code that is considered correct by the other compiler. Replace_In_Comments : Boolean := False; -- GNATPREP -- Set to True if -C switch used. RTS_Lib_Path_Name : String_Ptr := null; RTS_Src_Path_Name : String_Ptr := null; -- GNAT -- Set to the "adalib" and "adainclude" directories of the run time -- specified by --RTS=. RTS_Switch : Boolean := False; -- GNAT, GNATMAKE, GNATBIND, GNATLS, GNATFIND, GNATXREF -- Set to True when the --RTS switch is set Run_Path_Option : Boolean := True; -- GNATMAKE, GNATLINK -- Set to False when no run_path_option should be issued to the linker Search_Directory_Present : Boolean := False; -- GNAT -- Set to True when argument is -I. Reset to False when next argument, a -- search directory path is taken into account. Note that this is quite -- different from other switches in this section in that it is only set in -- a transitory manner as a result of scanning a -I switch with no file -- name, and if set, is an indication that the next argument is to be -- treated as a file name. Sec_Stack_Used : Boolean := False; -- GNAT, GBATBIND -- Set True if generated code uses the System.Secondary_Stack package. For -- the binder, set if any unit uses the secondary stack package. Setup_Projects : Boolean := False; -- GNAT DRIVER -- Set to True for GNAT SETUP: the Project Manager creates non existing -- object, library and exec directories. Shared_Libgnat : Boolean; -- GNATBIND -- Set to True if a shared libgnat is requested by using the -shared option -- for GNATBIND and to False when using the -static option. The value of -- this flag is set by Gnatbind.Scan_Bind_Arg. Short_Circuit_And_Or : Boolean := False; -- GNAT -- Set True if a pragma Short_Circuit_And_Or applies to the current unit. Short_Descriptors : Boolean := False; -- GNAT -- Set True if a pragma Short_Descriptors applies to the current unit. type SPARK_Mode_Type is (None, Off, On); -- Possible legal modes that can be set by aspect/pragma SPARK_Mode, as -- well as the value None, which indicates no such pragma/aspect applies. SPARK_Mode : SPARK_Mode_Type := None; -- GNAT -- Current SPARK mode setting. SPARK_Mode_Pragma : Node_Id := Empty; -- GNAT -- If the current SPARK_Mode (above) was set by a pragma, this records -- the pragma that set this mode. SPARK_Switches_File_Name : String_Ptr := null; -- GNAT -- Set to non-null file name by use of the -gnates switch to specify -- SPARK (gnat2why) specific switches in the given file name. Special_Exception_Package_Used : Boolean := False; -- GNAT -- Set to True if either of the unit GNAT.Most_Recent_Exception or -- GNAT.Exception_Traces is with'ed. Used to inhibit transformation of -- local raise statements into gotos in the presence of either package. Sprint_Line_Limit : Nat := 72; -- GNAT -- Limit values for chopping long lines in Cprint/Sprint output, can be -- reset by use of NNN parameter with -gnatG or -gnatD switches. Stack_Checking_Enabled : Boolean := False; -- GNAT -- Set to indicate if stack checking is enabled for the compilation. This -- is set directly from the value in the gcc back end in the body of the -- gcc version of back_end.adb. Style_Check : Boolean := False; -- GNAT -- Set True to perform style checks. Activates checks carried out in -- package Style (see body of this package for details of checks). This -- flag is set True by use of either the -gnatg or -gnaty switches, or -- by the Style_Check pragma. Style_Check_Main : Boolean := False; -- GNAT -- Set True if Style_Check was set for the main unit. This is used to -- renable style checks for units in the mail extended source that get -- with'ed indirectly. It is set True by use of either the -gnatg or -- -gnaty switches, but not by use of the Style_Checks pragma. Suppress_All_Inlining : Boolean := False; -- GNAT -- Set by -fno-inline. Suppresses all inlining, both front end and back end -- regardless of any other switches that are set. Suppress_Control_Flow_Optimizations : Boolean := False; -- GNAT -- Set by -fpreserve-control-flow. Suppresses control flow optimizations -- that interfere with coverage analysis based on the object code. System_Extend_Pragma_Arg : Node_Id := Empty; -- GNAT -- Set non-empty if and only if a correct Extend_System pragma was present -- in which case it points to the argument of the pragma, and the name can -- be located as Chars (Expression (System_Extend_Pragma_Arg)). System_Extend_Unit : Node_Id := Empty; -- GNAT -- This is set to Empty if GNAT_Mode is set, since pragma Extend_System -- is never appropriate in GNAT_Mode (and causes troubles, including -- bogus circularities, if we try to compile the run-time library with -- a System extension). If GNAT_Mode is not set, then System_Extend_Unit -- is a copy of the value set in System_Extend_Pragma_Arg. Subunits_Missing : Boolean := False; -- GNAT -- This flag is set true if missing subunits are detected with code -- generation active. This causes code generation to be skipped. Suppress_Checks : Boolean := False; -- GNAT -- Set to True if -gnatp (suppress all checks) switch present. Suppress_Options : Suppress_Record; -- GNAT -- Indicates outer level setting of check suppression. This initializes -- the settings of the outer scope level in any unit compiled. This is -- initialized by Osint.Initialize, and further initialized by the -- Adjust_Global_Switches flag in Gnat1drv. Table_Factor : Int := 1; -- GNAT -- Factor by which all initial table sizes set in Alloc are multiplied. -- Used in Table to calculate initial table sizes (the initial table size -- is the value in Alloc, used as the Table_Initial parameter value, -- multiplied by the factor given here. The default value is used if no -- -gnatT switch appears. Tagged_Type_Expansion : Boolean := True; -- GNAT -- Set True if tagged types and interfaces should be expanded by the -- front-end. If False, the original tree is left unexpanded for tagged -- types and dispatching calls, assuming the underlying target supports -- it (e.g. in the JVM case). Target_Dependent_Info_Read_Name : String_Ptr := null; -- GNAT -- Set non-null to override the normal processing in Get_Targ and set the -- necessary information by reading the target dependent information file -- whose name is given here (see packages Get_Targ and Set_Targ for full -- details). Set to non-null file name by use of the -gnateT switch. Target_Dependent_Info_Write_Name : String_Ptr := null; -- GNAT -- Set non-null to enable a call to Set_Targ.Write_Target_Dependent_Info -- which writes a target independent information file (see packages -- Get_Targ and Set_Targ for full details) using the name given by -- this switch. Set to non-null file name by use of the -gnatet switch. Task_Dispatching_Policy : Character := ' '; -- GNAT, GNATBIND -- Set to ' ' for the default case (no task dispatching policy specified). -- Reset to first character (uppercase) of task dispatching policy name -- if a valid Task_Dispatching_Policy pragma is encountered. Task_Dispatching_Policy_Sloc : Source_Ptr := No_Location; -- GNAT, GNATBIND -- Remember location of previous Task_Dispatching_Policy pragma. This is -- used for inconsistency error messages. A value of System_Location is -- used if the policy is set in package System. Tasking_Used : Boolean := False; -- Set True if any tasking construct is encountered. Used to activate the -- output of the Q, L and T lines in ALI files. Time_Slice_Set : Boolean := False; -- GNATBIND -- Set True if a pragma Time_Slice is processed in the main unit, or -- if the -gnatTnn switch is present to set a time slice value. Time_Slice_Value : Nat; -- GNATBIND -- Time slice value. Valid only if Time_Slice_Set is True, i.e. if -- Time_Slice pragma has been processed. Set to the time slice value in -- microseconds. Negative values are stored as zero, and the value is not -- larger than 1_000_000_000 (1000 seconds). Values larger than this are -- reset to this maximum. This can also be set with the -gnatTnn switch. Tolerate_Consistency_Errors : Boolean := False; -- GNATBIND -- Tolerate time stamp and other consistency errors. If this flag is set to -- True (-t), then inconsistencies result in warnings rather than errors. Treat_Categorization_Errors_As_Warnings : Boolean := False; -- Normally categorization errors are true illegalities. If this switch -- is set, then such errors result in warning messages rather than error -- messages. Set True by -gnateP (P for Pure/Preelaborate). Also set in -- Relaxed_RM_Semantics mode since some old Ada 83 compilers treated -- pragma Preelaborate differently. Treat_Restrictions_As_Warnings : Boolean := False; -- GNAT -- Set True to treat pragma Restrictions as Restriction_Warnings. Set by -- -gnatr switch. Tree_Output : Boolean := False; -- GNAT -- Set to True (-gnatt) to generate output tree file True_VMS_Target : Boolean := False; -- Set True if we are on a VMS target. The setting of this flag reflects -- the true state of the compile, unlike Targparm.OpenVMS_On_Target which -- can also be true when debug flag m is set (-gnatdm). This is used in the -- few cases where we do NOT want -gnatdm to trigger the VMS behavior. Try_Semantics : Boolean := False; -- GNAT -- Flag set to force attempt at semantic analysis, even if parser errors -- occur. This will probably cause blowups at this stage in the game. On -- the other hand, most such blowups will be caught cleanly and simply -- say compilation abandoned. This flag is set True by -gnatq or -gnatQ. Unchecked_Shared_Lib_Imports : Boolean := False; -- GPRBUILD -- Set to True when shared library projects are allowed to import projects -- that are not shared library projects. Set on by use of the switch -- --unchecked-shared-lib-imports. Undefined_Symbols_Are_False : Boolean := False; -- GNAT, GNATPREP -- Set to True by switch -u of gnatprep or -u in the preprocessing data -- file for the compiler. Indicates that while preprocessing sources, -- symbols that are not defined have the value FALSE. Uneval_Old : Character := 'E'; -- GNAT -- Set to 'E'/'W'/'A' for use of Error/Warn/Allow in a valid pragma -- Unevaluated_Use_Of_Old. Default in the absence of the pragma is 'E' -- for the RM default behavior of giving an error. Unique_Error_Tag : Boolean := Tag_Errors; -- GNAT -- Indicates if error messages are to be prefixed by the string error: -- Initialized from Tag_Errors, can be forced on with the -gnatU switch. Universal_Addressing_On_AAMP : Boolean := False; -- GNAAMP -- Indicates if library-level objects should be accessed and updated using -- universal addressing instructions on the AAMP architecture. This flag is -- set to True when pragma Universal_Data is given as a configuration -- pragma. Unreserve_All_Interrupts : Boolean := False; -- GNAT, GNATBIND -- Normally set False, set True if a valid Unreserve_All_Interrupts pragma -- appears anywhere in the main unit for GNAT, or if any ALI file has the -- corresponding attribute set in GNATBIND. Upper_Half_Encoding : Boolean := False; -- GNAT, GNATBIND -- Normally set False, indicating that upper half ISO 8859-1 characters are -- used in the normal way to represent themselves. If the wide character -- encoding method uses the upper bit for this encoding, then this flag is -- set True, and upper half characters in the source indicate the start of -- a wide character sequence. Set by -gnatW or -W switches. Use_Include_Path_File : Boolean := False; -- GNATMAKE, GPRBUILD -- When True, create a source search path file, even when a mapping file -- is used. Usage_Requested : Boolean := False; -- GNAT, GNATBIND, GNATMAKE -- Set to True if -h (-gnath for the compiler) switch encountered -- requesting usage information Use_Pragma_Linker_Constructor : Boolean := False; -- GNATBIND -- True if pragma Linker_Constructor applies to adainit Use_VADS_Size : Boolean := False; -- GNAT -- Set to True if a valid pragma Use_VADS_Size is processed Validity_Checks_On : Boolean := True; -- GNAT -- This flag determines if validity checking is on or off. The initial -- state is on, and the required default validity checks are active. The -- actual set of checks that is performed if Validity_Checks_On is set is -- defined by the switches in package Validsw. The Validity_Checks_On flag -- is controlled by pragma Validity_Checks (On | Off), and also some -- generated compiler code (typically code that has to do with validity -- check generation) is compiled with this flag set to False. This flag is -- set to False by the -gnatp switch. Verbose_Mode : Boolean := False; -- GNAT, GNATBIND, GNATMAKE, GNATLINK, GNATLS, GNATNAME, GNATCLEAN, -- GPRMAKE, GPRBUILD, GPRCLEAN -- Set to True to get verbose mode (full error message text and location -- information sent to standard output, also header, copyright and summary) type Verbosity_Level_Type is (None, Low, Medium, High); pragma Ordered (Verbosity_Level_Type); Verbosity_Level : Verbosity_Level_Type := High; -- GNATMAKE, GPRMAKE -- Modified by gnatmake or gprmake switches -v, -vl, -vm, -vh. Indicates -- the level of verbosity of informational messages: -- -- In Low Verbosity, the reasons why a source is recompiled, the name -- of the executable and the reason it must be rebuilt is output. -- -- In Medium Verbosity, additional lines are output for each ALI file -- that is checked. -- -- In High Verbosity, additional lines are output when the ALI file -- is part of an Ada library, is read-only or is part of the runtime. Warn_On_Ada_2005_Compatibility : Boolean := True; -- GNAT -- Set to True to generate all warnings on Ada 2005 compatibility issues, -- including warnings on Ada 2005 obsolescent features used in Ada 2005 -- mode. Set by default, modified by use of -gnatwy/Y. Warn_On_Ada_2012_Compatibility : Boolean := True; -- GNAT -- Set to True to generate all warnings on Ada 2012 compatibility issues, -- including warnings on Ada 2012 obsolescent features used in Ada 2012 -- mode. Modified by use of -gnatwy/Y. Warn_On_All_Unread_Out_Parameters : Boolean := False; -- GNAT -- Set to True to generate warnings in all cases where a variable is -- modified by being passed as to an OUT formal, but the resulting value is -- never read. The default is that this warning is suppressed. Modified -- by use of gnatw.o/.O. Warn_On_Assertion_Failure : Boolean := True; -- GNAT -- Set to True to activate warnings on assertions that can be determined -- at compile time will always fail. Modified by use of -gnatw.a/.A. Warn_On_Assumed_Low_Bound : Boolean := True; -- GNAT -- Set to True to activate warnings for string parameters that are indexed -- with literals or S'Length, presumably assuming a lower bound of one. -- Modified by use of -gnatww/W. Warn_On_Atomic_Synchronization : Boolean := False; -- GNAT -- Set to True to generate information messages for atomic synchronization. -- Modified by use of -gnatw.n/.N. Warn_On_Bad_Fixed_Value : Boolean := False; -- GNAT -- Set to True to generate warnings for static fixed-point expression -- values that are not an exact multiple of the small value of the type. -- Odd by default, modified by use of -gnatwb/B. Warn_On_Biased_Representation : Boolean := True; -- GNAT -- Set to True to generate warnings for size clauses, component clauses -- and component_size clauses that force biased representation. Modified -- by use of -gnatw.b/.B. Warn_On_Constant : Boolean := False; -- GNAT -- Set to True to generate warnings for variables that could be declared -- as constants. Modified by use of -gnatwk/K. Warn_On_Deleted_Code : Boolean := False; -- GNAT -- Set to True to generate warnings for code deleted by the front end -- for conditional statements whose outcome is known at compile time. -- Modified by use of -gnatwt/T. Warn_On_Dereference : Boolean := False; -- GNAT -- Set to True to generate warnings for implicit dereferences for array -- indexing and record component access. Modified by use of -gnatwd/D. Warn_On_Export_Import : Boolean := True; -- GNAT -- Set to True to generate warnings for suspicious use of export or -- import pragmas. Modified by use of -gnatwx/X. Warn_On_Hiding : Boolean := False; -- GNAT -- Set to True to generate warnings if a declared entity hides another -- entity. The default is that this warning is suppressed. Modified by -- use of -gnatwh/H. Warn_On_Modified_Unread : Boolean := False; -- GNAT -- Set to True to generate warnings if a variable is assigned but is never -- read. Also controls warnings for similar cases involving out parameters, -- but only if there is only one out parameter for the procedure involved. -- The default is that this warning is suppressed, modified by use of -- -gnatwm/M. Warn_On_No_Value_Assigned : Boolean := True; -- GNAT -- Set to True to generate warnings if no value is ever assigned to a -- variable that is at least partially uninitialized. Set to false to -- suppress such warnings. The default is that such warnings are enabled. -- Modified by use of -gnatwv/V. Warn_On_Non_Local_Exception : Boolean := False; -- GNAT -- Set to True to generate warnings for non-local exception raises and also -- handlers that can never handle a local raise. This warning is only ever -- generated if pragma Restrictions (No_Exception_Propagation) is set. The -- default is not to generate the warnings except that if the source has -- at least one exception handler, and this restriction is set, and the -- warning was not explicitly turned off, then it is turned on by default. -- Modified by use of -gnatw.x/.X. No_Warn_On_Non_Local_Exception : Boolean := False; -- GNAT -- This is set to True if the above warning is explicitly suppressed. We -- use this to avoid turning it on by default when No_Exception_Propagation -- restriction is set and an exception handler is present. Warn_On_Object_Renames_Function : Boolean := False; -- GNAT -- Set to True to generate warnings when a function result is renamed as -- an object. The default is that this warning is disabled. Modified by -- use of -gnatw.r/.R. Warn_On_Obsolescent_Feature : Boolean := False; -- GNAT -- Set to True to generate warnings on use of any feature in Annex or if a -- subprogram is called for which a pragma Obsolescent applies. Modified -- by use of -gnatwj/J. Warn_On_Overlap : Boolean := False; -- GNAT -- Set to True to generate warnings when a writable actual overlaps with -- another actual in a subprogram call. This applies only in modes before -- Ada 2012. Starting with Ada 2012, such overlaps are illegal. -- Modified by use of -gnatw.i/.I. Warn_On_Questionable_Missing_Parens : Boolean := True; -- GNAT -- Set to True to generate warnings for cases where parentheses are missing -- and the usage is questionable, because the intent is unclear. On by -- default, modified by use of -gnatwq/Q. Warn_On_Parameter_Order : Boolean := False; -- GNAT -- Set to True to generate warnings for cases where the argument list for -- a call is a sequence of identifiers that match the formal identifiers, -- but are in the wrong order. Warn_On_Redundant_Constructs : Boolean := False; -- GNAT -- Set to True to generate warnings for redundant constructs (e.g. useless -- assignments/conversions). The default is that this warning is disabled. -- Modified by use of -gnatwr/R. Warn_On_Reverse_Bit_Order : Boolean := True; -- GNAT -- Set to True to generate warning (informational) messages for component -- clauses that are affected by non-standard bit-order. The default is -- that this warning is enabled. Modified by -gnatw.v/.V. Warn_On_Suspicious_Contract : Boolean := True; -- GNAT -- Set to True to generate warnings for suspicious contracts expressed as -- pragmas or aspects precondition and postcondition. The default is that -- this warning is enabled. Modified by use of -gnatw.t/.T. Warn_On_Suspicious_Modulus_Value : Boolean := True; -- GNAT -- Set to True to generate warnings for suspicious modulus values. The -- default is that this warning is enabled. Modified by -gnatw.m/.M. Warn_On_Unchecked_Conversion : Boolean := True; -- GNAT -- Set to True to generate warnings for unchecked conversions that may have -- non-portable semantics (e.g. because sizes of types differ). Modified -- by use of -gnatwz/Z. Warn_On_Unordered_Enumeration_Type : Boolean := False; -- GNAT -- Set to True to generate warnings for inappropriate uses (comparisons -- and explicit ranges) on unordered enumeration types (which includes -- all enumeration types for which pragma Ordered is not given). The -- default is that this warning is disabled. Modified by -gnat.u/.U. Warn_On_Unrecognized_Pragma : Boolean := True; -- GNAT -- Set to True to generate warnings for unrecognized pragmas. The default -- is that this warning is enabled. Modified by use of -gnatwg/G. Warn_On_Unrepped_Components : Boolean := False; -- GNAT -- Set to True to generate warnings for the case of components of record -- which have a record representation clause but this component does not -- have a component clause. Modified by use of -gnatw.c/.C. Warn_On_Warnings_Off : Boolean := False; -- GNAT -- Set to True to generate warnings for use of Pragma Warnings (Off, ent), -- where either the pragma is never used, or it could be replaced by a -- pragma Unmodified or Unreferenced. Also generates warnings for pragma -- Warning (Off, string) which either has no matching pragma Warning On, -- or where no warning has been suppressed by the use of the pragma. -- Modified by use of -gnatw.w/.W. type Warning_Mode_Type is (Suppress, Normal, Treat_As_Error); Warning_Mode : Warning_Mode_Type := Normal; -- GNAT, GNATBIND -- Controls treatment of warning messages. If set to Suppress, warning -- messages are not generated at all. In Normal mode, they are generated -- but do not count as errors. In Treat_As_Error mode, warning messages are -- generated and are treated as errors. Note that Warning_Mode = Suppress -- causes pragma Warnings to be ignored (except for legality checks), -- unless we are in GNATprove_Mode, which requires pragma Warnings to -- be stored for the formal verification backend. Warnings_As_Errors_Count : Natural; -- GNAT -- Number of entries stored in Warnings_As_Errors table Wide_Character_Encoding_Method : WC_Encoding_Method := WCEM_Brackets; -- GNAT, GNATBIND -- Method used for encoding wide characters in the source program. See -- description of type in unit System.WCh_Con for a list of the methods -- that are currently supported. Note that brackets notation is always -- recognized in source programs regardless of the setting of this -- variable. The default setting causes only the brackets notation to be -- recognized. If this is the main unit, this setting also controls the -- output of the W=? parameter in the ALI file, which is used to provide -- the default for encoding [Wide_[Wide_]]Text_IO files. For the binder, -- the value set here overrides this main unit default. Wide_Character_Encoding_Method_Specified : Boolean := False; -- GNAT, GNATBIND -- Set True if the value in Wide_Character_Encoding_Method was set as -- a result of an explicit -gnatW? or -W? switch. False otherwise. Xref_Active : Boolean := True; -- GNAT -- Set if cross-referencing is enabled (i.e. xref info in ALI files) Zero_Formatting : Boolean := False; -- GNATBIND -- Do no formatting (no title, no leading spaces, no empty lines) in -- auxiliary outputs (-e, -K, -l, -R). ---------------------------- -- Configuration Settings -- ---------------------------- -- These are settings that are used to establish the mode at the start of -- each unit. The values defined below can be affected either by command -- line switches, or by the use of appropriate configuration pragmas in a -- configuration pragma file (but NOT by a local use of a configuration -- pragma in a single file). Ada_Version_Config : Ada_Version_Type; -- GNAT -- This is the value of the configuration switch for the Ada 83 mode, as -- set by the command line switches -gnat83/95/2005/2012, and possibly -- modified by the use of configuration pragmas Ada_*. This switch is used -- to set the initial value for Ada_Version mode at the start of analysis -- of a unit. Note however that the setting of this flag is ignored for -- internal and predefined units (which are always compiled in the most up -- to date version of Ada). Ada_Version_Pragma_Config : Node_Id; -- This will be set non empty if it is set by a configuration pragma Ada_Version_Explicit_Config : Ada_Version_Type; -- GNAT -- This is set in the same manner as Ada_Version_Config. The difference is -- that the setting of this flag is not ignored for internal and predefined -- units, which for some purposes do indeed access this value, regardless -- of the fact that they are compiled the most up to date ada version). Assertions_Enabled_Config : Boolean; -- GNAT -- This is the value of the configuration switch for assertions enabled -- mode, as possibly set by the command line switch -gnata, and possibly -- modified by the use of the configuration pragma Assertion_Policy. Assume_No_Invalid_Values_Config : Boolean; -- GNAT -- This is the value of the configuration switch for assuming "no invalid -- values enabled" mode, as possibly set by the command line switch -- -gnatB, and possibly modified by the use of the configuration pragma -- Assume_No_Invalid_Values. Check_Float_Overflow_Config : Boolean; -- GNAT -- Set to True to check that operations on predefined unconstrained float -- types (e.g. Float, Long_Float) do not overflow and generate infinities -- or invalid values. Set by the Check_Float_Overflow pragma, or by use -- of the -gnateF switch. Check_Policy_List_Config : Node_Id; -- GNAT -- This points to the list of N_Pragma nodes for Check_Policy pragmas -- that are linked through the Next_Pragma fields, with the list being -- terminated by Empty. The order is most recently processed first. This -- list includes only those pragmas in configuration pragma files. Default_Pool_Config : Node_Id := Empty; -- GNAT -- Same as Default_Pool above, except this is only for Default_Storage_Pool -- pragmas that are configuration pragmas. Default_SSO_Config : Character := ' '; -- GNAT -- Set if a pragma Default_Scalar_Storage_Order appears as a configuration -- pragma. A value of ' ' means that no pragma was given, otherwise the -- value is 'H' for High_Order_First or 'L' for Low_Order_First. Dynamic_Elaboration_Checks_Config : Boolean := False; -- GNAT -- Set True for dynamic elaboration checking mode, as set by the -gnatE -- switch or by the use of pragma Elaboration_Checking (Dynamic). Exception_Locations_Suppressed_Config : Boolean := False; -- GNAT -- Set True by use of the configuration pragma Suppress_Exception_Messages Extensions_Allowed_Config : Boolean; -- GNAT -- This is the flag that indicates whether extensions are allowed. It can -- be set True either by use of the -gnatX switch, or by use of the -- configuration pragma Extensions_Allowed (On). It is always set to True -- for internal GNAT units, since extensions are always permitted in such -- units. External_Name_Exp_Casing_Config : External_Casing_Type; -- GNAT -- This is the value of the configuration switch that controls casing of -- external symbols for which an explicit external name is given. It can be -- set to Uppercase by the command line switch -gnatF, and further modified -- by the use of the configuration pragma External_Name_Casing in the -- gnat.adc file. This flag is used to set the initial value for -- External_Name_Exp_Casing at the start of analyzing each unit. Note -- however that the setting of this flag is ignored for internal and -- predefined units (which are always compiled with As_Is mode). External_Name_Imp_Casing_Config : External_Casing_Type; -- GNAT -- This is the value of the configuration switch that controls casing of -- external symbols where the external name is implicitly given. It can be -- set to Uppercase by the command line switch -gnatF, and further modified -- by the use of the configuration pragma External_Name_Casing in the -- gnat.adc file. This flag is used to set the initial value for -- External_Name_Imp_Casing at the start of analyzing each unit. Note -- however that the setting of this flag is ignored for internal and -- predefined units (which are always compiled with Lowercase mode). Fast_Math_Config : Boolean; -- GNAT -- This is the value of the configuration switch that controls Fast_Math -- mode, as set by a Fast_Math pragma in configuration pragmas. It is -- used to set the initial value of Fast_Math at the start of each new -- compilation unit. Initialize_Scalars_Config : Boolean; -- GNAT -- This is the value of the configuration switch that is set by the -- pragma Initialize_Scalars when it appears in the gnat.adc file. -- This switch is not set when the pragma appears ahead of a given -- unit, so it does not affect the compilation of other units. Optimize_Alignment_Config : Character; -- GNAT -- This is the value of the configuration switch that controls the -- alignment optimization mode, as set by an Optimize_Alignment pragma. -- It is used to set the initial value of Optimize_Alignment at the start -- of each new compilation unit, except that it is always set to 'O' (off) -- for internal units. Persistent_BSS_Mode_Config : Boolean; -- GNAT -- This is the value of the configuration switch that controls whether -- potentially persistent data is to be placed in the persistent_bss -- section. It can be set True by use of the pragma Persistent_BSS. -- This flag is used to set the initial value of Persistent_BSS_Mode -- at the start of each compilation unit, except that it is always -- set False for predefined units. Polling_Required_Config : Boolean; -- GNAT -- This is the value of the configuration switch that controls polling -- mode. It can be set True by the command line switch -gnatP, and then -- further modified by the use of pragma Polling in the gnat.adc file. This -- flag is used to set the initial value for Polling_Required at the start -- of analyzing each unit. Short_Descriptors_Config : Boolean; -- GNAT -- This is the value of the configuration switch that controls the use of -- Short_Descriptors for setting descriptor default sizes. It can be set -- True by the use of the pragma Short_Descriptors in the gnat.adc file. -- This flag is used to set the initial value for Short_Descriptors at the -- start of analyzing each unit. SPARK_Mode_Config : SPARK_Mode_Type := None; -- GNAT -- The setting of SPARK_Mode from configuration pragmas SPARK_Mode_Pragma_Config : Node_Id := Empty; -- If a SPARK_Mode pragma appeared in the configuration pragmas (setting -- SPARK_Mode_Config appropriately), then this points to the N_Pragma node. Uneval_Old_Config : Character; -- GNAT -- The setting of Uneval_Old from configuration pragmas Use_VADS_Size_Config : Boolean; -- GNAT -- This is the value of the configuration switch that controls the use of -- VADS_Size instead of Size wherever the attribute Size is used. It can -- be set True by the use of the pragma Use_VADS_Size in the gnat.adc file. -- This flag is used to set the initial value for Use_VADS_Size at the -- start of analyzing each unit. Note however that the setting of this flag -- is ignored for internal and predefined units (which are always compiled -- with the standard Size semantics). Warnings_As_Errors_Count_Config : Natural; -- GNAT -- Count of pattern strings stored from Warning_As_Error pragmas type Config_Switches_Type is private; -- Type used to save values of the switches set from Config values procedure Save_Opt_Config_Switches (Save : out Config_Switches_Type); -- This procedure saves the current values of the switches which are -- initialized from the above Config values, and then resets these switches -- according to the Config value settings. procedure Set_Opt_Config_Switches (Internal_Unit : Boolean; Main_Unit : Boolean); -- This procedure sets the switches to the appropriate initial values. The -- parameter Internal_Unit is True for an internal or predefined unit, and -- affects the way the switches are set (see above). Main_Unit is true if -- switches are being set for the main unit or for the spec of the main -- unit. This affects setting of the assert/debug pragma switches, which -- are normally set false by default for an internal unit, except when the -- internal unit is the main unit, in which case we use the command line -- settings). procedure Restore_Opt_Config_Switches (Save : Config_Switches_Type); -- This procedure restores a set of switch values previously saved by a -- call to Save_Opt_Config_Switches (Save). procedure Register_Opt_Config_Switches; -- This procedure is called after processing the gnat.adc file and other -- configuration pragma files to record the values of the Config switches, -- as possibly modified by the use of command line switches and pragmas -- appearing in these files. ------------------------ -- Other Global Flags -- ------------------------ Expander_Active : Boolean := False; -- A flag that indicates if expansion is active (True) or deactivated -- (False). When expansion is deactivated all calls to expander routines -- have no effect. Note that the initial setting of False is merely to -- prevent saving of an undefined value for an initial call to the -- Expander_Mode_Save_And_Set procedure. For more information on the use of -- this flag, see package Expander. Indeed this flag might more logically -- be in the spec of Expander, but it is referenced by Errout, and it -- really seems wrong for Errout to depend on Expander. Static_Dispatch_Tables : Boolean := True; -- This flag indicates if the backend supports generation of statically -- allocated dispatch tables. If it is True, then the front end will -- generate static aggregates for dispatch tables that contain forward -- references to addresses of subprograms not seen yet, and the back end -- must be prepared to handle this case. If it is False, then the front -- end generates assignments to initialize the dispatch table, and there -- are no such forward references. By default we build statically allocated -- dispatch tables for all library level tagged types in all platforms.This -- behavior can be disabled using switch -gnatd.t which will set this flag -- to False and revert to the previous dynamic behavior. ----------------------- -- Tree I/O Routines -- ----------------------- procedure Tree_Read; -- Reads switch settings from current tree file using Tree_Read procedure Tree_Write; -- Writes out switch settings to current tree file using Tree_Write -------------------------- -- ASIS Version Control -- -------------------------- -- These two variables (Tree_Version_String and Tree_ASIS_Version_Number) -- are supposed to be used in the GNAT/ASIS version check performed in -- the ASIS code (this package is also a part of the ASIS implementation). -- They are set by Tree_Read procedure, so they represent the version -- number (and the version string) of the compiler which has created the -- tree, and they are supposed to be compared with the corresponding values -- from the Tree_IO and Gnatvsn packages which also are a part of ASIS -- implementation. Tree_Version_String : String_Access; -- Used to store the compiler version string read from a tree file to check -- if it is from the same date as stored in the version string in Gnatvsn. -- We require that ASIS Pro can be used only with GNAT Pro, but we allow -- non-Pro ASIS and ASIS-based tools to be used with any version of the -- GNAT compiler. Therefore, we need the possibility to compare the dates -- of the corresponding source sets, using version strings that may be -- of different lengths. Tree_ASIS_Version_Number : Int; -- Used to store the ASIS version number read from a tree file to check if -- it is the same as stored in the ASIS version number in Tree_IO. ----------------------------------- -- Modes for Formal Verification -- ----------------------------------- GNATprove_Mode : Boolean := False; -- Specific compiling mode targeting formal verification for those parts -- of the input code that belong to the SPARK 2014 subset of Ada. Set True -- by the gnat2why executable or by use of the -gnatd.F debug switch. Note -- that this is completely separate from the SPARK restriction defined in -- GNAT to detect violations of a subset of SPARK 2005 rules. --------------------------- -- Error/Warning Control -- --------------------------- -- The following array would more reasonably be located in Err_Vars or -- Errour, but but we put them here to deal with licensing issues (we need -- this to have the GPL exception licensing, since these variables and -- subprograms are accessed from units with this licensing). Warnings_As_Errors : array (1 .. 10_000) of String_Ptr; -- Table for recording Warning_As_Error pragmas as they are processed. -- It would be nicer to use Table, but there are circular elaboration -- problems if we try to do this, and an attempt to find some other -- appropriately licensed unit to declare this as a Table failed with -- various elaboration circularities. Memory is getting cheap these days! -------------------------- -- Private Declarations -- -------------------------- private -- The following type is used to save and restore settings of switches in -- Opt that represent the configuration (i.e. result of config pragmas). -- Note that Ada_Version_Explicit is not included, since this is a sticky -- flag that once set does not get reset, since the whole idea of this flag -- is to record the setting for the main unit. type Config_Switches_Type is record Ada_Version : Ada_Version_Type; Ada_Version_Explicit : Ada_Version_Type; Ada_Version_Pragma : Node_Id; Assertions_Enabled : Boolean; Assume_No_Invalid_Values : Boolean; Check_Float_Overflow : Boolean; Check_Policy_List : Node_Id; Default_Pool : Node_Id; Default_SSO : Character; Dynamic_Elaboration_Checks : Boolean; Exception_Locations_Suppressed : Boolean; Extensions_Allowed : Boolean; External_Name_Exp_Casing : External_Casing_Type; External_Name_Imp_Casing : External_Casing_Type; Fast_Math : Boolean; Initialize_Scalars : Boolean; Normalize_Scalars : Boolean; Optimize_Alignment : Character; Optimize_Alignment_Local : Boolean; Persistent_BSS_Mode : Boolean; Polling_Required : Boolean; Short_Descriptors : Boolean; SPARK_Mode : SPARK_Mode_Type; SPARK_Mode_Pragma : Node_Id; Uneval_Old : Character; Use_VADS_Size : Boolean; Warnings_As_Errors_Count : Natural; end record; -- The following declarations are for GCC version dependent flags. We do -- not let client code in the compiler test GCC_Version directly, but -- instead use deferred constants for relevant feature tags. -- Note: there currently are no such constants defined in this section, -- since the compiler front end is currently entirely independent of the -- GCC version, which is a desirable state of affairs. function get_gcc_version return Int; pragma Import (C, get_gcc_version, "get_gcc_version"); GCC_Version : constant Nat := get_gcc_version; -- GNATMAKE -- Indicates which version of gcc is in use (3 = 3.x, 4 = 4.x). Note that -- gcc 2.8.1 (which used to be a value of 2) is no longer supported. end Opt; gprbuild-gpl-2014-src/gnat/prj-conf.adb0000644000076700001450000020224412323721731017256 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . C O N F -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Hostparm; with Makeutl; use Makeutl; with MLib.Tgt; with Opt; use Opt; with Output; use Output; with Prj.Env; with Prj.Err; with Prj.Part; with Prj.PP; with Prj.Proc; use Prj.Proc; with Prj.Tree; use Prj.Tree; with Prj.Util; use Prj.Util; with Prj; use Prj; with Snames; use Snames; with Ada.Directories; use Ada.Directories; with Ada.Exceptions; use Ada.Exceptions; with GNAT.Case_Util; use GNAT.Case_Util; with GNAT.HTable; use GNAT.HTable; package body Prj.Conf is Auto_Cgpr : constant String := "auto.cgpr"; Config_Project_Env_Var : constant String := "GPR_CONFIG"; -- Name of the environment variable that provides the name of the -- configuration file to use. Gprconfig_Name : constant String := "gprconfig"; package RTS_Languages is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Name_Id, No_Element => No_Name, Key => Name_Id, Hash => Prj.Hash, Equal => "="); -- Stores the runtime names for the various languages. This is in general -- set from a --RTS command line option. ----------------------- -- Local_Subprograms -- ----------------------- function Check_Target (Config_File : Prj.Project_Id; Autoconf_Specified : Boolean; Project_Tree : Prj.Project_Tree_Ref; Target : String := "") return Boolean; -- Check that the config file's target matches Target. -- Target should be set to the empty string when the user did not specify -- a target. If the target in the configuration file is invalid, this -- function will raise Invalid_Config with an appropriate message. -- Autoconf_Specified should be set to True if the user has used -- autoconf. function Locate_Config_File (Name : String) return String_Access; -- Search for Name in the config files directory. Return full path if -- found, or null otherwise. procedure Raise_Invalid_Config (Msg : String); pragma No_Return (Raise_Invalid_Config); -- Raises exception Invalid_Config with given message procedure Apply_Config_File (Config_File : Prj.Project_Id; Project_Tree : Prj.Project_Tree_Ref); -- Apply the configuration file settings to all the projects in the -- project tree. The Project_Tree must have been parsed first, and -- processed through the first phase so that all its projects are known. -- -- Currently, this will add new attributes and packages in the various -- projects, so that when the second phase of the processing is performed -- these attributes are automatically taken into account. ------------------------------------ -- Add_Default_GNAT_Naming_Scheme -- ------------------------------------ procedure Add_Default_GNAT_Naming_Scheme (Config_File : in out Project_Node_Id; Project_Tree : Project_Node_Tree_Ref) is procedure Create_Attribute (Name : Name_Id; Value : String; Index : String := ""; Pkg : Project_Node_Id := Empty_Node); ---------------------- -- Create_Attribute -- ---------------------- procedure Create_Attribute (Name : Name_Id; Value : String; Index : String := ""; Pkg : Project_Node_Id := Empty_Node) is Attr : Project_Node_Id; pragma Unreferenced (Attr); Expr : Name_Id := No_Name; Val : Name_Id := No_Name; Parent : Project_Node_Id := Config_File; begin if Index /= "" then Name_Len := Index'Length; Name_Buffer (1 .. Name_Len) := Index; Val := Name_Find; end if; if Pkg /= Empty_Node then Parent := Pkg; end if; Name_Len := Value'Length; Name_Buffer (1 .. Name_Len) := Value; Expr := Name_Find; Attr := Create_Attribute (Tree => Project_Tree, Prj_Or_Pkg => Parent, Name => Name, Index_Name => Val, Kind => Prj.Single, Value => Create_Literal_String (Expr, Project_Tree)); end Create_Attribute; -- Local variables Name : Name_Id; Naming : Project_Node_Id; Compiler : Project_Node_Id; -- Start of processing for Add_Default_GNAT_Naming_Scheme begin if Config_File = Empty_Node then -- Create a dummy config file is none was found Name_Len := Auto_Cgpr'Length; Name_Buffer (1 .. Name_Len) := Auto_Cgpr; Name := Name_Find; -- An invalid project name to avoid conflicts with user-created ones Name_Len := 5; Name_Buffer (1 .. Name_Len) := "_auto"; Config_File := Create_Project (In_Tree => Project_Tree, Name => Name_Find, Full_Path => Path_Name_Type (Name), Is_Config_File => True); -- Setup library support case MLib.Tgt.Support_For_Libraries is when None => null; when Static_Only => Create_Attribute (Name_Library_Support, "static_only"); when Full => Create_Attribute (Name_Library_Support, "full"); end case; if MLib.Tgt.Standalone_Library_Auto_Init_Is_Supported then Create_Attribute (Name_Library_Auto_Init_Supported, "true"); else Create_Attribute (Name_Library_Auto_Init_Supported, "false"); end if; -- Declare an empty target Create_Attribute (Name_Target, ""); -- Setup Ada support (Ada is the default language here, since this -- is only called when no config file existed initially, ie for -- gnatmake). Create_Attribute (Name_Default_Language, "ada"); Compiler := Create_Package (Project_Tree, Config_File, "compiler"); Create_Attribute (Name_Driver, "gcc", "ada", Pkg => Compiler); Create_Attribute (Name_Language_Kind, "unit_based", "ada", Pkg => Compiler); Create_Attribute (Name_Dependency_Kind, "ALI_File", "ada", Pkg => Compiler); Naming := Create_Package (Project_Tree, Config_File, "naming"); Create_Attribute (Name_Spec_Suffix, ".ads", "ada", Pkg => Naming); Create_Attribute (Name_Separate_Suffix, ".adb", "ada", Pkg => Naming); Create_Attribute (Name_Body_Suffix, ".adb", "ada", Pkg => Naming); Create_Attribute (Name_Dot_Replacement, "-", Pkg => Naming); Create_Attribute (Name_Casing, "lowercase", Pkg => Naming); if Current_Verbosity = High then Write_Line ("Automatically generated (in-memory) config file"); Prj.PP.Pretty_Print (Project => Config_File, In_Tree => Project_Tree, Backward_Compatibility => False); end if; end if; end Add_Default_GNAT_Naming_Scheme; ----------------------- -- Apply_Config_File -- ----------------------- procedure Apply_Config_File (Config_File : Prj.Project_Id; Project_Tree : Prj.Project_Tree_Ref) is procedure Add_Attributes (Project_Tree : Project_Tree_Ref; Conf_Decl : Declarations; User_Decl : in out Declarations); -- Process the attributes in the config declarations. For -- single string values, if the attribute is not declared in -- the user declarations, declare it with the value in the -- config declarations. For string list values, prepend the -- value in the user declarations with the value in the config -- declarations. -------------------- -- Add_Attributes -- -------------------- procedure Add_Attributes (Project_Tree : Project_Tree_Ref; Conf_Decl : Declarations; User_Decl : in out Declarations) is Shared : constant Shared_Project_Tree_Data_Access := Project_Tree.Shared; Conf_Attr_Id : Variable_Id; Conf_Attr : Variable; Conf_Array_Id : Array_Id; Conf_Array : Array_Data; Conf_Array_Elem_Id : Array_Element_Id; Conf_Array_Elem : Array_Element; Conf_List : String_List_Id; Conf_List_Elem : String_Element; User_Attr_Id : Variable_Id; User_Attr : Variable; User_Array_Id : Array_Id; User_Array : Array_Data; User_Array_Elem_Id : Array_Element_Id; User_Array_Elem : Array_Element; begin Conf_Attr_Id := Conf_Decl.Attributes; User_Attr_Id := User_Decl.Attributes; while Conf_Attr_Id /= No_Variable loop Conf_Attr := Shared.Variable_Elements.Table (Conf_Attr_Id); User_Attr := Shared.Variable_Elements.Table (User_Attr_Id); if not Conf_Attr.Value.Default then if User_Attr.Value.Default then -- No attribute declared in user project file: just copy -- the value of the configuration attribute. User_Attr.Value := Conf_Attr.Value; Shared.Variable_Elements.Table (User_Attr_Id) := User_Attr; elsif User_Attr.Value.Kind = List and then Conf_Attr.Value.Values /= Nil_String then -- List attribute declared in both the user project and the -- configuration project: prepend the user list with the -- configuration list. declare User_List : constant String_List_Id := User_Attr.Value.Values; Conf_List : String_List_Id := Conf_Attr.Value.Values; Conf_Elem : String_Element; New_List : String_List_Id; New_Elem : String_Element; begin -- Create new list String_Element_Table.Increment_Last (Shared.String_Elements); New_List := String_Element_Table.Last (Shared.String_Elements); -- Value of attribute is new list User_Attr.Value.Values := New_List; Shared.Variable_Elements.Table (User_Attr_Id) := User_Attr; loop -- Get each element of configuration list Conf_Elem := Shared.String_Elements.Table (Conf_List); New_Elem := Conf_Elem; Conf_List := Conf_Elem.Next; if Conf_List = Nil_String then -- If it is the last element in the list, connect -- to first element of user list, and we are done. New_Elem.Next := User_List; Shared.String_Elements.Table (New_List) := New_Elem; exit; else -- If it is not the last element in the list, add -- to new list. String_Element_Table.Increment_Last (Shared.String_Elements); New_Elem.Next := String_Element_Table.Last (Shared.String_Elements); Shared.String_Elements.Table (New_List) := New_Elem; New_List := New_Elem.Next; end if; end loop; end; end if; end if; Conf_Attr_Id := Conf_Attr.Next; User_Attr_Id := User_Attr.Next; end loop; Conf_Array_Id := Conf_Decl.Arrays; while Conf_Array_Id /= No_Array loop Conf_Array := Shared.Arrays.Table (Conf_Array_Id); User_Array_Id := User_Decl.Arrays; while User_Array_Id /= No_Array loop User_Array := Shared.Arrays.Table (User_Array_Id); exit when User_Array.Name = Conf_Array.Name; User_Array_Id := User_Array.Next; end loop; -- If this associative array does not exist in the user project -- file, do a shallow copy of the full associative array. if User_Array_Id = No_Array then Array_Table.Increment_Last (Shared.Arrays); User_Array := Conf_Array; User_Array.Next := User_Decl.Arrays; User_Decl.Arrays := Array_Table.Last (Shared.Arrays); Shared.Arrays.Table (User_Decl.Arrays) := User_Array; -- Otherwise, check each array element else Conf_Array_Elem_Id := Conf_Array.Value; while Conf_Array_Elem_Id /= No_Array_Element loop Conf_Array_Elem := Shared.Array_Elements.Table (Conf_Array_Elem_Id); User_Array_Elem_Id := User_Array.Value; while User_Array_Elem_Id /= No_Array_Element loop User_Array_Elem := Shared.Array_Elements.Table (User_Array_Elem_Id); exit when User_Array_Elem.Index = Conf_Array_Elem.Index; User_Array_Elem_Id := User_Array_Elem.Next; end loop; -- If the array element doesn't exist in the user array, -- insert a shallow copy of the conf array element in the -- user array. if User_Array_Elem_Id = No_Array_Element then Array_Element_Table.Increment_Last (Shared.Array_Elements); User_Array_Elem := Conf_Array_Elem; User_Array_Elem.Next := User_Array.Value; User_Array.Value := Array_Element_Table.Last (Shared.Array_Elements); Shared.Array_Elements.Table (User_Array.Value) := User_Array_Elem; Shared.Arrays.Table (User_Array_Id) := User_Array; -- Otherwise, if the value is a string list, prepend the -- conf array element value to the array element. elsif Conf_Array_Elem.Value.Kind = List then Conf_List := Conf_Array_Elem.Value.Values; if Conf_List /= Nil_String then declare Link : constant String_List_Id := User_Array_Elem.Value.Values; Previous : String_List_Id := Nil_String; Next : String_List_Id; begin loop Conf_List_Elem := Shared.String_Elements.Table (Conf_List); String_Element_Table.Increment_Last (Shared.String_Elements); Next := String_Element_Table.Last (Shared.String_Elements); Shared.String_Elements.Table (Next) := Conf_List_Elem; if Previous = Nil_String then User_Array_Elem.Value.Values := Next; Shared.Array_Elements.Table (User_Array_Elem_Id) := User_Array_Elem; else Shared.String_Elements.Table (Previous).Next := Next; end if; Previous := Next; Conf_List := Conf_List_Elem.Next; if Conf_List = Nil_String then Shared.String_Elements.Table (Previous).Next := Link; exit; end if; end loop; end; end if; end if; Conf_Array_Elem_Id := Conf_Array_Elem.Next; end loop; end if; Conf_Array_Id := Conf_Array.Next; end loop; end Add_Attributes; Shared : constant Shared_Project_Tree_Data_Access := Project_Tree.Shared; Conf_Decl : constant Declarations := Config_File.Decl; Conf_Pack_Id : Package_Id; Conf_Pack : Package_Element; User_Decl : Declarations; User_Pack_Id : Package_Id; User_Pack : Package_Element; Proj : Project_List; begin Debug_Output ("Applying config file to a project tree"); Proj := Project_Tree.Projects; while Proj /= null loop if Proj.Project /= Config_File then User_Decl := Proj.Project.Decl; Add_Attributes (Project_Tree => Project_Tree, Conf_Decl => Conf_Decl, User_Decl => User_Decl); Conf_Pack_Id := Conf_Decl.Packages; while Conf_Pack_Id /= No_Package loop Conf_Pack := Shared.Packages.Table (Conf_Pack_Id); User_Pack_Id := User_Decl.Packages; while User_Pack_Id /= No_Package loop User_Pack := Shared.Packages.Table (User_Pack_Id); exit when User_Pack.Name = Conf_Pack.Name; User_Pack_Id := User_Pack.Next; end loop; if User_Pack_Id = No_Package then Package_Table.Increment_Last (Shared.Packages); User_Pack := Conf_Pack; User_Pack.Next := User_Decl.Packages; User_Decl.Packages := Package_Table.Last (Shared.Packages); Shared.Packages.Table (User_Decl.Packages) := User_Pack; else Add_Attributes (Project_Tree => Project_Tree, Conf_Decl => Conf_Pack.Decl, User_Decl => Shared.Packages.Table (User_Pack_Id).Decl); end if; Conf_Pack_Id := Conf_Pack.Next; end loop; Proj.Project.Decl := User_Decl; -- For aggregate projects, we need to apply the config to all -- their aggregated trees as well. if Proj.Project.Qualifier in Aggregate_Project then declare List : Aggregated_Project_List; begin List := Proj.Project.Aggregated_Projects; while List /= null loop Debug_Output ("Recursively apply config to aggregated tree", List.Project.Name); Apply_Config_File (Config_File, Project_Tree => List.Tree); List := List.Next; end loop; end; end if; end if; Proj := Proj.Next; end loop; end Apply_Config_File; ------------------ -- Check_Target -- ------------------ function Check_Target (Config_File : Project_Id; Autoconf_Specified : Boolean; Project_Tree : Prj.Project_Tree_Ref; Target : String := "") return Boolean is Shared : constant Shared_Project_Tree_Data_Access := Project_Tree.Shared; Variable : constant Variable_Value := Value_Of (Name_Target, Config_File.Decl.Attributes, Shared); Tgt_Name : Name_Id := No_Name; OK : Boolean; begin if Variable /= Nil_Variable_Value and then not Variable.Default then Tgt_Name := Variable.Value; end if; OK := Target = "" or else (Tgt_Name /= No_Name and then (Length_Of_Name (Tgt_Name) = 0 or else Target = Get_Name_String (Tgt_Name))); if not OK then if Autoconf_Specified then if Verbose_Mode then Write_Line ("inconsistent targets, performing autoconf"); end if; return False; else if Tgt_Name /= No_Name then Raise_Invalid_Config ("invalid target name """ & Get_Name_String (Tgt_Name) & """ in configuration"); else Raise_Invalid_Config ("no target specified in configuration file"); end if; end if; end if; return True; end Check_Target; -------------------------------------- -- Get_Or_Create_Configuration_File -- -------------------------------------- procedure Get_Or_Create_Configuration_File (Project : Project_Id; Conf_Project : Project_Id; Project_Tree : Project_Tree_Ref; Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref; Env : in out Prj.Tree.Environment; Allow_Automatic_Generation : Boolean; Config_File_Name : String := ""; Autoconf_Specified : Boolean; Target_Name : String := ""; Normalized_Hostname : String; Packages_To_Check : String_List_Access := null; Config : out Prj.Project_Id; Config_File_Path : out String_Access; Automatically_Generated : out Boolean; On_Load_Config : Config_File_Hook := null) is Shared : constant Shared_Project_Tree_Data_Access := Project_Tree.Shared; At_Least_One_Compiler_Command : Boolean := False; -- Set to True if at least one attribute Ide'Compiler_Command is -- specified for one language of the system. Conf_File_Name : String_Access := new String'(Config_File_Name); -- The configuration project file name. May be modified if there are -- switches --config= in the Builder package of the main project. Selected_Target : String_Access := new String'(Target_Name); function Default_File_Name return String; -- Return the name of the default config file that should be tested procedure Do_Autoconf; -- Generate a new config file through gprconfig. In case of error, this -- raises the Invalid_Config exception with an appropriate message procedure Check_Builder_Switches; -- Check for switches --config and --RTS in package Builder procedure Get_Project_Target; -- If Target_Name is empty, get the specified target in the project -- file, if any. function Get_Config_Switches return Argument_List_Access; -- Return the --config switches to use for gprconfig function Get_Db_Switches return Argument_List_Access; -- Return the --db switches to use for gprconfig function Might_Have_Sources (Project : Project_Id) return Boolean; -- True if the specified project might have sources (ie the user has not -- explicitly specified it. We haven't checked the file system, nor do -- we need to at this stage. ---------------------------- -- Check_Builder_Switches -- ---------------------------- procedure Check_Builder_Switches is Get_RTS_Switches : constant Boolean := RTS_Languages.Get_First = No_Name; -- If no switch --RTS have been specified on the command line, look -- for --RTS switches in the Builder switches. Builder : constant Package_Id := Value_Of (Name_Builder, Project.Decl.Packages, Shared); Switch_Array_Id : Array_Element_Id; -- The Switches to be checked procedure Check_Switches; -- Check the switches in Switch_Array_Id -------------------- -- Check_Switches -- -------------------- procedure Check_Switches is Switch_Array : Array_Element; Switch_List : String_List_Id := Nil_String; Switch : String_Element; Lang : Name_Id; Lang_Last : Positive; begin while Switch_Array_Id /= No_Array_Element loop Switch_Array := Shared.Array_Elements.Table (Switch_Array_Id); Switch_List := Switch_Array.Value.Values; List_Loop : while Switch_List /= Nil_String loop Switch := Shared.String_Elements.Table (Switch_List); if Switch.Value /= No_Name then Get_Name_String (Switch.Value); if Conf_File_Name'Length = 0 and then Name_Len > 9 and then Name_Buffer (1 .. 9) = "--config=" then Conf_File_Name := new String'(Name_Buffer (10 .. Name_Len)); elsif Get_RTS_Switches and then Name_Len >= 7 and then Name_Buffer (1 .. 5) = "--RTS" then if Name_Buffer (6) = '=' then if not Runtime_Name_Set_For (Name_Ada) then Set_Runtime_For (Name_Ada, Name_Buffer (7 .. Name_Len)); Locate_Runtime (Name_Ada, Project_Tree, Env); end if; elsif Name_Len > 7 and then Name_Buffer (6) = ':' and then Name_Buffer (7) /= '=' then Lang_Last := 7; while Lang_Last < Name_Len and then Name_Buffer (Lang_Last + 1) /= '=' loop Lang_Last := Lang_Last + 1; end loop; if Name_Buffer (Lang_Last + 1) = '=' then declare RTS : constant String := Name_Buffer (Lang_Last + 2 .. Name_Len); begin Name_Buffer (1 .. Lang_Last - 6) := Name_Buffer (7 .. Lang_Last); Name_Len := Lang_Last - 6; To_Lower (Name_Buffer (1 .. Name_Len)); Lang := Name_Find; if not Runtime_Name_Set_For (Lang) then Set_Runtime_For (Lang, RTS); Locate_Runtime (Lang, Project_Tree, Env); end if; end; end if; end if; end if; end if; Switch_List := Switch.Next; end loop List_Loop; Switch_Array_Id := Switch_Array.Next; end loop; end Check_Switches; -- Start of processing for Check_Builder_Switches begin if Builder /= No_Package then Switch_Array_Id := Value_Of (Name => Name_Switches, In_Arrays => Shared.Packages.Table (Builder).Decl.Arrays, Shared => Shared); Check_Switches; Switch_Array_Id := Value_Of (Name => Name_Default_Switches, In_Arrays => Shared.Packages.Table (Builder).Decl.Arrays, Shared => Shared); Check_Switches; end if; end Check_Builder_Switches; ------------------------ -- Get_Project_Target -- ------------------------ procedure Get_Project_Target is begin if Selected_Target'Length = 0 then -- Check if attribute Target is specified in the main -- project, or in a project it extends. If it is, use this -- target to invoke gprconfig. declare Variable : Variable_Value; Proj : Project_Id; Tgt_Name : Name_Id := No_Name; begin Proj := Project; Project_Loop : while Proj /= No_Project loop Variable := Value_Of (Name_Target, Proj.Decl.Attributes, Shared); if Variable /= Nil_Variable_Value and then not Variable.Default and then Variable.Value /= No_Name then Tgt_Name := Variable.Value; exit Project_Loop; end if; Proj := Proj.Extends; end loop Project_Loop; if Tgt_Name /= No_Name then Selected_Target := new String'(Get_Name_String (Tgt_Name)); end if; end; end if; end Get_Project_Target; ----------------------- -- Default_File_Name -- ----------------------- function Default_File_Name return String is Ada_RTS : constant String := Runtime_Name_For (Name_Ada); Tmp : String_Access; begin if Selected_Target'Length /= 0 then if Ada_RTS /= "" then return Selected_Target.all & '-' & Ada_RTS & Config_Project_File_Extension; else return Selected_Target.all & Config_Project_File_Extension; end if; elsif Ada_RTS /= "" then return Ada_RTS & Config_Project_File_Extension; else Tmp := Getenv (Config_Project_Env_Var); declare T : constant String := Tmp.all; begin Free (Tmp); if T'Length = 0 then return Default_Config_Name; else return T; end if; end; end if; end Default_File_Name; ----------------- -- Do_Autoconf -- ----------------- procedure Do_Autoconf is Obj_Dir : constant Variable_Value := Value_Of (Name_Object_Dir, Conf_Project.Decl.Attributes, Shared); Gprconfig_Path : String_Access; Success : Boolean; begin Gprconfig_Path := Locate_Exec_On_Path (Gprconfig_Name); if Gprconfig_Path = null then Raise_Invalid_Config ("could not locate gprconfig for auto-configuration"); end if; -- First, find the object directory of the Conf_Project if Obj_Dir = Nil_Variable_Value or else Obj_Dir.Default then Get_Name_String (Conf_Project.Directory.Display_Name); else if Is_Absolute_Path (Get_Name_String (Obj_Dir.Value)) then Get_Name_String (Obj_Dir.Value); else Name_Len := 0; Add_Str_To_Name_Buffer (Get_Name_String (Conf_Project.Directory.Display_Name)); Add_Str_To_Name_Buffer (Get_Name_String (Obj_Dir.Value)); end if; end if; if Subdirs /= null then Add_Char_To_Name_Buffer (Directory_Separator); Add_Str_To_Name_Buffer (Subdirs.all); end if; for J in 1 .. Name_Len loop if Name_Buffer (J) = '/' then Name_Buffer (J) := Directory_Separator; end if; end loop; -- Make sure that Obj_Dir ends with a directory separator if Name_Buffer (Name_Len) /= Directory_Separator then Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := Directory_Separator; end if; declare Obj_Dir : constant String := Name_Buffer (1 .. Name_Len); Config_Switches : Argument_List_Access; Db_Switches : Argument_List_Access; Args : Argument_List (1 .. 5); Arg_Last : Positive; Obj_Dir_Exists : Boolean := True; begin -- Check if the object directory exists. If Setup_Projects is True -- (-p) and directory does not exist, attempt to create it. -- Otherwise, if directory does not exist, fail without calling -- gprconfig. if not Is_Directory (Obj_Dir) and then (Setup_Projects or else Subdirs /= null) then begin Create_Path (Obj_Dir); if not Quiet_Output then Write_Str ("object directory """); Write_Str (Obj_Dir); Write_Line (""" created"); end if; exception when others => Raise_Invalid_Config ("could not create object directory " & Obj_Dir); end; end if; if not Is_Directory (Obj_Dir) then case Env.Flags.Require_Obj_Dirs is when Error => Raise_Invalid_Config ("object directory " & Obj_Dir & " does not exist"); when Warning => Prj.Err.Error_Msg (Env.Flags, "?object directory " & Obj_Dir & " does not exist"); Obj_Dir_Exists := False; when Silent => null; end case; end if; -- Get the config switches. This should be done only now, as some -- runtimes may have been found if the Builder switches. Config_Switches := Get_Config_Switches; -- Get eventual --db switches Db_Switches := Get_Db_Switches; -- Invoke gprconfig Args (1) := new String'("--batch"); Args (2) := new String'("-o"); -- If no config file was specified, set the auto.cgpr one if Conf_File_Name'Length = 0 then if Obj_Dir_Exists then Args (3) := new String'(Obj_Dir & Auto_Cgpr); else declare Path_FD : File_Descriptor; Path_Name : Path_Name_Type; begin Prj.Env.Create_Temp_File (Shared => Project_Tree.Shared, Path_FD => Path_FD, Path_Name => Path_Name, File_Use => "configuration file"); if Path_FD /= Invalid_FD then declare Temp_Dir : constant String := Containing_Directory (Get_Name_String (Path_Name)); begin GNAT.OS_Lib.Close (Path_FD); Args (3) := new String'(Temp_Dir & Directory_Separator & Auto_Cgpr); Delete_File (Get_Name_String (Path_Name)); end; else -- We'll have an error message later on Args (3) := new String'(Obj_Dir & Auto_Cgpr); end if; end; end if; else Args (3) := Conf_File_Name; end if; if Normalized_Hostname = "" then Arg_Last := 3; else if Selected_Target'Length = 0 then if At_Least_One_Compiler_Command then Args (4) := new String'("--target=all"); else Args (4) := new String'("--target=" & Normalized_Hostname); end if; else Args (4) := new String'("--target=" & Selected_Target.all); end if; Arg_Last := 4; end if; if not Verbose_Mode then Arg_Last := Arg_Last + 1; Args (Arg_Last) := new String'("-q"); end if; if Verbose_Mode then Write_Str (Gprconfig_Name); for J in 1 .. Arg_Last loop Write_Char (' '); Write_Str (Args (J).all); end loop; for J in Config_Switches'Range loop Write_Char (' '); Write_Str (Config_Switches (J).all); end loop; for J in Db_Switches'Range loop Write_Char (' '); Write_Str (Db_Switches (J).all); end loop; Write_Eol; elsif not Quiet_Output then -- Display no message if we are creating auto.cgpr, unless in -- verbose mode if Config_File_Name'Length > 0 or else Verbose_Mode then Write_Str ("creating "); Write_Str (Simple_Name (Args (3).all)); Write_Eol; end if; end if; Spawn (Gprconfig_Path.all, Args (1 .. Arg_Last) & Config_Switches.all & Db_Switches.all, Success); Free (Config_Switches); Config_File_Path := Locate_Config_File (Args (3).all); if Config_File_Path = null then Raise_Invalid_Config ("could not create " & Args (3).all); end if; for F in Args'Range loop Free (Args (F)); end loop; end; end Do_Autoconf; --------------------- -- Get_Db_Switches -- --------------------- function Get_Db_Switches return Argument_List_Access is Result : Argument_List_Access; Nmb_Arg : Natural; begin Nmb_Arg := (2 * Db_Switch_Args.Last) + Boolean'Pos (not Load_Standard_Base); Result := new Argument_List (1 .. Nmb_Arg); if Nmb_Arg /= 0 then for J in 1 .. Db_Switch_Args.Last loop Result (2 * J - 1) := new String'("--db"); Result (2 * J) := new String'(Get_Name_String (Db_Switch_Args.Table (J))); end loop; if not Load_Standard_Base then Result (Result'Last) := new String'("--db-"); end if; end if; return Result; end Get_Db_Switches; ------------------------- -- Get_Config_Switches -- ------------------------- function Get_Config_Switches return Argument_List_Access is package Language_Htable is new GNAT.HTable.Simple_HTable (Header_Num => Prj.Header_Num, Element => Name_Id, No_Element => No_Name, Key => Name_Id, Hash => Prj.Hash, Equal => "="); -- Hash table to keep the languages used in the project tree IDE : constant Package_Id := Value_Of (Name_Ide, Project.Decl.Packages, Shared); procedure Add_Config_Switches_For_Project (Project : Project_Id; Tree : Project_Tree_Ref; With_State : in out Integer); -- Add all --config switches for this project. This is also called -- for aggregate projects. ------------------------------------- -- Add_Config_Switches_For_Project -- ------------------------------------- procedure Add_Config_Switches_For_Project (Project : Project_Id; Tree : Project_Tree_Ref; With_State : in out Integer) is pragma Unreferenced (With_State); Shared : constant Shared_Project_Tree_Data_Access := Tree.Shared; Variable : Variable_Value; Check_Default : Boolean; Lang : Name_Id; List : String_List_Id; Elem : String_Element; begin if Might_Have_Sources (Project) then Variable := Value_Of (Name_Languages, Project.Decl.Attributes, Shared); if Variable = Nil_Variable_Value or else Variable.Default then -- Languages is not declared. If it is not an extending -- project, or if it extends a project with no Languages, -- check for Default_Language. Check_Default := Project.Extends = No_Project; if not Check_Default then Variable := Value_Of (Name_Languages, Project.Extends.Decl.Attributes, Shared); Check_Default := Variable /= Nil_Variable_Value and then Variable.Values = Nil_String; end if; if Check_Default then Variable := Value_Of (Name_Default_Language, Project.Decl.Attributes, Shared); if Variable /= Nil_Variable_Value and then not Variable.Default then Get_Name_String (Variable.Value); To_Lower (Name_Buffer (1 .. Name_Len)); Lang := Name_Find; Language_Htable.Set (Lang, Lang); -- If no default language is declared, default to Ada else Language_Htable.Set (Name_Ada, Name_Ada); end if; end if; elsif Variable.Values /= Nil_String then -- Attribute Languages is declared with a non empty list: -- put all the languages in Language_HTable. List := Variable.Values; while List /= Nil_String loop Elem := Shared.String_Elements.Table (List); Get_Name_String (Elem.Value); To_Lower (Name_Buffer (1 .. Name_Len)); Lang := Name_Find; Language_Htable.Set (Lang, Lang); List := Elem.Next; end loop; end if; end if; end Add_Config_Switches_For_Project; procedure For_Every_Imported_Project is new For_Every_Project_Imported (State => Integer, Action => Add_Config_Switches_For_Project); -- Document this procedure ??? -- Local variables Name : Name_Id; Count : Natural; Result : Argument_List_Access; Variable : Variable_Value; Dummy : Integer := 0; -- Start of processing for Get_Config_Switches begin For_Every_Imported_Project (By => Project, Tree => Project_Tree, With_State => Dummy, Include_Aggregated => True); Name := Language_Htable.Get_First; Count := 0; while Name /= No_Name loop Count := Count + 1; Name := Language_Htable.Get_Next; end loop; Result := new String_List (1 .. Count); Count := 1; Name := Language_Htable.Get_First; while Name /= No_Name loop -- Check if IDE'Compiler_Command is declared for the language. -- If it is, use its value to invoke gprconfig. Variable := Value_Of (Name, Attribute_Or_Array_Name => Name_Compiler_Command, In_Package => IDE, Shared => Shared, Force_Lower_Case_Index => True); declare Config_Command : constant String := "--config=" & Get_Name_String (Name); Runtime_Name : constant String := Runtime_Name_For (Name); begin if Variable = Nil_Variable_Value or else Length_Of_Name (Variable.Value) = 0 then Result (Count) := new String'(Config_Command & ",," & Runtime_Name); else At_Least_One_Compiler_Command := True; declare Compiler_Command : constant String := Get_Name_String (Variable.Value); begin if Is_Absolute_Path (Compiler_Command) then Result (Count) := new String' (Config_Command & ",," & Runtime_Name & "," & Containing_Directory (Compiler_Command) & "," & Simple_Name (Compiler_Command)); else Result (Count) := new String' (Config_Command & ",," & Runtime_Name & ",," & Compiler_Command); end if; end; end if; end; Count := Count + 1; Name := Language_Htable.Get_Next; end loop; return Result; end Get_Config_Switches; ------------------------ -- Might_Have_Sources -- ------------------------ function Might_Have_Sources (Project : Project_Id) return Boolean is Variable : Variable_Value; begin Variable := Value_Of (Name_Source_Dirs, Project.Decl.Attributes, Shared); if Variable = Nil_Variable_Value or else Variable.Default or else Variable.Values /= Nil_String then Variable := Value_Of (Name_Source_Files, Project.Decl.Attributes, Shared); return Variable = Nil_Variable_Value or else Variable.Default or else Variable.Values /= Nil_String; else return False; end if; end Might_Have_Sources; Success : Boolean; Config_Project_Node : Project_Node_Id := Empty_Node; begin pragma Assert (Prj.Env.Is_Initialized (Env.Project_Path)); Free (Config_File_Path); Config := No_Project; Get_Project_Target; Check_Builder_Switches; -- Do not attempt to find a configuration project file when -- Config_File_Name is No_Configuration_File. if Config_File_Name = No_Configuration_File then Config_File_Path := null; else if Conf_File_Name'Length > 0 then Config_File_Path := Locate_Config_File (Conf_File_Name.all); else Config_File_Path := Locate_Config_File (Default_File_Name); end if; if Config_File_Path = null then if not Allow_Automatic_Generation and then Conf_File_Name'Length > 0 then Raise_Invalid_Config ("could not locate main configuration project " & Conf_File_Name.all); end if; end if; end if; Automatically_Generated := Allow_Automatic_Generation and then Config_File_Path = null; <> if Automatically_Generated then if Hostparm.OpenVMS then -- There is no gprconfig on VMS Raise_Invalid_Config ("could not locate any configuration project file"); else -- This might raise an Invalid_Config exception Do_Autoconf; end if; -- If the config file is not auto-generated, warn if there is any --RTS -- switch, but not when the config file is generated in memory. elsif RTS_Languages.Get_First /= No_Name and then Opt.Warning_Mode /= Opt.Suppress and then On_Load_Config = null then Write_Line ("warning: " & "--RTS is taken into account only in auto-configuration"); end if; -- Parse the configuration file if Verbose_Mode and then Config_File_Path /= null then Write_Str ("Checking configuration "); Write_Line (Config_File_Path.all); end if; if Config_File_Path /= null then Prj.Part.Parse (In_Tree => Project_Node_Tree, Project => Config_Project_Node, Project_File_Name => Config_File_Path.all, Errout_Handling => Prj.Part.Finalize_If_Error, Packages_To_Check => Packages_To_Check, Current_Directory => Current_Directory, Is_Config_File => True, Env => Env); else Config_Project_Node := Empty_Node; end if; if On_Load_Config /= null then On_Load_Config (Config_File => Config_Project_Node, Project_Node_Tree => Project_Node_Tree); end if; if Config_Project_Node /= Empty_Node then Prj.Proc.Process_Project_Tree_Phase_1 (In_Tree => Project_Tree, Project => Config, Packages_To_Check => Packages_To_Check, Success => Success, From_Project_Node => Config_Project_Node, From_Project_Node_Tree => Project_Node_Tree, Env => Env, Reset_Tree => False, On_New_Tree_Loaded => null); end if; if Config_Project_Node = Empty_Node or else Config = No_Project then Raise_Invalid_Config ("processing of configuration project """ & Config_File_Path.all & """ failed"); end if; -- Check that the target of the configuration file is the one the user -- specified on the command line. We do not need to check that when in -- auto-conf mode, since the appropriate target was passed to gprconfig. if not Automatically_Generated and then not Check_Target (Config, Autoconf_Specified, Project_Tree, Selected_Target.all) then Automatically_Generated := True; goto Process_Config_File; end if; end Get_Or_Create_Configuration_File; ------------------------ -- Locate_Config_File -- ------------------------ function Locate_Config_File (Name : String) return String_Access is Prefix_Path : constant String := Executable_Prefix_Path; begin if Prefix_Path'Length /= 0 then return Locate_Regular_File (Name, "." & Path_Separator & Prefix_Path & "share" & Directory_Separator & "gpr"); else return Locate_Regular_File (Name, "."); end if; end Locate_Config_File; -------------------- -- Locate_Runtime -- -------------------- procedure Locate_Runtime (Language : Name_Id; Project_Tree : Prj.Project_Tree_Ref; Env : Prj.Tree.Environment) is function Is_Base_Name (Path : String) return Boolean; -- Returns True if Path has no directory separator ------------------ -- Is_Base_Name -- ------------------ function Is_Base_Name (Path : String) return Boolean is begin for I in Path'Range loop if Path (I) = Directory_Separator or else Path (I) = '/' then return False; end if; end loop; return True; end Is_Base_Name; -- Local declarations function Find_Rts_In_Path is new Prj.Env.Find_Name_In_Path (Check_Filename => Is_Directory); RTS_Name : constant String := Runtime_Name_For (Language); Full_Path : String_Access; -- Start of processing for Locate_Runtime begin if not Is_Base_Name (RTS_Name) then Full_Path := Find_Rts_In_Path (Env.Project_Path, RTS_Name); if Full_Path = null then Fail_Program (Project_Tree, "cannot find RTS " & RTS_Name); end if; Set_Runtime_For (Language, Normalize_Pathname (Full_Path.all)); Free (Full_Path); end if; end Locate_Runtime; ------------------------------------ -- Parse_Project_And_Apply_Config -- ------------------------------------ procedure Parse_Project_And_Apply_Config (Main_Project : out Prj.Project_Id; User_Project_Node : out Prj.Tree.Project_Node_Id; Config_File_Name : String := ""; Autoconf_Specified : Boolean; Project_File_Name : String; Project_Tree : Prj.Project_Tree_Ref; Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref; Env : in out Prj.Tree.Environment; Packages_To_Check : String_List_Access; Allow_Automatic_Generation : Boolean := True; Automatically_Generated : out Boolean; Config_File_Path : out String_Access; Target_Name : String := ""; Normalized_Hostname : String; On_Load_Config : Config_File_Hook := null; Implicit_Project : Boolean := False; On_New_Tree_Loaded : Prj.Proc.Tree_Loaded_Callback := null) is begin pragma Assert (Prj.Env.Is_Initialized (Env.Project_Path)); -- Parse the user project tree Prj.Initialize (Project_Tree); Main_Project := No_Project; Automatically_Generated := False; Prj.Part.Parse (In_Tree => Project_Node_Tree, Project => User_Project_Node, Project_File_Name => Project_File_Name, Errout_Handling => Prj.Part.Finalize_If_Error, Packages_To_Check => Packages_To_Check, Current_Directory => Current_Directory, Is_Config_File => False, Env => Env, Implicit_Project => Implicit_Project); if User_Project_Node = Empty_Node then User_Project_Node := Empty_Node; return; end if; Process_Project_And_Apply_Config (Main_Project => Main_Project, User_Project_Node => User_Project_Node, Config_File_Name => Config_File_Name, Autoconf_Specified => Autoconf_Specified, Project_Tree => Project_Tree, Project_Node_Tree => Project_Node_Tree, Env => Env, Packages_To_Check => Packages_To_Check, Allow_Automatic_Generation => Allow_Automatic_Generation, Automatically_Generated => Automatically_Generated, Config_File_Path => Config_File_Path, Target_Name => Target_Name, Normalized_Hostname => Normalized_Hostname, On_Load_Config => On_Load_Config, On_New_Tree_Loaded => On_New_Tree_Loaded); end Parse_Project_And_Apply_Config; -------------------------------------- -- Process_Project_And_Apply_Config -- -------------------------------------- procedure Process_Project_And_Apply_Config (Main_Project : out Prj.Project_Id; User_Project_Node : Prj.Tree.Project_Node_Id; Config_File_Name : String := ""; Autoconf_Specified : Boolean; Project_Tree : Prj.Project_Tree_Ref; Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref; Env : in out Prj.Tree.Environment; Packages_To_Check : String_List_Access; Allow_Automatic_Generation : Boolean := True; Automatically_Generated : out Boolean; Config_File_Path : out String_Access; Target_Name : String := ""; Normalized_Hostname : String; On_Load_Config : Config_File_Hook := null; Reset_Tree : Boolean := True; On_New_Tree_Loaded : Prj.Proc.Tree_Loaded_Callback := null) is Shared : constant Shared_Project_Tree_Data_Access := Project_Tree.Shared; Main_Config_Project : Project_Id; Success : Boolean; Conf_Project : Project_Id := No_Project; -- The object directory of this project is used to store the config -- project file in auto-configuration. Set by Check_Project below. procedure Check_Project (Project : Project_Id); -- Look for a non aggregate project. If one is found, put its project Id -- in Conf_Project. ------------------- -- Check_Project -- ------------------- procedure Check_Project (Project : Project_Id) is begin if Project.Qualifier = Aggregate or else Project.Qualifier = Aggregate_Library then declare List : Aggregated_Project_List := Project.Aggregated_Projects; begin -- Look for a non aggregate project until one is found while Conf_Project = No_Project and then List /= null loop Check_Project (List.Project); List := List.Next; end loop; end; else Conf_Project := Project; end if; end Check_Project; -- Start of processing for Process_Project_And_Apply_Config begin Main_Project := No_Project; Automatically_Generated := False; Process_Project_Tree_Phase_1 (In_Tree => Project_Tree, Project => Main_Project, Packages_To_Check => Packages_To_Check, Success => Success, From_Project_Node => User_Project_Node, From_Project_Node_Tree => Project_Node_Tree, Env => Env, Reset_Tree => Reset_Tree, On_New_Tree_Loaded => On_New_Tree_Loaded); if not Success then Main_Project := No_Project; return; end if; if Project_Tree.Source_Info_File_Name /= null then if not Is_Absolute_Path (Project_Tree.Source_Info_File_Name.all) then declare Obj_Dir : constant Variable_Value := Value_Of (Name_Object_Dir, Main_Project.Decl.Attributes, Shared); begin if Obj_Dir = Nil_Variable_Value or else Obj_Dir.Default then Get_Name_String (Main_Project.Directory.Display_Name); else if Is_Absolute_Path (Get_Name_String (Obj_Dir.Value)) then Get_Name_String (Obj_Dir.Value); else Name_Len := 0; Add_Str_To_Name_Buffer (Get_Name_String (Main_Project.Directory.Display_Name)); Add_Str_To_Name_Buffer (Get_Name_String (Obj_Dir.Value)); end if; end if; Add_Char_To_Name_Buffer (Directory_Separator); Add_Str_To_Name_Buffer (Project_Tree.Source_Info_File_Name.all); Free (Project_Tree.Source_Info_File_Name); Project_Tree.Source_Info_File_Name := new String'(Name_Buffer (1 .. Name_Len)); end; end if; Read_Source_Info_File (Project_Tree); end if; -- Get the first project that is not an aggregate project or an -- aggregate library project. The object directory of this project will -- be used to store the config project file in auto-configuration. Check_Project (Main_Project); -- Fail if there is only aggregate projects and aggregate library -- projects in the project tree. if Conf_Project = No_Project then Raise_Invalid_Config ("there are no non-aggregate projects"); end if; -- Find configuration file Get_Or_Create_Configuration_File (Config => Main_Config_Project, Project => Main_Project, Conf_Project => Conf_Project, Project_Tree => Project_Tree, Project_Node_Tree => Project_Node_Tree, Env => Env, Allow_Automatic_Generation => Allow_Automatic_Generation, Config_File_Name => Config_File_Name, Autoconf_Specified => Autoconf_Specified, Target_Name => Target_Name, Normalized_Hostname => Normalized_Hostname, Packages_To_Check => Packages_To_Check, Config_File_Path => Config_File_Path, Automatically_Generated => Automatically_Generated, On_Load_Config => On_Load_Config); Apply_Config_File (Main_Config_Project, Project_Tree); -- Finish processing the user's project Prj.Proc.Process_Project_Tree_Phase_2 (In_Tree => Project_Tree, Project => Main_Project, Success => Success, From_Project_Node => User_Project_Node, From_Project_Node_Tree => Project_Node_Tree, Env => Env); if Success then if Project_Tree.Source_Info_File_Name /= null and then not Project_Tree.Source_Info_File_Exists then Write_Source_Info_File (Project_Tree); end if; else Main_Project := No_Project; end if; end Process_Project_And_Apply_Config; -------------------------- -- Raise_Invalid_Config -- -------------------------- procedure Raise_Invalid_Config (Msg : String) is begin Raise_Exception (Invalid_Config'Identity, Msg); end Raise_Invalid_Config; ---------------------- -- Runtime_Name_For -- ---------------------- function Runtime_Name_For (Language : Name_Id) return String is begin if RTS_Languages.Get (Language) /= No_Name then return Get_Name_String (RTS_Languages.Get (Language)); else return ""; end if; end Runtime_Name_For; -------------------------- -- Runtime_Name_Set_For -- -------------------------- function Runtime_Name_Set_For (Language : Name_Id) return Boolean is begin return RTS_Languages.Get (Language) /= No_Name; end Runtime_Name_Set_For; --------------------- -- Set_Runtime_For -- --------------------- procedure Set_Runtime_For (Language : Name_Id; RTS_Name : String) is begin Name_Len := RTS_Name'Length; Name_Buffer (1 .. Name_Len) := RTS_Name; RTS_Languages.Set (Language, Name_Find); end Set_Runtime_For; end Prj.Conf; gprbuild-gpl-2014-src/gnat/nlists.adb0000644000076700001450000010752412323721731017061 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- N L I S T S -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- WARNING: There is a C version of this package. Any changes to this source -- file must be properly reflected in the corresponding C header a-nlists.h with Alloc; with Atree; use Atree; with Debug; use Debug; with Output; use Output; with Sinfo; use Sinfo; with Table; package body Nlists is use Atree_Private_Part; -- Get access to Nodes table ---------------------------------- -- Implementation of Node Lists -- ---------------------------------- -- A node list is represented by a list header which contains -- three fields: type List_Header is record First : Node_Or_Entity_Id; -- Pointer to first node in list. Empty if list is empty Last : Node_Or_Entity_Id; -- Pointer to last node in list. Empty if list is empty Parent : Node_Id; -- Pointer to parent of list. Empty if list has no parent end record; -- The node lists are stored in a table indexed by List_Id values package Lists is new Table.Table ( Table_Component_Type => List_Header, Table_Index_Type => List_Id'Base, Table_Low_Bound => First_List_Id, Table_Initial => Alloc.Lists_Initial, Table_Increment => Alloc.Lists_Increment, Table_Name => "Lists"); -- The nodes in the list all have the In_List flag set, and their Link -- fields (which otherwise point to the parent) contain the List_Id of -- the list header giving immediate access to the list containing the -- node, and its parent and first and last elements. -- Two auxiliary tables, indexed by Node_Id values and built in parallel -- with the main nodes table and always having the same size contain the -- list link values that allow locating the previous and next node in a -- list. The entries in these tables are valid only if the In_List flag -- is set in the corresponding node. Next_Node is Empty at the end of a -- list and Prev_Node is Empty at the start of a list. package Next_Node is new Table.Table ( Table_Component_Type => Node_Or_Entity_Id, Table_Index_Type => Node_Or_Entity_Id'Base, Table_Low_Bound => First_Node_Id, Table_Initial => Alloc.Orig_Nodes_Initial, Table_Increment => Alloc.Orig_Nodes_Increment, Table_Name => "Next_Node"); package Prev_Node is new Table.Table ( Table_Component_Type => Node_Or_Entity_Id, Table_Index_Type => Node_Or_Entity_Id'Base, Table_Low_Bound => First_Node_Id, Table_Initial => Alloc.Orig_Nodes_Initial, Table_Increment => Alloc.Orig_Nodes_Increment, Table_Name => "Prev_Node"); ----------------------- -- Local Subprograms -- ----------------------- procedure Set_First (List : List_Id; To : Node_Or_Entity_Id); pragma Inline (Set_First); -- Sets First field of list header List to reference To procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id); pragma Inline (Set_Last); -- Sets Last field of list header List to reference To procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id); pragma Inline (Set_List_Link); -- Sets list link of Node to list header To procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id); pragma Inline (Set_Next); -- Sets the Next_Node pointer for Node to reference To procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id); pragma Inline (Set_Prev); -- Sets the Prev_Node pointer for Node to reference To -------------------------- -- Allocate_List_Tables -- -------------------------- procedure Allocate_List_Tables (N : Node_Or_Entity_Id) is Old_Last : constant Node_Or_Entity_Id'Base := Next_Node.Last; begin pragma Assert (N >= Old_Last); Next_Node.Set_Last (N); Prev_Node.Set_Last (N); -- Make sure we have no uninitialized junk in any new entires added. -- This ensures that Tree_Gen will not write out any uninitialized junk. for J in Old_Last + 1 .. N loop Next_Node.Table (J) := Empty; Prev_Node.Table (J) := Empty; end loop; end Allocate_List_Tables; ------------ -- Append -- ------------ procedure Append (Node : Node_Or_Entity_Id; To : List_Id) is L : constant Node_Or_Entity_Id := Last (To); procedure Append_Debug; pragma Inline (Append_Debug); -- Output debug information if Debug_Flag_N set ------------------ -- Append_Debug -- ------------------ procedure Append_Debug is begin if Debug_Flag_N then Write_Str ("Append node "); Write_Int (Int (Node)); Write_Str (" to list "); Write_Int (Int (To)); Write_Eol; end if; end Append_Debug; -- Start of processing for Append begin pragma Assert (not Is_List_Member (Node)); if Node = Error then return; end if; pragma Debug (Append_Debug); if No (L) then Set_First (To, Node); else Set_Next (L, Node); end if; Set_Last (To, Node); Nodes.Table (Node).In_List := True; Set_Next (Node, Empty); Set_Prev (Node, L); Set_List_Link (Node, To); end Append; ----------------- -- Append_List -- ----------------- procedure Append_List (List : List_Id; To : List_Id) is procedure Append_List_Debug; pragma Inline (Append_List_Debug); -- Output debug information if Debug_Flag_N set ----------------------- -- Append_List_Debug -- ----------------------- procedure Append_List_Debug is begin if Debug_Flag_N then Write_Str ("Append list "); Write_Int (Int (List)); Write_Str (" to list "); Write_Int (Int (To)); Write_Eol; end if; end Append_List_Debug; -- Start of processing for Append_List begin if Is_Empty_List (List) then return; else declare L : constant Node_Or_Entity_Id := Last (To); F : constant Node_Or_Entity_Id := First (List); N : Node_Or_Entity_Id; begin pragma Debug (Append_List_Debug); N := F; loop Set_List_Link (N, To); N := Next (N); exit when No (N); end loop; if No (L) then Set_First (To, F); else Set_Next (L, F); end if; Set_Prev (F, L); Set_Last (To, Last (List)); Set_First (List, Empty); Set_Last (List, Empty); end; end if; end Append_List; -------------------- -- Append_List_To -- -------------------- procedure Append_List_To (To : List_Id; List : List_Id) is begin Append_List (List, To); end Append_List_To; --------------- -- Append_To -- --------------- procedure Append_To (To : List_Id; Node : Node_Or_Entity_Id) is begin Append (Node, To); end Append_To; ----------- -- First -- ----------- function First (List : List_Id) return Node_Or_Entity_Id is begin if List = No_List then return Empty; else pragma Assert (List <= Lists.Last); return Lists.Table (List).First; end if; end First; ---------------------- -- First_Non_Pragma -- ---------------------- function First_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is N : constant Node_Or_Entity_Id := First (List); begin if Nkind (N) /= N_Pragma and then Nkind (N) /= N_Null_Statement then return N; else return Next_Non_Pragma (N); end if; end First_Non_Pragma; ---------------- -- Initialize -- ---------------- procedure Initialize is E : constant List_Id := Error_List; begin Lists.Init; Next_Node.Init; Prev_Node.Init; -- Allocate Error_List list header Lists.Increment_Last; Set_Parent (E, Empty); Set_First (E, Empty); Set_Last (E, Empty); end Initialize; ------------------ -- In_Same_List -- ------------------ function In_Same_List (N1, N2 : Node_Or_Entity_Id) return Boolean is begin return List_Containing (N1) = List_Containing (N2); end In_Same_List; ------------------ -- Insert_After -- ------------------ procedure Insert_After (After : Node_Or_Entity_Id; Node : Node_Or_Entity_Id) is procedure Insert_After_Debug; pragma Inline (Insert_After_Debug); -- Output debug information if Debug_Flag_N set ------------------------ -- Insert_After_Debug -- ------------------------ procedure Insert_After_Debug is begin if Debug_Flag_N then Write_Str ("Insert node"); Write_Int (Int (Node)); Write_Str (" after node "); Write_Int (Int (After)); Write_Eol; end if; end Insert_After_Debug; -- Start of processing for Insert_After begin pragma Assert (Is_List_Member (After) and then not Is_List_Member (Node)); if Node = Error then return; end if; pragma Debug (Insert_After_Debug); declare Before : constant Node_Or_Entity_Id := Next (After); LC : constant List_Id := List_Containing (After); begin if Present (Before) then Set_Prev (Before, Node); else Set_Last (LC, Node); end if; Set_Next (After, Node); Nodes.Table (Node).In_List := True; Set_Prev (Node, After); Set_Next (Node, Before); Set_List_Link (Node, LC); end; end Insert_After; ------------------- -- Insert_Before -- ------------------- procedure Insert_Before (Before : Node_Or_Entity_Id; Node : Node_Or_Entity_Id) is procedure Insert_Before_Debug; pragma Inline (Insert_Before_Debug); -- Output debug information if Debug_Flag_N set ------------------------- -- Insert_Before_Debug -- ------------------------- procedure Insert_Before_Debug is begin if Debug_Flag_N then Write_Str ("Insert node"); Write_Int (Int (Node)); Write_Str (" before node "); Write_Int (Int (Before)); Write_Eol; end if; end Insert_Before_Debug; -- Start of processing for Insert_Before begin pragma Assert (Is_List_Member (Before) and then not Is_List_Member (Node)); if Node = Error then return; end if; pragma Debug (Insert_Before_Debug); declare After : constant Node_Or_Entity_Id := Prev (Before); LC : constant List_Id := List_Containing (Before); begin if Present (After) then Set_Next (After, Node); else Set_First (LC, Node); end if; Set_Prev (Before, Node); Nodes.Table (Node).In_List := True; Set_Prev (Node, After); Set_Next (Node, Before); Set_List_Link (Node, LC); end; end Insert_Before; ----------------------- -- Insert_List_After -- ----------------------- procedure Insert_List_After (After : Node_Or_Entity_Id; List : List_Id) is procedure Insert_List_After_Debug; pragma Inline (Insert_List_After_Debug); -- Output debug information if Debug_Flag_N set ----------------------------- -- Insert_List_After_Debug -- ----------------------------- procedure Insert_List_After_Debug is begin if Debug_Flag_N then Write_Str ("Insert list "); Write_Int (Int (List)); Write_Str (" after node "); Write_Int (Int (After)); Write_Eol; end if; end Insert_List_After_Debug; -- Start of processing for Insert_List_After begin pragma Assert (Is_List_Member (After)); if Is_Empty_List (List) then return; else declare Before : constant Node_Or_Entity_Id := Next (After); LC : constant List_Id := List_Containing (After); F : constant Node_Or_Entity_Id := First (List); L : constant Node_Or_Entity_Id := Last (List); N : Node_Or_Entity_Id; begin pragma Debug (Insert_List_After_Debug); N := F; loop Set_List_Link (N, LC); exit when N = L; N := Next (N); end loop; if Present (Before) then Set_Prev (Before, L); else Set_Last (LC, L); end if; Set_Next (After, F); Set_Prev (F, After); Set_Next (L, Before); Set_First (List, Empty); Set_Last (List, Empty); end; end if; end Insert_List_After; ------------------------ -- Insert_List_Before -- ------------------------ procedure Insert_List_Before (Before : Node_Or_Entity_Id; List : List_Id) is procedure Insert_List_Before_Debug; pragma Inline (Insert_List_Before_Debug); -- Output debug information if Debug_Flag_N set ------------------------------ -- Insert_List_Before_Debug -- ------------------------------ procedure Insert_List_Before_Debug is begin if Debug_Flag_N then Write_Str ("Insert list "); Write_Int (Int (List)); Write_Str (" before node "); Write_Int (Int (Before)); Write_Eol; end if; end Insert_List_Before_Debug; -- Start of processing for Insert_List_Before begin pragma Assert (Is_List_Member (Before)); if Is_Empty_List (List) then return; else declare After : constant Node_Or_Entity_Id := Prev (Before); LC : constant List_Id := List_Containing (Before); F : constant Node_Or_Entity_Id := First (List); L : constant Node_Or_Entity_Id := Last (List); N : Node_Or_Entity_Id; begin pragma Debug (Insert_List_Before_Debug); N := F; loop Set_List_Link (N, LC); exit when N = L; N := Next (N); end loop; if Present (After) then Set_Next (After, F); else Set_First (LC, F); end if; Set_Prev (Before, L); Set_Prev (F, After); Set_Next (L, Before); Set_First (List, Empty); Set_Last (List, Empty); end; end if; end Insert_List_Before; ------------------- -- Is_Empty_List -- ------------------- function Is_Empty_List (List : List_Id) return Boolean is begin return First (List) = Empty; end Is_Empty_List; -------------------- -- Is_List_Member -- -------------------- function Is_List_Member (Node : Node_Or_Entity_Id) return Boolean is begin return Nodes.Table (Node).In_List; end Is_List_Member; ----------------------- -- Is_Non_Empty_List -- ----------------------- function Is_Non_Empty_List (List : List_Id) return Boolean is begin return First (List) /= Empty; end Is_Non_Empty_List; ---------- -- Last -- ---------- function Last (List : List_Id) return Node_Or_Entity_Id is begin pragma Assert (List <= Lists.Last); return Lists.Table (List).Last; end Last; ------------------ -- Last_List_Id -- ------------------ function Last_List_Id return List_Id is begin return Lists.Last; end Last_List_Id; --------------------- -- Last_Non_Pragma -- --------------------- function Last_Non_Pragma (List : List_Id) return Node_Or_Entity_Id is N : constant Node_Or_Entity_Id := Last (List); begin if Nkind (N) /= N_Pragma then return N; else return Prev_Non_Pragma (N); end if; end Last_Non_Pragma; --------------------- -- List_Containing -- --------------------- function List_Containing (Node : Node_Or_Entity_Id) return List_Id is begin pragma Assert (Is_List_Member (Node)); return List_Id (Nodes.Table (Node).Link); end List_Containing; ----------------- -- List_Length -- ----------------- function List_Length (List : List_Id) return Nat is Result : Nat; Node : Node_Or_Entity_Id; begin Result := 0; Node := First (List); while Present (Node) loop Result := Result + 1; Node := Next (Node); end loop; return Result; end List_Length; ------------------- -- Lists_Address -- ------------------- function Lists_Address return System.Address is begin return Lists.Table (First_List_Id)'Address; end Lists_Address; ---------- -- Lock -- ---------- procedure Lock is begin Lists.Locked := True; Lists.Release; Prev_Node.Locked := True; Next_Node.Locked := True; Prev_Node.Release; Next_Node.Release; end Lock; ------------------- -- New_Copy_List -- ------------------- function New_Copy_List (List : List_Id) return List_Id is NL : List_Id; E : Node_Or_Entity_Id; begin if List = No_List then return No_List; else NL := New_List; E := First (List); while Present (E) loop Append (New_Copy (E), NL); E := Next (E); end loop; return NL; end if; end New_Copy_List; ---------------------------- -- New_Copy_List_Original -- ---------------------------- function New_Copy_List_Original (List : List_Id) return List_Id is NL : List_Id; E : Node_Or_Entity_Id; begin if List = No_List then return No_List; else NL := New_List; E := First (List); while Present (E) loop if Comes_From_Source (E) then Append (New_Copy (E), NL); end if; E := Next (E); end loop; return NL; end if; end New_Copy_List_Original; -------------- -- New_List -- -------------- function New_List return List_Id is procedure New_List_Debug; pragma Inline (New_List_Debug); -- Output debugging information if Debug_Flag_N is set -------------------- -- New_List_Debug -- -------------------- procedure New_List_Debug is begin if Debug_Flag_N then Write_Str ("Allocate new list, returned ID = "); Write_Int (Int (Lists.Last)); Write_Eol; end if; end New_List_Debug; -- Start of processing for New_List begin Lists.Increment_Last; declare List : constant List_Id := Lists.Last; begin Set_Parent (List, Empty); Set_First (List, Empty); Set_Last (List, Empty); pragma Debug (New_List_Debug); return (List); end; end New_List; -- Since the one argument case is common, we optimize to build the right -- list directly, rather than first building an empty list and then doing -- the insertion, which results in some unnecessary work. function New_List (Node : Node_Or_Entity_Id) return List_Id is procedure New_List_Debug; pragma Inline (New_List_Debug); -- Output debugging information if Debug_Flag_N is set -------------------- -- New_List_Debug -- -------------------- procedure New_List_Debug is begin if Debug_Flag_N then Write_Str ("Allocate new list, returned ID = "); Write_Int (Int (Lists.Last)); Write_Eol; end if; end New_List_Debug; -- Start of processing for New_List begin if Node = Error then return New_List; else pragma Assert (not Is_List_Member (Node)); Lists.Increment_Last; declare List : constant List_Id := Lists.Last; begin Set_Parent (List, Empty); Set_First (List, Node); Set_Last (List, Node); Nodes.Table (Node).In_List := True; Set_List_Link (Node, List); Set_Prev (Node, Empty); Set_Next (Node, Empty); pragma Debug (New_List_Debug); return List; end; end if; end New_List; function New_List (Node1 : Node_Or_Entity_Id; Node2 : Node_Or_Entity_Id) return List_Id is L : constant List_Id := New_List (Node1); begin Append (Node2, L); return L; end New_List; function New_List (Node1 : Node_Or_Entity_Id; Node2 : Node_Or_Entity_Id; Node3 : Node_Or_Entity_Id) return List_Id is L : constant List_Id := New_List (Node1); begin Append (Node2, L); Append (Node3, L); return L; end New_List; function New_List (Node1 : Node_Or_Entity_Id; Node2 : Node_Or_Entity_Id; Node3 : Node_Or_Entity_Id; Node4 : Node_Or_Entity_Id) return List_Id is L : constant List_Id := New_List (Node1); begin Append (Node2, L); Append (Node3, L); Append (Node4, L); return L; end New_List; function New_List (Node1 : Node_Or_Entity_Id; Node2 : Node_Or_Entity_Id; Node3 : Node_Or_Entity_Id; Node4 : Node_Or_Entity_Id; Node5 : Node_Or_Entity_Id) return List_Id is L : constant List_Id := New_List (Node1); begin Append (Node2, L); Append (Node3, L); Append (Node4, L); Append (Node5, L); return L; end New_List; function New_List (Node1 : Node_Or_Entity_Id; Node2 : Node_Or_Entity_Id; Node3 : Node_Or_Entity_Id; Node4 : Node_Or_Entity_Id; Node5 : Node_Or_Entity_Id; Node6 : Node_Or_Entity_Id) return List_Id is L : constant List_Id := New_List (Node1); begin Append (Node2, L); Append (Node3, L); Append (Node4, L); Append (Node5, L); Append (Node6, L); return L; end New_List; ---------- -- Next -- ---------- function Next (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is begin pragma Assert (Is_List_Member (Node)); return Next_Node.Table (Node); end Next; procedure Next (Node : in out Node_Or_Entity_Id) is begin Node := Next (Node); end Next; ----------------------- -- Next_Node_Address -- ----------------------- function Next_Node_Address return System.Address is begin return Next_Node.Table (First_Node_Id)'Address; end Next_Node_Address; --------------------- -- Next_Non_Pragma -- --------------------- function Next_Non_Pragma (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is N : Node_Or_Entity_Id; begin N := Node; loop N := Next (N); exit when not Nkind_In (N, N_Pragma, N_Null_Statement); end loop; return N; end Next_Non_Pragma; procedure Next_Non_Pragma (Node : in out Node_Or_Entity_Id) is begin Node := Next_Non_Pragma (Node); end Next_Non_Pragma; -------- -- No -- -------- function No (List : List_Id) return Boolean is begin return List = No_List; end No; --------------- -- Num_Lists -- --------------- function Num_Lists return Nat is begin return Int (Lists.Last) - Int (Lists.First) + 1; end Num_Lists; ------------ -- Parent -- ------------ function Parent (List : List_Id) return Node_Or_Entity_Id is begin pragma Assert (List <= Lists.Last); return Lists.Table (List).Parent; end Parent; ---------- -- Pick -- ---------- function Pick (List : List_Id; Index : Pos) return Node_Or_Entity_Id is Elmt : Node_Or_Entity_Id; begin Elmt := First (List); for J in 1 .. Index - 1 loop Elmt := Next (Elmt); end loop; return Elmt; end Pick; ------------- -- Prepend -- ------------- procedure Prepend (Node : Node_Or_Entity_Id; To : List_Id) is F : constant Node_Or_Entity_Id := First (To); procedure Prepend_Debug; pragma Inline (Prepend_Debug); -- Output debug information if Debug_Flag_N set ------------------- -- Prepend_Debug -- ------------------- procedure Prepend_Debug is begin if Debug_Flag_N then Write_Str ("Prepend node "); Write_Int (Int (Node)); Write_Str (" to list "); Write_Int (Int (To)); Write_Eol; end if; end Prepend_Debug; -- Start of processing for Prepend_Debug begin pragma Assert (not Is_List_Member (Node)); if Node = Error then return; end if; pragma Debug (Prepend_Debug); if No (F) then Set_Last (To, Node); else Set_Prev (F, Node); end if; Set_First (To, Node); Nodes.Table (Node).In_List := True; Set_Next (Node, F); Set_Prev (Node, Empty); Set_List_Link (Node, To); end Prepend; ------------------ -- Prepend_List -- ------------------ procedure Prepend_List (List : List_Id; To : List_Id) is procedure Prepend_List_Debug; pragma Inline (Prepend_List_Debug); -- Output debug information if Debug_Flag_N set ------------------------ -- Prepend_List_Debug -- ------------------------ procedure Prepend_List_Debug is begin if Debug_Flag_N then Write_Str ("Prepend list "); Write_Int (Int (List)); Write_Str (" to list "); Write_Int (Int (To)); Write_Eol; end if; end Prepend_List_Debug; -- Start of processing for Prepend_List begin if Is_Empty_List (List) then return; else declare F : constant Node_Or_Entity_Id := First (To); L : constant Node_Or_Entity_Id := Last (List); N : Node_Or_Entity_Id; begin pragma Debug (Prepend_List_Debug); N := L; loop Set_List_Link (N, To); N := Prev (N); exit when No (N); end loop; if No (F) then Set_Last (To, L); else Set_Next (L, F); end if; Set_Prev (F, L); Set_First (To, First (List)); Set_First (List, Empty); Set_Last (List, Empty); end; end if; end Prepend_List; --------------------- -- Prepend_List_To -- --------------------- procedure Prepend_List_To (To : List_Id; List : List_Id) is begin Prepend_List (List, To); end Prepend_List_To; ---------------- -- Prepend_To -- ---------------- procedure Prepend_To (To : List_Id; Node : Node_Or_Entity_Id) is begin Prepend (Node, To); end Prepend_To; ------------- -- Present -- ------------- function Present (List : List_Id) return Boolean is begin return List /= No_List; end Present; ---------- -- Prev -- ---------- function Prev (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is begin pragma Assert (Is_List_Member (Node)); return Prev_Node.Table (Node); end Prev; procedure Prev (Node : in out Node_Or_Entity_Id) is begin Node := Prev (Node); end Prev; ----------------------- -- Prev_Node_Address -- ----------------------- function Prev_Node_Address return System.Address is begin return Prev_Node.Table (First_Node_Id)'Address; end Prev_Node_Address; --------------------- -- Prev_Non_Pragma -- --------------------- function Prev_Non_Pragma (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is N : Node_Or_Entity_Id; begin N := Node; loop N := Prev (N); exit when Nkind (N) /= N_Pragma; end loop; return N; end Prev_Non_Pragma; procedure Prev_Non_Pragma (Node : in out Node_Or_Entity_Id) is begin Node := Prev_Non_Pragma (Node); end Prev_Non_Pragma; ------------ -- Remove -- ------------ procedure Remove (Node : Node_Or_Entity_Id) is Lst : constant List_Id := List_Containing (Node); Prv : constant Node_Or_Entity_Id := Prev (Node); Nxt : constant Node_Or_Entity_Id := Next (Node); procedure Remove_Debug; pragma Inline (Remove_Debug); -- Output debug information if Debug_Flag_N set ------------------ -- Remove_Debug -- ------------------ procedure Remove_Debug is begin if Debug_Flag_N then Write_Str ("Remove node "); Write_Int (Int (Node)); Write_Eol; end if; end Remove_Debug; -- Start of processing for Remove begin pragma Debug (Remove_Debug); if No (Prv) then Set_First (Lst, Nxt); else Set_Next (Prv, Nxt); end if; if No (Nxt) then Set_Last (Lst, Prv); else Set_Prev (Nxt, Prv); end if; Nodes.Table (Node).In_List := False; Set_Parent (Node, Empty); end Remove; ----------------- -- Remove_Head -- ----------------- function Remove_Head (List : List_Id) return Node_Or_Entity_Id is Frst : constant Node_Or_Entity_Id := First (List); procedure Remove_Head_Debug; pragma Inline (Remove_Head_Debug); -- Output debug information if Debug_Flag_N set ----------------------- -- Remove_Head_Debug -- ----------------------- procedure Remove_Head_Debug is begin if Debug_Flag_N then Write_Str ("Remove head of list "); Write_Int (Int (List)); Write_Eol; end if; end Remove_Head_Debug; -- Start of processing for Remove_Head begin pragma Debug (Remove_Head_Debug); if Frst = Empty then return Empty; else declare Nxt : constant Node_Or_Entity_Id := Next (Frst); begin Set_First (List, Nxt); if No (Nxt) then Set_Last (List, Empty); else Set_Prev (Nxt, Empty); end if; Nodes.Table (Frst).In_List := False; Set_Parent (Frst, Empty); return Frst; end; end if; end Remove_Head; ----------------- -- Remove_Next -- ----------------- function Remove_Next (Node : Node_Or_Entity_Id) return Node_Or_Entity_Id is Nxt : constant Node_Or_Entity_Id := Next (Node); procedure Remove_Next_Debug; pragma Inline (Remove_Next_Debug); -- Output debug information if Debug_Flag_N set ----------------------- -- Remove_Next_Debug -- ----------------------- procedure Remove_Next_Debug is begin if Debug_Flag_N then Write_Str ("Remove next node after "); Write_Int (Int (Node)); Write_Eol; end if; end Remove_Next_Debug; -- Start of processing for Remove_Next begin if Present (Nxt) then declare Nxt2 : constant Node_Or_Entity_Id := Next (Nxt); LC : constant List_Id := List_Containing (Node); begin pragma Debug (Remove_Next_Debug); Set_Next (Node, Nxt2); if No (Nxt2) then Set_Last (LC, Node); else Set_Prev (Nxt2, Node); end if; Nodes.Table (Nxt).In_List := False; Set_Parent (Nxt, Empty); end; end if; return Nxt; end Remove_Next; --------------- -- Set_First -- --------------- procedure Set_First (List : List_Id; To : Node_Or_Entity_Id) is begin Lists.Table (List).First := To; end Set_First; -------------- -- Set_Last -- -------------- procedure Set_Last (List : List_Id; To : Node_Or_Entity_Id) is begin Lists.Table (List).Last := To; end Set_Last; ------------------- -- Set_List_Link -- ------------------- procedure Set_List_Link (Node : Node_Or_Entity_Id; To : List_Id) is begin Nodes.Table (Node).Link := Union_Id (To); end Set_List_Link; -------------- -- Set_Next -- -------------- procedure Set_Next (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is begin Next_Node.Table (Node) := To; end Set_Next; ---------------- -- Set_Parent -- ---------------- procedure Set_Parent (List : List_Id; Node : Node_Or_Entity_Id) is begin pragma Assert (List <= Lists.Last); Lists.Table (List).Parent := Node; end Set_Parent; -------------- -- Set_Prev -- -------------- procedure Set_Prev (Node : Node_Or_Entity_Id; To : Node_Or_Entity_Id) is begin Prev_Node.Table (Node) := To; end Set_Prev; --------------- -- Tree_Read -- --------------- procedure Tree_Read is begin Lists.Tree_Read; Next_Node.Tree_Read; Prev_Node.Tree_Read; end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is begin Lists.Tree_Write; Next_Node.Tree_Write; Prev_Node.Tree_Write; end Tree_Write; ------------ -- Unlock -- ------------ procedure Unlock is begin Lists.Locked := False; Prev_Node.Locked := False; Next_Node.Locked := False; end Unlock; end Nlists; gprbuild-gpl-2014-src/gnat/prj-pp.adb0000644000076700001450000011020612323721731016744 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . P P -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Ada.Characters.Handling; use Ada.Characters.Handling; with Output; use Output; with Snames; package body Prj.PP is use Prj.Tree; Not_Tested : array (Project_Node_Kind) of Boolean := (others => True); procedure Indicate_Tested (Kind : Project_Node_Kind); -- Set the corresponding component of array Not_Tested to False. Only -- called by Debug pragmas. --------------------- -- Indicate_Tested -- --------------------- procedure Indicate_Tested (Kind : Project_Node_Kind) is begin Not_Tested (Kind) := False; end Indicate_Tested; ------------------ -- Pretty_Print -- ------------------ procedure Pretty_Print (Project : Prj.Tree.Project_Node_Id; In_Tree : Prj.Tree.Project_Node_Tree_Ref; Increment : Positive := 3; Eliminate_Empty_Case_Constructions : Boolean := False; Minimize_Empty_Lines : Boolean := False; W_Char : Write_Char_Ap := null; W_Eol : Write_Eol_Ap := null; W_Str : Write_Str_Ap := null; Backward_Compatibility : Boolean; Id : Prj.Project_Id := Prj.No_Project; Max_Line_Length : Max_Length_Of_Line := Max_Length_Of_Line'Last) is procedure Print (Node : Project_Node_Id; Indent : Natural); -- A recursive procedure that traverses a project file tree and outputs -- its source. Current_Prj is the project that we are printing. This -- is used when printing attributes, since in nested packages they -- need to use a fully qualified name. procedure Output_Attribute_Name (Name : Name_Id; Indent : Natural); -- Outputs an attribute name, taking into account the value of -- Backward_Compatibility. procedure Output_Name (Name : Name_Id; Indent : Natural; Capitalize : Boolean := True); -- Outputs a name procedure Start_Line (Indent : Natural); -- Outputs the indentation at the beginning of the line procedure Output_Project_File (S : Name_Id); -- Output a project file name in one single string literal procedure Output_String (S : Name_Id; Indent : Natural); -- Outputs a string using the default output procedures procedure Write_Empty_Line (Always : Boolean := False); -- Outputs an empty line, only if the previous line was not empty -- already and either Always is True or Minimize_Empty_Lines is False. procedure Write_Line (S : String); -- Outputs S followed by a new line procedure Write_String (S : String; Indent : Natural; Truncated : Boolean := False); -- Outputs S using Write_Str, starting a new line if line would become -- too long, when Truncated = False. When Truncated = True, only the -- part of the string that can fit on the line is output. procedure Write_End_Of_Line_Comment (Node : Project_Node_Id); -- Needs comment??? Write_Char : Write_Char_Ap := Output.Write_Char'Access; Write_Eol : Write_Eol_Ap := Output.Write_Eol'Access; Write_Str : Write_Str_Ap := Output.Write_Str'Access; -- These three access to procedure values are used for the output Last_Line_Is_Empty : Boolean := False; -- Used to avoid two consecutive empty lines Column : Natural := 0; -- Column number of the last character in the line. Used to avoid -- outputting lines longer than Max_Line_Length. First_With_In_List : Boolean := True; -- Indicate that the next with clause is first in a list such as -- with "A", "B"; -- First_With_In_List will be True for "A", but not for "B". --------------------------- -- Output_Attribute_Name -- --------------------------- procedure Output_Attribute_Name (Name : Name_Id; Indent : Natural) is begin if Backward_Compatibility then case Name is when Snames.Name_Spec => Output_Name (Snames.Name_Specification, Indent); when Snames.Name_Spec_Suffix => Output_Name (Snames.Name_Specification_Suffix, Indent); when Snames.Name_Body => Output_Name (Snames.Name_Implementation, Indent); when Snames.Name_Body_Suffix => Output_Name (Snames.Name_Implementation_Suffix, Indent); when others => Output_Name (Name, Indent); end case; else Output_Name (Name, Indent); end if; end Output_Attribute_Name; ----------------- -- Output_Name -- ----------------- procedure Output_Name (Name : Name_Id; Indent : Natural; Capitalize : Boolean := True) is Capital : Boolean := Capitalize; begin if Column = 0 and then Indent /= 0 then Start_Line (Indent + Increment); end if; Get_Name_String (Name); -- If line would become too long, create new line if Column + Name_Len > Max_Line_Length then Write_Eol.all; Column := 0; if Indent /= 0 then Start_Line (Indent + Increment); end if; end if; for J in 1 .. Name_Len loop if Capital then Write_Char (To_Upper (Name_Buffer (J))); else Write_Char (Name_Buffer (J)); end if; if Capitalize then Capital := Name_Buffer (J) = '_' or else Is_Digit (Name_Buffer (J)); end if; end loop; Column := Column + Name_Len; end Output_Name; ------------------------- -- Output_Project_File -- ------------------------- procedure Output_Project_File (S : Name_Id) is File_Name : constant String := Get_Name_String (S); begin Write_Char ('"'); for J in File_Name'Range loop if File_Name (J) = '"' then Write_Char ('"'); Write_Char ('"'); else Write_Char (File_Name (J)); end if; end loop; Write_Char ('"'); end Output_Project_File; ------------------- -- Output_String -- ------------------- procedure Output_String (S : Name_Id; Indent : Natural) is begin if Column = 0 and then Indent /= 0 then Start_Line (Indent + Increment); end if; Get_Name_String (S); -- If line could become too long, create new line. Note that the -- number of characters on the line could be twice the number of -- character in the string (if every character is a '"') plus two -- (the initial and final '"'). if Column + Name_Len + Name_Len + 2 > Max_Line_Length then Write_Eol.all; Column := 0; if Indent /= 0 then Start_Line (Indent + Increment); end if; end if; Write_Char ('"'); Column := Column + 1; Get_Name_String (S); for J in 1 .. Name_Len loop if Name_Buffer (J) = '"' then Write_Char ('"'); Write_Char ('"'); Column := Column + 2; else Write_Char (Name_Buffer (J)); Column := Column + 1; end if; -- If the string does not fit on one line, cut it in parts and -- concatenate. if J < Name_Len and then Column >= Max_Line_Length then Write_Str (""" &"); Write_Eol.all; Column := 0; Start_Line (Indent + Increment); Write_Char ('"'); Column := Column + 1; end if; end loop; Write_Char ('"'); Column := Column + 1; end Output_String; ---------------- -- Start_Line -- ---------------- procedure Start_Line (Indent : Natural) is begin if not Minimize_Empty_Lines then Write_Str ((1 .. Indent => ' ')); Column := Column + Indent; end if; end Start_Line; ---------------------- -- Write_Empty_Line -- ---------------------- procedure Write_Empty_Line (Always : Boolean := False) is begin if (Always or else not Minimize_Empty_Lines) and then not Last_Line_Is_Empty then Write_Eol.all; Column := 0; Last_Line_Is_Empty := True; end if; end Write_Empty_Line; ------------------------------- -- Write_End_Of_Line_Comment -- ------------------------------- procedure Write_End_Of_Line_Comment (Node : Project_Node_Id) is Value : constant Name_Id := End_Of_Line_Comment (Node, In_Tree); begin if Value /= No_Name then Write_String (" --", 0); Write_String (Get_Name_String (Value), 0, Truncated => True); end if; Write_Line (""); end Write_End_Of_Line_Comment; ---------------- -- Write_Line -- ---------------- procedure Write_Line (S : String) is begin Write_String (S, 0); Last_Line_Is_Empty := False; Write_Eol.all; Column := 0; end Write_Line; ------------------ -- Write_String -- ------------------ procedure Write_String (S : String; Indent : Natural; Truncated : Boolean := False) is Length : Natural := S'Length; begin if Column = 0 and then Indent /= 0 then Start_Line (Indent + Increment); end if; -- If the string would not fit on the line, start a new line if Column + Length > Max_Line_Length then if Truncated then Length := Max_Line_Length - Column; else Write_Eol.all; Column := 0; if Indent /= 0 then Start_Line (Indent + Increment); end if; end if; end if; Write_Str (S (S'First .. S'First + Length - 1)); Column := Column + Length; end Write_String; ----------- -- Print -- ----------- procedure Print (Node : Project_Node_Id; Indent : Natural) is begin if Present (Node) then case Kind_Of (Node, In_Tree) is when N_Project => pragma Debug (Indicate_Tested (N_Project)); if Present (First_With_Clause_Of (Node, In_Tree)) then -- with clause(s) First_With_In_List := True; Print (First_With_Clause_Of (Node, In_Tree), Indent); Write_Empty_Line (Always => True); end if; Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); case Project_Qualifier_Of (Node, In_Tree) is when Unspecified | Standard => null; when Aggregate => Write_String ("aggregate ", Indent); when Aggregate_Library => Write_String ("aggregate library ", Indent); when Library => Write_String ("library ", Indent); when Configuration => Write_String ("configuration ", Indent); when Dry => Write_String ("abstract ", Indent); end case; Write_String ("project ", Indent); if Id /= Prj.No_Project then Output_Name (Id.Display_Name, Indent); else Output_Name (Name_Of (Node, In_Tree), Indent); end if; -- Check if this project extends another project if Extended_Project_Path_Of (Node, In_Tree) /= No_Path then Write_String (" extends ", Indent); if Is_Extending_All (Node, In_Tree) then Write_String ("all ", Indent); end if; Output_Project_File (Name_Id (Extended_Project_Path_Of (Node, In_Tree))); end if; Write_String (" is", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent + Increment); Write_Empty_Line (Always => True); -- Output all of the declarations in the project Print (Project_Declaration_Of (Node, In_Tree), Indent); Print (First_Comment_Before_End (Node, In_Tree), Indent + Increment); Start_Line (Indent); Write_String ("end ", Indent); if Id /= Prj.No_Project then Output_Name (Id.Display_Name, Indent); else Output_Name (Name_Of (Node, In_Tree), Indent); end if; Write_Line (";"); Print (First_Comment_After_End (Node, In_Tree), Indent); when N_With_Clause => pragma Debug (Indicate_Tested (N_With_Clause)); -- The with clause will sometimes contain an invalid name -- when we are importing a virtual project from an extending -- all project. Do not output anything in this case. if Name_Of (Node, In_Tree) /= No_Name and then String_Value_Of (Node, In_Tree) /= No_Name then if First_With_In_List then Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); if Non_Limited_Project_Node_Of (Node, In_Tree) = Empty_Node then Write_String ("limited ", Indent); end if; Write_String ("with ", Indent); end if; -- Output the project name without concatenation, even if -- the line is too long. Output_Project_File (String_Value_Of (Node, In_Tree)); if Is_Not_Last_In_List (Node, In_Tree) then Write_String (", ", Indent); First_With_In_List := False; else Write_String (";", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent); First_With_In_List := True; end if; end if; Print (Next_With_Clause_Of (Node, In_Tree), Indent); when N_Project_Declaration => pragma Debug (Indicate_Tested (N_Project_Declaration)); if Present (First_Declarative_Item_Of (Node, In_Tree)) then Print (First_Declarative_Item_Of (Node, In_Tree), Indent + Increment); Write_Empty_Line (Always => True); end if; when N_Declarative_Item => pragma Debug (Indicate_Tested (N_Declarative_Item)); Print (Current_Item_Node (Node, In_Tree), Indent); Print (Next_Declarative_Item (Node, In_Tree), Indent); when N_Package_Declaration => pragma Debug (Indicate_Tested (N_Package_Declaration)); Write_Empty_Line (Always => True); Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); Write_String ("package ", Indent); Output_Name (Name_Of (Node, In_Tree), Indent); if Project_Of_Renamed_Package_Of (Node, In_Tree) /= Empty_Node then Write_String (" renames ", Indent); Output_Name (Name_Of (Project_Of_Renamed_Package_Of (Node, In_Tree), In_Tree), Indent); Write_String (".", Indent); Output_Name (Name_Of (Node, In_Tree), Indent); Write_String (";", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After_End (Node, In_Tree), Indent); else Write_String (" is", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent + Increment); if First_Declarative_Item_Of (Node, In_Tree) /= Empty_Node then Print (First_Declarative_Item_Of (Node, In_Tree), Indent + Increment); end if; Print (First_Comment_Before_End (Node, In_Tree), Indent + Increment); Start_Line (Indent); Write_String ("end ", Indent); Output_Name (Name_Of (Node, In_Tree), Indent); Write_Line (";"); Print (First_Comment_After_End (Node, In_Tree), Indent); Write_Empty_Line; end if; when N_String_Type_Declaration => pragma Debug (Indicate_Tested (N_String_Type_Declaration)); Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); Write_String ("type ", Indent); Output_Name (Name_Of (Node, In_Tree), Indent); Write_Line (" is"); Start_Line (Indent + Increment); Write_String ("(", Indent); declare String_Node : Project_Node_Id := First_Literal_String (Node, In_Tree); begin while Present (String_Node) loop Output_String (String_Value_Of (String_Node, In_Tree), Indent); String_Node := Next_Literal_String (String_Node, In_Tree); if Present (String_Node) then Write_String (", ", Indent); end if; end loop; end; Write_String (");", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent); when N_Literal_String => pragma Debug (Indicate_Tested (N_Literal_String)); Output_String (String_Value_Of (Node, In_Tree), Indent); if Source_Index_Of (Node, In_Tree) /= 0 then Write_String (" at", Indent); Write_String (Source_Index_Of (Node, In_Tree)'Img, Indent); end if; when N_Attribute_Declaration => pragma Debug (Indicate_Tested (N_Attribute_Declaration)); Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); Write_String ("for ", Indent); Output_Attribute_Name (Name_Of (Node, In_Tree), Indent); if Associative_Array_Index_Of (Node, In_Tree) /= No_Name then Write_String (" (", Indent); Output_String (Associative_Array_Index_Of (Node, In_Tree), Indent); if Source_Index_Of (Node, In_Tree) /= 0 then Write_String (" at", Indent); Write_String (Source_Index_Of (Node, In_Tree)'Img, Indent); end if; Write_String (")", Indent); end if; Write_String (" use ", Indent); if Present (Expression_Of (Node, In_Tree)) then Print (Expression_Of (Node, In_Tree), Indent); else -- Full associative array declaration if Present (Associative_Project_Of (Node, In_Tree)) then Output_Name (Name_Of (Associative_Project_Of (Node, In_Tree), In_Tree), Indent); if Present (Associative_Package_Of (Node, In_Tree)) then Write_String (".", Indent); Output_Name (Name_Of (Associative_Package_Of (Node, In_Tree), In_Tree), Indent); end if; elsif Present (Associative_Package_Of (Node, In_Tree)) then Output_Name (Name_Of (Associative_Package_Of (Node, In_Tree), In_Tree), Indent); end if; Write_String ("'", Indent); Output_Attribute_Name (Name_Of (Node, In_Tree), Indent); end if; Write_String (";", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent); when N_Typed_Variable_Declaration => pragma Debug (Indicate_Tested (N_Typed_Variable_Declaration)); Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); Output_Name (Name_Of (Node, In_Tree), Indent); Write_String (" : ", Indent); Output_Name (Name_Of (String_Type_Of (Node, In_Tree), In_Tree), Indent); Write_String (" := ", Indent); Print (Expression_Of (Node, In_Tree), Indent); Write_String (";", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent); when N_Variable_Declaration => pragma Debug (Indicate_Tested (N_Variable_Declaration)); Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); Output_Name (Name_Of (Node, In_Tree), Indent); Write_String (" := ", Indent); Print (Expression_Of (Node, In_Tree), Indent); Write_String (";", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent); when N_Expression => pragma Debug (Indicate_Tested (N_Expression)); declare Term : Project_Node_Id := First_Term (Node, In_Tree); begin while Present (Term) loop Print (Term, Indent); Term := Next_Term (Term, In_Tree); if Present (Term) then Write_String (" & ", Indent); end if; end loop; end; when N_Term => pragma Debug (Indicate_Tested (N_Term)); Print (Current_Term (Node, In_Tree), Indent); when N_Literal_String_List => pragma Debug (Indicate_Tested (N_Literal_String_List)); Write_String ("(", Indent); declare Expression : Project_Node_Id := First_Expression_In_List (Node, In_Tree); begin while Present (Expression) loop Print (Expression, Indent); Expression := Next_Expression_In_List (Expression, In_Tree); if Present (Expression) then Write_String (", ", Indent); end if; end loop; end; Write_String (")", Indent); when N_Variable_Reference => pragma Debug (Indicate_Tested (N_Variable_Reference)); if Present (Project_Node_Of (Node, In_Tree)) then Output_Name (Name_Of (Project_Node_Of (Node, In_Tree), In_Tree), Indent); Write_String (".", Indent); end if; if Present (Package_Node_Of (Node, In_Tree)) then Output_Name (Name_Of (Package_Node_Of (Node, In_Tree), In_Tree), Indent); Write_String (".", Indent); end if; Output_Name (Name_Of (Node, In_Tree), Indent); when N_External_Value => pragma Debug (Indicate_Tested (N_External_Value)); Write_String ("external (", Indent); Print (External_Reference_Of (Node, In_Tree), Indent); if Present (External_Default_Of (Node, In_Tree)) then Write_String (", ", Indent); Print (External_Default_Of (Node, In_Tree), Indent); end if; Write_String (")", Indent); when N_Attribute_Reference => pragma Debug (Indicate_Tested (N_Attribute_Reference)); if Present (Project_Node_Of (Node, In_Tree)) and then Project_Node_Of (Node, In_Tree) /= Project then Output_Name (Name_Of (Project_Node_Of (Node, In_Tree), In_Tree), Indent); if Present (Package_Node_Of (Node, In_Tree)) then Write_String (".", Indent); Output_Name (Name_Of (Package_Node_Of (Node, In_Tree), In_Tree), Indent); end if; elsif Present (Package_Node_Of (Node, In_Tree)) then Output_Name (Name_Of (Package_Node_Of (Node, In_Tree), In_Tree), Indent); else Write_String ("project", Indent); end if; Write_String ("'", Indent); Output_Attribute_Name (Name_Of (Node, In_Tree), Indent); declare Index : constant Name_Id := Associative_Array_Index_Of (Node, In_Tree); begin if Index /= No_Name then Write_String (" (", Indent); Output_String (Index, Indent); Write_String (")", Indent); end if; end; when N_Case_Construction => pragma Debug (Indicate_Tested (N_Case_Construction)); declare Case_Item : Project_Node_Id; Is_Non_Empty : Boolean := False; begin Case_Item := First_Case_Item_Of (Node, In_Tree); while Present (Case_Item) loop if Present (First_Declarative_Item_Of (Case_Item, In_Tree)) or else not Eliminate_Empty_Case_Constructions then Is_Non_Empty := True; exit; end if; Case_Item := Next_Case_Item (Case_Item, In_Tree); end loop; if Is_Non_Empty then Write_Empty_Line; Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); Write_String ("case ", Indent); Print (Case_Variable_Reference_Of (Node, In_Tree), Indent); Write_String (" is", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent + Increment); declare Case_Item : Project_Node_Id := First_Case_Item_Of (Node, In_Tree); begin while Present (Case_Item) loop pragma Assert (Kind_Of (Case_Item, In_Tree) = N_Case_Item); Print (Case_Item, Indent + Increment); Case_Item := Next_Case_Item (Case_Item, In_Tree); end loop; end; Print (First_Comment_Before_End (Node, In_Tree), Indent + Increment); Start_Line (Indent); Write_Line ("end case;"); Print (First_Comment_After_End (Node, In_Tree), Indent); end if; end; when N_Case_Item => pragma Debug (Indicate_Tested (N_Case_Item)); if Present (First_Declarative_Item_Of (Node, In_Tree)) or else not Eliminate_Empty_Case_Constructions then Write_Empty_Line; Print (First_Comment_Before (Node, In_Tree), Indent); Start_Line (Indent); Write_String ("when ", Indent); if No (First_Choice_Of (Node, In_Tree)) then Write_String ("others", Indent); else declare Label : Project_Node_Id := First_Choice_Of (Node, In_Tree); begin while Present (Label) loop Print (Label, Indent); Label := Next_Literal_String (Label, In_Tree); if Present (Label) then Write_String (" | ", Indent); end if; end loop; end; end if; Write_String (" =>", Indent); Write_End_Of_Line_Comment (Node); Print (First_Comment_After (Node, In_Tree), Indent + Increment); declare First : constant Project_Node_Id := First_Declarative_Item_Of (Node, In_Tree); begin if No (First) then Write_Empty_Line; else Print (First, Indent + Increment); end if; end; end if; when N_Comment_Zones => -- Nothing to do, because it will not be processed directly null; when N_Comment => pragma Debug (Indicate_Tested (N_Comment)); if Follows_Empty_Line (Node, In_Tree) then Write_Empty_Line; end if; Start_Line (Indent); Write_String ("--", Indent); Write_String (Get_Name_String (String_Value_Of (Node, In_Tree)), Indent, Truncated => True); Write_Line (""); if Is_Followed_By_Empty_Line (Node, In_Tree) then Write_Empty_Line; end if; Print (Next_Comment (Node, In_Tree), Indent); end case; end if; end Print; -- Start of processing for Pretty_Print begin if W_Char = null then Write_Char := Output.Write_Char'Access; else Write_Char := W_Char; end if; if W_Eol = null then Write_Eol := Output.Write_Eol'Access; else Write_Eol := W_Eol; end if; if W_Str = null then Write_Str := Output.Write_Str'Access; else Write_Str := W_Str; end if; Print (Project, 0); end Pretty_Print; ----------------------- -- Output_Statistics -- ----------------------- procedure Output_Statistics is begin Output.Write_Line ("Project_Node_Kinds not tested:"); for Kind in Project_Node_Kind loop if Kind /= N_Comment_Zones and then Not_Tested (Kind) then Output.Write_Str (" "); Output.Write_Line (Project_Node_Kind'Image (Kind)); end if; end loop; Output.Write_Eol; end Output_Statistics; --------- -- wpr -- --------- procedure wpr (Project : Prj.Tree.Project_Node_Id; In_Tree : Prj.Tree.Project_Node_Tree_Ref) is begin Pretty_Print (Project, In_Tree, Backward_Compatibility => False); end wpr; end Prj.PP; gprbuild-gpl-2014-src/gnat/err_vars.ads0000644000076700001450000001737112323721731017411 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- E R R _ V A R S -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains variables common to error reporting packages -- including Errout and Prj.Err. with Namet; use Namet; with Types; use Types; with Uintp; use Uintp; package Err_Vars is -- All of these variables are set when needed, so they do not need to be -- initialized. However, there is code that saves and restores existing -- values, which may malfunction in -gnatVa mode if the variable has never -- been initialized, so we initialize some variables to avoid exceptions -- from invalid values in such cases. -- Note on error counts (Serious_Errors_Detected, Total_Errors_Detected, -- Warnings_Detected). These counts might more logically appear in this -- unit, but we place them in atree.ads, because of licensing issues. We -- need to be able to access these counts from units that have the more -- general licensing conditions. ---------------------------------- -- Error Message Mode Variables -- ---------------------------------- -- These variables control special error message modes. The initialized -- values below give the normal default behavior, but they can be reset -- by the caller to get different behavior as noted in the comments. These -- variables are not reset by calls to the error message routines, so the -- caller is responsible for resetting the default behavior after use. Error_Msg_Qual_Level : Int := 0; -- Number of levels of qualification required for type name (see the -- description of the } insertion character. Note that this value does -- note get reset by any Error_Msg call, so the caller is responsible -- for resetting it. Warn_On_Instance : Boolean := False; -- Normally if a warning is generated in a generic template from the -- analysis of the template, then the warning really belongs in the -- template, and the default value of False for this Boolean achieves -- that effect. If Warn_On_Instance is set True, then the warnings are -- generated on the instantiation (referring to the template) rather -- than on the template itself. Raise_Exception_On_Error : Nat := 0; -- If this value is non-zero, then any attempt to generate an error -- message raises the exception Error_Msg_Exception, and the error -- message is not output. This is used for defending against junk -- resulting from illegalities, and also for substitution of more -- appropriate error messages from higher semantic levels. It is -- a counter so that the increment/decrement protocol nests neatly. -- Initialized for -gnatVa use, see comment above. Error_Msg_Exception : exception; -- Exception raised if Raise_Exception_On_Error is true Current_Error_Source_File : Source_File_Index := Internal_Source_File; -- Id of current messages. Used to post file name when unit changes. This -- is initialized to Main_Source_File at the start of a compilation, which -- means that no file names will be output unless there are errors in units -- other than the main unit. However, if the main unit has a pragma -- Source_Reference line, then this is initialized to No_Source_File, -- to force an initial reference to the real source file name. Warning_Doc_Switch : Boolean := False; -- If this is set True, then the ??/?x?/?x? sequences in error messages -- are active (see errout.ads for details). If this switch is False, then -- these sequences are ignored (i.e. simply equivalent to a single ?). The -- -gnatw.d switch sets this flag True, -gnatw.D sets this flag False. -- Note: always ignored on VMS, where we do not provide this capability. ---------------------------------------- -- Error Message Insertion Parameters -- ---------------------------------------- -- The error message routines work with strings that contain insertion -- sequences that result in the insertion of variable data. The following -- variables contain the required data. The procedure is to set one or more -- of the following global variables to appropriate values before making a -- call to one of the error message routines with a string containing the -- insertion character to get the value inserted in an appropriate format. Error_Msg_Col : Column_Number; -- Column for @ insertion character in message Error_Msg_Uint_1 : Uint; Error_Msg_Uint_2 : Uint; -- Uint values for ^ insertion characters in message Error_Msg_Sloc : Source_Ptr; -- Source location for # insertion character in message Error_Msg_Name_1 : Name_Id; Error_Msg_Name_2 : Name_Id; Error_Msg_Name_3 : Name_Id; -- Name_Id values for % insertion characters in message Error_Msg_File_1 : File_Name_Type; Error_Msg_File_2 : File_Name_Type; Error_Msg_File_3 : File_Name_Type; -- File_Name_Type values for { insertion characters in message Error_Msg_Unit_1 : Unit_Name_Type; Error_Msg_Unit_2 : Unit_Name_Type; -- Unit_Name_Type values for $ insertion characters in message Error_Msg_Node_1 : Node_Id; Error_Msg_Node_2 : Node_Id; -- Node_Id values for & insertion characters in message Error_Msg_Warn : Boolean; -- Used if current message contains a < insertion character to indicate -- if the current message is a warning message. Must be set appropriately -- before any call to Error_Msg_xxx with a < insertion character present. -- Setting is irrelevant if no < insertion character is present. Note -- that it is not necessary to reset this after using it, since the proper -- procedure is always to set it before issuing such a message. Note that -- the warning documentation tag is always [enabled by default] in the -- case where this flag is True. Error_Msg_String : String (1 .. 4096); Error_Msg_Strlen : Natural; -- Used if current message contains a ~ insertion character to indicate -- insertion of the string Error_Msg_String (1 .. Error_Msg_Strlen). end Err_Vars; gprbuild-gpl-2014-src/gnat/casing.adb0000644000076700001450000001637112323721731017010 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- C A S I N G -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Csets; use Csets; with Namet; use Namet; with Opt; use Opt; with Widechar; use Widechar; package body Casing is ---------------------- -- Determine_Casing -- ---------------------- function Determine_Casing (Ident : Text_Buffer) return Casing_Type is All_Lower : Boolean := True; -- Set False if upper case letter found All_Upper : Boolean := True; -- Set False if lower case letter found Mixed : Boolean := True; -- Set False if exception to mixed case rule found (lower case letter -- at start or after underline, or upper case letter elsewhere). Decisive : Boolean := False; -- Set True if at least one instance of letter not after underline After_Und : Boolean := True; -- True at start of string, and after an underline character begin -- A special exception, consider SPARK_Mode to be mixed case if Ident = "SPARK_Mode" then return Mixed_Case; end if; -- Proceed with normal determination for S in Ident'Range loop if Ident (S) = '_' or else Ident (S) = '.' then After_Und := True; elsif Is_Lower_Case_Letter (Ident (S)) then All_Upper := False; if not After_Und then Decisive := True; else After_Und := False; Mixed := False; end if; elsif Is_Upper_Case_Letter (Ident (S)) then All_Lower := False; if not After_Und then Decisive := True; Mixed := False; else After_Und := False; end if; end if; end loop; -- Now we can figure out the result from the flags we set in that loop if All_Lower then return All_Lower_Case; elsif not Decisive then return Unknown; elsif All_Upper then return All_Upper_Case; elsif Mixed then return Mixed_Case; else return Unknown; end if; end Determine_Casing; ------------------------ -- Set_All_Upper_Case -- ------------------------ procedure Set_All_Upper_Case is begin Set_Casing (All_Upper_Case); end Set_All_Upper_Case; ---------------- -- Set_Casing -- ---------------- procedure Set_Casing (C : Casing_Type; D : Casing_Type := Mixed_Case) is Ptr : Natural; Actual_Casing : Casing_Type; -- Set from C or D as appropriate After_Und : Boolean := True; -- True at start of string, and after an underline character or after -- any other special character that is not a normal identifier char). begin if C /= Unknown then Actual_Casing := C; else Actual_Casing := D; end if; Ptr := 1; while Ptr <= Name_Len loop -- Wide character. Note that we do nothing with casing in this case. -- In Ada 2005 mode, required folding of lower case letters happened -- as the identifier was scanned, and we do not attempt any further -- messing with case (note that in any case we do not know how to -- fold upper case to lower case in wide character mode). We also -- do not bother with recognizing punctuation as equivalent to an -- underscore. There is nothing functional at this stage in doing -- the requested casing operation, beyond folding to upper case -- when it is mandatory, which does not involve underscores. if Name_Buffer (Ptr) = ASCII.ESC or else Name_Buffer (Ptr) = '[' or else (Upper_Half_Encoding and then Name_Buffer (Ptr) in Upper_Half_Character) then Skip_Wide (Name_Buffer, Ptr); After_Und := False; -- Underscore, or non-identifer character (error case) elsif Name_Buffer (Ptr) = '_' or else not Identifier_Char (Name_Buffer (Ptr)) then After_Und := True; Ptr := Ptr + 1; -- Lower case letter elsif Is_Lower_Case_Letter (Name_Buffer (Ptr)) then if Actual_Casing = All_Upper_Case or else (After_Und and then Actual_Casing = Mixed_Case) then Name_Buffer (Ptr) := Fold_Upper (Name_Buffer (Ptr)); end if; After_Und := False; Ptr := Ptr + 1; -- Upper case letter elsif Is_Upper_Case_Letter (Name_Buffer (Ptr)) then if Actual_Casing = All_Lower_Case or else (not After_Und and then Actual_Casing = Mixed_Case) then Name_Buffer (Ptr) := Fold_Lower (Name_Buffer (Ptr)); end if; After_Und := False; Ptr := Ptr + 1; -- Other identifier character (must be digit) else After_Und := False; Ptr := Ptr + 1; end if; end loop; end Set_Casing; end Casing; gprbuild-gpl-2014-src/gnat/prj-strt.adb0000644000076700001450000015137512323721731017335 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . S T R T -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2010, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Err_Vars; use Err_Vars; with Prj.Attr; use Prj.Attr; with Prj.Err; use Prj.Err; with Snames; with Table; with Uintp; use Uintp; package body Prj.Strt is Buffer : String_Access; Buffer_Last : Natural := 0; type Choice_String is record The_String : Name_Id; Already_Used : Boolean := False; end record; -- The string of a case label, and an indication that it has already -- been used (to avoid duplicate case labels). Choices_Initial : constant := 10; Choices_Increment : constant := 100; -- These should be in alloc.ads Choice_Node_Low_Bound : constant := 0; Choice_Node_High_Bound : constant := 099_999_999; -- In practice, infinite type Choice_Node_Id is range Choice_Node_Low_Bound .. Choice_Node_High_Bound; First_Choice_Node_Id : constant Choice_Node_Id := Choice_Node_Low_Bound; package Choices is new Table.Table (Table_Component_Type => Choice_String, Table_Index_Type => Choice_Node_Id'Base, Table_Low_Bound => First_Choice_Node_Id, Table_Initial => Choices_Initial, Table_Increment => Choices_Increment, Table_Name => "Prj.Strt.Choices"); -- Used to store the case labels and check that there is no duplicate package Choice_Lasts is new Table.Table (Table_Component_Type => Choice_Node_Id, Table_Index_Type => Nat, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Prj.Strt.Choice_Lasts"); -- Used to store the indexes of the choices in table Choices, to -- distinguish nested case constructions. Choice_First : Choice_Node_Id := 0; -- Index in table Choices of the first case label of the current -- case construction. Zero means no current case construction. type Name_Location is record Name : Name_Id := No_Name; Location : Source_Ptr := No_Location; end record; -- Store the identifier and the location of a simple name package Names is new Table.Table (Table_Component_Type => Name_Location, Table_Index_Type => Nat, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Prj.Strt.Names"); -- Used to accumulate the single names of a name procedure Add (This_String : Name_Id); -- Add a string to the case label list, indicating that it has not -- yet been used. procedure Add_To_Names (NL : Name_Location); -- Add one single names to table Names procedure External_Reference (In_Tree : Project_Node_Tree_Ref; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; External_Value : out Project_Node_Id; Expr_Kind : in out Variable_Kind; Flags : Processing_Flags); -- Parse an external reference. Current token is "external" procedure Attribute_Reference (In_Tree : Project_Node_Tree_Ref; Reference : out Project_Node_Id; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Flags : Processing_Flags); -- Parse an attribute reference. Current token is an apostrophe procedure Terms (In_Tree : Project_Node_Tree_Ref; Term : out Project_Node_Id; Expr_Kind : in out Variable_Kind; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Optional_Index : Boolean; Flags : Processing_Flags); -- Recursive procedure to parse one term or several terms concatenated -- using "&". --------- -- Add -- --------- procedure Add (This_String : Name_Id) is begin Choices.Increment_Last; Choices.Table (Choices.Last) := (The_String => This_String, Already_Used => False); end Add; ------------------ -- Add_To_Names -- ------------------ procedure Add_To_Names (NL : Name_Location) is begin Names.Increment_Last; Names.Table (Names.Last) := NL; end Add_To_Names; ------------------------- -- Attribute_Reference -- ------------------------- procedure Attribute_Reference (In_Tree : Project_Node_Tree_Ref; Reference : out Project_Node_Id; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Flags : Processing_Flags) is Current_Attribute : Attribute_Node_Id := First_Attribute; begin -- Declare the node of the attribute reference Reference := Default_Project_Node (Of_Kind => N_Attribute_Reference, In_Tree => In_Tree); Set_Location_Of (Reference, In_Tree, To => Token_Ptr); Scan (In_Tree); -- past apostrophe -- Body may be an attribute name if Token = Tok_Body then Token := Tok_Identifier; Token_Name := Snames.Name_Body; end if; Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then Set_Name_Of (Reference, In_Tree, To => Token_Name); -- Check if the identifier is one of the attribute identifiers in the -- context (package or project level attributes). Current_Attribute := Attribute_Node_Id_Of (Token_Name, Starting_At => First_Attribute); -- If the identifier is not allowed, report an error if Current_Attribute = Empty_Attribute then Error_Msg_Name_1 := Token_Name; Error_Msg (Flags, "unknown attribute %%", Token_Ptr); Reference := Empty_Node; -- Scan past the attribute name Scan (In_Tree); else -- Give its characteristics to this attribute reference Set_Project_Node_Of (Reference, In_Tree, To => Current_Project); Set_Package_Node_Of (Reference, In_Tree, To => Current_Package); Set_Expression_Kind_Of (Reference, In_Tree, To => Variable_Kind_Of (Current_Attribute)); Set_Case_Insensitive (Reference, In_Tree, To => Attribute_Kind_Of (Current_Attribute) in All_Case_Insensitive_Associative_Array); -- Scan past the attribute name Scan (In_Tree); -- If the attribute is an associative array, get the index if Attribute_Kind_Of (Current_Attribute) /= Single then Expect (Tok_Left_Paren, "`(`"); if Token = Tok_Left_Paren then Scan (In_Tree); if Others_Allowed_For (Current_Attribute) and then Token = Tok_Others then Set_Associative_Array_Index_Of (Reference, In_Tree, To => All_Other_Names); Scan (In_Tree); else if Others_Allowed_For (Current_Attribute) then Expect (Tok_String_Literal, "literal string or others"); else Expect (Tok_String_Literal, "literal string"); end if; if Token = Tok_String_Literal then Set_Associative_Array_Index_Of (Reference, In_Tree, To => Token_Name); Scan (In_Tree); end if; end if; end if; Expect (Tok_Right_Paren, "`)`"); if Token = Tok_Right_Paren then Scan (In_Tree); end if; end if; end if; -- Change name of obsolete attributes if Present (Reference) then case Name_Of (Reference, In_Tree) is when Snames.Name_Specification => Set_Name_Of (Reference, In_Tree, To => Snames.Name_Spec); when Snames.Name_Specification_Suffix => Set_Name_Of (Reference, In_Tree, To => Snames.Name_Spec_Suffix); when Snames.Name_Implementation => Set_Name_Of (Reference, In_Tree, To => Snames.Name_Body); when Snames.Name_Implementation_Suffix => Set_Name_Of (Reference, In_Tree, To => Snames.Name_Body_Suffix); when others => null; end case; end if; end if; end Attribute_Reference; --------------------------- -- End_Case_Construction -- --------------------------- procedure End_Case_Construction (Check_All_Labels : Boolean; Case_Location : Source_Ptr; Flags : Processing_Flags) is Non_Used : Natural := 0; First_Non_Used : Choice_Node_Id := First_Choice_Node_Id; begin -- First, if Check_All_Labels is True, check if all values -- of the string type have been used. if Check_All_Labels then for Choice in Choice_First .. Choices.Last loop if not Choices.Table (Choice).Already_Used then Non_Used := Non_Used + 1; if Non_Used = 1 then First_Non_Used := Choice; end if; end if; end loop; -- If only one is not used, report a single warning for this value if Non_Used = 1 then Error_Msg_Name_1 := Choices.Table (First_Non_Used).The_String; Error_Msg (Flags, "?value %% is not used as label", Case_Location); -- If several are not used, report a warning for each one of them elsif Non_Used > 1 then Error_Msg (Flags, "?the following values are not used as labels:", Case_Location); for Choice in First_Non_Used .. Choices.Last loop if not Choices.Table (Choice).Already_Used then Error_Msg_Name_1 := Choices.Table (Choice).The_String; Error_Msg (Flags, "\?%%", Case_Location); end if; end loop; end if; end if; -- If this is the only case construction, empty the tables if Choice_Lasts.Last = 1 then Choice_Lasts.Set_Last (0); Choices.Set_Last (First_Choice_Node_Id); Choice_First := 0; elsif Choice_Lasts.Last = 2 then -- This is the second case construction, set the tables to the first Choice_Lasts.Set_Last (1); Choices.Set_Last (Choice_Lasts.Table (1)); Choice_First := 1; else -- This is the 3rd or more case construction, set the tables to the -- previous one. Choice_Lasts.Decrement_Last; Choices.Set_Last (Choice_Lasts.Table (Choice_Lasts.Last)); Choice_First := Choice_Lasts.Table (Choice_Lasts.Last - 1) + 1; end if; end End_Case_Construction; ------------------------ -- External_Reference -- ------------------------ procedure External_Reference (In_Tree : Project_Node_Tree_Ref; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; External_Value : out Project_Node_Id; Expr_Kind : in out Variable_Kind; Flags : Processing_Flags) is Field_Id : Project_Node_Id := Empty_Node; Ext_List : Boolean := False; begin External_Value := Default_Project_Node (Of_Kind => N_External_Value, In_Tree => In_Tree); Set_Location_Of (External_Value, In_Tree, To => Token_Ptr); -- The current token is either external or external_as_list Ext_List := Token = Tok_External_As_List; Scan (In_Tree); if Ext_List then Set_Expression_Kind_Of (External_Value, In_Tree, To => List); else Set_Expression_Kind_Of (External_Value, In_Tree, To => Single); end if; if Expr_Kind = Undefined then if Ext_List then Expr_Kind := List; else Expr_Kind := Single; end if; end if; Expect (Tok_Left_Paren, "`(`"); -- Scan past the left parenthesis if Token = Tok_Left_Paren then Scan (In_Tree); end if; -- Get the name of the external reference Expect (Tok_String_Literal, "literal string"); if Token = Tok_String_Literal then Field_Id := Default_Project_Node (Of_Kind => N_Literal_String, In_Tree => In_Tree, And_Expr_Kind => Single); Set_String_Value_Of (Field_Id, In_Tree, To => Token_Name); Set_External_Reference_Of (External_Value, In_Tree, To => Field_Id); -- Scan past the first argument Scan (In_Tree); case Token is when Tok_Right_Paren => if Ext_List then Error_Msg (Flags, "`,` expected", Token_Ptr); end if; Scan (In_Tree); -- scan past right paren when Tok_Comma => Scan (In_Tree); -- scan past comma -- Get the string expression for the default declare Loc : constant Source_Ptr := Token_Ptr; begin Parse_Expression (In_Tree => In_Tree, Expression => Field_Id, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package, Optional_Index => False); if Expression_Kind_Of (Field_Id, In_Tree) = List then Error_Msg (Flags, "expression must be a single string", Loc); else Set_External_Default_Of (External_Value, In_Tree, To => Field_Id); end if; end; Expect (Tok_Right_Paren, "`)`"); if Token = Tok_Right_Paren then Scan (In_Tree); -- scan past right paren end if; when others => if Ext_List then Error_Msg (Flags, "`,` expected", Token_Ptr); else Error_Msg (Flags, "`,` or `)` expected", Token_Ptr); end if; end case; end if; end External_Reference; ----------------------- -- Parse_Choice_List -- ----------------------- procedure Parse_Choice_List (In_Tree : Project_Node_Tree_Ref; First_Choice : out Project_Node_Id; Flags : Processing_Flags) is Current_Choice : Project_Node_Id := Empty_Node; Next_Choice : Project_Node_Id := Empty_Node; Choice_String : Name_Id := No_Name; Found : Boolean := False; begin -- Declare the node of the first choice First_Choice := Default_Project_Node (Of_Kind => N_Literal_String, In_Tree => In_Tree, And_Expr_Kind => Single); -- Initially Current_Choice is the same as First_Choice Current_Choice := First_Choice; loop Expect (Tok_String_Literal, "literal string"); exit when Token /= Tok_String_Literal; Set_Location_Of (Current_Choice, In_Tree, To => Token_Ptr); Choice_String := Token_Name; -- Give the string value to the current choice Set_String_Value_Of (Current_Choice, In_Tree, To => Choice_String); -- Check if the label is part of the string type and if it has not -- been already used. Found := False; for Choice in Choice_First .. Choices.Last loop if Choices.Table (Choice).The_String = Choice_String then -- This label is part of the string type Found := True; if Choices.Table (Choice).Already_Used then -- But it has already appeared in a choice list for this -- case construction so report an error. Error_Msg_Name_1 := Choice_String; Error_Msg (Flags, "duplicate case label %%", Token_Ptr); else Choices.Table (Choice).Already_Used := True; end if; exit; end if; end loop; -- If the label is not part of the string list, report an error if not Found then Error_Msg_Name_1 := Choice_String; Error_Msg (Flags, "illegal case label %%", Token_Ptr); end if; -- Scan past the label Scan (In_Tree); -- If there is no '|', we are done if Token = Tok_Vertical_Bar then -- Otherwise, declare the node of the next choice, link it to -- Current_Choice and set Current_Choice to this new node. Next_Choice := Default_Project_Node (Of_Kind => N_Literal_String, In_Tree => In_Tree, And_Expr_Kind => Single); Set_Next_Literal_String (Current_Choice, In_Tree, To => Next_Choice); Current_Choice := Next_Choice; Scan (In_Tree); else exit; end if; end loop; end Parse_Choice_List; ---------------------- -- Parse_Expression -- ---------------------- procedure Parse_Expression (In_Tree : Project_Node_Tree_Ref; Expression : out Project_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Optional_Index : Boolean; Flags : Processing_Flags) is First_Term : Project_Node_Id := Empty_Node; Expression_Kind : Variable_Kind := Undefined; begin -- Declare the node of the expression Expression := Default_Project_Node (Of_Kind => N_Expression, In_Tree => In_Tree); Set_Location_Of (Expression, In_Tree, To => Token_Ptr); -- Parse the term or terms of the expression Terms (In_Tree => In_Tree, Term => First_Term, Expr_Kind => Expression_Kind, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package, Optional_Index => Optional_Index); -- Set the first term and the expression kind Set_First_Term (Expression, In_Tree, To => First_Term); Set_Expression_Kind_Of (Expression, In_Tree, To => Expression_Kind); end Parse_Expression; ---------------------------- -- Parse_String_Type_List -- ---------------------------- procedure Parse_String_Type_List (In_Tree : Project_Node_Tree_Ref; First_String : out Project_Node_Id; Flags : Processing_Flags) is Last_String : Project_Node_Id := Empty_Node; Next_String : Project_Node_Id := Empty_Node; String_Value : Name_Id := No_Name; begin -- Declare the node of the first string First_String := Default_Project_Node (Of_Kind => N_Literal_String, In_Tree => In_Tree, And_Expr_Kind => Single); -- Initially, Last_String is the same as First_String Last_String := First_String; loop Expect (Tok_String_Literal, "literal string"); exit when Token /= Tok_String_Literal; String_Value := Token_Name; -- Give its string value to Last_String Set_String_Value_Of (Last_String, In_Tree, To => String_Value); Set_Location_Of (Last_String, In_Tree, To => Token_Ptr); -- Now, check if the string is already part of the string type declare Current : Project_Node_Id := First_String; begin while Current /= Last_String loop if String_Value_Of (Current, In_Tree) = String_Value then -- This is a repetition, report an error Error_Msg_Name_1 := String_Value; Error_Msg (Flags, "duplicate value %% in type", Token_Ptr); exit; end if; Current := Next_Literal_String (Current, In_Tree); end loop; end; -- Scan past the literal string Scan (In_Tree); -- If there is no comma following the literal string, we are done if Token /= Tok_Comma then exit; else -- Declare the next string, link it to Last_String and set -- Last_String to its node. Next_String := Default_Project_Node (Of_Kind => N_Literal_String, In_Tree => In_Tree, And_Expr_Kind => Single); Set_Next_Literal_String (Last_String, In_Tree, To => Next_String); Last_String := Next_String; Scan (In_Tree); end if; end loop; end Parse_String_Type_List; ------------------------------ -- Parse_Variable_Reference -- ------------------------------ procedure Parse_Variable_Reference (In_Tree : Project_Node_Tree_Ref; Variable : out Project_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Flags : Processing_Flags) is Current_Variable : Project_Node_Id := Empty_Node; The_Package : Project_Node_Id := Current_Package; The_Project : Project_Node_Id := Current_Project; Specified_Project : Project_Node_Id := Empty_Node; Specified_Package : Project_Node_Id := Empty_Node; Look_For_Variable : Boolean := True; First_Attribute : Attribute_Node_Id := Empty_Attribute; Variable_Name : Name_Id; begin Names.Init; loop Expect (Tok_Identifier, "identifier"); if Token /= Tok_Identifier then Look_For_Variable := False; exit; end if; Add_To_Names (NL => (Name => Token_Name, Location => Token_Ptr)); Scan (In_Tree); exit when Token /= Tok_Dot; Scan (In_Tree); end loop; if Look_For_Variable then if Token = Tok_Apostrophe then -- Attribute reference case Names.Last is when 0 => -- Cannot happen null; when 1 => -- This may be a project name or a package name. -- Project name have precedence. -- First, look if it can be a package name First_Attribute := First_Attribute_Of (Package_Node_Id_Of (Names.Table (1).Name)); -- Now, look if it can be a project name if Names.Table (1).Name = Name_Of (Current_Project, In_Tree) then The_Project := Current_Project; else The_Project := Imported_Or_Extended_Project_Of (Current_Project, In_Tree, Names.Table (1).Name); end if; if No (The_Project) then -- If it is neither a project name nor a package name, -- report an error. if First_Attribute = Empty_Attribute then Error_Msg_Name_1 := Names.Table (1).Name; Error_Msg (Flags, "unknown project %", Names.Table (1).Location); First_Attribute := Attribute_First; else -- If it is a package name, check if the package has -- already been declared in the current project. The_Package := First_Package_Of (Current_Project, In_Tree); while Present (The_Package) and then Name_Of (The_Package, In_Tree) /= Names.Table (1).Name loop The_Package := Next_Package_In_Project (The_Package, In_Tree); end loop; -- If it has not been already declared, report an -- error. if No (The_Package) then Error_Msg_Name_1 := Names.Table (1).Name; Error_Msg (Flags, "package % not yet defined", Names.Table (1).Location); end if; end if; else -- It is a project name First_Attribute := Attribute_First; The_Package := Empty_Node; end if; when others => -- We have either a project name made of several simple -- names (long project), or a project name (short project) -- followed by a package name. The long project name has -- precedence. declare Short_Project : Name_Id; Long_Project : Name_Id; begin -- Clear the Buffer Buffer_Last := 0; -- Get the name of the short project for Index in 1 .. Names.Last - 1 loop Add_To_Buffer (Get_Name_String (Names.Table (Index).Name), Buffer, Buffer_Last); if Index /= Names.Last - 1 then Add_To_Buffer (".", Buffer, Buffer_Last); end if; end loop; Name_Len := Buffer_Last; Name_Buffer (1 .. Buffer_Last) := Buffer (1 .. Buffer_Last); Short_Project := Name_Find; -- Now, add the last simple name to get the name of the -- long project. Add_To_Buffer (".", Buffer, Buffer_Last); Add_To_Buffer (Get_Name_String (Names.Table (Names.Last).Name), Buffer, Buffer_Last); Name_Len := Buffer_Last; Name_Buffer (1 .. Buffer_Last) := Buffer (1 .. Buffer_Last); Long_Project := Name_Find; -- Check if the long project is imported or extended if Long_Project = Name_Of (Current_Project, In_Tree) then The_Project := Current_Project; else The_Project := Imported_Or_Extended_Project_Of (Current_Project, In_Tree, Long_Project); end if; -- If the long project exists, then this is the prefix -- of the attribute. if Present (The_Project) then First_Attribute := Attribute_First; The_Package := Empty_Node; else -- Otherwise, check if the short project is imported -- or extended. if Short_Project = Name_Of (Current_Project, In_Tree) then The_Project := Current_Project; else The_Project := Imported_Or_Extended_Project_Of (Current_Project, In_Tree, Short_Project); end if; -- If short project does not exist, report an error if No (The_Project) then Error_Msg_Name_1 := Long_Project; Error_Msg_Name_2 := Short_Project; Error_Msg (Flags, "unknown projects % or %", Names.Table (1).Location); The_Package := Empty_Node; First_Attribute := Attribute_First; else -- Now, we check if the package has been declared -- in this project. The_Package := First_Package_Of (The_Project, In_Tree); while Present (The_Package) and then Name_Of (The_Package, In_Tree) /= Names.Table (Names.Last).Name loop The_Package := Next_Package_In_Project (The_Package, In_Tree); end loop; -- If it has not, then we report an error if No (The_Package) then Error_Msg_Name_1 := Names.Table (Names.Last).Name; Error_Msg_Name_2 := Short_Project; Error_Msg (Flags, "package % not declared in project %", Names.Table (Names.Last).Location); First_Attribute := Attribute_First; else -- Otherwise, we have the correct project and -- package. First_Attribute := First_Attribute_Of (Package_Id_Of (The_Package, In_Tree)); end if; end if; end if; end; end case; Attribute_Reference (In_Tree, Variable, Flags => Flags, Current_Project => The_Project, Current_Package => The_Package, First_Attribute => First_Attribute); return; end if; end if; Variable := Default_Project_Node (Of_Kind => N_Variable_Reference, In_Tree => In_Tree); if Look_For_Variable then case Names.Last is when 0 => -- Cannot happen (so why null instead of raise PE???) null; when 1 => -- Simple variable name Set_Name_Of (Variable, In_Tree, To => Names.Table (1).Name); when 2 => -- Variable name with a simple name prefix that can be -- a project name or a package name. Project names have -- priority over package names. Set_Name_Of (Variable, In_Tree, To => Names.Table (2).Name); -- Check if it can be a package name The_Package := First_Package_Of (Current_Project, In_Tree); while Present (The_Package) and then Name_Of (The_Package, In_Tree) /= Names.Table (1).Name loop The_Package := Next_Package_In_Project (The_Package, In_Tree); end loop; -- Now look for a possible project name The_Project := Imported_Or_Extended_Project_Of (Current_Project, In_Tree, Names.Table (1).Name); if Present (The_Project) then Specified_Project := The_Project; elsif No (The_Package) then Error_Msg_Name_1 := Names.Table (1).Name; Error_Msg (Flags, "unknown package or project %", Names.Table (1).Location); Look_For_Variable := False; else Specified_Package := The_Package; end if; when others => -- Variable name with a prefix that is either a project name -- made of several simple names, or a project name followed -- by a package name. Set_Name_Of (Variable, In_Tree, To => Names.Table (Names.Last).Name); declare Short_Project : Name_Id; Long_Project : Name_Id; begin -- First, we get the two possible project names -- Clear the buffer Buffer_Last := 0; -- Add all the simple names, except the last two for Index in 1 .. Names.Last - 2 loop Add_To_Buffer (Get_Name_String (Names.Table (Index).Name), Buffer, Buffer_Last); if Index /= Names.Last - 2 then Add_To_Buffer (".", Buffer, Buffer_Last); end if; end loop; Name_Len := Buffer_Last; Name_Buffer (1 .. Name_Len) := Buffer (1 .. Buffer_Last); Short_Project := Name_Find; -- Add the simple name before the name of the variable Add_To_Buffer (".", Buffer, Buffer_Last); Add_To_Buffer (Get_Name_String (Names.Table (Names.Last - 1).Name), Buffer, Buffer_Last); Name_Len := Buffer_Last; Name_Buffer (1 .. Name_Len) := Buffer (1 .. Buffer_Last); Long_Project := Name_Find; -- Check if the prefix is the name of an imported or -- extended project. The_Project := Imported_Or_Extended_Project_Of (Current_Project, In_Tree, Long_Project); if Present (The_Project) then Specified_Project := The_Project; else -- Now check if the prefix may be a project name followed -- by a package name. -- First check for a possible project name The_Project := Imported_Or_Extended_Project_Of (Current_Project, In_Tree, Short_Project); if No (The_Project) then -- Unknown prefix, report an error Error_Msg_Name_1 := Long_Project; Error_Msg_Name_2 := Short_Project; Error_Msg (Flags, "unknown projects % or %", Names.Table (1).Location); Look_For_Variable := False; else Specified_Project := The_Project; -- Now look for the package in this project The_Package := First_Package_Of (The_Project, In_Tree); while Present (The_Package) and then Name_Of (The_Package, In_Tree) /= Names.Table (Names.Last - 1).Name loop The_Package := Next_Package_In_Project (The_Package, In_Tree); end loop; if No (The_Package) then -- The package does not exist, report an error Error_Msg_Name_1 := Names.Table (2).Name; Error_Msg (Flags, "unknown package %", Names.Table (Names.Last - 1).Location); Look_For_Variable := False; else Specified_Package := The_Package; end if; end if; end if; end; end case; end if; if Look_For_Variable then Variable_Name := Name_Of (Variable, In_Tree); Set_Project_Node_Of (Variable, In_Tree, To => Specified_Project); Set_Package_Node_Of (Variable, In_Tree, To => Specified_Package); if Present (Specified_Project) then The_Project := Specified_Project; else The_Project := Current_Project; end if; Current_Variable := Empty_Node; -- Look for this variable -- If a package was specified, check if the variable has been -- declared in this package. if Present (Specified_Package) then Current_Variable := First_Variable_Of (Specified_Package, In_Tree); while Present (Current_Variable) and then Name_Of (Current_Variable, In_Tree) /= Variable_Name loop Current_Variable := Next_Variable (Current_Variable, In_Tree); end loop; else -- Otherwise, if no project has been specified and we are in -- a package, first check if the variable has been declared in -- the package. if No (Specified_Project) and then Present (Current_Package) then Current_Variable := First_Variable_Of (Current_Package, In_Tree); while Present (Current_Variable) and then Name_Of (Current_Variable, In_Tree) /= Variable_Name loop Current_Variable := Next_Variable (Current_Variable, In_Tree); end loop; end if; -- If we have not found the variable in the package, check if the -- variable has been declared in the project, or in any of its -- ancestors. if No (Current_Variable) then declare Proj : Project_Node_Id := The_Project; begin loop Current_Variable := First_Variable_Of (Proj, In_Tree); while Present (Current_Variable) and then Name_Of (Current_Variable, In_Tree) /= Variable_Name loop Current_Variable := Next_Variable (Current_Variable, In_Tree); end loop; exit when Present (Current_Variable); Proj := Parent_Project_Of (Proj, In_Tree); Set_Project_Node_Of (Variable, In_Tree, To => Proj); exit when No (Proj); end loop; end; end if; end if; -- If the variable was not found, report an error if No (Current_Variable) then Error_Msg_Name_1 := Variable_Name; Error_Msg (Flags, "unknown variable %", Names.Table (Names.Last).Location); end if; end if; if Present (Current_Variable) then Set_Expression_Kind_Of (Variable, In_Tree, To => Expression_Kind_Of (Current_Variable, In_Tree)); if Kind_Of (Current_Variable, In_Tree) = N_Typed_Variable_Declaration then Set_String_Type_Of (Variable, In_Tree, To => String_Type_Of (Current_Variable, In_Tree)); end if; end if; -- If the variable is followed by a left parenthesis, report an error -- but attempt to scan the index. if Token = Tok_Left_Paren then Error_Msg (Flags, "\variables cannot be associative arrays", Token_Ptr); Scan (In_Tree); Expect (Tok_String_Literal, "literal string"); if Token = Tok_String_Literal then Scan (In_Tree); Expect (Tok_Right_Paren, "`)`"); if Token = Tok_Right_Paren then Scan (In_Tree); end if; end if; end if; end Parse_Variable_Reference; --------------------------------- -- Start_New_Case_Construction -- --------------------------------- procedure Start_New_Case_Construction (In_Tree : Project_Node_Tree_Ref; String_Type : Project_Node_Id) is Current_String : Project_Node_Id; begin -- Set Choice_First, depending on whether this is the first case -- construction or not. if Choice_First = 0 then Choice_First := 1; Choices.Set_Last (First_Choice_Node_Id); else Choice_First := Choices.Last + 1; end if; -- Add the literal of the string type to the Choices table if Present (String_Type) then Current_String := First_Literal_String (String_Type, In_Tree); while Present (Current_String) loop Add (This_String => String_Value_Of (Current_String, In_Tree)); Current_String := Next_Literal_String (Current_String, In_Tree); end loop; end if; -- Set the value of the last choice in table Choice_Lasts Choice_Lasts.Increment_Last; Choice_Lasts.Table (Choice_Lasts.Last) := Choices.Last; end Start_New_Case_Construction; ----------- -- Terms -- ----------- procedure Terms (In_Tree : Project_Node_Tree_Ref; Term : out Project_Node_Id; Expr_Kind : in out Variable_Kind; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Optional_Index : Boolean; Flags : Processing_Flags) is Next_Term : Project_Node_Id := Empty_Node; Term_Id : Project_Node_Id := Empty_Node; Current_Expression : Project_Node_Id := Empty_Node; Next_Expression : Project_Node_Id := Empty_Node; Current_Location : Source_Ptr := No_Location; Reference : Project_Node_Id := Empty_Node; begin -- Declare a new node for the term Term := Default_Project_Node (Of_Kind => N_Term, In_Tree => In_Tree); Set_Location_Of (Term, In_Tree, To => Token_Ptr); case Token is when Tok_Left_Paren => -- If we have a left parenthesis and we don't know the expression -- kind, then this is a string list. case Expr_Kind is when Undefined => Expr_Kind := List; when List => null; when Single => -- If we already know that this is a single string, report -- an error, but set the expression kind to string list to -- avoid several errors. Expr_Kind := List; Error_Msg (Flags, "literal string list cannot appear in a string", Token_Ptr); end case; -- Declare a new node for this literal string list Term_Id := Default_Project_Node (Of_Kind => N_Literal_String_List, In_Tree => In_Tree, And_Expr_Kind => List); Set_Current_Term (Term, In_Tree, To => Term_Id); Set_Location_Of (Term, In_Tree, To => Token_Ptr); -- Scan past the left parenthesis Scan (In_Tree); -- If the left parenthesis is immediately followed by a right -- parenthesis, the literal string list is empty. if Token = Tok_Right_Paren then Scan (In_Tree); else -- Otherwise parse the expression(s) in the literal string list loop Current_Location := Token_Ptr; Parse_Expression (In_Tree => In_Tree, Expression => Next_Expression, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package, Optional_Index => Optional_Index); -- The expression kind is String list, report an error if Expression_Kind_Of (Next_Expression, In_Tree) = List then Error_Msg (Flags, "single expression expected", Current_Location); end if; -- If Current_Expression is empty, it means that the -- expression is the first in the string list. if No (Current_Expression) then Set_First_Expression_In_List (Term_Id, In_Tree, To => Next_Expression); else Set_Next_Expression_In_List (Current_Expression, In_Tree, To => Next_Expression); end if; Current_Expression := Next_Expression; -- If there is a comma, continue with the next expression exit when Token /= Tok_Comma; Scan (In_Tree); -- past the comma end loop; -- We expect a closing right parenthesis Expect (Tok_Right_Paren, "`)`"); if Token = Tok_Right_Paren then Scan (In_Tree); end if; end if; when Tok_String_Literal => -- If we don't know the expression kind (first term), then it is -- a simple string. if Expr_Kind = Undefined then Expr_Kind := Single; end if; -- Declare a new node for the string literal Term_Id := Default_Project_Node (Of_Kind => N_Literal_String, In_Tree => In_Tree); Set_Current_Term (Term, In_Tree, To => Term_Id); Set_String_Value_Of (Term_Id, In_Tree, To => Token_Name); -- Scan past the string literal Scan (In_Tree); -- Check for possible index expression if Token = Tok_At then if not Optional_Index then Error_Msg (Flags, "index not allowed here", Token_Ptr); Scan (In_Tree); if Token = Tok_Integer_Literal then Scan (In_Tree); end if; -- Set the index value else Scan (In_Tree); Expect (Tok_Integer_Literal, "integer literal"); if Token = Tok_Integer_Literal then declare Index : constant Int := UI_To_Int (Int_Literal_Value); begin if Index = 0 then Error_Msg (Flags, "index cannot be zero", Token_Ptr); else Set_Source_Index_Of (Term_Id, In_Tree, To => Index); end if; end; Scan (In_Tree); end if; end if; end if; when Tok_Identifier => Current_Location := Token_Ptr; -- Get the variable or attribute reference Parse_Variable_Reference (In_Tree => In_Tree, Variable => Reference, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package); Set_Current_Term (Term, In_Tree, To => Reference); if Present (Reference) then -- If we don't know the expression kind (first term), then it -- has the kind of the variable or attribute reference. if Expr_Kind = Undefined then Expr_Kind := Expression_Kind_Of (Reference, In_Tree); elsif Expr_Kind = Single and then Expression_Kind_Of (Reference, In_Tree) = List then -- If the expression is a single list, and the reference is -- a string list, report an error, and set the expression -- kind to string list to avoid multiple errors. Expr_Kind := List; Error_Msg (Flags, "list variable cannot appear in single string expression", Current_Location); end if; end if; when Tok_Project => -- Project can appear in an expression as the prefix of an -- attribute reference of the current project. Current_Location := Token_Ptr; Scan (In_Tree); Expect (Tok_Apostrophe, "`'`"); if Token = Tok_Apostrophe then Attribute_Reference (In_Tree => In_Tree, Reference => Reference, Flags => Flags, First_Attribute => Prj.Attr.Attribute_First, Current_Project => Current_Project, Current_Package => Empty_Node); Set_Current_Term (Term, In_Tree, To => Reference); end if; -- Same checks as above for the expression kind if Present (Reference) then if Expr_Kind = Undefined then Expr_Kind := Expression_Kind_Of (Reference, In_Tree); elsif Expr_Kind = Single and then Expression_Kind_Of (Reference, In_Tree) = List then Error_Msg (Flags, "lists cannot appear in single string expression", Current_Location); end if; end if; when Tok_External | Tok_External_As_List => External_Reference (In_Tree => In_Tree, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package, Expr_Kind => Expr_Kind, External_Value => Reference); Set_Current_Term (Term, In_Tree, To => Reference); when others => Error_Msg (Flags, "cannot be part of an expression", Token_Ptr); Term := Empty_Node; return; end case; -- If there is an '&', call Terms recursively if Token = Tok_Ampersand then Scan (In_Tree); -- scan past ampersand Terms (In_Tree => In_Tree, Term => Next_Term, Expr_Kind => Expr_Kind, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package, Optional_Index => Optional_Index); -- And link the next term to this term Set_Next_Term (Term, In_Tree, To => Next_Term); end if; end Terms; end Prj.Strt; gprbuild-gpl-2014-src/gnat/sinput-p.adb0000644000076700001450000001461312323721731017320 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S I N P U T . P -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Ada.Unchecked_Conversion; with Ada.Unchecked_Deallocation; with Prj.Err; with Sinput.C; with System; package body Sinput.P is First : Boolean := True; -- Flag used when Load_Project_File is called the first time, -- to set Main_Source_File. -- The flag is reset to False at the first call to Load_Project_File. -- Calling Reset_First sets it back to True. procedure Free is new Ada.Unchecked_Deallocation (Lines_Table_Type, Lines_Table_Ptr); procedure Free is new Ada.Unchecked_Deallocation (Logical_Lines_Table_Type, Logical_Lines_Table_Ptr); ----------------------------- -- Clear_Source_File_Table -- ----------------------------- procedure Clear_Source_File_Table is use System; begin for X in 1 .. Source_File.Last loop declare S : Source_File_Record renames Source_File.Table (X); Lo : constant Source_Ptr := S.Source_First; Hi : constant Source_Ptr := S.Source_Last; subtype Actual_Source_Buffer is Source_Buffer (Lo .. Hi); -- Physical buffer allocated type Actual_Source_Ptr is access Actual_Source_Buffer; -- This is the pointer type for the physical buffer allocated procedure Free is new Ada.Unchecked_Deallocation (Actual_Source_Buffer, Actual_Source_Ptr); pragma Suppress (All_Checks); pragma Warnings (Off); -- The following unchecked conversion is aliased safe, since it -- is not used to create improperly aliased pointer values. function To_Actual_Source_Ptr is new Ada.Unchecked_Conversion (Address, Actual_Source_Ptr); pragma Warnings (On); Actual_Ptr : Actual_Source_Ptr := To_Actual_Source_Ptr (S.Source_Text (Lo)'Address); begin Free (Actual_Ptr); Free (S.Lines_Table); Free (S.Logical_Lines_Table); end; end loop; Source_File.Free; Sinput.Initialize; end Clear_Source_File_Table; ----------------------- -- Load_Project_File -- ----------------------- function Load_Project_File (Path : String) return Source_File_Index is X : Source_File_Index; begin X := Sinput.C.Load_File (Path); if First then Main_Source_File := X; First := False; end if; return X; end Load_Project_File; ----------------- -- Reset_First -- ----------------- procedure Reset_First is begin First := True; end Reset_First; -------------------------------- -- Restore_Project_Scan_State -- -------------------------------- procedure Restore_Project_Scan_State (Saved_State : Saved_Project_Scan_State) is begin Restore_Scan_State (Saved_State.Scan_State); Source := Saved_State.Source; Current_Source_File := Saved_State.Current_Source_File; end Restore_Project_Scan_State; ----------------------------- -- Save_Project_Scan_State -- ----------------------------- procedure Save_Project_Scan_State (Saved_State : out Saved_Project_Scan_State) is begin Save_Scan_State (Saved_State.Scan_State); Saved_State.Source := Source; Saved_State.Current_Source_File := Current_Source_File; end Save_Project_Scan_State; ---------------------------- -- Source_File_Is_Subunit -- ---------------------------- function Source_File_Is_Subunit (X : Source_File_Index) return Boolean is begin -- Nothing to do if X is no source file, so simply return False if X = No_Source_File then return False; end if; Prj.Err.Scanner.Initialize_Scanner (X); -- No error for special characters that are used for preprocessing Prj.Err.Scanner.Set_Special_Character ('#'); Prj.Err.Scanner.Set_Special_Character ('$'); Check_For_BOM; -- We scan past junk to the first interesting compilation unit token, to -- see if it is SEPARATE. We ignore WITH keywords during this and also -- PRIVATE. The reason for ignoring PRIVATE is that it handles some -- error situations, and also to handle PRIVATE WITH in Ada 2005 mode. while Token = Tok_With or else Token = Tok_Private or else (Token not in Token_Class_Cunit and then Token /= Tok_EOF) loop Prj.Err.Scanner.Scan; end loop; Prj.Err.Scanner.Reset_Special_Characters; return Token = Tok_Separate; end Source_File_Is_Subunit; end Sinput.P; gprbuild-gpl-2014-src/gnat/butil.adb0000644000076700001450000001326412323721731016661 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- B U T I L -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Output; use Output; with Targparm; use Targparm; package body Butil is ---------------------- -- Is_Internal_Unit -- ---------------------- -- Note: the reason we do not use the Fname package for this function -- is that it would drag too much junk into the binder. function Is_Internal_Unit return Boolean is begin return Is_Predefined_Unit or else (Name_Len > 4 and then (Name_Buffer (1 .. 5) = "gnat%" or else Name_Buffer (1 .. 5) = "gnat.")) or else (OpenVMS_On_Target and then Name_Len > 3 and then (Name_Buffer (1 .. 4) = "dec%" or else Name_Buffer (1 .. 4) = "dec.")); end Is_Internal_Unit; ------------------------ -- Is_Predefined_Unit -- ------------------------ -- Note: the reason we do not use the Fname package for this function -- is that it would drag too much junk into the binder. function Is_Predefined_Unit return Boolean is begin return (Name_Len > 3 and then Name_Buffer (1 .. 4) = "ada.") or else (Name_Len > 6 and then Name_Buffer (1 .. 7) = "system.") or else (Name_Len > 10 and then Name_Buffer (1 .. 11) = "interfaces.") or else (Name_Len > 3 and then Name_Buffer (1 .. 4) = "ada%") or else (Name_Len > 8 and then Name_Buffer (1 .. 9) = "calendar%") or else (Name_Len > 9 and then Name_Buffer (1 .. 10) = "direct_io%") or else (Name_Len > 10 and then Name_Buffer (1 .. 11) = "interfaces%") or else (Name_Len > 13 and then Name_Buffer (1 .. 14) = "io_exceptions%") or else (Name_Len > 12 and then Name_Buffer (1 .. 13) = "machine_code%") or else (Name_Len > 13 and then Name_Buffer (1 .. 14) = "sequential_io%") or else (Name_Len > 6 and then Name_Buffer (1 .. 7) = "system%") or else (Name_Len > 7 and then Name_Buffer (1 .. 8) = "text_io%") or else (Name_Len > 20 and then Name_Buffer (1 .. 21) = "unchecked_conversion%") or else (Name_Len > 22 and then Name_Buffer (1 .. 23) = "unchecked_deallocation%") or else (Name_Len > 4 and then Name_Buffer (1 .. 5) = "gnat%") or else (Name_Len > 4 and then Name_Buffer (1 .. 5) = "gnat."); end Is_Predefined_Unit; ---------------- -- Uname_Less -- ---------------- function Uname_Less (U1, U2 : Unit_Name_Type) return Boolean is begin Get_Name_String (U1); declare U1_Name : constant String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len); Min_Length : Natural; begin Get_Name_String (U2); if Name_Len < U1_Name'Last then Min_Length := Name_Len; else Min_Length := U1_Name'Last; end if; for I in 1 .. Min_Length loop if U1_Name (I) > Name_Buffer (I) then return False; elsif U1_Name (I) < Name_Buffer (I) then return True; end if; end loop; return U1_Name'Last < Name_Len; end; end Uname_Less; --------------------- -- Write_Unit_Name -- --------------------- procedure Write_Unit_Name (U : Unit_Name_Type) is begin Get_Name_String (U); Write_Str (Name_Buffer (1 .. Name_Len - 2)); if Name_Buffer (Name_Len) = 's' then Write_Str (" (spec)"); else Write_Str (" (body)"); end if; Name_Len := Name_Len + 5; end Write_Unit_Name; end Butil; gprbuild-gpl-2014-src/gnat/opt.adb0000644000076700001450000004364312323721731016350 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- O P T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Gnatvsn; use Gnatvsn; with System; use System; with Tree_IO; use Tree_IO; package body Opt is SU : constant := Storage_Unit; -- Shorthand for System.Storage_Unit ---------------------------------- -- Register_Opt_Config_Switches -- ---------------------------------- procedure Register_Opt_Config_Switches is begin Ada_Version_Config := Ada_Version; Ada_Version_Pragma_Config := Ada_Version_Pragma; Ada_Version_Explicit_Config := Ada_Version_Explicit; Assertions_Enabled_Config := Assertions_Enabled; Assume_No_Invalid_Values_Config := Assume_No_Invalid_Values; Check_Float_Overflow_Config := Check_Float_Overflow; Check_Policy_List_Config := Check_Policy_List; Default_Pool_Config := Default_Pool; Default_SSO_Config := Default_SSO; Dynamic_Elaboration_Checks_Config := Dynamic_Elaboration_Checks; Exception_Locations_Suppressed_Config := Exception_Locations_Suppressed; Extensions_Allowed_Config := Extensions_Allowed; External_Name_Exp_Casing_Config := External_Name_Exp_Casing; External_Name_Imp_Casing_Config := External_Name_Imp_Casing; Fast_Math_Config := Fast_Math; Initialize_Scalars_Config := Initialize_Scalars; Optimize_Alignment_Config := Optimize_Alignment; Persistent_BSS_Mode_Config := Persistent_BSS_Mode; Polling_Required_Config := Polling_Required; Short_Descriptors_Config := Short_Descriptors; SPARK_Mode_Config := SPARK_Mode; SPARK_Mode_Pragma_Config := SPARK_Mode_Pragma; Uneval_Old_Config := Uneval_Old; Use_VADS_Size_Config := Use_VADS_Size; Warnings_As_Errors_Count_Config := Warnings_As_Errors_Count; -- Reset the indication that Optimize_Alignment was set locally, since -- if we had a pragma in the config file, it would set this flag True, -- but that's not a local setting. Optimize_Alignment_Local := False; end Register_Opt_Config_Switches; --------------------------------- -- Restore_Opt_Config_Switches -- --------------------------------- procedure Restore_Opt_Config_Switches (Save : Config_Switches_Type) is begin Ada_Version := Save.Ada_Version; Ada_Version_Pragma := Save.Ada_Version_Pragma; Ada_Version_Explicit := Save.Ada_Version_Explicit; Assertions_Enabled := Save.Assertions_Enabled; Assume_No_Invalid_Values := Save.Assume_No_Invalid_Values; Check_Float_Overflow := Save.Check_Float_Overflow; Check_Policy_List := Save.Check_Policy_List; Default_Pool := Save.Default_Pool; Default_SSO := Save.Default_SSO; Dynamic_Elaboration_Checks := Save.Dynamic_Elaboration_Checks; Exception_Locations_Suppressed := Save.Exception_Locations_Suppressed; Extensions_Allowed := Save.Extensions_Allowed; External_Name_Exp_Casing := Save.External_Name_Exp_Casing; External_Name_Imp_Casing := Save.External_Name_Imp_Casing; Fast_Math := Save.Fast_Math; Initialize_Scalars := Save.Initialize_Scalars; Optimize_Alignment := Save.Optimize_Alignment; Optimize_Alignment_Local := Save.Optimize_Alignment_Local; Persistent_BSS_Mode := Save.Persistent_BSS_Mode; Polling_Required := Save.Polling_Required; Short_Descriptors := Save.Short_Descriptors; SPARK_Mode := Save.SPARK_Mode; SPARK_Mode_Pragma := Save.SPARK_Mode_Pragma; Uneval_Old := Save.Uneval_Old; Use_VADS_Size := Save.Use_VADS_Size; Warnings_As_Errors_Count := Save.Warnings_As_Errors_Count; -- Update consistently the value of Init_Or_Norm_Scalars. The value of -- Normalize_Scalars is not saved/restored because after set to True its -- value is never changed. That is, if a compilation unit has pragma -- Normalize_Scalars then it forces that value for all with'ed units. Init_Or_Norm_Scalars := Initialize_Scalars or Normalize_Scalars; end Restore_Opt_Config_Switches; ------------------------------ -- Save_Opt_Config_Switches -- ------------------------------ procedure Save_Opt_Config_Switches (Save : out Config_Switches_Type) is begin Save.Ada_Version := Ada_Version; Save.Ada_Version_Pragma := Ada_Version_Pragma; Save.Ada_Version_Explicit := Ada_Version_Explicit; Save.Assertions_Enabled := Assertions_Enabled; Save.Assume_No_Invalid_Values := Assume_No_Invalid_Values; Save.Check_Float_Overflow := Check_Float_Overflow; Save.Check_Policy_List := Check_Policy_List; Save.Default_Pool := Default_Pool; Save.Default_SSO := Default_SSO; Save.Dynamic_Elaboration_Checks := Dynamic_Elaboration_Checks; Save.Exception_Locations_Suppressed := Exception_Locations_Suppressed; Save.Extensions_Allowed := Extensions_Allowed; Save.External_Name_Exp_Casing := External_Name_Exp_Casing; Save.External_Name_Imp_Casing := External_Name_Imp_Casing; Save.Fast_Math := Fast_Math; Save.Initialize_Scalars := Initialize_Scalars; Save.Optimize_Alignment := Optimize_Alignment; Save.Optimize_Alignment_Local := Optimize_Alignment_Local; Save.Persistent_BSS_Mode := Persistent_BSS_Mode; Save.Polling_Required := Polling_Required; Save.Short_Descriptors := Short_Descriptors; Save.SPARK_Mode := SPARK_Mode; Save.SPARK_Mode_Pragma := SPARK_Mode_Pragma; Save.Uneval_Old := Uneval_Old; Save.Use_VADS_Size := Use_VADS_Size; Save.Warnings_As_Errors_Count := Warnings_As_Errors_Count; end Save_Opt_Config_Switches; ----------------------------- -- Set_Opt_Config_Switches -- ----------------------------- procedure Set_Opt_Config_Switches (Internal_Unit : Boolean; Main_Unit : Boolean) is begin -- Case of internal unit if Internal_Unit then -- Set standard switches. Note we do NOT set Ada_Version_Explicit -- since the whole point of this is that it still properly indicates -- the configuration setting even in a run time unit. Ada_Version := Ada_Version_Runtime; Ada_Version_Pragma := Empty; Dynamic_Elaboration_Checks := False; Extensions_Allowed := True; External_Name_Exp_Casing := As_Is; External_Name_Imp_Casing := Lowercase; Optimize_Alignment := 'O'; Persistent_BSS_Mode := False; Uneval_Old := 'E'; Use_VADS_Size := False; Optimize_Alignment_Local := True; -- Note: we do not need to worry about Warnings_As_Errors_Count since -- we do not expect to get any warnings from compiling such a unit. -- For an internal unit, assertions/debug pragmas are off unless this -- is the main unit and they were explicitly enabled. We also make -- sure we do not assume that values are necessarily valid and that -- SPARK_Mode is set to its configuration value. if Main_Unit then Assertions_Enabled := Assertions_Enabled_Config; Assume_No_Invalid_Values := Assume_No_Invalid_Values_Config; Check_Policy_List := Check_Policy_List_Config; Default_SSO := Default_SSO_Config; SPARK_Mode := SPARK_Mode_Config; SPARK_Mode_Pragma := SPARK_Mode_Pragma_Config; else Assertions_Enabled := False; Assume_No_Invalid_Values := False; Check_Policy_List := Empty; SPARK_Mode := None; SPARK_Mode_Pragma := Empty; end if; -- Case of non-internal unit else Ada_Version := Ada_Version_Config; Ada_Version_Pragma := Ada_Version_Pragma_Config; Ada_Version_Explicit := Ada_Version_Explicit_Config; Assertions_Enabled := Assertions_Enabled_Config; Assume_No_Invalid_Values := Assume_No_Invalid_Values_Config; Check_Float_Overflow := Check_Float_Overflow_Config; Check_Policy_List := Check_Policy_List_Config; Default_SSO := Default_SSO_Config; Dynamic_Elaboration_Checks := Dynamic_Elaboration_Checks_Config; Extensions_Allowed := Extensions_Allowed_Config; External_Name_Exp_Casing := External_Name_Exp_Casing_Config; External_Name_Imp_Casing := External_Name_Imp_Casing_Config; Fast_Math := Fast_Math_Config; Initialize_Scalars := Initialize_Scalars_Config; Optimize_Alignment := Optimize_Alignment_Config; Optimize_Alignment_Local := False; Persistent_BSS_Mode := Persistent_BSS_Mode_Config; SPARK_Mode := SPARK_Mode_Config; SPARK_Mode_Pragma := SPARK_Mode_Pragma_Config; Uneval_Old := Uneval_Old_Config; Use_VADS_Size := Use_VADS_Size_Config; Warnings_As_Errors_Count := Warnings_As_Errors_Count_Config; -- Update consistently the value of Init_Or_Norm_Scalars. The value -- of Normalize_Scalars is not saved/restored because once set to -- True its value is never changed. That is, if a compilation unit -- has pragma Normalize_Scalars then it forces that value for all -- with'ed units. Init_Or_Norm_Scalars := Initialize_Scalars or Normalize_Scalars; end if; Default_Pool := Default_Pool_Config; Exception_Locations_Suppressed := Exception_Locations_Suppressed_Config; Fast_Math := Fast_Math_Config; Optimize_Alignment := Optimize_Alignment_Config; Polling_Required := Polling_Required_Config; Short_Descriptors := Short_Descriptors_Config; end Set_Opt_Config_Switches; --------------- -- Tree_Read -- --------------- procedure Tree_Read is Tree_Version_String_Len : Nat; Ada_Version_Config_Val : Nat; Ada_Version_Explicit_Config_Val : Nat; Assertions_Enabled_Config_Val : Nat; begin Tree_Read_Int (Tree_ASIS_Version_Number); Tree_Read_Bool (Address_Is_Private); Tree_Read_Bool (Brief_Output); Tree_Read_Bool (GNAT_Mode); Tree_Read_Char (Identifier_Character_Set); Tree_Read_Bool (Ignore_Rep_Clauses); Tree_Read_Bool (Ignore_Style_Checks_Pragmas); Tree_Read_Int (Maximum_File_Name_Length); Tree_Read_Data (Suppress_Options'Address, (Suppress_Options'Size + SU - 1) / SU); Tree_Read_Bool (Verbose_Mode); Tree_Read_Data (Warning_Mode'Address, (Warning_Mode'Size + SU - 1) / SU); Tree_Read_Int (Ada_Version_Config_Val); Tree_Read_Int (Ada_Version_Explicit_Config_Val); Tree_Read_Int (Assertions_Enabled_Config_Val); Tree_Read_Bool (All_Errors_Mode); Tree_Read_Bool (Assertions_Enabled); Tree_Read_Bool (Check_Float_Overflow); Tree_Read_Int (Int (Check_Policy_List)); Tree_Read_Int (Int (Default_Pool)); Tree_Read_Bool (Full_List); Ada_Version_Config := Ada_Version_Type'Val (Ada_Version_Config_Val); Ada_Version_Explicit_Config := Ada_Version_Type'Val (Ada_Version_Explicit_Config_Val); Assertions_Enabled_Config := Boolean'Val (Assertions_Enabled_Config_Val); -- Read version string: we have to get the length first Tree_Read_Int (Tree_Version_String_Len); declare Tmp : String (1 .. Integer (Tree_Version_String_Len)); begin Tree_Read_Data (Tmp'Address, Tree_Version_String_Len); System.Strings.Free (Tree_Version_String); Free (Tree_Version_String); Tree_Version_String := new String'(Tmp); end; Tree_Read_Data (Distribution_Stub_Mode'Address, (Distribution_Stub_Mode'Size + SU - 1) / Storage_Unit); Tree_Read_Bool (Inline_Active); Tree_Read_Bool (Inline_Processing_Required); Tree_Read_Bool (List_Units); Tree_Read_Int (Multiple_Unit_Index); Tree_Read_Bool (Configurable_Run_Time_Mode); Tree_Read_Data (Operating_Mode'Address, (Operating_Mode'Size + SU - 1) / Storage_Unit); Tree_Read_Bool (Suppress_Checks); Tree_Read_Bool (Try_Semantics); Tree_Read_Data (Wide_Character_Encoding_Method'Address, (Wide_Character_Encoding_Method'Size + SU - 1) / SU); Tree_Read_Bool (Upper_Half_Encoding); Tree_Read_Bool (Force_ALI_Tree_File); end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is Version_String : String := Gnat_Version_String; begin Tree_Write_Int (ASIS_Version_Number); Tree_Write_Bool (Address_Is_Private); Tree_Write_Bool (Brief_Output); Tree_Write_Bool (GNAT_Mode); Tree_Write_Char (Identifier_Character_Set); Tree_Write_Bool (Ignore_Rep_Clauses); Tree_Write_Bool (Ignore_Style_Checks_Pragmas); Tree_Write_Int (Maximum_File_Name_Length); Tree_Write_Data (Suppress_Options'Address, (Suppress_Options'Size + SU - 1) / SU); Tree_Write_Bool (Verbose_Mode); Tree_Write_Data (Warning_Mode'Address, (Warning_Mode'Size + SU - 1) / Storage_Unit); Tree_Write_Int (Ada_Version_Type'Pos (Ada_Version_Config)); Tree_Write_Int (Ada_Version_Type'Pos (Ada_Version_Explicit_Config)); Tree_Write_Int (Boolean'Pos (Assertions_Enabled_Config)); Tree_Write_Bool (All_Errors_Mode); Tree_Write_Bool (Assertions_Enabled); Tree_Write_Bool (Check_Float_Overflow); Tree_Write_Int (Int (Check_Policy_List)); Tree_Write_Int (Int (Default_Pool)); Tree_Write_Bool (Full_List); Tree_Write_Int (Int (Version_String'Length)); Tree_Write_Data (Version_String'Address, Version_String'Length); Tree_Write_Data (Distribution_Stub_Mode'Address, (Distribution_Stub_Mode'Size + SU - 1) / SU); Tree_Write_Bool (Inline_Active); Tree_Write_Bool (Inline_Processing_Required); Tree_Write_Bool (List_Units); Tree_Write_Int (Multiple_Unit_Index); Tree_Write_Bool (Configurable_Run_Time_Mode); Tree_Write_Data (Operating_Mode'Address, (Operating_Mode'Size + SU - 1) / SU); Tree_Write_Bool (Suppress_Checks); Tree_Write_Bool (Try_Semantics); Tree_Write_Data (Wide_Character_Encoding_Method'Address, (Wide_Character_Encoding_Method'Size + SU - 1) / SU); Tree_Write_Bool (Upper_Half_Encoding); Tree_Write_Bool (Force_ALI_Tree_File); end Tree_Write; end Opt; gprbuild-gpl-2014-src/gnat/sinput.adb0000644000076700001450000011432512323721731017064 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S I N P U T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ pragma Style_Checks (All_Checks); -- Subprograms not all in alpha order with Atree; use Atree; with Debug; use Debug; with Opt; use Opt; with Output; use Output; with Scans; use Scans; with Tree_IO; use Tree_IO; with Widechar; use Widechar; with GNAT.Byte_Order_Mark; use GNAT.Byte_Order_Mark; with System; use System; with System.Memory; with System.WCh_Con; use System.WCh_Con; with Unchecked_Conversion; with Unchecked_Deallocation; package body Sinput is use ASCII; -- Make control characters visible First_Time_Around : Boolean := True; -- This needs a comment ??? -- Routines to support conversion between types Lines_Table_Ptr, -- Logical_Lines_Table_Ptr and System.Address. pragma Warnings (Off); -- These unchecked conversions are aliasing safe, since they are never -- used to construct improperly aliased pointer values. function To_Address is new Unchecked_Conversion (Lines_Table_Ptr, Address); function To_Address is new Unchecked_Conversion (Logical_Lines_Table_Ptr, Address); function To_Pointer is new Unchecked_Conversion (Address, Lines_Table_Ptr); function To_Pointer is new Unchecked_Conversion (Address, Logical_Lines_Table_Ptr); pragma Warnings (On); --------------------------- -- Add_Line_Tables_Entry -- --------------------------- procedure Add_Line_Tables_Entry (S : in out Source_File_Record; P : Source_Ptr) is LL : Physical_Line_Number; begin -- Reallocate the lines tables if necessary -- Note: the reason we do not use the normal Table package -- mechanism is that we have several of these tables. We could -- use the new GNAT.Dynamic_Tables package and that would probably -- be a good idea ??? if S.Last_Source_Line = S.Lines_Table_Max then Alloc_Line_Tables (S, Int (S.Last_Source_Line) * ((100 + Alloc.Lines_Increment) / 100)); if Debug_Flag_D then Write_Str ("--> Reallocating lines table, size = "); Write_Int (Int (S.Lines_Table_Max)); Write_Eol; end if; end if; S.Last_Source_Line := S.Last_Source_Line + 1; LL := S.Last_Source_Line; S.Lines_Table (LL) := P; -- Deal with setting new entry in logical lines table if one is -- present. Note that there is always space (because the call to -- Alloc_Line_Tables makes sure both tables are the same length), if S.Logical_Lines_Table /= null then -- We can always set the entry from the previous one, because -- the processing for a Source_Reference pragma ensures that -- at least one entry following the pragma is set up correctly. S.Logical_Lines_Table (LL) := S.Logical_Lines_Table (LL - 1) + 1; end if; end Add_Line_Tables_Entry; ----------------------- -- Alloc_Line_Tables -- ----------------------- procedure Alloc_Line_Tables (S : in out Source_File_Record; New_Max : Nat) is subtype size_t is Memory.size_t; New_Table : Lines_Table_Ptr; New_Logical_Table : Logical_Lines_Table_Ptr; New_Size : constant size_t := size_t (New_Max * Lines_Table_Type'Component_Size / Storage_Unit); begin if S.Lines_Table = null then New_Table := To_Pointer (Memory.Alloc (New_Size)); else New_Table := To_Pointer (Memory.Realloc (To_Address (S.Lines_Table), New_Size)); end if; if New_Table = null then raise Storage_Error; else S.Lines_Table := New_Table; S.Lines_Table_Max := Physical_Line_Number (New_Max); end if; if S.Num_SRef_Pragmas /= 0 then if S.Logical_Lines_Table = null then New_Logical_Table := To_Pointer (Memory.Alloc (New_Size)); else New_Logical_Table := To_Pointer (Memory.Realloc (To_Address (S.Logical_Lines_Table), New_Size)); end if; if New_Logical_Table = null then raise Storage_Error; else S.Logical_Lines_Table := New_Logical_Table; end if; end if; end Alloc_Line_Tables; ----------------- -- Backup_Line -- ----------------- procedure Backup_Line (P : in out Source_Ptr) is Sindex : constant Source_File_Index := Get_Source_File_Index (P); Src : constant Source_Buffer_Ptr := Source_File.Table (Sindex).Source_Text; Sfirst : constant Source_Ptr := Source_File.Table (Sindex).Source_First; begin P := P - 1; if P = Sfirst then return; end if; if Src (P) = CR then if Src (P - 1) = LF then P := P - 1; end if; else -- Src (P) = LF if Src (P - 1) = CR then P := P - 1; end if; end if; -- Now find first character of the previous line while P > Sfirst and then Src (P - 1) /= LF and then Src (P - 1) /= CR loop P := P - 1; end loop; end Backup_Line; --------------------------- -- Build_Location_String -- --------------------------- procedure Build_Location_String (Loc : Source_Ptr) is Ptr : Source_Ptr; begin -- Loop through instantiations Ptr := Loc; loop Get_Name_String_And_Append (Reference_Name (Get_Source_File_Index (Ptr))); Add_Char_To_Name_Buffer (':'); Add_Nat_To_Name_Buffer (Nat (Get_Logical_Line_Number (Ptr))); Ptr := Instantiation_Location (Ptr); exit when Ptr = No_Location; Add_Str_To_Name_Buffer (" instantiated at "); end loop; Name_Buffer (Name_Len + 1) := NUL; return; end Build_Location_String; function Build_Location_String (Loc : Source_Ptr) return String is begin Name_Len := 0; Build_Location_String (Loc); return Name_Buffer (1 .. Name_Len); end Build_Location_String; ------------------- -- Check_For_BOM -- ------------------- procedure Check_For_BOM is BOM : BOM_Kind; Len : Natural; Tst : String (1 .. 5); C : Character; begin for J in 1 .. 5 loop C := Source (Scan_Ptr + Source_Ptr (J) - 1); -- Definitely no BOM if EOF character marks either end of file, or -- an illegal non-BOM character if not at the end of file. if C = EOF then return; end if; Tst (J) := C; end loop; Read_BOM (Tst, Len, BOM, False); case BOM is when UTF8_All => Scan_Ptr := Scan_Ptr + Source_Ptr (Len); Wide_Character_Encoding_Method := WCEM_UTF8; Upper_Half_Encoding := True; when UTF16_LE | UTF16_BE => Set_Standard_Error; Write_Line ("UTF-16 encoding format not recognized"); Set_Standard_Output; raise Unrecoverable_Error; when UTF32_LE | UTF32_BE => Set_Standard_Error; Write_Line ("UTF-32 encoding format not recognized"); Set_Standard_Output; raise Unrecoverable_Error; when Unknown => null; when others => raise Program_Error; end case; end Check_For_BOM; ----------------------- -- Get_Column_Number -- ----------------------- function Get_Column_Number (P : Source_Ptr) return Column_Number is S : Source_Ptr; C : Column_Number; Sindex : Source_File_Index; Src : Source_Buffer_Ptr; begin -- If the input source pointer is not a meaningful value then return -- at once with column number 1. This can happen for a file not found -- condition for a file loaded indirectly by RTE, and also perhaps on -- some unknown internal error conditions. In either case we certainly -- don't want to blow up. if P < 1 then return 1; else Sindex := Get_Source_File_Index (P); Src := Source_File.Table (Sindex).Source_Text; S := Line_Start (P); C := 1; while S < P loop if Src (S) = HT then C := (C - 1) / 8 * 8 + (8 + 1); S := S + 1; -- Deal with wide character case, but don't include brackets -- notation in this circuit, since we know that this will -- display unencoded (no one encodes brackets notation). elsif Src (S) /= '[' and then Is_Start_Of_Wide_Char (Src, S) then C := C + 1; Skip_Wide (Src, S); -- Normal (non-wide) character case or brackets sequence else C := C + 1; S := S + 1; end if; end loop; return C; end if; end Get_Column_Number; ----------------------------- -- Get_Logical_Line_Number -- ----------------------------- function Get_Logical_Line_Number (P : Source_Ptr) return Logical_Line_Number is SFR : Source_File_Record renames Source_File.Table (Get_Source_File_Index (P)); L : constant Physical_Line_Number := Get_Physical_Line_Number (P); begin if SFR.Num_SRef_Pragmas = 0 then return Logical_Line_Number (L); else return SFR.Logical_Lines_Table (L); end if; end Get_Logical_Line_Number; --------------------------------- -- Get_Logical_Line_Number_Img -- --------------------------------- function Get_Logical_Line_Number_Img (P : Source_Ptr) return String is begin Name_Len := 0; Add_Nat_To_Name_Buffer (Nat (Get_Logical_Line_Number (P))); return Name_Buffer (1 .. Name_Len); end Get_Logical_Line_Number_Img; ------------------------------ -- Get_Physical_Line_Number -- ------------------------------ function Get_Physical_Line_Number (P : Source_Ptr) return Physical_Line_Number is Sfile : Source_File_Index; Table : Lines_Table_Ptr; Lo : Physical_Line_Number; Hi : Physical_Line_Number; Mid : Physical_Line_Number; Loc : Source_Ptr; begin -- If the input source pointer is not a meaningful value then return -- at once with line number 1. This can happen for a file not found -- condition for a file loaded indirectly by RTE, and also perhaps on -- some unknown internal error conditions. In either case we certainly -- don't want to blow up. if P < 1 then return 1; -- Otherwise we can do the binary search else Sfile := Get_Source_File_Index (P); Loc := P + Source_File.Table (Sfile).Sloc_Adjust; Table := Source_File.Table (Sfile).Lines_Table; Lo := 1; Hi := Source_File.Table (Sfile).Last_Source_Line; loop Mid := (Lo + Hi) / 2; if Loc < Table (Mid) then Hi := Mid - 1; else -- Loc >= Table (Mid) if Mid = Hi or else Loc < Table (Mid + 1) then return Mid; else Lo := Mid + 1; end if; end if; end loop; end if; end Get_Physical_Line_Number; --------------------------- -- Get_Source_File_Index -- --------------------------- function Get_Source_File_Index (S : Source_Ptr) return Source_File_Index is begin return Source_File_Index_Table (Int (S) / Source_Align); end Get_Source_File_Index; ---------------- -- Initialize -- ---------------- procedure Initialize is begin Source_gnat_adc := No_Source_File; First_Time_Around := True; Source_File.Init; Instances.Init; Instances.Append (No_Location); pragma Assert (Instances.Last = No_Instance_Id); end Initialize; ------------------- -- Instantiation -- ------------------- function Instantiation (S : SFI) return Source_Ptr is SIE : Source_File_Record renames Source_File.Table (S); begin if SIE.Inlined_Body then return SIE.Inlined_Call; else return Instances.Table (SIE.Instance); end if; end Instantiation; ------------------------- -- Instantiation_Depth -- ------------------------- function Instantiation_Depth (S : Source_Ptr) return Nat is Sind : Source_File_Index; Sval : Source_Ptr; Depth : Nat; begin Sval := S; Depth := 0; loop Sind := Get_Source_File_Index (Sval); Sval := Instantiation (Sind); exit when Sval = No_Location; Depth := Depth + 1; end loop; return Depth; end Instantiation_Depth; ---------------------------- -- Instantiation_Location -- ---------------------------- function Instantiation_Location (S : Source_Ptr) return Source_Ptr is begin return Instantiation (Get_Source_File_Index (S)); end Instantiation_Location; -------------------------- -- Iterate_On_Instances -- -------------------------- procedure Iterate_On_Instances is begin for J in 1 .. Instances.Last loop Process (J, Instances.Table (J)); end loop; end Iterate_On_Instances; ---------------------- -- Last_Source_File -- ---------------------- function Last_Source_File return Source_File_Index is begin return Source_File.Last; end Last_Source_File; ---------------- -- Line_Start -- ---------------- function Line_Start (P : Source_Ptr) return Source_Ptr is Sindex : constant Source_File_Index := Get_Source_File_Index (P); Src : constant Source_Buffer_Ptr := Source_File.Table (Sindex).Source_Text; Sfirst : constant Source_Ptr := Source_File.Table (Sindex).Source_First; S : Source_Ptr; begin S := P; while S > Sfirst and then Src (S - 1) /= CR and then Src (S - 1) /= LF loop S := S - 1; end loop; return S; end Line_Start; function Line_Start (L : Physical_Line_Number; S : Source_File_Index) return Source_Ptr is begin return Source_File.Table (S).Lines_Table (L); end Line_Start; ---------- -- Lock -- ---------- procedure Lock is begin Source_File.Locked := True; Source_File.Release; end Lock; ---------------------- -- Num_Source_Files -- ---------------------- function Num_Source_Files return Nat is begin return Int (Source_File.Last) - Int (Source_File.First) + 1; end Num_Source_Files; ---------------------- -- Num_Source_Lines -- ---------------------- function Num_Source_Lines (S : Source_File_Index) return Nat is begin return Nat (Source_File.Table (S).Last_Source_Line); end Num_Source_Lines; ----------------------- -- Original_Location -- ----------------------- function Original_Location (S : Source_Ptr) return Source_Ptr is Sindex : Source_File_Index; Tindex : Source_File_Index; begin if S <= No_Location then return S; else Sindex := Get_Source_File_Index (S); if Instantiation (Sindex) = No_Location then return S; else Tindex := Template (Sindex); while Instantiation (Tindex) /= No_Location loop Tindex := Template (Tindex); end loop; return S - Source_First (Sindex) + Source_First (Tindex); end if; end if; end Original_Location; ------------------------- -- Physical_To_Logical -- ------------------------- function Physical_To_Logical (Line : Physical_Line_Number; S : Source_File_Index) return Logical_Line_Number is SFR : Source_File_Record renames Source_File.Table (S); begin if SFR.Num_SRef_Pragmas = 0 then return Logical_Line_Number (Line); else return SFR.Logical_Lines_Table (Line); end if; end Physical_To_Logical; -------------------------------- -- Register_Source_Ref_Pragma -- -------------------------------- procedure Register_Source_Ref_Pragma (File_Name : File_Name_Type; Stripped_File_Name : File_Name_Type; Mapped_Line : Nat; Line_After_Pragma : Physical_Line_Number) is subtype size_t is Memory.size_t; SFR : Source_File_Record renames Source_File.Table (Current_Source_File); ML : Logical_Line_Number; begin if File_Name /= No_File then SFR.Reference_Name := Stripped_File_Name; SFR.Full_Ref_Name := File_Name; if not Debug_Generated_Code then SFR.Debug_Source_Name := Stripped_File_Name; SFR.Full_Debug_Name := File_Name; end if; SFR.Num_SRef_Pragmas := SFR.Num_SRef_Pragmas + 1; end if; if SFR.Num_SRef_Pragmas = 1 then SFR.First_Mapped_Line := Logical_Line_Number (Mapped_Line); end if; if SFR.Logical_Lines_Table = null then SFR.Logical_Lines_Table := To_Pointer (Memory.Alloc (size_t (SFR.Lines_Table_Max * Logical_Lines_Table_Type'Component_Size / Storage_Unit))); end if; SFR.Logical_Lines_Table (Line_After_Pragma - 1) := No_Line_Number; ML := Logical_Line_Number (Mapped_Line); for J in Line_After_Pragma .. SFR.Last_Source_Line loop SFR.Logical_Lines_Table (J) := ML; ML := ML + 1; end loop; end Register_Source_Ref_Pragma; --------------------------------- -- Set_Source_File_Index_Table -- --------------------------------- procedure Set_Source_File_Index_Table (Xnew : Source_File_Index) is Ind : Int; SP : Source_Ptr; SL : constant Source_Ptr := Source_File.Table (Xnew).Source_Last; begin SP := Source_File.Table (Xnew).Source_First; pragma Assert (SP mod Source_Align = 0); Ind := Int (SP) / Source_Align; while SP <= SL loop Source_File_Index_Table (Ind) := Xnew; SP := SP + Source_Align; Ind := Ind + 1; end loop; end Set_Source_File_Index_Table; --------------------------- -- Skip_Line_Terminators -- --------------------------- procedure Skip_Line_Terminators (P : in out Source_Ptr; Physical : out Boolean) is Chr : constant Character := Source (P); begin if Chr = CR then if Source (P + 1) = LF then P := P + 2; else P := P + 1; end if; elsif Chr = LF then P := P + 1; elsif Chr = FF or else Chr = VT then P := P + 1; Physical := False; return; -- Otherwise we have a wide character else Skip_Wide (Source, P); end if; -- Fall through in the physical line terminator case. First deal with -- making a possible entry into the lines table if one is needed. -- Note: we are dealing with a real source file here, this cannot be -- the instantiation case, so we need not worry about Sloc adjustment. declare S : Source_File_Record renames Source_File.Table (Current_Source_File); begin Physical := True; -- Make entry in lines table if not already made (in some scan backup -- cases, we will be rescanning previously scanned source, so the -- entry may have already been made on the previous forward scan). if Source (P) /= EOF and then P > S.Lines_Table (S.Last_Source_Line) then Add_Line_Tables_Entry (S, P); end if; end; end Skip_Line_Terminators; ---------------- -- Sloc_Range -- ---------------- procedure Sloc_Range (N : Node_Id; Min, Max : out Source_Ptr) is function Process (N : Node_Id) return Traverse_Result; -- Process function for traversing the node tree procedure Traverse is new Traverse_Proc (Process); ------------- -- Process -- ------------- function Process (N : Node_Id) return Traverse_Result is Orig : constant Node_Id := Original_Node (N); begin if Sloc (Orig) < Min then if Sloc (Orig) > No_Location then Min := Sloc (Orig); end if; elsif Sloc (Orig) > Max then if Sloc (Orig) > No_Location then Max := Sloc (Orig); end if; end if; return OK_Orig; end Process; -- Start of processing for Sloc_Range begin Min := Sloc (N); Max := Sloc (N); Traverse (N); end Sloc_Range; ------------------- -- Source_Offset -- ------------------- function Source_Offset (S : Source_Ptr) return Nat is Sindex : constant Source_File_Index := Get_Source_File_Index (S); Sfirst : constant Source_Ptr := Source_File.Table (Sindex).Source_First; begin return Nat (S - Sfirst); end Source_Offset; ------------------------ -- Top_Level_Location -- ------------------------ function Top_Level_Location (S : Source_Ptr) return Source_Ptr is Oldloc : Source_Ptr; Newloc : Source_Ptr; begin Newloc := S; loop Oldloc := Newloc; Newloc := Instantiation_Location (Oldloc); exit when Newloc = No_Location; end loop; return Oldloc; end Top_Level_Location; --------------- -- Tree_Read -- --------------- procedure Tree_Read is begin -- First we must free any old source buffer pointers if not First_Time_Around then for J in Source_File.First .. Source_File.Last loop declare S : Source_File_Record renames Source_File.Table (J); procedure Free_Ptr is new Unchecked_Deallocation (Big_Source_Buffer, Source_Buffer_Ptr); pragma Warnings (Off); -- This unchecked conversion is aliasing safe, since it is not -- used to create improperly aliased pointer values. function To_Source_Buffer_Ptr is new Unchecked_Conversion (Address, Source_Buffer_Ptr); pragma Warnings (On); Tmp1 : Source_Buffer_Ptr; begin if S.Instance /= No_Instance_Id then null; else -- Free the buffer, we use Free here, because we used malloc -- or realloc directly to allocate the tables. That is -- because we were playing the big array trick. -- We have to recreate a proper pointer to the actual array -- from the zero origin pointer stored in the source table. Tmp1 := To_Source_Buffer_Ptr (S.Source_Text (S.Source_First)'Address); Free_Ptr (Tmp1); if S.Lines_Table /= null then Memory.Free (To_Address (S.Lines_Table)); S.Lines_Table := null; end if; if S.Logical_Lines_Table /= null then Memory.Free (To_Address (S.Logical_Lines_Table)); S.Logical_Lines_Table := null; end if; end if; end; end loop; end if; -- Read in source file table and instance table Source_File.Tree_Read; Instances.Tree_Read; -- The pointers we read in there for the source buffer and lines table -- pointers are junk. We now read in the actual data that is referenced -- by these two fields. for J in Source_File.First .. Source_File.Last loop declare S : Source_File_Record renames Source_File.Table (J); begin -- For the instantiation case, we do not read in any data. Instead -- we share the data for the generic template entry. Since the -- template always occurs first, we can safely refer to its data. if S.Instance /= No_Instance_Id then declare ST : Source_File_Record renames Source_File.Table (S.Template); begin -- The lines tables are copied from the template entry S.Lines_Table := Source_File.Table (S.Template).Lines_Table; S.Logical_Lines_Table := Source_File.Table (S.Template).Logical_Lines_Table; -- In the case of the source table pointer, we share the -- same data as the generic template, but the virtual origin -- is adjusted. For example, if the first subscript of the -- template is 100, and that of the instantiation is 200, -- then the instantiation pointer is obtained by subtracting -- 100 from the template pointer. declare pragma Suppress (All_Checks); pragma Warnings (Off); -- This unchecked conversion is aliasing safe since it -- not used to create improperly aliased pointer values. function To_Source_Buffer_Ptr is new Unchecked_Conversion (Address, Source_Buffer_Ptr); pragma Warnings (On); begin S.Source_Text := To_Source_Buffer_Ptr (ST.Source_Text (ST.Source_First - S.Source_First)'Address); end; end; -- Normal case (non-instantiation) else First_Time_Around := False; S.Lines_Table := null; S.Logical_Lines_Table := null; Alloc_Line_Tables (S, Int (S.Last_Source_Line)); for J in 1 .. S.Last_Source_Line loop Tree_Read_Int (Int (S.Lines_Table (J))); end loop; if S.Num_SRef_Pragmas /= 0 then for J in 1 .. S.Last_Source_Line loop Tree_Read_Int (Int (S.Logical_Lines_Table (J))); end loop; end if; -- Allocate source buffer and read in the data and then set the -- virtual origin to point to the logical zero'th element. This -- address must be computed with subscript checks turned off. declare subtype B is Text_Buffer (S.Source_First .. S.Source_Last); type Text_Buffer_Ptr is access B; T : Text_Buffer_Ptr; pragma Suppress (All_Checks); pragma Warnings (Off); -- This unchecked conversion is aliasing safe, since it is -- never used to create improperly aliased pointer values. function To_Source_Buffer_Ptr is new Unchecked_Conversion (Address, Source_Buffer_Ptr); pragma Warnings (On); begin T := new B; Tree_Read_Data (T (S.Source_First)'Address, Int (S.Source_Last) - Int (S.Source_First) + 1); S.Source_Text := To_Source_Buffer_Ptr (T (0)'Address); end; end if; end; Set_Source_File_Index_Table (J); end loop; end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is begin Source_File.Tree_Write; Instances.Tree_Write; -- The pointers we wrote out there for the source buffer and lines -- table pointers are junk, we now write out the actual data that -- is referenced by these two fields. for J in Source_File.First .. Source_File.Last loop declare S : Source_File_Record renames Source_File.Table (J); begin -- For instantiations, there is nothing to do, since the data is -- shared with the generic template. When the tree is read, the -- pointers must be set, but no extra data needs to be written. if S.Instance /= No_Instance_Id then null; -- For the normal case, write out the data of the tables else -- Lines table for J in 1 .. S.Last_Source_Line loop Tree_Write_Int (Int (S.Lines_Table (J))); end loop; -- Logical lines table if present if S.Num_SRef_Pragmas /= 0 then for J in 1 .. S.Last_Source_Line loop Tree_Write_Int (Int (S.Logical_Lines_Table (J))); end loop; end if; -- Source buffer Tree_Write_Data (S.Source_Text (S.Source_First)'Address, Int (S.Source_Last) - Int (S.Source_First) + 1); end if; end; end loop; end Tree_Write; -------------------- -- Write_Location -- -------------------- procedure Write_Location (P : Source_Ptr) is begin if P = No_Location then Write_Str (""); elsif P <= Standard_Location then Write_Str (""); else declare SI : constant Source_File_Index := Get_Source_File_Index (P); begin Write_Name (Debug_Source_Name (SI)); Write_Char (':'); Write_Int (Int (Get_Logical_Line_Number (P))); Write_Char (':'); Write_Int (Int (Get_Column_Number (P))); if Instantiation (SI) /= No_Location then Write_Str (" ["); Write_Location (Instantiation (SI)); Write_Char (']'); end if; end; end if; end Write_Location; ---------------------- -- Write_Time_Stamp -- ---------------------- procedure Write_Time_Stamp (S : Source_File_Index) is T : constant Time_Stamp_Type := Time_Stamp (S); P : Natural; begin if T (1) = '9' then Write_Str ("19"); P := 0; else Write_Char (T (1)); Write_Char (T (2)); P := 2; end if; Write_Char (T (P + 1)); Write_Char (T (P + 2)); Write_Char ('-'); Write_Char (T (P + 3)); Write_Char (T (P + 4)); Write_Char ('-'); Write_Char (T (P + 5)); Write_Char (T (P + 6)); Write_Char (' '); Write_Char (T (P + 7)); Write_Char (T (P + 8)); Write_Char (':'); Write_Char (T (P + 9)); Write_Char (T (P + 10)); Write_Char (':'); Write_Char (T (P + 11)); Write_Char (T (P + 12)); end Write_Time_Stamp; ---------------------------------------------- -- Access Subprograms for Source File Table -- ---------------------------------------------- function Debug_Source_Name (S : SFI) return File_Name_Type is begin return Source_File.Table (S).Debug_Source_Name; end Debug_Source_Name; function Instance (S : SFI) return Instance_Id is begin return Source_File.Table (S).Instance; end Instance; function File_Name (S : SFI) return File_Name_Type is begin return Source_File.Table (S).File_Name; end File_Name; function File_Type (S : SFI) return Type_Of_File is begin return Source_File.Table (S).File_Type; end File_Type; function First_Mapped_Line (S : SFI) return Logical_Line_Number is begin return Source_File.Table (S).First_Mapped_Line; end First_Mapped_Line; function Full_Debug_Name (S : SFI) return File_Name_Type is begin return Source_File.Table (S).Full_Debug_Name; end Full_Debug_Name; function Full_File_Name (S : SFI) return File_Name_Type is begin return Source_File.Table (S).Full_File_Name; end Full_File_Name; function Full_Ref_Name (S : SFI) return File_Name_Type is begin return Source_File.Table (S).Full_Ref_Name; end Full_Ref_Name; function Identifier_Casing (S : SFI) return Casing_Type is begin return Source_File.Table (S).Identifier_Casing; end Identifier_Casing; function Inlined_Body (S : SFI) return Boolean is begin return Source_File.Table (S).Inlined_Body; end Inlined_Body; function Inlined_Call (S : SFI) return Source_Ptr is begin return Source_File.Table (S).Inlined_Call; end Inlined_Call; function Keyword_Casing (S : SFI) return Casing_Type is begin return Source_File.Table (S).Keyword_Casing; end Keyword_Casing; function Last_Source_Line (S : SFI) return Physical_Line_Number is begin return Source_File.Table (S).Last_Source_Line; end Last_Source_Line; function License (S : SFI) return License_Type is begin return Source_File.Table (S).License; end License; function Num_SRef_Pragmas (S : SFI) return Nat is begin return Source_File.Table (S).Num_SRef_Pragmas; end Num_SRef_Pragmas; function Reference_Name (S : SFI) return File_Name_Type is begin return Source_File.Table (S).Reference_Name; end Reference_Name; function Source_Checksum (S : SFI) return Word is begin return Source_File.Table (S).Source_Checksum; end Source_Checksum; function Source_First (S : SFI) return Source_Ptr is begin if S = Internal_Source_File then return Internal_Source'First; else return Source_File.Table (S).Source_First; end if; end Source_First; function Source_Last (S : SFI) return Source_Ptr is begin if S = Internal_Source_File then return Internal_Source'Last; else return Source_File.Table (S).Source_Last; end if; end Source_Last; function Source_Text (S : SFI) return Source_Buffer_Ptr is begin if S = Internal_Source_File then return Internal_Source_Ptr; else return Source_File.Table (S).Source_Text; end if; end Source_Text; function Template (S : SFI) return SFI is begin return Source_File.Table (S).Template; end Template; function Time_Stamp (S : SFI) return Time_Stamp_Type is begin return Source_File.Table (S).Time_Stamp; end Time_Stamp; function Unit (S : SFI) return Unit_Number_Type is begin return Source_File.Table (S).Unit; end Unit; ------------------------------------------ -- Set Procedures for Source File Table -- ------------------------------------------ procedure Set_Identifier_Casing (S : SFI; C : Casing_Type) is begin Source_File.Table (S).Identifier_Casing := C; end Set_Identifier_Casing; procedure Set_Keyword_Casing (S : SFI; C : Casing_Type) is begin Source_File.Table (S).Keyword_Casing := C; end Set_Keyword_Casing; procedure Set_License (S : SFI; L : License_Type) is begin Source_File.Table (S).License := L; end Set_License; procedure Set_Unit (S : SFI; U : Unit_Number_Type) is begin Source_File.Table (S).Unit := U; end Set_Unit; ---------------------- -- Trim_Lines_Table -- ---------------------- procedure Trim_Lines_Table (S : Source_File_Index) is Max : constant Nat := Nat (Source_File.Table (S).Last_Source_Line); begin -- Release allocated storage that is no longer needed Source_File.Table (S).Lines_Table := To_Pointer (Memory.Realloc (To_Address (Source_File.Table (S).Lines_Table), Memory.size_t (Max * (Lines_Table_Type'Component_Size / System.Storage_Unit)))); Source_File.Table (S).Lines_Table_Max := Physical_Line_Number (Max); end Trim_Lines_Table; ------------ -- Unlock -- ------------ procedure Unlock is begin Source_File.Locked := False; Source_File.Release; end Unlock; -------- -- wl -- -------- procedure wl (P : Source_Ptr) is begin Write_Location (P); Write_Eol; end wl; end Sinput; gprbuild-gpl-2014-src/gnat/prj-pp.ads0000644000076700001450000001173212323721731016771 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . P P -- -- -- -- S p e c -- -- -- -- Copyright (C) 2001-2011, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package is the Project File Pretty Printer -- Used to output a project file from a project file tree. -- Used by gnatname to update or create project files. -- Also used GPS to display project file trees. -- Also be used for debugging tools that create project file trees. with Prj.Tree; package Prj.PP is -- The following access to procedure types are used to redirect output when -- calling Pretty_Print. type Write_Char_Ap is access procedure (C : Character); type Write_Eol_Ap is access procedure; type Write_Str_Ap is access procedure (S : String); subtype Max_Length_Of_Line is Positive range 50 .. 255; procedure Pretty_Print (Project : Prj.Tree.Project_Node_Id; In_Tree : Prj.Tree.Project_Node_Tree_Ref; Increment : Positive := 3; Eliminate_Empty_Case_Constructions : Boolean := False; Minimize_Empty_Lines : Boolean := False; W_Char : Write_Char_Ap := null; W_Eol : Write_Eol_Ap := null; W_Str : Write_Str_Ap := null; Backward_Compatibility : Boolean; Id : Prj.Project_Id := Prj.No_Project; Max_Line_Length : Max_Length_Of_Line := Max_Length_Of_Line'Last); -- Output a project file, using either the default output routines, or the -- ones specified by W_Char, W_Eol and W_Str. -- -- Increment is the number of spaces for each indentation level -- -- W_Char, W_Eol and W_Str can be used to change the default output -- procedures. The default values force the output to Standard_Output. -- -- If Eliminate_Empty_Case_Constructions is True, then case constructions -- and case items that do not include any declarations will not be output. -- -- If Minimize_Empty_Lines is True, empty lines will be output only after -- the last with clause, after the line declaring the project name, after -- the last declarative item of the project and before each package -- declaration. Otherwise, more empty lines are output. -- -- If Backward_Compatibility is True, then new attributes (Spec, -- Spec_Suffix, Body, Body_Suffix) will be replaced by obsolete ones -- (Specification, Specification_Suffix, Implementation, -- Implementation_Suffix). -- -- Id is used to compute the display name of the project including its -- proper casing. -- -- Max_Line_Length is the maximum line length in the project file private procedure Output_Statistics; -- This procedure can be used after one or more calls to Pretty_Print to -- display what Project_Node_Kinds have not been exercised by the call(s) -- to Pretty_Print. It is used only for testing purposes. procedure wpr (Project : Prj.Tree.Project_Node_Id; In_Tree : Prj.Tree.Project_Node_Tree_Ref); -- Wrapper for use from gdb: call Pretty_Print with default parameters end Prj.PP; gprbuild-gpl-2014-src/gnat/ali.ads0000644000076700001450000012316512323721731016332 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- A L I -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package defines the internal data structures used for representation -- of Ada Library Information (ALI) acquired from the ALI files generated by -- the front end. with Casing; use Casing; with Gnatvsn; use Gnatvsn; with Namet; use Namet; with Rident; use Rident; with Table; with Types; use Types; with GNAT.HTable; use GNAT.HTable; package ALI is -------------- -- Id Types -- -------------- -- The various entries are stored in tables with distinct subscript ranges. -- The following type definitions show the ranges used for the subscripts -- (Id values) for the various tables. type ALI_Id is range 0 .. 999_999; -- Id values used for ALIs table entries type Unit_Id is range 1_000_000 .. 1_999_999; -- Id values used for Unit table entries type With_Id is range 2_000_000 .. 2_999_999; -- Id values used for Withs table entries type Arg_Id is range 3_000_000 .. 3_999_999; -- Id values used for argument table entries type Sdep_Id is range 4_000_000 .. 4_999_999; -- Id values used for Sdep table entries type Source_Id is range 5_000_000 .. 5_999_999; -- Id values used for Source table entries type Interrupt_State_Id is range 6_000_000 .. 6_999_999; -- Id values used for Interrupt_State table entries type Priority_Specific_Dispatching_Id is range 7_000_000 .. 7_999_999; -- Id values used for Priority_Specific_Dispatching table entries -------------------- -- ALI File Table -- -------------------- -- Each ALI file read generates an entry in the ALIs table No_ALI_Id : constant ALI_Id := ALI_Id'First; -- Special value indicating no ALI entry First_ALI_Entry : constant ALI_Id := No_ALI_Id + 1; -- Id of first actual entry in table type Main_Program_Type is (None, Proc, Func); -- Indicator of whether unit can be used as main program type ALIs_Record is record Afile : File_Name_Type; -- Name of ALI file Ofile_Full_Name : File_Name_Type; -- Full name of object file corresponding to the ALI file Sfile : File_Name_Type; -- Name of source file that generates this ALI file (which is equal -- to the name of the source file in the first unit table entry for -- this ALI file, since the body if present is always first). Ver : String (1 .. Ver_Len_Max); -- Value of library version (V line in ALI file). Not set if -- V lines are ignored as a result of the Ignore_Lines parameter. Ver_Len : Natural; -- Length of characters stored in Ver. Not set if V lines are ignored as -- a result of the Ignore_Lines parameter. SAL_Interface : Boolean; -- Set True when this is an interface to a standalone library First_Unit : Unit_Id; -- Id of first Unit table entry for this file Last_Unit : Unit_Id; -- Id of last Unit table entry for this file First_Sdep : Sdep_Id; -- Id of first Sdep table entry for this file Last_Sdep : Sdep_Id; -- Id of last Sdep table entry for this file Main_Program : Main_Program_Type; -- Indicator of whether first unit can be used as main program. Not set -- if 'M' appears in Ignore_Lines. Main_Priority : Int; -- Indicates priority value if Main_Program field indicates that this -- can be a main program. A value of -1 (No_Main_Priority) indicates -- that no parameter was found, or no M line was present. Not set if -- 'M' appears in Ignore_Lines. Main_CPU : Int; -- Indicates processor if Main_Program field indicates that this can -- be a main program. A value of -1 (No_Main_CPU) indicates that no C -- parameter was found, or no M line was present. Not set if 'M' appears -- in Ignore_Lines. Time_Slice_Value : Int; -- Indicates value of time slice parameter from T=xxx on main program -- line. A value of -1 indicates that no T=xxx parameter was found, or -- no M line was present. Not set if 'M' appears in Ignore_Lines. WC_Encoding : Character; -- Wide character encoding if main procedure. Otherwise not relevant. -- Not set if 'M' appears in Ignore_Lines. Locking_Policy : Character; -- Indicates locking policy for units in this file. Space means tasking -- was not used, or that no Locking_Policy pragma was present or that -- this is a language defined unit. Otherwise set to first character -- (upper case) of policy name. Not set if 'P' appears in Ignore_Lines. Partition_Elaboration_Policy : Character; -- Indicates partition elaboration policy for units in this file. Space -- means that no Partition_Elaboration_Policy pragma was present or that -- this is a language defined unit. Otherwise set to first character -- (upper case) of policy name. Not set if 'P' appears in Ignore_Lines. Queuing_Policy : Character; -- Indicates queuing policy for units in this file. Space means tasking -- was not used, or that no Queuing_Policy pragma was present or that -- this is a language defined unit. Otherwise set to first character -- (upper case) of policy name. Not set if 'P' appears in Ignore_Lines. Task_Dispatching_Policy : Character; -- Indicates task dispatching policy for units in this file. Space means -- tasking was not used, or that no Task_Dispatching_Policy pragma was -- present or that this is a language defined unit. Otherwise set to -- first character (upper case) of policy name. Not set if 'P' appears -- in Ignore_Lines. Compile_Errors : Boolean; -- Set to True if compile errors for unit. Note that No_Object will -- always be set as well in this case. Not set if 'P' appears in -- Ignore_Lines. Float_Format : Character; -- Set to float format (set to I if no float-format given). Not set if -- 'P' appears in Ignore_Lines. No_Object : Boolean; -- Set to True if no object file generated. Not set if 'P' appears in -- Ignore_Lines. Normalize_Scalars : Boolean; -- Set to True if file was compiled with Normalize_Scalars. Not set if -- 'P' appears in Ignore_Lines. SSO_Default : Character; -- Set to 'H' or 'L' if file was compiled with a configuration pragma -- file containing Default_Scalar_Storage_Order (High/Low_Order_First). -- Set to ' ' if neither pragma was present. Not set if 'P' appears in -- Ignore_Lines. Unit_Exception_Table : Boolean; -- Set to True if unit exception table pointer generated. Not set if 'P' -- appears in Ignore_Lines. Zero_Cost_Exceptions : Boolean; -- Set to True if file was compiled with zero cost exceptions. Not set -- if 'P' appears in Ignore_Lines. Restrictions : Restrictions_Info; -- Restrictions information reconstructed from R lines First_Interrupt_State : Interrupt_State_Id; Last_Interrupt_State : Interrupt_State_Id'Base; -- These point to the first and last entries in the interrupt state -- table for this unit. If no entries, then Last_Interrupt_State = -- First_Interrupt_State - 1 (that's why the 'Base reference is there, -- it can be one less than the lower bound of the subtype). Not set if -- 'I' appears in Ignore_Lines First_Specific_Dispatching : Priority_Specific_Dispatching_Id; Last_Specific_Dispatching : Priority_Specific_Dispatching_Id'Base; -- These point to the first and last entries in the priority specific -- dispatching table for this unit. If there are no entries, then -- Last_Specific_Dispatching = First_Specific_Dispatching - 1. That -- is why the 'Base reference is there, it can be one less than the -- lower bound of the subtype. Not set if 'S' appears in Ignore_Lines. end record; No_Main_Priority : constant Int := -1; -- Code for no main priority set No_Main_CPU : constant Int := -1; -- Code for no main cpu set package ALIs is new Table.Table ( Table_Component_Type => ALIs_Record, Table_Index_Type => ALI_Id, Table_Low_Bound => First_ALI_Entry, Table_Initial => 500, Table_Increment => 200, Table_Name => "ALIs"); ---------------- -- Unit Table -- ---------------- -- Each unit within an ALI file generates an entry in the unit table No_Unit_Id : constant Unit_Id := Unit_Id'First; -- Special value indicating no unit table entry First_Unit_Entry : constant Unit_Id := No_Unit_Id + 1; -- Id of first actual entry in table type Unit_Type is (Is_Spec, Is_Body, Is_Spec_Only, Is_Body_Only); -- Indicates type of entry, if both body and spec appear in the ALI file, -- then the first unit is marked Is_Body, and the second is marked Is_Spec. -- If only a spec appears, then it is marked as Is_Spec_Only, and if only -- a body appears, then it is marked Is_Body_Only). subtype Version_String is String (1 .. 8); -- Version string, taken from unit record type Unit_Record is record My_ALI : ALI_Id; -- Corresponding ALI entry Uname : Unit_Name_Type; -- Name of Unit Sfile : File_Name_Type; -- Name of source file Preelab : Boolean; -- Indicates presence of PR parameter for a preelaborated package No_Elab : Boolean; -- Indicates presence of NE parameter for a unit that has does not -- have an elaboration routine (since it has no elaboration code). Pure : Boolean; -- Indicates presence of PU parameter for a package having pragma Pure Dynamic_Elab : Boolean; -- Set to True if the unit was compiled with dynamic elaboration checks -- (i.e. either -gnatE or pragma Elaboration_Checks (RM) was used to -- compile the unit). Elaborate_Body : Boolean; -- Indicates presence of EB parameter for a package which has a pragma -- Elaborate_Body, and also for generic package instantiations. Set_Elab_Entity : Boolean; -- Indicates presence of EE parameter for a unit which has an -- elaboration entity which must be set true as part of the -- elaboration of the unit. Has_RACW : Boolean; -- Indicates presence of RA parameter for a package that declares at -- least one Remote Access to Class_Wide (RACW) object. Remote_Types : Boolean; -- Indicates presence of RT parameter for a package which has a -- pragma Remote_Types. Shared_Passive : Boolean; -- Indicates presence of SP parameter for a package which has a pragma -- Shared_Passive. RCI : Boolean; -- Indicates presence of RC parameter for a package which has a pragma -- Remote_Call_Interface. Predefined : Boolean; -- Indicates if unit is language predefined (or a child of such a unit) Internal : Boolean; -- Indicates if unit is an internal unit (or a child of such a unit) First_With : With_Id; -- Id of first withs table entry for this file Last_With : With_Id; -- Id of last withs table entry for this file First_Arg : Arg_Id; -- Id of first args table entry for this file Last_Arg : Arg_Id; -- Id of last args table entry for this file Utype : Unit_Type; -- Type of entry Is_Generic : Boolean; -- True for generic unit (i.e. a generic declaration, or a generic -- body). False for a non-generic unit. Unit_Kind : Character; -- Indicates the nature of the unit. 'p' for Packages and 's' for -- subprograms. Version : Version_String; -- Version of unit Icasing : Casing_Type; -- Indicates casing of identifiers in source file for this unit. This -- is used for informational output, and also for constructing the main -- unit if it is being built in Ada. Kcasing : Casing_Type; -- Indicates casing of keywords in source file for this unit. This is -- used for informational output, and also for constructing the main -- unit if it is being built in Ada. Elab_Position : aliased Natural; -- Initialized to zero. Set non-zero when a unit is chosen and -- placed in the elaboration order. The value represents the -- ordinal position in the elaboration order. Init_Scalars : Boolean; -- Set True if IS qualifier appears in ALI file, indicating that -- an Initialize_Scalars pragma applies to the unit. SAL_Interface : Boolean; -- Set True when this is an interface to a standalone library Directly_Scanned : Boolean; -- True iff it is a unit from an ALI file specified to gnatbind Body_Needed_For_SAL : Boolean; -- Indicates that the source for the body of the unit (subprogram, -- package, or generic unit) must be included in a standalone library. Elaborate_Body_Desirable : Boolean; -- Indicates that the front end elaboration circuitry decided that it -- would be a good idea if this package had Elaborate_Body. The binder -- will attempt, but does not promise, to place the elaboration call -- for the body right after the call for the spec, or at least as close -- together as possible. Optimize_Alignment : Character; -- Optimize_Alignment setting. Set to L/S/T/O for OL/OS/OT/OO present Has_Finalizer : Boolean; -- Indicates whether a package body or a spec has a library-level -- finalization routine. end record; package Units is new Table.Table ( Table_Component_Type => Unit_Record, Table_Index_Type => Unit_Id, Table_Low_Bound => First_Unit_Entry, Table_Initial => 100, Table_Increment => 200, Table_Name => "Unit"); --------------------------- -- Interrupt State Table -- --------------------------- -- An entry is made in this table for each I (interrupt state) line -- encountered in the input ALI file. The First/Last_Interrupt_Id -- fields of the ALI file entry show the range of entries defined -- within a particular ALI file. type Interrupt_State_Record is record Interrupt_Id : Nat; -- Id from interrupt state entry Interrupt_State : Character; -- State from interrupt state entry ('u'/'r'/'s') IS_Pragma_Line : Nat; -- Line number of Interrupt_State pragma end record; package Interrupt_States is new Table.Table ( Table_Component_Type => Interrupt_State_Record, Table_Index_Type => Interrupt_State_Id'Base, Table_Low_Bound => Interrupt_State_Id'First, Table_Initial => 100, Table_Increment => 200, Table_Name => "Interrupt_States"); ----------------------------------------- -- Priority Specific Dispatching Table -- ----------------------------------------- -- An entry is made in this table for each S (priority specific -- dispatching) line encountered in the input ALI file. The -- First/Last_Specific_Dispatching_Id fields of the ALI file -- entry show the range of entries defined within a particular -- ALI file. type Specific_Dispatching_Record is record Dispatching_Policy : Character; -- First character (upper case) of the corresponding policy name First_Priority : Nat; -- Lower bound of the priority range to which the specified dispatching -- policy applies. Last_Priority : Nat; -- Upper bound of the priority range to which the specified dispatching -- policy applies. PSD_Pragma_Line : Nat; -- Line number of Priority_Specific_Dispatching pragma end record; package Specific_Dispatching is new Table.Table ( Table_Component_Type => Specific_Dispatching_Record, Table_Index_Type => Priority_Specific_Dispatching_Id'Base, Table_Low_Bound => Priority_Specific_Dispatching_Id'First, Table_Initial => 100, Table_Increment => 200, Table_Name => "Priority_Specific_Dispatching"); -------------- -- Switches -- -------------- -- These switches record status information about ali files that -- have been read, for quick reference without searching tables. -- Note: a switch will be left set at its default value if the line -- which might otherwise set it is ignored (from Ignore_Lines). Dynamic_Elaboration_Checks_Specified : Boolean := False; -- Set to False by Initialize_ALI. Set to True if Scan_ALI reads -- a unit for which dynamic elaboration checking is enabled. Float_Format_Specified : Character := ' '; -- Set to blank by Initialize_ALI. Set to appropriate float format -- character (V or I, see Opt.Float_Format) if an ali file that -- is read contains an F line setting the floating point format. Initialize_Scalars_Used : Boolean := False; -- Set True if an ali file contains the Initialize_Scalars flag Locking_Policy_Specified : Character := ' '; -- Set to blank by Initialize_ALI. Set to the appropriate locking policy -- character if an ali file contains a P line setting the locking policy. No_Normalize_Scalars_Specified : Boolean := False; -- Set to False by Initialize_ALI. Set to True if an ali file indicates -- that the file was compiled without normalize scalars. No_Object_Specified : Boolean := False; -- Set to False by Initialize_ALI. Set to True if an ali file contains -- the No_Object flag. Normalize_Scalars_Specified : Boolean := False; -- Set to False by Initialize_ALI. Set to True if an ali file indicates -- that the file was compiled in Normalize_Scalars mode. Partition_Elaboration_Policy_Specified : Character := ' '; -- Set to blank by Initialize_ALI. Set to the appropriate partition -- elaboration policy character if an ali file contains a P line setting -- the policy. Queuing_Policy_Specified : Character := ' '; -- Set to blank by Initialize_ALI. Set to the appropriate queuing policy -- character if an ali file contains a P line setting the queuing policy. Cumulative_Restrictions : Restrictions_Info := No_Restrictions; -- This variable records the cumulative contributions of R lines in all -- ali files, showing whether a restriction pragma exists anywhere, and -- accumulating the aggregate knowledge of violations. SSO_Default_Specified : Boolean := False; -- Set to True if at least one ALI file contains an OH/OL flag indicating -- that it was compiled with a configuration pragmas file containing the -- pragma Default_Scalar_Storage_Order (OH/OL present in ALI file P line). Stack_Check_Switch_Set : Boolean := False; -- Set to True if at least one ALI file contains '-fstack-check' in its -- argument list. Static_Elaboration_Model_Used : Boolean := False; -- Set to False by Initialize_ALI. Set to True if any ALI file for a -- non-internal unit compiled with the static elaboration model is -- encountered. Task_Dispatching_Policy_Specified : Character := ' '; -- Set to blank by Initialize_ALI. Set to the appropriate task dispatching -- policy character if an ali file contains a P line setting the -- task dispatching policy. Unreserve_All_Interrupts_Specified : Boolean := False; -- Set to False by Initialize_ALI. Set to True if an ali file is read that -- has P line specifying unreserve all interrupts mode. Zero_Cost_Exceptions_Specified : Boolean := False; -- Set to False by Initialize_ALI. Set to True if an ali file is read that -- has a P line specifying the generation of zero cost exceptions. ----------------- -- Withs Table -- ----------------- -- Each With line (W line) in an ALI file generates a Withs table entry -- Note: there will be no entries in this table if 'W' lines are ignored No_With_Id : constant With_Id := With_Id'First; -- Special value indicating no withs table entry First_With_Entry : constant With_Id := No_With_Id + 1; -- Id of first actual entry in table type With_Record is record Uname : Unit_Name_Type; -- Name of Unit Sfile : File_Name_Type; -- Name of source file, set to No_File in generic case Afile : File_Name_Type; -- Name of ALI file, set to No_File in generic case Elaborate : Boolean; -- Indicates presence of E parameter Elaborate_All : Boolean; -- Indicates presence of EA parameter Elab_All_Desirable : Boolean; -- Indicates presence of AD parameter Elab_Desirable : Boolean; -- Indicates presence of ED parameter SAL_Interface : Boolean := False; -- True if the Unit is an Interface of a Stand-Alone Library Limited_With : Boolean := False; -- True if unit is named in a limited_with_clause Implicit_With_From_Instantiation : Boolean := False; -- True if this is an implicit with from a generic instantiation end record; package Withs is new Table.Table ( Table_Component_Type => With_Record, Table_Index_Type => With_Id, Table_Low_Bound => First_With_Entry, Table_Initial => 5000, Table_Increment => 200, Table_Name => "Withs"); --------------------- -- Arguments Table -- --------------------- -- Each Arg line (A line) in an ALI file generates an Args table entry -- Note: there will be no entries in this table if 'A' lines are ignored No_Arg_Id : constant Arg_Id := Arg_Id'First; -- Special value indicating no args table entry First_Arg_Entry : constant Arg_Id := No_Arg_Id + 1; -- Id of first actual entry in table package Args is new Table.Table ( Table_Component_Type => String_Ptr, Table_Index_Type => Arg_Id, Table_Low_Bound => First_Arg_Entry, Table_Initial => 1000, Table_Increment => 100, Table_Name => "Args"); -------------------------- -- Linker_Options Table -- -------------------------- -- If an ALI file has one of more Linker_Options lines, then a single -- entry is made in this table. If more than one Linker_Options lines -- appears in a given ALI file, then the arguments are concatenated -- to form the entry in this table, using a NUL character as the -- separator, and a final NUL character is appended to the end. -- Note: there will be no entries in this table if 'L' lines are ignored type Linker_Option_Record is record Name : Name_Id; -- Name entry containing concatenated list of Linker_Options -- arguments separated by NUL and ended by NUL as described above. Unit : Unit_Id; -- Unit_Id for the entry Internal_File : Boolean; -- Set True if the linker options are from an internal file. This is -- used to insert certain standard entries after all the user entries -- but before the entries from the run-time. Original_Pos : Positive; -- Keep track of original position in the linker options table. This -- is used to implement a stable sort when we sort the linker options -- table. end record; -- The indexes of active entries in this table range from 1 to the -- value of Linker_Options.Last. The zero'th element is for sort call. package Linker_Options is new Table.Table ( Table_Component_Type => Linker_Option_Record, Table_Index_Type => Integer, Table_Low_Bound => 0, Table_Initial => 200, Table_Increment => 400, Table_Name => "Linker_Options"); ----------------- -- Notes Table -- ----------------- -- The notes table records entries from N lines type Notes_Record is record Pragma_Type : Character; -- 'A', 'C', 'I', 'S', 'T' for Annotate/Comment/Ident/Subtitle/Title Pragma_Line : Nat; -- Line number of pragma Pragma_Col : Nat; -- Column number of pragma Unit : Unit_Id; -- Unit_Id for the entry Pragma_Args : Name_Id; -- Pragma arguments. No_Name if no arguments, otherwise a single -- name table entry consisting of all the characters on the notes -- line from the first non-blank character following the source -- location to the last character on the line. end record; -- The indexes of active entries in this table range from 1 to the -- value of Linker_Options.Last. The zero'th element is for convenience -- if the table needs to be sorted. package Notes is new Table.Table ( Table_Component_Type => Notes_Record, Table_Index_Type => Integer, Table_Low_Bound => 0, Table_Initial => 200, Table_Increment => 400, Table_Name => "Notes"); ------------------------------------------- -- External Version Reference Hash Table -- ------------------------------------------- -- This hash table keeps track of external version reference strings -- as read from E lines in the ali file. The stored values do not -- include the terminating quote characters. -- Note: there will be no entries in this table if 'E' lines are ignored type Vindex is range 0 .. 98; -- Type to define range of headers function SHash (S : String_Ptr) return Vindex; -- Hash function for this table function SEq (F1, F2 : String_Ptr) return Boolean; -- Equality function for this table package Version_Ref is new Simple_HTable ( Header_Num => Vindex, Element => Boolean, No_Element => False, Key => String_Ptr, Hash => SHash, Equal => SEq); ------------------------- -- No_Dependency Table -- ------------------------- -- Each R line for a No_Dependency Restriction generates an entry in -- this No_Dependency table. type No_Dep_Record is record ALI_File : ALI_Id; -- ALI File containing the entry No_Dep_Unit : Name_Id; -- Id for names table entry including entire name, including periods end record; package No_Deps is new Table.Table ( Table_Component_Type => No_Dep_Record, Table_Index_Type => Integer, Table_Low_Bound => 0, Table_Initial => 200, Table_Increment => 400, Table_Name => "No_Deps"); ------------------------------------ -- Sdep (Source Dependency) Table -- ------------------------------------ -- Each source dependency (D line) in an ALI file generates an entry in the -- Sdep table. -- Note: there will be no entries in this table if 'D' lines are ignored No_Sdep_Id : constant Sdep_Id := Sdep_Id'First; -- Special value indicating no Sdep table entry First_Sdep_Entry : Sdep_Id := No_Sdep_Id + 1; -- Id of first Sdep entry for current ali file. This is initialized to the -- first Sdep entry in the table, and then incremented appropriately as -- successive ALI files are scanned. type Sdep_Record is record Sfile : File_Name_Type; -- Name of source file Stamp : Time_Stamp_Type; -- Time stamp value. Note that this will be all zero characters for the -- dummy entries for missing or non-dependent files. Checksum : Word; -- Checksum value. Note that this will be all zero characters for the -- dummy entries for missing or non-dependent files Dummy_Entry : Boolean; -- Set True for dummy entries that correspond to missing files or files -- where no dependency relationship exists. Subunit_Name : Name_Id; -- Name_Id for subunit name if present, else No_Name Unit_Name : Name_Id; -- Name_Id for the unit name if not a subunit (No_Name for a subunit) Rfile : File_Name_Type; -- Reference file name. Same as Sfile unless a Source_Reference pragma -- was used, in which case it reflects the name used in the pragma. Start_Line : Nat; -- Starting line number in file. Always 1, unless a Source_Reference -- pragma was used, in which case it reflects the line number value -- given in the pragma. end record; package Sdep is new Table.Table ( Table_Component_Type => Sdep_Record, Table_Index_Type => Sdep_Id, Table_Low_Bound => First_Sdep_Entry, Table_Initial => 5000, Table_Increment => 200, Table_Name => "Sdep"); ---------------------------- -- Use of Name Table Info -- ---------------------------- -- All unit names and file names are entered into the Names table. The Info -- fields of these entries are used as follows: -- Unit name Info field has Unit_Id of unit table entry -- ALI file name Info field has ALI_Id of ALI table entry -- Source file name Info field has Source_Id of source table entry -------------------------- -- Cross-Reference Data -- -------------------------- -- The following table records cross-reference sections, there is one entry -- for each X header line in the ALI file for an xref section. -- Note: there will be no entries in this table if 'X' lines are ignored type Xref_Section_Record is record File_Num : Sdep_Id; -- Dependency number for file (entry in Sdep.Table) File_Name : File_Name_Type; -- Name of file First_Entity : Nat; -- First entry in Xref_Entity table Last_Entity : Nat; -- Last entry in Xref_Entity table end record; package Xref_Section is new Table.Table ( Table_Component_Type => Xref_Section_Record, Table_Index_Type => Nat, Table_Low_Bound => 1, Table_Initial => 50, Table_Increment => 300, Table_Name => "Xref_Section"); -- The following is used to indicate whether a typeref field is present -- for the entity, and if so what kind of typeref field. type Tref_Kind is ( Tref_None, -- No typeref present Tref_Access, -- Access type typeref (points to designated type) Tref_Derived, -- Derived type typeref (points to parent type) Tref_Type); -- All other cases type Visibility_Kind is (Global, -- Library level entity Static, -- Static C/C++ entity Other); -- Local and other entity -- The following table records entities for which xrefs are recorded type Xref_Entity_Record is record Line : Pos; -- Line number of definition Etype : Character; -- Set to the identification character for the entity. See section -- "Cross-Reference Entity Identifiers" in lib-xref.ads for details. Col : Pos; -- Column number of definition Visibility : Visibility_Kind; -- Visibility of entity Entity : Name_Id; -- Name of entity Iref_File_Num : Sdep_Id; -- This field is set to the dependency reference for the file containing -- the generic entity that this one instantiates, or to No_Sdep_Id if -- the current entity is not an instantiation Iref_Line : Nat; -- This field is set to the line number in Iref_File_Num of the generic -- entity that this one instantiates, or to zero if the current entity -- is not an instantiation. Rref_Line : Nat; -- This field is set to the line number of a renaming reference if -- one is present, or to zero if no renaming reference is present Rref_Col : Nat; -- This field is set to the column number of a renaming reference -- if one is present, or to zero if no renaming reference is present. Tref : Tref_Kind; -- Indicates if a typeref is present, and if so what kind. Set to -- Tref_None if no typeref field is present. Tref_File_Num : Sdep_Id; -- This field is set to No_Sdep_Id if no typeref is present, or -- if the typeref refers to an entity in standard. Otherwise it -- it is the dependency reference for the file containing the -- declaration of the typeref entity. Tref_Line : Nat; -- This field is set to zero if no typeref is present, or if the -- typeref refers to an entity in standard. Otherwise it contains -- the line number of the declaration of the typeref entity. Tref_Type : Character; -- This field is set to blank if no typeref is present, or if the -- typeref refers to an entity in standard. Otherwise it contains -- the identification character for the typeref entity. See section -- "Cross-Reference Entity Identifiers" in lib-xref.ads for details. Tref_Col : Nat; -- This field is set to zero if no typeref is present, or if the -- typeref refers to an entity in standard. Otherwise it contains -- the column number of the declaration of the parent type. Tref_Standard_Entity : Name_Id; -- This field is set to No_Name if no typeref is present or if the -- typeref refers to a declared entity rather than an entity in -- package Standard. If there is a typeref that references an -- entity in package Standard, then this field is a Name_Id -- reference for the entity name. Oref_File_Num : Sdep_Id; -- This field is set to No_Sdep_Id if the entity doesn't override any -- other entity, or to the dependency reference for the overridden -- entity. Oref_Line : Nat; Oref_Col : Nat; -- These two fields are set to the line and column of the overridden -- entity. First_Xref : Nat; -- Index into Xref table of first cross-reference Last_Xref : Nat; -- Index into Xref table of last cross-reference. The value in -- Last_Xref can be less than the First_Xref value to indicate -- that no entries are present in the Xref Table. end record; package Xref_Entity is new Table.Table ( Table_Component_Type => Xref_Entity_Record, Table_Index_Type => Nat, Table_Low_Bound => 1, Table_Initial => 500, Table_Increment => 300, Table_Name => "Xref_Entity"); Array_Index_Reference : constant Character := '*'; Interface_Reference : constant Character := 'I'; -- Some special types of references. In the ALI file itself, these -- are output as attributes of the entity, not as references, but -- there is no provision in Xref_Entity_Record for storing multiple -- such references. -- The following table records actual cross-references type Xref_Record is record File_Num : Sdep_Id; -- Set to the file dependency number for the cross-reference. Note -- that if no file entry is present explicitly, this is just a copy -- of the reference for the current cross-reference section. Line : Nat; -- Line number for the reference. This is zero when referencing a -- predefined entity, but in this case Name is set. Rtype : Character; -- Indicates type of reference, using code used in ALI file: -- r = reference -- m = modification -- b = body entity -- c = completion of private or incomplete type -- x = type extension -- i = implicit reference -- Array_Index_Reference = reference to the index of an array -- Interface_Reference = reference to an interface implemented -- by the type -- See description in lib-xref.ads for further details Col : Nat; -- Column number for the reference Name : Name_Id := No_Name; -- This is only used when referencing a predefined entity. Currently, -- this only occurs for array indexes. -- Note: for instantiation references, Rtype is set to ' ', and Col is -- set to zero. One or more such entries can follow any other reference. -- When there is more than one such entry, this is to be read as: -- e.g. ref1 ref2 ref3 -- ref1 is a reference to an entity that was instantied at ref2. -- ref2 itself is also the result of an instantiation, that took -- place at ref3 Imported_Lang : Name_Id := No_Name; Imported_Name : Name_Id := No_Name; -- Language and name of imported entity reference end record; package Xref is new Table.Table ( Table_Component_Type => Xref_Record, Table_Index_Type => Nat, Table_Low_Bound => 1, Table_Initial => 2000, Table_Increment => 300, Table_Name => "Xref"); -------------------------------------- -- Subprograms for Reading ALI File -- -------------------------------------- procedure Initialize_ALI; -- Initialize the ALI tables. Also resets all switch values to defaults function Scan_ALI (F : File_Name_Type; T : Text_Buffer_Ptr; Ignore_ED : Boolean; Err : Boolean; Read_Xref : Boolean := False; Read_Lines : String := ""; Ignore_Lines : String := "X"; Ignore_Errors : Boolean := False; Directly_Scanned : Boolean := False) return ALI_Id; -- Given the text, T, of an ALI file, F, scan and store the information -- from the file, and return the Id of the resulting entry in the ALI -- table. Switch settings may be modified as described above in the -- switch description settings. -- -- Ignore_ED is normally False. If set to True, it indicates that -- all AD/ED (elaboration desirable) indications in the ALI file are -- to be ignored. This parameter is obsolete now that the -f switch -- is removed from gnatbind, and should be removed ??? -- -- Err determines the action taken on an incorrectly formatted file. -- If Err is False, then an error message is output, and the program -- is terminated. If Err is True, then no error message is output, -- and No_ALI_Id is returned. -- -- Ignore_Lines requests that Scan_ALI ignore any lines that start -- with any given key character. The default value of X causes all -- Xref lines to be ignored. The corresponding data in the ALI -- tables will not be filled in this case. It is not possible -- to ignore U (unit) lines, they are always read. -- -- Read_Lines requests that Scan_ALI process only lines that start -- with one of the given characters. The corresponding data in the -- ALI file for any characters not given in the list will not be -- set. The default value of the null string indicates that all -- lines should be read (unless Ignore_Lines is specified). U -- (unit) lines are always read regardless of the value of this -- parameter. -- -- Note: either Ignore_Lines or Read_Lines should be non-null, but not -- both. If both are provided then only the Read_Lines value is used, -- and the Ignore_Lines parameter is ignored. -- -- Read_XREF is set True to read and acquire the cross-reference -- information. If Read_XREF is set to True, then the effect is to ignore -- all lines other than U, W, D and X lines and the Ignore_Lines and -- Read_Lines parameters are ignored (i.e. the use of True for Read_XREF -- is equivalent to specifying an argument of "UWDX" for Read_Lines. -- -- Ignore_Errors is normally False. If it is set True, then Scan_ALI -- will do its best to scan through a file and extract all information -- it can, even if there are errors. In this case Err is only set if -- Scan_ALI was completely unable to process the file (e.g. it did not -- look like an ALI file at all). Ignore_Errors is intended to improve -- the downward compatibility of new compilers with old tools. -- -- Directly_Scanned is normally False. If it is set to True, then the -- units (spec and/or body) corresponding to the ALI file are marked as -- such. It is used to decide for what units gnatbind should generate -- the symbols corresponding to 'Version or 'Body_Version in -- Stand-Alone Libraries. end ALI; gprbuild-gpl-2014-src/gnat/sinput-p.ads0000644000076700001450000001045112323721731017335 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S I N P U T . P -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This child package contains the routines used to actually load a project -- file and create entries in the source file table. It also contains two -- routines to save and restore a project scan context. with Scans; use Scans; package Sinput.P is procedure Clear_Source_File_Table; -- This procedure frees memory allocated in the Source_File table (in the -- private part of package Sinput). It should only be used when it is -- guaranteed that all source files that have been loaded so far will not -- be accessed before being reloaded. It is intended for tools that parse -- several times sources, to avoid memory leaks. function Load_Project_File (Path : String) return Source_File_Index; -- Load the source of a project source file into memory and initialize the -- Scans state. procedure Reset_First; -- Indicate that the next project loaded should be considered as the first -- one, so that Sinput.Main_Source_File is set for this project file. This -- is to get the correct number of lines when error finalization is called. function Source_File_Is_Subunit (X : Source_File_Index) return Boolean; -- This function determines if a source file represents a subunit. It works -- by scanning for the first compilation unit token, and returning True if -- it is the token SEPARATE. It will return False otherwise, meaning that -- the file cannot possibly be a legal subunit. This function does NOT do a -- complete parse of the file, or build a tree. It is used in gnatmake and -- gprbuild to decide if a body without a spec in a project file needs to -- be compiled or not. Returns False if X = No_Source_File. type Saved_Project_Scan_State is limited private; -- Used to save project scan state in following two routines procedure Save_Project_Scan_State (Saved_State : out Saved_Project_Scan_State); pragma Inline (Save_Project_Scan_State); -- Save the Scans state, as well as the values of Source and -- Current_Source_File. procedure Restore_Project_Scan_State (Saved_State : Saved_Project_Scan_State); pragma Inline (Restore_Project_Scan_State); -- Restore the Scans state and the values of Source and -- Current_Source_File. private type Saved_Project_Scan_State is record Scan_State : Saved_Scan_State; Source : Source_Buffer_Ptr; Current_Source_File : Source_File_Index; end record; end Sinput.P; gprbuild-gpl-2014-src/gnat/prj-attr.ads0000644000076700001450000003460712323721731017332 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . A T T R -- -- -- -- S p e c -- -- -- -- Copyright (C) 2001-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package defines packages and attributes in GNAT project files. -- There are predefined packages and attributes. -- It is also possible to define new packages with their attributes with Table; with GNAT.Strings; package Prj.Attr is function Package_Name_List return GNAT.Strings.String_List; -- Returns the list of valid package names, including those added by -- procedures Register_New_Package below. The String_Access components of -- the returned String_List should never be freed. procedure Initialize; -- Initialize the predefined project level attributes and the predefined -- packages and their attribute. This procedure should be called by -- Prj.Initialize. type Attribute_Kind is ( Unknown, -- The attribute does not exist Single, -- Single variable attribute (not an associative array) Associative_Array, -- Associative array attribute with a case sensitive index Optional_Index_Associative_Array, -- Associative array attribute with a case sensitive index and an -- optional source index. Case_Insensitive_Associative_Array, -- Associative array attribute with a case insensitive index Optional_Index_Case_Insensitive_Associative_Array -- Associative array attribute with a case insensitive index and an -- optional source index. ); -- Characteristics of an attribute. Optional_Index indicates that there -- may be an optional index in the index of the associative array, as in -- for Switches ("files.ada" at 2) use ... subtype Defined_Attribute_Kind is Attribute_Kind range Single .. Optional_Index_Case_Insensitive_Associative_Array; -- Subset of Attribute_Kinds that may be used for the attributes that is -- used when defining a new package. subtype All_Case_Insensitive_Associative_Array is Attribute_Kind range Case_Insensitive_Associative_Array .. Optional_Index_Case_Insensitive_Associative_Array; -- Subtype including both cases of Case_Insensitive_Associative_Array Max_Attribute_Name_Length : constant := 64; -- The maximum length of attribute names subtype Attribute_Name_Length is Positive range 1 .. Max_Attribute_Name_Length; type Attribute_Data (Name_Length : Attribute_Name_Length := 1) is record Name : String (1 .. Name_Length); -- The name of the attribute Attr_Kind : Defined_Attribute_Kind; -- The type of the attribute Index_Is_File_Name : Boolean; -- For associative arrays, indicate if the index is a file name, so -- that the attribute kind may be modified depending on the case -- sensitivity of file names. This is only taken into account when -- Attr_Kind is Associative_Array or Optional_Index_Associative_Array. Opt_Index : Boolean; -- True if there may be an optional index in the value of the index, -- as in: -- "file.ada" at 2 -- ("main.adb", "file.ada" at 1) Var_Kind : Defined_Variable_Kind; -- The attribute value kind: single or list end record; -- Name and characteristics of an attribute in a package registered -- explicitly with Register_New_Package (see below). type Attribute_Data_Array is array (Positive range <>) of Attribute_Data; -- A list of attribute name/characteristics to be used as parameter of -- procedure Register_New_Package below. -- In the subprograms below, when it is specified that the subprogram -- "fails", procedure Prj.Com.Fail is called. Unless it is specified -- otherwise, if Prj.Com.Fail returns, exception Prj.Prj_Error is raised. procedure Register_New_Package (Name : String; Attributes : Attribute_Data_Array); -- Add a new package with its attributes. This procedure can only be -- called after Initialize, but before any other call to a service of -- the Project Manager. Fail if the name of the package is empty or not -- unique, or if the names of the attributes are not different. ---------------- -- Attributes -- ---------------- type Attribute_Node_Id is private; -- The type to refers to an attribute, self-initialized Empty_Attribute : constant Attribute_Node_Id; -- Indicates no attribute. Default value of Attribute_Node_Id objects Attribute_First : constant Attribute_Node_Id; -- First attribute node id of project level attributes function Attribute_Node_Id_Of (Name : Name_Id; Starting_At : Attribute_Node_Id) return Attribute_Node_Id; -- Returns the node id of an attribute at the project level or in -- a package. Starting_At indicates the first known attribute node where -- to start the search. Returns Empty_Attribute if the attribute cannot -- be found. function Attribute_Kind_Of (Attribute : Attribute_Node_Id) return Attribute_Kind; -- Returns the attribute kind of a known attribute. Returns Unknown if -- Attribute is Empty_Attribute. -- -- To use this function, the following code should be used: -- -- Pkg : constant Package_Node_Id := -- Prj.Attr.Package_Node_Id_Of (Name => ); -- Att : constant Attribute_Node_Id := -- Prj.Attr.Attribute_Node_Id_Of -- (Name => , -- Starting_At => First_Attribute_Of (Pkg)); -- Kind : constant Attribute_Kind := Attribute_Kind_Of (Att); -- -- However, do not use this function once you have an already parsed -- project tree. Instead, given a Project_Node_Id corresponding to the -- attribute declaration ("for Attr (index) use ..."), use for example: -- -- if Case_Insensitive (Attr, Tree) then ... procedure Set_Attribute_Kind_Of (Attribute : Attribute_Node_Id; To : Attribute_Kind); -- Set the attribute kind of a known attribute. Does nothing if -- Attribute is Empty_Attribute. function Attribute_Name_Of (Attribute : Attribute_Node_Id) return Name_Id; -- Returns the name of a known attribute. Returns No_Name if Attribute is -- Empty_Attribute. function Variable_Kind_Of (Attribute : Attribute_Node_Id) return Variable_Kind; -- Returns the variable kind of a known attribute. Returns Undefined if -- Attribute is Empty_Attribute. procedure Set_Variable_Kind_Of (Attribute : Attribute_Node_Id; To : Variable_Kind); -- Set the variable kind of a known attribute. Does nothing if Attribute is -- Empty_Attribute. function Optional_Index_Of (Attribute : Attribute_Node_Id) return Boolean; -- Returns True if Attribute is a known attribute and may have an -- optional index. Returns False otherwise. function Is_Read_Only (Attribute : Attribute_Node_Id) return Boolean; function Next_Attribute (After : Attribute_Node_Id) return Attribute_Node_Id; -- Returns the attribute that follow After in the list of project level -- attributes or the list of attributes in a package. -- Returns Empty_Attribute if After is either Empty_Attribute or is the -- last of the list. function Others_Allowed_For (Attribute : Attribute_Node_Id) return Boolean; -- True iff the index for an associative array attributes may be others -------------- -- Packages -- -------------- type Package_Node_Id is private; -- Type to refer to a package, self initialized Empty_Package : constant Package_Node_Id; -- Default value of Package_Node_Id objects Unknown_Package : constant Package_Node_Id; -- Value of an unknown package that has been found but is unknown procedure Register_New_Package (Name : String; Id : out Package_Node_Id); -- Add a new package. Fails if Name (the package name) is empty or is -- already the name of a package, and set Id to Empty_Package, -- if Prj.Com.Fail returns. Initially, the new package has no attributes. -- Id may be used to add attributes using procedure Register_New_Attribute -- below. procedure Register_New_Attribute (Name : String; In_Package : Package_Node_Id; Attr_Kind : Defined_Attribute_Kind; Var_Kind : Defined_Variable_Kind; Index_Is_File_Name : Boolean := False; Opt_Index : Boolean := False); -- Add a new attribute to registered package In_Package. Fails if Name -- (the attribute name) is empty, if In_Package is Empty_Package or if -- the attribute name has a duplicate name. See definition of type -- Attribute_Data above for the meaning of parameters Attr_Kind, Var_Kind, -- Index_Is_File_Name and Opt_Index. function Package_Node_Id_Of (Name : Name_Id) return Package_Node_Id; -- Returns the package node id of the package with name Name. Returns -- Empty_Package if there is no package with this name. function First_Attribute_Of (Pkg : Package_Node_Id) return Attribute_Node_Id; -- Returns the first attribute in the list of attributes of package Pkg. -- Returns Empty_Attribute if Pkg is Empty_Package or Unknown_Package. private ---------------- -- Attributes -- ---------------- Attributes_Initial : constant := 50; Attributes_Increment : constant := 100; Attribute_Node_Low_Bound : constant := 0; Attribute_Node_High_Bound : constant := 099_999_999; type Attr_Node_Id is range Attribute_Node_Low_Bound .. Attribute_Node_High_Bound; -- Index type for table Attrs in the body type Attribute_Node_Id is record Value : Attr_Node_Id := Attribute_Node_Low_Bound; end record; -- Full declaration of self-initialized private type Empty_Attr : constant Attr_Node_Id := Attribute_Node_Low_Bound; Empty_Attribute : constant Attribute_Node_Id := (Value => Empty_Attr); First_Attribute : constant Attr_Node_Id := Attribute_Node_Low_Bound + 1; First_Attribute_Node_Id : constant Attribute_Node_Id := (Value => First_Attribute); Attribute_First : constant Attribute_Node_Id := First_Attribute_Node_Id; -------------- -- Packages -- -------------- Packages_Initial : constant := 10; Packages_Increment : constant := 100; Package_Node_Low_Bound : constant := 0; Package_Node_High_Bound : constant := 099_999_999; type Pkg_Node_Id is range Package_Node_Low_Bound .. Package_Node_High_Bound; -- Index type for table Package_Attributes in the body type Package_Node_Id is record Value : Pkg_Node_Id := Package_Node_Low_Bound; end record; -- Full declaration of self-initialized private type Empty_Pkg : constant Pkg_Node_Id := Package_Node_Low_Bound; Empty_Package : constant Package_Node_Id := (Value => Empty_Pkg); Unknown_Pkg : constant Pkg_Node_Id := Package_Node_High_Bound; Unknown_Package : constant Package_Node_Id := (Value => Unknown_Pkg); First_Package : constant Pkg_Node_Id := Package_Node_Low_Bound + 1; First_Package_Node_Id : constant Package_Node_Id := (Value => First_Package); Package_First : constant Package_Node_Id := First_Package_Node_Id; ---------------- -- Attributes -- ---------------- type Attribute_Record is record Name : Name_Id; Var_Kind : Variable_Kind; Optional_Index : Boolean; Attr_Kind : Attribute_Kind; Read_Only : Boolean; Others_Allowed : Boolean; Next : Attr_Node_Id; end record; -- Data for an attribute package Attrs is new Table.Table (Table_Component_Type => Attribute_Record, Table_Index_Type => Attr_Node_Id, Table_Low_Bound => First_Attribute, Table_Initial => Attributes_Initial, Table_Increment => Attributes_Increment, Table_Name => "Prj.Attr.Attrs"); -- The table of the attributes -------------- -- Packages -- -------------- type Package_Record is record Name : Name_Id; Known : Boolean := True; First_Attribute : Attr_Node_Id; end record; -- Data for a package package Package_Attributes is new Table.Table (Table_Component_Type => Package_Record, Table_Index_Type => Pkg_Node_Id, Table_Low_Bound => First_Package, Table_Initial => Packages_Initial, Table_Increment => Packages_Increment, Table_Name => "Prj.Attr.Packages"); -- The table of the packages end Prj.Attr; gprbuild-gpl-2014-src/gnat/ali-util.adb0000644000076700001450000004533512323721731017266 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- A L I . U T I L -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Debug; use Debug; with Binderr; use Binderr; with Opt; use Opt; with Output; use Output; with Osint; use Osint; with Scans; use Scans; with Scng; with Sinput.C; with Snames; use Snames; with Stringt; with Styleg; with System.OS_Lib; use System.OS_Lib; package body ALI.Util is -- Empty procedures needed to instantiate Scng. Error procedures are -- empty, because we don't want to report any errors when computing -- a source checksum. procedure Post_Scan; procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr); procedure Error_Msg_S (Msg : String); procedure Error_Msg_SC (Msg : String); procedure Error_Msg_SP (Msg : String); -- Instantiation of Styleg, needed to instantiate Scng package Style is new Styleg (Error_Msg, Error_Msg_S, Error_Msg_SC, Error_Msg_SP); -- A Scanner is needed to get checksum of a source (procedure -- Get_File_Checksum). package Scanner is new Scng (Post_Scan, Error_Msg, Error_Msg_S, Error_Msg_SC, Error_Msg_SP, Style); type Header_Num is range 0 .. 1_000; function Hash (F : File_Name_Type) return Header_Num; -- Function used to compute hash of ALI file name package Interfaces is new Simple_HTable ( Header_Num => Header_Num, Element => Boolean, No_Element => False, Key => File_Name_Type, Hash => Hash, Equal => "="); --------------------- -- Checksums_Match -- --------------------- function Checksums_Match (Checksum1, Checksum2 : Word) return Boolean is begin return Checksum1 = Checksum2 and then Checksum1 /= Checksum_Error; end Checksums_Match; --------------- -- Error_Msg -- --------------- procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr) is pragma Warnings (Off, Msg); pragma Warnings (Off, Flag_Location); begin null; end Error_Msg; ----------------- -- Error_Msg_S -- ----------------- procedure Error_Msg_S (Msg : String) is pragma Warnings (Off, Msg); begin null; end Error_Msg_S; ------------------ -- Error_Msg_SC -- ------------------ procedure Error_Msg_SC (Msg : String) is pragma Warnings (Off, Msg); begin null; end Error_Msg_SC; ------------------ -- Error_Msg_SP -- ------------------ procedure Error_Msg_SP (Msg : String) is pragma Warnings (Off, Msg); begin null; end Error_Msg_SP; ----------------------- -- Get_File_Checksum -- ----------------------- function Get_File_Checksum (Fname : File_Name_Type) return Word is Full_Name : File_Name_Type; Source_Index : Source_File_Index; begin Full_Name := Find_File (Fname, Osint.Source); -- If we cannot find the file, then return an impossible checksum, -- impossible because checksums have the high order bit zero, so -- that checksums do not match. if Full_Name = No_File then return Checksum_Error; end if; Source_Index := Sinput.C.Load_File (Get_Name_String (Full_Name)); if Source_Index = No_Source_File then return Checksum_Error; end if; Scanner.Initialize_Scanner (Source_Index); -- Make sure that the project language reserved words are not -- recognized as reserved words, but as identifiers. The byte info for -- those names have been set if we are in gnatmake. Set_Name_Table_Byte (Name_Project, 0); Set_Name_Table_Byte (Name_Extends, 0); Set_Name_Table_Byte (Name_External, 0); Set_Name_Table_Byte (Name_External_As_List, 0); -- Scan the complete file to compute its checksum loop Scanner.Scan; exit when Token = Tok_EOF; end loop; return Scans.Checksum; end Get_File_Checksum; ---------- -- Hash -- ---------- function Hash (F : File_Name_Type) return Header_Num is begin return Header_Num (Int (F) rem Header_Num'Range_Length); end Hash; --------------------------- -- Initialize_ALI_Source -- --------------------------- procedure Initialize_ALI_Source is begin -- When (re)initializing ALI data structures the ALI user expects to -- get a fresh set of data structures. Thus we first need to erase the -- marks put in the name table by the previous set of ALI routine calls. -- This loop is empty and harmless the first time in. for J in Source.First .. Source.Last loop Set_Name_Table_Info (Source.Table (J).Sfile, 0); Source.Table (J).Source_Found := False; end loop; Source.Init; Interfaces.Reset; end Initialize_ALI_Source; --------------- -- Post_Scan -- --------------- procedure Post_Scan is begin null; end Post_Scan; ---------------------- -- Read_Withed_ALIs -- ---------------------- procedure Read_Withed_ALIs (Id : ALI_Id; Ignore_Errors : Boolean := False) is Afile : File_Name_Type; Text : Text_Buffer_Ptr; Idread : ALI_Id; begin -- Process all dependent units for U in ALIs.Table (Id).First_Unit .. ALIs.Table (Id).Last_Unit loop for W in Units.Table (U).First_With .. Units.Table (U).Last_With loop Afile := Withs.Table (W).Afile; -- Only process if not a generic (Afile /= No_File) and if -- file has not been processed already. if Afile /= No_File and then Get_Name_Table_Info (Afile) = 0 then Text := Read_Library_Info (Afile); -- Unless Ignore_Errors is true, return with an error if source -- cannot be found. We used to skip this check when we did not -- compile library generics separately, but we now always do, -- so there is no special case here anymore. if Text = null then if not Ignore_Errors then Error_Msg_File_1 := Afile; Error_Msg_File_2 := Withs.Table (W).Sfile; Error_Msg ("{ not found, { must be compiled"); Set_Name_Table_Info (Afile, Int (No_Unit_Id)); return; end if; else -- Enter in ALIs table Idread := Scan_ALI (F => Afile, T => Text, Ignore_ED => False, Err => False); Free (Text); if ALIs.Table (Idread).Compile_Errors and then not Ignore_Errors then Error_Msg_File_1 := Withs.Table (W).Sfile; Error_Msg ("{ had errors, must be fixed, and recompiled"); Set_Name_Table_Info (Afile, Int (No_Unit_Id)); -- In GNATprove mode, object files are never generated, so -- No_Object=True is not considered an error. elsif ALIs.Table (Idread).No_Object and then not GNATprove_Mode and then not Ignore_Errors then Error_Msg_File_1 := Withs.Table (W).Sfile; Error_Msg ("{ must be recompiled"); Set_Name_Table_Info (Afile, Int (No_Unit_Id)); end if; -- If the Unit is an Interface to a Stand-Alone Library, -- set the Interface flag in the Withs table, so that its -- dependant are not considered for elaboration order. if ALIs.Table (Idread).SAL_Interface then Withs.Table (W).SAL_Interface := True; Interface_Library_Unit := True; -- Set the entry in the Interfaces hash table, so that -- other units that import this unit will set the flag -- in their entry in the Withs table. Interfaces.Set (Afile, True); else -- Otherwise, recurse to get new dependents Read_Withed_ALIs (Idread); end if; end if; -- If the ALI file has already been processed and is an interface, -- set the flag in the entry of the Withs table. elsif Interface_Library_Unit and then Interfaces.Get (Afile) then Withs.Table (W).SAL_Interface := True; end if; end loop; end loop; end Read_Withed_ALIs; ---------------------- -- Set_Source_Table -- ---------------------- procedure Set_Source_Table (A : ALI_Id) is F : File_Name_Type; S : Source_Id; Stamp : Time_Stamp_Type; begin Sdep_Loop : for D in ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep loop F := Sdep.Table (D).Sfile; if F /= No_File then -- If this is the first time we are seeing this source file, -- then make a new entry in the source table. if Get_Name_Table_Info (F) = 0 then Source.Increment_Last; S := Source.Last; Set_Name_Table_Info (F, Int (S)); Source.Table (S).Sfile := F; Source.Table (S).All_Timestamps_Match := True; -- Initialize checksum fields Source.Table (S).Checksum := Sdep.Table (D).Checksum; Source.Table (S).All_Checksums_Match := True; -- In check source files mode, try to get time stamp from file if Opt.Check_Source_Files then Stamp := Source_File_Stamp (F); -- If we got the stamp, then set the stamp in the source -- table entry and mark it as set from the source so that -- it does not get subsequently changed. if Stamp (Stamp'First) /= ' ' then Source.Table (S).Stamp := Stamp; Source.Table (S).Source_Found := True; Source.Table (S).Stamp_File := F; -- If we could not find the file, then the stamp is set -- from the dependency table entry (to be possibly reset -- if we find a later stamp in subsequent processing) else Source.Table (S).Stamp := Sdep.Table (D).Stamp; Source.Table (S).Source_Found := False; Source.Table (S).Stamp_File := ALIs.Table (A).Afile; -- In All_Sources mode, flag error of file not found if Opt.All_Sources then Error_Msg_File_1 := F; Error_Msg ("cannot locate {"); end if; end if; -- First time for this source file, but Check_Source_Files -- is off, so simply initialize the stamp from the Sdep entry else Source.Table (S).Stamp := Sdep.Table (D).Stamp; Source.Table (S).Source_Found := False; Source.Table (S).Stamp_File := ALIs.Table (A).Afile; end if; -- Here if this is not the first time for this source file, -- so that the source table entry is already constructed. else S := Source_Id (Get_Name_Table_Info (F)); -- Update checksum flag if not Checksums_Match (Sdep.Table (D).Checksum, Source.Table (S).Checksum) then Source.Table (S).All_Checksums_Match := False; end if; -- Check for time stamp mismatch if Sdep.Table (D).Stamp /= Source.Table (S).Stamp then Source.Table (S).All_Timestamps_Match := False; -- When we have a time stamp mismatch, we go look for the -- source file even if Check_Source_Files is false, since -- if we find it, then we can use it to resolve which of the -- two timestamps in the ALI files is likely to be correct. -- We only look in the current directory, because when -- Check_Source_Files is false, other search directories are -- likely to be incorrect. if not Check_Source_Files and then Is_Regular_File (Get_Name_String (F)) then Stamp := Source_File_Stamp (F); if Stamp (Stamp'First) /= ' ' then Source.Table (S).Stamp := Stamp; Source.Table (S).Source_Found := True; Source.Table (S).Stamp_File := F; end if; end if; -- If the stamp in the source table entry was set from the -- source file, then we do not change it (the stamp in the -- source file is always taken as the "right" one). if Source.Table (S).Source_Found then null; -- Otherwise, we have no source file available, so we guess -- that the later of the two timestamps is the right one. -- Note that this guess only affects which error messages -- are issued later on, not correct functionality. else if Sdep.Table (D).Stamp > Source.Table (S).Stamp then Source.Table (S).Stamp := Sdep.Table (D).Stamp; Source.Table (S).Stamp_File := ALIs.Table (A).Afile; end if; end if; end if; end if; -- Set the checksum value in the source table S := Source_Id (Get_Name_Table_Info (F)); Source.Table (S).Checksum := Sdep.Table (D).Checksum; end if; end loop Sdep_Loop; end Set_Source_Table; ---------------------- -- Set_Source_Table -- ---------------------- procedure Set_Source_Table is begin for A in ALIs.First .. ALIs.Last loop Set_Source_Table (A); end loop; end Set_Source_Table; ------------------------- -- Time_Stamp_Mismatch -- ------------------------- function Time_Stamp_Mismatch (A : ALI_Id; Read_Only : Boolean := False) return File_Name_Type is Src : Source_Id; -- Source file Id for the current Sdep entry begin for D in ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep loop Src := Source_Id (Get_Name_Table_Info (Sdep.Table (D).Sfile)); if Opt.Minimal_Recompilation and then Sdep.Table (D).Stamp /= Source.Table (Src).Stamp then -- If minimal recompilation is in action, replace the stamp -- of the source file in the table if checksums match. -- ??? It is probably worth updating the ALI file with a new -- field to avoid recomputing it each time. In any case we ensure -- that we don't gobble up string table space by doing a mark -- release around this computation. Stringt.Mark; if Checksums_Match (Get_File_Checksum (Sdep.Table (D).Sfile), Source.Table (Src).Checksum) then if Verbose_Mode then Write_Str (" "); Write_Str (Get_Name_String (Sdep.Table (D).Sfile)); Write_Str (": up to date, different timestamps " & "but same checksum"); Write_Eol; end if; Sdep.Table (D).Stamp := Source.Table (Src).Stamp; end if; Stringt.Release; end if; if (not Read_Only) or else Source.Table (Src).Source_Found then if not Source.Table (Src).Source_Found or else Sdep.Table (D).Stamp /= Source.Table (Src).Stamp then -- If -dt debug flag set, output time stamp found/expected if Source.Table (Src).Source_Found and then Debug_Flag_T then Write_Str ("Source: """); Get_Name_String (Sdep.Table (D).Sfile); Write_Str (Name_Buffer (1 .. Name_Len)); Write_Line (""""); Write_Str (" time stamp expected: "); Write_Line (String (Sdep.Table (D).Stamp)); Write_Str (" time stamp found: "); Write_Line (String (Source.Table (Src).Stamp)); end if; -- Return the source file return Source.Table (Src).Sfile; end if; end if; end loop; return No_File; end Time_Stamp_Mismatch; end ALI.Util; gprbuild-gpl-2014-src/gnat/stand.adb0000644000076700001450000001776412323721731016664 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S T A N D -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Elists; use Elists; with System; use System; with Tree_IO; use Tree_IO; package body Stand is --------------- -- Tree_Read -- --------------- procedure Tree_Read is begin Tree_Read_Data (Standard_Entity'Address, Standard_Entity_Array_Type'Size / Storage_Unit); Tree_Read_Int (Int (Standard_Package_Node)); Tree_Read_Int (Int (Last_Standard_Node_Id)); Tree_Read_Int (Int (Last_Standard_List_Id)); Tree_Read_Int (Int (Boolean_Literals (False))); Tree_Read_Int (Int (Boolean_Literals (True))); Tree_Read_Int (Int (Standard_Void_Type)); Tree_Read_Int (Int (Standard_Exception_Type)); Tree_Read_Int (Int (Standard_A_String)); Tree_Read_Int (Int (Standard_A_Char)); Tree_Read_Int (Int (Standard_Debug_Renaming_Type)); -- Deal with Predefined_Float_Types, which is an Elist. We wrote the -- entities out in sequence, terminated by an Empty entry. declare Elmt : Entity_Id; begin Predefined_Float_Types := New_Elmt_List; loop Tree_Read_Int (Int (Elmt)); exit when Elmt = Empty; Append_Elmt (Elmt, Predefined_Float_Types); end loop; end; -- Remainder of special entities Tree_Read_Int (Int (Any_Id)); Tree_Read_Int (Int (Any_Type)); Tree_Read_Int (Int (Any_Access)); Tree_Read_Int (Int (Any_Array)); Tree_Read_Int (Int (Any_Boolean)); Tree_Read_Int (Int (Any_Character)); Tree_Read_Int (Int (Any_Composite)); Tree_Read_Int (Int (Any_Discrete)); Tree_Read_Int (Int (Any_Fixed)); Tree_Read_Int (Int (Any_Integer)); Tree_Read_Int (Int (Any_Modular)); Tree_Read_Int (Int (Any_Numeric)); Tree_Read_Int (Int (Any_Real)); Tree_Read_Int (Int (Any_Scalar)); Tree_Read_Int (Int (Any_String)); Tree_Read_Int (Int (Raise_Type)); Tree_Read_Int (Int (Universal_Integer)); Tree_Read_Int (Int (Universal_Real)); Tree_Read_Int (Int (Universal_Fixed)); Tree_Read_Int (Int (Standard_Integer_8)); Tree_Read_Int (Int (Standard_Integer_16)); Tree_Read_Int (Int (Standard_Integer_32)); Tree_Read_Int (Int (Standard_Integer_64)); Tree_Read_Int (Int (Standard_Short_Short_Unsigned)); Tree_Read_Int (Int (Standard_Short_Unsigned)); Tree_Read_Int (Int (Standard_Unsigned)); Tree_Read_Int (Int (Standard_Long_Unsigned)); Tree_Read_Int (Int (Standard_Long_Long_Unsigned)); Tree_Read_Int (Int (Standard_Unsigned_64)); Tree_Read_Int (Int (Abort_Signal)); Tree_Read_Int (Int (Standard_Op_Rotate_Left)); Tree_Read_Int (Int (Standard_Op_Rotate_Right)); Tree_Read_Int (Int (Standard_Op_Shift_Left)); Tree_Read_Int (Int (Standard_Op_Shift_Right)); Tree_Read_Int (Int (Standard_Op_Shift_Right_Arithmetic)); end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is begin Tree_Write_Data (Standard_Entity'Address, Standard_Entity_Array_Type'Size / Storage_Unit); Tree_Write_Int (Int (Standard_Package_Node)); Tree_Write_Int (Int (Last_Standard_Node_Id)); Tree_Write_Int (Int (Last_Standard_List_Id)); Tree_Write_Int (Int (Boolean_Literals (False))); Tree_Write_Int (Int (Boolean_Literals (True))); Tree_Write_Int (Int (Standard_Void_Type)); Tree_Write_Int (Int (Standard_Exception_Type)); Tree_Write_Int (Int (Standard_A_String)); Tree_Write_Int (Int (Standard_A_Char)); Tree_Write_Int (Int (Standard_Debug_Renaming_Type)); -- Deal with Predefined_Float_Types, which is an Elist. Write the -- entities out in sequence, terminated by an Empty entry. declare Elmt : Elmt_Id; begin Elmt := First_Elmt (Predefined_Float_Types); while Present (Elmt) loop Tree_Write_Int (Int (Node (Elmt))); Next_Elmt (Elmt); end loop; Tree_Write_Int (Int (Empty)); end; -- Remainder of special entries Tree_Write_Int (Int (Any_Id)); Tree_Write_Int (Int (Any_Type)); Tree_Write_Int (Int (Any_Access)); Tree_Write_Int (Int (Any_Array)); Tree_Write_Int (Int (Any_Boolean)); Tree_Write_Int (Int (Any_Character)); Tree_Write_Int (Int (Any_Composite)); Tree_Write_Int (Int (Any_Discrete)); Tree_Write_Int (Int (Any_Fixed)); Tree_Write_Int (Int (Any_Integer)); Tree_Write_Int (Int (Any_Modular)); Tree_Write_Int (Int (Any_Numeric)); Tree_Write_Int (Int (Any_Real)); Tree_Write_Int (Int (Any_Scalar)); Tree_Write_Int (Int (Any_String)); Tree_Write_Int (Int (Raise_Type)); Tree_Write_Int (Int (Universal_Integer)); Tree_Write_Int (Int (Universal_Real)); Tree_Write_Int (Int (Universal_Fixed)); Tree_Write_Int (Int (Standard_Integer_8)); Tree_Write_Int (Int (Standard_Integer_16)); Tree_Write_Int (Int (Standard_Integer_32)); Tree_Write_Int (Int (Standard_Integer_64)); Tree_Write_Int (Int (Standard_Short_Short_Unsigned)); Tree_Write_Int (Int (Standard_Short_Unsigned)); Tree_Write_Int (Int (Standard_Unsigned)); Tree_Write_Int (Int (Standard_Long_Unsigned)); Tree_Write_Int (Int (Standard_Long_Long_Unsigned)); Tree_Write_Int (Int (Standard_Unsigned_64)); Tree_Write_Int (Int (Abort_Signal)); Tree_Write_Int (Int (Standard_Op_Rotate_Left)); Tree_Write_Int (Int (Standard_Op_Rotate_Right)); Tree_Write_Int (Int (Standard_Op_Shift_Left)); Tree_Write_Int (Int (Standard_Op_Shift_Right)); Tree_Write_Int (Int (Standard_Op_Shift_Right_Arithmetic)); end Tree_Write; end Stand; gprbuild-gpl-2014-src/gnat/tree_io.adb0000644000076700001450000004431012323721731017164 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- T R E E _ I O -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2009 Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Debug; use Debug; with Output; use Output; with Unchecked_Conversion; package body Tree_IO is Debug_Flag_Tree : Boolean := False; -- Debug flag for debug output from tree read/write ------------------------------------------- -- Compression Scheme Used for Tree File -- ------------------------------------------- -- We don't just write the data directly, but instead do a mild form -- of compression, since we expect lots of compressible zeroes and -- blanks. The compression scheme is as follows: -- 00nnnnnn followed by nnnnnn bytes (non compressed data) -- 01nnnnnn indicates nnnnnn binary zero bytes -- 10nnnnnn indicates nnnnnn ASCII space bytes -- 11nnnnnn bbbbbbbb indicates nnnnnnnn occurrences of byte bbbbbbbb -- Since we expect many zeroes in trees, and many spaces in sources, -- this compression should be reasonably efficient. We can put in -- something better later on. -- Note that this compression applies to the Write_Tree_Data and -- Read_Tree_Data calls, not to the calls to read and write single -- scalar values, which are written in memory format without any -- compression. C_Noncomp : constant := 2#00_000000#; C_Zeros : constant := 2#01_000000#; C_Spaces : constant := 2#10_000000#; C_Repeat : constant := 2#11_000000#; -- Codes for compression sequences Max_Count : constant := 63; -- Maximum data length for one compression sequence -- The above compression scheme applies only to data written with the -- Tree_Write routine and read with Tree_Read. Data written using the -- Tree_Write_Char or Tree_Write_Int routines and read using the -- corresponding input routines is not compressed. type Int_Bytes is array (1 .. 4) of Byte; for Int_Bytes'Size use 32; function To_Int_Bytes is new Unchecked_Conversion (Int, Int_Bytes); function To_Int is new Unchecked_Conversion (Int_Bytes, Int); ---------------------- -- Global Variables -- ---------------------- Tree_FD : File_Descriptor; -- File descriptor for tree Buflen : constant Int := 8_192; -- Length of buffer for read and write file data Buf : array (Pos range 1 .. Buflen) of Byte; -- Read/write file data buffer Bufn : Nat; -- Number of bytes read/written from/to buffer Buft : Nat; -- Total number of bytes in input buffer containing valid data. Used only -- for input operations. There is data left to be processed in the buffer -- if Buft > Bufn. A value of zero for Buft means that the buffer is empty. ----------------------- -- Local Subprograms -- ----------------------- procedure Read_Buffer; -- Reads data into buffer, setting Bufn appropriately function Read_Byte return Byte; pragma Inline (Read_Byte); -- Returns next byte from input file, raises Tree_Format_Error if none left procedure Write_Buffer; -- Writes out current buffer contents procedure Write_Byte (B : Byte); pragma Inline (Write_Byte); -- Write one byte to output buffer, checking for buffer-full condition ----------------- -- Read_Buffer -- ----------------- procedure Read_Buffer is begin Buft := Int (Read (Tree_FD, Buf (1)'Address, Integer (Buflen))); if Buft = 0 then raise Tree_Format_Error; else Bufn := 0; end if; end Read_Buffer; --------------- -- Read_Byte -- --------------- function Read_Byte return Byte is begin if Bufn = Buft then Read_Buffer; end if; Bufn := Bufn + 1; return Buf (Bufn); end Read_Byte; -------------------- -- Tree_Read_Bool -- -------------------- procedure Tree_Read_Bool (B : out Boolean) is begin B := Boolean'Val (Read_Byte); if Debug_Flag_Tree then if B then Write_Str ("True"); else Write_Str ("False"); end if; Write_Eol; end if; end Tree_Read_Bool; -------------------- -- Tree_Read_Char -- -------------------- procedure Tree_Read_Char (C : out Character) is begin C := Character'Val (Read_Byte); if Debug_Flag_Tree then Write_Str ("==> transmitting Character = "); Write_Char (C); Write_Eol; end if; end Tree_Read_Char; -------------------- -- Tree_Read_Data -- -------------------- procedure Tree_Read_Data (Addr : Address; Length : Int) is type S is array (Pos) of Byte; -- This is a big array, for which we have to suppress the warning type SP is access all S; function To_SP is new Unchecked_Conversion (Address, SP); Data : constant SP := To_SP (Addr); -- Data buffer to be read as an indexable array of bytes OP : Pos := 1; -- Pointer to next byte of data buffer to be read into B : Byte; C : Byte; L : Int; begin if Debug_Flag_Tree then Write_Str ("==> transmitting "); Write_Int (Length); Write_Str (" data bytes"); Write_Eol; end if; -- Verify data length Tree_Read_Int (L); if L /= Length then Write_Str ("==> transmitting, expected "); Write_Int (Length); Write_Str (" bytes, found length = "); Write_Int (L); Write_Eol; raise Tree_Format_Error; end if; -- Loop to read data while OP <= Length loop -- Get compression control character B := Read_Byte; C := B and 2#00_111111#; B := B and 2#11_000000#; -- Non-repeat case if B = C_Noncomp then if Debug_Flag_Tree then Write_Str ("==> uncompressed: "); Write_Int (Int (C)); Write_Str (", starting at "); Write_Int (OP); Write_Eol; end if; for J in 1 .. C loop Data (OP) := Read_Byte; OP := OP + 1; end loop; -- Repeated zeroes elsif B = C_Zeros then if Debug_Flag_Tree then Write_Str ("==> zeroes: "); Write_Int (Int (C)); Write_Str (", starting at "); Write_Int (OP); Write_Eol; end if; for J in 1 .. C loop Data (OP) := 0; OP := OP + 1; end loop; -- Repeated spaces elsif B = C_Spaces then if Debug_Flag_Tree then Write_Str ("==> spaces: "); Write_Int (Int (C)); Write_Str (", starting at "); Write_Int (OP); Write_Eol; end if; for J in 1 .. C loop Data (OP) := Character'Pos (' '); OP := OP + 1; end loop; -- Specified repeated character else -- B = C_Repeat B := Read_Byte; if Debug_Flag_Tree then Write_Str ("==> other char: "); Write_Int (Int (C)); Write_Str (" ("); Write_Int (Int (B)); Write_Char (')'); Write_Str (", starting at "); Write_Int (OP); Write_Eol; end if; for J in 1 .. C loop Data (OP) := B; OP := OP + 1; end loop; end if; end loop; -- At end of loop, data item must be exactly filled if OP /= Length + 1 then raise Tree_Format_Error; end if; end Tree_Read_Data; -------------------------- -- Tree_Read_Initialize -- -------------------------- procedure Tree_Read_Initialize (Desc : File_Descriptor) is begin Buft := 0; Bufn := 0; Tree_FD := Desc; Debug_Flag_Tree := Debug_Flag_5; end Tree_Read_Initialize; ------------------- -- Tree_Read_Int -- ------------------- procedure Tree_Read_Int (N : out Int) is N_Bytes : Int_Bytes; begin for J in 1 .. 4 loop N_Bytes (J) := Read_Byte; end loop; N := To_Int (N_Bytes); if Debug_Flag_Tree then Write_Str ("==> transmitting Int = "); Write_Int (N); Write_Eol; end if; end Tree_Read_Int; ------------------- -- Tree_Read_Str -- ------------------- procedure Tree_Read_Str (S : out String_Ptr) is N : Nat; begin Tree_Read_Int (N); S := new String (1 .. Natural (N)); Tree_Read_Data (S.all (1)'Address, N); end Tree_Read_Str; ------------------------- -- Tree_Read_Terminate -- ------------------------- procedure Tree_Read_Terminate is begin -- Must be at end of input buffer, so we should get Tree_Format_Error -- if we try to read one more byte, if not, we have a format error. declare B : Byte; pragma Warnings (Off, B); begin B := Read_Byte; exception when Tree_Format_Error => return; end; raise Tree_Format_Error; end Tree_Read_Terminate; --------------------- -- Tree_Write_Bool -- --------------------- procedure Tree_Write_Bool (B : Boolean) is begin if Debug_Flag_Tree then Write_Str ("==> transmitting Boolean = "); if B then Write_Str ("True"); else Write_Str ("False"); end if; Write_Eol; end if; Write_Byte (Boolean'Pos (B)); end Tree_Write_Bool; --------------------- -- Tree_Write_Char -- --------------------- procedure Tree_Write_Char (C : Character) is begin if Debug_Flag_Tree then Write_Str ("==> transmitting Character = "); Write_Char (C); Write_Eol; end if; Write_Byte (Character'Pos (C)); end Tree_Write_Char; --------------------- -- Tree_Write_Data -- --------------------- procedure Tree_Write_Data (Addr : Address; Length : Int) is type S is array (Pos) of Byte; -- This is a big array, for which we have to suppress the warning type SP is access all S; function To_SP is new Unchecked_Conversion (Address, SP); Data : constant SP := To_SP (Addr); -- Pointer to data to be written, converted to array type IP : Pos := 1; -- Input buffer pointer, next byte to be processed NC : Nat range 0 .. Max_Count := 0; -- Number of bytes of non-compressible sequence C : Byte; procedure Write_Non_Compressed_Sequence; -- Output currently collected sequence of non-compressible data ----------------------------------- -- Write_Non_Compressed_Sequence -- ----------------------------------- procedure Write_Non_Compressed_Sequence is begin if NC > 0 then Write_Byte (C_Noncomp + Byte (NC)); if Debug_Flag_Tree then Write_Str ("==> uncompressed: "); Write_Int (NC); Write_Str (", starting at "); Write_Int (IP - NC); Write_Eol; end if; for J in reverse 1 .. NC loop Write_Byte (Data (IP - J)); end loop; NC := 0; end if; end Write_Non_Compressed_Sequence; -- Start of processing for Tree_Write_Data begin if Debug_Flag_Tree then Write_Str ("==> transmitting "); Write_Int (Length); Write_Str (" data bytes"); Write_Eol; end if; -- We write the count at the start, so that we can check it on -- the corresponding read to make sure that reads and writes match Tree_Write_Int (Length); -- Conversion loop -- IP is index of next input character -- NC is number of non-compressible bytes saved up loop -- If input is completely processed, then we are all done if IP > Length then Write_Non_Compressed_Sequence; return; end if; -- Test for compressible sequence, must be at least three identical -- bytes in a row to be worthwhile compressing. if IP + 2 <= Length and then Data (IP) = Data (IP + 1) and then Data (IP) = Data (IP + 2) then Write_Non_Compressed_Sequence; -- Count length of new compression sequence C := 3; IP := IP + 3; while IP < Length and then Data (IP) = Data (IP - 1) and then C < Max_Count loop C := C + 1; IP := IP + 1; end loop; -- Output compression sequence if Data (IP - 1) = 0 then if Debug_Flag_Tree then Write_Str ("==> zeroes: "); Write_Int (Int (C)); Write_Str (", starting at "); Write_Int (IP - Int (C)); Write_Eol; end if; Write_Byte (C_Zeros + C); elsif Data (IP - 1) = Character'Pos (' ') then if Debug_Flag_Tree then Write_Str ("==> spaces: "); Write_Int (Int (C)); Write_Str (", starting at "); Write_Int (IP - Int (C)); Write_Eol; end if; Write_Byte (C_Spaces + C); else if Debug_Flag_Tree then Write_Str ("==> other char: "); Write_Int (Int (C)); Write_Str (" ("); Write_Int (Int (Data (IP - 1))); Write_Char (')'); Write_Str (", starting at "); Write_Int (IP - Int (C)); Write_Eol; end if; Write_Byte (C_Repeat + C); Write_Byte (Data (IP - 1)); end if; -- No compression possible here else -- Output non-compressed sequence if at maximum length if NC = Max_Count then Write_Non_Compressed_Sequence; end if; NC := NC + 1; IP := IP + 1; end if; end loop; end Tree_Write_Data; --------------------------- -- Tree_Write_Initialize -- --------------------------- procedure Tree_Write_Initialize (Desc : File_Descriptor) is begin Bufn := 0; Tree_FD := Desc; Set_Standard_Error; Debug_Flag_Tree := Debug_Flag_5; end Tree_Write_Initialize; -------------------- -- Tree_Write_Int -- -------------------- procedure Tree_Write_Int (N : Int) is N_Bytes : constant Int_Bytes := To_Int_Bytes (N); begin if Debug_Flag_Tree then Write_Str ("==> transmitting Int = "); Write_Int (N); Write_Eol; end if; for J in 1 .. 4 loop Write_Byte (N_Bytes (J)); end loop; end Tree_Write_Int; -------------------- -- Tree_Write_Str -- -------------------- procedure Tree_Write_Str (S : String_Ptr) is begin Tree_Write_Int (S'Length); Tree_Write_Data (S (1)'Address, S'Length); end Tree_Write_Str; -------------------------- -- Tree_Write_Terminate -- -------------------------- procedure Tree_Write_Terminate is begin if Bufn > 0 then Write_Buffer; end if; end Tree_Write_Terminate; ------------------ -- Write_Buffer -- ------------------ procedure Write_Buffer is begin if Integer (Bufn) = Write (Tree_FD, Buf'Address, Integer (Bufn)) then Bufn := 0; else Set_Standard_Error; Write_Str ("fatal error: disk full"); OS_Exit (2); end if; end Write_Buffer; ---------------- -- Write_Byte -- ---------------- procedure Write_Byte (B : Byte) is begin Bufn := Bufn + 1; Buf (Bufn) := B; if Bufn = Buflen then Write_Buffer; end if; end Write_Byte; end Tree_IO; gprbuild-gpl-2014-src/gnat/link.c0000644000076700001450000002453412323721732016176 0ustar gnatmailgnat/**************************************************************************** * * * GNAT COMPILER COMPONENTS * * * * L I N K * * * * C Implementation File * * * * Copyright (C) 1992-2012, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * * ware Foundation; either version 3, or (at your option) any later ver- * * sion. GNAT is distributed in the hope that it will be useful, but WITH- * * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * * or FITNESS FOR A PARTICULAR PURPOSE. * * * * * * * * * * * * You should have received a copy of the GNU General Public License and * * a copy of the GCC Runtime Library Exception along with this program; * * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see * * . * * * * GNAT was originally developed by the GNAT team at New York University. * * Extensive contributions were provided by Ada Core Technologies Inc. * * * ****************************************************************************/ /* This file contains host-specific parameters describing the behavior of the linker. It is used by gnatlink as well as all tools that use Mlib. */ #ifdef __cplusplus extern "C" { #endif #ifdef IN_GCC #include "auto-host.h" #endif #include /* objlist_file_supported is set to 1 when the system linker allows */ /* response file, that is a file that contains the list of object files. */ /* This is useful on systems where the command line length is limited, */ /* meaning that putting all the object files on the command line can */ /* result in an unacceptable limit on the number of files. */ /* object_file_option denotes the system dependent linker option which */ /* allows object file names to be placed in a file and then passed to */ /* the linker. object_file_option must be set if objlist_file_supported */ /* is set to 1. */ /* link_max is a conservative system specific threshold (in bytes) of the */ /* argument length passed to the linker which will trigger a file being */ /* used instead of the command line directly. If the argument length is */ /* greater than this threshold, then an objlist_file will be generated */ /* and object_file_option and objlist_file_supported must be set. If */ /* objlist_file_supported is set to 0 (unsupported), then link_max is */ /* set to 2**31-1 so that the limit will never be exceeded. */ /* run_path_option is the system dependent linker option which specifies */ /* the run time path to use when loading dynamic libraries. This should */ /* be set to the null string if the system does not support dynamic */ /* loading of libraries. */ /* shared_libgnat_default gives the system dependent link method that */ /* be used by default for linking libgnat (shared or static) */ /* shared_libgcc_default gives the system dependent link method that */ /* be used by default for linking libgcc (shared or static) */ /* separate_run_path_options is set to 1 when separate "rpath" arguments */ /* must be passed to the linker for each directory in the rpath. */ /* default_libgcc_subdir is the subdirectory name (from the installation */ /* root) where we may find a shared libgcc to use by default. */ #define SHARED 'H' #define STATIC 'T' #if defined (__WIN32) const char *__gnat_object_file_option = "-Wl,@"; const char *__gnat_run_path_option = ""; int __gnat_link_max = 30000; unsigned char __gnat_objlist_file_supported = 1; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #elif defined (__hpux__) const char *__gnat_object_file_option = "-Wl,-c,"; const char *__gnat_run_path_option = "-Wl,+b,"; int __gnat_link_max = 5000; unsigned char __gnat_objlist_file_supported = 1; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #elif defined (__FreeBSD__) const char *__gnat_object_file_option = "-Wl,@"; const char *__gnat_run_path_option = "-Wl,-rpath,"; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 8192; unsigned char __gnat_objlist_file_supported = 1; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #elif defined (__APPLE__) const char *__gnat_object_file_option = "-Wl,-filelist,"; const char *__gnat_run_path_option = "-Wl,-rpath,"; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = SHARED; int __gnat_link_max = 262144; unsigned char __gnat_objlist_file_supported = 1; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 1; const char *__gnat_default_libgcc_subdir = "lib"; #elif defined (linux) || defined(__GLIBC__) const char *__gnat_object_file_option = "-Wl,@"; const char *__gnat_run_path_option = "-Wl,-rpath,"; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 8192; unsigned char __gnat_objlist_file_supported = 1; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; #if defined (__x86_64) # if defined (__LP64__) const char *__gnat_default_libgcc_subdir = "lib64"; # else const char *__gnat_default_libgcc_subdir = "libx32"; # endif #else const char *__gnat_default_libgcc_subdir = "lib"; #endif #elif defined (_AIX) /* On AIX, even when with GNU ld we use native linker switches. This is particularly important for '-f' as it should be interpreted by collect2. */ const char *__gnat_object_file_option = "-Wl,-f,"; const char *__gnat_run_path_option = ""; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 15000; const unsigned char __gnat_objlist_file_supported = 1; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #elif (HAVE_GNU_LD) /* These are the settings for all systems that use gnu ld. GNU style response file is supported, the shared library default is STATIC. */ const char *__gnat_object_file_option = "-Wl,@"; const char *__gnat_run_path_option = ""; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 8192; unsigned char __gnat_objlist_file_supported = 1; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #elif defined (VMS) const char *__gnat_object_file_option = ""; const char *__gnat_run_path_option = ""; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 2147483647; unsigned char __gnat_objlist_file_supported = 0; const char *__gnat_object_library_extension = ".olb"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #elif defined (sun) const char *__gnat_object_file_option = ""; const char *__gnat_run_path_option = "-Wl,-R"; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 2147483647; unsigned char __gnat_objlist_file_supported = 0; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; #if defined (__sparc_v9__) || defined (__sparcv9) const char *__gnat_default_libgcc_subdir = "lib/sparcv9"; #elif defined (__x86_64) const char *__gnat_default_libgcc_subdir = "lib/amd64"; #else const char *__gnat_default_libgcc_subdir = "lib"; #endif #elif defined (__svr4__) && defined (i386) const char *__gnat_object_file_option = ""; const char *__gnat_run_path_option = ""; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 2147483647; unsigned char __gnat_objlist_file_supported = 0; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #else /* These are the default settings for all other systems. No response file is supported, the shared library default is STATIC. */ const char *__gnat_run_path_option = ""; const char *__gnat_object_file_option = ""; char __gnat_shared_libgnat_default = STATIC; char __gnat_shared_libgcc_default = STATIC; int __gnat_link_max = 2147483647; unsigned char __gnat_objlist_file_supported = 0; const char *__gnat_object_library_extension = ".a"; unsigned char __gnat_separate_run_path_options = 0; const char *__gnat_default_libgcc_subdir = "lib"; #endif #ifdef __cplusplus } #endif gprbuild-gpl-2014-src/gnat/prj-util.ads0000644000076700001450000002731212323721731017330 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . U T I L -- -- -- -- S p e c -- -- -- -- Copyright (C) 2001-2012, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- Utilities for use in processing project files package Prj.Util is function Executable_Of (Project : Project_Id; Shared : Shared_Project_Tree_Data_Access; Main : File_Name_Type; Index : Int; Ada_Main : Boolean := True; Language : String := ""; Include_Suffix : Boolean := True) return File_Name_Type; -- Return the value of the attribute Builder'Executable for file Main in -- the project Project, if it exists. If there is no attribute Executable -- for Main, remove the suffix from Main; then, if the attribute -- Executable_Suffix is specified, add this suffix, otherwise add the -- standard executable suffix for the platform. -- -- If Include_Suffix is true, then the ".exe" suffix (or any suffix defined -- in the config) will be added. The suffix defined by the user in his own -- project file is always taken into account. Otherwise, such a suffix is -- not added. In particular, the prefix should not be added if you are -- potentially testing for cross-platforms, since the suffix might not be -- known (its default value comes from the ...-gnatmake prefix). -- -- What is Ada_Main??? -- What is Language??? procedure Put (Into_List : in out Name_List_Index; From_List : String_List_Id; In_Tree : Project_Tree_Ref; Lower_Case : Boolean := False); -- Append a name list to a string list -- Describe parameters??? procedure Duplicate (This : in out Name_List_Index; Shared : Shared_Project_Tree_Data_Access); -- Duplicate a name list function Value_Of (Variable : Variable_Value; Default : String) return String; -- Get the value of a single string variable. If Variable is a string list, -- is Nil_Variable_Value,or is defaulted, return Default. function Value_Of (Index : Name_Id; In_Array : Array_Element_Id; Shared : Shared_Project_Tree_Data_Access) return Name_Id; -- Get a single string array component. Returns No_Name if there is no -- component Index, if In_Array is null, or if the component is a String -- list. Depending on the attribute (only attributes may be associative -- arrays) the index may or may not be case sensitive. If the index is not -- case sensitive, it is first set to lower case before the search in the -- associative array. function Value_Of (Index : Name_Id; Src_Index : Int := 0; In_Array : Array_Element_Id; Shared : Shared_Project_Tree_Data_Access; Force_Lower_Case_Index : Boolean := False; Allow_Wildcards : Boolean := False) return Variable_Value; -- Get a string array component (single String or String list). Returns -- Nil_Variable_Value if no component Index or if In_Array is null. -- -- Depending on the attribute (only attributes may be associative arrays) -- the index may or may not be case sensitive. If the index is not case -- sensitive, it is first set to lower case before the search in the -- associative array. function Value_Of (Name : Name_Id; Index : Int := 0; Attribute_Or_Array_Name : Name_Id; In_Package : Package_Id; Shared : Shared_Project_Tree_Data_Access; Force_Lower_Case_Index : Boolean := False; Allow_Wildcards : Boolean := False) return Variable_Value; -- In a specific package: -- - if there exists an array Attribute_Or_Array_Name with an index Name, -- returns the corresponding component (depending on the attribute, the -- index may or may not be case sensitive, see previous function), -- - otherwise if there is a single attribute Attribute_Or_Array_Name, -- returns this attribute, -- - otherwise, returns Nil_Variable_Value. -- If In_Package is null, returns Nil_Variable_Value. function Value_Of (Index : Name_Id; In_Array : Name_Id; In_Arrays : Array_Id; Shared : Shared_Project_Tree_Data_Access) return Name_Id; -- Get a string array component in an array of an array list. Returns -- No_Name if there is no component Index, if In_Arrays is null, if -- In_Array is not found in In_Arrays or if the component is a String list. function Value_Of (Name : Name_Id; In_Arrays : Array_Id; Shared : Shared_Project_Tree_Data_Access) return Array_Element_Id; -- Returns a specified array in an array list. Returns No_Array_Element -- if In_Arrays is null or if Name is not the name of an array in -- In_Arrays. The caller must ensure that Name is in lower case. function Value_Of (Name : Name_Id; In_Packages : Package_Id; Shared : Shared_Project_Tree_Data_Access) return Package_Id; -- Returns a specified package in a package list. Returns No_Package -- if In_Packages is null or if Name is not the name of a package in -- Package_List. The caller must ensure that Name is in lower case. function Value_Of (Variable_Name : Name_Id; In_Variables : Variable_Id; Shared : Shared_Project_Tree_Data_Access) return Variable_Value; -- Returns a specified variable in a variable list. Returns null if -- In_Variables is null or if Variable_Name is not the name of a -- variable in In_Variables. Caller must ensure that Name is lower case. procedure Write_Str (S : String; Max_Length : Positive; Separator : Character); -- Output string S using Output.Write_Str. If S is too long to fit in one -- line of Max_Length, cut it in several lines, using Separator as the last -- character of each line, if possible. type Text_File is limited private; -- Represents a text file (default is invalid text file) function Is_Valid (File : Text_File) return Boolean; -- Returns True if File designates an open text file that has not yet been -- closed. procedure Open (File : out Text_File; Name : String); -- Open a text file to read (File is invalid if text file cannot be opened) procedure Create (File : out Text_File; Name : String); -- Create a text file to write (File is invalid if text file cannot be -- created). function End_Of_File (File : Text_File) return Boolean; -- Returns True if the end of the text file File has been reached. Fails if -- File is invalid. Return True if File is an out file. procedure Get_Line (File : Text_File; Line : out String; Last : out Natural); -- Reads a line from an open text file (fails if File is invalid or in an -- out file). procedure Put (File : Text_File; S : String); procedure Put_Line (File : Text_File; Line : String); -- Output a string or a line to an out text file (fails if File is invalid -- or in an in file). procedure Close (File : in out Text_File); -- Close an open text file. File becomes invalid. Fails if File is already -- invalid or if an out file cannot be closed successfully. ----------------------- -- Source info files -- ----------------------- procedure Write_Source_Info_File (Tree : Project_Tree_Ref); -- Create a new source info file, with the path name specified in the -- project tree data. Issue a warning if it is not possible to create -- the new file. procedure Read_Source_Info_File (Tree : Project_Tree_Ref); -- Check if there is a source info file specified for the project Tree. If -- so, attempt to read it. If the file exists and is successfully read, set -- the flag Source_Info_File_Exists to True for the tree. type Source_Info_Data is record Project : Name_Id; Language : Name_Id; Kind : Source_Kind; Display_Path_Name : Name_Id; Path_Name : Name_Id; Unit_Name : Name_Id := No_Name; Index : Int := 0; Naming_Exception : Naming_Exception_Type := No; end record; -- Data read from a source info file for a single source type Source_Info is access all Source_Info_Data; No_Source_Info : constant Source_Info := null; type Source_Info_Iterator is private; -- Iterator to get the sources for a single project procedure Initialize (Iter : out Source_Info_Iterator; For_Project : Name_Id); -- Initialize Iter for the project function Source_Info_Of (Iter : Source_Info_Iterator) return Source_Info; -- Get the source info for the source corresponding to the current value of -- the iterator. Returns No_Source_Info if there is no source corresponding -- to the iterator. procedure Next (Iter : in out Source_Info_Iterator); -- Advance the iterator to the next source in the project generic with procedure Action (Source : Source_Id); procedure For_Interface_Sources (Tree : Project_Tree_Ref; Project : Project_Id); -- Call Action for every sources that are needed to use Project. This is -- either the sources corresponding to the units in attribute Interfaces -- or all sources of the project. Note that only the bodies that are -- needed (because the unit is generic or contains some inline pragmas) -- are handled. This routine must be called only when the project has -- been built successfully. private type Text_File_Data is record FD : File_Descriptor := Invalid_FD; Out_File : Boolean := False; Buffer : String (1 .. 1_000); Buffer_Len : Natural := 0; Cursor : Natural := 0; End_Of_File_Reached : Boolean := False; end record; type Text_File is access Text_File_Data; type Source_Info_Iterator is record Info : Source_Info; Next : Natural; end record; end Prj.Util; gprbuild-gpl-2014-src/gnat/projects.texi0000644000076700001450000057724312307305637017637 0ustar gnatmailgnat@set gprconfig GPRconfig @c ------ projects.texi @c Copyright (C) 2002-2014, Free Software Foundation, Inc. @c This file is shared between the GNAT user's guide and gprbuild. It is not @c compilable on its own, you should instead compile the other two manuals. @c For that reason, there is no toplevel @menu @c --------------------------------------------- @node GNAT Project Manager @chapter GNAT Project Manager @c --------------------------------------------- @noindent @menu * Introduction:: * Building With Projects:: * Organizing Projects into Subsystems:: * Scenarios in Projects:: * Library Projects:: * Project Extension:: * Aggregate Projects:: * Aggregate Library Projects:: * Project File Reference:: @end menu @c --------------------------------------------- @node Introduction @section Introduction @c --------------------------------------------- @noindent This chapter describes GNAT's @emph{Project Manager}, a facility that allows you to manage complex builds involving a number of source files, directories, and options for different system configurations. In particular, project files allow you to specify: @itemize @bullet @item The directory or set of directories containing the source files, and/or the names of the specific source files themselves @item The directory in which the compiler's output (@file{ALI} files, object files, tree files, etc.) is to be placed @item The directory in which the executable programs are to be placed @item ^Switch^Switch^ settings for any of the project-enabled tools; you can apply these settings either globally or to individual compilation units. @item The source files containing the main subprogram(s) to be built @item The source programming language(s) @item Source file naming conventions; you can specify these either globally or for individual compilation units (@pxref{Naming Schemes}). @item Change any of the above settings depending on external values, thus enabling the reuse of the projects in various @b{scenarios} (@pxref{Scenarios in Projects}). @item Automatically build libraries as part of the build process (@pxref{Library Projects}). @end itemize @noindent Project files are written in a syntax close to that of Ada, using familiar notions such as packages, context clauses, declarations, default values, assignments, and inheritance (@pxref{Project File Reference}). Project files can be built hierarchically from other project files, simplifying complex system integration and project reuse (@pxref{Organizing Projects into Subsystems}). @itemize @bullet @item One project can import other projects containing needed source files. More generally, the Project Manager lets you structure large development efforts into hierarchical subsystems, where build decisions are delegated to the subsystem level, and thus different compilation environments (^switch^switch^ settings) used for different subsystems. @item You can organize GNAT projects in a hierarchy: a child project can extend a parent project, inheriting the parent's source files and optionally overriding any of them with alternative versions (@pxref{Project Extension}). @end itemize @noindent Several tools support project files, generally in addition to specifying the information on the command line itself). They share common switches to control the loading of the project (in particular @option{^-P^/PROJECT_FILE=^@emph{projectfile}} and @option{^-X^/EXTERNAL_REFERENCE=^@emph{vbl}=@emph{value}}). The Project Manager supports a wide range of development strategies, for systems of all sizes. Here are some typical practices that are easily handled: @itemize @bullet @item Using a common set of source files and generating object files in different directories via different ^switch^switch^ settings. It can be used for instance, for generating separate sets of object files for debugging and for production. @item Using a mostly-shared set of source files with different versions of some units or subunits. It can be used for instance, for grouping and hiding @end itemize @noindent all OS dependencies in a small number of implementation units. Project files can be used to achieve some of the effects of a source versioning system (for example, defining separate projects for the different sets of sources that comprise different releases) but the Project Manager is independent of any source configuration management tool that might be used by the developers. The various sections below introduce the different concepts related to projects. Each section starts with examples and use cases, and then goes into the details of related project file capabilities. @c --------------------------------------------- @node Building With Projects @section Building With Projects @c --------------------------------------------- @noindent In its simplest form, a unique project is used to build a single executable. This section concentrates on such a simple setup. Later sections will extend this basic model to more complex setups. The following concepts are the foundation of project files, and will be further detailed later in this documentation. They are summarized here as a reference. @table @asis @item @b{Project file}: A text file using an Ada-like syntax, generally using the @file{.gpr} extension. It defines build-related characteristics of an application. The characteristics include the list of sources, the location of those sources, the location for the generated object files, the name of the main program, and the options for the various tools involved in the build process. @item @b{Project attribute}: A specific project characteristic is defined by an attribute clause. Its value is a string or a sequence of strings. All settings in a project are defined through a list of predefined attributes with precise semantics. @xref{Attributes}. @item @b{Package in a project}: Global attributes are defined at the top level of a project. Attributes affecting specific tools are grouped in a package whose name is related to tool's function. The most common packages are @code{Builder}, @code{Compiler}, @code{Binder}, and @code{Linker}. @xref{Packages}. @item @b{Project variables}: In addition to attributes, a project can use variables to store intermediate values and avoid duplication in complex expressions. It can be initialized with a value coming from the environment. A frequent use of variables is to define scenarios. @xref{External Values}, @xref{Scenarios in Projects}, and @xref{Variables}. @item @b{Source files} and @b{source directories}: A source file is associated with a language through a naming convention. For instance, @code{foo.c} is typically the name of a C source file; @code{bar.ads} or @code{bar.1.ada} are two common naming conventions for a file containing an Ada spec. A compilation unit is often composed of a main source file and potentially several auxiliary ones, such as header files in C. The naming conventions can be user defined @xref{Naming Schemes}, and will drive the builder to call the appropriate compiler for the given source file. Source files are searched for in the source directories associated with the project through the @b{Source_Dirs} attribute. By default, all the files (in these source directories) following the naming conventions associated with the declared languages are considered to be part of the project. It is also possible to limit the list of source files using the @b{Source_Files} or @b{Source_List_File} attributes. Note that those last two attributes only accept basenames with no directory information. @item @b{Object files} and @b{object directory}: An object file is an intermediate file produced by the compiler from a compilation unit. It is used by post-compilation tools to produce final executables or libraries. Object files produced in the context of a given project are stored in a single directory that can be specified by the @b{Object_Dir} attribute. In order to store objects in two or more object directories, the system must be split into distinct subsystems with their own project file. /first exam @end table The following subsections introduce gradually all the attributes of interest for simple build needs. Here is the simple setup that will be used in the following examples. The Ada source files @file{pack.ads}, @file{pack.adb}, and @file{proc.adb} are in the @file{common/} directory. The file @file{proc.adb} contains an Ada main subprogram @code{Proc} that @code{with}s package @code{Pack}. We want to compile these source files with the ^switch^switch^ @option{^-O2^-O2^}, and put the resulting files in the directory @file{obj/}. @smallexample @group ^common/^[COMMON]^ pack.ads pack.adb proc.adb @end group @group ^common/release/^[COMMON.RELEASE]^ proc.ali, proc.o pack.ali, pack.o @end group @end smallexample @noindent Our project is to be called @emph{Build}. The name of the file is the name of the project (case-insensitive) with the @file{.gpr} extension, therefore the project file name is @file{build.gpr}. This is not mandatory, but a warning is issued when this convention is not followed. This is a very simple example, and as stated above, a single project file is enough for it. We will thus create a new file, that for now should contain the following code: @smallexample @b{project} Build @b{is} @b{end} Build; @end smallexample @menu * Source Files and Directories:: * Duplicate Sources in Projects:: * Object and Exec Directory:: * Main Subprograms:: * Tools Options in Project Files:: * Compiling with Project Files:: * Executable File Names:: * Avoid Duplication With Variables:: * Naming Schemes:: * Installation:: * Distributed support:: @end menu @c --------------------------------------------- @node Source Files and Directories @subsection Source Files and Directories @c --------------------------------------------- @noindent When you create a new project, the first thing to describe is how to find the corresponding source files. This is the only settings that are needed by all the tools that will use this project (builder, compiler, binder and linker for the compilation, IDEs to edit the source files,@dots{}). @cindex Source directories First step is to declare the source directories, which are the directories to be searched to find source files. In the case of the example, the @file{common} directory is the only source directory. @cindex @code{Source_Dirs} There are several ways of defining source directories: @itemize @bullet @item When the attribute @b{Source_Dirs} is not used, a project contains a single source directory which is the one where the project file itself resides. In our example, if @file{build.gpr} is placed in the @file{common} directory, the project has the needed implicit source directory. @item The attribute @b{Source_Dirs} can be set to a list of path names, one for each of the source directories. Such paths can either be absolute names (for instance @file{"/usr/local/common/"} on UNIX), or relative to the directory in which the project file resides (for instance "." if @file{build.gpr} is inside @file{common/}, or "common" if it is one level up). Each of the source directories must exist and be readable. @cindex portability The syntax for directories is platform specific. For portability, however, the project manager will always properly translate UNIX-like path names to the native format of specific platform. For instance, when the same project file is to be used both on Unix and Windows, "/" should be used as the directory separator rather than "\". @item The attribute @b{Source_Dirs} can automatically include subdirectories using a special syntax inspired by some UNIX shells. If any of the path in the list ends with @emph{"**"}, then that path and all its subdirectories (recursively) are included in the list of source directories. For instance, @file{**} and @file{./**} represent the complete directory tree rooted at ".". @cindex Source directories, recursive @cindex @code{Excluded_Source_Dirs} When using that construct, it can sometimes be convenient to also use the attribute @b{Excluded_Source_Dirs}, which is also a list of paths. Each entry specifies a directory whose immediate content, not including subdirs, is to be excluded. It is also possible to exclude a complete directory subtree using the "**" notation. @cindex @code{Ignore_Source_Sub_Dirs} It is often desirable to remove, from the source directories, directory subtrees rooted at some subdirectories. An example is the subdirectories created by a Version Control System such as Subversion that creates directory subtrees rooted at subdirectories ".svn". To do that, attribute @b{Ignore_Source_Sub_Dirs} can be used. It specifies the list of simple file names for the roots of these undesirable directory subtrees. @smallexample @b{for} Source_Dirs @b{use} ("./**"); @b{for} Ignore_Source_Sub_Dirs @b{use} (".svn"); @end smallexample @end itemize @noindent When applied to the simple example, and because we generally prefer to have the project file at the toplevel directory rather than mixed with the sources, we will create the following file @smallexample build.gpr @b{project} Build @b{is} @b{for} Source_Dirs @b{use} ("common"); -- <<<< @b{end} Build; @end smallexample @noindent Once source directories have been specified, one may need to indicate source files of interest. By default, all source files present in the source directories are considered by the project manager. When this is not desired, it is possible to specify the list of sources to consider explicitly. In such a case, only source file base names are indicated and not their absolute or relative path names. The project manager is in charge of locating the specified source files in the specified source directories. @itemize @bullet @item By default, the project manager search for all source files of all specified languages in all the source directories. Since the project manager was initially developed for Ada environments, the default language is usually Ada and the above project file is complete: it defines without ambiguity the sources composing the project: that is to say, all the sources in subdirectory "common" for the default language (Ada) using the default naming convention. @cindex @code{Languages} However, when compiling a multi-language application, or a pure C application, the project manager must be told which languages are of interest, which is done by setting the @b{Languages} attribute to a list of strings, each of which is the name of a language. Tools like @command{gnatmake} only know about Ada, while other tools like @command{gprbuild} know about many more languages such as C, C++, Fortran, assembly and others can be added dynamically. @cindex Naming scheme Even when using only Ada, the default naming might not be suitable. Indeed, how does the project manager recognizes an "Ada file" from any other file? Project files can describe the naming scheme used for source files, and override the default (@pxref{Naming Schemes}). The default is the standard GNAT extension (@file{.adb} for bodies and @file{.ads} for specs), which is what is used in our example, explaining why no naming scheme is explicitly specified. @xref{Naming Schemes}. @item @code{Source_Files} @cindex @code{Source_Files} In some cases, source directories might contain files that should not be included in a project. One can specify the explicit list of file names to be considered through the @b{Source_Files} attribute. When this attribute is defined, instead of looking at every file in the source directories, the project manager takes only those names into consideration reports errors if they cannot be found in the source directories or does not correspond to the naming scheme. @item For various reasons, it is sometimes useful to have a project with no sources (most of the time because the attributes defined in the project file will be reused in other projects, as explained in @pxref{Organizing Projects into Subsystems}. To do this, the attribute @emph{Source_Files} is set to the empty list, i.e. @code{()}. Alternatively, @emph{Source_Dirs} can be set to the empty list, with the same result. @item @code{Source_List_File} @cindex @code{Source_List_File} If there is a great number of files, it might be more convenient to use the attribute @b{Source_List_File}, which specifies the full path of a file. This file must contain a list of source file names (one per line, no directory information) that are searched as if they had been defined through @emph{Source_Files}. Such a file can easily be created through external tools. A warning is issued if both attributes @code{Source_Files} and @code{Source_List_File} are given explicit values. In this case, the attribute @code{Source_Files} prevails. @item @code{Excluded_Source_Files} @cindex @code{Excluded_Source_Files} @cindex @code{Locally_Removed_Files} @cindex @code{Excluded_Source_List_File} Specifying an explicit list of files is not always convenient.It might be more convenient to use the default search rules with specific exceptions. This can be done thanks to the attribute @b{Excluded_Source_Files} (or its synonym @b{Locally_Removed_Files}). Its value is the list of file names that should not be taken into account. This attribute is often used when extending a project, @xref{Project Extension}. A similar attribute @b{Excluded_Source_List_File} plays the same role but takes the name of file containing file names similarly to @code{Source_List_File}. @end itemize @noindent In most simple cases, such as the above example, the default source file search behavior provides the expected result, and we do not need to add anything after setting @code{Source_Dirs}. The project manager automatically finds @file{pack.ads}, @file{pack.adb} and @file{proc.adb} as source files of the project. Note that by default a warning is issued when a project has no sources attached to it and this is not explicitly indicated in the project file. @c --------------------------------------------- @node Duplicate Sources in Projects @subsection Duplicate Sources in Projects @c --------------------------------------------- @noindent If the order of the source directories is known statically, that is if @code{"/**"} is not used in the string list @code{Source_Dirs}, then there may be several files with the same source file name sitting in different directories of the project. In this case, only the file in the first directory is considered as a source of the project and the others are hidden. If @code{"/**"} is used in the string list @code{Source_Dirs}, it is an error to have several files with the same source file name in the same directory @code{"/**"} subtree, since there would be an ambiguity as to which one should be used. However, two files with the same source file name may exist in two single directories or directory subtrees. In this case, the one in the first directory or directory subtree is a source of the project. If there are two sources in different directories of the same @code{"/**"} subtree, one way to resolve the problem is to exclude the directory of the file that should not be used as a source of the project. @c --------------------------------------------- @node Object and Exec Directory @subsection Object and Exec Directory @c --------------------------------------------- @noindent The next step when writing a project is to indicate where the compiler should put the object files. In fact, the compiler and other tools might create several different kind of files (for GNAT, there is the object file and the ALI file for instance). One of the important concepts in projects is that most tools may consider source directories as read-only and do not attempt to create new or temporary files there. Instead, all files are created in the object directory. It is of course not true for project-aware IDEs, whose purpose it is to create the source files. @cindex @code{Object_Dir} The object directory is specified through the @b{Object_Dir} attribute. Its value is the path to the object directory, either absolute or relative to the directory containing the project file. This directory must already exist and be readable and writable, although some tools have a switch to create the directory if needed (See the switch @code{^-p^/CREATE_MISSING_DIRS^} for @command{gnatmake} and @command{gprbuild}). If the attribute @code{Object_Dir} is not specified, it defaults to the project directory, that is the directory containing the project file. For our example, we can specify the object dir in this way: @smallexample @b{project} Build @b{is} @b{for} Source_Dirs @b{use} ("common"); @b{for} Object_Dir @b{use} "obj"; -- <<<< @b{end} Build; @end smallexample @noindent As mentioned earlier, there is a single object directory per project. As a result, if you have an existing system where the object files are spread in several directories, you can either move all of them into the same directory if you want to build it with a single project file, or study the section on subsystems (@pxref{Organizing Projects into Subsystems}) to see how each separate object directory can be associated with one of the subsystem constituting the application. When the @command{linker} is called, it usually creates an executable. By default, this executable is placed in the object directory of the project. It might be convenient to store it in its own directory. @cindex @code{Exec_Dir} This can be done through the @code{Exec_Dir} attribute, which, like @emph{Object_Dir} contains a single absolute or relative path and must point to an existing and writable directory, unless you ask the tool to create it on your behalf. When not specified, It defaults to the object directory and therefore to the project file's directory if neither @emph{Object_Dir} nor @emph{Exec_Dir} was specified. In the case of the example, let's place the executable in the root of the hierarchy, ie the same directory as @file{build.gpr}. Hence the project file is now @smallexample @b{project} Build @b{is} @b{for} Source_Dirs @b{use} ("common"); @b{for} Object_Dir @b{use} "obj"; @b{for} Exec_Dir @b{use} "."; -- <<<< @b{end} Build; @end smallexample @c --------------------------------------------- @node Main Subprograms @subsection Main Subprograms @c --------------------------------------------- @noindent In the previous section, executables were mentioned. The project manager needs to be taught what they are. In a project file, an executable is indicated by pointing to source file of the main subprogram. In C this is the file that contains the @code{main} function, and in Ada the file that contains the main unit. There can be any number of such main files within a given project, and thus several executables can be built in the context of a single project file. Of course, one given executable might not (and in fact will not) need all the source files referenced by the project. As opposed to other build environments such as @command{makefile}, one does not need to specify the list of dependencies of each executable, the project-aware builders knows enough of the semantics of the languages to build ands link only the necessary elements. @cindex @code{Main} The list of main files is specified via the @b{Main} attribute. It contains a list of file names (no directories). If a project defines this attribute, it is not necessary to identify main files on the command line when invoking a builder, and editors like @command{GPS} will be able to create extra menus to spawn or debug the corresponding executables. @smallexample @b{project} Build @b{is} @b{for} Source_Dirs @b{use} ("common"); @b{for} Object_Dir @b{use} "obj"; @b{for} Exec_Dir @b{use} "."; @b{for} Main @b{use} ("proc.adb"); -- <<<< @b{end} Build; @end smallexample @noindent If this attribute is defined in the project, then spawning the builder with a command such as @smallexample gnatmake ^-Pbuild^/PROJECT_FILE=build^ @end smallexample @noindent automatically builds all the executables corresponding to the files listed in the @emph{Main} attribute. It is possible to specify one or more executables on the command line to build a subset of them. @c --------------------------------------------- @node Tools Options in Project Files @subsection Tools Options in Project Files @c --------------------------------------------- @noindent We now have a project file that fully describes our environment, and can be used to build the application with a simple @command{gnatmake} command as seen in the previous section. In fact, the empty project we showed immediately at the beginning (with no attribute at all) could already fulfill that need if it was put in the @file{common} directory. Of course, we always want more control. This section will show you how to specify the compilation switches that the various tools involved in the building of the executable should use. @cindex command line length Since source names and locations are described into the project file, it is not necessary to use switches on the command line for this purpose (switches such as -I for gcc). This removes a major source of command line length overflow. Clearly, the builders will have to communicate this information one way or another to the underlying compilers and tools they call but they usually use response files for this and thus should not be subject to command line overflows. Several tools are participating to the creation of an executable: the compiler produces object files from the source files; the binder (in the Ada case) creates an source file that takes care, among other things, of elaboration issues and global variables initialization; and the linker gathers everything into a single executable that users can execute. All these tools are known by the project manager and will be called with user defined switches from the project files. However, we need to introduce a new project file concept to express which switches to be used for any of the tools involved in the build. @cindex project file packages A project file is subdivided into zero or more @b{packages}, each of which contains the attributes specific to one tool (or one set of tools). Project files use an Ada-like syntax for packages. Package names permitted in project files are restricted to a predefined set (@pxref{Packages}), and the contents of packages are limited to a small set of constructs and attributes (@pxref{Attributes}). Our example project file can be extended with the following empty packages. At this stage, they could all be omitted since they are empty, but they show which packages would be involved in the build process. @smallexample @b{project} Build @b{is} @b{for} Source_Dirs @b{use} ("common"); @b{for} Object_Dir @b{use} "obj"; @b{for} Exec_Dir @b{use} "."; @b{for} Main @b{use} ("proc.adb"); @b{package} Builder @b{is} --<<< for gnatmake and gprbuild @b{end} Builder; @b{package} Compiler @b{is} --<<< for the compiler @b{end} Compiler; @b{package} Binder @b{is} --<<< for the binder @b{end} Binder; @b{package} Linker @b{is} --<<< for the linker @b{end} Linker; @b{end} Build; @end smallexample @noindent Let's first examine the compiler switches. As stated in the initial description of the example, we want to compile all files with @option{^-O2^-O2^}. This is a compiler switch, although it is usual, on the command line, to pass it to the builder which then passes it to the compiler. It is recommended to use directly the right package, which will make the setup easier to understand for other people. Several attributes can be used to specify the ^switches^switches^: @table @asis @item @b{Default_Switches}: @cindex @code{Default_Switches} This is the first mention in this manual of an @b{indexed attribute}. When this attribute is defined, one must supply an @emph{index} in the form of a literal string. In the case of @emph{Default_Switches}, the index is the name of the language to which the switches apply (since a different compiler will likely be used for each language, and each compiler has its own set of switches). The value of the attribute is a list of switches. In this example, we want to compile all Ada source files with the ^switch^switch^ @option{^-O2^-O2^}, and the resulting project file is as follows (only the @code{Compiler} package is shown): @smallexample @b{package} Compiler @b{is} @b{for} Default_Switches ("Ada") @b{use} ("^-O2^-O2^"); @b{end} Compiler; @end smallexample @item @b{^Switches^Switches^}: @cindex @code{^Switches^Switches^} in some cases, we might want to use specific ^switches^switches^ for one or more files. For instance, compiling @file{proc.adb} might not be possible at high level of optimization because of a compiler issue. In such a case, the @emph{^Switches^Switches^} attribute (indexed on the file name) can be used and will override the switches defined by @emph{Default_Switches}. Our project file would become: @smallexample package Compiler is for Default_Switches ("Ada") use ("^-O2^-O2^"); for ^Switches^Switches^ ("proc.adb") use ("^-O0^-O0^"); end Compiler; @end smallexample @noindent @code{^Switches^Switches^} may take a pattern as an index, such as in: @smallexample package Compiler is for Default_Switches ("Ada") use ("^-O2^-O2^"); for ^Switches^Switches^ ("pkg*") use ("^-O0^-O0^"); end Compiler; @end smallexample @noindent Sources @file{pkg.adb} and @file{pkg-child.adb} would be compiled with ^-O0^-O0^, not ^-O2^-O2^. @noindent @code{^Switches^Switches^} can also be given a language name as index instead of a file name in which case it has the same semantics as @emph{Default_Switches}. However, indexes with wild cards are never valid for language name. @item @b{Local_Configuration_Pragmas}: @cindex @code{Local_Configuration_Pragmas} this attribute may specify the path of a file containing configuration pragmas for use by the Ada compiler, such as @code{pragma Restrictions (No_Tasking)}. These pragmas will be used for all the sources of the project. @end table The switches for the other tools are defined in a similar manner through the @b{Default_Switches} and @b{^Switches^Switches^} attributes, respectively in the @emph{Builder} package (for @command{gnatmake} and @command{gprbuild}), the @emph{Binder} package (binding Ada executables) and the @emph{Linker} package (for linking executables). @c --------------------------------------------- @node Compiling with Project Files @subsection Compiling with Project Files @c --------------------------------------------- @noindent Now that our project files are written, let's build our executable. Here is the command we would use from the command line: @smallexample gnatmake ^-Pbuild^/PROJECT_FILE=build^ @end smallexample @noindent This will automatically build the executables specified through the @emph{Main} attribute: for each, it will compile or recompile the sources for which the object file does not exist or is not up-to-date; it will then run the binder; and finally run the linker to create the executable itself. @command{gnatmake} only knows how to handle Ada files. By using @command{gprbuild} as a builder, you could automatically manage C files the same way: create the file @file{utils.c} in the @file{common} directory, set the attribute @emph{Languages} to @code{"(Ada, C)"}, and run @smallexample gprbuild ^-Pbuild^/PROJECT_FILE=build^ @end smallexample @noindent Gprbuild knows how to recompile the C files and will recompile them only if one of their dependencies has changed. No direct indication on how to build the various elements is given in the project file, which describes the project properties rather than a set of actions to be executed. Here is the invocation of @command{gprbuild} when building a multi-language program: @smallexample $ gprbuild -Pbuild gcc -c proc.adb gcc -c pack.adb gcc -c utils.c gprbind proc ... gcc proc.o -o proc @end smallexample @noindent Notice the three steps described earlier: @itemize @bullet @item The first three gcc commands correspond to the compilation phase. @item The gprbind command corresponds to the post-compilation phase. @item The last gcc command corresponds to the final link. @end itemize @noindent @cindex @option{-v} option (for GPRbuild) The default output of GPRbuild's execution is kept reasonably simple and easy to understand. In particular, some of the less frequently used commands are not shown, and some parameters are abbreviated. So it is not possible to rerun the effect of the @command{gprbuild} command by cut-and-pasting its output. GPRbuild's option @code{-v} provides a much more verbose output which includes, among other information, more complete compilation, post-compilation and link commands. @c --------------------------------------------- @node Executable File Names @subsection Executable File Names @c --------------------------------------------- @noindent @cindex @code{Executable} By default, the executable name corresponding to a main file is computed from the main source file name. Through the attribute @b{Builder.Executable}, it is possible to change this default. For instance, instead of building @command{proc} (or @command{proc.exe} on Windows), we could configure our project file to build "proc1" (resp proc1.exe) with the following addition: @smallexample @c projectfile project Build is ... -- same as before package Builder is for Executable ("proc.adb") use "proc1"; end Builder end Build; @end smallexample @noindent @cindex @code{Executable_Suffix} Attribute @b{Executable_Suffix}, when specified, may change the suffix of the executable files, when no attribute @code{Executable} applies: its value replace the platform-specific executable suffix. The default executable suffix is empty on UNIX and ".exe" on Windows. It is also possible to change the name of the produced executable by using the command line switch @option{-o}. When several mains are defined in the project, it is not possible to use the @option{-o} switch and the only way to change the names of the executable is provided by Attributes @code{Executable} and @code{Executable_Suffix}. @c --------------------------------------------- @node Avoid Duplication With Variables @subsection Avoid Duplication With Variables @c --------------------------------------------- @noindent To illustrate some other project capabilities, here is a slightly more complex project using similar sources and a main program in C: @smallexample @c projectfile project C_Main is for Languages use ("Ada", "C"); for Source_Dirs use ("common"); for Object_Dir use "obj"; for Main use ("main.c"); package Compiler is C_Switches := ("-pedantic"); for Default_Switches ("C") use C_Switches; for Default_Switches ("Ada") use ("^-gnaty^-gnaty^"); for ^Switches^Switches^ ("main.c") use C_Switches & ("-g"); end Compiler; end C_Main; @end smallexample @noindent This project has many similarities with the previous one. As expected, its @code{Main} attribute now refers to a C source. The attribute @emph{Exec_Dir} is now omitted, thus the resulting executable will be put in the directory @file{obj}. The most noticeable difference is the use of a variable in the @emph{Compiler} package to store settings used in several attributes. This avoids text duplication, and eases maintenance (a single place to modify if we want to add new switches for C files). We will revisit the use of variables in the context of scenarios (@pxref{Scenarios in Projects}). In this example, we see how the file @file{main.c} can be compiled with the switches used for all the other C files, plus @option{-g}. In this specific situation the use of a variable could have been replaced by a reference to the @code{Default_Switches} attribute: @smallexample @c projectfile for ^Switches^Switches^ ("c_main.c") use Compiler'Default_Switches ("C") & ("-g"); @end smallexample @noindent Note the tick (@emph{'}) used to refer to attributes defined in a package. Here is the output of the GPRbuild command using this project: @smallexample $gprbuild -Pc_main gcc -c -pedantic -g main.c gcc -c -gnaty proc.adb gcc -c -gnaty pack.adb gcc -c -pedantic utils.c gprbind main.bexch ... gcc main.o -o main @end smallexample @noindent The default switches for Ada sources, the default switches for C sources (in the compilation of @file{lib.c}), and the specific switches for @file{main.c} have all been taken into account. @c --------------------------------------------- @node Naming Schemes @subsection Naming Schemes @c --------------------------------------------- @noindent Sometimes an Ada software system is ported from one compilation environment to another (say GNAT), and the file are not named using the default GNAT conventions. Instead of changing all the file names, which for a variety of reasons might not be possible, you can define the relevant file naming scheme in the @b{Naming} package of your project file. The naming scheme has two distinct goals for the project manager: it allows finding of source files when searching in the source directories, and given a source file name it makes it possible to guess the associated language, and thus the compiler to use. Note that the use by the Ada compiler of pragmas Source_File_Name is not supported when using project files. You must use the features described in this paragraph. You can however specify other configuration pragmas. The following attributes can be defined in package @code{Naming}: @table @asis @item @b{Casing}: @cindex @code{Casing} Its value must be one of @code{"lowercase"} (the default if unspecified), @code{"uppercase"} or @code{"mixedcase"}. It describes the casing of file names with regards to the Ada unit name. Given an Ada unit My_Unit, the file name will respectively be @file{my_unit.adb} (lowercase), @file{MY_UNIT.ADB} (uppercase) or @file{My_Unit.adb} (mixedcase). On Windows, file names are case insensitive, so this attribute is irrelevant. @item @b{Dot_Replacement}: @cindex @code{Dot_Replacement} This attribute specifies the string that should replace the "." in unit names. Its default value is @code{"-"} so that a unit @code{Parent.Child} is expected to be found in the file @file{parent-child.adb}. The replacement string must satisfy the following requirements to avoid ambiguities in the naming scheme: @itemize - @item It must not be empty @item It cannot start or end with an alphanumeric character @item It cannot be a single underscore @item It cannot start with an underscore followed by an alphanumeric @item It cannot contain a dot @code{'.'} except if the entire string is @code{"."} @end itemize @item @b{Spec_Suffix} and @b{Specification_Suffix}: @cindex @code{Spec_Suffix} @cindex @code{Specification_Suffix} For Ada, these attributes give the suffix used in file names that contain specifications. For other languages, they give the extension for files that contain declaration (header files in C for instance). The attribute is indexed on the language. The two attributes are equivalent, but the latter is obsolescent. If the value of the attribute is the empty string, it indicates to the Project Manager that the only specifications/header files for the language are those specified with attributes @code{Spec} or @code{Specification_Exceptions}. If @code{Spec_Suffix ("Ada")} is not specified, then the default is @code{"^.ads^.ADS^"}. A non empty value must satisfy the following requirements: @itemize - @item It must include at least one dot @item If @code{Dot_Replacement} is a single dot, then it cannot include more than one dot. @end itemize @item @b{Body_Suffix} and @b{Implementation_Suffix}: @cindex @code{Body_Suffix} @cindex @code{Implementation_Suffix} These attributes give the extension used for file names that contain code (bodies in Ada). They are indexed on the language. The second version is obsolescent and fully replaced by the first attribute. For each language of a project, one of these two attributes need to be specified, either in the project itself or in the configuration project file. If the value of the attribute is the empty string, it indicates to the Project Manager that the only source files for the language are those specified with attributes @code{Body} or @code{Implementation_Exceptions}. These attributes must satisfy the same requirements as @code{Spec_Suffix}. In addition, they must be different from any of the values in @code{Spec_Suffix}. If @code{Body_Suffix ("Ada")} is not specified, then the default is @code{"^.adb^.ADB^"}. If @code{Body_Suffix ("Ada")} and @code{Spec_Suffix ("Ada")} end with the same string, then a file name that ends with the longest of these two suffixes will be a body if the longest suffix is @code{Body_Suffix ("Ada")} or a spec if the longest suffix is @code{Spec_Suffix ("Ada")}. If the suffix does not start with a '.', a file with a name exactly equal to the suffix will also be part of the project (for instance if you define the suffix as @code{Makefile.in}, a file called @file{Makefile.in} will be part of the project. This capability is usually not interesting when building. However, it might become useful when a project is also used to find the list of source files in an editor, like the GNAT Programming System (GPS). @item @b{Separate_Suffix}: @cindex @code{Separate_Suffix} This attribute is specific to Ada. It denotes the suffix used in file names that contain separate bodies. If it is not specified, then it defaults to same value as @code{Body_Suffix ("Ada")}. The value of this attribute cannot be the empty string. Otherwise, the same rules apply as for the @code{Body_Suffix} attribute. The only accepted index is "Ada". @item @b{Spec} or @b{Specification}: @cindex @code{Spec} @cindex @code{Specification} This attribute @code{Spec} can be used to define the source file name for a given Ada compilation unit's spec. The index is the literal name of the Ada unit (case insensitive). The value is the literal base name of the file that contains this unit's spec (case sensitive or insensitive depending on the operating system). This attribute allows the definition of exceptions to the general naming scheme, in case some files do not follow the usual convention. When a source file contains several units, the relative position of the unit can be indicated. The first unit in the file is at position 1 @smallexample @c projectfile for Spec ("MyPack.MyChild") use "mypack.mychild.spec"; for Spec ("top") use "foo.a" at 1; for Spec ("foo") use "foo.a" at 2; @end smallexample @item @b{Body} or @b{Implementation}: @cindex @code{Body} @cindex @code{Implementation} These attribute play the same role as @emph{Spec} for Ada bodies. @item @b{Specification_Exceptions} and @b{Implementation_Exceptions}: @cindex @code{Specification_Exceptions} @cindex @code{Implementation_Exceptions} These attributes define exceptions to the naming scheme for languages other than Ada. They are indexed on the language name, and contain a list of file names respectively for headers and source code. @end table @ifclear vms For example, the following package models the Apex file naming rules: @smallexample @c projectfile @group package Naming is for Casing use "lowercase"; for Dot_Replacement use "."; for Spec_Suffix ("Ada") use ".1.ada"; for Body_Suffix ("Ada") use ".2.ada"; end Naming; @end group @end smallexample @end ifclear @ifset vms For example, the following package models the DEC Ada file naming rules: @smallexample @c projectfile @group package Naming is for Casing use "lowercase"; for Dot_Replacement use "__"; for Spec_Suffix ("Ada") use "_.ada"; for Body_Suffix ("Ada") use ".ada"; end Naming; @end group @end smallexample @noindent (Note that @code{Casing} is @code{"lowercase"} because GNAT gets the file names in lower case) @end ifset @c --------------------------------------------- @node Installation @subsection Installation @c --------------------------------------------- @noindent After building an application or a library it is often required to install it into the development environment. For instance this step is required if the library is to be used by another application. The @command{gprinstall} tool provides an easy way to install libraries, executable or object code generated during the build. The @b{Install} package can be used to change the default locations. The following attributes can be defined in package @code{Install}: @table @asis @item @b{Active} Whether the project is to be installed, values are @code{true} (default) or @code{false}. @item @b{Artifacts} @cindex @code{Artifacts} An array attribute to declare a set of files not part of the sources to be installed. The array discriminant is the directory where the file is to be installed. If a relative directory then Prefix (see below) is prepended. @item @b{Prefix}: @cindex @code{Prefix} Root directory for the installation. @item @b{Exec_Subdir} Subdirectory of @b{Prefix} where executables are to be installed. Default is @b{bin}. @item @b{Lib_Subdir} Subdirectory of @b{Prefix} where directory with the library or object files is to be installed. Default is @b{lib}. @item @b{Sources_Subdir} Subdirectory of @b{Prefix} where directory with sources is to be installed. Default is @b{include}. @item @b{Project_Subdir} Subdirectory of @b{Prefix} where the generated project file is to be installed. Default is @b{share/gpr}. @end table @c --------------------------------------------- @node Distributed support @subsection Distributed support @c --------------------------------------------- @noindent For large projects the compilation time can become a limitation in the development cycle. To cope with that, GPRbuild supports distributed compilation. The following attributes can be defined in package @code{Remote}: @table @asis @item @b{Root_Dir}: @cindex @code{Root_Dir} Root directory of the project's sources. The default value is the project's directory. @end table @c --------------------------------------------- @node Organizing Projects into Subsystems @section Organizing Projects into Subsystems @c --------------------------------------------- @noindent A @b{subsystem} is a coherent part of the complete system to be built. It is represented by a set of sources and one single object directory. A system can be composed of a single subsystem when it is simple as we have seen in the first section. Complex systems are usually composed of several interdependent subsystems. A subsystem is dependent on another subsystem if knowledge of the other one is required to build it, and in particular if visibility on some of the sources of this other subsystem is required. Each subsystem is usually represented by its own project file. In this section, the previous example is being extended. Let's assume some sources of our @code{Build} project depend on other sources. For instance, when building a graphical interface, it is usual to depend upon a graphical library toolkit such as GtkAda. Furthermore, we also need sources from a logging module we had previously written. @menu * Project Dependencies:: * Cyclic Project Dependencies:: * Sharing Between Projects:: * Global Attributes:: @end menu @c --------------------------------------------- @node Project Dependencies @subsection Project Dependencies @c --------------------------------------------- @noindent GtkAda comes with its own project file (appropriately called @file{gtkada.gpr}), and we will assume we have already built a project called @file{logging.gpr} for the logging module. With the information provided so far in @file{build.gpr}, building the application would fail with an error indicating that the gtkada and logging units that are relied upon by the sources of this project cannot be found. This is easily solved by adding the following @b{with} clauses at the beginning of our project: @smallexample @c projectfile with "gtkada.gpr"; with "a/b/logging.gpr"; project Build is ... -- as before end Build; @end smallexample @noindent @cindex @code{Externally_Built} When such a project is compiled, @command{gnatmake} will automatically check the other projects and recompile their sources when needed. It will also recompile the sources from @code{Build} when needed, and finally create the executable. In some cases, the implementation units needed to recompile a project are not available, or come from some third-party and you do not want to recompile it yourself. In this case, the attribute @b{Externally_Built} to "true" can be set, indicating to the builder that this project can be assumed to be up-to-date, and should not be considered for recompilation. In Ada, if the sources of this externally built project were compiled with another version of the compiler or with incompatible options, the binder will issue an error. The project's @code{with} clause has several effects. It provides source visibility between projects during the compilation process. It also guarantees that the necessary object files from @code{Logging} and @code{GtkAda} are available when linking @code{Build}. As can be seen in this example, the syntax for importing projects is similar to the syntax for importing compilation units in Ada. However, project files use literal strings instead of names, and the @code{with} clause identifies project files rather than packages. Each literal string after @code{with} is the path (absolute or relative) to a project file. The @code{.gpr} extension is optional, although we recommend adding it. If no extension is specified, and no project file with the @file{^.gpr^.GPR^} extension is found, then the file is searched for exactly as written in the @code{with} clause, that is with no extension. As mentioned above, the path after a @code{with} has to be a literal string, and you cannot use concatenation, or lookup the value of external variables to change the directories from which a project is loaded. A solution if you need something like this is to use aggregate projects (@pxref{Aggregate Projects}). @cindex project path When a relative path or a base name is used, the project files are searched relative to each of the directories in the @b{project path}. This path includes all the directories found with the following algorithm, in that order, as soon as a matching file is found, the search stops: @itemize @bullet @item First, the file is searched relative to the directory that contains the current project file. @item @cindex @code{GPR_PROJECT_PATH_FILE} @cindex @code{GPR_PROJECT_PATH} @cindex @code{ADA_PROJECT_PATH} Then it is searched relative to all the directories specified in the ^environment variables^logical names^ @b{GPR_PROJECT_PATH_FILE}, @b{GPR_PROJECT_PATH} and @b{ADA_PROJECT_PATH} (in that order) if they exist. The value of @b{GPR_PROJECT_PATH_FILE}, when defined, is the path name of a text file that contains project directory path names, one per line. @b{GPR_PROJECT_PATH} and @b{ADA_PROJECT_PATH}, when defined, contain project directory path names separated by directory separators. @b{ADA_PROJECT_PATH} is used for compatibility, it is recommended to use @b{GPR_PROJECT_PATH_FILE} or @b{GPR_PROJECT_PATH}. @item Finally, it is searched relative to the default project directories. Such directories depends on the tool used. The different locations searched in the specified order are: @itemize @bullet @item @file{//lib/gnat} (for @command{gnatmake} in all cases, and for @command{gprbuild} if option @option{--target} is specified) @item @file{//share/gpr} (for @command{gnatmake} in all cases, and for @command{gprbuild} if option @option{--target} is specified) @item @file{/share/gpr/} (for @command{gnatmake} and @command{gprbuild}) @item @file{/lib/gnat/} (for @command{gnatmake} and @command{gprbuild}) @end itemize In our example, @file{gtkada.gpr} is found in the predefined directory if it was installed at the same root as GNAT. @end itemize @noindent Some tools also support extending the project path from the command line, generally through the @option{-aP}. You can see the value of the project path by using the @command{gnatls -v} command. Any symbolic link will be fully resolved in the directory of the importing project file before the imported project file is examined. Any source file in the imported project can be used by the sources of the importing project, transitively. Thus if @code{A} imports @code{B}, which imports @code{C}, the sources of @code{A} may depend on the sources of @code{C}, even if @code{A} does not import @code{C} explicitly. However, this is not recommended, because if and when @code{B} ceases to import @code{C}, some sources in @code{A} will no longer compile. @command{gprbuild} has a switch @option{--no-indirect-imports} that will report such indirect dependencies. One very important aspect of a project hierarchy is that @b{a given source can only belong to one project} (otherwise the project manager would not know which settings apply to it and when to recompile it). It means that different project files do not usually share source directories or when they do, they need to specify precisely which project owns which sources using attribute @code{Source_Files} or equivalent. By contrast, 2 projects can each own a source with the same base file name as long as they live in different directories. The latter is not true for Ada Sources because of the correlation between source files and Ada units. @c --------------------------------------------- @node Cyclic Project Dependencies @subsection Cyclic Project Dependencies @c --------------------------------------------- @noindent Cyclic dependencies are mostly forbidden: if @code{A} imports @code{B} (directly or indirectly) then @code{B} is not allowed to import @code{A}. However, there are cases when cyclic dependencies would be beneficial. For these cases, another form of import between projects exists: the @b{limited with}. A project @code{A} that imports a project @code{B} with a straight @code{with} may also be imported, directly or indirectly, by @code{B} through a @code{limited with}. The difference between straight @code{with} and @code{limited with} is that the name of a project imported with a @code{limited with} cannot be used in the project importing it. In particular, its packages cannot be renamed and its variables cannot be referred to. @smallexample @c 0projectfile with "b.gpr"; with "c.gpr"; project A is For Exec_Dir use B'Exec_Dir; -- ok end A; limited with "a.gpr"; -- Cyclic dependency: A -> B -> A project B is For Exec_Dir use A'Exec_Dir; -- not ok end B; with "d.gpr"; project C is end C; limited with "a.gpr"; -- Cyclic dependency: A -> C -> D -> A project D is For Exec_Dir use A'Exec_Dir; -- not ok end D; @end smallexample @c --------------------------------------------- @node Sharing Between Projects @subsection Sharing Between Projects @c --------------------------------------------- @noindent When building an application, it is common to have similar needs in several of the projects corresponding to the subsystems under construction. For instance, they will all have the same compilation switches. As seen before (@pxref{Tools Options in Project Files}), setting compilation switches for all sources of a subsystem is simple: it is just a matter of adding a @code{Compiler.Default_Switches} attribute to each project files with the same value. Of course, that means duplication of data, and both places need to be changed in order to recompile the whole application with different switches. It can become a real problem if there are many subsystems and thus many project files to edit. There are two main approaches to avoiding this duplication: @itemize @bullet @item Since @file{build.gpr} imports @file{logging.gpr}, we could change it to reference the attribute in Logging, either through a package renaming, or by referencing the attribute. The following example shows both cases: @smallexample @c projectfile project Logging is package Compiler is for ^Switches^Switches^ ("Ada") use ("^-O2^-O2^"); end Compiler; package Binder is for ^Switches^Switches^ ("Ada") use ("-E"); end Binder; end Logging; with "logging.gpr"; project Build is package Compiler renames Logging.Compiler; package Binder is for ^Switches^Switches^ ("Ada") use Logging.Binder'Switches ("Ada"); end Binder; end Build; @end smallexample @noindent The solution used for @code{Compiler} gets the same value for all attributes of the package, but you cannot modify anything from the package (adding extra switches or some exceptions). The second version is more flexible, but more verbose. If you need to refer to the value of a variable in an imported project, rather than an attribute, the syntax is similar but uses a "." rather than an apostrophe. For instance: @smallexample @c projectfile with "imported"; project Main is Var1 := Imported.Var; end Main; @end smallexample @item The second approach is to define the switches in a third project. That project is setup without any sources (so that, as opposed to the first example, none of the project plays a special role), and will only be used to define the attributes. Such a project is typically called @file{shared.gpr}. @smallexample @c projectfile abstract project Shared is for Source_Files use (); -- no sources package Compiler is for ^Switches^Switches^ ("Ada") use ("^-O2^-O2^"); end Compiler; end Shared; with "shared.gpr"; project Logging is package Compiler renames Shared.Compiler; end Logging; with "shared.gpr"; project Build is package Compiler renames Shared.Compiler; end Build; @end smallexample @noindent As for the first example, we could have chosen to set the attributes one by one rather than to rename a package. The reason we explicitly indicate that @code{Shared} has no sources is so that it can be created in any directory and we are sure it shares no sources with @code{Build} or @code{Logging}, which of course would be invalid. @cindex project qualifier Note the additional use of the @b{abstract} qualifier in @file{shared.gpr}. This qualifier is optional, but helps convey the message that we do not intend this project to have sources (@pxref{Qualified Projects} for more qualifiers). @end itemize @c --------------------------------------------- @node Global Attributes @subsection Global Attributes @c --------------------------------------------- @noindent We have already seen many examples of attributes used to specify a special option of one of the tools involved in the build process. Most of those attributes are project specific. That it to say, they only affect the invocation of tools on the sources of the project where they are defined. There are a few additional attributes that apply to all projects in a hierarchy as long as they are defined on the "main" project. The main project is the project explicitly mentioned on the command-line. The project hierarchy is the "with"-closure of the main project. Here is a list of commonly used global attributes: @table @asis @item @b{Builder.Global_Configuration_Pragmas}: @cindex @code{Global_Configuration_Pragmas} This attribute points to a file that contains configuration pragmas to use when building executables. These pragmas apply for all executables built from this project hierarchy. As we have seen before, additional pragmas can be specified on a per-project basis by setting the @code{Compiler.Local_Configuration_Pragmas} attribute. @item @b{Builder.Global_Compilation_Switches}: @cindex @code{Global_Compilation_Switches} This attribute is a list of compiler switches to use when compiling any source file in the project hierarchy. These switches are used in addition to the ones defined in the @code{Compiler} package, which only apply to the sources of the corresponding project. This attribute is indexed on the name of the language. @end table Using such global capabilities is convenient. It can also lead to unexpected behavior. Especially when several subsystems are shared among different main projects and the different global attributes are not compatible. Note that using aggregate projects can be a safer and more powerful replacement to global attributes. @c --------------------------------------------- @node Scenarios in Projects @section Scenarios in Projects @c --------------------------------------------- @noindent Various aspects of the projects can be modified based on @b{scenarios}. These are user-defined modes that change the behavior of a project. Typical examples are the setup of platform-specific compiler options, or the use of a debug and a release mode (the former would activate the generation of debug information, when the second will focus on improving code optimization). Let's enhance our example to support a debug and a release modes.The issue is to let the user choose what kind of system he is building: use @option{-g} as compiler switches in debug mode and @option{^-O2^-O2^} in release mode. We will also setup the projects so that we do not share the same object directory in both modes, otherwise switching from one to the other might trigger more recompilations than needed or mix objects from the 2 modes. One naive approach is to create two different project files, say @file{build_debug.gpr} and @file{build_release.gpr}, that set the appropriate attributes as explained in previous sections. This solution does not scale well, because in presence of multiple projects depending on each other, you will also have to duplicate the complete hierarchy and adapt the project files to point to the right copies. @cindex scenarios Instead, project files support the notion of scenarios controlled by external values. Such values can come from several sources (in decreasing order of priority): @table @asis @item @b{Command line}: @cindex @option{-X} When launching @command{gnatmake} or @command{gprbuild}, the user can pass extra @option{-X} switches to define the external value. In our case, the command line might look like @smallexample gnatmake -Pbuild.gpr -Xmode=debug or gnatmake -Pbuild.gpr -Xmode=release @end smallexample @item @b{^Environment variables^Logical names^}: When the external value does not come from the command line, it can come from the value of ^environment variables^logical names^ of the appropriate name. In our case, if ^an environment variable^a logical name^ called "mode" exist, its value will be taken into account. @item @b{External function second parameter} @end table @cindex @code{external} We now need to get that value in the project. The general form is to use the predefined function @b{external} which returns the current value of the external. For instance, we could setup the object directory to point to either @file{obj/debug} or @file{obj/release} by changing our project to @smallexample @c projectfile project Build is for Object_Dir use "obj/" & external ("mode", "debug"); ... -- as before end Build; @end smallexample @noindent The second parameter to @code{external} is optional, and is the default value to use if "mode" is not set from the command line or the environment. In order to set the switches according to the different scenarios, other constructs have to be introduced such as typed variables and case constructions. @cindex typed variable @cindex case construction A @b{typed variable} is a variable that can take only a limited number of values, similar to an enumeration in Ada. Such a variable can then be used in a @b{case construction} and create conditional sections in the project. The following example shows how this can be done: @smallexample @c projectfile project Build is type Mode_Type is ("debug", "release"); -- all possible values Mode : Mode_Type := external ("mode", "debug"); -- a typed variable package Compiler is case Mode is when "debug" => for ^Switches^Switches^ ("Ada") use ("-g"); when "release" => for ^Switches^Switches^ ("Ada") use ("^-O2^-O2^"); end case; end Compiler; end Build; @end smallexample @noindent The project has suddenly grown in size, but has become much more flexible. @code{Mode_Type} defines the only valid values for the @code{mode} variable. If any other value is read from the environment, an error is reported and the project is considered as invalid. The @code{Mode} variable is initialized with an external value defaulting to @code{"debug"}. This default could be omitted and that would force the user to define the value. Finally, we can use a case construction to set the switches depending on the scenario the user has chosen. Most aspects of the projects can depend on scenarios. The notable exception are project dependencies (@code{with} clauses), which may not depend on a scenario. Scenarios work the same way with @b{project hierarchies}: you can either duplicate a variable similar to @code{Mode} in each of the project (as long as the first argument to @code{external} is always the same and the type is the same), or simply set the variable in the @file{shared.gpr} project (@pxref{Sharing Between Projects}). @c --------------------------------------------- @node Library Projects @section Library Projects @c --------------------------------------------- @noindent So far, we have seen examples of projects that create executables. However, it is also possible to create libraries instead. A @b{library} is a specific type of subsystem where, for convenience, objects are grouped together using system-specific means such as archives or windows DLLs. Library projects provide a system- and language-independent way of building both @b{static} and @b{dynamic} libraries. They also support the concept of @b{standalone libraries} (SAL) which offers two significant properties: the elaboration (e.g. initialization) of the library is either automatic or very simple; a change in the implementation part of the library implies minimal post-compilation actions on the complete system and potentially no action at all for the rest of the system in the case of dynamic SALs. There is a restriction on shared library projects: by default, they are only allowed to import other shared library projects. They are not allowed to import non library projects or static library projects. The GNAT Project Manager takes complete care of the library build, rebuild and installation tasks, including recompilation of the source files for which objects do not exist or are not up to date, assembly of the library archive, and installation of the library (i.e., copying associated source, object and @file{ALI} files to the specified location). @menu * Building Libraries:: * Using Library Projects:: * Stand-alone Library Projects:: * Installing a library with project files:: @end menu @c --------------------------------------------- @node Building Libraries @subsection Building Libraries @c --------------------------------------------- @noindent Let's enhance our example and transform the @code{logging} subsystem into a library. In order to do so, a few changes need to be made to @file{logging.gpr}. A number of specific attributes needs to be defined: at least @code{Library_Name} and @code{Library_Dir}; in addition, a number of other attributes can be used to specify specific aspects of the library. For readability, it is also recommended (although not mandatory), to use the qualifier @code{library} in front of the @code{project} keyword. @table @asis @item @b{Library_Name}: @cindex @code{Library_Name} This attribute is the name of the library to be built. There is no restriction on the name of a library imposed by the project manager, except for stand-alone libraries whose names must follow the syntax of Ada identifiers; however, there may be system specific restrictions on the name. In general, it is recommended to stick to alphanumeric characters (and possibly single underscores) to help portability. @item @b{Library_Dir}: @cindex @code{Library_Dir} This attribute is the path (absolute or relative) of the directory where the library is to be installed. In the process of building a library, the sources are compiled, the object files end up in the explicit or implicit @code{Object_Dir} directory. When all sources of a library are compiled, some of the compilation artifacts, including the library itself, are copied to the library_dir directory. This directory must exists and be writable. It must also be different from the object directory so that cleanup activities in the Library_Dir do not affect recompilation needs. @end table Here is the new version of @file{logging.gpr} that makes it a library: @smallexample @c projectfile library project Logging is -- "library" is optional for Library_Name use "logging"; -- will create "liblogging.a" on Unix for Object_Dir use "obj"; for Library_Dir use "lib"; -- different from object_dir end Logging; @end smallexample @noindent Once the above two attributes are defined, the library project is valid and is enough for building a library with default characteristics. Other library-related attributes can be used to change the defaults: @table @asis @item @b{Library_Kind}: @cindex @code{Library_Kind} The value of this attribute must be either @code{"static"}, @code{"dynamic"} or @code{"relocatable"} (the latter is a synonym for dynamic). It indicates which kind of library should be built (the default is to build a static library, that is an archive of object files that can potentially be linked into a static executable). When the library is set to be dynamic, a separate image is created that will be loaded independently, usually at the start of the main program execution. Support for dynamic libraries is very platform specific, for instance on Windows it takes the form of a DLL while on GNU/Linux, it is a dynamic elf image whose suffix is usually @file{.so}. Library project files, on the other hand, can be written in a platform independent way so that the same project file can be used to build a library on different operating systems. If you need to build both a static and a dynamic library, it is recommended use two different object directories, since in some cases some extra code needs to be generated for the latter. For such cases, one can either define two different project files, or a single one which uses scenarios to indicate the various kinds of library to be built and their corresponding object_dir. @cindex @code{Library_ALI_Dir} @item @b{Library_ALI_Dir}: This attribute may be specified to indicate the directory where the ALI files of the library are installed. By default, they are copied into the @code{Library_Dir} directory, but as for the executables where we have a separate @code{Exec_Dir} attribute, you might want to put them in a separate directory since there can be hundreds of them. The same restrictions as for the @code{Library_Dir} attribute apply. @cindex @code{Library_Version} @item @b{Library_Version}: This attribute is platform dependent, and has no effect on VMS and Windows. On Unix, it is used only for dynamic libraries as the internal name of the library (the @code{"soname"}). If the library file name (built from the @code{Library_Name}) is different from the @code{Library_Version}, then the library file will be a symbolic link to the actual file whose name will be @code{Library_Version}. This follows the usual installation schemes for dynamic libraries on many Unix systems. @smallexample @c projectfile @group project Logging is Version := "1"; for Library_Dir use "lib"; for Library_Name use "logging"; for Library_Kind use "dynamic"; for Library_Version use "liblogging.so." & Version; end Logging; @end group @end smallexample @noindent After the compilation, the directory @file{lib} will contain both a @file{libdummy.so.1} library and a symbolic link to it called @file{libdummy.so}. @cindex @code{Library_GCC} @item @b{Library_GCC}: This attribute is the name of the tool to use instead of "gcc" to link shared libraries. A common use of this attribute is to define a wrapper script that accomplishes specific actions before calling gcc (which itself is calling the linker to build the library image). @item @b{Library_Options}: @cindex @code{Library_Options} This attribute may be used to specify additional switches (last switches) when linking a shared library. @item @b{Leading_Library_Options}: @cindex @code{Leading_Library_Options} This attribute, that is taken into account only by @command{gprbuild}, may be used to specified leading options (first switches) when linking a shared library. @cindex @code{Linker_Options} @item @b{Linker.Linker_Options}: This attribute specifies additional switches to be given to the linker when linking an executable. It is ignored when defined in the main project and taken into account in all other projects that are imported directly or indirectly. These switches complement the @code{Linker.Switches} defined in the main project. This is useful when a particular subsystem depends on an external library: adding this dependency as a @code{Linker_Options} in the project of the subsystem is more convenient than adding it to all the @code{Linker.Switches} of the main projects that depend upon this subsystem. @end table @c --------------------------------------------- @node Using Library Projects @subsection Using Library Projects @c --------------------------------------------- @noindent When the builder detects that a project file is a library project file, it recompiles all sources of the project that need recompilation and rebuild the library if any of the sources have been recompiled. It then groups all object files into a single file, which is a shared or a static library. This library can later on be linked with multiple executables. Note that the use of shard libraries reduces the size of the final executable and can also reduce the memory footprint at execution time when the library is shared among several executables. It is also possible to build @b{multi-language libraries}. When using @command{gprbuild} as a builder, multi-language library projects allow naturally the creation of multi-language libraries . @command{gnatmake}, does not try to compile non Ada sources. However, when the project is multi-language, it will automatically link all object files found in the object directory, whether or not they were compiled from an Ada source file. This specific behavior does not apply to Ada-only projects which only take into account the objects corresponding to the sources of the project. A non-library project can import a library project. When the builder is invoked on the former, the library of the latter is only rebuilt when absolutely necessary. For instance, if a unit of the library is not up-to-date but non of the executables need this unit, then the unit is not recompiled and the library is not reassembled. For instance, let's assume in our example that logging has the following sources: @file{log1.ads}, @file{log1.adb}, @file{log2.ads} and @file{log2.adb}. If @file{log1.adb} has been modified, then the library @file{liblogging} will be rebuilt when compiling all the sources of @code{Build} only if @file{proc.ads}, @file{pack.ads} or @file{pack.adb} include a @code{"with Log1"}. To ensure that all the sources in the @code{Logging} library are up to date, and that all the sources of @code{Build} are also up to date, the following two commands needs to be used: @smallexample gnatmake -Plogging.gpr gnatmake -Pbuild.gpr @end smallexample @noindent All @file{ALI} files will also be copied from the object directory to the library directory. To build executables, @command{gnatmake} will use the library rather than the individual object files. @ifclear vms Library projects can also be useful to describe a library that need to be used but, for some reason, cannot be rebuilt. For instance, it is the case when some of the library sources are not available. Such library projects need simply to use the @code{Externally_Built} attribute as in the example below: @smallexample @c projectfile library project Extern_Lib is for Languages use ("Ada", "C"); for Source_Dirs use ("lib_src"); for Library_Dir use "lib2"; for Library_Kind use "dynamic"; for Library_Name use "l2"; for Externally_Built use "true"; -- <<<< end Extern_Lib; @end smallexample @noindent In the case of externally built libraries, the @code{Object_Dir} attribute does not need to be specified because it will never be used. The main effect of using such an externally built library project is mostly to affect the linker command in order to reference the desired library. It can also be achieved by using @code{Linker.Linker_Options} or @code{Linker.Switches} in the project corresponding to the subsystem needing this external library. This latter method is more straightforward in simple cases but when several subsystems depend upon the same external library, finding the proper place for the @code{Linker.Linker_Options} might not be easy and if it is not placed properly, the final link command is likely to present ordering issues. In such a situation, it is better to use the externally built library project so that all other subsystems depending on it can declare this dependency thanks to a project @code{with} clause, which in turn will trigger the builder to find the proper order of libraries in the final link command. @end ifclear @c --------------------------------------------- @node Stand-alone Library Projects @subsection Stand-alone Library Projects @c --------------------------------------------- @noindent @cindex standalone libraries A @b{stand-alone library} is a library that contains the necessary code to elaborate the Ada units that are included in the library. A stand-alone library is a convenient way to add an Ada subsystem to a more global system whose main is not in Ada since it makes the elaboration of the Ada part mostly transparent. However, stand-alone libraries are also useful when the main is in Ada: they provide a means for minimizing relinking & redeployment of complex systems when localized changes are made. The name of a stand-alone library, specified with attribute @code{Library_Name}, must have the syntax of an Ada identifier. The most prominent characteristic of a stand-alone library is that it offers a distinction between interface units and implementation units. Only the former are visible to units outside the library. A stand-alone library project is thus characterised by a third attribute, usually @b{Library_Interface}, in addition to the two attributes that make a project a Library Project (@code{Library_Name} and @code{Library_Dir}). This third attribute may also be @b{Interfaces}. @b{Library_Interface} only works when the interface is in Ada and takes a list of units as parameter. @b{Interfaces} works for any supported language and takes a list of sources as parameter. @table @asis @item @b{Library_Interface}: @cindex @code{Library_Interface} This attribute defines an explicit subset of the units of the project. Units from projects importing this library project may only "with" units whose sources are listed in the @code{Library_Interface}. Other sources are considered implementation units. @smallexample @c projectfile @group for Library_Dir use "lib"; for Library_Name use "loggin"; for Library_Interface use ("lib1", "lib2"); -- unit names @end group @end smallexample @item @b{Interfaces} This attribute defines an explicit subset of the source files of a project. Sources from projects importing this project, can only depend on sources from this subset. This attribute can be used on non library projects. It can also be used as a replacement for attribute @code{Library_Interface}, in which case, units have to be replaced by source files. For multi-language library projects, it is the only way to make the project a Stand-Alone Library project whose interface is not purely Ada. @item @b{Library_Standalone}: @cindex @code{Library_Standalone} This attribute defines the kind of standalone library to build. Values are either @code{standard} (the default), @code{no} or @code{encapsulated}. When @code{standard} is used the code to elaborate and finalize the library is embedded, when @code{encapsulated} is used the library can furthermore only depends on static libraries (including the GNAT runtime). This attribute can be set to @code{no} to make it clear that the library should not be standalone in which case the @code{Library_Interface} should not defined. Note that this attribute only applies to shared libraries, so @code{Library_Kind} must be set to @code{dynamic}. @smallexample @c projectfile @group for Library_Dir use "lib"; for Library_Name use "loggin"; for Library_Kind use "dynamic"; for Library_Interface use ("lib1", "lib2"); -- unit names for Library_Standalone use "encapsulated"; @end group @end smallexample @end table In order to include the elaboration code in the stand-alone library, the binder is invoked on the closure of the library units creating a package whose name depends on the library name (^b~logging.ads/b^B$LOGGING.ADS/B^ in the example). This binder-generated package includes @b{initialization} and @b{finalization} procedures whose names depend on the library name (@code{logginginit} and @code{loggingfinal} in the example). The object corresponding to this package is included in the library. @table @asis @item @b{Library_Auto_Init}: @cindex @code{Library_Auto_Init} A dynamic stand-alone Library is automatically initialized if automatic initialization of Stand-alone Libraries is supported on the platform and if attribute @b{Library_Auto_Init} is not specified or is specified with the value "true". A static Stand-alone Library is never automatically initialized. Specifying "false" for this attribute prevent automatic initialization. When a non-automatically initialized stand-alone library is used in an executable, its initialization procedure must be called before any service of the library is used. When the main subprogram is in Ada, it may mean that the initialization procedure has to be called during elaboration of another package. @item @b{Library_Dir}: @cindex @code{Library_Dir} For a stand-alone library, only the @file{ALI} files of the interface units (those that are listed in attribute @code{Library_Interface}) are copied to the library directory. As a consequence, only the interface units may be imported from Ada units outside of the library. If other units are imported, the binding phase will fail. @item @b{Binder.Default_Switches}: When a stand-alone library is bound, the switches that are specified in the attribute @b{Binder.Default_Switches ("Ada")} are used in the call to @command{gnatbind}. @item @b{Library_Src_Dir}: @cindex @code{Library_Src_Dir} This attribute defines the location (absolute or relative to the project directory) where the sources of the interface units are copied at installation time. These sources includes the specs of the interface units along with the closure of sources necessary to compile them successfully. That may include bodies and subunits, when pragmas @code{Inline} are used, or when there is a generic units in the spec. This directory cannot point to the object directory or one of the source directories, but it can point to the library directory, which is the default value for this attribute. @item @b{Library_Symbol_Policy}: @cindex @code{Library_Symbol_Policy} This attribute controls the export of symbols and, on some platforms (like VMS) that have the notions of major and minor IDs built in the library files, it controls the setting of these IDs. It is not supported on all platforms (where it will just have no effect). It may have one of the following values: @itemize - @item @code{"autonomous"} or @code{"default"}: exported symbols are not controlled @item @code{"compliant"}: if attribute @b{Library_Reference_Symbol_File} is not defined, then it is equivalent to policy "autonomous". If there are exported symbols in the reference symbol file that are not in the object files of the interfaces, the major ID of the library is increased. If there are symbols in the object files of the interfaces that are not in the reference symbol file, these symbols are put at the end of the list in the newly created symbol file and the minor ID is increased. @item @code{"controlled"}: the attribute @b{Library_Reference_Symbol_File} must be defined. The library will fail to build if the exported symbols in the object files of the interfaces do not match exactly the symbol in the symbol file. @item @code{"restricted"}: The attribute @b{Library_Symbol_File} must be defined. The library will fail to build if there are symbols in the symbol file that are not in the exported symbols of the object files of the interfaces. Additional symbols in the object files are not added to the symbol file. @item @code{"direct"}: The attribute @b{Library_Symbol_File} must be defined and must designate an existing file in the object directory. This symbol file is passed directly to the underlying linker without any symbol processing. @end itemize @item @b{Library_Reference_Symbol_File} @cindex @code{Library_Reference_Symbol_File} This attribute may define the path name of a reference symbol file that is read when the symbol policy is either "compliant" or "controlled", on platforms that support symbol control, such as VMS, when building a stand-alone library. The path may be an absolute path or a path relative to the project directory. @item @b{Library_Symbol_File} @cindex @code{Library_Symbol_File} This attribute may define the name of the symbol file to be created when building a stand-alone library when the symbol policy is either "compliant", "controlled" or "restricted", on platforms that support symbol control, such as VMS. When symbol policy is "direct", then a file with this name must exist in the object directory. @end table @c --------------------------------------------- @node Installing a library with project files @subsection Installing a library with project files @c --------------------------------------------- @noindent When using project files, a usable version of the library is created in the directory specified by the @code{Library_Dir} attribute of the library project file. Thus no further action is needed in order to make use of the libraries that are built as part of the general application build. You may want to install a library in a context different from where the library is built. This situation arises with third party suppliers, who may want to distribute a library in binary form where the user is not expected to be able to recompile the library. The simplest option in this case is to provide a project file slightly different from the one used to build the library, by using the @code{externally_built} attribute. @ref{Using Library Projects} Another option is to use @command{gprinstall} to install the library in a different context than the build location. A project to use this library is generated automatically by @command{gprinstall} which also copy, in the install location, the minimum set of sources needed to use the library. @ref{Installation} @c --------------------------------------------- @node Project Extension @section Project Extension @c --------------------------------------------- @noindent During development of a large system, it is sometimes necessary to use modified versions of some of the source files, without changing the original sources. This can be achieved through the @b{project extension} facility. Suppose for instance that our example @code{Build} project is built every night for the whole team, in some shared directory. A developer usually need to work on a small part of the system, and might not want to have a copy of all the sources and all the object files (mostly because that would require too much disk space, time to recompile everything). He prefers to be able to override some of the source files in his directory, while taking advantage of all the object files generated at night. Another example can be taken from large software systems, where it is common to have multiple implementations of a common interface; in Ada terms, multiple versions of a package body for the same spec. For example, one implementation might be safe for use in tasking programs, while another might only be used in sequential applications. This can be modeled in GNAT using the concept of @emph{project extension}. If one project (the ``child'') @emph{extends} another project (the ``parent'') then by default all source files of the parent project are inherited by the child, but the child project can override any of the parent's source files with new versions, and can also add new files or remove unnecessary ones. This facility is the project analog of a type extension in object-oriented programming. Project hierarchies are permitted (an extending project may itself be extended), and a project that extends a project can also import other projects. A third example is that of using project extensions to provide different versions of the same system. For instance, assume that a @code{Common} project is used by two development branches. One of the branches has now been frozen, and no further change can be done to it or to @code{Common}. However, the other development branch still needs evolution of @code{Common}. Project extensions provide a flexible solution to create a new version of a subsystem while sharing and reusing as much as possible from the original one. A project extension inherits implicitly all the sources and objects from the project it extends. It is possible to create a new version of some of the sources in one of the additional source dirs of the extending project. Those new versions hide the original versions. Adding new sources or removing existing ones is also possible. Here is an example on how to extend the project @code{Build} from previous examples: @smallexample @c projectfile project Work extends "../bld/build.gpr" is end Work; @end smallexample @noindent The project after @b{extends} is the one being extended. As usual, it can be specified using an absolute path, or a path relative to any of the directories in the project path (@pxref{Project Dependencies}). This project does not specify source or object directories, so the default value for these attribute will be used that is to say the current directory (where project @code{Work} is placed). We can already compile that project with @smallexample gnatmake -Pwork @end smallexample @noindent If no sources have been placed in the current directory, this command won't do anything, since this project does not change the sources it inherited from @code{Build}, therefore all the object files in @code{Build} and its dependencies are still valid and are reused automatically. Suppose we now want to supply an alternate version of @file{pack.adb} but use the existing versions of @file{pack.ads} and @file{proc.adb}. We can create the new file Work's current directory (likely by copying the one from the @code{Build} project and making changes to it. If new packages are needed at the same time, we simply create new files in the source directory of the extending project. When we recompile, @command{gnatmake} will now automatically recompile this file (thus creating @file{pack.o} in the current directory) and any file that depends on it (thus creating @file{proc.o}). Finally, the executable is also linked locally. Note that we could have obtained the desired behavior using project import rather than project inheritance. A @code{base} project would contain the sources for @file{pack.ads} and @file{proc.adb}, and @code{Work} would import @code{base} and add @file{pack.adb}. In this scenario, @code{base} cannot contain the original version of @file{pack.adb} otherwise there would be 2 versions of the same unit in the closure of the project and this is not allowed. Generally speaking, it is not recommended to put the spec and the body of a unit in different projects since this affects their autonomy and reusability. In a project file that extends another project, it is possible to indicate that an inherited source is @b{not part} of the sources of the extending project. This is necessary sometimes when a package spec has been overridden and no longer requires a body: in this case, it is necessary to indicate that the inherited body is not part of the sources of the project, otherwise there will be a compilation error when compiling the spec. @cindex @code{Excluded_Source_Files} @cindex @code{Excluded_Source_List_File} For that purpose, the attribute @b{Excluded_Source_Files} is used. Its value is a list of file names. It is also possible to use attribute @code{Excluded_Source_List_File}. Its value is the path of a text file containing one file name per line. @smallexample @c @projectfile project Work extends "../bld/build.gpr" is for Source_Files use ("pack.ads"); -- New spec of Pkg does not need a completion for Excluded_Source_Files use ("pack.adb"); end Work; @end smallexample @noindent All packages that are not declared in the extending project are inherited from the project being extended, with their attributes, with the exception of @code{Linker'Linker_Options} which is never inherited. In particular, an extending project retains all the switches specified in the project being extended. At the project level, if they are not declared in the extending project, some attributes are inherited from the project being extended. They are: @code{Languages}, @code{Main} (for a root non library project) and @code{Library_Name} (for a project extending a library project) @menu * Project Hierarchy Extension:: @end menu @c --------------------------------------------- @node Project Hierarchy Extension @subsection Project Hierarchy Extension @c --------------------------------------------- @noindent One of the fundamental restrictions in project extension is the following: @b{A project is not allowed to import directly or indirectly at the same time an extending project and one of its ancestors}. By means of example, consider the following hierarchy of projects. @smallexample a.gpr contains package A1 b.gpr, imports a.gpr and contains B1, which depends on A1 c.gpr, imports b.gpr and contains C1, which depends on B1 @end smallexample @noindent If we want to locally extend the packages @code{A1} and @code{C1}, we need to create several extending projects: @smallexample a_ext.gpr which extends a.gpr, and overrides A1 b_ext.gpr which extends b.gpr and imports a_ext.gpr c_ext.gpr which extends c.gpr, imports b_ext.gpr and overrides C1 @end smallexample @noindent @smallexample @c projectfile project A_Ext extends "a.gpr" is for Source_Files use ("a1.adb", "a1.ads"); end A_Ext; with "a_ext.gpr"; project B_Ext extends "b.gpr" is end B_Ext; with "b_ext.gpr"; project C_Ext extends "c.gpr" is for Source_Files use ("c1.adb"); end C_Ext; @end smallexample @noindent The extension @file{b_ext.gpr} is required, even though we are not overriding any of the sources of @file{b.gpr} because otherwise @file{c_expr.gpr} would import @file{b.gpr} which itself knows nothing about @file{a_ext.gpr}. @cindex extends all When extending a large system spanning multiple projects, it is often inconvenient to extend every project in the hierarchy that is impacted by a small change introduced in a low layer. In such cases, it is possible to create an @b{implicit extension} of entire hierarchy using @b{extends all} relationship. When the project is extended using @code{extends all} inheritance, all projects that are imported by it, both directly and indirectly, are considered virtually extended. That is, the project manager creates implicit projects that extend every project in the hierarchy; all these implicit projects do not control sources on their own and use the object directory of the "extending all" project. It is possible to explicitly extend one or more projects in the hierarchy in order to modify the sources. These extending projects must be imported by the "extending all" project, which will replace the corresponding virtual projects with the explicit ones. When building such a project hierarchy extension, the project manager will ensure that both modified sources and sources in implicit extending projects that depend on them, are recompiled. Thus, in our example we could create the following projects instead: @smallexample a_ext.gpr, extends a.gpr and overrides A1 c_ext.gpr, "extends all" c.gpr, imports a_ext.gpr and overrides C1 @end smallexample @noindent @smallexample @c projectfile project A_Ext extends "a.gpr" is for Source_Files use ("a1.adb", "a1.ads"); end A_Ext; with "a_ext.gpr"; project C_Ext extends all "c.gpr" is for Source_Files use ("c1.adb"); end C_Ext; @end smallexample @noindent When building project @file{c_ext.gpr}, the entire modified project space is considered for recompilation, including the sources of @file{b.gpr} that are impacted by the changes in @code{A1} and @code{C1}. @c --------------------------------------------- @node Aggregate Projects @section Aggregate Projects @c --------------------------------------------- @noindent Aggregate projects are an extension of the project paradigm, and are meant to solve a few specific use cases that cannot be solved directly using standard projects. This section will go over a few of these use cases to try to explain what you can use aggregate projects for. @menu * Building all main programs from a single project tree:: * Building a set of projects with a single command:: * Define a build environment:: * Performance improvements in builder:: * Syntax of aggregate projects:: * package Builder in aggregate projects:: @end menu @c ----------------------------------------------------------- @node Building all main programs from a single project tree @subsection Building all main programs from a single project tree @c ----------------------------------------------------------- Most often, an application is organized into modules and submodules, which are very conveniently represented as a project tree or graph (the root project A @code{with}s the projects for each modules (say B and C), which in turn @code{with} projects for submodules. Very often, modules will build their own executables (for testing purposes for instance), or libraries (for easier reuse in various contexts). However, if you build your project through @command{gnatmake} or @command{gprbuild}, using a syntax similar to @smallexample gprbuild -PA.gpr @end smallexample this will only rebuild the main programs of project A, not those of the imported projects B and C. Therefore you have to spawn several @command{gnatmake} commands, one per project, to build all executables. This is a little inconvenient, but more importantly is inefficient because @command{gnatmake} needs to do duplicate work to ensure that sources are up-to-date, and cannot easily compile things in parallel when using the -j switch. Also libraries are always rebuilt when building a project. You could therefore define an aggregate project Agg that groups A, B and C. Then, when you build with @smallexample gprbuild -PAgg.gpr @end smallexample this will build all mains from A, B and C. @smallexample @c projectfile aggregate project Agg is for Project_Files use ("a.gpr", "b.gpr", "c.gpr"); end Agg; @end smallexample If B or C do not define any main program (through their Main attribute), all their sources are built. When you do not group them in the aggregate project, only those sources that are needed by A will be built. If you add a main to a project P not already explicitly referenced in the aggregate project, you will need to add "p.gpr" in the list of project files for the aggregate project, or the main will not be built when building the aggregate project. Aggregate projects are only supported with @command{gprbuild}, but not with @command{gnatmake}. @c --------------------------------------------------------- @node Building a set of projects with a single command @subsection Building a set of projects with a single command @c --------------------------------------------------------- One other case is when you have multiple applications and libraries that are built independently from each other (but can be built in parallel). For instance, you have a project tree rooted at A, and another one (which might share some subprojects) rooted at B. Using only @command{gprbuild}, you could do @smallexample gprbuild -PA.gpr gprbuild -PB.gpr @end smallexample to build both. But again, @command{gprbuild} has to do some duplicate work for those files that are shared between the two, and cannot truly build things in parallel efficiently. If the two projects are really independent, share no sources other than through a common subproject, and have no source files with a common basename, you could create a project C that imports A and B. But these restrictions are often too strong, and one has to build them independently. An aggregate project does not have these limitations and can aggregate two project trees that have common sources. This scenario is particularly useful in environments like VxWorks 653 where the applications running in the multiple partitions can be built in parallel through a single @command{gprbuild} command. This also works nicely with Annex E. @c --------------------------------------------- @node Define a build environment @subsection Define a build environment @c --------------------------------------------- The environment variables at the time you launch @command{gprbuild} will influence the view these tools have of the project (PATH to find the compiler, ADA_PROJECT_PATH or GPR_PROJECT_PATH to find the projects, environment variables that are referenced in project files through the "external" statement,...). Several command line switches can be used to override those (-X or -aP), but on some systems and with some projects, this might make the command line too long, and on all systems often make it hard to read. An aggregate project can be used to set the environment for all projects built through that aggregate. One of the nice aspects is that you can put the aggregate project under configuration management, and make sure all your user have a consistent environment when building. The syntax looks like @smallexample @c projectfile aggregate project Agg is for Project_Files use ("A.gpr", "B.gpr"); for Project_Path use ("../dir1", "../dir1/dir2"); for External ("BUILD") use "PRODUCTION"; package Builder is for ^Switches^Switches^ ("Ada") use ("-q"); end Builder; end Agg; @end smallexample One of the often requested features in projects is to be able to reference external variables in @code{with} statements, as in @smallexample @c projectfile with external("SETUP") & "path/prj.gpr"; -- ILLEGAL project MyProject is ... end MyProject; @end smallexample For various reasons, this isn't authorized. But using aggregate projects provide an elegant solution. For instance, you could use a project file like: @smallexample @c projectfile aggregate project Agg is for Project_Path use (external("SETUP") & "path"); for Project_Files use ("myproject.gpr"); end Agg; with "prj.gpr"; -- searched on Agg'Project_Path project MyProject is ... end MyProject; @end smallexample @c -------------------------------------------- @node Performance improvements in builder @subsection Performance improvements in builder @c -------------------------------------------- The loading of aggregate projects is optimized in @command{gprbuild}, so that all files are searched for only once on the disk (thus reducing the number of system calls and contributing to faster compilation times especially on systems with sources on remote servers). As part of the loading, @command{gprbuild} computes how and where a source file should be compiled, and even if it is found several times in the aggregated projects it will be compiled only once. Since there is no ambiguity as to which switches should be used, files can be compiled in parallel (through the usual -j switch) and this can be done while maximizing the use of CPUs (compared to launching multiple @command{gprbuild} and @command{gnatmake} commands in parallel). @c ------------------------------------- @node Syntax of aggregate projects @subsection Syntax of aggregate projects @c ------------------------------------- An aggregate project follows the general syntax of project files. The recommended extension is still @file{.gpr}. However, a special @code{aggregate} qualifier must be put before the keyword @code{project}. An aggregate project cannot @code{with} any other project (standard or aggregate), except an abstract project which can be used to share attribute values. Also, aggregate projects cannot be extended or imported though a @code{with} clause by any other project. Building other aggregate projects from an aggregate project is done through the Project_Files attribute (see below). An aggregate project does not have any source files directly (only through other standard projects). Therefore a number of the standard attributes and packages are forbidden in an aggregate project. Here is the (non exhaustive) list: @itemize @bullet @item Languages @item Source_Files, Source_List_File and other attributes dealing with list of sources. @item Source_Dirs, Exec_Dir and Object_Dir @item Library_Dir, Library_Name and other library-related attributes @item Main @item Roots @item Externally_Built @item Inherit_Source_Path @item Excluded_Source_Dirs @item Locally_Removed_Files @item Excluded_Source_Files @item Excluded_Source_List_File @item Interfaces @end itemize The only package that is authorized (albeit optional) is Builder. Other packages (in particular Compiler, Binder and Linker) are forbidden. It is an error to have any of these (and such an error prevents the proper loading of the aggregate project). Three new attributes have been created, which can only be used in the context of aggregate projects: @table @asis @item @b{Project_Files}: @cindex @code{Project_Files} This attribute is compulsory (or else we are not aggregating any project, and thus not doing anything). It specifies a list of @file{.gpr} files that are grouped in the aggregate. The list may be empty. The project files can be either other aggregate projects, or standard projects. When grouping standard projects, you can have both the root of a project tree (and you do not need to specify all its imported projects), and any project within the tree. Basically, the idea is to specify all those projects that have main programs you want to build and link, or libraries you want to build. You can even specify projects that do not use the Main attribute nor the @code{Library_*} attributes, and the result will be to build all their source files (not just the ones needed by other projects). The file can include paths (absolute or relative). Paths are relative to the location of the aggregate project file itself (if you use a base name, we expect to find the .gpr file in the same directory as the aggregate project file). The environment variables @code{ADA_PROJECT_PATH}, @code{GPR_PROJECT_PATH} and @code{GPR_PROJECT_PATH_FILE} are not used to find the project files. The extension @file{.gpr} is mandatory, since this attribute contains file names, not project names. Paths can also include the @code{"*"} and @code{"**"} globbing patterns. The latter indicates that any subdirectory (recursively) will be searched for matching files. The latter (@code{"**"}) can only occur at the last position in the directory part (ie @code{"a/**/*.gpr"} is supported, but not @code{"**/a/*.gpr"}). Starting the pattern with @code{"**"} is equivalent to starting with @code{"./**"}. For now, the pattern @code{"*"} is only allowed in the filename part, not in the directory part. This is mostly for efficiency reasons to limit the number of system calls that are needed. Here are a few valid examples: @smallexample @c projectfile for Project_Files use ("a.gpr", "subdir/b.gpr"); -- two specific projects relative to the directory of agg.gpr for Project_Files use ("**/*.gpr"); -- all projects recursively @end smallexample @item @b{Project_Path}: @cindex @code{Project_Path} This attribute can be used to specify a list of directories in which to look for project files in @code{with} statements. When you specify a project in Project_Files say @code{"x/y/a.gpr"}), and this projects imports a project "b.gpr", only b.gpr is searched in the project path. a.gpr must be exactly at /x/y/a.gpr. This attribute, however, does not affect the search for the aggregated project files specified with @code{Project_Files}. Each aggregate project has its own (that is if agg1.gpr includes agg2.gpr, they can potentially both have a different project path). This project path is defined as the concatenation, in that order, of: @itemize @bullet @item the current directory; @item followed by the command line -aP switches; @item then the directories from the GPR_PROJECT_PATH and ADA_PROJECT_PATH environment variables; @item then the directories from the Project_Path attribute; @item and finally the predefined directories. @end itemize In the example above, agg2.gpr's project path is not influenced by the attribute agg1'Project_Path, nor is agg1 influenced by agg2'Project_Path. This can potentially lead to errors. In the following example: @smallexample +---------------+ +----------------+ | Agg1.gpr |-=--includes--=-->| Agg2.gpr | | 'project_path| | 'project_path | | | | | +---------------+ +----------------+ : : includes includes : : v v +-------+ +---------+ | P.gpr |<---------- withs --------| Q.gpr | +-------+---------\ +---------+ | | withs | | | v v +-------+ +---------+ | R.gpr | | R'.gpr | +-------+ +---------+ @end smallexample When looking for p.gpr, both aggregates find the same physical file on the disk. However, it might happen that with their different project paths, both aggregate projects would in fact find a different r.gpr. Since we have a common project (p.gpr) "with"ing two different r.gpr, this will be reported as an error by the builder. Directories are relative to the location of the aggregate project file. Here are a few valid examples: @smallexample @c projectfile for Project_Path use ("/usr/local/gpr", "gpr/"); @end smallexample @item @b{External}: @cindex @code{External} This attribute can be used to set the value of environment variables as retrieved through the @code{external} statement in projects. It does not affect the environment variables themselves (so for instance you cannot use it to change the value of your PATH as seen from the spawned compiler). This attribute affects the external values as seen in the rest of the aggreate projects, and in the aggregated projects. The exact value of external a variable comes from one of three sources (each level overrides the previous levels): @itemize @bullet @item An External attribute in aggregate project, for instance @code{for External ("BUILD_MODE") use "DEBUG"}; @item Environment variables These override the value given by the attribute, so that users can override the value set in the (presumably shared with others in his team) aggregate project. @item The -X command line switch to @command{gprbuild} This always takes precedence. @end itemize This attribute is only taken into account in the main aggregate project (i.e. the one specified on the command line to @command{gprbuild}), and ignored in other aggregate projects. It is invalid in standard projects. The goal is to have a consistent value in all projects that are built through the aggregate, which would not be the case in the diamond case: A groups the aggregate projects B and C, which both (either directly or indirectly) build the project P. If B and C could set different values for the environment variables, we would have two different views of P, which in particular might impact the list of source files in P. @end table @c ---------------------------------------------- @node package Builder in aggregate projects @subsection package Builder in aggregate projects @c ---------------------------------------------- As we mentioned before, only the package Builder can be specified in an aggregate project. In this package, only the following attributes are valid: @table @asis @item @b{^Switches^Switches^}: @cindex @code{^Switches^Switches^} This attribute gives the list of switches to use for @command{gprbuild}. Because no mains can be specified for aggregate projects, the only possible index for attribute @code{Switches} is @code{others}. All other indexes will be ignored. Example: @smallexample @c projectfile for ^Switches^Switches^ (other) use ("-v", "-k", "-j8"); @end smallexample These switches are only read from the main aggregate project (the one passed on the command line), and ignored in all other aggregate projects or projects. It can only contain builder switches, not compiler switches. @item @b{Global_Compilation_Switches} @cindex @code{Global_Compilation_Switches} This attribute gives the list of compiler switches for the various languages. For instance, @smallexample @c projectfile for Global_Compilation_Switches ("Ada") use ("^O1^-O1^", "-g"); for Global_Compilation_Switches ("C") use ("^-O2^-O2^"); @end smallexample This attribute is only taken into account in the aggregate project specified on the command line, not in other aggregate projects. In the projects grouped by that aggregate, the attribute Builder.Global_Compilation_Switches is also ignored. However, the attribute Compiler.Default_Switches will be taken into account (but that of the aggregate have higher priority). The attribute Compiler.Switches is also taken into account and can be used to override the switches for a specific file. As a result, it always has priority. The rules are meant to avoid ambiguities when compiling. For instance, aggregate project Agg groups the projects A and B, that both depend on C. Here is an extra for all of these projects: @smallexample @c projectfile aggregate project Agg is for Project_Files use ("a.gpr", "b.gpr"); package Builder is for Global_Compilation_Switches ("Ada") use ("^-O2^-O2^"); end Builder; end Agg; with "c.gpr"; project A is package Builder is for Global_Compilation_Switches ("Ada") use ("^-O1^-O1^"); -- ignored end Builder; package Compiler is for Default_Switches ("Ada") use ("^-O1^-O1^", "-g"); for ^Switches^Switches^ ("a_file1.adb") use ("^-O0^-O0^"); end Compiler; end A; with "c.gpr"; project B is package Compiler is for Default_Switches ("Ada") use ("^-O0^-O0^"); end Compiler; end B; project C is package Compiler is for Default_Switches ("Ada") use ("^-O3^-O3^", "^-gnatn^-gnatn^"); for ^Switches^Switches^ ("c_file1.adb") use ("^-O0^-O0^", "-g"); end Compiler; end C; @end smallexample then the following switches are used: @itemize @bullet @item all files from project A except a_file1.adb are compiled with "^-O2^-O2^ -g", since the aggregate project has priority. @item the file a_file1.adb is compiled with "^-O0^-O0^", since the Compiler.Switches has priority @item all files from project B are compiled with "^-O2^-O2^", since the aggregate project has priority @item all files from C are compiled with "^-O2^-O2^ -gnatn", except for c_file1.adb which is compiled with "^-O0^-O0^ -g" @end itemize Even though C is seen through two paths (through A and through B), the switches used by the compiler are unambiguous. @item @b{Global_Configuration_Pragmas} @cindex @code{Global_Configuration_Pragmas} This attribute can be used to specify a file containing configuration pragmas, to be passed to the Ada compiler. Since we ignore the package Builder in other aggregate projects and projects, only those pragmas defined in the main aggregate project will be taken into account. Projects can locally add to those by using the @code{Compiler.Local_Configuration_Pragmas} attribute if they need. @item @b{Global_Config_File} @cindex @code{Global_Config_File} This attribute, indexed with a language name, can be used to specify a config when compiling sources of the language. For Ada, these files are configuration pragmas files. @end table For projects that are built through the aggregate, the package Builder is ignored, except for the Executable attribute which specifies the name of the executables resulting from the link of the main programs, and for the Executable_Suffix. @c --------------------------------------------- @node Aggregate Library Projects @section Aggregate Library Projects @c --------------------------------------------- @noindent Aggregate library projects make it possible to build a single library using object files built using other standard or library projects. This gives the flexibility to describe an application as having multiple modules (a GUI, database access, ...) using different project files (so possibly built with different compiler options) and yet create a single library (static or relocatable) out of the corresponding object files. @menu * Building aggregate library projects:: * Syntax of aggregate library projects:: @end menu @c --------------------------------------------- @node Building aggregate library projects @subsection Building aggregate library projects @c --------------------------------------------- For example, we can define an aggregate project Agg that groups A, B and C: @smallexample @c projectfile aggregate library project Agg is for Project_Files use ("a.gpr", "b.gpr", "c.gpr"); for Library_Name use ("agg"); for Library_Dir use ("lagg"); end Agg; @end smallexample Then, when you build with: @smallexample gprbuild agg.gpr @end smallexample This will build all units from projects A, B and C and will create a static library named @file{libagg.a} into the @file{lagg} directory. An aggregate library project has the same set of restriction as a standard library project. Note that a shared aggregate library project cannot aggregates a static library project. In platforms where a compiler option is required to create relocatable object files, a Builder package in the aggregate library project may be used: @smallexample @c projectfile aggregate library project Agg is for Project_Files use ("a.gpr", "b.gpr", "c.gpr"); for Library_Name use ("agg"); for Library_Dir use ("lagg"); for Library_Kind use "relocatable"; package Builder is for Global_Compilation_Switches ("Ada") use ("-fPIC"); end Builder; end Agg; @end smallexample With the above aggregate library Builder package, the @code{-fPIC} option will be passed to the compiler when building any source code from projects @file{a.gpr}, @file{b.gpr} and @file{c.gpr}. @c --------------------------------------------- @node Syntax of aggregate library projects @subsection Syntax of aggregate library projects @c --------------------------------------------- An aggregate library project follows the general syntax of project files. The recommended extension is still @file{.gpr}. However, a special @code{aggregate library} qualifier must be put before the keyword @code{project}. An aggregate library project cannot @code{with} any other project (standard or aggregate), except an abstract project which can be used to share attribute values. An aggregate library project does not have any source files directly (only through other standard projects). Therefore a number of the standard attributes and packages are forbidden in an aggregate library project. Here is the (non exhaustive) list: @itemize @bullet @item Languages @item Source_Files, Source_List_File and other attributes dealing with list of sources. @item Source_Dirs, Exec_Dir and Object_Dir @item Main @item Roots @item Externally_Built @item Inherit_Source_Path @item Excluded_Source_Dirs @item Locally_Removed_Files @item Excluded_Source_Files @item Excluded_Source_List_File @item Interfaces @end itemize The only package that is authorized (albeit optional) is Builder. The Project_Files attribute (See @pxref{Aggregate Projects}) is used to described the aggregated projects whose object files have to be included into the aggregate library. The environment variables @code{ADA_PROJECT_PATH}, @code{GPR_PROJECT_PATH} and @code{GPR_PROJECT_PATH_FILE} are not used to find the project files. @c --------------------------------------------- @node Project File Reference @section Project File Reference @c --------------------------------------------- @noindent This section describes the syntactic structure of project files, the various constructs that can be used. Finally, it ends with a summary of all available attributes. @menu * Project Declaration:: * Qualified Projects:: * Declarations:: * Packages:: * Expressions:: * External Values:: * Typed String Declaration:: * Variables:: * Case Constructions:: * Attributes:: @end menu @c --------------------------------------------- @node Project Declaration @subsection Project Declaration @c --------------------------------------------- @noindent Project files have an Ada-like syntax. The minimal project file is: @smallexample @c projectfile @group project Empty is end Empty; @end group @end smallexample @noindent The identifier @code{Empty} is the name of the project. This project name must be present after the reserved word @code{end} at the end of the project file, followed by a semi-colon. @b{Identifiers} (i.e.@: the user-defined names such as project or variable names) have the same syntax as Ada identifiers: they must start with a letter, and be followed by zero or more letters, digits or underscore characters; it is also illegal to have two underscores next to each other. Identifiers are always case-insensitive ("Name" is the same as "name"). @smallexample simple_name ::= identifier name ::= simple_name @{ . simple_name @} @end smallexample @noindent @b{Strings} are used for values of attributes or as indexes for these attributes. They are in general case sensitive, except when noted otherwise (in particular, strings representing file names will be case insensitive on some systems, so that "file.adb" and "File.adb" both represent the same file). @b{Reserved words} are the same as for standard Ada 95, and cannot be used for identifiers. In particular, the following words are currently used in project files, but others could be added later on. In bold are the extra reserved words in project files: @code{all, at, case, end, for, is, limited, null, others, package, renames, type, use, when, with, @b{extends}, @b{external}, @b{project}}. @b{Comments} in project files have the same syntax as in Ada, two consecutive hyphens through the end of the line. A project may be an @b{independent project}, entirely defined by a single project file. Any source file in an independent project depends only on the predefined library and other source files in the same project. But a project may also depend on other projects, either by importing them through @b{with clauses}, or by @b{extending} at most one other project. Both types of dependency can be used in the same project. A path name denotes a project file. It can be absolute or relative. An absolute path name includes a sequence of directories, in the syntax of the host operating system, that identifies uniquely the project file in the file system. A relative path name identifies the project file, relative to the directory that contains the current project, or relative to a directory listed in the environment variables ADA_PROJECT_PATH and GPR_PROJECT_PATH. Path names are case sensitive if file names in the host operating system are case sensitive. As a special case, the directory separator can always be "/" even on Windows systems, so that project files can be made portable across architectures. The syntax of the environment variable ADA_PROJECT_PATH and GPR_PROJECT_PATH is a list of directory names separated by colons on UNIX and semicolons on Windows. A given project name can appear only once in a context clause. It is illegal for a project imported by a context clause to refer, directly or indirectly, to the project in which this context clause appears (the dependency graph cannot contain cycles), except when one of the with clause in the cycle is a @b{limited with}. @c ??? Need more details here @smallexample @c projectfile with "other_project.gpr"; project My_Project extends "extended.gpr" is end My_Project; @end smallexample @noindent These dependencies form a @b{directed graph}, potentially cyclic when using @b{limited with}. The subprogram reflecting the @b{extends} relations is a tree. A project's @b{immediate sources} are the source files directly defined by that project, either implicitly by residing in the project source directories, or explicitly through any of the source-related attributes. More generally, a project sources are the immediate sources of the project together with the immediate sources (unless overridden) of any project on which it depends directly or indirectly. A @b{project hierarchy} can be created, where projects are children of other projects. The name of such a child project must be @code{Parent.Child}, where @code{Parent} is the name of the parent project. In particular, this makes all @code{with} clauses of the parent project automatically visible in the child project. @smallexample project ::= context_clause project_declaration context_clause ::= @{with_clause@} with_clause ::= @i{with} path_name @{ , path_name @} ; path_name ::= string_literal project_declaration ::= simple_project_declaration | project_extension simple_project_declaration ::= @i{project} @i{}name @i{is} @{declarative_item@} @i{end} simple_name; @end smallexample @c --------------------------------------------- @node Qualified Projects @subsection Qualified Projects @c --------------------------------------------- @noindent Before the reserved @code{project}, there may be one or two @b{qualifiers}, that is identifiers or reserved words, to qualify the project. The current list of qualifiers is: @table @asis @item @b{abstract}: qualifies a project with no sources. Such a project must either have no declaration of attributes @code{Source_Dirs}, @code{Source_Files}, @code{Languages} or @code{Source_List_File}, or one of @code{Source_Dirs}, @code{Source_Files}, or @code{Languages} must be declared as empty. If it extends another project, the project it extends must also be a qualified abstract project. @item @b{standard}: a standard project is a non library project with sources. This is the default (implicit) qualifier. @item @b{aggregate}: a project whose sources are aggregated from other project files. @item @b{aggregate library}: a library whose sources are aggregated from other project or library project files. @item @b{library}: a library project must declare both attributes @code{Library_Name} and @code{Library_Dir}. @item @b{configuration}: a configuration project cannot be in a project tree. It describes compilers and other tools to @command{gprbuild}. @end table @c --------------------------------------------- @node Declarations @subsection Declarations @c --------------------------------------------- @noindent Declarations introduce new entities that denote types, variables, attributes, and packages. Some declarations can only appear immediately within a project declaration. Others can appear within a project or within a package. @smallexample declarative_item ::= simple_declarative_item | typed_string_declaration | package_declaration simple_declarative_item ::= variable_declaration | typed_variable_declaration | attribute_declaration | case_construction | empty_declaration empty_declaration ::= @i{null} ; @end smallexample @noindent An empty declaration is allowed anywhere a declaration is allowed. It has no effect. @c --------------------------------------------- @node Packages @subsection Packages @c --------------------------------------------- @noindent A project file may contain @b{packages}, that group attributes (typically all the attributes that are used by one of the GNAT tools). A package with a given name may only appear once in a project file. The following packages are currently supported in project files (See @pxref{Attributes} for the list of attributes that each can contain). @table @code @item Binder This package specifies characteristics useful when invoking the binder either directly via the @command{gnat} driver or when using a builder such as @command{gnatmake} or @command{gprbuild}. @xref{Main Subprograms}. @item Builder This package specifies the compilation options used when building an executable or a library for a project. Most of the options should be set in one of @code{Compiler}, @code{Binder} or @code{Linker} packages, but there are some general options that should be defined in this package. @xref{Main Subprograms}, and @pxref{Executable File Names} in particular. @ifclear FSFEDITION @item Check This package specifies the options used when calling the checking tool @command{gnatcheck} via the @command{gnat} driver. Its attribute @b{Default_Switches} has the same semantics as for the package @code{Builder}. The first string should always be @code{-rules} to specify that all the other options belong to the @code{-rules} section of the parameters to @command{gnatcheck}. @end ifclear @item Clean This package specifies the options used when cleaning a project or a project tree using the tools @command{gnatclean} or @command{gprclean}. @item Compiler This package specifies the compilation options used by the compiler for each languages. @xref{Tools Options in Project Files}. @item Cross_Reference This package specifies the options used when calling the library tool @command{gnatxref} via the @command{gnat} driver. Its attributes @b{Default_Switches} and @b{^Switches^Switches^} have the same semantics as for the package @code{Builder}. @ifclear FSFEDITION @item Eliminate This package specifies the options used when calling the tool @command{gnatelim} via the @command{gnat} driver. Its attributes @b{Default_Switches} and @b{^Switches^Switches^} have the same semantics as for the package @code{Builder}. @end ifclear @item Finder This package specifies the options used when calling the search tool @command{gnatfind} via the @command{gnat} driver. Its attributes @b{Default_Switches} and @b{^Switches^Switches^} have the same semantics as for the package @code{Builder}. @item ^Gnatls^Gnatls^ This package specifies the options to use when invoking @command{gnatls} via the @command{gnat} driver. @ifclear FSFEDITION @item ^Gnatstub^Gnatstub^ This package specifies the options used when calling the tool @command{gnatstub} via the @command{gnat} driver. Its attributes @b{Default_Switches} and @b{^Switches^Switches^} have the same semantics as for the package @code{Builder}. @end ifclear @item IDE This package specifies the options used when starting an integrated development environment, for instance @command{GPS} or @command{Gnatbench}. @item Install This package specifies the options used when installing a project with @command{gprinstall}. @xref{Installation}. @item Linker This package specifies the options used by the linker. @xref{Main Subprograms}. @ifclear FSFEDITION @item Metrics This package specifies the options used when calling the tool @command{gnatmetric} via the @command{gnat} driver. Its attributes @b{Default_Switches} and @b{^Switches^Switches^} have the same semantics as for the package @code{Builder}. @end ifclear @item Naming This package specifies the naming conventions that apply to the source files in a project. In particular, these conventions are used to automatically find all source files in the source directories, or given a file name to find out its language for proper processing. @xref{Naming Schemes}. @ifclear FSFEDITION @item Pretty_Printer This package specifies the options used when calling the formatting tool @command{gnatpp} via the @command{gnat} driver. Its attributes @b{Default_Switches} and @b{^Switches^Switches^} have the same semantics as for the package @code{Builder}. @end ifclear @item Remote This package is used by @command{gprbuild} to describe how distributed compilation should be done. @item Stack This package specifies the options used when calling the tool @command{gnatstack} via the @command{gnat} driver. Its attributes @b{Default_Switches} and @b{^Switches^Switches^} have the same semantics as for the package @code{Builder}. @item Synchronize This package specifies the options used when calling the tool @command{gnatsync} via the @command{gnat} driver. @end table In its simplest form, a package may be empty: @smallexample @c projectfile @group project Simple is package Builder is end Builder; end Simple; @end group @end smallexample @noindent A package may contain @b{attribute declarations}, @b{variable declarations} and @b{case constructions}, as will be described below. When there is ambiguity between a project name and a package name, the name always designates the project. To avoid possible confusion, it is always a good idea to avoid naming a project with one of the names allowed for packages or any name that starts with @code{gnat}. A package can also be defined by a @b{renaming declaration}. The new package renames a package declared in a different project file, and has the same attributes as the package it renames. The name of the renamed package must be the same as the name of the renaming package. The project must contain a package declaration with this name, and the project must appear in the context clause of the current project, or be its parent project. It is not possible to add or override attributes to the renaming project. If you need to do so, you should use an @b{extending declaration} (see below). Packages that are renamed in other project files often come from project files that have no sources: they are just used as templates. Any modification in the template will be reflected automatically in all the project files that rename a package from the template. This is a very common way to share settings between projects. Finally, a package can also be defined by an @b{extending declaration}. This is similar to a @b{renaming declaration}, except that it is possible to add or override attributes. @smallexample package_declaration ::= package_spec | package_renaming | package_extension package_spec ::= @i{package} @i{}simple_name @i{is} @{simple_declarative_item@} @i{end} package_identifier ; package_renaming ::== @i{package} @i{}simple_name @i{renames} @i{}simple_name.package_identifier ; package_extension ::== @i{package} @i{}simple_name @i{extends} @i{}simple_name.package_identifier @i{is} @{simple_declarative_item@} @i{end} package_identifier ; @end smallexample @c --------------------------------------------- @node Expressions @subsection Expressions @c --------------------------------------------- @noindent An expression is any value that can be assigned to an attribute or a variable. It is either a literal value, or a construct requiring runtime computation by the project manager. In a project file, the computed value of an expression is either a string or a list of strings. A string value is one of: @itemize @bullet @item A literal string, for instance @code{"comm/my_proj.gpr"} @item The name of a variable that evaluates to a string (@pxref{Variables}) @item The name of an attribute that evaluates to a string (@pxref{Attributes}) @item An external reference (@pxref{External Values}) @item A concatenation of the above, as in @code{"prefix_" & Var}. @end itemize @noindent A list of strings is one of the following: @itemize @bullet @item A parenthesized comma-separated list of zero or more string expressions, for instance @code{(File_Name, "gnat.adc", File_Name & ".orig")} or @code{()}. @item The name of a variable that evaluates to a list of strings @item The name of an attribute that evaluates to a list of strings @item A concatenation of a list of strings and a string (as defined above), for instance @code{("A", "B") & "C"} @item A concatenation of two lists of strings @end itemize @noindent The following is the grammar for expressions @smallexample string_literal ::= "@{string_element@}" -- Same as Ada string_expression ::= string_literal | @i{variable_}name | external_value | attribute_reference | ( string_expression @{ & string_expression @} ) string_list ::= ( string_expression @{ , string_expression @} ) | @i{string_variable}_name | @i{string_}attribute_reference term ::= string_expression | string_list expression ::= term @{ & term @} -- Concatenation @end smallexample @noindent Concatenation involves strings and list of strings. As soon as a list of strings is involved, the result of the concatenation is a list of strings. The following Ada declarations show the existing operators: @smallexample @c ada function "&" (X : String; Y : String) return String; function "&" (X : String_List; Y : String) return String_List; function "&" (X : String_List; Y : String_List) return String_List; @end smallexample @noindent Here are some specific examples: @smallexample @c projectfile @group List := () & File_Name; -- One string in this list List2 := List & (File_Name & ".orig"); -- Two strings Big_List := List & Lists2; -- Three strings Illegal := "gnat.adc" & List2; -- Illegal, must start with list @end group @end smallexample @c --------------------------------------------- @node External Values @subsection External Values @c --------------------------------------------- @noindent An external value is an expression whose value is obtained from the command that invoked the processing of the current project file (typically a @command{gnatmake} or @command{gprbuild} command). There are two kinds of external values, one that returns a single string, and one that returns a string list. The syntax of a single string external value is: @smallexample external_value ::= @i{external} ( string_literal [, string_literal] ) @end smallexample @noindent The first string_literal is the string to be used on the command line or in the environment to specify the external value. The second string_literal, if present, is the default to use if there is no specification for this external value either on the command line or in the environment. Typically, the external value will either exist in the ^environment variables^logical name^ or be specified on the command line through the @option{^-X^/EXTERNAL_REFERENCE=^@emph{vbl}=@emph{value}} switch. If both are specified, then the command line value is used, so that a user can more easily override the value. The function @code{external} always returns a string. It is an error if the value was not found in the environment and no default was specified in the call to @code{external}. An external reference may be part of a string expression or of a string list expression, and can therefore appear in a variable declaration or an attribute declaration. Most of the time, this construct is used to initialize typed variables, which are then used in @b{case} statements to control the value assigned to attributes in various scenarios. Thus such variables are often called @b{scenario variables}. The syntax for a string list external value is: @smallexample external_value ::= @i{external_as_list} ( string_literal , string_literal ) @end smallexample @noindent The first string_literal is the string to be used on the command line or in the environment to specify the external value. The second string_literal is the separator between each component of the string list. If the external value does not exist in the environment or on the command line, the result is an empty list. This is also the case, if the separator is an empty string or if the external value is only one separator. Any separator at the beginning or at the end of the external value is discarded. Then, if there is no separator in the external value, the result is a string list with only one string. Otherwise, any string between the beginning and the first separator, between two consecutive separators and between the last separator and the end are components of the string list. @smallexample @i{external_as_list} ("SWITCHES", ",") @end smallexample @noindent If the external value is "^-O2^-O2^,-g", the result is ("^-O2^-O2^", "-g"). If the external value is ",^-O2^-O2^,-g,", the result is also ("^-O2^-O2^", "-g"). if the external value is "^-gnatv^-gnatv^", the result is ("^-gnatv^-gnatv^"). If the external value is ",,", the result is (""). If the external value is ",", the result is (), the empty string list. @c --------------------------------------------- @node Typed String Declaration @subsection Typed String Declaration @c --------------------------------------------- @noindent A @b{type declaration} introduces a discrete set of string literals. If a string variable is declared to have this type, its value is restricted to the given set of literals. These are the only named types in project files. A string type may only be declared at the project level, not inside a package. @smallexample typed_string_declaration ::= @i{type} @i{}_simple_name @i{is} ( string_literal @{, string_literal@} ); @end smallexample @noindent The string literals in the list are case sensitive and must all be different. They may include any graphic characters allowed in Ada, including spaces. Here is an example of a string type declaration: @smallexample @c projectfile type OS is ("NT", "nt", "Unix", "GNU/Linux", "other OS"); @end smallexample @noindent Variables of a string type are called @b{typed variables}; all other variables are called @b{untyped variables}. Typed variables are particularly useful in @code{case} constructions, to support conditional attribute declarations. (@pxref{Case Constructions}). A string type may be referenced by its name if it has been declared in the same project file, or by an expanded name whose prefix is the name of the project in which it is declared. @c --------------------------------------------- @node Variables @subsection Variables @c --------------------------------------------- @noindent @b{Variables} store values (strings or list of strings) and can appear as part of an expression. The declaration of a variable creates the variable and assigns the value of the expression to it. The name of the variable is available immediately after the assignment symbol, if you need to reuse its old value to compute the new value. Before the completion of its first declaration, the value of a variable defaults to the empty string (""). A @b{typed} variable can be used as part of a @b{case} expression to compute the value, but it can only be declared once in the project file, so that all case constructions see the same value for the variable. This provides more consistency and makes the project easier to understand. The syntax for its declaration is identical to the Ada syntax for an object declaration. In effect, a typed variable acts as a constant. An @b{untyped} variable can be declared and overridden multiple times within the same project. It is declared implicitly through an Ada assignment. The first declaration establishes the kind of the variable (string or list of strings) and successive declarations must respect the initial kind. Assignments are executed in the order in which they appear, so the new value replaces the old one and any subsequent reference to the variable uses the new value. A variable may be declared at the project file level, or within a package. @smallexample typed_variable_declaration ::= @i{}simple_name : @i{}name := string_expression; variable_declaration ::= @i{}simple_name := expression; @end smallexample @noindent Here are some examples of variable declarations: @smallexample @c projectfile @group This_OS : OS := external ("OS"); -- a typed variable declaration That_OS := "GNU/Linux"; -- an untyped variable declaration Name := "readme.txt"; Save_Name := Name & ".saved"; Empty_List := (); List_With_One_Element := ("-gnaty"); List_With_Two_Elements := List_With_One_Element & "-gnatg"; Long_List := ("main.ada", "pack1_.ada", "pack1.ada", "pack2_.ada"); @end group @end smallexample @noindent A @b{variable reference} may take several forms: @itemize @bullet @item The simple variable name, for a variable in the current package (if any) or in the current project @item An expanded name, whose prefix is a context name. @end itemize @noindent A @b{context} may be one of the following: @itemize @bullet @item The name of an existing package in the current project @item The name of an imported project of the current project @item The name of an ancestor project (i.e., a project extended by the current project, either directly or indirectly) @item An expanded name whose prefix is an imported/parent project name, and whose selector is a package name in that project. @end itemize @c --------------------------------------------- @node Case Constructions @subsection Case Constructions @c --------------------------------------------- @noindent A @b{case} statement is used in a project file to effect conditional behavior. Through this statement, you can set the value of attributes and variables depending on the value previously assigned to a typed variable. All choices in a choice list must be distinct. Unlike Ada, the choice lists of all alternatives do not need to include all values of the type. An @code{others} choice must appear last in the list of alternatives. The syntax of a @code{case} construction is based on the Ada case statement (although the @code{null} statement for empty alternatives is optional). The case expression must be a typed string variable, whose value is often given by an external reference (@pxref{External Values}). Each alternative starts with the reserved word @code{when}, either a list of literal strings separated by the @code{"|"} character or the reserved word @code{others}, and the @code{"=>"} token. Each literal string must belong to the string type that is the type of the case variable. After each @code{=>}, there are zero or more statements. The only statements allowed in a case construction are other case constructions, attribute declarations and variable declarations. String type declarations and package declarations are not allowed. Variable declarations are restricted to variables that have already been declared before the case construction. @smallexample case_statement ::= @i{case} @i{}name @i{is} @{case_item@} @i{end case} ; case_item ::= @i{when} discrete_choice_list => @{case_statement | attribute_declaration | variable_declaration | empty_declaration@} discrete_choice_list ::= string_literal @{| string_literal@} | @i{others} @end smallexample @noindent Here is a typical example: @smallexample @c projectfile @group project MyProj is type OS_Type is ("GNU/Linux", "Unix", "NT", "VMS"); OS : OS_Type := external ("OS", "GNU/Linux"); package Compiler is case OS is when "GNU/Linux" | "Unix" => for ^Switches^Switches^ ("Ada") use ("-gnath"); when "NT" => for ^Switches^Switches^ ("Ada") use ("^-gnatP^-gnatP^"); when others => null; end case; end Compiler; end MyProj; @end group @end smallexample @c --------------------------------------------- @node Attributes @subsection Attributes @c --------------------------------------------- @menu * Project Level Attributes:: * Package Binder Attributes:: * Package Builder Attributes:: @ifclear FSFEDITION * Package Check Attributes:: @end ifclear * Package Clean Attributes:: * Package Compiler Attributes:: * Package Cross_Reference Attributes:: @ifclear FSFEDITION * Package Eliminate Attributes:: @end ifclear * Package Finder Attributes:: * Package ^gnatls^gnatls^ Attributes:: @ifclear FSFEDITION * Package ^gnatstub^gnatstub^ Attributes:: @end ifclear * Package IDE Attributes:: * Package Install Attributes:: * Package Linker Attributes:: @ifclear FSFEDITION * Package Metrics Attribute:: @end ifclear * Package Naming Attributes:: @ifclear FSFEDITION * Package Pretty_Printer Attributes:: @end ifclear * Package Remote Attributes:: * Package Stack Attributes:: * Package Synchronize Attributes:: @end menu @noindent A project (and its packages) may have @b{attributes} that define the project's properties. Some attributes have values that are strings; others have values that are string lists. @smallexample attribute_declaration ::= simple_attribute_declaration | indexed_attribute_declaration simple_attribute_declaration ::= @i{for} attribute_designator @i{use} expression ; indexed_attribute_declaration ::= @i{for} @i{}simple_name ( string_literal) @i{use} expression ; attribute_designator ::= @i{}simple_name | @i{}simple_name ( string_literal ) @end smallexample @noindent There are two categories of attributes: @b{simple attributes} and @b{indexed attributes}. Each simple attribute has a default value: the empty string (for string attributes) and the empty list (for string list attributes). An attribute declaration defines a new value for an attribute, and overrides the previous value. The syntax of a simple attribute declaration is similar to that of an attribute definition clause in Ada. Some attributes are indexed. These attributes are mappings whose domain is a set of strings. They are declared one association at a time, by specifying a point in the domain and the corresponding image of the attribute. Like untyped variables and simple attributes, indexed attributes may be declared several times. Each declaration supplies a new value for the attribute, and replaces the previous setting. Here are some examples of attribute declarations: @smallexample @c projectfile -- simple attributes for Object_Dir use "objects"; for Source_Dirs use ("units", "test/drivers"); -- indexed attributes for Body ("main") use "Main.ada"; for ^Switches^Switches^ ("main.ada") use ("-v", "^-gnatv^-gnatv^"); for ^Switches^Switches^ ("main.ada") use Builder'Switches ("main.ada") & "-g"; -- indexed attributes copy (from package Builder in project Default) -- The package name must always be specified, even if it is the current -- package. for Default_Switches use Default.Builder'Default_Switches; @end smallexample @noindent Attributes references may appear anywhere in expressions, and are used to retrieve the value previously assigned to the attribute. If an attribute has not been set in a given package or project, its value defaults to the empty string or the empty list. @smallexample attribute_reference ::= attribute_prefix ' @i{_}simple_name [ (string_literal) ] attribute_prefix ::= @i{project} | @i{}simple_name | package_identifier | @i{}simple_name . package_identifier @end smallexample @noindent Examples are: @smallexample @c projectfile project'Object_Dir Naming'Dot_Replacement Imported_Project'Source_Dirs Imported_Project.Naming'Casing Builder'Default_Switches ("Ada") @end smallexample @noindent The prefix of an attribute may be: @itemize @bullet @item @code{project} for an attribute of the current project @item The name of an existing package of the current project @item The name of an imported project @item The name of a parent project that is extended by the current project @item An expanded name whose prefix is imported/parent project name, and whose selector is a package name @end itemize @noindent In the following sections, all predefined attributes are succinctly described, first the project level attributes, that is those attributes that are not in a package, then the attributes in the different packages. It is possible for different tools to create dynamically new packages with attributes, or new attribute in predefined packages. These attributes are not documented here. The attributes under Configuration headings are usually found only in configuration project files. The characteristics of each attribute are indicated as follows: @itemize @bullet @item @b{Type of value} The value of an attribute may be a single string, indicated by the word "single", or a string list, indicated by the word "list". @item @b{Read-only} When the attribute is read-only, that is when it is not allowed to declare the attribute, this is indicated by the words "read-only". @item @b{Optional index} If it is allowed in the value of the attribute (both single and list) to have an optional index, this is indicated by the words "optional index". @item @b{Indexed attribute} When an it is an indexed attribute, this is indicated by the word "indexed". @item @b{Case-sensitivity of the index} For an indexed attribute, if the index is case-insensitive, this is indicated by the words "case-insensitive index". @item @b{File name index} For an indexed attribute, when the index is a file name, this is indicated by the words "file name index". The index may or may not be case-sensitive, depending on the platform. @item @b{others allowed in index} For an indexed attribute, if it is allowed to use @b{others} as the index, this is indicated by the words "others allowed". When @b{others} is used as the index of an indexed attribute, the value of the attribute indexed by @b{others} is used when no other index would apply. @end itemize @node Project Level Attributes @subsubsection Project Level Attributes @noindent @itemize @bullet @item @b{General} @itemize @bullet @item @b{Name}: single, read-only The name of the project. @item @b{Project_Dir}: single, read-only The path name of the project directory. @item @b{Main}: list, optional index The list of main sources for the executables. @item @b{Languages}: list The list of languages of the sources of the project. @item @b{Roots}: list, indexed, file name index The index is the file name of an executable source. Indicates the list of units from the main project that need to be bound and linked with their closures with the executable. The index is either a file name, a language name or "*". The roots for an executable source are those in @b{Roots} with an index that is the executable source file name, if declared. Otherwise, they are those in @b{Roots} with an index that is the language name of the executable source, if present. Otherwise, they are those in @b{Roots ("*")}, if declared. If none of these three possibilities are declared, then there are no roots for the executable source. @item @b{Externally_Built}: single Indicates if the project is externally built. Only case-insensitive values allowed are "true" and "false", the default. @end itemize @noindent @item @b{Directories} @itemize @bullet @item @b{Object_Dir}: single Indicates the object directory for the project. @item @b{Exec_Dir}: single Indicates the exec directory for the project, that is the directory where the executables are. @item @b{Source_Dirs}: list The list of source directories of the project. @item @b{Inherit_Source_Path}: list, indexed, case-insensitive index Index is a language name. Value is a list of language names. Indicates that in the source search path of the index language the source directories of the languages in the list should be included. Example: for Inherit_Source_Path ("C++") use ("C"); @item @b{Exclude_Source_Dirs}: list The list of directories that are included in Source_Dirs but are not source directories of the project. @item @b{Ignore_Source_Sub_Dirs}: list Value is a list of simple names for subdirectories that are removed from the list of source directories, including theur subdirectories. @end itemize @item @b{Source Files} @itemize @bullet @item @b{Source_Files}: list Value is a list of source file simple names. @item @b{Locally_Removed_Files}: list Obsolescent. Equivalent to Excluded_Source_Files. @item @b{Excluded_Source_Files}: list Value is a list of simple file names that are not sources of the project. Allows to remove sources that are inherited or found in the source directories and that match the naming scheme. @item @b{Source_List_File}: single Value is a text file name that contains a list of source file simple names, one on each line. @item @b{Excluded_Source_List_File}: single Value is a text file name that contains a list of file simple names that are not sources of the project. @item @b{Interfaces}: list Value is a list of file names that constitutes the interfaces of the project. @end itemize @item @b{Aggregate Projects} @itemize @bullet @item @b{Project_Files}: list Value is the list of aggregated projects. @item @b{Project_Path}: list Value is a list of directories that are added to the project search path when looking for the aggregated projects. @item @b{External}: single, indexed Index is the name of an external reference. Value is the value of the external reference to be used when parsing the aggregated projects. @end itemize @item @b{Libraries} @itemize @bullet @item @b{Library_Dir}: single Value is the name of the library directory. This attribute needs to be declared for each library project. @item @b{Library_Name}: single Value is the name of the library. This attribute needs to be declared or inherited for each library project. @item @b{Library_Kind}: single Specifies the kind of library: static library (archive) or shared library. Case-insensitive values must be one of "static" for archives (the default) or "dynamic" or "relocatable" for shared libraries. @item @b{Library_Version}: single Value is the name of the library file. @item @b{Library_Interface}: list Value is the list of unit names that constitutes the interfaces of a Stand-Alone Library project. @item @b{Library_Standalone}: single Specifies if a Stand-Alone Library (SAL) is encapsulated or not. Only authorized case-insensitive values are "standard" for non encapsulated SALs, "encapsulated" for encapsulated SALs or "no" for non SAL library project. @item @b{Library_Encapsulated_Options}: list Value is a list of options that need to be used when linking an encapsulated Stand-Alone Library. @item @b{Library_Encapsulated_Supported}: single Indicates if encapsulated Stand-Alone Libraries are supported. Only authorized case-insensitive values are "true" and "false" (the default). @item @b{Library_Auto_Init}: single Indicates if a Stand-Alone Library is auto-initialized. Only authorized case-insentive values are "true" and "false". @item @b{Leading_Library_Options}: list Value is a list of options that are to be used at the beginning of the command line when linking a shared library. @item @b{Library_Options}: list Value is a list of options that are to be used when linking a shared library. @item @b{Library_Rpath_Options}: list, indexed, case-insensitive index Index is a language name. Value is a list of options for an invocation of the compiler of the language. This invocation is done for a shared library project with sources of the language. The output of the invocation is the path name of a shared library file. The directory name is to be put in the run path option switch when linking the shared library for the project. @item @b{Library_Src_Dir}: single Value is the name of the directory where copies of the sources of the interfaces of a Stand-Alone Library are to be copied. @item @b{Library_ALI_Dir}: single Value is the name of the directory where the ALI files of the interfaces of a Stand-Alone Library are to be copied. When this attribute is not declared, the directory is the library directory. @item @b{Library_gcc}: single Obsolescent attribute. Specify the linker driver used to link a shared library. Use instead attribute Linker'Driver. @item @b{Library_Symbol_File}: single Value is the name of the library symbol file. @item @b{Library_Symbol_Policy}: single Indicates the symbol policy kind. Only authorized case-insensitive values are "autonomous", "default", "compliant", "controlled" or "direct". @item @b{Library_Reference_Symbol_File}: single Value is the name of the reference symbol file. @end itemize @item @b{Configuration - General} @itemize @bullet @item @b{Default_Language}: single Value is the case-insensitive name of the language of a project when attribute Languages is not specified. @item @b{Run_Path_Option}: list Value is the list of switches to be used when specifying the run path option in an executable. @item @b{Run_Path_Origin}: single Value is the the string that may replace the path name of the executable directory in the run path options. @item @b{Separate_Run_Path_Options}: single Indicates if there may be or not several run path options specified when linking an executable. Only authorized case-insensitive b=values are "true" or "false" (the default). @item @b{Toolchain_Version}: single, indexed, case-insensitive index Index is a language name. Specify the version of a toolchain for a language. @item @b{Toolchain_Description}: single, indexed, case-insensitive index Obsolescent. No longer used. @item @b{Object_Generated}: single, indexed, case-insensitive index Index is a language name. Indicates if invoking the compiler for a language produces an object file. Only authorized case-insensitive values are "false" and "true" (the default). @item @b{Objects_Linked}: single, indexed, case-insensitive index Index is a language name. Indicates if the object files created by the compiler for a language need to be linked in the executable. Only authorized case-insensitive values are "false" and "true" (the default). @item @b{Target}: single Value is the name of the target platform. @end itemize @item @b{Configuration - Libraries} @itemize @bullet @item @b{Library_Builder}: single Value is the path name of the application that is to be used to build libraries. Usually the path name of "gprlib". @item @b{Library_Support}: single Indicates the level of support of libraries. Only authorized case-insensitive values are "static_only", "full" or "none" (the default). @end itemize @item @b{Configuration - Archives} @itemize @bullet @item @b{Archive_Builder}: list Value is the name of the application to be used to create a static library (archive), followed by the options to be used. @item @b{Archive_Builder_Append_Option}: list Value is the list of options to be used when invoking the archive builder to add project files into an archive. @item @b{Archive_Indexer}: list Value is the name of the archive indexer, followed by the required options. @item @b{Archive_Suffix}: single Value is the extension of archives. When not declared, the extension is ".a". @item @b{Library_Partial_Linker}: list Value is the name of the partial linker executable, followed by the required options. @end itemize @item @b{Configuration - Shared Libraries} @itemize @bullet @item @b{Shared_Library_Prefix}: single Value is the prefix in the name of shared library files. When not declared, the prefix is "lib". @item @b{Shared_Library_Suffix}: single Value is the the extension of the name of shared library files. When not declared, the extension is ".so". @item @b{Symbolic_Link_Supported}: single Indicates if symbolic links are supported on the platform. Only authorized case-insensitive values are "true" and "false" (the default). @item @b{Library_Major_Minor_Id_Supported}: single Indicates if major and minor ids for shared library names are supported on the platform. Only authorized case-insensitive values are "true" and "false" (the default). @item @b{Library_Auto_Init_Supported}: single Indicates if auto-initialization of Stand-Alone Libraries is supported. Only authorized case-insensitive values are "true" and "false" (the default). @item @b{Shared_Library_Minimum_Switches}: list Value is the list of required switches when linking a shared library. @item @b{Library_Version_Switches}: list Value is the list of switches to specify a internal name for a shared library. @item @b{Library_Install_Name_Option}: single Value is the name of the option that needs to be used, concatenated with the path name of the library file, when linking a shared library. @item @b{Runtime_Library_Dir}: single, indexed, case-insensitive index Index is a language name. Value is the path name of the directory where the runtime libraries are located. @item @b{Runtime_Source_Dir}: single, indexed, case-insensitive index Index is a language name. Value is the path name of the directory where the sources of runtime libraries are located. @end itemize @end itemize @node Package Binder Attributes @subsubsection Package Binder Attributes @itemize @bullet @item @b{General} @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to be used when binding code of the language, if there is no applicable attribute ^Switches^Switches^. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is either a language name or a source file name. Value is the list of switches to be used when binding code. Index is either the source file name of the executable to be bound or the language name of the code to be bound. @end itemize @item @b{Configuration - Binding} @itemize @bullet @item @b{Driver}: single, indexed, case-insensitive index Index is a language name. Value is the name of the application to be used when binding code of the language. @item @b{Required_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of the required switches to be used when binding code of the language. @item @b{Prefix}: single, indexed, case-insensitive index Index is a language name. Value is a prefix to be used for the binder exchange file name for the language. Used to have different binder exchange file names when binding different languages. @item @b{Objects_Path}: single,indexed, case-insensitive index Index is a language name. Value is the name of the environment variable that contains the path for the object directories. @item @b{Object_Path_File}: single,indexed, case-insensitive index Index is a language name. Value is the name of the environment variable. The value of the environment variable is the path name of a text file that contains the list of object directories. @end itemize @end itemize @node Package Builder Attributes @subsubsection Package Builder Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of builder switches to be used when building an executable of the language, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is either a language name or a source file name. Value is the list of builder switches to be used when building an executable. Index is either the source file name of the executable to be built or its language name. @item @b{Global_Compilation_Switches}: list, optional index, indexed, case-insensitive index Index is either a language name or a source file name. Value is the list of compilation switches to be used when building an executable. Index is either the source file name of the executable to be built or its language name. @item @b{Executable}: single, indexed, case-insensitive index Index is an executable source file name. Value is the simple file name of the executable to be built. @item @b{Executable_Suffix}: single Value is the extension of the file names of executable. When not specified, the extension is the default extension of executables on the platform. @item @b{Global_Configuration_Pragmas}: single Value is the file name of a configuration pragmas file that is specified to the Ada compiler when compiling any Ada source in the project tree. @item @b{Global_Config_File}: single, indexed, case-insensitive index Index is a language name. Value is the file name of a configuration file that is specified to the compiler when compiling any source of the language in the project tree. @end itemize @ifclear FSFEDITION @node Package Check Attributes @subsubsection Package Check Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatcheck} for a source of the language, if there is no applicable attribute ^Switches^Switches^. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatcheck} for the source. @end itemize @end ifclear @node Package Clean Attributes @subsubsection Package Clean Attributes @itemize @bullet @item @b{^Switches^Switches^}: list Value is a list of switches to be used by the cleaning application. @item @b{Source_Artifact_Extensions}: list, indexed, case-insensitive index Index is a language names. Value is the list of extensions for file names derived from object file names that need to be cleaned in the object directory of the project. @item @b{Object_Artifact_Extensions}: list, indexed, case-insensitive index Index is a language names. Value is the list of extensions for file names derived from source file names that need to be cleaned in the object directory of the project. @item @b{Artifacts_In_Object_Dir}: single Value is a list of file names expressed as regular expressions that are to be deleted by gprclean in the object directory of the project. @item @b{Artifacts_In_Exec_Dir}: single Value is list of file names expressed as regular expressions that are to be deleted by gprclean in the exec directory of the main project. @end itemize @node Package Compiler Attributes @subsubsection Package Compiler Attributes @itemize @bullet @item @b{General} @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking the compiler for the language for a source of the project, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language. @item @b{Local_Configuration_Pragmas}: single Value is the file name of a configuration pragmas file that is specified to the Ada compiler when compiling any Ada source in the project. @item @b{Local_Config_File}: single, indexed, case-insensitive index Index is a language name. Value is the file name of a configuration file that is specified to the compiler when compiling any source of the language in the project. @end itemize @item @b{Configuration - Compiling} @itemize @bullet @item @b{Driver}: single, indexed, case-insensitive index Index is a language name. Value is the name of the executable for the compiler of the language. @item @b{Language_Kind}: single, indexed, case-insensitive index Index is a language name. Indicates the kind of the language, either file based or unit based. Only authorized case-insensitive values are "unit_based" and "file_based" (the default). @item @b{Dependency_Kind}: single, indexed, case-insensitive index Index is a language name. Indicates how the dependencies are handled for the language. Only authorized case-insensitive values are "makefile", "ali_file", "ali_closure" or "none" (the default). @item @b{Required_Switches}: list, indexed, case-insensitive index Equivalent to attribute Leading_Required_Switches. @item @b{Leading_Required_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of the minimum switches to be used at the beginning of the command line when invoking the compiler for the language. @item @b{Trailing_Required_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of the minimum switches to be used at the end of the command line when invoking the compiler for the language. @item @b{PIC_Option}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to be used when compiling a source of the language when the project is a shared library project. @item @b{Path_Syntax}: single, indexed, case-insensitive index Index is a language name. Value is the kind of path syntax to be used when invoking the compiler for the language. Only authorized case-insensitive values are "canonical" and "host" (the default). @item @b{Source_File_Switches}: single, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used just before the path name of the source to compile when invoking the compiler for a source of the language. @item @b{Object_File_Suffix}: single, indexed, case-insensitive index Index is a language name. Value is the extension of the object files created by the compiler of the language. When not specified, the extension is the default one for the platform. @item @b{Object_File_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to be used by the compiler of the language to specify the path name of the object file. When not specified, the switch used is "-o". @item @b{Multi_Unit_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to be used to compile a unit in a multi unit source of the language. The index of the unit in the source is concatenated with the last switches in the list. @item @b{Multi_Unit_Object_Separator}: single, indexed, case-insensitive index Index is a language name. Value is the string to be used in the object file name before the index of the unit, when compiling a unit in a multi unit source of the language. @end itemize @item @b{Configuration - Mapping Files} @itemize @bullet @item @b{Mapping_File_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to be used to specify a mapping file when invoking the compiler for a source of the language. @item @b{Mapping_Spec_Suffix}: single, indexed, case-insensitive index Index is a language name. Value is the suffix to be used in a mapping file to indicate that the source is a spec. @item @b{Mapping_Body_Suffix}: single, indexed, case-insensitive index Index is a language name. Value is the suffix to be used in a mapping file to indicate that the source is a body. @end itemize @item @b{Configuration - Config Files} @itemize @bullet @item @b{Config_File_Switches}: list: single, indexed, case-insensitive index Index is a language name. Value is the list of switches to specify to the compiler of the language a configuration file. @item @b{Config_Body_File_Name}: single, indexed, case-insensitive index Index is a language name. Value is the template to be used to indicate a configuration specific to a body of the language in a configuration file. @item @b{Config_Body_File_Name_Index}: single, indexed, case-insensitive index Index is a language name. Value is the template to be used to indicate a configuration specific to the body a unit in a multi unit source of the language in a configuration file. @item @b{Config_Body_File_Name_Pattern}: single, indexed, case-insensitive index Index is a language name. Value is the template to be used to indicate a configuration for all bodies of the languages in a configuration file. @item @b{Config_Spec_File_Name}: single, indexed, case-insensitive index Index is a language name. Value is the template to be used to indicate a configuration specific to a spec of the language in a configuration file. @item @b{Config_Spec_File_Name_Index}: single, indexed, case-insensitive index Index is a language name. Value is the template to be used to indicate a configuration specific to the spec a unit in a multi unit source of the language in a configuration file. @item @b{Config_Spec_File_Name_Pattern}: single, indexed, case-insensitive index Index is a language name. Value is the template to be used to indicate a configuration for all specs of the languages in a configuration file. @item @b{Config_File_Unique}: single, indexed, case-insensitive index Index is a language name. Indicates if there should be only one configuration file specified to the compiler of the language. Only authorized case-insensitive values are "true" and "false" (the default). @end itemize @item @b{Configuration - Dependencies} @itemize @bullet @item @b{Dependency_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to be used to specify to the compiler the dependency file when the dependency kind of the language is file based, and when Dependency_Driver is not specified for the language. @item @b{Dependency_Driver}: list, indexed, case-insensitive index Index is a language name. Value is the name of the executable to be used to create the dependency file for a source of the language, followed by the required switches. @end itemize @item @b{Configuration - Search Paths} @itemize @bullet @item @b{Include_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to specify to the compiler of the language to indicate a directory to look for sources. @item @b{Include_Path}: single, indexed, case-insensitive index Index is a language name. Value is the name of an environment variable that contains the path of all the directories that the compiler of the language may search for sources. @item @b{Include_Path_File}: single, indexed, case-insensitive index Index is a language name. Value is the name of an environment variable the value of which is the path name of a text file that contains the directories that the compiler of the language may search for sources. @item @b{Object_Path_Switches}: list, indexed, case-insensitive index Index is a language name. Value is the list of switches to specify to the compiler of the language the name of a text file that contains the list of object directories. When this attribute is not declared, the text file is not created. @end itemize @end itemize @node Package Cross_Reference Attributes @subsubsection Package Cross_Reference Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatxref} for a source of the language, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatxref} for the source. @end itemize @ifclear FSFEDITION @node Package Eliminate Attributes @subsubsection Package Eliminate Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatelim} for a source of the language, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatelim} for the source. @end itemize @end ifclear @node Package Finder Attributes @subsubsection Package Finder Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatfind} for a source of the language, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatfind} for the source. @end itemize @node Package ^gnatls^gnatls^ Attributes @subsubsection Package ^gnatls^gnatls^ Attributes @itemize @bullet @item @b{^Switches^Switches^}: list Value is a list of switches to be used when invoking @code{gnatls}. @end itemize @ifclear FSFEDITION @node Package ^gnatstub^gnatstub^ Attributes @subsubsection Package ^gnatstub^gnatstub^ Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatstub} for a source of the language, if there is no applicable attribute ^Switches^Switches^. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatstub} for the source. @end itemize @end ifclear @node Package IDE Attributes @subsubsection Package IDE Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed Index is the name of an external tool that the GNAT Programming System (GPS) is supporting. Value is a list of switches to use when invoking that tool. @item @b{Remote_Host}: single Value is a string that designates the remote host in a cross-compilation environment, to be used for remote compilation and debugging. This attribute should not be specified when running on the local machine. @item @b{Program_Host}: single Value is a string that specifies the name of IP address of the embedded target in a cross-compilation environment, on which the program should execute. @item @b{Communication_Protocol}: single Value is the name of the protocol to use to communicate with the target in a cross-compilation environment, for example @code{"wtx"} or @code{"vxworks"}. @item @b{Compiler_Command}: single, indexed, case-insensitive index Index is a language Name. Value is a string that denotes the command to be used to invoke the compiler. The value of @code{Compiler_Command ("Ada")} is expected to be compatible with @command{gnatmake}, in particular in the handling of switches. @item @b{Debugger_Command}: single Value is a string that specifies the name of the debugger to be used, such as gdb, powerpc-wrs-vxworks-gdb or gdb-4. @item @b{^gnatlist^gnatlist^}: single Value is a string that specifies the name of the @command{^gnatls^gnatls^} utility to be used to retrieve information about the predefined path; for example, @code{"^gnatls^gnatls^"}, @code{"powerpc-wrs-vxworks-gnatls"}. @item @b{VCS_Kind}: single Value is a string used to specify the Version Control System (VCS) to be used for this project, for example "Subversion", "ClearCase". If the value is set to "Auto", the IDE will try to detect the actual VCS used on the list of supported ones. @item @b{VCS_File_Check}: single Value is a string that specifies the command used by the VCS to check the validity of a file, either when the user explicitly asks for a check, or as a sanity check before doing the check-in. @item @b{VCS_Log_Check}: single Value is a string that specifies the command used by the VCS to check the validity of a log file. @item @b{Documentation_Dir}: single Value is the directory used to generate the documentation of source code. @end itemize @node Package Install Attributes @subsubsection Package Install Attributes @itemize @bullet @item @b{Prefix}: single Value is the install destination directory. @item @b{Sources_Subdir}: single Value is the sources directory or subdirectory of Prefix. @item @b{Exec_Subdir}: single Value is the executables directory or subdirectory of Prefix. @item @b{Lib_Subdir}: single Value is library directory or subdirectory of Prefix. @item @b{Project_Subdir}: single Value is the project directory or subdirectory of Prefix. @item @b{Active}: single Indicates that the project is to be installed or not. Case-insensitive value "false" means that the project is not to be installed, all other values mean that the project is to be installed. @end itemize @node Package Linker Attributes @subsubsection Package Linker Attributes @itemize @bullet @item @b{General} @itemize @bullet @item @b{Required_Switches}: list Value is a list of switches that are required when invoking the linker to link an executable. @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches for the linker when linking an executable for a main source of the language, when there is no applicable Switches. @item @b{Leading_Switches}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name or a language name. Value is the list of switches to be used at the beginning of the command line when invoking the linker to build an executable for the source or for its language. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name or a language name. Value is the list of switches to be used when invoking the linker to build an executable for the source or for its language. @item @b{Trailing_Switches}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name or a language name. Value is the list of switches to be used at the end of the command line when invoking the linker to build an executable for the source or for its language. These switches may override the Required_Switches. @item @b{Linker_Options}: list Value is a list of switches/options that are to be added when linking an executable from a project importing the current project directly or indirectly. Linker_Options are not used when linking an executable from the current project. @item @b{Map_File_Option}: single Value is the switch to specify the map file name that the linker needs to create. @end itemize @item @b{Configuration - Linking} @itemize @bullet @item @b{Driver}: single Value is the name of the linker executable. @end itemize @item @b{Configuration - Response Files} @itemize @bullet @item @b{Max_Command_Line_Length}: single Value is the maximum number of character in the command line when invoking the linker to link an executable. @item @b{Response_File_Format}: single Indicates the kind of response file to create when the length of the linking command line is too large. Only authorized case-insensitive values are "none", "gnu", "object_list", "gcc_gnu", "gcc_option_list" and "gcc_object_list". @item @b{Response_File_Switches}: list Value is the list of switches to specify a response file to the linker. @end itemize @end itemize @ifclear FSFEDITION @node Package Metrics Attribute @subsubsection Package Metrics Attribute @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatmetric} for a source of the language, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatmetric} for the source. @end itemize @end ifclear @node Package Naming Attributes @subsubsection Package Naming Attributes @itemize @bullet @item @b{Specification_Suffix}: single, indexed, case-insensitive index Equivalent to attribute Spec_Suffix. @item @b{Spec_Suffix}: single, indexed, case-insensitive index Index is a language name. Value is the extension of file names for specs of the language. @item @b{Implementation_Suffix}: single, indexed, case-insensitive index Equivalent to attribute Body_Suffix. @item @b{Body_Suffix}: single, indexed, case-insensitive index Index is a language name. Value is the extension of file names for bodies of the language. @item @b{Separate_Suffix}: single Value is the extension of file names for subunits of Ada. @item @b{Casing}: single Indicates the casing of sources of the Ada language. Only authorized case-insensitive values are "lowercase", "uppercase" and "mixedcase". @item @b{Dot_Replacement}: single Value is the string that replace the dot of unit names in the source file names of the Ada language. @item @b{Specification}: single, optional index, indexed, case-insensitive index Equivalent to attribute Spec. @item @b{Spec}: single, optional index, indexed, case-insensitive index Index is a unit name. Value is the file name of the spec of the unit. @item @b{Implementation}: single, optional index, indexed, case-insensitive index Equivalent to attribute Body. @item @b{Body}: single, optional index, indexed, case-insensitive index Index is a unit name. Value is the file name of the body of the unit. @item @b{Specification_Exceptions}: list, indexed, case-insensitive index Index is a language name. Value is a list of specs for the language that do not necessarily follow the naming scheme for the language and that may or may not be found in the source directories of the project. @item @b{Implementation_Exceptions}: list, indexed, case-insensitive index Index is a language name. Value is a list of bodies for the language that do not necessarily follow the naming scheme for the language and that may or may not be found in the source directories of the project. @end itemize @ifclear FSFEDITION @node Package Pretty_Printer Attributes @subsubsection Package Pretty_Printer Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatpp} for a source of the language, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatpp} for the source. @end itemize @end ifclear @node Package Remote Attributes @subsubsection Package Remote Attributes @itemize @bullet @item @b{Included_Patterns}: list If this attribute is defined it sets the patterns to synchronized from the master to the slaves. It is exclusive with Excluded_Patterns, that is it is an error to define both. @item @b{Included_Artifact_Patterns}: list If this attribute is defined it sets the patterns of compilation artifacts to synchronized from the slaves to the build master. This attribute replace the default hard-coded patterns. @item @b{Excluded_Patterns}: list Set of patterns to ignore when synchronizing sources from the build master to the slaves. A set of predefined patterns are supported (e.g. *.o, *.ali, *.exe, etc.), this attributes make it possible to add some more patterns. @item @b{Root_Dir}: single Value is the root directory used by the slave machines. @end itemize @node Package Stack Attributes @subsubsection Package Stack Attributes @itemize @bullet @item @b{^Switches^Switches^}: list Value is the list of switches to be used when invoking @code{gnatstack}. @end itemize @node Package Synchronize Attributes @subsubsection Package Synchronize Attributes @itemize @bullet @item @b{Default_Switches}: list, indexed, case-insensitive index Index is a language name. Value is a list of switches to be used when invoking @code{gnatsync} for a source of the language, if there is no applicable attribute Switches. @item @b{^Switches^Switches^}: list, optional index, indexed, case-insensitive index, others allowed Index is a source file name. Value is the list of switches to be used when invoking @code{gnatsync} for the source. @end itemize gprbuild-gpl-2014-src/gnat/prj-tree.adb0000644000076700001450000027427612323721731017306 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . T R E E -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Osint; use Osint; with Prj.Env; use Prj.Env; with Prj.Err; with Ada.Unchecked_Deallocation; package body Prj.Tree is Node_With_Comments : constant array (Project_Node_Kind) of Boolean := (N_Project => True, N_With_Clause => True, N_Project_Declaration => False, N_Declarative_Item => False, N_Package_Declaration => True, N_String_Type_Declaration => True, N_Literal_String => False, N_Attribute_Declaration => True, N_Typed_Variable_Declaration => True, N_Variable_Declaration => True, N_Expression => False, N_Term => False, N_Literal_String_List => False, N_Variable_Reference => False, N_External_Value => False, N_Attribute_Reference => False, N_Case_Construction => True, N_Case_Item => True, N_Comment_Zones => True, N_Comment => True); -- Indicates the kinds of node that may have associated comments package Next_End_Nodes is new Table.Table (Table_Component_Type => Project_Node_Id, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 10, Table_Increment => 100, Table_Name => "Next_End_Nodes"); -- A stack of nodes to indicates to what node the next "end" is associated use Tree_Private_Part; End_Of_Line_Node : Project_Node_Id := Empty_Node; -- The node an end of line comment may be associated with Previous_Line_Node : Project_Node_Id := Empty_Node; -- The node an immediately following comment may be associated with Previous_End_Node : Project_Node_Id := Empty_Node; -- The node comments immediately following an "end" line may be -- associated with. Unkept_Comments : Boolean := False; -- Set to True when some comments may not be associated with any node function Comment_Zones_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id; -- Returns the ID of the N_Comment_Zones node associated with node Node. -- If there is not already an N_Comment_Zones node, create one and -- associate it with node Node. ------------------ -- Add_Comments -- ------------------ procedure Add_Comments (To : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; Where : Comment_Location) is Zone : Project_Node_Id := Empty_Node; Previous : Project_Node_Id := Empty_Node; begin pragma Assert (Present (To) and then In_Tree.Project_Nodes.Table (To).Kind /= N_Comment); Zone := In_Tree.Project_Nodes.Table (To).Comments; if No (Zone) then -- Create new N_Comment_Zones node Project_Node_Table.Increment_Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (Project_Node_Table.Last (In_Tree.Project_Nodes)) := (Kind => N_Comment_Zones, Qualifier => Unspecified, Expr_Kind => Undefined, Location => No_Location, Directory => No_Path, Variables => Empty_Node, Packages => Empty_Node, Pkg_Id => Empty_Package, Name => No_Name, Src_Index => 0, Path_Name => No_Path, Value => No_Name, Field1 => Empty_Node, Field2 => Empty_Node, Field3 => Empty_Node, Field4 => Empty_Node, Flag1 => False, Flag2 => False, Comments => Empty_Node); Zone := Project_Node_Table.Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (To).Comments := Zone; end if; if Where = End_Of_Line then In_Tree.Project_Nodes.Table (Zone).Value := Comments.Table (1).Value; else -- Get each comments in the Comments table and link them to node To for J in 1 .. Comments.Last loop -- Create new N_Comment node if (Where = After or else Where = After_End) and then Token /= Tok_EOF and then Comments.Table (J).Follows_Empty_Line then Comments.Table (1 .. Comments.Last - J + 1) := Comments.Table (J .. Comments.Last); Comments.Set_Last (Comments.Last - J + 1); return; end if; Project_Node_Table.Increment_Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (Project_Node_Table.Last (In_Tree.Project_Nodes)) := (Kind => N_Comment, Qualifier => Unspecified, Expr_Kind => Undefined, Flag1 => Comments.Table (J).Follows_Empty_Line, Flag2 => Comments.Table (J).Is_Followed_By_Empty_Line, Location => No_Location, Directory => No_Path, Variables => Empty_Node, Packages => Empty_Node, Pkg_Id => Empty_Package, Name => No_Name, Src_Index => 0, Path_Name => No_Path, Value => Comments.Table (J).Value, Field1 => Empty_Node, Field2 => Empty_Node, Field3 => Empty_Node, Field4 => Empty_Node, Comments => Empty_Node); -- If this is the first comment, put it in the right field of -- the node Zone. if No (Previous) then case Where is when Before => In_Tree.Project_Nodes.Table (Zone).Field1 := Project_Node_Table.Last (In_Tree.Project_Nodes); when After => In_Tree.Project_Nodes.Table (Zone).Field2 := Project_Node_Table.Last (In_Tree.Project_Nodes); when Before_End => In_Tree.Project_Nodes.Table (Zone).Field3 := Project_Node_Table.Last (In_Tree.Project_Nodes); when After_End => In_Tree.Project_Nodes.Table (Zone).Comments := Project_Node_Table.Last (In_Tree.Project_Nodes); when End_Of_Line => null; end case; else -- When it is not the first, link it to the previous one In_Tree.Project_Nodes.Table (Previous).Comments := Project_Node_Table.Last (In_Tree.Project_Nodes); end if; -- This node becomes the previous one for the next comment, if -- there is one. Previous := Project_Node_Table.Last (In_Tree.Project_Nodes); end loop; end if; -- Empty the Comments table, so that there is no risk to link the same -- comments to another node. Comments.Set_Last (0); end Add_Comments; -------------------------------- -- Associative_Array_Index_Of -- -------------------------------- function Associative_Array_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); return In_Tree.Project_Nodes.Table (Node).Value; end Associative_Array_Index_Of; ---------------------------- -- Associative_Package_Of -- ---------------------------- function Associative_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration)); return In_Tree.Project_Nodes.Table (Node).Field3; end Associative_Package_Of; ---------------------------- -- Associative_Project_Of -- ---------------------------- function Associative_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration)); return In_Tree.Project_Nodes.Table (Node).Field2; end Associative_Project_Of; ---------------------- -- Case_Insensitive -- ---------------------- function Case_Insensitive (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); return In_Tree.Project_Nodes.Table (Node).Flag1; end Case_Insensitive; -------------------------------- -- Case_Variable_Reference_Of -- -------------------------------- function Case_Variable_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction); return In_Tree.Project_Nodes.Table (Node).Field1; end Case_Variable_Reference_Of; ---------------------- -- Comment_Zones_Of -- ---------------------- function Comment_Zones_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is Zone : Project_Node_Id; begin pragma Assert (Present (Node)); Zone := In_Tree.Project_Nodes.Table (Node).Comments; -- If there is not already an N_Comment_Zones associated, create a new -- one and associate it with node Node. if No (Zone) then Project_Node_Table.Increment_Last (In_Tree.Project_Nodes); Zone := Project_Node_Table.Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (Zone) := (Kind => N_Comment_Zones, Qualifier => Unspecified, Location => No_Location, Directory => No_Path, Expr_Kind => Undefined, Variables => Empty_Node, Packages => Empty_Node, Pkg_Id => Empty_Package, Name => No_Name, Src_Index => 0, Path_Name => No_Path, Value => No_Name, Field1 => Empty_Node, Field2 => Empty_Node, Field3 => Empty_Node, Field4 => Empty_Node, Flag1 => False, Flag2 => False, Comments => Empty_Node); In_Tree.Project_Nodes.Table (Node).Comments := Zone; end if; return Zone; end Comment_Zones_Of; ----------------------- -- Current_Item_Node -- ----------------------- function Current_Item_Node (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item); return In_Tree.Project_Nodes.Table (Node).Field1; end Current_Item_Node; ------------------ -- Current_Term -- ------------------ function Current_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Term); return In_Tree.Project_Nodes.Table (Node).Field1; end Current_Term; -------------------------- -- Default_Project_Node -- -------------------------- function Default_Project_Node (In_Tree : Project_Node_Tree_Ref; Of_Kind : Project_Node_Kind; And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id is Result : Project_Node_Id; Zone : Project_Node_Id; Previous : Project_Node_Id; begin -- Create new node with specified kind and expression kind Project_Node_Table.Increment_Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (Project_Node_Table.Last (In_Tree.Project_Nodes)) := (Kind => Of_Kind, Qualifier => Unspecified, Location => No_Location, Directory => No_Path, Expr_Kind => And_Expr_Kind, Variables => Empty_Node, Packages => Empty_Node, Pkg_Id => Empty_Package, Name => No_Name, Src_Index => 0, Path_Name => No_Path, Value => No_Name, Field1 => Empty_Node, Field2 => Empty_Node, Field3 => Empty_Node, Field4 => Empty_Node, Flag1 => False, Flag2 => False, Comments => Empty_Node); -- Save the new node for the returned value Result := Project_Node_Table.Last (In_Tree.Project_Nodes); if Comments.Last > 0 then -- If this is not a node with comments, then set the flag if not Node_With_Comments (Of_Kind) then Unkept_Comments := True; elsif Of_Kind /= N_Comment and then Of_Kind /= N_Comment_Zones then Project_Node_Table.Increment_Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (Project_Node_Table.Last (In_Tree.Project_Nodes)) := (Kind => N_Comment_Zones, Qualifier => Unspecified, Expr_Kind => Undefined, Location => No_Location, Directory => No_Path, Variables => Empty_Node, Packages => Empty_Node, Pkg_Id => Empty_Package, Name => No_Name, Src_Index => 0, Path_Name => No_Path, Value => No_Name, Field1 => Empty_Node, Field2 => Empty_Node, Field3 => Empty_Node, Field4 => Empty_Node, Flag1 => False, Flag2 => False, Comments => Empty_Node); Zone := Project_Node_Table.Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (Result).Comments := Zone; Previous := Empty_Node; for J in 1 .. Comments.Last loop -- Create a new N_Comment node Project_Node_Table.Increment_Last (In_Tree.Project_Nodes); In_Tree.Project_Nodes.Table (Project_Node_Table.Last (In_Tree.Project_Nodes)) := (Kind => N_Comment, Qualifier => Unspecified, Expr_Kind => Undefined, Flag1 => Comments.Table (J).Follows_Empty_Line, Flag2 => Comments.Table (J).Is_Followed_By_Empty_Line, Location => No_Location, Directory => No_Path, Variables => Empty_Node, Packages => Empty_Node, Pkg_Id => Empty_Package, Name => No_Name, Src_Index => 0, Path_Name => No_Path, Value => Comments.Table (J).Value, Field1 => Empty_Node, Field2 => Empty_Node, Field3 => Empty_Node, Field4 => Empty_Node, Comments => Empty_Node); -- Link it to the N_Comment_Zones node, if it is the first, -- otherwise to the previous one. if No (Previous) then In_Tree.Project_Nodes.Table (Zone).Field1 := Project_Node_Table.Last (In_Tree.Project_Nodes); else In_Tree.Project_Nodes.Table (Previous).Comments := Project_Node_Table.Last (In_Tree.Project_Nodes); end if; -- This new node will be the previous one for the next -- N_Comment node, if there is one. Previous := Project_Node_Table.Last (In_Tree.Project_Nodes); end loop; -- Empty the Comments table after all comments have been processed Comments.Set_Last (0); end if; end if; return Result; end Default_Project_Node; ------------------ -- Directory_Of -- ------------------ function Directory_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Path_Name_Type is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return In_Tree.Project_Nodes.Table (Node).Directory; end Directory_Of; ------------------------- -- End_Of_Line_Comment -- ------------------------- function End_Of_Line_Comment (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id is Zone : Project_Node_Id := Empty_Node; begin pragma Assert (Present (Node)); Zone := In_Tree.Project_Nodes.Table (Node).Comments; if No (Zone) then return No_Name; else return In_Tree.Project_Nodes.Table (Zone).Value; end if; end End_Of_Line_Comment; ------------------------ -- Expression_Kind_Of -- ------------------------ function Expression_Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Variable_Kind is begin pragma Assert (Present (Node) and then -- should use Nkind_In here ??? why not??? (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Expression or else In_Tree.Project_Nodes.Table (Node).Kind = N_Term or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value)); return In_Tree.Project_Nodes.Table (Node).Expr_Kind; end Expression_Kind_Of; ------------------- -- Expression_Of -- ------------------- function Expression_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration)); return In_Tree.Project_Nodes.Table (Node).Field1; end Expression_Of; ------------------------- -- Extended_Project_Of -- ------------------------- function Extended_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration); return In_Tree.Project_Nodes.Table (Node).Field2; end Extended_Project_Of; ------------------------------ -- Extended_Project_Path_Of -- ------------------------------ function Extended_Project_Path_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Path_Name_Type is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return Path_Name_Type (In_Tree.Project_Nodes.Table (Node).Value); end Extended_Project_Path_Of; -------------------------- -- Extending_Project_Of -- -------------------------- function Extending_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration); return In_Tree.Project_Nodes.Table (Node).Field3; end Extending_Project_Of; --------------------------- -- External_Reference_Of -- --------------------------- function External_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value); return In_Tree.Project_Nodes.Table (Node).Field1; end External_Reference_Of; ------------------------- -- External_Default_Of -- ------------------------- function External_Default_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value); return In_Tree.Project_Nodes.Table (Node).Field2; end External_Default_Of; ------------------------ -- First_Case_Item_Of -- ------------------------ function First_Case_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction); return In_Tree.Project_Nodes.Table (Node).Field2; end First_Case_Item_Of; --------------------- -- First_Choice_Of -- --------------------- function First_Choice_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item); return In_Tree.Project_Nodes.Table (Node).Field1; end First_Choice_Of; ------------------------- -- First_Comment_After -- ------------------------- function First_Comment_After (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is Zone : Project_Node_Id := Empty_Node; begin pragma Assert (Present (Node)); Zone := In_Tree.Project_Nodes.Table (Node).Comments; if No (Zone) then return Empty_Node; else return In_Tree.Project_Nodes.Table (Zone).Field2; end if; end First_Comment_After; ----------------------------- -- First_Comment_After_End -- ----------------------------- function First_Comment_After_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is Zone : Project_Node_Id := Empty_Node; begin pragma Assert (Present (Node)); Zone := In_Tree.Project_Nodes.Table (Node).Comments; if No (Zone) then return Empty_Node; else return In_Tree.Project_Nodes.Table (Zone).Comments; end if; end First_Comment_After_End; -------------------------- -- First_Comment_Before -- -------------------------- function First_Comment_Before (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is Zone : Project_Node_Id := Empty_Node; begin pragma Assert (Present (Node)); Zone := In_Tree.Project_Nodes.Table (Node).Comments; if No (Zone) then return Empty_Node; else return In_Tree.Project_Nodes.Table (Zone).Field1; end if; end First_Comment_Before; ------------------------------ -- First_Comment_Before_End -- ------------------------------ function First_Comment_Before_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is Zone : Project_Node_Id := Empty_Node; begin pragma Assert (Present (Node)); Zone := In_Tree.Project_Nodes.Table (Node).Comments; if No (Zone) then return Empty_Node; else return In_Tree.Project_Nodes.Table (Zone).Field3; end if; end First_Comment_Before_End; ------------------------------- -- First_Declarative_Item_Of -- ------------------------------- function First_Declarative_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item or else In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration)); if In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration then return In_Tree.Project_Nodes.Table (Node).Field1; else return In_Tree.Project_Nodes.Table (Node).Field2; end if; end First_Declarative_Item_Of; ------------------------------ -- First_Expression_In_List -- ------------------------------ function First_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List); return In_Tree.Project_Nodes.Table (Node).Field1; end First_Expression_In_List; -------------------------- -- First_Literal_String -- -------------------------- function First_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_String_Type_Declaration); return In_Tree.Project_Nodes.Table (Node).Field1; end First_Literal_String; ---------------------- -- First_Package_Of -- ---------------------- function First_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Package_Declaration_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return In_Tree.Project_Nodes.Table (Node).Packages; end First_Package_Of; -------------------------- -- First_String_Type_Of -- -------------------------- function First_String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return In_Tree.Project_Nodes.Table (Node).Field3; end First_String_Type_Of; ---------------- -- First_Term -- ---------------- function First_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Expression); return In_Tree.Project_Nodes.Table (Node).Field1; end First_Term; ----------------------- -- First_Variable_Of -- ----------------------- function First_Variable_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Variable_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project or else In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration)); return In_Tree.Project_Nodes.Table (Node).Variables; end First_Variable_Of; -------------------------- -- First_With_Clause_Of -- -------------------------- function First_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return In_Tree.Project_Nodes.Table (Node).Field1; end First_With_Clause_Of; ------------------------ -- Follows_Empty_Line -- ------------------------ function Follows_Empty_Line (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Comment); return In_Tree.Project_Nodes.Table (Node).Flag1; end Follows_Empty_Line; ---------- -- Hash -- ---------- function Hash (N : Project_Node_Id) return Header_Num is begin return Header_Num (N mod Project_Node_Id (Header_Num'Last)); end Hash; ---------------- -- Initialize -- ---------------- procedure Initialize (Tree : Project_Node_Tree_Ref) is begin Project_Node_Table.Init (Tree.Project_Nodes); Projects_Htable.Reset (Tree.Projects_HT); end Initialize; -------------------- -- Override_Flags -- -------------------- procedure Override_Flags (Self : in out Environment; Flags : Prj.Processing_Flags) is begin Self.Flags := Flags; end Override_Flags; ---------------- -- Initialize -- ---------------- procedure Initialize (Self : out Environment; Flags : Processing_Flags) is begin -- Do not reset the external references, in case we are reloading a -- project, since we want to preserve the current environment. But we -- still need to ensure that the external references are properly -- initialized. Prj.Ext.Initialize (Self.External); Self.Flags := Flags; end Initialize; ------------------------- -- Initialize_And_Copy -- ------------------------- procedure Initialize_And_Copy (Self : out Environment; Copy_From : Environment) is begin Self.Flags := Copy_From.Flags; Prj.Ext.Initialize (Self.External, Copy_From => Copy_From.External); Prj.Env.Copy (From => Copy_From.Project_Path, To => Self.Project_Path); end Initialize_And_Copy; ---------- -- Free -- ---------- procedure Free (Self : in out Environment) is begin Prj.Ext.Free (Self.External); Free (Self.Project_Path); end Free; ---------- -- Free -- ---------- procedure Free (Proj : in out Project_Node_Tree_Ref) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Project_Node_Tree_Data, Project_Node_Tree_Ref); begin if Proj /= null then Project_Node_Table.Free (Proj.Project_Nodes); Projects_Htable.Reset (Proj.Projects_HT); Unchecked_Free (Proj); end if; end Free; ------------------------------- -- Is_Followed_By_Empty_Line -- ------------------------------- function Is_Followed_By_Empty_Line (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Comment); return In_Tree.Project_Nodes.Table (Node).Flag2; end Is_Followed_By_Empty_Line; ---------------------- -- Is_Extending_All -- ---------------------- function Is_Extending_All (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project or else In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause)); return In_Tree.Project_Nodes.Table (Node).Flag2; end Is_Extending_All; ------------------------- -- Is_Not_Last_In_List -- ------------------------- function Is_Not_Last_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause); return In_Tree.Project_Nodes.Table (Node).Flag1; end Is_Not_Last_In_List; ------------------------------------- -- Imported_Or_Extended_Project_Of -- ------------------------------------- function Imported_Or_Extended_Project_Of (Project : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; With_Name : Name_Id) return Project_Node_Id is With_Clause : Project_Node_Id; Result : Project_Node_Id := Empty_Node; begin -- First check all the imported projects With_Clause := First_With_Clause_Of (Project, In_Tree); while Present (With_Clause) loop -- Only non limited imported project may be used as prefix of -- variables or attributes. Result := Non_Limited_Project_Node_Of (With_Clause, In_Tree); while Present (Result) loop if Name_Of (Result, In_Tree) = With_Name then return Result; end if; Result := Extended_Project_Of (Project_Declaration_Of (Result, In_Tree), In_Tree); end loop; With_Clause := Next_With_Clause_Of (With_Clause, In_Tree); end loop; -- If it is not an imported project, it might be an extended project if No (With_Clause) then Result := Project; loop Result := Extended_Project_Of (Project_Declaration_Of (Result, In_Tree), In_Tree); exit when No (Result) or else Name_Of (Result, In_Tree) = With_Name; end loop; end if; return Result; end Imported_Or_Extended_Project_Of; ------------- -- Kind_Of -- ------------- function Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind is begin pragma Assert (Present (Node)); return In_Tree.Project_Nodes.Table (Node).Kind; end Kind_Of; ----------------- -- Location_Of -- ----------------- function Location_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Source_Ptr is begin pragma Assert (Present (Node)); return In_Tree.Project_Nodes.Table (Node).Location; end Location_Of; ------------- -- Name_Of -- ------------- function Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id is begin pragma Assert (Present (Node)); return In_Tree.Project_Nodes.Table (Node).Name; end Name_Of; -------------------- -- Next_Case_Item -- -------------------- function Next_Case_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item); return In_Tree.Project_Nodes.Table (Node).Field3; end Next_Case_Item; ------------------ -- Next_Comment -- ------------------ function Next_Comment (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Comment); return In_Tree.Project_Nodes.Table (Node).Comments; end Next_Comment; --------------------------- -- Next_Declarative_Item -- --------------------------- function Next_Declarative_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item); return In_Tree.Project_Nodes.Table (Node).Field2; end Next_Declarative_Item; ----------------------------- -- Next_Expression_In_List -- ----------------------------- function Next_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Expression); return In_Tree.Project_Nodes.Table (Node).Field2; end Next_Expression_In_List; ------------------------- -- Next_Literal_String -- ------------------------- function Next_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String); return In_Tree.Project_Nodes.Table (Node).Field1; end Next_Literal_String; ----------------------------- -- Next_Package_In_Project -- ----------------------------- function Next_Package_In_Project (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration); return In_Tree.Project_Nodes.Table (Node).Field3; end Next_Package_In_Project; ---------------------- -- Next_String_Type -- ---------------------- function Next_String_Type (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_String_Type_Declaration); return In_Tree.Project_Nodes.Table (Node).Field2; end Next_String_Type; --------------- -- Next_Term -- --------------- function Next_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Term); return In_Tree.Project_Nodes.Table (Node).Field2; end Next_Term; ------------------- -- Next_Variable -- ------------------- function Next_Variable (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration)); return In_Tree.Project_Nodes.Table (Node).Field3; end Next_Variable; ------------------------- -- Next_With_Clause_Of -- ------------------------- function Next_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause); return In_Tree.Project_Nodes.Table (Node).Field2; end Next_With_Clause_Of; -------- -- No -- -------- function No (Node : Project_Node_Id) return Boolean is begin return Node = Empty_Node; end No; --------------------------------- -- Non_Limited_Project_Node_Of -- --------------------------------- function Non_Limited_Project_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause)); return In_Tree.Project_Nodes.Table (Node).Field3; end Non_Limited_Project_Node_Of; ------------------- -- Package_Id_Of -- ------------------- function Package_Id_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Package_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration); return In_Tree.Project_Nodes.Table (Node).Pkg_Id; end Package_Id_Of; --------------------- -- Package_Node_Of -- --------------------- function Package_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); return In_Tree.Project_Nodes.Table (Node).Field2; end Package_Node_Of; ------------------ -- Path_Name_Of -- ------------------ function Path_Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Path_Name_Type is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project or else In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause)); return In_Tree.Project_Nodes.Table (Node).Path_Name; end Path_Name_Of; ------------- -- Present -- ------------- function Present (Node : Project_Node_Id) return Boolean is begin return Node /= Empty_Node; end Present; ---------------------------- -- Project_Declaration_Of -- ---------------------------- function Project_Declaration_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return In_Tree.Project_Nodes.Table (Node).Field2; end Project_Declaration_Of; -------------------------- -- Project_Qualifier_Of -- -------------------------- function Project_Qualifier_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Qualifier is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return In_Tree.Project_Nodes.Table (Node).Qualifier; end Project_Qualifier_Of; ----------------------- -- Parent_Project_Of -- ----------------------- function Parent_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); return In_Tree.Project_Nodes.Table (Node).Field4; end Parent_Project_Of; ------------------------------------------- -- Project_File_Includes_Unkept_Comments -- ------------------------------------------- function Project_File_Includes_Unkept_Comments (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Boolean is Declaration : constant Project_Node_Id := Project_Declaration_Of (Node, In_Tree); begin return In_Tree.Project_Nodes.Table (Declaration).Flag1; end Project_File_Includes_Unkept_Comments; --------------------- -- Project_Node_Of -- --------------------- function Project_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); return In_Tree.Project_Nodes.Table (Node).Field1; end Project_Node_Of; ----------------------------------- -- Project_Of_Renamed_Package_Of -- ----------------------------------- function Project_Of_Renamed_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration); return In_Tree.Project_Nodes.Table (Node).Field1; end Project_Of_Renamed_Package_Of; -------------------------- -- Remove_Next_End_Node -- -------------------------- procedure Remove_Next_End_Node is begin Next_End_Nodes.Decrement_Last; end Remove_Next_End_Node; ----------------- -- Reset_State -- ----------------- procedure Reset_State is begin End_Of_Line_Node := Empty_Node; Previous_Line_Node := Empty_Node; Previous_End_Node := Empty_Node; Unkept_Comments := False; Comments.Set_Last (0); end Reset_State; ---------------------- -- Restore_And_Free -- ---------------------- procedure Restore_And_Free (S : in out Comment_State) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Comment_Array, Comments_Ptr); begin End_Of_Line_Node := S.End_Of_Line_Node; Previous_Line_Node := S.Previous_Line_Node; Previous_End_Node := S.Previous_End_Node; Next_End_Nodes.Set_Last (0); Unkept_Comments := S.Unkept_Comments; Comments.Set_Last (0); for J in S.Comments'Range loop Comments.Increment_Last; Comments.Table (Comments.Last) := S.Comments (J); end loop; Unchecked_Free (S.Comments); end Restore_And_Free; ---------- -- Save -- ---------- procedure Save (S : out Comment_State) is Cmts : constant Comments_Ptr := new Comment_Array (1 .. Comments.Last); begin for J in 1 .. Comments.Last loop Cmts (J) := Comments.Table (J); end loop; S := (End_Of_Line_Node => End_Of_Line_Node, Previous_Line_Node => Previous_Line_Node, Previous_End_Node => Previous_End_Node, Unkept_Comments => Unkept_Comments, Comments => Cmts); end Save; ---------- -- Scan -- ---------- procedure Scan (In_Tree : Project_Node_Tree_Ref) is Empty_Line : Boolean := False; begin -- If there are comments, then they will not be kept. Set the flag and -- clear the comments. if Comments.Last > 0 then Unkept_Comments := True; Comments.Set_Last (0); end if; -- Loop until a token other that End_Of_Line or Comment is found loop Prj.Err.Scanner.Scan; case Token is when Tok_End_Of_Line => if Prev_Token = Tok_End_Of_Line then Empty_Line := True; if Comments.Last > 0 then Comments.Table (Comments.Last).Is_Followed_By_Empty_Line := True; end if; end if; when Tok_Comment => -- If this is a line comment, add it to the comment table if Prev_Token = Tok_End_Of_Line or else Prev_Token = No_Token then Comments.Increment_Last; Comments.Table (Comments.Last) := (Value => Comment_Id, Follows_Empty_Line => Empty_Line, Is_Followed_By_Empty_Line => False); -- Otherwise, it is an end of line comment. If there is an -- end of line node specified, associate the comment with -- this node. elsif Present (End_Of_Line_Node) then declare Zones : constant Project_Node_Id := Comment_Zones_Of (End_Of_Line_Node, In_Tree); begin In_Tree.Project_Nodes.Table (Zones).Value := Comment_Id; end; -- Otherwise, this end of line node cannot be kept else Unkept_Comments := True; Comments.Set_Last (0); end if; Empty_Line := False; when others => -- If there are comments, where the first comment is not -- following an empty line, put the initial uninterrupted -- comment zone with the node of the preceding line (either -- a Previous_Line or a Previous_End node), if any. if Comments.Last > 0 and then not Comments.Table (1).Follows_Empty_Line then if Present (Previous_Line_Node) then Add_Comments (To => Previous_Line_Node, Where => After, In_Tree => In_Tree); elsif Present (Previous_End_Node) then Add_Comments (To => Previous_End_Node, Where => After_End, In_Tree => In_Tree); end if; end if; -- If there are still comments and the token is "end", then -- put these comments with the Next_End node, if any; -- otherwise, these comments cannot be kept. Always clear -- the comments. if Comments.Last > 0 and then Token = Tok_End then if Next_End_Nodes.Last > 0 then Add_Comments (To => Next_End_Nodes.Table (Next_End_Nodes.Last), Where => Before_End, In_Tree => In_Tree); else Unkept_Comments := True; end if; Comments.Set_Last (0); end if; -- Reset the End_Of_Line, Previous_Line and Previous_End nodes -- so that they are not used again. End_Of_Line_Node := Empty_Node; Previous_Line_Node := Empty_Node; Previous_End_Node := Empty_Node; -- And return exit; end case; end loop; end Scan; ------------------------------------ -- Set_Associative_Array_Index_Of -- ------------------------------------ procedure Set_Associative_Array_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Name_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); In_Tree.Project_Nodes.Table (Node).Value := To; end Set_Associative_Array_Index_Of; -------------------------------- -- Set_Associative_Package_Of -- -------------------------------- procedure Set_Associative_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration); In_Tree.Project_Nodes.Table (Node).Field3 := To; end Set_Associative_Package_Of; -------------------------------- -- Set_Associative_Project_Of -- -------------------------------- procedure Set_Associative_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration)); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Associative_Project_Of; -------------------------- -- Set_Case_Insensitive -- -------------------------- procedure Set_Case_Insensitive (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Boolean) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); In_Tree.Project_Nodes.Table (Node).Flag1 := To; end Set_Case_Insensitive; ------------------------------------ -- Set_Case_Variable_Reference_Of -- ------------------------------------ procedure Set_Case_Variable_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_Case_Variable_Reference_Of; --------------------------- -- Set_Current_Item_Node -- --------------------------- procedure Set_Current_Item_Node (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_Current_Item_Node; ---------------------- -- Set_Current_Term -- ---------------------- procedure Set_Current_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Term); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_Current_Term; ---------------------- -- Set_Directory_Of -- ---------------------- procedure Set_Directory_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Path_Name_Type) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Directory := To; end Set_Directory_Of; --------------------- -- Set_End_Of_Line -- --------------------- procedure Set_End_Of_Line (To : Project_Node_Id) is begin End_Of_Line_Node := To; end Set_End_Of_Line; ---------------------------- -- Set_Expression_Kind_Of -- ---------------------------- procedure Set_Expression_Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Variable_Kind) is begin pragma Assert (Present (Node) and then -- should use Nkind_In here ??? why not??? (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Expression or else In_Tree.Project_Nodes.Table (Node).Kind = N_Term or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value)); In_Tree.Project_Nodes.Table (Node).Expr_Kind := To; end Set_Expression_Kind_Of; ----------------------- -- Set_Expression_Of -- ----------------------- procedure Set_Expression_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration)); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_Expression_Of; ------------------------------- -- Set_External_Reference_Of -- ------------------------------- procedure Set_External_Reference_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_External_Reference_Of; ----------------------------- -- Set_External_Default_Of -- ----------------------------- procedure Set_External_Default_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_External_Default_Of; ---------------------------- -- Set_First_Case_Item_Of -- ---------------------------- procedure Set_First_Case_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_First_Case_Item_Of; ------------------------- -- Set_First_Choice_Of -- ------------------------- procedure Set_First_Choice_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_First_Choice_Of; ----------------------------- -- Set_First_Comment_After -- ----------------------------- procedure Set_First_Comment_After (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree); begin In_Tree.Project_Nodes.Table (Zone).Field2 := To; end Set_First_Comment_After; --------------------------------- -- Set_First_Comment_After_End -- --------------------------------- procedure Set_First_Comment_After_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree); begin In_Tree.Project_Nodes.Table (Zone).Comments := To; end Set_First_Comment_After_End; ------------------------------ -- Set_First_Comment_Before -- ------------------------------ procedure Set_First_Comment_Before (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree); begin In_Tree.Project_Nodes.Table (Zone).Field1 := To; end Set_First_Comment_Before; ---------------------------------- -- Set_First_Comment_Before_End -- ---------------------------------- procedure Set_First_Comment_Before_End (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree); begin In_Tree.Project_Nodes.Table (Zone).Field2 := To; end Set_First_Comment_Before_End; ------------------------ -- Set_Next_Case_Item -- ------------------------ procedure Set_Next_Case_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item); In_Tree.Project_Nodes.Table (Node).Field3 := To; end Set_Next_Case_Item; ---------------------- -- Set_Next_Comment -- ---------------------- procedure Set_Next_Comment (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Comment); In_Tree.Project_Nodes.Table (Node).Comments := To; end Set_Next_Comment; ----------------------------------- -- Set_First_Declarative_Item_Of -- ----------------------------------- procedure Set_First_Declarative_Item_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item or else In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration)); if In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration then In_Tree.Project_Nodes.Table (Node).Field1 := To; else In_Tree.Project_Nodes.Table (Node).Field2 := To; end if; end Set_First_Declarative_Item_Of; ---------------------------------- -- Set_First_Expression_In_List -- ---------------------------------- procedure Set_First_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_First_Expression_In_List; ------------------------------ -- Set_First_Literal_String -- ------------------------------ procedure Set_First_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_String_Type_Declaration); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_First_Literal_String; -------------------------- -- Set_First_Package_Of -- -------------------------- procedure Set_First_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Package_Declaration_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Packages := To; end Set_First_Package_Of; ------------------------------ -- Set_First_String_Type_Of -- ------------------------------ procedure Set_First_String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Field3 := To; end Set_First_String_Type_Of; -------------------- -- Set_First_Term -- -------------------- procedure Set_First_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Expression); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_First_Term; --------------------------- -- Set_First_Variable_Of -- --------------------------- procedure Set_First_Variable_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Variable_Node_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project or else In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration)); In_Tree.Project_Nodes.Table (Node).Variables := To; end Set_First_Variable_Of; ------------------------------ -- Set_First_With_Clause_Of -- ------------------------------ procedure Set_First_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_First_With_Clause_Of; -------------------------- -- Set_Is_Extending_All -- -------------------------- procedure Set_Is_Extending_All (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project or else In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause)); In_Tree.Project_Nodes.Table (Node).Flag2 := True; end Set_Is_Extending_All; ----------------------------- -- Set_Is_Not_Last_In_List -- ----------------------------- procedure Set_Is_Not_Last_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause); In_Tree.Project_Nodes.Table (Node).Flag1 := True; end Set_Is_Not_Last_In_List; ----------------- -- Set_Kind_Of -- ----------------- procedure Set_Kind_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Kind) is begin pragma Assert (Present (Node)); In_Tree.Project_Nodes.Table (Node).Kind := To; end Set_Kind_Of; --------------------- -- Set_Location_Of -- --------------------- procedure Set_Location_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Source_Ptr) is begin pragma Assert (Present (Node)); In_Tree.Project_Nodes.Table (Node).Location := To; end Set_Location_Of; ----------------------------- -- Set_Extended_Project_Of -- ----------------------------- procedure Set_Extended_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Extended_Project_Of; ---------------------------------- -- Set_Extended_Project_Path_Of -- ---------------------------------- procedure Set_Extended_Project_Path_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Path_Name_Type) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Value := Name_Id (To); end Set_Extended_Project_Path_Of; ------------------------------ -- Set_Extending_Project_Of -- ------------------------------ procedure Set_Extending_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration); In_Tree.Project_Nodes.Table (Node).Field3 := To; end Set_Extending_Project_Of; ----------------- -- Set_Name_Of -- ----------------- procedure Set_Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Name_Id) is begin pragma Assert (Present (Node)); In_Tree.Project_Nodes.Table (Node).Name := To; end Set_Name_Of; ------------------------------- -- Set_Next_Declarative_Item -- ------------------------------- procedure Set_Next_Declarative_Item (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Next_Declarative_Item; ----------------------- -- Set_Next_End_Node -- ----------------------- procedure Set_Next_End_Node (To : Project_Node_Id) is begin Next_End_Nodes.Increment_Last; Next_End_Nodes.Table (Next_End_Nodes.Last) := To; end Set_Next_End_Node; --------------------------------- -- Set_Next_Expression_In_List -- --------------------------------- procedure Set_Next_Expression_In_List (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Expression); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Next_Expression_In_List; ----------------------------- -- Set_Next_Literal_String -- ----------------------------- procedure Set_Next_Literal_String (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_Next_Literal_String; --------------------------------- -- Set_Next_Package_In_Project -- --------------------------------- procedure Set_Next_Package_In_Project (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration); In_Tree.Project_Nodes.Table (Node).Field3 := To; end Set_Next_Package_In_Project; -------------------------- -- Set_Next_String_Type -- -------------------------- procedure Set_Next_String_Type (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_String_Type_Declaration); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Next_String_Type; ------------------- -- Set_Next_Term -- ------------------- procedure Set_Next_Term (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Term); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Next_Term; ----------------------- -- Set_Next_Variable -- ----------------------- procedure Set_Next_Variable (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration)); In_Tree.Project_Nodes.Table (Node).Field3 := To; end Set_Next_Variable; ----------------------------- -- Set_Next_With_Clause_Of -- ----------------------------- procedure Set_Next_With_Clause_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Next_With_Clause_Of; ----------------------- -- Set_Package_Id_Of -- ----------------------- procedure Set_Package_Id_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Package_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration); In_Tree.Project_Nodes.Table (Node).Pkg_Id := To; end Set_Package_Id_Of; ------------------------- -- Set_Package_Node_Of -- ------------------------- procedure Set_Package_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Package_Node_Of; ---------------------- -- Set_Path_Name_Of -- ---------------------- procedure Set_Path_Name_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Path_Name_Type) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Project or else In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause)); In_Tree.Project_Nodes.Table (Node).Path_Name := To; end Set_Path_Name_Of; --------------------------- -- Set_Previous_End_Node -- --------------------------- procedure Set_Previous_End_Node (To : Project_Node_Id) is begin Previous_End_Node := To; end Set_Previous_End_Node; ---------------------------- -- Set_Previous_Line_Node -- ---------------------------- procedure Set_Previous_Line_Node (To : Project_Node_Id) is begin Previous_Line_Node := To; end Set_Previous_Line_Node; -------------------------------- -- Set_Project_Declaration_Of -- -------------------------------- procedure Set_Project_Declaration_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Field2 := To; end Set_Project_Declaration_Of; ------------------------------ -- Set_Project_Qualifier_Of -- ------------------------------ procedure Set_Project_Qualifier_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Qualifier) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Qualifier := To; end Set_Project_Qualifier_Of; --------------------------- -- Set_Parent_Project_Of -- --------------------------- procedure Set_Parent_Project_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project); In_Tree.Project_Nodes.Table (Node).Field4 := To; end Set_Parent_Project_Of; ----------------------------------------------- -- Set_Project_File_Includes_Unkept_Comments -- ----------------------------------------------- procedure Set_Project_File_Includes_Unkept_Comments (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Boolean) is Declaration : constant Project_Node_Id := Project_Declaration_Of (Node, In_Tree); begin In_Tree.Project_Nodes.Table (Declaration).Flag1 := To; end Set_Project_File_Includes_Unkept_Comments; ------------------------- -- Set_Project_Node_Of -- ------------------------- procedure Set_Project_Node_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id; Limited_With : Boolean := False) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause or else In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference)); In_Tree.Project_Nodes.Table (Node).Field1 := To; if In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause and then not Limited_With then In_Tree.Project_Nodes.Table (Node).Field3 := To; end if; end Set_Project_Node_Of; --------------------------------------- -- Set_Project_Of_Renamed_Package_Of -- --------------------------------------- procedure Set_Project_Of_Renamed_Package_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration); In_Tree.Project_Nodes.Table (Node).Field1 := To; end Set_Project_Of_Renamed_Package_Of; ------------------------- -- Set_Source_Index_Of -- ------------------------- procedure Set_Source_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Int) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration)); In_Tree.Project_Nodes.Table (Node).Src_Index := To; end Set_Source_Index_Of; ------------------------ -- Set_String_Type_Of -- ------------------------ procedure Set_String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Project_Node_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration) and then In_Tree.Project_Nodes.Table (To).Kind = N_String_Type_Declaration); if In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference then In_Tree.Project_Nodes.Table (Node).Field3 := To; else In_Tree.Project_Nodes.Table (Node).Field2 := To; end if; end Set_String_Type_Of; ------------------------- -- Set_String_Value_Of -- ------------------------- procedure Set_String_Value_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; To : Name_Id) is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause or else In_Tree.Project_Nodes.Table (Node).Kind = N_Comment or else In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String)); In_Tree.Project_Nodes.Table (Node).Value := To; end Set_String_Value_Of; --------------------- -- Source_Index_Of -- --------------------- function Source_Index_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Int is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String or else In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration)); return In_Tree.Project_Nodes.Table (Node).Src_Index; end Source_Index_Of; -------------------- -- String_Type_Of -- -------------------- function String_Type_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference or else In_Tree.Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration)); if In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference then return In_Tree.Project_Nodes.Table (Node).Field3; else return In_Tree.Project_Nodes.Table (Node).Field2; end if; end String_Type_Of; --------------------- -- String_Value_Of -- --------------------- function String_Value_Of (Node : Project_Node_Id; In_Tree : Project_Node_Tree_Ref) return Name_Id is begin pragma Assert (Present (Node) and then (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause or else In_Tree.Project_Nodes.Table (Node).Kind = N_Comment or else In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String)); return In_Tree.Project_Nodes.Table (Node).Value; end String_Value_Of; -------------------- -- Value_Is_Valid -- -------------------- function Value_Is_Valid (For_Typed_Variable : Project_Node_Id; In_Tree : Project_Node_Tree_Ref; Value : Name_Id) return Boolean is begin pragma Assert (Present (For_Typed_Variable) and then (In_Tree.Project_Nodes.Table (For_Typed_Variable).Kind = N_Typed_Variable_Declaration)); declare Current_String : Project_Node_Id := First_Literal_String (String_Type_Of (For_Typed_Variable, In_Tree), In_Tree); begin while Present (Current_String) and then String_Value_Of (Current_String, In_Tree) /= Value loop Current_String := Next_Literal_String (Current_String, In_Tree); end loop; return Present (Current_String); end; end Value_Is_Valid; ------------------------------- -- There_Are_Unkept_Comments -- ------------------------------- function There_Are_Unkept_Comments return Boolean is begin return Unkept_Comments; end There_Are_Unkept_Comments; -------------------- -- Create_Project -- -------------------- function Create_Project (In_Tree : Project_Node_Tree_Ref; Name : Name_Id; Full_Path : Path_Name_Type; Is_Config_File : Boolean := False) return Project_Node_Id is Project : Project_Node_Id; Qualifier : Project_Qualifier := Unspecified; begin Project := Default_Project_Node (In_Tree, N_Project); Set_Name_Of (Project, In_Tree, Name); Set_Directory_Of (Project, In_Tree, Path_Name_Type (Get_Directory (File_Name_Type (Full_Path)))); Set_Path_Name_Of (Project, In_Tree, Full_Path); Set_Project_Declaration_Of (Project, In_Tree, Default_Project_Node (In_Tree, N_Project_Declaration)); if Is_Config_File then Qualifier := Configuration; end if; if not Is_Config_File then Prj.Tree.Tree_Private_Part.Projects_Htable.Set (In_Tree.Projects_HT, Name, Prj.Tree.Tree_Private_Part.Project_Name_And_Node' (Name => Name, Display_Name => Name, Resolved_Path => No_Path, Node => Project, Extended => False, From_Extended => False, Proj_Qualifier => Qualifier)); end if; return Project; end Create_Project; ---------------- -- Add_At_End -- ---------------- procedure Add_At_End (Tree : Project_Node_Tree_Ref; Parent : Project_Node_Id; Expr : Project_Node_Id; Add_Before_First_Pkg : Boolean := False; Add_Before_First_Case : Boolean := False) is Real_Parent : Project_Node_Id; New_Decl, Decl, Next : Project_Node_Id; Last, L : Project_Node_Id; begin if Kind_Of (Expr, Tree) /= N_Declarative_Item then New_Decl := Default_Project_Node (Tree, N_Declarative_Item); Set_Current_Item_Node (New_Decl, Tree, Expr); else New_Decl := Expr; end if; if Kind_Of (Parent, Tree) = N_Project then Real_Parent := Project_Declaration_Of (Parent, Tree); else Real_Parent := Parent; end if; Decl := First_Declarative_Item_Of (Real_Parent, Tree); if Decl = Empty_Node then Set_First_Declarative_Item_Of (Real_Parent, Tree, New_Decl); else loop Next := Next_Declarative_Item (Decl, Tree); exit when Next = Empty_Node or else (Add_Before_First_Pkg and then Kind_Of (Current_Item_Node (Next, Tree), Tree) = N_Package_Declaration) or else (Add_Before_First_Case and then Kind_Of (Current_Item_Node (Next, Tree), Tree) = N_Case_Construction); Decl := Next; end loop; -- In case Expr is in fact a range of declarative items Last := New_Decl; loop L := Next_Declarative_Item (Last, Tree); exit when L = Empty_Node; Last := L; end loop; -- In case Expr is in fact a range of declarative items Last := New_Decl; loop L := Next_Declarative_Item (Last, Tree); exit when L = Empty_Node; Last := L; end loop; Set_Next_Declarative_Item (Last, Tree, Next); Set_Next_Declarative_Item (Decl, Tree, New_Decl); end if; end Add_At_End; --------------------------- -- Create_Literal_String -- --------------------------- function Create_Literal_String (Str : Namet.Name_Id; Tree : Project_Node_Tree_Ref) return Project_Node_Id is Node : Project_Node_Id; begin Node := Default_Project_Node (Tree, N_Literal_String, Prj.Single); Set_Next_Literal_String (Node, Tree, Empty_Node); Set_String_Value_Of (Node, Tree, Str); return Node; end Create_Literal_String; --------------------------- -- Enclose_In_Expression -- --------------------------- function Enclose_In_Expression (Node : Project_Node_Id; Tree : Project_Node_Tree_Ref) return Project_Node_Id is Expr : Project_Node_Id; begin if Kind_Of (Node, Tree) /= N_Expression then Expr := Default_Project_Node (Tree, N_Expression, Single); Set_First_Term (Expr, Tree, Default_Project_Node (Tree, N_Term, Single)); Set_Current_Term (First_Term (Expr, Tree), Tree, Node); return Expr; else return Node; end if; end Enclose_In_Expression; -------------------- -- Create_Package -- -------------------- function Create_Package (Tree : Project_Node_Tree_Ref; Project : Project_Node_Id; Pkg : String) return Project_Node_Id is Pack : Project_Node_Id; N : Name_Id; begin Name_Len := Pkg'Length; Name_Buffer (1 .. Name_Len) := Pkg; N := Name_Find; -- Check if the package already exists Pack := First_Package_Of (Project, Tree); while Pack /= Empty_Node loop if Prj.Tree.Name_Of (Pack, Tree) = N then return Pack; end if; Pack := Next_Package_In_Project (Pack, Tree); end loop; -- Create the package and add it to the declarative item Pack := Default_Project_Node (Tree, N_Package_Declaration); Set_Name_Of (Pack, Tree, N); -- Find the correct package id to use Set_Package_Id_Of (Pack, Tree, Package_Node_Id_Of (N)); -- Add it to the list of packages Set_Next_Package_In_Project (Pack, Tree, First_Package_Of (Project, Tree)); Set_First_Package_Of (Project, Tree, Pack); Add_At_End (Tree, Project_Declaration_Of (Project, Tree), Pack); return Pack; end Create_Package; ---------------------- -- Create_Attribute -- ---------------------- function Create_Attribute (Tree : Project_Node_Tree_Ref; Prj_Or_Pkg : Project_Node_Id; Name : Name_Id; Index_Name : Name_Id := No_Name; Kind : Variable_Kind := List; At_Index : Integer := 0; Value : Project_Node_Id := Empty_Node) return Project_Node_Id is Node : constant Project_Node_Id := Default_Project_Node (Tree, N_Attribute_Declaration, Kind); Case_Insensitive : Boolean; Pkg : Package_Node_Id; Start_At : Attribute_Node_Id; Expr : Project_Node_Id; begin Set_Name_Of (Node, Tree, Name); if Index_Name /= No_Name then Set_Associative_Array_Index_Of (Node, Tree, Index_Name); end if; if Prj_Or_Pkg /= Empty_Node then Add_At_End (Tree, Prj_Or_Pkg, Node); end if; -- Find out the case sensitivity of the attribute if Prj_Or_Pkg /= Empty_Node and then Kind_Of (Prj_Or_Pkg, Tree) = N_Package_Declaration then Pkg := Prj.Attr.Package_Node_Id_Of (Name_Of (Prj_Or_Pkg, Tree)); Start_At := First_Attribute_Of (Pkg); else Start_At := Attribute_First; end if; Start_At := Attribute_Node_Id_Of (Name, Start_At); Case_Insensitive := Attribute_Kind_Of (Start_At) = Case_Insensitive_Associative_Array; Tree.Project_Nodes.Table (Node).Flag1 := Case_Insensitive; if At_Index /= 0 then if Attribute_Kind_Of (Start_At) = Optional_Index_Associative_Array or else Attribute_Kind_Of (Start_At) = Optional_Index_Case_Insensitive_Associative_Array then -- Results in: for Name ("index" at index) use "value"; -- This is currently only used for executables. Set_Source_Index_Of (Node, Tree, To => Int (At_Index)); else -- Results in: for Name ("index") use "value" at index; -- ??? This limitation makes no sense, we should be able to -- set the source index on an expression. pragma Assert (Kind_Of (Value, Tree) = N_Literal_String); Set_Source_Index_Of (Value, Tree, To => Int (At_Index)); end if; end if; if Value /= Empty_Node then Expr := Enclose_In_Expression (Value, Tree); Set_Expression_Of (Node, Tree, Expr); end if; return Node; end Create_Attribute; end Prj.Tree; gprbuild-gpl-2014-src/gnat/fname.adb0000644000076700001450000001636612323721731016636 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- F N A M E -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Alloc; with Hostparm; use Hostparm; with Table; with Types; use Types; package body Fname is ----------------------------- -- Dummy Table Definitions -- ----------------------------- -- The following table was used in old versions of the compiler. We retain -- the declarations here for compatibility with old tree files. The new -- version of the compiler does not use this table, and will write out a -- dummy empty table for Tree_Write. type SFN_Entry is record U : Unit_Name_Type; F : File_Name_Type; end record; package SFN_Table is new Table.Table ( Table_Component_Type => SFN_Entry, Table_Index_Type => Int, Table_Low_Bound => 0, Table_Initial => Alloc.SFN_Table_Initial, Table_Increment => Alloc.SFN_Table_Increment, Table_Name => "Fname_Dummy_Table"); --------------------------- -- Is_Internal_File_Name -- --------------------------- function Is_Internal_File_Name (Fname : File_Name_Type; Renamings_Included : Boolean := True) return Boolean is begin if Is_Predefined_File_Name (Fname, Renamings_Included) then return True; -- Once Is_Predefined_File_Name has been called and returns False, -- Name_Buffer contains Fname and Name_Len is set to 8. elsif Name_Buffer (1 .. 2) = "g-" or else Name_Buffer (1 .. 8) = "gnat " then return True; elsif OpenVMS and then (Name_Buffer (1 .. 4) = "dec-" or else Name_Buffer (1 .. 8) = "dec ") then return True; else return False; end if; end Is_Internal_File_Name; ----------------------------- -- Is_Predefined_File_Name -- ----------------------------- -- This should really be a test of unit name, given the possibility of -- pragma Source_File_Name setting arbitrary file names for any files??? -- Once Is_Predefined_File_Name has been called and returns False, -- Name_Buffer contains Fname and Name_Len is set to 8. This is used -- only by Is_Internal_File_Name, and is not part of the official -- external interface of this function. function Is_Predefined_File_Name (Fname : File_Name_Type; Renamings_Included : Boolean := True) return Boolean is begin Get_Name_String (Fname); return Is_Predefined_File_Name (Renamings_Included); end Is_Predefined_File_Name; function Is_Predefined_File_Name (Renamings_Included : Boolean := True) return Boolean is subtype Str8 is String (1 .. 8); Predef_Names : constant array (1 .. 11) of Str8 := ("ada ", -- Ada "interfac", -- Interfaces "system ", -- System -- Remaining entries are only considered if Renamings_Included true "calendar", -- Calendar "machcode", -- Machine_Code "unchconv", -- Unchecked_Conversion "unchdeal", -- Unchecked_Deallocation "directio", -- Direct_IO "ioexcept", -- IO_Exceptions "sequenio", -- Sequential_IO "text_io "); -- Text_IO Num_Entries : constant Natural := 3 + 8 * Boolean'Pos (Renamings_Included); begin -- Remove extension (if present) if Name_Len > 4 and then Name_Buffer (Name_Len - 3) = '.' then Name_Len := Name_Len - 4; end if; -- Definitely false if longer than 12 characters (8.3) if Name_Len > 8 then return False; -- Definitely predefined if prefix is a- i- or s- followed by letter elsif Name_Len >= 3 and then Name_Buffer (2) = '-' and then (Name_Buffer (1) = 'a' or else Name_Buffer (1) = 'i' or else Name_Buffer (1) = 's') and then (Name_Buffer (3) in 'a' .. 'z' or else Name_Buffer (3) in 'A' .. 'Z') then return True; end if; -- Otherwise check against special list, first padding to 8 characters while Name_Len < 8 loop Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := ' '; end loop; for J in 1 .. Num_Entries loop if Name_Buffer (1 .. 8) = Predef_Names (J) then return True; end if; end loop; -- Note: when we return False here, the Name_Buffer contains the -- padded file name. This is not defined for clients of the package, -- but is used by Is_Internal_File_Name. return False; end Is_Predefined_File_Name; --------------- -- Tree_Read -- --------------- procedure Tree_Read is begin SFN_Table.Tree_Read; end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is begin SFN_Table.Tree_Write; end Tree_Write; end Fname; gprbuild-gpl-2014-src/gnat/output.ads0000644000076700001450000002467012323721731017126 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- O U T P U T -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains low level output routines used by the compiler for -- writing error messages and informational output. It is also used by the -- debug source file output routines (see Sprint.Print_Debug_Line). with Hostparm; use Hostparm; with Types; use Types; pragma Warnings (Off); -- This package is used also by gnatcoll with System.OS_Lib; use System.OS_Lib; pragma Warnings (On); package Output is pragma Elaborate_Body; type Output_Proc is access procedure (S : String); -- This type is used for the Set_Special_Output procedure. If Output_Proc -- is called, then instead of lines being written to standard error or -- standard output, a call is made to the given procedure for each line, -- passing the line with an end of line character (which is a single -- ASCII.LF character, even in systems which normally use CR/LF or some -- other sequence for line end). ----------------- -- Subprograms -- ----------------- procedure Set_Special_Output (P : Output_Proc); -- Sets subsequent output to call procedure P. If P is null, then the call -- cancels the effect of a previous call, reverting the output to standard -- error or standard output depending on the mode at the time of previous -- call. Any exception generated by by calls to P is simply propagated to -- the caller of the routine causing the write operation. procedure Cancel_Special_Output; -- Cancels the effect of a call to Set_Special_Output, if any. The output -- is then directed to standard error or standard output depending on the -- last call to Set_Standard_Error or Set_Standard_Output. It is never an -- error to call Cancel_Special_Output. It has the same effect as calling -- Set_Special_Output (null). procedure Ignore_Output (S : String); -- Does nothing. To disable output, pass Ignore_Output'Access to -- Set_Special_Output. procedure Set_Standard_Error; -- Sets subsequent output to appear on the standard error file (whatever -- that might mean for the host operating system, if anything) when -- no special output is in effect. When a special output is in effect, -- the output will appear on standard error only after special output -- has been cancelled. procedure Set_Standard_Output; -- Sets subsequent output to appear on the standard output file (whatever -- that might mean for the host operating system, if anything) when no -- special output is in effect. When a special output is in effect, the -- output will appear on standard output only after special output has been -- cancelled. Output to standard output is the default mode before any call -- to either of the Set procedures. procedure Set_Output (FD : File_Descriptor); -- Sets subsequent output to appear on the given file descriptor when no -- special output is in effect. When a special output is in effect, the -- output will appear on the given file descriptor only after special -- output has been cancelled. procedure Indent; -- Increases the current indentation level. Whenever a line is written -- (triggered by Eol), an appropriate amount of whitespace is added to the -- beginning of the line, wrapping around if it gets too long. procedure Outdent; -- Decreases the current indentation level procedure Write_Char (C : Character); -- Write one character to the standard output file. If the character is LF, -- this is equivalent to Write_Eol. procedure Write_Erase_Char (C : Character); -- If last character in buffer matches C, erase it, otherwise no effect procedure Write_Eol; -- Write an end of line (whatever is required by the system in use, e.g. -- CR/LF for DOS, or LF for Unix) to the standard output file. This routine -- also empties the line buffer, actually writing it to the file. Note that -- Write_Eol is the only routine that causes any actual output to be -- written. Trailing spaces are removed. procedure Write_Eol_Keep_Blanks; -- Similar as Write_Eol, except that trailing spaces are not removed procedure Write_Int (Val : Int); -- Write an integer value with no leading blanks or zeroes. Negative values -- are preceded by a minus sign). procedure Write_Spaces (N : Nat); -- Write N spaces procedure Write_Str (S : String); -- Write a string of characters to the standard output file. Note that -- end of line is normally handled separately using WRITE_EOL, but it is -- allowable for the string to contain LF (but not CR) characters, which -- are properly interpreted as end of line characters. The string may also -- contain horizontal tab characters. procedure Write_Line (S : String); -- Equivalent to Write_Str (S) followed by Write_Eol; function Last_Char return Character; -- Returns last character written on the current line, or null if the -- current line is (so far) empty. procedure Delete_Last_Char; -- Deletes last character written on the current line, no effect if the -- current line is (so far) empty. function Column return Pos; pragma Inline (Column); -- Returns the number of the column about to be written (e.g. a value of 1 -- means the current line is empty). ------------------------- -- Buffer Save/Restore -- ------------------------- -- This facility allows the current line buffer to be saved and restored type Saved_Output_Buffer is private; -- Type used for Save/Restore_Buffer Buffer_Max : constant := Hostparm.Max_Line_Length; -- Maximal size of a buffered output line function Save_Output_Buffer return Saved_Output_Buffer; -- Save current line buffer and reset line buffer to empty procedure Restore_Output_Buffer (S : Saved_Output_Buffer); -- Restore previously saved output buffer. The value in S is not affected -- so it is legitimate to restore a buffer more than once. -------------------------- -- Debugging Procedures -- -------------------------- -- The following procedures are intended only for debugging purposes, -- for temporary insertion into the text in environments where a debugger -- is not available. They all have non-standard very short lower case -- names, precisely to make sure that they are only used for debugging. procedure w (C : Character); -- Dump quote, character, quote, followed by line return procedure w (S : String); -- Dump string followed by line return procedure w (V : Int); -- Dump integer followed by line return procedure w (B : Boolean); -- Dump Boolean followed by line return procedure w (L : String; C : Character); -- Dump contents of string followed by blank, quote, character, quote procedure w (L : String; S : String); -- Dump two strings separated by blanks, followed by line return procedure w (L : String; V : Int); -- Dump contents of string followed by blank, integer, line return procedure w (L : String; B : Boolean); -- Dump contents of string followed by blank, Boolean, line return private -- Note: the following buffer and column position are maintained by the -- subprograms defined in this package, and cannot be directly modified or -- accessed by a client. Buffer : String (1 .. Buffer_Max + 1) := (others => '*'); for Buffer'Alignment use 4; -- Buffer used to build output line. We do line buffering because it -- is needed for the support of the debug-generated-code option (-gnatD). -- Historically it was first added because on VMS, line buffering is -- needed with certain file formats. So in any case line buffering must -- be retained for this purpose, even if other reasons disappear. Note -- any attempt to write more output to a line than can fit in the buffer -- will be silently ignored. The alignment clause improves the efficiency -- of the save/restore procedures. Next_Col : Positive range 1 .. Buffer'Length + 1 := 1; -- Column about to be written type Saved_Output_Buffer is record Buffer : String (1 .. Buffer_Max + 1); Next_Col : Positive; Cur_Indentation : Natural; end record; end Output; gprbuild-gpl-2014-src/gnat/lib.ads0000644000076700001450000013270112323721731016327 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- L I B -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains routines for accessing and outputting the library -- information. It contains the routine to load subsidiary units. with Alloc; with Namet; use Namet; with Table; with Types; use Types; package Lib is type Unit_Ref_Table is array (Pos range <>) of Unit_Number_Type; -- Type to hold list of indirect references to unit number table type Compiler_State_Type is (Parsing, Analyzing); Compiler_State : Compiler_State_Type; -- Indicates current state of compilation. This is used to implement the -- function In_Extended_Main_Source_Unit. Parsing_Main_Extended_Source : Boolean := False; -- Set True if we are currently parsing a file that is part of the main -- extended source (the main unit, its spec, or one of its subunits). This -- flag to implement In_Extended_Main_Source_Unit. Analysing_Subunit_Of_Main : Boolean := False; -- Set to True when analyzing a subunit of the main source. When True, if -- the subunit is preprocessed and -gnateG is specified, then the -- preprocessed file (.prep) is written. -------------------------------------------- -- General Approach to Library Management -- -------------------------------------------- -- As described in GNote #1, when a unit is compiled, all its subsidiary -- units are recompiled, including the following: -- (a) Corresponding spec for a body -- (b) Parent spec of a child library spec -- (d) With'ed specs -- (d) Parent body of a subunit -- (e) Subunits corresponding to any specified stubs -- (f) Bodies of inlined subprograms that are called -- (g) Bodies of generic subprograms or packages that are instantiated -- (h) Bodies of packages containing either of the above two items -- (i) Specs and bodies of runtime units -- (j) Parent specs for with'ed child library units -- If a unit is being compiled only for syntax checking, then no subsidiary -- units are loaded, the syntax check applies only to the main unit, -- i.e. the one contained in the source submitted to the library. -- If a unit is being compiled for syntax and semantic checking, then only -- cases (a)-(d) loads are performed, since the full semantic checking can -- be carried out without needing (e)-(i) loads. In this case no object -- file, or library information file, is generated, so the missing units -- do not affect the results. -- Specifications of library subprograms, subunits, and generic specs -- and bodies, can only be compiled in syntax/semantic checking mode, -- since no code is ever generated directly for these units. In the case -- of subunits, only the compilation of the ultimate parent unit generates -- actual code. If a subunit is submitted to the compiler in syntax/ -- semantic checking mode, the parent (or parents in the nested case) are -- semantically checked only up to the point of the corresponding stub. -- If code is being generated, then all the above units are required, -- although the need for bodies of inlined procedures can be suppressed -- by the use of a switch that sets the mode to ignore pragma Inline -- statements. -- The two main sections of the front end, Par and Sem, are recursive. -- Compilation proceeds unit by unit making recursive calls as necessary. -- The process is controlled from the GNAT main program, which makes calls -- to Par and Sem sequence for the main unit. -- Par parses the given unit, and then, after the parse is complete, uses -- the Par.Load subprogram to load all its subsidiary units in categories -- (a)-(d) above, installing pointers to the loaded units in the parse -- tree, as described in a later section of this spec. If any of these -- required units is missing, a fatal error is signalled, so that no -- attempt is made to run Sem in such cases, since it is assumed that -- too many cascaded errors would result, and the confusion would not -- be helpful. -- Following the call to Par on the main unit, the entire tree of required -- units is thus loaded, and Sem is called on the main unit. The parameter -- passed to Sem is the unit to be analyzed. The visibility table, which -- is a single global structure, starts out containing only the entries -- for the visible entities in Standard. Every call to Sem establishes a -- new scope stack table, pushing an entry for Standard on entry to provide -- the proper initial scope environment. -- Sem first proceeds to perform semantic analysis on the currently loaded -- units as follows: -- In the case of a body (case (a) above), Sem analyzes the corresponding -- spec, using a recursive call to Sem. As is always expected to be the -- case with calls to Sem, any entities installed in the visibility table -- are removed on exit from Sem, so that these entities have to be -- reinstalled on return to continue the analysis of the body which of -- course needs visibility of these entities. -- -- In the case of the parent of a child spec (case (b) above), a similar -- call is made to Sem to analyze the parent. Again, on return, the -- entities from the analyzed parent spec have to be installed in the -- visibility table of the caller (the child unit), which must have -- visibility to the entities in its parent spec. -- For with'ed specs (case (c) above), a recursive call to Sem is made -- to analyze each spec in turn. After all the spec's have been analyzed, -- but not till that point, the entities from all the with'ed units are -- reinstalled in the visibility table so that the caller can proceed -- with the analysis of the unit doing the with's with the necessary -- entities made either potentially use visible or visible by selection -- as needed. -- Case (d) arises when Sem is passed a subunit to analyze. This means -- that the main unit is a subunit, and the unit passed to Sem is either -- the main unit, or one of its ancestors that is still a subunit. Since -- analysis must start at the top of the tree, Sem essentially cancels -- the current call by immediately making a call to analyze the parent -- (when this call is finished it immediately returns, so logically this -- call is like a goto). The subunit will then be analyzed at the proper -- time as described for the stub case. Note that we also turn off the -- indication that code should be generated in this case, since the only -- time we generate code for subunits is when compiling the main parent. -- Case (e), subunits corresponding to stubs, are handled as the stubs -- are encountered. There are three sub-cases: -- If the subunit has already been loaded, then this means that the -- main unit was a subunit, and we are back on our way down to it -- after following the initial processing described for case (d). -- In this case we analyze this particular subunit, as described -- for the case where we are generating code, but when we get back -- we are all done, since the rest of the parent is irrelevant. To -- get out of the parent, we raise the exception Subunit_Found, which -- is handled at the outer level of Sem. -- The cases where the subunit has not already been loaded correspond -- to cases where the main unit was a parent. In this case the action -- depends on whether or not we are generating code. If we are not -- generating code, then this is the case where we can simply ignore -- the subunit, since in checking mode we don't even want to insist -- that the subunit exist, much less waste time checking it. -- If we are generating code, then we need to load and analyze -- all subunits. This is achieved with a call to Lib.Load to load -- and parse the unit, followed by processing that installs the -- context clause of the subunit, analyzes the subunit, and then -- removes the context clause (from the visibility chains of the -- parent). Note that we do *not* do a recursive call to Sem in -- this case, precisely because we need to do the analysis of the -- subunit with the current visibility table and scope stack. -- Case (f) applies only to subprograms for which a pragma Inline is -- given, providing that the compiler is operating in the mode where -- pragma Inline's are activated. When the expander encounters a call -- to such a subprogram, it loads the body of the subprogram if it has -- not already been loaded, and calls Sem to process it. -- Case (g) is similar to case (f), except that the body of a generic -- is unconditionally required, regardless of compiler mode settings. -- As in the subprogram case, when the expander encounters a generic -- instantiation, it loads the generic body of the subprogram if it -- has not already been loaded, and calls Sem to process it. -- Case (h) arises when a package contains either an inlined subprogram -- which is called, or a generic which is instantiated. In this case the -- body of the package must be loaded and analyzed with a call to Sem. -- Case (i) is handled by adding implicit with clauses to the context -- clauses of all units that potentially reference the relevant runtime -- entities. Note that since we have the full set of units available, -- the parser can always determine the set of runtime units that is -- needed. These with clauses do not have associated use clauses, so -- all references to the entities must be by selection. Once the with -- clauses have been added, subsequent processing is as for normal -- with clauses. -- Case (j) is also handled by adding appropriate implicit with clauses -- to any unit that withs a child unit. Again there is no use clause, -- and subsequent processing proceeds as for an explicit with clause. -- Sem thus completes the loading of all required units, except those -- required for inline subprogram bodies or inlined generics. If any -- of these load attempts fails, then the expander will not be called, -- even if code was to be generated. If the load attempts all succeed -- then the expander is called, though the attempt to generate code may -- still fail if an error occurs during a load attempt for an inlined -- body or a generic body. ------------------------------------------- -- Special Handling of Subprogram Bodies -- ------------------------------------------- -- A subprogram body (in an adb file) may stand for both a spec and a body. -- A simple model (and one that was adopted through version 2.07) is simply -- to assume that such an adb file acts as its own spec if no ads file is -- is present. -- However, this is not correct. RM 10.1.4(4) requires that such a body -- act as a spec unless a subprogram declaration of the same name is -- already present. The correct interpretation of this in GNAT library -- terms is to ignore an existing ads file of the same name unless this -- ads file contains a subprogram declaration with the same name. -- If there is an ads file with a unit other than a subprogram declaration -- with the same name, then a fatal message is output, noting that this -- irrelevant file must be deleted before the body can be compiled. See -- ACVC test CA1020D to see how this processing is required. ----------------- -- Global Data -- ----------------- Current_Sem_Unit : Unit_Number_Type := Main_Unit; -- Unit number of unit currently being analyzed/expanded. This is set when -- ever a new unit is entered, saving and restoring the old value, so that -- it always reflects the unit currently being analyzed. The initial value -- of Main_Unit ensures that a proper value is set initially, and in -- particular for analysis of configuration pragmas in gnat.adc. Main_Unit_Entity : Entity_Id; -- Entity of main unit, same as Cunit_Entity (Main_Unit) except where -- Main_Unit is a body with a separate spec, in which case it is the -- entity for the spec. ----------------- -- Units Table -- ----------------- -- The units table has an entry for each unit (source file) read in by the -- current compilation. The table is indexed by the unit number value, -- The first entry in the table, subscript Main_Unit, is for the main file. -- Each entry in this units table contains the following data. -- Cunit -- Pointer to the N_Compilation_Unit node. Initially set to Empty by -- Lib.Load, and then reset to the required node by the parser when -- the unit is parsed. -- Cunit_Entity -- Pointer to the entity node for the compilation unit. Initially set -- to Empty by Lib.Load, and then reset to the required entity by the -- parser when the unit is parsed. -- Dependency_Num -- This is the number of the unit within the generated dependency -- lines (D lines in the ALI file) which are sorted into alphabetical -- order. The number is ones origin, so a value of 2 refers to the -- second generated D line. The Dependency_Num values are set as the -- D lines are generated, and are used to generate proper unit -- references in the generated xref information and SCO output. -- Dynamic_Elab -- A flag indicating if this unit was compiled with dynamic elaboration -- checks specified (as the result of using the -gnatE compilation -- option or a pragma Elaboration_Checks (Dynamic). -- Error_Location -- This is copied from the Sloc field of the Enode argument passed -- to Load_Unit. It refers to the enclosing construct which caused -- this unit to be loaded, e.g. most typically the with clause that -- referenced the unit, and is used for error handling in Par.Load. -- Expected_Unit -- This is the expected unit name for a file other than the main unit, -- since these are cases where we load the unit using Lib.Load and we -- know the unit that is expected. It must be the same as Unit_Name -- if it is set (see test in Par.Load). Expected_Unit is set to -- No_Name for the main unit. -- Fatal_Error -- A flag that is initialized to False, and gets set to True if a fatal -- error occurs during the processing of a unit. A fatal error is one -- defined as serious enough to stop the next phase of the compiler -- from running (i.e. fatal error during parsing stops semantics, -- fatal error during semantics stops code generation). Note that -- currently, errors of any kind cause Fatal_Error to be set, but -- eventually perhaps only errors labeled as fatal errors should be -- this severe if we decide to try Sem on sources with minor errors. -- Generate_Code -- This flag is set True for all units in the current file for which -- code is to be generated. This includes the unit explicitly compiled, -- together with its specification, and any subunits. -- Has_RACW -- A Boolean flag, initially set to False when a unit entry is created, -- and set to True if the unit defines a remote access to class wide -- (RACW) object. This is used for controlling generation of the RA -- attribute in the ali file. -- Ident_String -- N_String_Literal node from a valid pragma Ident that applies to -- this unit. If no Ident pragma applies to the unit, then Empty. -- Loading -- A flag that is used to catch circular WITH dependencies. It is set -- True when an entry is initially created in the file table, and set -- False when the load is completed, or ends with an error. -- Main_Priority -- This field is used to indicate the priority of a possible main -- program, as set by a pragma Priority. A value of -1 indicates -- that the default priority is to be used (and is also used for -- entries that do not correspond to possible main programs). -- Main_CPU -- This field is used to indicate the affinity of a possible main -- program, as set by a pragma CPU. A value of -1 indicates -- that the default affinity is to be used (and is also used for -- entries that do not correspond to possible main programs). -- Munit_Index -- The index of the unit within the file for multiple unit per file -- mode. Set to zero in normal single unit per file mode. -- OA_Setting -- This is a character field containing L if Optimize_Alignment mode -- was set locally, and O/T/S for Off/Time/Space default if not. -- Serial_Number -- This field holds a serial number used by New_Internal_Name to -- generate unique temporary numbers on a unit by unit basis. The -- only access to this field is via the Increment_Serial_Number -- routine which increments the current value and returns it. This -- serial number is separate for each unit. -- Source_Index -- The index in the source file table of the corresponding source file. -- Set when the entry is created by a call to Lib.Load and then cannot -- be changed. -- Unit_File_Name -- The name of the source file containing the unit. Set when the entry -- is created by a call to Lib.Load, and then cannot be changed. -- Unit_Name -- The name of the unit. Initialized to No_Name by Lib.Load, and then -- set by the parser when the unit is parsed to the unit name actually -- found in the file (which should, in the absence of errors) be the -- same name as Expected_Unit. -- Version -- This field holds the version of the unit, which is computed as -- the exclusive or of the checksums of this unit, and all its -- semantically dependent units. Access to the version number field -- is not direct, but is done through the routines described below. -- When a unit table entry is created, this field is initialized to -- the checksum of the corresponding source file. Version_Update is -- then called to reflect the contributions of any unit on which this -- unit is semantically dependent. -- The units table is reset to empty at the start of the compilation of -- each main unit by Lib.Initialize. Entries are then added by calls to -- the Lib.Load procedure. The following subprograms are used to access -- and modify entries in the Units table. Individual entries are accessed -- using a unit number value which ranges from Main_Unit (the first entry, -- which is always for the current main unit) to Last_Unit. Default_Main_Priority : constant Int := -1; -- Value used in Main_Priority field to indicate default main priority Default_Main_CPU : constant Int := -1; -- Value used in Main_CPU field to indicate default main affinity function Cunit (U : Unit_Number_Type) return Node_Id; function Cunit_Entity (U : Unit_Number_Type) return Entity_Id; function Dependency_Num (U : Unit_Number_Type) return Nat; function Dynamic_Elab (U : Unit_Number_Type) return Boolean; function Error_Location (U : Unit_Number_Type) return Source_Ptr; function Expected_Unit (U : Unit_Number_Type) return Unit_Name_Type; function Fatal_Error (U : Unit_Number_Type) return Boolean; function Generate_Code (U : Unit_Number_Type) return Boolean; function Ident_String (U : Unit_Number_Type) return Node_Id; function Has_RACW (U : Unit_Number_Type) return Boolean; function Loading (U : Unit_Number_Type) return Boolean; function Main_CPU (U : Unit_Number_Type) return Int; function Main_Priority (U : Unit_Number_Type) return Int; function Munit_Index (U : Unit_Number_Type) return Nat; function OA_Setting (U : Unit_Number_Type) return Character; function Source_Index (U : Unit_Number_Type) return Source_File_Index; function Unit_File_Name (U : Unit_Number_Type) return File_Name_Type; function Unit_Name (U : Unit_Number_Type) return Unit_Name_Type; -- Get value of named field from given units table entry procedure Set_Cunit (U : Unit_Number_Type; N : Node_Id); procedure Set_Cunit_Entity (U : Unit_Number_Type; E : Entity_Id); procedure Set_Dynamic_Elab (U : Unit_Number_Type; B : Boolean := True); procedure Set_Error_Location (U : Unit_Number_Type; W : Source_Ptr); procedure Set_Fatal_Error (U : Unit_Number_Type; B : Boolean := True); procedure Set_Generate_Code (U : Unit_Number_Type; B : Boolean := True); procedure Set_Has_RACW (U : Unit_Number_Type; B : Boolean := True); procedure Set_Ident_String (U : Unit_Number_Type; N : Node_Id); procedure Set_Loading (U : Unit_Number_Type; B : Boolean := True); procedure Set_Main_CPU (U : Unit_Number_Type; P : Int); procedure Set_Main_Priority (U : Unit_Number_Type; P : Int); procedure Set_OA_Setting (U : Unit_Number_Type; C : Character); procedure Set_Unit_Name (U : Unit_Number_Type; N : Unit_Name_Type); -- Set value of named field for given units table entry. Note that we -- do not have an entry for each possible field, since some of the fields -- can only be set by specialized interfaces (defined below). function Version_Get (U : Unit_Number_Type) return Word_Hex_String; -- Returns the version as a string with 8 hex digits (upper case letters) function Last_Unit return Unit_Number_Type; -- Unit number of last allocated unit function Num_Units return Nat; -- Number of units currently in unit table procedure Remove_Unit (U : Unit_Number_Type); -- Remove unit U from unit table. Currently this is effective only -- if U is the last unit currently stored in the unit table. function Entity_Is_In_Main_Unit (E : Entity_Id) return Boolean; -- Returns True if the entity E is declared in the main unit, or, in -- its corresponding spec, or one of its subunits. Entities declared -- within generic instantiations return True if the instantiation is -- itself "in the main unit" by this definition. Otherwise False. function Get_Source_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type; pragma Inline (Get_Source_Unit); function Get_Source_Unit (S : Source_Ptr) return Unit_Number_Type; -- Return unit number of file identified by given source pointer value. -- This call must always succeed, since any valid source pointer value -- belongs to some previously loaded module. If the given source pointer -- value is within an instantiation, this function returns the unit number -- of the template, i.e. the unit containing the source code corresponding -- to the given Source_Ptr value. The version taking a Node_Id argument, N, -- simply applies the function to Sloc (N). function Get_Code_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type; pragma Inline (Get_Code_Unit); function Get_Code_Unit (S : Source_Ptr) return Unit_Number_Type; -- This is like Get_Source_Unit, except that in the instantiation case, -- it uses the location of the top level instantiation, rather than the -- template, so it returns the unit number containing the code that -- corresponds to the node N, or the source location S. function In_Same_Source_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean; pragma Inline (In_Same_Source_Unit); -- Determines if the two nodes or entities N1 and N2 are in the same -- source unit, the criterion being that Get_Source_Unit yields the -- same value for each argument. function In_Same_Code_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean; pragma Inline (In_Same_Code_Unit); -- Determines if the two nodes or entities N1 and N2 are in the same -- code unit, the criterion being that Get_Code_Unit yields the same -- value for each argument. function In_Same_Extended_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean; pragma Inline (In_Same_Extended_Unit); -- Determines if two nodes or entities N1 and N2 are in the same -- extended unit, where an extended unit is defined as a unit and all -- its subunits (considered recursively, i.e. subunits of subunits are -- included). Returns true if S1 and S2 are in the same extended unit -- and False otherwise. function In_Same_Extended_Unit (S1, S2 : Source_Ptr) return Boolean; pragma Inline (In_Same_Extended_Unit); -- Determines if the two source locations S1 and S2 are in the same -- extended unit, where an extended unit is defined as a unit and all -- its subunits (considered recursively, i.e. subunits of subunits are -- included). Returns true if S1 and S2 are in the same extended unit -- and False otherwise. function In_Extended_Main_Code_Unit (N : Node_Or_Entity_Id) return Boolean; -- Return True if the node is in the generated code of the extended main -- unit, defined as the main unit, its specification (if any), and all -- its subunits (considered recursively). Units for which this enquiry -- returns True are those for which code will be generated. Nodes from -- instantiations are included in the extended main unit for this call. -- If the main unit is itself a subunit, then the extended main code unit -- includes its parent unit, and the parent unit spec if it is separate. -- -- This routine (and the following three routines) all return False if -- Sloc (N) is No_Location or Standard_Location. In an earlier version, -- they returned True for Standard_Location, but this was odd, and some -- archeology indicated that this was done for the sole benefit of the -- call in Restrict.Check_Restriction_No_Dependence, so we have moved -- the special case check to that routine. This avoids some difficulties -- with some other calls that malfunctioned with the odd return of True. function In_Extended_Main_Code_Unit (Loc : Source_Ptr) return Boolean; -- Same function as above, but argument is a source pointer rather -- than a node. function In_Extended_Main_Source_Unit (N : Node_Or_Entity_Id) return Boolean; -- Return True if the node is in the source text of the extended main -- unit, defined as the main unit, its specification (if any), and all -- its subunits (considered recursively). Units for which this enquiry -- returns True are those for which code will be generated. This differs -- from In_Extended_Main_Code_Unit only in that instantiations are not -- included for the purposes of this call. If the main unit is itself -- a subunit, then the extended main source unit includes its parent unit, -- and the parent unit spec if it is separate. function In_Extended_Main_Source_Unit (Loc : Source_Ptr) return Boolean; -- Same function as above, but argument is a source pointer function In_Predefined_Unit (N : Node_Or_Entity_Id) return Boolean; -- Returns True if the given node or entity appears within the source text -- of a predefined unit (i.e. within Ada, Interfaces, System or within one -- of the descendent packages of one of these three packages). function In_Predefined_Unit (S : Source_Ptr) return Boolean; -- Same function as above but argument is a source pointer function Earlier_In_Extended_Unit (S1, S2 : Source_Ptr) return Boolean; -- Given two Sloc values for which In_Same_Extended_Unit is true, determine -- if S1 appears before S2. Returns True if S1 appears before S2, and False -- otherwise. The result is undefined if S1 and S2 are not in the same -- extended unit. Note: this routine will not give reliable results if -- called after Sprint has been called with -gnatD set. function Exact_Source_Name (Loc : Source_Ptr) return String; -- Return name of entity at location Loc exactly as written in the source. -- this includes copying the wide character encodings exactly as they were -- used in the source, so the caller must be aware of the possibility of -- such encodings. function Compilation_Switches_Last return Nat; -- Return the count of stored compilation switches function Get_Compilation_Switch (N : Pos) return String_Ptr; -- Return the Nth stored compilation switch, or null if less than N -- switches have been stored. Used by ASIS and back ends written in Ada. function Get_Cunit_Unit_Number (N : Node_Id) return Unit_Number_Type; -- Return unit number of the unit whose N_Compilation_Unit node is the -- one passed as an argument. This must always succeed since the node -- could not have been built without making a unit table entry. function Get_Cunit_Entity_Unit_Number (E : Entity_Id) return Unit_Number_Type; -- Return unit number of the unit whose compilation unit spec entity is -- the one passed as an argument. This must always succeed since the -- entity could not have been built without making a unit table entry. function Increment_Serial_Number return Nat; -- Increment Serial_Number field for current unit, and return the -- incremented value. procedure Synchronize_Serial_Number; -- This function increments the Serial_Number field for the current unit -- but does not return the incremented value. This is used when there -- is a situation where one path of control increments a serial number -- (using Increment_Serial_Number), and the other path does not and it is -- important to keep the serial numbers synchronized in the two cases (e.g. -- when the references in a package and a client must be kept consistent). procedure Replace_Linker_Option_String (S : String_Id; Match_String : String); -- Replace an existing Linker_Option if the prefix Match_String matches, -- otherwise call Store_Linker_Option_String. procedure Store_Compilation_Switch (Switch : String); -- Called to register a compilation switch, either front-end or back-end, -- which may influence the generated output file(s). Switch is the text of -- the switch to store (except that -fRTS gets changed back to --RTS). procedure Enable_Switch_Storing; -- Enable registration of switches by Store_Compilation_Switch. Used to -- avoid registering switches added automatically by the gcc driver at the -- beginning of the command line. procedure Disable_Switch_Storing; -- Disable registration of switches by Store_Compilation_Switch. Used to -- avoid registering switches added automatically by the gcc driver at the -- end of the command line. procedure Store_Linker_Option_String (S : String_Id); -- This procedure is called to register the string from a pragma -- Linker_Option. The argument is the Id of the string to register. procedure Store_Note (N : Node_Id); -- This procedure is called to register a pragma N for which a notes -- entry is required. procedure Initialize; -- Initialize internal tables procedure Lock; -- Lock internal tables before calling back end procedure Unlock; -- Unlock internal tables, in cases where the back end needs to modify them procedure Tree_Read; -- Initializes internal tables from current tree file using the relevant -- Table.Tree_Read routines. procedure Tree_Write; -- Writes out internal tables to current tree file using the relevant -- Table.Tree_Write routines. function Is_Loaded (Uname : Unit_Name_Type) return Boolean; -- Determines if unit with given name is already loaded, i.e. there is -- already an entry in the file table with this unit name for which the -- corresponding file was found and parsed. Note that the Fatal_Error flag -- of this entry must be checked before proceeding with further processing. procedure Version_Referenced (S : String_Id); -- This routine is called from Exp_Attr to register the use of a Version -- or Body_Version attribute. The argument is the external name used to -- access the version string. procedure List (File_Names_Only : Boolean := False); -- Lists units in active library (i.e. generates output consisting of a -- sorted listing of the units represented in File table, except for the -- main unit). If File_Names_Only is set to True, then the list includes -- only file names, and no other information. Otherwise the unit name and -- time stamp are also output. File_Names_Only also restricts the list to -- exclude any predefined files. function Generic_May_Lack_ALI (Sfile : File_Name_Type) return Boolean; -- Generic units must be separately compiled. Since we always use -- macro substitution for generics, the resulting object file is a dummy -- one with no code, but the ALI file has the normal form, and we need -- this ALI file so that the binder can work out a correct order of -- elaboration. -- -- However, ancient versions of GNAT used to not generate code or ALI -- files for generic units, and this would yield complex order of -- elaboration issues. These were fixed in GNAT 3.10. The support for not -- compiling language-defined library generics was retained nonetheless -- to facilitate bootstrap. Specifically, it is convenient to have -- the same list of files to be compiled for all stages. So, if the -- bootstrap compiler does not generate code for a given file, then -- the stage1 compiler (and binder) also must deal with the case of -- that file not being compiled. The predicate Generic_May_Lack_ALI is -- True for those generic units for which missing ALI files are allowed. procedure Write_Unit_Info (Unit_Num : Unit_Number_Type; Item : Node_Id; Prefix : String := ""; Withs : Boolean := False); -- Print out debugging information about the unit. Prefix precedes the rest -- of the printout. If Withs is True, we print out units with'ed by this -- unit (not counting limited withs). --------------------------------------------------------------- -- Special Handling for Restriction_Set (No_Dependence) Case -- --------------------------------------------------------------- -- If we have a Restriction_Set attribute for No_Dependence => unit, -- and the unit is not given in a No_Dependence restriction that we -- can see, the attribute will return False. -- We have to ensure in this case that the binder will reject any attempt -- to set a No_Dependence restriction in some other unit in the partition. -- If the unit is in the semantic closure, then of course it is properly -- WITH'ed by someone, and the binder will do this job automatically as -- part of its normal processing. -- But if the unit is not in the semantic closure, we must make sure the -- binder knows about it. The use of the Restriction_Set attribute giving -- a result of False does not mean of itself that we have to include the -- unit in the partition. So what we do is to generate a with (W) line in -- the ali file (with no file name information), but no corresponding D -- (dependency) line. This is recognized by the binder as meaning "Don't -- let anyone specify No_Dependence for this unit, but you don't have to -- include it if there is no real W line for the unit". -- The following table keeps track of relevant units. It is used in the -- Lib.Writ circuit for outputting With lines to output the special with -- line with RA if the unit is not in the semantic closure. package Restriction_Set_Dependences is new Table.Table ( Table_Component_Type => Unit_Name_Type, Table_Index_Type => Int, Table_Low_Bound => 0, Table_Initial => 10, Table_Increment => 100, Table_Name => "Restriction_Attribute_Dependences"); private pragma Inline (Cunit); pragma Inline (Cunit_Entity); pragma Inline (Dependency_Num); pragma Inline (Fatal_Error); pragma Inline (Generate_Code); pragma Inline (Has_RACW); pragma Inline (Increment_Serial_Number); pragma Inline (Loading); pragma Inline (Main_CPU); pragma Inline (Main_Priority); pragma Inline (Munit_Index); pragma Inline (OA_Setting); pragma Inline (Set_Cunit); pragma Inline (Set_Cunit_Entity); pragma Inline (Set_Fatal_Error); pragma Inline (Set_Generate_Code); pragma Inline (Set_Has_RACW); pragma Inline (Set_Loading); pragma Inline (Set_Main_CPU); pragma Inline (Set_Main_Priority); pragma Inline (Set_OA_Setting); pragma Inline (Set_Unit_Name); pragma Inline (Source_Index); pragma Inline (Unit_File_Name); pragma Inline (Unit_Name); type Unit_Record is record Unit_File_Name : File_Name_Type; Unit_Name : Unit_Name_Type; Munit_Index : Nat; Expected_Unit : Unit_Name_Type; Source_Index : Source_File_Index; Cunit : Node_Id; Cunit_Entity : Entity_Id; Dependency_Num : Int; Ident_String : Node_Id; Main_Priority : Int; Main_CPU : Int; Serial_Number : Nat; Version : Word; Error_Location : Source_Ptr; Fatal_Error : Boolean; Generate_Code : Boolean; Has_RACW : Boolean; Dynamic_Elab : Boolean; Filler : Boolean; Loading : Boolean; OA_Setting : Character; SPARK_Mode_Pragma : Node_Id; end record; -- The following representation clause ensures that the above record -- has no holes. We do this so that when instances of this record are -- written by Tree_Gen, we do not write uninitialized values to the file. for Unit_Record use record Unit_File_Name at 0 range 0 .. 31; Unit_Name at 4 range 0 .. 31; Munit_Index at 8 range 0 .. 31; Expected_Unit at 12 range 0 .. 31; Source_Index at 16 range 0 .. 31; Cunit at 20 range 0 .. 31; Cunit_Entity at 24 range 0 .. 31; Dependency_Num at 28 range 0 .. 31; Ident_String at 32 range 0 .. 31; Main_Priority at 36 range 0 .. 31; Main_CPU at 40 range 0 .. 31; Serial_Number at 44 range 0 .. 31; Version at 48 range 0 .. 31; Error_Location at 52 range 0 .. 31; Fatal_Error at 56 range 0 .. 7; Generate_Code at 57 range 0 .. 7; Has_RACW at 58 range 0 .. 7; Dynamic_Elab at 59 range 0 .. 7; Filler at 60 range 0 .. 15; OA_Setting at 62 range 0 .. 7; Loading at 63 range 0 .. 7; SPARK_Mode_Pragma at 64 range 0 .. 31; end record; for Unit_Record'Size use 68 * 8; -- This ensures that we did not leave out any fields package Units is new Table.Table ( Table_Component_Type => Unit_Record, Table_Index_Type => Unit_Number_Type, Table_Low_Bound => Main_Unit, Table_Initial => Alloc.Units_Initial, Table_Increment => Alloc.Units_Increment, Table_Name => "Units"); -- The following table stores strings from pragma Linker_Option lines type Linker_Option_Entry is record Option : String_Id; -- The string for the linker option line Unit : Unit_Number_Type; -- The unit from which the linker option comes end record; package Linker_Option_Lines is new Table.Table ( Table_Component_Type => Linker_Option_Entry, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => Alloc.Linker_Option_Lines_Initial, Table_Increment => Alloc.Linker_Option_Lines_Increment, Table_Name => "Linker_Option_Lines"); -- The following table stores references to pragmas that generate Notes type Notes_Entry is record Pragma_Node : Node_Id; Unit : Unit_Number_Type; end record; package Notes is new Table.Table ( Table_Component_Type => Notes_Entry, Table_Index_Type => Integer, Table_Low_Bound => 1, Table_Initial => Alloc.Notes_Initial, Table_Increment => Alloc.Notes_Increment, Table_Name => "Notes"); -- The following table records the compilation switches used to compile -- the main unit. The table includes only switches. It excludes -o -- switches as well as artifacts of the gcc/gnat1 interface such as -- -quiet, -dumpbase, or -auxbase. -- This table is set as part of the compiler argument scanning in -- Back_End. It can also be reset in -gnatc mode from the data in an -- existing ali file, and is read and written by the Tree_Read and -- Tree_Write routines for ASIS. package Compilation_Switches is new Table.Table ( Table_Component_Type => String_Ptr, Table_Index_Type => Nat, Table_Low_Bound => 1, Table_Initial => 30, Table_Increment => 100, Table_Name => "Compilation_Switches"); Load_Msg_Sloc : Source_Ptr; -- Location for placing error messages (a token in the main source text) -- This is set from Sloc (Enode) by Load only in the case where this Sloc -- is in the main source file. This ensures that not found messages and -- circular dependency messages reference the original with in this source. type Load_Stack_Entry is record Unit_Number : Unit_Number_Type; With_Node : Node_Id; end record; -- The Load_Stack table contains a list of unit numbers (indexes into the -- unit table) of units being loaded on a single dependency chain, and a -- flag to indicate whether this unit is loaded through a limited_with -- clause. The First entry is the main unit. The second entry, if present -- is a unit on which the first unit depends, etc. This stack is used to -- generate error messages showing the dependency chain if a file is not -- found, or whether a true circular dependency exists. The Load_Unit -- function makes an entry in this table when it is called, and removes -- the entry just before it returns. package Load_Stack is new Table.Table ( Table_Component_Type => Load_Stack_Entry, Table_Index_Type => Int, Table_Low_Bound => 0, Table_Initial => Alloc.Load_Stack_Initial, Table_Increment => Alloc.Load_Stack_Increment, Table_Name => "Load_Stack"); procedure Sort (Tbl : in out Unit_Ref_Table); -- This procedure sorts the given unit reference table in order of -- ascending unit names, where the ordering relation is as described -- by the comparison routines provided by package Uname. -- The Version_Ref table records Body_Version and Version attribute -- references. The entries are simply the strings for the external -- names that correspond to the referenced values. package Version_Ref is new Table.Table ( Table_Component_Type => String_Id, Table_Index_Type => Nat, Table_Low_Bound => 1, Table_Initial => 20, Table_Increment => 100, Table_Name => "Version_Ref"); end Lib; gprbuild-gpl-2014-src/gnat/einfo.adb0000644000076700001450000111076612323721731016650 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- E I N F O -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ pragma Style_Checks (All_Checks); -- Turn off subprogram ordering, not used for this unit with Atree; use Atree; with Elists; use Elists; with Namet; use Namet; with Nlists; use Nlists; with Output; use Output; with Sinfo; use Sinfo; with Stand; use Stand; package body Einfo is use Atree.Unchecked_Access; -- This is one of the packages that is allowed direct untyped access to -- the fields in a node, since it provides the next level abstraction -- which incorporates appropriate checks. ---------------------------------------------- -- Usage of Fields in Defining Entity Nodes -- ---------------------------------------------- -- Four of these fields are defined in Sinfo, since they in are the base -- part of the node. The access routines for these four fields and the -- corresponding set procedures are defined in Sinfo. These fields are -- present in all entities. Note that Homonym is also in the base part of -- the node, but has access routines that are more properly part of Einfo, -- which is why they are defined here. -- Chars Name1 -- Next_Entity Node2 -- Scope Node3 -- Etype Node5 -- Remaining fields are present only in extended nodes (i.e. entities) -- The following fields are present in all entities -- Homonym Node4 -- First_Rep_Item Node6 -- Freeze_Node Node7 -- The usage of other fields (and the entity kinds to which it applies) -- depends on the particular field (see Einfo spec for details). -- Associated_Node_For_Itype Node8 -- Dependent_Instances Elist8 -- Hiding_Loop_Variable Node8 -- Mechanism Uint8 (but returns Mechanism_Type) -- Normalized_First_Bit Uint8 -- Postcondition_Proc Node8 -- Refinement_Constituents Elist8 -- Return_Applies_To Node8 -- First_Exit_Statement Node8 -- Class_Wide_Type Node9 -- Current_Value Node9 -- Part_Of_Constituents Elist9 -- Renaming_Map Uint9 -- Encapsulating_State Node10 -- Direct_Primitive_Operations Elist10 -- Discriminal_Link Node10 -- Float_Rep Uint10 (but returns Float_Rep_Kind) -- Handler_Records List10 -- Normalized_Position_Max Uint10 -- Component_Bit_Offset Uint11 -- Full_View Node11 -- Entry_Component Node11 -- Enumeration_Pos Uint11 -- Generic_Homonym Node11 -- Protected_Body_Subprogram Node11 -- Block_Node Node11 -- Barrier_Function Node12 -- Enumeration_Rep Uint12 -- Esize Uint12 -- Next_Inlined_Subprogram Node12 -- Component_Clause Node13 -- Elaboration_Entity Node13 -- Extra_Accessibility Node13 -- RM_Size Uint13 -- Alignment Uint14 -- First_Optional_Parameter Node14 -- Normalized_Position Uint14 -- Shadow_Entities List14 -- Discriminant_Number Uint15 -- DT_Position Uint15 -- DT_Entry_Count Uint15 -- Entry_Bodies_Array Node15 -- Entry_Parameters_Type Node15 -- Extra_Formal Node15 -- Lit_Indexes Node15 -- Related_Instance Node15 -- Status_Flag_Or_Transient_Decl Node15 -- Scale_Value Uint15 -- Storage_Size_Variable Node15 -- String_Literal_Low_Bound Node15 -- Access_Disp_Table Elist16 -- Body_References Elist16 -- Cloned_Subtype Node16 -- DTC_Entity Node16 -- Entry_Formal Node16 -- First_Private_Entity Node16 -- Lit_Strings Node16 -- String_Literal_Length Uint16 -- Unset_Reference Node16 -- Actual_Subtype Node17 -- Digits_Value Uint17 -- Discriminal Node17 -- First_Entity Node17 -- First_Index Node17 -- First_Literal Node17 -- Master_Id Node17 -- Modulus Uint17 -- Non_Limited_View Node17 -- Prival Node17 -- Alias Node18 -- Corresponding_Concurrent_Type Node18 -- Corresponding_Protected_Entry Node18 -- Corresponding_Record_Type Node18 -- Delta_Value Ureal18 -- Enclosing_Scope Node18 -- Equivalent_Type Node18 -- Private_Dependents Elist18 -- Renamed_Entity Node18 -- Renamed_Object Node18 -- Body_Entity Node19 -- Corresponding_Discriminant Node19 -- Default_Aspect_Component_Value Node19 -- Default_Aspect_Value Node19 -- Extra_Accessibility_Of_Result Node19 -- Parent_Subtype Node19 -- Size_Check_Code Node19 -- Spec_Entity Node19 -- Underlying_Full_View Node19 -- Component_Type Node20 -- Default_Value Node20 -- Directly_Designated_Type Node20 -- Discriminant_Checking_Func Node20 -- Discriminant_Default_Value Node20 -- Last_Entity Node20 -- Prival_Link Node20 -- Register_Exception_Call Node20 -- Scalar_Range Node20 -- Accept_Address Elist21 -- Default_Expr_Function Node21 -- Discriminant_Constraint Elist21 -- Interface_Name Node21 -- Original_Array_Type Node21 -- Small_Value Ureal21 -- Associated_Storage_Pool Node22 -- Component_Size Uint22 -- Corresponding_Remote_Type Node22 -- Enumeration_Rep_Expr Node22 -- Exception_Code Uint22 -- Original_Record_Component Node22 -- Private_View Node22 -- Protected_Formal Node22 -- Scope_Depth_Value Uint22 -- Shared_Var_Procs_Instance Node22 -- CR_Discriminant Node23 -- Entry_Cancel_Parameter Node23 -- Enum_Pos_To_Rep Node23 -- Extra_Constrained Node23 -- Finalization_Master Node23 -- Generic_Renamings Elist23 -- Inner_Instances Elist23 -- Limited_View Node23 -- Packed_Array_Impl_Type Node23 -- Protection_Object Node23 -- Stored_Constraint Elist23 -- Related_Expression Node24 -- Interface_Alias Node25 -- Interfaces Elist25 -- Debug_Renaming_Link Node25 -- DT_Offset_To_Top_Func Node25 -- PPC_Wrapper Node25 -- Related_Array_Object Node25 -- Static_Discrete_Predicate List25 -- Static_Real_Or_String_Predicate Node25 -- Task_Body_Procedure Node25 -- Dispatch_Table_Wrappers Elist26 -- Last_Assignment Node26 -- Original_Access_Type Node26 -- Overridden_Operation Node26 -- Package_Instantiation Node26 -- Relative_Deadline_Variable Node26 -- Current_Use_Clause Node27 -- Related_Type Node27 -- Wrapped_Entity Node27 -- Extra_Formals Node28 -- Finalizer Node28 -- Initialization_Statements Node28 -- Underlying_Record_View Node28 -- BIP_Initialization_Call Node29 -- Subprograms_For_Type Node29 -- Corresponding_Equality Node30 -- Last_Aggregate_Assignment Node30 -- Static_Initialization Node30 -- Derived_Type_Link Node31 -- Thunk_Entity Node31 -- SPARK_Pragma Node32 -- Linker_Section_Pragma Node33 -- SPARK_Aux_Pragma Node33 -- Contract Node34 -- Import_Pragma Node35 --------------------------------------------- -- Usage of Flags in Defining Entity Nodes -- --------------------------------------------- -- All flags are unique, there is no overlaying, so each flag is physically -- present in every entity. However, for many of the flags, it only makes -- sense for them to be set true for certain subsets of entity kinds. See -- the spec of Einfo for further details. -- Is_Frozen Flag4 -- Has_Discriminants Flag5 -- Is_Dispatching_Operation Flag6 -- Is_Immediately_Visible Flag7 -- In_Use Flag8 -- Is_Potentially_Use_Visible Flag9 -- Is_Public Flag10 -- Is_Inlined Flag11 -- Is_Constrained Flag12 -- Is_Generic_Type Flag13 -- Depends_On_Private Flag14 -- Is_Aliased Flag15 -- Is_Volatile Flag16 -- Is_Internal Flag17 -- Has_Delayed_Freeze Flag18 -- Is_Abstract_Subprogram Flag19 -- Is_Concurrent_Record_Type Flag20 -- Has_Master_Entity Flag21 -- Needs_No_Actuals Flag22 -- Has_Storage_Size_Clause Flag23 -- Is_Imported Flag24 -- Is_Limited_Record Flag25 -- Has_Completion Flag26 -- Has_Pragma_Controlled Flag27 -- Is_Statically_Allocated Flag28 -- Has_Size_Clause Flag29 -- Has_Task Flag30 -- Checks_May_Be_Suppressed Flag31 -- Kill_Elaboration_Checks Flag32 -- Kill_Range_Checks Flag33 -- Has_Independent_Components Flag34 -- Is_Class_Wide_Equivalent_Type Flag35 -- Referenced_As_LHS Flag36 -- Is_Known_Non_Null Flag37 -- Can_Never_Be_Null Flag38 -- Has_Default_Aspect Flag39 -- Body_Needed_For_SAL Flag40 -- Treat_As_Volatile Flag41 -- Is_Controlled Flag42 -- Has_Controlled_Component Flag43 -- Is_Pure Flag44 -- In_Private_Part Flag45 -- Has_Alignment_Clause Flag46 -- Has_Exit Flag47 -- In_Package_Body Flag48 -- Reachable Flag49 -- Delay_Subprogram_Descriptors Flag50 -- Is_Packed Flag51 -- Is_Entry_Formal Flag52 -- Is_Private_Descendant Flag53 -- Return_Present Flag54 -- Is_Tagged_Type Flag55 -- Has_Homonym Flag56 -- Is_Hidden Flag57 -- Non_Binary_Modulus Flag58 -- Is_Preelaborated Flag59 -- Is_Shared_Passive Flag60 -- Is_Remote_Types Flag61 -- Is_Remote_Call_Interface Flag62 -- Is_Character_Type Flag63 -- Is_Intrinsic_Subprogram Flag64 -- Has_Record_Rep_Clause Flag65 -- Has_Enumeration_Rep_Clause Flag66 -- Has_Small_Clause Flag67 -- Has_Component_Size_Clause Flag68 -- Is_Access_Constant Flag69 -- Is_First_Subtype Flag70 -- Has_Completion_In_Body Flag71 -- Has_Unknown_Discriminants Flag72 -- Is_Child_Unit Flag73 -- Is_CPP_Class Flag74 -- Has_Non_Standard_Rep Flag75 -- Is_Constructor Flag76 -- Static_Elaboration_Desired Flag77 -- Is_Tag Flag78 -- Has_All_Calls_Remote Flag79 -- Is_Constr_Subt_For_U_Nominal Flag80 -- Is_Asynchronous Flag81 -- Has_Gigi_Rep_Item Flag82 -- Has_Machine_Radix_Clause Flag83 -- Machine_Radix_10 Flag84 -- Is_Atomic Flag85 -- Has_Atomic_Components Flag86 -- Has_Volatile_Components Flag87 -- Discard_Names Flag88 -- Is_Interrupt_Handler Flag89 -- Returns_By_Ref Flag90 -- Is_Itype Flag91 -- Size_Known_At_Compile_Time Flag92 -- Reverse_Storage_Order Flag93 -- Is_Generic_Actual_Type Flag94 -- Uses_Sec_Stack Flag95 -- Warnings_Off Flag96 -- Is_Controlling_Formal Flag97 -- Has_Controlling_Result Flag98 -- Is_Exported Flag99 -- Has_Specified_Layout Flag100 -- Has_Nested_Block_With_Handler Flag101 -- Is_Called Flag102 -- Is_Completely_Hidden Flag103 -- Address_Taken Flag104 -- Suppress_Initialization Flag105 -- Is_Limited_Composite Flag106 -- Is_Private_Composite Flag107 -- Default_Expressions_Processed Flag108 -- Is_Non_Static_Subtype Flag109 -- Has_Out_Or_In_Out_Parameter Flag110 -- Is_Formal_Subprogram Flag111 -- Is_Renaming_Of_Object Flag112 -- No_Return Flag113 -- Delay_Cleanups Flag114 -- Never_Set_In_Source Flag115 -- Is_Visible_Lib_Unit Flag116 -- Is_Unchecked_Union Flag117 -- Is_For_Access_Subtype Flag118 -- Has_Convention_Pragma Flag119 -- Has_Primitive_Operations Flag120 -- Has_Pragma_Pack Flag121 -- Is_Bit_Packed_Array Flag122 -- Has_Unchecked_Union Flag123 -- Is_Eliminated Flag124 -- C_Pass_By_Copy Flag125 -- Is_Instantiated Flag126 -- Is_Valued_Procedure Flag127 -- (used for Component_Alignment) Flag128 -- (used for Component_Alignment) Flag129 -- Is_Generic_Instance Flag130 -- No_Pool_Assigned Flag131 -- Is_AST_Entry Flag132 -- Is_VMS_Exception Flag133 -- Is_Optional_Parameter Flag134 -- Has_Aliased_Components Flag135 -- No_Strict_Aliasing Flag136 -- Is_Machine_Code_Subprogram Flag137 -- Is_Packed_Array_Impl_Type Flag138 -- Has_Biased_Representation Flag139 -- Has_Complex_Representation Flag140 -- Is_Constr_Subt_For_UN_Aliased Flag141 -- Has_Missing_Return Flag142 -- Has_Recursive_Call Flag143 -- Is_Unsigned_Type Flag144 -- Strict_Alignment Flag145 -- Is_Abstract_Type Flag146 -- Needs_Debug_Info Flag147 -- Suppress_Elaboration_Warnings Flag148 -- Is_Compilation_Unit Flag149 -- Has_Pragma_Elaborate_Body Flag150 -- Has_Private_Ancestor Flag151 -- Entry_Accepted Flag152 -- Is_Obsolescent Flag153 -- Has_Per_Object_Constraint Flag154 -- Has_Private_Declaration Flag155 -- Referenced Flag156 -- Has_Pragma_Inline Flag157 -- Finalize_Storage_Only Flag158 -- From_Limited_With Flag159 -- Is_Package_Body_Entity Flag160 -- Has_Qualified_Name Flag161 -- Nonzero_Is_True Flag162 -- Is_True_Constant Flag163 -- Reverse_Bit_Order Flag164 -- Suppress_Style_Checks Flag165 -- Debug_Info_Off Flag166 -- Sec_Stack_Needed_For_Return Flag167 -- Materialize_Entity Flag168 -- Has_Pragma_Thread_Local_Storage Flag169 -- Is_Known_Valid Flag170 -- Is_Hidden_Open_Scope Flag171 -- Has_Object_Size_Clause Flag172 -- Has_Fully_Qualified_Name Flag173 -- Elaboration_Entity_Required Flag174 -- Has_Forward_Instantiation Flag175 -- Is_Discrim_SO_Function Flag176 -- Size_Depends_On_Discriminant Flag177 -- Is_Null_Init_Proc Flag178 -- Has_Pragma_Pure_Function Flag179 -- Has_Pragma_Unreferenced Flag180 -- Has_Contiguous_Rep Flag181 -- Has_Xref_Entry Flag182 -- Must_Be_On_Byte_Boundary Flag183 -- Has_Stream_Size_Clause Flag184 -- Is_Ada_2005_Only Flag185 -- Is_Interface Flag186 -- Has_Constrained_Partial_View Flag187 -- Uses_Lock_Free Flag188 -- Is_Pure_Unit_Access_Type Flag189 -- Has_Specified_Stream_Input Flag190 -- Has_Specified_Stream_Output Flag191 -- Has_Specified_Stream_Read Flag192 -- Has_Specified_Stream_Write Flag193 -- Is_Local_Anonymous_Access Flag194 -- Is_Primitive_Wrapper Flag195 -- Was_Hidden Flag196 -- Is_Limited_Interface Flag197 -- Has_Pragma_Ordered Flag198 -- Is_Ada_2012_Only Flag199 -- Has_Delayed_Aspects Flag200 -- Has_Pragma_No_Inline Flag201 -- Itype_Printed Flag202 -- Has_Pragma_Pure Flag203 -- Is_Known_Null Flag204 -- Low_Bound_Tested Flag205 -- Is_Visible_Formal Flag206 -- Known_To_Have_Preelab_Init Flag207 -- Must_Have_Preelab_Init Flag208 -- Is_Return_Object Flag209 -- Elaborate_Body_Desirable Flag210 -- Has_Static_Discriminants Flag211 -- Has_Pragma_Unreferenced_Objects Flag212 -- Requires_Overriding Flag213 -- Has_RACW Flag214 -- Has_Up_Level_Access Flag215 -- Universal_Aliasing Flag216 -- Suppress_Value_Tracking_On_Call Flag217 -- Is_Primitive Flag218 -- Has_Initial_Value Flag219 -- Has_Dispatch_Table Flag220 -- Has_Pragma_Preelab_Init Flag221 -- Used_As_Generic_Actual Flag222 -- Is_Descendent_Of_Address Flag223 -- Is_Raised Flag224 -- Is_Thunk Flag225 -- Is_Only_Out_Parameter Flag226 -- Referenced_As_Out_Parameter Flag227 -- Has_Thunks Flag228 -- Can_Use_Internal_Rep Flag229 -- Has_Pragma_Inline_Always Flag230 -- Renamed_In_Spec Flag231 -- Has_Invariants Flag232 -- Has_Pragma_Unmodified Flag233 -- Is_Dispatch_Table_Entity Flag234 -- Is_Trivial_Subprogram Flag235 -- Warnings_Off_Used Flag236 -- Warnings_Off_Used_Unmodified Flag237 -- Warnings_Off_Used_Unreferenced Flag238 -- OK_To_Reorder_Components Flag239 -- Has_Postconditions Flag240 -- Optimize_Alignment_Space Flag241 -- Optimize_Alignment_Time Flag242 -- Overlays_Constant Flag243 -- Is_RACW_Stub_Type Flag244 -- Is_Private_Primitive Flag245 -- Is_Underlying_Record_View Flag246 -- OK_To_Rename Flag247 -- Has_Inheritable_Invariants Flag248 -- Is_Safe_To_Reevaluate Flag249 -- Has_Predicates Flag250 -- Has_Implicit_Dereference Flag251 -- Is_Processed_Transient Flag252 -- Has_Anonymous_Master Flag253 -- Is_Implementation_Defined Flag254 -- Is_Predicate_Function Flag255 -- Is_Predicate_Function_M Flag256 -- Is_Invariant_Procedure Flag257 -- Has_Dynamic_Predicate_Aspect Flag258 -- Has_Static_Predicate_Aspect Flag259 -- Has_Loop_Entry_Attributes Flag260 -- Has_Delayed_Rep_Aspects Flag261 -- May_Inherit_Delayed_Rep_Aspects Flag262 -- Has_Visible_Refinement Flag263 -- Is_Discriminant_Check_Function Flag264 -- SPARK_Pragma_Inherited Flag265 -- SPARK_Aux_Pragma_Inherited Flag266 -- Has_Shift_Operator Flag267 -- Is_Independent Flag268 -- Has_Static_Predicate Flag269 -- Stores_Attribute_Old_Prefix Flag270 -- (Has_Protected) Flag271 -- (SSO_Set_Low_By_Default) Flag272 -- (SSO_Set_Low_By_Default) Flag273 -- (unused) Flag1 -- (unused) Flag2 -- (unused) Flag3 -- (unused) Flag274 -- (unused) Flag275 -- (unused) Flag276 -- (unused) Flag277 -- (unused) Flag278 -- (unused) Flag279 -- (unused) Flag280 -- (unused) Flag281 -- (unused) Flag282 -- (unused) Flag283 -- (unused) Flag284 -- (unused) Flag285 -- (unused) Flag286 -- Note: Flag287-317 are defined in atree.ads/adb, but not yet in atree.h ----------------------- -- Local subprograms -- ----------------------- function Has_Option (State_Id : Entity_Id; Option_Nam : Name_Id) return Boolean; -- Determine whether abstract state State_Id has particular option denoted -- by the name Option_Nam. --------------- -- Float_Rep -- --------------- function Float_Rep (Id : E) return F is pragma Assert (Is_Floating_Point_Type (Id)); begin return F'Val (UI_To_Int (Uint10 (Base_Type (Id)))); end Float_Rep; ---------------- -- Has_Option -- ---------------- function Has_Option (State_Id : Entity_Id; Option_Nam : Name_Id) return Boolean is Decl : constant Node_Id := Parent (State_Id); Opt : Node_Id; Opt_Nam : Node_Id; begin pragma Assert (Ekind (State_Id) = E_Abstract_State); -- The declaration of abstract states with options appear as an -- extension aggregate. If this is not the case, the option is not -- available. if Nkind (Decl) /= N_Extension_Aggregate then return False; end if; -- Simple options Opt := First (Expressions (Decl)); while Present (Opt) loop -- Currently the only simple option allowed is External if Nkind (Opt) = N_Identifier and then Chars (Opt) = Name_External and then Chars (Opt) = Option_Nam then return True; end if; Next (Opt); end loop; -- Complex options with various specifiers Opt := First (Component_Associations (Decl)); while Present (Opt) loop Opt_Nam := First (Choices (Opt)); if Nkind (Opt_Nam) = N_Identifier and then Chars (Opt_Nam) = Option_Nam then return True; end if; Next (Opt); end loop; return False; end Has_Option; -------------------------------- -- Attribute Access Functions -- -------------------------------- function Abstract_States (Id : E) return L is begin pragma Assert (Ekind_In (Id, E_Generic_Package, E_Package)); return Elist25 (Id); end Abstract_States; function Accept_Address (Id : E) return L is begin return Elist21 (Id); end Accept_Address; function Access_Disp_Table (Id : E) return L is begin pragma Assert (Ekind_In (Id, E_Record_Type, E_Record_Subtype)); return Elist16 (Implementation_Base_Type (Id)); end Access_Disp_Table; function Actual_Subtype (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable, E_Generic_In_Out_Parameter) or else Is_Formal (Id)); return Node17 (Id); end Actual_Subtype; function Address_Taken (Id : E) return B is begin return Flag104 (Id); end Address_Taken; function Alias (Id : E) return E is begin pragma Assert (Is_Overloadable (Id) or else Ekind (Id) = E_Subprogram_Type); return Node18 (Id); end Alias; function Alignment (Id : E) return U is begin pragma Assert (Is_Type (Id) or else Is_Formal (Id) or else Ekind_In (Id, E_Loop_Parameter, E_Constant, E_Exception, E_Variable)); return Uint14 (Id); end Alignment; function Associated_Formal_Package (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Package); return Node12 (Id); end Associated_Formal_Package; function Associated_Node_For_Itype (Id : E) return N is begin return Node8 (Id); end Associated_Node_For_Itype; function Associated_Storage_Pool (Id : E) return E is begin pragma Assert (Is_Access_Type (Id)); return Node22 (Root_Type (Id)); end Associated_Storage_Pool; function Barrier_Function (Id : E) return N is begin pragma Assert (Is_Entry (Id)); return Node12 (Id); end Barrier_Function; function Block_Node (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Block); return Node11 (Id); end Block_Node; function Body_Entity (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Package, E_Generic_Package)); return Node19 (Id); end Body_Entity; function Body_Needed_For_SAL (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Package or else Is_Subprogram (Id) or else Is_Generic_Unit (Id)); return Flag40 (Id); end Body_Needed_For_SAL; function Body_References (Id : E) return L is begin pragma Assert (Ekind (Id) = E_Abstract_State); return Elist16 (Id); end Body_References; function BIP_Initialization_Call (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); return Node29 (Id); end BIP_Initialization_Call; function C_Pass_By_Copy (Id : E) return B is begin pragma Assert (Is_Record_Type (Id)); return Flag125 (Implementation_Base_Type (Id)); end C_Pass_By_Copy; function Can_Never_Be_Null (Id : E) return B is begin return Flag38 (Id); end Can_Never_Be_Null; function Checks_May_Be_Suppressed (Id : E) return B is begin return Flag31 (Id); end Checks_May_Be_Suppressed; function Class_Wide_Type (Id : E) return E is begin pragma Assert (Is_Type (Id)); return Node9 (Id); end Class_Wide_Type; function Cloned_Subtype (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Record_Subtype, E_Class_Wide_Subtype)); return Node16 (Id); end Cloned_Subtype; function Component_Bit_Offset (Id : E) return U is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); return Uint11 (Id); end Component_Bit_Offset; function Component_Clause (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); return Node13 (Id); end Component_Clause; function Component_Size (Id : E) return U is begin pragma Assert (Is_Array_Type (Id)); return Uint22 (Implementation_Base_Type (Id)); end Component_Size; function Component_Type (Id : E) return E is begin pragma Assert (Is_Array_Type (Id) or else Is_String_Type (Id)); return Node20 (Implementation_Base_Type (Id)); end Component_Type; function Corresponding_Concurrent_Type (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Record_Type); return Node18 (Id); end Corresponding_Concurrent_Type; function Corresponding_Discriminant (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Discriminant); return Node19 (Id); end Corresponding_Discriminant; function Corresponding_Equality (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Function and then not Comes_From_Source (Id) and then Chars (Id) = Name_Op_Ne); return Node30 (Id); end Corresponding_Equality; function Corresponding_Protected_Entry (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Subprogram_Body); return Node18 (Id); end Corresponding_Protected_Entry; function Corresponding_Record_Type (Id : E) return E is begin pragma Assert (Is_Concurrent_Type (Id)); return Node18 (Id); end Corresponding_Record_Type; function Corresponding_Remote_Type (Id : E) return E is begin return Node22 (Id); end Corresponding_Remote_Type; function Current_Use_Clause (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Package or else Is_Type (Id)); return Node27 (Id); end Current_Use_Clause; function Current_Value (Id : E) return N is begin pragma Assert (Ekind (Id) in Object_Kind); return Node9 (Id); end Current_Value; function CR_Discriminant (Id : E) return E is begin return Node23 (Id); end CR_Discriminant; function Debug_Info_Off (Id : E) return B is begin return Flag166 (Id); end Debug_Info_Off; function Debug_Renaming_Link (Id : E) return E is begin return Node25 (Id); end Debug_Renaming_Link; function Default_Aspect_Component_Value (Id : E) return N is begin pragma Assert (Is_Array_Type (Id)); return Node19 (Base_Type (Id)); end Default_Aspect_Component_Value; function Default_Aspect_Value (Id : E) return N is begin pragma Assert (Is_Scalar_Type (Id)); return Node19 (Base_Type (Id)); end Default_Aspect_Value; function Default_Expr_Function (Id : E) return E is begin pragma Assert (Is_Formal (Id)); return Node21 (Id); end Default_Expr_Function; function Default_Expressions_Processed (Id : E) return B is begin return Flag108 (Id); end Default_Expressions_Processed; function Default_Value (Id : E) return N is begin pragma Assert (Is_Formal (Id)); return Node20 (Id); end Default_Value; function Delay_Cleanups (Id : E) return B is begin return Flag114 (Id); end Delay_Cleanups; function Delay_Subprogram_Descriptors (Id : E) return B is begin return Flag50 (Id); end Delay_Subprogram_Descriptors; function Delta_Value (Id : E) return R is begin pragma Assert (Is_Fixed_Point_Type (Id)); return Ureal18 (Id); end Delta_Value; function Dependent_Instances (Id : E) return L is begin pragma Assert (Is_Generic_Instance (Id)); return Elist8 (Id); end Dependent_Instances; function Depends_On_Private (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag14 (Id); end Depends_On_Private; function Derived_Type_Link (Id : E) return E is begin pragma Assert (Is_Type (Id)); return Node31 (Base_Type (Id)); end Derived_Type_Link; function Digits_Value (Id : E) return U is begin pragma Assert (Is_Floating_Point_Type (Id) or else Is_Decimal_Fixed_Point_Type (Id)); return Uint17 (Id); end Digits_Value; function Direct_Primitive_Operations (Id : E) return L is begin pragma Assert (Is_Tagged_Type (Id)); return Elist10 (Id); end Direct_Primitive_Operations; function Directly_Designated_Type (Id : E) return E is begin pragma Assert (Is_Access_Type (Id)); return Node20 (Id); end Directly_Designated_Type; function Discard_Names (Id : E) return B is begin return Flag88 (Id); end Discard_Names; function Discriminal (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Discriminant); return Node17 (Id); end Discriminal; function Discriminal_Link (Id : E) return N is begin return Node10 (Id); end Discriminal_Link; function Discriminant_Checking_Func (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Component); return Node20 (Id); end Discriminant_Checking_Func; function Discriminant_Constraint (Id : E) return L is begin pragma Assert (Is_Composite_Type (Id) and then Has_Discriminants (Id)); return Elist21 (Id); end Discriminant_Constraint; function Discriminant_Default_Value (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Discriminant); return Node20 (Id); end Discriminant_Default_Value; function Discriminant_Number (Id : E) return U is begin pragma Assert (Ekind (Id) = E_Discriminant); return Uint15 (Id); end Discriminant_Number; function Dispatch_Table_Wrappers (Id : E) return L is begin pragma Assert (Ekind_In (Id, E_Record_Type, E_Record_Subtype)); return Elist26 (Implementation_Base_Type (Id)); end Dispatch_Table_Wrappers; function DT_Entry_Count (Id : E) return U is begin pragma Assert (Ekind (Id) = E_Component and then Is_Tag (Id)); return Uint15 (Id); end DT_Entry_Count; function DT_Offset_To_Top_Func (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Component and then Is_Tag (Id)); return Node25 (Id); end DT_Offset_To_Top_Func; function DT_Position (Id : E) return U is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure) and then Present (DTC_Entity (Id))); return Uint15 (Id); end DT_Position; function DTC_Entity (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); return Node16 (Id); end DTC_Entity; function Elaborate_Body_Desirable (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Package); return Flag210 (Id); end Elaborate_Body_Desirable; function Elaboration_Entity (Id : E) return E is begin pragma Assert (Is_Subprogram (Id) or else Ekind (Id) = E_Package or else Is_Generic_Unit (Id)); return Node13 (Id); end Elaboration_Entity; function Elaboration_Entity_Required (Id : E) return B is begin pragma Assert (Is_Subprogram (Id) or else Ekind (Id) = E_Package or else Is_Generic_Unit (Id)); return Flag174 (Id); end Elaboration_Entity_Required; function Encapsulating_State (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Abstract_State, E_Variable)); return Node10 (Id); end Encapsulating_State; function Enclosing_Scope (Id : E) return E is begin return Node18 (Id); end Enclosing_Scope; function Entry_Accepted (Id : E) return B is begin pragma Assert (Is_Entry (Id)); return Flag152 (Id); end Entry_Accepted; function Entry_Bodies_Array (Id : E) return E is begin return Node15 (Id); end Entry_Bodies_Array; function Entry_Cancel_Parameter (Id : E) return E is begin return Node23 (Id); end Entry_Cancel_Parameter; function Entry_Component (Id : E) return E is begin return Node11 (Id); end Entry_Component; function Entry_Formal (Id : E) return E is begin return Node16 (Id); end Entry_Formal; function Entry_Index_Constant (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Entry_Index_Parameter); return Node18 (Id); end Entry_Index_Constant; function Contract (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Entry, E_Entry_Family, E_Generic_Package, E_Package, E_Package_Body, E_Subprogram_Body, E_Variable) or else Is_Generic_Subprogram (Id) or else Is_Subprogram (Id)); return Node34 (Id); end Contract; function Entry_Parameters_Type (Id : E) return E is begin return Node15 (Id); end Entry_Parameters_Type; function Enum_Pos_To_Rep (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Enumeration_Type); return Node23 (Id); end Enum_Pos_To_Rep; function Enumeration_Pos (Id : E) return Uint is begin pragma Assert (Ekind (Id) = E_Enumeration_Literal); return Uint11 (Id); end Enumeration_Pos; function Enumeration_Rep (Id : E) return U is begin pragma Assert (Ekind (Id) = E_Enumeration_Literal); return Uint12 (Id); end Enumeration_Rep; function Enumeration_Rep_Expr (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Enumeration_Literal); return Node22 (Id); end Enumeration_Rep_Expr; function Equivalent_Type (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Class_Wide_Type, E_Class_Wide_Subtype, E_Access_Subprogram_Type, E_Access_Protected_Subprogram_Type, E_Anonymous_Access_Protected_Subprogram_Type, E_Access_Subprogram_Type, E_Exception_Type)); return Node18 (Id); end Equivalent_Type; function Esize (Id : E) return Uint is begin return Uint12 (Id); end Esize; function Exception_Code (Id : E) return Uint is begin pragma Assert (Ekind (Id) = E_Exception); return Uint22 (Id); end Exception_Code; function Extra_Accessibility (Id : E) return E is begin pragma Assert (Is_Formal (Id) or else Ekind_In (Id, E_Variable, E_Constant)); return Node13 (Id); end Extra_Accessibility; function Extra_Accessibility_Of_Result (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Function, E_Operator, E_Subprogram_Type)); return Node19 (Id); end Extra_Accessibility_Of_Result; function Extra_Constrained (Id : E) return E is begin pragma Assert (Is_Formal (Id) or else Ekind (Id) = E_Variable); return Node23 (Id); end Extra_Constrained; function Extra_Formal (Id : E) return E is begin return Node15 (Id); end Extra_Formal; function Extra_Formals (Id : E) return E is begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Entry_Family, E_Subprogram_Body, E_Subprogram_Type)); return Node28 (Id); end Extra_Formals; function Can_Use_Internal_Rep (Id : E) return B is begin pragma Assert (Is_Access_Subprogram_Type (Base_Type (Id))); return Flag229 (Base_Type (Id)); end Can_Use_Internal_Rep; function Finalization_Master (Id : E) return E is begin pragma Assert (Is_Access_Type (Id)); return Node23 (Root_Type (Id)); end Finalization_Master; function Finalize_Storage_Only (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag158 (Base_Type (Id)); end Finalize_Storage_Only; function Finalizer (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Package, E_Package_Body)); return Node28 (Id); end Finalizer; function First_Entity (Id : E) return E is begin return Node17 (Id); end First_Entity; function First_Exit_Statement (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Loop); return Node8 (Id); end First_Exit_Statement; function First_Index (Id : E) return N is begin pragma Assert (Is_Array_Type (Id) or else Is_String_Type (Id)); return Node17 (Id); end First_Index; function First_Literal (Id : E) return E is begin pragma Assert (Is_Enumeration_Type (Id)); return Node17 (Id); end First_Literal; function First_Optional_Parameter (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); return Node14 (Id); end First_Optional_Parameter; function First_Private_Entity (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Package, E_Generic_Package) or else Ekind (Id) in Concurrent_Kind); return Node16 (Id); end First_Private_Entity; function First_Rep_Item (Id : E) return E is begin return Node6 (Id); end First_Rep_Item; function Freeze_Node (Id : E) return N is begin return Node7 (Id); end Freeze_Node; function From_Limited_With (Id : E) return B is begin return Flag159 (Id); end From_Limited_With; function Full_View (Id : E) return E is begin pragma Assert (Is_Type (Id) or else Ekind (Id) = E_Constant); return Node11 (Id); end Full_View; function Generic_Homonym (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Generic_Package); return Node11 (Id); end Generic_Homonym; function Generic_Renamings (Id : E) return L is begin return Elist23 (Id); end Generic_Renamings; function Handler_Records (Id : E) return S is begin return List10 (Id); end Handler_Records; function Has_Aliased_Components (Id : E) return B is begin return Flag135 (Implementation_Base_Type (Id)); end Has_Aliased_Components; function Has_Alignment_Clause (Id : E) return B is begin return Flag46 (Id); end Has_Alignment_Clause; function Has_All_Calls_Remote (Id : E) return B is begin return Flag79 (Id); end Has_All_Calls_Remote; function Has_Anonymous_Master (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Function, E_Package, E_Package_Body, E_Procedure)); return Flag253 (Id); end Has_Anonymous_Master; function Has_Atomic_Components (Id : E) return B is begin return Flag86 (Implementation_Base_Type (Id)); end Has_Atomic_Components; function Has_Biased_Representation (Id : E) return B is begin return Flag139 (Id); end Has_Biased_Representation; function Has_Completion (Id : E) return B is begin return Flag26 (Id); end Has_Completion; function Has_Completion_In_Body (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag71 (Id); end Has_Completion_In_Body; function Has_Complex_Representation (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag140 (Implementation_Base_Type (Id)); end Has_Complex_Representation; function Has_Component_Size_Clause (Id : E) return B is begin pragma Assert (Is_Array_Type (Id)); return Flag68 (Implementation_Base_Type (Id)); end Has_Component_Size_Clause; function Has_Constrained_Partial_View (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag187 (Id); end Has_Constrained_Partial_View; function Has_Controlled_Component (Id : E) return B is begin return Flag43 (Base_Type (Id)); end Has_Controlled_Component; function Has_Contiguous_Rep (Id : E) return B is begin return Flag181 (Id); end Has_Contiguous_Rep; function Has_Controlling_Result (Id : E) return B is begin return Flag98 (Id); end Has_Controlling_Result; function Has_Convention_Pragma (Id : E) return B is begin return Flag119 (Id); end Has_Convention_Pragma; function Has_Default_Aspect (Id : E) return B is begin return Flag39 (Base_Type (Id)); end Has_Default_Aspect; function Has_Delayed_Aspects (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag200 (Id); end Has_Delayed_Aspects; function Has_Delayed_Freeze (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag18 (Id); end Has_Delayed_Freeze; function Has_Delayed_Rep_Aspects (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag261 (Id); end Has_Delayed_Rep_Aspects; function Has_Discriminants (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag5 (Id); end Has_Discriminants; function Has_Dispatch_Table (Id : E) return B is begin pragma Assert (Is_Tagged_Type (Id)); return Flag220 (Id); end Has_Dispatch_Table; function Has_Dynamic_Predicate_Aspect (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag258 (Id); end Has_Dynamic_Predicate_Aspect; function Has_Enumeration_Rep_Clause (Id : E) return B is begin pragma Assert (Is_Enumeration_Type (Id)); return Flag66 (Id); end Has_Enumeration_Rep_Clause; function Has_Exit (Id : E) return B is begin return Flag47 (Id); end Has_Exit; function Has_Forward_Instantiation (Id : E) return B is begin return Flag175 (Id); end Has_Forward_Instantiation; function Has_Fully_Qualified_Name (Id : E) return B is begin return Flag173 (Id); end Has_Fully_Qualified_Name; function Has_Gigi_Rep_Item (Id : E) return B is begin return Flag82 (Id); end Has_Gigi_Rep_Item; function Has_Homonym (Id : E) return B is begin return Flag56 (Id); end Has_Homonym; function Has_Implicit_Dereference (Id : E) return B is begin return Flag251 (Id); end Has_Implicit_Dereference; function Has_Independent_Components (Id : E) return B is begin pragma Assert (Is_Array_Type (Id) or else Is_Record_Type (Id)); return Flag34 (Base_Type (Id)); end Has_Independent_Components; function Has_Inheritable_Invariants (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag248 (Id); end Has_Inheritable_Invariants; function Has_Initial_Value (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Variable or else Is_Formal (Id)); return Flag219 (Id); end Has_Initial_Value; function Has_Invariants (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag232 (Id); end Has_Invariants; function Has_Loop_Entry_Attributes (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Loop); return Flag260 (Id); end Has_Loop_Entry_Attributes; function Has_Machine_Radix_Clause (Id : E) return B is begin pragma Assert (Is_Decimal_Fixed_Point_Type (Id)); return Flag83 (Id); end Has_Machine_Radix_Clause; function Has_Master_Entity (Id : E) return B is begin return Flag21 (Id); end Has_Master_Entity; function Has_Missing_Return (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Function, E_Generic_Function)); return Flag142 (Id); end Has_Missing_Return; function Has_Nested_Block_With_Handler (Id : E) return B is begin return Flag101 (Id); end Has_Nested_Block_With_Handler; function Has_Non_Standard_Rep (Id : E) return B is begin return Flag75 (Implementation_Base_Type (Id)); end Has_Non_Standard_Rep; function Has_Object_Size_Clause (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag172 (Id); end Has_Object_Size_Clause; function Has_Out_Or_In_Out_Parameter (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Function, E_Generic_Function)); return Flag110 (Id); end Has_Out_Or_In_Out_Parameter; function Has_Per_Object_Constraint (Id : E) return B is begin return Flag154 (Id); end Has_Per_Object_Constraint; function Has_Postconditions (Id : E) return B is begin pragma Assert (Is_Subprogram (Id)); return Flag240 (Id); end Has_Postconditions; function Has_Pragma_Controlled (Id : E) return B is begin pragma Assert (Is_Access_Type (Id)); return Flag27 (Implementation_Base_Type (Id)); end Has_Pragma_Controlled; function Has_Pragma_Elaborate_Body (Id : E) return B is begin return Flag150 (Id); end Has_Pragma_Elaborate_Body; function Has_Pragma_Inline (Id : E) return B is begin return Flag157 (Id); end Has_Pragma_Inline; function Has_Pragma_Inline_Always (Id : E) return B is begin return Flag230 (Id); end Has_Pragma_Inline_Always; function Has_Pragma_No_Inline (Id : E) return B is begin return Flag201 (Id); end Has_Pragma_No_Inline; function Has_Pragma_Ordered (Id : E) return B is begin pragma Assert (Is_Enumeration_Type (Id)); return Flag198 (Implementation_Base_Type (Id)); end Has_Pragma_Ordered; function Has_Pragma_Pack (Id : E) return B is begin pragma Assert (Is_Record_Type (Id) or else Is_Array_Type (Id)); return Flag121 (Implementation_Base_Type (Id)); end Has_Pragma_Pack; function Has_Pragma_Preelab_Init (Id : E) return B is begin return Flag221 (Id); end Has_Pragma_Preelab_Init; function Has_Pragma_Pure (Id : E) return B is begin return Flag203 (Id); end Has_Pragma_Pure; function Has_Pragma_Pure_Function (Id : E) return B is begin return Flag179 (Id); end Has_Pragma_Pure_Function; function Has_Pragma_Thread_Local_Storage (Id : E) return B is begin return Flag169 (Id); end Has_Pragma_Thread_Local_Storage; function Has_Pragma_Unmodified (Id : E) return B is begin return Flag233 (Id); end Has_Pragma_Unmodified; function Has_Pragma_Unreferenced (Id : E) return B is begin return Flag180 (Id); end Has_Pragma_Unreferenced; function Has_Pragma_Unreferenced_Objects (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag212 (Id); end Has_Pragma_Unreferenced_Objects; function Has_Predicates (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag250 (Id); end Has_Predicates; function Has_Primitive_Operations (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag120 (Base_Type (Id)); end Has_Primitive_Operations; function Has_Private_Ancestor (Id : E) return B is begin return Flag151 (Id); end Has_Private_Ancestor; function Has_Private_Declaration (Id : E) return B is begin return Flag155 (Id); end Has_Private_Declaration; function Has_Protected (Id : E) return B is begin return Flag271 (Base_Type (Id)); end Has_Protected; function Has_Qualified_Name (Id : E) return B is begin return Flag161 (Id); end Has_Qualified_Name; function Has_RACW (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Package); return Flag214 (Id); end Has_RACW; function Has_Record_Rep_Clause (Id : E) return B is begin pragma Assert (Is_Record_Type (Id)); return Flag65 (Implementation_Base_Type (Id)); end Has_Record_Rep_Clause; function Has_Recursive_Call (Id : E) return B is begin pragma Assert (Is_Subprogram (Id)); return Flag143 (Id); end Has_Recursive_Call; function Has_Shift_Operator (Id : E) return B is begin pragma Assert (Is_Integer_Type (Id)); return Flag267 (Base_Type (Id)); end Has_Shift_Operator; function Has_Size_Clause (Id : E) return B is begin return Flag29 (Id); end Has_Size_Clause; function Has_Small_Clause (Id : E) return B is begin return Flag67 (Id); end Has_Small_Clause; function Has_Specified_Layout (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag100 (Implementation_Base_Type (Id)); end Has_Specified_Layout; function Has_Specified_Stream_Input (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag190 (Id); end Has_Specified_Stream_Input; function Has_Specified_Stream_Output (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag191 (Id); end Has_Specified_Stream_Output; function Has_Specified_Stream_Read (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag192 (Id); end Has_Specified_Stream_Read; function Has_Specified_Stream_Write (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag193 (Id); end Has_Specified_Stream_Write; function Has_Static_Discriminants (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag211 (Id); end Has_Static_Discriminants; function Has_Static_Predicate (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag269 (Id); end Has_Static_Predicate; function Has_Static_Predicate_Aspect (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag259 (Id); end Has_Static_Predicate_Aspect; function Has_Storage_Size_Clause (Id : E) return B is begin pragma Assert (Is_Access_Type (Id) or else Is_Task_Type (Id)); return Flag23 (Implementation_Base_Type (Id)); end Has_Storage_Size_Clause; function Has_Stream_Size_Clause (Id : E) return B is begin return Flag184 (Id); end Has_Stream_Size_Clause; function Has_Task (Id : E) return B is begin return Flag30 (Base_Type (Id)); end Has_Task; function Has_Thunks (Id : E) return B is begin return Flag228 (Id); end Has_Thunks; function Has_Unchecked_Union (Id : E) return B is begin return Flag123 (Base_Type (Id)); end Has_Unchecked_Union; function Has_Unknown_Discriminants (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag72 (Id); end Has_Unknown_Discriminants; function Has_Up_Level_Access (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Variable, E_Constant, E_Loop_Parameter)); return Flag215 (Id); end Has_Up_Level_Access; function Has_Visible_Refinement (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Abstract_State); return Flag263 (Id); end Has_Visible_Refinement; function Has_Volatile_Components (Id : E) return B is begin return Flag87 (Implementation_Base_Type (Id)); end Has_Volatile_Components; function Has_Xref_Entry (Id : E) return B is begin return Flag182 (Id); end Has_Xref_Entry; function Hiding_Loop_Variable (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Variable); return Node8 (Id); end Hiding_Loop_Variable; function Homonym (Id : E) return E is begin return Node4 (Id); end Homonym; function Import_Pragma (Id : E) return E is begin pragma Assert (Is_Subprogram (Id)); return Node35 (Id); end Import_Pragma; function Interface_Alias (Id : E) return E is begin pragma Assert (Is_Subprogram (Id)); return Node25 (Id); end Interface_Alias; function Interfaces (Id : E) return L is begin pragma Assert (Is_Record_Type (Id)); return Elist25 (Id); end Interfaces; function In_Package_Body (Id : E) return B is begin return Flag48 (Id); end In_Package_Body; function In_Private_Part (Id : E) return B is begin return Flag45 (Id); end In_Private_Part; function In_Use (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag8 (Id); end In_Use; function Initialization_Statements (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); return Node28 (Id); end Initialization_Statements; function Inner_Instances (Id : E) return L is begin return Elist23 (Id); end Inner_Instances; function Interface_Name (Id : E) return N is begin return Node21 (Id); end Interface_Name; function Is_Abstract_Subprogram (Id : E) return B is begin pragma Assert (Is_Overloadable (Id)); return Flag19 (Id); end Is_Abstract_Subprogram; function Is_Abstract_Type (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag146 (Id); end Is_Abstract_Type; function Is_Local_Anonymous_Access (Id : E) return B is begin pragma Assert (Is_Access_Type (Id)); return Flag194 (Id); end Is_Local_Anonymous_Access; function Is_Access_Constant (Id : E) return B is begin pragma Assert (Is_Access_Type (Id)); return Flag69 (Id); end Is_Access_Constant; function Is_Ada_2005_Only (Id : E) return B is begin return Flag185 (Id); end Is_Ada_2005_Only; function Is_Ada_2012_Only (Id : E) return B is begin return Flag199 (Id); end Is_Ada_2012_Only; function Is_Aliased (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag15 (Id); end Is_Aliased; function Is_AST_Entry (Id : E) return B is begin pragma Assert (Is_Entry (Id)); return Flag132 (Id); end Is_AST_Entry; function Is_Asynchronous (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Procedure or else Is_Type (Id)); return Flag81 (Id); end Is_Asynchronous; function Is_Atomic (Id : E) return B is begin return Flag85 (Id); end Is_Atomic; function Is_Bit_Packed_Array (Id : E) return B is begin return Flag122 (Implementation_Base_Type (Id)); end Is_Bit_Packed_Array; function Is_Called (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Procedure, E_Function)); return Flag102 (Id); end Is_Called; function Is_Character_Type (Id : E) return B is begin return Flag63 (Id); end Is_Character_Type; function Is_Child_Unit (Id : E) return B is begin return Flag73 (Id); end Is_Child_Unit; function Is_Class_Wide_Equivalent_Type (Id : E) return B is begin return Flag35 (Id); end Is_Class_Wide_Equivalent_Type; function Is_Compilation_Unit (Id : E) return B is begin return Flag149 (Id); end Is_Compilation_Unit; function Is_Completely_Hidden (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Discriminant); return Flag103 (Id); end Is_Completely_Hidden; function Is_Constr_Subt_For_U_Nominal (Id : E) return B is begin return Flag80 (Id); end Is_Constr_Subt_For_U_Nominal; function Is_Constr_Subt_For_UN_Aliased (Id : E) return B is begin return Flag141 (Id); end Is_Constr_Subt_For_UN_Aliased; function Is_Constrained (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag12 (Id); end Is_Constrained; function Is_Constructor (Id : E) return B is begin return Flag76 (Id); end Is_Constructor; function Is_Controlled (Id : E) return B is begin return Flag42 (Base_Type (Id)); end Is_Controlled; function Is_Controlling_Formal (Id : E) return B is begin pragma Assert (Is_Formal (Id)); return Flag97 (Id); end Is_Controlling_Formal; function Is_CPP_Class (Id : E) return B is begin return Flag74 (Id); end Is_CPP_Class; function Is_Descendent_Of_Address (Id : E) return B is begin return Flag223 (Id); end Is_Descendent_Of_Address; function Is_Discrim_SO_Function (Id : E) return B is begin return Flag176 (Id); end Is_Discrim_SO_Function; function Is_Discriminant_Check_Function (Id : E) return B is begin return Flag264 (Id); end Is_Discriminant_Check_Function; function Is_Dispatch_Table_Entity (Id : E) return B is begin return Flag234 (Id); end Is_Dispatch_Table_Entity; function Is_Dispatching_Operation (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag6 (Id); end Is_Dispatching_Operation; function Is_Eliminated (Id : E) return B is begin return Flag124 (Id); end Is_Eliminated; function Is_Entry_Formal (Id : E) return B is begin return Flag52 (Id); end Is_Entry_Formal; function Is_Exported (Id : E) return B is begin return Flag99 (Id); end Is_Exported; function Is_First_Subtype (Id : E) return B is begin return Flag70 (Id); end Is_First_Subtype; function Is_For_Access_Subtype (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Record_Subtype, E_Private_Subtype)); return Flag118 (Id); end Is_For_Access_Subtype; function Is_Formal_Subprogram (Id : E) return B is begin return Flag111 (Id); end Is_Formal_Subprogram; function Is_Frozen (Id : E) return B is begin return Flag4 (Id); end Is_Frozen; function Is_Generic_Actual_Type (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag94 (Id); end Is_Generic_Actual_Type; function Is_Generic_Instance (Id : E) return B is begin return Flag130 (Id); end Is_Generic_Instance; function Is_Generic_Type (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag13 (Id); end Is_Generic_Type; function Is_Hidden (Id : E) return B is begin return Flag57 (Id); end Is_Hidden; function Is_Hidden_Open_Scope (Id : E) return B is begin return Flag171 (Id); end Is_Hidden_Open_Scope; function Is_Immediately_Visible (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag7 (Id); end Is_Immediately_Visible; function Is_Implementation_Defined (Id : E) return B is begin return Flag254 (Id); end Is_Implementation_Defined; function Is_Imported (Id : E) return B is begin return Flag24 (Id); end Is_Imported; function Is_Independent (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Component); return Flag268 (Id); end Is_Independent; function Is_Inlined (Id : E) return B is begin return Flag11 (Id); end Is_Inlined; function Is_Interface (Id : E) return B is begin return Flag186 (Id); end Is_Interface; function Is_Instantiated (Id : E) return B is begin return Flag126 (Id); end Is_Instantiated; function Is_Internal (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag17 (Id); end Is_Internal; function Is_Interrupt_Handler (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag89 (Id); end Is_Interrupt_Handler; function Is_Intrinsic_Subprogram (Id : E) return B is begin return Flag64 (Id); end Is_Intrinsic_Subprogram; function Is_Invariant_Procedure (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure); return Flag257 (Id); end Is_Invariant_Procedure; function Is_Itype (Id : E) return B is begin return Flag91 (Id); end Is_Itype; function Is_Known_Non_Null (Id : E) return B is begin return Flag37 (Id); end Is_Known_Non_Null; function Is_Known_Null (Id : E) return B is begin return Flag204 (Id); end Is_Known_Null; function Is_Known_Valid (Id : E) return B is begin return Flag170 (Id); end Is_Known_Valid; function Is_Limited_Composite (Id : E) return B is begin return Flag106 (Id); end Is_Limited_Composite; function Is_Limited_Interface (Id : E) return B is begin return Flag197 (Id); end Is_Limited_Interface; function Is_Limited_Record (Id : E) return B is begin return Flag25 (Id); end Is_Limited_Record; function Is_Machine_Code_Subprogram (Id : E) return B is begin pragma Assert (Is_Subprogram (Id)); return Flag137 (Id); end Is_Machine_Code_Subprogram; function Is_Non_Static_Subtype (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag109 (Id); end Is_Non_Static_Subtype; function Is_Null_Init_Proc (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Procedure); return Flag178 (Id); end Is_Null_Init_Proc; function Is_Obsolescent (Id : E) return B is begin return Flag153 (Id); end Is_Obsolescent; function Is_Only_Out_Parameter (Id : E) return B is begin pragma Assert (Is_Formal (Id)); return Flag226 (Id); end Is_Only_Out_Parameter; function Is_Optional_Parameter (Id : E) return B is begin pragma Assert (Is_Formal (Id)); return Flag134 (Id); end Is_Optional_Parameter; function Is_Package_Body_Entity (Id : E) return B is begin return Flag160 (Id); end Is_Package_Body_Entity; function Is_Packed (Id : E) return B is begin return Flag51 (Implementation_Base_Type (Id)); end Is_Packed; function Is_Packed_Array_Impl_Type (Id : E) return B is begin return Flag138 (Id); end Is_Packed_Array_Impl_Type; function Is_Potentially_Use_Visible (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag9 (Id); end Is_Potentially_Use_Visible; function Is_Predicate_Function (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure); return Flag255 (Id); end Is_Predicate_Function; function Is_Predicate_Function_M (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure); return Flag256 (Id); end Is_Predicate_Function_M; function Is_Preelaborated (Id : E) return B is begin return Flag59 (Id); end Is_Preelaborated; function Is_Primitive (Id : E) return B is begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Generic_Function, E_Generic_Procedure)); return Flag218 (Id); end Is_Primitive; function Is_Primitive_Wrapper (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); return Flag195 (Id); end Is_Primitive_Wrapper; function Is_Private_Composite (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag107 (Id); end Is_Private_Composite; function Is_Private_Descendant (Id : E) return B is begin return Flag53 (Id); end Is_Private_Descendant; function Is_Private_Primitive (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); return Flag245 (Id); end Is_Private_Primitive; function Is_Processed_Transient (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); return Flag252 (Id); end Is_Processed_Transient; function Is_Public (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag10 (Id); end Is_Public; function Is_Pure (Id : E) return B is begin return Flag44 (Id); end Is_Pure; function Is_Pure_Unit_Access_Type (Id : E) return B is begin pragma Assert (Is_Access_Type (Id)); return Flag189 (Id); end Is_Pure_Unit_Access_Type; function Is_RACW_Stub_Type (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag244 (Id); end Is_RACW_Stub_Type; function Is_Raised (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Exception); return Flag224 (Id); end Is_Raised; function Is_Remote_Call_Interface (Id : E) return B is begin return Flag62 (Id); end Is_Remote_Call_Interface; function Is_Remote_Types (Id : E) return B is begin return Flag61 (Id); end Is_Remote_Types; function Is_Renaming_Of_Object (Id : E) return B is begin return Flag112 (Id); end Is_Renaming_Of_Object; function Is_Return_Object (Id : E) return B is begin return Flag209 (Id); end Is_Return_Object; function Is_Safe_To_Reevaluate (Id : E) return B is begin return Flag249 (Id); end Is_Safe_To_Reevaluate; function Is_Shared_Passive (Id : E) return B is begin return Flag60 (Id); end Is_Shared_Passive; function Is_Statically_Allocated (Id : E) return B is begin return Flag28 (Id); end Is_Statically_Allocated; function Is_Tag (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); return Flag78 (Id); end Is_Tag; function Is_Tagged_Type (Id : E) return B is begin return Flag55 (Id); end Is_Tagged_Type; function Is_Thunk (Id : E) return B is begin return Flag225 (Id); end Is_Thunk; function Is_Trivial_Subprogram (Id : E) return B is begin return Flag235 (Id); end Is_Trivial_Subprogram; function Is_True_Constant (Id : E) return B is begin return Flag163 (Id); end Is_True_Constant; function Is_Unchecked_Union (Id : E) return B is begin return Flag117 (Implementation_Base_Type (Id)); end Is_Unchecked_Union; function Is_Underlying_Record_View (Id : E) return B is begin return Flag246 (Id); end Is_Underlying_Record_View; function Is_Unsigned_Type (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag144 (Id); end Is_Unsigned_Type; function Is_Valued_Procedure (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Procedure); return Flag127 (Id); end Is_Valued_Procedure; function Is_Visible_Formal (Id : E) return B is begin return Flag206 (Id); end Is_Visible_Formal; function Is_Visible_Lib_Unit (Id : E) return B is begin return Flag116 (Id); end Is_Visible_Lib_Unit; function Is_VMS_Exception (Id : E) return B is begin return Flag133 (Id); end Is_VMS_Exception; function Is_Volatile (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); if Is_Type (Id) then return Flag16 (Base_Type (Id)); else return Flag16 (Id); end if; end Is_Volatile; function Itype_Printed (Id : E) return B is begin pragma Assert (Is_Itype (Id)); return Flag202 (Id); end Itype_Printed; function Kill_Elaboration_Checks (Id : E) return B is begin return Flag32 (Id); end Kill_Elaboration_Checks; function Kill_Range_Checks (Id : E) return B is begin return Flag33 (Id); end Kill_Range_Checks; function Known_To_Have_Preelab_Init (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag207 (Id); end Known_To_Have_Preelab_Init; function Last_Aggregate_Assignment (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); return Node30 (Id); end Last_Aggregate_Assignment; function Last_Assignment (Id : E) return N is begin pragma Assert (Is_Assignable (Id)); return Node26 (Id); end Last_Assignment; function Last_Entity (Id : E) return E is begin return Node20 (Id); end Last_Entity; function Limited_View (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Package); return Node23 (Id); end Limited_View; function Linker_Section_Pragma (Id : E) return N is begin pragma Assert (Is_Type (Id) or else Is_Object (Id) or else Is_Subprogram (Id)); return Node33 (Id); end Linker_Section_Pragma; function Lit_Indexes (Id : E) return E is begin pragma Assert (Is_Enumeration_Type (Id)); return Node15 (Id); end Lit_Indexes; function Lit_Strings (Id : E) return E is begin pragma Assert (Is_Enumeration_Type (Id)); return Node16 (Id); end Lit_Strings; function Low_Bound_Tested (Id : E) return B is begin return Flag205 (Id); end Low_Bound_Tested; function Machine_Radix_10 (Id : E) return B is begin pragma Assert (Is_Decimal_Fixed_Point_Type (Id)); return Flag84 (Id); end Machine_Radix_10; function Master_Id (Id : E) return E is begin pragma Assert (Is_Access_Type (Id)); return Node17 (Id); end Master_Id; function Materialize_Entity (Id : E) return B is begin return Flag168 (Id); end Materialize_Entity; function May_Inherit_Delayed_Rep_Aspects (Id : E) return B is begin return Flag262 (Id); end May_Inherit_Delayed_Rep_Aspects; function Mechanism (Id : E) return M is begin pragma Assert (Ekind (Id) = E_Function or else Is_Formal (Id)); return UI_To_Int (Uint8 (Id)); end Mechanism; function Modulus (Id : E) return Uint is begin pragma Assert (Is_Modular_Integer_Type (Id)); return Uint17 (Base_Type (Id)); end Modulus; function Must_Be_On_Byte_Boundary (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag183 (Id); end Must_Be_On_Byte_Boundary; function Must_Have_Preelab_Init (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag208 (Id); end Must_Have_Preelab_Init; function Needs_Debug_Info (Id : E) return B is begin return Flag147 (Id); end Needs_Debug_Info; function Needs_No_Actuals (Id : E) return B is begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Subprogram_Type, E_Entry_Family)); return Flag22 (Id); end Needs_No_Actuals; function Never_Set_In_Source (Id : E) return B is begin return Flag115 (Id); end Never_Set_In_Source; function Next_Inlined_Subprogram (Id : E) return E is begin return Node12 (Id); end Next_Inlined_Subprogram; function No_Pool_Assigned (Id : E) return B is begin pragma Assert (Is_Access_Type (Id)); return Flag131 (Root_Type (Id)); end No_Pool_Assigned; function No_Return (Id : E) return B is begin return Flag113 (Id); end No_Return; function No_Strict_Aliasing (Id : E) return B is begin pragma Assert (Is_Access_Type (Id)); return Flag136 (Base_Type (Id)); end No_Strict_Aliasing; function Non_Binary_Modulus (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag58 (Base_Type (Id)); end Non_Binary_Modulus; function Non_Limited_View (Id : E) return E is begin pragma Assert (Ekind (Id) in Incomplete_Kind or else Ekind (Id) = E_Abstract_State); return Node17 (Id); end Non_Limited_View; function Nonzero_Is_True (Id : E) return B is begin pragma Assert (Root_Type (Id) = Standard_Boolean); return Flag162 (Base_Type (Id)); end Nonzero_Is_True; function Normalized_First_Bit (Id : E) return U is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); return Uint8 (Id); end Normalized_First_Bit; function Normalized_Position (Id : E) return U is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); return Uint14 (Id); end Normalized_Position; function Normalized_Position_Max (Id : E) return U is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); return Uint10 (Id); end Normalized_Position_Max; function OK_To_Rename (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Variable); return Flag247 (Id); end OK_To_Rename; function OK_To_Reorder_Components (Id : E) return B is begin pragma Assert (Is_Record_Type (Id)); return Flag239 (Base_Type (Id)); end OK_To_Reorder_Components; function Optimize_Alignment_Space (Id : E) return B is begin pragma Assert (Is_Type (Id) or else Ekind_In (Id, E_Constant, E_Variable)); return Flag241 (Id); end Optimize_Alignment_Space; function Optimize_Alignment_Time (Id : E) return B is begin pragma Assert (Is_Type (Id) or else Ekind_In (Id, E_Constant, E_Variable)); return Flag242 (Id); end Optimize_Alignment_Time; function Original_Access_Type (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Access_Subprogram_Type); return Node26 (Id); end Original_Access_Type; function Original_Array_Type (Id : E) return E is begin pragma Assert (Is_Array_Type (Id) or else Is_Modular_Integer_Type (Id)); return Node21 (Id); end Original_Array_Type; function Original_Record_Component (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Void, E_Component, E_Discriminant)); return Node22 (Id); end Original_Record_Component; function Overlays_Constant (Id : E) return B is begin return Flag243 (Id); end Overlays_Constant; function Overridden_Operation (Id : E) return E is begin return Node26 (Id); end Overridden_Operation; function Package_Instantiation (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Package, E_Generic_Package)); return Node26 (Id); end Package_Instantiation; function Packed_Array_Impl_Type (Id : E) return E is begin pragma Assert (Is_Array_Type (Id)); return Node23 (Id); end Packed_Array_Impl_Type; function Parent_Subtype (Id : E) return E is begin pragma Assert (Is_Record_Type (Id)); return Node19 (Base_Type (Id)); end Parent_Subtype; function Part_Of_Constituents (Id : E) return L is begin pragma Assert (Ekind (Id) = E_Abstract_State); return Elist9 (Id); end Part_Of_Constituents; function Postcondition_Proc (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Procedure); return Node8 (Id); end Postcondition_Proc; function PPC_Wrapper (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Entry, E_Entry_Family)); return Node25 (Id); end PPC_Wrapper; function Prival (Id : E) return E is begin pragma Assert (Is_Protected_Component (Id)); return Node17 (Id); end Prival; function Prival_Link (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); return Node20 (Id); end Prival_Link; function Private_Dependents (Id : E) return L is begin pragma Assert (Is_Incomplete_Or_Private_Type (Id)); return Elist18 (Id); end Private_Dependents; function Private_View (Id : E) return N is begin pragma Assert (Is_Private_Type (Id)); return Node22 (Id); end Private_View; function Protected_Body_Subprogram (Id : E) return E is begin pragma Assert (Is_Subprogram (Id) or else Is_Entry (Id)); return Node11 (Id); end Protected_Body_Subprogram; function Protected_Formal (Id : E) return E is begin pragma Assert (Is_Formal (Id)); return Node22 (Id); end Protected_Formal; function Protection_Object (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Entry, E_Entry_Family, E_Function, E_Procedure)); return Node23 (Id); end Protection_Object; function Reachable (Id : E) return B is begin return Flag49 (Id); end Reachable; function Referenced (Id : E) return B is begin return Flag156 (Id); end Referenced; function Referenced_As_LHS (Id : E) return B is begin return Flag36 (Id); end Referenced_As_LHS; function Referenced_As_Out_Parameter (Id : E) return B is begin return Flag227 (Id); end Referenced_As_Out_Parameter; function Refinement_Constituents (Id : E) return L is begin pragma Assert (Ekind (Id) = E_Abstract_State); return Elist8 (Id); end Refinement_Constituents; function Register_Exception_Call (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Exception); return Node20 (Id); end Register_Exception_Call; function Related_Array_Object (Id : E) return E is begin pragma Assert (Is_Array_Type (Id)); return Node25 (Id); end Related_Array_Object; function Related_Expression (Id : E) return N is begin pragma Assert (Ekind (Id) in Type_Kind or else Ekind_In (Id, E_Constant, E_Variable)); return Node24 (Id); end Related_Expression; function Related_Instance (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Package, E_Package_Body)); return Node15 (Id); end Related_Instance; function Related_Type (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Component, E_Constant, E_Variable)); return Node27 (Id); end Related_Type; function Relative_Deadline_Variable (Id : E) return E is begin pragma Assert (Is_Task_Type (Id)); return Node26 (Implementation_Base_Type (Id)); end Relative_Deadline_Variable; function Renamed_Entity (Id : E) return N is begin return Node18 (Id); end Renamed_Entity; function Renamed_In_Spec (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Package); return Flag231 (Id); end Renamed_In_Spec; function Renamed_Object (Id : E) return N is begin return Node18 (Id); end Renamed_Object; function Renaming_Map (Id : E) return U is begin return Uint9 (Id); end Renaming_Map; function Requires_Overriding (Id : E) return B is begin pragma Assert (Is_Overloadable (Id)); return Flag213 (Id); end Requires_Overriding; function Return_Present (Id : E) return B is begin return Flag54 (Id); end Return_Present; function Return_Applies_To (Id : E) return N is begin return Node8 (Id); end Return_Applies_To; function Returns_By_Ref (Id : E) return B is begin return Flag90 (Id); end Returns_By_Ref; function Reverse_Bit_Order (Id : E) return B is begin pragma Assert (Is_Record_Type (Id)); return Flag164 (Base_Type (Id)); end Reverse_Bit_Order; function Reverse_Storage_Order (Id : E) return B is begin pragma Assert (Is_Record_Type (Id) or else Is_Array_Type (Id)); return Flag93 (Base_Type (Id)); end Reverse_Storage_Order; function RM_Size (Id : E) return U is begin pragma Assert (Is_Type (Id)); return Uint13 (Id); end RM_Size; function Scalar_Range (Id : E) return N is begin return Node20 (Id); end Scalar_Range; function Scale_Value (Id : E) return U is begin return Uint15 (Id); end Scale_Value; function Scope_Depth_Value (Id : E) return U is begin return Uint22 (Id); end Scope_Depth_Value; function Sec_Stack_Needed_For_Return (Id : E) return B is begin return Flag167 (Id); end Sec_Stack_Needed_For_Return; function Shadow_Entities (Id : E) return S is begin pragma Assert (Ekind_In (Id, E_Package, E_Generic_Package)); return List14 (Id); end Shadow_Entities; function Shared_Var_Procs_Instance (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Variable); return Node22 (Id); end Shared_Var_Procs_Instance; function Size_Check_Code (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); return Node19 (Id); end Size_Check_Code; function Size_Depends_On_Discriminant (Id : E) return B is begin return Flag177 (Id); end Size_Depends_On_Discriminant; function Size_Known_At_Compile_Time (Id : E) return B is begin return Flag92 (Id); end Size_Known_At_Compile_Time; function Small_Value (Id : E) return R is begin pragma Assert (Is_Fixed_Point_Type (Id)); return Ureal21 (Id); end Small_Value; function SPARK_Aux_Pragma (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); return Node33 (Id); end SPARK_Aux_Pragma; function SPARK_Aux_Pragma_Inherited (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); return Flag266 (Id); end SPARK_Aux_Pragma_Inherited; function SPARK_Pragma (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Function, -- subprogram variants E_Generic_Function, E_Generic_Procedure, E_Procedure, E_Subprogram_Body) or else Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); return Node32 (Id); end SPARK_Pragma; function SPARK_Pragma_Inherited (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Function, -- subprogram variants E_Generic_Function, E_Generic_Procedure, E_Procedure, E_Subprogram_Body) or else Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); return Flag265 (Id); end SPARK_Pragma_Inherited; function Spec_Entity (Id : E) return E is begin pragma Assert (Ekind (Id) = E_Package_Body or else Is_Formal (Id)); return Node19 (Id); end Spec_Entity; function SSO_Set_High_By_Default (Id : E) return B is begin pragma Assert (Is_Record_Type (Id) or else Is_Array_Type (Id)); return Flag273 (Base_Type (Id)); end SSO_Set_High_By_Default; function SSO_Set_Low_By_Default (Id : E) return B is begin pragma Assert (Is_Record_Type (Id) or else Is_Array_Type (Id)); return Flag272 (Base_Type (Id)); end SSO_Set_Low_By_Default; function Static_Discrete_Predicate (Id : E) return S is begin pragma Assert (Is_Discrete_Type (Id)); return List25 (Id); end Static_Discrete_Predicate; function Static_Real_Or_String_Predicate (Id : E) return N is begin pragma Assert (Is_Real_Type (Id) or else Is_String_Type (Id)); return Node25 (Id); end Static_Real_Or_String_Predicate; function Status_Flag_Or_Transient_Decl (Id : E) return N is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); return Node15 (Id); end Status_Flag_Or_Transient_Decl; function Storage_Size_Variable (Id : E) return E is begin pragma Assert (Is_Access_Type (Id) or else Is_Task_Type (Id)); return Node15 (Implementation_Base_Type (Id)); end Storage_Size_Variable; function Static_Elaboration_Desired (Id : E) return B is begin pragma Assert (Ekind (Id) = E_Package); return Flag77 (Id); end Static_Elaboration_Desired; function Static_Initialization (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Procedure and then not Is_Dispatching_Operation (Id)); return Node30 (Id); end Static_Initialization; function Stored_Constraint (Id : E) return L is begin pragma Assert (Is_Composite_Type (Id) and then not Is_Array_Type (Id)); return Elist23 (Id); end Stored_Constraint; function Stores_Attribute_Old_Prefix (Id : E) return B is begin return Flag270 (Id); end Stores_Attribute_Old_Prefix; function Strict_Alignment (Id : E) return B is begin return Flag145 (Implementation_Base_Type (Id)); end Strict_Alignment; function String_Literal_Length (Id : E) return U is begin return Uint16 (Id); end String_Literal_Length; function String_Literal_Low_Bound (Id : E) return N is begin return Node15 (Id); end String_Literal_Low_Bound; function Subprograms_For_Type (Id : E) return E is begin pragma Assert (Is_Type (Id) or else Is_Subprogram (Id)); return Node29 (Id); end Subprograms_For_Type; function Suppress_Elaboration_Warnings (Id : E) return B is begin return Flag148 (Id); end Suppress_Elaboration_Warnings; function Suppress_Initialization (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag105 (Id); end Suppress_Initialization; function Suppress_Style_Checks (Id : E) return B is begin return Flag165 (Id); end Suppress_Style_Checks; function Suppress_Value_Tracking_On_Call (Id : E) return B is begin return Flag217 (Id); end Suppress_Value_Tracking_On_Call; function Task_Body_Procedure (Id : E) return N is begin pragma Assert (Ekind (Id) in Task_Kind); return Node25 (Id); end Task_Body_Procedure; function Thunk_Entity (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure) and then Is_Thunk (Id)); return Node31 (Id); end Thunk_Entity; function Treat_As_Volatile (Id : E) return B is begin return Flag41 (Id); end Treat_As_Volatile; function Underlying_Full_View (Id : E) return E is begin pragma Assert (Ekind (Id) in Private_Kind); return Node19 (Id); end Underlying_Full_View; function Underlying_Record_View (Id : E) return E is begin return Node28 (Id); end Underlying_Record_View; function Universal_Aliasing (Id : E) return B is begin pragma Assert (Is_Type (Id)); return Flag216 (Implementation_Base_Type (Id)); end Universal_Aliasing; function Unset_Reference (Id : E) return N is begin return Node16 (Id); end Unset_Reference; function Used_As_Generic_Actual (Id : E) return B is begin return Flag222 (Id); end Used_As_Generic_Actual; function Uses_Lock_Free (Id : E) return B is begin pragma Assert (Is_Protected_Type (Id)); return Flag188 (Id); end Uses_Lock_Free; function Uses_Sec_Stack (Id : E) return B is begin return Flag95 (Id); end Uses_Sec_Stack; function Warnings_Off (Id : E) return B is begin return Flag96 (Id); end Warnings_Off; function Warnings_Off_Used (Id : E) return B is begin return Flag236 (Id); end Warnings_Off_Used; function Warnings_Off_Used_Unmodified (Id : E) return B is begin return Flag237 (Id); end Warnings_Off_Used_Unmodified; function Warnings_Off_Used_Unreferenced (Id : E) return B is begin return Flag238 (Id); end Warnings_Off_Used_Unreferenced; function Wrapped_Entity (Id : E) return E is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure) and then Is_Primitive_Wrapper (Id)); return Node27 (Id); end Wrapped_Entity; function Was_Hidden (Id : E) return B is begin return Flag196 (Id); end Was_Hidden; ------------------------------ -- Classification Functions -- ------------------------------ function Is_Access_Type (Id : E) return B is begin return Ekind (Id) in Access_Kind; end Is_Access_Type; function Is_Access_Protected_Subprogram_Type (Id : E) return B is begin return Ekind (Id) in Access_Protected_Kind; end Is_Access_Protected_Subprogram_Type; function Is_Access_Subprogram_Type (Id : E) return B is begin return Ekind (Id) in Access_Subprogram_Kind; end Is_Access_Subprogram_Type; function Is_Aggregate_Type (Id : E) return B is begin return Ekind (Id) in Aggregate_Kind; end Is_Aggregate_Type; function Is_Array_Type (Id : E) return B is begin return Ekind (Id) in Array_Kind; end Is_Array_Type; function Is_Assignable (Id : E) return B is begin return Ekind (Id) in Assignable_Kind; end Is_Assignable; function Is_Class_Wide_Type (Id : E) return B is begin return Ekind (Id) in Class_Wide_Kind; end Is_Class_Wide_Type; function Is_Composite_Type (Id : E) return B is begin return Ekind (Id) in Composite_Kind; end Is_Composite_Type; function Is_Concurrent_Body (Id : E) return B is begin return Ekind (Id) in Concurrent_Body_Kind; end Is_Concurrent_Body; function Is_Concurrent_Record_Type (Id : E) return B is begin return Flag20 (Id); end Is_Concurrent_Record_Type; function Is_Concurrent_Type (Id : E) return B is begin return Ekind (Id) in Concurrent_Kind; end Is_Concurrent_Type; function Is_Decimal_Fixed_Point_Type (Id : E) return B is begin return Ekind (Id) in Decimal_Fixed_Point_Kind; end Is_Decimal_Fixed_Point_Type; function Is_Digits_Type (Id : E) return B is begin return Ekind (Id) in Digits_Kind; end Is_Digits_Type; function Is_Discrete_Or_Fixed_Point_Type (Id : E) return B is begin return Ekind (Id) in Discrete_Or_Fixed_Point_Kind; end Is_Discrete_Or_Fixed_Point_Type; function Is_Discrete_Type (Id : E) return B is begin return Ekind (Id) in Discrete_Kind; end Is_Discrete_Type; function Is_Elementary_Type (Id : E) return B is begin return Ekind (Id) in Elementary_Kind; end Is_Elementary_Type; function Is_Entry (Id : E) return B is begin return Ekind (Id) in Entry_Kind; end Is_Entry; function Is_Enumeration_Type (Id : E) return B is begin return Ekind (Id) in Enumeration_Kind; end Is_Enumeration_Type; function Is_Fixed_Point_Type (Id : E) return B is begin return Ekind (Id) in Fixed_Point_Kind; end Is_Fixed_Point_Type; function Is_Floating_Point_Type (Id : E) return B is begin return Ekind (Id) in Float_Kind; end Is_Floating_Point_Type; function Is_Formal (Id : E) return B is begin return Ekind (Id) in Formal_Kind; end Is_Formal; function Is_Formal_Object (Id : E) return B is begin return Ekind (Id) in Formal_Object_Kind; end Is_Formal_Object; function Is_Generic_Subprogram (Id : E) return B is begin return Ekind (Id) in Generic_Subprogram_Kind; end Is_Generic_Subprogram; function Is_Generic_Unit (Id : E) return B is begin return Ekind (Id) in Generic_Unit_Kind; end Is_Generic_Unit; function Is_Incomplete_Or_Private_Type (Id : E) return B is begin return Ekind (Id) in Incomplete_Or_Private_Kind; end Is_Incomplete_Or_Private_Type; function Is_Incomplete_Type (Id : E) return B is begin return Ekind (Id) in Incomplete_Kind; end Is_Incomplete_Type; function Is_Integer_Type (Id : E) return B is begin return Ekind (Id) in Integer_Kind; end Is_Integer_Type; function Is_Modular_Integer_Type (Id : E) return B is begin return Ekind (Id) in Modular_Integer_Kind; end Is_Modular_Integer_Type; function Is_Named_Number (Id : E) return B is begin return Ekind (Id) in Named_Kind; end Is_Named_Number; function Is_Numeric_Type (Id : E) return B is begin return Ekind (Id) in Numeric_Kind; end Is_Numeric_Type; function Is_Object (Id : E) return B is begin return Ekind (Id) in Object_Kind; end Is_Object; function Is_Ordinary_Fixed_Point_Type (Id : E) return B is begin return Ekind (Id) in Ordinary_Fixed_Point_Kind; end Is_Ordinary_Fixed_Point_Type; function Is_Overloadable (Id : E) return B is begin return Ekind (Id) in Overloadable_Kind; end Is_Overloadable; function Is_Private_Type (Id : E) return B is begin return Ekind (Id) in Private_Kind; end Is_Private_Type; function Is_Protected_Type (Id : E) return B is begin return Ekind (Id) in Protected_Kind; end Is_Protected_Type; function Is_Real_Type (Id : E) return B is begin return Ekind (Id) in Real_Kind; end Is_Real_Type; function Is_Record_Type (Id : E) return B is begin return Ekind (Id) in Record_Kind; end Is_Record_Type; function Is_Scalar_Type (Id : E) return B is begin return Ekind (Id) in Scalar_Kind; end Is_Scalar_Type; function Is_Signed_Integer_Type (Id : E) return B is begin return Ekind (Id) in Signed_Integer_Kind; end Is_Signed_Integer_Type; function Is_Subprogram (Id : E) return B is begin return Ekind (Id) in Subprogram_Kind; end Is_Subprogram; function Is_Task_Type (Id : E) return B is begin return Ekind (Id) in Task_Kind; end Is_Task_Type; function Is_Type (Id : E) return B is begin return Ekind (Id) in Type_Kind; end Is_Type; ------------------------------ -- Attribute Set Procedures -- ------------------------------ -- Note: in many of these set procedures an "obvious" assertion is missing. -- The reason for this is that in many cases, a field is set before the -- Ekind field is set, so that the field is set when Ekind = E_Void. It -- it is possible to add assertions that specifically include the E_Void -- possibility, but in some cases, we just omit the assertions. procedure Set_Abstract_States (Id : E; V : L) is begin pragma Assert (Ekind_In (Id, E_Generic_Package, E_Package)); Set_Elist25 (Id, V); end Set_Abstract_States; procedure Set_Accept_Address (Id : E; V : L) is begin Set_Elist21 (Id, V); end Set_Accept_Address; procedure Set_Access_Disp_Table (Id : E; V : L) is begin pragma Assert (Ekind (Id) = E_Record_Type and then Id = Implementation_Base_Type (Id)); pragma Assert (V = No_Elist or else Is_Tagged_Type (Id)); Set_Elist16 (Id, V); end Set_Access_Disp_Table; procedure Set_Associated_Formal_Package (Id : E; V : E) is begin Set_Node12 (Id, V); end Set_Associated_Formal_Package; procedure Set_Associated_Node_For_Itype (Id : E; V : E) is begin Set_Node8 (Id, V); end Set_Associated_Node_For_Itype; procedure Set_Associated_Storage_Pool (Id : E; V : E) is begin pragma Assert (Is_Access_Type (Id) and then Is_Base_Type (Id)); Set_Node22 (Id, V); end Set_Associated_Storage_Pool; procedure Set_Actual_Subtype (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable, E_Generic_In_Out_Parameter) or else Is_Formal (Id)); Set_Node17 (Id, V); end Set_Actual_Subtype; procedure Set_Address_Taken (Id : E; V : B := True) is begin Set_Flag104 (Id, V); end Set_Address_Taken; procedure Set_Alias (Id : E; V : E) is begin pragma Assert (Is_Overloadable (Id) or else Ekind (Id) = E_Subprogram_Type); Set_Node18 (Id, V); end Set_Alias; procedure Set_Alignment (Id : E; V : U) is begin pragma Assert (Is_Type (Id) or else Is_Formal (Id) or else Ekind_In (Id, E_Loop_Parameter, E_Constant, E_Exception, E_Variable)); Set_Uint14 (Id, V); end Set_Alignment; procedure Set_Barrier_Function (Id : E; V : N) is begin pragma Assert (Is_Entry (Id)); Set_Node12 (Id, V); end Set_Barrier_Function; procedure Set_Block_Node (Id : E; V : N) is begin pragma Assert (Ekind (Id) = E_Block); Set_Node11 (Id, V); end Set_Block_Node; procedure Set_Body_Entity (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Package, E_Generic_Package)); Set_Node19 (Id, V); end Set_Body_Entity; procedure Set_Body_Needed_For_SAL (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Package or else Is_Subprogram (Id) or else Is_Generic_Unit (Id)); Set_Flag40 (Id, V); end Set_Body_Needed_For_SAL; procedure Set_Body_References (Id : E; V : L) is begin pragma Assert (Ekind (Id) = E_Abstract_State); Set_Elist16 (Id, V); end Set_Body_References; procedure Set_BIP_Initialization_Call (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); Set_Node29 (Id, V); end Set_BIP_Initialization_Call; procedure Set_C_Pass_By_Copy (Id : E; V : B := True) is begin pragma Assert (Is_Record_Type (Id) and then Is_Base_Type (Id)); Set_Flag125 (Id, V); end Set_C_Pass_By_Copy; procedure Set_Can_Never_Be_Null (Id : E; V : B := True) is begin Set_Flag38 (Id, V); end Set_Can_Never_Be_Null; procedure Set_Checks_May_Be_Suppressed (Id : E; V : B := True) is begin Set_Flag31 (Id, V); end Set_Checks_May_Be_Suppressed; procedure Set_Class_Wide_Type (Id : E; V : E) is begin pragma Assert (Is_Type (Id)); Set_Node9 (Id, V); end Set_Class_Wide_Type; procedure Set_Cloned_Subtype (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Record_Subtype, E_Class_Wide_Subtype)); Set_Node16 (Id, V); end Set_Cloned_Subtype; procedure Set_Component_Bit_Offset (Id : E; V : U) is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); Set_Uint11 (Id, V); end Set_Component_Bit_Offset; procedure Set_Component_Clause (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); Set_Node13 (Id, V); end Set_Component_Clause; procedure Set_Component_Size (Id : E; V : U) is begin pragma Assert (Is_Array_Type (Id) and then Is_Base_Type (Id)); Set_Uint22 (Id, V); end Set_Component_Size; procedure Set_Component_Type (Id : E; V : E) is begin pragma Assert (Is_Array_Type (Id) and then Is_Base_Type (Id)); Set_Node20 (Id, V); end Set_Component_Type; procedure Set_Corresponding_Concurrent_Type (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Record_Type and then Is_Concurrent_Type (V)); Set_Node18 (Id, V); end Set_Corresponding_Concurrent_Type; procedure Set_Corresponding_Discriminant (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Discriminant); Set_Node19 (Id, V); end Set_Corresponding_Discriminant; procedure Set_Corresponding_Equality (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Function and then not Comes_From_Source (Id) and then Chars (Id) = Name_Op_Ne); Set_Node30 (Id, V); end Set_Corresponding_Equality; procedure Set_Corresponding_Protected_Entry (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Void, E_Subprogram_Body)); Set_Node18 (Id, V); end Set_Corresponding_Protected_Entry; procedure Set_Corresponding_Record_Type (Id : E; V : E) is begin pragma Assert (Is_Concurrent_Type (Id)); Set_Node18 (Id, V); end Set_Corresponding_Record_Type; procedure Set_Corresponding_Remote_Type (Id : E; V : E) is begin Set_Node22 (Id, V); end Set_Corresponding_Remote_Type; procedure Set_Current_Use_Clause (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Package or else Is_Type (Id)); Set_Node27 (Id, V); end Set_Current_Use_Clause; procedure Set_Current_Value (Id : E; V : N) is begin pragma Assert (Ekind (Id) in Object_Kind or else Ekind (Id) = E_Void); Set_Node9 (Id, V); end Set_Current_Value; procedure Set_CR_Discriminant (Id : E; V : E) is begin Set_Node23 (Id, V); end Set_CR_Discriminant; procedure Set_Debug_Info_Off (Id : E; V : B := True) is begin Set_Flag166 (Id, V); end Set_Debug_Info_Off; procedure Set_Debug_Renaming_Link (Id : E; V : E) is begin Set_Node25 (Id, V); end Set_Debug_Renaming_Link; procedure Set_Default_Aspect_Component_Value (Id : E; V : E) is begin pragma Assert (Is_Array_Type (Id) and then Is_Base_Type (Id)); Set_Node19 (Id, V); end Set_Default_Aspect_Component_Value; procedure Set_Default_Aspect_Value (Id : E; V : E) is begin pragma Assert (Is_Scalar_Type (Id) and then Is_Base_Type (Id)); Set_Node19 (Id, V); end Set_Default_Aspect_Value; procedure Set_Default_Expr_Function (Id : E; V : E) is begin pragma Assert (Is_Formal (Id)); Set_Node21 (Id, V); end Set_Default_Expr_Function; procedure Set_Default_Expressions_Processed (Id : E; V : B := True) is begin Set_Flag108 (Id, V); end Set_Default_Expressions_Processed; procedure Set_Default_Value (Id : E; V : N) is begin pragma Assert (Is_Formal (Id)); Set_Node20 (Id, V); end Set_Default_Value; procedure Set_Delay_Cleanups (Id : E; V : B := True) is begin pragma Assert (Is_Subprogram (Id) or else Is_Task_Type (Id) or else Ekind (Id) = E_Block); Set_Flag114 (Id, V); end Set_Delay_Cleanups; procedure Set_Delay_Subprogram_Descriptors (Id : E; V : B := True) is begin pragma Assert (Is_Subprogram (Id) or else Ekind_In (Id, E_Package, E_Package_Body)); Set_Flag50 (Id, V); end Set_Delay_Subprogram_Descriptors; procedure Set_Delta_Value (Id : E; V : R) is begin pragma Assert (Is_Fixed_Point_Type (Id)); Set_Ureal18 (Id, V); end Set_Delta_Value; procedure Set_Dependent_Instances (Id : E; V : L) is begin pragma Assert (Is_Generic_Instance (Id)); Set_Elist8 (Id, V); end Set_Dependent_Instances; procedure Set_Depends_On_Private (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag14 (Id, V); end Set_Depends_On_Private; procedure Set_Derived_Type_Link (Id : E; V : E) is begin pragma Assert (Is_Type (Id) and then Is_Base_Type (Id)); Set_Node31 (Id, V); end Set_Derived_Type_Link; procedure Set_Digits_Value (Id : E; V : U) is begin pragma Assert (Is_Floating_Point_Type (Id) or else Is_Decimal_Fixed_Point_Type (Id)); Set_Uint17 (Id, V); end Set_Digits_Value; procedure Set_Directly_Designated_Type (Id : E; V : E) is begin Set_Node20 (Id, V); end Set_Directly_Designated_Type; procedure Set_Discard_Names (Id : E; V : B := True) is begin Set_Flag88 (Id, V); end Set_Discard_Names; procedure Set_Discriminal (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Discriminant); Set_Node17 (Id, V); end Set_Discriminal; procedure Set_Discriminal_Link (Id : E; V : E) is begin Set_Node10 (Id, V); end Set_Discriminal_Link; procedure Set_Discriminant_Checking_Func (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Component); Set_Node20 (Id, V); end Set_Discriminant_Checking_Func; procedure Set_Discriminant_Constraint (Id : E; V : L) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Elist21 (Id, V); end Set_Discriminant_Constraint; procedure Set_Discriminant_Default_Value (Id : E; V : N) is begin Set_Node20 (Id, V); end Set_Discriminant_Default_Value; procedure Set_Discriminant_Number (Id : E; V : U) is begin Set_Uint15 (Id, V); end Set_Discriminant_Number; procedure Set_Dispatch_Table_Wrappers (Id : E; V : L) is begin pragma Assert (Ekind (Id) = E_Record_Type and then Id = Implementation_Base_Type (Id)); pragma Assert (V = No_Elist or else Is_Tagged_Type (Id)); Set_Elist26 (Id, V); end Set_Dispatch_Table_Wrappers; procedure Set_DT_Entry_Count (Id : E; V : U) is begin pragma Assert (Ekind (Id) = E_Component); Set_Uint15 (Id, V); end Set_DT_Entry_Count; procedure Set_DT_Offset_To_Top_Func (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Component and then Is_Tag (Id)); Set_Node25 (Id, V); end Set_DT_Offset_To_Top_Func; procedure Set_DT_Position (Id : E; V : U) is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); Set_Uint15 (Id, V); end Set_DT_Position; procedure Set_DTC_Entity (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); Set_Node16 (Id, V); end Set_DTC_Entity; procedure Set_Elaborate_Body_Desirable (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Package); Set_Flag210 (Id, V); end Set_Elaborate_Body_Desirable; procedure Set_Elaboration_Entity (Id : E; V : E) is begin pragma Assert (Is_Subprogram (Id) or else Ekind (Id) = E_Package or else Is_Generic_Unit (Id)); Set_Node13 (Id, V); end Set_Elaboration_Entity; procedure Set_Elaboration_Entity_Required (Id : E; V : B := True) is begin pragma Assert (Is_Subprogram (Id) or else Ekind (Id) = E_Package or else Is_Generic_Unit (Id)); Set_Flag174 (Id, V); end Set_Elaboration_Entity_Required; procedure Set_Encapsulating_State (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Abstract_State, E_Variable)); Set_Node10 (Id, V); end Set_Encapsulating_State; procedure Set_Enclosing_Scope (Id : E; V : E) is begin Set_Node18 (Id, V); end Set_Enclosing_Scope; procedure Set_Entry_Accepted (Id : E; V : B := True) is begin pragma Assert (Is_Entry (Id)); Set_Flag152 (Id, V); end Set_Entry_Accepted; procedure Set_Entry_Bodies_Array (Id : E; V : E) is begin Set_Node15 (Id, V); end Set_Entry_Bodies_Array; procedure Set_Entry_Cancel_Parameter (Id : E; V : E) is begin Set_Node23 (Id, V); end Set_Entry_Cancel_Parameter; procedure Set_Entry_Component (Id : E; V : E) is begin Set_Node11 (Id, V); end Set_Entry_Component; procedure Set_Entry_Formal (Id : E; V : E) is begin Set_Node16 (Id, V); end Set_Entry_Formal; procedure Set_Entry_Index_Constant (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Entry_Index_Parameter); Set_Node18 (Id, V); end Set_Entry_Index_Constant; procedure Set_Contract (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Entry, E_Entry_Family, E_Generic_Package, E_Package, E_Package_Body, E_Subprogram_Body, E_Variable, E_Void) or else Is_Generic_Subprogram (Id) or else Is_Subprogram (Id)); Set_Node34 (Id, V); end Set_Contract; procedure Set_Entry_Parameters_Type (Id : E; V : E) is begin Set_Node15 (Id, V); end Set_Entry_Parameters_Type; procedure Set_Enum_Pos_To_Rep (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Enumeration_Type); Set_Node23 (Id, V); end Set_Enum_Pos_To_Rep; procedure Set_Enumeration_Pos (Id : E; V : U) is begin pragma Assert (Ekind (Id) = E_Enumeration_Literal); Set_Uint11 (Id, V); end Set_Enumeration_Pos; procedure Set_Enumeration_Rep (Id : E; V : U) is begin pragma Assert (Ekind (Id) = E_Enumeration_Literal); Set_Uint12 (Id, V); end Set_Enumeration_Rep; procedure Set_Enumeration_Rep_Expr (Id : E; V : N) is begin pragma Assert (Ekind (Id) = E_Enumeration_Literal); Set_Node22 (Id, V); end Set_Enumeration_Rep_Expr; procedure Set_Equivalent_Type (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Class_Wide_Type, E_Class_Wide_Subtype, E_Access_Protected_Subprogram_Type, E_Anonymous_Access_Protected_Subprogram_Type, E_Access_Subprogram_Type, E_Exception_Type)); Set_Node18 (Id, V); end Set_Equivalent_Type; procedure Set_Esize (Id : E; V : U) is begin Set_Uint12 (Id, V); end Set_Esize; procedure Set_Exception_Code (Id : E; V : U) is begin pragma Assert (Ekind (Id) = E_Exception); Set_Uint22 (Id, V); end Set_Exception_Code; procedure Set_Extra_Accessibility (Id : E; V : E) is begin pragma Assert (Is_Formal (Id) or else Ekind_In (Id, E_Variable, E_Constant)); Set_Node13 (Id, V); end Set_Extra_Accessibility; procedure Set_Extra_Accessibility_Of_Result (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Function, E_Operator, E_Subprogram_Type)); Set_Node19 (Id, V); end Set_Extra_Accessibility_Of_Result; procedure Set_Extra_Constrained (Id : E; V : E) is begin pragma Assert (Is_Formal (Id) or else Ekind (Id) = E_Variable); Set_Node23 (Id, V); end Set_Extra_Constrained; procedure Set_Extra_Formal (Id : E; V : E) is begin Set_Node15 (Id, V); end Set_Extra_Formal; procedure Set_Extra_Formals (Id : E; V : E) is begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Entry_Family, E_Subprogram_Body, E_Subprogram_Type)); Set_Node28 (Id, V); end Set_Extra_Formals; procedure Set_Can_Use_Internal_Rep (Id : E; V : B := True) is begin pragma Assert (Is_Access_Subprogram_Type (Id) and then Is_Base_Type (Id)); Set_Flag229 (Id, V); end Set_Can_Use_Internal_Rep; procedure Set_Finalization_Master (Id : E; V : E) is begin pragma Assert (Is_Access_Type (Id) and then Is_Base_Type (Id)); Set_Node23 (Id, V); end Set_Finalization_Master; procedure Set_Finalize_Storage_Only (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) and then Is_Base_Type (Id)); Set_Flag158 (Id, V); end Set_Finalize_Storage_Only; procedure Set_Finalizer (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Package, E_Package_Body)); Set_Node28 (Id, V); end Set_Finalizer; procedure Set_First_Entity (Id : E; V : E) is begin Set_Node17 (Id, V); end Set_First_Entity; procedure Set_First_Exit_Statement (Id : E; V : N) is begin pragma Assert (Ekind (Id) = E_Loop); Set_Node8 (Id, V); end Set_First_Exit_Statement; procedure Set_First_Index (Id : E; V : N) is begin pragma Assert (Is_Array_Type (Id) or else Is_String_Type (Id)); Set_Node17 (Id, V); end Set_First_Index; procedure Set_First_Literal (Id : E; V : E) is begin pragma Assert (Is_Enumeration_Type (Id)); Set_Node17 (Id, V); end Set_First_Literal; procedure Set_First_Optional_Parameter (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); Set_Node14 (Id, V); end Set_First_Optional_Parameter; procedure Set_First_Private_Entity (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Package, E_Generic_Package) or else Ekind (Id) in Concurrent_Kind); Set_Node16 (Id, V); end Set_First_Private_Entity; procedure Set_First_Rep_Item (Id : E; V : N) is begin Set_Node6 (Id, V); end Set_First_Rep_Item; procedure Set_Float_Rep (Id : E; V : F) is pragma Assert (Ekind (Id) = E_Floating_Point_Type); begin Set_Uint10 (Id, UI_From_Int (F'Pos (V))); end Set_Float_Rep; procedure Set_Freeze_Node (Id : E; V : N) is begin Set_Node7 (Id, V); end Set_Freeze_Node; procedure Set_From_Limited_With (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) or else Ekind_In (Id, E_Abstract_State, E_Package)); Set_Flag159 (Id, V); end Set_From_Limited_With; procedure Set_Full_View (Id : E; V : E) is begin pragma Assert (Is_Type (Id) or else Ekind (Id) = E_Constant); Set_Node11 (Id, V); end Set_Full_View; procedure Set_Generic_Homonym (Id : E; V : E) is begin Set_Node11 (Id, V); end Set_Generic_Homonym; procedure Set_Generic_Renamings (Id : E; V : L) is begin Set_Elist23 (Id, V); end Set_Generic_Renamings; procedure Set_Handler_Records (Id : E; V : S) is begin Set_List10 (Id, V); end Set_Handler_Records; procedure Set_Has_Aliased_Components (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag135 (Id, V); end Set_Has_Aliased_Components; procedure Set_Has_Alignment_Clause (Id : E; V : B := True) is begin Set_Flag46 (Id, V); end Set_Has_Alignment_Clause; procedure Set_Has_All_Calls_Remote (Id : E; V : B := True) is begin Set_Flag79 (Id, V); end Set_Has_All_Calls_Remote; procedure Set_Has_Anonymous_Master (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Function, E_Package, E_Package_Body, E_Procedure)); Set_Flag253 (Id, V); end Set_Has_Anonymous_Master; procedure Set_Has_Atomic_Components (Id : E; V : B := True) is begin pragma Assert (not Is_Type (Id) or else Is_Base_Type (Id)); Set_Flag86 (Id, V); end Set_Has_Atomic_Components; procedure Set_Has_Biased_Representation (Id : E; V : B := True) is begin pragma Assert ((V = False) or else (Is_Discrete_Type (Id) or else Is_Object (Id))); Set_Flag139 (Id, V); end Set_Has_Biased_Representation; procedure Set_Has_Completion (Id : E; V : B := True) is begin Set_Flag26 (Id, V); end Set_Has_Completion; procedure Set_Has_Completion_In_Body (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag71 (Id, V); end Set_Has_Completion_In_Body; procedure Set_Has_Complex_Representation (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Record_Type); Set_Flag140 (Id, V); end Set_Has_Complex_Representation; procedure Set_Has_Component_Size_Clause (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Array_Type); Set_Flag68 (Id, V); end Set_Has_Component_Size_Clause; procedure Set_Has_Constrained_Partial_View (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag187 (Id, V); end Set_Has_Constrained_Partial_View; procedure Set_Has_Contiguous_Rep (Id : E; V : B := True) is begin Set_Flag181 (Id, V); end Set_Has_Contiguous_Rep; procedure Set_Has_Controlled_Component (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag43 (Id, V); end Set_Has_Controlled_Component; procedure Set_Has_Controlling_Result (Id : E; V : B := True) is begin Set_Flag98 (Id, V); end Set_Has_Controlling_Result; procedure Set_Has_Convention_Pragma (Id : E; V : B := True) is begin Set_Flag119 (Id, V); end Set_Has_Convention_Pragma; procedure Set_Has_Default_Aspect (Id : E; V : B := True) is begin pragma Assert ((Is_Scalar_Type (Id) or else Is_Array_Type (Id)) and then Is_Base_Type (Id)); Set_Flag39 (Id, V); end Set_Has_Default_Aspect; procedure Set_Has_Delayed_Aspects (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag200 (Id, V); end Set_Has_Delayed_Aspects; procedure Set_Has_Delayed_Freeze (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag18 (Id, V); end Set_Has_Delayed_Freeze; procedure Set_Has_Delayed_Rep_Aspects (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag261 (Id, V); end Set_Has_Delayed_Rep_Aspects; procedure Set_Has_Discriminants (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag5 (Id, V); end Set_Has_Discriminants; procedure Set_Has_Dispatch_Table (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Record_Type and then Is_Tagged_Type (Id)); Set_Flag220 (Id, V); end Set_Has_Dispatch_Table; procedure Set_Has_Dynamic_Predicate_Aspect (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag258 (Id, V); end Set_Has_Dynamic_Predicate_Aspect; procedure Set_Has_Enumeration_Rep_Clause (Id : E; V : B := True) is begin pragma Assert (Is_Enumeration_Type (Id)); Set_Flag66 (Id, V); end Set_Has_Enumeration_Rep_Clause; procedure Set_Has_Exit (Id : E; V : B := True) is begin Set_Flag47 (Id, V); end Set_Has_Exit; procedure Set_Has_Forward_Instantiation (Id : E; V : B := True) is begin Set_Flag175 (Id, V); end Set_Has_Forward_Instantiation; procedure Set_Has_Fully_Qualified_Name (Id : E; V : B := True) is begin Set_Flag173 (Id, V); end Set_Has_Fully_Qualified_Name; procedure Set_Has_Gigi_Rep_Item (Id : E; V : B := True) is begin Set_Flag82 (Id, V); end Set_Has_Gigi_Rep_Item; procedure Set_Has_Homonym (Id : E; V : B := True) is begin Set_Flag56 (Id, V); end Set_Has_Homonym; procedure Set_Has_Implicit_Dereference (Id : E; V : B := True) is begin Set_Flag251 (Id, V); end Set_Has_Implicit_Dereference; procedure Set_Has_Independent_Components (Id : E; V : B := True) is begin pragma Assert ((Is_Array_Type (Id) or else Is_Record_Type (Id)) and then Is_Base_Type (Id)); Set_Flag34 (Id, V); end Set_Has_Independent_Components; procedure Set_Has_Inheritable_Invariants (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag248 (Id, V); end Set_Has_Inheritable_Invariants; procedure Set_Has_Initial_Value (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Variable, E_Out_Parameter)); Set_Flag219 (Id, V); end Set_Has_Initial_Value; procedure Set_Has_Invariants (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag232 (Id, V); end Set_Has_Invariants; procedure Set_Has_Loop_Entry_Attributes (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Loop); Set_Flag260 (Id, V); end Set_Has_Loop_Entry_Attributes; procedure Set_Has_Machine_Radix_Clause (Id : E; V : B := True) is begin pragma Assert (Is_Decimal_Fixed_Point_Type (Id)); Set_Flag83 (Id, V); end Set_Has_Machine_Radix_Clause; procedure Set_Has_Master_Entity (Id : E; V : B := True) is begin Set_Flag21 (Id, V); end Set_Has_Master_Entity; procedure Set_Has_Missing_Return (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Function, E_Generic_Function)); Set_Flag142 (Id, V); end Set_Has_Missing_Return; procedure Set_Has_Nested_Block_With_Handler (Id : E; V : B := True) is begin Set_Flag101 (Id, V); end Set_Has_Nested_Block_With_Handler; procedure Set_Has_Up_Level_Access (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Variable, E_Constant, E_Loop_Parameter)); Set_Flag215 (Id, V); end Set_Has_Up_Level_Access; procedure Set_Has_Non_Standard_Rep (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag75 (Id, V); end Set_Has_Non_Standard_Rep; procedure Set_Has_Object_Size_Clause (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag172 (Id, V); end Set_Has_Object_Size_Clause; procedure Set_Has_Out_Or_In_Out_Parameter (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Function, E_Generic_Function)); Set_Flag110 (Id, V); end Set_Has_Out_Or_In_Out_Parameter; procedure Set_Has_Per_Object_Constraint (Id : E; V : B := True) is begin Set_Flag154 (Id, V); end Set_Has_Per_Object_Constraint; procedure Set_Has_Postconditions (Id : E; V : B := True) is begin pragma Assert (Is_Subprogram (Id)); Set_Flag240 (Id, V); end Set_Has_Postconditions; procedure Set_Has_Pragma_Controlled (Id : E; V : B := True) is begin pragma Assert (Is_Access_Type (Id)); Set_Flag27 (Base_Type (Id), V); end Set_Has_Pragma_Controlled; procedure Set_Has_Pragma_Elaborate_Body (Id : E; V : B := True) is begin Set_Flag150 (Id, V); end Set_Has_Pragma_Elaborate_Body; procedure Set_Has_Pragma_Inline (Id : E; V : B := True) is begin Set_Flag157 (Id, V); end Set_Has_Pragma_Inline; procedure Set_Has_Pragma_Inline_Always (Id : E; V : B := True) is begin Set_Flag230 (Id, V); end Set_Has_Pragma_Inline_Always; procedure Set_Has_Pragma_No_Inline (Id : E; V : B := True) is begin Set_Flag201 (Id, V); end Set_Has_Pragma_No_Inline; procedure Set_Has_Pragma_Ordered (Id : E; V : B := True) is begin pragma Assert (Is_Enumeration_Type (Id)); pragma Assert (Id = Base_Type (Id)); Set_Flag198 (Id, V); end Set_Has_Pragma_Ordered; procedure Set_Has_Pragma_Pack (Id : E; V : B := True) is begin pragma Assert (Is_Array_Type (Id) or else Is_Record_Type (Id)); pragma Assert (Id = Base_Type (Id)); Set_Flag121 (Id, V); end Set_Has_Pragma_Pack; procedure Set_Has_Pragma_Preelab_Init (Id : E; V : B := True) is begin Set_Flag221 (Id, V); end Set_Has_Pragma_Preelab_Init; procedure Set_Has_Pragma_Pure (Id : E; V : B := True) is begin Set_Flag203 (Id, V); end Set_Has_Pragma_Pure; procedure Set_Has_Pragma_Pure_Function (Id : E; V : B := True) is begin Set_Flag179 (Id, V); end Set_Has_Pragma_Pure_Function; procedure Set_Has_Pragma_Thread_Local_Storage (Id : E; V : B := True) is begin Set_Flag169 (Id, V); end Set_Has_Pragma_Thread_Local_Storage; procedure Set_Has_Pragma_Unmodified (Id : E; V : B := True) is begin Set_Flag233 (Id, V); end Set_Has_Pragma_Unmodified; procedure Set_Has_Pragma_Unreferenced (Id : E; V : B := True) is begin Set_Flag180 (Id, V); end Set_Has_Pragma_Unreferenced; procedure Set_Has_Pragma_Unreferenced_Objects (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag212 (Id, V); end Set_Has_Pragma_Unreferenced_Objects; procedure Set_Has_Predicates (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) or else Ekind (Id) = E_Void); Set_Flag250 (Id, V); end Set_Has_Predicates; procedure Set_Has_Primitive_Operations (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag120 (Id, V); end Set_Has_Primitive_Operations; procedure Set_Has_Private_Ancestor (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag151 (Id, V); end Set_Has_Private_Ancestor; procedure Set_Has_Private_Declaration (Id : E; V : B := True) is begin Set_Flag155 (Id, V); end Set_Has_Private_Declaration; procedure Set_Has_Protected (Id : E; V : B := True) is begin Set_Flag271 (Id, V); end Set_Has_Protected; procedure Set_Has_Qualified_Name (Id : E; V : B := True) is begin Set_Flag161 (Id, V); end Set_Has_Qualified_Name; procedure Set_Has_RACW (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Package); Set_Flag214 (Id, V); end Set_Has_RACW; procedure Set_Has_Record_Rep_Clause (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag65 (Id, V); end Set_Has_Record_Rep_Clause; procedure Set_Has_Recursive_Call (Id : E; V : B := True) is begin pragma Assert (Is_Subprogram (Id)); Set_Flag143 (Id, V); end Set_Has_Recursive_Call; procedure Set_Has_Shift_Operator (Id : E; V : B := True) is begin pragma Assert (Is_Integer_Type (Id) and then Is_Base_Type (Id)); Set_Flag267 (Id, V); end Set_Has_Shift_Operator; procedure Set_Has_Size_Clause (Id : E; V : B := True) is begin Set_Flag29 (Id, V); end Set_Has_Size_Clause; procedure Set_Has_Small_Clause (Id : E; V : B := True) is begin Set_Flag67 (Id, V); end Set_Has_Small_Clause; procedure Set_Has_Specified_Layout (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag100 (Id, V); end Set_Has_Specified_Layout; procedure Set_Has_Specified_Stream_Input (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag190 (Id, V); end Set_Has_Specified_Stream_Input; procedure Set_Has_Specified_Stream_Output (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag191 (Id, V); end Set_Has_Specified_Stream_Output; procedure Set_Has_Specified_Stream_Read (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag192 (Id, V); end Set_Has_Specified_Stream_Read; procedure Set_Has_Specified_Stream_Write (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag193 (Id, V); end Set_Has_Specified_Stream_Write; procedure Set_Has_Static_Discriminants (Id : E; V : B := True) is begin Set_Flag211 (Id, V); end Set_Has_Static_Discriminants; procedure Set_Has_Static_Predicate (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag269 (Id, V); end Set_Has_Static_Predicate; procedure Set_Has_Static_Predicate_Aspect (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag259 (Id, V); end Set_Has_Static_Predicate_Aspect; procedure Set_Has_Storage_Size_Clause (Id : E; V : B := True) is begin pragma Assert (Is_Access_Type (Id) or else Is_Task_Type (Id)); pragma Assert (Id = Base_Type (Id)); Set_Flag23 (Id, V); end Set_Has_Storage_Size_Clause; procedure Set_Has_Stream_Size_Clause (Id : E; V : B := True) is begin pragma Assert (Is_Elementary_Type (Id)); Set_Flag184 (Id, V); end Set_Has_Stream_Size_Clause; procedure Set_Has_Task (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag30 (Id, V); end Set_Has_Task; procedure Set_Has_Thunks (Id : E; V : B := True) is begin pragma Assert (Is_Tag (Id)); Set_Flag228 (Id, V); end Set_Has_Thunks; procedure Set_Has_Unchecked_Union (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag123 (Id, V); end Set_Has_Unchecked_Union; procedure Set_Has_Unknown_Discriminants (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag72 (Id, V); end Set_Has_Unknown_Discriminants; procedure Set_Has_Visible_Refinement (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Abstract_State); Set_Flag263 (Id, V); end Set_Has_Visible_Refinement; procedure Set_Has_Volatile_Components (Id : E; V : B := True) is begin pragma Assert (not Is_Type (Id) or else Is_Base_Type (Id)); Set_Flag87 (Id, V); end Set_Has_Volatile_Components; procedure Set_Has_Xref_Entry (Id : E; V : B := True) is begin Set_Flag182 (Id, V); end Set_Has_Xref_Entry; procedure Set_Hiding_Loop_Variable (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Variable); Set_Node8 (Id, V); end Set_Hiding_Loop_Variable; procedure Set_Homonym (Id : E; V : E) is begin pragma Assert (Id /= V); Set_Node4 (Id, V); end Set_Homonym; procedure Set_Import_Pragma (Id : E; V : E) is begin pragma Assert (Is_Subprogram (Id)); Set_Node35 (Id, V); end Set_Import_Pragma; procedure Set_Interface_Alias (Id : E; V : E) is begin pragma Assert (Is_Internal (Id) and then Is_Hidden (Id) and then (Ekind_In (Id, E_Procedure, E_Function))); Set_Node25 (Id, V); end Set_Interface_Alias; procedure Set_Interfaces (Id : E; V : L) is begin pragma Assert (Is_Record_Type (Id)); Set_Elist25 (Id, V); end Set_Interfaces; procedure Set_In_Package_Body (Id : E; V : B := True) is begin Set_Flag48 (Id, V); end Set_In_Package_Body; procedure Set_In_Private_Part (Id : E; V : B := True) is begin Set_Flag45 (Id, V); end Set_In_Private_Part; procedure Set_In_Use (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag8 (Id, V); end Set_In_Use; procedure Set_Initialization_Statements (Id : E; V : N) is begin -- Tolerate an E_Void entity since this can be called while resolving -- an aggregate used as the initialization expression for an object -- declaration, and this occurs before the Ekind for the object is set. pragma Assert (Ekind_In (Id, E_Void, E_Constant, E_Variable)); Set_Node28 (Id, V); end Set_Initialization_Statements; procedure Set_Inner_Instances (Id : E; V : L) is begin Set_Elist23 (Id, V); end Set_Inner_Instances; procedure Set_Interface_Name (Id : E; V : N) is begin Set_Node21 (Id, V); end Set_Interface_Name; procedure Set_Is_Abstract_Subprogram (Id : E; V : B := True) is begin pragma Assert (Is_Overloadable (Id)); Set_Flag19 (Id, V); end Set_Is_Abstract_Subprogram; procedure Set_Is_Abstract_Type (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag146 (Id, V); end Set_Is_Abstract_Type; procedure Set_Is_Local_Anonymous_Access (Id : E; V : B := True) is begin pragma Assert (Is_Access_Type (Id)); Set_Flag194 (Id, V); end Set_Is_Local_Anonymous_Access; procedure Set_Is_Access_Constant (Id : E; V : B := True) is begin pragma Assert (Is_Access_Type (Id)); Set_Flag69 (Id, V); end Set_Is_Access_Constant; procedure Set_Is_Ada_2005_Only (Id : E; V : B := True) is begin Set_Flag185 (Id, V); end Set_Is_Ada_2005_Only; procedure Set_Is_Ada_2012_Only (Id : E; V : B := True) is begin Set_Flag199 (Id, V); end Set_Is_Ada_2012_Only; procedure Set_Is_Aliased (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag15 (Id, V); end Set_Is_Aliased; procedure Set_Is_AST_Entry (Id : E; V : B := True) is begin pragma Assert (Is_Entry (Id)); Set_Flag132 (Id, V); end Set_Is_AST_Entry; procedure Set_Is_Asynchronous (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Procedure or else Is_Type (Id)); Set_Flag81 (Id, V); end Set_Is_Asynchronous; procedure Set_Is_Atomic (Id : E; V : B := True) is begin Set_Flag85 (Id, V); end Set_Is_Atomic; procedure Set_Is_Bit_Packed_Array (Id : E; V : B := True) is begin pragma Assert ((not V) or else (Is_Array_Type (Id) and then Is_Base_Type (Id))); Set_Flag122 (Id, V); end Set_Is_Bit_Packed_Array; procedure Set_Is_Called (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Procedure, E_Function)); Set_Flag102 (Id, V); end Set_Is_Called; procedure Set_Is_Character_Type (Id : E; V : B := True) is begin Set_Flag63 (Id, V); end Set_Is_Character_Type; procedure Set_Is_Child_Unit (Id : E; V : B := True) is begin Set_Flag73 (Id, V); end Set_Is_Child_Unit; procedure Set_Is_Class_Wide_Equivalent_Type (Id : E; V : B := True) is begin Set_Flag35 (Id, V); end Set_Is_Class_Wide_Equivalent_Type; procedure Set_Is_Compilation_Unit (Id : E; V : B := True) is begin Set_Flag149 (Id, V); end Set_Is_Compilation_Unit; procedure Set_Is_Completely_Hidden (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Discriminant); Set_Flag103 (Id, V); end Set_Is_Completely_Hidden; procedure Set_Is_Concurrent_Record_Type (Id : E; V : B := True) is begin Set_Flag20 (Id, V); end Set_Is_Concurrent_Record_Type; procedure Set_Is_Constr_Subt_For_U_Nominal (Id : E; V : B := True) is begin Set_Flag80 (Id, V); end Set_Is_Constr_Subt_For_U_Nominal; procedure Set_Is_Constr_Subt_For_UN_Aliased (Id : E; V : B := True) is begin Set_Flag141 (Id, V); end Set_Is_Constr_Subt_For_UN_Aliased; procedure Set_Is_Constrained (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag12 (Id, V); end Set_Is_Constrained; procedure Set_Is_Constructor (Id : E; V : B := True) is begin Set_Flag76 (Id, V); end Set_Is_Constructor; procedure Set_Is_Controlled (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag42 (Id, V); end Set_Is_Controlled; procedure Set_Is_Controlling_Formal (Id : E; V : B := True) is begin pragma Assert (Is_Formal (Id)); Set_Flag97 (Id, V); end Set_Is_Controlling_Formal; procedure Set_Is_CPP_Class (Id : E; V : B := True) is begin Set_Flag74 (Id, V); end Set_Is_CPP_Class; procedure Set_Is_Descendent_Of_Address (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag223 (Id, V); end Set_Is_Descendent_Of_Address; procedure Set_Is_Discrim_SO_Function (Id : E; V : B := True) is begin Set_Flag176 (Id, V); end Set_Is_Discrim_SO_Function; procedure Set_Is_Discriminant_Check_Function (Id : E; V : B := True) is begin Set_Flag264 (Id, V); end Set_Is_Discriminant_Check_Function; procedure Set_Is_Dispatch_Table_Entity (Id : E; V : B := True) is begin Set_Flag234 (Id, V); end Set_Is_Dispatch_Table_Entity; procedure Set_Is_Dispatching_Operation (Id : E; V : B := True) is begin pragma Assert (V = False or else Is_Overloadable (Id) or else Ekind (Id) = E_Subprogram_Type); Set_Flag6 (Id, V); end Set_Is_Dispatching_Operation; procedure Set_Is_Eliminated (Id : E; V : B := True) is begin Set_Flag124 (Id, V); end Set_Is_Eliminated; procedure Set_Is_Entry_Formal (Id : E; V : B := True) is begin Set_Flag52 (Id, V); end Set_Is_Entry_Formal; procedure Set_Is_Exported (Id : E; V : B := True) is begin Set_Flag99 (Id, V); end Set_Is_Exported; procedure Set_Is_First_Subtype (Id : E; V : B := True) is begin Set_Flag70 (Id, V); end Set_Is_First_Subtype; procedure Set_Is_For_Access_Subtype (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Record_Subtype, E_Private_Subtype)); Set_Flag118 (Id, V); end Set_Is_For_Access_Subtype; procedure Set_Is_Formal_Subprogram (Id : E; V : B := True) is begin Set_Flag111 (Id, V); end Set_Is_Formal_Subprogram; procedure Set_Is_Frozen (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag4 (Id, V); end Set_Is_Frozen; procedure Set_Is_Generic_Actual_Type (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag94 (Id, V); end Set_Is_Generic_Actual_Type; procedure Set_Is_Generic_Instance (Id : E; V : B := True) is begin Set_Flag130 (Id, V); end Set_Is_Generic_Instance; procedure Set_Is_Generic_Type (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag13 (Id, V); end Set_Is_Generic_Type; procedure Set_Is_Hidden (Id : E; V : B := True) is begin Set_Flag57 (Id, V); end Set_Is_Hidden; procedure Set_Is_Hidden_Open_Scope (Id : E; V : B := True) is begin Set_Flag171 (Id, V); end Set_Is_Hidden_Open_Scope; procedure Set_Is_Immediately_Visible (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag7 (Id, V); end Set_Is_Immediately_Visible; procedure Set_Is_Implementation_Defined (Id : E; V : B := True) is begin Set_Flag254 (Id, V); end Set_Is_Implementation_Defined; procedure Set_Is_Imported (Id : E; V : B := True) is begin Set_Flag24 (Id, V); end Set_Is_Imported; procedure Set_Is_Independent (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Component, E_Void)); Set_Flag268 (Id, V); end Set_Is_Independent; procedure Set_Is_Inlined (Id : E; V : B := True) is begin Set_Flag11 (Id, V); end Set_Is_Inlined; procedure Set_Is_Interface (Id : E; V : B := True) is begin pragma Assert (Is_Record_Type (Id)); Set_Flag186 (Id, V); end Set_Is_Interface; procedure Set_Is_Instantiated (Id : E; V : B := True) is begin Set_Flag126 (Id, V); end Set_Is_Instantiated; procedure Set_Is_Internal (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag17 (Id, V); end Set_Is_Internal; procedure Set_Is_Interrupt_Handler (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag89 (Id, V); end Set_Is_Interrupt_Handler; procedure Set_Is_Intrinsic_Subprogram (Id : E; V : B := True) is begin Set_Flag64 (Id, V); end Set_Is_Intrinsic_Subprogram; procedure Set_Is_Invariant_Procedure (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure); Set_Flag257 (Id, V); end Set_Is_Invariant_Procedure; procedure Set_Is_Itype (Id : E; V : B := True) is begin Set_Flag91 (Id, V); end Set_Is_Itype; procedure Set_Is_Known_Non_Null (Id : E; V : B := True) is begin Set_Flag37 (Id, V); end Set_Is_Known_Non_Null; procedure Set_Is_Known_Null (Id : E; V : B := True) is begin Set_Flag204 (Id, V); end Set_Is_Known_Null; procedure Set_Is_Known_Valid (Id : E; V : B := True) is begin Set_Flag170 (Id, V); end Set_Is_Known_Valid; procedure Set_Is_Limited_Composite (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag106 (Id, V); end Set_Is_Limited_Composite; procedure Set_Is_Limited_Interface (Id : E; V : B := True) is begin pragma Assert (Is_Interface (Id)); Set_Flag197 (Id, V); end Set_Is_Limited_Interface; procedure Set_Is_Limited_Record (Id : E; V : B := True) is begin Set_Flag25 (Id, V); end Set_Is_Limited_Record; procedure Set_Is_Machine_Code_Subprogram (Id : E; V : B := True) is begin pragma Assert (Is_Subprogram (Id)); Set_Flag137 (Id, V); end Set_Is_Machine_Code_Subprogram; procedure Set_Is_Non_Static_Subtype (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag109 (Id, V); end Set_Is_Non_Static_Subtype; procedure Set_Is_Null_Init_Proc (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Procedure); Set_Flag178 (Id, V); end Set_Is_Null_Init_Proc; procedure Set_Is_Obsolescent (Id : E; V : B := True) is begin Set_Flag153 (Id, V); end Set_Is_Obsolescent; procedure Set_Is_Only_Out_Parameter (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Out_Parameter); Set_Flag226 (Id, V); end Set_Is_Only_Out_Parameter; procedure Set_Is_Optional_Parameter (Id : E; V : B := True) is begin pragma Assert (Is_Formal (Id)); Set_Flag134 (Id, V); end Set_Is_Optional_Parameter; procedure Set_Is_Package_Body_Entity (Id : E; V : B := True) is begin Set_Flag160 (Id, V); end Set_Is_Package_Body_Entity; procedure Set_Is_Packed (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag51 (Id, V); end Set_Is_Packed; procedure Set_Is_Packed_Array_Impl_Type (Id : E; V : B := True) is begin Set_Flag138 (Id, V); end Set_Is_Packed_Array_Impl_Type; procedure Set_Is_Potentially_Use_Visible (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag9 (Id, V); end Set_Is_Potentially_Use_Visible; procedure Set_Is_Predicate_Function (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure); Set_Flag255 (Id, V); end Set_Is_Predicate_Function; procedure Set_Is_Predicate_Function_M (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure); Set_Flag256 (Id, V); end Set_Is_Predicate_Function_M; procedure Set_Is_Preelaborated (Id : E; V : B := True) is begin Set_Flag59 (Id, V); end Set_Is_Preelaborated; procedure Set_Is_Primitive (Id : E; V : B := True) is begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Generic_Function, E_Generic_Procedure)); Set_Flag218 (Id, V); end Set_Is_Primitive; procedure Set_Is_Primitive_Wrapper (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); Set_Flag195 (Id, V); end Set_Is_Primitive_Wrapper; procedure Set_Is_Private_Composite (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag107 (Id, V); end Set_Is_Private_Composite; procedure Set_Is_Private_Descendant (Id : E; V : B := True) is begin Set_Flag53 (Id, V); end Set_Is_Private_Descendant; procedure Set_Is_Private_Primitive (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure)); Set_Flag245 (Id, V); end Set_Is_Private_Primitive; procedure Set_Is_Processed_Transient (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); Set_Flag252 (Id, V); end Set_Is_Processed_Transient; procedure Set_Is_Public (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag10 (Id, V); end Set_Is_Public; procedure Set_Is_Pure (Id : E; V : B := True) is begin Set_Flag44 (Id, V); end Set_Is_Pure; procedure Set_Is_Pure_Unit_Access_Type (Id : E; V : B := True) is begin pragma Assert (Is_Access_Type (Id)); Set_Flag189 (Id, V); end Set_Is_Pure_Unit_Access_Type; procedure Set_Is_RACW_Stub_Type (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag244 (Id, V); end Set_Is_RACW_Stub_Type; procedure Set_Is_Raised (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Exception); Set_Flag224 (Id, V); end Set_Is_Raised; procedure Set_Is_Remote_Call_Interface (Id : E; V : B := True) is begin Set_Flag62 (Id, V); end Set_Is_Remote_Call_Interface; procedure Set_Is_Remote_Types (Id : E; V : B := True) is begin Set_Flag61 (Id, V); end Set_Is_Remote_Types; procedure Set_Is_Renaming_Of_Object (Id : E; V : B := True) is begin Set_Flag112 (Id, V); end Set_Is_Renaming_Of_Object; procedure Set_Is_Return_Object (Id : E; V : B := True) is begin Set_Flag209 (Id, V); end Set_Is_Return_Object; procedure Set_Is_Safe_To_Reevaluate (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Variable); Set_Flag249 (Id, V); end Set_Is_Safe_To_Reevaluate; procedure Set_Is_Shared_Passive (Id : E; V : B := True) is begin Set_Flag60 (Id, V); end Set_Is_Shared_Passive; procedure Set_Is_Statically_Allocated (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) or else Ekind_In (Id, E_Exception, E_Variable, E_Constant, E_Void)); Set_Flag28 (Id, V); end Set_Is_Statically_Allocated; procedure Set_Is_Tag (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Component, E_Constant, E_Variable)); Set_Flag78 (Id, V); end Set_Is_Tag; procedure Set_Is_Tagged_Type (Id : E; V : B := True) is begin Set_Flag55 (Id, V); end Set_Is_Tagged_Type; procedure Set_Is_Thunk (Id : E; V : B := True) is begin pragma Assert (Is_Subprogram (Id)); Set_Flag225 (Id, V); end Set_Is_Thunk; procedure Set_Is_Trivial_Subprogram (Id : E; V : B := True) is begin Set_Flag235 (Id, V); end Set_Is_Trivial_Subprogram; procedure Set_Is_True_Constant (Id : E; V : B := True) is begin Set_Flag163 (Id, V); end Set_Is_True_Constant; procedure Set_Is_Unchecked_Union (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag117 (Id, V); end Set_Is_Unchecked_Union; procedure Set_Is_Underlying_Record_View (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Record_Type); Set_Flag246 (Id, V); end Set_Is_Underlying_Record_View; procedure Set_Is_Unsigned_Type (Id : E; V : B := True) is begin pragma Assert (Is_Discrete_Or_Fixed_Point_Type (Id)); Set_Flag144 (Id, V); end Set_Is_Unsigned_Type; procedure Set_Is_Valued_Procedure (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Procedure); Set_Flag127 (Id, V); end Set_Is_Valued_Procedure; procedure Set_Is_Visible_Formal (Id : E; V : B := True) is begin Set_Flag206 (Id, V); end Set_Is_Visible_Formal; procedure Set_Is_Visible_Lib_Unit (Id : E; V : B := True) is begin Set_Flag116 (Id, V); end Set_Is_Visible_Lib_Unit; procedure Set_Is_VMS_Exception (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Exception); Set_Flag133 (Id, V); end Set_Is_VMS_Exception; procedure Set_Is_Volatile (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Flag16 (Id, V); end Set_Is_Volatile; procedure Set_Itype_Printed (Id : E; V : B := True) is begin pragma Assert (Is_Itype (Id)); Set_Flag202 (Id, V); end Set_Itype_Printed; procedure Set_Kill_Elaboration_Checks (Id : E; V : B := True) is begin Set_Flag32 (Id, V); end Set_Kill_Elaboration_Checks; procedure Set_Kill_Range_Checks (Id : E; V : B := True) is begin Set_Flag33 (Id, V); end Set_Kill_Range_Checks; procedure Set_Known_To_Have_Preelab_Init (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag207 (Id, V); end Set_Known_To_Have_Preelab_Init; procedure Set_Last_Aggregate_Assignment (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); Set_Node30 (Id, V); end Set_Last_Aggregate_Assignment; procedure Set_Last_Assignment (Id : E; V : N) is begin pragma Assert (Is_Assignable (Id)); Set_Node26 (Id, V); end Set_Last_Assignment; procedure Set_Last_Entity (Id : E; V : E) is begin Set_Node20 (Id, V); end Set_Last_Entity; procedure Set_Limited_View (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Package); Set_Node23 (Id, V); end Set_Limited_View; procedure Set_Linker_Section_Pragma (Id : E; V : N) is begin pragma Assert (Is_Type (Id) or else Ekind_In (Id, E_Constant, E_Variable) or else Is_Subprogram (Id)); Set_Node33 (Id, V); end Set_Linker_Section_Pragma; procedure Set_Lit_Indexes (Id : E; V : E) is begin pragma Assert (Is_Enumeration_Type (Id) and then Root_Type (Id) = Id); Set_Node15 (Id, V); end Set_Lit_Indexes; procedure Set_Lit_Strings (Id : E; V : E) is begin pragma Assert (Is_Enumeration_Type (Id) and then Root_Type (Id) = Id); Set_Node16 (Id, V); end Set_Lit_Strings; procedure Set_Low_Bound_Tested (Id : E; V : B := True) is begin pragma Assert (Is_Formal (Id)); Set_Flag205 (Id, V); end Set_Low_Bound_Tested; procedure Set_Machine_Radix_10 (Id : E; V : B := True) is begin pragma Assert (Is_Decimal_Fixed_Point_Type (Id)); Set_Flag84 (Id, V); end Set_Machine_Radix_10; procedure Set_Master_Id (Id : E; V : E) is begin pragma Assert (Is_Access_Type (Id)); Set_Node17 (Id, V); end Set_Master_Id; procedure Set_Materialize_Entity (Id : E; V : B := True) is begin Set_Flag168 (Id, V); end Set_Materialize_Entity; procedure Set_May_Inherit_Delayed_Rep_Aspects (Id : E; V : B := True) is begin Set_Flag262 (Id, V); end Set_May_Inherit_Delayed_Rep_Aspects; procedure Set_Mechanism (Id : E; V : M) is begin pragma Assert (Ekind (Id) = E_Function or else Is_Formal (Id)); Set_Uint8 (Id, UI_From_Int (V)); end Set_Mechanism; procedure Set_Modulus (Id : E; V : U) is begin pragma Assert (Ekind (Id) = E_Modular_Integer_Type); Set_Uint17 (Id, V); end Set_Modulus; procedure Set_Must_Be_On_Byte_Boundary (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag183 (Id, V); end Set_Must_Be_On_Byte_Boundary; procedure Set_Must_Have_Preelab_Init (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag208 (Id, V); end Set_Must_Have_Preelab_Init; procedure Set_Needs_Debug_Info (Id : E; V : B := True) is begin Set_Flag147 (Id, V); end Set_Needs_Debug_Info; procedure Set_Needs_No_Actuals (Id : E; V : B := True) is begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Subprogram_Type, E_Entry_Family)); Set_Flag22 (Id, V); end Set_Needs_No_Actuals; procedure Set_Never_Set_In_Source (Id : E; V : B := True) is begin Set_Flag115 (Id, V); end Set_Never_Set_In_Source; procedure Set_Next_Inlined_Subprogram (Id : E; V : E) is begin Set_Node12 (Id, V); end Set_Next_Inlined_Subprogram; procedure Set_No_Pool_Assigned (Id : E; V : B := True) is begin pragma Assert (Is_Access_Type (Id) and then Is_Base_Type (Id)); Set_Flag131 (Id, V); end Set_No_Pool_Assigned; procedure Set_No_Return (Id : E; V : B := True) is begin pragma Assert (V = False or else Ekind_In (Id, E_Procedure, E_Generic_Procedure)); Set_Flag113 (Id, V); end Set_No_Return; procedure Set_No_Strict_Aliasing (Id : E; V : B := True) is begin pragma Assert (Is_Access_Type (Id) and then Is_Base_Type (Id)); Set_Flag136 (Id, V); end Set_No_Strict_Aliasing; procedure Set_Non_Binary_Modulus (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) and then Is_Base_Type (Id)); Set_Flag58 (Id, V); end Set_Non_Binary_Modulus; procedure Set_Non_Limited_View (Id : E; V : E) is begin pragma Assert (Ekind (Id) in Incomplete_Kind or else Ekind (Id) = E_Abstract_State); Set_Node17 (Id, V); end Set_Non_Limited_View; procedure Set_Nonzero_Is_True (Id : E; V : B := True) is begin pragma Assert (Root_Type (Id) = Standard_Boolean and then Ekind (Id) = E_Enumeration_Type); Set_Flag162 (Id, V); end Set_Nonzero_Is_True; procedure Set_Normalized_First_Bit (Id : E; V : U) is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); Set_Uint8 (Id, V); end Set_Normalized_First_Bit; procedure Set_Normalized_Position (Id : E; V : U) is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); Set_Uint14 (Id, V); end Set_Normalized_Position; procedure Set_Normalized_Position_Max (Id : E; V : U) is begin pragma Assert (Ekind_In (Id, E_Component, E_Discriminant)); Set_Uint10 (Id, V); end Set_Normalized_Position_Max; procedure Set_OK_To_Rename (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Variable); Set_Flag247 (Id, V); end Set_OK_To_Rename; procedure Set_OK_To_Reorder_Components (Id : E; V : B := True) is begin pragma Assert (Is_Record_Type (Id) and then Is_Base_Type (Id)); Set_Flag239 (Id, V); end Set_OK_To_Reorder_Components; procedure Set_Optimize_Alignment_Space (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) or else Ekind_In (Id, E_Constant, E_Variable)); Set_Flag241 (Id, V); end Set_Optimize_Alignment_Space; procedure Set_Optimize_Alignment_Time (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) or else Ekind_In (Id, E_Constant, E_Variable)); Set_Flag242 (Id, V); end Set_Optimize_Alignment_Time; procedure Set_Original_Access_Type (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Access_Subprogram_Type); Set_Node26 (Id, V); end Set_Original_Access_Type; procedure Set_Original_Array_Type (Id : E; V : E) is begin pragma Assert (Is_Array_Type (Id) or else Is_Modular_Integer_Type (Id)); Set_Node21 (Id, V); end Set_Original_Array_Type; procedure Set_Original_Record_Component (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Void, E_Component, E_Discriminant)); Set_Node22 (Id, V); end Set_Original_Record_Component; procedure Set_Overlays_Constant (Id : E; V : B := True) is begin Set_Flag243 (Id, V); end Set_Overlays_Constant; procedure Set_Overridden_Operation (Id : E; V : E) is begin Set_Node26 (Id, V); end Set_Overridden_Operation; procedure Set_Package_Instantiation (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Void, E_Generic_Package, E_Package)); Set_Node26 (Id, V); end Set_Package_Instantiation; procedure Set_Packed_Array_Impl_Type (Id : E; V : E) is begin pragma Assert (Is_Array_Type (Id)); Set_Node23 (Id, V); end Set_Packed_Array_Impl_Type; procedure Set_Parent_Subtype (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Record_Type); Set_Node19 (Id, V); end Set_Parent_Subtype; procedure Set_Part_Of_Constituents (Id : E; V : L) is begin pragma Assert (Ekind (Id) = E_Abstract_State); Set_Elist9 (Id, V); end Set_Part_Of_Constituents; procedure Set_Postcondition_Proc (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Procedure); Set_Node8 (Id, V); end Set_Postcondition_Proc; procedure Set_PPC_Wrapper (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Entry, E_Entry_Family)); Set_Node25 (Id, V); end Set_PPC_Wrapper; procedure Set_Direct_Primitive_Operations (Id : E; V : L) is begin pragma Assert (Is_Tagged_Type (Id)); Set_Elist10 (Id, V); end Set_Direct_Primitive_Operations; procedure Set_Prival (Id : E; V : E) is begin pragma Assert (Is_Protected_Component (Id)); Set_Node17 (Id, V); end Set_Prival; procedure Set_Prival_Link (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); Set_Node20 (Id, V); end Set_Prival_Link; procedure Set_Private_Dependents (Id : E; V : L) is begin pragma Assert (Is_Incomplete_Or_Private_Type (Id)); Set_Elist18 (Id, V); end Set_Private_Dependents; procedure Set_Private_View (Id : E; V : N) is begin pragma Assert (Is_Private_Type (Id)); Set_Node22 (Id, V); end Set_Private_View; procedure Set_Protected_Body_Subprogram (Id : E; V : E) is begin pragma Assert (Is_Subprogram (Id) or else Is_Entry (Id)); Set_Node11 (Id, V); end Set_Protected_Body_Subprogram; procedure Set_Protected_Formal (Id : E; V : E) is begin pragma Assert (Is_Formal (Id)); Set_Node22 (Id, V); end Set_Protected_Formal; procedure Set_Protection_Object (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Entry, E_Entry_Family, E_Function, E_Procedure)); Set_Node23 (Id, V); end Set_Protection_Object; procedure Set_Reachable (Id : E; V : B := True) is begin Set_Flag49 (Id, V); end Set_Reachable; procedure Set_Referenced (Id : E; V : B := True) is begin Set_Flag156 (Id, V); end Set_Referenced; procedure Set_Referenced_As_LHS (Id : E; V : B := True) is begin Set_Flag36 (Id, V); end Set_Referenced_As_LHS; procedure Set_Referenced_As_Out_Parameter (Id : E; V : B := True) is begin Set_Flag227 (Id, V); end Set_Referenced_As_Out_Parameter; procedure Set_Refinement_Constituents (Id : E; V : L) is begin pragma Assert (Ekind (Id) = E_Abstract_State); Set_Elist8 (Id, V); end Set_Refinement_Constituents; procedure Set_Register_Exception_Call (Id : E; V : N) is begin pragma Assert (Ekind (Id) = E_Exception); Set_Node20 (Id, V); end Set_Register_Exception_Call; procedure Set_Related_Array_Object (Id : E; V : E) is begin pragma Assert (Is_Array_Type (Id)); Set_Node25 (Id, V); end Set_Related_Array_Object; procedure Set_Related_Expression (Id : E; V : N) is begin pragma Assert (Ekind (Id) in Type_Kind or else Ekind_In (Id, E_Constant, E_Variable, E_Void)); Set_Node24 (Id, V); end Set_Related_Expression; procedure Set_Related_Instance (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Package, E_Package_Body)); Set_Node15 (Id, V); end Set_Related_Instance; procedure Set_Related_Type (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Component, E_Constant, E_Variable)); Set_Node27 (Id, V); end Set_Related_Type; procedure Set_Relative_Deadline_Variable (Id : E; V : E) is begin pragma Assert (Is_Task_Type (Id) and then Is_Base_Type (Id)); Set_Node26 (Id, V); end Set_Relative_Deadline_Variable; procedure Set_Renamed_Entity (Id : E; V : N) is begin Set_Node18 (Id, V); end Set_Renamed_Entity; procedure Set_Renamed_In_Spec (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Package); Set_Flag231 (Id, V); end Set_Renamed_In_Spec; procedure Set_Renamed_Object (Id : E; V : N) is begin Set_Node18 (Id, V); end Set_Renamed_Object; procedure Set_Renaming_Map (Id : E; V : U) is begin Set_Uint9 (Id, V); end Set_Renaming_Map; procedure Set_Requires_Overriding (Id : E; V : B := True) is begin pragma Assert (Is_Overloadable (Id)); Set_Flag213 (Id, V); end Set_Requires_Overriding; procedure Set_Return_Present (Id : E; V : B := True) is begin Set_Flag54 (Id, V); end Set_Return_Present; procedure Set_Return_Applies_To (Id : E; V : N) is begin Set_Node8 (Id, V); end Set_Return_Applies_To; procedure Set_Returns_By_Ref (Id : E; V : B := True) is begin Set_Flag90 (Id, V); end Set_Returns_By_Ref; procedure Set_Reverse_Bit_Order (Id : E; V : B := True) is begin pragma Assert (Is_Record_Type (Id) and then Is_Base_Type (Id)); Set_Flag164 (Id, V); end Set_Reverse_Bit_Order; procedure Set_Reverse_Storage_Order (Id : E; V : B := True) is begin pragma Assert (Is_Base_Type (Id) and then (Is_Record_Type (Id) or else Is_Array_Type (Id))); Set_Flag93 (Id, V); end Set_Reverse_Storage_Order; procedure Set_RM_Size (Id : E; V : U) is begin pragma Assert (Is_Type (Id)); Set_Uint13 (Id, V); end Set_RM_Size; procedure Set_Scalar_Range (Id : E; V : N) is begin Set_Node20 (Id, V); end Set_Scalar_Range; procedure Set_Scale_Value (Id : E; V : U) is begin Set_Uint15 (Id, V); end Set_Scale_Value; procedure Set_Scope_Depth_Value (Id : E; V : U) is begin pragma Assert (not Is_Record_Type (Id)); Set_Uint22 (Id, V); end Set_Scope_Depth_Value; procedure Set_Sec_Stack_Needed_For_Return (Id : E; V : B := True) is begin Set_Flag167 (Id, V); end Set_Sec_Stack_Needed_For_Return; procedure Set_Shadow_Entities (Id : E; V : S) is begin pragma Assert (Ekind_In (Id, E_Package, E_Generic_Package)); Set_List14 (Id, V); end Set_Shadow_Entities; procedure Set_Shared_Var_Procs_Instance (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Variable); Set_Node22 (Id, V); end Set_Shared_Var_Procs_Instance; procedure Set_Size_Check_Code (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); Set_Node19 (Id, V); end Set_Size_Check_Code; procedure Set_Size_Depends_On_Discriminant (Id : E; V : B := True) is begin Set_Flag177 (Id, V); end Set_Size_Depends_On_Discriminant; procedure Set_Size_Known_At_Compile_Time (Id : E; V : B := True) is begin Set_Flag92 (Id, V); end Set_Size_Known_At_Compile_Time; procedure Set_Small_Value (Id : E; V : R) is begin pragma Assert (Is_Fixed_Point_Type (Id)); Set_Ureal21 (Id, V); end Set_Small_Value; procedure Set_SPARK_Aux_Pragma (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); Set_Node33 (Id, V); end Set_SPARK_Aux_Pragma; procedure Set_SPARK_Aux_Pragma_Inherited (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); Set_Flag266 (Id, V); end Set_SPARK_Aux_Pragma_Inherited; procedure Set_SPARK_Pragma (Id : E; V : N) is begin pragma Assert (Ekind_In (Id, E_Function, -- subprogram variants E_Generic_Function, E_Generic_Procedure, E_Procedure, E_Subprogram_Body) or else Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); Set_Node32 (Id, V); end Set_SPARK_Pragma; procedure Set_SPARK_Pragma_Inherited (Id : E; V : B := True) is begin pragma Assert (Ekind_In (Id, E_Function, -- subprogram variants E_Generic_Function, E_Generic_Procedure, E_Procedure, E_Subprogram_Body) or else Ekind_In (Id, E_Generic_Package, -- package variants E_Package, E_Package_Body)); Set_Flag265 (Id, V); end Set_SPARK_Pragma_Inherited; procedure Set_Spec_Entity (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Package_Body or else Is_Formal (Id)); Set_Node19 (Id, V); end Set_Spec_Entity; procedure Set_SSO_Set_High_By_Default (Id : E; V : B := True) is begin pragma Assert (Is_Base_Type (Id) and then (Is_Record_Type (Id) or else Is_Array_Type (Id))); Set_Flag273 (Id, V); end Set_SSO_Set_High_By_Default; procedure Set_SSO_Set_Low_By_Default (Id : E; V : B := True) is begin pragma Assert (Is_Base_Type (Id) and then (Is_Record_Type (Id) or else Is_Array_Type (Id))); Set_Flag272 (Id, V); end Set_SSO_Set_Low_By_Default; procedure Set_Static_Discrete_Predicate (Id : E; V : S) is begin pragma Assert (Is_Discrete_Type (Id) and then Has_Predicates (Id)); Set_List25 (Id, V); end Set_Static_Discrete_Predicate; procedure Set_Static_Real_Or_String_Predicate (Id : E; V : N) is begin pragma Assert ((Is_Real_Type (Id) or else Is_String_Type (Id)) and then Has_Predicates (Id)); Set_Node25 (Id, V); end Set_Static_Real_Or_String_Predicate; procedure Set_Status_Flag_Or_Transient_Decl (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Constant, E_Variable)); Set_Node15 (Id, V); end Set_Status_Flag_Or_Transient_Decl; procedure Set_Storage_Size_Variable (Id : E; V : E) is begin pragma Assert (Is_Access_Type (Id) or else Is_Task_Type (Id)); pragma Assert (Id = Base_Type (Id)); Set_Node15 (Id, V); end Set_Storage_Size_Variable; procedure Set_Static_Elaboration_Desired (Id : E; V : B) is begin pragma Assert (Ekind (Id) = E_Package); Set_Flag77 (Id, V); end Set_Static_Elaboration_Desired; procedure Set_Static_Initialization (Id : E; V : N) is begin pragma Assert (Ekind (Id) = E_Procedure and then not Is_Dispatching_Operation (Id)); Set_Node30 (Id, V); end Set_Static_Initialization; procedure Set_Stored_Constraint (Id : E; V : L) is begin pragma Assert (Nkind (Id) in N_Entity); Set_Elist23 (Id, V); end Set_Stored_Constraint; procedure Set_Stores_Attribute_Old_Prefix (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Constant); Set_Flag270 (Id, V); end Set_Stores_Attribute_Old_Prefix; procedure Set_Strict_Alignment (Id : E; V : B := True) is begin pragma Assert (Id = Base_Type (Id)); Set_Flag145 (Id, V); end Set_Strict_Alignment; procedure Set_String_Literal_Length (Id : E; V : U) is begin pragma Assert (Ekind (Id) = E_String_Literal_Subtype); Set_Uint16 (Id, V); end Set_String_Literal_Length; procedure Set_String_Literal_Low_Bound (Id : E; V : N) is begin pragma Assert (Ekind (Id) = E_String_Literal_Subtype); Set_Node15 (Id, V); end Set_String_Literal_Low_Bound; procedure Set_Subprograms_For_Type (Id : E; V : E) is begin pragma Assert (Is_Type (Id) or else Is_Subprogram (Id)); Set_Node29 (Id, V); end Set_Subprograms_For_Type; procedure Set_Suppress_Elaboration_Warnings (Id : E; V : B := True) is begin Set_Flag148 (Id, V); end Set_Suppress_Elaboration_Warnings; procedure Set_Suppress_Initialization (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id)); Set_Flag105 (Id, V); end Set_Suppress_Initialization; procedure Set_Suppress_Style_Checks (Id : E; V : B := True) is begin Set_Flag165 (Id, V); end Set_Suppress_Style_Checks; procedure Set_Suppress_Value_Tracking_On_Call (Id : E; V : B := True) is begin Set_Flag217 (Id, V); end Set_Suppress_Value_Tracking_On_Call; procedure Set_Task_Body_Procedure (Id : E; V : N) is begin pragma Assert (Ekind (Id) in Task_Kind); Set_Node25 (Id, V); end Set_Task_Body_Procedure; procedure Set_Thunk_Entity (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure) and then Is_Thunk (Id)); Set_Node31 (Id, V); end Set_Thunk_Entity; procedure Set_Treat_As_Volatile (Id : E; V : B := True) is begin Set_Flag41 (Id, V); end Set_Treat_As_Volatile; procedure Set_Underlying_Full_View (Id : E; V : E) is begin pragma Assert (Ekind (Id) in Private_Kind); Set_Node19 (Id, V); end Set_Underlying_Full_View; procedure Set_Underlying_Record_View (Id : E; V : E) is begin pragma Assert (Ekind (Id) = E_Record_Type); Set_Node28 (Id, V); end Set_Underlying_Record_View; procedure Set_Universal_Aliasing (Id : E; V : B := True) is begin pragma Assert (Is_Type (Id) and then Is_Base_Type (Id)); Set_Flag216 (Id, V); end Set_Universal_Aliasing; procedure Set_Unset_Reference (Id : E; V : N) is begin Set_Node16 (Id, V); end Set_Unset_Reference; procedure Set_Used_As_Generic_Actual (Id : E; V : B := True) is begin Set_Flag222 (Id, V); end Set_Used_As_Generic_Actual; procedure Set_Uses_Lock_Free (Id : E; V : B := True) is begin pragma Assert (Ekind (Id) = E_Protected_Type); Set_Flag188 (Id, V); end Set_Uses_Lock_Free; procedure Set_Uses_Sec_Stack (Id : E; V : B := True) is begin Set_Flag95 (Id, V); end Set_Uses_Sec_Stack; procedure Set_Warnings_Off (Id : E; V : B := True) is begin Set_Flag96 (Id, V); end Set_Warnings_Off; procedure Set_Warnings_Off_Used (Id : E; V : B := True) is begin Set_Flag236 (Id, V); end Set_Warnings_Off_Used; procedure Set_Warnings_Off_Used_Unmodified (Id : E; V : B := True) is begin Set_Flag237 (Id, V); end Set_Warnings_Off_Used_Unmodified; procedure Set_Warnings_Off_Used_Unreferenced (Id : E; V : B := True) is begin Set_Flag238 (Id, V); end Set_Warnings_Off_Used_Unreferenced; procedure Set_Was_Hidden (Id : E; V : B := True) is begin Set_Flag196 (Id, V); end Set_Was_Hidden; procedure Set_Wrapped_Entity (Id : E; V : E) is begin pragma Assert (Ekind_In (Id, E_Function, E_Procedure) and then Is_Primitive_Wrapper (Id)); Set_Node27 (Id, V); end Set_Wrapped_Entity; ----------------------------------- -- Field Initialization Routines -- ----------------------------------- procedure Init_Alignment (Id : E) is begin Set_Uint14 (Id, Uint_0); end Init_Alignment; procedure Init_Alignment (Id : E; V : Int) is begin Set_Uint14 (Id, UI_From_Int (V)); end Init_Alignment; procedure Init_Component_Bit_Offset (Id : E) is begin Set_Uint11 (Id, No_Uint); end Init_Component_Bit_Offset; procedure Init_Component_Bit_Offset (Id : E; V : Int) is begin Set_Uint11 (Id, UI_From_Int (V)); end Init_Component_Bit_Offset; procedure Init_Component_Size (Id : E) is begin Set_Uint22 (Id, Uint_0); end Init_Component_Size; procedure Init_Component_Size (Id : E; V : Int) is begin Set_Uint22 (Id, UI_From_Int (V)); end Init_Component_Size; procedure Init_Digits_Value (Id : E) is begin Set_Uint17 (Id, Uint_0); end Init_Digits_Value; procedure Init_Digits_Value (Id : E; V : Int) is begin Set_Uint17 (Id, UI_From_Int (V)); end Init_Digits_Value; procedure Init_Esize (Id : E) is begin Set_Uint12 (Id, Uint_0); end Init_Esize; procedure Init_Esize (Id : E; V : Int) is begin Set_Uint12 (Id, UI_From_Int (V)); end Init_Esize; procedure Init_Normalized_First_Bit (Id : E) is begin Set_Uint8 (Id, No_Uint); end Init_Normalized_First_Bit; procedure Init_Normalized_First_Bit (Id : E; V : Int) is begin Set_Uint8 (Id, UI_From_Int (V)); end Init_Normalized_First_Bit; procedure Init_Normalized_Position (Id : E) is begin Set_Uint14 (Id, No_Uint); end Init_Normalized_Position; procedure Init_Normalized_Position (Id : E; V : Int) is begin Set_Uint14 (Id, UI_From_Int (V)); end Init_Normalized_Position; procedure Init_Normalized_Position_Max (Id : E) is begin Set_Uint10 (Id, No_Uint); end Init_Normalized_Position_Max; procedure Init_Normalized_Position_Max (Id : E; V : Int) is begin Set_Uint10 (Id, UI_From_Int (V)); end Init_Normalized_Position_Max; procedure Init_RM_Size (Id : E) is begin Set_Uint13 (Id, Uint_0); end Init_RM_Size; procedure Init_RM_Size (Id : E; V : Int) is begin Set_Uint13 (Id, UI_From_Int (V)); end Init_RM_Size; ----------------------------- -- Init_Component_Location -- ----------------------------- procedure Init_Component_Location (Id : E) is begin Set_Uint8 (Id, No_Uint); -- Normalized_First_Bit Set_Uint10 (Id, No_Uint); -- Normalized_Position_Max Set_Uint11 (Id, No_Uint); -- Component_Bit_Offset Set_Uint12 (Id, Uint_0); -- Esize Set_Uint14 (Id, No_Uint); -- Normalized_Position end Init_Component_Location; ---------------------------- -- Init_Object_Size_Align -- ---------------------------- procedure Init_Object_Size_Align (Id : E) is begin Set_Uint12 (Id, Uint_0); -- Esize Set_Uint14 (Id, Uint_0); -- Alignment end Init_Object_Size_Align; --------------- -- Init_Size -- --------------- procedure Init_Size (Id : E; V : Int) is begin pragma Assert (not Is_Object (Id)); Set_Uint12 (Id, UI_From_Int (V)); -- Esize Set_Uint13 (Id, UI_From_Int (V)); -- RM_Size end Init_Size; --------------------- -- Init_Size_Align -- --------------------- procedure Init_Size_Align (Id : E) is begin pragma Assert (not Is_Object (Id)); Set_Uint12 (Id, Uint_0); -- Esize Set_Uint13 (Id, Uint_0); -- RM_Size Set_Uint14 (Id, Uint_0); -- Alignment end Init_Size_Align; ---------------------------------------------- -- Type Representation Attribute Predicates -- ---------------------------------------------- function Known_Alignment (E : Entity_Id) return B is begin return Uint14 (E) /= Uint_0 and then Uint14 (E) /= No_Uint; end Known_Alignment; function Known_Component_Bit_Offset (E : Entity_Id) return B is begin return Uint11 (E) /= No_Uint; end Known_Component_Bit_Offset; function Known_Component_Size (E : Entity_Id) return B is begin return Uint22 (Base_Type (E)) /= Uint_0 and then Uint22 (Base_Type (E)) /= No_Uint; end Known_Component_Size; function Known_Esize (E : Entity_Id) return B is begin return Uint12 (E) /= Uint_0 and then Uint12 (E) /= No_Uint; end Known_Esize; function Known_Normalized_First_Bit (E : Entity_Id) return B is begin return Uint8 (E) /= No_Uint; end Known_Normalized_First_Bit; function Known_Normalized_Position (E : Entity_Id) return B is begin return Uint14 (E) /= No_Uint; end Known_Normalized_Position; function Known_Normalized_Position_Max (E : Entity_Id) return B is begin return Uint10 (E) /= No_Uint; end Known_Normalized_Position_Max; function Known_RM_Size (E : Entity_Id) return B is begin return Uint13 (E) /= No_Uint and then (Uint13 (E) /= Uint_0 or else Is_Discrete_Type (E) or else Is_Fixed_Point_Type (E)); end Known_RM_Size; function Known_Static_Component_Bit_Offset (E : Entity_Id) return B is begin return Uint11 (E) /= No_Uint and then Uint11 (E) >= Uint_0; end Known_Static_Component_Bit_Offset; function Known_Static_Component_Size (E : Entity_Id) return B is begin return Uint22 (Base_Type (E)) > Uint_0; end Known_Static_Component_Size; function Known_Static_Esize (E : Entity_Id) return B is begin return Uint12 (E) > Uint_0 and then not Is_Generic_Type (E); end Known_Static_Esize; function Known_Static_Normalized_First_Bit (E : Entity_Id) return B is begin return Uint8 (E) /= No_Uint and then Uint8 (E) >= Uint_0; end Known_Static_Normalized_First_Bit; function Known_Static_Normalized_Position (E : Entity_Id) return B is begin return Uint14 (E) /= No_Uint and then Uint14 (E) >= Uint_0; end Known_Static_Normalized_Position; function Known_Static_Normalized_Position_Max (E : Entity_Id) return B is begin return Uint10 (E) /= No_Uint and then Uint10 (E) >= Uint_0; end Known_Static_Normalized_Position_Max; function Known_Static_RM_Size (E : Entity_Id) return B is begin return (Uint13 (E) > Uint_0 or else Is_Discrete_Type (E) or else Is_Fixed_Point_Type (E)) and then not Is_Generic_Type (E); end Known_Static_RM_Size; function Unknown_Alignment (E : Entity_Id) return B is begin return Uint14 (E) = Uint_0 or else Uint14 (E) = No_Uint; end Unknown_Alignment; function Unknown_Component_Bit_Offset (E : Entity_Id) return B is begin return Uint11 (E) = No_Uint; end Unknown_Component_Bit_Offset; function Unknown_Component_Size (E : Entity_Id) return B is begin return Uint22 (Base_Type (E)) = Uint_0 or else Uint22 (Base_Type (E)) = No_Uint; end Unknown_Component_Size; function Unknown_Esize (E : Entity_Id) return B is begin return Uint12 (E) = No_Uint or else Uint12 (E) = Uint_0; end Unknown_Esize; function Unknown_Normalized_First_Bit (E : Entity_Id) return B is begin return Uint8 (E) = No_Uint; end Unknown_Normalized_First_Bit; function Unknown_Normalized_Position (E : Entity_Id) return B is begin return Uint14 (E) = No_Uint; end Unknown_Normalized_Position; function Unknown_Normalized_Position_Max (E : Entity_Id) return B is begin return Uint10 (E) = No_Uint; end Unknown_Normalized_Position_Max; function Unknown_RM_Size (E : Entity_Id) return B is begin return (Uint13 (E) = Uint_0 and then not Is_Discrete_Type (E) and then not Is_Fixed_Point_Type (E)) or else Uint13 (E) = No_Uint; end Unknown_RM_Size; -------------------- -- Address_Clause -- -------------------- function Address_Clause (Id : E) return N is begin return Get_Attribute_Definition_Clause (Id, Attribute_Address); end Address_Clause; --------------- -- Aft_Value -- --------------- function Aft_Value (Id : E) return U is Result : Nat := 1; Delta_Val : Ureal := Delta_Value (Id); begin while Delta_Val < Ureal_Tenth loop Delta_Val := Delta_Val * Ureal_10; Result := Result + 1; end loop; return UI_From_Int (Result); end Aft_Value; ---------------------- -- Alignment_Clause -- ---------------------- function Alignment_Clause (Id : E) return N is begin return Get_Attribute_Definition_Clause (Id, Attribute_Alignment); end Alignment_Clause; ------------------- -- Append_Entity -- ------------------- procedure Append_Entity (Id : Entity_Id; V : Entity_Id) is begin if Last_Entity (V) = Empty then Set_First_Entity (Id => V, V => Id); else Set_Next_Entity (Last_Entity (V), Id); end if; Set_Next_Entity (Id, Empty); Set_Scope (Id, V); Set_Last_Entity (Id => V, V => Id); end Append_Entity; --------------- -- Base_Type -- --------------- function Base_Type (Id : E) return E is begin if Is_Base_Type (Id) then return Id; else pragma Assert (Is_Type (Id)); return Etype (Id); end if; end Base_Type; ------------------------- -- Component_Alignment -- ------------------------- -- Component Alignment is encoded using two flags, Flag128/129 as -- follows. Note that both flags False = Align_Default, so that the -- default initialization of flags to False initializes component -- alignment to the default value as required. -- Flag128 Flag129 Value -- ------- ------- ----- -- False False Calign_Default -- False True Calign_Component_Size -- True False Calign_Component_Size_4 -- True True Calign_Storage_Unit function Component_Alignment (Id : E) return C is BT : constant Node_Id := Base_Type (Id); begin pragma Assert (Is_Array_Type (Id) or else Is_Record_Type (Id)); if Flag128 (BT) then if Flag129 (BT) then return Calign_Storage_Unit; else return Calign_Component_Size_4; end if; else if Flag129 (BT) then return Calign_Component_Size; else return Calign_Default; end if; end if; end Component_Alignment; ---------------------- -- Declaration_Node -- ---------------------- function Declaration_Node (Id : E) return N is P : Node_Id; begin if Ekind (Id) = E_Incomplete_Type and then Present (Full_View (Id)) then P := Parent (Full_View (Id)); else P := Parent (Id); end if; loop if Nkind (P) /= N_Selected_Component and then Nkind (P) /= N_Expanded_Name and then not (Nkind (P) = N_Defining_Program_Unit_Name and then Is_Child_Unit (Id)) then return P; else P := Parent (P); end if; end loop; end Declaration_Node; --------------------- -- Designated_Type -- --------------------- function Designated_Type (Id : E) return E is Desig_Type : E; begin Desig_Type := Directly_Designated_Type (Id); if Ekind (Desig_Type) = E_Incomplete_Type and then Present (Full_View (Desig_Type)) then return Full_View (Desig_Type); elsif Is_Class_Wide_Type (Desig_Type) and then Ekind (Etype (Desig_Type)) = E_Incomplete_Type and then Present (Full_View (Etype (Desig_Type))) and then Present (Class_Wide_Type (Full_View (Etype (Desig_Type)))) then return Class_Wide_Type (Full_View (Etype (Desig_Type))); else return Desig_Type; end if; end Designated_Type; ---------------------- -- Entry_Index_Type -- ---------------------- function Entry_Index_Type (Id : E) return N is begin pragma Assert (Ekind (Id) = E_Entry_Family); return Etype (Discrete_Subtype_Definition (Parent (Id))); end Entry_Index_Type; --------------------- -- First_Component -- --------------------- function First_Component (Id : E) return E is Comp_Id : E; begin pragma Assert (Is_Record_Type (Id) or else Is_Incomplete_Or_Private_Type (Id)); Comp_Id := First_Entity (Id); while Present (Comp_Id) loop exit when Ekind (Comp_Id) = E_Component; Comp_Id := Next_Entity (Comp_Id); end loop; return Comp_Id; end First_Component; ------------------------------------- -- First_Component_Or_Discriminant -- ------------------------------------- function First_Component_Or_Discriminant (Id : E) return E is Comp_Id : E; begin pragma Assert (Is_Record_Type (Id) or else Is_Incomplete_Or_Private_Type (Id) or else Has_Discriminants (Id)); Comp_Id := First_Entity (Id); while Present (Comp_Id) loop exit when Ekind_In (Comp_Id, E_Component, E_Discriminant); Comp_Id := Next_Entity (Comp_Id); end loop; return Comp_Id; end First_Component_Or_Discriminant; ------------------ -- First_Formal -- ------------------ function First_Formal (Id : E) return E is Formal : E; begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Entry_Family, E_Subprogram_Body, E_Subprogram_Type)); if Ekind (Id) = E_Enumeration_Literal then return Empty; else Formal := First_Entity (Id); if Present (Formal) and then Is_Formal (Formal) then return Formal; else return Empty; end if; end if; end First_Formal; ------------------------------ -- First_Formal_With_Extras -- ------------------------------ function First_Formal_With_Extras (Id : E) return E is Formal : E; begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Entry_Family, E_Subprogram_Body, E_Subprogram_Type)); if Ekind (Id) = E_Enumeration_Literal then return Empty; else Formal := First_Entity (Id); if Present (Formal) and then Is_Formal (Formal) then return Formal; else return Extra_Formals (Id); -- Empty if no extra formals end if; end if; end First_Formal_With_Extras; ------------------------------------- -- Get_Attribute_Definition_Clause -- ------------------------------------- function Get_Attribute_Definition_Clause (E : Entity_Id; Id : Attribute_Id) return Node_Id is N : Node_Id; begin N := First_Rep_Item (E); while Present (N) loop if Nkind (N) = N_Attribute_Definition_Clause and then Get_Attribute_Id (Chars (N)) = Id then return N; else Next_Rep_Item (N); end if; end loop; return Empty; end Get_Attribute_Definition_Clause; ------------------- -- Get_Full_View -- ------------------- function Get_Full_View (T : Entity_Id) return Entity_Id is begin if Ekind (T) = E_Incomplete_Type and then Present (Full_View (T)) then return Full_View (T); elsif Is_Class_Wide_Type (T) and then Ekind (Root_Type (T)) = E_Incomplete_Type and then Present (Full_View (Root_Type (T))) then return Class_Wide_Type (Full_View (Root_Type (T))); else return T; end if; end Get_Full_View; ---------------- -- Get_Pragma -- ---------------- function Get_Pragma (E : Entity_Id; Id : Pragma_Id) return Node_Id is Is_CDG : constant Boolean := Id = Pragma_Abstract_State or else Id = Pragma_Async_Readers or else Id = Pragma_Async_Writers or else Id = Pragma_Depends or else Id = Pragma_Effective_Reads or else Id = Pragma_Effective_Writes or else Id = Pragma_Global or else Id = Pragma_Initial_Condition or else Id = Pragma_Initializes or else Id = Pragma_Part_Of or else Id = Pragma_Refined_Depends or else Id = Pragma_Refined_Global or else Id = Pragma_Refined_State; Is_CTC : constant Boolean := Id = Pragma_Contract_Cases or else Id = Pragma_Test_Case; Is_PPC : constant Boolean := Id = Pragma_Precondition or else Id = Pragma_Postcondition or else Id = Pragma_Refined_Post; In_Contract : constant Boolean := Is_CDG or Is_CTC or Is_PPC; Item : Node_Id; Items : Node_Id; begin -- Handle pragmas that appear in N_Contract nodes. Those have to be -- extracted from their specialized list. if In_Contract then Items := Contract (E); if No (Items) then return Empty; elsif Is_CDG then Item := Classifications (Items); elsif Is_CTC then Item := Contract_Test_Cases (Items); else Item := Pre_Post_Conditions (Items); end if; -- Regular pragmas else Item := First_Rep_Item (E); end if; while Present (Item) loop if Nkind (Item) = N_Pragma and then Get_Pragma_Id (Pragma_Name (Item)) = Id then return Item; -- All nodes in N_Contract are chained using Next_Pragma elsif In_Contract then Item := Next_Pragma (Item); -- Regular pragmas else Next_Rep_Item (Item); end if; end loop; return Empty; end Get_Pragma; -------------------------------------- -- Get_Record_Representation_Clause -- -------------------------------------- function Get_Record_Representation_Clause (E : Entity_Id) return Node_Id is N : Node_Id; begin N := First_Rep_Item (E); while Present (N) loop if Nkind (N) = N_Record_Representation_Clause then return N; end if; Next_Rep_Item (N); end loop; return Empty; end Get_Record_Representation_Clause; ------------------------ -- Has_Attach_Handler -- ------------------------ function Has_Attach_Handler (Id : E) return B is Ritem : Node_Id; begin pragma Assert (Is_Protected_Type (Id)); Ritem := First_Rep_Item (Id); while Present (Ritem) loop if Nkind (Ritem) = N_Pragma and then Pragma_Name (Ritem) = Name_Attach_Handler then return True; else Next_Rep_Item (Ritem); end if; end loop; return False; end Has_Attach_Handler; ----------------- -- Has_Entries -- ----------------- function Has_Entries (Id : E) return B is Ent : Entity_Id; begin pragma Assert (Is_Concurrent_Type (Id)); Ent := First_Entity (Id); while Present (Ent) loop if Is_Entry (Ent) then return True; end if; Ent := Next_Entity (Ent); end loop; return False; end Has_Entries; ---------------------------- -- Has_Foreign_Convention -- ---------------------------- function Has_Foreign_Convention (Id : E) return B is begin -- While regular Intrinsics such as the Standard operators fit in the -- "Ada" convention, those with an Interface_Name materialize GCC -- builtin imports for which Ada special treatments shouldn't apply. return Convention (Id) in Foreign_Convention or else (Convention (Id) = Convention_Intrinsic and then Present (Interface_Name (Id))); end Has_Foreign_Convention; --------------------------- -- Has_Interrupt_Handler -- --------------------------- function Has_Interrupt_Handler (Id : E) return B is Ritem : Node_Id; begin pragma Assert (Is_Protected_Type (Id)); Ritem := First_Rep_Item (Id); while Present (Ritem) loop if Nkind (Ritem) = N_Pragma and then Pragma_Name (Ritem) = Name_Interrupt_Handler then return True; else Next_Rep_Item (Ritem); end if; end loop; return False; end Has_Interrupt_Handler; ----------------------------- -- Has_Non_Null_Refinement -- ----------------------------- function Has_Non_Null_Refinement (Id : E) return B is begin -- "Refinement" is a concept applicable only to abstract states pragma Assert (Ekind (Id) = E_Abstract_State); if Has_Visible_Refinement (Id) then pragma Assert (Present (Refinement_Constituents (Id))); -- For a refinement to be non-null, the first constituent must be -- anything other than null. return Nkind (Node (First_Elmt (Refinement_Constituents (Id)))) /= N_Null; end if; return False; end Has_Non_Null_Refinement; ----------------------------- -- Has_Null_Abstract_State -- ----------------------------- function Has_Null_Abstract_State (Id : E) return B is begin pragma Assert (Ekind_In (Id, E_Generic_Package, E_Package)); return Present (Abstract_States (Id)) and then Is_Null_State (Node (First_Elmt (Abstract_States (Id)))); end Has_Null_Abstract_State; ------------------------- -- Has_Null_Refinement -- ------------------------- function Has_Null_Refinement (Id : E) return B is begin -- "Refinement" is a concept applicable only to abstract states pragma Assert (Ekind (Id) = E_Abstract_State); if Has_Visible_Refinement (Id) then pragma Assert (Present (Refinement_Constituents (Id))); -- For a refinement to be null, the state's sole constituent must be -- a null. return Nkind (Node (First_Elmt (Refinement_Constituents (Id)))) = N_Null; end if; return False; end Has_Null_Refinement; -------------------- -- Has_Unmodified -- -------------------- function Has_Unmodified (E : Entity_Id) return Boolean is begin if Has_Pragma_Unmodified (E) then return True; elsif Warnings_Off (E) then Set_Warnings_Off_Used_Unmodified (E); return True; else return False; end if; end Has_Unmodified; --------------------- -- Has_Unreferenced -- --------------------- function Has_Unreferenced (E : Entity_Id) return Boolean is begin if Has_Pragma_Unreferenced (E) then return True; elsif Warnings_Off (E) then Set_Warnings_Off_Used_Unreferenced (E); return True; else return False; end if; end Has_Unreferenced; ---------------------- -- Has_Warnings_Off -- ---------------------- function Has_Warnings_Off (E : Entity_Id) return Boolean is begin if Warnings_Off (E) then Set_Warnings_Off_Used (E); return True; else return False; end if; end Has_Warnings_Off; ------------------------------ -- Implementation_Base_Type -- ------------------------------ function Implementation_Base_Type (Id : E) return E is Bastyp : Entity_Id; Imptyp : Entity_Id; begin Bastyp := Base_Type (Id); if Is_Incomplete_Or_Private_Type (Bastyp) then Imptyp := Underlying_Type (Bastyp); -- If we have an implementation type, then just return it, -- otherwise we return the Base_Type anyway. This can only -- happen in error situations and should avoid some error bombs. if Present (Imptyp) then return Base_Type (Imptyp); else return Bastyp; end if; else return Bastyp; end if; end Implementation_Base_Type; ------------------------- -- Invariant_Procedure -- ------------------------- function Invariant_Procedure (Id : E) return E is S : Entity_Id; begin pragma Assert (Is_Type (Id) and then Has_Invariants (Id)); if No (Subprograms_For_Type (Id)) then return Empty; else S := Subprograms_For_Type (Id); while Present (S) loop if Is_Invariant_Procedure (S) then return S; else S := Subprograms_For_Type (S); end if; end loop; return Empty; end if; end Invariant_Procedure; ------------------ -- Is_Base_Type -- ------------------ -- Global flag table allowing rapid computation of this function Entity_Is_Base_Type : constant array (Entity_Kind) of Boolean := (E_Enumeration_Subtype | E_Incomplete_Type | E_Signed_Integer_Subtype | E_Modular_Integer_Subtype | E_Floating_Point_Subtype | E_Ordinary_Fixed_Point_Subtype | E_Decimal_Fixed_Point_Subtype | E_Array_Subtype | E_String_Subtype | E_Record_Subtype | E_Private_Subtype | E_Record_Subtype_With_Private | E_Limited_Private_Subtype | E_Access_Subtype | E_Protected_Subtype | E_Task_Subtype | E_String_Literal_Subtype | E_Class_Wide_Subtype => False, others => True); function Is_Base_Type (Id : E) return Boolean is begin return Entity_Is_Base_Type (Ekind (Id)); end Is_Base_Type; --------------------- -- Is_Boolean_Type -- --------------------- function Is_Boolean_Type (Id : E) return B is begin return Root_Type (Id) = Standard_Boolean; end Is_Boolean_Type; ------------------------ -- Is_Constant_Object -- ------------------------ function Is_Constant_Object (Id : E) return B is K : constant Entity_Kind := Ekind (Id); begin return K = E_Constant or else K = E_In_Parameter or else K = E_Loop_Parameter; end Is_Constant_Object; -------------------- -- Is_Discriminal -- -------------------- function Is_Discriminal (Id : E) return B is begin return (Ekind_In (Id, E_Constant, E_In_Parameter) and then Present (Discriminal_Link (Id))); end Is_Discriminal; ---------------------- -- Is_Dynamic_Scope -- ---------------------- function Is_Dynamic_Scope (Id : E) return B is begin return Ekind (Id) = E_Block or else Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure or else Ekind (Id) = E_Subprogram_Body or else Ekind (Id) = E_Task_Type or else (Ekind (Id) = E_Limited_Private_Type and then Present (Full_View (Id)) and then Ekind (Full_View (Id)) = E_Task_Type) or else Ekind (Id) = E_Entry or else Ekind (Id) = E_Entry_Family or else Ekind (Id) = E_Return_Statement; end Is_Dynamic_Scope; -------------------- -- Is_Entity_Name -- -------------------- function Is_Entity_Name (N : Node_Id) return Boolean is Kind : constant Node_Kind := Nkind (N); begin -- Identifiers, operator symbols, expanded names are entity names return Kind = N_Identifier or else Kind = N_Operator_Symbol or else Kind = N_Expanded_Name -- Attribute references are entity names if they refer to an entity. -- Note that we don't do this by testing for the presence of the -- Entity field in the N_Attribute_Reference node, since it may not -- have been set yet. or else (Kind = N_Attribute_Reference and then Is_Entity_Attribute_Name (Attribute_Name (N))); end Is_Entity_Name; ----------------------- -- Is_External_State -- ----------------------- function Is_External_State (Id : E) return B is begin return Ekind (Id) = E_Abstract_State and then Has_Option (Id, Name_External); end Is_External_State; ------------------ -- Is_Finalizer -- ------------------ function Is_Finalizer (Id : E) return B is begin return Ekind (Id) = E_Procedure and then Chars (Id) = Name_uFinalizer; end Is_Finalizer; --------------------- -- Is_Ghost_Entity -- --------------------- -- Note: coding below allows for ghost variables. They are not currently -- implemented, so we will always get False for variables, but that is -- expected to change in the future. function Is_Ghost_Entity (Id : E) return B is begin if Present (Id) and then Ekind (Id) = E_Variable then return Convention (Id) = Convention_Ghost; else return Is_Ghost_Subprogram (Id); end if; end Is_Ghost_Entity; ------------------------- -- Is_Ghost_Subprogram -- ------------------------- function Is_Ghost_Subprogram (Id : E) return B is begin if Present (Id) and then Ekind_In (Id, E_Function, E_Procedure) then return Convention (Id) = Convention_Ghost; else return False; end if; end Is_Ghost_Subprogram; ------------------- -- Is_Null_State -- ------------------- function Is_Null_State (Id : E) return B is begin return Ekind (Id) = E_Abstract_State and then Nkind (Parent (Id)) = N_Null; end Is_Null_State; --------------------- -- Is_Packed_Array -- --------------------- function Is_Packed_Array (Id : E) return B is begin return Is_Array_Type (Id) and then Is_Packed (Id); end Is_Packed_Array; ----------------------------------- -- Is_Package_Or_Generic_Package -- ----------------------------------- function Is_Package_Or_Generic_Package (Id : E) return B is begin return Ekind_In (Id, E_Generic_Package, E_Package); end Is_Package_Or_Generic_Package; --------------- -- Is_Prival -- --------------- function Is_Prival (Id : E) return B is begin return (Ekind_In (Id, E_Constant, E_Variable) and then Present (Prival_Link (Id))); end Is_Prival; ---------------------------- -- Is_Protected_Component -- ---------------------------- function Is_Protected_Component (Id : E) return B is begin return Ekind (Id) = E_Component and then Is_Protected_Type (Scope (Id)); end Is_Protected_Component; ---------------------------- -- Is_Protected_Interface -- ---------------------------- function Is_Protected_Interface (Id : E) return B is Typ : constant Entity_Id := Base_Type (Id); begin if not Is_Interface (Typ) then return False; elsif Is_Class_Wide_Type (Typ) then return Is_Protected_Interface (Etype (Typ)); else return Protected_Present (Type_Definition (Parent (Typ))); end if; end Is_Protected_Interface; ------------------------------ -- Is_Protected_Record_Type -- ------------------------------ function Is_Protected_Record_Type (Id : E) return B is begin return Is_Concurrent_Record_Type (Id) and then Is_Protected_Type (Corresponding_Concurrent_Type (Id)); end Is_Protected_Record_Type; -------------------------------- -- Is_Standard_Character_Type -- -------------------------------- function Is_Standard_Character_Type (Id : E) return B is begin if Is_Type (Id) then declare R : constant Entity_Id := Root_Type (Id); begin return R = Standard_Character or else R = Standard_Wide_Character or else R = Standard_Wide_Wide_Character; end; else return False; end if; end Is_Standard_Character_Type; -------------------- -- Is_String_Type -- -------------------- function Is_String_Type (Id : E) return B is begin return Is_Array_Type (Id) and then Id /= Any_Composite and then Number_Dimensions (Id) = 1 and then Is_Character_Type (Component_Type (Id)); end Is_String_Type; ------------------------------- -- Is_Synchronized_Interface -- ------------------------------- function Is_Synchronized_Interface (Id : E) return B is Typ : constant Entity_Id := Base_Type (Id); begin if not Is_Interface (Typ) then return False; elsif Is_Class_Wide_Type (Typ) then return Is_Synchronized_Interface (Etype (Typ)); else return Protected_Present (Type_Definition (Parent (Typ))) or else Synchronized_Present (Type_Definition (Parent (Typ))) or else Task_Present (Type_Definition (Parent (Typ))); end if; end Is_Synchronized_Interface; ----------------------- -- Is_Task_Interface -- ----------------------- function Is_Task_Interface (Id : E) return B is Typ : constant Entity_Id := Base_Type (Id); begin if not Is_Interface (Typ) then return False; elsif Is_Class_Wide_Type (Typ) then return Is_Task_Interface (Etype (Typ)); else return Task_Present (Type_Definition (Parent (Typ))); end if; end Is_Task_Interface; ------------------------- -- Is_Task_Record_Type -- ------------------------- function Is_Task_Record_Type (Id : E) return B is begin return Is_Concurrent_Record_Type (Id) and then Is_Task_Type (Corresponding_Concurrent_Type (Id)); end Is_Task_Record_Type; ------------------------ -- Is_Wrapper_Package -- ------------------------ function Is_Wrapper_Package (Id : E) return B is begin return (Ekind (Id) = E_Package and then Present (Related_Instance (Id))); end Is_Wrapper_Package; ----------------- -- Last_Formal -- ----------------- function Last_Formal (Id : E) return E is Formal : E; begin pragma Assert (Is_Overloadable (Id) or else Ekind_In (Id, E_Entry_Family, E_Subprogram_Body, E_Subprogram_Type)); if Ekind (Id) = E_Enumeration_Literal then return Empty; else Formal := First_Formal (Id); if Present (Formal) then while Present (Next_Formal (Formal)) loop Formal := Next_Formal (Formal); end loop; end if; return Formal; end if; end Last_Formal; function Model_Emin_Value (Id : E) return Uint is begin return Machine_Emin_Value (Id); end Model_Emin_Value; ------------------------- -- Model_Epsilon_Value -- ------------------------- function Model_Epsilon_Value (Id : E) return Ureal is Radix : constant Ureal := UR_From_Uint (Machine_Radix_Value (Id)); begin return Radix ** (1 - Model_Mantissa_Value (Id)); end Model_Epsilon_Value; -------------------------- -- Model_Mantissa_Value -- -------------------------- function Model_Mantissa_Value (Id : E) return Uint is begin return Machine_Mantissa_Value (Id); end Model_Mantissa_Value; ----------------------- -- Model_Small_Value -- ----------------------- function Model_Small_Value (Id : E) return Ureal is Radix : constant Ureal := UR_From_Uint (Machine_Radix_Value (Id)); begin return Radix ** (Model_Emin_Value (Id) - 1); end Model_Small_Value; ------------------------ -- Machine_Emax_Value -- ------------------------ function Machine_Emax_Value (Id : E) return Uint is Digs : constant Pos := UI_To_Int (Digits_Value (Base_Type (Id))); begin case Float_Rep (Id) is when IEEE_Binary => case Digs is when 1 .. 6 => return Uint_128; when 7 .. 15 => return 2**10; when 16 .. 33 => return 2**14; when others => return No_Uint; end case; when VAX_Native => case Digs is when 1 .. 9 => return 2**7 - 1; when 10 .. 15 => return 2**10 - 1; when others => return No_Uint; end case; when AAMP => return Uint_2 ** Uint_7 - Uint_1; end case; end Machine_Emax_Value; ------------------------ -- Machine_Emin_Value -- ------------------------ function Machine_Emin_Value (Id : E) return Uint is begin case Float_Rep (Id) is when IEEE_Binary => return Uint_3 - Machine_Emax_Value (Id); when VAX_Native => return -Machine_Emax_Value (Id); when AAMP => return -Machine_Emax_Value (Id); end case; end Machine_Emin_Value; ---------------------------- -- Machine_Mantissa_Value -- ---------------------------- function Machine_Mantissa_Value (Id : E) return Uint is Digs : constant Pos := UI_To_Int (Digits_Value (Base_Type (Id))); begin case Float_Rep (Id) is when IEEE_Binary => case Digs is when 1 .. 6 => return Uint_24; when 7 .. 15 => return UI_From_Int (53); when 16 .. 18 => return Uint_64; when 19 .. 33 => return UI_From_Int (113); when others => return No_Uint; end case; when VAX_Native => case Digs is when 1 .. 6 => return Uint_24; when 7 .. 9 => return UI_From_Int (56); when 10 .. 15 => return UI_From_Int (53); when others => return No_Uint; end case; when AAMP => case Digs is when 1 .. 6 => return Uint_24; when 7 .. 9 => return UI_From_Int (40); when others => return No_Uint; end case; end case; end Machine_Mantissa_Value; ------------------------- -- Machine_Radix_Value -- ------------------------- function Machine_Radix_Value (Id : E) return U is begin case Float_Rep (Id) is when IEEE_Binary | VAX_Native | AAMP => return Uint_2; end case; end Machine_Radix_Value; -------------------- -- Next_Component -- -------------------- function Next_Component (Id : E) return E is Comp_Id : E; begin Comp_Id := Next_Entity (Id); while Present (Comp_Id) loop exit when Ekind (Comp_Id) = E_Component; Comp_Id := Next_Entity (Comp_Id); end loop; return Comp_Id; end Next_Component; ------------------------------------ -- Next_Component_Or_Discriminant -- ------------------------------------ function Next_Component_Or_Discriminant (Id : E) return E is Comp_Id : E; begin Comp_Id := Next_Entity (Id); while Present (Comp_Id) loop exit when Ekind_In (Comp_Id, E_Component, E_Discriminant); Comp_Id := Next_Entity (Comp_Id); end loop; return Comp_Id; end Next_Component_Or_Discriminant; ----------------------- -- Next_Discriminant -- ----------------------- -- This function actually implements both Next_Discriminant and -- Next_Stored_Discriminant by making sure that the Discriminant -- returned is of the same variety as Id. function Next_Discriminant (Id : E) return E is -- Derived Tagged types with private extensions look like this... -- E_Discriminant d1 -- E_Discriminant d2 -- E_Component _tag -- E_Discriminant d1 -- E_Discriminant d2 -- ... -- so it is critical not to go past the leading discriminants D : E := Id; begin pragma Assert (Ekind (Id) = E_Discriminant); loop D := Next_Entity (D); if No (D) or else (Ekind (D) /= E_Discriminant and then not Is_Itype (D)) then return Empty; end if; exit when Ekind (D) = E_Discriminant and then (Is_Completely_Hidden (D) = Is_Completely_Hidden (Id)); end loop; return D; end Next_Discriminant; ----------------- -- Next_Formal -- ----------------- function Next_Formal (Id : E) return E is P : E; begin -- Follow the chain of declared entities as long as the kind of the -- entity corresponds to a formal parameter. Skip internal entities -- that may have been created for implicit subtypes, in the process -- of analyzing default expressions. P := Id; loop P := Next_Entity (P); if No (P) or else Is_Formal (P) then return P; elsif not Is_Internal (P) then return Empty; end if; end loop; end Next_Formal; ----------------------------- -- Next_Formal_With_Extras -- ----------------------------- function Next_Formal_With_Extras (Id : E) return E is begin if Present (Extra_Formal (Id)) then return Extra_Formal (Id); else return Next_Formal (Id); end if; end Next_Formal_With_Extras; ---------------- -- Next_Index -- ---------------- function Next_Index (Id : Node_Id) return Node_Id is begin return Next (Id); end Next_Index; ------------------ -- Next_Literal -- ------------------ function Next_Literal (Id : E) return E is begin pragma Assert (Nkind (Id) in N_Entity); return Next (Id); end Next_Literal; ------------------------------ -- Next_Stored_Discriminant -- ------------------------------ function Next_Stored_Discriminant (Id : E) return E is begin -- See comment in Next_Discriminant return Next_Discriminant (Id); end Next_Stored_Discriminant; ----------------------- -- Number_Dimensions -- ----------------------- function Number_Dimensions (Id : E) return Pos is N : Int; T : Node_Id; begin if Ekind (Id) = E_String_Literal_Subtype then return 1; else N := 0; T := First_Index (Id); while Present (T) loop N := N + 1; Next_Index (T); end loop; return N; end if; end Number_Dimensions; -------------------- -- Number_Entries -- -------------------- function Number_Entries (Id : E) return Nat is N : Int; Ent : Entity_Id; begin pragma Assert (Is_Concurrent_Type (Id)); N := 0; Ent := First_Entity (Id); while Present (Ent) loop if Is_Entry (Ent) then N := N + 1; end if; Ent := Next_Entity (Ent); end loop; return N; end Number_Entries; -------------------- -- Number_Formals -- -------------------- function Number_Formals (Id : E) return Pos is N : Int; Formal : Entity_Id; begin N := 0; Formal := First_Formal (Id); while Present (Formal) loop N := N + 1; Formal := Next_Formal (Formal); end loop; return N; end Number_Formals; -------------------- -- Parameter_Mode -- -------------------- function Parameter_Mode (Id : E) return Formal_Kind is begin return Ekind (Id); end Parameter_Mode; ------------------------ -- Predicate_Function -- ------------------------ function Predicate_Function (Id : E) return E is S : Entity_Id; T : Entity_Id; begin pragma Assert (Is_Type (Id)); -- If type is private and has a completion, predicate may be defined -- on the full view. if Is_Private_Type (Id) and then Present (Full_View (Id)) then T := Full_View (Id); else T := Id; end if; if No (Subprograms_For_Type (T)) then return Empty; else S := Subprograms_For_Type (T); while Present (S) loop if Is_Predicate_Function (S) then return S; else S := Subprograms_For_Type (S); end if; end loop; return Empty; end if; end Predicate_Function; -------------------------- -- Predicate_Function_M -- -------------------------- function Predicate_Function_M (Id : E) return E is S : Entity_Id; T : Entity_Id; begin pragma Assert (Is_Type (Id)); -- If type is private and has a completion, predicate may be defined -- on the full view. if Is_Private_Type (Id) and then Present (Full_View (Id)) then T := Full_View (Id); else T := Id; end if; if No (Subprograms_For_Type (T)) then return Empty; else S := Subprograms_For_Type (T); while Present (S) loop if Is_Predicate_Function_M (S) then return S; else S := Subprograms_For_Type (S); end if; end loop; return Empty; end if; end Predicate_Function_M; ------------------------- -- Present_In_Rep_Item -- ------------------------- function Present_In_Rep_Item (E : Entity_Id; N : Node_Id) return Boolean is Ritem : Node_Id; begin Ritem := First_Rep_Item (E); while Present (Ritem) loop if Ritem = N then return True; end if; Next_Rep_Item (Ritem); end loop; return False; end Present_In_Rep_Item; -------------------------- -- Primitive_Operations -- -------------------------- function Primitive_Operations (Id : E) return L is begin if Is_Concurrent_Type (Id) then if Present (Corresponding_Record_Type (Id)) then return Direct_Primitive_Operations (Corresponding_Record_Type (Id)); -- If expansion is disabled the corresponding record type is absent, -- but if the type has ancestors it may have primitive operations. elsif Is_Tagged_Type (Id) then return Direct_Primitive_Operations (Id); else return No_Elist; end if; else return Direct_Primitive_Operations (Id); end if; end Primitive_Operations; --------------------- -- Record_Rep_Item -- --------------------- procedure Record_Rep_Item (E : Entity_Id; N : Node_Id) is begin Set_Next_Rep_Item (N, First_Rep_Item (E)); Set_First_Rep_Item (E, N); end Record_Rep_Item; --------------- -- Root_Type -- --------------- function Root_Type (Id : E) return E is T, Etyp : E; begin pragma Assert (Nkind (Id) in N_Entity); T := Base_Type (Id); if Ekind (T) = E_Class_Wide_Type then return Etype (T); -- Other cases else loop Etyp := Etype (T); if T = Etyp then return T; -- Following test catches some error cases resulting from -- previous errors. elsif No (Etyp) then Check_Error_Detected; return T; elsif Is_Private_Type (T) and then Etyp = Full_View (T) then return T; elsif Is_Private_Type (Etyp) and then Full_View (Etyp) = T then return T; end if; T := Etyp; -- Return if there is a circularity in the inheritance chain. This -- happens in some error situations and we do not want to get -- stuck in this loop. if T = Base_Type (Id) then return T; end if; end loop; end if; end Root_Type; --------------------- -- Safe_Emax_Value -- --------------------- function Safe_Emax_Value (Id : E) return Uint is begin return Machine_Emax_Value (Id); end Safe_Emax_Value; ---------------------- -- Safe_First_Value -- ---------------------- function Safe_First_Value (Id : E) return Ureal is begin return -Safe_Last_Value (Id); end Safe_First_Value; --------------------- -- Safe_Last_Value -- --------------------- function Safe_Last_Value (Id : E) return Ureal is Radix : constant Uint := Machine_Radix_Value (Id); Mantissa : constant Uint := Machine_Mantissa_Value (Id); Emax : constant Uint := Safe_Emax_Value (Id); Significand : constant Uint := Radix ** Mantissa - 1; Exponent : constant Uint := Emax - Mantissa; begin if Radix = 2 then return UR_From_Components (Num => Significand * 2 ** (Exponent mod 4), Den => -Exponent / 4, Rbase => 16); else return UR_From_Components (Num => Significand, Den => -Exponent, Rbase => 16); end if; end Safe_Last_Value; ----------------- -- Scope_Depth -- ----------------- function Scope_Depth (Id : E) return Uint is Scop : Entity_Id; begin Scop := Id; while Is_Record_Type (Scop) loop Scop := Scope (Scop); end loop; return Scope_Depth_Value (Scop); end Scope_Depth; --------------------- -- Scope_Depth_Set -- --------------------- function Scope_Depth_Set (Id : E) return B is begin return not Is_Record_Type (Id) and then Field22 (Id) /= Union_Id (Empty); end Scope_Depth_Set; ----------------------------- -- Set_Component_Alignment -- ----------------------------- -- Component Alignment is encoded using two flags, Flag128/129 as -- follows. Note that both flags False = Align_Default, so that the -- default initialization of flags to False initializes component -- alignment to the default value as required. -- Flag128 Flag129 Value -- ------- ------- ----- -- False False Calign_Default -- False True Calign_Component_Size -- True False Calign_Component_Size_4 -- True True Calign_Storage_Unit procedure Set_Component_Alignment (Id : E; V : C) is begin pragma Assert ((Is_Array_Type (Id) or else Is_Record_Type (Id)) and then Is_Base_Type (Id)); case V is when Calign_Default => Set_Flag128 (Id, False); Set_Flag129 (Id, False); when Calign_Component_Size => Set_Flag128 (Id, False); Set_Flag129 (Id, True); when Calign_Component_Size_4 => Set_Flag128 (Id, True); Set_Flag129 (Id, False); when Calign_Storage_Unit => Set_Flag128 (Id, True); Set_Flag129 (Id, True); end case; end Set_Component_Alignment; ----------------------------- -- Set_Invariant_Procedure -- ----------------------------- procedure Set_Invariant_Procedure (Id : E; V : E) is S : Entity_Id; begin pragma Assert (Is_Type (Id) and then Has_Invariants (Id)); S := Subprograms_For_Type (Id); Set_Subprograms_For_Type (Id, V); Set_Subprograms_For_Type (V, S); -- Check for duplicate entry while Present (S) loop if Is_Invariant_Procedure (S) then raise Program_Error; else S := Subprograms_For_Type (S); end if; end loop; end Set_Invariant_Procedure; ---------------------------- -- Set_Predicate_Function -- ---------------------------- procedure Set_Predicate_Function (Id : E; V : E) is S : Entity_Id; begin pragma Assert (Is_Type (Id) and then Has_Predicates (Id)); S := Subprograms_For_Type (Id); Set_Subprograms_For_Type (Id, V); Set_Subprograms_For_Type (V, S); while Present (S) loop if Is_Predicate_Function (S) then raise Program_Error; else S := Subprograms_For_Type (S); end if; end loop; end Set_Predicate_Function; ------------------------------ -- Set_Predicate_Function_M -- ------------------------------ procedure Set_Predicate_Function_M (Id : E; V : E) is S : Entity_Id; begin pragma Assert (Is_Type (Id) and then Has_Predicates (Id)); S := Subprograms_For_Type (Id); Set_Subprograms_For_Type (Id, V); Set_Subprograms_For_Type (V, S); -- Check for duplicates while Present (S) loop if Is_Predicate_Function_M (S) then raise Program_Error; else S := Subprograms_For_Type (S); end if; end loop; end Set_Predicate_Function_M; ----------------- -- Size_Clause -- ----------------- function Size_Clause (Id : E) return N is begin return Get_Attribute_Definition_Clause (Id, Attribute_Size); end Size_Clause; ------------------------ -- Stream_Size_Clause -- ------------------------ function Stream_Size_Clause (Id : E) return N is begin return Get_Attribute_Definition_Clause (Id, Attribute_Stream_Size); end Stream_Size_Clause; ------------------ -- Subtype_Kind -- ------------------ function Subtype_Kind (K : Entity_Kind) return Entity_Kind is Kind : Entity_Kind; begin case K is when Access_Kind => Kind := E_Access_Subtype; when E_Array_Type | E_Array_Subtype => Kind := E_Array_Subtype; when E_Class_Wide_Type | E_Class_Wide_Subtype => Kind := E_Class_Wide_Subtype; when E_Decimal_Fixed_Point_Type | E_Decimal_Fixed_Point_Subtype => Kind := E_Decimal_Fixed_Point_Subtype; when E_Ordinary_Fixed_Point_Type | E_Ordinary_Fixed_Point_Subtype => Kind := E_Ordinary_Fixed_Point_Subtype; when E_Private_Type | E_Private_Subtype => Kind := E_Private_Subtype; when E_Limited_Private_Type | E_Limited_Private_Subtype => Kind := E_Limited_Private_Subtype; when E_Record_Type_With_Private | E_Record_Subtype_With_Private => Kind := E_Record_Subtype_With_Private; when E_Record_Type | E_Record_Subtype => Kind := E_Record_Subtype; when Enumeration_Kind => Kind := E_Enumeration_Subtype; when Float_Kind => Kind := E_Floating_Point_Subtype; when Signed_Integer_Kind => Kind := E_Signed_Integer_Subtype; when Modular_Integer_Kind => Kind := E_Modular_Integer_Subtype; when Protected_Kind => Kind := E_Protected_Subtype; when Task_Kind => Kind := E_Task_Subtype; when others => Kind := E_Void; raise Program_Error; end case; return Kind; end Subtype_Kind; --------------------- -- Type_High_Bound -- --------------------- function Type_High_Bound (Id : E) return Node_Id is Rng : constant Node_Id := Scalar_Range (Id); begin if Nkind (Rng) = N_Subtype_Indication then return High_Bound (Range_Expression (Constraint (Rng))); else return High_Bound (Rng); end if; end Type_High_Bound; -------------------- -- Type_Low_Bound -- -------------------- function Type_Low_Bound (Id : E) return Node_Id is Rng : constant Node_Id := Scalar_Range (Id); begin if Nkind (Rng) = N_Subtype_Indication then return Low_Bound (Range_Expression (Constraint (Rng))); else return Low_Bound (Rng); end if; end Type_Low_Bound; --------------------- -- Underlying_Type -- --------------------- function Underlying_Type (Id : E) return E is begin -- For record_with_private the underlying type is always the direct -- full view. Never try to take the full view of the parent it -- doesn't make sense. if Ekind (Id) = E_Record_Type_With_Private then return Full_View (Id); elsif Ekind (Id) in Incomplete_Or_Private_Kind then -- If we have an incomplete or private type with a full view, -- then we return the Underlying_Type of this full view if Present (Full_View (Id)) then if Id = Full_View (Id) then -- Previous error in declaration return Empty; else return Underlying_Type (Full_View (Id)); end if; -- If we have an incomplete entity that comes from the limited -- view then we return the Underlying_Type of its non-limited -- view. elsif From_Limited_With (Id) and then Present (Non_Limited_View (Id)) then return Underlying_Type (Non_Limited_View (Id)); -- Otherwise check for the case where we have a derived type or -- subtype, and if so get the Underlying_Type of the parent type. elsif Etype (Id) /= Id then return Underlying_Type (Etype (Id)); -- Otherwise we have an incomplete or private type that has -- no full view, which means that we have not encountered the -- completion, so return Empty to indicate the underlying type -- is not yet known. else return Empty; end if; -- For non-incomplete, non-private types, return the type itself -- Also for entities that are not types at all return the entity -- itself. else return Id; end if; end Underlying_Type; --------------- -- Vax_Float -- --------------- function Vax_Float (Id : E) return B is begin return Is_Floating_Point_Type (Id) and then Float_Rep (Id) = VAX_Native; end Vax_Float; ------------------------ -- Write_Entity_Flags -- ------------------------ procedure Write_Entity_Flags (Id : Entity_Id; Prefix : String) is procedure W (Flag_Name : String; Flag : Boolean); -- Write out given flag if it is set ------- -- W -- ------- procedure W (Flag_Name : String; Flag : Boolean) is begin if Flag then Write_Str (Prefix); Write_Str (Flag_Name); Write_Str (" = True"); Write_Eol; end if; end W; -- Start of processing for Write_Entity_Flags begin if (Is_Array_Type (Id) or else Is_Record_Type (Id)) and then Is_Base_Type (Id) then Write_Str (Prefix); Write_Str ("Component_Alignment = "); case Component_Alignment (Id) is when Calign_Default => Write_Str ("Calign_Default"); when Calign_Component_Size => Write_Str ("Calign_Component_Size"); when Calign_Component_Size_4 => Write_Str ("Calign_Component_Size_4"); when Calign_Storage_Unit => Write_Str ("Calign_Storage_Unit"); end case; Write_Eol; end if; W ("Address_Taken", Flag104 (Id)); W ("Body_Needed_For_SAL", Flag40 (Id)); W ("C_Pass_By_Copy", Flag125 (Id)); W ("Can_Never_Be_Null", Flag38 (Id)); W ("Checks_May_Be_Suppressed", Flag31 (Id)); W ("Debug_Info_Off", Flag166 (Id)); W ("Default_Expressions_Processed", Flag108 (Id)); W ("Delay_Cleanups", Flag114 (Id)); W ("Delay_Subprogram_Descriptors", Flag50 (Id)); W ("Depends_On_Private", Flag14 (Id)); W ("Discard_Names", Flag88 (Id)); W ("Elaboration_Entity_Required", Flag174 (Id)); W ("Elaborate_Body_Desirable", Flag210 (Id)); W ("Entry_Accepted", Flag152 (Id)); W ("Can_Use_Internal_Rep", Flag229 (Id)); W ("Finalize_Storage_Only", Flag158 (Id)); W ("From_Limited_With", Flag159 (Id)); W ("Has_Aliased_Components", Flag135 (Id)); W ("Has_Alignment_Clause", Flag46 (Id)); W ("Has_All_Calls_Remote", Flag79 (Id)); W ("Has_Anonymous_Master", Flag253 (Id)); W ("Has_Atomic_Components", Flag86 (Id)); W ("Has_Biased_Representation", Flag139 (Id)); W ("Has_Completion", Flag26 (Id)); W ("Has_Completion_In_Body", Flag71 (Id)); W ("Has_Complex_Representation", Flag140 (Id)); W ("Has_Component_Size_Clause", Flag68 (Id)); W ("Has_Contiguous_Rep", Flag181 (Id)); W ("Has_Controlled_Component", Flag43 (Id)); W ("Has_Controlling_Result", Flag98 (Id)); W ("Has_Convention_Pragma", Flag119 (Id)); W ("Has_Default_Aspect", Flag39 (Id)); W ("Has_Delayed_Aspects", Flag200 (Id)); W ("Has_Delayed_Freeze", Flag18 (Id)); W ("Has_Delayed_Rep_Aspects", Flag261 (Id)); W ("Has_Discriminants", Flag5 (Id)); W ("Has_Dispatch_Table", Flag220 (Id)); W ("Has_Dynamic_Predicate_Aspect", Flag258 (Id)); W ("Has_Enumeration_Rep_Clause", Flag66 (Id)); W ("Has_Exit", Flag47 (Id)); W ("Has_Forward_Instantiation", Flag175 (Id)); W ("Has_Fully_Qualified_Name", Flag173 (Id)); W ("Has_Gigi_Rep_Item", Flag82 (Id)); W ("Has_Homonym", Flag56 (Id)); W ("Has_Implicit_Dereference", Flag251 (Id)); W ("Has_Independent_Components", Flag34 (Id)); W ("Has_Inheritable_Invariants", Flag248 (Id)); W ("Has_Initial_Value", Flag219 (Id)); W ("Has_Invariants", Flag232 (Id)); W ("Has_Loop_Entry_Attributes", Flag260 (Id)); W ("Has_Machine_Radix_Clause", Flag83 (Id)); W ("Has_Master_Entity", Flag21 (Id)); W ("Has_Missing_Return", Flag142 (Id)); W ("Has_Nested_Block_With_Handler", Flag101 (Id)); W ("Has_Non_Standard_Rep", Flag75 (Id)); W ("Has_Out_Or_In_Out_Parameter", Flag110 (Id)); W ("Has_Object_Size_Clause", Flag172 (Id)); W ("Has_Per_Object_Constraint", Flag154 (Id)); W ("Has_Postconditions", Flag240 (Id)); W ("Has_Pragma_Controlled", Flag27 (Id)); W ("Has_Pragma_Elaborate_Body", Flag150 (Id)); W ("Has_Pragma_Inline", Flag157 (Id)); W ("Has_Pragma_Inline_Always", Flag230 (Id)); W ("Has_Pragma_No_Inline", Flag201 (Id)); W ("Has_Pragma_Ordered", Flag198 (Id)); W ("Has_Pragma_Pack", Flag121 (Id)); W ("Has_Pragma_Preelab_Init", Flag221 (Id)); W ("Has_Pragma_Pure", Flag203 (Id)); W ("Has_Pragma_Pure_Function", Flag179 (Id)); W ("Has_Pragma_Thread_Local_Storage", Flag169 (Id)); W ("Has_Pragma_Unmodified", Flag233 (Id)); W ("Has_Pragma_Unreferenced", Flag180 (Id)); W ("Has_Pragma_Unreferenced_Objects", Flag212 (Id)); W ("Has_Predicates", Flag250 (Id)); W ("Has_Primitive_Operations", Flag120 (Id)); W ("Has_Private_Ancestor", Flag151 (Id)); W ("Has_Private_Declaration", Flag155 (Id)); W ("Has_Protected", Flag271 (Id)); W ("Has_Qualified_Name", Flag161 (Id)); W ("Has_RACW", Flag214 (Id)); W ("Has_Record_Rep_Clause", Flag65 (Id)); W ("Has_Recursive_Call", Flag143 (Id)); W ("Has_Shift_Operator", Flag267 (Id)); W ("Has_Size_Clause", Flag29 (Id)); W ("Has_Small_Clause", Flag67 (Id)); W ("Has_Specified_Layout", Flag100 (Id)); W ("Has_Specified_Stream_Input", Flag190 (Id)); W ("Has_Specified_Stream_Output", Flag191 (Id)); W ("Has_Specified_Stream_Read", Flag192 (Id)); W ("Has_Specified_Stream_Write", Flag193 (Id)); W ("Has_Static_Discriminants", Flag211 (Id)); W ("Has_Static_Predicate", Flag269 (Id)); W ("Has_Static_Predicate_Aspect", Flag259 (Id)); W ("Has_Storage_Size_Clause", Flag23 (Id)); W ("Has_Stream_Size_Clause", Flag184 (Id)); W ("Has_Task", Flag30 (Id)); W ("Has_Thunks", Flag228 (Id)); W ("Has_Unchecked_Union", Flag123 (Id)); W ("Has_Unknown_Discriminants", Flag72 (Id)); W ("Has_Up_Level_Access", Flag215 (Id)); W ("Has_Visible_Refinement", Flag263 (Id)); W ("Has_Volatile_Components", Flag87 (Id)); W ("Has_Xref_Entry", Flag182 (Id)); W ("In_Package_Body", Flag48 (Id)); W ("In_Private_Part", Flag45 (Id)); W ("In_Use", Flag8 (Id)); W ("Is_AST_Entry", Flag132 (Id)); W ("Is_Abstract_Subprogram", Flag19 (Id)); W ("Is_Abstract_Type", Flag146 (Id)); W ("Is_Local_Anonymous_Access", Flag194 (Id)); W ("Is_Access_Constant", Flag69 (Id)); W ("Is_Ada_2005_Only", Flag185 (Id)); W ("Is_Ada_2012_Only", Flag199 (Id)); W ("Is_Aliased", Flag15 (Id)); W ("Is_Asynchronous", Flag81 (Id)); W ("Is_Atomic", Flag85 (Id)); W ("Is_Bit_Packed_Array", Flag122 (Id)); W ("Is_CPP_Class", Flag74 (Id)); W ("Is_Called", Flag102 (Id)); W ("Is_Character_Type", Flag63 (Id)); W ("Is_Child_Unit", Flag73 (Id)); W ("Is_Class_Wide_Equivalent_Type", Flag35 (Id)); W ("Is_Compilation_Unit", Flag149 (Id)); W ("Is_Completely_Hidden", Flag103 (Id)); W ("Is_Concurrent_Record_Type", Flag20 (Id)); W ("Is_Constr_Subt_For_UN_Aliased", Flag141 (Id)); W ("Is_Constr_Subt_For_U_Nominal", Flag80 (Id)); W ("Is_Constrained", Flag12 (Id)); W ("Is_Constructor", Flag76 (Id)); W ("Is_Controlled", Flag42 (Id)); W ("Is_Controlling_Formal", Flag97 (Id)); W ("Is_Descendent_Of_Address", Flag223 (Id)); W ("Is_Discrim_SO_Function", Flag176 (Id)); W ("Is_Discriminant_Check_Function", Flag264 (Id)); W ("Is_Dispatch_Table_Entity", Flag234 (Id)); W ("Is_Dispatching_Operation", Flag6 (Id)); W ("Is_Eliminated", Flag124 (Id)); W ("Is_Entry_Formal", Flag52 (Id)); W ("Is_Exported", Flag99 (Id)); W ("Is_First_Subtype", Flag70 (Id)); W ("Is_For_Access_Subtype", Flag118 (Id)); W ("Is_Formal_Subprogram", Flag111 (Id)); W ("Is_Frozen", Flag4 (Id)); W ("Is_Generic_Actual_Type", Flag94 (Id)); W ("Is_Generic_Instance", Flag130 (Id)); W ("Is_Generic_Type", Flag13 (Id)); W ("Is_Hidden", Flag57 (Id)); W ("Is_Hidden_Open_Scope", Flag171 (Id)); W ("Is_Immediately_Visible", Flag7 (Id)); W ("Is_Implementation_Defined", Flag254 (Id)); W ("Is_Imported", Flag24 (Id)); W ("Is_Independent", Flag268 (Id)); W ("Is_Inlined", Flag11 (Id)); W ("Is_Instantiated", Flag126 (Id)); W ("Is_Interface", Flag186 (Id)); W ("Is_Internal", Flag17 (Id)); W ("Is_Interrupt_Handler", Flag89 (Id)); W ("Is_Intrinsic_Subprogram", Flag64 (Id)); W ("Is_Invariant_Procedure", Flag257 (Id)); W ("Is_Itype", Flag91 (Id)); W ("Is_Known_Non_Null", Flag37 (Id)); W ("Is_Known_Null", Flag204 (Id)); W ("Is_Known_Valid", Flag170 (Id)); W ("Is_Limited_Composite", Flag106 (Id)); W ("Is_Limited_Interface", Flag197 (Id)); W ("Is_Limited_Record", Flag25 (Id)); W ("Is_Machine_Code_Subprogram", Flag137 (Id)); W ("Is_Non_Static_Subtype", Flag109 (Id)); W ("Is_Null_Init_Proc", Flag178 (Id)); W ("Is_Obsolescent", Flag153 (Id)); W ("Is_Only_Out_Parameter", Flag226 (Id)); W ("Is_Optional_Parameter", Flag134 (Id)); W ("Is_Package_Body_Entity", Flag160 (Id)); W ("Is_Packed", Flag51 (Id)); W ("Is_Packed_Array_Impl_Type", Flag138 (Id)); W ("Is_Potentially_Use_Visible", Flag9 (Id)); W ("Is_Predicate_Function", Flag255 (Id)); W ("Is_Predicate_Function_M", Flag256 (Id)); W ("Is_Preelaborated", Flag59 (Id)); W ("Is_Primitive", Flag218 (Id)); W ("Is_Primitive_Wrapper", Flag195 (Id)); W ("Is_Private_Composite", Flag107 (Id)); W ("Is_Private_Descendant", Flag53 (Id)); W ("Is_Private_Primitive", Flag245 (Id)); W ("Is_Processed_Transient", Flag252 (Id)); W ("Is_Public", Flag10 (Id)); W ("Is_Pure", Flag44 (Id)); W ("Is_Pure_Unit_Access_Type", Flag189 (Id)); W ("Is_RACW_Stub_Type", Flag244 (Id)); W ("Is_Raised", Flag224 (Id)); W ("Is_Remote_Call_Interface", Flag62 (Id)); W ("Is_Remote_Types", Flag61 (Id)); W ("Is_Renaming_Of_Object", Flag112 (Id)); W ("Is_Return_Object", Flag209 (Id)); W ("Is_Safe_To_Reevaluate", Flag249 (Id)); W ("Is_Shared_Passive", Flag60 (Id)); W ("Is_Statically_Allocated", Flag28 (Id)); W ("Is_Tag", Flag78 (Id)); W ("Is_Tagged_Type", Flag55 (Id)); W ("Is_Thunk", Flag225 (Id)); W ("Is_Trivial_Subprogram", Flag235 (Id)); W ("Is_True_Constant", Flag163 (Id)); W ("Is_Unchecked_Union", Flag117 (Id)); W ("Is_Underlying_Record_View", Flag246 (Id)); W ("Is_Unsigned_Type", Flag144 (Id)); W ("Is_VMS_Exception", Flag133 (Id)); W ("Is_Valued_Procedure", Flag127 (Id)); W ("Is_Visible_Formal", Flag206 (Id)); W ("Is_Visible_Lib_Unit", Flag116 (Id)); W ("Is_Volatile", Flag16 (Id)); W ("Itype_Printed", Flag202 (Id)); W ("Kill_Elaboration_Checks", Flag32 (Id)); W ("Kill_Range_Checks", Flag33 (Id)); W ("Known_To_Have_Preelab_Init", Flag207 (Id)); W ("Low_Bound_Tested", Flag205 (Id)); W ("Machine_Radix_10", Flag84 (Id)); W ("Materialize_Entity", Flag168 (Id)); W ("May_Inherit_Delayed_Rep_Aspects", Flag262 (Id)); W ("Must_Be_On_Byte_Boundary", Flag183 (Id)); W ("Must_Have_Preelab_Init", Flag208 (Id)); W ("Needs_Debug_Info", Flag147 (Id)); W ("Needs_No_Actuals", Flag22 (Id)); W ("Never_Set_In_Source", Flag115 (Id)); W ("No_Pool_Assigned", Flag131 (Id)); W ("No_Return", Flag113 (Id)); W ("No_Strict_Aliasing", Flag136 (Id)); W ("Non_Binary_Modulus", Flag58 (Id)); W ("Nonzero_Is_True", Flag162 (Id)); W ("OK_To_Rename", Flag247 (Id)); W ("OK_To_Reorder_Components", Flag239 (Id)); W ("Optimize_Alignment_Space", Flag241 (Id)); W ("Optimize_Alignment_Time", Flag242 (Id)); W ("Overlays_Constant", Flag243 (Id)); W ("Reachable", Flag49 (Id)); W ("Referenced", Flag156 (Id)); W ("Referenced_As_LHS", Flag36 (Id)); W ("Referenced_As_Out_Parameter", Flag227 (Id)); W ("Renamed_In_Spec", Flag231 (Id)); W ("Requires_Overriding", Flag213 (Id)); W ("Return_Present", Flag54 (Id)); W ("Returns_By_Ref", Flag90 (Id)); W ("Reverse_Bit_Order", Flag164 (Id)); W ("Reverse_Storage_Order", Flag93 (Id)); W ("Sec_Stack_Needed_For_Return", Flag167 (Id)); W ("Size_Depends_On_Discriminant", Flag177 (Id)); W ("Size_Known_At_Compile_Time", Flag92 (Id)); W ("SPARK_Aux_Pragma_Inherited", Flag266 (Id)); W ("SPARK_Pragma_Inherited", Flag265 (Id)); W ("SSO_Set_High_By_Default", Flag273 (Id)); W ("SSO_Set_Low_By_Default", Flag272 (Id)); W ("Static_Elaboration_Desired", Flag77 (Id)); W ("Stores_Attribute_Old_Prefix", Flag270 (Id)); W ("Strict_Alignment", Flag145 (Id)); W ("Suppress_Elaboration_Warnings", Flag148 (Id)); W ("Suppress_Initialization", Flag105 (Id)); W ("Suppress_Style_Checks", Flag165 (Id)); W ("Suppress_Value_Tracking_On_Call", Flag217 (Id)); W ("Treat_As_Volatile", Flag41 (Id)); W ("Universal_Aliasing", Flag216 (Id)); W ("Used_As_Generic_Actual", Flag222 (Id)); W ("Uses_Sec_Stack", Flag95 (Id)); W ("Warnings_Off", Flag96 (Id)); W ("Warnings_Off_Used", Flag236 (Id)); W ("Warnings_Off_Used_Unmodified", Flag237 (Id)); W ("Warnings_Off_Used_Unreferenced", Flag238 (Id)); W ("Was_Hidden", Flag196 (Id)); end Write_Entity_Flags; ----------------------- -- Write_Entity_Info -- ----------------------- procedure Write_Entity_Info (Id : Entity_Id; Prefix : String) is procedure Write_Attribute (Which : String; Nam : E); -- Write attribute value with given string name procedure Write_Kind (Id : Entity_Id); -- Write Ekind field of entity --------------------- -- Write_Attribute -- --------------------- procedure Write_Attribute (Which : String; Nam : E) is begin Write_Str (Prefix); Write_Str (Which); Write_Int (Int (Nam)); Write_Str (" "); Write_Name (Chars (Nam)); Write_Str (" "); end Write_Attribute; ---------------- -- Write_Kind -- ---------------- procedure Write_Kind (Id : Entity_Id) is K : constant String := Entity_Kind'Image (Ekind (Id)); begin Write_Str (Prefix); Write_Str (" Kind "); if Is_Type (Id) and then Is_Tagged_Type (Id) then Write_Str ("TAGGED "); end if; Write_Str (K (3 .. K'Length)); Write_Str (" "); if Is_Type (Id) and then Depends_On_Private (Id) then Write_Str ("Depends_On_Private "); end if; end Write_Kind; -- Start of processing for Write_Entity_Info begin Write_Eol; Write_Attribute ("Name ", Id); Write_Int (Int (Id)); Write_Eol; Write_Kind (Id); Write_Eol; Write_Attribute (" Type ", Etype (Id)); Write_Eol; Write_Attribute (" Scope ", Scope (Id)); Write_Eol; case Ekind (Id) is when Discrete_Kind => Write_Str ("Bounds: Id = "); if Present (Scalar_Range (Id)) then Write_Int (Int (Type_Low_Bound (Id))); Write_Str (" .. Id = "); Write_Int (Int (Type_High_Bound (Id))); else Write_Str ("Empty"); end if; Write_Eol; when Array_Kind => declare Index : E; begin Write_Attribute (" Component Type ", Component_Type (Id)); Write_Eol; Write_Str (Prefix); Write_Str (" Indexes "); Index := First_Index (Id); while Present (Index) loop Write_Attribute (" ", Etype (Index)); Index := Next_Index (Index); end loop; Write_Eol; end; when Access_Kind => Write_Attribute (" Directly Designated Type ", Directly_Designated_Type (Id)); Write_Eol; when Overloadable_Kind => if Present (Homonym (Id)) then Write_Str (" Homonym "); Write_Name (Chars (Homonym (Id))); Write_Str (" "); Write_Int (Int (Homonym (Id))); Write_Eol; end if; Write_Eol; when E_Component => if Ekind (Scope (Id)) in Record_Kind then Write_Attribute ( " Original_Record_Component ", Original_Record_Component (Id)); Write_Int (Int (Original_Record_Component (Id))); Write_Eol; end if; when others => null; end case; end Write_Entity_Info; ----------------------- -- Write_Field6_Name -- ----------------------- procedure Write_Field6_Name (Id : Entity_Id) is pragma Warnings (Off, Id); begin Write_Str ("First_Rep_Item"); end Write_Field6_Name; ----------------------- -- Write_Field7_Name -- ----------------------- procedure Write_Field7_Name (Id : Entity_Id) is pragma Warnings (Off, Id); begin Write_Str ("Freeze_Node"); end Write_Field7_Name; ----------------------- -- Write_Field8_Name -- ----------------------- procedure Write_Field8_Name (Id : Entity_Id) is begin case Ekind (Id) is when Type_Kind => Write_Str ("Associated_Node_For_Itype"); when E_Package => Write_Str ("Dependent_Instances"); when E_Loop => Write_Str ("First_Exit_Statement"); when E_Variable => Write_Str ("Hiding_Loop_Variable"); when Formal_Kind | E_Function | E_Subprogram_Body => Write_Str ("Mechanism"); when E_Component | E_Discriminant => Write_Str ("Normalized_First_Bit"); when E_Procedure => Write_Str ("Postcondition_Proc"); when E_Abstract_State => Write_Str ("Refinement_Constituents"); when E_Return_Statement => Write_Str ("Return_Applies_To"); when others => Write_Str ("Field8??"); end case; end Write_Field8_Name; ----------------------- -- Write_Field9_Name -- ----------------------- procedure Write_Field9_Name (Id : Entity_Id) is begin case Ekind (Id) is when Type_Kind => Write_Str ("Class_Wide_Type"); when Object_Kind => Write_Str ("Current_Value"); when E_Abstract_State => Write_Str ("Part_Of_Constituents"); when E_Function | E_Generic_Function | E_Generic_Package | E_Generic_Procedure | E_Package | E_Procedure => Write_Str ("Renaming_Map"); when others => Write_Str ("Field9??"); end case; end Write_Field9_Name; ------------------------ -- Write_Field10_Name -- ------------------------ procedure Write_Field10_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Abstract_State | E_Variable => Write_Str ("Encapsulating_State"); when Class_Wide_Kind | Incomplete_Kind | E_Record_Type | E_Record_Subtype | Private_Kind | Concurrent_Kind => Write_Str ("Direct_Primitive_Operations"); when Float_Kind => Write_Str ("Float_Rep"); when E_In_Parameter | E_Constant => Write_Str ("Discriminal_Link"); when E_Function | E_Package | E_Package_Body | E_Procedure => Write_Str ("Handler_Records"); when E_Component | E_Discriminant => Write_Str ("Normalized_Position_Max"); when others => Write_Str ("Field10??"); end case; end Write_Field10_Name; ------------------------ -- Write_Field11_Name -- ------------------------ procedure Write_Field11_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Block => Write_Str ("Block_Node"); when E_Component | E_Discriminant => Write_Str ("Component_Bit_Offset"); when Formal_Kind => Write_Str ("Entry_Component"); when E_Enumeration_Literal => Write_Str ("Enumeration_Pos"); when Type_Kind | E_Constant => Write_Str ("Full_View"); when E_Generic_Package => Write_Str ("Generic_Homonym"); when E_Function | E_Procedure | E_Entry | E_Entry_Family => Write_Str ("Protected_Body_Subprogram"); when others => Write_Str ("Field11??"); end case; end Write_Field11_Name; ------------------------ -- Write_Field12_Name -- ------------------------ procedure Write_Field12_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Package => Write_Str ("Associated_Formal_Package"); when Entry_Kind => Write_Str ("Barrier_Function"); when E_Enumeration_Literal => Write_Str ("Enumeration_Rep"); when Type_Kind | E_Component | E_Constant | E_Discriminant | E_Exception | E_In_Parameter | E_In_Out_Parameter | E_Out_Parameter | E_Loop_Parameter | E_Variable => Write_Str ("Esize"); when E_Function | E_Procedure => Write_Str ("Next_Inlined_Subprogram"); when others => Write_Str ("Field12??"); end case; end Write_Field12_Name; ------------------------ -- Write_Field13_Name -- ------------------------ procedure Write_Field13_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Component | E_Discriminant => Write_Str ("Component_Clause"); when E_Function => Write_Str ("Elaboration_Entity"); when E_Procedure | E_Package | Generic_Unit_Kind => Write_Str ("Elaboration_Entity"); when Formal_Kind | E_Variable => Write_Str ("Extra_Accessibility"); when Type_Kind => Write_Str ("RM_Size"); when others => Write_Str ("Field13??"); end case; end Write_Field13_Name; ----------------------- -- Write_Field14_Name -- ----------------------- procedure Write_Field14_Name (Id : Entity_Id) is begin case Ekind (Id) is when Type_Kind | Formal_Kind | E_Constant | E_Exception | E_Variable | E_Loop_Parameter => Write_Str ("Alignment"); when E_Function | E_Procedure => Write_Str ("First_Optional_Parameter"); when E_Component | E_Discriminant => Write_Str ("Normalized_Position"); when E_Package | E_Generic_Package => Write_Str ("Shadow_Entities"); when others => Write_Str ("Field14??"); end case; end Write_Field14_Name; ------------------------ -- Write_Field15_Name -- ------------------------ procedure Write_Field15_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Discriminant => Write_Str ("Discriminant_Number"); when E_Component => Write_Str ("DT_Entry_Count"); when E_Function | E_Procedure => Write_Str ("DT_Position"); when E_Protected_Type => Write_Str ("Entry_Bodies_Array"); when Entry_Kind => Write_Str ("Entry_Parameters_Type"); when Formal_Kind => Write_Str ("Extra_Formal"); when Enumeration_Kind => Write_Str ("Lit_Indexes"); when E_Package | E_Package_Body => Write_Str ("Related_Instance"); when Decimal_Fixed_Point_Kind => Write_Str ("Scale_Value"); when E_Constant | E_Variable => Write_Str ("Status_Flag_Or_Transient_Decl"); when Access_Kind | Task_Kind => Write_Str ("Storage_Size_Variable"); when E_String_Literal_Subtype => Write_Str ("String_Literal_Low_Bound"); when others => Write_Str ("Field15??"); end case; end Write_Field15_Name; ------------------------ -- Write_Field16_Name -- ------------------------ procedure Write_Field16_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Record_Type | E_Record_Type_With_Private => Write_Str ("Access_Disp_Table"); when E_Abstract_State => Write_Str ("Body_References"); when E_Record_Subtype | E_Class_Wide_Subtype => Write_Str ("Cloned_Subtype"); when E_Function | E_Procedure => Write_Str ("DTC_Entity"); when E_Component => Write_Str ("Entry_Formal"); when E_Package | E_Generic_Package | Concurrent_Kind => Write_Str ("First_Private_Entity"); when Enumeration_Kind => Write_Str ("Lit_Strings"); when E_String_Literal_Subtype => Write_Str ("String_Literal_Length"); when E_Variable | E_Out_Parameter => Write_Str ("Unset_Reference"); when others => Write_Str ("Field16??"); end case; end Write_Field16_Name; ------------------------ -- Write_Field17_Name -- ------------------------ procedure Write_Field17_Name (Id : Entity_Id) is begin case Ekind (Id) is when Formal_Kind | E_Constant | E_Generic_In_Out_Parameter | E_Variable => Write_Str ("Actual_Subtype"); when Digits_Kind => Write_Str ("Digits_Value"); when E_Discriminant => Write_Str ("Discriminal"); when E_Block | Class_Wide_Kind | Concurrent_Kind | Private_Kind | E_Entry | E_Entry_Family | E_Function | E_Generic_Function | E_Generic_Package | E_Generic_Procedure | E_Loop | E_Operator | E_Package | E_Package_Body | E_Procedure | E_Record_Type | E_Record_Subtype | E_Return_Statement | E_Subprogram_Body | E_Subprogram_Type => Write_Str ("First_Entity"); when Array_Kind => Write_Str ("First_Index"); when Enumeration_Kind => Write_Str ("First_Literal"); when Access_Kind => Write_Str ("Master_Id"); when Modular_Integer_Kind => Write_Str ("Modulus"); when E_Abstract_State | E_Incomplete_Type => Write_Str ("Non_Limited_View"); when E_Incomplete_Subtype => if From_Limited_With (Id) then Write_Str ("Non_Limited_View"); end if; when E_Component => Write_Str ("Prival"); when others => Write_Str ("Field17??"); end case; end Write_Field17_Name; ------------------------ -- Write_Field18_Name -- ------------------------ procedure Write_Field18_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Enumeration_Literal | E_Function | E_Operator | E_Procedure => Write_Str ("Alias"); when E_Record_Type => Write_Str ("Corresponding_Concurrent_Type"); when E_Subprogram_Body => Write_Str ("Corresponding_Protected_Entry"); when Concurrent_Kind => Write_Str ("Corresponding_Record_Type"); when E_Label | E_Loop | E_Block => Write_Str ("Enclosing_Scope"); when E_Entry_Index_Parameter => Write_Str ("Entry_Index_Constant"); when E_Class_Wide_Subtype | E_Access_Protected_Subprogram_Type | E_Anonymous_Access_Protected_Subprogram_Type | E_Access_Subprogram_Type | E_Exception_Type => Write_Str ("Equivalent_Type"); when Fixed_Point_Kind => Write_Str ("Delta_Value"); when Incomplete_Or_Private_Kind | E_Record_Subtype => Write_Str ("Private_Dependents"); when Object_Kind => Write_Str ("Renamed_Object"); when E_Exception | E_Package | E_Generic_Function | E_Generic_Procedure | E_Generic_Package => Write_Str ("Renamed_Entity"); when others => Write_Str ("Field18??"); end case; end Write_Field18_Name; ----------------------- -- Write_Field19_Name -- ----------------------- procedure Write_Field19_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Package | E_Generic_Package => Write_Str ("Body_Entity"); when E_Discriminant => Write_Str ("Corresponding_Discriminant"); when Scalar_Kind => Write_Str ("Default_Aspect_Value"); when E_Array_Type => Write_Str ("Default_Component_Value"); when E_Record_Type => Write_Str ("Parent_Subtype"); when E_Constant | E_Variable => Write_Str ("Size_Check_Code"); when E_Package_Body | Formal_Kind => Write_Str ("Spec_Entity"); when Private_Kind => Write_Str ("Underlying_Full_View"); when E_Function | E_Operator | E_Subprogram_Type => Write_Str ("Extra_Accessibility_Of_Result"); when others => Write_Str ("Field19??"); end case; end Write_Field19_Name; ----------------------- -- Write_Field20_Name -- ----------------------- procedure Write_Field20_Name (Id : Entity_Id) is begin case Ekind (Id) is when Array_Kind => Write_Str ("Component_Type"); when E_In_Parameter | E_Generic_In_Parameter => Write_Str ("Default_Value"); when Access_Kind => Write_Str ("Directly_Designated_Type"); when E_Component => Write_Str ("Discriminant_Checking_Func"); when E_Discriminant => Write_Str ("Discriminant_Default_Value"); when E_Block | Class_Wide_Kind | Concurrent_Kind | Private_Kind | E_Entry | E_Entry_Family | E_Function | E_Generic_Function | E_Generic_Package | E_Generic_Procedure | E_Loop | E_Operator | E_Package | E_Package_Body | E_Procedure | E_Record_Type | E_Record_Subtype | E_Return_Statement | E_Subprogram_Body | E_Subprogram_Type => Write_Str ("Last_Entity"); when E_Constant | E_Variable => Write_Str ("Prival_Link"); when Scalar_Kind => Write_Str ("Scalar_Range"); when E_Exception => Write_Str ("Register_Exception_Call"); when others => Write_Str ("Field20??"); end case; end Write_Field20_Name; ----------------------- -- Write_Field21_Name -- ----------------------- procedure Write_Field21_Name (Id : Entity_Id) is begin case Ekind (Id) is when Entry_Kind => Write_Str ("Accept_Address"); when E_In_Parameter => Write_Str ("Default_Expr_Function"); when Concurrent_Kind | Incomplete_Or_Private_Kind | Class_Wide_Kind | E_Record_Type | E_Record_Subtype => Write_Str ("Discriminant_Constraint"); when E_Constant | E_Exception | E_Function | E_Generic_Function | E_Procedure | E_Generic_Procedure | E_Variable => Write_Str ("Interface_Name"); when Array_Kind | Modular_Integer_Kind => Write_Str ("Original_Array_Type"); when Fixed_Point_Kind => Write_Str ("Small_Value"); when others => Write_Str ("Field21??"); end case; end Write_Field21_Name; ----------------------- -- Write_Field22_Name -- ----------------------- procedure Write_Field22_Name (Id : Entity_Id) is begin case Ekind (Id) is when Access_Kind => Write_Str ("Associated_Storage_Pool"); when Array_Kind => Write_Str ("Component_Size"); when E_Record_Type => Write_Str ("Corresponding_Remote_Type"); when E_Component | E_Discriminant => Write_Str ("Original_Record_Component"); when E_Enumeration_Literal => Write_Str ("Enumeration_Rep_Expr"); when E_Exception => Write_Str ("Exception_Code"); when E_Record_Type_With_Private | E_Record_Subtype_With_Private | E_Private_Type | E_Private_Subtype | E_Limited_Private_Type | E_Limited_Private_Subtype => Write_Str ("Private_View"); when Formal_Kind => Write_Str ("Protected_Formal"); when E_Block | E_Entry | E_Entry_Family | E_Function | E_Loop | E_Package | E_Package_Body | E_Generic_Package | E_Generic_Function | E_Generic_Procedure | E_Procedure | E_Protected_Type | E_Return_Statement | E_Subprogram_Body | E_Task_Type => Write_Str ("Scope_Depth_Value"); when E_Variable => Write_Str ("Shared_Var_Procs_Instance"); when others => Write_Str ("Field22??"); end case; end Write_Field22_Name; ------------------------ -- Write_Field23_Name -- ------------------------ procedure Write_Field23_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Discriminant => Write_Str ("CR_Discriminant"); when E_Block => Write_Str ("Entry_Cancel_Parameter"); when E_Enumeration_Type => Write_Str ("Enum_Pos_To_Rep"); when Formal_Kind | E_Variable => Write_Str ("Extra_Constrained"); when Access_Kind => Write_Str ("Finalization_Master"); when E_Generic_Function | E_Generic_Package | E_Generic_Procedure => Write_Str ("Inner_Instances"); when Array_Kind => Write_Str ("Packed_Array_Impl_Type"); when Entry_Kind => Write_Str ("Protection_Object"); when Concurrent_Kind | Incomplete_Or_Private_Kind | Class_Wide_Kind | E_Record_Type | E_Record_Subtype => Write_Str ("Stored_Constraint"); when E_Function | E_Procedure => if Present (Scope (Id)) and then Is_Protected_Type (Scope (Id)) then Write_Str ("Protection_Object"); else Write_Str ("Generic_Renamings"); end if; when E_Package => if Is_Generic_Instance (Id) then Write_Str ("Generic_Renamings"); else Write_Str ("Limited_View"); end if; when others => Write_Str ("Field23??"); end case; end Write_Field23_Name; ------------------------ -- Write_Field24_Name -- ------------------------ procedure Write_Field24_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Constant | E_Variable | Type_Kind => Write_Str ("Related_Expression"); when others => Write_Str ("Field24???"); end case; end Write_Field24_Name; ------------------------ -- Write_Field25_Name -- ------------------------ procedure Write_Field25_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Generic_Package | E_Package => Write_Str ("Abstract_States"); when E_Variable => Write_Str ("Debug_Renaming_Link"); when E_Component => Write_Str ("DT_Offset_To_Top_Func"); when E_Procedure | E_Function => Write_Str ("Interface_Alias"); when E_Record_Type | E_Record_Subtype | E_Record_Type_With_Private | E_Record_Subtype_With_Private => Write_Str ("Interfaces"); when E_Array_Type | E_Array_Subtype => Write_Str ("Related_Array_Object"); when Task_Kind => Write_Str ("Task_Body_Procedure"); when E_Entry | E_Entry_Family => Write_Str ("PPC_Wrapper"); when Discrete_Kind => Write_Str ("Static_Discrete_Predicate"); when Real_Kind => Write_Str ("Static_Real_Or_String_Predicate"); when others => Write_Str ("Field25??"); end case; end Write_Field25_Name; ------------------------ -- Write_Field26_Name -- ------------------------ procedure Write_Field26_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Record_Type | E_Record_Type_With_Private => Write_Str ("Dispatch_Table_Wrappers"); when E_In_Out_Parameter | E_Out_Parameter | E_Variable => Write_Str ("Last_Assignment"); when E_Access_Subprogram_Type => Write_Str ("Original_Access_Type"); when E_Generic_Package | E_Package => Write_Str ("Package_Instantiation"); when E_Component | E_Constant => Write_Str ("Related_Type"); when Task_Kind => Write_Str ("Relative_Deadline_Variable"); when E_Procedure | E_Function => Write_Str ("Overridden_Operation"); when others => Write_Str ("Field26??"); end case; end Write_Field26_Name; ------------------------ -- Write_Field27_Name -- ------------------------ procedure Write_Field27_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Package | Type_Kind => Write_Str ("Current_Use_Clause"); when E_Component | E_Constant | E_Variable => Write_Str ("Related_Type"); when E_Procedure | E_Function => Write_Str ("Wrapped_Entity"); when others => Write_Str ("Field27??"); end case; end Write_Field27_Name; ------------------------ -- Write_Field28_Name -- ------------------------ procedure Write_Field28_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Entry | E_Entry_Family | E_Function | E_Procedure | E_Subprogram_Body | E_Subprogram_Type => Write_Str ("Extra_Formals"); when E_Package | E_Package_Body => Write_Str ("Finalizer"); when E_Constant | E_Variable => Write_Str ("Initialization_Statements"); when E_Record_Type => Write_Str ("Underlying_Record_View"); when others => Write_Str ("Field28??"); end case; end Write_Field28_Name; ------------------------ -- Write_Field29_Name -- ------------------------ procedure Write_Field29_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Constant | E_Variable => Write_Str ("BIP_Initialization_Call"); when Type_Kind => Write_Str ("Subprograms_For_Type"); when others => Write_Str ("Field29??"); end case; end Write_Field29_Name; ------------------------ -- Write_Field30_Name -- ------------------------ procedure Write_Field30_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Function => Write_Str ("Corresponding_Equality"); when E_Constant | E_Variable => Write_Str ("Last_Aggregate_Assignment"); when E_Procedure => Write_Str ("Static_Initialization"); when others => Write_Str ("Field30??"); end case; end Write_Field30_Name; ------------------------ -- Write_Field31_Name -- ------------------------ procedure Write_Field31_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Procedure | E_Function => Write_Str ("Thunk_Entity"); when Type_Kind => Write_Str ("Derived_Type_Link"); when others => Write_Str ("Field31??"); end case; end Write_Field31_Name; ------------------------ -- Write_Field32_Name -- ------------------------ procedure Write_Field32_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Function | E_Generic_Function | E_Generic_Package | E_Generic_Procedure | E_Package | E_Package_Body | E_Procedure | E_Subprogram_Body => Write_Str ("SPARK_Pragma"); when others => Write_Str ("Field32??"); end case; end Write_Field32_Name; ------------------------ -- Write_Field33_Name -- ------------------------ procedure Write_Field33_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Generic_Package | E_Package | E_Package_Body => Write_Str ("SPARK_Aux_Pragma"); when E_Constant | E_Variable | Subprogram_Kind | Type_Kind => Write_Str ("Linker_Section_Pragma"); when others => Write_Str ("Field33??"); end case; end Write_Field33_Name; ------------------------ -- Write_Field34_Name -- ------------------------ procedure Write_Field34_Name (Id : Entity_Id) is begin case Ekind (Id) is when E_Entry | E_Entry_Family | E_Generic_Package | E_Package | E_Package_Body | E_Subprogram_Body | E_Variable | Generic_Subprogram_Kind | Subprogram_Kind => Write_Str ("Contract"); when others => Write_Str ("Field34??"); end case; end Write_Field34_Name; ------------------------ -- Write_Field35_Name -- ------------------------ procedure Write_Field35_Name (Id : Entity_Id) is begin case Ekind (Id) is when Subprogram_Kind => Write_Str ("Import_Pragma"); when others => Write_Str ("Field35??"); end case; end Write_Field35_Name; ------------------------- -- Iterator Procedures -- ------------------------- procedure Proc_Next_Component (N : in out Node_Id) is begin N := Next_Component (N); end Proc_Next_Component; procedure Proc_Next_Component_Or_Discriminant (N : in out Node_Id) is begin N := Next_Entity (N); while Present (N) loop exit when Ekind_In (N, E_Component, E_Discriminant); N := Next_Entity (N); end loop; end Proc_Next_Component_Or_Discriminant; procedure Proc_Next_Discriminant (N : in out Node_Id) is begin N := Next_Discriminant (N); end Proc_Next_Discriminant; procedure Proc_Next_Formal (N : in out Node_Id) is begin N := Next_Formal (N); end Proc_Next_Formal; procedure Proc_Next_Formal_With_Extras (N : in out Node_Id) is begin N := Next_Formal_With_Extras (N); end Proc_Next_Formal_With_Extras; procedure Proc_Next_Index (N : in out Node_Id) is begin N := Next_Index (N); end Proc_Next_Index; procedure Proc_Next_Inlined_Subprogram (N : in out Node_Id) is begin N := Next_Inlined_Subprogram (N); end Proc_Next_Inlined_Subprogram; procedure Proc_Next_Literal (N : in out Node_Id) is begin N := Next_Literal (N); end Proc_Next_Literal; procedure Proc_Next_Stored_Discriminant (N : in out Node_Id) is begin N := Next_Stored_Discriminant (N); end Proc_Next_Stored_Discriminant; end Einfo; gprbuild-gpl-2014-src/gnat/sinput.ads0000644000076700001450000013115112323721731017101 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S I N P U T -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains the input routines used for reading the -- input source file. The actual I/O routines are in OS_Interface, -- with this module containing only the system independent processing. -- General Note: throughout the compiler, we use the term line or source -- line to refer to a physical line in the source, terminated by the end of -- physical line sequence. -- There are two distinct concepts of line terminator in GNAT -- A logical line terminator is what corresponds to the "end of a line" as -- described in RM 2.2 (13). Any of the characters FF, LF, CR or VT or any -- wide character that is a Line or Paragraph Separator acts as an end of -- logical line in this sense, and it is essentially irrelevant whether one -- or more appears in sequence (since if a sequence of such characters is -- regarded as separate ends of line, then the intervening logical lines -- are null in any case). -- A physical line terminator is a sequence of format effectors that is -- treated as ending a physical line. Physical lines have no Ada semantic -- significance, but they are significant for error reporting purposes, -- since errors are identified by line and column location. -- In GNAT, a physical line is ended by any of the sequences LF, CR/LF, or -- CR. LF is used in typical Unix systems, CR/LF in DOS systems, and CR -- alone in System 7. In addition, we recognize any of these sequences in -- any of the operating systems, for better behavior in treating foreign -- files (e.g. a Unix file with LF terminators transferred to a DOS system). -- Finally, wide character codes in categories Separator, Line and Separator, -- Paragraph are considered to be physical line terminators. with Alloc; with Casing; use Casing; with Namet; use Namet; with Table; with Types; use Types; package Sinput is type Type_Of_File is ( -- Indicates type of file being read Src, -- Normal Ada source file Config, -- Configuration pragma file Def, -- Preprocessing definition file Preproc); -- Source file with preprocessing commands to be preprocessed type Instance_Id is new Nat; No_Instance_Id : constant Instance_Id; ---------------------------- -- Source License Control -- ---------------------------- -- The following type indicates the license state of a source if it -- is known. type License_Type is (Unknown, -- Licensing status of this source unit is unknown Restricted, -- This is a non-GPL'ed unit that is restricted from depending -- on GPL'ed units (e.g. proprietary code is in this category) GPL, -- This file is licensed under the unmodified GPL. It is not allowed -- to depend on Non_GPL units, and Non_GPL units may not depend on -- this source unit. Modified_GPL, -- This file is licensed under the GNAT modified GPL (see header of -- This file for wording of the modification). It may depend on other -- Modified_GPL units or on unrestricted units. Unrestricted); -- The license on this file is permitted to depend on any other -- units, or have other units depend on it, without violating the -- license of this unit. Examples are public domain units, and -- units defined in the RM). -- The above license status is checked when the appropriate check is -- activated and one source depends on another, and the licensing state -- of both files is known: -- The prohibited combinations are: -- Restricted file may not depend on GPL file -- GPL file may not depend on Restricted file -- Modified GPL file may not depend on Restricted file -- Modified_GPL file may not depend on GPL file -- The reason for the last restriction here is that a client depending -- on a modified GPL file must be sure that the license condition is -- correct considered transitively. -- The licensing status is determined either by the presence of a -- specific pragma License, or by scanning the header for a predefined -- file, or any file if compiling in -gnatg mode. ----------------------- -- Source File Table -- ----------------------- -- The source file table has an entry for each source file read in for -- this run of the compiler. This table is (default) initialized when -- the compiler is loaded, and simply accumulates entries as compilation -- proceeds and various routines in Sinput and its child packages are -- called to load required source files. -- Virtual entries are also created for generic templates when they are -- instantiated, as described in a separate section later on. -- In the case where there are multiple main units (e.g. in the case of -- the cross-reference tool), this table is not reset between these units, -- so that a given source file is only read once if it is used by two -- separate main units. -- The entries in the table are accessed using a Source_File_Index that -- ranges from 1 to Last_Source_File. Each entry has the following fields -- Note: fields marked read-only are set by Sinput or one of its child -- packages when a source file table entry is created, and cannot be -- subsequently modified, or alternatively are set only by very special -- circumstances, documented in the comments. -- File_Name : File_Name_Type (read-only) -- Name of the source file (simple name with no directory information) -- Full_File_Name : File_Name_Type (read-only) -- Full file name (full name with directory info), used for generation -- of error messages, etc. -- File_Type : Type_Of_File (read-only) -- Indicates type of file (source file, configuration pragmas file, -- preprocessor definition file, preprocessor input file). -- Reference_Name : File_Name_Type (read-only) -- Name to be used for source file references in error messages where -- only the simple name of the file is required. Identical to File_Name -- unless pragma Source_Reference is used to change it. Only processing -- for the Source_Reference pragma circuit may set this field. -- Full_Ref_Name : File_Name_Type (read-only) -- Name to be used for source file references in error messages where -- the full name of the file is required. Identical to Full_File_Name -- unless pragma Source_Reference is used to change it. Only processing -- for the Source_Reference pragma may set this field. -- Debug_Source_Name : File_Name_Type (read-only) -- Name to be used for source file references in debugging information -- where only the simple name of the file is required. Identical to -- Reference_Name unless the -gnatD (debug source file) switch is used. -- Only processing in Sprint that generates this file is permitted to -- set this field. -- Full_Debug_Name : File_Name_Type (read-only) -- Name to be used for source file references in debugging information -- where the full name of the file is required. This is identical to -- Full_Ref_Name unless the -gnatD (debug source file) switch is used. -- Only processing in Sprint that generates this file is permitted to -- set this field. -- Instance : Instance_Id (read-only) -- For entries corresponding to a generic instantiation, unique -- identifier denoting the full chain of nested instantiations. Set to -- No_Instance_Id for the case of a normal, non-instantiation entry. -- See below for details on the handling of generic instantiations. -- License : License_Type; -- License status of source file -- Num_SRef_Pragmas : Nat; -- Number of source reference pragmas present in source file -- First_Mapped_Line : Logical_Line_Number; -- This field stores logical line number of the first line in the -- file that is not a Source_Reference pragma. If no source reference -- pragmas are used, then the value is set to No_Line_Number. -- Source_Text : Source_Buffer_Ptr (read-only) -- Text of source file. Note that every source file has a distinct set -- of non-overlapping logical bounds, so it is possible to determine -- which file is referenced from a given subscript (Source_Ptr) value. -- Source_First : Source_Ptr; (read-only) -- Subscript of first character in Source_Text. Note that this cannot -- be obtained as Source_Text'First, because we use virtual origin -- addressing. -- Source_Last : Source_Ptr; (read-only) -- Subscript of last character in Source_Text. Note that this cannot -- be obtained as Source_Text'Last, because we use virtual origin -- addressing, so this value is always Source_Ptr'Last. -- Time_Stamp : Time_Stamp_Type; (read-only) -- Time stamp of the source file -- Source_Checksum : Word; -- Computed checksum for contents of source file. See separate section -- later on in this spec for a description of the checksum algorithm. -- Last_Source_Line : Physical_Line_Number; -- Physical line number of last source line. While a file is being -- read, this refers to the last line scanned. Once a file has been -- completely scanned, it is the number of the last line in the file, -- and hence also gives the number of source lines in the file. -- Keyword_Casing : Casing_Type; -- Casing style used in file for keyword casing. This is initialized -- to Unknown, and then set from the first occurrence of a keyword. -- This value is used only for formatting of error messages. -- Identifier_Casing : Casing_Type; -- Casing style used in file for identifier casing. This is initialized -- to Unknown, and then set from an identifier in the program as soon as -- one is found whose casing is sufficiently clear to make a decision. -- This value is used for formatting of error messages, and also is used -- in the detection of keywords misused as identifiers. -- Inlined_Call : Source_Ptr; -- Source file location of the subprogram call if this source file entry -- represents an inlined body. Set to No_Location otherwise. -- This field is read-only for clients. -- Inlined_Body : Boolean; -- This can only be set True if Instantiation has a value other than -- No_Location. If true it indicates that the instantiation is actually -- an instance of an inlined body. -- ??? Redundant, always equal to (Inlined_Call /= No_Location) -- Template : Source_File_Index; (read-only) -- Source file index of the source file containing the template if this -- is a generic instantiation. Set to No_Source_File for the normal case -- of a non-instantiation entry. See Sinput-L for details. -- Unit : Unit_Number_Type; -- Identifies the unit contained in this source file. Set by -- Initialize_Scanner, must not be subsequently altered. -- The source file table is accessed by clients using the following -- subprogram interface: subtype SFI is Source_File_Index; System_Source_File_Index : SFI; -- The file system.ads is always read by the compiler to determine the -- settings of the target parameters in the private part of System. This -- variable records the source file index of system.ads. Typically this -- will be 1 since system.ads is read first. function Debug_Source_Name (S : SFI) return File_Name_Type; function File_Name (S : SFI) return File_Name_Type; function File_Type (S : SFI) return Type_Of_File; function First_Mapped_Line (S : SFI) return Logical_Line_Number; function Full_Debug_Name (S : SFI) return File_Name_Type; function Full_File_Name (S : SFI) return File_Name_Type; function Full_Ref_Name (S : SFI) return File_Name_Type; function Identifier_Casing (S : SFI) return Casing_Type; function Inlined_Body (S : SFI) return Boolean; function Inlined_Call (S : SFI) return Source_Ptr; function Instance (S : SFI) return Instance_Id; function Keyword_Casing (S : SFI) return Casing_Type; function Last_Source_Line (S : SFI) return Physical_Line_Number; function License (S : SFI) return License_Type; function Num_SRef_Pragmas (S : SFI) return Nat; function Reference_Name (S : SFI) return File_Name_Type; function Source_Checksum (S : SFI) return Word; function Source_First (S : SFI) return Source_Ptr; function Source_Last (S : SFI) return Source_Ptr; function Source_Text (S : SFI) return Source_Buffer_Ptr; function Template (S : SFI) return Source_File_Index; function Unit (S : SFI) return Unit_Number_Type; function Time_Stamp (S : SFI) return Time_Stamp_Type; procedure Set_Keyword_Casing (S : SFI; C : Casing_Type); procedure Set_Identifier_Casing (S : SFI; C : Casing_Type); procedure Set_License (S : SFI; L : License_Type); procedure Set_Unit (S : SFI; U : Unit_Number_Type); function Last_Source_File return Source_File_Index; -- Index of last source file table entry function Num_Source_Files return Nat; -- Number of source file table entries procedure Initialize; -- Initialize internal tables procedure Lock; -- Lock internal tables procedure Unlock; -- Unlock internal tables Main_Source_File : Source_File_Index := No_Source_File; -- This is set to the source file index of the main unit ----------------------------- -- Source_File_Index_Table -- ----------------------------- -- The Get_Source_File_Index function is called very frequently. Earlier -- versions cached a single entry, but then reverted to a serial search, -- and this proved to be a significant source of inefficiency. We then -- switched to using a table with a start point followed by a serial -- search. Now we make sure source buffers are on a reasonable boundary -- (see Types.Source_Align), and we can just use a direct look up in the -- following table. -- Note that this array is pretty large, but in most operating systems -- it will not be allocated in physical memory unless it is actually used. Source_File_Index_Table : array (Int range 0 .. 1 + (Int'Last / Source_Align)) of Source_File_Index; procedure Set_Source_File_Index_Table (Xnew : Source_File_Index); -- Sets entries in the Source_File_Index_Table for the newly created -- Source_File table entry whose index is Xnew. The Source_First and -- Source_Last fields of this entry must be set before the call. ----------------------- -- Checksum Handling -- ----------------------- -- As a source file is scanned, a checksum is computed by taking all the -- non-blank characters in the file, excluding comment characters, the -- minus-minus sequence starting a comment, and all control characters -- except ESC. -- The checksum algorithm used is the standard CRC-32 algorithm, as -- implemented by System.CRC32, except that we do not bother with the -- final XOR with all 1 bits. -- This algorithm ensures that the checksum includes all semantically -- significant aspects of the program represented by the source file, -- but is insensitive to layout, presence or contents of comments, wide -- character representation method, or casing conventions outside strings. -- Scans.Checksum is initialized appropriately at the start of scanning -- a file, and copied into the Source_Checksum field of the file table -- entry when the end of file is encountered. ------------------------------------- -- Handling Generic Instantiations -- ------------------------------------- -- As described in Sem_Ch12, a generic instantiation involves making a -- copy of the tree of the generic template. The source locations in -- this tree directly reference the source of the template. However it -- is also possible to find the location of the instantiation. -- This is achieved as follows. When an instantiation occurs, a new entry -- is made in the source file table. This entry points to the same source -- text, i.e. the file that contains the instantiation, but has a distinct -- set of Source_Ptr index values. The separate range of Sloc values avoids -- confusion, and means that the Sloc values can still be used to uniquely -- identify the source file table entry. It is possible for both entries -- to point to the same text, because of the virtual origin pointers used -- in the source table. -- The Instantiation_Id field of this source file index entry, set -- to No_Instance_Id for normal entries, instead contains a value that -- uniquely identifies a particular instantiation, and the associated -- entry in the Instances table. The source location of the instantiation -- can be retrieved using function Instantiation below. In the case of -- nested instantiations, the Instances table can be used to trace the -- complete chain of nested instantiations. -- Two routines are used to build the special instance entries in the -- source file table. Create_Instantiation_Source is first called to build -- the virtual source table entry for the instantiation, and then the -- Sloc values in the copy are adjusted using Adjust_Instantiation_Sloc. -- See child unit Sinput.L for details on these two routines. generic with procedure Process (Id : Instance_Id; Inst_Sloc : Source_Ptr); procedure Iterate_On_Instances; -- Execute Process for each entry in the instance table function Instantiation (S : SFI) return Source_Ptr; -- For a source file entry that represents an inlined body, source location -- of the inlined call. Otherwise, for a source file entry that represents -- a generic instantiation, source location of the instantiation. Returns -- No_Location in all other cases. ----------------- -- Global Data -- ----------------- Current_Source_File : Source_File_Index := No_Source_File; -- Source_File table index of source file currently being scanned. -- Initialized so that some tools (such as gprbuild) can be built with -- -gnatVa and pragma Initialized_Scalars without problems. Current_Source_Unit : Unit_Number_Type; -- Unit number of source file currently being scanned. The special value -- of No_Unit indicates that the configuration pragma file is currently -- being scanned (this has no entry in the unit table). Source_gnat_adc : Source_File_Index := No_Source_File; -- This is set if a gnat.adc file is present to reference this file Source : Source_Buffer_Ptr; -- Current source (copy of Source_File.Table (Current_Source_Unit).Source) Internal_Source : aliased Source_Buffer (1 .. 81); -- This buffer is used internally in the compiler when the lexical analyzer -- is used to scan a string from within the compiler. The procedure is to -- establish Internal_Source_Ptr as the value of Source, set the string to -- be scanned, appropriately terminated, in this buffer, and set Scan_Ptr -- to point to the start of the buffer. It is a fatal error if the scanner -- signals an error while scanning a token in this internal buffer. Internal_Source_Ptr : constant Source_Buffer_Ptr := Internal_Source'Unrestricted_Access; -- Pointer to internal source buffer ----------------------------------------- -- Handling of Source Line Terminators -- ----------------------------------------- -- In this section we discuss in detail the issue of terminators used to -- terminate source lines. The RM says that one or more format effectors -- (other than horizontal tab) end a source line, and defines the set of -- such format effectors, but does not talk about exactly how they are -- represented in the source program (since in general the RM is not in -- the business of specifying source program formats). -- The type Types.Line_Terminator is defined as a subtype of Character -- that includes CR/LF/VT/FF. The most common line enders in practice -- are CR (some MAC systems), LF (Unix systems), and CR/LF (DOS/Windows -- systems). Any of these sequences is recognized as ending a physical -- source line, and if multiple such terminators appear (e.g. LF/LF), -- then we consider we have an extra blank line. -- VT and FF are recognized as terminating source lines, but they are -- considered to end a logical line instead of a physical line, so that -- the line numbering ignores such terminators. The use of VT and FF is -- mandated by the standard, and correctly handled in a conforming manner -- by GNAT, but their use is not recommended. -- In addition to the set of characters defined by the type in Types, in -- wide character encoding, then the codes returning True for a call to -- System.UTF_32.Is_UTF_32_Line_Terminator are also recognized as ending a -- source line. This includes the standard codes defined above in addition -- to NEL (NEXT LINE), LINE SEPARATOR and PARAGRAPH SEPARATOR. Again, as in -- the case of VT and FF, the standard requires we recognize these as line -- terminators, but we consider them to be logical line terminators. The -- only physical line terminators recognized are the standard ones (CR, -- LF, or CR/LF). -- However, we do not recognize the NEL (16#85#) character as having the -- significance of an end of line character when operating in normal 8-bit -- Latin-n input mode for the compiler. Instead the rule in this mode is -- that all upper half control codes (16#80# .. 16#9F#) are illegal if they -- occur in program text, and are ignored if they appear in comments. -- First, note that this behavior is fully conforming with the standard. -- The standard has nothing whatever to say about source representation -- and implementations are completely free to make there own rules. In -- this case, in 8-bit mode, GNAT decides that the 16#0085# character is -- not a representation of the NEL character, even though it looks like it. -- If you have NEL's in your program, which you expect to be treated as -- end of line characters, you must use a wide character encoding such as -- UTF-8 for this code to be recognized. -- Second, an explanation of why we take this slightly surprising choice. -- We have never encountered anyone actually using the NEL character to -- end lines. One user raised the issue as a result of some experiments, -- but no one has ever submitted a program encoded this way, in any of -- the possible encodings. It seems that even when using wide character -- codes extensively, the normal approach is to use standard line enders -- (LF or CR/LF). So the failure to recognize NEL in this mode seems to -- have no practical downside. -- Moreover, what we have seen in a significant number of programs from -- multiple sources is the practice of writing all program text in lower -- half (ASCII) form, but using UTF-8 encoded wide characters freely in -- comments, where the comments are terminated by normal line endings -- (LF or CR/LF). The comments do not contain NEL codes, but they can and -- do contain other UTF-8 encoding sequences where one of the bytes is the -- NEL code. Now such programs can of course be compiled in UTF-8 mode, -- but in practice they also compile fine in standard 8-bit mode without -- specifying a character encoding. Since this is common practice, it would -- be a signficant upwards incompatibility to recognize NEL in 8-bit mode. ----------------- -- Subprograms -- ----------------- procedure Backup_Line (P : in out Source_Ptr); -- Back up the argument pointer to the start of the previous line. On -- entry, P points to the start of a physical line in the source buffer. -- On return, P is updated to point to the start of the previous line. -- The caller has checked that a Line_Terminator character precedes P so -- that there definitely is a previous line in the source buffer. procedure Build_Location_String (Loc : Source_Ptr); -- This function builds a string literal of the form "name:line", where -- name is the file name corresponding to Loc, and line is the line number. -- In the event that instantiations are involved, additional suffixes of -- the same form are appended after the separating string " instantiated at -- ". The returned string is appended to the Name_Buffer, terminated by -- ASCII.NUL, with Name_Length indicating the length not including the -- terminating Nul. function Build_Location_String (Loc : Source_Ptr) return String; -- Functional form returning a string, which does not include a terminating -- null character. The contents of Name_Buffer is destroyed. procedure Check_For_BOM; -- Check if the current source starts with a BOM. Scan_Ptr needs to be at -- the start of the current source. If the current source starts with a -- recognized BOM, then some flags such as Wide_Character_Encoding_Method -- are set accordingly, and the Scan_Ptr on return points past this BOM. -- An error message is output and Unrecoverable_Error raised if a non- -- recognized BOM is detected. The call has no effect if no BOM is found. function Get_Column_Number (P : Source_Ptr) return Column_Number; -- The ones-origin column number of the specified Source_Ptr value is -- determined and returned. Tab characters if present are assumed to -- represent the standard 1,9,17.. spacing pattern. function Get_Logical_Line_Number (P : Source_Ptr) return Logical_Line_Number; -- The line number of the specified source position is obtained by -- doing a binary search on the source positions in the lines table -- for the unit containing the given source position. The returned -- value is the logical line number, already adjusted for the effect -- of source reference pragmas. If P refers to the line of a source -- reference pragma itself, then No_Line is returned. If no source -- reference pragmas have been encountered, the value returned is -- the same as the physical line number. function Get_Logical_Line_Number_Img (P : Source_Ptr) return String; -- Same as above function, but returns the line number as a string of -- decimal digits, with no leading space. Destroys Name_Buffer. function Get_Physical_Line_Number (P : Source_Ptr) return Physical_Line_Number; -- The line number of the specified source position is obtained by -- doing a binary search on the source positions in the lines table -- for the unit containing the given source position. The returned -- value is the physical line number in the source being compiled. function Get_Source_File_Index (S : Source_Ptr) return Source_File_Index; pragma Inline (Get_Source_File_Index); -- Return file table index of file identified by given source pointer -- value. This call must always succeed, since any valid source pointer -- value belongs to some previously loaded source file. function Instantiation_Depth (S : Source_Ptr) return Nat; -- Determine instantiation depth for given Sloc value. A value of -- zero means that the given Sloc is not in an instantiation. function Line_Start (P : Source_Ptr) return Source_Ptr; -- Finds the source position of the start of the line containing the -- given source location. function Line_Start (L : Physical_Line_Number; S : Source_File_Index) return Source_Ptr; -- Finds the source position of the start of the given line in the -- given source file, using a physical line number to identify the line. function Num_Source_Lines (S : Source_File_Index) return Nat; -- Returns the number of source lines (this is equivalent to reading -- the value of Last_Source_Line, but returns Nat rather than a -- physical line number. procedure Register_Source_Ref_Pragma (File_Name : File_Name_Type; Stripped_File_Name : File_Name_Type; Mapped_Line : Nat; Line_After_Pragma : Physical_Line_Number); -- Register a source reference pragma, the parameter File_Name is the -- file name from the pragma, and Stripped_File_Name is this name with -- the directory information stripped. Both these parameters are set -- to No_Name if no file name parameter was given in the pragma. -- (which can only happen for the second and subsequent pragmas). -- Mapped_Line is the line number parameter from the pragma, and -- Line_After_Pragma is the physical line number of the line that -- follows the line containing the Source_Reference pragma. function Original_Location (S : Source_Ptr) return Source_Ptr; -- Given a source pointer S, returns the corresponding source pointer -- value ignoring instantiation copies. For locations that do not -- correspond to instantiation copies of templates, the argument is -- returned unchanged. For locations that do correspond to copies of -- templates from instantiations, the location within the original -- template is returned. This is useful in canonicalizing locations. function Instantiation_Location (S : Source_Ptr) return Source_Ptr; pragma Inline (Instantiation_Location); -- Given a source pointer S, returns the corresponding source pointer -- value of the instantiation if this location is within an instance. -- If S is not within an instance, then this returns No_Location. function Top_Level_Location (S : Source_Ptr) return Source_Ptr; -- Given a source pointer S, returns the argument unchanged if it is -- not in an instantiation. If S is in an instantiation, then it returns -- the location of the top level instantiation, i.e. the outer level -- instantiation in the nested case. function Physical_To_Logical (Line : Physical_Line_Number; S : Source_File_Index) return Logical_Line_Number; -- Given a physical line number in source file whose source index is S, -- return the corresponding logical line number. If the physical line -- number is one containing a Source_Reference pragma, the result will -- be No_Line_Number. procedure Skip_Line_Terminators (P : in out Source_Ptr; Physical : out Boolean); -- On entry, P points to a line terminator that has been encountered, -- which is one of FF,LF,VT,CR or a wide character sequence whose value is -- in category Separator,Line or Separator,Paragraph. P points just past -- the character that was scanned. The purpose of this routine is to -- distinguish physical and logical line endings. A physical line ending -- is one of: -- -- CR on its own (MAC System 7) -- LF on its own (Unix and unix-like systems) -- CR/LF (DOS, Windows) -- Wide character in Separator,Line or Separator,Paragraph category -- -- Note: we no longer recognize LF/CR (which we did in some earlier -- versions of GNAT. The reason for this is that this sequence is not -- used and recognizing it generated confusion. For example given the -- sequence LF/CR/LF we were interpreting that as (LF/CR) ending the -- first line and a blank line ending with CR following, but it is -- clearly better to interpret this as LF, with a blank line terminated -- by CR/LF, given that LF and CR/LF are both in common use, but no -- system we know of uses LF/CR. -- -- A logical line ending (that is not a physical line ending) is one of: -- -- VT on its own -- FF on its own -- -- On return, P is bumped past the line ending sequence (one of the above -- seven possibilities). Physical is set to True to indicate that a -- physical end of line was encountered, in which case this routine also -- makes sure that the lines table for the current source file has an -- appropriate entry for the start of the new physical line. procedure Sloc_Range (N : Node_Id; Min, Max : out Source_Ptr); -- Given a node, returns the minimum and maximum source locations of any -- node in the syntactic subtree for the node. This is not quite the same -- as the locations of the first and last token in the node construct -- because parentheses at the outer level do not have a recorded Sloc. -- -- Note: At each step of the tree traversal, we make sure to go back to -- the Original_Node, since this function is concerned about original -- (source) locations. -- -- Note: if the tree for the expression contains no "real" Sloc values, -- i.e. values > No_Location, then both Min and Max are set to -- Sloc (Original_Node (N)). function Source_Offset (S : Source_Ptr) return Nat; -- Returns the zero-origin offset of the given source location from the -- start of its corresponding unit. This is used for creating canonical -- names in some situations. procedure Write_Location (P : Source_Ptr); -- Writes out a string of the form fff:nn:cc, where fff, nn, cc are the -- file name, line number and column corresponding to the given source -- location. No_Location and Standard_Location appear as the strings -- and . If the location is within an -- instantiation, then the instance location is appended, enclosed in -- square brackets (which can nest if necessary). Note that this routine -- is used only for internal compiler debugging output purposes (which -- is why the somewhat cryptic use of brackets is acceptable). procedure wl (P : Source_Ptr); pragma Export (Ada, wl); -- Equivalent to Write_Location (P); Write_Eol; for calls from GDB procedure Write_Time_Stamp (S : Source_File_Index); -- Writes time stamp of specified file in YY-MM-DD HH:MM.SS format procedure Tree_Read; -- Initializes internal tables from current tree file using the relevant -- Table.Tree_Read routines. procedure Tree_Write; -- Writes out internal tables to current tree file using the relevant -- Table.Tree_Write routines. private pragma Inline (File_Name); pragma Inline (Full_File_Name); pragma Inline (File_Type); pragma Inline (Reference_Name); pragma Inline (Full_Ref_Name); pragma Inline (Debug_Source_Name); pragma Inline (Full_Debug_Name); pragma Inline (Instance); pragma Inline (License); pragma Inline (Num_SRef_Pragmas); pragma Inline (First_Mapped_Line); pragma Inline (Source_Text); pragma Inline (Source_First); pragma Inline (Source_Last); pragma Inline (Time_Stamp); pragma Inline (Source_Checksum); pragma Inline (Last_Source_Line); pragma Inline (Keyword_Casing); pragma Inline (Identifier_Casing); pragma Inline (Inlined_Call); pragma Inline (Inlined_Body); pragma Inline (Template); pragma Inline (Unit); pragma Inline (Set_Keyword_Casing); pragma Inline (Set_Identifier_Casing); pragma Inline (Last_Source_File); pragma Inline (Num_Source_Files); pragma Inline (Num_Source_Lines); No_Instance_Id : constant Instance_Id := 0; ------------------------- -- Source_Lines Tables -- ------------------------- type Lines_Table_Type is array (Physical_Line_Number) of Source_Ptr; -- Type used for lines table. The entries are indexed by physical line -- numbers. The values are the starting Source_Ptr values for the start -- of the corresponding physical line. Note that we make this a bogus -- big array, sized as required, so that we avoid the use of fat pointers. type Lines_Table_Ptr is access all Lines_Table_Type; -- Type used for pointers to line tables type Logical_Lines_Table_Type is array (Physical_Line_Number) of Logical_Line_Number; -- Type used for logical lines table. This table is used if a source -- reference pragma is present. It is indexed by physical line numbers, -- and contains the corresponding logical line numbers. An entry that -- corresponds to a source reference pragma is set to No_Line_Number. -- Note that we make this a bogus big array, sized as required, so that -- we avoid the use of fat pointers. type Logical_Lines_Table_Ptr is access all Logical_Lines_Table_Type; -- Type used for pointers to logical line tables ----------------------- -- Source_File Table -- ----------------------- -- See earlier descriptions for meanings of public fields type Source_File_Record is record File_Name : File_Name_Type; Reference_Name : File_Name_Type; Debug_Source_Name : File_Name_Type; Full_Debug_Name : File_Name_Type; Full_File_Name : File_Name_Type; Full_Ref_Name : File_Name_Type; Instance : Instance_Id; Num_SRef_Pragmas : Nat; First_Mapped_Line : Logical_Line_Number; Source_Text : Source_Buffer_Ptr; Source_First : Source_Ptr; Source_Last : Source_Ptr; Source_Checksum : Word; Last_Source_Line : Physical_Line_Number; Template : Source_File_Index; Unit : Unit_Number_Type; Time_Stamp : Time_Stamp_Type; File_Type : Type_Of_File; Inlined_Call : Source_Ptr; Inlined_Body : Boolean; License : License_Type; Keyword_Casing : Casing_Type; Identifier_Casing : Casing_Type; -- The following fields are for internal use only (i.e. only in the -- body of Sinput or its children, with no direct access by clients). Sloc_Adjust : Source_Ptr; -- A value to be added to Sloc values for this file to reference the -- corresponding lines table. This is zero for the non-instantiation -- case, and set so that the addition references the ultimate template -- for the instantiation case. See Sinput-L for further details. Lines_Table : Lines_Table_Ptr; -- Pointer to lines table for this source. Updated as additional -- lines are accessed using the Skip_Line_Terminators procedure. -- Note: the lines table for an instantiation entry refers to the -- original line numbers of the template see Sinput-L for details. Logical_Lines_Table : Logical_Lines_Table_Ptr; -- Pointer to logical lines table for this source. Non-null only if -- a source reference pragma has been processed. Updated as lines -- are accessed using the Skip_Line_Terminators procedure. Lines_Table_Max : Physical_Line_Number; -- Maximum subscript values for currently allocated Lines_Table -- and (if present) the allocated Logical_Lines_Table. The value -- Max_Source_Line gives the maximum used value, this gives the -- maximum allocated value. end record; -- The following representation clause ensures that the above record -- has no holes. We do this so that when instances of this record are -- written by Tree_Gen, we do not write uninitialized values to the file. AS : constant Pos := Standard'Address_Size; for Source_File_Record use record File_Name at 0 range 0 .. 31; Reference_Name at 4 range 0 .. 31; Debug_Source_Name at 8 range 0 .. 31; Full_Debug_Name at 12 range 0 .. 31; Full_File_Name at 16 range 0 .. 31; Full_Ref_Name at 20 range 0 .. 31; Instance at 48 range 0 .. 31; Num_SRef_Pragmas at 24 range 0 .. 31; First_Mapped_Line at 28 range 0 .. 31; Source_First at 32 range 0 .. 31; Source_Last at 36 range 0 .. 31; Source_Checksum at 40 range 0 .. 31; Last_Source_Line at 44 range 0 .. 31; Template at 52 range 0 .. 31; Unit at 56 range 0 .. 31; Time_Stamp at 60 range 0 .. 8 * Time_Stamp_Length - 1; File_Type at 74 range 0 .. 7; Inlined_Call at 88 range 0 .. 31; Inlined_Body at 75 range 0 .. 7; License at 76 range 0 .. 7; Keyword_Casing at 77 range 0 .. 7; Identifier_Casing at 78 range 0 .. 15; Sloc_Adjust at 80 range 0 .. 31; Lines_Table_Max at 84 range 0 .. 31; -- The following fields are pointers, so we have to specialize their -- lengths using pointer size, obtained above as Standard'Address_Size. Source_Text at 92 range 0 .. AS - 1; Lines_Table at 92 range AS .. AS * 2 - 1; Logical_Lines_Table at 92 range AS * 2 .. AS * 3 - 1; end record; for Source_File_Record'Size use 92 * 8 + AS * 3; -- This ensures that we did not leave out any fields package Source_File is new Table.Table ( Table_Component_Type => Source_File_Record, Table_Index_Type => Source_File_Index, Table_Low_Bound => 1, Table_Initial => Alloc.Source_File_Initial, Table_Increment => Alloc.Source_File_Increment, Table_Name => "Source_File"); -- Auxiliary table containing source location of instantiations. Index 0 -- is used for code that does not come from an instance. package Instances is new Table.Table ( Table_Component_Type => Source_Ptr, Table_Index_Type => Instance_Id, Table_Low_Bound => 0, Table_Initial => Alloc.Source_File_Initial, Table_Increment => Alloc.Source_File_Increment, Table_Name => "Instances"); ----------------- -- Subprograms -- ----------------- procedure Alloc_Line_Tables (S : in out Source_File_Record; New_Max : Nat); -- Allocate or reallocate the lines table for the given source file so -- that it can accommodate at least New_Max lines. Also allocates or -- reallocates logical lines table if source ref pragmas are present. procedure Add_Line_Tables_Entry (S : in out Source_File_Record; P : Source_Ptr); -- Increment line table size by one (reallocating the lines table if -- needed) and set the new entry to contain the value P. Also bumps -- the Source_Line_Count field. If source reference pragmas are -- present, also increments logical lines table size by one, and -- sets new entry. procedure Trim_Lines_Table (S : Source_File_Index); -- Set lines table size for entry S in the source file table to -- correspond to the current value of Num_Source_Lines, releasing -- any unused storage. This is used by Sinput.L and Sinput.D. end Sinput; gprbuild-gpl-2014-src/gnat/csets.ads0000644000076700001450000001226412323721731016703 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- C S E T S -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ package Csets is pragma Elaborate_Body; -- This package contains character tables for the various character -- sets that are supported for source representation. Character and -- string literals are not affected, only identifiers. For each set, -- the table in this package gives the mapping of letters to their -- upper case equivalent. Each table thus provides the information -- for building the table used to fold lower case to upper case, and -- also the table of flags showing which characters are allowed in -- identifiers. type Translate_Table is array (Character) of Character; -- Type used to describe translate tables type Char_Array_Flags is array (Character) of Boolean; -- Type used for character attribute arrays. Note that we deliberately -- do NOT pack this table, since we don't want the extra overhead of -- accessing a packed bit string. ---------------------------------------------- -- Character Tables For Current Compilation -- ---------------------------------------------- procedure Initialize; -- Routine to initialize following character tables, whose content depends -- on the character code being used to represent the source program. In -- particular, the use of the upper half of the 8-bit code set varies. -- The character set in use is specified by the value stored in -- Opt.Identifier_Character_Set, which has the following settings: -- '1' Latin-1 (ISO-8859-1) -- '2' Latin-2 (ISO-8859-2) -- '3' Latin-3 (ISO-8859-3) -- '4' Latin-4 (ISO-8859-4) -- '5' Cyrillic (ISO-8859-5) -- 'p' IBM PC (code page 437) -- '8' IBM PC (code page 850) -- '9' Latin-9 (ISO-8859-15) -- 'f' Full upper set (all distinct) -- 'n' No upper characters (Ada/83 rules) -- 'w' Latin-1 plus wide characters also allowed function Is_Upper_Case_Letter (C : Character) return Boolean; pragma Inline (Is_Upper_Case_Letter); -- Determine if character is upper case letter function Is_Lower_Case_Letter (C : Character) return Boolean; pragma Inline (Is_Lower_Case_Letter); -- Determine if character is lower case letter Fold_Upper : Translate_Table; -- Table to fold lower case identifier letters to upper case Fold_Lower : Translate_Table; -- Table to fold upper case identifier letters to lower case Identifier_Char : Char_Array_Flags; -- This table has True entries for all characters that can legally appear -- in identifiers, including digits, the underline character, all letters -- including upper and lower case and extended letters (as controlled by -- the setting of Opt.Identifier_Character_Set), left bracket for brackets -- notation wide characters and also ESC if wide characters are permitted -- in identifiers using escape sequences starting with ESC. end Csets; gprbuild-gpl-2014-src/gnat/scans.adb0000644000076700001450000002106112323721731016643 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S C A N S -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Snames; use Snames; package body Scans is ----------------------------- -- Initialize_Ada_Keywords -- ----------------------------- procedure Initialize_Ada_Keywords is procedure Set_Reserved (N : Name_Id; T : Token_Type); pragma Inline (Set_Reserved); -- Set given name as a reserved word (T is the corresponding token) ------------------ -- Set_Reserved -- ------------------ procedure Set_Reserved (N : Name_Id; T : Token_Type) is begin -- Set up Token_Type values in Names table entries for reserved -- words. We use the Pos value of the Token_Type value. Note that -- Is_Keyword_Name relies on the fact that Token_Type'Val (0) is not -- a reserved word. Set_Name_Table_Byte (N, Token_Type'Pos (T)); end Set_Reserved; -- Start of processing for Initialize_Ada_Keywords begin -- Establish reserved words Set_Reserved (Name_Abort, Tok_Abort); Set_Reserved (Name_Abs, Tok_Abs); Set_Reserved (Name_Abstract, Tok_Abstract); Set_Reserved (Name_Accept, Tok_Accept); Set_Reserved (Name_Access, Tok_Access); Set_Reserved (Name_And, Tok_And); Set_Reserved (Name_Aliased, Tok_Aliased); Set_Reserved (Name_All, Tok_All); Set_Reserved (Name_Array, Tok_Array); Set_Reserved (Name_At, Tok_At); Set_Reserved (Name_Begin, Tok_Begin); Set_Reserved (Name_Body, Tok_Body); Set_Reserved (Name_Case, Tok_Case); Set_Reserved (Name_Constant, Tok_Constant); Set_Reserved (Name_Declare, Tok_Declare); Set_Reserved (Name_Delay, Tok_Delay); Set_Reserved (Name_Delta, Tok_Delta); Set_Reserved (Name_Digits, Tok_Digits); Set_Reserved (Name_Do, Tok_Do); Set_Reserved (Name_Else, Tok_Else); Set_Reserved (Name_Elsif, Tok_Elsif); Set_Reserved (Name_End, Tok_End); Set_Reserved (Name_Entry, Tok_Entry); Set_Reserved (Name_Exception, Tok_Exception); Set_Reserved (Name_Exit, Tok_Exit); Set_Reserved (Name_For, Tok_For); Set_Reserved (Name_Function, Tok_Function); Set_Reserved (Name_Generic, Tok_Generic); Set_Reserved (Name_Goto, Tok_Goto); Set_Reserved (Name_If, Tok_If); Set_Reserved (Name_In, Tok_In); Set_Reserved (Name_Is, Tok_Is); Set_Reserved (Name_Limited, Tok_Limited); Set_Reserved (Name_Loop, Tok_Loop); Set_Reserved (Name_Mod, Tok_Mod); Set_Reserved (Name_New, Tok_New); Set_Reserved (Name_Not, Tok_Not); Set_Reserved (Name_Null, Tok_Null); Set_Reserved (Name_Of, Tok_Of); Set_Reserved (Name_Or, Tok_Or); Set_Reserved (Name_Others, Tok_Others); Set_Reserved (Name_Out, Tok_Out); Set_Reserved (Name_Package, Tok_Package); Set_Reserved (Name_Pragma, Tok_Pragma); Set_Reserved (Name_Private, Tok_Private); Set_Reserved (Name_Procedure, Tok_Procedure); Set_Reserved (Name_Protected, Tok_Protected); Set_Reserved (Name_Raise, Tok_Raise); Set_Reserved (Name_Range, Tok_Range); Set_Reserved (Name_Record, Tok_Record); Set_Reserved (Name_Rem, Tok_Rem); Set_Reserved (Name_Renames, Tok_Renames); Set_Reserved (Name_Requeue, Tok_Requeue); Set_Reserved (Name_Return, Tok_Return); Set_Reserved (Name_Reverse, Tok_Reverse); Set_Reserved (Name_Select, Tok_Select); Set_Reserved (Name_Separate, Tok_Separate); Set_Reserved (Name_Subtype, Tok_Subtype); Set_Reserved (Name_Tagged, Tok_Tagged); Set_Reserved (Name_Task, Tok_Task); Set_Reserved (Name_Terminate, Tok_Terminate); Set_Reserved (Name_Then, Tok_Then); Set_Reserved (Name_Type, Tok_Type); Set_Reserved (Name_Until, Tok_Until); Set_Reserved (Name_Use, Tok_Use); Set_Reserved (Name_When, Tok_When); Set_Reserved (Name_While, Tok_While); Set_Reserved (Name_With, Tok_With); Set_Reserved (Name_Xor, Tok_Xor); -- Ada 2005 reserved words Set_Reserved (Name_Interface, Tok_Interface); Set_Reserved (Name_Overriding, Tok_Overriding); Set_Reserved (Name_Synchronized, Tok_Synchronized); -- Ada 2012 reserved words Set_Reserved (Name_Some, Tok_Some); end Initialize_Ada_Keywords; ------------------------ -- Restore_Scan_State -- ------------------------ procedure Restore_Scan_State (Saved_State : Saved_Scan_State) is begin Scan_Ptr := Saved_State.Save_Scan_Ptr; Token := Saved_State.Save_Token; Token_Ptr := Saved_State.Save_Token_Ptr; Current_Line_Start := Saved_State.Save_Current_Line_Start; Start_Column := Saved_State.Save_Start_Column; Checksum := Saved_State.Save_Checksum; First_Non_Blank_Location := Saved_State.Save_First_Non_Blank_Location; Token_Node := Saved_State.Save_Token_Node; Token_Name := Saved_State.Save_Token_Name; Prev_Token := Saved_State.Save_Prev_Token; Prev_Token_Ptr := Saved_State.Save_Prev_Token_Ptr; end Restore_Scan_State; --------------------- -- Save_Scan_State -- --------------------- procedure Save_Scan_State (Saved_State : out Saved_Scan_State) is begin Saved_State.Save_Scan_Ptr := Scan_Ptr; Saved_State.Save_Token := Token; Saved_State.Save_Token_Ptr := Token_Ptr; Saved_State.Save_Current_Line_Start := Current_Line_Start; Saved_State.Save_Start_Column := Start_Column; Saved_State.Save_Checksum := Checksum; Saved_State.Save_First_Non_Blank_Location := First_Non_Blank_Location; Saved_State.Save_Token_Node := Token_Node; Saved_State.Save_Token_Name := Token_Name; Saved_State.Save_Prev_Token := Prev_Token; Saved_State.Save_Prev_Token_Ptr := Prev_Token_Ptr; end Save_Scan_State; end Scans; gprbuild-gpl-2014-src/gnat/prj-ext.ads0000644000076700001450000001437512323721731017160 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . E X T -- -- -- -- S p e c -- -- -- -- Copyright (C) 2000-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- Subprograms to set, get and cache external references, to be used as -- External functions in project files. with GNAT.Dynamic_HTables; package Prj.Ext is ------------------------- -- External References -- ------------------------- -- External references influence the way a project tree is processed (in -- particular they provide the values for the typed string variables that -- are then used in case constructions). -- External references are project-tree specific, so that when multiple -- trees are loaded in parallel we can have different scenarios (or even -- load the same tree twice and see different views of it). type External_References is private; No_External_Refs : constant External_References; procedure Initialize (Self : out External_References; Copy_From : External_References := No_External_Refs); -- Initialize Self, and copy all values from Copy_From if needed. -- This has no effect if Self was already initialized. procedure Free (Self : in out External_References); -- Free memory used by Self type External_Source is (From_Command_Line, From_Environment, From_External_Attribute); -- Indicates where was the value of an external reference defined. They are -- prioritized in that order, so that a user can always use the command -- line to override a value coming from his environment, or an environment -- variable to override a value defined in an aggregate project through the -- "for External()..." attribute. procedure Add (Self : External_References; External_Name : String; Value : String; Source : External_Source := External_Source'First; Silent : Boolean := False); -- Add an external reference (or modify an existing one). No overriding is -- done if the Source's priority is less than the one used to previously -- set the value of the variable. The default for Source is such that -- overriding always occurs. When Silent is True, nothing is output even -- with non default verbosity. function Value_Of (Self : External_References; External_Name : Name_Id; With_Default : Name_Id := No_Name) return Name_Id; -- Get the value of an external reference, and cache it for future uses function Check (Self : External_References; Declaration : String) return Boolean; -- Check that an external declaration = is correct. -- If it is correct, the external reference is Added. procedure Reset (Self : External_References); -- Clear the internal data structure that stores the external references -- and free any allocated memory. private -- Use a Static_HTable, rather than a Simple_HTable -- The issue is that we need to be able to copy the contents of the table -- (in Initialize), but this isn't doable for Simple_HTable for which -- iterators do not return the key. type Name_To_Name; type Name_To_Name_Ptr is access all Name_To_Name; type Name_To_Name is record Key : Name_Id; Value : Name_Id; Source : External_Source; Next : Name_To_Name_Ptr; end record; procedure Set_Next (E : Name_To_Name_Ptr; Next : Name_To_Name_Ptr); function Next (E : Name_To_Name_Ptr) return Name_To_Name_Ptr; function Get_Key (E : Name_To_Name_Ptr) return Name_Id; package Name_To_Name_HTable is new GNAT.Dynamic_HTables.Static_HTable (Header_Num => Header_Num, Element => Name_To_Name, Elmt_Ptr => Name_To_Name_Ptr, Null_Ptr => null, Set_Next => Set_Next, Next => Next, Key => Name_Id, Get_Key => Get_Key, Hash => Hash, Equal => "="); -- General type for htables associating name_id to name_id. This is in -- particular used to store the values of external references. type Instance_Access is access all Name_To_Name_HTable.Instance; type External_References is record Refs : Instance_Access; -- External references are stored in this hash table (and manipulated -- through subprogrames in prj-ext.ads). External references are -- project-tree specific so that one can load the same tree twice but -- have two views of it, for instance. end record; No_External_Refs : constant External_References := (Refs => null); end Prj.Ext; gprbuild-gpl-2014-src/gnat/errout.adb0000644000076700001450000032667612323721731017100 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- E R R O U T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- Warning: Error messages can be generated during Gigi processing by direct -- calls to error message routines, so it is essential that the processing -- in this body be consistent with the requirements for the Gigi processing -- environment, and that in particular, no disallowed table expansion is -- allowed to occur. with Atree; use Atree; with Casing; use Casing; with Csets; use Csets; with Debug; use Debug; with Einfo; use Einfo; with Erroutc; use Erroutc; with Fname; use Fname; with Gnatvsn; use Gnatvsn; with Hostparm; use Hostparm; with Lib; use Lib; with Opt; use Opt; with Nlists; use Nlists; with Output; use Output; with Scans; use Scans; with Sem_Aux; use Sem_Aux; with Sinput; use Sinput; with Sinfo; use Sinfo; with Snames; use Snames; with Stand; use Stand; with Stylesw; use Stylesw; with Uname; use Uname; package body Errout is Errors_Must_Be_Ignored : Boolean := False; -- Set to True by procedure Set_Ignore_Errors (True), when calls to error -- message procedures should be ignored (when parsing irrelevant text in -- sources being preprocessed). Finalize_Called : Boolean := False; -- Set True if the Finalize routine has been called Warn_On_Instance : Boolean; -- Flag set true for warning message to be posted on instance ------------------------------------ -- Table of Non-Instance Messages -- ------------------------------------ -- This table contains an entry for every error message processed by the -- Error_Msg routine that is not posted on generic (or inlined) instance. -- As explained in further detail in the Error_Msg procedure body, this -- table is used to avoid posting redundant messages on instances. type NIM_Record is record Msg : String_Ptr; Loc : Source_Ptr; end record; -- Type used to store text and location of one message package Non_Instance_Msgs is new Table.Table ( Table_Component_Type => NIM_Record, Table_Index_Type => Int, Table_Low_Bound => 1, Table_Initial => 100, Table_Increment => 100, Table_Name => "Non_Instance_Msgs"); ----------------------- -- Local Subprograms -- ----------------------- procedure Error_Msg_Internal (Msg : String; Sptr : Source_Ptr; Optr : Source_Ptr; Msg_Cont : Boolean); -- This is the low level routine used to post messages after dealing with -- the issue of messages placed on instantiations (which get broken up -- into separate calls in Error_Msg). Sptr is the location on which the -- flag will be placed in the output. In the case where the flag is on -- the template, this points directly to the template, not to one of the -- instantiation copies of the template. Optr is the original location -- used to flag the error, and this may indeed point to an instantiation -- copy. So typically we can see Optr pointing to the template location -- in an instantiation copy when Sptr points to the source location of -- the actual instantiation (i.e the line with the new). Msg_Cont is -- set true if this is a continuation message. function No_Warnings (N : Node_Or_Entity_Id) return Boolean; -- Determines if warnings should be suppressed for the given node function OK_Node (N : Node_Id) return Boolean; -- Determines if a node is an OK node to place an error message on (return -- True) or if the error message should be suppressed (return False). A -- message is suppressed if the node already has an error posted on it, -- or if it refers to an Etype that has an error posted on it, or if -- it references an Entity that has an error posted on it. procedure Output_Source_Line (L : Physical_Line_Number; Sfile : Source_File_Index; Errs : Boolean); -- Outputs text of source line L, in file S, together with preceding line -- number, as described above for Output_Line_Number. The Errs parameter -- indicates if there are errors attached to the line, which forces -- listing on, even in the presence of pragma List (Off). procedure Set_Msg_Insertion_Column; -- Handle column number insertion (@ insertion character) procedure Set_Msg_Insertion_Node; -- Handle node (name from node) insertion (& insertion character) procedure Set_Msg_Insertion_Type_Reference (Flag : Source_Ptr); -- Handle type reference (right brace insertion character). Flag is the -- location of the flag, which is provided for the internal call to -- Set_Msg_Insertion_Line_Number, procedure Set_Msg_Insertion_Unit_Name (Suffix : Boolean := True); -- Handle unit name insertion ($ insertion character). Depending on Boolean -- parameter Suffix, (spec) or (body) is appended after the unit name. procedure Set_Msg_Node (Node : Node_Id); -- Add the sequence of characters for the name associated with the given -- node to the current message. For N_Designator, N_Selected_Component, -- N_Defining_Program_Unit_Name, and N_Expanded_Name, the Prefix is -- included as well. procedure Set_Msg_Text (Text : String; Flag : Source_Ptr); -- Add a sequence of characters to the current message. The characters may -- be one of the special insertion characters (see documentation in spec). -- Flag is the location at which the error is to be posted, which is used -- to determine whether or not the # insertion needs a file name. The -- variables Msg_Buffer are set on return Msglen. procedure Set_Posted (N : Node_Id); -- Sets the Error_Posted flag on the given node, and all its parents that -- are subexpressions and then on the parent non-subexpression construct -- that contains the original expression. If that parent is a named -- association, the flag is further propagated to its parent. This is done -- in order to guard against cascaded errors. Note that this call has an -- effect for a serious error only. procedure Set_Qualification (N : Nat; E : Entity_Id); -- Outputs up to N levels of qualification for the given entity. For -- example, the entity A.B.C.D will output B.C. if N = 2. function Special_Msg_Delete (Msg : String; N : Node_Or_Entity_Id; E : Node_Or_Entity_Id) return Boolean; -- This function is called from Error_Msg_NEL, passing the message Msg, -- node N on which the error is to be posted, and the entity or node E -- to be used for an & insertion in the message if any. The job of this -- procedure is to test for certain cascaded messages that we would like -- to suppress. If the message is to be suppressed then we return True. -- If the message should be generated (the normal case) False is returned. procedure Unwind_Internal_Type (Ent : in out Entity_Id); -- This procedure is given an entity id for an internal type, i.e. a type -- with an internal name. It unwinds the type to try to get to something -- reasonably printable, generating prefixes like "subtype of", "access -- to", etc along the way in the buffer. The value in Ent on return is the -- final name to be printed. Hopefully this is not an internal name, but in -- some internal name cases, it is an internal name, and has to be printed -- anyway (although in this case the message has been killed if possible). -- The global variable Class_Flag is set to True if the resulting entity -- should have 'Class appended to its name (see Add_Class procedure), and -- is otherwise unchanged. procedure VMS_Convert; -- This procedure has no effect if called when the host is not OpenVMS. If -- the host is indeed OpenVMS, then the error message stored in Msg_Buffer -- is scanned for appearances of switch names which need converting to -- corresponding VMS qualifier names. See Gnames/Vnames table in Errout -- spec for precise definition of the conversion that is performed by this -- routine in OpenVMS mode. function Warn_Insertion return String; -- This is called for warning messages only (so Warning_Msg_Char is set) -- and returns a corresponding string to use at the beginning of generated -- auxiliary messages, such as "in instantiation at ...". -- 'a' .. 'z' returns "?x?" -- 'A' .. 'Z' returns "?X?" -- '*' returns "?*?" -- '$' returns "?$?info: " -- ' ' returns " " -- No other settings are valid ----------------------- -- Change_Error_Text -- ----------------------- procedure Change_Error_Text (Error_Id : Error_Msg_Id; New_Msg : String) is Save_Next : Error_Msg_Id; Err_Id : Error_Msg_Id := Error_Id; begin Set_Msg_Text (New_Msg, Errors.Table (Error_Id).Sptr); Errors.Table (Error_Id).Text := new String'(Msg_Buffer (1 .. Msglen)); -- If in immediate error message mode, output modified error message now -- This is just a bit tricky, because we want to output just a single -- message, and the messages we modified is already linked in. We solve -- this by temporarily resetting its forward pointer to empty. if Debug_Flag_OO then Save_Next := Errors.Table (Error_Id).Next; Errors.Table (Error_Id).Next := No_Error_Msg; Write_Eol; Output_Source_Line (Errors.Table (Error_Id).Line, Errors.Table (Error_Id).Sfile, True); Output_Error_Msgs (Err_Id); Errors.Table (Error_Id).Next := Save_Next; end if; end Change_Error_Text; ------------------------ -- Compilation_Errors -- ------------------------ function Compilation_Errors return Boolean is begin if not Finalize_Called then raise Program_Error; else return Erroutc.Compilation_Errors; end if; end Compilation_Errors; -------------------------------------- -- Delete_Warning_And_Continuations -- -------------------------------------- procedure Delete_Warning_And_Continuations (Msg : Error_Msg_Id) is Id : Error_Msg_Id; begin pragma Assert (not Errors.Table (Msg).Msg_Cont); Id := Msg; loop declare M : Error_Msg_Object renames Errors.Table (Id); begin if not M.Deleted then M.Deleted := True; Warnings_Detected := Warnings_Detected - 1; if M.Warn_Err then Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; end if; end if; Id := M.Next; exit when Id = No_Error_Msg; exit when not Errors.Table (Id).Msg_Cont; end; end loop; end Delete_Warning_And_Continuations; --------------- -- Error_Msg -- --------------- -- Error_Msg posts a flag at the given location, except that if the -- Flag_Location points within a generic template and corresponds to an -- instantiation of this generic template, then the actual message will be -- posted on the generic instantiation, along with additional messages -- referencing the generic declaration. procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr) is Sindex : Source_File_Index; -- Source index for flag location Orig_Loc : Source_Ptr; -- Original location of Flag_Location (i.e. location in original -- template in instantiation case, otherwise unchanged). begin -- It is a fatal error to issue an error message when scanning from the -- internal source buffer (see Sinput for further documentation) pragma Assert (Sinput.Source /= Internal_Source_Ptr); -- Return if all errors are to be ignored if Errors_Must_Be_Ignored then return; end if; -- If we already have messages, and we are trying to place a message at -- No_Location or in package Standard, then just ignore the attempt -- since we assume that what is happening is some cascaded junk. Note -- that this is safe in the sense that proceeding will surely bomb. if Flag_Location < First_Source_Ptr and then Total_Errors_Detected > 0 then return; end if; -- Start of processing for new message Sindex := Get_Source_File_Index (Flag_Location); Prescan_Message (Msg); Orig_Loc := Original_Location (Flag_Location); -- If the current location is in an instantiation, the issue arises of -- whether to post the message on the template or the instantiation. -- The way we decide is to see if we have posted the same message on -- the template when we compiled the template (the template is always -- compiled before any instantiations). For this purpose, we use a -- separate table of messages. The reason we do this is twofold: -- First, the messages can get changed by various processing -- including the insertion of tokens etc, making it hard to -- do the comparison. -- Second, we will suppress a warning on a template if it is not in -- the current extended source unit. That's reasonable and means we -- don't want the warning on the instantiation here either, but it -- does mean that the main error table would not in any case include -- the message. if Flag_Location = Orig_Loc then Non_Instance_Msgs.Append ((new String'(Msg), Flag_Location)); Warn_On_Instance := False; -- Here we have an instance message else -- Delete if debug flag off, and this message duplicates a message -- already posted on the corresponding template if not Debug_Flag_GG then for J in Non_Instance_Msgs.First .. Non_Instance_Msgs.Last loop if Msg = Non_Instance_Msgs.Table (J).Msg.all and then Non_Instance_Msgs.Table (J).Loc = Orig_Loc then return; end if; end loop; end if; -- No duplicate, so error/warning will be posted on instance Warn_On_Instance := Is_Warning_Msg; end if; -- Ignore warning message that is suppressed for this location. Note -- that style checks are not considered warning messages for this -- purpose. if Is_Warning_Msg and then Warnings_Suppressed (Orig_Loc) /= No_String then return; -- For style messages, check too many messages so far elsif Is_Style_Msg and then Maximum_Messages /= 0 and then Warnings_Detected >= Maximum_Messages then return; end if; -- The idea at this stage is that we have two kinds of messages -- First, we have those messages that are to be placed as requested at -- Flag_Location. This includes messages that have nothing to do with -- generics, and also messages placed on generic templates that reflect -- an error in the template itself. For such messages we simply call -- Error_Msg_Internal to place the message in the requested location. if Instantiation (Sindex) = No_Location then Error_Msg_Internal (Msg, Flag_Location, Flag_Location, False); return; end if; -- If we are trying to flag an error in an instantiation, we may have -- a generic contract violation. What we generate in this case is: -- instantiation error at ... -- original error message -- or -- warning: in instantiation at -- warning: original warning message -- All these messages are posted at the location of the top level -- instantiation. If there are nested instantiations, then the -- instantiation error message can be repeated, pointing to each -- of the relevant instantiations. -- Note: the instantiation mechanism is also shared for inlining of -- subprogram bodies when front end inlining is done. In this case the -- messages have the form: -- in inlined body at ... -- original error message -- or -- warning: in inlined body at -- warning: original warning message -- OK, here we have an instantiation error, and we need to generate the -- error on the instantiation, rather than on the template. declare Actual_Error_Loc : Source_Ptr; -- Location of outer level instantiation in instantiation case, or -- just a copy of Flag_Location in the normal case. This is the -- location where all error messages will actually be posted. Save_Error_Msg_Sloc : constant Source_Ptr := Error_Msg_Sloc; -- Save possible location set for caller's message. We need to use -- Error_Msg_Sloc for the location of the instantiation error but we -- have to preserve a possible original value. X : Source_File_Index; Msg_Cont_Status : Boolean; -- Used to label continuation lines in instantiation case with -- proper Msg_Cont status. begin -- Loop to find highest level instantiation, where all error -- messages will be placed. X := Sindex; loop Actual_Error_Loc := Instantiation (X); X := Get_Source_File_Index (Actual_Error_Loc); exit when Instantiation (X) = No_Location; end loop; -- Since we are generating the messages at the instantiation point in -- any case, we do not want the references to the bad lines in the -- instance to be annotated with the location of the instantiation. Suppress_Instance_Location := True; Msg_Cont_Status := False; -- Loop to generate instantiation messages Error_Msg_Sloc := Flag_Location; X := Get_Source_File_Index (Flag_Location); while Instantiation (X) /= No_Location loop -- Suppress instantiation message on continuation lines if Msg (Msg'First) /= '\' then -- Case of inlined body if Inlined_Body (X) then if Is_Warning_Msg or Is_Style_Msg then Error_Msg_Internal (Warn_Insertion & "in inlined body #", Actual_Error_Loc, Flag_Location, Msg_Cont_Status); else Error_Msg_Internal ("error in inlined body #", Actual_Error_Loc, Flag_Location, Msg_Cont_Status); end if; -- Case of generic instantiation else if Is_Warning_Msg or else Is_Style_Msg then Error_Msg_Internal (Warn_Insertion & "in instantiation #", Actual_Error_Loc, Flag_Location, Msg_Cont_Status); else Error_Msg_Internal ("instantiation error #", Actual_Error_Loc, Flag_Location, Msg_Cont_Status); end if; end if; end if; Error_Msg_Sloc := Instantiation (X); X := Get_Source_File_Index (Error_Msg_Sloc); Msg_Cont_Status := True; end loop; Suppress_Instance_Location := False; Error_Msg_Sloc := Save_Error_Msg_Sloc; -- Here we output the original message on the outer instantiation Error_Msg_Internal (Msg, Actual_Error_Loc, Flag_Location, Msg_Cont_Status); end; end Error_Msg; -------------------------------- -- Error_Msg_Ada_2012_Feature -- -------------------------------- procedure Error_Msg_Ada_2012_Feature (Feature : String; Loc : Source_Ptr) is begin if Ada_Version < Ada_2012 then Error_Msg (Feature & " is an Ada 2012 feature", Loc); if No (Ada_Version_Pragma) then Error_Msg ("\unit must be compiled with -gnat2012 switch", Loc); else Error_Msg_Sloc := Sloc (Ada_Version_Pragma); Error_Msg ("\incompatible with Ada version set#", Loc); end if; end if; end Error_Msg_Ada_2012_Feature; ------------------ -- Error_Msg_AP -- ------------------ procedure Error_Msg_AP (Msg : String) is S1 : Source_Ptr; C : Character; begin -- If we had saved the Scan_Ptr value after scanning the previous -- token, then we would have exactly the right place for putting -- the flag immediately at hand. However, that would add at least -- two instructions to a Scan call *just* to service the possibility -- of an Error_Msg_AP call. So instead we reconstruct that value. -- We have two possibilities, start with Prev_Token_Ptr and skip over -- the current token, which is made harder by the possibility that this -- token may be in error, or start with Token_Ptr and work backwards. -- We used to take the second approach, but it's hard because of -- comments, and harder still because things that look like comments -- can appear inside strings. So now we take the first approach. -- Note: in the case where there is no previous token, Prev_Token_Ptr -- is set to Source_First, which is a reasonable position for the -- error flag in this situation. S1 := Prev_Token_Ptr; C := Source (S1); -- If the previous token is a string literal, we need a special approach -- since there may be white space inside the literal and we don't want -- to stop on that white space. -- Note: since this is an error recovery issue anyway, it is not worth -- worrying about special UTF_32 line terminator characters here. if Prev_Token = Tok_String_Literal then loop S1 := S1 + 1; if Source (S1) = C then S1 := S1 + 1; exit when Source (S1) /= C; elsif Source (S1) in Line_Terminator then exit; end if; end loop; -- Character literal also needs special handling elsif Prev_Token = Tok_Char_Literal then S1 := S1 + 3; -- Otherwise we search forward for the end of the current token, marked -- by a line terminator, white space, a comment symbol or if we bump -- into the following token (i.e. the current token). -- Again, it is not worth worrying about UTF_32 special line terminator -- characters in this context, since this is only for error recovery. else while Source (S1) not in Line_Terminator and then Source (S1) /= ' ' and then Source (S1) /= ASCII.HT and then (Source (S1) /= '-' or else Source (S1 + 1) /= '-') and then S1 /= Token_Ptr loop S1 := S1 + 1; end loop; end if; -- S1 is now set to the location for the flag Error_Msg (Msg, S1); end Error_Msg_AP; ------------------ -- Error_Msg_BC -- ------------------ procedure Error_Msg_BC (Msg : String) is begin -- If we are at end of file, post the flag after the previous token if Token = Tok_EOF then Error_Msg_AP (Msg); -- If we are at start of file, post the flag at the current token elsif Token_Ptr = Source_First (Current_Source_File) then Error_Msg_SC (Msg); -- If the character before the current token is a space or a horizontal -- tab, then we place the flag on this character (in the case of a tab -- we would really like to place it in the "last" character of the tab -- space, but that it too much trouble to worry about). elsif Source (Token_Ptr - 1) = ' ' or else Source (Token_Ptr - 1) = ASCII.HT then Error_Msg (Msg, Token_Ptr - 1); -- If there is no space or tab before the current token, then there is -- no room to place the flag before the token, so we place it on the -- token instead (this happens for example at the start of a line). else Error_Msg (Msg, Token_Ptr); end if; end Error_Msg_BC; ------------------- -- Error_Msg_CRT -- ------------------- procedure Error_Msg_CRT (Feature : String; N : Node_Id) is CNRT : constant String := " not allowed in no run time mode"; CCRT : constant String := " not supported by configuration>"; S : String (1 .. Feature'Length + 1 + CCRT'Length); L : Natural; begin S (1) := '|'; S (2 .. Feature'Length + 1) := Feature; L := Feature'Length + 2; if No_Run_Time_Mode then S (L .. L + CNRT'Length - 1) := CNRT; L := L + CNRT'Length - 1; else pragma Assert (Configurable_Run_Time_Mode); S (L .. L + CCRT'Length - 1) := CCRT; L := L + CCRT'Length - 1; end if; Error_Msg_N (S (1 .. L), N); Configurable_Run_Time_Violations := Configurable_Run_Time_Violations + 1; end Error_Msg_CRT; ------------------ -- Error_Msg_PT -- ------------------ procedure Error_Msg_PT (Typ : Node_Id; Subp : Node_Id) is begin Error_Msg_NE ("first formal of & must be of mode `OUT`, `IN OUT` or " & "access-to-variable", Typ, Subp); Error_Msg_N ("\in order to be overridden by protected procedure or entry " & "(RM 9.4(11.9/2))", Typ); end Error_Msg_PT; ----------------- -- Error_Msg_F -- ----------------- procedure Error_Msg_F (Msg : String; N : Node_Id) is begin Error_Msg_NEL (Msg, N, N, Sloc (First_Node (N))); end Error_Msg_F; ------------------ -- Error_Msg_FE -- ------------------ procedure Error_Msg_FE (Msg : String; N : Node_Id; E : Node_Or_Entity_Id) is begin Error_Msg_NEL (Msg, N, E, Sloc (First_Node (N))); end Error_Msg_FE; ------------------------ -- Error_Msg_Internal -- ------------------------ procedure Error_Msg_Internal (Msg : String; Sptr : Source_Ptr; Optr : Source_Ptr; Msg_Cont : Boolean) is Next_Msg : Error_Msg_Id; -- Pointer to next message at insertion point Prev_Msg : Error_Msg_Id; -- Pointer to previous message at insertion point Temp_Msg : Error_Msg_Id; Warn_Err : Boolean; -- Set if warning to be treated as error procedure Handle_Serious_Error; -- Internal procedure to do all error message handling for a serious -- error message, other than bumping the error counts and arranging -- for the message to be output. -------------------------- -- Handle_Serious_Error -- -------------------------- procedure Handle_Serious_Error is begin -- Turn off code generation if not done already if Operating_Mode = Generate_Code then Operating_Mode := Check_Semantics; Expander_Active := False; end if; -- Set the fatal error flag in the unit table unless we are in -- Try_Semantics mode. This stops the semantics from being performed -- if we find a serious error. This is skipped if we are currently -- dealing with the configuration pragma file. if not Try_Semantics and then Current_Source_Unit /= No_Unit then Set_Fatal_Error (Get_Source_Unit (Sptr)); end if; end Handle_Serious_Error; -- Start of processing for Error_Msg_Internal begin if Raise_Exception_On_Error /= 0 then raise Error_Msg_Exception; end if; Continuation := Msg_Cont; Continuation_New_Line := False; Suppress_Message := False; Kill_Message := False; Set_Msg_Text (Msg, Sptr); -- Kill continuation if parent message killed if Continuation and Last_Killed then return; end if; -- Return without doing anything if message is suppressed if Suppress_Message and then not All_Errors_Mode and then not Is_Warning_Msg and then not Is_Unconditional_Msg then if not Continuation then Last_Killed := True; end if; return; end if; -- Return without doing anything if message is killed and this is not -- the first error message. The philosophy is that if we get a weird -- error message and we already have had a message, then we hope the -- weird message is a junk cascaded message if Kill_Message and then not All_Errors_Mode and then Total_Errors_Detected /= 0 then if not Continuation then Last_Killed := True; end if; return; end if; -- Special check for warning message to see if it should be output if Is_Warning_Msg then -- Immediate return if warning message and warnings are suppressed if Warnings_Suppressed (Optr) /= No_String or else Warnings_Suppressed (Sptr) /= No_String then Cur_Msg := No_Error_Msg; return; end if; -- If the flag location is in the main extended source unit then for -- sure we want the warning since it definitely belongs if In_Extended_Main_Source_Unit (Sptr) then null; -- If the main unit has not been read yet. the warning must be on -- a configuration file: gnat.adc or user-defined. This means we -- are not parsing the main unit yet, so skip following checks. elsif No (Cunit (Main_Unit)) then null; -- If the flag location is not in the main extended source unit, then -- we want to eliminate the warning, unless it is in the extended -- main code unit and we want warnings on the instance. elsif In_Extended_Main_Code_Unit (Sptr) and then Warn_On_Instance then null; -- Keep warning if debug flag G set elsif Debug_Flag_GG then null; -- Keep warning if message text contains !! elsif Has_Double_Exclam then null; -- Here is where we delete a warning from a with'ed unit else Cur_Msg := No_Error_Msg; if not Continuation then Last_Killed := True; end if; return; end if; end if; -- If message is to be ignored in special ignore message mode, this is -- where we do this special processing, bypassing message output. if Ignore_Errors_Enable > 0 then if Is_Serious_Error then Handle_Serious_Error; end if; return; end if; -- If error message line length set, and this is a continuation message -- then all we do is to append the text to the text of the last message -- with a comma space separator (eliminating a possible (style) or -- info prefix). if Error_Msg_Line_Length /= 0 and then Continuation then Cur_Msg := Errors.Last; declare Oldm : String_Ptr := Errors.Table (Cur_Msg).Text; Newm : String (1 .. Oldm'Last + 2 + Msglen); Newl : Natural; M : Natural; begin -- First copy old message to new one and free it Newm (Oldm'Range) := Oldm.all; Newl := Oldm'Length; Free (Oldm); -- Remove (style) or info: at start of message if Msglen > 8 and then Msg_Buffer (1 .. 8) = "(style) " then M := 9; elsif Msglen > 6 and then Msg_Buffer (1 .. 6) = "info: " then M := 7; else M := 1; end if; -- Now deal with separation between messages. Normally this is -- simply comma space, but there are some special cases. -- If continuation new line, then put actual NL character in msg if Continuation_New_Line then Newl := Newl + 1; Newm (Newl) := ASCII.LF; -- If continuation message is enclosed in parentheses, then -- special treatment (don't need a comma, and we want to combine -- successive parenthetical remarks into a single one with -- separating commas). elsif Msg_Buffer (M) = '(' and then Msg_Buffer (Msglen) = ')' then -- Case where existing message ends in right paren, remove -- and separate parenthetical remarks with a comma. if Newm (Newl) = ')' then Newm (Newl) := ','; Msg_Buffer (M) := ' '; -- Case where we are adding new parenthetical comment else Newl := Newl + 1; Newm (Newl) := ' '; end if; -- Case where continuation not in parens and no new line else Newm (Newl + 1 .. Newl + 2) := ", "; Newl := Newl + 2; end if; -- Append new message Newm (Newl + 1 .. Newl + Msglen - M + 1) := Msg_Buffer (M .. Msglen); Newl := Newl + Msglen - M + 1; Errors.Table (Cur_Msg).Text := new String'(Newm (1 .. Newl)); -- Update warning msg flag and message doc char if needed if Is_Warning_Msg then if not Errors.Table (Cur_Msg).Warn then Errors.Table (Cur_Msg).Warn := True; Errors.Table (Cur_Msg).Warn_Chr := Warning_Msg_Char; elsif Warning_Msg_Char /= ' ' then Errors.Table (Cur_Msg).Warn_Chr := Warning_Msg_Char; end if; end if; end; return; end if; -- Here we build a new error object Errors.Append ((Text => new String'(Msg_Buffer (1 .. Msglen)), Next => No_Error_Msg, Prev => No_Error_Msg, Sptr => Sptr, Optr => Optr, Sfile => Get_Source_File_Index (Sptr), Line => Get_Physical_Line_Number (Sptr), Col => Get_Column_Number (Sptr), Warn => Is_Warning_Msg, Info => Is_Info_Msg, Warn_Err => False, -- reset below Warn_Chr => Warning_Msg_Char, Style => Is_Style_Msg, Serious => Is_Serious_Error, Uncond => Is_Unconditional_Msg, Msg_Cont => Continuation, Deleted => False)); Cur_Msg := Errors.Last; -- Test if warning to be treated as error Warn_Err := Is_Warning_Msg and then (Warning_Treated_As_Error (Msg_Buffer (1 .. Msglen)) or else Warning_Treated_As_Error (Get_Warning_Tag (Cur_Msg))); -- Propagate Warn_Err to this message and preceding continuations for J in reverse 1 .. Errors.Last loop Errors.Table (J).Warn_Err := Warn_Err; exit when not Errors.Table (J).Msg_Cont; end loop; -- If immediate errors mode set, output error message now. Also output -- now if the -d1 debug flag is set (so node number message comes out -- just before actual error message) if Debug_Flag_OO or else Debug_Flag_1 then Write_Eol; Output_Source_Line (Errors.Table (Cur_Msg).Line, Errors.Table (Cur_Msg).Sfile, True); Temp_Msg := Cur_Msg; Output_Error_Msgs (Temp_Msg); -- If not in immediate errors mode, then we insert the message in the -- error chain for later output by Finalize. The messages are sorted -- first by unit (main unit comes first), and within a unit by source -- location (earlier flag location first in the chain). else -- First a quick check, does this belong at the very end of the chain -- of error messages. This saves a lot of time in the normal case if -- there are lots of messages. if Last_Error_Msg /= No_Error_Msg and then Errors.Table (Cur_Msg).Sfile = Errors.Table (Last_Error_Msg).Sfile and then (Sptr > Errors.Table (Last_Error_Msg).Sptr or else (Sptr = Errors.Table (Last_Error_Msg).Sptr and then Optr > Errors.Table (Last_Error_Msg).Optr)) then Prev_Msg := Last_Error_Msg; Next_Msg := No_Error_Msg; -- Otherwise do a full sequential search for the insertion point else Prev_Msg := No_Error_Msg; Next_Msg := First_Error_Msg; while Next_Msg /= No_Error_Msg loop exit when Errors.Table (Cur_Msg).Sfile < Errors.Table (Next_Msg).Sfile; if Errors.Table (Cur_Msg).Sfile = Errors.Table (Next_Msg).Sfile then exit when Sptr < Errors.Table (Next_Msg).Sptr or else (Sptr = Errors.Table (Next_Msg).Sptr and then Optr < Errors.Table (Next_Msg).Optr); end if; Prev_Msg := Next_Msg; Next_Msg := Errors.Table (Next_Msg).Next; end loop; end if; -- Now we insert the new message in the error chain. The insertion -- point for the message is after Prev_Msg and before Next_Msg. -- The possible insertion point for the new message is after Prev_Msg -- and before Next_Msg. However, this is where we do a special check -- for redundant parsing messages, defined as messages posted on the -- same line. The idea here is that probably such messages are junk -- from the parser recovering. In full errors mode, we don't do this -- deletion, but otherwise such messages are discarded at this stage. if Prev_Msg /= No_Error_Msg and then Errors.Table (Prev_Msg).Line = Errors.Table (Cur_Msg).Line and then Errors.Table (Prev_Msg).Sfile = Errors.Table (Cur_Msg).Sfile and then Compiler_State = Parsing and then not All_Errors_Mode then -- Don't delete unconditional messages and at this stage, don't -- delete continuation lines (we attempted to delete those earlier -- if the parent message was deleted. if not Errors.Table (Cur_Msg).Uncond and then not Continuation then -- Don't delete if prev msg is warning and new msg is an error. -- This is because we don't want a real error masked by a -- warning. In all other cases (that is parse errors for the -- same line that are not unconditional) we do delete the -- message. This helps to avoid junk extra messages from -- cascaded parsing errors if not (Errors.Table (Prev_Msg).Warn or else Errors.Table (Prev_Msg).Style) or else (Errors.Table (Cur_Msg).Warn or else Errors.Table (Cur_Msg).Style) then -- All tests passed, delete the message by simply returning -- without any further processing. if not Continuation then Last_Killed := True; end if; return; end if; end if; end if; -- Come here if message is to be inserted in the error chain if not Continuation then Last_Killed := False; end if; if Prev_Msg = No_Error_Msg then First_Error_Msg := Cur_Msg; else Errors.Table (Prev_Msg).Next := Cur_Msg; end if; Errors.Table (Cur_Msg).Next := Next_Msg; if Next_Msg = No_Error_Msg then Last_Error_Msg := Cur_Msg; end if; end if; -- Bump appropriate statistics count if Errors.Table (Cur_Msg).Warn or else Errors.Table (Cur_Msg).Style then Warnings_Detected := Warnings_Detected + 1; else Total_Errors_Detected := Total_Errors_Detected + 1; if Errors.Table (Cur_Msg).Serious then Serious_Errors_Detected := Serious_Errors_Detected + 1; Handle_Serious_Error; end if; end if; -- Record warning message issued if Errors.Table (Cur_Msg).Warn and then not Errors.Table (Cur_Msg).Msg_Cont then Warning_Msg := Cur_Msg; end if; -- If too many warnings turn off warnings if Maximum_Messages /= 0 then if Warnings_Detected = Maximum_Messages then Warning_Mode := Suppress; end if; -- If too many errors abandon compilation if Total_Errors_Detected = Maximum_Messages then raise Unrecoverable_Error; end if; end if; end Error_Msg_Internal; ----------------- -- Error_Msg_N -- ----------------- procedure Error_Msg_N (Msg : String; N : Node_Or_Entity_Id) is begin Error_Msg_NEL (Msg, N, N, Sloc (N)); end Error_Msg_N; ------------------ -- Error_Msg_NE -- ------------------ procedure Error_Msg_NE (Msg : String; N : Node_Or_Entity_Id; E : Node_Or_Entity_Id) is begin Error_Msg_NEL (Msg, N, E, Sloc (N)); end Error_Msg_NE; ------------------- -- Error_Msg_NEL -- ------------------- procedure Error_Msg_NEL (Msg : String; N : Node_Or_Entity_Id; E : Node_Or_Entity_Id; Flag_Location : Source_Ptr) is begin if Special_Msg_Delete (Msg, N, E) then return; end if; Prescan_Message (Msg); -- Special handling for warning messages if Is_Warning_Msg then -- Suppress if no warnings set for either entity or node if No_Warnings (N) or else No_Warnings (E) then -- Disable any continuation messages as well Last_Killed := True; return; end if; -- Suppress if inside loop that is known to be null or is probably -- null (case where loop executes only if invalid values present). -- In either case warnings in the loop are likely to be junk. declare P : Node_Id; begin P := Parent (N); while Present (P) loop if Nkind (P) = N_Loop_Statement and then Suppress_Loop_Warnings (P) then return; end if; P := Parent (P); end loop; end; end if; -- Test for message to be output if All_Errors_Mode or else Is_Unconditional_Msg or else Is_Warning_Msg or else OK_Node (N) or else (Msg (Msg'First) = '\' and then not Last_Killed) then Debug_Output (N); Error_Msg_Node_1 := E; Error_Msg (Msg, Flag_Location); else Last_Killed := True; end if; if not (Is_Warning_Msg or Is_Style_Msg) then Set_Posted (N); end if; end Error_Msg_NEL; ------------------ -- Error_Msg_NW -- ------------------ procedure Error_Msg_NW (Eflag : Boolean; Msg : String; N : Node_Or_Entity_Id) is begin if Eflag and then In_Extended_Main_Source_Unit (N) and then Comes_From_Source (N) then Error_Msg_NEL (Msg, N, N, Sloc (N)); end if; end Error_Msg_NW; ----------------- -- Error_Msg_S -- ----------------- procedure Error_Msg_S (Msg : String) is begin Error_Msg (Msg, Scan_Ptr); end Error_Msg_S; ------------------ -- Error_Msg_SC -- ------------------ procedure Error_Msg_SC (Msg : String) is begin -- If we are at end of file, post the flag after the previous token if Token = Tok_EOF then Error_Msg_AP (Msg); -- For all other cases the message is posted at the current token -- pointer position else Error_Msg (Msg, Token_Ptr); end if; end Error_Msg_SC; ------------------ -- Error_Msg_SP -- ------------------ procedure Error_Msg_SP (Msg : String) is begin -- Note: in the case where there is no previous token, Prev_Token_Ptr -- is set to Source_First, which is a reasonable position for the -- error flag in this situation Error_Msg (Msg, Prev_Token_Ptr); end Error_Msg_SP; -------------- -- Finalize -- -------------- procedure Finalize (Last_Call : Boolean) is Cur : Error_Msg_Id; Nxt : Error_Msg_Id; F : Error_Msg_Id; procedure Delete_Warning (E : Error_Msg_Id); -- Delete a warning msg if not already deleted and adjust warning count -------------------- -- Delete_Warning -- -------------------- procedure Delete_Warning (E : Error_Msg_Id) is begin if not Errors.Table (E).Deleted then Errors.Table (E).Deleted := True; Warnings_Detected := Warnings_Detected - 1; if Errors.Table (E).Warn_Err then Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; end if; end if; end Delete_Warning; -- Start of processing for Finalize begin -- Set Prev pointers Cur := First_Error_Msg; while Cur /= No_Error_Msg loop Nxt := Errors.Table (Cur).Next; exit when Nxt = No_Error_Msg; Errors.Table (Nxt).Prev := Cur; Cur := Nxt; end loop; -- Eliminate any duplicated error messages from the list. This is -- done after the fact to avoid problems with Change_Error_Text. Cur := First_Error_Msg; while Cur /= No_Error_Msg loop Nxt := Errors.Table (Cur).Next; F := Nxt; while F /= No_Error_Msg and then Errors.Table (F).Sptr = Errors.Table (Cur).Sptr loop Check_Duplicate_Message (Cur, F); F := Errors.Table (F).Next; end loop; Cur := Nxt; end loop; -- Mark any messages suppressed by specific warnings as Deleted Cur := First_Error_Msg; while Cur /= No_Error_Msg loop declare CE : Error_Msg_Object renames Errors.Table (Cur); Tag : constant String := Get_Warning_Tag (Cur); begin if (CE.Warn and not CE.Deleted) and then (Warning_Specifically_Suppressed (CE.Sptr, CE.Text, Tag) /= No_String or else Warning_Specifically_Suppressed (CE.Optr, CE.Text, Tag) /= No_String) then Delete_Warning (Cur); -- If this is a continuation, delete previous parts of message F := Cur; while Errors.Table (F).Msg_Cont loop F := Errors.Table (F).Prev; exit when F = No_Error_Msg; Delete_Warning (F); end loop; -- Delete any following continuations F := Cur; loop F := Errors.Table (F).Next; exit when F = No_Error_Msg; exit when not Errors.Table (F).Msg_Cont; Delete_Warning (F); end loop; end if; end; Cur := Errors.Table (Cur).Next; end loop; Finalize_Called := True; -- Check consistency of specific warnings (may add warnings). We only -- do this on the last call, after all possible warnings are posted. if Last_Call then Validate_Specific_Warnings (Error_Msg'Access); end if; end Finalize; ---------------- -- First_Node -- ---------------- function First_Node (C : Node_Id) return Node_Id is Orig : constant Node_Id := Original_Node (C); Loc : constant Source_Ptr := Sloc (Orig); Sfile : constant Source_File_Index := Get_Source_File_Index (Loc); Earliest : Node_Id; Eloc : Source_Ptr; function Test_Earlier (N : Node_Id) return Traverse_Result; -- Function applied to every node in the construct procedure Search_Tree_First is new Traverse_Proc (Test_Earlier); -- Create traversal procedure ------------------ -- Test_Earlier -- ------------------ function Test_Earlier (N : Node_Id) return Traverse_Result is Norig : constant Node_Id := Original_Node (N); Loc : constant Source_Ptr := Sloc (Norig); begin -- Check for earlier if Loc < Eloc -- Ignore nodes with no useful location information and then Loc /= Standard_Location and then Loc /= No_Location -- Ignore nodes from a different file. This ensures against cases -- of strange foreign code somehow being present. We don't want -- wild placement of messages if that happens. and then Get_Source_File_Index (Loc) = Sfile then Earliest := Norig; Eloc := Loc; end if; return OK_Orig; end Test_Earlier; -- Start of processing for First_Node begin if Nkind (Orig) in N_Subexpr then Earliest := Orig; Eloc := Loc; Search_Tree_First (Orig); return Earliest; else return Orig; end if; end First_Node; ---------------- -- First_Sloc -- ---------------- function First_Sloc (N : Node_Id) return Source_Ptr is SI : constant Source_File_Index := Source_Index (Get_Source_Unit (N)); SF : constant Source_Ptr := Source_First (SI); F : Node_Id; S : Source_Ptr; begin F := First_Node (N); S := Sloc (F); -- The following circuit is a bit subtle. When we have parenthesized -- expressions, then the Sloc will not record the location of the paren, -- but we would like to post the flag on the paren. So what we do is to -- crawl up the tree from the First_Node, adjusting the Sloc value for -- any parentheses we know are present. Yes, we know this circuit is not -- 100% reliable (e.g. because we don't record all possible paren level -- values), but this is only for an error message so it is good enough. Node_Loop : loop Paren_Loop : for J in 1 .. Paren_Count (F) loop -- We don't look more than 12 characters behind the current -- location, and in any case not past the front of the source. Search_Loop : for K in 1 .. 12 loop exit Search_Loop when S = SF; if Source_Text (SI) (S - 1) = '(' then S := S - 1; exit Search_Loop; elsif Source_Text (SI) (S - 1) <= ' ' then S := S - 1; else exit Search_Loop; end if; end loop Search_Loop; end loop Paren_Loop; exit Node_Loop when F = N; F := Parent (F); exit Node_Loop when Nkind (F) not in N_Subexpr; end loop Node_Loop; return S; end First_Sloc; ----------------------- -- Get_Ignore_Errors -- ----------------------- function Get_Ignore_Errors return Boolean is begin return Errors_Must_Be_Ignored; end Get_Ignore_Errors; ---------------- -- Initialize -- ---------------- procedure Initialize is begin Errors.Init; First_Error_Msg := No_Error_Msg; Last_Error_Msg := No_Error_Msg; Serious_Errors_Detected := 0; Total_Errors_Detected := 0; Warnings_Treated_As_Errors := 0; Warnings_Detected := 0; Warnings_As_Errors_Count := 0; Cur_Msg := No_Error_Msg; List_Pragmas.Init; -- Initialize warnings tables Warnings.Init; Specific_Warnings.Init; end Initialize; ----------------- -- No_Warnings -- ----------------- function No_Warnings (N : Node_Or_Entity_Id) return Boolean is begin if Error_Posted (N) then return True; elsif Nkind (N) in N_Entity and then Has_Warnings_Off (N) then return True; elsif Is_Entity_Name (N) and then Present (Entity (N)) and then Has_Warnings_Off (Entity (N)) then return True; else return False; end if; end No_Warnings; ------------- -- OK_Node -- ------------- function OK_Node (N : Node_Id) return Boolean is K : constant Node_Kind := Nkind (N); begin if Error_Posted (N) then return False; elsif K in N_Has_Etype and then Present (Etype (N)) and then Error_Posted (Etype (N)) then return False; elsif (K in N_Op or else K = N_Attribute_Reference or else K = N_Character_Literal or else K = N_Expanded_Name or else K = N_Identifier or else K = N_Operator_Symbol) and then Present (Entity (N)) and then Error_Posted (Entity (N)) then return False; else return True; end if; end OK_Node; --------------------- -- Output_Messages -- --------------------- procedure Output_Messages is E : Error_Msg_Id; Err_Flag : Boolean; procedure Write_Error_Summary; -- Write error summary procedure Write_Header (Sfile : Source_File_Index); -- Write header line (compiling or checking given file) procedure Write_Max_Errors; -- Write message if max errors reached ------------------------- -- Write_Error_Summary -- ------------------------- procedure Write_Error_Summary is begin -- Extra blank line if error messages or source listing were output if Total_Errors_Detected + Warnings_Detected > 0 or else Full_List then Write_Eol; end if; -- Message giving number of lines read and number of errors detected. -- This normally goes to Standard_Output. The exception is when brief -- mode is not set, verbose mode (or full list mode) is set, and -- there are errors. In this case we send the message to standard -- error to make sure that *something* appears on standard error in -- an error situation. -- Formerly, only the "# errors" suffix was sent to stderr, whereas -- "# lines:" appeared on stdout. This caused problems on VMS when -- the stdout buffer was flushed, giving an extra line feed after -- the prefix. if Total_Errors_Detected + Warnings_Detected /= 0 and then not Brief_Output and then (Verbose_Mode or Full_List) then Set_Standard_Error; end if; -- Message giving total number of lines. Don't give this message if -- the Main_Source line is unknown (this happens in error situations, -- e.g. when integrated preprocessing fails). if Main_Source_File /= No_Source_File then Write_Str (" "); Write_Int (Num_Source_Lines (Main_Source_File)); if Num_Source_Lines (Main_Source_File) = 1 then Write_Str (" line: "); else Write_Str (" lines: "); end if; end if; if Total_Errors_Detected = 0 then Write_Str ("No errors"); elsif Total_Errors_Detected = 1 then Write_Str ("1 error"); else Write_Int (Total_Errors_Detected); Write_Str (" errors"); end if; if Warnings_Detected /= 0 then Write_Str (", "); Write_Int (Warnings_Detected); Write_Str (" warning"); if Warnings_Detected /= 1 then Write_Char ('s'); end if; if Warning_Mode = Treat_As_Error then Write_Str (" (treated as error"); if Warnings_Detected /= 1 then Write_Char ('s'); end if; Write_Char (')'); elsif Warnings_Treated_As_Errors /= 0 then Write_Str (" ("); Write_Int (Warnings_Treated_As_Errors); Write_Str (" treated as errors)"); end if; end if; Write_Eol; Set_Standard_Output; end Write_Error_Summary; ------------------ -- Write_Header -- ------------------ procedure Write_Header (Sfile : Source_File_Index) is begin if Verbose_Mode or Full_List then if Original_Operating_Mode = Generate_Code then Write_Str ("Compiling: "); else Write_Str ("Checking: "); end if; Write_Name (Full_File_Name (Sfile)); if not Debug_Flag_7 then Write_Str (" (source file time stamp: "); Write_Time_Stamp (Sfile); Write_Char (')'); end if; Write_Eol; end if; end Write_Header; ---------------------- -- Write_Max_Errors -- ---------------------- procedure Write_Max_Errors is begin if Maximum_Messages /= 0 then if Warnings_Detected >= Maximum_Messages then Set_Standard_Error; Write_Line ("maximum number of warnings output"); Write_Line ("any further warnings suppressed"); Set_Standard_Output; end if; -- If too many errors print message if Total_Errors_Detected >= Maximum_Messages then Set_Standard_Error; Write_Line ("fatal error: maximum number of errors detected"); Set_Standard_Output; end if; end if; end Write_Max_Errors; -- Start of processing for Output_Messages begin -- Error if Finalize has not been called if not Finalize_Called then raise Program_Error; end if; -- Reset current error source file if the main unit has a pragma -- Source_Reference. This ensures outputting the proper name of -- the source file in this situation. if Main_Source_File = No_Source_File or else Num_SRef_Pragmas (Main_Source_File) /= 0 then Current_Error_Source_File := No_Source_File; end if; -- Brief Error mode if Brief_Output or (not Full_List and not Verbose_Mode) then Set_Standard_Error; E := First_Error_Msg; while E /= No_Error_Msg loop if not Errors.Table (E).Deleted and then not Debug_Flag_KK then if Full_Path_Name_For_Brief_Errors then Write_Name (Full_Ref_Name (Errors.Table (E).Sfile)); else Write_Name (Reference_Name (Errors.Table (E).Sfile)); end if; Write_Char (':'); Write_Int (Int (Physical_To_Logical (Errors.Table (E).Line, Errors.Table (E).Sfile))); Write_Char (':'); if Errors.Table (E).Col < 10 then Write_Char ('0'); end if; Write_Int (Int (Errors.Table (E).Col)); Write_Str (": "); Output_Msg_Text (E); Write_Eol; end if; E := Errors.Table (E).Next; end loop; Set_Standard_Output; end if; -- Full source listing case if Full_List then List_Pragmas_Index := 1; List_Pragmas_Mode := True; E := First_Error_Msg; -- Normal case, to stdout (copyright notice already output) if Full_List_File_Name = null then if not Debug_Flag_7 then Write_Eol; end if; -- Output to file else Create_List_File_Access.all (Full_List_File_Name.all); Set_Special_Output (Write_List_Info_Access.all'Access); -- Write copyright notice to file if not Debug_Flag_7 then Write_Str ("GNAT "); Write_Str (Gnat_Version_String); Write_Eol; Write_Str ("Copyright 1992-" & Current_Year & ", Free Software Foundation, Inc."); Write_Eol; end if; end if; -- First list extended main source file units with errors for U in Main_Unit .. Last_Unit loop if In_Extended_Main_Source_Unit (Cunit_Entity (U)) -- If debug flag d.m is set, only the main source is listed and then (U = Main_Unit or else not Debug_Flag_Dot_M) -- If the unit of the entity does not come from source, it is -- an implicit subprogram declaration for a child subprogram. -- Do not emit errors for it, they are listed with the body. and then (No (Cunit_Entity (U)) or else Comes_From_Source (Cunit_Entity (U)) or else not Is_Subprogram (Cunit_Entity (U))) -- If the compilation unit associated with this unit does not -- come from source, it means it is an instantiation that should -- not be included in the source listing. and then Comes_From_Source (Cunit (U)) then declare Sfile : constant Source_File_Index := Source_Index (U); begin Write_Eol; -- Only write the header if Sfile is known if Sfile /= No_Source_File then Write_Header (Sfile); Write_Eol; end if; -- Normally, we don't want an "error messages from file" -- message when listing the entire file, so we set the -- current source file as the current error source file. -- However, the old style of doing things was to list this -- message if pragma Source_Reference is present, even for -- the main unit. Since the purpose of the -gnatd.m switch -- is to duplicate the old behavior, we skip the reset if -- this debug flag is set. if not Debug_Flag_Dot_M then Current_Error_Source_File := Sfile; end if; -- Only output the listing if Sfile is known, to avoid -- crashing the compiler. if Sfile /= No_Source_File then for N in 1 .. Last_Source_Line (Sfile) loop while E /= No_Error_Msg and then Errors.Table (E).Deleted loop E := Errors.Table (E).Next; end loop; Err_Flag := E /= No_Error_Msg and then Errors.Table (E).Line = N and then Errors.Table (E).Sfile = Sfile; Output_Source_Line (N, Sfile, Err_Flag); if Err_Flag then Output_Error_Msgs (E); if not Debug_Flag_2 then Write_Eol; end if; end if; end loop; end if; end; end if; end loop; -- Then output errors, if any, for subsidiary units not in the -- main extended unit. -- Note: if debug flag d.m set, include errors for any units other -- than the main unit in the extended source unit (e.g. spec and -- subunits for a body). while E /= No_Error_Msg and then (not In_Extended_Main_Source_Unit (Errors.Table (E).Sptr) or else (Debug_Flag_Dot_M and then Get_Source_Unit (Errors.Table (E).Sptr) /= Main_Unit)) loop if Errors.Table (E).Deleted then E := Errors.Table (E).Next; else Write_Eol; Output_Source_Line (Errors.Table (E).Line, Errors.Table (E).Sfile, True); Output_Error_Msgs (E); end if; end loop; -- If output to file, write extra copy of error summary to the -- output file, and then close it. if Full_List_File_Name /= null then Write_Error_Summary; Write_Max_Errors; Close_List_File_Access.all; Cancel_Special_Output; end if; end if; -- Verbose mode (error lines only with error flags). Normally this is -- ignored in full list mode, unless we are listing to a file, in which -- case we still generate -gnatv output to standard output. if Verbose_Mode and then (not Full_List or else Full_List_File_Name /= null) then Write_Eol; -- Output the header only when Main_Source_File is known if Main_Source_File /= No_Source_File then Write_Header (Main_Source_File); end if; E := First_Error_Msg; -- Loop through error lines while E /= No_Error_Msg loop if Errors.Table (E).Deleted then E := Errors.Table (E).Next; else Write_Eol; Output_Source_Line (Errors.Table (E).Line, Errors.Table (E).Sfile, True); Output_Error_Msgs (E); end if; end loop; end if; -- Output error summary if verbose or full list mode if Verbose_Mode or else Full_List then Write_Error_Summary; end if; Write_Max_Errors; if Warning_Mode = Treat_As_Error then Total_Errors_Detected := Total_Errors_Detected + Warnings_Detected; Warnings_Detected := 0; end if; end Output_Messages; ------------------------ -- Output_Source_Line -- ------------------------ procedure Output_Source_Line (L : Physical_Line_Number; Sfile : Source_File_Index; Errs : Boolean) is S : Source_Ptr; C : Character; Line_Number_Output : Boolean := False; -- Set True once line number is output Empty_Line : Boolean := True; -- Set False if line includes at least one character begin if Sfile /= Current_Error_Source_File then Write_Str ("==============Error messages for "); case Sinput.File_Type (Sfile) is when Sinput.Src => Write_Str ("source"); when Sinput.Config => Write_Str ("configuration pragmas"); when Sinput.Def => Write_Str ("symbol definition"); when Sinput.Preproc => Write_Str ("preprocessing data"); end case; Write_Str (" file: "); Write_Name (Full_File_Name (Sfile)); Write_Eol; if Num_SRef_Pragmas (Sfile) > 0 then Write_Str ("--------------Line numbers from file: "); Write_Name (Full_Ref_Name (Sfile)); Write_Str (" (starting at line "); Write_Int (Int (First_Mapped_Line (Sfile))); Write_Char (')'); Write_Eol; end if; Current_Error_Source_File := Sfile; end if; if Errs or List_Pragmas_Mode then Output_Line_Number (Physical_To_Logical (L, Sfile)); Line_Number_Output := True; end if; S := Line_Start (L, Sfile); loop C := Source_Text (Sfile) (S); exit when C = ASCII.LF or else C = ASCII.CR or else C = EOF; -- Deal with matching entry in List_Pragmas table if Full_List and then List_Pragmas_Index <= List_Pragmas.Last and then S = List_Pragmas.Table (List_Pragmas_Index).Ploc then case List_Pragmas.Table (List_Pragmas_Index).Ptyp is when Page => Write_Char (C); -- Ignore if on line with errors so that error flags -- get properly listed with the error line . if not Errs then Write_Char (ASCII.FF); end if; when List_On => List_Pragmas_Mode := True; if not Line_Number_Output then Output_Line_Number (Physical_To_Logical (L, Sfile)); Line_Number_Output := True; end if; Write_Char (C); when List_Off => Write_Char (C); List_Pragmas_Mode := False; end case; List_Pragmas_Index := List_Pragmas_Index + 1; -- Normal case (no matching entry in List_Pragmas table) else if Errs or List_Pragmas_Mode then Write_Char (C); end if; end if; Empty_Line := False; S := S + 1; end loop; -- If we have output a source line, then add the line terminator, with -- training spaces preserved (so we output the line exactly as input). if Line_Number_Output then if Empty_Line then Write_Eol; else Write_Eol_Keep_Blanks; end if; end if; end Output_Source_Line; ----------------------------- -- Remove_Warning_Messages -- ----------------------------- procedure Remove_Warning_Messages (N : Node_Id) is function Check_For_Warning (N : Node_Id) return Traverse_Result; -- This function checks one node for a possible warning message function Check_All_Warnings is new Traverse_Func (Check_For_Warning); -- This defines the traversal operation ----------------------- -- Check_For_Warning -- ----------------------- function Check_For_Warning (N : Node_Id) return Traverse_Result is Loc : constant Source_Ptr := Sloc (N); E : Error_Msg_Id; function To_Be_Removed (E : Error_Msg_Id) return Boolean; -- Returns True for a message that is to be removed. Also adjusts -- warning count appropriately. ------------------- -- To_Be_Removed -- ------------------- function To_Be_Removed (E : Error_Msg_Id) return Boolean is begin if E /= No_Error_Msg -- Don't remove if location does not match and then Errors.Table (E).Optr = Loc -- Don't remove if not warning/info message. Note that we do -- not remove style messages here. They are warning messages -- but not ones we want removed in this context. and then Errors.Table (E).Warn -- Don't remove unconditional messages and then not Errors.Table (E).Uncond then Warnings_Detected := Warnings_Detected - 1; return True; -- No removal required else return False; end if; end To_Be_Removed; -- Start of processing for Check_For_Warnings begin while To_Be_Removed (First_Error_Msg) loop First_Error_Msg := Errors.Table (First_Error_Msg).Next; end loop; if First_Error_Msg = No_Error_Msg then Last_Error_Msg := No_Error_Msg; end if; E := First_Error_Msg; while E /= No_Error_Msg loop while To_Be_Removed (Errors.Table (E).Next) loop Errors.Table (E).Next := Errors.Table (Errors.Table (E).Next).Next; if Errors.Table (E).Next = No_Error_Msg then Last_Error_Msg := E; end if; end loop; E := Errors.Table (E).Next; end loop; if Nkind (N) = N_Raise_Constraint_Error and then Original_Node (N) /= N and then No (Condition (N)) then -- Warnings may have been posted on subexpressions of the original -- tree. We place the original node back on the tree to remove -- those warnings, whose sloc do not match those of any node in -- the current tree. Given that we are in unreachable code, this -- modification to the tree is harmless. declare Status : Traverse_Final_Result; begin if Is_List_Member (N) then Set_Condition (N, Original_Node (N)); Status := Check_All_Warnings (Condition (N)); else Rewrite (N, Original_Node (N)); Status := Check_All_Warnings (N); end if; return Status; end; else return OK; end if; end Check_For_Warning; -- Start of processing for Remove_Warning_Messages begin if Warnings_Detected /= 0 then declare Discard : Traverse_Final_Result; pragma Warnings (Off, Discard); begin Discard := Check_All_Warnings (N); end; end if; end Remove_Warning_Messages; procedure Remove_Warning_Messages (L : List_Id) is Stat : Node_Id; begin if Is_Non_Empty_List (L) then Stat := First (L); while Present (Stat) loop Remove_Warning_Messages (Stat); Next (Stat); end loop; end if; end Remove_Warning_Messages; --------------------------- -- Set_Identifier_Casing -- --------------------------- procedure Set_Identifier_Casing (Identifier_Name : System.Address; File_Name : System.Address) is Ident : constant Big_String_Ptr := To_Big_String_Ptr (Identifier_Name); File : constant Big_String_Ptr := To_Big_String_Ptr (File_Name); Flen : Natural; Desired_Case : Casing_Type := Mixed_Case; -- Casing required for result. Default value of Mixed_Case is used if -- for some reason we cannot find the right file name in the table. begin -- Get length of file name Flen := 0; while File (Flen + 1) /= ASCII.NUL loop Flen := Flen + 1; end loop; -- Loop through file names to find matching one. This is a bit slow, but -- we only do it in error situations so it is not so terrible. Note that -- if the loop does not exit, then the desired case will be left set to -- Mixed_Case, this can happen if the name was not in canonical form, -- and gets canonicalized on VMS. Possibly we could fix this by -- unconditionally canonicalizing these names ??? for J in 1 .. Last_Source_File loop Get_Name_String (Full_Debug_Name (J)); if Name_Len = Flen and then Name_Buffer (1 .. Name_Len) = String (File (1 .. Flen)) then Desired_Case := Identifier_Casing (J); exit; end if; end loop; -- Copy identifier as given to Name_Buffer for J in Name_Buffer'Range loop Name_Buffer (J) := Ident (J); if Name_Buffer (J) = ASCII.NUL then Name_Len := J - 1; exit; end if; end loop; Set_Casing (Desired_Case); end Set_Identifier_Casing; ----------------------- -- Set_Ignore_Errors -- ----------------------- procedure Set_Ignore_Errors (To : Boolean) is begin Errors_Must_Be_Ignored := To; end Set_Ignore_Errors; ------------------------------ -- Set_Msg_Insertion_Column -- ------------------------------ procedure Set_Msg_Insertion_Column is begin if RM_Column_Check then Set_Msg_Str (" in column "); Set_Msg_Int (Int (Error_Msg_Col) + 1); end if; end Set_Msg_Insertion_Column; ---------------------------- -- Set_Msg_Insertion_Node -- ---------------------------- procedure Set_Msg_Insertion_Node is K : Node_Kind; begin Suppress_Message := Error_Msg_Node_1 = Error or else Error_Msg_Node_1 = Any_Type; if Error_Msg_Node_1 = Empty then Set_Msg_Blank_Conditional; Set_Msg_Str (""); elsif Error_Msg_Node_1 = Error then Set_Msg_Blank; Set_Msg_Str (""); elsif Error_Msg_Node_1 = Standard_Void_Type then Set_Msg_Blank; Set_Msg_Str ("procedure name"); elsif Nkind (Error_Msg_Node_1) in N_Entity and then Ekind (Error_Msg_Node_1) = E_Anonymous_Access_Subprogram_Type then Set_Msg_Blank; Set_Msg_Str ("access to subprogram"); else Set_Msg_Blank_Conditional; -- Output name K := Nkind (Error_Msg_Node_1); -- If we have operator case, skip quotes since name of operator -- itself will supply the required quotations. An operator can be an -- applied use in an expression or an explicit operator symbol, or an -- identifier whose name indicates it is an operator. if K in N_Op or else K = N_Operator_Symbol or else K = N_Defining_Operator_Symbol or else ((K = N_Identifier or else K = N_Defining_Identifier) and then Is_Operator_Name (Chars (Error_Msg_Node_1))) then Set_Msg_Node (Error_Msg_Node_1); -- Normal case, not an operator, surround with quotes else Set_Msg_Quote; Set_Qualification (Error_Msg_Qual_Level, Error_Msg_Node_1); Set_Msg_Node (Error_Msg_Node_1); Set_Msg_Quote; end if; end if; -- The following assignment ensures that a second ampersand insertion -- character will correspond to the Error_Msg_Node_2 parameter. We -- suppress possible validity checks in case operating in -gnatVa mode, -- and Error_Msg_Node_2 is not needed and has not been set. declare pragma Suppress (Range_Check); begin Error_Msg_Node_1 := Error_Msg_Node_2; end; end Set_Msg_Insertion_Node; -------------------------------------- -- Set_Msg_Insertion_Type_Reference -- -------------------------------------- procedure Set_Msg_Insertion_Type_Reference (Flag : Source_Ptr) is Ent : Entity_Id; begin Set_Msg_Blank; if Error_Msg_Node_1 = Standard_Void_Type then Set_Msg_Str ("package or procedure name"); return; elsif Error_Msg_Node_1 = Standard_Exception_Type then Set_Msg_Str ("exception name"); return; elsif Error_Msg_Node_1 = Any_Access or else Error_Msg_Node_1 = Any_Array or else Error_Msg_Node_1 = Any_Boolean or else Error_Msg_Node_1 = Any_Character or else Error_Msg_Node_1 = Any_Composite or else Error_Msg_Node_1 = Any_Discrete or else Error_Msg_Node_1 = Any_Fixed or else Error_Msg_Node_1 = Any_Integer or else Error_Msg_Node_1 = Any_Modular or else Error_Msg_Node_1 = Any_Numeric or else Error_Msg_Node_1 = Any_Real or else Error_Msg_Node_1 = Any_Scalar or else Error_Msg_Node_1 = Any_String then Get_Unqualified_Decoded_Name_String (Chars (Error_Msg_Node_1)); Set_Msg_Name_Buffer; return; elsif Error_Msg_Node_1 = Universal_Real then Set_Msg_Str ("type universal real"); return; elsif Error_Msg_Node_1 = Universal_Integer then Set_Msg_Str ("type universal integer"); return; elsif Error_Msg_Node_1 = Universal_Fixed then Set_Msg_Str ("type universal fixed"); return; end if; -- Special case of anonymous array if Nkind (Error_Msg_Node_1) in N_Entity and then Is_Array_Type (Error_Msg_Node_1) and then Present (Related_Array_Object (Error_Msg_Node_1)) then Set_Msg_Str ("type of "); Set_Msg_Node (Related_Array_Object (Error_Msg_Node_1)); Set_Msg_Str (" declared"); Set_Msg_Insertion_Line_Number (Sloc (Related_Array_Object (Error_Msg_Node_1)), Flag); return; end if; -- If we fall through, it is not a special case, so first output -- the name of the type, preceded by private for a private type if Is_Private_Type (Error_Msg_Node_1) then Set_Msg_Str ("private type "); else Set_Msg_Str ("type "); end if; Ent := Error_Msg_Node_1; if Is_Internal_Name (Chars (Ent)) then Unwind_Internal_Type (Ent); end if; -- Types in Standard are displayed as "Standard.name" if Sloc (Ent) <= Standard_Location then Set_Msg_Quote; Set_Msg_Str ("Standard."); Set_Msg_Node (Ent); Add_Class; Set_Msg_Quote; -- Types in other language defined units are displayed as -- "package-name.type-name" elsif Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (Ent))) then Get_Unqualified_Decoded_Name_String (Unit_Name (Get_Source_Unit (Ent))); Name_Len := Name_Len - 2; Set_Msg_Blank_Conditional; Set_Msg_Quote; Set_Casing (Mixed_Case); Set_Msg_Name_Buffer; Set_Msg_Char ('.'); Set_Casing (Mixed_Case); Set_Msg_Node (Ent); Add_Class; Set_Msg_Quote; -- All other types display as "type name" defined at line xxx -- possibly qualified if qualification is requested. else Set_Msg_Quote; Set_Qualification (Error_Msg_Qual_Level, Ent); Set_Msg_Node (Ent); Add_Class; -- If we did not print a name (e.g. in the case of an anonymous -- subprogram type), there is no name to print, so remove quotes. if Buffer_Ends_With ('"') then Buffer_Remove ('"'); else Set_Msg_Quote; end if; end if; -- If the original type did not come from a predefined file, add the -- location where the type was defined. if Sloc (Error_Msg_Node_1) > Standard_Location and then not Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (Error_Msg_Node_1))) then Set_Msg_Str (" defined"); Set_Msg_Insertion_Line_Number (Sloc (Error_Msg_Node_1), Flag); -- If it did come from a predefined file, deal with the case where -- this was a file with a generic instantiation from elsewhere. else if Sloc (Error_Msg_Node_1) > Standard_Location then declare Iloc : constant Source_Ptr := Instantiation_Location (Sloc (Error_Msg_Node_1)); begin if Iloc /= No_Location and then not Suppress_Instance_Location then Set_Msg_Str (" from instance"); Set_Msg_Insertion_Line_Number (Iloc, Flag); end if; end; end if; end if; end Set_Msg_Insertion_Type_Reference; --------------------------------- -- Set_Msg_Insertion_Unit_Name -- --------------------------------- procedure Set_Msg_Insertion_Unit_Name (Suffix : Boolean := True) is begin if Error_Msg_Unit_1 = No_Unit_Name then null; elsif Error_Msg_Unit_1 = Error_Unit_Name then Set_Msg_Blank; Set_Msg_Str (""); else Get_Unit_Name_String (Error_Msg_Unit_1, Suffix); Set_Msg_Blank; Set_Msg_Quote; Set_Msg_Name_Buffer; Set_Msg_Quote; end if; -- The following assignment ensures that a second percent insertion -- character will correspond to the Error_Msg_Unit_2 parameter. We -- suppress possible validity checks in case operating in -gnatVa mode, -- and Error_Msg_Unit_2 is not needed and has not been set. declare pragma Suppress (Range_Check); begin Error_Msg_Unit_1 := Error_Msg_Unit_2; end; end Set_Msg_Insertion_Unit_Name; ------------------ -- Set_Msg_Node -- ------------------ procedure Set_Msg_Node (Node : Node_Id) is Ent : Entity_Id; Nam : Name_Id; begin case Nkind (Node) is when N_Designator => Set_Msg_Node (Name (Node)); Set_Msg_Char ('.'); Set_Msg_Node (Identifier (Node)); return; when N_Defining_Program_Unit_Name => Set_Msg_Node (Name (Node)); Set_Msg_Char ('.'); Set_Msg_Node (Defining_Identifier (Node)); return; when N_Selected_Component | N_Expanded_Name => Set_Msg_Node (Prefix (Node)); Set_Msg_Char ('.'); Set_Msg_Node (Selector_Name (Node)); return; when others => null; end case; -- The only remaining possibilities are identifiers, defining -- identifiers, pragmas, and pragma argument associations. if Nkind (Node) = N_Pragma then Nam := Pragma_Name (Node); -- The other cases have Chars fields, and we want to test for possible -- internal names, which generally represent something gone wrong. An -- exception is the case of internal type names, where we try to find a -- reasonable external representation for the external name elsif Is_Internal_Name (Chars (Node)) and then ((Is_Entity_Name (Node) and then Present (Entity (Node)) and then Is_Type (Entity (Node))) or else (Nkind (Node) = N_Defining_Identifier and then Is_Type (Node))) then if Nkind (Node) = N_Identifier then Ent := Entity (Node); else Ent := Node; end if; -- If the type is the designated type of an access_to_subprogram, -- then there is no name to provide in the call. if Ekind (Ent) = E_Subprogram_Type then return; -- Otherwise, we will be able to find some kind of name to output else Unwind_Internal_Type (Ent); Nam := Chars (Ent); end if; -- If not internal name, just use name in Chars field else Nam := Chars (Node); end if; -- At this stage, the name to output is in Nam Get_Unqualified_Decoded_Name_String (Nam); -- Remove trailing upper case letters from the name (useful for -- dealing with some cases of internal names. while Name_Len > 1 and then Name_Buffer (Name_Len) in 'A' .. 'Z' loop Name_Len := Name_Len - 1; end loop; -- If we have any of the names from standard that start with the -- characters "any " (e.g. Any_Type), then kill the message since -- almost certainly it is a junk cascaded message. if Name_Len > 4 and then Name_Buffer (1 .. 4) = "any " then Kill_Message := True; end if; -- Now we have to set the proper case. If we have a source location -- then do a check to see if the name in the source is the same name -- as the name in the Names table, except for possible differences -- in case, which is the case when we can copy from the source. declare Src_Loc : constant Source_Ptr := Sloc (Node); Sbuffer : Source_Buffer_Ptr; Ref_Ptr : Integer; Src_Ptr : Source_Ptr; begin Ref_Ptr := 1; Src_Ptr := Src_Loc; -- For standard locations, always use mixed case if Src_Loc <= No_Location or else Sloc (Node) <= No_Location then Set_Casing (Mixed_Case); else -- Determine if the reference we are dealing with corresponds to -- text at the point of the error reference. This will often be -- the case for simple identifier references, and is the case -- where we can copy the spelling from the source. Sbuffer := Source_Text (Get_Source_File_Index (Src_Loc)); while Ref_Ptr <= Name_Len loop exit when Fold_Lower (Sbuffer (Src_Ptr)) /= Fold_Lower (Name_Buffer (Ref_Ptr)); Ref_Ptr := Ref_Ptr + 1; Src_Ptr := Src_Ptr + 1; end loop; -- If we get through the loop without a mismatch, then output the -- name the way it is spelled in the source program if Ref_Ptr > Name_Len then Src_Ptr := Src_Loc; for J in 1 .. Name_Len loop Name_Buffer (J) := Sbuffer (Src_Ptr); Src_Ptr := Src_Ptr + 1; end loop; -- Otherwise set the casing using the default identifier casing else Set_Casing (Identifier_Casing (Flag_Source), Mixed_Case); end if; end if; end; Set_Msg_Name_Buffer; Add_Class; end Set_Msg_Node; ------------------ -- Set_Msg_Text -- ------------------ procedure Set_Msg_Text (Text : String; Flag : Source_Ptr) is C : Character; -- Current character P : Natural; -- Current index; procedure Skip_Msg_Insertion_Warning (C : Character); -- Deal with ? ?? ?x? ?X? ?*? ?$? insertion sequences (and the same -- sequences using < instead of ?). The caller has already bumped -- the pointer past the initial ? or < and C is set to this initial -- character (? or <). This procedure skips past the rest of the -- sequence. We do not need to set Msg_Insertion_Char, since this -- was already done during the message prescan. -------------------------------- -- Skip_Msg_Insertion_Warning -- -------------------------------- procedure Skip_Msg_Insertion_Warning (C : Character) is begin if P <= Text'Last and then Text (P) = C then P := P + 1; elsif P + 1 <= Text'Last and then (Text (P) in 'a' .. 'z' or else Text (P) in 'A' .. 'Z' or else Text (P) = '*' or else Text (P) = '$') and then Text (P + 1) = C then P := P + 2; end if; end Skip_Msg_Insertion_Warning; -- Start of processing for Set_Msg_Text begin Manual_Quote_Mode := False; Msglen := 0; Flag_Source := Get_Source_File_Index (Flag); -- Skip info: at start, we have recorded this in Is_Info_Msg, and this -- will be used (Info field in error message object) to put back the -- string when it is printed. We need to do this, or we get confused -- with instantiation continuations. if Text'Length > 6 and then Text (Text'First .. Text'First + 5) = "info: " then P := Text'First + 6; else P := Text'First; end if; -- Loop through characters of message while P <= Text'Last loop C := Text (P); P := P + 1; -- Check for insertion character or sequence case C is when '%' => if P <= Text'Last and then Text (P) = '%' then P := P + 1; Set_Msg_Insertion_Name_Literal; else Set_Msg_Insertion_Name; end if; when '$' => if P <= Text'Last and then Text (P) = '$' then P := P + 1; Set_Msg_Insertion_Unit_Name (Suffix => False); else Set_Msg_Insertion_Unit_Name; end if; when '{' => Set_Msg_Insertion_File_Name; when '}' => Set_Msg_Insertion_Type_Reference (Flag); when '*' => Set_Msg_Insertion_Reserved_Name; when '&' => Set_Msg_Insertion_Node; when '#' => Set_Msg_Insertion_Line_Number (Error_Msg_Sloc, Flag); when '\' => Continuation := True; if Text (P) = '\' then Continuation_New_Line := True; P := P + 1; end if; when '@' => Set_Msg_Insertion_Column; when '>' => Set_Msg_Insertion_Run_Time_Name; when '^' => Set_Msg_Insertion_Uint; when '`' => Manual_Quote_Mode := not Manual_Quote_Mode; Set_Msg_Char ('"'); when '!' => null; -- already dealt with when '?' => Skip_Msg_Insertion_Warning ('?'); when '<' => Skip_Msg_Insertion_Warning ('<'); when '|' => null; -- already dealt with when ''' => Set_Msg_Char (Text (P)); P := P + 1; when '~' => Set_Msg_Str (Error_Msg_String (1 .. Error_Msg_Strlen)); -- Upper case letter when 'A' .. 'Z' => -- Start of reserved word if two or more if P <= Text'Last and then Text (P) in 'A' .. 'Z' then P := P - 1; Set_Msg_Insertion_Reserved_Word (Text, P); -- Single upper case letter is just inserted else Set_Msg_Char (C); end if; -- '[' (will be/would have been raised at run time) when '[' => if Is_Warning_Msg then Set_Msg_Str ("will be raised at run time"); else Set_Msg_Str ("would have been raised at run time"); end if; -- ']' (may be/might have been raised at run time) when ']' => if Is_Warning_Msg then Set_Msg_Str ("may be raised at run time"); else Set_Msg_Str ("might have been raised at run time"); end if; -- Normal character with no special treatment when others => Set_Msg_Char (C); end case; end loop; VMS_Convert; end Set_Msg_Text; ---------------- -- Set_Posted -- ---------------- procedure Set_Posted (N : Node_Id) is P : Node_Id; begin if Is_Serious_Error then -- We always set Error_Posted on the node itself Set_Error_Posted (N); -- If it is a subexpression, then set Error_Posted on parents up to -- and including the first non-subexpression construct. This helps -- avoid cascaded error messages within a single expression. P := N; loop P := Parent (P); exit when No (P); Set_Error_Posted (P); exit when Nkind (P) not in N_Subexpr; end loop; if Nkind_In (P, N_Pragma_Argument_Association, N_Component_Association, N_Discriminant_Association, N_Generic_Association, N_Parameter_Association) then Set_Error_Posted (Parent (P)); end if; -- A special check, if we just posted an error on an attribute -- definition clause, then also set the entity involved as posted. -- For example, this stops complaining about the alignment after -- complaining about the size, which is likely to be useless. if Nkind (P) = N_Attribute_Definition_Clause then if Is_Entity_Name (Name (P)) then Set_Error_Posted (Entity (Name (P))); end if; end if; end if; end Set_Posted; ----------------------- -- Set_Qualification -- ----------------------- procedure Set_Qualification (N : Nat; E : Entity_Id) is begin if N /= 0 and then Scope (E) /= Standard_Standard then Set_Qualification (N - 1, Scope (E)); Set_Msg_Node (Scope (E)); Set_Msg_Char ('.'); end if; end Set_Qualification; ------------------------ -- Special_Msg_Delete -- ------------------------ -- Is it really right to have all this specialized knowledge in errout? function Special_Msg_Delete (Msg : String; N : Node_Or_Entity_Id; E : Node_Or_Entity_Id) return Boolean is begin -- Never delete messages in -gnatdO mode if Debug_Flag_OO then return False; -- Processing for "atomic access cannot be guaranteed" elsif Msg = "atomic access to & cannot be guaranteed" then -- When an atomic object refers to a non-atomic type in the same -- scope, we implicitly make the type atomic. In the non-error case -- this is surely safe (and in fact prevents an error from occurring -- if the type is not atomic by default). But if the object cannot be -- made atomic, then we introduce an extra junk message by this -- manipulation, which we get rid of here. -- We identify this case by the fact that it references a type for -- which Is_Atomic is set, but there is no Atomic pragma setting it. if Is_Type (E) and then Is_Atomic (E) and then No (Get_Rep_Pragma (E, Name_Atomic)) then return True; end if; -- Processing for "Size too small" messages elsif Msg = "size for& too small, minimum allowed is ^" then -- Suppress "size too small" errors in CodePeer mode, since code may -- be analyzed in a different configuration than the one used for -- compilation. Even when the configurations match, this message -- may be issued on correct code, because pragma Pack is ignored -- in CodePeer mode. if CodePeer_Mode then return True; -- When a size is wrong for a frozen type there is no explicit size -- clause, and other errors have occurred, suppress the message, -- since it is likely that this size error is a cascaded result of -- other errors. The reason we eliminate unfrozen types is that -- messages issued before the freeze type are for sure OK. elsif Is_Frozen (E) and then Serious_Errors_Detected > 0 and then Nkind (N) /= N_Component_Clause and then Nkind (Parent (N)) /= N_Component_Clause and then No (Get_Attribute_Definition_Clause (E, Attribute_Size)) and then No (Get_Attribute_Definition_Clause (E, Attribute_Object_Size)) and then No (Get_Attribute_Definition_Clause (E, Attribute_Value_Size)) then return True; end if; end if; -- All special tests complete, so go ahead with message return False; end Special_Msg_Delete; ----------------- -- SPARK_Msg_N -- ----------------- procedure SPARK_Msg_N (Msg : String; N : Node_Or_Entity_Id) is begin if SPARK_Mode = On then Error_Msg_N (Msg, N); end if; end SPARK_Msg_N; ------------------ -- SPARK_Msg_NE -- ------------------ procedure SPARK_Msg_NE (Msg : String; N : Node_Or_Entity_Id; E : Node_Or_Entity_Id) is begin if SPARK_Mode = On then Error_Msg_NE (Msg, N, E); end if; end SPARK_Msg_NE; -------------------------- -- Unwind_Internal_Type -- -------------------------- procedure Unwind_Internal_Type (Ent : in out Entity_Id) is Derived : Boolean := False; Mchar : Character; Old_Ent : Entity_Id; begin -- Undo placement of a quote, since we will put it back later Mchar := Msg_Buffer (Msglen); if Mchar = '"' then Msglen := Msglen - 1; end if; -- The loop here deals with recursive types, we are trying to find a -- related entity that is not an implicit type. Note that the check with -- Old_Ent stops us from getting "stuck". Also, we don't output the -- "type derived from" message more than once in the case where we climb -- up multiple levels. Find : loop Old_Ent := Ent; -- Implicit access type, use directly designated type In Ada 2005, -- the designated type may be an anonymous access to subprogram, in -- which case we can only point to its definition. if Is_Access_Type (Ent) then if Ekind (Ent) = E_Access_Subprogram_Type or else Ekind (Ent) = E_Anonymous_Access_Subprogram_Type or else Is_Access_Protected_Subprogram_Type (Ent) then Ent := Directly_Designated_Type (Ent); if not Comes_From_Source (Ent) then if Buffer_Ends_With ("type ") then Buffer_Remove ("type "); end if; end if; if Ekind (Ent) = E_Function then Set_Msg_Str ("access to function "); elsif Ekind (Ent) = E_Procedure then Set_Msg_Str ("access to procedure "); else Set_Msg_Str ("access to subprogram"); end if; exit Find; -- Type is access to object, named or anonymous else Set_Msg_Str ("access to "); Ent := Directly_Designated_Type (Ent); end if; -- Classwide type elsif Is_Class_Wide_Type (Ent) then Class_Flag := True; Ent := Root_Type (Ent); -- Use base type if this is a subtype elsif Ent /= Base_Type (Ent) then Buffer_Remove ("type "); -- Avoid duplication "subtype of subtype of", and also replace -- "derived from subtype of" simply by "derived from" if not Buffer_Ends_With ("subtype of ") and then not Buffer_Ends_With ("derived from ") then Set_Msg_Str ("subtype of "); end if; Ent := Base_Type (Ent); -- If this is a base type with a first named subtype, use the first -- named subtype instead. This is not quite accurate in all cases, -- but it makes too much noise to be accurate and add 'Base in all -- cases. Note that we only do this is the first named subtype is not -- itself an internal name. This avoids the obvious loop (subtype -> -- basetype -> subtype) which would otherwise occur). else declare FST : constant Entity_Id := First_Subtype (Ent); begin if not Is_Internal_Name (Chars (FST)) then Ent := FST; exit Find; -- Otherwise use root type else if not Derived then Buffer_Remove ("type "); -- Test for "subtype of type derived from" which seems -- excessive and is replaced by "type derived from". Buffer_Remove ("subtype of"); -- Avoid duplicated "type derived from type derived from" if not Buffer_Ends_With ("type derived from ") then Set_Msg_Str ("type derived from "); end if; Derived := True; end if; end if; end; Ent := Etype (Ent); end if; -- If we are stuck in a loop, get out and settle for the internal -- name after all. In this case we set to kill the message if it is -- not the first error message (we really try hard not to show the -- dirty laundry of the implementation to the poor user). if Ent = Old_Ent then Kill_Message := True; exit Find; end if; -- Get out if we finally found a non-internal name to use exit Find when not Is_Internal_Name (Chars (Ent)); end loop Find; if Mchar = '"' then Set_Msg_Char ('"'); end if; end Unwind_Internal_Type; ----------------- -- VMS_Convert -- ----------------- procedure VMS_Convert is P : Natural; L : Natural; N : Natural; begin if not OpenVMS then return; end if; P := Msg_Buffer'First; loop if P >= Msglen then return; end if; if Msg_Buffer (P) = '-' then for G in Gnames'Range loop L := Gnames (G)'Length; -- See if we have "-ggg switch", where ggg is Gnames entry if P + L + 7 <= Msglen and then Msg_Buffer (P + 1 .. P + L) = Gnames (G).all and then Msg_Buffer (P + L + 1 .. P + L + 7) = " switch" then -- Replace by "/vvv qualifier", where vvv is Vnames entry N := Vnames (G)'Length; Msg_Buffer (P + N + 11 .. Msglen + N - L + 3) := Msg_Buffer (P + L + 8 .. Msglen); Msg_Buffer (P) := '/'; Msg_Buffer (P + 1 .. P + N) := Vnames (G).all; Msg_Buffer (P + N + 1 .. P + N + 10) := " qualifier"; P := P + N + 10; Msglen := Msglen + N - L + 3; exit; end if; end loop; end if; P := P + 1; end loop; end VMS_Convert; -------------------- -- Warn_Insertion -- -------------------- function Warn_Insertion return String is begin case Warning_Msg_Char is when '?' => return "??"; when 'a' .. 'z' | 'A' .. 'Z' | '*' | '$' => return '?' & Warning_Msg_Char & '?'; when ' ' => return "?"; when others => raise Program_Error; end case; end Warn_Insertion; end Errout; gprbuild-gpl-2014-src/gnat/lib.adb0000644000076700001450000010546112323721731016311 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- L I B -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ pragma Style_Checks (All_Checks); -- Subprogram ordering not enforced in this unit -- (because of some logical groupings). with Atree; use Atree; with Csets; use Csets; with Einfo; use Einfo; with Fname; use Fname; with Nlists; use Nlists; with Output; use Output; with Sinfo; use Sinfo; with Sinput; use Sinput; with Stand; use Stand; with Stringt; use Stringt; with Tree_IO; use Tree_IO; with Uname; use Uname; with Widechar; use Widechar; package body Lib is Switch_Storing_Enabled : Boolean := True; -- Controlled by Enable_Switch_Storing/Disable_Switch_Storing ----------------------- -- Local Subprograms -- ----------------------- type SEU_Result is ( Yes_Before, -- S1 is in same extended unit as S2 and appears before it Yes_Same, -- S1 is in same extended unit as S2, Slocs are the same Yes_After, -- S1 is in same extended unit as S2, and appears after it No); -- S2 is not in same extended unit as S2 function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result; -- Used by In_Same_Extended_Unit and Earlier_In_Extended_Unit. Returns -- value as described above. function Get_Code_Or_Source_Unit (S : Source_Ptr; Unwind_Instances : Boolean) return Unit_Number_Type; -- Common code for Get_Code_Unit (get unit of instantiation for location) -- and Get_Source_Unit (get unit of template for location). -------------------------------------------- -- Access Functions for Unit Table Fields -- -------------------------------------------- function Cunit (U : Unit_Number_Type) return Node_Id is begin return Units.Table (U).Cunit; end Cunit; function Cunit_Entity (U : Unit_Number_Type) return Entity_Id is begin return Units.Table (U).Cunit_Entity; end Cunit_Entity; function Dependency_Num (U : Unit_Number_Type) return Nat is begin return Units.Table (U).Dependency_Num; end Dependency_Num; function Dynamic_Elab (U : Unit_Number_Type) return Boolean is begin return Units.Table (U).Dynamic_Elab; end Dynamic_Elab; function Error_Location (U : Unit_Number_Type) return Source_Ptr is begin return Units.Table (U).Error_Location; end Error_Location; function Expected_Unit (U : Unit_Number_Type) return Unit_Name_Type is begin return Units.Table (U).Expected_Unit; end Expected_Unit; function Fatal_Error (U : Unit_Number_Type) return Boolean is begin return Units.Table (U).Fatal_Error; end Fatal_Error; function Generate_Code (U : Unit_Number_Type) return Boolean is begin return Units.Table (U).Generate_Code; end Generate_Code; function Has_RACW (U : Unit_Number_Type) return Boolean is begin return Units.Table (U).Has_RACW; end Has_RACW; function Ident_String (U : Unit_Number_Type) return Node_Id is begin return Units.Table (U).Ident_String; end Ident_String; function Loading (U : Unit_Number_Type) return Boolean is begin return Units.Table (U).Loading; end Loading; function Main_CPU (U : Unit_Number_Type) return Int is begin return Units.Table (U).Main_CPU; end Main_CPU; function Main_Priority (U : Unit_Number_Type) return Int is begin return Units.Table (U).Main_Priority; end Main_Priority; function Munit_Index (U : Unit_Number_Type) return Nat is begin return Units.Table (U).Munit_Index; end Munit_Index; function OA_Setting (U : Unit_Number_Type) return Character is begin return Units.Table (U).OA_Setting; end OA_Setting; function Source_Index (U : Unit_Number_Type) return Source_File_Index is begin return Units.Table (U).Source_Index; end Source_Index; function Unit_File_Name (U : Unit_Number_Type) return File_Name_Type is begin return Units.Table (U).Unit_File_Name; end Unit_File_Name; function Unit_Name (U : Unit_Number_Type) return Unit_Name_Type is begin return Units.Table (U).Unit_Name; end Unit_Name; ------------------------------------------ -- Subprograms to Set Unit Table Fields -- ------------------------------------------ procedure Set_Cunit (U : Unit_Number_Type; N : Node_Id) is begin Units.Table (U).Cunit := N; end Set_Cunit; procedure Set_Cunit_Entity (U : Unit_Number_Type; E : Entity_Id) is begin Units.Table (U).Cunit_Entity := E; Set_Is_Compilation_Unit (E); end Set_Cunit_Entity; procedure Set_Dynamic_Elab (U : Unit_Number_Type; B : Boolean := True) is begin Units.Table (U).Dynamic_Elab := B; end Set_Dynamic_Elab; procedure Set_Error_Location (U : Unit_Number_Type; W : Source_Ptr) is begin Units.Table (U).Error_Location := W; end Set_Error_Location; procedure Set_Fatal_Error (U : Unit_Number_Type; B : Boolean := True) is begin Units.Table (U).Fatal_Error := B; end Set_Fatal_Error; procedure Set_Generate_Code (U : Unit_Number_Type; B : Boolean := True) is begin Units.Table (U).Generate_Code := B; end Set_Generate_Code; procedure Set_Has_RACW (U : Unit_Number_Type; B : Boolean := True) is begin Units.Table (U).Has_RACW := B; end Set_Has_RACW; procedure Set_Ident_String (U : Unit_Number_Type; N : Node_Id) is begin Units.Table (U).Ident_String := N; end Set_Ident_String; procedure Set_Loading (U : Unit_Number_Type; B : Boolean := True) is begin Units.Table (U).Loading := B; end Set_Loading; procedure Set_Main_CPU (U : Unit_Number_Type; P : Int) is begin Units.Table (U).Main_CPU := P; end Set_Main_CPU; procedure Set_Main_Priority (U : Unit_Number_Type; P : Int) is begin Units.Table (U).Main_Priority := P; end Set_Main_Priority; procedure Set_OA_Setting (U : Unit_Number_Type; C : Character) is begin Units.Table (U).OA_Setting := C; end Set_OA_Setting; procedure Set_Unit_Name (U : Unit_Number_Type; N : Unit_Name_Type) is begin Units.Table (U).Unit_Name := N; end Set_Unit_Name; ------------------------------ -- Check_Same_Extended_Unit -- ------------------------------ function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result is Sloc1 : Source_Ptr; Sloc2 : Source_Ptr; Sind1 : Source_File_Index; Sind2 : Source_File_Index; Inst1 : Source_Ptr; Inst2 : Source_Ptr; Unum1 : Unit_Number_Type; Unum2 : Unit_Number_Type; Unit1 : Node_Id; Unit2 : Node_Id; Depth1 : Nat; Depth2 : Nat; begin if S1 = No_Location or else S2 = No_Location then return No; elsif S1 = Standard_Location then if S2 = Standard_Location then return Yes_Same; else return No; end if; elsif S2 = Standard_Location then return No; end if; Sloc1 := S1; Sloc2 := S2; Unum1 := Get_Source_Unit (Sloc1); Unum2 := Get_Source_Unit (Sloc2); loop -- Step 1: Check whether the two locations are in the same source -- file. Sind1 := Get_Source_File_Index (Sloc1); Sind2 := Get_Source_File_Index (Sloc2); if Sind1 = Sind2 then if Sloc1 < Sloc2 then return Yes_Before; elsif Sloc1 > Sloc2 then return Yes_After; else return Yes_Same; end if; end if; -- Step 2: Check subunits. If a subunit is instantiated, follow the -- instantiation chain rather than the stub chain. Unit1 := Unit (Cunit (Unum1)); Unit2 := Unit (Cunit (Unum2)); Inst1 := Instantiation (Sind1); Inst2 := Instantiation (Sind2); if Nkind (Unit1) = N_Subunit and then Present (Corresponding_Stub (Unit1)) and then Inst1 = No_Location then if Nkind (Unit2) = N_Subunit and then Present (Corresponding_Stub (Unit2)) and then Inst2 = No_Location then -- Both locations refer to subunits which may have a common -- ancestor. If they do, the deeper subunit must have a longer -- unit name. Replace the deeper one with its corresponding -- stub in order to find the nearest ancestor. if Length_Of_Name (Unit_Name (Unum1)) < Length_Of_Name (Unit_Name (Unum2)) then Sloc2 := Sloc (Corresponding_Stub (Unit2)); Unum2 := Get_Source_Unit (Sloc2); goto Continue; else Sloc1 := Sloc (Corresponding_Stub (Unit1)); Unum1 := Get_Source_Unit (Sloc1); goto Continue; end if; -- Sloc1 in subunit, Sloc2 not else Sloc1 := Sloc (Corresponding_Stub (Unit1)); Unum1 := Get_Source_Unit (Sloc1); goto Continue; end if; -- Sloc2 in subunit, Sloc1 not elsif Nkind (Unit2) = N_Subunit and then Present (Corresponding_Stub (Unit2)) and then Inst2 = No_Location then Sloc2 := Sloc (Corresponding_Stub (Unit2)); Unum2 := Get_Source_Unit (Sloc2); goto Continue; end if; -- Step 3: Check instances. The two locations may yield a common -- ancestor. if Inst1 /= No_Location then if Inst2 /= No_Location then -- Both locations denote instantiations Depth1 := Instantiation_Depth (Sloc1); Depth2 := Instantiation_Depth (Sloc2); if Depth1 < Depth2 then Sloc2 := Inst2; Unum2 := Get_Source_Unit (Sloc2); goto Continue; elsif Depth1 > Depth2 then Sloc1 := Inst1; Unum1 := Get_Source_Unit (Sloc1); goto Continue; else Sloc1 := Inst1; Sloc2 := Inst2; Unum1 := Get_Source_Unit (Sloc1); Unum2 := Get_Source_Unit (Sloc2); goto Continue; end if; -- Sloc1 is an instantiation else Sloc1 := Inst1; Unum1 := Get_Source_Unit (Sloc1); goto Continue; end if; -- Sloc2 is an instantiation elsif Inst2 /= No_Location then Sloc2 := Inst2; Unum2 := Get_Source_Unit (Sloc2); goto Continue; end if; -- Step 4: One location in the spec, the other in the corresponding -- body of the same unit. The location in the spec is considered -- earlier. if Nkind (Unit1) = N_Subprogram_Body or else Nkind (Unit1) = N_Package_Body then if Library_Unit (Cunit (Unum1)) = Cunit (Unum2) then return Yes_After; end if; elsif Nkind (Unit2) = N_Subprogram_Body or else Nkind (Unit2) = N_Package_Body then if Library_Unit (Cunit (Unum2)) = Cunit (Unum1) then return Yes_Before; end if; end if; -- At this point it is certain that the two locations denote two -- entirely separate units. return No; <> null; end loop; end Check_Same_Extended_Unit; ------------------------------- -- Compilation_Switches_Last -- ------------------------------- function Compilation_Switches_Last return Nat is begin return Compilation_Switches.Last; end Compilation_Switches_Last; --------------------------- -- Enable_Switch_Storing -- --------------------------- procedure Enable_Switch_Storing is begin Switch_Storing_Enabled := True; end Enable_Switch_Storing; ---------------------------- -- Disable_Switch_Storing -- ---------------------------- procedure Disable_Switch_Storing is begin Switch_Storing_Enabled := False; end Disable_Switch_Storing; ------------------------------ -- Earlier_In_Extended_Unit -- ------------------------------ function Earlier_In_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is begin return Check_Same_Extended_Unit (S1, S2) = Yes_Before; end Earlier_In_Extended_Unit; ----------------------- -- Exact_Source_Name -- ----------------------- function Exact_Source_Name (Loc : Source_Ptr) return String is U : constant Unit_Number_Type := Get_Source_Unit (Loc); Buf : constant Source_Buffer_Ptr := Source_Text (Source_Index (U)); Orig : constant Source_Ptr := Original_Location (Loc); P : Source_Ptr; WC : Char_Code; Err : Boolean; pragma Warnings (Off, WC); pragma Warnings (Off, Err); begin -- Entity is character literal if Buf (Orig) = ''' then return String (Buf (Orig .. Orig + 2)); -- Entity is operator symbol elsif Buf (Orig) = '"' or else Buf (Orig) = '%' then P := Orig; loop P := P + 1; exit when Buf (P) = Buf (Orig); end loop; return String (Buf (Orig .. P)); -- Entity is identifier else P := Orig; loop if Is_Start_Of_Wide_Char (Buf, P) then Scan_Wide (Buf, P, WC, Err); elsif not Identifier_Char (Buf (P)) then exit; else P := P + 1; end if; end loop; -- Write out the identifier by copying the exact source characters -- used in its declaration. Note that this means wide characters will -- be in their original encoded form. return String (Buf (Orig .. P - 1)); end if; end Exact_Source_Name; ---------------------------- -- Entity_Is_In_Main_Unit -- ---------------------------- function Entity_Is_In_Main_Unit (E : Entity_Id) return Boolean is S : Entity_Id; begin S := Scope (E); while S /= Standard_Standard loop if S = Main_Unit_Entity then return True; elsif Ekind (S) = E_Package and then Is_Child_Unit (S) then return False; else S := Scope (S); end if; end loop; return False; end Entity_Is_In_Main_Unit; -------------------------- -- Generic_May_Lack_ALI -- -------------------------- function Generic_May_Lack_ALI (Sfile : File_Name_Type) return Boolean is begin -- We allow internal generic units to be used without having a -- corresponding ALI files to help bootstrapping with older compilers -- that did not support generating ALIs for such generics. It is safe -- to do so because the only thing the generated code would contain -- is the elaboration boolean, and we are careful to elaborate all -- predefined units first anyway. return Is_Internal_File_Name (Fname => Sfile, Renamings_Included => True); end Generic_May_Lack_ALI; ----------------------------- -- Get_Code_Or_Source_Unit -- ----------------------------- function Get_Code_Or_Source_Unit (S : Source_Ptr; Unwind_Instances : Boolean) return Unit_Number_Type is begin -- Search table unless we have No_Location, which can happen if the -- relevant location has not been set yet. Happens for example when -- we obtain Sloc (Cunit (Main_Unit)) before it is set. if S /= No_Location then declare Source_File : Source_File_Index; Source_Unit : Unit_Number_Type; begin Source_File := Get_Source_File_Index (S); if Unwind_Instances then while Template (Source_File) /= No_Source_File loop Source_File := Template (Source_File); end loop; end if; Source_Unit := Unit (Source_File); if Source_Unit /= No_Unit then return Source_Unit; end if; end; end if; -- If S was No_Location, or was not in the table, we must be in the main -- source unit (and the value has not been placed in the table yet), -- or in one of the configuration pragma files. return Main_Unit; end Get_Code_Or_Source_Unit; ------------------- -- Get_Code_Unit -- ------------------- function Get_Code_Unit (S : Source_Ptr) return Unit_Number_Type is begin return Get_Code_Or_Source_Unit (Top_Level_Location (S), Unwind_Instances => False); end Get_Code_Unit; function Get_Code_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is begin return Get_Code_Unit (Sloc (N)); end Get_Code_Unit; ---------------------------- -- Get_Compilation_Switch -- ---------------------------- function Get_Compilation_Switch (N : Pos) return String_Ptr is begin if N <= Compilation_Switches.Last then return Compilation_Switches.Table (N); else return null; end if; end Get_Compilation_Switch; ---------------------------------- -- Get_Cunit_Entity_Unit_Number -- ---------------------------------- function Get_Cunit_Entity_Unit_Number (E : Entity_Id) return Unit_Number_Type is begin for U in Units.First .. Units.Last loop if Cunit_Entity (U) = E then return U; end if; end loop; -- If not in the table, must be the main source unit, and we just -- have not got it put into the table yet. return Main_Unit; end Get_Cunit_Entity_Unit_Number; --------------------------- -- Get_Cunit_Unit_Number -- --------------------------- function Get_Cunit_Unit_Number (N : Node_Id) return Unit_Number_Type is begin for U in Units.First .. Units.Last loop if Cunit (U) = N then return U; end if; end loop; -- If not in the table, must be a spec created for a main unit that is a -- child subprogram body which we have not inserted into the table yet. if N = Library_Unit (Cunit (Main_Unit)) then return Main_Unit; -- If it is anything else, something is seriously wrong, and we really -- don't want to proceed, even if assertions are off, so we explicitly -- raise an exception in this case to terminate compilation. else raise Program_Error; end if; end Get_Cunit_Unit_Number; --------------------- -- Get_Source_Unit -- --------------------- function Get_Source_Unit (S : Source_Ptr) return Unit_Number_Type is begin return Get_Code_Or_Source_Unit (S, Unwind_Instances => True); end Get_Source_Unit; function Get_Source_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is begin return Get_Source_Unit (Sloc (N)); end Get_Source_Unit; -------------------------------- -- In_Extended_Main_Code_Unit -- -------------------------------- function In_Extended_Main_Code_Unit (N : Node_Or_Entity_Id) return Boolean is begin if Sloc (N) = Standard_Location then return False; elsif Sloc (N) = No_Location then return False; -- Special case Itypes to test the Sloc of the associated node. The -- reason we do this is for possible calls from gigi after -gnatD -- processing is complete in sprint. This processing updates the -- sloc fields of all nodes in the tree, but itypes are not in the -- tree so their slocs do not get updated. elsif Nkind (N) = N_Defining_Identifier and then Is_Itype (N) then return In_Extended_Main_Code_Unit (Associated_Node_For_Itype (N)); -- Otherwise see if we are in the main unit elsif Get_Code_Unit (Sloc (N)) = Get_Code_Unit (Cunit (Main_Unit)) then return True; -- Node may be in spec (or subunit etc) of main unit else return In_Same_Extended_Unit (N, Cunit (Main_Unit)); end if; end In_Extended_Main_Code_Unit; function In_Extended_Main_Code_Unit (Loc : Source_Ptr) return Boolean is begin if Loc = Standard_Location then return False; elsif Loc = No_Location then return False; -- Otherwise see if we are in the main unit elsif Get_Code_Unit (Loc) = Get_Code_Unit (Cunit (Main_Unit)) then return True; -- Location may be in spec (or subunit etc) of main unit else return In_Same_Extended_Unit (Loc, Sloc (Cunit (Main_Unit))); end if; end In_Extended_Main_Code_Unit; ---------------------------------- -- In_Extended_Main_Source_Unit -- ---------------------------------- function In_Extended_Main_Source_Unit (N : Node_Or_Entity_Id) return Boolean is Nloc : constant Source_Ptr := Sloc (N); Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit)); begin -- If parsing, then use the global flag to indicate result if Compiler_State = Parsing then return Parsing_Main_Extended_Source; -- Special value cases elsif Nloc = Standard_Location then return False; elsif Nloc = No_Location then return False; -- Special case Itypes to test the Sloc of the associated node. The -- reason we do this is for possible calls from gigi after -gnatD -- processing is complete in sprint. This processing updates the -- sloc fields of all nodes in the tree, but itypes are not in the -- tree so their slocs do not get updated. elsif Nkind (N) = N_Defining_Identifier and then Is_Itype (N) then return In_Extended_Main_Source_Unit (Associated_Node_For_Itype (N)); -- Otherwise compare original locations to see if in same unit else return In_Same_Extended_Unit (Original_Location (Nloc), Original_Location (Mloc)); end if; end In_Extended_Main_Source_Unit; function In_Extended_Main_Source_Unit (Loc : Source_Ptr) return Boolean is Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit)); begin -- If parsing, then use the global flag to indicate result if Compiler_State = Parsing then return Parsing_Main_Extended_Source; -- Special value cases elsif Loc = Standard_Location then return False; elsif Loc = No_Location then return False; -- Otherwise compare original locations to see if in same unit else return In_Same_Extended_Unit (Original_Location (Loc), Original_Location (Mloc)); end if; end In_Extended_Main_Source_Unit; ------------------------ -- In_Predefined_Unit -- ------------------------ function In_Predefined_Unit (N : Node_Or_Entity_Id) return Boolean is begin return In_Predefined_Unit (Sloc (N)); end In_Predefined_Unit; function In_Predefined_Unit (S : Source_Ptr) return Boolean is Unit : constant Unit_Number_Type := Get_Source_Unit (S); File : constant File_Name_Type := Unit_File_Name (Unit); begin return Is_Predefined_File_Name (File); end In_Predefined_Unit; ----------------------- -- In_Same_Code_Unit -- ----------------------- function In_Same_Code_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is S1 : constant Source_Ptr := Sloc (N1); S2 : constant Source_Ptr := Sloc (N2); begin if S1 = No_Location or else S2 = No_Location then return False; elsif S1 = Standard_Location then return S2 = Standard_Location; elsif S2 = Standard_Location then return False; end if; return Get_Code_Unit (N1) = Get_Code_Unit (N2); end In_Same_Code_Unit; --------------------------- -- In_Same_Extended_Unit -- --------------------------- function In_Same_Extended_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is begin return Check_Same_Extended_Unit (Sloc (N1), Sloc (N2)) /= No; end In_Same_Extended_Unit; function In_Same_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is begin return Check_Same_Extended_Unit (S1, S2) /= No; end In_Same_Extended_Unit; ------------------------- -- In_Same_Source_Unit -- ------------------------- function In_Same_Source_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is S1 : constant Source_Ptr := Sloc (N1); S2 : constant Source_Ptr := Sloc (N2); begin if S1 = No_Location or else S2 = No_Location then return False; elsif S1 = Standard_Location then return S2 = Standard_Location; elsif S2 = Standard_Location then return False; end if; return Get_Source_Unit (N1) = Get_Source_Unit (N2); end In_Same_Source_Unit; ----------------------------- -- Increment_Serial_Number -- ----------------------------- function Increment_Serial_Number return Nat is TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number; begin TSN := TSN + 1; return TSN; end Increment_Serial_Number; ---------------- -- Initialize -- ---------------- procedure Initialize is begin Linker_Option_Lines.Init; Notes.Init; Load_Stack.Init; Units.Init; Compilation_Switches.Init; end Initialize; --------------- -- Is_Loaded -- --------------- function Is_Loaded (Uname : Unit_Name_Type) return Boolean is begin for Unum in Units.First .. Units.Last loop if Uname = Unit_Name (Unum) then return True; end if; end loop; return False; end Is_Loaded; --------------- -- Last_Unit -- --------------- function Last_Unit return Unit_Number_Type is begin return Units.Last; end Last_Unit; ---------- -- List -- ---------- procedure List (File_Names_Only : Boolean := False) is separate; ---------- -- Lock -- ---------- procedure Lock is begin Linker_Option_Lines.Locked := True; Load_Stack.Locked := True; Units.Locked := True; Linker_Option_Lines.Release; Load_Stack.Release; Units.Release; end Lock; --------------- -- Num_Units -- --------------- function Num_Units return Nat is begin return Int (Units.Last) - Int (Main_Unit) + 1; end Num_Units; ----------------- -- Remove_Unit -- ----------------- procedure Remove_Unit (U : Unit_Number_Type) is begin if U = Units.Last then Units.Decrement_Last; end if; end Remove_Unit; ---------------------------------- -- Replace_Linker_Option_String -- ---------------------------------- procedure Replace_Linker_Option_String (S : String_Id; Match_String : String) is begin if Match_String'Length > 0 then for J in 1 .. Linker_Option_Lines.Last loop String_To_Name_Buffer (Linker_Option_Lines.Table (J).Option); if Match_String = Name_Buffer (1 .. Match_String'Length) then Linker_Option_Lines.Table (J).Option := S; return; end if; end loop; end if; Store_Linker_Option_String (S); end Replace_Linker_Option_String; ---------- -- Sort -- ---------- procedure Sort (Tbl : in out Unit_Ref_Table) is separate; ------------------------------ -- Store_Compilation_Switch -- ------------------------------ procedure Store_Compilation_Switch (Switch : String) is begin if Switch_Storing_Enabled then Compilation_Switches.Increment_Last; Compilation_Switches.Table (Compilation_Switches.Last) := new String'(Switch); -- Fix up --RTS flag which has been transformed by the gcc driver -- into -fRTS if Switch'Last >= Switch'First + 4 and then Switch (Switch'First .. Switch'First + 4) = "-fRTS" then Compilation_Switches.Table (Compilation_Switches.Last) (Switch'First + 1) := '-'; end if; end if; end Store_Compilation_Switch; -------------------------------- -- Store_Linker_Option_String -- -------------------------------- procedure Store_Linker_Option_String (S : String_Id) is begin Linker_Option_Lines.Append ((Option => S, Unit => Current_Sem_Unit)); end Store_Linker_Option_String; ---------------- -- Store_Note -- ---------------- procedure Store_Note (N : Node_Id) is begin Notes.Append ((Pragma_Node => N, Unit => Current_Sem_Unit)); end Store_Note; ------------------------------- -- Synchronize_Serial_Number -- ------------------------------- procedure Synchronize_Serial_Number is TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number; begin TSN := TSN + 1; end Synchronize_Serial_Number; --------------- -- Tree_Read -- --------------- procedure Tree_Read is N : Nat; S : String_Ptr; begin Units.Tree_Read; -- Read Compilation_Switches table. First release the memory occupied -- by the previously loaded switches. for J in Compilation_Switches.First .. Compilation_Switches.Last loop Free (Compilation_Switches.Table (J)); end loop; Tree_Read_Int (N); Compilation_Switches.Set_Last (N); for J in 1 .. N loop Tree_Read_Str (S); Compilation_Switches.Table (J) := S; end loop; end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is begin Units.Tree_Write; -- Write Compilation_Switches table Tree_Write_Int (Compilation_Switches.Last); for J in 1 .. Compilation_Switches.Last loop Tree_Write_Str (Compilation_Switches.Table (J)); end loop; end Tree_Write; ------------ -- Unlock -- ------------ procedure Unlock is begin Linker_Option_Lines.Locked := False; Load_Stack.Locked := False; Units.Locked := False; end Unlock; ----------------- -- Version_Get -- ----------------- function Version_Get (U : Unit_Number_Type) return Word_Hex_String is begin return Get_Hex_String (Units.Table (U).Version); end Version_Get; ------------------------ -- Version_Referenced -- ------------------------ procedure Version_Referenced (S : String_Id) is begin Version_Ref.Append (S); end Version_Referenced; --------------------- -- Write_Unit_Info -- --------------------- procedure Write_Unit_Info (Unit_Num : Unit_Number_Type; Item : Node_Id; Prefix : String := ""; Withs : Boolean := False) is begin Write_Str (Prefix); Write_Unit_Name (Unit_Name (Unit_Num)); Write_Str (", unit "); Write_Int (Int (Unit_Num)); Write_Str (", "); Write_Int (Int (Item)); Write_Str ("="); Write_Str (Node_Kind'Image (Nkind (Item))); if Item /= Original_Node (Item) then Write_Str (", orig = "); Write_Int (Int (Original_Node (Item))); Write_Str ("="); Write_Str (Node_Kind'Image (Nkind (Original_Node (Item)))); end if; Write_Eol; -- Skip the rest if we're not supposed to print the withs if not Withs then return; end if; declare Context_Item : Node_Id; begin Context_Item := First (Context_Items (Cunit (Unit_Num))); while Present (Context_Item) and then (Nkind (Context_Item) /= N_With_Clause or else Limited_Present (Context_Item)) loop Context_Item := Next (Context_Item); end loop; if Present (Context_Item) then Indent; Write_Line ("withs:"); Indent; while Present (Context_Item) loop if Nkind (Context_Item) = N_With_Clause and then not Limited_Present (Context_Item) then pragma Assert (Present (Library_Unit (Context_Item))); Write_Unit_Name (Unit_Name (Get_Cunit_Unit_Number (Library_Unit (Context_Item)))); if Implicit_With (Context_Item) then Write_Str (" -- implicit"); end if; Write_Eol; end if; Context_Item := Next (Context_Item); end loop; Outdent; Write_Line ("end withs"); Outdent; end if; end; end Write_Unit_Info; end Lib; gprbuild-gpl-2014-src/gnat/uintp.ads0000644000076700001450000006055412323721731016726 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- U I N T P -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- Support for universal integer arithmetic -- WARNING: There is a C version of this package. Any changes to this -- source file must be properly reflected in the C header file uintp.h with Alloc; with Table; pragma Elaborate_All (Table); with Types; use Types; package Uintp is ------------------------------------------------- -- Basic Types and Constants for Uintp Package -- ------------------------------------------------- type Uint is private; -- The basic universal integer type No_Uint : constant Uint; -- A constant value indicating a missing or unset Uint value Uint_0 : constant Uint; Uint_1 : constant Uint; Uint_2 : constant Uint; Uint_3 : constant Uint; Uint_4 : constant Uint; Uint_5 : constant Uint; Uint_6 : constant Uint; Uint_7 : constant Uint; Uint_8 : constant Uint; Uint_9 : constant Uint; Uint_10 : constant Uint; Uint_11 : constant Uint; Uint_12 : constant Uint; Uint_13 : constant Uint; Uint_14 : constant Uint; Uint_15 : constant Uint; Uint_16 : constant Uint; Uint_24 : constant Uint; Uint_32 : constant Uint; Uint_63 : constant Uint; Uint_64 : constant Uint; Uint_80 : constant Uint; Uint_128 : constant Uint; Uint_Minus_1 : constant Uint; Uint_Minus_2 : constant Uint; Uint_Minus_3 : constant Uint; Uint_Minus_4 : constant Uint; Uint_Minus_5 : constant Uint; Uint_Minus_6 : constant Uint; Uint_Minus_7 : constant Uint; Uint_Minus_8 : constant Uint; Uint_Minus_9 : constant Uint; Uint_Minus_12 : constant Uint; Uint_Minus_36 : constant Uint; Uint_Minus_63 : constant Uint; Uint_Minus_80 : constant Uint; Uint_Minus_128 : constant Uint; ----------------- -- Subprograms -- ----------------- procedure Initialize; -- Initialize Uint tables. Note that Initialize must not be called if -- Tree_Read is used. Note also that there is no lock routine in this -- unit, these are among the few tables that can be expanded during -- gigi processing. procedure Tree_Read; -- Initializes internal tables from current tree file using the relevant -- Table.Tree_Read routines. Note that Initialize should not be called if -- Tree_Read is used. Tree_Read includes all necessary initialization. procedure Tree_Write; -- Writes out internal tables to current tree file using the relevant -- Table.Tree_Write routines. function UI_Abs (Right : Uint) return Uint; pragma Inline (UI_Abs); -- Returns abs function of universal integer function UI_Add (Left : Uint; Right : Uint) return Uint; function UI_Add (Left : Int; Right : Uint) return Uint; function UI_Add (Left : Uint; Right : Int) return Uint; -- Returns sum of two integer values function UI_Decimal_Digits_Hi (U : Uint) return Nat; -- Returns an estimate of the number of decimal digits required to -- represent the absolute value of U. This estimate is correct or high, -- i.e. it never returns a value that is too low. The accuracy of the -- estimate affects only the effectiveness of comparison optimizations -- in Urealp. function UI_Decimal_Digits_Lo (U : Uint) return Nat; -- Returns an estimate of the number of decimal digits required to -- represent the absolute value of U. This estimate is correct or low, -- i.e. it never returns a value that is too high. The accuracy of the -- estimate affects only the effectiveness of comparison optimizations -- in Urealp. function UI_Div (Left : Uint; Right : Uint) return Uint; function UI_Div (Left : Int; Right : Uint) return Uint; function UI_Div (Left : Uint; Right : Int) return Uint; -- Returns quotient of two integer values. Fatal error if Right = 0 function UI_Eq (Left : Uint; Right : Uint) return Boolean; function UI_Eq (Left : Int; Right : Uint) return Boolean; function UI_Eq (Left : Uint; Right : Int) return Boolean; pragma Inline (UI_Eq); -- Compares integer values for equality function UI_Expon (Left : Uint; Right : Uint) return Uint; function UI_Expon (Left : Int; Right : Uint) return Uint; function UI_Expon (Left : Uint; Right : Int) return Uint; function UI_Expon (Left : Int; Right : Int) return Uint; -- Returns result of exponentiating two integer values. -- Fatal error if Right is negative. function UI_GCD (Uin, Vin : Uint) return Uint; -- Computes GCD of input values. Assumes Uin >= Vin >= 0 function UI_Ge (Left : Uint; Right : Uint) return Boolean; function UI_Ge (Left : Int; Right : Uint) return Boolean; function UI_Ge (Left : Uint; Right : Int) return Boolean; pragma Inline (UI_Ge); -- Compares integer values for greater than or equal function UI_Gt (Left : Uint; Right : Uint) return Boolean; function UI_Gt (Left : Int; Right : Uint) return Boolean; function UI_Gt (Left : Uint; Right : Int) return Boolean; pragma Inline (UI_Gt); -- Compares integer values for greater than function UI_Is_In_Int_Range (Input : Uint) return Boolean; pragma Inline (UI_Is_In_Int_Range); -- Determines if universal integer is in Int range function UI_Le (Left : Uint; Right : Uint) return Boolean; function UI_Le (Left : Int; Right : Uint) return Boolean; function UI_Le (Left : Uint; Right : Int) return Boolean; pragma Inline (UI_Le); -- Compares integer values for less than or equal function UI_Lt (Left : Uint; Right : Uint) return Boolean; function UI_Lt (Left : Int; Right : Uint) return Boolean; function UI_Lt (Left : Uint; Right : Int) return Boolean; -- Compares integer values for less than function UI_Max (Left : Uint; Right : Uint) return Uint; function UI_Max (Left : Int; Right : Uint) return Uint; function UI_Max (Left : Uint; Right : Int) return Uint; -- Returns maximum of two integer values function UI_Min (Left : Uint; Right : Uint) return Uint; function UI_Min (Left : Int; Right : Uint) return Uint; function UI_Min (Left : Uint; Right : Int) return Uint; -- Returns minimum of two integer values function UI_Mod (Left : Uint; Right : Uint) return Uint; function UI_Mod (Left : Int; Right : Uint) return Uint; function UI_Mod (Left : Uint; Right : Int) return Uint; pragma Inline (UI_Mod); -- Returns mod function of two integer values function UI_Mul (Left : Uint; Right : Uint) return Uint; function UI_Mul (Left : Int; Right : Uint) return Uint; function UI_Mul (Left : Uint; Right : Int) return Uint; -- Returns product of two integer values function UI_Ne (Left : Uint; Right : Uint) return Boolean; function UI_Ne (Left : Int; Right : Uint) return Boolean; function UI_Ne (Left : Uint; Right : Int) return Boolean; pragma Inline (UI_Ne); -- Compares integer values for inequality function UI_Negate (Right : Uint) return Uint; pragma Inline (UI_Negate); -- Returns negative of universal integer function UI_Rem (Left : Uint; Right : Uint) return Uint; function UI_Rem (Left : Int; Right : Uint) return Uint; function UI_Rem (Left : Uint; Right : Int) return Uint; -- Returns rem of two integer values function UI_Sub (Left : Uint; Right : Uint) return Uint; function UI_Sub (Left : Int; Right : Uint) return Uint; function UI_Sub (Left : Uint; Right : Int) return Uint; pragma Inline (UI_Sub); -- Returns difference of two integer values function UI_Modular_Exponentiation (B : Uint; E : Uint; Modulo : Uint) return Uint; -- Efficiently compute (B ** E) rem Modulo function UI_Modular_Inverse (N : Uint; Modulo : Uint) return Uint; -- Compute the multiplicative inverse of N in modular arithmetics with the -- given Modulo (uses Euclid's algorithm). Note: the call is considered -- to be erroneous (and the behavior is undefined) if n is not invertible. function UI_From_Int (Input : Int) return Uint; -- Converts Int value to universal integer form function UI_From_CC (Input : Char_Code) return Uint; -- Converts Char_Code value to universal integer form function UI_To_Int (Input : Uint) return Int; -- Converts universal integer value to Int. Fatal error if value is not in -- appropriate range. function UI_To_CC (Input : Uint) return Char_Code; -- Converts universal integer value to Char_Code. Fatal error if value is -- not in Char_Code range. function Num_Bits (Input : Uint) return Nat; -- Approximate number of binary bits in given universal integer. This -- function is used for capacity checks, and it can be one bit off -- without affecting its usage. --------------------- -- Output Routines -- --------------------- type UI_Format is (Hex, Decimal, Auto); -- Used to determine whether UI_Image/UI_Write output is in hexadecimal -- or decimal format. Auto, the default setting, lets the routine make a -- decision based on the value. UI_Image_Max : constant := 48; -- Enough for a 128-bit number UI_Image_Buffer : String (1 .. UI_Image_Max); UI_Image_Length : Natural; -- Buffer used for UI_Image as described below procedure UI_Image (Input : Uint; Format : UI_Format := Auto); -- Places a representation of Uint, consisting of a possible minus sign, -- followed by the value in UI_Image_Buffer. The form of the value is an -- integer literal in either decimal (no base) or hexadecimal (base 16) -- format. If Hex is True on entry, then hex mode is forced, otherwise -- UI_Image makes a guess at which output format is more convenient. -- The value must fit in UI_Image_Buffer. If necessary, the result is an -- approximation of the proper value, using an exponential format. The -- image of No_Uint is output as a single question mark. procedure UI_Write (Input : Uint; Format : UI_Format := Auto); -- Writes a representation of Uint, consisting of a possible minus sign, -- followed by the value to the output file. The form of the value is an -- integer literal in either decimal (no base) or hexadecimal (base 16) -- format as appropriate. UI_Format shows which format to use. Auto, the -- default, asks UI_Write to make a guess at which output format will be -- more convenient to read. procedure pid (Input : Uint); pragma Export (Ada, pid); -- Writes representation of Uint in decimal with a terminating line -- return. This is intended for use from the debugger. procedure pih (Input : Uint); pragma Export (Ada, pih); -- Writes representation of Uint in hex with a terminating line return. -- This is intended for use from the debugger. ------------------------ -- Operator Renamings -- ------------------------ function "+" (Left : Uint; Right : Uint) return Uint renames UI_Add; function "+" (Left : Int; Right : Uint) return Uint renames UI_Add; function "+" (Left : Uint; Right : Int) return Uint renames UI_Add; function "/" (Left : Uint; Right : Uint) return Uint renames UI_Div; function "/" (Left : Int; Right : Uint) return Uint renames UI_Div; function "/" (Left : Uint; Right : Int) return Uint renames UI_Div; function "*" (Left : Uint; Right : Uint) return Uint renames UI_Mul; function "*" (Left : Int; Right : Uint) return Uint renames UI_Mul; function "*" (Left : Uint; Right : Int) return Uint renames UI_Mul; function "-" (Left : Uint; Right : Uint) return Uint renames UI_Sub; function "-" (Left : Int; Right : Uint) return Uint renames UI_Sub; function "-" (Left : Uint; Right : Int) return Uint renames UI_Sub; function "**" (Left : Uint; Right : Uint) return Uint renames UI_Expon; function "**" (Left : Uint; Right : Int) return Uint renames UI_Expon; function "**" (Left : Int; Right : Uint) return Uint renames UI_Expon; function "**" (Left : Int; Right : Int) return Uint renames UI_Expon; function "abs" (Real : Uint) return Uint renames UI_Abs; function "mod" (Left : Uint; Right : Uint) return Uint renames UI_Mod; function "mod" (Left : Int; Right : Uint) return Uint renames UI_Mod; function "mod" (Left : Uint; Right : Int) return Uint renames UI_Mod; function "rem" (Left : Uint; Right : Uint) return Uint renames UI_Rem; function "rem" (Left : Int; Right : Uint) return Uint renames UI_Rem; function "rem" (Left : Uint; Right : Int) return Uint renames UI_Rem; function "-" (Real : Uint) return Uint renames UI_Negate; function "=" (Left : Uint; Right : Uint) return Boolean renames UI_Eq; function "=" (Left : Int; Right : Uint) return Boolean renames UI_Eq; function "=" (Left : Uint; Right : Int) return Boolean renames UI_Eq; function ">=" (Left : Uint; Right : Uint) return Boolean renames UI_Ge; function ">=" (Left : Int; Right : Uint) return Boolean renames UI_Ge; function ">=" (Left : Uint; Right : Int) return Boolean renames UI_Ge; function ">" (Left : Uint; Right : Uint) return Boolean renames UI_Gt; function ">" (Left : Int; Right : Uint) return Boolean renames UI_Gt; function ">" (Left : Uint; Right : Int) return Boolean renames UI_Gt; function "<=" (Left : Uint; Right : Uint) return Boolean renames UI_Le; function "<=" (Left : Int; Right : Uint) return Boolean renames UI_Le; function "<=" (Left : Uint; Right : Int) return Boolean renames UI_Le; function "<" (Left : Uint; Right : Uint) return Boolean renames UI_Lt; function "<" (Left : Int; Right : Uint) return Boolean renames UI_Lt; function "<" (Left : Uint; Right : Int) return Boolean renames UI_Lt; ----------------------------- -- Mark/Release Processing -- ----------------------------- -- The space used by Uint data is not automatically reclaimed. However, a -- mark-release regime is implemented which allows storage to be released -- back to a previously noted mark. This is used for example when doing -- comparisons, where only intermediate results get stored that do not -- need to be saved for future use. type Save_Mark is private; function Mark return Save_Mark; -- Note mark point for future release procedure Release (M : Save_Mark); -- Release storage allocated since mark was noted procedure Release_And_Save (M : Save_Mark; UI : in out Uint); -- Like Release, except that the given Uint value (which is typically among -- the data being released) is recopied after the release, so that it is -- the most recent item, and UI is updated to point to its copied location. procedure Release_And_Save (M : Save_Mark; UI1, UI2 : in out Uint); -- Like Release, except that the given Uint values (which are typically -- among the data being released) are recopied after the release, so that -- they are the most recent items, and UI1 and UI2 are updated if necessary -- to point to the copied locations. This routine is careful to do things -- in the right order, so that the values do not clobber one another. ----------------------------------- -- Representation of Uint Values -- ----------------------------------- private type Uint is new Int range Uint_Low_Bound .. Uint_High_Bound; for Uint'Size use 32; No_Uint : constant Uint := Uint (Uint_Low_Bound); -- Uint values are represented as multiple precision integers stored in -- a multi-digit format using Base as the base. This value is chosen so -- that the product Base*Base is within the range of allowed Int values. -- Base is defined to allow efficient execution of the primitive operations -- (a0, b0, c0) defined in the section "The Classical Algorithms" -- (sec. 4.3.1) of Donald Knuth's "The Art of Computer Programming", -- Vol. 2. These algorithms are used in this package. In particular, -- the product of two single digits in this base fits in a 32-bit integer. Base_Bits : constant := 15; -- Number of bits in base value Base : constant Int := 2 ** Base_Bits; -- Values in the range -(Base-1) .. Max_Direct are encoded directly as -- Uint values by adding a bias value. The value of Max_Direct is chosen -- so that a directly represented number always fits in two digits when -- represented in base format. Min_Direct : constant Int := -(Base - 1); Max_Direct : constant Int := (Base - 1) * (Base - 1); -- The following values define the bias used to store Uint values which -- are in this range, as well as the biased values for the first and last -- values in this range. We use a new derived type for these constants to -- avoid accidental use of Uint arithmetic on these values, which is never -- correct. type Ctrl is range Int'First .. Int'Last; Uint_Direct_Bias : constant Ctrl := Ctrl (Uint_Low_Bound) + Ctrl (Base); Uint_Direct_First : constant Ctrl := Uint_Direct_Bias + Ctrl (Min_Direct); Uint_Direct_Last : constant Ctrl := Uint_Direct_Bias + Ctrl (Max_Direct); Uint_0 : constant Uint := Uint (Uint_Direct_Bias); Uint_1 : constant Uint := Uint (Uint_Direct_Bias + 1); Uint_2 : constant Uint := Uint (Uint_Direct_Bias + 2); Uint_3 : constant Uint := Uint (Uint_Direct_Bias + 3); Uint_4 : constant Uint := Uint (Uint_Direct_Bias + 4); Uint_5 : constant Uint := Uint (Uint_Direct_Bias + 5); Uint_6 : constant Uint := Uint (Uint_Direct_Bias + 6); Uint_7 : constant Uint := Uint (Uint_Direct_Bias + 7); Uint_8 : constant Uint := Uint (Uint_Direct_Bias + 8); Uint_9 : constant Uint := Uint (Uint_Direct_Bias + 9); Uint_10 : constant Uint := Uint (Uint_Direct_Bias + 10); Uint_11 : constant Uint := Uint (Uint_Direct_Bias + 11); Uint_12 : constant Uint := Uint (Uint_Direct_Bias + 12); Uint_13 : constant Uint := Uint (Uint_Direct_Bias + 13); Uint_14 : constant Uint := Uint (Uint_Direct_Bias + 14); Uint_15 : constant Uint := Uint (Uint_Direct_Bias + 15); Uint_16 : constant Uint := Uint (Uint_Direct_Bias + 16); Uint_24 : constant Uint := Uint (Uint_Direct_Bias + 24); Uint_32 : constant Uint := Uint (Uint_Direct_Bias + 32); Uint_63 : constant Uint := Uint (Uint_Direct_Bias + 63); Uint_64 : constant Uint := Uint (Uint_Direct_Bias + 64); Uint_80 : constant Uint := Uint (Uint_Direct_Bias + 80); Uint_128 : constant Uint := Uint (Uint_Direct_Bias + 128); Uint_Minus_1 : constant Uint := Uint (Uint_Direct_Bias - 1); Uint_Minus_2 : constant Uint := Uint (Uint_Direct_Bias - 2); Uint_Minus_3 : constant Uint := Uint (Uint_Direct_Bias - 3); Uint_Minus_4 : constant Uint := Uint (Uint_Direct_Bias - 4); Uint_Minus_5 : constant Uint := Uint (Uint_Direct_Bias - 5); Uint_Minus_6 : constant Uint := Uint (Uint_Direct_Bias - 6); Uint_Minus_7 : constant Uint := Uint (Uint_Direct_Bias - 7); Uint_Minus_8 : constant Uint := Uint (Uint_Direct_Bias - 8); Uint_Minus_9 : constant Uint := Uint (Uint_Direct_Bias - 9); Uint_Minus_12 : constant Uint := Uint (Uint_Direct_Bias - 12); Uint_Minus_36 : constant Uint := Uint (Uint_Direct_Bias - 36); Uint_Minus_63 : constant Uint := Uint (Uint_Direct_Bias - 63); Uint_Minus_80 : constant Uint := Uint (Uint_Direct_Bias - 80); Uint_Minus_128 : constant Uint := Uint (Uint_Direct_Bias - 128); Uint_Max_Simple_Mul : constant := Uint_Direct_Bias + 2 ** 15; -- If two values are directly represented and less than or equal to this -- value, then we know the product fits in a 32-bit integer. This allows -- UI_Mul to efficiently compute the product in this case. type Save_Mark is record Save_Uint : Uint; Save_Udigit : Int; end record; -- Values outside the range that is represented directly are stored using -- two tables. The secondary table Udigits contains sequences of Int values -- consisting of the digits of the number in a radix Base system. The -- digits are stored from most significant to least significant with the -- first digit only carrying the sign. -- There is one entry in the primary Uints table for each distinct Uint -- value. This table entry contains the length (number of digits) and -- a starting offset of the value in the Udigits table. Uint_First_Entry : constant Uint := Uint (Uint_Table_Start); -- Some subprograms defined in this package manipulate the Udigits table -- directly, while for others it is more convenient to work with locally -- defined arrays of the digits of the Universal Integers. The type -- UI_Vector is defined for this purpose and some internal subprograms -- used for converting from one to the other are defined. type UI_Vector is array (Pos range <>) of Int; -- Vector containing the integer values of a Uint value -- Note: An earlier version of this package used pointers of arrays of Ints -- (dynamically allocated) for the Uint type. The change leads to a few -- less natural idioms used throughout this code, but eliminates all uses -- of the heap except for the table package itself. For example, Uint -- parameters are often converted to UI_Vectors for internal manipulation. -- This is done by creating the local UI_Vector using the function N_Digits -- on the Uint to find the size needed for the vector, and then calling -- Init_Operand to copy the values out of the table into the vector. type Uint_Entry is record Length : Pos; -- Length of entry in Udigits table in digits (i.e. in words) Loc : Int; -- Starting location in Udigits table of this Uint value end record; package Uints is new Table.Table ( Table_Component_Type => Uint_Entry, Table_Index_Type => Uint'Base, Table_Low_Bound => Uint_First_Entry, Table_Initial => Alloc.Uints_Initial, Table_Increment => Alloc.Uints_Increment, Table_Name => "Uints"); package Udigits is new Table.Table ( Table_Component_Type => Int, Table_Index_Type => Int, Table_Low_Bound => 0, Table_Initial => Alloc.Udigits_Initial, Table_Increment => Alloc.Udigits_Increment, Table_Name => "Udigits"); -- Note: the reason these tables are defined here in the private part of -- the spec, rather than in the body, is that they are referenced directly -- by gigi. end Uintp; gprbuild-gpl-2014-src/gnat/prj-attr.adb0000644000076700001450000007070212323721731017305 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . A T T R -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Osint; with Prj.Com; use Prj.Com; with GNAT.Case_Util; use GNAT.Case_Util; package body Prj.Attr is use GNAT; -- Data for predefined attributes and packages -- Names are in lower case and end with '#' -- Package names are preceded by 'P' -- Attribute names are preceded by two or three letters: -- The first letter is one of -- 'S' for Single -- 's' for Single with optional index -- 'L' for List -- 'l' for List of strings with optional indexes -- The second letter is one of -- 'V' for single variable -- 'A' for associative array -- 'a' for case insensitive associative array -- 'b' for associative array, case insensitive if file names are case -- insensitive -- 'c' same as 'b', with optional index -- The third optional letter is -- 'R' to indicate that the attribute is read-only -- 'O' to indicate that others is allowed as an index for an associative -- array -- End is indicated by two consecutive '#' Initialization_Data : constant String := -- project level attributes -- General "SVRname#" & "SVRproject_dir#" & "lVmain#" & "LVlanguages#" & "Lbroots#" & "SVexternally_built#" & -- Directories "SVobject_dir#" & "SVexec_dir#" & "LVsource_dirs#" & "Lainherit_source_path#" & "LVexcluded_source_dirs#" & "LVignore_source_sub_dirs#" & -- Source files "LVsource_files#" & "LVlocally_removed_files#" & "LVexcluded_source_files#" & "SVsource_list_file#" & "SVexcluded_source_list_file#" & "LVinterfaces#" & -- Projects (in aggregate projects) "LVproject_files#" & "LVproject_path#" & "SAexternal#" & -- Libraries "SVlibrary_dir#" & "SVlibrary_name#" & "SVlibrary_kind#" & "SVlibrary_version#" & "LVlibrary_interface#" & "SVlibrary_standalone#" & "LVlibrary_encapsulated_options#" & "SVlibrary_encapsulated_supported#" & "SVlibrary_auto_init#" & "LVleading_library_options#" & "LVlibrary_options#" & "Lalibrary_rpath_options#" & "SVlibrary_src_dir#" & "SVlibrary_ali_dir#" & "SVlibrary_gcc#" & "SVlibrary_symbol_file#" & "SVlibrary_symbol_policy#" & "SVlibrary_reference_symbol_file#" & -- Configuration - General "SVdefault_language#" & "LVrun_path_option#" & "SVrun_path_origin#" & "SVseparate_run_path_options#" & "Satoolchain_version#" & "Satoolchain_description#" & "Saobject_generated#" & "Saobjects_linked#" & "SVtarget#" & -- Configuration - Libraries "SVlibrary_builder#" & "SVlibrary_support#" & -- Configuration - Archives "LVarchive_builder#" & "LVarchive_builder_append_option#" & "LVarchive_indexer#" & "SVarchive_suffix#" & "LVlibrary_partial_linker#" & -- Configuration - Shared libraries "SVshared_library_prefix#" & "SVshared_library_suffix#" & "SVsymbolic_link_supported#" & "SVlibrary_major_minor_id_supported#" & "SVlibrary_auto_init_supported#" & "LVshared_library_minimum_switches#" & "LVlibrary_version_switches#" & "SVlibrary_install_name_option#" & "Saruntime_library_dir#" & "Saruntime_source_dir#" & -- package Naming -- Some attributes are obsolescent, and renamed in the tree (see -- Prj.Dect.Rename_Obsolescent_Attributes). "Pnaming#" & "Saspecification_suffix#" & -- Always renamed to "spec_suffix" in tree "Saspec_suffix#" & "Saimplementation_suffix#" & -- Always renamed to "body_suffix" in tree "Sabody_suffix#" & "SVseparate_suffix#" & "SVcasing#" & "SVdot_replacement#" & "saspecification#" & -- Always renamed to "spec" in project tree "saspec#" & "saimplementation#" & -- Always renamed to "body" in project tree "sabody#" & "Laspecification_exceptions#" & "Laimplementation_exceptions#" & -- package Compiler "Pcompiler#" & "Ladefault_switches#" & "LcOswitches#" & "SVlocal_configuration_pragmas#" & "Salocal_config_file#" & -- Configuration - Compiling "Sadriver#" & "Salanguage_kind#" & "Sadependency_kind#" & "Larequired_switches#" & "Laleading_required_switches#" & "Latrailing_required_switches#" & "Lapic_option#" & "Sapath_syntax#" & "Lasource_file_switches#" & "Saobject_file_suffix#" & "Laobject_file_switches#" & "Lamulti_unit_switches#" & "Samulti_unit_object_separator#" & -- Configuration - Mapping files "Lamapping_file_switches#" & "Samapping_spec_suffix#" & "Samapping_body_suffix#" & -- Configuration - Config files "Laconfig_file_switches#" & "Saconfig_body_file_name#" & "Saconfig_body_file_name_index#" & "Saconfig_body_file_name_pattern#" & "Saconfig_spec_file_name#" & "Saconfig_spec_file_name_index#" & "Saconfig_spec_file_name_pattern#" & "Saconfig_file_unique#" & -- Configuration - Dependencies "Ladependency_switches#" & "Ladependency_driver#" & -- Configuration - Search paths "Lainclude_switches#" & "Sainclude_path#" & "Sainclude_path_file#" & "Laobject_path_switches#" & -- package Builder "Pbuilder#" & "Ladefault_switches#" & "LcOswitches#" & "Lcglobal_compilation_switches#" & "Scexecutable#" & "SVexecutable_suffix#" & "SVglobal_configuration_pragmas#" & "Saglobal_config_file#" & -- package gnatls "Pgnatls#" & "LVswitches#" & -- package Binder "Pbinder#" & "Ladefault_switches#" & "LcOswitches#" & -- Configuration - Binding "Sadriver#" & "Larequired_switches#" & "Saprefix#" & "Saobjects_path#" & "Saobjects_path_file#" & -- package Linker "Plinker#" & "LVrequired_switches#" & "Ladefault_switches#" & "LcOleading_switches#" & "LcOswitches#" & "LcOtrailing_switches#" & "LVlinker_options#" & "SVmap_file_option#" & -- Configuration - Linking "SVdriver#" & "LVexecutable_switch#" & "SVlib_dir_switch#" & "SVlib_name_switch#" & -- Configuration - Response files "SVmax_command_line_length#" & "SVresponse_file_format#" & "LVresponse_file_switches#" & -- package Clean "Pclean#" & "LVswitches#" & "Lasource_artifact_extensions#" & "Laobject_artifact_extensions#" & "LVartifacts_in_exec_dir#" & "LVartifacts_in_object_dir#" & -- package Cross_Reference "Pcross_reference#" & "Ladefault_switches#" & "LbOswitches#" & -- package Finder "Pfinder#" & "Ladefault_switches#" & "LbOswitches#" & -- package Pretty_Printer "Ppretty_printer#" & "Ladefault_switches#" & "LbOswitches#" & -- package gnatstub "Pgnatstub#" & "Ladefault_switches#" & "LbOswitches#" & -- package Check "Pcheck#" & "Ladefault_switches#" & "LbOswitches#" & -- package Synchronize "Psynchronize#" & "Ladefault_switches#" & "LbOswitches#" & -- package Eliminate "Peliminate#" & "Ladefault_switches#" & "LbOswitches#" & -- package Metrics "Pmetrics#" & "Ladefault_switches#" & "LbOswitches#" & -- package Ide "Pide#" & "Ladefault_switches#" & "SVremote_host#" & "SVprogram_host#" & "SVcommunication_protocol#" & "Sacompiler_command#" & "SVdebugger_command#" & "SVgnatlist#" & "SVvcs_kind#" & "SVvcs_file_check#" & "SVvcs_log_check#" & "SVdocumentation_dir#" & -- package Install "Pinstall#" & "SVprefix#" & "SVsources_subdir#" & "SVexec_subdir#" & "SVlib_subdir#" & "SVproject_subdir#" & "SVactive#" & "LAartifacts#" & -- package Remote "Premote#" & "SVroot_dir#" & "LVexcluded_patterns#" & "LVincluded_patterns#" & "LVincluded_artifact_patterns#" & -- package Stack "Pstack#" & "LVswitches#" & "#"; Initialized : Boolean := False; -- A flag to avoid multiple initialization Package_Names : String_List_Access := new Strings.String_List (1 .. 20); Last_Package_Name : Natural := 0; -- Package_Names (1 .. Last_Package_Name) contains the list of the known -- package names, coming from the Initialization_Data string or from -- calls to one of the two procedures Register_New_Package. procedure Add_Package_Name (Name : String); -- Add a package name in the Package_Name list, extending it, if necessary function Name_Id_Of (Name : String) return Name_Id; -- Returns the Name_Id for Name in lower case ---------------------- -- Add_Package_Name -- ---------------------- procedure Add_Package_Name (Name : String) is begin if Last_Package_Name = Package_Names'Last then declare New_List : constant Strings.String_List_Access := new Strings.String_List (1 .. Package_Names'Last * 2); begin New_List (Package_Names'Range) := Package_Names.all; Package_Names := New_List; end; end if; Last_Package_Name := Last_Package_Name + 1; Package_Names (Last_Package_Name) := new String'(Name); end Add_Package_Name; ----------------------- -- Attribute_Kind_Of -- ----------------------- function Attribute_Kind_Of (Attribute : Attribute_Node_Id) return Attribute_Kind is begin if Attribute = Empty_Attribute then return Unknown; else return Attrs.Table (Attribute.Value).Attr_Kind; end if; end Attribute_Kind_Of; ----------------------- -- Attribute_Name_Of -- ----------------------- function Attribute_Name_Of (Attribute : Attribute_Node_Id) return Name_Id is begin if Attribute = Empty_Attribute then return No_Name; else return Attrs.Table (Attribute.Value).Name; end if; end Attribute_Name_Of; -------------------------- -- Attribute_Node_Id_Of -- -------------------------- function Attribute_Node_Id_Of (Name : Name_Id; Starting_At : Attribute_Node_Id) return Attribute_Node_Id is Id : Attr_Node_Id := Starting_At.Value; begin while Id /= Empty_Attr and then Attrs.Table (Id).Name /= Name loop Id := Attrs.Table (Id).Next; end loop; return (Value => Id); end Attribute_Node_Id_Of; ---------------- -- Initialize -- ---------------- procedure Initialize is Start : Positive := Initialization_Data'First; Finish : Positive := Start; Current_Package : Pkg_Node_Id := Empty_Pkg; Current_Attribute : Attr_Node_Id := Empty_Attr; Is_An_Attribute : Boolean := False; Var_Kind : Variable_Kind := Undefined; Optional_Index : Boolean := False; Attr_Kind : Attribute_Kind := Single; Package_Name : Name_Id := No_Name; Attribute_Name : Name_Id := No_Name; First_Attribute : Attr_Node_Id := Attr.First_Attribute; Read_Only : Boolean; Others_Allowed : Boolean; function Attribute_Location return String; -- Returns a string depending if we are in the project level attributes -- or in the attributes of a package. ------------------------ -- Attribute_Location -- ------------------------ function Attribute_Location return String is begin if Package_Name = No_Name then return "project level attributes"; else return "attribute of package """ & Get_Name_String (Package_Name) & """"; end if; end Attribute_Location; -- Start of processing for Initialize begin -- Don't allow Initialize action to be repeated if Initialized then return; end if; -- Make sure the two tables are empty Attrs.Init; Package_Attributes.Init; while Initialization_Data (Start) /= '#' loop Is_An_Attribute := True; case Initialization_Data (Start) is when 'P' => -- New allowed package Start := Start + 1; Finish := Start; while Initialization_Data (Finish) /= '#' loop Finish := Finish + 1; end loop; Package_Name := Name_Id_Of (Initialization_Data (Start .. Finish - 1)); for Index in First_Package .. Package_Attributes.Last loop if Package_Name = Package_Attributes.Table (Index).Name then Osint.Fail ("duplicate name """ & Initialization_Data (Start .. Finish - 1) & """ in predefined packages."); end if; end loop; Is_An_Attribute := False; Current_Attribute := Empty_Attr; Package_Attributes.Increment_Last; Current_Package := Package_Attributes.Last; Package_Attributes.Table (Current_Package) := (Name => Package_Name, Known => True, First_Attribute => Empty_Attr); Start := Finish + 1; Add_Package_Name (Get_Name_String (Package_Name)); when 'S' => Var_Kind := Single; Optional_Index := False; when 's' => Var_Kind := Single; Optional_Index := True; when 'L' => Var_Kind := List; Optional_Index := False; when 'l' => Var_Kind := List; Optional_Index := True; when others => raise Program_Error; end case; if Is_An_Attribute then -- New attribute Start := Start + 1; case Initialization_Data (Start) is when 'V' => Attr_Kind := Single; when 'A' => Attr_Kind := Associative_Array; when 'a' => Attr_Kind := Case_Insensitive_Associative_Array; when 'b' => if Osint.File_Names_Case_Sensitive then Attr_Kind := Associative_Array; else Attr_Kind := Case_Insensitive_Associative_Array; end if; when 'c' => if Osint.File_Names_Case_Sensitive then Attr_Kind := Optional_Index_Associative_Array; else Attr_Kind := Optional_Index_Case_Insensitive_Associative_Array; end if; when others => raise Program_Error; end case; Start := Start + 1; Read_Only := False; Others_Allowed := False; if Initialization_Data (Start) = 'R' then Read_Only := True; Start := Start + 1; elsif Initialization_Data (Start) = 'O' then Others_Allowed := True; Start := Start + 1; end if; Finish := Start; while Initialization_Data (Finish) /= '#' loop Finish := Finish + 1; end loop; Attribute_Name := Name_Id_Of (Initialization_Data (Start .. Finish - 1)); Attrs.Increment_Last; if Current_Attribute = Empty_Attr then First_Attribute := Attrs.Last; if Current_Package /= Empty_Pkg then Package_Attributes.Table (Current_Package).First_Attribute := Attrs.Last; end if; else -- Check that there are no duplicate attributes for Index in First_Attribute .. Attrs.Last - 1 loop if Attribute_Name = Attrs.Table (Index).Name then Osint.Fail ("duplicate attribute """ & Initialization_Data (Start .. Finish - 1) & """ in " & Attribute_Location); end if; end loop; Attrs.Table (Current_Attribute).Next := Attrs.Last; end if; Current_Attribute := Attrs.Last; Attrs.Table (Current_Attribute) := (Name => Attribute_Name, Var_Kind => Var_Kind, Optional_Index => Optional_Index, Attr_Kind => Attr_Kind, Read_Only => Read_Only, Others_Allowed => Others_Allowed, Next => Empty_Attr); Start := Finish + 1; end if; end loop; Initialized := True; end Initialize; ------------------ -- Is_Read_Only -- ------------------ function Is_Read_Only (Attribute : Attribute_Node_Id) return Boolean is begin return Attrs.Table (Attribute.Value).Read_Only; end Is_Read_Only; ---------------- -- Name_Id_Of -- ---------------- function Name_Id_Of (Name : String) return Name_Id is begin Name_Len := 0; Add_Str_To_Name_Buffer (Name); To_Lower (Name_Buffer (1 .. Name_Len)); return Name_Find; end Name_Id_Of; -------------------- -- Next_Attribute -- -------------------- function Next_Attribute (After : Attribute_Node_Id) return Attribute_Node_Id is begin if After = Empty_Attribute then return Empty_Attribute; else return (Value => Attrs.Table (After.Value).Next); end if; end Next_Attribute; ----------------------- -- Optional_Index_Of -- ----------------------- function Optional_Index_Of (Attribute : Attribute_Node_Id) return Boolean is begin if Attribute = Empty_Attribute then return False; else return Attrs.Table (Attribute.Value).Optional_Index; end if; end Optional_Index_Of; function Others_Allowed_For (Attribute : Attribute_Node_Id) return Boolean is begin if Attribute = Empty_Attribute then return False; else return Attrs.Table (Attribute.Value).Others_Allowed; end if; end Others_Allowed_For; ----------------------- -- Package_Name_List -- ----------------------- function Package_Name_List return Strings.String_List is begin return Package_Names (1 .. Last_Package_Name); end Package_Name_List; ------------------------ -- Package_Node_Id_Of -- ------------------------ function Package_Node_Id_Of (Name : Name_Id) return Package_Node_Id is begin for Index in Package_Attributes.First .. Package_Attributes.Last loop if Package_Attributes.Table (Index).Name = Name then if Package_Attributes.Table (Index).Known then return (Value => Index); else return Unknown_Package; end if; end if; end loop; -- If there is no package with this name, return Empty_Package return Empty_Package; end Package_Node_Id_Of; ---------------------------- -- Register_New_Attribute -- ---------------------------- procedure Register_New_Attribute (Name : String; In_Package : Package_Node_Id; Attr_Kind : Defined_Attribute_Kind; Var_Kind : Defined_Variable_Kind; Index_Is_File_Name : Boolean := False; Opt_Index : Boolean := False) is Attr_Name : Name_Id; First_Attr : Attr_Node_Id := Empty_Attr; Curr_Attr : Attr_Node_Id; Real_Attr_Kind : Attribute_Kind; begin if Name'Length = 0 then Fail ("cannot register an attribute with no name"); raise Project_Error; end if; if In_Package = Empty_Package then Fail ("attempt to add attribute """ & Name & """ to an undefined package"); raise Project_Error; end if; Attr_Name := Name_Id_Of (Name); First_Attr := Package_Attributes.Table (In_Package.Value).First_Attribute; -- Check if attribute name is a duplicate Curr_Attr := First_Attr; while Curr_Attr /= Empty_Attr loop if Attrs.Table (Curr_Attr).Name = Attr_Name then Fail ("duplicate attribute name """ & Name & """ in package """ & Get_Name_String (Package_Attributes.Table (In_Package.Value).Name) & """"); raise Project_Error; end if; Curr_Attr := Attrs.Table (Curr_Attr).Next; end loop; Real_Attr_Kind := Attr_Kind; -- If Index_Is_File_Name, change the attribute kind if necessary if Index_Is_File_Name and then not Osint.File_Names_Case_Sensitive then case Attr_Kind is when Associative_Array => Real_Attr_Kind := Case_Insensitive_Associative_Array; when Optional_Index_Associative_Array => Real_Attr_Kind := Optional_Index_Case_Insensitive_Associative_Array; when others => null; end case; end if; -- Add the new attribute Attrs.Increment_Last; Attrs.Table (Attrs.Last) := (Name => Attr_Name, Var_Kind => Var_Kind, Optional_Index => Opt_Index, Attr_Kind => Real_Attr_Kind, Read_Only => False, Others_Allowed => False, Next => First_Attr); Package_Attributes.Table (In_Package.Value).First_Attribute := Attrs.Last; end Register_New_Attribute; -------------------------- -- Register_New_Package -- -------------------------- procedure Register_New_Package (Name : String; Id : out Package_Node_Id) is Pkg_Name : Name_Id; begin if Name'Length = 0 then Fail ("cannot register a package with no name"); Id := Empty_Package; return; end if; Pkg_Name := Name_Id_Of (Name); for Index in Package_Attributes.First .. Package_Attributes.Last loop if Package_Attributes.Table (Index).Name = Pkg_Name then Fail ("cannot register a package with a non unique name """ & Name & """"); Id := Empty_Package; return; end if; end loop; Package_Attributes.Increment_Last; Id := (Value => Package_Attributes.Last); Package_Attributes.Table (Package_Attributes.Last) := (Name => Pkg_Name, Known => True, First_Attribute => Empty_Attr); Add_Package_Name (Get_Name_String (Pkg_Name)); end Register_New_Package; procedure Register_New_Package (Name : String; Attributes : Attribute_Data_Array) is Pkg_Name : Name_Id; Attr_Name : Name_Id; First_Attr : Attr_Node_Id := Empty_Attr; Curr_Attr : Attr_Node_Id; Attr_Kind : Attribute_Kind; begin if Name'Length = 0 then Fail ("cannot register a package with no name"); raise Project_Error; end if; Pkg_Name := Name_Id_Of (Name); for Index in Package_Attributes.First .. Package_Attributes.Last loop if Package_Attributes.Table (Index).Name = Pkg_Name then Fail ("cannot register a package with a non unique name """ & Name & """"); raise Project_Error; end if; end loop; for Index in Attributes'Range loop Attr_Name := Name_Id_Of (Attributes (Index).Name); Curr_Attr := First_Attr; while Curr_Attr /= Empty_Attr loop if Attrs.Table (Curr_Attr).Name = Attr_Name then Fail ("duplicate attribute name """ & Attributes (Index).Name & """ in new package """ & Name & """"); raise Project_Error; end if; Curr_Attr := Attrs.Table (Curr_Attr).Next; end loop; Attr_Kind := Attributes (Index).Attr_Kind; if Attributes (Index).Index_Is_File_Name and then not Osint.File_Names_Case_Sensitive then case Attr_Kind is when Associative_Array => Attr_Kind := Case_Insensitive_Associative_Array; when Optional_Index_Associative_Array => Attr_Kind := Optional_Index_Case_Insensitive_Associative_Array; when others => null; end case; end if; Attrs.Increment_Last; Attrs.Table (Attrs.Last) := (Name => Attr_Name, Var_Kind => Attributes (Index).Var_Kind, Optional_Index => Attributes (Index).Opt_Index, Attr_Kind => Attr_Kind, Read_Only => False, Others_Allowed => False, Next => First_Attr); First_Attr := Attrs.Last; end loop; Package_Attributes.Increment_Last; Package_Attributes.Table (Package_Attributes.Last) := (Name => Pkg_Name, Known => True, First_Attribute => First_Attr); Add_Package_Name (Get_Name_String (Pkg_Name)); end Register_New_Package; --------------------------- -- Set_Attribute_Kind_Of -- --------------------------- procedure Set_Attribute_Kind_Of (Attribute : Attribute_Node_Id; To : Attribute_Kind) is begin if Attribute /= Empty_Attribute then Attrs.Table (Attribute.Value).Attr_Kind := To; end if; end Set_Attribute_Kind_Of; -------------------------- -- Set_Variable_Kind_Of -- -------------------------- procedure Set_Variable_Kind_Of (Attribute : Attribute_Node_Id; To : Variable_Kind) is begin if Attribute /= Empty_Attribute then Attrs.Table (Attribute.Value).Var_Kind := To; end if; end Set_Variable_Kind_Of; ---------------------- -- Variable_Kind_Of -- ---------------------- function Variable_Kind_Of (Attribute : Attribute_Node_Id) return Variable_Kind is begin if Attribute = Empty_Attribute then return Undefined; else return Attrs.Table (Attribute.Value).Var_Kind; end if; end Variable_Kind_Of; ------------------------ -- First_Attribute_Of -- ------------------------ function First_Attribute_Of (Pkg : Package_Node_Id) return Attribute_Node_Id is begin if Pkg = Empty_Package or else Pkg = Unknown_Package then return Empty_Attribute; else return (Value => Package_Attributes.Table (Pkg.Value).First_Attribute); end if; end First_Attribute_Of; end Prj.Attr; gprbuild-gpl-2014-src/gnat/gnatvsn.ads0000644000076700001450000001334512323721731017243 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- G N A T V S N -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package spec holds version information for the GNAT tools. -- It is updated whenever the release number is changed. package Gnatvsn is Gnat_Static_Version_String : constant String := "2014 (20140331)"; -- Static string identifying this version, that can be used as an argument -- to e.g. pragma Ident. -- -- WARNING: some scripts rely on the format of this string. Any change -- must be coordinated with the scripts requirements. Furthermore, no -- other variable in this package may have a name starting with -- Gnat_Static_Version. function Gnat_Version_String return String; -- Version output when GNAT (compiler), or its related tools, including -- GNATBIND, GNATCHOP, GNATFIND, GNATLINK, GNATMAKE, GNATXREF, are run -- (with appropriate verbose option switch set). type Gnat_Build_Type is (Gnatpro, FSF, GPL); -- See Get_Gnat_Build_Type below for the meaning of these values Build_Type : constant Gnat_Build_Type := GPL; -- Kind of GNAT Build: -- -- FSF -- GNAT FSF version. This version of GNAT is part of a Free Software -- Foundation release of the GNU Compiler Collection (GCC). The bug -- box generated by Comperr gives information on how to report bugs -- and list the "no warranty" information. -- -- Gnatpro -- GNAT Professional version. This version of GNAT is supported by Ada -- Core Technologies. The bug box generated by package Comperr gives -- instructions on bug submission that include references to customer -- number, gnattracker site etc. -- -- GPL -- GNAT GPL Edition. This is a special version of GNAT, released by -- Ada Core Technologies and intended for academic users, and free -- software developers. The bug box generated by the package Comperr -- gives appropriate bug submission instructions that do not reference -- customer number etc. function Gnat_Free_Software return String; -- Text to be displayed by the different GNAT tools when switch --version -- is used. This text depends on the GNAT build type. function Copyright_Holder return String; -- Return the name of the Copyright holder to be displayed by the different -- GNAT tools when switch --version is used. Ver_Len_Max : constant := 64; -- Longest possible length for Gnat_Version_String in this or any -- other version of GNAT. This is used by the binder to establish -- space to store any possible version string value for checks. This -- value should never be decreased in the future, but it would be -- OK to increase it if absolutely necessary. If it is increased, -- be sure to increase GNAT.Compiler.Version.Ver_Len_Max as well. Ver_Prefix : constant String := "GNAT Version: "; -- Prefix generated by binder. If it is changed, be sure to change -- GNAT.Compiler_Version.Ver_Prefix as well. Library_Version : constant String := "2014"; -- Library version. This value must be updated when the compiler -- version number Gnat_Static_Version_String is updated. -- -- Note: Makefile.in uses the library version string to construct the -- soname value. Verbose_Library_Version : constant String := "GNAT Lib v" & Library_Version; -- Version string stored in e.g. ALI files Current_Year : constant String := "2014"; -- Used in printing copyright messages end Gnatvsn; gprbuild-gpl-2014-src/gnat/gnat_style.css0000644000076700001450000000072410271373615017756 0ustar gnatmailgnatbody { width: 750px; font-size: 14px; font-family: Verdana; } h1 { font-size: medium; font-weight: bold; color: #1275bc; } h2 { font-size: medium; font-weight: bold; color: black; border-top: 1px solid black; padding-top: 10px;} div.contents h2 { font-size: medium; font-weight: bold; color: #1275bc; border-top: 0px; padding: 0px} div.contents li { list-style-type: none; } gprbuild-gpl-2014-src/gnat/ali.adb0000644000076700001450000024736012323721731016315 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- A L I -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Butil; use Butil; with Debug; use Debug; with Fname; use Fname; with Opt; use Opt; with Osint; use Osint; with Output; use Output; package body ALI is use ASCII; -- Make control characters visible -- The following variable records which characters currently are -- used as line type markers in the ALI file. This is used in -- Scan_ALI to detect (or skip) invalid lines. Known_ALI_Lines : constant array (Character range 'A' .. 'Z') of Boolean := ('V' => True, -- version 'M' => True, -- main program 'A' => True, -- argument 'P' => True, -- program 'R' => True, -- restriction 'I' => True, -- interrupt 'U' => True, -- unit 'W' => True, -- with 'L' => True, -- linker option 'N' => True, -- notes 'E' => True, -- external 'D' => True, -- dependency 'X' => True, -- xref 'S' => True, -- specific dispatching 'Y' => True, -- limited_with 'Z' => True, -- implicit with from instantiation 'C' => True, -- SCO information 'F' => True, -- SPARK cross-reference information others => False); -------------------- -- Initialize_ALI -- -------------------- procedure Initialize_ALI is begin -- When (re)initializing ALI data structures the ALI user expects to -- get a fresh set of data structures. Thus we first need to erase the -- marks put in the name table by the previous set of ALI routine calls. -- These two loops are empty and harmless the first time in. for J in ALIs.First .. ALIs.Last loop Set_Name_Table_Info (ALIs.Table (J).Afile, 0); end loop; for J in Units.First .. Units.Last loop Set_Name_Table_Info (Units.Table (J).Uname, 0); end loop; -- Free argument table strings for J in Args.First .. Args.Last loop Free (Args.Table (J)); end loop; -- Initialize all tables ALIs.Init; No_Deps.Init; Units.Init; Withs.Init; Sdep.Init; Linker_Options.Init; Notes.Init; Xref_Section.Init; Xref_Entity.Init; Xref.Init; Version_Ref.Reset; -- Add dummy zero'th item in Linker_Options and Notes for sort calls Linker_Options.Increment_Last; Notes.Increment_Last; -- Initialize global variables recording cumulative options in all -- ALI files that are read for a given processing run in gnatbind. Dynamic_Elaboration_Checks_Specified := False; Float_Format_Specified := ' '; Locking_Policy_Specified := ' '; No_Normalize_Scalars_Specified := False; No_Object_Specified := False; Normalize_Scalars_Specified := False; Partition_Elaboration_Policy_Specified := ' '; Queuing_Policy_Specified := ' '; SSO_Default_Specified := False; Static_Elaboration_Model_Used := False; Task_Dispatching_Policy_Specified := ' '; Unreserve_All_Interrupts_Specified := False; Zero_Cost_Exceptions_Specified := False; end Initialize_ALI; -------------- -- Scan_ALI -- -------------- function Scan_ALI (F : File_Name_Type; T : Text_Buffer_Ptr; Ignore_ED : Boolean; Err : Boolean; Read_Xref : Boolean := False; Read_Lines : String := ""; Ignore_Lines : String := "X"; Ignore_Errors : Boolean := False; Directly_Scanned : Boolean := False) return ALI_Id is P : Text_Ptr := T'First; Line : Logical_Line_Number := 1; Id : ALI_Id; C : Character; NS_Found : Boolean; First_Arg : Arg_Id; Ignore : array (Character range 'A' .. 'Z') of Boolean; -- Ignore (X) is set to True if lines starting with X are to -- be ignored by Scan_ALI and skipped, and False if the lines -- are to be read and processed. Bad_ALI_Format : exception; -- Exception raised by Fatal_Error if Err is True function At_Eol return Boolean; -- Test if at end of line function At_End_Of_Field return Boolean; -- Test if at end of line, or if at blank or horizontal tab procedure Check_At_End_Of_Field; -- Check if we are at end of field, fatal error if not procedure Checkc (C : Character); -- Check next character is C. If so bump past it, if not fatal error procedure Check_Unknown_Line; -- If Ignore_Errors mode, then checks C to make sure that it is not -- an unknown ALI line type characters, and if so, skips lines -- until the first character of the line is one of these characters, -- at which point it does a Getc to put that character in C. The -- call has no effect if C is already an appropriate character. -- If not in Ignore_Errors mode, a fatal error is signalled if the -- line is unknown. Note that if C is an EOL on entry, the line is -- skipped (it is assumed that blank lines are never significant). -- If C is EOF on entry, the call has no effect (it is assumed that -- the caller will properly handle this case). procedure Fatal_Error; -- Generate fatal error message for badly formatted ALI file if -- Err is false, or raise Bad_ALI_Format if Err is True. procedure Fatal_Error_Ignore; pragma Inline (Fatal_Error_Ignore); -- In Ignore_Errors mode, has no effect, otherwise same as Fatal_Error function Getc return Character; -- Get next character, bumping P past the character obtained function Get_File_Name (Lower : Boolean := False; May_Be_Quoted : Boolean := False) return File_Name_Type; -- Skip blanks, then scan out a file name (name is left in Name_Buffer -- with length in Name_Len, as well as returning a File_Name_Type value. -- If May_Be_Quoted is True and the first non blank character is '"', -- then remove starting and ending quotes and undoubled internal quotes. -- If lower is false, the case is unchanged, if Lower is True then the -- result is forced to all lower case for systems where file names are -- not case sensitive. This ensures that gnatbind works correctly -- regardless of the case of the file name on all systems. The scan -- is terminated by a end of line, space or horizontal tab. Any other -- special characters are included in the returned name. function Get_Name (Ignore_Spaces : Boolean := False; Ignore_Special : Boolean := False; May_Be_Quoted : Boolean := False) return Name_Id; -- Skip blanks, then scan out a name (name is left in Name_Buffer with -- length in Name_Len, as well as being returned in Name_Id form). -- If Lower is set to True then the Name_Buffer will be converted to -- all lower case, for systems where file names are not case sensitive. -- This ensures that gnatbind works correctly regardless of the case -- of the file name on all systems. The termination condition depends -- on the settings of Ignore_Spaces and Ignore_Special: -- -- If Ignore_Spaces is False (normal case), then scan is terminated -- by the normal end of field condition (EOL, space, horizontal tab) -- -- If Ignore_Special is False (normal case), the scan is terminated by -- a typeref bracket or an equal sign except for the special case of -- an operator name starting with a double quote which is terminated -- by another double quote. -- -- If May_Be_Quoted is True and the first non blank character is '"' -- the name is 'unquoted'. In this case Ignore_Special is ignored and -- assumed to be True. -- -- It is an error to set both Ignore_Spaces and Ignore_Special to True. -- This function handles wide characters properly. function Get_Nat return Nat; -- Skip blanks, then scan out an unsigned integer value in Nat range -- raises ALI_Reading_Error if the encoutered type is not natural. function Get_Stamp return Time_Stamp_Type; -- Skip blanks, then scan out a time stamp function Get_Unit_Name return Unit_Name_Type; -- Skip blanks, then scan out a file name (name is left in Name_Buffer -- with length in Name_Len, as well as returning a Unit_Name_Type value. -- The case is unchanged and terminated by a normal end of field. function Nextc return Character; -- Return current character without modifying pointer P procedure Get_Typeref (Current_File_Num : Sdep_Id; Ref : out Tref_Kind; File_Num : out Sdep_Id; Line : out Nat; Ref_Type : out Character; Col : out Nat; Standard_Entity : out Name_Id); -- Parse the definition of a typeref (<...>, {...} or (...)) procedure Skip_Eol; -- Skip past spaces, then skip past end of line (fatal error if not -- at end of line). Also skips past any following blank lines. procedure Skip_Line; -- Skip rest of current line and any following blank lines procedure Skip_Space; -- Skip past white space (blanks or horizontal tab) procedure Skipc; -- Skip past next character, does not affect value in C. This call -- is like calling Getc and ignoring the returned result. --------------------- -- At_End_Of_Field -- --------------------- function At_End_Of_Field return Boolean is begin return Nextc <= ' '; end At_End_Of_Field; ------------ -- At_Eol -- ------------ function At_Eol return Boolean is begin return Nextc = EOF or else Nextc = CR or else Nextc = LF; end At_Eol; --------------------------- -- Check_At_End_Of_Field -- --------------------------- procedure Check_At_End_Of_Field is begin if not At_End_Of_Field then if Ignore_Errors then while Nextc > ' ' loop P := P + 1; end loop; else Fatal_Error; end if; end if; end Check_At_End_Of_Field; ------------------------ -- Check_Unknown_Line -- ------------------------ procedure Check_Unknown_Line is begin while C not in 'A' .. 'Z' or else not Known_ALI_Lines (C) loop if C = CR or else C = LF then Skip_Line; C := Nextc; elsif C = EOF then return; elsif Ignore_Errors then Skip_Line; C := Getc; else Fatal_Error; end if; end loop; end Check_Unknown_Line; ------------ -- Checkc -- ------------ procedure Checkc (C : Character) is begin if Nextc = C then P := P + 1; elsif Ignore_Errors then P := P + 1; else Fatal_Error; end if; end Checkc; ----------------- -- Fatal_Error -- ----------------- procedure Fatal_Error is Ptr1 : Text_Ptr; Ptr2 : Text_Ptr; Col : Int; procedure Wchar (C : Character); -- Write a single character, replacing horizontal tab by spaces procedure Wchar (C : Character) is begin if C = HT then loop Wchar (' '); exit when Col mod 8 = 0; end loop; else Write_Char (C); Col := Col + 1; end if; end Wchar; -- Start of processing for Fatal_Error begin if Err then raise Bad_ALI_Format; end if; Set_Standard_Error; Write_Str ("fatal error: file "); Write_Name (F); Write_Str (" is incorrectly formatted"); Write_Eol; Write_Str ("make sure you are using consistent versions " & -- Split the following line so that it can easily be transformed for -- e.g. JVM/.NET back-ends where the compiler has a different name. "of gcc/gnatbind"); Write_Eol; -- Find start of line Ptr1 := P; while Ptr1 > T'First and then T (Ptr1 - 1) /= CR and then T (Ptr1 - 1) /= LF loop Ptr1 := Ptr1 - 1; end loop; Write_Int (Int (Line)); Write_Str (". "); if Line < 100 then Write_Char (' '); end if; if Line < 10 then Write_Char (' '); end if; Col := 0; Ptr2 := Ptr1; while Ptr2 < T'Last and then T (Ptr2) /= CR and then T (Ptr2) /= LF loop Wchar (T (Ptr2)); Ptr2 := Ptr2 + 1; end loop; Write_Eol; Write_Str (" "); Col := 0; while Ptr1 < P loop if T (Ptr1) = HT then Wchar (HT); else Wchar (' '); end if; Ptr1 := Ptr1 + 1; end loop; Wchar ('|'); Write_Eol; Exit_Program (E_Fatal); end Fatal_Error; ------------------------ -- Fatal_Error_Ignore -- ------------------------ procedure Fatal_Error_Ignore is begin if not Ignore_Errors then Fatal_Error; end if; end Fatal_Error_Ignore; ------------------- -- Get_File_Name -- ------------------- function Get_File_Name (Lower : Boolean := False; May_Be_Quoted : Boolean := False) return File_Name_Type is F : Name_Id; begin F := Get_Name (Ignore_Special => True, May_Be_Quoted => May_Be_Quoted); -- Convert file name to all lower case if file names are not case -- sensitive. This ensures that we handle names in the canonical -- lower case format, regardless of the actual case. if Lower and not File_Names_Case_Sensitive then Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); return Name_Find; else return File_Name_Type (F); end if; end Get_File_Name; -------------- -- Get_Name -- -------------- function Get_Name (Ignore_Spaces : Boolean := False; Ignore_Special : Boolean := False; May_Be_Quoted : Boolean := False) return Name_Id is Char : Character; begin Name_Len := 0; Skip_Space; if At_Eol then if Ignore_Errors then return Error_Name; else Fatal_Error; end if; end if; Char := Getc; -- Deal with quoted characters if May_Be_Quoted and then Char = '"' then loop if At_Eol then if Ignore_Errors then return Error_Name; else Fatal_Error; end if; end if; Char := Getc; if Char = '"' then if At_Eol then exit; else Char := Getc; if Char /= '"' then P := P - 1; exit; end if; end if; end if; Add_Char_To_Name_Buffer (Char); end loop; -- Other than case of quoted character else P := P - 1; loop Add_Char_To_Name_Buffer (Getc); exit when At_End_Of_Field and then not Ignore_Spaces; if not Ignore_Special then if Name_Buffer (1) = '"' then exit when Name_Len > 1 and then Name_Buffer (Name_Len) = '"'; else -- Terminate on parens or angle brackets or equal sign exit when Nextc = '(' or else Nextc = ')' or else Nextc = '{' or else Nextc = '}' or else Nextc = '<' or else Nextc = '>' or else Nextc = '='; -- Terminate on comma exit when Nextc = ','; -- Terminate if left bracket not part of wide char -- sequence Note that we only recognize brackets -- notation so far ??? exit when Nextc = '[' and then T (P + 1) /= '"'; -- Terminate if right bracket not part of wide char -- sequence. exit when Nextc = ']' and then T (P - 1) /= '"'; end if; end if; end loop; end if; return Name_Find; end Get_Name; ------------------- -- Get_Unit_Name -- ------------------- function Get_Unit_Name return Unit_Name_Type is begin return Unit_Name_Type (Get_Name); end Get_Unit_Name; ------------- -- Get_Nat -- ------------- function Get_Nat return Nat is V : Nat; begin Skip_Space; -- Check if we are on a number. In the case of bad ALI files, this -- may not be true. if not (Nextc in '0' .. '9') then Fatal_Error; end if; V := 0; loop V := V * 10 + (Character'Pos (Getc) - Character'Pos ('0')); exit when At_End_Of_Field; exit when Nextc < '0' or else Nextc > '9'; end loop; return V; end Get_Nat; --------------- -- Get_Stamp -- --------------- function Get_Stamp return Time_Stamp_Type is T : Time_Stamp_Type; Start : Integer; begin Skip_Space; if At_Eol then if Ignore_Errors then return Dummy_Time_Stamp; else Fatal_Error; end if; end if; -- Following reads old style time stamp missing first two digits if Nextc in '7' .. '9' then T (1) := '1'; T (2) := '9'; Start := 3; -- Normal case of full year in time stamp else Start := 1; end if; for J in Start .. T'Last loop T (J) := Getc; end loop; return T; end Get_Stamp; ----------------- -- Get_Typeref -- ----------------- procedure Get_Typeref (Current_File_Num : Sdep_Id; Ref : out Tref_Kind; File_Num : out Sdep_Id; Line : out Nat; Ref_Type : out Character; Col : out Nat; Standard_Entity : out Name_Id) is N : Nat; begin case Nextc is when '<' => Ref := Tref_Derived; when '(' => Ref := Tref_Access; when '{' => Ref := Tref_Type; when others => Ref := Tref_None; end case; -- Case of typeref field present if Ref /= Tref_None then P := P + 1; -- skip opening bracket if Nextc in 'a' .. 'z' then File_Num := No_Sdep_Id; Line := 0; Ref_Type := ' '; Col := 0; Standard_Entity := Get_Name (Ignore_Spaces => True); else N := Get_Nat; if Nextc = '|' then File_Num := Sdep_Id (N + Nat (First_Sdep_Entry) - 1); P := P + 1; N := Get_Nat; else File_Num := Current_File_Num; end if; Line := N; Ref_Type := Getc; Col := Get_Nat; Standard_Entity := No_Name; end if; -- ??? Temporary workaround for nested generics case: -- 4i4 Directories{1|4I9[4|6[3|3]]} -- See C918-002 declare Nested_Brackets : Natural := 0; begin loop case Nextc is when '[' => Nested_Brackets := Nested_Brackets + 1; when ']' => Nested_Brackets := Nested_Brackets - 1; when others => if Nested_Brackets = 0 then exit; end if; end case; Skipc; end loop; end; P := P + 1; -- skip closing bracket Skip_Space; -- No typeref entry present else File_Num := No_Sdep_Id; Line := 0; Ref_Type := ' '; Col := 0; Standard_Entity := No_Name; end if; end Get_Typeref; ---------- -- Getc -- ---------- function Getc return Character is begin if P = T'Last then return EOF; else P := P + 1; return T (P - 1); end if; end Getc; ----------- -- Nextc -- ----------- function Nextc return Character is begin return T (P); end Nextc; -------------- -- Skip_Eol -- -------------- procedure Skip_Eol is begin Skip_Space; if not At_Eol then if Ignore_Errors then while not At_Eol loop P := P + 1; end loop; else Fatal_Error; end if; end if; -- Loop to skip past blank lines (first time through skips this EOL) while Nextc < ' ' and then Nextc /= EOF loop if Nextc = LF then Line := Line + 1; end if; P := P + 1; end loop; end Skip_Eol; --------------- -- Skip_Line -- --------------- procedure Skip_Line is begin while not At_Eol loop P := P + 1; end loop; Skip_Eol; end Skip_Line; ---------------- -- Skip_Space -- ---------------- procedure Skip_Space is begin while Nextc = ' ' or else Nextc = HT loop P := P + 1; end loop; end Skip_Space; ----------- -- Skipc -- ----------- procedure Skipc is begin if P /= T'Last then P := P + 1; end if; end Skipc; -- Start of processing for Scan_ALI begin First_Sdep_Entry := Sdep.Last + 1; -- Acquire lines to be ignored if Read_Xref then Ignore := ('U' | 'W' | 'Y' | 'Z' | 'D' | 'X' => False, others => True); -- Read_Lines parameter given elsif Read_Lines /= "" then Ignore := ('U' => False, others => True); for J in Read_Lines'Range loop Ignore (Read_Lines (J)) := False; end loop; -- Process Ignore_Lines parameter else Ignore := (others => False); for J in Ignore_Lines'Range loop pragma Assert (Ignore_Lines (J) /= 'U'); Ignore (Ignore_Lines (J)) := True; end loop; end if; -- Setup ALI Table entry with appropriate defaults ALIs.Increment_Last; Id := ALIs.Last; Set_Name_Table_Info (F, Int (Id)); ALIs.Table (Id) := ( Afile => F, Compile_Errors => False, First_Interrupt_State => Interrupt_States.Last + 1, First_Sdep => No_Sdep_Id, First_Specific_Dispatching => Specific_Dispatching.Last + 1, First_Unit => No_Unit_Id, Float_Format => 'I', Last_Interrupt_State => Interrupt_States.Last, Last_Sdep => No_Sdep_Id, Last_Specific_Dispatching => Specific_Dispatching.Last, Last_Unit => No_Unit_Id, Locking_Policy => ' ', Main_Priority => -1, Main_CPU => -1, Main_Program => None, No_Object => False, Normalize_Scalars => False, Ofile_Full_Name => Full_Object_File_Name, Partition_Elaboration_Policy => ' ', Queuing_Policy => ' ', Restrictions => No_Restrictions, SAL_Interface => False, Sfile => No_File, SSO_Default => ' ', Task_Dispatching_Policy => ' ', Time_Slice_Value => -1, WC_Encoding => 'b', Unit_Exception_Table => False, Ver => (others => ' '), Ver_Len => 0, Zero_Cost_Exceptions => False); -- Now we acquire the input lines from the ALI file. Note that the -- convention in the following code is that as we enter each section, -- C is set to contain the first character of the following line. C := Getc; Check_Unknown_Line; -- Acquire library version if C /= 'V' then -- The V line missing really indicates trouble, most likely it -- means we don't have an ALI file at all, so here we give a -- fatal error even if we are in Ignore_Errors mode. Fatal_Error; elsif Ignore ('V') then Skip_Line; else Checkc (' '); Skip_Space; Checkc ('"'); for J in 1 .. Ver_Len_Max loop C := Getc; exit when C = '"'; ALIs.Table (Id).Ver (J) := C; ALIs.Table (Id).Ver_Len := J; end loop; Skip_Eol; end if; C := Getc; Check_Unknown_Line; -- Acquire main program line if present if C = 'M' then if Ignore ('M') then Skip_Line; else Checkc (' '); Skip_Space; C := Getc; if C = 'F' then ALIs.Table (Id).Main_Program := Func; elsif C = 'P' then ALIs.Table (Id).Main_Program := Proc; else P := P - 1; Fatal_Error; end if; Skip_Space; if not At_Eol then if Nextc < 'A' then ALIs.Table (Id).Main_Priority := Get_Nat; end if; Skip_Space; if Nextc = 'T' then P := P + 1; Checkc ('='); ALIs.Table (Id).Time_Slice_Value := Get_Nat; end if; Skip_Space; if Nextc = 'C' then P := P + 1; Checkc ('='); ALIs.Table (Id).Main_CPU := Get_Nat; end if; Skip_Space; Checkc ('W'); Checkc ('='); ALIs.Table (Id).WC_Encoding := Getc; end if; Skip_Eol; end if; C := Getc; end if; -- Acquire argument lines First_Arg := Args.Last + 1; A_Loop : loop Check_Unknown_Line; exit A_Loop when C /= 'A'; if Ignore ('A') then Skip_Line; else Checkc (' '); -- Scan out argument Name_Len := 0; while not At_Eol loop Add_Char_To_Name_Buffer (Getc); end loop; -- If -fstack-check, record that it occurred. Note that an -- additional string parameter can be specified, in the form of -- -fstack-check={no|generic|specific}. "no" means no checking, -- "generic" means force the use of old-style checking, and -- "specific" means use the best checking method. if Name_Len >= 13 and then Name_Buffer (1 .. 13) = "-fstack-check" and then Name_Buffer (1 .. Name_Len) /= "-fstack-check=no" then Stack_Check_Switch_Set := True; end if; -- Store the argument Args.Increment_Last; Args.Table (Args.Last) := new String'(Name_Buffer (1 .. Name_Len)); Skip_Eol; end if; C := Getc; end loop A_Loop; -- Acquire P line Check_Unknown_Line; while C /= 'P' loop if Ignore_Errors then if C = EOF then Fatal_Error; else Skip_Line; C := Nextc; end if; else Fatal_Error; end if; end loop; if Ignore ('P') then Skip_Line; -- Process P line else NS_Found := False; while not At_Eol loop Checkc (' '); Skip_Space; C := Getc; -- Processing for CE if C = 'C' then Checkc ('E'); ALIs.Table (Id).Compile_Errors := True; -- Processing for DB elsif C = 'D' then Checkc ('B'); Detect_Blocking := True; -- Processing for Ex elsif C = 'E' then Partition_Elaboration_Policy_Specified := Getc; ALIs.Table (Id).Partition_Elaboration_Policy := Partition_Elaboration_Policy_Specified; -- Processing for FD/FG/FI elsif C = 'F' then Float_Format_Specified := Getc; ALIs.Table (Id).Float_Format := Float_Format_Specified; -- Processing for Lx elsif C = 'L' then Locking_Policy_Specified := Getc; ALIs.Table (Id).Locking_Policy := Locking_Policy_Specified; -- Processing for flags starting with N elsif C = 'N' then C := Getc; -- Processing for NO if C = 'O' then ALIs.Table (Id).No_Object := True; No_Object_Specified := True; -- Processing for NR elsif C = 'R' then No_Run_Time_Mode := True; Configurable_Run_Time_Mode := True; -- Processing for NS elsif C = 'S' then ALIs.Table (Id).Normalize_Scalars := True; Normalize_Scalars_Specified := True; NS_Found := True; -- Invalid switch starting with N else Fatal_Error_Ignore; end if; -- Processing for OH/OL elsif C = 'O' then C := Getc; if C = 'L' or else C = 'H' then ALIs.Table (Id).SSO_Default := C; SSO_Default_Specified := True; else Fatal_Error_Ignore; end if; -- Processing for Qx elsif C = 'Q' then Queuing_Policy_Specified := Getc; ALIs.Table (Id).Queuing_Policy := Queuing_Policy_Specified; -- Processing for flags starting with S elsif C = 'S' then C := Getc; -- Processing for SL if C = 'L' then ALIs.Table (Id).SAL_Interface := True; -- Processing for SS elsif C = 'S' then Opt.Sec_Stack_Used := True; -- Invalid switch starting with S else Fatal_Error_Ignore; end if; -- Processing for Tx elsif C = 'T' then Task_Dispatching_Policy_Specified := Getc; ALIs.Table (Id).Task_Dispatching_Policy := Task_Dispatching_Policy_Specified; -- Processing for switch starting with U elsif C = 'U' then C := Getc; -- Processing for UA if C = 'A' then Unreserve_All_Interrupts_Specified := True; -- Processing for UX elsif C = 'X' then ALIs.Table (Id).Unit_Exception_Table := True; -- Invalid switches starting with U else Fatal_Error_Ignore; end if; -- Processing for ZX elsif C = 'Z' then C := Getc; if C = 'X' then ALIs.Table (Id).Zero_Cost_Exceptions := True; Zero_Cost_Exceptions_Specified := True; else Fatal_Error_Ignore; end if; -- Invalid parameter else C := Getc; Fatal_Error_Ignore; end if; end loop; if not NS_Found then No_Normalize_Scalars_Specified := True; end if; Skip_Eol; end if; C := Getc; Check_Unknown_Line; -- Loop to skip to first restrictions line while C /= 'R' loop if Ignore_Errors then if C = EOF then Fatal_Error; else Skip_Line; C := Nextc; end if; else Fatal_Error; end if; end loop; -- Ignore all 'R' lines if that is required if Ignore ('R') then while C = 'R' loop Skip_Line; C := Getc; end loop; -- Here we process the restrictions lines (other than unit name cases) else Scan_Restrictions : declare Save_R : constant Restrictions_Info := Cumulative_Restrictions; -- Save cumulative restrictions in case we have a fatal error Bad_R_Line : exception; -- Signal bad restrictions line (raised on unexpected character) Typ : Character; R : Restriction_Id; N : Natural; begin -- Named restriction case if Nextc = 'N' then Skip_Line; C := Getc; -- Loop through RR and RV lines while C = 'R' and then Nextc /= ' ' loop Typ := Getc; Checkc (' '); -- Acquire restriction name Name_Len := 0; while not At_Eol and then Nextc /= '=' loop Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := Getc; end loop; -- Now search list of restrictions to find match declare RN : String renames Name_Buffer (1 .. Name_Len); begin R := Restriction_Id'First; while R /= Not_A_Restriction_Id loop if Restriction_Id'Image (R) = RN then goto R_Found; end if; R := Restriction_Id'Succ (R); end loop; -- We don't recognize the restriction. This might be -- thought of as an error, and it really is, but we -- want to allow building with inconsistent versions -- of the binder and ali files (see comments at the -- start of package System.Rident), so we just ignore -- this situation. goto Done_With_Restriction_Line; end; <> case R is -- Boolean restriction case when All_Boolean_Restrictions => case Typ is when 'V' => ALIs.Table (Id).Restrictions.Violated (R) := True; Cumulative_Restrictions.Violated (R) := True; when 'R' => ALIs.Table (Id).Restrictions.Set (R) := True; Cumulative_Restrictions.Set (R) := True; when others => raise Bad_R_Line; end case; -- Parameter restriction case when All_Parameter_Restrictions => if At_Eol or else Nextc /= '=' then raise Bad_R_Line; else Skipc; end if; N := Natural (Get_Nat); case Typ is -- Restriction set when 'R' => ALIs.Table (Id).Restrictions.Set (R) := True; ALIs.Table (Id).Restrictions.Value (R) := N; if Cumulative_Restrictions.Set (R) then Cumulative_Restrictions.Value (R) := Integer'Min (Cumulative_Restrictions.Value (R), N); else Cumulative_Restrictions.Set (R) := True; Cumulative_Restrictions.Value (R) := N; end if; -- Restriction violated when 'V' => ALIs.Table (Id).Restrictions.Violated (R) := True; Cumulative_Restrictions.Violated (R) := True; ALIs.Table (Id).Restrictions.Count (R) := N; -- Checked Max_Parameter case if R in Checked_Max_Parameter_Restrictions then Cumulative_Restrictions.Count (R) := Integer'Max (Cumulative_Restrictions.Count (R), N); -- Other checked parameter cases else declare pragma Unsuppress (Overflow_Check); begin Cumulative_Restrictions.Count (R) := Cumulative_Restrictions.Count (R) + N; exception when Constraint_Error => -- A constraint error comes from the -- addition. We reset to the maximum -- and indicate that the real value -- is now unknown. Cumulative_Restrictions.Value (R) := Integer'Last; Cumulative_Restrictions.Unknown (R) := True; end; end if; -- Deal with + case if Nextc = '+' then Skipc; ALIs.Table (Id).Restrictions.Unknown (R) := True; Cumulative_Restrictions.Unknown (R) := True; end if; -- Other than 'R' or 'V' when others => raise Bad_R_Line; end case; if not At_Eol then raise Bad_R_Line; end if; -- Bizarre error case NOT_A_RESTRICTION when Not_A_Restriction_Id => raise Bad_R_Line; end case; if not At_Eol then raise Bad_R_Line; end if; <> Skip_Line; C := Getc; end loop; -- Positional restriction case else Checkc (' '); Skip_Space; -- Acquire information for boolean restrictions for R in All_Boolean_Restrictions loop C := Getc; case C is when 'v' => ALIs.Table (Id).Restrictions.Violated (R) := True; Cumulative_Restrictions.Violated (R) := True; when 'r' => ALIs.Table (Id).Restrictions.Set (R) := True; Cumulative_Restrictions.Set (R) := True; when 'n' => null; when others => raise Bad_R_Line; end case; end loop; -- Acquire information for parameter restrictions for RP in All_Parameter_Restrictions loop case Getc is when 'n' => null; when 'r' => ALIs.Table (Id).Restrictions.Set (RP) := True; declare N : constant Integer := Integer (Get_Nat); begin ALIs.Table (Id).Restrictions.Value (RP) := N; if Cumulative_Restrictions.Set (RP) then Cumulative_Restrictions.Value (RP) := Integer'Min (Cumulative_Restrictions.Value (RP), N); else Cumulative_Restrictions.Set (RP) := True; Cumulative_Restrictions.Value (RP) := N; end if; end; when others => raise Bad_R_Line; end case; -- Acquire restrictions violations information case Getc is when 'n' => null; when 'v' => ALIs.Table (Id).Restrictions.Violated (RP) := True; Cumulative_Restrictions.Violated (RP) := True; declare N : constant Integer := Integer (Get_Nat); begin ALIs.Table (Id).Restrictions.Count (RP) := N; if RP in Checked_Max_Parameter_Restrictions then Cumulative_Restrictions.Count (RP) := Integer'Max (Cumulative_Restrictions.Count (RP), N); else declare pragma Unsuppress (Overflow_Check); begin Cumulative_Restrictions.Count (RP) := Cumulative_Restrictions.Count (RP) + N; exception when Constraint_Error => -- A constraint error comes from the add. We -- reset to the maximum and indicate that the -- real value is now unknown. Cumulative_Restrictions.Value (RP) := Integer'Last; Cumulative_Restrictions.Unknown (RP) := True; end; end if; if Nextc = '+' then Skipc; ALIs.Table (Id).Restrictions.Unknown (RP) := True; Cumulative_Restrictions.Unknown (RP) := True; end if; end; when others => raise Bad_R_Line; end case; end loop; if not At_Eol then raise Bad_R_Line; else Skip_Line; C := Getc; end if; end if; -- Here if error during scanning of restrictions line exception when Bad_R_Line => -- In Ignore_Errors mode, undo any changes to restrictions -- from this unit, and continue on, skipping remaining R -- lines for this unit. if Ignore_Errors then Cumulative_Restrictions := Save_R; ALIs.Table (Id).Restrictions := No_Restrictions; loop Skip_Eol; C := Getc; exit when C /= 'R'; end loop; -- In normal mode, this is a fatal error else Fatal_Error; end if; end Scan_Restrictions; end if; -- Acquire additional restrictions (No_Dependence) lines if present while C = 'R' loop if Ignore ('R') then Skip_Line; else Skip_Space; No_Deps.Append ((Id, Get_Name)); Skip_Eol; end if; C := Getc; end loop; -- Acquire 'I' lines if present Check_Unknown_Line; while C = 'I' loop if Ignore ('I') then Skip_Line; else declare Int_Num : Nat; I_State : Character; Line_No : Nat; begin Int_Num := Get_Nat; Skip_Space; I_State := Getc; Line_No := Get_Nat; Interrupt_States.Append ( (Interrupt_Id => Int_Num, Interrupt_State => I_State, IS_Pragma_Line => Line_No)); ALIs.Table (Id).Last_Interrupt_State := Interrupt_States.Last; Skip_Eol; end; end if; C := Getc; end loop; -- Acquire 'S' lines if present Check_Unknown_Line; while C = 'S' loop if Ignore ('S') then Skip_Line; else declare Policy : Character; First_Prio : Nat; Last_Prio : Nat; Line_No : Nat; begin Checkc (' '); Skip_Space; Policy := Getc; Skip_Space; First_Prio := Get_Nat; Last_Prio := Get_Nat; Line_No := Get_Nat; Specific_Dispatching.Append ( (Dispatching_Policy => Policy, First_Priority => First_Prio, Last_Priority => Last_Prio, PSD_Pragma_Line => Line_No)); ALIs.Table (Id).Last_Specific_Dispatching := Specific_Dispatching.Last; Skip_Eol; end; end if; C := Getc; end loop; -- Loop to acquire unit entries U_Loop : loop Check_Unknown_Line; exit U_Loop when C /= 'U'; -- Note: as per spec, we never ignore U lines Checkc (' '); Skip_Space; Units.Increment_Last; if ALIs.Table (Id).First_Unit = No_Unit_Id then ALIs.Table (Id).First_Unit := Units.Last; end if; declare UL : Unit_Record renames Units.Table (Units.Last); begin UL.Uname := Get_Unit_Name; UL.Predefined := Is_Predefined_Unit; UL.Internal := Is_Internal_Unit; UL.My_ALI := Id; UL.Sfile := Get_File_Name (Lower => True); UL.Pure := False; UL.Preelab := False; UL.No_Elab := False; UL.Shared_Passive := False; UL.RCI := False; UL.Remote_Types := False; UL.Has_RACW := False; UL.Init_Scalars := False; UL.Is_Generic := False; UL.Icasing := Mixed_Case; UL.Kcasing := All_Lower_Case; UL.Dynamic_Elab := False; UL.Elaborate_Body := False; UL.Set_Elab_Entity := False; UL.Version := "00000000"; UL.First_With := Withs.Last + 1; UL.First_Arg := First_Arg; UL.Elab_Position := 0; UL.SAL_Interface := ALIs.Table (Id).SAL_Interface; UL.Directly_Scanned := Directly_Scanned; UL.Body_Needed_For_SAL := False; UL.Elaborate_Body_Desirable := False; UL.Optimize_Alignment := 'O'; UL.Has_Finalizer := False; if Debug_Flag_U then Write_Str (" ----> reading unit "); Write_Int (Int (Units.Last)); Write_Str (" "); Write_Unit_Name (UL.Uname); Write_Str (" from file "); Write_Name (UL.Sfile); Write_Eol; end if; end; -- Check for duplicated unit in different files declare Info : constant Int := Get_Name_Table_Info (Units.Table (Units.Last).Uname); begin if Info /= 0 and then Units.Table (Units.Last).Sfile /= Units.Table (Unit_Id (Info)).Sfile then -- If Err is set then ignore duplicate unit name. This is the -- case of a call from gnatmake, where the situation can arise -- from substitution of source files. In such situations, the -- processing in gnatmake will always result in any required -- recompilations in any case, and if we consider this to be -- an error we get strange cases (for example when a generic -- instantiation is replaced by a normal package) where we -- read the old ali file, decide to recompile, and then decide -- that the old and new ali files are incompatible. if Err then null; -- If Err is not set, then this is a fatal error. This is -- the case of being called from the binder, where we must -- definitely diagnose this as an error. else Set_Standard_Error; Write_Str ("error: duplicate unit name: "); Write_Eol; Write_Str ("error: unit """); Write_Unit_Name (Units.Table (Units.Last).Uname); Write_Str (""" found in file """); Write_Name_Decoded (Units.Table (Units.Last).Sfile); Write_Char ('"'); Write_Eol; Write_Str ("error: unit """); Write_Unit_Name (Units.Table (Unit_Id (Info)).Uname); Write_Str (""" found in file """); Write_Name_Decoded (Units.Table (Unit_Id (Info)).Sfile); Write_Char ('"'); Write_Eol; Exit_Program (E_Fatal); end if; end if; end; Set_Name_Table_Info (Units.Table (Units.Last).Uname, Int (Units.Last)); -- Scan out possible version and other parameters loop Skip_Space; exit when At_Eol; C := Getc; -- Version field if C in '0' .. '9' or else C in 'a' .. 'f' then Units.Table (Units.Last).Version (1) := C; for J in 2 .. 8 loop C := Getc; Units.Table (Units.Last).Version (J) := C; end loop; -- BD/BN parameters elsif C = 'B' then C := Getc; if C = 'D' then Check_At_End_Of_Field; Units.Table (Units.Last).Elaborate_Body_Desirable := True; elsif C = 'N' then Check_At_End_Of_Field; Units.Table (Units.Last).Body_Needed_For_SAL := True; else Fatal_Error_Ignore; end if; -- DE parameter (Dynamic elaboration checks) elsif C = 'D' then C := Getc; if C = 'E' then Check_At_End_Of_Field; Units.Table (Units.Last).Dynamic_Elab := True; Dynamic_Elaboration_Checks_Specified := True; else Fatal_Error_Ignore; end if; -- EB/EE parameters elsif C = 'E' then C := Getc; if C = 'B' then Units.Table (Units.Last).Elaborate_Body := True; elsif C = 'E' then Units.Table (Units.Last).Set_Elab_Entity := True; else Fatal_Error_Ignore; end if; Check_At_End_Of_Field; -- GE parameter (generic) elsif C = 'G' then C := Getc; if C = 'E' then Check_At_End_Of_Field; Units.Table (Units.Last).Is_Generic := True; else Fatal_Error_Ignore; end if; -- IL/IS/IU parameters elsif C = 'I' then C := Getc; if C = 'L' then Units.Table (Units.Last).Icasing := All_Lower_Case; elsif C = 'S' then Units.Table (Units.Last).Init_Scalars := True; Initialize_Scalars_Used := True; elsif C = 'U' then Units.Table (Units.Last).Icasing := All_Upper_Case; else Fatal_Error_Ignore; end if; Check_At_End_Of_Field; -- KM/KU parameters elsif C = 'K' then C := Getc; if C = 'M' then Units.Table (Units.Last).Kcasing := Mixed_Case; elsif C = 'U' then Units.Table (Units.Last).Kcasing := All_Upper_Case; else Fatal_Error_Ignore; end if; Check_At_End_Of_Field; -- NE parameter elsif C = 'N' then C := Getc; if C = 'E' then Units.Table (Units.Last).No_Elab := True; Check_At_End_Of_Field; else Fatal_Error_Ignore; end if; -- PF/PR/PU/PK parameters elsif C = 'P' then C := Getc; if C = 'F' then Units.Table (Units.Last).Has_Finalizer := True; elsif C = 'R' then Units.Table (Units.Last).Preelab := True; elsif C = 'U' then Units.Table (Units.Last).Pure := True; elsif C = 'K' then Units.Table (Units.Last).Unit_Kind := 'p'; else Fatal_Error_Ignore; end if; Check_At_End_Of_Field; -- OL/OO/OS/OT parameters elsif C = 'O' then C := Getc; if C = 'L' or else C = 'O' or else C = 'S' or else C = 'T' then Units.Table (Units.Last).Optimize_Alignment := C; else Fatal_Error_Ignore; end if; Check_At_End_Of_Field; -- RC/RT parameters elsif C = 'R' then C := Getc; if C = 'C' then Units.Table (Units.Last).RCI := True; elsif C = 'T' then Units.Table (Units.Last).Remote_Types := True; elsif C = 'A' then Units.Table (Units.Last).Has_RACW := True; else Fatal_Error_Ignore; end if; Check_At_End_Of_Field; elsif C = 'S' then C := Getc; if C = 'P' then Units.Table (Units.Last).Shared_Passive := True; elsif C = 'U' then Units.Table (Units.Last).Unit_Kind := 's'; else Fatal_Error_Ignore; end if; Check_At_End_Of_Field; else C := Getc; Fatal_Error_Ignore; end if; end loop; Skip_Eol; -- Check if static elaboration model used if not Units.Table (Units.Last).Dynamic_Elab and then not Units.Table (Units.Last).Internal then Static_Elaboration_Model_Used := True; end if; C := Getc; -- Scan out With lines for this unit With_Loop : loop Check_Unknown_Line; exit With_Loop when C /= 'W' and then C /= 'Y' and then C /= 'Z'; if Ignore ('W') then Skip_Line; else Checkc (' '); Skip_Space; Withs.Increment_Last; Withs.Table (Withs.Last).Uname := Get_Unit_Name; Withs.Table (Withs.Last).Elaborate := False; Withs.Table (Withs.Last).Elaborate_All := False; Withs.Table (Withs.Last).Elab_Desirable := False; Withs.Table (Withs.Last).Elab_All_Desirable := False; Withs.Table (Withs.Last).SAL_Interface := False; Withs.Table (Withs.Last).Limited_With := (C = 'Y'); Withs.Table (Withs.Last).Implicit_With_From_Instantiation := (C = 'Z'); -- Generic case with no object file available if At_Eol then Withs.Table (Withs.Last).Sfile := No_File; Withs.Table (Withs.Last).Afile := No_File; -- Normal case else Withs.Table (Withs.Last).Sfile := Get_File_Name (Lower => True); Withs.Table (Withs.Last).Afile := Get_File_Name (Lower => True); -- Scan out possible E, EA, ED, and AD parameters while not At_Eol loop Skip_Space; if Nextc = 'A' then P := P + 1; Checkc ('D'); Check_At_End_Of_Field; -- Store AD indication unless ignore required if not Ignore_ED then Withs.Table (Withs.Last).Elab_All_Desirable := True; end if; elsif Nextc = 'E' then P := P + 1; if At_End_Of_Field then Withs.Table (Withs.Last).Elaborate := True; elsif Nextc = 'A' then P := P + 1; Check_At_End_Of_Field; Withs.Table (Withs.Last).Elaborate_All := True; else Checkc ('D'); Check_At_End_Of_Field; -- Store ED indication unless ignore required if not Ignore_ED then Withs.Table (Withs.Last).Elab_Desirable := True; end if; end if; else Fatal_Error; end if; end loop; end if; Skip_Eol; end if; C := Getc; end loop With_Loop; Units.Table (Units.Last).Last_With := Withs.Last; Units.Table (Units.Last).Last_Arg := Args.Last; -- If there are linker options lines present, scan them Name_Len := 0; Linker_Options_Loop : loop Check_Unknown_Line; exit Linker_Options_Loop when C /= 'L'; if Ignore ('L') then Skip_Line; else Checkc (' '); Skip_Space; Checkc ('"'); loop C := Getc; if C < Character'Val (16#20#) or else C > Character'Val (16#7E#) then Fatal_Error_Ignore; elsif C = '{' then C := Character'Val (0); declare V : Natural; begin V := 0; for J in 1 .. 2 loop C := Getc; if C in '0' .. '9' then V := V * 16 + Character'Pos (C) - Character'Pos ('0'); elsif C in 'A' .. 'F' then V := V * 16 + Character'Pos (C) - Character'Pos ('A') + 10; else Fatal_Error_Ignore; end if; end loop; Checkc ('}'); Add_Char_To_Name_Buffer (Character'Val (V)); end; else if C = '"' then exit when Nextc /= '"'; C := Getc; end if; Add_Char_To_Name_Buffer (C); end if; end loop; Add_Char_To_Name_Buffer (NUL); Skip_Eol; end if; C := Getc; end loop Linker_Options_Loop; -- Store the linker options entry if one was found if Name_Len /= 0 then Linker_Options.Increment_Last; Linker_Options.Table (Linker_Options.Last).Name := Name_Enter; Linker_Options.Table (Linker_Options.Last).Unit := Units.Last; Linker_Options.Table (Linker_Options.Last).Internal_File := Is_Internal_File_Name (F); Linker_Options.Table (Linker_Options.Last).Original_Pos := Linker_Options.Last; end if; -- If there are notes present, scan them Notes_Loop : loop Check_Unknown_Line; exit Notes_Loop when C /= 'N'; if Ignore ('N') then Skip_Line; else Checkc (' '); Notes.Increment_Last; Notes.Table (Notes.Last).Pragma_Type := Getc; Notes.Table (Notes.Last).Pragma_Line := Get_Nat; Checkc (':'); Notes.Table (Notes.Last).Pragma_Col := Get_Nat; Notes.Table (Notes.Last).Unit := Units.Last; if At_Eol then Notes.Table (Notes.Last).Pragma_Args := No_Name; else Checkc (' '); Name_Len := 0; while not At_Eol loop Add_Char_To_Name_Buffer (Getc); end loop; Notes.Table (Notes.Last).Pragma_Args := Name_Enter; end if; Skip_Eol; end if; C := Getc; end loop Notes_Loop; end loop U_Loop; -- End loop through units for one ALI file ALIs.Table (Id).Last_Unit := Units.Last; ALIs.Table (Id).Sfile := Units.Table (ALIs.Table (Id).First_Unit).Sfile; -- Set types of the units (there can be at most 2 of them) if ALIs.Table (Id).First_Unit /= ALIs.Table (Id).Last_Unit then Units.Table (ALIs.Table (Id).First_Unit).Utype := Is_Body; Units.Table (ALIs.Table (Id).Last_Unit).Utype := Is_Spec; else -- Deal with body only and spec only cases, note that the reason we -- do our own checking of the name (rather than using Is_Body_Name) -- is that Uname drags in far too much compiler junk. Get_Name_String (Units.Table (Units.Last).Uname); if Name_Buffer (Name_Len) = 'b' then Units.Table (Units.Last).Utype := Is_Body_Only; else Units.Table (Units.Last).Utype := Is_Spec_Only; end if; end if; -- Scan out external version references and put in hash table E_Loop : loop Check_Unknown_Line; exit E_Loop when C /= 'E'; if Ignore ('E') then Skip_Line; else Checkc (' '); Skip_Space; Name_Len := 0; Name_Len := 0; loop C := Getc; if C < ' ' then Fatal_Error; end if; exit when At_End_Of_Field; Add_Char_To_Name_Buffer (C); end loop; Version_Ref.Set (new String'(Name_Buffer (1 .. Name_Len)), True); Skip_Eol; end if; C := Getc; end loop E_Loop; -- Scan out source dependency lines for this ALI file ALIs.Table (Id).First_Sdep := Sdep.Last + 1; D_Loop : loop Check_Unknown_Line; exit D_Loop when C /= 'D'; if Ignore ('D') then Skip_Line; else Checkc (' '); Skip_Space; Sdep.Increment_Last; -- In the following call, Lower is not set to True, this is either -- a bug, or it deserves a special comment as to why this is so??? -- The file/path name may be quoted Sdep.Table (Sdep.Last).Sfile := Get_File_Name (May_Be_Quoted => True); Sdep.Table (Sdep.Last).Stamp := Get_Stamp; Sdep.Table (Sdep.Last).Dummy_Entry := (Sdep.Table (Sdep.Last).Stamp = Dummy_Time_Stamp); -- Acquire checksum value Skip_Space; declare Ctr : Natural; Chk : Word; begin Ctr := 0; Chk := 0; loop exit when At_Eol or else Ctr = 8; if Nextc in '0' .. '9' then Chk := Chk * 16 + Character'Pos (Nextc) - Character'Pos ('0'); elsif Nextc in 'a' .. 'f' then Chk := Chk * 16 + Character'Pos (Nextc) - Character'Pos ('a') + 10; else exit; end if; Ctr := Ctr + 1; P := P + 1; end loop; if Ctr = 8 and then At_End_Of_Field then Sdep.Table (Sdep.Last).Checksum := Chk; else Fatal_Error; end if; end; -- Acquire (sub)unit and reference file name entries Sdep.Table (Sdep.Last).Subunit_Name := No_Name; Sdep.Table (Sdep.Last).Unit_Name := No_Name; Sdep.Table (Sdep.Last).Rfile := Sdep.Table (Sdep.Last).Sfile; Sdep.Table (Sdep.Last).Start_Line := 1; if not At_Eol then Skip_Space; -- Here for (sub)unit name if Nextc not in '0' .. '9' then Name_Len := 0; while not At_End_Of_Field loop Add_Char_To_Name_Buffer (Getc); end loop; -- Set the (sub)unit name. Note that we use Name_Find rather -- than Name_Enter here as the subunit name may already -- have been put in the name table by the Project Manager. if Name_Len <= 2 or else Name_Buffer (Name_Len - 1) /= '%' then Sdep.Table (Sdep.Last).Subunit_Name := Name_Find; else Name_Len := Name_Len - 2; Sdep.Table (Sdep.Last).Unit_Name := Name_Find; end if; Skip_Space; end if; -- Here for reference file name entry if Nextc in '0' .. '9' then Sdep.Table (Sdep.Last).Start_Line := Get_Nat; Checkc (':'); Name_Len := 0; while not At_End_Of_Field loop Add_Char_To_Name_Buffer (Getc); end loop; Sdep.Table (Sdep.Last).Rfile := Name_Enter; end if; end if; Skip_Eol; end if; C := Getc; end loop D_Loop; ALIs.Table (Id).Last_Sdep := Sdep.Last; -- We must at this stage be at an Xref line or the end of file if C = EOF then return Id; end if; Check_Unknown_Line; if C /= 'X' then Fatal_Error; end if; -- If we are ignoring Xref sections we are done (we ignore all -- remaining lines since only xref related lines follow X). if Ignore ('X') and then not Debug_Flag_X then return Id; end if; -- Loop through Xref sections X_Loop : loop Check_Unknown_Line; exit X_Loop when C /= 'X'; -- Make new entry in section table Xref_Section.Increment_Last; Read_Refs_For_One_File : declare XS : Xref_Section_Record renames Xref_Section.Table (Xref_Section.Last); Current_File_Num : Sdep_Id; -- Keeps track of the current file number (changed by nn|) begin XS.File_Num := Sdep_Id (Get_Nat + Nat (First_Sdep_Entry) - 1); XS.File_Name := Get_File_Name; XS.First_Entity := Xref_Entity.Last + 1; Current_File_Num := XS.File_Num; Skip_Space; Skip_Eol; C := Nextc; -- Loop through Xref entities while C /= 'X' and then C /= EOF loop Xref_Entity.Increment_Last; Read_Refs_For_One_Entity : declare XE : Xref_Entity_Record renames Xref_Entity.Table (Xref_Entity.Last); N : Nat; procedure Read_Instantiation_Reference; -- Acquire instantiation reference. Caller has checked -- that current character is '[' and on return the cursor -- is skipped past the corresponding closing ']'. ---------------------------------- -- Read_Instantiation_Reference -- ---------------------------------- procedure Read_Instantiation_Reference is Local_File_Num : Sdep_Id := Current_File_Num; begin Xref.Increment_Last; declare XR : Xref_Record renames Xref.Table (Xref.Last); begin P := P + 1; -- skip [ N := Get_Nat; if Nextc = '|' then XR.File_Num := Sdep_Id (N + Nat (First_Sdep_Entry) - 1); Local_File_Num := XR.File_Num; P := P + 1; N := Get_Nat; else XR.File_Num := Local_File_Num; end if; XR.Line := N; XR.Rtype := ' '; XR.Col := 0; -- Recursive call for next reference if Nextc = '[' then pragma Warnings (Off); -- kill recursion warning Read_Instantiation_Reference; pragma Warnings (On); end if; -- Skip closing bracket after recursive call P := P + 1; end; end Read_Instantiation_Reference; -- Start of processing for Read_Refs_For_One_Entity begin XE.Line := Get_Nat; XE.Etype := Getc; XE.Col := Get_Nat; case Getc is when '*' => XE.Visibility := Global; when '+' => XE.Visibility := Static; when others => XE.Visibility := Other; end case; XE.Entity := Get_Name; -- Handle the information about generic instantiations if Nextc = '[' then Skipc; -- Opening '[' N := Get_Nat; if Nextc /= '|' then XE.Iref_File_Num := Current_File_Num; XE.Iref_Line := N; else XE.Iref_File_Num := Sdep_Id (N + Nat (First_Sdep_Entry) - 1); Skipc; XE.Iref_Line := Get_Nat; end if; if Getc /= ']' then Fatal_Error; end if; else XE.Iref_File_Num := No_Sdep_Id; XE.Iref_Line := 0; end if; Current_File_Num := XS.File_Num; -- Renaming reference is present if Nextc = '=' then P := P + 1; XE.Rref_Line := Get_Nat; if Getc /= ':' then Fatal_Error; end if; XE.Rref_Col := Get_Nat; -- No renaming reference present else XE.Rref_Line := 0; XE.Rref_Col := 0; end if; Skip_Space; XE.Oref_File_Num := No_Sdep_Id; XE.Tref_File_Num := No_Sdep_Id; XE.Tref := Tref_None; XE.First_Xref := Xref.Last + 1; -- Loop to check for additional info present loop declare Ref : Tref_Kind; File : Sdep_Id; Line : Nat; Typ : Character; Col : Nat; Std : Name_Id; begin Get_Typeref (Current_File_Num, Ref, File, Line, Typ, Col, Std); exit when Ref = Tref_None; -- Do we have an overriding procedure? if Ref = Tref_Derived and then Typ = 'p' then XE.Oref_File_Num := File; XE.Oref_Line := Line; XE.Oref_Col := Col; -- Arrays never override anything, and <> points to -- the index types instead elsif Ref = Tref_Derived and then XE.Etype = 'A' then -- Index types are stored in the list of references Xref.Increment_Last; declare XR : Xref_Record renames Xref.Table (Xref.Last); begin XR.File_Num := File; XR.Line := Line; XR.Rtype := Array_Index_Reference; XR.Col := Col; XR.Name := Std; end; -- Interfaces are stored in the list of references, -- although the parent type itself is stored in XE. -- The first interface (when there are only -- interfaces) is stored in XE.Tref*) elsif Ref = Tref_Derived and then Typ = 'R' and then XE.Tref_File_Num /= No_Sdep_Id then Xref.Increment_Last; declare XR : Xref_Record renames Xref.Table (Xref.Last); begin XR.File_Num := File; XR.Line := Line; XR.Rtype := Interface_Reference; XR.Col := Col; XR.Name := Std; end; else XE.Tref := Ref; XE.Tref_File_Num := File; XE.Tref_Line := Line; XE.Tref_Type := Typ; XE.Tref_Col := Col; XE.Tref_Standard_Entity := Std; end if; end; end loop; -- Loop through cross-references for this entity loop Skip_Space; if At_Eol then Skip_Eol; exit when Nextc /= '.'; P := P + 1; end if; Xref.Increment_Last; declare XR : Xref_Record renames Xref.Table (Xref.Last); begin N := Get_Nat; if Nextc = '|' then XR.File_Num := Sdep_Id (N + Nat (First_Sdep_Entry) - 1); Current_File_Num := XR.File_Num; P := P + 1; N := Get_Nat; else XR.File_Num := Current_File_Num; end if; XR.Line := N; XR.Rtype := Getc; -- Imported entities reference as in: -- 494b25 if Nextc = '<' then Skipc; XR.Imported_Lang := Get_Name; pragma Assert (Nextc = ','); Skipc; XR.Imported_Name := Get_Name; pragma Assert (Nextc = '>'); Skipc; else XR.Imported_Lang := No_Name; XR.Imported_Name := No_Name; end if; XR.Col := Get_Nat; if Nextc = '[' then Read_Instantiation_Reference; end if; end; end loop; -- Record last cross-reference XE.Last_Xref := Xref.Last; C := Nextc; exception when Bad_ALI_Format => -- If ignoring errors, then we skip a line with an -- unexpected error, and try to continue subsequent -- xref lines. if Ignore_Errors then Xref_Entity.Decrement_Last; Skip_Line; C := Nextc; -- Otherwise, we reraise the fatal exception else raise; end if; end Read_Refs_For_One_Entity; end loop; -- Record last entity XS.Last_Entity := Xref_Entity.Last; end Read_Refs_For_One_File; C := Getc; end loop X_Loop; -- Here after dealing with xref sections -- Ignore remaining lines, which belong to an additional section of the -- ALI file not considered here (like SCO or SPARK information). Check_Unknown_Line; return Id; exception when Bad_ALI_Format => return No_ALI_Id; end Scan_ALI; --------- -- SEq -- --------- function SEq (F1, F2 : String_Ptr) return Boolean is begin return F1.all = F2.all; end SEq; ----------- -- SHash -- ----------- function SHash (S : String_Ptr) return Vindex is H : Word; begin H := 0; for J in S.all'Range loop H := H * 2 + Character'Pos (S (J)); end loop; return Vindex (Vindex'First + Vindex (H mod Vindex'Range_Length)); end SHash; end ALI; gprbuild-gpl-2014-src/gnat/sinput-c.ads0000644000076700001450000000430112323721731017315 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- S I N P U T . C -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2007, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This child package contains a procedure to load files -- It is used by Sinput.P to load project files, and by GPrep to load -- preprocessor definition files and input files. package Sinput.C is function Load_File (Path : String) return Source_File_Index; -- Load a file into memory and Initialize the Scans state end Sinput.C; gprbuild-gpl-2014-src/gnat/prj-dect.adb0000644000076700001450000017715212323721731017261 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . D E C T -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Err_Vars; use Err_Vars; with Opt; use Opt; with Prj.Attr; use Prj.Attr; with Prj.Attr.PM; use Prj.Attr.PM; with Prj.Err; use Prj.Err; with Prj.Strt; use Prj.Strt; with Prj.Tree; use Prj.Tree; with Snames; with Uintp; use Uintp; with GNAT; use GNAT; with GNAT.Case_Util; use GNAT.Case_Util; with GNAT.Spelling_Checker; use GNAT.Spelling_Checker; with GNAT.Strings; package body Prj.Dect is type Zone is (In_Project, In_Package, In_Case_Construction); -- Used to indicate if we are parsing a package (In_Package), a case -- construction (In_Case_Construction) or none of those two (In_Project). procedure Rename_Obsolescent_Attributes (In_Tree : Project_Node_Tree_Ref; Attribute : Project_Node_Id; Current_Package : Project_Node_Id); -- Rename obsolescent attributes in the tree. When the attribute has been -- renamed since its initial introduction in the design of projects, we -- replace the old name in the tree with the new name, so that the code -- does not have to check both names forever. procedure Check_Attribute_Allowed (In_Tree : Project_Node_Tree_Ref; Project : Project_Node_Id; Attribute : Project_Node_Id; Flags : Processing_Flags); -- Check whether the attribute is valid in this project. In particular, -- depending on the type of project (qualifier), some attributes might -- be disabled. procedure Check_Package_Allowed (In_Tree : Project_Node_Tree_Ref; Project : Project_Node_Id; Current_Package : Project_Node_Id; Flags : Processing_Flags); -- Check whether the package is valid in this project procedure Parse_Attribute_Declaration (In_Tree : Project_Node_Tree_Ref; Attribute : out Project_Node_Id; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Packages_To_Check : String_List_Access; Flags : Processing_Flags); -- Parse an attribute declaration procedure Parse_Case_Construction (In_Tree : Project_Node_Tree_Ref; Case_Construction : out Project_Node_Id; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags); -- Parse a case construction procedure Parse_Declarative_Items (In_Tree : Project_Node_Tree_Ref; Declarations : out Project_Node_Id; In_Zone : Zone; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags); -- Parse declarative items. Depending on In_Zone, some declarative items -- may be forbidden. Is_Config_File should be set to True if the project -- represents a config file (.cgpr) since some specific checks apply. procedure Parse_Package_Declaration (In_Tree : Project_Node_Tree_Ref; Package_Declaration : out Project_Node_Id; Current_Project : Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags); -- Parse a package declaration. -- Is_Config_File should be set to True if the project represents a config -- file (.cgpr) since some specific checks apply. procedure Parse_String_Type_Declaration (In_Tree : Project_Node_Tree_Ref; String_Type : out Project_Node_Id; Current_Project : Project_Node_Id; Flags : Processing_Flags); -- type is ( { , } ) ; procedure Parse_Variable_Declaration (In_Tree : Project_Node_Tree_Ref; Variable : out Project_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Flags : Processing_Flags); -- Parse a variable assignment -- := ; OR -- : := ; ----------- -- Parse -- ----------- procedure Parse (In_Tree : Project_Node_Tree_Ref; Declarations : out Project_Node_Id; Current_Project : Project_Node_Id; Extends : Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags) is First_Declarative_Item : Project_Node_Id := Empty_Node; begin Declarations := Default_Project_Node (Of_Kind => N_Project_Declaration, In_Tree => In_Tree); Set_Location_Of (Declarations, In_Tree, To => Token_Ptr); Set_Extended_Project_Of (Declarations, In_Tree, To => Extends); Set_Project_Declaration_Of (Current_Project, In_Tree, Declarations); Parse_Declarative_Items (Declarations => First_Declarative_Item, In_Tree => In_Tree, In_Zone => In_Project, First_Attribute => Prj.Attr.Attribute_First, Current_Project => Current_Project, Current_Package => Empty_Node, Packages_To_Check => Packages_To_Check, Is_Config_File => Is_Config_File, Flags => Flags); Set_First_Declarative_Item_Of (Declarations, In_Tree, To => First_Declarative_Item); end Parse; ----------------------------------- -- Rename_Obsolescent_Attributes -- ----------------------------------- procedure Rename_Obsolescent_Attributes (In_Tree : Project_Node_Tree_Ref; Attribute : Project_Node_Id; Current_Package : Project_Node_Id) is begin if Present (Current_Package) and then Expression_Kind_Of (Current_Package, In_Tree) /= Ignored then case Name_Of (Attribute, In_Tree) is when Snames.Name_Specification => Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec); when Snames.Name_Specification_Suffix => Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Spec_Suffix); when Snames.Name_Implementation => Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body); when Snames.Name_Implementation_Suffix => Set_Name_Of (Attribute, In_Tree, To => Snames.Name_Body_Suffix); when others => null; end case; end if; end Rename_Obsolescent_Attributes; --------------------------- -- Check_Package_Allowed -- --------------------------- procedure Check_Package_Allowed (In_Tree : Project_Node_Tree_Ref; Project : Project_Node_Id; Current_Package : Project_Node_Id; Flags : Processing_Flags) is Qualif : constant Project_Qualifier := Project_Qualifier_Of (Project, In_Tree); Name : constant Name_Id := Name_Of (Current_Package, In_Tree); begin if (Qualif = Aggregate and then Name /= Snames.Name_Builder) or else (Qualif = Aggregate_Library and then Name /= Snames.Name_Builder and then Name /= Snames.Name_Install) then Error_Msg_Name_1 := Name; Error_Msg (Flags, "package %% is forbidden in aggregate projects", Location_Of (Current_Package, In_Tree)); end if; end Check_Package_Allowed; ----------------------------- -- Check_Attribute_Allowed -- ----------------------------- procedure Check_Attribute_Allowed (In_Tree : Project_Node_Tree_Ref; Project : Project_Node_Id; Attribute : Project_Node_Id; Flags : Processing_Flags) is Qualif : constant Project_Qualifier := Project_Qualifier_Of (Project, In_Tree); Name : constant Name_Id := Name_Of (Attribute, In_Tree); begin case Qualif is when Aggregate | Aggregate_Library => if Name = Snames.Name_Languages or else Name = Snames.Name_Source_Files or else Name = Snames.Name_Source_List_File or else Name = Snames.Name_Locally_Removed_Files or else Name = Snames.Name_Excluded_Source_Files or else Name = Snames.Name_Excluded_Source_List_File or else Name = Snames.Name_Interfaces or else Name = Snames.Name_Object_Dir or else Name = Snames.Name_Exec_Dir or else Name = Snames.Name_Source_Dirs or else Name = Snames.Name_Inherit_Source_Path or else (Qualif = Aggregate and then Name = Snames.Name_Library_Dir) or else (Qualif = Aggregate and then Name = Snames.Name_Library_Name) or else Name = Snames.Name_Main or else Name = Snames.Name_Roots or else Name = Snames.Name_Externally_Built or else Name = Snames.Name_Executable or else Name = Snames.Name_Executable_Suffix or else Name = Snames.Name_Default_Switches then Error_Msg_Name_1 := Name; Error_Msg (Flags, "%% is not valid in aggregate projects", Location_Of (Attribute, In_Tree)); end if; when others => if Name = Snames.Name_Project_Files or else Name = Snames.Name_Project_Path or else Name = Snames.Name_External then Error_Msg_Name_1 := Name; Error_Msg (Flags, "%% is only valid in aggregate projects", Location_Of (Attribute, In_Tree)); end if; end case; end Check_Attribute_Allowed; --------------------------------- -- Parse_Attribute_Declaration -- --------------------------------- procedure Parse_Attribute_Declaration (In_Tree : Project_Node_Tree_Ref; Attribute : out Project_Node_Id; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Packages_To_Check : String_List_Access; Flags : Processing_Flags) is Current_Attribute : Attribute_Node_Id := First_Attribute; Full_Associative_Array : Boolean := False; Attribute_Name : Name_Id := No_Name; Optional_Index : Boolean := False; Pkg_Id : Package_Node_Id := Empty_Package; procedure Process_Attribute_Name; -- Read the name of the attribute, and check its type procedure Process_Associative_Array_Index; -- Read the index of the associative array and check its validity ---------------------------- -- Process_Attribute_Name -- ---------------------------- procedure Process_Attribute_Name is Ignore : Boolean; begin Attribute_Name := Token_Name; Set_Name_Of (Attribute, In_Tree, To => Attribute_Name); Set_Location_Of (Attribute, In_Tree, To => Token_Ptr); -- Find the attribute Current_Attribute := Attribute_Node_Id_Of (Attribute_Name, First_Attribute); -- If the attribute cannot be found, create the attribute if inside -- an unknown package. if Current_Attribute = Empty_Attribute then if Present (Current_Package) and then Expression_Kind_Of (Current_Package, In_Tree) = Ignored then Pkg_Id := Package_Id_Of (Current_Package, In_Tree); Add_Attribute (Pkg_Id, Token_Name, Current_Attribute); else -- If not a valid attribute name, issue an error if inside -- a package that need to be checked. Ignore := Present (Current_Package) and then Packages_To_Check /= All_Packages; if Ignore then -- Check that we are not in a package to check Get_Name_String (Name_Of (Current_Package, In_Tree)); for Index in Packages_To_Check'Range loop if Name_Buffer (1 .. Name_Len) = Packages_To_Check (Index).all then Ignore := False; exit; end if; end loop; end if; if not Ignore then Error_Msg_Name_1 := Token_Name; Error_Msg (Flags, "undefined attribute %%", Token_Ptr); end if; end if; -- Set, if appropriate the index case insensitivity flag else if Is_Read_Only (Current_Attribute) then Error_Msg_Name_1 := Token_Name; Error_Msg (Flags, "read-only attribute %% cannot be given a value", Token_Ptr); end if; if Attribute_Kind_Of (Current_Attribute) in All_Case_Insensitive_Associative_Array then Set_Case_Insensitive (Attribute, In_Tree, To => True); end if; end if; Scan (In_Tree); -- past the attribute name -- Set the expression kind of the attribute if Current_Attribute /= Empty_Attribute then Set_Expression_Kind_Of (Attribute, In_Tree, To => Variable_Kind_Of (Current_Attribute)); Optional_Index := Optional_Index_Of (Current_Attribute); end if; end Process_Attribute_Name; ------------------------------------- -- Process_Associative_Array_Index -- ------------------------------------- procedure Process_Associative_Array_Index is begin -- If the attribute is not an associative array attribute, report -- an error. If this information is still unknown, set the kind -- to Associative_Array. if Current_Attribute /= Empty_Attribute and then Attribute_Kind_Of (Current_Attribute) = Single then Error_Msg (Flags, "the attribute """ & Get_Name_String (Attribute_Name_Of (Current_Attribute)) & """ cannot be an associative array", Location_Of (Attribute, In_Tree)); elsif Attribute_Kind_Of (Current_Attribute) = Unknown then Set_Attribute_Kind_Of (Current_Attribute, To => Associative_Array); end if; Scan (In_Tree); -- past the left parenthesis if Others_Allowed_For (Current_Attribute) and then Token = Tok_Others then Set_Associative_Array_Index_Of (Attribute, In_Tree, All_Other_Names); Scan (In_Tree); -- past others else if Others_Allowed_For (Current_Attribute) then Expect (Tok_String_Literal, "literal string or others"); else Expect (Tok_String_Literal, "literal string"); end if; if Token = Tok_String_Literal then Get_Name_String (Token_Name); if Case_Insensitive (Attribute, In_Tree) then To_Lower (Name_Buffer (1 .. Name_Len)); end if; Set_Associative_Array_Index_Of (Attribute, In_Tree, Name_Find); Scan (In_Tree); -- past the literal string index if Token = Tok_At then case Attribute_Kind_Of (Current_Attribute) is when Optional_Index_Associative_Array | Optional_Index_Case_Insensitive_Associative_Array => Scan (In_Tree); Expect (Tok_Integer_Literal, "integer literal"); if Token = Tok_Integer_Literal then -- Set the source index value from given literal declare Index : constant Int := UI_To_Int (Int_Literal_Value); begin if Index = 0 then Error_Msg (Flags, "index cannot be zero", Token_Ptr); else Set_Source_Index_Of (Attribute, In_Tree, To => Index); end if; end; Scan (In_Tree); end if; when others => Error_Msg (Flags, "index not allowed here", Token_Ptr); Scan (In_Tree); if Token = Tok_Integer_Literal then Scan (In_Tree); end if; end case; end if; end if; end if; Expect (Tok_Right_Paren, "`)`"); if Token = Tok_Right_Paren then Scan (In_Tree); -- past the right parenthesis end if; end Process_Associative_Array_Index; begin Attribute := Default_Project_Node (Of_Kind => N_Attribute_Declaration, In_Tree => In_Tree); Set_Location_Of (Attribute, In_Tree, To => Token_Ptr); Set_Previous_Line_Node (Attribute); -- Scan past "for" Scan (In_Tree); -- Body or External may be an attribute name if Token = Tok_Body then Token := Tok_Identifier; Token_Name := Snames.Name_Body; end if; if Token = Tok_External then Token := Tok_Identifier; Token_Name := Snames.Name_External; end if; Expect (Tok_Identifier, "identifier"); Process_Attribute_Name; Rename_Obsolescent_Attributes (In_Tree, Attribute, Current_Package); Check_Attribute_Allowed (In_Tree, Current_Project, Attribute, Flags); -- Associative array attributes if Token = Tok_Left_Paren then Process_Associative_Array_Index; else -- If it is an associative array attribute and there are no left -- parenthesis, then this is a full associative array declaration. -- Flag it as such for later processing of its value. if Current_Attribute /= Empty_Attribute and then Attribute_Kind_Of (Current_Attribute) /= Single then if Attribute_Kind_Of (Current_Attribute) = Unknown then Set_Attribute_Kind_Of (Current_Attribute, To => Single); else Full_Associative_Array := True; end if; end if; end if; Expect (Tok_Use, "USE"); if Token = Tok_Use then Scan (In_Tree); if Full_Associative_Array then -- Expect ', or -- .' declare The_Project : Project_Node_Id := Empty_Node; -- The node of the project where the associative array is -- declared. The_Package : Project_Node_Id := Empty_Node; -- The node of the package where the associative array is -- declared, if any. Project_Name : Name_Id := No_Name; -- The name of the project where the associative array is -- declared. Location : Source_Ptr := No_Location; -- The location of the project name begin Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then Location := Token_Ptr; -- Find the project node in the imported project or -- in the project being extended. The_Project := Imported_Or_Extended_Project_Of (Current_Project, In_Tree, Token_Name); if No (The_Project) then Error_Msg (Flags, "unknown project", Location); Scan (In_Tree); -- past the project name else Project_Name := Token_Name; Scan (In_Tree); -- past the project name -- If this is inside a package, a dot followed by the -- name of the package must followed the project name. if Present (Current_Package) then Expect (Tok_Dot, "`.`"); if Token /= Tok_Dot then The_Project := Empty_Node; else Scan (In_Tree); -- past the dot Expect (Tok_Identifier, "identifier"); if Token /= Tok_Identifier then The_Project := Empty_Node; -- If it is not the same package name, issue error elsif Token_Name /= Name_Of (Current_Package, In_Tree) then The_Project := Empty_Node; Error_Msg (Flags, "not the same package as " & Get_Name_String (Name_Of (Current_Package, In_Tree)), Token_Ptr); else The_Package := First_Package_Of (The_Project, In_Tree); -- Look for the package node while Present (The_Package) and then Name_Of (The_Package, In_Tree) /= Token_Name loop The_Package := Next_Package_In_Project (The_Package, In_Tree); end loop; -- If the package cannot be found in the -- project, issue an error. if No (The_Package) then The_Project := Empty_Node; Error_Msg_Name_2 := Project_Name; Error_Msg_Name_1 := Token_Name; Error_Msg (Flags, "package % not declared in project %", Token_Ptr); end if; Scan (In_Tree); -- past the package name end if; end if; end if; end if; end if; if Present (The_Project) then -- Looking for ' Expect (Tok_Apostrophe, "`''`"); if Token /= Tok_Apostrophe then The_Project := Empty_Node; else Scan (In_Tree); -- past the apostrophe Expect (Tok_Identifier, "identifier"); if Token /= Tok_Identifier then The_Project := Empty_Node; else -- If it is not the same attribute name, issue error if Token_Name /= Attribute_Name then The_Project := Empty_Node; Error_Msg_Name_1 := Attribute_Name; Error_Msg (Flags, "invalid name, should be %", Token_Ptr); end if; Scan (In_Tree); -- past the attribute name end if; end if; end if; if No (The_Project) then -- If there were any problem, set the attribute id to null, -- so that the node will not be recorded. Current_Attribute := Empty_Attribute; else -- Set the appropriate field in the node. -- Note that the index and the expression are nil. This -- characterizes full associative array attribute -- declarations. Set_Associative_Project_Of (Attribute, In_Tree, The_Project); Set_Associative_Package_Of (Attribute, In_Tree, The_Package); end if; end; -- Other attribute declarations (not full associative array) else declare Expression_Location : constant Source_Ptr := Token_Ptr; -- The location of the first token of the expression Expression : Project_Node_Id := Empty_Node; -- The expression, value for the attribute declaration begin -- Get the expression value and set it in the attribute node Parse_Expression (In_Tree => In_Tree, Expression => Expression, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package, Optional_Index => Optional_Index); Set_Expression_Of (Attribute, In_Tree, To => Expression); -- If the expression is legal, but not of the right kind -- for the attribute, issue an error. if Current_Attribute /= Empty_Attribute and then Present (Expression) and then Variable_Kind_Of (Current_Attribute) /= Expression_Kind_Of (Expression, In_Tree) then if Variable_Kind_Of (Current_Attribute) = Undefined then Set_Variable_Kind_Of (Current_Attribute, To => Expression_Kind_Of (Expression, In_Tree)); else Error_Msg (Flags, "wrong expression kind for attribute """ & Get_Name_String (Attribute_Name_Of (Current_Attribute)) & """", Expression_Location); end if; end if; end; end if; end if; -- If the attribute was not recognized, return an empty node. -- It may be that it is not in a package to check, and the node will -- not be added to the tree. if Current_Attribute = Empty_Attribute then Attribute := Empty_Node; end if; Set_End_Of_Line (Attribute); Set_Previous_Line_Node (Attribute); end Parse_Attribute_Declaration; ----------------------------- -- Parse_Case_Construction -- ----------------------------- procedure Parse_Case_Construction (In_Tree : Project_Node_Tree_Ref; Case_Construction : out Project_Node_Id; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags) is Current_Item : Project_Node_Id := Empty_Node; Next_Item : Project_Node_Id := Empty_Node; First_Case_Item : Boolean := True; Variable_Location : Source_Ptr := No_Location; String_Type : Project_Node_Id := Empty_Node; Case_Variable : Project_Node_Id := Empty_Node; First_Declarative_Item : Project_Node_Id := Empty_Node; First_Choice : Project_Node_Id := Empty_Node; When_Others : Boolean := False; -- Set to True when there is a "when others =>" clause begin Case_Construction := Default_Project_Node (Of_Kind => N_Case_Construction, In_Tree => In_Tree); Set_Location_Of (Case_Construction, In_Tree, To => Token_Ptr); -- Scan past "case" Scan (In_Tree); -- Get the switch variable Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then Variable_Location := Token_Ptr; Parse_Variable_Reference (In_Tree => In_Tree, Variable => Case_Variable, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package); Set_Case_Variable_Reference_Of (Case_Construction, In_Tree, To => Case_Variable); else if Token /= Tok_Is then Scan (In_Tree); end if; end if; if Present (Case_Variable) then String_Type := String_Type_Of (Case_Variable, In_Tree); if No (String_Type) then Error_Msg (Flags, "variable """ & Get_Name_String (Name_Of (Case_Variable, In_Tree)) & """ is not typed", Variable_Location); end if; end if; Expect (Tok_Is, "IS"); if Token = Tok_Is then Set_End_Of_Line (Case_Construction); Set_Previous_Line_Node (Case_Construction); Set_Next_End_Node (Case_Construction); -- Scan past "is" Scan (In_Tree); end if; Start_New_Case_Construction (In_Tree, String_Type); When_Loop : while Token = Tok_When loop if First_Case_Item then Current_Item := Default_Project_Node (Of_Kind => N_Case_Item, In_Tree => In_Tree); Set_First_Case_Item_Of (Case_Construction, In_Tree, To => Current_Item); First_Case_Item := False; else Next_Item := Default_Project_Node (Of_Kind => N_Case_Item, In_Tree => In_Tree); Set_Next_Case_Item (Current_Item, In_Tree, To => Next_Item); Current_Item := Next_Item; end if; Set_Location_Of (Current_Item, In_Tree, To => Token_Ptr); -- Scan past "when" Scan (In_Tree); if Token = Tok_Others then When_Others := True; -- Scan past "others" Scan (In_Tree); Expect (Tok_Arrow, "`=>`"); Set_End_Of_Line (Current_Item); Set_Previous_Line_Node (Current_Item); -- Empty_Node in Field1 of a Case_Item indicates -- the "when others =>" branch. Set_First_Choice_Of (Current_Item, In_Tree, To => Empty_Node); Parse_Declarative_Items (In_Tree => In_Tree, Declarations => First_Declarative_Item, In_Zone => In_Case_Construction, First_Attribute => First_Attribute, Current_Project => Current_Project, Current_Package => Current_Package, Packages_To_Check => Packages_To_Check, Is_Config_File => Is_Config_File, Flags => Flags); -- "when others =>" must be the last branch, so save the -- Case_Item and exit Set_First_Declarative_Item_Of (Current_Item, In_Tree, To => First_Declarative_Item); exit When_Loop; else Parse_Choice_List (In_Tree => In_Tree, First_Choice => First_Choice, Flags => Flags); Set_First_Choice_Of (Current_Item, In_Tree, To => First_Choice); Expect (Tok_Arrow, "`=>`"); Set_End_Of_Line (Current_Item); Set_Previous_Line_Node (Current_Item); Parse_Declarative_Items (In_Tree => In_Tree, Declarations => First_Declarative_Item, In_Zone => In_Case_Construction, First_Attribute => First_Attribute, Current_Project => Current_Project, Current_Package => Current_Package, Packages_To_Check => Packages_To_Check, Is_Config_File => Is_Config_File, Flags => Flags); Set_First_Declarative_Item_Of (Current_Item, In_Tree, To => First_Declarative_Item); end if; end loop When_Loop; End_Case_Construction (Check_All_Labels => not When_Others and not Quiet_Output, Case_Location => Location_Of (Case_Construction, In_Tree), Flags => Flags); Expect (Tok_End, "`END CASE`"); Remove_Next_End_Node; if Token = Tok_End then -- Scan past "end" Scan (In_Tree); Expect (Tok_Case, "CASE"); end if; -- Scan past "case" Scan (In_Tree); Expect (Tok_Semicolon, "`;`"); Set_Previous_End_Node (Case_Construction); end Parse_Case_Construction; ----------------------------- -- Parse_Declarative_Items -- ----------------------------- procedure Parse_Declarative_Items (In_Tree : Project_Node_Tree_Ref; Declarations : out Project_Node_Id; In_Zone : Zone; First_Attribute : Attribute_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags) is Current_Declarative_Item : Project_Node_Id := Empty_Node; Next_Declarative_Item : Project_Node_Id := Empty_Node; Current_Declaration : Project_Node_Id := Empty_Node; Item_Location : Source_Ptr := No_Location; begin Declarations := Empty_Node; loop -- We are always positioned at the token that precedes the first -- token of the declarative element. Scan past it. Scan (In_Tree); Item_Location := Token_Ptr; case Token is when Tok_Identifier => if In_Zone = In_Case_Construction then -- Check if the variable has already been declared declare The_Variable : Project_Node_Id := Empty_Node; begin if Present (Current_Package) then The_Variable := First_Variable_Of (Current_Package, In_Tree); elsif Present (Current_Project) then The_Variable := First_Variable_Of (Current_Project, In_Tree); end if; while Present (The_Variable) and then Name_Of (The_Variable, In_Tree) /= Token_Name loop The_Variable := Next_Variable (The_Variable, In_Tree); end loop; -- It is an error to declare a variable in a case -- construction for the first time. if No (The_Variable) then Error_Msg (Flags, "a variable cannot be declared " & "for the first time here", Token_Ptr); end if; end; end if; Parse_Variable_Declaration (In_Tree, Current_Declaration, Current_Project => Current_Project, Current_Package => Current_Package, Flags => Flags); Set_End_Of_Line (Current_Declaration); Set_Previous_Line_Node (Current_Declaration); when Tok_For => Parse_Attribute_Declaration (In_Tree => In_Tree, Attribute => Current_Declaration, First_Attribute => First_Attribute, Current_Project => Current_Project, Current_Package => Current_Package, Packages_To_Check => Packages_To_Check, Flags => Flags); Set_End_Of_Line (Current_Declaration); Set_Previous_Line_Node (Current_Declaration); when Tok_Null => Scan (In_Tree); -- past "null" when Tok_Package => -- Package declaration if In_Zone /= In_Project then Error_Msg (Flags, "a package cannot be declared here", Token_Ptr); end if; Parse_Package_Declaration (In_Tree => In_Tree, Package_Declaration => Current_Declaration, Current_Project => Current_Project, Packages_To_Check => Packages_To_Check, Is_Config_File => Is_Config_File, Flags => Flags); Set_Previous_End_Node (Current_Declaration); when Tok_Type => -- Type String Declaration if In_Zone /= In_Project then Error_Msg (Flags, "a string type cannot be declared here", Token_Ptr); end if; Parse_String_Type_Declaration (In_Tree => In_Tree, String_Type => Current_Declaration, Current_Project => Current_Project, Flags => Flags); Set_End_Of_Line (Current_Declaration); Set_Previous_Line_Node (Current_Declaration); when Tok_Case => -- Case construction Parse_Case_Construction (In_Tree => In_Tree, Case_Construction => Current_Declaration, First_Attribute => First_Attribute, Current_Project => Current_Project, Current_Package => Current_Package, Packages_To_Check => Packages_To_Check, Is_Config_File => Is_Config_File, Flags => Flags); Set_Previous_End_Node (Current_Declaration); when others => exit; -- We are leaving Parse_Declarative_Items positioned -- at the first token after the list of declarative items. -- It could be "end" (for a project, a package declaration or -- a case construction) or "when" (for a case construction) end case; Expect (Tok_Semicolon, "`;` after declarative items"); -- Insert an N_Declarative_Item in the tree, but only if -- Current_Declaration is not an empty node. if Present (Current_Declaration) then if No (Current_Declarative_Item) then Current_Declarative_Item := Default_Project_Node (Of_Kind => N_Declarative_Item, In_Tree => In_Tree); Declarations := Current_Declarative_Item; else Next_Declarative_Item := Default_Project_Node (Of_Kind => N_Declarative_Item, In_Tree => In_Tree); Set_Next_Declarative_Item (Current_Declarative_Item, In_Tree, To => Next_Declarative_Item); Current_Declarative_Item := Next_Declarative_Item; end if; Set_Current_Item_Node (Current_Declarative_Item, In_Tree, To => Current_Declaration); Set_Location_Of (Current_Declarative_Item, In_Tree, To => Item_Location); end if; end loop; end Parse_Declarative_Items; ------------------------------- -- Parse_Package_Declaration -- ------------------------------- procedure Parse_Package_Declaration (In_Tree : Project_Node_Tree_Ref; Package_Declaration : out Project_Node_Id; Current_Project : Project_Node_Id; Packages_To_Check : String_List_Access; Is_Config_File : Boolean; Flags : Processing_Flags) is First_Attribute : Attribute_Node_Id := Empty_Attribute; Current_Package : Package_Node_Id := Empty_Package; First_Declarative_Item : Project_Node_Id := Empty_Node; Package_Location : constant Source_Ptr := Token_Ptr; Renaming : Boolean := False; Extending : Boolean := False; begin Package_Declaration := Default_Project_Node (Of_Kind => N_Package_Declaration, In_Tree => In_Tree); Set_Location_Of (Package_Declaration, In_Tree, To => Package_Location); -- Scan past "package" Scan (In_Tree); Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then Set_Name_Of (Package_Declaration, In_Tree, To => Token_Name); Current_Package := Package_Node_Id_Of (Token_Name); if Current_Package = Empty_Package then if not Quiet_Output then declare List : constant Strings.String_List := Package_Name_List; Index : Natural; Name : constant String := Get_Name_String (Token_Name); begin -- Check for possible misspelling of a known package name Index := 0; loop if Index >= List'Last then Index := 0; exit; end if; Index := Index + 1; exit when GNAT.Spelling_Checker.Is_Bad_Spelling_Of (Name, List (Index).all); end loop; -- Issue warning(s) in verbose mode or when a possible -- misspelling has been found. if Verbose_Mode or else Index /= 0 then Error_Msg (Flags, "?""" & Get_Name_String (Name_Of (Package_Declaration, In_Tree)) & """ is not a known package name", Token_Ptr); end if; if Index /= 0 then Error_Msg -- CODEFIX (Flags, "\?possible misspelling of """ & List (Index).all & """", Token_Ptr); end if; end; end if; -- Set the package declaration to "ignored" so that it is not -- processed by Prj.Proc.Process. Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored); -- Add the unknown package in the list of packages Add_Unknown_Package (Token_Name, Current_Package); elsif Current_Package = Unknown_Package then -- Set the package declaration to "ignored" so that it is not -- processed by Prj.Proc.Process. Set_Expression_Kind_Of (Package_Declaration, In_Tree, Ignored); else First_Attribute := First_Attribute_Of (Current_Package); end if; Set_Package_Id_Of (Package_Declaration, In_Tree, To => Current_Package); declare Current : Project_Node_Id := First_Package_Of (Current_Project, In_Tree); begin while Present (Current) and then Name_Of (Current, In_Tree) /= Token_Name loop Current := Next_Package_In_Project (Current, In_Tree); end loop; if Present (Current) then Error_Msg (Flags, "package """ & Get_Name_String (Name_Of (Package_Declaration, In_Tree)) & """ is declared twice in the same project", Token_Ptr); else -- Add the package to the project list Set_Next_Package_In_Project (Package_Declaration, In_Tree, To => First_Package_Of (Current_Project, In_Tree)); Set_First_Package_Of (Current_Project, In_Tree, To => Package_Declaration); end if; end; -- Scan past the package name Scan (In_Tree); end if; Check_Package_Allowed (In_Tree, Current_Project, Package_Declaration, Flags); if Token = Tok_Renames then Renaming := True; elsif Token = Tok_Extends then Extending := True; end if; if Renaming or else Extending then if Is_Config_File then Error_Msg (Flags, "no package rename or extension in configuration projects", Token_Ptr); end if; -- Scan past "renames" or "extends" Scan (In_Tree); Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then declare Project_Name : constant Name_Id := Token_Name; Clause : Project_Node_Id := First_With_Clause_Of (Current_Project, In_Tree); The_Project : Project_Node_Id := Empty_Node; Extended : constant Project_Node_Id := Extended_Project_Of (Project_Declaration_Of (Current_Project, In_Tree), In_Tree); begin while Present (Clause) loop -- Only non limited imported projects may be used in a -- renames declaration. The_Project := Non_Limited_Project_Node_Of (Clause, In_Tree); exit when Present (The_Project) and then Name_Of (The_Project, In_Tree) = Project_Name; Clause := Next_With_Clause_Of (Clause, In_Tree); end loop; if No (Clause) then -- As we have not found the project in the imports, we check -- if it's the name of an eventual extended project. if Present (Extended) and then Name_Of (Extended, In_Tree) = Project_Name then Set_Project_Of_Renamed_Package_Of (Package_Declaration, In_Tree, To => Extended); else Error_Msg_Name_1 := Project_Name; Error_Msg (Flags, "% is not an imported or extended project", Token_Ptr); end if; else Set_Project_Of_Renamed_Package_Of (Package_Declaration, In_Tree, To => The_Project); end if; end; Scan (In_Tree); Expect (Tok_Dot, "`.`"); if Token = Tok_Dot then Scan (In_Tree); Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then if Name_Of (Package_Declaration, In_Tree) /= Token_Name then Error_Msg (Flags, "not the same package name", Token_Ptr); elsif Present (Project_Of_Renamed_Package_Of (Package_Declaration, In_Tree)) then declare Current : Project_Node_Id := First_Package_Of (Project_Of_Renamed_Package_Of (Package_Declaration, In_Tree), In_Tree); begin while Present (Current) and then Name_Of (Current, In_Tree) /= Token_Name loop Current := Next_Package_In_Project (Current, In_Tree); end loop; if No (Current) then Error_Msg (Flags, """" & Get_Name_String (Token_Name) & """ is not a package declared by the project", Token_Ptr); end if; end; end if; Scan (In_Tree); end if; end if; end if; end if; if Renaming then Expect (Tok_Semicolon, "`;`"); Set_End_Of_Line (Package_Declaration); Set_Previous_Line_Node (Package_Declaration); elsif Token = Tok_Is then Set_End_Of_Line (Package_Declaration); Set_Previous_Line_Node (Package_Declaration); Set_Next_End_Node (Package_Declaration); Parse_Declarative_Items (In_Tree => In_Tree, Declarations => First_Declarative_Item, In_Zone => In_Package, First_Attribute => First_Attribute, Current_Project => Current_Project, Current_Package => Package_Declaration, Packages_To_Check => Packages_To_Check, Is_Config_File => Is_Config_File, Flags => Flags); Set_First_Declarative_Item_Of (Package_Declaration, In_Tree, To => First_Declarative_Item); Expect (Tok_End, "END"); if Token = Tok_End then -- Scan past "end" Scan (In_Tree); end if; -- We should have the name of the package after "end" Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier and then Name_Of (Package_Declaration, In_Tree) /= No_Name and then Token_Name /= Name_Of (Package_Declaration, In_Tree) then Error_Msg_Name_1 := Name_Of (Package_Declaration, In_Tree); Error_Msg (Flags, "expected %%", Token_Ptr); end if; if Token /= Tok_Semicolon then -- Scan past the package name Scan (In_Tree); end if; Expect (Tok_Semicolon, "`;`"); Remove_Next_End_Node; else Error_Msg (Flags, "expected IS", Token_Ptr); end if; end Parse_Package_Declaration; ----------------------------------- -- Parse_String_Type_Declaration -- ----------------------------------- procedure Parse_String_Type_Declaration (In_Tree : Project_Node_Tree_Ref; String_Type : out Project_Node_Id; Current_Project : Project_Node_Id; Flags : Processing_Flags) is Current : Project_Node_Id := Empty_Node; First_String : Project_Node_Id := Empty_Node; begin String_Type := Default_Project_Node (Of_Kind => N_String_Type_Declaration, In_Tree => In_Tree); Set_Location_Of (String_Type, In_Tree, To => Token_Ptr); -- Scan past "type" Scan (In_Tree); Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then Set_Name_Of (String_Type, In_Tree, To => Token_Name); Current := First_String_Type_Of (Current_Project, In_Tree); while Present (Current) and then Name_Of (Current, In_Tree) /= Token_Name loop Current := Next_String_Type (Current, In_Tree); end loop; if Present (Current) then Error_Msg (Flags, "duplicate string type name """ & Get_Name_String (Token_Name) & """", Token_Ptr); else Current := First_Variable_Of (Current_Project, In_Tree); while Present (Current) and then Name_Of (Current, In_Tree) /= Token_Name loop Current := Next_Variable (Current, In_Tree); end loop; if Present (Current) then Error_Msg (Flags, """" & Get_Name_String (Token_Name) & """ is already a variable name", Token_Ptr); else Set_Next_String_Type (String_Type, In_Tree, To => First_String_Type_Of (Current_Project, In_Tree)); Set_First_String_Type_Of (Current_Project, In_Tree, To => String_Type); end if; end if; -- Scan past the name Scan (In_Tree); end if; Expect (Tok_Is, "IS"); if Token = Tok_Is then Scan (In_Tree); end if; Expect (Tok_Left_Paren, "`(`"); if Token = Tok_Left_Paren then Scan (In_Tree); end if; Parse_String_Type_List (In_Tree => In_Tree, First_String => First_String, Flags => Flags); Set_First_Literal_String (String_Type, In_Tree, To => First_String); Expect (Tok_Right_Paren, "`)`"); if Token = Tok_Right_Paren then Scan (In_Tree); end if; end Parse_String_Type_Declaration; -------------------------------- -- Parse_Variable_Declaration -- -------------------------------- procedure Parse_Variable_Declaration (In_Tree : Project_Node_Tree_Ref; Variable : out Project_Node_Id; Current_Project : Project_Node_Id; Current_Package : Project_Node_Id; Flags : Processing_Flags) is Expression_Location : Source_Ptr; String_Type_Name : Name_Id := No_Name; Project_String_Type_Name : Name_Id := No_Name; Type_Location : Source_Ptr := No_Location; Project_Location : Source_Ptr := No_Location; Expression : Project_Node_Id := Empty_Node; Variable_Name : constant Name_Id := Token_Name; OK : Boolean := True; begin Variable := Default_Project_Node (Of_Kind => N_Variable_Declaration, In_Tree => In_Tree); Set_Name_Of (Variable, In_Tree, To => Variable_Name); Set_Location_Of (Variable, In_Tree, To => Token_Ptr); -- Scan past the variable name Scan (In_Tree); if Token = Tok_Colon then -- Typed string variable declaration Scan (In_Tree); Set_Kind_Of (Variable, In_Tree, N_Typed_Variable_Declaration); Expect (Tok_Identifier, "identifier"); OK := Token = Tok_Identifier; if OK then String_Type_Name := Token_Name; Type_Location := Token_Ptr; Scan (In_Tree); if Token = Tok_Dot then Project_String_Type_Name := String_Type_Name; Project_Location := Type_Location; -- Scan past the dot Scan (In_Tree); Expect (Tok_Identifier, "identifier"); if Token = Tok_Identifier then String_Type_Name := Token_Name; Type_Location := Token_Ptr; Scan (In_Tree); else OK := False; end if; end if; if OK then declare Proj : Project_Node_Id := Current_Project; Current : Project_Node_Id := Empty_Node; begin if Project_String_Type_Name /= No_Name then declare The_Project_Name_And_Node : constant Tree_Private_Part.Project_Name_And_Node := Tree_Private_Part.Projects_Htable.Get (In_Tree.Projects_HT, Project_String_Type_Name); use Tree_Private_Part; begin if The_Project_Name_And_Node = Tree_Private_Part.No_Project_Name_And_Node then Error_Msg (Flags, "unknown project """ & Get_Name_String (Project_String_Type_Name) & """", Project_Location); Current := Empty_Node; else Current := First_String_Type_Of (The_Project_Name_And_Node.Node, In_Tree); while Present (Current) and then Name_Of (Current, In_Tree) /= String_Type_Name loop Current := Next_String_Type (Current, In_Tree); end loop; end if; end; else -- Look for a string type with the correct name in this -- project or in any of its ancestors. loop Current := First_String_Type_Of (Proj, In_Tree); while Present (Current) and then Name_Of (Current, In_Tree) /= String_Type_Name loop Current := Next_String_Type (Current, In_Tree); end loop; exit when Present (Current); Proj := Parent_Project_Of (Proj, In_Tree); exit when No (Proj); end loop; end if; if No (Current) then Error_Msg (Flags, "unknown string type """ & Get_Name_String (String_Type_Name) & """", Type_Location); OK := False; else Set_String_Type_Of (Variable, In_Tree, To => Current); end if; end; end if; end if; end if; Expect (Tok_Colon_Equal, "`:=`"); OK := OK and then Token = Tok_Colon_Equal; if Token = Tok_Colon_Equal then Scan (In_Tree); end if; -- Get the single string or string list value Expression_Location := Token_Ptr; Parse_Expression (In_Tree => In_Tree, Expression => Expression, Flags => Flags, Current_Project => Current_Project, Current_Package => Current_Package, Optional_Index => False); Set_Expression_Of (Variable, In_Tree, To => Expression); if Present (Expression) then -- A typed string must have a single string value, not a list if Kind_Of (Variable, In_Tree) = N_Typed_Variable_Declaration and then Expression_Kind_Of (Expression, In_Tree) = List then Error_Msg (Flags, "expression must be a single string", Expression_Location); end if; Set_Expression_Kind_Of (Variable, In_Tree, To => Expression_Kind_Of (Expression, In_Tree)); end if; if OK then declare The_Variable : Project_Node_Id := Empty_Node; begin if Present (Current_Package) then The_Variable := First_Variable_Of (Current_Package, In_Tree); elsif Present (Current_Project) then The_Variable := First_Variable_Of (Current_Project, In_Tree); end if; while Present (The_Variable) and then Name_Of (The_Variable, In_Tree) /= Variable_Name loop The_Variable := Next_Variable (The_Variable, In_Tree); end loop; if No (The_Variable) then if Present (Current_Package) then Set_Next_Variable (Variable, In_Tree, To => First_Variable_Of (Current_Package, In_Tree)); Set_First_Variable_Of (Current_Package, In_Tree, To => Variable); elsif Present (Current_Project) then Set_Next_Variable (Variable, In_Tree, To => First_Variable_Of (Current_Project, In_Tree)); Set_First_Variable_Of (Current_Project, In_Tree, To => Variable); end if; else if Expression_Kind_Of (Variable, In_Tree) /= Undefined then if Expression_Kind_Of (The_Variable, In_Tree) = Undefined then Set_Expression_Kind_Of (The_Variable, In_Tree, To => Expression_Kind_Of (Variable, In_Tree)); else if Expression_Kind_Of (The_Variable, In_Tree) /= Expression_Kind_Of (Variable, In_Tree) then Error_Msg (Flags, "wrong expression kind for variable """ & Get_Name_String (Name_Of (The_Variable, In_Tree)) & """", Expression_Location); end if; end if; end if; end if; end; end if; end Parse_Variable_Declaration; end Prj.Dect; gprbuild-gpl-2014-src/gnat/mlib-tgt.ads0000644000076700001450000002771412323721731017307 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- M L I B . T G T -- -- -- -- S p e c -- -- -- -- Copyright (C) 2001-2009, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package provides a set of target dependent routines to build static, -- dynamic and shared libraries. There are several packages providing -- the actual routines. This package calls them indirectly by means of -- access-to-subprogram values. Each target-dependent package initializes -- these values in its elaboration block. with Prj; use Prj; package MLib.Tgt is function Support_For_Libraries return Library_Support; -- Indicates how building libraries by gnatmake is supported by the GNAT -- implementation for the platform. function Standalone_Library_Auto_Init_Is_Supported return Boolean; -- Indicates if when building a dynamic Standalone Library, -- automatic initialization is supported. If it is, then it is the default, -- unless attribute Library_Auto_Init has the value "false". function Archive_Builder return String; -- Returns the name of the archive builder program, usually "ar" function Archive_Builder_Options return String_List_Access; -- A list of options to invoke the Archive_Builder, usually "cr" for "ar" function Archive_Builder_Append_Options return String_List_Access; -- A list of options to use with the archive builder to append object -- files ("q", for example). function Archive_Indexer return String; -- Returns the name of the program, if any, that generates an index to the -- contents of an archive, usually "ranlib". If there is no archive indexer -- to be used, returns an empty string. function Archive_Indexer_Options return String_List_Access; -- A list of options to invoke the Archive_Indexer, usually empty function Dynamic_Option return String; -- gcc option to create a dynamic library. -- For Unix, returns "-shared", for Windows returns "-mdll". function Libgnat return String; -- System dependent static GNAT library function Archive_Ext return String; -- System dependent static library extension, without leading dot. -- For Unix and Windows, return "a". function Object_Ext return String; -- System dependent object extension, without leading dot. -- On Unix, returns "o". function DLL_Prefix return String; -- System dependent dynamic library prefix. -- On Windows, returns "". On other platforms, returns "lib". function DLL_Ext return String; -- System dependent dynamic library extension, without leading dot. -- On Windows, returns "dll". On Unix, usually returns "so", but not -- always, e.g. on HP-UX the extension for shared libraries is "sl". function PIC_Option return String; -- Position independent code option function Is_Object_Ext (Ext : String) return Boolean; -- Returns True iff Ext is an object file extension function Is_C_Ext (Ext : String) return Boolean; -- Returns True iff Ext is a C file extension function Is_Archive_Ext (Ext : String) return Boolean; -- Returns True iff Ext is an extension for a library function Default_Symbol_File_Name return String; -- Returns the name of the symbol file when Library_Symbol_File is not -- specified. Return the empty string when symbol files are not supported. procedure Build_Dynamic_Library (Ofiles : Argument_List; Options : Argument_List; Interfaces : Argument_List; Lib_Filename : String; Lib_Dir : String; Symbol_Data : Symbol_Record; Driver_Name : Name_Id := No_Name; Lib_Version : String := ""; Auto_Init : Boolean := False); -- Build a dynamic/relocatable library -- -- Ofiles is the list of all object files in the library -- -- Options is a list of options to be passed to the tool -- (gcc or other) that effectively builds the dynamic library. -- -- Interfaces is the list of ALI files for the interfaces of a SAL. -- It is empty if the library is not a SAL. -- -- Lib_Filename is the name of the library, without any prefix or -- extension. For example, on Unix, if Lib_Filename is "toto", the -- name of the library file will be "libtoto.so". -- -- Lib_Dir is the directory path where the library will be located -- -- For OSes that support symbolic links, Lib_Version, if non null, -- is the actual file name of the library. For example on Unix, if -- Lib_Filename is "toto" and Lib_Version is "libtoto.so.2.1", -- "libtoto.so" will be a symbolic link to "libtoto.so.2.1" which -- will be the actual library file. -- -- Symbol_Data is used for some platforms, including VMS, to generate -- the symbols to be exported by the library. -- -- Note: Depending on the OS, some of the parameters may not be taken into -- account. For example, on Linux, Interfaces, Symbol_Data and Auto_Init -- are ignored. function Library_Exists_For (Project : Project_Id; In_Tree : Project_Tree_Ref) return Boolean; -- Return True if the library file for a library project already exists. -- This function can only be called for library projects. function Library_File_Name_For (Project : Project_Id; In_Tree : Project_Tree_Ref) return File_Name_Type; -- Returns the file name of the library file of a library project. -- This function can only be called for library projects. function Library_Major_Minor_Id_Supported return Boolean; -- Indicates if major and minor ids are supported for libraries. -- If they are supported, then a Library_Version such as libtoto.so.1.2 -- will have a major id of 1 and a minor id of 2. Then libtoto.so, -- libtoto.so.1 and libtoto.so.1.2 will be created, all three designating -- the same file. private No_Argument_List : constant Argument_List := (1 .. 0 => null); -- Access to subprogram types for indirection type String_Function is access function return String; type Is_Ext_Function is access function (Ext : String) return Boolean; type String_List_Access_Function is access function return String_List_Access; type Build_Dynamic_Library_Function is access procedure (Ofiles : Argument_List; Options : Argument_List; Interfaces : Argument_List; Lib_Filename : String; Lib_Dir : String; Symbol_Data : Symbol_Record; Driver_Name : Name_Id := No_Name; Lib_Version : String := ""; Auto_Init : Boolean := False); type Library_Exists_For_Function is access function (Project : Project_Id; In_Tree : Project_Tree_Ref) return Boolean; type Library_File_Name_For_Function is access function (Project : Project_Id; In_Tree : Project_Tree_Ref) return File_Name_Type; type Boolean_Function is access function return Boolean; type Library_Support_Function is access function return Library_Support; function Archive_Builder_Default return String; Archive_Builder_Ptr : String_Function := Archive_Builder_Default'Access; function Archive_Builder_Options_Default return String_List_Access; Archive_Builder_Options_Ptr : String_List_Access_Function := Archive_Builder_Options_Default'Access; function Archive_Builder_Append_Options_Default return String_List_Access; Archive_Builder_Append_Options_Ptr : String_List_Access_Function := Archive_Builder_Append_Options_Default'Access; function Archive_Ext_Default return String; Archive_Ext_Ptr : String_Function := Archive_Ext_Default'Access; function Archive_Indexer_Default return String; Archive_Indexer_Ptr : String_Function := Archive_Indexer_Default'Access; function Archive_Indexer_Options_Default return String_List_Access; Archive_Indexer_Options_Ptr : String_List_Access_Function := Archive_Indexer_Options_Default'Access; function Default_Symbol_File_Name_Default return String; Default_Symbol_File_Name_Ptr : String_Function := Default_Symbol_File_Name_Default'Access; Build_Dynamic_Library_Ptr : Build_Dynamic_Library_Function; function DLL_Ext_Default return String; DLL_Ext_Ptr : String_Function := DLL_Ext_Default'Access; function DLL_Prefix_Default return String; DLL_Prefix_Ptr : String_Function := DLL_Prefix_Default'Access; function Dynamic_Option_Default return String; Dynamic_Option_Ptr : String_Function := Dynamic_Option_Default'Access; function Is_Object_Ext_Default (Ext : String) return Boolean; Is_Object_Ext_Ptr : Is_Ext_Function := Is_Object_Ext_Default'Access; function Is_C_Ext_Default (Ext : String) return Boolean; Is_C_Ext_Ptr : Is_Ext_Function := Is_C_Ext_Default'Access; function Is_Archive_Ext_Default (Ext : String) return Boolean; Is_Archive_Ext_Ptr : Is_Ext_Function := Is_Archive_Ext_Default'Access; function Libgnat_Default return String; Libgnat_Ptr : String_Function := Libgnat_Default'Access; function Library_Exists_For_Default (Project : Project_Id; In_Tree : Project_Tree_Ref) return Boolean; Library_Exists_For_Ptr : Library_Exists_For_Function := Library_Exists_For_Default'Access; function Library_File_Name_For_Default (Project : Project_Id; In_Tree : Project_Tree_Ref) return File_Name_Type; Library_File_Name_For_Ptr : Library_File_Name_For_Function := Library_File_Name_For_Default'Access; function Object_Ext_Default return String; Object_Ext_Ptr : String_Function := Object_Ext_Default'Access; function PIC_Option_Default return String; PIC_Option_Ptr : String_Function := PIC_Option_Default'Access; function Standalone_Library_Auto_Init_Is_Supported_Default return Boolean; Standalone_Library_Auto_Init_Is_Supported_Ptr : Boolean_Function := Standalone_Library_Auto_Init_Is_Supported_Default'Access; function Support_For_Libraries_Default return Library_Support; Support_For_Libraries_Ptr : Library_Support_Function := Support_For_Libraries_Default'Access; function Library_Major_Minor_Id_Supported_Default return Boolean; Library_Major_Minor_Id_Supported_Ptr : Boolean_Function := Library_Major_Minor_Id_Supported_Default'Access; end MLib.Tgt; gprbuild-gpl-2014-src/gnat/prj-ext.adb0000644000076700001450000002162212323721731017130 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- P R J . E X T -- -- -- -- B o d y -- -- -- -- Copyright (C) 2000-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Osint; use Osint; with Ada.Unchecked_Deallocation; package body Prj.Ext is ---------------- -- Initialize -- ---------------- procedure Initialize (Self : out External_References; Copy_From : External_References := No_External_Refs) is N : Name_To_Name_Ptr; N2 : Name_To_Name_Ptr; begin if Self.Refs = null then Self.Refs := new Name_To_Name_HTable.Instance; if Copy_From.Refs /= null then N := Name_To_Name_HTable.Get_First (Copy_From.Refs.all); while N /= null loop N2 := new Name_To_Name' (Key => N.Key, Value => N.Value, Source => N.Source, Next => null); Name_To_Name_HTable.Set (Self.Refs.all, N2); N := Name_To_Name_HTable.Get_Next (Copy_From.Refs.all); end loop; end if; end if; end Initialize; --------- -- Add -- --------- procedure Add (Self : External_References; External_Name : String; Value : String; Source : External_Source := External_Source'First; Silent : Boolean := False) is Key : Name_Id; N : Name_To_Name_Ptr; begin -- For external attribute, set the environment variable if Source = From_External_Attribute and then External_Name /= "" then declare Env_Var : String_Access := Getenv (External_Name); begin if Env_Var = null or else Env_Var.all = "" then Setenv (Name => External_Name, Value => Value); if not Silent then Debug_Output ("Environment variable """ & External_Name & """ = """ & Value & '"'); end if; elsif not Silent then Debug_Output ("Not overriding existing environment variable """ & External_Name & """, value is """ & Env_Var.all & '"'); end if; Free (Env_Var); end; end if; Name_Len := External_Name'Length; Name_Buffer (1 .. Name_Len) := External_Name; Canonical_Case_Env_Var_Name (Name_Buffer (1 .. Name_Len)); Key := Name_Find; -- Check whether the value is already defined, to properly respect the -- overriding order. if Source /= External_Source'First then N := Name_To_Name_HTable.Get (Self.Refs.all, Key); if N /= null then if External_Source'Pos (N.Source) < External_Source'Pos (Source) then if not Silent then Debug_Output ("Not overridding existing external reference '" & External_Name & "', value was defined in " & N.Source'Img); end if; return; end if; end if; end if; Name_Len := Value'Length; Name_Buffer (1 .. Name_Len) := Value; N := new Name_To_Name' (Key => Key, Source => Source, Value => Name_Find, Next => null); if not Silent then Debug_Output ("Add external (" & External_Name & ") is", N.Value); end if; Name_To_Name_HTable.Set (Self.Refs.all, N); end Add; ----------- -- Check -- ----------- function Check (Self : External_References; Declaration : String) return Boolean is begin for Equal_Pos in Declaration'Range loop if Declaration (Equal_Pos) = '=' then exit when Equal_Pos = Declaration'First; Add (Self => Self, External_Name => Declaration (Declaration'First .. Equal_Pos - 1), Value => Declaration (Equal_Pos + 1 .. Declaration'Last), Source => From_Command_Line); return True; end if; end loop; return False; end Check; ----------- -- Reset -- ----------- procedure Reset (Self : External_References) is begin if Self.Refs /= null then Debug_Output ("Reset external references"); Name_To_Name_HTable.Reset (Self.Refs.all); end if; end Reset; -------------- -- Value_Of -- -------------- function Value_Of (Self : External_References; External_Name : Name_Id; With_Default : Name_Id := No_Name) return Name_Id is Value : Name_To_Name_Ptr; Val : Name_Id; Name : String := Get_Name_String (External_Name); begin Canonical_Case_Env_Var_Name (Name); if Self.Refs /= null then Name_Len := Name'Length; Name_Buffer (1 .. Name_Len) := Name; Value := Name_To_Name_HTable.Get (Self.Refs.all, Name_Find); if Value /= null then Debug_Output ("Value_Of (" & Name & ") is in cache", Value.Value); return Value.Value; end if; end if; -- Find if it is an environment, if it is, put value in the hash table declare Env_Value : String_Access := Getenv (Name); begin if Env_Value /= null and then Env_Value'Length > 0 then Name_Len := Env_Value'Length; Name_Buffer (1 .. Name_Len) := Env_Value.all; Val := Name_Find; if Current_Verbosity = High then Debug_Output ("Value_Of (" & Name & ") is", Val); end if; if Self.Refs /= null then Value := new Name_To_Name' (Key => External_Name, Value => Val, Source => From_Environment, Next => null); Name_To_Name_HTable.Set (Self.Refs.all, Value); end if; Free (Env_Value); return Val; else if Current_Verbosity = High then Debug_Output ("Value_Of (" & Name & ") is default", With_Default); end if; Free (Env_Value); return With_Default; end if; end; end Value_Of; ---------- -- Free -- ---------- procedure Free (Self : in out External_References) is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Name_To_Name_HTable.Instance, Instance_Access); begin if Self.Refs /= null then Reset (Self); Unchecked_Free (Self.Refs); end if; end Free; -------------- -- Set_Next -- -------------- procedure Set_Next (E : Name_To_Name_Ptr; Next : Name_To_Name_Ptr) is begin E.Next := Next; end Set_Next; ---------- -- Next -- ---------- function Next (E : Name_To_Name_Ptr) return Name_To_Name_Ptr is begin return E.Next; end Next; ------------- -- Get_Key -- ------------- function Get_Key (E : Name_To_Name_Ptr) return Name_Id is begin return E.Key; end Get_Key; end Prj.Ext; gprbuild-gpl-2014-src/gnat/mlib-fil.adb0000644000076700001450000001065412323721731017235 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- M L I B . F I L -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2007, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package provides a set of routines to deal with file extensions with Ada.Strings.Fixed; with MLib.Tgt; package body MLib.Fil is use Ada; package Target renames MLib.Tgt; --------------- -- Append_To -- --------------- function Append_To (Filename : String; Ext : String) return String is begin if Ext'Length = 0 then return Filename; elsif Filename (Filename'Last) = '.' then if Ext (Ext'First) = '.' then return Filename & Ext (Ext'First + 1 .. Ext'Last); else return Filename & Ext; end if; else if Ext (Ext'First) = '.' then return Filename & Ext; else return Filename & '.' & Ext; end if; end if; end Append_To; ------------ -- Ext_To -- ------------ function Ext_To (Filename : String; New_Ext : String := "") return String is use Strings.Fixed; J : constant Natural := Index (Source => Filename, Pattern => ".", Going => Strings.Backward); begin if J = 0 then if New_Ext = "" then return Filename; else return Filename & "." & New_Ext; end if; else if New_Ext = "" then return Head (Filename, J - 1); else return Head (Filename, J - 1) & '.' & New_Ext; end if; end if; end Ext_To; ------------- -- Get_Ext -- ------------- function Get_Ext (Filename : String) return String is use Strings.Fixed; J : constant Natural := Index (Source => Filename, Pattern => ".", Going => Strings.Backward); begin if J = 0 then return ""; else return Filename (J .. Filename'Last); end if; end Get_Ext; ---------------- -- Is_Archive -- ---------------- function Is_Archive (Filename : String) return Boolean is Ext : constant String := Get_Ext (Filename); begin return Target.Is_Archive_Ext (Ext); end Is_Archive; ---------- -- Is_C -- ---------- function Is_C (Filename : String) return Boolean is Ext : constant String := Get_Ext (Filename); begin return Target.Is_C_Ext (Ext); end Is_C; ------------ -- Is_Obj -- ------------ function Is_Obj (Filename : String) return Boolean is Ext : constant String := Get_Ext (Filename); begin return Target.Is_Object_Ext (Ext); end Is_Obj; end MLib.Fil; gprbuild-gpl-2014-src/gnat/binderr.adb0000644000076700001450000001575512323721731017176 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- B I N D E R R -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2008, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Butil; use Butil; with Opt; use Opt; with Output; use Output; package body Binderr is --------------- -- Error_Msg -- --------------- procedure Error_Msg (Msg : String) is begin if Msg (Msg'First) = '?' then if Warning_Mode = Suppress then return; end if; if Warning_Mode = Treat_As_Error then Errors_Detected := Errors_Detected + 1; else Warnings_Detected := Warnings_Detected + 1; end if; else Errors_Detected := Errors_Detected + 1; end if; if Brief_Output or else (not Verbose_Mode) then Set_Standard_Error; Error_Msg_Output (Msg, Info => False); Set_Standard_Output; end if; if Verbose_Mode then if Errors_Detected + Warnings_Detected = 0 then Write_Eol; end if; Error_Msg_Output (Msg, Info => False); end if; -- If too many warnings print message and then turn off warnings if Warnings_Detected = Maximum_Messages then Set_Standard_Error; Write_Line ("maximum number of warnings reached"); Write_Line ("further warnings will be suppressed"); Set_Standard_Output; Warning_Mode := Suppress; end if; -- If too many errors print message and give fatal error if Errors_Detected = Maximum_Messages then Set_Standard_Error; Write_Line ("fatal error: maximum number of errors exceeded"); Set_Standard_Output; raise Unrecoverable_Error; end if; end Error_Msg; -------------------- -- Error_Msg_Info -- -------------------- procedure Error_Msg_Info (Msg : String) is begin if Brief_Output or else (not Verbose_Mode) then Set_Standard_Error; Error_Msg_Output (Msg, Info => True); Set_Standard_Output; end if; if Verbose_Mode then Error_Msg_Output (Msg, Info => True); end if; end Error_Msg_Info; ---------------------- -- Error_Msg_Output -- ---------------------- procedure Error_Msg_Output (Msg : String; Info : Boolean) is Use_Second_File : Boolean := False; Use_Second_Unit : Boolean := False; Use_Second_Nat : Boolean := False; Warning : Boolean := False; begin if Warnings_Detected + Errors_Detected > Maximum_Messages then Write_Str ("error: maximum errors exceeded"); Write_Eol; return; end if; -- First, check for warnings for J in Msg'Range loop if Msg (J) = '?' then Warning := True; exit; end if; end loop; if Warning then Write_Str ("warning: "); elsif Info then if not Info_Prefix_Suppress then Write_Str ("info: "); end if; else Write_Str ("error: "); end if; for J in Msg'Range loop if Msg (J) = '%' then Get_Name_String (Error_Msg_Name_1); Write_Char ('"'); Write_Str (Name_Buffer (1 .. Name_Len)); Write_Char ('"'); elsif Msg (J) = '{' then if Use_Second_File then Get_Name_String (Error_Msg_File_2); else Use_Second_File := True; Get_Name_String (Error_Msg_File_1); end if; Write_Char ('"'); Write_Str (Name_Buffer (1 .. Name_Len)); Write_Char ('"'); elsif Msg (J) = '$' then Write_Char ('"'); if Use_Second_Unit then Write_Unit_Name (Error_Msg_Unit_2); else Use_Second_Unit := True; Write_Unit_Name (Error_Msg_Unit_1); end if; Write_Char ('"'); elsif Msg (J) = '#' then if Use_Second_Nat then Write_Int (Error_Msg_Nat_2); else Use_Second_Nat := True; Write_Int (Error_Msg_Nat_1); end if; elsif Msg (J) /= '?' then Write_Char (Msg (J)); end if; end loop; Write_Eol; end Error_Msg_Output; ---------------------- -- Finalize_Binderr -- ---------------------- procedure Finalize_Binderr is begin -- Message giving number of errors detected (verbose mode only) if Verbose_Mode then Write_Eol; if Errors_Detected = 0 then Write_Str ("No errors"); elsif Errors_Detected = 1 then Write_Str ("1 error"); else Write_Int (Errors_Detected); Write_Str (" errors"); end if; if Warnings_Detected = 1 then Write_Str (", 1 warning"); elsif Warnings_Detected > 1 then Write_Str (", "); Write_Int (Warnings_Detected); Write_Str (" warnings"); end if; Write_Eol; end if; end Finalize_Binderr; ------------------------ -- Initialize_Binderr -- ------------------------ procedure Initialize_Binderr is begin Errors_Detected := 0; Warnings_Detected := 0; end Initialize_Binderr; end Binderr; gprbuild-gpl-2014-src/gnat/mlib.adb0000644000076700001450000003650512323721731016470 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- M L I B -- -- -- -- B o d y -- -- -- -- Copyright (C) 1999-2009, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Ada.Characters.Handling; use Ada.Characters.Handling; with Interfaces.C.Strings; with System; with Hostparm; with Opt; with Output; use Output; with MLib.Utl; use MLib.Utl; with Prj.Com; with GNAT.Directory_Operations; use GNAT.Directory_Operations; package body MLib is ------------------- -- Build_Library -- ------------------- procedure Build_Library (Ofiles : Argument_List; Output_File : String; Output_Dir : String) is begin if Opt.Verbose_Mode and not Opt.Quiet_Output then Write_Line ("building a library..."); Write_Str (" make "); Write_Line (Output_File); end if; Ar (Output_Dir & "lib" & Output_File & ".a", Objects => Ofiles); end Build_Library; ------------------------ -- Check_Library_Name -- ------------------------ procedure Check_Library_Name (Name : String) is begin if Name'Length = 0 then Prj.Com.Fail ("library name cannot be empty"); end if; if Name'Length > Max_Characters_In_Library_Name then Prj.Com.Fail ("illegal library name """ & Name & """: too long"); end if; if not Is_Letter (Name (Name'First)) then Prj.Com.Fail ("illegal library name """ & Name & """: should start with a letter"); end if; for Index in Name'Range loop if not Is_Alphanumeric (Name (Index)) then Prj.Com.Fail ("illegal library name """ & Name & """: should include only letters and digits"); end if; end loop; end Check_Library_Name; -------------------- -- Copy_ALI_Files -- -------------------- procedure Copy_ALI_Files (Files : Argument_List; To : Path_Name_Type; Interfaces : String_List) is Success : Boolean := False; To_Dir : constant String := Get_Name_String (To); Is_Interface : Boolean := False; procedure Verbose_Copy (Index : Positive); -- In verbose mode, output a message that the indexed file is copied -- to the destination directory. ------------------ -- Verbose_Copy -- ------------------ procedure Verbose_Copy (Index : Positive) is begin if Opt.Verbose_Mode then Write_Str ("Copying """); Write_Str (Files (Index).all); Write_Str (""" to """); Write_Str (To_Dir); Write_Line (""""); end if; end Verbose_Copy; -- Start of processing for Copy_ALI_Files begin if Interfaces'Length = 0 then -- If there are no Interfaces, copy all the ALI files as is for Index in Files'Range loop Verbose_Copy (Index); Set_Writable (To_Dir & Directory_Separator & Base_Name (Files (Index).all)); Copy_File (Files (Index).all, To_Dir, Success, Mode => Overwrite, Preserve => Preserve); exit when not Success; end loop; else -- Copy only the interface ALI file, and put the special indicator -- "SL" on the P line. for Index in Files'Range loop declare File_Name : String := Base_Name (Files (Index).all); begin Canonical_Case_File_Name (File_Name); -- Check if this is one of the interface ALIs Is_Interface := False; for Index in Interfaces'Range loop if File_Name = Interfaces (Index).all then Is_Interface := True; exit; end if; end loop; -- If it is an interface ALI, copy line by line. Insert -- the interface indication at the end of the P line. -- Do not copy ALI files that are not Interfaces. if Is_Interface then Success := False; Verbose_Copy (Index); Set_Writable (To_Dir & Directory_Separator & Base_Name (Files (Index).all)); declare FD : File_Descriptor; Len : Integer; Actual_Len : Integer; S : String_Access; Curr : Natural; P_Line_Found : Boolean; Status : Boolean; begin -- Open the file Name_Len := Files (Index)'Length; Name_Buffer (1 .. Name_Len) := Files (Index).all; Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := ASCII.NUL; FD := Open_Read (Name_Buffer'Address, Binary); if FD /= Invalid_FD then Len := Integer (File_Length (FD)); -- ??? Why "+3" here S := new String (1 .. Len + 3); -- Read the file. Note that the loop is not necessary -- since the whole file is read at once except on VMS. Curr := S'First; while Curr <= Len loop Actual_Len := Read (FD, S (Curr)'Address, Len); -- Exit if we could not read for some reason exit when Actual_Len = 0; Curr := Curr + Actual_Len; end loop; -- We are done with the input file, so we close it -- ignoring any bad status. Close (FD, Status); P_Line_Found := False; -- Look for the P line. When found, add marker SL -- at the beginning of the P line. for Index in 1 .. Len - 3 loop if (S (Index) = ASCII.LF or else S (Index) = ASCII.CR) and then S (Index + 1) = 'P' then S (Index + 5 .. Len + 3) := S (Index + 2 .. Len); S (Index + 2 .. Index + 4) := " SL"; P_Line_Found := True; exit; end if; end loop; if P_Line_Found then -- Create new modified ALI file Name_Len := To_Dir'Length; Name_Buffer (1 .. Name_Len) := To_Dir; Name_Len := Name_Len + 1; Name_Buffer (Name_Len) := Directory_Separator; Name_Buffer (Name_Len + 1 .. Name_Len + File_Name'Length) := File_Name; Name_Len := Name_Len + File_Name'Length + 1; Name_Buffer (Name_Len) := ASCII.NUL; FD := Create_File (Name_Buffer'Address, Binary); -- Write the modified text and close the newly -- created file. if FD /= Invalid_FD then Actual_Len := Write (FD, S (1)'Address, Len + 3); Close (FD, Status); -- Set Success to True only if the newly -- created file has been correctly written. Success := Status and then Actual_Len = Len + 3; if Success then -- Set_Read_Only is used here, rather than -- Set_Non_Writable, so that gprbuild can -- he compiled with older compilers. Set_Read_Only (Name_Buffer (1 .. Name_Len - 1)); end if; end if; end if; end if; end; -- This is not an interface ALI else Success := True; end if; end; if not Success then Prj.Com.Fail ("could not copy ALI files to library dir"); end if; end loop; end if; end Copy_ALI_Files; ---------------------- -- Create_Sym_Links -- ---------------------- procedure Create_Sym_Links (Lib_Path : String; Lib_Version : String; Lib_Dir : String; Maj_Version : String) is function Symlink (Oldpath : System.Address; Newpath : System.Address) return Integer; pragma Import (C, Symlink, "__gnat_symlink"); Version_Path : String_Access; Success : Boolean; Result : Integer; pragma Unreferenced (Success, Result); begin Version_Path := new String (1 .. Lib_Version'Length + 1); Version_Path (1 .. Lib_Version'Length) := Lib_Version; Version_Path (Version_Path'Last) := ASCII.NUL; if Maj_Version'Length = 0 then declare Newpath : String (1 .. Lib_Path'Length + 1); begin Newpath (1 .. Lib_Path'Length) := Lib_Path; Newpath (Newpath'Last) := ASCII.NUL; Delete_File (Lib_Path, Success); Result := Symlink (Version_Path (1)'Address, Newpath'Address); end; else declare Newpath1 : String (1 .. Lib_Path'Length + 1); Maj_Path : constant String := Lib_Dir & Directory_Separator & Maj_Version; Newpath2 : String (1 .. Maj_Path'Length + 1); Maj_Ver : String (1 .. Maj_Version'Length + 1); begin Newpath1 (1 .. Lib_Path'Length) := Lib_Path; Newpath1 (Newpath1'Last) := ASCII.NUL; Newpath2 (1 .. Maj_Path'Length) := Maj_Path; Newpath2 (Newpath2'Last) := ASCII.NUL; Maj_Ver (1 .. Maj_Version'Length) := Maj_Version; Maj_Ver (Maj_Ver'Last) := ASCII.NUL; Delete_File (Maj_Path, Success); Result := Symlink (Version_Path (1)'Address, Newpath2'Address); Delete_File (Lib_Path, Success); Result := Symlink (Maj_Ver'Address, Newpath1'Address); end; end if; end Create_Sym_Links; -------------------------------- -- Linker_Library_Path_Option -- -------------------------------- function Linker_Library_Path_Option return String_Access is Run_Path_Option_Ptr : Interfaces.C.Strings.chars_ptr; pragma Import (C, Run_Path_Option_Ptr, "__gnat_run_path_option"); -- Pointer to string representing the native linker option which -- specifies the path where the dynamic loader should find shared -- libraries. Equal to null string if this system doesn't support it. S : constant String := Interfaces.C.Strings.Value (Run_Path_Option_Ptr); begin if S'Length = 0 then return null; else return new String'(S); end if; end Linker_Library_Path_Option; ------------------- -- Major_Id_Name -- ------------------- function Major_Id_Name (Lib_Filename : String; Lib_Version : String) return String is Maj_Version : constant String := Lib_Version; Last_Maj : Positive; Last : Positive; Ok_Maj : Boolean := False; begin Last_Maj := Maj_Version'Last; while Last_Maj > Maj_Version'First loop if Maj_Version (Last_Maj) in '0' .. '9' then Last_Maj := Last_Maj - 1; else Ok_Maj := Last_Maj /= Maj_Version'Last and then Maj_Version (Last_Maj) = '.'; if Ok_Maj then Last_Maj := Last_Maj - 1; end if; exit; end if; end loop; if Ok_Maj then Last := Last_Maj; while Last > Maj_Version'First loop if Maj_Version (Last) in '0' .. '9' then Last := Last - 1; else Ok_Maj := Last /= Last_Maj and then Maj_Version (Last) = '.'; if Ok_Maj then Last := Last - 1; Ok_Maj := Maj_Version (Maj_Version'First .. Last) = Lib_Filename; end if; exit; end if; end loop; end if; if Ok_Maj then return Maj_Version (Maj_Version'First .. Last_Maj); else return ""; end if; end Major_Id_Name; ------------------------------- -- Separate_Run_Path_Options -- ------------------------------- function Separate_Run_Path_Options return Boolean is Separate_Paths : Boolean; for Separate_Paths'Size use Character'Size; pragma Import (C, Separate_Paths, "__gnat_separate_run_path_options"); begin return Separate_Paths; end Separate_Run_Path_Options; -- Package elaboration begin -- Copy_Attributes always fails on VMS if Hostparm.OpenVMS then Preserve := None; end if; end MLib; gprbuild-gpl-2014-src/gnat/targparm.adb0000644000076700001450000006530712323721731017364 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT RUN-TIME COMPONENTS -- -- -- -- T A R G P A R M -- -- -- -- B o d y -- -- -- -- Copyright (C) 1999-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Csets; use Csets; with Opt; use Opt; with Osint; use Osint; with Output; use Output; package body Targparm is use ASCII; Parameters_Obtained : Boolean := False; -- Set True after first call to Get_Target_Parameters. Used to avoid -- reading system.ads more than once, since it cannot change. -- The following array defines a tag name for each entry type Targparm_Tags is (AAM, -- AAMP ACR, -- Always_Compatible_Rep ASD, -- Atomic_Sync_Default BDC, -- Backend_Divide_Checks BOC, -- Backend_Overflow_Checks CLA, -- Command_Line_Args CLI, -- CLI (.NET) CRT, -- Configurable_Run_Times D32, -- Duration_32_Bits DEN, -- Denorm EXS, -- Exit_Status_Supported FEL, -- Frontend_Layout FFO, -- Fractional_Fixed_Ops JVM, -- JVM MOV, -- Machine_Overflows MRN, -- Machine_Rounds PAS, -- Preallocated_Stacks RTX, -- RTX_RTSS_Kernel_Module SAG, -- Support_Aggregates SAP, -- Support_Atomic_Primitives SCA, -- Support_Composite_Assign SCC, -- Support_Composite_Compare SCD, -- Stack_Check_Default SCL, -- Stack_Check_Limits SCP, -- Stack_Check_Probes SLS, -- Support_Long_Shifts SNZ, -- Signed_Zeros SSL, -- Suppress_Standard_Library UAM, -- Use_Ada_Main_Program_Name VMS, -- OpenVMS VXF, -- VAX Float ZCD); -- ZCX_By_Default Targparm_Flags : array (Targparm_Tags) of Boolean := (others => False); -- Flag is set True if corresponding parameter is scanned -- The following list of string constants gives the parameter names AAM_Str : aliased constant Source_Buffer := "AAMP"; ACR_Str : aliased constant Source_Buffer := "Always_Compatible_Rep"; ASD_Str : aliased constant Source_Buffer := "Atomic_Sync_Default"; BDC_Str : aliased constant Source_Buffer := "Backend_Divide_Checks"; BOC_Str : aliased constant Source_Buffer := "Backend_Overflow_Checks"; CLA_Str : aliased constant Source_Buffer := "Command_Line_Args"; CLI_Str : aliased constant Source_Buffer := "CLI"; CRT_Str : aliased constant Source_Buffer := "Configurable_Run_Time"; D32_Str : aliased constant Source_Buffer := "Duration_32_Bits"; DEN_Str : aliased constant Source_Buffer := "Denorm"; EXS_Str : aliased constant Source_Buffer := "Exit_Status_Supported"; FEL_Str : aliased constant Source_Buffer := "Frontend_Layout"; FFO_Str : aliased constant Source_Buffer := "Fractional_Fixed_Ops"; JVM_Str : aliased constant Source_Buffer := "JVM"; MOV_Str : aliased constant Source_Buffer := "Machine_Overflows"; MRN_Str : aliased constant Source_Buffer := "Machine_Rounds"; PAS_Str : aliased constant Source_Buffer := "Preallocated_Stacks"; RTX_Str : aliased constant Source_Buffer := "RTX_RTSS_Kernel_Module"; SAG_Str : aliased constant Source_Buffer := "Support_Aggregates"; SAP_Str : aliased constant Source_Buffer := "Support_Atomic_Primitives"; SCA_Str : aliased constant Source_Buffer := "Support_Composite_Assign"; SCC_Str : aliased constant Source_Buffer := "Support_Composite_Compare"; SCD_Str : aliased constant Source_Buffer := "Stack_Check_Default"; SCL_Str : aliased constant Source_Buffer := "Stack_Check_Limits"; SCP_Str : aliased constant Source_Buffer := "Stack_Check_Probes"; SLS_Str : aliased constant Source_Buffer := "Support_Long_Shifts"; SNZ_Str : aliased constant Source_Buffer := "Signed_Zeros"; SSL_Str : aliased constant Source_Buffer := "Suppress_Standard_Library"; UAM_Str : aliased constant Source_Buffer := "Use_Ada_Main_Program_Name"; VMS_Str : aliased constant Source_Buffer := "OpenVMS"; VXF_Str : aliased constant Source_Buffer := "VAX_Float"; ZCD_Str : aliased constant Source_Buffer := "ZCX_By_Default"; -- The following defines a set of pointers to the above strings, -- indexed by the tag values. type Buffer_Ptr is access constant Source_Buffer; Targparm_Str : constant array (Targparm_Tags) of Buffer_Ptr := (AAM_Str'Access, ACR_Str'Access, ASD_Str'Access, BDC_Str'Access, BOC_Str'Access, CLA_Str'Access, CLI_Str'Access, CRT_Str'Access, D32_Str'Access, DEN_Str'Access, EXS_Str'Access, FEL_Str'Access, FFO_Str'Access, JVM_Str'Access, MOV_Str'Access, MRN_Str'Access, PAS_Str'Access, RTX_Str'Access, SAG_Str'Access, SAP_Str'Access, SCA_Str'Access, SCC_Str'Access, SCD_Str'Access, SCL_Str'Access, SCP_Str'Access, SLS_Str'Access, SNZ_Str'Access, SSL_Str'Access, UAM_Str'Access, VMS_Str'Access, VXF_Str'Access, ZCD_Str'Access); ----------------------- -- Local Subprograms -- ----------------------- procedure Set_Profile_Restrictions (P : Profile_Name); -- Set Restrictions_On_Target for the given profile --------------------------- -- Get_Target_Parameters -- --------------------------- -- Version which reads in system.ads procedure Get_Target_Parameters (Make_Id : Make_Id_Type := null; Make_SC : Make_SC_Type := null; Set_RND : Set_RND_Type := null) is Text : Source_Buffer_Ptr; Hi : Source_Ptr; begin if Parameters_Obtained then return; end if; Name_Buffer (1 .. 10) := "system.ads"; Name_Len := 10; Read_Source_File (Name_Find, Lo => 0, Hi => Hi, Src => Text); if Text = null then Write_Line ("fatal error, run-time library not installed correctly"); Write_Line ("cannot locate file system.ads"); raise Unrecoverable_Error; end if; Get_Target_Parameters (System_Text => Text, Source_First => 0, Source_Last => Hi, Make_Id => Make_Id, Make_SC => Make_SC, Set_RND => Set_RND); end Get_Target_Parameters; -- Version where caller supplies system.ads text procedure Get_Target_Parameters (System_Text : Source_Buffer_Ptr; Source_First : Source_Ptr; Source_Last : Source_Ptr; Make_Id : Make_Id_Type := null; Make_SC : Make_SC_Type := null; Set_RND : Set_RND_Type := null) is P : Source_Ptr; -- Scans source buffer containing source of system.ads Fatal : Boolean := False; -- Set True if a fatal error is detected Result : Boolean; -- Records boolean from system line begin if Parameters_Obtained then return; else Parameters_Obtained := True; end if; Opt.Address_Is_Private := False; P := Source_First; Line_Loop : while System_Text (P .. P + 10) /= "end System;" loop -- Skip comments quickly if System_Text (P) = '-' then goto Line_Loop_Continue; -- Test for type Address is private elsif System_Text (P .. P + 26) = " type Address is private;" then Opt.Address_Is_Private := True; P := P + 26; goto Line_Loop_Continue; -- Test for pragma Profile (Ravenscar); elsif System_Text (P .. P + 26) = "pragma Profile (Ravenscar);" then Set_Profile_Restrictions (Ravenscar); Opt.Task_Dispatching_Policy := 'F'; Opt.Locking_Policy := 'C'; P := P + 27; goto Line_Loop_Continue; -- Test for pragma Profile (Restricted); elsif System_Text (P .. P + 27) = "pragma Profile (Restricted);" then Set_Profile_Restrictions (Restricted); P := P + 28; goto Line_Loop_Continue; -- Test for pragma Restrictions elsif System_Text (P .. P + 20) = "pragma Restrictions (" then P := P + 21; Rloop : for K in All_Boolean_Restrictions loop declare Rname : constant String := Restriction_Id'Image (K); begin for J in Rname'Range loop if Fold_Upper (System_Text (P + Source_Ptr (J - 1))) /= Rname (J) then goto Rloop_Continue; end if; end loop; if System_Text (P + Rname'Length) = ')' then Restrictions_On_Target.Set (K) := True; goto Line_Loop_Continue; end if; end; <> null; end loop Rloop; Ploop : for K in All_Parameter_Restrictions loop declare Rname : constant String := All_Parameter_Restrictions'Image (K); V : Natural; -- Accumulates value begin for J in Rname'Range loop if Fold_Upper (System_Text (P + Source_Ptr (J - 1))) /= Rname (J) then goto Ploop_Continue; end if; end loop; if System_Text (P + Rname'Length .. P + Rname'Length + 3) = " => " then P := P + Rname'Length + 4; V := 0; loop if System_Text (P) in '0' .. '9' then declare pragma Unsuppress (Overflow_Check); begin -- Accumulate next digit V := 10 * V + Character'Pos (System_Text (P)) - Character'Pos ('0'); exception -- On overflow, we just ignore the pragma since -- that is the standard handling in this case. when Constraint_Error => goto Line_Loop_Continue; end; elsif System_Text (P) = '_' then null; elsif System_Text (P) = ')' then Restrictions_On_Target.Value (K) := V; Restrictions_On_Target.Set (K) := True; goto Line_Loop_Continue; else exit Ploop; end if; P := P + 1; end loop; else exit Ploop; end if; end; <> null; end loop Ploop; -- No_Dependence case if System_Text (P .. P + 16) = "No_Dependence => " then P := P + 17; -- Skip this processing (and simply ignore No_Dependence lines) -- if caller did not supply the three subprograms we need to -- process these lines. if Make_Id = null then goto Line_Loop_Continue; end if; -- We have scanned out "pragma Restrictions (No_Dependence =>" declare Unit : Node_Id; Id : Node_Id; Start : Source_Ptr; begin Unit := Empty; -- Loop through components of name, building up Unit loop Start := P; while System_Text (P) /= '.' and then System_Text (P) /= ')' loop P := P + 1; end loop; Id := Make_Id (System_Text (Start .. P - 1)); -- If first name, just capture the identifier if Unit = Empty then Unit := Id; else Unit := Make_SC (Unit, Id); end if; exit when System_Text (P) = ')'; P := P + 1; end loop; Set_RND (Unit); goto Line_Loop_Continue; end; end if; -- Here if unrecognizable restrictions pragma form Set_Standard_Error; Write_Line ("fatal error: system.ads is incorrectly formatted"); Write_Str ("unrecognized or incorrect restrictions pragma: "); while System_Text (P) /= ')' and then System_Text (P) /= ASCII.LF loop Write_Char (System_Text (P)); P := P + 1; end loop; Write_Eol; Fatal := True; Set_Standard_Output; -- Test for pragma Detect_Blocking; elsif System_Text (P .. P + 22) = "pragma Detect_Blocking;" then P := P + 23; Opt.Detect_Blocking := True; goto Line_Loop_Continue; -- Discard_Names elsif System_Text (P .. P + 20) = "pragma Discard_Names;" then P := P + 21; Opt.Global_Discard_Names := True; goto Line_Loop_Continue; -- Locking Policy elsif System_Text (P .. P + 22) = "pragma Locking_Policy (" then P := P + 23; Opt.Locking_Policy := System_Text (P); Opt.Locking_Policy_Sloc := System_Location; goto Line_Loop_Continue; -- Normalize_Scalars elsif System_Text (P .. P + 24) = "pragma Normalize_Scalars;" then P := P + 25; Opt.Normalize_Scalars := True; Opt.Init_Or_Norm_Scalars := True; goto Line_Loop_Continue; -- Partition_Elaboration_Policy elsif System_Text (P .. P + 36) = "pragma Partition_Elaboration_Policy (" then P := P + 37; Opt.Partition_Elaboration_Policy := System_Text (P); Opt.Partition_Elaboration_Policy_Sloc := System_Location; goto Line_Loop_Continue; -- Polling (On) elsif System_Text (P .. P + 19) = "pragma Polling (On);" then P := P + 20; Opt.Polling_Required := True; goto Line_Loop_Continue; -- Ignore pragma Pure (System) elsif System_Text (P .. P + 20) = "pragma Pure (System);" then P := P + 21; goto Line_Loop_Continue; -- Queuing Policy elsif System_Text (P .. P + 22) = "pragma Queuing_Policy (" then P := P + 23; Opt.Queuing_Policy := System_Text (P); Opt.Queuing_Policy_Sloc := System_Location; goto Line_Loop_Continue; -- Suppress_Exception_Locations elsif System_Text (P .. P + 35) = "pragma Suppress_Exception_Locations;" then P := P + 36; Opt.Exception_Locations_Suppressed := True; goto Line_Loop_Continue; -- Task_Dispatching Policy elsif System_Text (P .. P + 31) = "pragma Task_Dispatching_Policy (" then P := P + 32; Opt.Task_Dispatching_Policy := System_Text (P); Opt.Task_Dispatching_Policy_Sloc := System_Location; goto Line_Loop_Continue; -- No other pragmas are permitted elsif System_Text (P .. P + 6) = "pragma " then Set_Standard_Error; Write_Line ("unrecognized line in system.ads: "); while System_Text (P) /= ')' and then System_Text (P) /= ASCII.LF loop Write_Char (System_Text (P)); P := P + 1; end loop; Write_Eol; Set_Standard_Output; Fatal := True; -- See if we have a Run_Time_Name elsif System_Text (P .. P + 38) = " Run_Time_Name : constant String := """ then P := P + 39; Name_Len := 0; while System_Text (P) in 'A' .. 'Z' or else System_Text (P) in 'a' .. 'z' or else System_Text (P) in '0' .. '9' or else System_Text (P) = ' ' or else System_Text (P) = '_' loop Add_Char_To_Name_Buffer (System_Text (P)); P := P + 1; end loop; if System_Text (P) /= '"' or else System_Text (P + 1) /= ';' or else (System_Text (P + 2) /= ASCII.LF and then System_Text (P + 2) /= ASCII.CR) then Set_Standard_Error; Write_Line ("incorrectly formatted Run_Time_Name in system.ads"); Set_Standard_Output; Fatal := True; else Run_Time_Name_On_Target := Name_Enter; end if; goto Line_Loop_Continue; -- See if we have an Executable_Extension elsif System_Text (P .. P + 45) = " Executable_Extension : constant String := """ then P := P + 46; Name_Len := 0; while System_Text (P) /= '"' and then System_Text (P) /= ASCII.LF loop Add_Char_To_Name_Buffer (System_Text (P)); P := P + 1; end loop; if System_Text (P) /= '"' or else System_Text (P + 1) /= ';' then Set_Standard_Error; Write_Line ("incorrectly formatted Executable_Extension in system.ads"); Set_Standard_Output; Fatal := True; else Executable_Extension_On_Target := Name_Enter; end if; goto Line_Loop_Continue; -- Next see if we have a configuration parameter else Config_Param_Loop : for K in Targparm_Tags loop if System_Text (P + 3 .. P + 2 + Targparm_Str (K)'Length) = Targparm_Str (K).all then P := P + 3 + Targparm_Str (K)'Length; if Targparm_Flags (K) then Set_Standard_Error; Write_Line ("fatal error: system.ads is incorrectly formatted"); Write_Str ("duplicate line for parameter: "); for J in Targparm_Str (K)'Range loop Write_Char (Targparm_Str (K).all (J)); end loop; Write_Eol; Set_Standard_Output; Fatal := True; else Targparm_Flags (K) := True; end if; while System_Text (P) /= ':' or else System_Text (P + 1) /= '=' loop P := P + 1; end loop; P := P + 2; while System_Text (P) = ' ' loop P := P + 1; end loop; Result := (System_Text (P) = 'T'); case K is when AAM => AAMP_On_Target := Result; when ACR => Always_Compatible_Rep_On_Target := Result; when ASD => Atomic_Sync_Default_On_Target := Result; when BDC => Backend_Divide_Checks_On_Target := Result; when BOC => Backend_Overflow_Checks_On_Target := Result; when CLA => Command_Line_Args_On_Target := Result; when CLI => if Result then VM_Target := CLI_Target; Tagged_Type_Expansion := False; end if; -- This is wrong, this processing should be done in -- Gnat1drv.Adjust_Global_Switches. It is not the -- right level for targparm to know about tagged -- type extension??? when CRT => Configurable_Run_Time_On_Target := Result; when D32 => Duration_32_Bits_On_Target := Result; when DEN => Denorm_On_Target := Result; when EXS => Exit_Status_Supported_On_Target := Result; when FEL => Frontend_Layout_On_Target := Result; when FFO => Fractional_Fixed_Ops_On_Target := Result; when JVM => if Result then VM_Target := JVM_Target; Tagged_Type_Expansion := False; end if; -- This is wrong, this processing should be done in -- Gnat1drv.Adjust_Global_Switches. It is not the -- right level for targparm to know about tagged -- type extension??? when MOV => Machine_Overflows_On_Target := Result; when MRN => Machine_Rounds_On_Target := Result; when PAS => Preallocated_Stacks_On_Target := Result; when RTX => RTX_RTSS_Kernel_Module_On_Target := Result; when SAG => Support_Aggregates_On_Target := Result; when SAP => Support_Atomic_Primitives_On_Target := Result; when SCA => Support_Composite_Assign_On_Target := Result; when SCC => Support_Composite_Compare_On_Target := Result; when SCD => Stack_Check_Default_On_Target := Result; when SCL => Stack_Check_Limits_On_Target := Result; when SCP => Stack_Check_Probes_On_Target := Result; when SLS => Support_Long_Shifts_On_Target := Result; when SSL => Suppress_Standard_Library_On_Target := Result; when SNZ => Signed_Zeros_On_Target := Result; when UAM => Use_Ada_Main_Program_Name_On_Target := Result; when VMS => OpenVMS_On_Target := Result; when VXF => VAX_Float_On_Target := Result; when ZCD => ZCX_By_Default_On_Target := Result; goto Line_Loop_Continue; end case; -- Here we are seeing a parameter we do not understand. We -- simply ignore this (will happen when an old compiler is -- used to compile a newer version of GNAT which does not -- support the parameter). end if; end loop Config_Param_Loop; end if; -- Here after processing one line of System spec <> while System_Text (P) /= CR and then System_Text (P) /= LF loop P := P + 1; exit when P >= Source_Last; end loop; while System_Text (P) = CR or else System_Text (P) = LF loop P := P + 1; exit when P >= Source_Last; end loop; if P >= Source_Last then Set_Standard_Error; Write_Line ("fatal error, system.ads not formatted correctly"); Write_Line ("unexpected end of file"); Set_Standard_Output; raise Unrecoverable_Error; end if; end loop Line_Loop; -- Now that OpenVMS_On_Target has been given its definitive value, -- change the multi-unit index character from '~' to '$' for OpenVMS. if OpenVMS_On_Target then Multi_Unit_Index_Character := '$'; end if; if Fatal then raise Unrecoverable_Error; end if; end Get_Target_Parameters; ------------------------------ -- Set_Profile_Restrictions -- ------------------------------ procedure Set_Profile_Restrictions (P : Profile_Name) is R : Restriction_Flags renames Profile_Info (P).Set; V : Restriction_Values renames Profile_Info (P).Value; begin for J in R'Range loop if R (J) then Restrictions_On_Target.Set (J) := True; if J in All_Parameter_Restrictions then Restrictions_On_Target.Value (J) := V (J); end if; end if; end loop; end Set_Profile_Restrictions; end Targparm; gprbuild-gpl-2014-src/gnat/gnatvsn.adb0000644000076700001450000001004412323721731017213 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- G N A T V S N -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2007, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ package body Gnatvsn is ---------------------- -- Copyright_Holder -- ---------------------- function Copyright_Holder return String is begin return "Free Software Foundation, Inc."; end Copyright_Holder; ------------------------ -- Gnat_Free_Software -- ------------------------ function Gnat_Free_Software return String is begin case Build_Type is when GPL | FSF => return "This is free software; see the source for copying conditions." & ASCII.LF & "There is NO warranty; not even for MERCHANTABILITY or FITNESS" & " FOR A PARTICULAR PURPOSE."; when Gnatpro => return "This is free software; see the source for copying conditions." & ASCII.LF & "See your AdaCore support agreement for details of warranty" & " and support." & ASCII.LF & "If you do not have a current support agreement, then there" & " is absolutely" & ASCII.LF & "no warranty; not even for MERCHANTABILITY or FITNESS FOR" & " A PARTICULAR" & ASCII.LF & "PURPOSE."; end case; end Gnat_Free_Software; ------------------------- -- Gnat_Version_String -- ------------------------- function Gnat_Version_String return String is begin case Build_Type is when Gnatpro => return "Pro " & Gnat_Static_Version_String; when GPL => return "GPL " & Gnat_Static_Version_String; when FSF => return Gnat_Static_Version_String; end case; end Gnat_Version_String; end Gnatvsn; gprbuild-gpl-2014-src/gnat/uintp.adb0000644000076700001450000020152112323721731016674 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- U I N T P -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Output; use Output; with Tree_IO; use Tree_IO; with GNAT.HTable; use GNAT.HTable; package body Uintp is ------------------------ -- Local Declarations -- ------------------------ Uint_Int_First : Uint := Uint_0; -- Uint value containing Int'First value, set by Initialize. The initial -- value of Uint_0 is used for an assertion check that ensures that this -- value is not used before it is initialized. This value is used in the -- UI_Is_In_Int_Range predicate, and it is right that this is a host value, -- since the issue is host representation of integer values. Uint_Int_Last : Uint; -- Uint value containing Int'Last value set by Initialize UI_Power_2 : array (Int range 0 .. 64) of Uint; -- This table is used to memoize exponentiations by powers of 2. The Nth -- entry, if set, contains the Uint value 2 ** N. Initially UI_Power_2_Set -- is zero and only the 0'th entry is set, the invariant being that all -- entries in the range 0 .. UI_Power_2_Set are initialized. UI_Power_2_Set : Nat; -- Number of entries set in UI_Power_2; UI_Power_10 : array (Int range 0 .. 64) of Uint; -- This table is used to memoize exponentiations by powers of 10 in the -- same manner as described above for UI_Power_2. UI_Power_10_Set : Nat; -- Number of entries set in UI_Power_10; Uints_Min : Uint; Udigits_Min : Int; -- These values are used to make sure that the mark/release mechanism does -- not destroy values saved in the U_Power tables or in the hash table used -- by UI_From_Int. Whenever an entry is made in either of these tables, -- Uints_Min and Udigits_Min are updated to protect the entry, and Release -- never cuts back beyond these minimum values. Int_0 : constant Int := 0; Int_1 : constant Int := 1; Int_2 : constant Int := 2; -- These values are used in some cases where the use of numeric literals -- would cause ambiguities (integer vs Uint). ---------------------------- -- UI_From_Int Hash Table -- ---------------------------- -- UI_From_Int uses a hash table to avoid duplicating entries and wasting -- storage. This is particularly important for complex cases of back -- annotation. subtype Hnum is Nat range 0 .. 1022; function Hash_Num (F : Int) return Hnum; -- Hashing function package UI_Ints is new Simple_HTable ( Header_Num => Hnum, Element => Uint, No_Element => No_Uint, Key => Int, Hash => Hash_Num, Equal => "="); ----------------------- -- Local Subprograms -- ----------------------- function Direct (U : Uint) return Boolean; pragma Inline (Direct); -- Returns True if U is represented directly function Direct_Val (U : Uint) return Int; -- U is a Uint for is represented directly. The returned result is the -- value represented. function GCD (Jin, Kin : Int) return Int; -- Compute GCD of two integers. Assumes that Jin >= Kin >= 0 procedure Image_Out (Input : Uint; To_Buffer : Boolean; Format : UI_Format); -- Common processing for UI_Image and UI_Write, To_Buffer is set True for -- UI_Image, and false for UI_Write, and Format is copied from the Format -- parameter to UI_Image or UI_Write. procedure Init_Operand (UI : Uint; Vec : out UI_Vector); pragma Inline (Init_Operand); -- This procedure puts the value of UI into the vector in canonical -- multiple precision format. The parameter should be of the correct size -- as determined by a previous call to N_Digits (UI). The first digit of -- Vec contains the sign, all other digits are always non-negative. Note -- that the input may be directly represented, and in this case Vec will -- contain the corresponding one or two digit value. The low bound of Vec -- is always 1. function Least_Sig_Digit (Arg : Uint) return Int; pragma Inline (Least_Sig_Digit); -- Returns the Least Significant Digit of Arg quickly. When the given Uint -- is less than 2**15, the value returned is the input value, in this case -- the result may be negative. It is expected that any use will mask off -- unnecessary bits. This is used for finding Arg mod B where B is a power -- of two. Hence the actual base is irrelevant as long as it is a power of -- two. procedure Most_Sig_2_Digits (Left : Uint; Right : Uint; Left_Hat : out Int; Right_Hat : out Int); -- Returns leading two significant digits from the given pair of Uint's. -- Mathematically: returns Left / (Base ** K) and Right / (Base ** K) where -- K is as small as possible S.T. Right_Hat < Base * Base. It is required -- that Left > Right for the algorithm to work. function N_Digits (Input : Uint) return Int; pragma Inline (N_Digits); -- Returns number of "digits" in a Uint procedure UI_Div_Rem (Left, Right : Uint; Quotient : out Uint; Remainder : out Uint; Discard_Quotient : Boolean := False; Discard_Remainder : Boolean := False); -- Compute Euclidean division of Left by Right. If Discard_Quotient is -- False then the quotient is returned in Quotient (otherwise Quotient is -- set to No_Uint). If Discard_Remainder is False, then the remainder is -- returned in Remainder (otherwise Remainder is set to No_Uint). -- -- If Discard_Quotient is True, Quotient is set to No_Uint -- If Discard_Remainder is True, Remainder is set to No_Uint function Vector_To_Uint (In_Vec : UI_Vector; Negative : Boolean) return Uint; -- Functions that calculate values in UI_Vectors, call this function to -- create and return the Uint value. In_Vec contains the multiple precision -- (Base) representation of a non-negative value. Leading zeroes are -- permitted. Negative is set if the desired result is the negative of the -- given value. The result will be either the appropriate directly -- represented value, or a table entry in the proper canonical format is -- created and returned. -- -- Note that Init_Operand puts a signed value in the result vector, but -- Vector_To_Uint is always presented with a non-negative value. The -- processing of signs is something that is done by the caller before -- calling Vector_To_Uint. ------------ -- Direct -- ------------ function Direct (U : Uint) return Boolean is begin return Int (U) <= Int (Uint_Direct_Last); end Direct; ---------------- -- Direct_Val -- ---------------- function Direct_Val (U : Uint) return Int is begin pragma Assert (Direct (U)); return Int (U) - Int (Uint_Direct_Bias); end Direct_Val; --------- -- GCD -- --------- function GCD (Jin, Kin : Int) return Int is J, K, Tmp : Int; begin pragma Assert (Jin >= Kin); pragma Assert (Kin >= Int_0); J := Jin; K := Kin; while K /= Uint_0 loop Tmp := J mod K; J := K; K := Tmp; end loop; return J; end GCD; -------------- -- Hash_Num -- -------------- function Hash_Num (F : Int) return Hnum is begin return Types."mod" (F, Hnum'Range_Length); end Hash_Num; --------------- -- Image_Out -- --------------- procedure Image_Out (Input : Uint; To_Buffer : Boolean; Format : UI_Format) is Marks : constant Uintp.Save_Mark := Uintp.Mark; Base : Uint; Ainput : Uint; Digs_Output : Natural := 0; -- Counts digits output. In hex mode, but not in decimal mode, we -- put an underline after every four hex digits that are output. Exponent : Natural := 0; -- If the number is too long to fit in the buffer, we switch to an -- approximate output format with an exponent. This variable records -- the exponent value. function Better_In_Hex return Boolean; -- Determines if it is better to generate digits in base 16 (result -- is true) or base 10 (result is false). The choice is purely a -- matter of convenience and aesthetics, so it does not matter which -- value is returned from a correctness point of view. procedure Image_Char (C : Character); -- Internal procedure to output one character procedure Image_Exponent (N : Natural); -- Output non-zero exponent. Note that we only use the exponent form in -- the buffer case, so we know that To_Buffer is true. procedure Image_Uint (U : Uint); -- Internal procedure to output characters of non-negative Uint ------------------- -- Better_In_Hex -- ------------------- function Better_In_Hex return Boolean is T16 : constant Uint := Uint_2 ** Int'(16); A : Uint; begin A := UI_Abs (Input); -- Small values up to 2**16 can always be in decimal if A < T16 then return False; end if; -- Otherwise, see if we are a power of 2 or one less than a power -- of 2. For the moment these are the only cases printed in hex. if A mod Uint_2 = Uint_1 then A := A + Uint_1; end if; loop if A mod T16 /= Uint_0 then return False; else A := A / T16; end if; exit when A < T16; end loop; while A > Uint_2 loop if A mod Uint_2 /= Uint_0 then return False; else A := A / Uint_2; end if; end loop; return True; end Better_In_Hex; ---------------- -- Image_Char -- ---------------- procedure Image_Char (C : Character) is begin if To_Buffer then if UI_Image_Length + 6 > UI_Image_Max then Exponent := Exponent + 1; else UI_Image_Length := UI_Image_Length + 1; UI_Image_Buffer (UI_Image_Length) := C; end if; else Write_Char (C); end if; end Image_Char; -------------------- -- Image_Exponent -- -------------------- procedure Image_Exponent (N : Natural) is begin if N >= 10 then Image_Exponent (N / 10); end if; UI_Image_Length := UI_Image_Length + 1; UI_Image_Buffer (UI_Image_Length) := Character'Val (Character'Pos ('0') + N mod 10); end Image_Exponent; ---------------- -- Image_Uint -- ---------------- procedure Image_Uint (U : Uint) is H : constant array (Int range 0 .. 15) of Character := "0123456789ABCDEF"; Q, R : Uint; begin UI_Div_Rem (U, Base, Q, R); if Q > Uint_0 then Image_Uint (Q); end if; if Digs_Output = 4 and then Base = Uint_16 then Image_Char ('_'); Digs_Output := 0; end if; Image_Char (H (UI_To_Int (R))); Digs_Output := Digs_Output + 1; end Image_Uint; -- Start of processing for Image_Out begin if Input = No_Uint then Image_Char ('?'); return; end if; UI_Image_Length := 0; if Input < Uint_0 then Image_Char ('-'); Ainput := -Input; else Ainput := Input; end if; if Format = Hex or else (Format = Auto and then Better_In_Hex) then Base := Uint_16; Image_Char ('1'); Image_Char ('6'); Image_Char ('#'); Image_Uint (Ainput); Image_Char ('#'); else Base := Uint_10; Image_Uint (Ainput); end if; if Exponent /= 0 then UI_Image_Length := UI_Image_Length + 1; UI_Image_Buffer (UI_Image_Length) := 'E'; Image_Exponent (Exponent); end if; Uintp.Release (Marks); end Image_Out; ------------------- -- Init_Operand -- ------------------- procedure Init_Operand (UI : Uint; Vec : out UI_Vector) is Loc : Int; pragma Assert (Vec'First = Int'(1)); begin if Direct (UI) then Vec (1) := Direct_Val (UI); if Vec (1) >= Base then Vec (2) := Vec (1) rem Base; Vec (1) := Vec (1) / Base; end if; else Loc := Uints.Table (UI).Loc; for J in 1 .. Uints.Table (UI).Length loop Vec (J) := Udigits.Table (Loc + J - 1); end loop; end if; end Init_Operand; ---------------- -- Initialize -- ---------------- procedure Initialize is begin Uints.Init; Udigits.Init; Uint_Int_First := UI_From_Int (Int'First); Uint_Int_Last := UI_From_Int (Int'Last); UI_Power_2 (0) := Uint_1; UI_Power_2_Set := 0; UI_Power_10 (0) := Uint_1; UI_Power_10_Set := 0; Uints_Min := Uints.Last; Udigits_Min := Udigits.Last; UI_Ints.Reset; end Initialize; --------------------- -- Least_Sig_Digit -- --------------------- function Least_Sig_Digit (Arg : Uint) return Int is V : Int; begin if Direct (Arg) then V := Direct_Val (Arg); if V >= Base then V := V mod Base; end if; -- Note that this result may be negative return V; else return Udigits.Table (Uints.Table (Arg).Loc + Uints.Table (Arg).Length - 1); end if; end Least_Sig_Digit; ---------- -- Mark -- ---------- function Mark return Save_Mark is begin return (Save_Uint => Uints.Last, Save_Udigit => Udigits.Last); end Mark; ----------------------- -- Most_Sig_2_Digits -- ----------------------- procedure Most_Sig_2_Digits (Left : Uint; Right : Uint; Left_Hat : out Int; Right_Hat : out Int) is begin pragma Assert (Left >= Right); if Direct (Left) then Left_Hat := Direct_Val (Left); Right_Hat := Direct_Val (Right); return; else declare L1 : constant Int := Udigits.Table (Uints.Table (Left).Loc); L2 : constant Int := Udigits.Table (Uints.Table (Left).Loc + 1); begin -- It is not so clear what to return when Arg is negative??? Left_Hat := abs (L1) * Base + L2; end; end if; declare Length_L : constant Int := Uints.Table (Left).Length; Length_R : Int; R1 : Int; R2 : Int; T : Int; begin if Direct (Right) then T := Direct_Val (Left); R1 := abs (T / Base); R2 := T rem Base; Length_R := 2; else R1 := abs (Udigits.Table (Uints.Table (Right).Loc)); R2 := Udigits.Table (Uints.Table (Right).Loc + 1); Length_R := Uints.Table (Right).Length; end if; if Length_L = Length_R then Right_Hat := R1 * Base + R2; elsif Length_L = Length_R + Int_1 then Right_Hat := R1; else Right_Hat := 0; end if; end; end Most_Sig_2_Digits; --------------- -- N_Digits -- --------------- -- Note: N_Digits returns 1 for No_Uint function N_Digits (Input : Uint) return Int is begin if Direct (Input) then if Direct_Val (Input) >= Base then return 2; else return 1; end if; else return Uints.Table (Input).Length; end if; end N_Digits; -------------- -- Num_Bits -- -------------- function Num_Bits (Input : Uint) return Nat is Bits : Nat; Num : Nat; begin -- Largest negative number has to be handled specially, since it is in -- Int_Range, but we cannot take the absolute value. if Input = Uint_Int_First then return Int'Size; -- For any other number in Int_Range, get absolute value of number elsif UI_Is_In_Int_Range (Input) then Num := abs (UI_To_Int (Input)); Bits := 0; -- If not in Int_Range then initialize bit count for all low order -- words, and set number to high order digit. else Bits := Base_Bits * (Uints.Table (Input).Length - 1); Num := abs (Udigits.Table (Uints.Table (Input).Loc)); end if; -- Increase bit count for remaining value in Num while Types.">" (Num, 0) loop Num := Num / 2; Bits := Bits + 1; end loop; return Bits; end Num_Bits; --------- -- pid -- --------- procedure pid (Input : Uint) is begin UI_Write (Input, Decimal); Write_Eol; end pid; --------- -- pih -- --------- procedure pih (Input : Uint) is begin UI_Write (Input, Hex); Write_Eol; end pih; ------------- -- Release -- ------------- procedure Release (M : Save_Mark) is begin Uints.Set_Last (Uint'Max (M.Save_Uint, Uints_Min)); Udigits.Set_Last (Int'Max (M.Save_Udigit, Udigits_Min)); end Release; ---------------------- -- Release_And_Save -- ---------------------- procedure Release_And_Save (M : Save_Mark; UI : in out Uint) is begin if Direct (UI) then Release (M); else declare UE_Len : constant Pos := Uints.Table (UI).Length; UE_Loc : constant Int := Uints.Table (UI).Loc; UD : constant Udigits.Table_Type (1 .. UE_Len) := Udigits.Table (UE_Loc .. UE_Loc + UE_Len - 1); begin Release (M); Uints.Append ((Length => UE_Len, Loc => Udigits.Last + 1)); UI := Uints.Last; for J in 1 .. UE_Len loop Udigits.Append (UD (J)); end loop; end; end if; end Release_And_Save; procedure Release_And_Save (M : Save_Mark; UI1, UI2 : in out Uint) is begin if Direct (UI1) then Release_And_Save (M, UI2); elsif Direct (UI2) then Release_And_Save (M, UI1); else declare UE1_Len : constant Pos := Uints.Table (UI1).Length; UE1_Loc : constant Int := Uints.Table (UI1).Loc; UD1 : constant Udigits.Table_Type (1 .. UE1_Len) := Udigits.Table (UE1_Loc .. UE1_Loc + UE1_Len - 1); UE2_Len : constant Pos := Uints.Table (UI2).Length; UE2_Loc : constant Int := Uints.Table (UI2).Loc; UD2 : constant Udigits.Table_Type (1 .. UE2_Len) := Udigits.Table (UE2_Loc .. UE2_Loc + UE2_Len - 1); begin Release (M); Uints.Append ((Length => UE1_Len, Loc => Udigits.Last + 1)); UI1 := Uints.Last; for J in 1 .. UE1_Len loop Udigits.Append (UD1 (J)); end loop; Uints.Append ((Length => UE2_Len, Loc => Udigits.Last + 1)); UI2 := Uints.Last; for J in 1 .. UE2_Len loop Udigits.Append (UD2 (J)); end loop; end; end if; end Release_And_Save; --------------- -- Tree_Read -- --------------- procedure Tree_Read is begin Uints.Tree_Read; Udigits.Tree_Read; Tree_Read_Int (Int (Uint_Int_First)); Tree_Read_Int (Int (Uint_Int_Last)); Tree_Read_Int (UI_Power_2_Set); Tree_Read_Int (UI_Power_10_Set); Tree_Read_Int (Int (Uints_Min)); Tree_Read_Int (Udigits_Min); for J in 0 .. UI_Power_2_Set loop Tree_Read_Int (Int (UI_Power_2 (J))); end loop; for J in 0 .. UI_Power_10_Set loop Tree_Read_Int (Int (UI_Power_10 (J))); end loop; end Tree_Read; ---------------- -- Tree_Write -- ---------------- procedure Tree_Write is begin Uints.Tree_Write; Udigits.Tree_Write; Tree_Write_Int (Int (Uint_Int_First)); Tree_Write_Int (Int (Uint_Int_Last)); Tree_Write_Int (UI_Power_2_Set); Tree_Write_Int (UI_Power_10_Set); Tree_Write_Int (Int (Uints_Min)); Tree_Write_Int (Udigits_Min); for J in 0 .. UI_Power_2_Set loop Tree_Write_Int (Int (UI_Power_2 (J))); end loop; for J in 0 .. UI_Power_10_Set loop Tree_Write_Int (Int (UI_Power_10 (J))); end loop; end Tree_Write; ------------- -- UI_Abs -- ------------- function UI_Abs (Right : Uint) return Uint is begin if Right < Uint_0 then return -Right; else return Right; end if; end UI_Abs; ------------- -- UI_Add -- ------------- function UI_Add (Left : Int; Right : Uint) return Uint is begin return UI_Add (UI_From_Int (Left), Right); end UI_Add; function UI_Add (Left : Uint; Right : Int) return Uint is begin return UI_Add (Left, UI_From_Int (Right)); end UI_Add; function UI_Add (Left : Uint; Right : Uint) return Uint is begin -- Simple cases of direct operands and addition of zero if Direct (Left) then if Direct (Right) then return UI_From_Int (Direct_Val (Left) + Direct_Val (Right)); elsif Int (Left) = Int (Uint_0) then return Right; end if; elsif Direct (Right) and then Int (Right) = Int (Uint_0) then return Left; end if; -- Otherwise full circuit is needed declare L_Length : constant Int := N_Digits (Left); R_Length : constant Int := N_Digits (Right); L_Vec : UI_Vector (1 .. L_Length); R_Vec : UI_Vector (1 .. R_Length); Sum_Length : Int; Tmp_Int : Int; Carry : Int; Borrow : Int; X_Bigger : Boolean := False; Y_Bigger : Boolean := False; Result_Neg : Boolean := False; begin Init_Operand (Left, L_Vec); Init_Operand (Right, R_Vec); -- At least one of the two operands is in multi-digit form. -- Calculate the number of digits sufficient to hold result. if L_Length > R_Length then Sum_Length := L_Length + 1; X_Bigger := True; else Sum_Length := R_Length + 1; if R_Length > L_Length then Y_Bigger := True; end if; end if; -- Make copies of the absolute values of L_Vec and R_Vec into X and Y -- both with lengths equal to the maximum possibly needed. This makes -- looping over the digits much simpler. declare X : UI_Vector (1 .. Sum_Length); Y : UI_Vector (1 .. Sum_Length); Tmp_UI : UI_Vector (1 .. Sum_Length); begin for J in 1 .. Sum_Length - L_Length loop X (J) := 0; end loop; X (Sum_Length - L_Length + 1) := abs L_Vec (1); for J in 2 .. L_Length loop X (J + (Sum_Length - L_Length)) := L_Vec (J); end loop; for J in 1 .. Sum_Length - R_Length loop Y (J) := 0; end loop; Y (Sum_Length - R_Length + 1) := abs R_Vec (1); for J in 2 .. R_Length loop Y (J + (Sum_Length - R_Length)) := R_Vec (J); end loop; if (L_Vec (1) < Int_0) = (R_Vec (1) < Int_0) then -- Same sign so just add Carry := 0; for J in reverse 1 .. Sum_Length loop Tmp_Int := X (J) + Y (J) + Carry; if Tmp_Int >= Base then Tmp_Int := Tmp_Int - Base; Carry := 1; else Carry := 0; end if; X (J) := Tmp_Int; end loop; return Vector_To_Uint (X, L_Vec (1) < Int_0); else -- Find which one has bigger magnitude if not (X_Bigger or Y_Bigger) then for J in L_Vec'Range loop if abs L_Vec (J) > abs R_Vec (J) then X_Bigger := True; exit; elsif abs R_Vec (J) > abs L_Vec (J) then Y_Bigger := True; exit; end if; end loop; end if; -- If they have identical magnitude, just return 0, else swap -- if necessary so that X had the bigger magnitude. Determine -- if result is negative at this time. Result_Neg := False; if not (X_Bigger or Y_Bigger) then return Uint_0; elsif Y_Bigger then if R_Vec (1) < Int_0 then Result_Neg := True; end if; Tmp_UI := X; X := Y; Y := Tmp_UI; else if L_Vec (1) < Int_0 then Result_Neg := True; end if; end if; -- Subtract Y from the bigger X Borrow := 0; for J in reverse 1 .. Sum_Length loop Tmp_Int := X (J) - Y (J) + Borrow; if Tmp_Int < Int_0 then Tmp_Int := Tmp_Int + Base; Borrow := -1; else Borrow := 0; end if; X (J) := Tmp_Int; end loop; return Vector_To_Uint (X, Result_Neg); end if; end; end; end UI_Add; -------------------------- -- UI_Decimal_Digits_Hi -- -------------------------- function UI_Decimal_Digits_Hi (U : Uint) return Nat is begin -- The maximum value of a "digit" is 32767, which is 5 decimal digits, -- so an N_Digit number could take up to 5 times this number of digits. -- This is certainly too high for large numbers but it is not worth -- worrying about. return 5 * N_Digits (U); end UI_Decimal_Digits_Hi; -------------------------- -- UI_Decimal_Digits_Lo -- -------------------------- function UI_Decimal_Digits_Lo (U : Uint) return Nat is begin -- The maximum value of a "digit" is 32767, which is more than four -- decimal digits, but not a full five digits. The easily computed -- minimum number of decimal digits is thus 1 + 4 * the number of -- digits. This is certainly too low for large numbers but it is not -- worth worrying about. return 1 + 4 * (N_Digits (U) - 1); end UI_Decimal_Digits_Lo; ------------ -- UI_Div -- ------------ function UI_Div (Left : Int; Right : Uint) return Uint is begin return UI_Div (UI_From_Int (Left), Right); end UI_Div; function UI_Div (Left : Uint; Right : Int) return Uint is begin return UI_Div (Left, UI_From_Int (Right)); end UI_Div; function UI_Div (Left, Right : Uint) return Uint is Quotient : Uint; Remainder : Uint; pragma Warnings (Off, Remainder); begin UI_Div_Rem (Left, Right, Quotient, Remainder, Discard_Remainder => True); return Quotient; end UI_Div; ---------------- -- UI_Div_Rem -- ---------------- procedure UI_Div_Rem (Left, Right : Uint; Quotient : out Uint; Remainder : out Uint; Discard_Quotient : Boolean := False; Discard_Remainder : Boolean := False) is begin pragma Assert (Right /= Uint_0); Quotient := No_Uint; Remainder := No_Uint; -- Cases where both operands are represented directly if Direct (Left) and then Direct (Right) then declare DV_Left : constant Int := Direct_Val (Left); DV_Right : constant Int := Direct_Val (Right); begin if not Discard_Quotient then Quotient := UI_From_Int (DV_Left / DV_Right); end if; if not Discard_Remainder then Remainder := UI_From_Int (DV_Left rem DV_Right); end if; return; end; end if; declare L_Length : constant Int := N_Digits (Left); R_Length : constant Int := N_Digits (Right); Q_Length : constant Int := L_Length - R_Length + 1; L_Vec : UI_Vector (1 .. L_Length); R_Vec : UI_Vector (1 .. R_Length); D : Int; Remainder_I : Int; Tmp_Divisor : Int; Carry : Int; Tmp_Int : Int; Tmp_Dig : Int; procedure UI_Div_Vector (L_Vec : UI_Vector; R_Int : Int; Quotient : out UI_Vector; Remainder : out Int); pragma Inline (UI_Div_Vector); -- Specialised variant for case where the divisor is a single digit procedure UI_Div_Vector (L_Vec : UI_Vector; R_Int : Int; Quotient : out UI_Vector; Remainder : out Int) is Tmp_Int : Int; begin Remainder := 0; for J in L_Vec'Range loop Tmp_Int := Remainder * Base + abs L_Vec (J); Quotient (Quotient'First + J - L_Vec'First) := Tmp_Int / R_Int; Remainder := Tmp_Int rem R_Int; end loop; if L_Vec (L_Vec'First) < Int_0 then Remainder := -Remainder; end if; end UI_Div_Vector; -- Start of processing for UI_Div_Rem begin -- Result is zero if left operand is shorter than right if L_Length < R_Length then if not Discard_Quotient then Quotient := Uint_0; end if; if not Discard_Remainder then Remainder := Left; end if; return; end if; Init_Operand (Left, L_Vec); Init_Operand (Right, R_Vec); -- Case of right operand is single digit. Here we can simply divide -- each digit of the left operand by the divisor, from most to least -- significant, carrying the remainder to the next digit (just like -- ordinary long division by hand). if R_Length = Int_1 then Tmp_Divisor := abs R_Vec (1); declare Quotient_V : UI_Vector (1 .. L_Length); begin UI_Div_Vector (L_Vec, Tmp_Divisor, Quotient_V, Remainder_I); if not Discard_Quotient then Quotient := Vector_To_Uint (Quotient_V, (L_Vec (1) < Int_0 xor R_Vec (1) < Int_0)); end if; if not Discard_Remainder then Remainder := UI_From_Int (Remainder_I); end if; return; end; end if; -- The possible simple cases have been exhausted. Now turn to the -- algorithm D from the section of Knuth mentioned at the top of -- this package. Algorithm_D : declare Dividend : UI_Vector (1 .. L_Length + 1); Divisor : UI_Vector (1 .. R_Length); Quotient_V : UI_Vector (1 .. Q_Length); Divisor_Dig1 : Int; Divisor_Dig2 : Int; Q_Guess : Int; R_Guess : Int; begin -- [ NORMALIZE ] (step D1 in the algorithm). First calculate the -- scale d, and then multiply Left and Right (u and v in the book) -- by d to get the dividend and divisor to work with. D := Base / (abs R_Vec (1) + 1); Dividend (1) := 0; Dividend (2) := abs L_Vec (1); for J in 3 .. L_Length + Int_1 loop Dividend (J) := L_Vec (J - 1); end loop; Divisor (1) := abs R_Vec (1); for J in Int_2 .. R_Length loop Divisor (J) := R_Vec (J); end loop; if D > Int_1 then -- Multiply Dividend by d Carry := 0; for J in reverse Dividend'Range loop Tmp_Int := Dividend (J) * D + Carry; Dividend (J) := Tmp_Int rem Base; Carry := Tmp_Int / Base; end loop; -- Multiply Divisor by d Carry := 0; for J in reverse Divisor'Range loop Tmp_Int := Divisor (J) * D + Carry; Divisor (J) := Tmp_Int rem Base; Carry := Tmp_Int / Base; end loop; end if; -- Main loop of long division algorithm Divisor_Dig1 := Divisor (1); Divisor_Dig2 := Divisor (2); for J in Quotient_V'Range loop -- [ CALCULATE Q (hat) ] (step D3 in the algorithm) -- Note: this version of step D3 is from the original published -- algorithm, which is known to have a bug causing overflows. -- See: http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz -- and http://www-cs-faculty.stanford.edu/~uno/all2-pre.ps.gz. -- The code below is the fixed version of this step. Tmp_Int := Dividend (J) * Base + Dividend (J + 1); -- Initial guess Q_Guess := Tmp_Int / Divisor_Dig1; R_Guess := Tmp_Int rem Divisor_Dig1; -- Refine the guess while Q_Guess >= Base or else Divisor_Dig2 * Q_Guess > R_Guess * Base + Dividend (J + 2) loop Q_Guess := Q_Guess - 1; R_Guess := R_Guess + Divisor_Dig1; exit when R_Guess >= Base; end loop; -- [ MULTIPLY & SUBTRACT ] (step D4). Q_Guess * Divisor is -- subtracted from the remaining dividend. Carry := 0; for K in reverse Divisor'Range loop Tmp_Int := Dividend (J + K) - Q_Guess * Divisor (K) + Carry; Tmp_Dig := Tmp_Int rem Base; Carry := Tmp_Int / Base; if Tmp_Dig < Int_0 then Tmp_Dig := Tmp_Dig + Base; Carry := Carry - 1; end if; Dividend (J + K) := Tmp_Dig; end loop; Dividend (J) := Dividend (J) + Carry; -- [ TEST REMAINDER ] & [ ADD BACK ] (steps D5 and D6) -- Here there is a slight difference from the book: the last -- carry is always added in above and below (cancelling each -- other). In fact the dividend going negative is used as -- the test. -- If the Dividend went negative, then Q_Guess was off by -- one, so it is decremented, and the divisor is added back -- into the relevant portion of the dividend. if Dividend (J) < Int_0 then Q_Guess := Q_Guess - 1; Carry := 0; for K in reverse Divisor'Range loop Tmp_Int := Dividend (J + K) + Divisor (K) + Carry; if Tmp_Int >= Base then Tmp_Int := Tmp_Int - Base; Carry := 1; else Carry := 0; end if; Dividend (J + K) := Tmp_Int; end loop; Dividend (J) := Dividend (J) + Carry; end if; -- Finally we can get the next quotient digit Quotient_V (J) := Q_Guess; end loop; -- [ UNNORMALIZE ] (step D8) if not Discard_Quotient then Quotient := Vector_To_Uint (Quotient_V, (L_Vec (1) < Int_0 xor R_Vec (1) < Int_0)); end if; if not Discard_Remainder then declare Remainder_V : UI_Vector (1 .. R_Length); Discard_Int : Int; pragma Warnings (Off, Discard_Int); begin UI_Div_Vector (Dividend (Dividend'Last - R_Length + 1 .. Dividend'Last), D, Remainder_V, Discard_Int); Remainder := Vector_To_Uint (Remainder_V, L_Vec (1) < Int_0); end; end if; end Algorithm_D; end; end UI_Div_Rem; ------------ -- UI_Eq -- ------------ function UI_Eq (Left : Int; Right : Uint) return Boolean is begin return not UI_Ne (UI_From_Int (Left), Right); end UI_Eq; function UI_Eq (Left : Uint; Right : Int) return Boolean is begin return not UI_Ne (Left, UI_From_Int (Right)); end UI_Eq; function UI_Eq (Left : Uint; Right : Uint) return Boolean is begin return not UI_Ne (Left, Right); end UI_Eq; -------------- -- UI_Expon -- -------------- function UI_Expon (Left : Int; Right : Uint) return Uint is begin return UI_Expon (UI_From_Int (Left), Right); end UI_Expon; function UI_Expon (Left : Uint; Right : Int) return Uint is begin return UI_Expon (Left, UI_From_Int (Right)); end UI_Expon; function UI_Expon (Left : Int; Right : Int) return Uint is begin return UI_Expon (UI_From_Int (Left), UI_From_Int (Right)); end UI_Expon; function UI_Expon (Left : Uint; Right : Uint) return Uint is begin pragma Assert (Right >= Uint_0); -- Any value raised to power of 0 is 1 if Right = Uint_0 then return Uint_1; -- 0 to any positive power is 0 elsif Left = Uint_0 then return Uint_0; -- 1 to any power is 1 elsif Left = Uint_1 then return Uint_1; -- Any value raised to power of 1 is that value elsif Right = Uint_1 then return Left; -- Cases which can be done by table lookup elsif Right <= Uint_64 then -- 2 ** N for N in 2 .. 64 if Left = Uint_2 then declare Right_Int : constant Int := Direct_Val (Right); begin if Right_Int > UI_Power_2_Set then for J in UI_Power_2_Set + Int_1 .. Right_Int loop UI_Power_2 (J) := UI_Power_2 (J - Int_1) * Int_2; Uints_Min := Uints.Last; Udigits_Min := Udigits.Last; end loop; UI_Power_2_Set := Right_Int; end if; return UI_Power_2 (Right_Int); end; -- 10 ** N for N in 2 .. 64 elsif Left = Uint_10 then declare Right_Int : constant Int := Direct_Val (Right); begin if Right_Int > UI_Power_10_Set then for J in UI_Power_10_Set + Int_1 .. Right_Int loop UI_Power_10 (J) := UI_Power_10 (J - Int_1) * Int (10); Uints_Min := Uints.Last; Udigits_Min := Udigits.Last; end loop; UI_Power_10_Set := Right_Int; end if; return UI_Power_10 (Right_Int); end; end if; end if; -- If we fall through, then we have the general case (see Knuth 4.6.3) declare N : Uint := Right; Squares : Uint := Left; Result : Uint := Uint_1; M : constant Uintp.Save_Mark := Uintp.Mark; begin loop if (Least_Sig_Digit (N) mod Int_2) = Int_1 then Result := Result * Squares; end if; N := N / Uint_2; exit when N = Uint_0; Squares := Squares * Squares; end loop; Uintp.Release_And_Save (M, Result); return Result; end; end UI_Expon; ---------------- -- UI_From_CC -- ---------------- function UI_From_CC (Input : Char_Code) return Uint is begin return UI_From_Int (Int (Input)); end UI_From_CC; ----------------- -- UI_From_Int -- ----------------- function UI_From_Int (Input : Int) return Uint is U : Uint; begin if Min_Direct <= Input and then Input <= Max_Direct then return Uint (Int (Uint_Direct_Bias) + Input); end if; -- If already in the hash table, return entry U := UI_Ints.Get (Input); if U /= No_Uint then return U; end if; -- For values of larger magnitude, compute digits into a vector and call -- Vector_To_Uint. declare Max_For_Int : constant := 3; -- Base is defined so that 3 Uint digits is sufficient to hold the -- largest possible Int value. V : UI_Vector (1 .. Max_For_Int); Temp_Integer : Int := Input; begin for J in reverse V'Range loop V (J) := abs (Temp_Integer rem Base); Temp_Integer := Temp_Integer / Base; end loop; U := Vector_To_Uint (V, Input < Int_0); UI_Ints.Set (Input, U); Uints_Min := Uints.Last; Udigits_Min := Udigits.Last; return U; end; end UI_From_Int; ------------ -- UI_GCD -- ------------ -- Lehmer's algorithm for GCD -- The idea is to avoid using multiple precision arithmetic wherever -- possible, substituting Int arithmetic instead. See Knuth volume II, -- Algorithm L (page 329). -- We use the same notation as Knuth (U_Hat standing for the obvious) function UI_GCD (Uin, Vin : Uint) return Uint is U, V : Uint; -- Copies of Uin and Vin U_Hat, V_Hat : Int; -- The most Significant digits of U,V A, B, C, D, T, Q, Den1, Den2 : Int; Tmp_UI : Uint; Marks : constant Uintp.Save_Mark := Uintp.Mark; Iterations : Integer := 0; begin pragma Assert (Uin >= Vin); pragma Assert (Vin >= Uint_0); U := Uin; V := Vin; loop Iterations := Iterations + 1; if Direct (V) then if V = Uint_0 then return U; else return UI_From_Int (GCD (Direct_Val (V), UI_To_Int (U rem V))); end if; end if; Most_Sig_2_Digits (U, V, U_Hat, V_Hat); A := 1; B := 0; C := 0; D := 1; loop -- We might overflow and get division by zero here. This just -- means we cannot take the single precision step Den1 := V_Hat + C; Den2 := V_Hat + D; exit when Den1 = Int_0 or else Den2 = Int_0; -- Compute Q, the trial quotient Q := (U_Hat + A) / Den1; exit when Q /= ((U_Hat + B) / Den2); -- A single precision step Euclid step will give same answer as a -- multiprecision one. T := A - (Q * C); A := C; C := T; T := B - (Q * D); B := D; D := T; T := U_Hat - (Q * V_Hat); U_Hat := V_Hat; V_Hat := T; end loop; -- Take a multiprecision Euclid step if B = Int_0 then -- No single precision steps take a regular Euclid step Tmp_UI := U rem V; U := V; V := Tmp_UI; else -- Use prior single precision steps to compute this Euclid step -- For constructs such as: -- sqrt_2: constant := 1.41421_35623_73095_04880_16887_24209_698; -- sqrt_eps: constant long_float := long_float( 1.0 / sqrt_2) -- ** long_float'machine_mantissa; -- -- we spend 80% of our time working on this step. Perhaps we need -- a special case Int / Uint dot product to speed things up. ??? -- Alternatively we could increase the single precision iterations -- to handle Uint's of some small size ( <5 digits?). Then we -- would have more iterations on small Uint. On the code above, we -- only get 5 (on average) single precision iterations per large -- iteration. ??? Tmp_UI := (UI_From_Int (A) * U) + (UI_From_Int (B) * V); V := (UI_From_Int (C) * U) + (UI_From_Int (D) * V); U := Tmp_UI; end if; -- If the operands are very different in magnitude, the loop will -- generate large amounts of short-lived data, which it is worth -- removing periodically. if Iterations > 100 then Release_And_Save (Marks, U, V); Iterations := 0; end if; end loop; end UI_GCD; ------------ -- UI_Ge -- ------------ function UI_Ge (Left : Int; Right : Uint) return Boolean is begin return not UI_Lt (UI_From_Int (Left), Right); end UI_Ge; function UI_Ge (Left : Uint; Right : Int) return Boolean is begin return not UI_Lt (Left, UI_From_Int (Right)); end UI_Ge; function UI_Ge (Left : Uint; Right : Uint) return Boolean is begin return not UI_Lt (Left, Right); end UI_Ge; ------------ -- UI_Gt -- ------------ function UI_Gt (Left : Int; Right : Uint) return Boolean is begin return UI_Lt (Right, UI_From_Int (Left)); end UI_Gt; function UI_Gt (Left : Uint; Right : Int) return Boolean is begin return UI_Lt (UI_From_Int (Right), Left); end UI_Gt; function UI_Gt (Left : Uint; Right : Uint) return Boolean is begin return UI_Lt (Left => Right, Right => Left); end UI_Gt; --------------- -- UI_Image -- --------------- procedure UI_Image (Input : Uint; Format : UI_Format := Auto) is begin Image_Out (Input, True, Format); end UI_Image; ------------------------- -- UI_Is_In_Int_Range -- ------------------------- function UI_Is_In_Int_Range (Input : Uint) return Boolean is begin -- Make sure we don't get called before Initialize pragma Assert (Uint_Int_First /= Uint_0); if Direct (Input) then return True; else return Input >= Uint_Int_First and then Input <= Uint_Int_Last; end if; end UI_Is_In_Int_Range; ------------ -- UI_Le -- ------------ function UI_Le (Left : Int; Right : Uint) return Boolean is begin return not UI_Lt (Right, UI_From_Int (Left)); end UI_Le; function UI_Le (Left : Uint; Right : Int) return Boolean is begin return not UI_Lt (UI_From_Int (Right), Left); end UI_Le; function UI_Le (Left : Uint; Right : Uint) return Boolean is begin return not UI_Lt (Left => Right, Right => Left); end UI_Le; ------------ -- UI_Lt -- ------------ function UI_Lt (Left : Int; Right : Uint) return Boolean is begin return UI_Lt (UI_From_Int (Left), Right); end UI_Lt; function UI_Lt (Left : Uint; Right : Int) return Boolean is begin return UI_Lt (Left, UI_From_Int (Right)); end UI_Lt; function UI_Lt (Left : Uint; Right : Uint) return Boolean is begin -- Quick processing for identical arguments if Int (Left) = Int (Right) then return False; -- Quick processing for both arguments directly represented elsif Direct (Left) and then Direct (Right) then return Int (Left) < Int (Right); -- At least one argument is more than one digit long else declare L_Length : constant Int := N_Digits (Left); R_Length : constant Int := N_Digits (Right); L_Vec : UI_Vector (1 .. L_Length); R_Vec : UI_Vector (1 .. R_Length); begin Init_Operand (Left, L_Vec); Init_Operand (Right, R_Vec); if L_Vec (1) < Int_0 then -- First argument negative, second argument non-negative if R_Vec (1) >= Int_0 then return True; -- Both arguments negative else if L_Length /= R_Length then return L_Length > R_Length; elsif L_Vec (1) /= R_Vec (1) then return L_Vec (1) < R_Vec (1); else for J in 2 .. L_Vec'Last loop if L_Vec (J) /= R_Vec (J) then return L_Vec (J) > R_Vec (J); end if; end loop; return False; end if; end if; else -- First argument non-negative, second argument negative if R_Vec (1) < Int_0 then return False; -- Both arguments non-negative else if L_Length /= R_Length then return L_Length < R_Length; else for J in L_Vec'Range loop if L_Vec (J) /= R_Vec (J) then return L_Vec (J) < R_Vec (J); end if; end loop; return False; end if; end if; end if; end; end if; end UI_Lt; ------------ -- UI_Max -- ------------ function UI_Max (Left : Int; Right : Uint) return Uint is begin return UI_Max (UI_From_Int (Left), Right); end UI_Max; function UI_Max (Left : Uint; Right : Int) return Uint is begin return UI_Max (Left, UI_From_Int (Right)); end UI_Max; function UI_Max (Left : Uint; Right : Uint) return Uint is begin if Left >= Right then return Left; else return Right; end if; end UI_Max; ------------ -- UI_Min -- ------------ function UI_Min (Left : Int; Right : Uint) return Uint is begin return UI_Min (UI_From_Int (Left), Right); end UI_Min; function UI_Min (Left : Uint; Right : Int) return Uint is begin return UI_Min (Left, UI_From_Int (Right)); end UI_Min; function UI_Min (Left : Uint; Right : Uint) return Uint is begin if Left <= Right then return Left; else return Right; end if; end UI_Min; ------------- -- UI_Mod -- ------------- function UI_Mod (Left : Int; Right : Uint) return Uint is begin return UI_Mod (UI_From_Int (Left), Right); end UI_Mod; function UI_Mod (Left : Uint; Right : Int) return Uint is begin return UI_Mod (Left, UI_From_Int (Right)); end UI_Mod; function UI_Mod (Left : Uint; Right : Uint) return Uint is Urem : constant Uint := Left rem Right; begin if (Left < Uint_0) = (Right < Uint_0) or else Urem = Uint_0 then return Urem; else return Right + Urem; end if; end UI_Mod; ------------------------------- -- UI_Modular_Exponentiation -- ------------------------------- function UI_Modular_Exponentiation (B : Uint; E : Uint; Modulo : Uint) return Uint is M : constant Save_Mark := Mark; Result : Uint := Uint_1; Base : Uint := B; Exponent : Uint := E; begin while Exponent /= Uint_0 loop if Least_Sig_Digit (Exponent) rem Int'(2) = Int'(1) then Result := (Result * Base) rem Modulo; end if; Exponent := Exponent / Uint_2; Base := (Base * Base) rem Modulo; end loop; Release_And_Save (M, Result); return Result; end UI_Modular_Exponentiation; ------------------------ -- UI_Modular_Inverse -- ------------------------ function UI_Modular_Inverse (N : Uint; Modulo : Uint) return Uint is M : constant Save_Mark := Mark; U : Uint; V : Uint; Q : Uint; R : Uint; X : Uint; Y : Uint; T : Uint; S : Int := 1; begin U := Modulo; V := N; X := Uint_1; Y := Uint_0; loop UI_Div_Rem (U, V, Quotient => Q, Remainder => R); U := V; V := R; T := X; X := Y + Q * X; Y := T; S := -S; exit when R = Uint_1; end loop; if S = Int'(-1) then X := Modulo - X; end if; Release_And_Save (M, X); return X; end UI_Modular_Inverse; ------------ -- UI_Mul -- ------------ function UI_Mul (Left : Int; Right : Uint) return Uint is begin return UI_Mul (UI_From_Int (Left), Right); end UI_Mul; function UI_Mul (Left : Uint; Right : Int) return Uint is begin return UI_Mul (Left, UI_From_Int (Right)); end UI_Mul; function UI_Mul (Left : Uint; Right : Uint) return Uint is begin -- Case where product fits in the range of a 32-bit integer if Int (Left) <= Int (Uint_Max_Simple_Mul) and then Int (Right) <= Int (Uint_Max_Simple_Mul) then return UI_From_Int (Direct_Val (Left) * Direct_Val (Right)); end if; -- Otherwise we have the general case (Algorithm M in Knuth) declare L_Length : constant Int := N_Digits (Left); R_Length : constant Int := N_Digits (Right); L_Vec : UI_Vector (1 .. L_Length); R_Vec : UI_Vector (1 .. R_Length); Neg : Boolean; begin Init_Operand (Left, L_Vec); Init_Operand (Right, R_Vec); Neg := (L_Vec (1) < Int_0) xor (R_Vec (1) < Int_0); L_Vec (1) := abs (L_Vec (1)); R_Vec (1) := abs (R_Vec (1)); Algorithm_M : declare Product : UI_Vector (1 .. L_Length + R_Length); Tmp_Sum : Int; Carry : Int; begin for J in Product'Range loop Product (J) := 0; end loop; for J in reverse R_Vec'Range loop Carry := 0; for K in reverse L_Vec'Range loop Tmp_Sum := L_Vec (K) * R_Vec (J) + Product (J + K) + Carry; Product (J + K) := Tmp_Sum rem Base; Carry := Tmp_Sum / Base; end loop; Product (J) := Carry; end loop; return Vector_To_Uint (Product, Neg); end Algorithm_M; end; end UI_Mul; ------------ -- UI_Ne -- ------------ function UI_Ne (Left : Int; Right : Uint) return Boolean is begin return UI_Ne (UI_From_Int (Left), Right); end UI_Ne; function UI_Ne (Left : Uint; Right : Int) return Boolean is begin return UI_Ne (Left, UI_From_Int (Right)); end UI_Ne; function UI_Ne (Left : Uint; Right : Uint) return Boolean is begin -- Quick processing for identical arguments. Note that this takes -- care of the case of two No_Uint arguments. if Int (Left) = Int (Right) then return False; end if; -- See if left operand directly represented if Direct (Left) then -- If right operand directly represented then compare if Direct (Right) then return Int (Left) /= Int (Right); -- Left operand directly represented, right not, must be unequal else return True; end if; -- Right operand directly represented, left not, must be unequal elsif Direct (Right) then return True; end if; -- Otherwise both multi-word, do comparison declare Size : constant Int := N_Digits (Left); Left_Loc : Int; Right_Loc : Int; begin if Size /= N_Digits (Right) then return True; end if; Left_Loc := Uints.Table (Left).Loc; Right_Loc := Uints.Table (Right).Loc; for J in Int_0 .. Size - Int_1 loop if Udigits.Table (Left_Loc + J) /= Udigits.Table (Right_Loc + J) then return True; end if; end loop; return False; end; end UI_Ne; ---------------- -- UI_Negate -- ---------------- function UI_Negate (Right : Uint) return Uint is begin -- Case where input is directly represented. Note that since the range -- of Direct values is non-symmetrical, the result may not be directly -- represented, this is taken care of in UI_From_Int. if Direct (Right) then return UI_From_Int (-Direct_Val (Right)); -- Full processing for multi-digit case. Note that we cannot just copy -- the value to the end of the table negating the first digit, since the -- range of Direct values is non-symmetrical, so we can have a negative -- value that is not Direct whose negation can be represented directly. else declare R_Length : constant Int := N_Digits (Right); R_Vec : UI_Vector (1 .. R_Length); Neg : Boolean; begin Init_Operand (Right, R_Vec); Neg := R_Vec (1) > Int_0; R_Vec (1) := abs R_Vec (1); return Vector_To_Uint (R_Vec, Neg); end; end if; end UI_Negate; ------------- -- UI_Rem -- ------------- function UI_Rem (Left : Int; Right : Uint) return Uint is begin return UI_Rem (UI_From_Int (Left), Right); end UI_Rem; function UI_Rem (Left : Uint; Right : Int) return Uint is begin return UI_Rem (Left, UI_From_Int (Right)); end UI_Rem; function UI_Rem (Left, Right : Uint) return Uint is Remainder : Uint; Quotient : Uint; pragma Warnings (Off, Quotient); begin pragma Assert (Right /= Uint_0); if Direct (Right) and then Direct (Left) then return UI_From_Int (Direct_Val (Left) rem Direct_Val (Right)); else UI_Div_Rem (Left, Right, Quotient, Remainder, Discard_Quotient => True); return Remainder; end if; end UI_Rem; ------------ -- UI_Sub -- ------------ function UI_Sub (Left : Int; Right : Uint) return Uint is begin return UI_Add (Left, -Right); end UI_Sub; function UI_Sub (Left : Uint; Right : Int) return Uint is begin return UI_Add (Left, -Right); end UI_Sub; function UI_Sub (Left : Uint; Right : Uint) return Uint is begin if Direct (Left) and then Direct (Right) then return UI_From_Int (Direct_Val (Left) - Direct_Val (Right)); else return UI_Add (Left, -Right); end if; end UI_Sub; -------------- -- UI_To_CC -- -------------- function UI_To_CC (Input : Uint) return Char_Code is begin if Direct (Input) then return Char_Code (Direct_Val (Input)); -- Case of input is more than one digit else declare In_Length : constant Int := N_Digits (Input); In_Vec : UI_Vector (1 .. In_Length); Ret_CC : Char_Code; begin Init_Operand (Input, In_Vec); -- We assume value is positive Ret_CC := 0; for Idx in In_Vec'Range loop Ret_CC := Ret_CC * Char_Code (Base) + Char_Code (abs In_Vec (Idx)); end loop; return Ret_CC; end; end if; end UI_To_CC; ---------------- -- UI_To_Int -- ---------------- function UI_To_Int (Input : Uint) return Int is pragma Assert (Input /= No_Uint); begin if Direct (Input) then return Direct_Val (Input); -- Case of input is more than one digit else declare In_Length : constant Int := N_Digits (Input); In_Vec : UI_Vector (1 .. In_Length); Ret_Int : Int; begin -- Uints of more than one digit could be outside the range for -- Ints. Caller should have checked for this if not certain. -- Fatal error to attempt to convert from value outside Int'Range. pragma Assert (UI_Is_In_Int_Range (Input)); -- Otherwise, proceed ahead, we are OK Init_Operand (Input, In_Vec); Ret_Int := 0; -- Calculate -|Input| and then negates if value is positive. This -- handles our current definition of Int (based on 2s complement). -- Is it secure enough??? for Idx in In_Vec'Range loop Ret_Int := Ret_Int * Base - abs In_Vec (Idx); end loop; if In_Vec (1) < Int_0 then return Ret_Int; else return -Ret_Int; end if; end; end if; end UI_To_Int; -------------- -- UI_Write -- -------------- procedure UI_Write (Input : Uint; Format : UI_Format := Auto) is begin Image_Out (Input, False, Format); end UI_Write; --------------------- -- Vector_To_Uint -- --------------------- function Vector_To_Uint (In_Vec : UI_Vector; Negative : Boolean) return Uint is Size : Int; Val : Int; begin -- The vector can contain leading zeros. These are not stored in the -- table, so loop through the vector looking for first non-zero digit for J in In_Vec'Range loop if In_Vec (J) /= Int_0 then -- The length of the value is the length of the rest of the vector Size := In_Vec'Last - J + 1; -- One digit value can always be represented directly if Size = Int_1 then if Negative then return Uint (Int (Uint_Direct_Bias) - In_Vec (J)); else return Uint (Int (Uint_Direct_Bias) + In_Vec (J)); end if; -- Positive two digit values may be in direct representation range elsif Size = Int_2 and then not Negative then Val := In_Vec (J) * Base + In_Vec (J + 1); if Val <= Max_Direct then return Uint (Int (Uint_Direct_Bias) + Val); end if; end if; -- The value is outside the direct representation range and must -- therefore be stored in the table. Expand the table to contain -- the count and digits. The index of the new table entry will be -- returned as the result. Uints.Append ((Length => Size, Loc => Udigits.Last + 1)); if Negative then Val := -In_Vec (J); else Val := +In_Vec (J); end if; Udigits.Append (Val); for K in 2 .. Size loop Udigits.Append (In_Vec (J + K - 1)); end loop; return Uints.Last; end if; end loop; -- Dropped through loop only if vector contained all zeros return Uint_0; end Vector_To_Uint; end Uintp; gprbuild-gpl-2014-src/gnat/errutil.ads0000644000076700001450000001604712323721731017253 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- E R R U T I L -- -- -- -- S p e c -- -- -- -- Copyright (C) 2002-2012, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package contains routines to output error messages and the -- corresponding instantiation of Styleg, suitable to instantiate Scng. -- It uses the same global variables as Errout, located in packages Atree and -- Err_Vars. Like Errout, it also uses the common variables and routines -- in package Erroutc. -- This package is used by the preprocessor (gprep.adb) and the project -- manager (prj-err.ads). with Styleg; with Types; use Types; package Errutil is --------------------------------------------------------- -- Error Message Text and Message Insertion Characters -- --------------------------------------------------------- -- Error message text strings are composed of lower case letters, digits -- and the special characters space, comma, period, colon and semicolon, -- apostrophe and parentheses. Special insertion characters can also -- appear which cause the error message circuit to modify the given -- string. For a full list of these, see the spec of errout. ----------------------------------------------------- -- Format of Messages and Manual Quotation Control -- ----------------------------------------------------- -- Messages are generally all in lower case, except for inserted names -- and appear in one of the following two forms: -- error: text -- warning: text -- The prefixes error and warning are supplied automatically (depending -- on the use of the ? insertion character), and the call to the error -- message routine supplies the text. The "error: " prefix is omitted -- in brief error message formats. -- Reserved keywords in the message are in the default keyword case -- (determined from the given source program), surrounded by quotation -- marks. This is achieved by spelling the reserved word in upper case -- letters, which is recognized as a request for insertion of quotation -- marks by the error text processor. Thus for example: -- Error_Msg_AP ("IS expected"); -- would result in the output of one of the following: -- error: "is" expected -- error: "IS" expected -- error: "Is" expected -- the choice between these being made by looking at the casing convention -- used for keywords (actually the first compilation unit keyword) in the -- source file. -- In the case of names, the default mode for the error text processor -- is to surround the name by quotation marks automatically. The case -- used for the identifier names is taken from the source program where -- possible, and otherwise is the default casing convention taken from -- the source file usage. -- In some cases, better control over the placement of quote marks is -- required. This is achieved using manual quotation mode. In this mode, -- one or more insertion sequences is surrounded by backquote characters. -- The backquote characters are output as double quote marks, and normal -- automatic insertion of quotes is suppressed between the double quotes. -- For example: -- Error_Msg_AP ("`END &;` expected"); -- generates a message like -- error: "end Open_Scope;" expected -- where the node specifying the name Open_Scope has been stored in -- Error_Msg_Node_1 prior to the call. The great majority of error -- messages operates in normal quotation mode. -- Note: the normal automatic insertion of spaces before insertion -- sequences (such as those that come from & and %) is suppressed in -- manual quotation mode, so blanks, if needed as in the above example, -- must be explicitly present. ------------------------------ -- Error Output Subprograms -- ------------------------------ procedure Initialize; -- Initializes for output of error messages. Must be called for each -- file before using any of the other routines in the package. procedure Finalize (Source_Type : String := "project"); -- Finalize processing of error messages for one file and output message -- indicating the number of detected errors. -- Source_Type is used in verbose mode to indicate the type of the source -- being parsed (project file, definition file or input file for the -- preprocessor). procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr); -- Output a message at specified location procedure Error_Msg_S (Msg : String); -- Output a message at current scan pointer location procedure Error_Msg_SC (Msg : String); -- Output a message at the start of the current token, unless we are at -- the end of file, in which case we always output the message after the -- last real token in the file. procedure Error_Msg_SP (Msg : String); -- Output a message at the start of the previous token procedure Set_Ignore_Errors (To : Boolean); -- Indicate, when To = True, that all reported errors should -- be ignored. By default reported errors are not ignored. package Style is new Styleg (Error_Msg => Error_Msg, Error_Msg_S => Error_Msg_S, Error_Msg_SC => Error_Msg_SC, Error_Msg_SP => Error_Msg_SP); -- Instantiation of the generic style package, suitable for an -- instantiation of Scng. end Errutil; gprbuild-gpl-2014-src/gnat/restrict.adb0000644000076700001450000014051412323721731017400 0ustar gnatmailgnat------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- R E S T R I C T -- -- -- -- B o d y -- -- -- -- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT 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 distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ with Aspects; use Aspects; with Atree; use Atree; with Casing; use Casing; with Einfo; use Einfo; with Errout; use Errout; with Debug; use Debug; with Fname; use Fname; with Fname.UF; use Fname.UF; with Lib; use Lib; with Opt; use Opt; with Sinfo; use Sinfo; with Sinput; use Sinput; with Snames; use Snames; with Stand; use Stand; with Uname; use Uname; package body Restrict is ------------------------------- -- SPARK Restriction Control -- ------------------------------- -- SPARK HIDE directives allow the effect of the SPARK_05 restriction to be -- turned off for a specified region of code, and the following tables are -- the data structures used to keep track of these regions. -- The table contains pairs of source locations, the first being the start -- location for hidden region, and the second being the end location. -- Note that the start location is included in the hidden region, while -- the end location is excluded from it. (It typically corresponds to the -- next token during scanning.) type SPARK_Hide_Entry is record Start : Source_Ptr; Stop : Source_Ptr; end record; package SPARK_Hides is new Table.Table ( Table_Component_Type => SPARK_Hide_Entry, Table_Index_Type => Natural, Table_Low_Bound => 1, Table_Initial => 100, Table_Increment => 200, Table_Name => "SPARK Hides"); -------------------------------- -- Package Local Declarations -- -------------------------------- Config_Cunit_Boolean_Restrictions : Save_Cunit_Boolean_Restrictions; -- Save compilation unit restrictions set by config pragma files Restricted_Profile_Result : Boolean := False; -- This switch memoizes the result of Restricted_Profile function calls for -- improved efficiency. Valid only if Restricted_Profile_Cached is True. -- Note: if this switch is ever set True, it is never turned off again. Restricted_Profile_Cached : Boolean := False; -- This flag is set to True if the Restricted_Profile_Result contains the -- correct cached result of Restricted_Profile calls. No_Specification_Of_Aspects : array (Aspect_Id) of Source_Ptr := (others => No_Location); -- Entries in this array are set to point to a previously occuring pragma -- that activates a No_Specification_Of_Aspect check. No_Specification_Of_Aspect_Warning : array (Aspect_Id) of Boolean := (others => True); -- An entry in this array is set False in reponse to a previous call to -- Set_No_Speficiation_Of_Aspect for pragmas in the main unit that -- specify Warning as False. Once set False, an entry is never reset. No_Specification_Of_Aspect_Set : Boolean := False; -- Set True if any entry of No_Specifcation_Of_Aspects has been set True. -- Once set True, this is never turned off again. No_Use_Of_Attribute : array (Attribute_Id) of Source_Ptr := (others => No_Location); No_Use_Of_Attribute_Warning : array (Attribute_Id) of Boolean := (others => False); No_Use_Of_Attribute_Set : Boolean := False; -- Indicates that No_Use_Of_Attribute was set at least once No_Use_Of_Pragma : array (Pragma_Id) of Source_Ptr := (others => No_Location); No_Use_Of_Pragma_Warning : array (Pragma_Id) of Boolean := (others => False); No_Use_Of_Pragma_Set : Boolean := False; -- Indicates that No_Use_Of_Pragma was set at least once ----------------------- -- Local Subprograms -- ----------------------- procedure Restriction_Msg (R : Restriction_Id; N : Node_Id); -- Called if a violation of restriction R at node N is found. This routine -- outputs the appropriate message or messages taking care of warning vs -- real violation, serious vs non-serious, implicit vs explicit, the second -- message giving the profile name if needed, and the location information. function Same_Unit (U1, U2 : Node_Id) return Boolean; -- Returns True iff U1 and U2 represent the same library unit. Used for -- handling of No_Dependence => Unit restriction case. function Suppress_Restriction_Message (N : Node_Id) return Boolean; -- N is the node for a possible restriction violation message, but the -- message is to be suppressed if this is an internal file and this file is -- not the main unit. Returns True if message is to be suppressed. ------------------- -- Abort_Allowed -- ------------------- function Abort_Allowed return Boolean is begin if Restrictions.Set (No_Abort_Statements) and then Restrictions.Set (Max_Asynchronous_Select_Nesting) and then Restrictions.Value (Max_Asynchronous_Select_Nesting) = 0 then return False; else return True; end if; end Abort_Allowed; ---------------------------------------- -- Add_To_Config_Boolean_Restrictions -- ---------------------------------------- procedure Add_To_Config_Boolean_Restrictions (R : Restriction_Id) is begin Config_Cunit_Boolean_Restrictions (R) := True; end Add_To_Config_Boolean_Restrictions; -- Add specified restriction to stored configuration boolean restrictions. -- This is used for handling the special case of No_Elaboration_Code. ------------------------- -- Check_Compiler_Unit -- ------------------------- procedure Check_Compiler_Unit (Feature : String; N : Node_Id) is begin if Compiler_Unit then Error_Msg_N (Feature & " not allowed in compiler unit!!??", N); end if; end Check_Compiler_Unit; procedure Check_Compiler_Unit (Feature : String; Loc : Source_Ptr) is begin if Compiler_Unit then Error_Msg (Feature & " not allowed in compiler unit!!??", Loc); end if; end Check_Compiler_Unit; ------------------------------------ -- Check_Elaboration_Code_Allowed -- ------------------------------------ procedure Check_Elaboration_Code_Allowed (N : Node_Id) is begin Check_Restriction (No_Elaboration_Code, N); end Check_Elaboration_Code_Allowed; -------------------------------- -- Check_No_Implicit_Aliasing -- -------------------------------- procedure Check_No_Implicit_Aliasing (Obj : Node_Id) is E : Entity_Id; begin -- If restriction not active, nothing to check if not Restriction_Active (No_Implicit_Aliasing) then return; end if; -- If we have an entity name, check entity if Is_Entity_Name (Obj) then E := Entity (Obj); -- Restriction applies to entities that are objects if Is_Object (E) then if Is_Aliased (E) then return; elsif Present (Renamed_Object (E)) then Check_No_Implicit_Aliasing (Renamed_Object (E)); return; end if; -- If we don't have an object, then it's OK else return; end if; -- For selected component, check selector elsif Nkind (Obj) = N_Selected_Component then Check_No_Implicit_Aliasing (Selector_Name (Obj)); return; -- Indexed component is OK if aliased components elsif Nkind (Obj) = N_Indexed_Component then if Has_Aliased_Components (Etype (Prefix (Obj))) or else (Is_Access_Type (Etype (Prefix (Obj))) and then Has_Aliased_Components (Designated_Type (Etype (Prefix (Obj))))) then return; end if; -- For type conversion, check converted expression elsif Nkind_In (Obj, N_Unchecked_Type_Conversion, N_Type_Conversion) then Check_No_Implicit_Aliasing (Expression (Obj)); return; -- Explicit dereference is always OK elsif Nkind (Obj) = N_Explicit_Dereference then return; end if; -- If we fall through, then we have an aliased view that does not meet -- the rules for being explicitly aliased, so issue restriction msg. Check_Restriction (No_Implicit_Aliasing, Obj); end Check_No_Implicit_Aliasing; ----------------------------------------- -- Check_Implicit_Dynamic_Code_Allowed -- ----------------------------------------- procedure Check_Implicit_Dynamic_Code_Allowed (N : Node_Id) is begin Check_Restriction (No_Implicit_Dynamic_Code, N); end Check_Implicit_Dynamic_Code_Allowed; ---------------------------------- -- Check_No_Implicit_Heap_Alloc -- ---------------------------------- procedure Check_No_Implicit_Heap_Alloc (N : Node_Id) is begin Check_Restriction (No_Implicit_Heap_Allocations, N); end Check_No_Implicit_Heap_Alloc; ----------------------------------- -- Check_Obsolescent_2005_Entity -- ----------------------------------- procedure Check_Obsolescent_2005_Entity (E : Entity_Id; N : Node_Id) is function Chars_Is (E : Entity_Id; S : String) return Boolean; -- Return True iff Chars (E) matches S (given in lower case) -------------- -- Chars_Is -- -------------- function Chars_Is (E : Entity_Id; S : String) return Boolean is Nam : constant Name_Id := Chars (E); begin if Length_Of_Name (Nam) /= S'Length then return False; else return Get_Name_String (Nam) = S; end if; end Chars_Is; -- Start of processing for Check_Obsolescent_2005_Entity begin if Restriction_Check_Required (No_Obsolescent_Features) and then Ada_Version >= Ada_2005 and then Chars_Is (Scope (E), "handling") and then Chars_Is (Scope (Scope (E)), "characters") and then Chars_Is (Scope (Scope (Scope (E))), "ada") and then Scope (Scope (Scope (Scope (E)))) = Standard_Standard then if Chars_Is (E, "is_character") or else Chars_Is (E, "is_string") or else Chars_Is (E, "to_character") or else Chars_Is (E, "to_string") or else Chars_Is (E, "to_wide_character") or else Chars_Is (E, "to_wide_string") then Check_Restriction (No_Obsolescent_Features, N); end if; end if; end Check_Obsolescent_2005_Entity; --------------------------- -- Check_Restricted_Unit -- --------------------------- procedure Check_Restricted_Unit (U : Unit_Name_Type; N : Node_Id) is begin if Suppress_Restriction_Message (N) then return; elsif Is_Spec_Name (U) then declare Fnam : constant File_Name_Type := Get_File_Name (U, Subunit => False); begin -- Get file name Get_Name_String (Fnam); -- Nothing to do if name not at least 5 characters long ending -- in .ads or .adb extension, which we strip. if Name_Len < 5 or else (Name_Buffer (Name_Len - 3 .. Name_Len) /= ".ads" and then Name_Buffer (Name_Len - 3 .. Name_Len) /= ".adb") then return; end if; -- Strip extension and pad to eight characters Name_Len := Name_Len - 4; Add_Str_To_Name_Buffer ((Name_Len + 1 .. 8 => ' ')); -- If predefined unit, check the list of restricted units if Is_Predefined_File_Name (Fnam) then for J in Unit_Array'Range loop if Name_Len = 8 and then Name_Buffer (1 .. 8) = Unit_Array (J).Filenm then Check_Restriction (Unit_Array (J).Res_Id, N); end if; end loop; -- If not predefined unit, then one special check still -- remains. GNAT.Current_Exception is not allowed if we have -- restriction No_Exception_Propagation active. else if Name_Buffer (1 .. 8) = "g-curexc" then Check_Restriction (No_Exception_Propagation, N); end if; end if; end; end if; end Check_Restricted_Unit; ----------------------- -- Check_Restriction -- ----------------------- procedure Check_Restriction (R : Restriction_Id; N : Node_Id; V : Uint := Uint_Minus_1) is Msg_Issued : Boolean; pragma Unreferenced (Msg_Issued); begin Check_Restriction (Msg_Issued, R, N, V); end Check_Restriction; procedure Check_Restriction (Msg_Issued : out Boolean; R : Restriction_Id; N : Node_Id; V : Uint := Uint_Minus_1) is VV : Integer; -- V converted to integer form. If V is greater than Integer'Last, -- it is reset to minus 1 (unknown value). procedure Update_Restrictions (Info : in out Restrictions_Info); -- Update violation information in Info.Violated and Info.Count ------------------------- -- Update_Restrictions -- ------------------------- procedure Update_Restrictions (Info : in out Restrictions_Info) is begin -- If not violated, set as violated now if not Info.Violated (R) then Info.Violated (R) := True; if R in All_Parameter_Restrictions then if VV < 0 then Info.Unknown (R) := True; Info.Count (R) := 1; else Info.Count (R) := VV; end if; end if; -- Otherwise if violated already and a parameter restriction, -- update count by maximizing or summing depending on restriction. elsif R in All_Parameter_Restrictions then -- If new value is unknown, result is unknown if VV < 0 then Info.Unknown (R) := True; -- If checked by maximization, do maximization elsif R in Checked_Max_Parameter_Restrictions then Info.Count (R) := Integer'Max (Info.Count (R), VV); -- If checked by adding, do add, checking for overflow elsif R in Checked_Add_Parameter_Restrictions then declare pragma Unsuppress (Overflow_Check); begin Info.Count (R) := Info.Count (R) + VV; exception when Constraint_Error => Info.Count (R) := Integer'Last; Info.Unknown (R) := True; end; -- Should not be able to come here, known counts should only -- occur for restrictions that are Checked_max or Checked_Sum. else raise Program_Error; end if; end if; end Update_Restrictions; -- Start of processing for Check_Restriction begin Msg_Issued := False; -- In CodePeer and SPARK mode, we do not want to check for any -- restriction, or set additional restrictions other than those already -- set in gnat1drv.adb so that we have consistency between each -- compilation. -- Just checking, SPARK does not allow restrictions to be set ??? if CodePeer_Mode or GNATprove_Mode then return; end if; -- In SPARK mode, issue an error for any use of class-wide, even if the -- No_Dispatch restriction is not set. if R = No_Dispatch then Check_SPARK_Restriction ("class-wide is not allowed", N); end if; if UI_Is_In_Int_Range (V) then VV := Integer (UI_To_Int (V)); else VV := -1; end if; -- Count can only be specified in the checked val parameter case pragma Assert (VV < 0 or else R in Checked_Val_Parameter_Restrictions); -- Nothing to do if value of zero specified for parameter restriction if VV = 0 then return; end if; -- Update current restrictions Update_Restrictions (Restrictions); -- If in main extended unit, update main restrictions as well. Note -- that as usual we check for Main_Unit explicitly to deal with the -- case of configuration pragma files. if Current_Sem_Unit = Main_Unit or else In_Extended_Main_Source_Unit (N) then Update_Restrictions (Main_Restrictions); end if; -- Nothing to do if restriction message suppressed if Suppress_Restriction_Message (N) then null; -- If restriction not set, nothing to do elsif not Restrictions.Set (R) then null; -- Don't complain about No_Obsolescent_Features in an instance, since we -- will complain on the template, which is much better. Are there other -- cases like this ??? Do we need a more general mechanism ??? elsif R = No_Obsolescent_Features and then Instantiation_Location (Sloc (N)) /= No_Location then null; -- Here if restriction set, check for violation (this is a Boolean -- restriction, or a parameter restriction with a value of zero and an -- unknown count, or a parameter restriction with a known value that -- exceeds the restriction count). elsif R in All_Boolean_Restrictions or else (Restrictions.Unknown (R) and then Restrictions.Value (R) = 0) or else Restrictions.Count (R) > Restrictions.Value (R) then Msg_Issued := True; Restriction_Msg (R, N); end if; end Check_Restriction; ------------------------------------- -- Check_Restriction_No_Dependence -- ------------------------------------- procedure Check_Restriction_No_Dependence (U : Node_Id; Err : Node_Id) is DU : Node_Id; begin -- Ignore call if node U is not in the main source unit. This avoids -- cascaded errors, e.g. when Ada.Containers units with other units. -- However, allow Standard_Location here, since this catches some cases -- of constructs that get converted to run-time calls. if not In_Extended_Main_Source_Unit (U) and then Sloc (U) /= Standard_Location then return; end if; -- Loop through entries in No_Dependence table to check each one in turn for J in No_Dependences.First .. No_Dependences.Last loop DU := No_Dependences.Table (J).Unit; if Same_Unit (U, DU) then Error_Msg_Sloc := Sloc (DU); Error_Msg_Node_1 := DU; if No_Dependences.Table (J).Warn then Error_Msg ("?*?violation of restriction `No_Dependence '='> &`#", Sloc (Err)); else Error_Msg ("|violation of restriction `No_Dependence '='> &`#", Sloc (Err)); end if; return; end if; end loop; end Check_Restriction_No_Dependence; -------------------------------------------------- -- Check_Restriction_No_Specification_Of_Aspect -- -------------------------------------------------- procedure Check_Restriction_No_Specification_Of_Aspect (N : Node_Id) is A_Id : Aspect_Id; Id : Node_Id; begin -- Ignore call if no instances of this restriction set if not No_Specification_Of_Aspect_Set then return; end if; -- Ignore call if node N is not in the main source unit, since we only -- give messages for the main unit. This avoids giving messages for -- aspects that are specified in withed units. if not In_Extended_Main_Source_Unit (N) then return; end if; Id := Identifier (N); A_Id := Get_Aspect_Id (Chars (Id)); pragma Assert (A_Id /= No_Aspect); Error_Msg_Sloc := No_Specification_Of_Aspects (A_Id); if Error_Msg_Sloc /= No_Location then Error_Msg_Node_1 := Id; Error_Msg_Warn := No_Specification_Of_Aspect_Warning (A_Id); Error_Msg_N ("<* &`#", N); end if; end Check_Restriction_No_Use_Of_Attribute; ---------------------------------------- -- Check_Restriction_No_Use_Of_Pragma -- ---------------------------------------- procedure Check_Restriction_No_Use_Of_Pragma (N : Node_Id) is Id : constant Node_Id := Pragma_Identifier (N); P_Id : constant Pragma_Id := Get_Pragma_Id (Chars (Id)); begin -- Ignore call if node N is not in the main source unit, since we only -- give messages for the main unit. This avoids giving messages for -- aspects that are specified in withed units. if not In_Extended_Main_Source_Unit (N) then return; end if; -- If nothing set, nothing to check if not No_Use_Of_Pragma_Set then return; end if; Error_Msg_Sloc := No_Use_Of_Pragma (P_Id); if Error_Msg_Sloc /= No_Location then Error_Msg_Node_1 := Id; Error_Msg_Warn := No_Use_Of_Pragma_Warning (P_Id); Error_Msg_N ("<*