/* * 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 #include #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; }