## -*- c -*-
## Portions of this file ar Copyright (C) Apple, Inc.
## Use is subject to license terms specified in the COPYING file
## distributed with the Net-SNMP package.
######################################################################
## Do the .h file
######################################################################
@open ${name}.h@
/*
 * Note: this file originally auto-generated by mib2c using
 *  $Id$
 */
#ifndef $name.uc_H
#define $name.uc_H

/* function declarations */
void init_$name(void);
@foreach $i table@
void initialize_table_$i(void);
Netsnmp_Node_Handler ${i}_handler;
@end@
@foreach $i table@

/* column number definitions for table $i */
    @foreach $c column@
       #define COLUMN_$c.uc		$c.subid
    @end@
@end@
#endif /* $name.uc_H */
######################################################################
## Do the .c file
######################################################################
@open ${name}.c@
/*
 * Note: this file originally auto-generated by mib2c using
 *  $Id$
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/table_container.h>
#include "${name}.h"

#ifdef ${i.uc}_USE_CACHE
static void _cache_free(netsnmp_cache * cache, void *magic);
static int _cache_load(netsnmp_cache * cache, void *vmagic);
#endif

/** Initializes the $name module */
void
init_$name(void)
{
  /* here we initialize all the tables we're planning on supporting */
  @foreach $i table@
    initialize_table_$i();
  @end@
}
##
@foreach $i table@
## Determine the first/last column names
  @eval $first_column = "-"@
  @eval $last_column = "-"@
  @foreach $c column@
    @if $c.readable@
      @if "$first_column" eq "-"@
        @eval $first_column = $c@
      @end@
      @eval $last_column = $c@
    @end@
  @end@

/** Initialize the $i table by defining its contents and how it's structured */
void
initialize_table_$i(void)
{
    const oid ${i}_oid[] = {$i.commaoid};
    const size_t ${i}_oid_len   = OID_LENGTH(${i}_oid);
    netsnmp_handler_registration    *reg = NULL;
    netsnmp_mib_handler             *handler = NULL;
    netsnmp_container               *container = NULL;
    netsnmp_table_registration_info *table_info = NULL;
#ifdef ${i.uc}_USE_CACHE
    netsnmp_cache  *cache = NULL;
#endif

    DEBUGMSGTL(("${name}:init", "initializing table $i\n"));
    
    reg = netsnmp_create_handler_registration(
              "$i",     ${i}_handler,
              ${i}_oid, ${i}_oid_len,
@if $i.settable@
              HANDLER_CAN_RWRITE
@else@
              HANDLER_CAN_RONLY
@end@
              );
    if (NULL == reg) {
        snmp_log(LOG_ERR,"error creating handler registration for $i\n");
        goto bail;
    }
@if $i.settable@
    /** should a set on a non-existent row create a new one? */
    /** reg->modes |= HANDLER_CAN_NOT_CREATE; */
@end@

    container  = netsnmp_container_find( "$i:table_container" );
    if (NULL == container) {
        snmp_log(LOG_ERR,"error creating container for $i\n");
        goto bail;
    }

    table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    if (NULL == table_info) {
        snmp_log(LOG_ERR,"error allocating table registration for $i\n");
        goto bail;
    }
    netsnmp_table_helper_add_indexes(table_info,
    @foreach $idx index@
                           $idx.type,  /* index: $idx */
    @end@
                           0);
    table_info->min_column = COLUMN_$first_column.uc;
    table_info->max_column = COLUMN_$last_column.uc;
    
    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,"error allocating table registration for $i\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting container_table handler for $i\n");
        goto bail;
    }
    handler = NULL; /* reg has it, will reuse below */

#ifdef ${i.uc}_USE_CACHE
    /*************************************************
     *
     * inject cache helper
     */
    cache = netsnmp_cache_create(30,    /* timeout in seconds */
                                 _cache_load, _cache_free,
                                 ${i}_oid, ${i}_oid_len);

    if (NULL == cache) {
        snmp_log(LOG_ERR, "error creating cache for $i\n");
        goto bail;
    }
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;
    cache->magic = container;

    handler = netsnmp_cache_handler_get(cache);
    if (NULL == handler) {
        snmp_log(LOG_ERR, "error creating cache handler for $i\n");
        goto bail;
    }

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,"error injecting cache handler for $i\n");
        goto bail;
    }
    handler = NULL; /* reg has it*/
