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