Commit a3c42725 authored by Matthew Fernandez's avatar Matthew Fernandez
Browse files

Merge branch 'smattr/D2AA2D59-2982-42CC-9CA3-374F58FDC5B2' into 'main'

fix: put HTML bit at the top of the count in reference counted strings

Closes #1984

See merge request !1873
parents db90567d 64b798af
Pipeline #281146579 passed with stages
in 47 minutes and 19 seconds
......@@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Align rank from bottom in dot graph #1339
- Fix for TBbalance attribute code #1980
- HTML parser error with single closing square bracket in table row #1893
- reference counted strings put the HTML bit in the middle of the reference
count #1984
## [2.47.0] - 2021-03-15
......
......@@ -10,17 +10,16 @@
#include <cgraph/cghdr.h>
#include <stddef.h>
#include <stdio.h>
/*
* reference counted strings.
*/
enum { HTML_BIT = (uint64_t)(1u << (sizeof(unsigned) * 8 - 1)) };
enum { CNT_BITS = ~(uint64_t)HTML_BIT };
typedef struct refstr_t {
typedef struct {
Dtlink_t link;
uint64_t refcnt;
uint64_t refcnt: sizeof(uint64_t) * 8 - 1;
uint64_t is_html: 1;
char *s;
char store[1]; /* this is actually a dynamic array */
} refstr_t;
......@@ -105,6 +104,7 @@ char *agstrdup(Agraph_t * g, char *s)
else
r = malloc(sz);
r->refcnt = 1;
r->is_html = 0;
strcpy(r->store, s);
r->s = r->store;
dtinsert(strdict, r);
......@@ -130,7 +130,8 @@ char *agstrdup_html(Agraph_t * g, char *s)
r = (refstr_t *) agalloc(g, sz);
else
r = malloc(sz);
r->refcnt = 1 | HTML_BIT;
r->refcnt = 1;
r->is_html = 1;
strcpy(r->store, s);
r->s = r->store;
dtinsert(strdict, r);
......@@ -150,7 +151,7 @@ int agstrfree(Agraph_t * g, char *s)
r = refsymbind(strdict, s);
if (r && (r->s == s)) {
r->refcnt--;
if ((r->refcnt & CNT_BITS) == 0) {
if (r->refcnt == 0) {
agdtdelete(g, strdict, r);
}
}
......@@ -170,7 +171,7 @@ int aghtmlstr(char *s)
if (s == NULL)
return 0;
key = (refstr_t *) (s - offsetof(refstr_t, store[0]));
return (key->refcnt & HTML_BIT) != 0;
return key->is_html;
}
void agmarkhtmlstr(char *s)
......@@ -180,7 +181,7 @@ void agmarkhtmlstr(char *s)
if (s == NULL)
return;
key = (refstr_t *) (s - offsetof(refstr_t, store[0]));
key->refcnt |= HTML_BIT;
key->is_html = 1;
}
#ifdef DEBUG
......@@ -191,8 +192,7 @@ static int refstrprint(Dict_t * dict, void *ptr, void *user)
NOTUSED(dict);
r = ptr;
NOTUSED(user);
write(2, r->s, strlen(r->s));
write(2, "\n", 1);
fprintf(stderr, "%s\n", r->s);
return 0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment