glib-mkenums(1) General Commands Manual glib-mkenums(1)

glib-mkenums - ابزار استخراج توضیحات شمارشی C و تولید تعاریف GType

glib-mkenums [OPTION…] [FILE…]

دستور glib-mkenums ابزار کوچکی است که کدهای C را برای استخراج تعاریف enum تجزیه کرده و بر اساس الگوهای متنی مشخص‌شده توسط کاربر، توصیف‌های enum را تولید می‌کند. به طور معمول، می‌توانید از این ابزار برای تولید انواع شمارشی برای سیستم نوع GType، ویژگی‌های GObject و مرتب‌سازی سیگنال‌ها (signal marshalling) استفاده کنید؛ علاوه بر این، می‌توانید از آن برای تولید مقادیر شمارشی طرح‌واره‌های GSettings بهره ببرید.

دستور glib-mkenums فهرستی از پرونده‌های معتبر کد C را به عنوان ورودی دریافت می‌کند. گزینه‌های مشخص‌شده متن تولیدشده را کنترل کرده و کلیدواژه‌های گوناگون محصور در نویسه‌های @ را در الگوها جایگزین می‌نمایند.

از نسخهٔ 2.74، کتابخانهٔ GLib ماکروهای پیش‌پردازندهٔ C با نام‌های G_DEFINE_ENUM_TYPE و G_DEFINE_FLAGS_TYPE را ارائه می‌دهد. این ماکروها می‌توانند برای تعریف یک GType در پروژه‌هایی که دارای تعداد اندکی از انواع شمارشی کوچک هستند، بدون نیاز به درگیر شدن با پیچیدگی‌های تولید کد در زمان ساخت (build time)، به کار روند.

کلیدواژه‌های مشخصی که در نویسه‌های @ محصور شده‌اند در متن خروجی جایگزین خواهند شد. برای مثال‌های جایگزینی کلیدواژه‌های زیر، تعریف نمونهٔ enum زیر در نظر گرفته شده است:

typedef enum
{
  PREFIX_THE_XVALUE    = 1 << 3,
  PREFIX_ANOTHER_VALUE = 1 << 4
} PrefixTheXEnum;

@EnumName@

نام enum که هم‌اکنون در حال پردازش است؛ فرض می‌شود نام‌های enum دارای فضای نام مناسب بوده و برای جداسازی واژه‌ها از حروف کوچک و بزرگ ترکیبی استفاده می‌کنند (مانند PrefixTheXEnum).

@enum_name@

نام enum با واژه‌های حروف کوچک که با زیرخط از یکدیگر جدا شده‌اند (مانند prefix_the_xenum).

@ENUMNAME@

نام enum با واژه‌های حروف بزرگ که با زیرخط از یکدیگر جدا شده‌اند (مانند PREFIX_THE_XENUM).

@ENUMSHORT@

نام enum با واژه‌های حروف بزرگ و جداشده با زیرخط، با پیشوند حذف‌شده (مانند THE_XENUM).

@ENUMPREFIX@

پیشوند نام enum (مانند PREFIX).

@VALUENAME@

نام مقدار enum که هم‌اکنون در حال پردازش است، با واژه‌های حروف بزرگ و جداشده با زیرخط؛ این همان نگارش تحت‌اللفظی پیش‌فرض مقادیر enum در کدهای مبدأ C است (مانند PREFIX_THE_XVALUE).

@valuenick@

یک نام مستعار برای مقدار enum که هم‌اکنون در حال پردازش است؛ این مقدار معمولاً با حذف واژه‌های پیشوند مشترک تمامی مقادیر enum جاری تولید می‌شود که در آن واژه‌ها با حروف کوچک نوشته شده و زیرخط‌ها با خط تیره جایگزین می‌شوند (مانند the-xvalue).

@valuenum@

مقدار عدد صحیح برای مقدار enum که هم‌اکنون در حال پردازش است. اگر ارزیابی مقدار ناموفق باشد، glib-mkenums با وضعیت خطا خارج می‌شود، اما این اتفاق تنها در صورتی رخ می‌دهد که @valuenum@ در الگوی تولید مقادیر شما ظاهر شده باشد. (از نسخهٔ: 2.26)

@type@

بسته به این که آیا تعاریف مقدار enum شامل عملگرهای شیفت بیتی بوده‌اند یا خیر، این مقدار با ‘enum’ یا ‘flags’ جایگزین می‌شود (مانند flags).

@Type@

همانند @type@ با این تفاوت که حرف اول آن بزرگ است (مانند Flags).

