summaryrefslogtreecommitdiffstats
path: root/src/vf_search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vf_search.c')
-rw-r--r--src/vf_search.c457
1 files changed, 457 insertions, 0 deletions
diff --git a/src/vf_search.c b/src/vf_search.c
new file mode 100644
index 0000000..71be484
--- /dev/null
+++ b/src/vf_search.c
@@ -0,0 +1,457 @@
+/****************************************************************************
+
+ (C) Nick Marley, 2001 -
+
+ This software is distributed under the GNU Lesser General Public Licence.
+ Please read and understand the comments at the top of vf_iface.h before use!
+
+FILE
+ $Workfile: vf_access.c $
+ $Revision: 1.11 $
+ $Author: tilda $
+
+ORIGINAL AUTHOR
+ Nick Marley
+
+DESCRIPTION
+ Basic searching functions for the vformat library.
+
+REFERENCES
+ (none)
+
+MODIFICATION HISTORY
+ * $Log: vf_search.c,v $
+ * Revision 1.11 2002/11/03 18:43:16 tilda
+ * IID619851 - Update and check headers and function prototypes.
+ *
+ * Revision 1.10 2002/11/02 18:29:26 tilda
+ * IID485157 - UI does character conversion based on CHARSET property.
+ *
+ * Revision 1.9 2002/10/26 16:09:23 tilda
+ * IID629125 - Ensure string functions used are portable.
+ *
+ * Revision 1.8 2002/10/08 21:45:07 tilda
+ * IID620473 - reduce c-runtime dependencies.
+ *
+ * Revision 1.7 2002/10/08 21:11:36 tilda
+ * Remove common.h.
+ *
+ * Revision 1.6 2002/02/24 17:10:34 tilda
+ * Add API for "is modified" functionality.
+ *
+ * Revision 1.5 2001/11/18 21:46:59 tilda
+ * Remove redundant code.
+ *
+ * Revision 1.4 2001/11/16 22:34:50 tilda
+ * New vf_get_property() allows append as well as find,
+ *
+ * Revision 1.3 2001/11/05 21:07:19 tilda
+ * Various changes for initial version of vfedit.
+ *
+ * Revision 1.2 2001/10/24 18:56:29 tilda
+ * Tidy headers after import. Fix include path in release build.
+ *
+ * Revision 1.1 2001/10/24 18:34:35 tilda
+ * Initial Version.
+ *
+ *****************************************************************************/
+
+#ifndef NORCSID
+static const char vf_search_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_search.c,v 1.11 2002/11/03 18:43:16 tilda Exp $";
+#endif
+
+/*============================================================================*
+ ANSI C & System-wide Header Files
+ *============================================================================*/
+
+#include <common/types.h>
+
+/*===========================================================================*
+ Interface Header Files
+ *===========================================================================*/
+
+#include "vformat/vf_iface.h"
+
+/*===========================================================================*
+ Local Header File
+ *===========================================================================*/
+
+#include "vf_config.h"
+#include "vf_malloc.h"
+#include "vf_internals.h"
+#include "vf_strings.h"
+#include "vf_string_arrays.h"
+
+/*===========================================================================*
+ Public Data
+ *===========================================================================*/
+/* None */
+
+/*===========================================================================*
+ Private Defines
+ *===========================================================================*/
+
+/*
+ * Maximum supported search tags.
+ */
+#define MAXNUMTAGS (10)
+
+/*===========================================================================*
+ Private Data Types
+ *===========================================================================*/
+/* None */
+
+/*===========================================================================*
+ Private Function Prototypes
+ *===========================================================================*/
+
+
+/*===========================================================================*
+ Private Data
+ *===========================================================================*/
+/* None */
+
+/*===========================================================================*
+ Public Function Implementations
+ *===========================================================================*/
+
+
+
+/*---------------------------------------------------------------------------*
+ * NAME
+ * vf_get_property()
+ *
+ * DESCRIPTION
+ * Basic searching function locating elements of the VOBJECT by qualified
+ * name. The function is a varargs function (like sprintf) and the list
+ * of arguments must be NULL terminated (hence the appearance of the
+ * p_qualifier argument in the arglist). Valid calls might be:
+ *
+ * vf_get_property(&p_out, p_object, FALSE, NULL, "N", NULL);
+ * vf_get_property(&p_out, p_object, FALSE, NULL, "TEL", "WORK", NULL);
+ * vf_get_property(&p_out, p_object, FALSE, "ME", "TEL", "WORK", NULL);
+ * vf_get_property(&p_out, p_object, FALSE, "ME", "*", NULL);
+ *
+ * A pointer to the first property matching the search criteria is returned
+ * the pp_prop argument. The search actually locates all such matches and
+ * pointer to subsequent entries (if there are >1) may be found by calling
+ * the vf_get_next_property() function.
+ *
+ * Qualifying tags (ie. not the name) may occur in any order
+ *
+ * Note that the VF_PROP_T returned vi pp_prop is an opaque type and the
+ * various accessor functions must be used to get to the data.
+ *
+ * RETURNS
+ * TRUE iff found/added successfully. ptr to prop returned via pp_prop.
+ *---------------------------------------------------------------------------*/
+
+bool_t vf_get_property(
+ VF_PROP_T **pp_prop, /* Output pointer */
+ VF_OBJECT_T *p_object, /* Object to add to */
+ vf_get_t ops, /* Search flags */
+ const char *p_group, /* Group name if any */
+ const char *p_name, /* Name of tag */
+ const char *p_qualifier, /* First qualifier if any */
+ ... /* Subequent qualifiers */
+ )
+{
+ bool_t ret = FALSE;
+ va_list args;
+
+ va_start(args, p_qualifier);
+
+ ret = vf_get_property_ex(pp_prop, p_object, ops, p_group, p_name, p_qualifier, args);
+
+ va_end(args);
+
+ return ret;
+}
+
+
+
+
+
+
+
+
+/*---------------------------------------------------------------------------*
+ * NAME
+ * vf_get_property_ex()
+ *
+ * DESCRIPTION
+ * The grunt behind vf_get_property(). Manages the search as described
+ * vf_get_property() but takes the list of arguments as a va_list.
+ *
+ * RETURNS
+ * TRUE iff found / appended OK.
+ *---------------------------------------------------------------------------*/
+
+bool_t vf_get_property_ex(
+ VF_PROP_T **pp_prop, /* Output pointer */
+ VF_OBJECT_T *p_object, /* Object to search */
+ vf_get_t ops, /* Search flags */
+ const char *p_group, /* Group name if any */
+ const char *p_name, /* Name of tag */
+ const char *p_qualifier, /* First qualifier if any */
+ va_list args /* Argument list */
+ )
+{
+ bool_t ret = FALSE;
+ char **pp_tags = NULL;
+
+ if (!p_name || !p_object)
+ return ret;
+
+ if (pp_prop)
+ {
+ *pp_prop = NULL;
+ }
+
+ pp_tags = (char **)vf_malloc(MAXNUMTAGS * sizeof(char *));
+
+ if (pp_tags)
+ {
+ VOBJECT_T *p_obj = (VOBJECT_T *)p_object;
+ VPROP_T *p_props = p_obj->p_props;
+ int i;
+
+ VPROP_T **pp_lastprop = &(p_obj->p_props);
+ VPROP_T **pp_next_srch = NULL;
+
+ p_memset(pp_tags, '\0', MAXNUMTAGS * sizeof(char *));
+
+ pp_tags[0] = (char *)p_name;
+
+ /*
+ * The name is the first tag. We insist on there being at least one qualifier in the
+ * argument list to make sure callers terminate the list. Subsequent arguments are
+ * optional, but will be ignored if the (first) qualifier is NULL.
+ */
+ if (p_qualifier)
+ {
+ pp_tags[1] = (char *)p_qualifier;
+
+ for (i = 2;i < MAXNUMTAGS;i++)
+ {
+ char *p_tag = va_arg(args, char *);
+
+ if (p_tag)
+ {
+ pp_tags[i] = p_tag;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ if (ops & VFGP_FIND)
+ {
+ /*
+ * Skip down the list or properties. I'm assuming that we only want to search the
+ * current object for properties not the current object AND any contained objects.
+ * Such a search sounds a bit application specific, ie. the caller would be looking
+ * for a particular structure of things. Each element that is found is stitched
+ * into the emerging list.
+ */
+ for (;NULL != p_props;p_props = p_props->p_next)
+ {
+ bool_t found = TRUE;
+
+ /*
+ * Check the name & qualifiers.
+ */
+ for (i = 0;found && (i < MAXNUMTAGS) && pp_tags[i];i++)
+ {
+ if (0 != p_strcmp(VFP_ANY, pp_tags[i]))
+ found &= string_array_contains_string(&p_props->name, NULL, -1, pp_tags[i], TRUE);
+ }
+ if (p_group && found)
+ {
+ found = FALSE;
+
+ if (p_props->p_group)
+ {
+ if (0 == p_stricmp(p_props->p_group, p_group))
+ {
+ found = TRUE;
+ }
+ }
+ else
+ {
+ /* Search group specified & property doesn't have a group => not required */
+ }
+ }
+
+ if (found)
+ {
+ if (pp_prop)
+ {
+ if (!*pp_prop)
+ {
+ pp_next_srch = &(p_props->p_next_srch);
+ p_props->p_next_srch = NULL;
+
+ *pp_prop = (VF_PROP_T *)p_props;
+ }
+ else
+ {
+ *pp_next_srch = p_props;
+
+ pp_next_srch = &(p_props->p_next_srch);
+ p_props->p_next_srch = NULL;
+ }
+ }
+
+ ret = TRUE;
+ }
+
+ if (p_props->p_next)
+ {
+ pp_lastprop = &(p_props->p_next);
+ }
+ }
+ }
+
+ if (!ret && (ops & VFGP_APPEND))
+ {
+ VPROP_T *p_new = (VPROP_T *)vf_malloc(sizeof(VPROP_T));
+
+ if (p_new)
+ {
+ ret = TRUE;
+
+ p_memset(p_new, '\0', sizeof(VPROP_T));
+
+ p_new->p_parent = p_obj;
+
+ for (i = 0;ret && (i < MAXNUMTAGS) && pp_tags[i];i++)
+ {
+ ret = add_string_to_array(&p_new->name, pp_tags[i]);
+ }
+
+ if (ret)
+ {
+ /* All OK */
+
+ p_new->value.encoding = VF_ENC_7BIT;
+ }
+ else
+ {
+ free_string_array_contents(&p_new->name);
+
+ vf_free(p_new);
+ p_new = NULL;
+ }
+ }
+
+ if (p_new)
+ {
+ if (pp_prop)
+ {
+ *pp_prop = (VF_PROP_T *)p_new;
+ }
+
+ p_new->p_next = *pp_lastprop;
+ *pp_lastprop = p_new;
+
+ ret = TRUE;
+ }
+ }
+
+ vf_free(pp_tags);
+ }
+
+ return ret;
+}
+
+
+
+
+
+
+
+/*---------------------------------------------------------------------------*
+ * NAME
+ * vf_get_next_property()
+ *
+ * DESCRIPTION
+ * Find the next property given the current search critera.
+ *
+ * RETURNS
+ * TRUE iff found, FALSE else. *pp_prop points to the next property.
+ *---------------------------------------------------------------------------*/
+
+bool_t vf_get_next_property(
+ VF_PROP_T **pp_prop /* Output pointer */
+ )
+{
+ bool_t ret = FALSE;
+
+ if (pp_prop)
+ {
+ VPROP_T **pp_vprop = (VPROP_T **)pp_prop;
+
+ if (*pp_vprop)
+ {
+ *pp_prop = (VF_PROP_T *)((*pp_vprop)->p_next_srch);
+
+ if (*pp_prop)
+ {
+ ret = TRUE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+
+/*---------------------------------------------------------------------------*
+ * NAME
+ * vf_get_next_object()
+ *
+ * DESCRIPTION
+ * Find "next" vobject.
+ *
+ * RETURNS
+ * TRUE iff found next object.
+ *---------------------------------------------------------------------------*/
+
+bool_t vf_get_next_object(
+ VF_OBJECT_T **pp_object
+ )
+{
+ bool_t ret = FALSE;
+
+ if (pp_object)
+ {
+ if (*pp_object)
+ {
+ *pp_object = (VF_OBJECT_T *)(((VOBJECT_T *)(*pp_object))->p_next);
+
+ if (*pp_object)
+ {
+ ret = TRUE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+
+/*===========================================================================*
+ Private Function Implementations
+ *===========================================================================*/
+/* None */
+
+/*===========================================================================*
+ End Of File
+ *===========================================================================*/