Files
magic/database/DBprop.c
T
Tim Edwards a35f3b3d14 Additional code to make sure that the database scaling acts on all
values in a mask hints property, and added back the handling of
mask hints in the top level cell, since the hierarchical function
on cells does not apply the function to the top level.
2021-01-06 11:35:03 -05:00

229 lines
6.2 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. 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)
{
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;
}
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;
}