E.8.4 Разные удобные функции для модулей

В этом подразделе описаны несколько удобных функций, предоставляемых API модулей. Как и функции, описанные в предыдущих подразделах, все они являются указателями на функции и должны вызываться через указатель emacs_env. Описание функций, появившихся после Emacs 25, содержит указание на первую версию, в которой они стали доступны.

Функция: bool eq (emacs_env *env, emacs_value a, emacs_value b)

Эта функция возвращает true, если объекты Lisp, представленные a и b, идентичны, и false в противном случае. Это то же самое, что и функция Lisp eq (см. Предикаты равенства), но позволяет избежать необходимости интернирования объектов, представленных аргументами.

В API нет функций для других предикатов равенства, поэтому вам потребуется использовать intern и funcall, описанные ниже, для выполнения более сложных проверок на равенство.

Функция: bool is_not_nil (emacs_env *env, emacs_value arg)

Эта функция проверяет, является ли объект Lisp, представленный arg, не-nil; она возвращает true или false соответственно.

Заметьте, что вы могли бы реализовать эквивалентную проверку, используя intern для получения emacs_value, представляющего nil, а затем используя eq, описанную выше, для проверки на равенство. Но использование этой функции удобнее.

Функция: emacs_value type_of (emacs_env *env, emacs_value arg)

Эта функция возвращает тип arg в виде значения, представляющего символ: string для строки, integer для целого числа, process для процесса и т.д. См. Предикаты типов. Вы можете использовать intern и eq для сравнения с известными символами типов, если вашему коду требуется зависеть от типа объекта.

Функция: emacs_value intern (emacs_env *env, const char *name)

Эта функция возвращает интернированный символ Emacs, имя которого равно name, которое должно быть ASCII-строкой, завершающейся нулевым байтом. Она создаёт новый символ, если такого ещё не существует.

Вместе с funcall, описанной ниже, эта функция предоставляет средство для вызова любой вызываемой из Lisp функции Emacs при условии, что её имя является чистой ASCII-строкой. Например, вот как интернировать символ, имя которого name_str не является ASCII, путём вызова более мощной функции Emacs intern (см. Создание и интернирование символов):

emacs_value fintern = env->intern (env, "intern");
emacs_value sym_name =
  env->make_string (env, name_str, strlen (name_str));
emacs_value symbol = env->funcall (env, fintern, 1, &sym_name);
Функция: emacs_value funcall (emacs_env *env, emacs_value func, ptrdiff_t nargs, emacs_value *args)

Эта функция вызывает указанную func, передавая ей nargs аргументов из массива, на который указывает args. Аргумент func может быть символом функции (например, возвращённым intern, описанной выше), функцией модуля, возвращённой make_function (см. Написание функций модулей), подпрограммой, написанной на C, и т.д. Если nargs равно нулю, args может быть указателем NULL.

Функция возвращает значение, которое вернула func.

Если ваш модуль содержит потенциально долго выполняющийся код, рекомендуется время от времени проверять в этом коде, не хочет ли пользователь выйти, например, набрав C-g (см. Выход). Для этой цели предназначена следующая функция, доступная начиная с Emacs 26.1.

Функция: bool should_quit (emacs_env *env)

Эта функция возвращает true, если пользователь хочет выйти. В этом случае мы рекомендуем, чтобы ваша функция модуля прерывала все текущие обработки и возвращала управление как можно скорее. В большинстве случаев используйте process_input вместо неё.

Для обработки событий ввода в дополнение к проверке, хочет ли пользователь выйти, используйте следующую функцию, доступную начиная с Emacs 27.1.

Функция: enum emacs_process_input_result process_input (emacs_env *env)

Эта функция обрабатывает ожидающие события ввода. Она возвращает emacs_process_input_quit, если пользователь хочет выйти или произошла ошибка при обработке сигналов. В этом случае мы рекомендуем, чтобы ваша функция модуля прерывала все текущие обработки и возвращала управление как можно скорее. Если код модуля может продолжить выполнение, process_input возвращает emacs_process_input_continue. Возвращаемое значение равно emacs_process_input_continue тогда и только тогда, когда в env нет ожидающего нелокального выхода. Если модуль продолжает работу после вызова process_input, глобальное состояние, такое как значения переменных и содержимое буферов, может быть изменено произвольным образом.

Функция: int open_channel (emacs_env *env, emacs_value pipe_process)

Эта функция, доступная начиная с Emacs 28, открывает канал к существующему процессу-каналу. pipe_process должен ссылаться на существующий процесс-канал, созданный с помощью make-pipe-process. Процессы-каналы. В случае успеха возвращаемым значением будет новый файловый дескриптор, который вы можете использовать для записи в канал. В отличие от всех остальных функций модуля, вы можете использовать возвращённый файловый дескриптор из произвольных потоков, даже если активное окружение модуля отсутствует. Вы можете использовать функцию write для записи в файловый дескриптор. По завершении закройте файловый дескриптор с помощью close. (libc)Низкоуровневый ввод/вывод.