|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 13421 (0x346d)
Types: TextFile
Names: »guide.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/dsap/common/guide.c«
/* guide.c - Search Guide handling */
#ifndef lint
static char *rcsid = "$Header: /f/osi/dsap/common/RCS/guide.c,v 7.0 89/11/23 21:42:17 mrose Rel $";
#endif
/*
* $Header: /f/osi/dsap/common/RCS/guide.c,v 7.0 89/11/23 21:42:17 mrose Rel $
*
*
* $Log: guide.c,v $
* Revision 7.0 89/11/23 21:42:17 mrose
* Release 6.0
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
/*
SYNTAX:
Guide ::= [<objectclass> '#'] <Criteria>
Criteria ::= CriteriaItem | CriteriaSet | '!' Criteria
CrtieriaSet ::= ['('] Criteria '@' CriteriaSet [')'] |
['('] Criteria '|' CriteriaSet [')']
CriteriaItem ::= ['('] <attributetype> '$' <matchType> [')']
matchType ::= "EQ" | "SUBSTR" | "GE" | "LE" | "APPROX"
EXAMPLES:
Person # commonName $ APPROX
( organization $ EQ ) @ (commonName $ SUBSTR)
( organization $ EQ ) @ ((commonName $ SUBSTR) | (commonName $ EQ))
NOTE:
Use of @ for "and" as '&' get filtered out earlier!!!
*/
/* LINTLIBRARY */
#include "quipu/util.h"
#include "quipu/attrvalue.h"
#include "cmd_srch.h"
static Criteria_free (arg)
struct Criteria *arg;
{
struct Criteria *parm = arg;
if (parm == NULL)
return;
switch (parm -> offset) {
case Criteria_type:
if (parm -> un.type)
free_CriteriaItem (parm -> un.type),
parm -> un.type = NULL;
break;
case Criteria_and:
case Criteria_or:
{
struct and_or_set *and_or_set;
for (and_or_set = parm -> un.and_or; and_or_set;) {
struct and_or_set *f_and_or_set = and_or_set -> and_or_next;
if (and_or_set -> and_or_comp)
Criteria_free (and_or_set -> and_or_comp),
and_or_set -> and_or_comp = NULL;
if (and_or_set)
free ((char *) and_or_set);
and_or_set = f_and_or_set;
}
parm -> un.and_or = NULL;
}
break;
case Criteria_not:
if (parm -> un.not)
Criteria_free (parm -> un.not),
parm -> un.not = NULL;
break;
}
free ((char *) arg);
}
static free_CriteriaItem (arg)
struct CriteriaItem *arg;
{
struct CriteriaItem *parm = arg;
if (parm == NULL)
return;
if (parm -> attrib)
AttrT_free (parm -> attrib), parm -> attrib = NULL;
free ((char *) arg);
}
static guidefree (arg)
struct Guide * arg;
{
if (arg == NULL)
return;
if (arg->objectClass)
oid_free (arg->objectClass);
Criteria_free (arg->criteria);
free ((char *)arg);
}
static struct CriteriaItem * CriteriaItem_cpy (arg)
struct CriteriaItem *arg;
{
struct CriteriaItem *parm = arg;
struct CriteriaItem *res;
if (parm == NULL)
return NULL;
res = (struct CriteriaItem *) smalloc (sizeof(struct CriteriaItem));
res->offset = parm->offset;
res->attrib = AttrT_cpy (parm->attrib);
return (res);
}
static struct Criteria * Criteria_cpy (a)
struct Criteria * a;
{
struct Criteria *b;
if (a == NULL)
return NULL;
b = (struct Criteria *) smalloc (sizeof(struct Criteria));
b-> offset = a->offset;
switch (a -> offset) {
case Criteria_type:
b->un.type = CriteriaItem_cpy (a->un.type);
break;
case Criteria_and:
case Criteria_or:
{
struct and_or_set *and_or_set;
struct and_or_set *ao_res = (struct and_or_set *)NULL;
struct and_or_set *ao_tmp;
ao_tmp = ao_res; /* OK lint ? */
for (and_or_set = a -> un.and_or; and_or_set; and_or_set = and_or_set->and_or_next) {
struct and_or_set *tmp;
tmp = (struct and_or_set *) smalloc (sizeof(struct and_or_set));
tmp->and_or_comp = Criteria_cpy(and_or_set->and_or_comp);
tmp->and_or_next = (struct and_or_set *)NULL;
if (ao_res == ((struct and_or_set *)NULL))
ao_res = tmp;
else
ao_tmp->and_or_next = tmp;
ao_tmp = tmp;
}
b->un.and_or = ao_res;
}
break;
case Criteria_not:
b->un.not = Criteria_cpy (a->un.not);
break;
}
return (b);
}
static struct Guide * guidecpy (a)
struct Guide * a;
{
struct Guide * b;
b = (struct Guide * ) smalloc (sizeof(struct Guide));
if (a->objectClass)
b->objectClass = oid_cpy (a->objectClass);
else
b->objectClass = NULLOID;
b->criteria = Criteria_cpy (a->criteria);
return (b);
}
#define NOCHOICE 255
static CMD_TABLE guide_tab [] = {
"EQ", choice_equality,
"SUBSTR", choice_substrings,
"GE", choice_greaterOrEqual,
"LE", choice_lessOrEqual,
"APPROX", choice_approximateMatch,
0, NOCHOICE
};
static struct CriteriaItem * CriteriaItem_parse (str)
char * str;
{
struct CriteriaItem * res;
char * ptr;
if ((str == NULLCP) || (*str == 0))
return ((struct CriteriaItem *) NULL);
res = (struct CriteriaItem *) smalloc (sizeof(struct CriteriaItem));
if ((ptr = index (str,'$')) == NULLCP) {
parse_error ("Seperator missing in CriteriaItem %s",str);
return ((struct CriteriaItem *) NULL);
}
*ptr-- = 0;
if (isspace (*ptr))
*ptr = 0;
ptr++;
if ((res -> attrib = AttrT_new (str)) == NULLAttrT) {
parse_error ("Unknown attribute type in CriteriaItem %s",str);
return ((struct CriteriaItem *) NULL);
}
*ptr++ = '$';
if ((res -> offset = cmd_srch(SkipSpace(ptr),guide_tab)) == NOCHOICE) {
parse_error ("Unknown search type in CriteriaItem %s",ptr);
return ((struct CriteriaItem *) NULL);
}
return (res);
}
static getop (str, ch)
char *str,
*ch;
{
int i,
bracket = 0;
for (i = 0; i < strlen (str); i++) {
if (bracket == 0 && (str[i] == '@' || str[i] == '|')) {
*ch = str[i];
return (i);
}
if (str[i] == '(')
++bracket;
if (str[i] == ')')
--bracket;
if (bracket < 0) {
parse_error ("Too many close brackets",NULLCP);
return (-2);
}
}
return (-1);
}
static struct Criteria * Criteria_parse (str)
char *str;
{
int gotit,
bracketed;
char ch,
och = '\0';
char * TidyString();
struct Criteria * result;
struct and_or_set * ao = (struct and_or_set *)NULL;
struct and_or_set * ao_ptr;
result = (struct Criteria *) smalloc (sizeof(struct Criteria));
str = TidyString (str);
/* Got a multiple-component string for parsing */
do {
bracketed = FALSE;
if ((gotit = getop (str, &ch)) == -2)
return ((struct Criteria *)NULL);
if (gotit < 0) {/* Match an open bracket. */
if (*str == '(')
if (str[strlen (str) - 1] == ')') {
str[strlen (str) - 1] = '\0';
++str;
bracketed = TRUE;
} else {
parse_error ("Too many open brackets",NULLCP);
return ((struct Criteria *)NULL);
}
if (och == '\0') {
if (bracketed == TRUE) {
gotit = 0; /* Stop 'while' loop
* falling */
continue; /* Parse the internals */
} else
break; /* Single item only */
} else
ch = och; /* Use last operation */
}
if (och == '\0')/* Remember last operation */
och = ch;
else if (och != ch) {
parse_error ("Can't Mix Operations.",NULLCP);
return ((struct Criteria *)NULL);
}
if (gotit >= 0) /* If got an op, make it null */
str[gotit] = '\0';
/* Recurse on the 'first' string */
ao_ptr = (struct and_or_set*) smalloc (sizeof(struct and_or_set));
if ((ao_ptr->and_or_comp = Criteria_parse (str)) == (struct Criteria *)NULL)
return ((struct Criteria *)NULL);
ao_ptr->and_or_next = (struct and_or_set*) NULL;
if (ao != (struct and_or_set *)NULL)
ao_ptr->and_or_next = ao;
ao = ao_ptr;
str += gotit + 1;
if (gotit >= 0) { /* Match an and symbol */
if (och == '@') {
result->offset = Criteria_and;
} else {/* Match an or symbol */
result->offset = Criteria_or;
}
}
result->un.and_or = ao;
}
while (gotit >= 0);
if (och == '\0') {
if (*str == '!') { /* Match a not symbol */
result->offset = Criteria_not;
if ((result->un.not = Criteria_parse (str + 1)) == (struct Criteria *)NULL)
return ((struct Criteria *)NULL);
} else {
result->offset = Criteria_type;
if ((result->un.type = CriteriaItem_parse(str)) == (struct CriteriaItem *)NULL)
return ((struct Criteria *)NULL);
}
}
return (result);
}
static struct Guide * guideparse (str)
char *str;
{
char *ptr;
struct Guide * res;
res = (struct Guide *) smalloc (sizeof (struct Guide));
if ((ptr = index (str,'#')) != NULLCP) {
*ptr-- = 0;
if (isspace (*ptr))
*ptr = 0;
ptr++;
if (( res->objectClass = name2oid(str)) == NULLOID) {
parse_error ("Unknown class in Guide %s",str);
return ((struct Guide *)NULL);
}
res->objectClass = oid_cpy (res->objectClass);
*ptr++ = '#';
str = ptr;
}
if ((res->criteria = Criteria_parse (SkipSpace(str))) == (struct Criteria *)NULL)
return ((struct Guide *)NULL);
return (res);
}
static CriteriaItem_print(ps,parm,format)
PS ps;
struct CriteriaItem * parm;
int format;
{
char *ptr;
if (parm == NULL)
return;
if ((ptr = rcmd_srch ((int)parm->offset,guide_tab)) == NULLCP)
ptr = "UNKNOWN !!!";
if (format == READOUT) {
ps_printf (ps,"%s on ",ptr);
AttrT_print (ps,parm->attrib,EDBOUT);
} else {
AttrT_print (ps,parm->attrib,format);
ps_printf (ps,"$%s",ptr);
}
}
static Criteria_print (ps,a,format)
PS ps;
struct Criteria * a;
int format;
{
char * sep;
if (format == READOUT)
sep = " OR ";
else
sep = "|";
if (a == NULL)
return;
switch (a -> offset) {
case Criteria_type:
CriteriaItem_print (ps,a->un.type,format);
break;
case Criteria_and:
if (format == READOUT)
sep = " AND ";
else
sep = "@";
case Criteria_or:
{
struct and_or_set *and_or_set;
char * tmp = NULLCP;
for (and_or_set = a -> un.and_or; and_or_set; and_or_set = and_or_set->and_or_next) {
if (tmp != NULLCP)
ps_print (ps,tmp);
ps_print (ps,"(");
Criteria_print(ps,and_or_set->and_or_comp,format);
ps_print (ps,")");
tmp = sep;
}
}
break;
case Criteria_not:
if (format == READOUT)
ps_print (ps,"NOT ");
else
ps_print (ps,"!");
ps_print (ps,"(");
Criteria_print (ps,a->un.not,format);
ps_print (ps,")");
break;
}
}
static guideprint (ps,a,format)
PS ps;
struct Guide * a;
int format;
{
if (a->objectClass) {
if (format == READOUT) {
ps_print (ps,"Class: ");
oidprint (ps,a->objectClass,format);
ps_print (ps,", search for: ");
} else {
oidprint (ps,a->objectClass,format);
ps_print (ps,"#");
}
}
Criteria_print (ps,a->criteria,format);
}
static PE guideenc (m)
struct Guide * m;
{
PE ret_pe;
(void) encode_SA_Guide (&ret_pe,0,0,NULLCP,m);
return (ret_pe);
}
static struct Guide * guidedec (pe)
PE pe;
{
struct Guide * m;
if (decode_SA_Guide (pe,1,NULLIP,NULLVP,&m) == NOTOK)
return ((struct Guide *) NULL);
if (decode_Criteria (m->criteria) == NOTOK)
return ((struct Guide *) NULL);
return (m);
}
static decode_Criteria (m)
struct Criteria * m;
{
int result;
switch (m -> offset) {
case Criteria_type:
result = decode_CriteriaItem (m -> un.type);
break;
case Criteria_and:
case Criteria_or:
{
struct and_or_set *and_or_set;
result = OK;
for (and_or_set = m -> un.and_or; and_or_set;) {
struct and_or_set *f_and_or_set = and_or_set -> and_or_next;
if (decode_Criteria (and_or_set -> and_or_comp) == NOTOK)
result = NOTOK;
and_or_set = f_and_or_set;
}
}
break;
case Criteria_not:
result = decode_Criteria (m -> un.not);
break;
}
return (result);
}
static decode_CriteriaItem (m)
struct CriteriaItem *m;
{
if (m == NULL)
return OK;
if (m -> attrib)
return (AttrT_decode (m -> attrib));
return OK;
}
static criteriaItem_cmp (a,b)
struct CriteriaItem *a,*b;
{
if (a == NULL)
return (b==NULL ? 0 : -1);
if (b == NULL)
return (1);
if (a->offset != b->offset)
return (a->offset>b->offset ? 1 : -1);
return (AttrT_cmp (a->attrib,b->attrib));
}
static criteria_cmp(a,b)
struct Criteria * a, *b;
{
int result;
if (a==NULL)
return(b==NULL ? 0 : -1);
if (b==NULL)
return(1);
if (a->offset != b->offset)
return (a->offset > b->offset ? 1 : -1);
switch (a -> offset) {
case Criteria_type:
return (criteriaItem_cmp (a->un.type, b->un.type));
case Criteria_and:
case Criteria_or:
{
struct and_or_set *a_set;
struct and_or_set *b_set;
for (a_set = a->un.and_or; a_set ; a_set = a_set->and_or_next) {
for (b_set = b->un.and_or; b_set ; b_set = b_set->and_or_next) {
if ((result=criteria_cmp (a_set -> and_or_comp,b_set->and_or_comp)) == 0)
break;
}
if (result != 0)
return (1);
}
for (b_set = b->un.and_or; b_set ; b_set = b_set->and_or_next) {
for (a_set = a->un.and_or; a_set ; a_set = a_set->and_or_next) {
if ((result=criteria_cmp (a_set -> and_or_comp,b_set->and_or_comp)) == 0)
break;
}
if (result != 0)
return (-1);
}
return (0);
}
case Criteria_not:
result = criteria_cmp (a->un.not,b->un.not);
break;
}
return (result);
}
static guidecmp (a,b)
struct Guide *a, *b;
{
int i;
if (a == (struct Guide *)NULL)
if (b == (struct Guide *)NULL)
return (0);
else
return (1);
if (b==(struct Guide *)NULL)
return (-1);
if ((i=oid_cmp(a->objectClass,b->objectClass)) == 0)
return (criteria_cmp(a->criteria,b->criteria));
return (i);
}
guide_syntax ()
{
(void) add_attribute_syntax ("Guide",
(IFP) guideenc, (IFP) guidedec,
(IFP) guideparse,guideprint,
(IFP) guidecpy, guidecmp,
guidefree, NULLCP,
NULLIFP, TRUE);
}