222 lines
6.0 KiB
C
222 lines
6.0 KiB
C
/*
|
||
* DBprop.c --
|
||
*
|
||
* Implement properties on database cells. Properties are name-value pairs
|
||
* and provide a flexible way of extending the data that is stored in a
|
||
* CellDef. Maybe in the future properties will be added to other database
|
||
* objects.
|
||
*
|
||
* *********************************************************************
|
||
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
||
* * Permission to use, copy, modify, and distribute this *
|
||
* * software and its documentation for any purpose and without *
|
||
* * fee is hereby granted, provided that the above copyright *
|
||
* * notice appear in all copies. The University of California *
|
||
* * makes no representations about the suitability of this *
|
||
* * software for any purpose. It is provided "as is" without *
|
||
* * express or implied warranty. Export of this software outside *
|
||
* * of the United States of America may require an export license. *
|
||
* *********************************************************************
|
||
*/
|
||
|
||
#ifndef lint
|
||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/database/DBprop.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||
#endif /* not lint */
|
||
|
||
#include <stdio.h>
|
||
#include "utils/magic.h"
|
||
#include "utils/geometry.h"
|
||
#include "tiles/tile.h"
|
||
#include "utils/hash.h"
|
||
#include "database/database.h"
|
||
#include "utils/malloc.h"
|
||
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
*
|
||
*DBPropPut --
|
||
*
|
||
* Put a property onto a celldef.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
DBPropPut(cellDef, name, value)
|
||
CellDef *cellDef; /* Pointer to definition of cell. */
|
||
char *name; /* The name of the property desired. */
|
||
ClientData value; /* MUST point to a malloc'ed structure, or NULL.
|
||
* This will be freed when the CellDef is freed.
|
||
*/
|
||
|
||
{
|
||
HashTable *htab;
|
||
HashEntry *entry;
|
||
char *oldvalue;
|
||
|
||
/* Honor the NOEDIT flag */
|
||
if (cellDef->cd_flags & CDNOEDIT) return;
|
||
|
||
if (cellDef->cd_props == (ClientData) NULL)
|
||
{
|
||
cellDef->cd_props = (ClientData) mallocMagic(sizeof(HashTable));
|
||
HashInit( (HashTable *) cellDef->cd_props, 8, 0);
|
||
}
|
||
htab = (HashTable *) cellDef->cd_props;
|
||
|
||
/* Special handling of FIXED_BBOX, which uses CDFIXEDBBOX as a quick lookup */
|
||
if (!strcmp(name, "FIXED_BBOX"))
|
||
{
|
||
if (value == (ClientData)NULL)
|
||
cellDef->cd_flags &= ~CDFIXEDBBOX;
|
||
else
|
||
cellDef->cd_flags |= CDFIXEDBBOX;
|
||
}
|
||
|
||
entry = HashFind(htab, name);
|
||
oldvalue = (char *)HashGetValue(entry);
|
||
if (oldvalue != NULL) freeMagic(oldvalue);
|
||
if (value == (ClientData)NULL)
|
||
HashRemove(htab, name);
|
||
else
|
||
HashSetValue(entry, value);
|
||
}
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
*
|
||
* DBPropGet --
|
||
*
|
||
* Get a property from a celldef.
|
||
*
|
||
* Results:
|
||
* NULL if the property didn't exist, or if the property value was NULL.
|
||
* Otherwise, ClientData that represents the property.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
ClientData
|
||
DBPropGet(cellDef, name, found)
|
||
CellDef *cellDef; /* Pointer to definition of cell. */
|
||
char *name; /* The name of the property desired. */
|
||
bool *found; /* If not NULL, filled in with TRUE iff the property
|
||
* exists.
|
||
*/
|
||
{
|
||
ClientData result;
|
||
bool haveit;
|
||
HashTable *htab;
|
||
HashEntry *entry;
|
||
|
||
result = (ClientData) NULL;
|
||
haveit = FALSE;
|
||
htab = (HashTable *) cellDef->cd_props;
|
||
if (htab == (HashTable *) NULL) goto done;
|
||
|
||
entry = HashLookOnly(htab, name);
|
||
if (entry != NULL)
|
||
{
|
||
haveit = TRUE;
|
||
result = (ClientData) HashGetValue(entry);
|
||
}
|
||
|
||
done:
|
||
if (found != (bool *) NULL) *found = haveit;
|
||
return result;
|
||
}
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
*
|
||
* DBPropEnum --
|
||
*
|
||
* Enumerate all the properties on a cell.
|
||
*
|
||
* Results:
|
||
* 0 if the search completed, else whatever value was returned by the
|
||
* called proc.
|
||
*
|
||
* Side effects:
|
||
* Depends on the called proc.
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
int
|
||
DBPropEnum(cellDef, func, cdata)
|
||
CellDef *cellDef; /* Pointer to definition of cell. */
|
||
int (*func)(); /* Function of the form:
|
||
*
|
||
* int foo(name, value, cdata)
|
||
* char *name;
|
||
* ClientData value;
|
||
* ClientData cdata;
|
||
* {
|
||
* -- return 0 to continue,
|
||
* -- nonzero to abort.
|
||
* return result;
|
||
* }
|
||
*/
|
||
ClientData cdata;
|
||
{
|
||
HashTable *htab;
|
||
HashSearch hs;
|
||
HashEntry *entry;
|
||
int res;
|
||
|
||
if (cellDef->cd_props == (ClientData) NULL) return 0;
|
||
htab = (HashTable *) cellDef->cd_props;
|
||
|
||
HashStartSearch(&hs);
|
||
while ((entry = HashNext(htab, &hs)) != NULL)
|
||
{
|
||
res = (*func)(entry->h_key.h_name, (ClientData) entry->h_pointer, cdata);
|
||
if (res != 0) return res;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
/* ----------------------------------------------------------------------------
|
||
*
|
||
* DBPropClearAll --
|
||
*
|
||
* Free up all properties and associated storage for a CellDef.
|
||
*
|
||
* Results:
|
||
* none.
|
||
*
|
||
* Side effects:
|
||
* Frees up storage, even for the property table itself.
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
DBPropClearAll(cellDef)
|
||
CellDef *cellDef; /* Pointer to definition of cell. */
|
||
{
|
||
HashTable *htab;
|
||
HashSearch hs;
|
||
HashEntry *entry;
|
||
|
||
if (cellDef->cd_props == (ClientData) NULL) return;
|
||
htab = (HashTable *) cellDef->cd_props;
|
||
|
||
HashStartSearch(&hs);
|
||
while ((entry = HashNext(htab, &hs)) != NULL)
|
||
{
|
||
if (entry->h_pointer != NULL) freeMagic((char *) entry->h_pointer);
|
||
HashSetValue(entry, NULL);
|
||
}
|
||
|
||
HashKill(htab);
|
||
freeMagic((char *) htab);
|
||
cellDef->cd_props = (ClientData) NULL;
|
||
|
||
/* Since CDFIXEDBBOX requires a FIXED_BBOX property, clearing all */
|
||
/* properties necessarily means this flag must be clear. */
|
||
cellDef->cd_flags &= ~CDFIXEDBBOX;
|
||
}
|