PureBasic

Руководство - Директивы компилятора (для различного поведения на различных OS)

Это будет нашим последним визитом в программу сбора Свойств Файлов. Осталось последнее ограничение, которое мы должны преодолеть. Мы его оставили напоследок, потому что оно представляет собой особый случай.

До сих пор столбец Attributes на экране был просто значением типа integer. Это вызвано тем, что возвращаемые значения команд GetFileAttributes() и DirectoryEntryAttributes() в системах Windows отличаются от значений в системах Mac и Linux.

Мы не можем допустить такое различие результатов работы программы, но мы можем использовать Директивы компилятора, чтобы создать программу, которая будет менять алгоритм для получения параметров, в зависимости от того на какой операционной системе запущена.

Добавить новое описание процедуры в этот раздел.

Declare.s AttributeString(Attributes.l)

Добавить эту новую процедуру в раздел реализации.

Procedure.s AttributeString(Attributes.l)
    ; Преобразует целочисленное значение атрибута в строковый вид.
    ; Поддерживаются атрибуты системы Linux, Mac и Windows.

    Protected.s Result

    Result = ""

    CompilerIf #PB_Compiler_OS = #PB_OS_Windows

        ; Это атрибуты для систем Windows.
        ; Логическое И значения Attributes с каждой константой отфильтровывают заданный бит и затем используются для сравнения.

        If Attributes & #PB_FileSystem_Archive
            Result + "A"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_Compressed
            Result + "C"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_Hidden
            Result + "H"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_ReadOnly
            Result + "R"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_System
            Result + "S"
        Else
            Result + " "
        EndIf

    CompilerElse

        ; Это атрибуты для систем Mac и Linux.

        If Attributes & #PB_FileSystem_Link
            Result + "L "
        Else
            Result + " "
        EndIf

        ; Атрибуты пользователя.
        If Attributes & #PB_FileSystem_ReadUser
            Result + "R"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_WriteUser
            Result + "W"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_ExecUser
            Result + "X "
        Else
            Result + " "
        EndIf

        ; Групповые атрибуты.
        If Attributes & #PB_FileSystem_ReadGroup
            Result + "R"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_WriteGroup
            Result + "W"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_ExecGroup
            Result + "X "
        Else
            Result + " "
        EndIf

        ; Все атрибуты.
        If Attributes & #PB_FileSystem_ReadAll
            Result + "R"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_WriteAll
            Result + "W"
        Else
            Result + " "
        EndIf

        If Attributes & #PB_FileSystem_ExecAll
            Result + "X"
        Else
            Result + " "
        EndIf

    CompilerEndIf

    ; Возврат результата
    ProcedureReturn Result

EndProcedure

Наконец, замените эти две строки в процедуре ListLoad

; Преобразовывает атрибуты в строку.
Attrib = StrU(Files()\Attributes)

с ними,

; Вызов AttributeString для преобразования атрибутов в строковое представление.
Attrib = AttributeString(Files()\Attributes)

Теперь, при выполнении программы, на экране будут отображаться строковые данные вместо целочисленных значений. В системе Windows это выглядело бы примерно так (предполагается, что все атрибуты установлены):
  ACHRS
и в других двух системах:
  L RWX RWX RWX
Инструкция CompilerIf очень похожа на инструкцию IF однако компилятор принимает решение во время компиляции, а не во время выполнения. Это означает, что мы можем включать разный код для обработки атрибутов файлов в разных операционных системах.

Строки между:

CompilerIf #PB_Compiler_OS = #PB_OS_Windows

и
  CompilerElse
будут компилироваться в системах Windows. Константа #PB_Compiler_OS определяется в PureBasic автоматически, что позволяет работать в программе такому виду логики.

Другая секция кода будет использоваться в системах Mac и Linux - которые работают одинаково. Если бы эти операционные системы также имели бы разные значения атрибутов, мы могли бы использовать CompilerSelect и CompilerCase, чтобы сделать ветвление на три ветки кода.

CompilerSelect #PB_Compiler_OS

    CompilerCase #PB_OS_Linux
        ; Код для систем Linux.

    CompilerCase #PB_OS_MacOS
        ; Код для систем Mac.

    CompilerCase #PB_OS_Windows
        ; Код для систем Windows.

CompilerEndSelect

Последняя директива компилятора, которую мы собираемся обсудить это: EnableExplicit.

Есть серьезное основание для использования этой директивы. Она требует, чтобы все переменные были явно определены до использования каким-либо образом (использованием с Define, Dim, Global, Protected, Static и т.д.). Это устраняет возможность возникновения логических ошибок, которые появляются из-за того, что имена переменных с ошибками объявляются "на лету". Этот тип трудноуловимой ошибки может не влиять на компиляцию программы, но при этом, во время выполнения программы нарушает её работу. Использование этой директивы заставляет компилятор проверять все переменные на то, были ли они явно объявлены в коде, если нет, то выдаёт ошибку.

Например:

EnableExplicit

Define.l Field, FieldMax

; ...

If Field < FieldMax
    ; Если EnableExplicit не включен, этот раздел кода может не выполняться когда должен, потому что FieldMax будет нулевым.
EndIf

Навигация Руководства

< Структурирование кода в Процедурах - Обзор - Чтение и запись файлов >