Для получения информации о внесении вклада в проект CUPS обратитесь к файлу Participation in CUPS.
Основной способ обращения с вопросами и неформального обсуждения проблем и требований к новым функциям — это списки рассылки CUPS. Список рассылки "cups" предназначен для вопросов использования CUPS и объявлений новых программ, включая бета-версии, а список рассылки "cups-devel" предоставляет форум для разработчиков CUPS и отслеживания новых ошибок.
Интерфейсы CUPS, включая C API и командные строки, переменные окружения, конфигурационные файлы и формат вывода данных, являются стабильными между патчами версий и обычно совместимыми с предыдущими основными и минорными версиями. Однако программные интерфейсы, такие как те, что используются планировщиком для запуска фильтров, мониторов портов и процессов backends для обработки задач, следует считать стабильными только с точки зрения фильтров, мониторов портов и backends. Программы, имитирующие планировщика для запуска этих программ вне CUPS, должны обязательно обновляться при изменении соответствующего интерфейса в последующих выпусках CUPS; в противном случае может произойти неопределенное поведение.C API CUPS, начинающиеся со знака подчеркивания (_), считаются приватными для CUPS и не подлежат обычным гарантиям стабильности между выпусками CUPS и никогда не должны использоваться в исходном коде, отличном от CUPS. Аналогично, конфигурационные и состояние файлы, созданные CUPS, считаются приватными, если соответствующая страница справки не предоставляется вместе с выпуском CUPS. Никогда не полагайтесь на незадокументированные файлы или форматы при разработке программного обеспечения для CUPS. Всегда используйте опубликованный C API для доступа к данным, хранящимся в файлах, чтобы избежать проблем совместимости в будущем.
CUPS использует трехчастную систему версионирования, разделённую точками, чтобы представить номера основной, второстепенной и патч-версий. Номера основной версии указывают на крупные изменения дизайна или обратно-несовместимые изменения в API CUPS или Imaging API CUPS. Номера второстепенной версии указывают на новые возможности и другие более мелкие изменения, совместимые с предыдущими версиями CUPS. Номера патчей указывают на исправления ошибок в предыдущих версиях функциональности или патчей. Эта система нумерации версий согласуется со спецификацией Семантического Версионирования.
Примечание:
Когда мы говорим о совместимости, имеется в виду бинарная совместимость для открытых API и совместимость формата вывода для программных интерфейсов. Изменения в формате конфигурационных файлов или по умолчанию поведение программ обычно не считаются несовместимыми, так как процесс обновления может гладко учесть такие изменения.
Производственные выпуски используют простую систему нумерации версий:
MAJOR.MINOR.PATCH
1.0.0
...
1.1.0
...
1.1.23
...
2.0.0
...
2.1.0
2.1.1
2.1.2
2.1.3
```Первый производственный выпуск в серии MAJOR.MINOR (MAJOR.MINOR.0) называется выпуском функциональности. Выпуски функциональности — это единственные выпуски, которые могут содержать новые возможности. Подsequent производственные выпуски в серии MAJOR.MINOR могут содержать только исправления ошибок.
Исправлено:
Подsequent -> Подsequent (следующий)
MAJOR.MINORbNUMBER 2.2b1
Кандидаты на выпуск идентифицируются путём добавления букв RC к номерам основной и второстепенной версий, за которыми следует номер кандидата на выпуск:
MAJOR.MINORrcNUMBER 2.2rc1
Руководства по кодированию
---------------------------
Представленный исходный код должен следовать нижеуказанным руководствам. Хотя примеры даны для исходных файлов на C и C++, исходный код для других языков также должен соответствовать этим руководствам в рамках возможностей данного языка.
Комментарии к исходному коду предоставляют справочную часть Книги программиста CUPS, которая генерируется с помощью программы [codedoc](https://www.msweet.org/codedoc).
### Исходные файлы
Имена всех исходных файлов должны содержать 16 символов или меньше для обеспечения совместимости с более старыми файловыми системами UNIX. Исходные файлы, содержащие функции, имеют расширение ".c" для языка C и ".cxx" для исходных файлов на языке C++. Все остальные файлы включения имеют расширение ".h". Отступы установлены на 8 символов или столбцов.
> **Примечание**:
>
> Расширение ".cxx" используется потому что это единственный общий для C++ расширение между Linux, macOS, UNIX и Windows.В начале каждого исходного файла находится заголовок, который указывает назначение или природу исходного файла и информацию о правах авторства и лицензии:
/*
* Description of the file content.
*
* Copyright © 2017 Apple Inc.
*
* Licensed under the Apache License, Version 2.0. See the LICENSE file for details.
*/
### Заголовочные файлы
Все публичные заголовочные файлы должны включать заголовочный файл `versioning.h` или заголовочный файл, который его включает. Объявления функций затем "украшаются" корректным макросом `_CUPS_API_major_minor`, чтобы определить доступность функции в зависимости от среды сборки, например:
extern int cupsDoThis(int foo, int bar) _CUPS_API_2_2;
Заголовочные файлы частного API должны иметь суффикс `-private`. Например, заголовочный файл `cups.h` определяет все публичные API CUPS, а заголовочный файл `cups-private.h` определяет все частные API CUPS. Как правило, заголовочный файл частного API будет включать соответствующий ему публичный API заголовочный файл.
### КомментарииВсе исходные коды используют блочные комментарии внутри функций для описания операций, выполняемых группой заявлений; избегайте помещения комментария на каждую строку, если это абсолютно необходимо, и тогда рассмотрите возможность рефакторинга кода так, чтобы этот комментарий был не нужен. Исходные файлы на языке C используют формат блочных комментариев ("/* комментарий */"), поскольку многие компиляторы C поставщиков до сих пор не поддерживают комментарии C99/C++ ("// комментарий"). /*
* Очистить массив состояния перед началом...
*/
for (i = 0; i < (sizeof(array) / sizeof(array[0])); i++)
array[i] = CUPS_STATE_IDLE;
/*
* Ждать изменения состояния в другом потоке...
*/
do
{
for (i = 0; i < (sizeof(array) / sizeof(array[0])); i++)
if (array[i] != CUPS_STATE_IDLE)
break;
if (i == (sizeof(array) / sizeof(array[0])))
time.sleep(1)
} while (i == (sizeof(array) / sizeof(array[0])))
### Отступы
Все блоки кода, заключенные в фигурные скобки, начинаются с открывающей скобки на новой строке. Код следует за скобкой на новой строке и отступается на два пробела. Закрывающая скобка располагается на новой строке после кода, начинаясь с исходной позиции отступа:
{ int i; /* Переменная цикла */
/*
for (i = 0; i < 1000; i++) { do_this(i); do_that(i); } }
Односимвольные операторы, следующие за "do", "else", "for", "if" и "while", также отступаются на два пробела. Блоки кода внутри блока "switch" отступаются на четыре пробела после каждого "case" и "default":
switch (array[i]) { case CUPS_STATE_IDLE : do_this(i); do_that(i); break;
default : do_nothing(i); break; }
### Пробелы
После каждого зарезервированного слова, такого как `if`, `while` и т.д., следует пробел. Пробелы между названием функции и аргументами в скобках не используются.
### Возвращаемые значения
Скобки окружают значения, возвращаемые из функции:```
return (CUPS_STATE_IDLE);
Функции глобального уровня имеют префикс маленькой буквы, за которым следуют прописные слова, например, cupsDoThis
, cupsDoThat
, cupsDoSomethingElse
, и т.д. Личные глобальные функции начинаются с нижнего подчеркивания, например, _cupsDoThis
, _cupsDoThat
, и т.д.
Локальные функции объявлены как статические с маленькими буквами и подчеркиваниями между словами, например, do_this
, do_that
, do_something_else
, и т.д.
Каждая функция начинается с комментария-шапки, описывающего, что делает функция, возможные ограничения входных данных (если они есть), возможные выходные значения (если они есть) и любую специальную информацию, необходимую:
/*
* 'do_this()' - Вычисляет y = this(x).
*
* Примечания: отсутствуют.
*/
static float /* O - Обратное значение мощности, 0.0 <= y <= 1.1 */
do_this(float x) /* I - Значение мощности (0.0 <= x <= 1.1) */
{
...
return (y);
}
Выходные/входные значения указываются с использованием префикса "O", входные значения — с префиксом "I", а значения, являющиеся как входными, так и выходными, — с префиксом "IO". Документация генератора codedoc также понимает следующие специальные тексты в комментариях описания функции: @deprecated@ - Отмечает функцию как устаревшую: не рекомендованную для новых разработок и запланированную к удалению. @link имя@ - Предоставляет гиперссылку на соответствующую функцию или определение типа. @since версия CUPS@ - Отмечает функцию как новую с указанной версией CUPS. @private@ - Отмечает функцию как приватную, чтобы она не была включена в документацию.### Переменные
Переменные с глобальным диапазоном имеют заглавные буквы, например, THISVARIABLE
, THATVARIABLE
, THISSTATEVARIABLE
и т.д. Глобальные переменные в библиотеках CUPS либо являются частью глобальных значений на уровне потока, управляемых функцией _cupsGlobals
, либо надлежащим образом защищены от параллельного доступа. Глобальные переменные следует заменять аргументами функций, когда это возможно.
Переменные с локальным диапазоном имеют строчные буквы с нижними подчеркиваниями между словами, например, this_variable
, that_variable
и т.д. Любые "локально глобальные" переменные, используемые несколькими функциями внутри одного файла источника, объявлены как статические. Как и глобальные переменные, локальные статические переменные надлежащим образом защищены от параллельного доступа.
Каждая переменная объявляется на отдельной строке и немедленно за ней следует блок комментариев, описывающий переменную:
int THISVARIABLE; /* текущее состояние этого */
static int that_variable; /* текущее состояние того */
Все имена типов имеют строчные буквы с нижними подчеркиваниями между словами и _t
приписано в конце имени, например, cups_this_type_t
, cups_that_type_t
и т.д. Имена типов начинаются префиксом, обычно cups
или именем программы, чтобы избежать конфликтов с системными типами. Приватные имена типов начинаются с подчеркивания, например, _cups_this_t
, _cups_that_t
и т.д.У каждого типа есть блок комментариев сразу после определения типа:
typedef int cups_this_type_t; /* This type is used for the foobar CUPS options. */
Все имена структур имеют строчные буквы с нижними подчеркиваниями между словами и _s
приписано в конце имени, например, cups_this_s
, cups_that_s
и т.д. Имена структур начинаются префиксом, обычно cups
или именем программы, чтобы избежать конфликтов с системными типами. Приватные имена структур начинаются с подчеркивания, например, _cups_this_s
, _cups_that_s
и т.д. Каждая структура имеет блок комментариев сразу после объявления структуры, а каждый член структуры документирован аналогично политике названий переменных выше:
struct cups_this_struct_s /* This structure is intended for the foobar CUPS options. */
{
int this_member; /* Current state for this */
int that_member; /* Current state for that */
};
Все константные имена пишутся прописными буквами с нижним подчеркиванием между словами, например, CUPS_THIS_CONSTANT
, CUPS_THAT_CONSTANT
и т.д. Константы начинаются с прописной буквы префикса, обычно это CUPS_
или имя программы или типа. Приватные константы начинаются с подчеркивания, например, _CUPS_THIS_CONSTANT
, _CUPS_THAT_CONSTANT
и т.д.
Заполненные перечисления должны использоваться всякий раз, когда это возможно, чтобы позволить компилятору выполнять проверку типов.Блоки комментариев следуют сразу за каждой константой:
typedef enum cups_tray_e /* Перечисление поддонов */
{
CUPS_TRAY_THIS, /* Этот поддон */
CUPS_TRAY_THAT /* Тот поддон */
} cups_tray_t;
Следующие правила относятся к системе сборки на основе файла Makefile, используемому в CUPS. Эти стандарты были разработаны годами, чтобы обеспечить возможность сборки CUPS на максимальном количестве систем и сред.
Исходный код CUPS организован функционально в виде верхнего уровня файла Makefile, файла include и подкаталогов со своими собственными файлами Makefile и файлами зависимостей. Файлы с расширением .in
являются шаблонными файлами для программного обеспечения autoconf и используются для генерации статической версии соответствующего файла.
Каждый файл Makefile начинается с стандартного заголовка CUPS, содержащего описание файла, а также информацию о правах собственности CUPS и лицензии:
#
# Makefile для ...
#
# Copyright © 2017 Apple Inc.
#
# Распространяется в соответствии с лицензией Apache v2.0. Смотрите файл LICENSE для получения дополнительной информации.
#
цель:
команда цели
Взаимозависимости; мы предполагаем, что программа make поддерживает рекурсивные зависимости между целями, например:
цель: foo bar
команда цели
foo: bla
команда foo
bar:
команда bar
bla:
команда bla
Определение переменной; мы предполагаем, что программа make поддерживает определение переменных в командной строке или в файле make с помощью следующей формы:
имя=значение
Подстановка переменных; мы предполагаем, что программа make поддерживает подстановку переменных с помощью следующих форм:
- `$(имя)`; подставляет значение "имя",
- `$(имя:.старое=.новое)`; подставляет значение "имя", заменяя расширение файла ".старое"
на ".новое",
- `$(MAKEFLAGS)`; подставляет опции командной строки, переданные программе без начального дефиса (-),
- `$$`; подставляет одиночный символ $,
- `$<`; подставляет текущий исходный файл или зависимость,
- `$@`; подставляет текущее имя цели.
Расширения; мы предполагаем, что программа make поддерживает расширения файлов с предполагаемыми зависимостями, например: .SUFFIXES: .c .o .c.o: ЦЕЛЕНаправление $(CC) $(CFLAGS) -o $@ -c $<
Включение файлов; мы предполагаем, что программа make поддерживает директиву include, например:
include ../Makedefs
include Dependencies
Комментарии; мы предполагаем, что комментарии начинаются с символа # и продолжаются до конца текущей строки.
Длина строки; мы предполагаем, что фактических ограничений на длину строк нет.
Продолжение длинных строк; мы предполагаем, что символ \
может быть помещён в конце строки для
объединения двух или более строк в файле make в одну длинную строку.
Shell; мы предполагаем наличие совместимой с POSIX оболочки на системе сборки.
ALL_CFLAGS
; объединённые опции компилятора C,
ALL_CXXFLAGS
; объединённые опции компилятора C++,
AMANDIR
; директория установки административной страницы справки (раздел 8/1m в зависимости от платформы),
AR
; команда архиватора библиотек,
ARFLAGS
; опции для команды архиватора библиотек,
AWK
; локальная команда awk,
BINDIR
; директория установки исполняемых файлов,
BUILDROOT
; опциональный префикс установки (по умолчанию равен DSTROOT),
CC
; команда компилятора C,
CFLAGS
; опции для команды компилятора C,
CHMOD
; команда chmod,
CXX
; команда компилятора C++,
CXXFLAGS
; опции для команды компилятора C++,
DATADIR
; директория установки данных,
DSO
; команда сборки общедоступной C-библиотеки,
DSOXX
; команда сборки общедоступной C++-библиотеки,
DSOFLAGS
; опции для команды сборки общедоступной библиотеки,
INCLUDEDIR
; директория установки публичных заголовочных файлов,
INSTALL
; команда установки,
INSTALL_BIN
; команда установки исполняемых файлов,
INSTALL_COMPDATA
; команда установки сжатых данных,
INSTALL_CONFIG
; команда установки конфигурационных файлов,
INSTALL_DATA
; команда установки данных,
INSTALL_DIR
; команда установки директорий,
INSTALL_LIB
; команда установки библиотек,
INSTALL_MAN
; команда установки документации,
INSTALL_SCRIPT
; команда установки скриптов shell,
LD
; команда линковщика,
LDFLAGS
; опции для команды линковщика,- LIBDIR
; директория установки библиотек,
LIBS
; библиотеки для всех программ,
LN
; команда ln,
MAN1EXT
; расширение для страниц справки раздела 1,
MAN3EXT
; расширение для страниц справки раздела 3,
MAN5EXT
; расширение для страниц справки раздела 5,
MAN7EXT
; расширение для страниц справки раздела 7,
MAN8DIR
; поддиректория для страниц справки раздела 8,
MAN8EXT
; расширение для страниц справки раздела 8,
MANDIR
; директория установки страниц справки,
OPTIM
; общие опции оптимизации компилятора,
PRIVATEINCLUDE
; директория установки приватных заголовочных файлов,
RM
; команда rm,
SHELL
; команда sh (POSIX shell),
STRIP
; команда strip,
srcdir
; директория исходных файлов. ### Стандартные целиСледующие стандартные цели определены в каждом файле Make:
all
; создаёт все целевые программы, библиотеки и файлы документации,
clean
; удаляет все целевые программы, библиотеки, файлы документации и объектные файлы,
depend
; генерирует автоматические зависимости для любых файлов исходного кода на C или C++ (см. также "Зависимости"),
distclean
; удаляет сгенерированные файлами autoconf вместе с теми, что удаляются целью "clean",
install
; устанавливает все распределённые файлы в соответствующих местах (см. также "Поддержка установки/удаления"),
install-data
; устанавливает все данные файлы в соответствующих местах (см. также "Поддержка установки/удаления"),
install-exec
; устанавливает все исполняемые файлы в соответствующих местах (см. также "Поддержка установки/удаления"),
install-headers
; устанавливает все файлы заголовков в соответствующих местах (см. также "Поддержка установки/удаления"),
install-libs
; устанавливает все библиотечные файлы в соответствующих местах (см. также "Поддержка установки/удаления"), и
uninstall
; удаляет все распределённые файлы из соответствующих мест (см. также "Поддержка установки/удаления").
Объектные файлы (результат компиляции файла исходного кода на C или C++) имеют расширение ".o".
program: $(OBJS) TAB echo Связывание $@... TAB $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
### Статические библиотеки
Статические библиотеки имеют префикс "lib" и расширение ".a". Пример типичной цели статической библиотеки выглядит следующим образом:
```makefile
libname.a: $(OBJECTS)
TAB echo Создание $@...
TAB $(RM) $@
TAB $(AR) $(ARFLAGS) $@ $(OBJECTS)
TAB $(RANLIB) $@
Динамически загружаемые библиотеки имеют префикс "lib" и расширение ".dylib" или ".so", в зависимости от операционной системы. Пример типичной цели динамически загружаемой библиотеки выглядит следующим образом:
libname.so: $(OBJECTS)
TAB echo $(DSOCOMMAND) libname.so.$(DSOVERSION) ...
TAB $(DSOCOMMAND) libname.so.$(DSOVERSION) $(OBJECTS)
TAB $(RM) libname.so libname.so.$(DSOMAJOR)
TAB $(LN) libname.so.$(DSOVERSION) libname.so.$(DSOMAJOR)
TAB $(LN) libname.so.$(DSOVERSION) libname.so
libname.dylib: $(OBJECTS)
TAB echo $(DSOCOMMAND) libname.$(DSOVERSION).dylib ...
TAB $(DSOCOMMAND) libname.$(DSOVERSION).dylib \
TAB TAB -install_name $(libdir)/libname.$(DSOMAJOR).dylib \
TAB TAB -current_version libname.$(DSOVERSION).dylib \
TAB TAB -compatibility_version $(DSOMAJOR).0 \
TAB TAB $(OBJECTS) $(LIBS)
TAB $(RM) libname.dylib
TAB $(RM) libname.$(DSOMAJOR).dylib
TAB $(LN) libname.$(DSOVERSION).dylib libname.$(DSOMAJOR).dylib
TAB $(LN) libname.$(DSOVERSION).dylib libname.dylib
Статические зависимости указаны в каждом makefile после цели, например:
foo: bar
```Статические зависимости используются только тогда, когда автоматически сгенерировать их невозможно. Абсолютные зависимости хранятся в файле с именем "Dependencies" и включаются в конце makefile. Для создания абсолютных зависимостей используется следующее правило цели "depend": depend:
TAB $(CC) -MM $(ALL_CFLAGS) $(OBJS:.o=.c) > Dependencies
Мы регенерируем автоматические зависимости на системах macOS и указываем любые не-macOS зависимости статически в makefile.
### Поддержка установки/удаления
Все makefile содержат правила установки и удаления, которые устанавливают или удаляют соответствующее программное обеспечение. Эти правила должны использовать переменную $(BUILDROOT) как префикс для любого каталога установки, чтобы CUPS можно было установить в временное место для упаковки программами типа rpmbuild.
Переменные `INSTALL_BIN`, `INSTALL_COMPDATA`, `INSTALL_CONFIG`, `INSTALL_DATA`, `INSTALL_DIR`, `INSTALL_LIB`, `INSTALL_MAN` и `INSTALL_SCRIPT` должны использоваться при установке файлов, чтобы обеспечить правильное владение и права доступа установленных файлов.
Команда `$(RANLIB)` должна выполняться для всех статических библиотек после установки, так как таблица символов становится недействительной при копировании библиотеки на некоторых платформах.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )