Альтернативные схемы именования
Ранее мы рассмотрели использование директивы компилятора Source_File_Name, которая позволяет использовать произвольные имена для отдельных файлов с исходными текстами.
Этот подход требует наличия директивы для каждого файла именуемого произвольным образом.
Таким образом, в случае разработки большой системы, это ведет к значительному увеличению размеров файла gnat.adc
и, как следствие, может осложнить сопровождение проекта.
Начиная с версии 3.15, GNAT предусматривает возможность указания общей схемы именования файлов с исходными текстами, которая отличается от используемой по умолчанию стандартной схемы именования файлов.
Для этого используются показанные ниже формы директивы компилятора Source_File_Name:
pragma Source_File_Name ( Spec_File_Name => FILE_NAME_PATTERN [,Casing => CASING_SPEC] [,Dot_Replacement => STRING_LITERAL]);
pragma Source_File_Name ( Body_File_Name => FILE_NAME_PATTERN [,Casing => CASING_SPEC] [,Dot_Replacement => STRING_LITERAL]); pragma Source_File_Name ( Subunit_File_Name => FILE_NAME_PATTERN [,Casing => CASING_SPEC] [,Dot_Replacement => STRING_LITERAL]); FILE_NAME_PATTERN ::= STRING_LITERAL CASING_SPEC ::= Lowercase | Uppercase | Mixedcase |
Строка FILE_NAME_PATTERN является шаблоном имен файлов.
Она содержит один символ звездочки, вместо которого подставляется имя модуля.
Необязательный параметр Casing указывает используемый в имени файла регистр символов: Lowercase - нижний регистр (маленькие буквы), Uppercase - верхний регистр (большие буквы), Mixedcase - смешанное использование регистра символов.
При отсутствии параметра Casing, по умолчанию, используется Lowercase.
Необязательный параметр, строка Dot_Replacement, используется для подстановки вместо точек, которые присутствуют в именах субмодулей.
Когда строка Dot_Replacement не указывается, разделяющие точки неизменно присутствуют в имени файла.
Хотя показанный выше синтаксис демонстрирует, что параметр Casing
указывается перед параметром Dot_Replacement, допускается запись этих параметров в противоположной последовательности.
Из показанной выше формы директивы Source_File_Name видно, что возможно указание различных схем именования для тел, спецификаций и субмодулей.
Достаточно часто для именования субмодулей желательно использовать такое же правило как и для тел модулей.
В таком случае можно не указывать правило Subunit_File_Name, и для именования субмодулей будет использоваться правило Body_File_name.
Указание отдельного правила для именования субмодулей может быть использовано в случае реализации необычного окружения компиляции (например, при компиляции в одном каталоге), которое содержит субмодули и дочерние модули с одинаковыми именами.
Хотя оба модуля не могут одновременно присутствовать в одном разделе программы, стандарт допускает (но не требует) возможность сосуществования двух таких модулей в одном окружении.
Трансляция имен файлов включает следующие шаги:
Если для данного модуля существует соответствующая директива Source_File_Name, то всегда используется информация указанная в этой директиве, а любые другие шаблонные правила игнорируются.
Если указана директива Source_File_Name
задающая тип шаблона, который применим для модуля, то полученное имя файла будет использовано в случае существования соответствующего файла.
Когда обнаружено совпадение более одного шаблона, то первым проверяется последний шаблон, и, в итоге, будет использован результат первой успешной проверки существования файла.
Если директива Source_File_Name задающая тип шаблона применимого для модуля, для которого существует соответствующий файл, отсутствует, то используется правило именования, которое применяется по умолчанию и является стандартным для GNAT.
Как пример использования этого механизма рассмотрим распространенную схему именования, когда для имен файлов используется нижний регистр, разделительная точка неизменно копируется в результирующее имя файла, имена файлов спецификаций заканчиваются как ".1.ada", а имена файлов тел заканчиваются как ".2.ada".
GNAT будет следовать этой схеме при наличии двух директив:
pragma Source_File_Name (Spec_File_Name => "*.1.ada"); pragma Source_File_Name (Body_File_Name => "*.2.ada"); |
pragma Source_File_Name (Spec_File_Name => "*.ads", Dot_Replacement => "-"); pragma Source_File_Name (Body_File_Name => "*.adb", Dot_Replacement => "-"); |
Для всех имен файлов используется верхний регистр символов.
Естественно, что дочерние модули - не представлены, поскольку это компилятор Ada83, однако, будет логично расширить эту схему указанием использовать двойное подчеркивание в качестве разделителя для дочерних модулей.
pragma Source_File_Name (Spec_File_Name => "*_.ADA", Dot_Replacement => "__", Casing = Uppercase); pragma Source_File_Name (Body_File_Name => "*.ADA", Dot_Replacement => "__", Casing = Uppercase); pragma Source_File_Name (Subunit_File_Name => "*.SEP", Dot_Replacement => "__", Casing = Uppercase); |