Annotation of embedaddon/mpd/src/contrib/libpdel/structs/structs.h, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (c) 2001-2002 Packet Design, LLC.
                      4:  * All rights reserved.
                      5:  * 
                      6:  * Subject to the following obligations and disclaimer of warranty,
                      7:  * use and redistribution of this software, in source or object code
                      8:  * forms, with or without modifications are expressly permitted by
                      9:  * Packet Design; provided, however, that:
                     10:  * 
                     11:  *    (i)  Any and all reproductions of the source or object code
                     12:  *         must include the copyright notice above and the following
                     13:  *         disclaimer of warranties; and
                     14:  *    (ii) No rights are granted, in any manner or form, to use
                     15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
                     16:  *         on advertising, endorsements, or otherwise except as such
                     17:  *         appears in the above copyright notice or in the software.
                     18:  * 
                     19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
                     20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
                     21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
                     22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
                     23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
                     24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
                     25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
                     26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
                     27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
                     28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
                     29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
                     30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
                     31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
                     32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
                     33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
                     35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
                     36:  * THE POSSIBILITY OF SUCH DAMAGE.
                     37:  *
                     38:  * Author: Archie Cobbs <archie@freebsd.org>
                     39:  */
                     40: 
                     41: #ifndef _PDEL_STRUCTS_STRUCTS_H_
                     42: #define _PDEL_STRUCTS_STRUCTS_H_
                     43: 
                     44: /*********************************************************************
                     45: 
                     46:                            STRUCTS TYPES
                     47:                            -------------
                     48: 
                     49:     A "structs type" is a descriptor for a C data structure that
                     50:     allows access to the data structure in an automated fashion.
                     51:     For example, once a data structure is described by a associated
                     52:     structs type, the following operations can be performed
                     53:     automatically on any instance of the data structure:
                     54: 
                     55:        o Initialization to default value
                     56:        o Comparison of two instances for equality
                     57:        o "Deep" copying (aka. "cloning")
                     58:        o Access to arbitrary sub-fields by name (aka. "introspection")
                     59:        o Conversion to/from ASCII (primitive types)
                     60:        o Import/export from/to XML, with precise input validation,
                     61:          automating conversion between internal and external formats
                     62:        o Conversion into XML-RPC request or reply
                     63:        o Import/export from/to a machine independent binary encoding
                     64:        o Inserting, deleting, and extending elements in arrays
                     65: 
                     66:     In addition, any required dynamic memory allocation and free'ing
                     67:     is handled automatically.
                     68: 
                     69:     Supported data structures include the normal primitive C types,
                     70:     plus arrays, structures, unions, and pointers to supported types,
                     71:     as well as some other useful types such as opaque binary data,
                     72:     IP address, regular expression, etc. User-defined types may be
                     73:     added as well.
                     74: 
                     75:     Put simply, a structs type describes how to interpret a region
                     76:     of memory so that the operations listed above may be peformed
                     77:     in an automated fashion.
                     78: 
                     79:     Arrays must be defined using the "structs_array" structure.
                     80:     Unions must be defined using the "structs_union" structure.
                     81: 
                     82:     Nested items in a data structure can be identified by names,
                     83:     where each name component is either the name of a structure or
                     84:     union field, or an array index. Name components are separated
                     85:     by dots. For example, "foo.list.12" (see below).
                     86: 
                     87:     EXAMPLE
                     88:     -------
                     89: 
                     90:     Consider the C data structure defined by "struct janfu":
                     91: 
                     92:        struct fubar {
                     93:                struct structs_array    list;   // array of strings
                     94:        };
                     95: 
                     96:        struct janfu {
                     97:                u_int16_t               value;  // 16 bit hex value
                     98:                struct fubar            *foo;   // fubar structure
                     99:        };
                    100: 
                    101:     A memory region containing a 'struct janfu' would be described
                    102:     in C code like so:
                    103: 
                    104:        // Descriptor for field 'list' in 'struct fubar': array of strings
                    105:        static const struct structs_type list_array_type =
                    106:            STRUCTS_ARRAY_TYPE(&structs_type_string, "list_elem", "list_elem");
                    107: 
                    108:        // Descriptor for 'struct fubar'
                    109:        static const struct structs_field fubar_fields[] = {
                    110:            STRUCTS_STRUCT_FIELD(fubar, list, &list_array_type),
                    111:            STRUCTS_STRUCT_FIELD_END
                    112:        };
                    113:        static const struct structs_type fubar_type =
                    114:            STRUCTS_STRUCT_TYPE(fubar, &fubar_fields);
                    115: 
                    116:        // Descriptor for a variable of type 'struct fubar *'
                    117:        static const struct structs_type foo_ptr_type =
                    118:            STRUCTS_POINTER_TYPE(&fubar_type, "struct fubar");
                    119: 
                    120:        // Descriptor for 'struct janfu'
                    121:        static const struct structs_field janfu_fields[] = {
                    122:            STRUCTS_STRUCT_FIELD(janfu, value, &structs_type_uint16),
                    123:            STRUCTS_STRUCT_FIELD(janfu, foo, &foo_ptr_type),
                    124:            STRUCTS_STRUCT_FIELD_END
                    125:        };
                    126:        static const struct structs_type janfu_type =
                    127:            STRUCTS_STRUCT_TYPE(janfu, &janfu_fields);
                    128: 
                    129:     The type "janfu_type" describes a 'struct janfu' data structure.
                    130: 
                    131:     Then "foo.list.12" refers to the 12th item in the "list" array
                    132:     (assuming it actually exists), counting from zero. It's value
                    133:     could be accessed like this:
                    134: 
                    135:        void
                    136:        print_list_12(const struct janfu *j)
                    137:        {
                    138:            char *s;
                    139: 
                    140:            s = structs_get_string(&janfu_type, "foo.list.12", j, NULL);
                    141:            if (s == NULL) {
                    142:                    fprintf(stderr, "structs_get_string: %s: %s",
                    143:                        "foo.list.12", strerror(errno));
                    144:                    exit(1);
                    145:            }
                    146:            printf("foo.list.12 = %s\n", s);
                    147:            free(s);
                    148:        }
                    149: 
                    150:     An instance of a "struct janfu", if output as XML, might look
                    151:     like this:
                    152: 
                    153:        <?xml version="1.0" standalone="yes"?>
                    154:        <janfu>
                    155:            <value>0x1234</value>
                    156:            <list>
                    157:                <list_elem>first list element</list_elem>
                    158:                <list_elem>second list element</list_elem>
                    159:                <list_elem>third list element</list_elem>
                    160:            </list>
                    161:        </janfu>
                    162: 
                    163:     A function call that would produce the above output is:
                    164: 
                    165:        void
                    166:        dump_janfu(struct janfu *j)
                    167:        {
                    168:            structs_xml_output(&janfu_type, "janfu", NULL, j, stdout, NULL, 0);
                    169:        }
                    170: 
                    171: *********************************************************************/
                    172: 
                    173: /* Name component separator */
                    174: #define STRUCTS_SEPARATOR      '.'
                    175: 
                    176: struct structs_type;
                    177: 
                    178: /* For representing arbitrary binary data */
                    179: struct structs_data {
                    180:        u_int   length;                 /* number of bytes */
                    181:        u_char  *data;                  /* bytes */
                    182: };
                    183: 
                    184: /*********************************************************************
                    185:                        STRUCTS TYPE METHODS
                    186: *********************************************************************/
                    187: 
                    188: /*
                    189:  * The structs type "init" method.
                    190:  *
                    191:  * The region of memory pointed to by "data" must be at least
                    192:  * type->size bytes and should be uninitialized (i.e., it should
                    193:  * not contain a valid instance of the type).
                    194:  *
                    195:  * This method should initialize the memory with a valid instance
                    196:  * of the type, setting this new instance to be equal to the default
                    197:  * value for the type, and allocating any resources required for the
                    198:  * instance in the process.
                    199:  *
                    200:  * Returns 0 if successful, or -1 (and sets errno) if there was an error.
                    201:  */
                    202: typedef int    structs_init_t(const struct structs_type *type, void *data);
                    203: 
                    204: /*
                    205:  * The structs type "copy" method.
                    206:  *
                    207:  * The region of memory pointed to by "from" contains a valid instance
                    208:  * of the type described by "type".
                    209:  *
                    210:  * The region of memory pointed to by "to" is uninitialized.
                    211:  *
                    212:  * This method should initialize "to" with a "deep" copy of the
                    213:  * data structure pointed to by "from". The copy must be equal
                    214:  * (according to the "equal" method) to the original.
                    215:  *
                    216:  * Returns 0 if successful, or -1 (and sets errno) if there was an error.
                    217:  */
                    218: typedef int    structs_copy_t(const struct structs_type *type,
                    219:                        const void *from, void *to);
                    220: 
                    221: /*
                    222:  * The structs type "equal" method.
                    223:  *
                    224:  * The regions of memory pointed to by "data1" and "data2" contain valid
                    225:  * instances of the type described by "type".
                    226:  *
                    227:  * Returns 1 if "data1" and "data2" are equal (by a "deep" comparison), or
                    228:  * 0 if not, or -1 (and sets errno) if there was an error.
                    229:  */
                    230: typedef int    structs_equal_t(const struct structs_type *type,
                    231:                        const void *data1, const void *data2);
                    232: 
                    233: /*
                    234:  * The structs type "ascify" method.
                    235:  *
                    236:  * The region of memory pointed to by "data" contains a valid instance
                    237:  * of the type described by "type".
                    238:  *
                    239:  * The method should convert this instance into a NUL-terminated
                    240:  * ASCII string stored in a dynamically allocated buffer that is
                    241:  * allocated with the memory type described by "mtype".
                    242:  *
                    243:  * The ASCII string must be unique, in that it can be used as input
                    244:  * to the "binify" method to create an instance equal (according to the
                    245:  * "equal" method) to the original.
                    246:  *
                    247:  * Returns the ASCII string buffer if successful, or NULL
                    248:  * (and sets errno) if error.
                    249:  */
                    250: typedef char   *structs_ascify_t(const struct structs_type *type,
                    251:                        const char *mtype, const void *data);
                    252: 
                    253: /*
                    254:  * The structs type "binify" method.
                    255:  *
                    256:  * The region of memory pointed to by "data" is uninitialized.
                    257:  *
                    258:  * The variable "ascii" points to a NUL-terminated string. This method
                    259:  * should use the contents of the string to create a new instace of
                    260:  * the type in the memory pointed to by "data".
                    261:  *
                    262:  * Returns 0 if successful, or -1 if there was an error. In the latter
                    263:  * case, either errno should be set, or a more informative error string
                    264:  * may be printed (including NUL) into "ebuf", which has total size "emax"
                    265:  * (see snprintf(3)).
                    266:  *
                    267:  * This method must be robust in the face of bogus data in "ascii";
                    268:  * it must return an error if "ascii" is invalid.
                    269:  */
                    270: typedef int    structs_binify_t(const struct structs_type *type,
                    271:                        const char *ascii, void *data, char *ebuf, size_t emax);
                    272: 
                    273: /*
                    274:  * The structs type "encode" method.
                    275:  *
                    276:  * The region of memory pointed to by "data" contains a valid instance
                    277:  * of the type described by "type".
                    278:  *
                    279:  * This method should encode the data structure into a host order
                    280:  * independent, self-delimiting sequence of bytes. The sequence must be
                    281:  * stored in a dynamically allocated buffer allocated with the memory type
                    282:  * described by "mtype", and "code" must be filled in with the buffer's
                    283:  * pointer and length.
                    284:  *
                    285:  * The binary sequence must be unique, in that it can be used as input
                    286:  * to the "decode" method to create an instance equal (according to the
                    287:  * "equal" method) to the original.
                    288:  *
                    289:  * Returns 0 if successful, or -1 (and sets errno) if there was an error.
                    290:  */
                    291: typedef        int     structs_encode_t(const struct structs_type *type,
                    292:                        const char *mtype, struct structs_data *code,
                    293:                        const void *data);
                    294: 
                    295: /*
                    296:  * The structs type "decode" method.
                    297:  *
                    298:  * The region of memory pointed to by "data" is uninitialized.
                    299:  *
                    300:  * The "code" parameter points to a sequence of "cmax" binary data bytes.
                    301:  * This method should decode the binary data and use it to reconstruct
                    302:  * an instance of "type" in the memory region pointed to by "data".
                    303:  *
                    304:  * Returns the number of bytes consumed in the decoding process if
                    305:  * successful, or -1 (and sets errno) if there was an error. In the
                    306:  * latter case, either errno should be set, or a more informative error
                    307:  * string may be printed (including NUL) into "ebuf", which has total
                    308:  * size "emax" (see snprintf(3)).
                    309:  */
                    310: typedef        int     structs_decode_t(const struct structs_type *type,
                    311:                        const u_char *code, size_t cmax, void *data,
                    312:                        char *ebuf, size_t emax);
                    313: 
                    314: /*
                    315:  * The structs type "uninit" method.
                    316:  *
                    317:  * The region of memory pointed to by "data" contains a valid instance
                    318:  * of the type described by "type".
                    319:  *
                    320:  * This method should free any resources associated with the instance
                    321:  * pointed to by "data".  Upon return, the memory pointed to by "data"
                    322:  * may be no longer used or referenced.
                    323:  */
                    324: typedef void   structs_uninit_t(const struct structs_type *type, void *data);
                    325: 
                    326: /*********************************************************************
                    327:                        STRUCTS TYPE DEFINITION
                    328: *********************************************************************/
                    329: 
                    330: /*
                    331:  * This structure defines a structs type.
                    332:  */
                    333: struct structs_type {
                    334:        size_t                  size;           /* size of an instance */
                    335:        const char              *name;          /* human informative name */
                    336:        int                     tclass;         /* see classes listed below */
                    337:        structs_init_t          *init;          /* type "init" method */
                    338:        structs_copy_t          *copy;          /* type "copy" method */
                    339:        structs_equal_t         *equal;         /* type "equal" method */
                    340:        structs_ascify_t        *ascify;        /* type "ascify" method */
                    341:        structs_binify_t        *binify;        /* type "binify" method */
                    342:        structs_encode_t        *encode;        /* type "encode" method */
                    343:        structs_decode_t        *decode;        /* type "decode" method */
                    344:        structs_uninit_t        *uninit;        /* type "uninit" method */
                    345:        union {                                 /* type specific arguments */
                    346:                const void      *v;
                    347:                const char      *s;
                    348:                int             i;
                    349:        }                       args[3];
                    350: };
                    351: 
                    352: /* Classes of types */
                    353: #define STRUCTS_TYPE_PRIMITIVE 0
                    354: #define STRUCTS_TYPE_POINTER   1
                    355: #define STRUCTS_TYPE_ARRAY     2
                    356: #define STRUCTS_TYPE_FIXEDARRAY        3
                    357: #define STRUCTS_TYPE_STRUCTURE 4
                    358: #define STRUCTS_TYPE_UNION     5
                    359: 
                    360: /*********************************************************************
                    361:                        GENERIC TYPE METHODS
                    362: *********************************************************************/
                    363: 
                    364: __BEGIN_DECLS
                    365: 
                    366: /* These operate on simple block regions of memory */
                    367: extern structs_init_t          structs_region_init;
                    368: extern structs_copy_t          structs_region_copy;
                    369: extern structs_equal_t         structs_region_equal;
                    370: 
                    371: extern structs_encode_t                structs_region_encode;
                    372: extern structs_decode_t                structs_region_decode;
                    373: extern structs_encode_t                structs_region_encode_netorder;
                    374: extern structs_decode_t                structs_region_decode_netorder;
                    375: 
                    376: /* These always return an error with errno set to EOPNOTSUPP */
                    377: extern structs_init_t          structs_notsupp_init;
                    378: extern structs_copy_t          structs_notsupp_copy;
                    379: extern structs_equal_t         structs_notsupp_equal;
                    380: extern structs_ascify_t                structs_notsupp_ascify;
                    381: extern structs_binify_t                structs_notsupp_binify;
                    382: extern structs_encode_t                structs_notsupp_encode;
                    383: extern structs_decode_t                structs_notsupp_decode;
                    384: 
                    385: /* This copies any type that is ascifyable by converting to ASCII and back */
                    386: extern structs_copy_t          structs_ascii_copy;
                    387: 
                    388: /* This does nothing */
                    389: extern structs_uninit_t                structs_nothing_free;
                    390: 
                    391: __END_DECLS
                    392: 
                    393: /*********************************************************************
                    394:                        BASIC STRUCTS FUNCTIONS
                    395: *********************************************************************/
                    396: 
                    397: __BEGIN_DECLS
                    398: 
                    399: /*
                    400:  * Initialize an item in a data structure to its default value.
                    401:  * This assumes the item is not already initialized.
                    402:  *
                    403:  * If "name" is NULL or empty string, the entire structure is initialied.
                    404:  *
                    405:  * Returns 0 if successful, otherwise -1 and sets errno.
                    406:  */
                    407: extern int     structs_init(const struct structs_type *type,
                    408:                        const char *name, void *data);
                    409: 
                    410: /*
                    411:  * Reset an item in a data structure to its default value.
                    412:  * This assumes the item is already initialized.
                    413:  *
                    414:  * If "name" is NULL or empty string, the entire structure is reset.
                    415:  *
                    416:  * Returns 0 if successful, otherwise -1 and sets errno.
                    417:  */
                    418: extern int     structs_reset(const struct structs_type *type,
                    419:                        const char *name, void *data);
                    420: 
                    421: /*
                    422:  * Free an item in a data structure, returning it to its uninitialized state.
                    423:  * This function can be thought of as the opposite of structs_init().
                    424:  *
                    425:  * If "name" is NULL or empty string, the entire structure is free'd.
                    426:  *
                    427:  * Returns 0 if successful, otherwise -1 and sets errno.
                    428:  */
                    429: extern int     structs_free(const struct structs_type *type,
                    430:                        const char *name, void *data);
                    431: 
                    432: /*
                    433:  * Compare two data structures of the same type for equality.
                    434:  *
                    435:  * If "name" is NULL or empty string, the entire structures are compared.
                    436:  * Otherwise, the "name" sub-elements of both structures are compared.
                    437:  *
                    438:  * Returns zero or one (for not equal or equal, respectively),
                    439:  * or -1 (and sets errno) if there was an error.
                    440:  */
                    441: extern int     structs_equal(const struct structs_type *type,
                    442:                        const char *name, const void *data1, const void *data2);
                    443: 
                    444: /*
                    445:  * Find an item in a data structure structure.
                    446:  *
                    447:  * If "name" is NULL or empty string, "type" is returned and "datap"
                    448:  * is unmodified.
                    449:  *
                    450:  * If "set_union" is true, then any unions in the path will be reset
                    451:  * so that their fields agree with "name" in the case that "name" contains
                    452:  * a different field name than is currently set for that union. However,
                    453:  * these changes will only occur if "name" is actually found.
                    454:  *
                    455:  * Returns the type of the item and points *datap at it, or NULL
                    456:  * (and sets errno) if there was an error.
                    457:  */
                    458: extern const   struct structs_type *structs_find(
                    459:                        const struct structs_type *type, const char *name,
                    460:                        void **datap, int set_union);
                    461: 
                    462: /*
                    463:  * Get a copy of an item from a data structure.
                    464:  *
                    465:  * If "name" is NULL or empty string, the entire structure is copied.
                    466:  *
                    467:  * It is assumed that "to" points to a region big enough to hold
                    468:  * the copy of the item. "to" will not be free'd first, so it should
                    469:  * not already be initialized.
                    470:  *
                    471:  * Note: "name" is only applied to "from". The structs types of
                    472:  * "from.<name>" and "to" must be the same.
                    473:  *
                    474:  * Returns 0 if successful, otherwise -1 and sets errno.
                    475:  */
                    476: extern int     structs_get(const struct structs_type *type,
                    477:                        const char *name, const void *from, void *to);
                    478: 
                    479: /*
                    480:  * Set an item in a data structure.
                    481:  *
                    482:  * If "name" is NULL or empty string, the entire structure is copied.
                    483:  *
                    484:  * It is assumed that "to" is already initialized.
                    485:  *
                    486:  * Note: "name" is only applied to "to". The structs types of
                    487:  * "from" and "to.<name>" must be the same.
                    488:  *
                    489:  * Returns 0 if successful, otherwise -1 and sets errno.
                    490:  */
                    491: extern int     structs_set(const struct structs_type *type,
                    492:                        const void *from, const char *name, void *to);
                    493: 
                    494: /*
                    495:  * Get the ASCII form of an item, in a string allocated with the
                    496:  * memory type described by "mtype".
                    497:  *
                    498:  * The caller is reponsible for freeing the returned string.
                    499:  *
                    500:  * Returns the ASCII string if successful, otherwise NULL and sets errno.
                    501:  */
                    502: extern char    *structs_get_string(const struct structs_type *type,
                    503:                        const char *name, const void *data, const char *mtype);
                    504: 
                    505: /*
                    506:  * Set the value of an item in a data structure from an ASCII string.
                    507:  *
                    508:  * The referred to item must be of a type that supports ASCII encoding,
                    509:  * and is assumed to be already initialized.
                    510:  *
                    511:  * Returns 0 if successful, otherwise -1 and sets errno.
                    512:  */
                    513: extern int     structs_set_string(const struct structs_type *type,
                    514:                        const char *name, const char *ascii,
                    515:                        void *data, char *ebuf, size_t emax);
                    516: 
                    517: /*
                    518:  * Get the binary encoded form of an item, put into a buffer
                    519:  * allocated with memory type "mtype" and described by "code".
                    520:  *
                    521:  * The caller is reponsible for freeing the allocated bytes.
                    522:  *
                    523:  * Returns 0 if successful, otherwise -1 and sets errno.
                    524:  */
                    525: extern int     structs_get_binary(const struct structs_type *type,
                    526:                        const char *name, const void *data,
                    527:                        const char *mtype, struct structs_data *code);
                    528: 
                    529: /*
                    530:  * Set an item's value from its binary encoded value.
                    531:  *
                    532:  * The referred to item is assumed to be already initialized.
                    533:  *
                    534:  * Returns 0 if successful, otherwise -1 and sets errno.
                    535:  */
                    536: extern int     structs_set_binary(const struct structs_type *type,
                    537:                        const char *name, const struct structs_data *code,
                    538:                        void *data, char *ebuf, size_t emax);
                    539: 
                    540: /*
                    541:  * Traverse a structure, returning the names of all primitive fields
                    542:  * (i.e., the "leaves" of the data structure).
                    543:  *
                    544:  * The number of items is returned, or -1 and errno if there was an error.
                    545:  * The caller must free the list by freeing each string in the array,
                    546:  * and then the array itself; all memory is allocated using memory type
                    547:  * "mtype".
                    548:  *
                    549:  * If "type" is a primitive type, a list of length one is returned
                    550:  * containing an empty string.
                    551:  */
                    552: extern int     structs_traverse(const struct structs_type *type,
                    553:                        const void *data, char ***listp, const char *mtype);
                    554: 
                    555: __END_DECLS
                    556: 
                    557: #endif /* _PDEL_STRUCTS_STRUCTS_H_ */
                    558: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>