@TYPE@

همانند @type@ با این تفاوت که تمام حروف آن بزرگ هستند (مانند FLAGS).

@filename@

مسیر کامل پروندهٔ ورودی که هم‌اکنون در حال پردازش است (مانند /build/environment/project/src/foo.h).

@basename@

نام پایه پرونده ورودی که در حال حاضر پردازش می‌شود (مانند foo.h). معمولاً برای بهبود بازتولیدپذیری ساخت، بهتر است در الگوهای خود به جای @filename@ از @basename@ استفاده کنید. (از نسخه: 2.22)

برخی از کامنت‌های C در تعاریف enum تجزیه‌شده به شکل ویژه‌ای پردازش می‌شوند؛ چنین کامنت‌هایی با توالی تری‌گراف /*< آغاز شده و با توالی تری‌گراف >*/ پایان می‌یابند.

گزینه‌های زیر را می‌توان به ازای هر تعریف enum مشخص کرد:

skip

مشخص می‌کند که باید از این تعریف enum صرف‌نظر شود.

flags

مشخص می‌کند که با این enum باید به عنوان یک تعریف پرچم (flags) رفتار شود.

underscore_name

جداسازی کلمات مورد استفاده در تابع *_get_type() را مشخص می‌کند. برای نمونه، /*< underscore_name=gnome_vfs_uri_hide_options >*/.

since

برچسب نسخه‌ای را مشخص می‌کند که برای جایگزینی کلمه کلیدی @enumsince@ در الگو استفاده خواهد شد؛ هنگام مستندسازی متدهای تولیدشده از enumها کاربرد دارد (مانند Since: @enumsince@). (از نسخه: 2.66)

گزینه‌های زیر را می‌توان به ازای هر تعریف مقدار مشخص کرد:

skip

مشخص می‌کند که باید از این مقدار صرف‌نظر شود.

nick

نام مستعاری را که در غیر این صورت به طور خودکار تولید می‌شد، مشخص می‌کند.

مثال‌ها:

typedef enum /*< skip >*/
{
  PREFIX_FOO
} PrefixThisEnumWillBeSkipped;
typedef enum /*< flags,prefix=PREFIX,since=1.0 >*/
{
  PREFIX_THE_ZEROTH_VALUE,   /*< skip >*/
  PREFIX_THE_FIRST_VALUE,
  PREFIX_THE_SECOND_VALUE,
  PREFIX_THE_THIRD_VALUE,    /*< nick=the-last-value >*/
} PrefixTheFlagsEnum;

--fhead <TEXT>

پیش از پردازش پرونده‌های ورودی، TEXT را خروجی می‌دهد.

می‌توانید این گزینه را چندین بار مشخص کنید و مقادیر TEXT به یکدیگر متصل خواهند شد.

هنگامی که همراه با یک پرونده الگو استفاده شود، TEXT به ابتدای بخش file-header الگو افزوده خواهد شد.

--fprod <TEXT>

هر بار که یک پرونده ورودی جدید پردازش می‌شود، TEXT را خروجی می‌دهد.

می‌توانید این گزینه را چندین بار مشخص کنید و مقادیر TEXT به یکدیگر متصل خواهند شد.

هنگامی که همراه با یک پرونده الگو استفاده شود، TEXT به انتهای بخش file-production الگو افزوده خواهد شد.

--ftail <TEXT>

پس از پردازش تمام پرونده‌های ورودی، TEXT را خروجی می‌دهد.

می‌توانید این گزینه را چندین بار مشخص کنید و مقادیر TEXT به یکدیگر متصل خواهند شد.

هنگامی که همراه با یک پرونده الگو استفاده شود، TEXT به انتهای بخش file-tail الگو افزوده خواهد شد.

--eprod <TEXT>

هر بار که در پرونده‌های ورودی با یک enum مواجه شود، TEXT را خروجی می‌دهد.

--vhead <TEXT>

پیش از پیمایش بر روی مجموعه مقادیر یک enum، متن TEXT را خروجی می‌دهد.

می‌توانید این گزینه را چندین بار مشخص کنید و مقادیر TEXT به یکدیگر متصل خواهند شد.

هنگامی که همراه با یک پرونده الگو استفاده شود، TEXT به ابتدای بخش value-header الگو افزوده خواهد شد.

--vprod <TEXT>

به ازای هر مقدار از یک enum، متن TEXT را خروجی می‌دهد.