#endif

    /*
     * register the table
     */
    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,"error registering table handler for $i\n");
        reg = NULL; /* it was freed inside netsnmp_register_table */
        goto bail;
    }

    /*
     * Initialise the contents of the table here
     */

    
    return; /* ok */

    /*
     * Some error occurred during registration. Clean up and bail.
     */
  bail: /* not ok */
    
    if (handler)
        netsnmp_handler_free(handler);

#ifdef ${i.uc}_USE_CACHE
    if (cache)
        netsnmp_cache_free(cache);
#endif
    
    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (container)
        CONTAINER_FREE(container);

    if (reg) 
        netsnmp_handler_registration_free(reg);
}

/** Typical data structure for a row entry */
typedef struct ${i}_entry_s {
    netsnmp_index oid_index;

    /* Index values */
    @foreach $idx index@
     @if $idx.needlength@
    $idx.decl $idx[NNN];
    size_t ${idx}_len;
     @else@
    $idx.decl $idx;
     @end@
    @end@

    /* Column values */
    @foreach $c column@
    @if $c.readable@
     @if $c.needlength@
    $c.decl $c[NNN];
    size_t ${c}_len;
     @else@
    $c.decl $c;
     @end@
     @if $c.settable@
      @if !$c.rowstatus@
       @if $c.needlength@
    $c.decl old_$c[NNN];
    size_t old_${c}_len;
       @else@
    $c.decl old_$c;
       @end@
      @end@
     @end@
    @end@
    @end@

    int   valid;
} ${i}_entry;

/** create a new row in the table */
${i}_entry *
${i}_createEntry(netsnmp_container *container, 
  @foreach $idx index@
    @if $idx.needlength@
                 , $idx.decl* $idx
                 , size_t ${idx}_len
    @else@
                 , $idx.decl  $idx
    @end@
  @end@
                ) {
    ${i}_entry *entry;

    entry = SNMP_MALLOC_TYPEDEF(${i}_entry);
    if (!entry)
        return NULL;

  @foreach $idx index@
   @if $idx.needlength@
    memcpy(entry->$idx, $idx, ${idx}_len);
    entry->${idx}_len = ${idx}_len;
   @else@
    entry->$idx = $idx;
   @end@
  @end@
    entry->oid_index.len  = XXX;
    entry->oid_index.oids = YYY;
    CONTAINER_INSERT( container, entry );
    return entry;
}

/** remove a row from the table */
void
${i}_removeEntry(netsnmp_container *container, 
                 ${i}_entry *entry) {

    if (!entry)
        return;    /* Nothing to remove */
    CONTAINER_REMOVE( container, entry );
    if (entry)
        SNMP_FREE( entry );   /* XXX - release any other internal resources */
}

/** remove a row from the table */
void
${i}_freeEntry(${i}_entry *entry) {

    if (!entry)
        return;    /* Nothing to remove */
    SNMP_FREE( entry );   /* XXX - release any other internal resources */
}

/** handles requests for the $i table */
int
${i}_handler(
    netsnmp_mib_handler               *handler,
    netsnmp_handler_registration      *reginfo,
    netsnmp_agent_request_info        *reqinfo,
    netsnmp_request_info              *requests) {

    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_info;
    netsnmp_container          *container;
    ${i}_entry                 *table_entry;
@if $i.settable@
    int                         ret;
@end@

    DEBUGMSGTL(("${name}:handler", "Processing request (%d)\n", reqinfo->mode));

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.readable@
            case COLUMN_$c.uc:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
            @if $c.needlength@
                snmp_set_var_typed_value( request->requestvb, $c.type,
                                          table_entry->$c,
                                          table_entry->${c}_len);
            @else@
                snmp_set_var_typed_integer( request->requestvb, $c.type,
                                            table_entry->$c);
            @end@
                break;
            @end@
            @end@
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;

@if $i.settable@
        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.settable@
            case COLUMN_$c.uc:
            @if $c.rowstatus@
                ret = netsnmp_check_vb_rowstatus(request->requestvb,
                         (table_entry ? RS_ACTIVE : RS_NONEXISTENT ));
            @else@
            @if $c.needlength@
	        /* or possibly 'netsnmp_check_vb_type_and_size' */
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, $c.type, sizeof(table_entry->$c));
            @else@
                /* or possibly 'netsnmp_check_vb_int_range' */
                ret = netsnmp_check_vb_int( request->requestvb );
            @end@
            @end@
                if ( ret != SNMP_ERR_NOERROR ) {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;
            @end@
            @end@
            default:
                netsnmp_set_request_error( reqinfo, request,
                                           SNMP_ERR_NOTWRITABLE );
                return SNMP_ERR_NOERROR;
            }
        }
        break;

    case MODE_SET_RESERVE2:
