240 lines
6.5 KiB
C
240 lines
6.5 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 <string.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. Note that the caller always assumes that */
|
|
/* the value would be saved in the hash table, so if it is not */
|
|
/* being used, then it must be freed here. */
|
|
|
|
if (cellDef->cd_flags & CDNOEDIT)
|
|
{
|
|
if (value != (ClientData)NULL)
|
|
freeMagic((char *)value);
|
|
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;
|
|
}
|
|
|
|
/* Special handling of GDS_FILE, which uses CDVENDORGDS as a quick lookup */
|
|
if (!strcmp(name, "GDS_FILE"))
|
|
{
|
|
if (value == (ClientData)NULL)
|
|
cellDef->cd_flags &= ~CDVENDORGDS;
|
|
else
|
|
cellDef->cd_flags |= CDVENDORGDS;
|
|
}
|
|
|
|
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;
|
|
}
|