می‌توانید این گزینه را چندین بار مشخص کنید و مقادیر TEXT به یکدیگر متصل خواهند شد.

هنگامی که همراه با یک پرونده الگو استفاده شود، TEXT به انتهای بخش value-production الگو افزوده خواهد شد.

--vtail <TEXT>

پس از پیمایش تمام مقادیر یک enum، متن TEXT را خروجی می‌دهد.

می‌توانید این گزینه را چندین بار مشخص کنید و مقادیر TEXT به یکدیگر متصل خواهند شد.

هنگامی که همراه با یک پرونده الگو استفاده شود، TEXT به انتهای بخش value-tail الگو افزوده خواهد شد.

--comments <TEXT>

الگویی برای کامنت‌های خودکار تولیدشده؛ مقدار پیش‌فرض (برای تولید کدهای C) عبارت است از "/* @comment@ */".

--template <FILE>

خواندن قالب‌ها از پروندهٔ مشخص‌شده. قالب‌ها در کامنت‌های زبان C با قالب‌بندی ویژه قرار دارند:
/*** BEGIN section ***/
/*** END section ***/

مقدار section می‌تواند file-header، file-production، file-tail، enumeration-production، value-header، value-production، value-tail یا comment باشد.

--identifier-prefix <PREFIX>

مشخص می‌کند چه بخشی از نام enum باید به عنوان پیشوند تفسیر شود (برای نمونه، Gtk در GtkDirectionType). به طور معمول این مقدار به صورت خودکار تشخیص داده می‌شود، اما در صورتی که بزرگ و کوچک بودن حروف فضای نام شما غیرعادی باشد، ممکن است نیاز به تغییر و بازنویسی مقدار پیش‌فرض داشته باشید.

--symbol-prefix <PREFIX>

مشخص می‌کند چه پیشوندی باید برای مطابقت با پیشوند شناسه در نام توابع مرتبط در C استفاده شود (برای نمونه، gtk در gtk_direction_type_get_type). به طور معادل، این نسخه با حروف کوچک از بخش پیشوند نام مقادیر enum است (برای نمونه، GTK در GTK_DIR_UP). مقدار پیش‌فرض، همان پیشوند شناسه تبدیل‌شده به حروف کوچک است.

--help

نمایش راهنمای مختصر و خروج.

--version

نمایش نسخه و خروج.

--output <FILE>

نوشتن خروجی در FILE به جای خروجی استاندارد (stdout).

@RSPFILE

هنگامی که به عنوان تنها آرگومان ارسال شود، آرگومان‌های واقعی را از RSPFILE می‌خواند و تجزیه می‌کند. این ویژگی در سیستم‌هایی با محدودیت طول کم در خط فرمان مفید است. برای نمونه، ویندوز محدودیتی برابر با ۸۱۹۱ نویسه دارد.

به جای ارسال بخش‌های گوناگون پروندهٔ تولیدشده به خط فرمان glib-mkenums، قویاً توصیه می‌شود که از یک پروندهٔ قالب استفاده کنید، به‌ویژه برای تولید کدهای منبع C.

یک پروندهٔ قالب سرایند (header) C معمولاً به این صورت خواهد بود:

/*** BEGIN file-header ***/
#pragma once
/* Include the main project header */
#include "project.h"
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@basename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void);
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
/*** END value-header ***/
/*** BEGIN file-tail ***/
G_END_DECLS
/*** END file-tail ***/

یک پروندهٔ قالب منبع C معمولاً به این صورت خواهد بود:

/*** BEGIN file-header ***/
#include "config.h"
#include "enum-types.h"
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@basename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
  static GType static_g_@type@_type_id = 0;
  if (g_once_init_enter_pointer (&static_g_@type@_type_id))
    {
      static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
        { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
        { 0, NULL, NULL }
      };
      GType g_@type@_type_id =
        g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
      g_once_init_leave_pointer (&static_g_@type@_type_id, g_@type@_type_id);
    }
  return static_g_@type@_type_id;
}
/*** END value-tail ***/

پرونده‌های قالب برای ویرایش و به‌روزرسانی آسان‌تر هستند، و می‌توان از آن‌ها برای تولید انواع مختلف خروجی با استفاده از همان خط فرمان یا ابزارها در طول فرایند ساخت استفاده کرد.

Meson در ماژول gnome خود، به‌طور پیش‌فرض از تولید انواع شمارشی با استفاده از glib-mkenums پشتیبانی می‌کند.

