/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/graph/refstr.c

Go to the documentation of this file.
00001 /* $Id: refstr.c,v 1.1.1.1 2004/12/23 04:02:40 ellson Exp $ $Revision: 1.1.1.1 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 #include        "libgraph.h"
00019 #include        <assert.h>
00020 
00021 static unsigned int HTML_BIT;
00022 static unsigned int CNT_BITS;
00023 
00024 #ifdef DMALLOC
00025 #include "dmalloc.h"
00026 #endif
00027 
00028 typedef struct refstr_t {
00029     Dtlink_t link;
00030     unsigned int refcnt;
00031     char s[1];
00032 } refstr_t;
00033 
00034 static Dtdisc_t Refstrdisc = {
00035     offsetof(refstr_t, s[0]),
00036     0,
00037     0,
00038     ((Dtmake_f) 0),
00039     ((Dtfree_f) 0),
00040     ((Dtcompar_f) 0),           /* use strcmp */
00041     ((Dthash_f) 0),
00042     ((Dtmemory_f) 0),
00043     ((Dtevent_f) 0)
00044 };
00045 
00046 static Dict_t *StringDict;
00047 
00048 #ifdef DEBUG
00049 static int refstrprint(Dt_t * d, Void_t * obj, Void_t * env)
00050 {
00051     refstr_t *r = (refstr_t *) obj;
00052     fprintf(stderr, "%s\n", r->s);
00053     return 0;
00054 }
00055 
00056 void agrefstrdump(void)
00057 {
00058     dtwalk(StringDict, refstrprint, 0);
00059 }
00060 #endif
00061 
00062 /* initialize_strings:
00063  * Create dictionary and masks for HTML strings.
00064  * HTML_BIT must be the most significant bit. We assume 8-bit bytes.
00065  */
00066 static void initialize_strings(void)
00067 {
00068     StringDict = dtopen(&Refstrdisc, Dttree);
00069     HTML_BIT = ((unsigned int) 1) << (sizeof(unsigned int) * 8 - 1);
00070     CNT_BITS = ~HTML_BIT;
00071 }
00072 
00073 char *agstrdup(char *s)
00074 {
00075     refstr_t *key, *r;
00076 
00077     if (StringDict == NULL)
00078         initialize_strings();
00079     if (s == NULL)
00080         return s;
00081 
00082     key = (refstr_t *) (s - offsetof(refstr_t, s[0]));
00083     r = (refstr_t *) dtsearch(StringDict, key);
00084     if (r)
00085         r->refcnt++;
00086     else {
00087         r = (refstr_t *) malloc(sizeof(refstr_t) + strlen(s));
00088         r->refcnt = 1;
00089         strcpy(r->s, s);
00090         dtinsert(StringDict, r);
00091     }
00092     return r->s;
00093 }
00094 
00095 /* agstrdup_html:
00096  * For various purposes, including deparsing, we have to recognize
00097  * strings coming from <...> rather than "...". To do this, we set
00098  * the top bit of the refcnt field. Since the use of html strings
00099  * is localized, we allow the application to make the distinction.
00100  */
00101 char *agstrdup_html(char *s)
00102 {
00103     refstr_t *key, *r;
00104 
00105     if (StringDict == NULL)
00106         initialize_strings();
00107     if (s == NULL)
00108         return s;
00109 
00110     key = (refstr_t *) (s - offsetof(refstr_t, s[0]));
00111     r = (refstr_t *) dtsearch(StringDict, key);
00112     if (r)
00113         r->refcnt++;
00114     else {
00115         r = (refstr_t *) malloc(sizeof(refstr_t) + strlen(s));
00116         r->refcnt = 1 | HTML_BIT;
00117         strcpy(r->s, s);
00118         dtinsert(StringDict, r);
00119     }
00120     return r->s;
00121 }
00122 
00123 void agstrfree(char *s)
00124 {
00125     refstr_t *key, *r;
00126 
00127     if ((StringDict == NULL) || (s == NULL))
00128         return;
00129     key = (refstr_t *) (s - offsetof(refstr_t, s[0]));
00130     r = (refstr_t *) dtsearch(StringDict, key);
00131 
00132     if (r) {
00133         r->refcnt--;
00134         if ((r->refcnt && CNT_BITS) == 0) {
00135             dtdelete(StringDict, r);
00136             free(r);
00137         }
00138     } else
00139         agerr(AGERR, "agstrfree lost %s\n", s);
00140 }
00141 
00142 /* aghtmlstr:
00143  * Return true if s is an HTML string.
00144  * We assume s points to the datafield s[0] of a refstr.
00145  */
00146 int aghtmlstr(char *s)
00147 {
00148     refstr_t *key;
00149 
00150     if ((StringDict == NULL) || (s == NULL))
00151         return 0;
00152     key = (refstr_t *) (s - offsetof(refstr_t, s[0]));
00153     return (key->refcnt & HTML_BIT);
00154 }

Generated on Mon Mar 31 19:03:26 2008 for Graphviz by  doxygen 1.5.1