Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

tc_set.c

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2004, 2005 by Kevin L. Mitchell <klmitch@mit.edu>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 **
00018 ** @(#)$Id: tc_set.c,v 1.5 2005/06/07 04:53:50 klmitch Exp $
00019 */
00027 #include <errno.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 
00031 #include "treeconf_int.h"
00032 
00033 RCSTAG("@(#)$Id: tc_set.c,v 1.5 2005/06/07 04:53:50 klmitch Exp $");
00034 
00047 static unsigned int
00048 _tc_set(treeconf_node_t *node, const char *value)
00049 {
00050   if (!node->tn_value) /* make certain we're set... */
00051     node->tn_value = node->tn_default;
00052 
00053   /* Check to see if we're actually changing the value */
00054   if ((!value && tn_isdef(node)) ||
00055       (value && node->tn_value && !strcmp(node->tn_value, value)))
00056     return 0; /* setting to current value */
00057 
00058   /* Canonicalize value...allocating memory if necessary */
00059   if (!value || (node->tn_default && !strcmp(node->tn_default, value)))
00060     value = node->tn_default;
00061   else if (value && !(value = strdup(value)))
00062     return ENOMEM;
00063 
00064   /* If the current value is set and not to the default, release memory... */
00065   if (node->tn_value && !tn_isdef(node))
00066     free((void *)node->tn_value);
00067 
00068   node->tn_value = value; /* set the new value */
00069 
00070   _tn_call_change(node); /* notify of the setting change */
00071 
00072   return 0;
00073 }
00074 
00075 unsigned int
00076 tc_set(treeconf_ctx_t *ctx, const char *name, const char *value,
00077        treeconf_node_t *parent)
00078 {
00079   treeconf_node_t *node;
00080   struct result res;
00081   unsigned int err = 0;
00082   int i;
00083 
00084   initialize_trcf_error_table();
00085 
00086   /* Verify the arguments */
00087   if (!tx_verify(ctx) || !name ||
00088       (parent && (!tn_verify(parent) || parent->tn_context != ctx)))
00089     return EINVAL;
00090 
00091   /* OK, look up the node... */
00092   if ((err = _tc_lookup_node(ctx, name, parent, &res)))
00093     return err;
00094 
00095   /* Found the specific node... */
00096   if (res.r_node && res.r_count == res.r_startnew) {
00097     if (res.r_node->tn_type == (TC_NODETYPE_IMPLICIT | TC_NODETYPE_NODE)) {
00098       _tc_release_children(res.r_node); /* Release all the children... */
00099       res.r_node->tn_type = (res.r_node->tn_type & ~TC_NODETYPE_MASK) |
00100       TC_NODETYPE_VARIABLE; /* Make it into a variable... */
00101     }
00102 
00103     if ((res.r_node->tn_type & TC_NODETYPE_MASK) == TC_NODETYPE_VARIABLE)
00104       err = _tc_set(res.r_node, value); /* set the variable */
00105     else
00106       err = TC_ERR_MISMATCH; /* non-implicit internal node */
00107   } else if (_tn_call_nodown(res.r_node, &res.r_comps[res.r_startnew],
00108                        res.r_count - res.r_startnew)) {
00109     /* Create the nodes... */
00110     for (i = res.r_startnew, node = res.r_node; i < res.r_count; i++)
00111       /* All created nodes are implicit and default is 0 */
00112       if (!(node = _tc_create_node(ctx, node,
00113                            ((i == res.r_count - 1 ?
00114                              (TC_NODETYPE_VARIABLE) :
00115                              (TC_NODETYPE_NODE)) |
00116                             TC_NODETYPE_IMPLICIT),
00117                            res.r_comps[i].ts_string,
00118                            res.r_comps[i].ts_length, 0,
00119                            res.r_node->tn_nodown,
00120                            res.r_node->tn_change, 0)))
00121       _tc_doerror(ENOMEM);
00122 
00123     err = _tc_set(node, value); /* Set the node value */
00124   } else
00125     err = ENOENT;
00126 
00127  error:
00128   free(res.r_comps); /* Release temporarily allocated memory */
00129 
00130   return err;
00131 }

Generated on Wed Jun 8 09:18:27 2005 for treeconf by  doxygen 1.3.9.1