#############################################################  -*- c -*-
## generic include for XXX. Do not use directly.
##
## $Id$
########################################################################
@if $m2c_mark_boundary == 1@
/** START code generated by $RCSfile$ $Revision$ */
@end@
########################################################################
##
##----------------------------------------------------------------------
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param $m2c_node_param_val_name
 *        A $node.decl containing the new value.
@    if $m2c_node_needlength == 1@
 * @param $m2c_node_param_val_lname
 *        The size (in bytes) of the data pointed to by $m2c_node_param_val_name
@    end@
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
@if ("$m2c_data_context" ne "generated") && ($m2c_node_needlength == 1)@
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
@end@
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * ${context}_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is $node.type
@if ("$m2c_data_context" eq "generated") && ($m2c_node_needlength == 1)@
 *    The length is < sizeof($m2c_data_item$node).
@end@
@if $node.enums == 1@
 *    The value is one of $m2c_evals
@elsif $node.ranges == 1@
@    if ("$node.decl" eq "long") || ("$node.decl" eq "u_long")@
@        eval $m2c_tmp_ns = "value"@
@    else@
@        eval $m2c_tmp_ns = "length"@
@    end@
 *    The $m2c_tmp_ns is in (one of) the range set(s): $m2c_evals
@end@
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
@  if $mfd_code_verbose == 1@
@    if ("$node.decl" eq "long") || ("$node.decl" eq "u_long")@
 * For example, an object with the syntax INTEGER(0..500) will
 * have already been checked for a value between 0 and 500. But
 * if the description also specifies that the value must be an
 * even number, you would enforce that requirement here. If and odd
 * numer is set, return MFD_NOT_VALID_EVER. If the description also
 * specified that changed must be made in single steps of 2, then a set
 * to change the value 10 to an even value other than 8 or 12 should
 * return MFD_NOT_VALID_NOW.
@    else@
 * For example, and object with the syntax DisplayString(0..40)
 * will have already been checked for a length between 0 and 40.
 * But if the description also specified that the value must
 * be all uppercase letters, you would enforce that requirement here
 * by returning MFD_NOT_VALID_EVER for a set containing lowercase
 * letters. If the description also specified that the value can not
 * change by more than one letter at a time, an attempt to change
 * "ABBY" to "ANNIE" should return MFD_NOT_VALID_NOW.
@    end@
 *
@  end@
 */
int
${node}_check_value( ${context}_rowreq_ctx *rowreq_ctx, $m2c_node_param_val)
{
    DEBUGMSGTL(("verbose:${context}:${node}_check_value","called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
@if $m2c_node_needlength == 1@
    netsnmp_assert(NULL != $m2c_node_param_val_name);
@end@

    /*
     * TODO:441:o: |-> Check for valid $node value.
     */

    return MFD_SUCCESS; /* $node value not illegal */
} /* ${node}_check_value */

##----------------------------------------------------------------------
/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (${context}_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ${context}_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
${node}_undo_setup( ${context}_rowreq_ctx *rowreq_ctx)
{
    DEBUGMSGTL(("verbose:${context}:${node}_undo_setup","called\n"));

@ifconf syntax-$node.syntax-undo-setup.m2i@
@    include syntax-$node.syntax-undo-setup.m2i@
@else@
    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup $node undo.
     */
@   eval $m2c_ctx_lh = "${m2c_undo_item}${node}"@
@   eval $m2c_ctx_lhs = "${m2c_undo_item}${node}_len"@
@   eval $m2c_ctx_rh = "${m2c_data_item}${node}"@
@   eval $m2c_ctx_rhs = "${m2c_data_item}${node}_len"@
@   include generic-ctx-copy.m2i@
@end@

    return MFD_SUCCESS;
} /* ${node}_undo_setup */

##----------------------------------------------------------------------
/**
 * Set the new value.
 *
@if $m2c_node_set_comments ne ""@
$m2c_node_set_comments
*
@end@
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param $m2c_node_param_val_name
 *        A $node.decl containing the new value.
@    if $m2c_node_needlength == 1@
 * @param $m2c_node_param_val_lname
 *        The size (in bytes) of the data pointed to by $m2c_node_param_val_name
@    end@
 */
int
${node}_set( ${context}_rowreq_ctx *rowreq_ctx, $m2c_node_param_val )
{
@ifconf syntax-$node.syntax-set.m2i@
@    include syntax-$node.syntax-set.m2i@
@else@

    DEBUGMSGTL(("verbose:${context}:${node}_set","called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
@if $m2c_node_needlength == 1@
    netsnmp_assert(NULL != $m2c_node_param_val_name);
@end@

@    if $m2c_node_skip_mapping != 1@
@        include generic-value-map-reverse.m2i@
@    else@
@        include generic-ctx-set.m2i@
@    end@
@end@ # no syntax include
    return MFD_SUCCESS;
} /* ${node}_set */

##----------------------------------------------------------------------
/**
 * undo the previous set.
 *
@if $m2c_node_undo_comments ne ""@
$m2c_node_undo_comments
*
@end@
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
${node}_undo( ${context}_rowreq_ctx *rowreq_ctx)
{
@ifconf syntax-$node.syntax-undo.m2i@
@    include syntax-$node.syntax-undo.m2i@
@else@

    DEBUGMSGTL(("verbose:${context}:${node}_undo","called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up $node undo.
     */
@   eval $m2c_ctx_rh = "${m2c_undo_item}${node}"@
@   eval $m2c_ctx_rhs = "${m2c_undo_item}${node}_len"@
@   eval $m2c_ctx_lh = "${m2c_data_item}${node}"@
@   eval $m2c_ctx_lhs = "${m2c_data_item}${node}_len"@
@   include generic-ctx-copy.m2i@
@end@ # no syntax include
    
    return MFD_SUCCESS;
} /* ${node}_undo */

##
########################################################################
@if $m2c_mark_boundary == 1@
/** END code generated by $RCSfile$ $Revision$ */
@end@