در پروندهٔ meson.build خود، معمولاً متد gnome.mkenums_simple() را برای تولید انواع شمارشی استاندارد از فهرستی از هدرهای مورد بررسی فراخوانی خواهید کرد:

project_headers = [
  'project-foo.h',
  'project-bar.h',
  'project-baz.h',
]
gnome = import('gnome')
enum_files = gnome.mkenums_simple('enum-types',
  sources: project_headers,
)

متغیر enum_files شامل آرایه‌ای از دو عنصر با ترتیب زیر خواهد بود:

1.
یک هدف ساخت برای پروندهٔ منبع
2.
یک هدف ساخت برای پروندهٔ هدر

باید از اشیاء بازگردانده‌شده برای ایجاد وابستگی به هر هدف ساخت دیگری که به پروندهٔ منبع یا هدر ارجاع می‌دهد استفاده کنید؛ برای نمونه، اگر از پروندهٔ منبع برای ساخت یک کتابخانه استفاده می‌کنید:

mainlib = library('project',
  sources: project_sources + enum_files,
  …
)

علاوه بر این، اگر پروندهٔ هدر تولیدشده را در یک هدف ساخت که به کتابخانهٔ ساخته‌شده وابسته است وارد می‌کنید، باید مطمئن شوید که وابستگی داخلی، هدر تولیدشده را به عنوان یک پروندهٔ منبع مورد نیاز در بر می‌گیرد:

mainlib_dep = declare_dependency(sources: enum_files[1], link_with: mainlib)

نباید پروندهٔ منبع تولیدشده را نیز اضافه کنید، در غیر این صورت برای هر هدفی که به آن وابسته است به‌طور جداگانه ساخته می‌شود که باعث شکست ساخت خواهد شد. برای آگاهی بیشتر دربارهٔ این که چرا همهٔ این موارد الزامی است، لطفاً به بخش مربوطه در پرسش‌های متداول Meson مراجعه کنید: https://mesonbuild.com/FAQ.html#how-do-i-tell-meson-that-my-sources-use-generated-headers.

اگر در حال تولید پرونده‌های هدر و منبع C هستید که به الگوهای خاصی نیاز دارند، می‌توانید از gnome.mkenums() برای ارائهٔ آن هدرها استفاده کنید؛ برای نمونه:

enum_files = gnome.mkenums('enum-types',
  sources: project_headers,
  h_template: 'enum-types.h.in',
  c_template: 'enum-types.c.in',
  install_header: true,
)

برای اطلاعات بیشتر، به مستندات Meson در https://mesonbuild.com/Gnome-module.html#gnomegenmarshal برای gnome.mkenums() مراجعه کنید.

برای استفاده از glib-mkenums در پروژهٔ خود هنگام استفاده از Autotools به عنوان سیستم ساخت، ابتدا باید پروندهٔ configure.ac خود را ویرایش کنید تا مطمئن شوید دستور مناسب را با استفاده از pkg-config پیدا می‌کنید، مشابه روشی که فلگ‌های کامپایلر و پیونددهنده را برای GLib می‌یابید:

PKG_PROG_PKG_CONFIG([0.28])
PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums])

در پروندهٔ Makefile.am خود، معمولاً از قواعدی مانند این استفاده خواهید کرد:

# A list of headers to inspect
project_headers = \
        project-foo.h \
        project-bar.h \
        project-baz.h
enum-types.h: $(project_headers) enum-types.h.in
        $(AM_V_GEN)$(GLIB_MKENUMS) \
                --template=enum-types.h.in \
                --output=$@ \
               $(project_headers)
enum-types.c: $(project_headers) enum-types.c.in enum-types.h
        $(AM_V_GEN)$(GLIB_MKENUMS) \
                --template=enum-types.c.in \
                --output=$@ \
                $(project_headers)
# Build the enum types files before every other target
BUILT_SOURCES += enum-types.h enum-types.c
CLEANFILES += enum-types.h enum-types.c
EXTRA_DIST += enum-types.h.in enum-types.c.in

در مثال بالا، متغیری به نام project_headers داریم که در آن به تمام پرونده‌های هدری که می‌خواهیم برای تولید GTypeهای شمارشی بررسی شوند ارجاع می‌دهیم. در قاعدهٔ enum-types.h از glib-mkenums با الگویی به نام enum-types.h.in برای تولید پروندهٔ هدر استفاده می‌کنیم؛ به طور مشابه، در قاعدهٔ enum-types.c از الگویی به نام enum-types.c.in استفاده می‌کنیم.

glib-genmarshal(1) <man:glib-genmarshal(1)>