usr/src/doc/rad-dev/c-libadr-radadrgen.xml
author Stephen Talley <stephen.talley@oracle.com>
Wed, 14 Mar 2012 10:45:15 -0400
changeset 809 8a6fba4105d7
parent 797 a33daeba9b4c
child 853 e2d9352738a7
permissions -rw-r--r--
7150175 radadrgen should generate rad module man pages 7150179 radadrgen should validate against original rng schema 7150184 radadrgen's output doesn't conform to docbook schema 7150189 adr schema should support documentation markup for union arms 7150226 radadrgen transforms should be internationalized 7150292 radadrgen -c should take a directory name, like -j 7150294 radadrgen command line usage should be broken into multiple synopses 7150352 radadrgen -o text should be revisited 7106700 radadrgen man page lacks documentation, -N, -m options

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<!--
  PDL HEADER START

  Public Documentation License Notice

  The contents of this Documentation are subject to the Public
  Documentation License Version 1.01 (the "License"); you may only
  use this Documentation if you comply with the terms of this License.
  A copy of the License is available at
  http://www.opensolaris.org/os/community/documentation/license.

  PDL HEADER END

  Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
-->

<section xmlns:xi="http://www.w3.org/2001/XInclude">
<title><command>radadrgen</command>-generated definitions</title>
<para>
Whether you are using <filename class='libraryfile'>libadr</filename>
in a C-based client or as part of writing a <command>rad</command>
server module, you will need to understand the data definitions
generated by <command>radadrgen</command>.  Fortunately, the definitions
are the same in both environments.
</para>

    <section><title>Running <command>radadrgen</command></title>
    <para>
    <command>radadrgen</command> is instructed to produce definitions for
    C/<filename class='libraryfile'>libadr</filename> consumers by
    using its <option>-c</option> option.  e.g.
    </para>

<example><title>Invoking <command>radadrgen</command></title>
<programlisting>
$ radadrgen -c . example.xml
</programlisting>
</example>

    <para>
    The <option>-c</option> option produces two files,
    <filename>api_INTERFACE.h</filename> and
    <filename>api_INTERFACE_impl.c</filename>, where INTERFACE is the
    value of the <sgmltag class='attribute'>name</sgmltag> attribute of
    the interface document's <sgmltag
    class='element'>interface</sgmltag> element.
    <filename>api_INTERFACE_impl.c</filename> contains the
    implementation of the <acronym>API</acronym>s and data types
    defined by the interface description.  It should be compiled and
    linked with the software needing those definitions.
    <filename>api_INTERFACE.h</filename> externs the specific symbols
    defined by <filename>api_INTERFACE_impl.c</filename> that consumers
    will need to reference, and should be #included by those
    consumers.  <filename>api_INTERFACE.h</filename> contains no data
    definitions itself and may be included in as many places as
    necessary.  The definitions
    <filename>api_INTERFACE_impl.c</filename> are 100% data and are
    statically initialized.  There are no initialization functions to
    be called.  Neither file should be modified.
    </para>

    <para>
    For each derived type TYPE (be it <type>enumeration</type> or
    <type>structure</type>) defined in the interface description, a
    <type>type_t</type> named <symbol>t__TYPE</symbol> (two
    underscores) representing that type is generated and externed by
    the header file.  If an array of that type is used anywhere in the
    interface definition, a <type>type_t</type> named
    <symbol>t_array__TYPE</symbol> (one underscore, two underscores)
    representing that array type is generated and externed.  For each
    <acronym>API</acronym> APINAME defined in the file, an
    <type>adr_object_t</type> named <symbol>api_APINAME</symbol> is
    defined and externed.
    </para>

    <para>
    For each value VALUE of an <type>enumeration</type> named TYPE, a
    <type>data_t</type> named <symbol>e__TYPE_VALUE</symbol> is defined
    and externed.  These <type>data_t</type>s are marked as constants
    and are not affected by <function>data_ref</function> or
    <function>data_free</function>.
    </para>
    </section>

    <section><title>Example <command>radadrgen</command> output</title>
    <para>
    When we run <command>radadrgen</command> on the example given in the
    <acronym>ADR</acronym> chapter (see <xref linkend="adr.idl.example"
    />), we get two files.  One,
    <filename>api_example_impl.c</filename>, holds the implementation
    of the GrabBag <acronym>API</acronym> and data types it depends on,
    and should be simply be compiled and linked with the GrabBag
    consumer.  The other, <filename>api_example.h</filename>, exposes
    only the relevant symbols defined by
    <filename>api_example_impl.c</filename> and should be included by
    consumers of the <type>GrabBag</type> <acronym>API</acronym> and
    its related types:
    </para>

<example>
<title>Sample <command>radadrgen</command>-generated C header file</title>
<programlisting>
<xi:include parse="text" href="api_example.h" />
</programlisting>
</example>

    <para>
    Though the function of <symbol>api_GrabBag</symbol> won't be
    discussed until the chapters on <command>rad</command> client
    programming and module development, the purpose of the other
    definitions in this file should be clear.  A consumer needing to
    create a <type>MoodStatus</type> structure indicating the
    <symbol>mood</symbol> is <constant>IRREVERENT</constant> and has
    changed would do the following:
    </para>

<example>
<title>Consuming <command>radadrgen</command>-generated definitions</title>
<programlisting><![CDATA[
status = data_new_struct(&t__MoodStatus);
struct_set(status, "mood", e__Mood_IRREVERENT);
/* struct_set(status, "mood", data_new_enum_byname(&t__Mood, "IRREVERENT")); */
struct_set(status, "changed", data_new_boolean(B_TRUE));

if (!data_verify(struct, NULL, B_TRUE)) {
        ...
]]></programlisting>
</example>

    <para>
    In addition to showing how to use the type definitions, this also
    illustrates the multiple ways of referencing an enumerated value.
    Using the defined symbols, as implemented above, is faster and can
    be checked by the compiler.  The commented out line uses
    <function>data_new_enum_byname</function> which offers flexibility
    that could be useful in some situations but necessarily defers
    error checking until runtime.  e.g. if the programmer mistyped the
    value <quote>IRREVERENT</quote> it wouldn't be detected until the
    code was run (if they were fortunate, in testing).  Obviously, it
    is preferable to use the enumerated value symbols when possible.
    </para>
    </section>

</section>