00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include <errno.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include "treeconf_int.h"
00032
00033 RCSTAG("@(#)$Id: tc_register.c,v 1.6 2005/06/07 04:53:50 klmitch Exp $");
00034
00035 unsigned int
00036 tc_register(treeconf_ctx_t *ctx, const char *name, const char *def,
00037 treeconf_node_t *parent, treeconf_nodown_t nodown,
00038 treeconf_change_t change, void *assoc)
00039 {
00040 treeconf_node_t *node;
00041 struct result res;
00042 unsigned int err = 0;
00043 int i;
00044
00045 initialize_trcf_error_table();
00046
00047
00048 if (!tx_verify(ctx) || !name ||
00049 (parent && (!tn_verify(parent) || parent->tn_context != ctx)))
00050 return EINVAL;
00051
00052
00053 if ((err = _tc_lookup_node(ctx, name, parent, &res)))
00054 return err;
00055
00056
00057 if (res.r_node && res.r_count == res.r_startnew) {
00058 treeconf_type_t type = (def ? TC_NODETYPE_VARIABLE : TC_NODETYPE_NODE);
00059
00060 if (!(res.r_node->tn_type & TC_NODETYPE_IMPLICIT) ||
00061 res.r_node->tn_default)
00062 _tc_doerror(TC_ERR_MULTREG);
00063
00064 if (def && !(def = strdup(def)))
00065 _tc_doerror(ENOMEM);
00066
00067
00068 if (((1 << type) ^ (1 << (res.r_node->tn_type & TC_NODETYPE_MASK))) &&
00069 res.r_node->tn_down)
00070 _tc_release_children(res.r_node);
00071
00072
00073 res.r_node->tn_type = type;
00074 res.r_node->tn_default = def;
00075 res.r_node->tn_nodown = nodown;
00076 res.r_node->tn_change = change;
00077 res.r_node->tn_assoc = assoc;
00078
00079 if (def) {
00080 if (!res.r_node->tn_value)
00081 res.r_node->tn_value = def;
00082 else if (!strcmp(res.r_node->tn_value, def)) {
00083
00084 free((void *)res.r_node->tn_value);
00085 res.r_node->tn_value = def;
00086 } else
00087 _tn_call_change(res.r_node);
00088 }
00089 } else
00090 for (i = res.r_startnew, node = res.r_node; i < res.r_count; i++)
00091 if (!(node = _tc_create_node(ctx, node,
00092 (def && i == res.r_count - 1 ?
00093 TC_NODETYPE_VARIABLE : TC_NODETYPE_NODE),
00094 res.r_comps[i].ts_string,
00095 res.r_comps[i].ts_length,
00096 (i == res.r_count - 1 ? def : 0),
00097 nodown, change, assoc)))
00098 _tc_doerror(ENOMEM);
00099
00100
00101 if (res.r_node)
00102 for (node = (res.r_node->tn_type & TC_NODETYPE_IMPLICIT) ?
00103 res.r_node : res.r_node->tn_parent;
00104 node && node->tn_type & TC_NODETYPE_IMPLICIT;
00105 node = node->tn_parent)
00106 node->tn_type &= ~TC_NODETYPE_IMPLICIT;
00107
00108 error:
00109 free(res.r_comps);
00110
00111 return err;
00112 }