@if $i.creatable@
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
@if $i.rowstatus@
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    container   =     netsnmp_container_table_extract(request);
                    if (NULL == container) {
                        snmp_log(LOG_ERR,
                                 "could not extract table container for $i\n");
                        snmp_set_var_typed_value(request->requestvb,
                                                 SNMP_ERR_GENERR, NULL, 0);
                        continue;
                    }
                    table_entry = ${i}_createEntry(container
  @foreach $idx index@
    @if $idx.needlength@
                        ,  table_info->indexes->val.string
                        ,  table_info->indexes->val_len
    @else@
                        , *table_info->indexes->val.integer
    @end@
  @end@
                        );
                    if (table_entry) {
                        netsnmp_container_table_insert_row( request, table_entry );
                    } else {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_RESOURCEUNAVAILABLE );
                        return SNMP_ERR_NOERROR;
                    }
                }
            @end@
            @end@
@else@
            @foreach $c column@
            @if $c.creatable@
            case COLUMN_$c.uc:
            @end@
            @end@
                if ( !table_entry ) {
                    container   =     netsnmp_container_table_extract(request);
                    if (NULL == container) {
                        snmp_log(LOG_ERR,
                                 "could not extract table container for $i\n");
                        snmp_set_var_typed_value(request->requestvb,
                                                 SNMP_ERR_GENERR, NULL, 0);
                        continue;
                    }
                    table_entry = ${i}_createEntry(container
  @foreach $idx index@
    @if $idx.needlength@
                        ,  table_info->indexes->val.string
                        ,  table_info->indexes->val_len
    @else@
                        , *table_info->indexes->val.integer
    @end@
  @end@
                        );
                    if (table_entry) {
                        netsnmp_container_table_insert_row( request, table_entry );
                    } else {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_RESOURCEUNAVAILABLE );
                        return SNMP_ERR_NOERROR;
                    }
                }
                break;
@end@
            }
        }
@end@
        break;

    case MODE_SET_FREE:
@if $i.creatable@
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            container   =     netsnmp_container_table_extract(request);
            if (NULL == container) {
                snmp_log(LOG_ERR,
                         "could not extract table container for $i\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
@if $i.rowstatus@
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    if (table_entry && !table_entry->valid) {
                        ${i}_removeEntry(container, table_entry );
                    }
                }
            @end@
            @end@
@else@
            @foreach $c column@
            @if $c.creatable@
            case COLUMN_$c.uc:
            @end@
            @end@
                if ( table_entry && !table_entry->valid ) {
                    ${i}_removeEntry(container, table_entry );
                }
                break;
@end@
            }
        }
@end@
        break;

    case MODE_SET_ACTION:
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.settable@
            @if !$c.rowstatus@
            case COLUMN_$c.uc:
                @if $c.needlength@
                memcpy( table_entry->old_$c,
                        table_entry->$c,
                        sizeof(table_entry->$c));
                table_entry->old_${c}_len =
                        table_entry->${c}_len;
                memset( table_entry->$c, 0,
                        sizeof(table_entry->$c));
                memcpy( table_entry->$c,
                        request->requestvb->val.string,
                        request->requestvb->val_len);
                table_entry->${c}_len =
                        request->requestvb->val_len;
                @else@
                table_entry->old_$c = table_entry->$c;
                table_entry->$c     = *request->requestvb->val.integer;
                @end@
                break;
            @end@
            @end@
            @end@
            }
        }
@if $i.rowstatus@
        /* Check the internal consistency of an active row */
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_ACTIVE:
                case RS_CREATEANDGO:
                    if (/* XXX */) {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_INCONSISTENTVALUE );
                        return SNMP_ERR_NOERROR;
                    }
                }
            @end@
            @end@
            }
        }
