Files
magic/database/DBprop.c
T
Tim Edwards ea9d8cc3e5 Implemented first part of "mask hints", a method to allow mask
layers that are normally automatically generated to be supplemented
with additional geometry in the form of properties.  The first
commit implements a CIF operator "mask-hints" that tells CIFGenLayer
that additional geometry may be specified with a property named
"MASKHINTS_" plus the name passed to the operator as its only
argument.  A more extensive commit to be done will allow this
operator to be used on cifinput to use mask hints to retain the
exact geometry of mask layers used in the input file.
2020-12-14 16:16:37 -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;
}