@end@
        break;

    case MODE_SET_UNDO:
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            container   =     netsnmp_container_table_extract(request);
            if (NULL == container) {
                snmp_log(LOG_ERR,
                         "could not extract table container for $i\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.settable@
            case COLUMN_$c.uc:
@if $i.rowstatus@
  @if $c.rowstatus@
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    if (table_entry && !table_entry->valid) {
                        ${i}_removeEntry(container, table_entry );
                    }
                }
  @else@
                @if $c.needlength@
                memcpy( table_entry->$c,
                        table_entry->old_$c,
                        sizeof(table_entry->$c));
                memset( table_entry->old_$c, 0,
                        sizeof(table_entry->$c));
                table_entry->${c}_len =
                        table_entry->old_${c}_len;
                @else@
                table_entry->$c     = table_entry->old_$c;
                table_entry->old_$c = 0;
                @end@
  @end@
@else@
  @if $c.creatable@
                if ( table_entry && !table_entry->valid ) {
                    ${i}_removeEntry(container, table_row );
                } else {
                    @if $c.needlength@
                    memcpy( table_entry->$c,
                            table_entry->old_$c,
                            sizeof(table_entry->$c));
                    memset( table_entry->old_$c, 0,
                            sizeof(table_entry->$c));
                    table_entry->${c}_len =
                            table_entry->old_${c}_len;
                    @else@
                    table_entry->$c     = table_entry->old_$c;
                    table_entry->old_$c = 0;
                    @end@
                }
  @else@
                @if $c.needlength@
                memcpy( table_entry->$c,
                        table_entry->old_$c,
                        sizeof(table_entry->$c));
                memset( table_entry->old_$c, 0,
                        sizeof(table_entry->$c));
                table_entry->${c}_len =
                        table_entry->old_${c}_len;
                @else@
                table_entry->$c     = table_entry->old_$c;
                table_entry->old_$c = 0;
                @end@
  @end@
@end@
                break;
            @end@
            @end@
            }
        }
        break;

    case MODE_SET_COMMIT:
@if $i.creatable@
        for (request=requests; request; request=request->next) {
            if (request->processed)
               continue;
            table_entry = (${i}_entry *)
                              netsnmp_container_table_extract_context(request);
            table_info  =     netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for $i\n");
                snmp_set_var_typed_value(request->requestvb, SNMP_ERR_GENERR,
                                         NULL, 0);
                continue;
            }
    
            switch (table_info->colnum) {
@if $i.rowstatus@
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                    table_entry->valid = 1;
                    /* Fall-through */
                case RS_ACTIVE:
                    table_entry->$c = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    table_entry->valid = 1;
                    /* Fall-through */
                case RS_NOTINSERVICE:
                    table_entry->$c = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    container = netsnmp_container_table_extract(request);
                    if (NULL == container) {
                        snmp_log(LOG_ERR,
                                 "could not extract table container for $i\n");
                        snmp_set_var_typed_value(request->requestvb,
                                                 SNMP_ERR_GENERR, NULL, 0);
                        continue;
                    }
                    ${i}_removeEntry(container, table_entry );
                }
            @end@
            @end@
@else@
            @foreach $c column@
            @if $c.creatable@
            case COLUMN_$c.uc:
            @end@
            @end@
                if ( table_entry && !table_entry->valid ) {
                    table_entry->valid = 1;
                }
@end@
            }
        }
@end@
        break;
@end@
    }
    return SNMP_ERR_NOERROR;
}

#ifdef ${i.uc}_USE_CACHE
/**
 * @internal
 */
static int
_cache_load(netsnmp_cache * cache, void *vmagic)
{
    netsnmp_container *container;
    
    DEBUGMSGTL(("internal:${i}:_cache_load", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache for ${i}_cache_load\n");
        return -1;
    }
    container = (netsnmp_container *)cache->magic;

    /** should only be called for an invalid or expired cache */
    netsnmp_assert((0 == cache->valid) || (1 == cache->expired));

    /*
     * load cache here (or call function to do it)
     */
    /** CONTAINER_INSERT(container, record); */

    return 0;
}                               /* _cache_load */

/**
 * @Internal
 */
/** remove a row from the table */
static void
${i}_freeEntry_cb(${i}_entry *entry, void *magic) {

    ${i}_freeEntry(entry);
}

/**
 * @internal
 */
static void
_cache_free(netsnmp_cache * cache, void *magic)
{
    netsnmp_container *container;

    DEBUGMSGTL(("internal:${i}:_cache_free", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache in ${i}_cache_free\n");
        return;
    }
    container = (netsnmp_container *) cache->magic;

    /*
     * empty (but don't free) cache here
     */
    CONTAINER_CLEAR(container,
                    (netsnmp_container_obj_func*)${i}_freeEntry_cb,
                    NULL);
}                               /* _cache_free */
#endif /* ${i.uc}_USE_CACHE */
@end@
