Cleanup textblock's strbuf implementation.

This should provide correct code in a simpler way by sharing some of
the common code among functions.

Tested with E17 basics, require some applications with extensive usage
of textblock manipulation to do validate results.


SVN revision: 33939
This commit is contained in:
Gustavo Sverzut Barbieri 2008-03-06 00:41:47 +00:00
parent 4bd8fdaeeb
commit 23c566bb07
1 changed files with 119 additions and 108 deletions

View File

@ -245,132 +245,143 @@ _style_match_tag(Evas_Textblock_Style *ts, char *s)
return NULL;
}
static char *
_strbuf_append(char *s, const char *s2, int *len, int *alloc)
static inline int
_strbuf_realloc(char **strbuf, int *strbuf_alloc, int req_alloc)
{
int l2;
int tlen;
if (!s2) return s;
if ((!s) && (s2[0] == 0))
char *newbuf;
int newbuf_alloc;
newbuf_alloc = ((req_alloc + 31) >> 5) << 5;
if (newbuf_alloc == *strbuf_alloc)
return 1;
newbuf = realloc(*strbuf, newbuf_alloc);
if (!newbuf)
{
*len = 0;
*alloc = 1;
return strdup("");
perror("realloc: could not allocate new strbuf");
return 0;
}
l2 = strlen(s2);
tlen = *len + l2 + 1;
if (tlen > *alloc)
{
char *ts;
int talloc;
talloc = ((tlen + 31) >> 5) << 5;
ts = realloc(s, talloc);
if (!ts) return s;
s = ts;
*alloc = talloc;
}
strcpy(s + *len, s2);
*len += l2;
return s;
*strbuf = newbuf;
*strbuf_alloc = newbuf_alloc;
return 1;
}
static inline int
_strbuf_grow_if_required(char **strbuf, int *strbuf_alloc, int req_alloc)
{
if (req_alloc <= *strbuf_alloc)
return 1;
return _strbuf_realloc(strbuf, strbuf_alloc, req_alloc);
}
static char *
_strbuf_append_n(char *s, char *s2, int n, int *len, int *alloc)
_strbuf_append_int(char *strbuf, const char *text, int text_len, int *strbuf_len, int *strbuf_alloc)
{
int l2;
int tlen;
if (!s2) return s;
l2 = 0;
if (n < 1) return s;
else
{
char *p;
for (p = s2; (l2 < n) && (*p != 0); p++, l2++);
}
tlen = *len + l2 + 1;
if (tlen > *alloc)
{
char *ts;
int talloc;
talloc = ((tlen + 31) >> 5) << 5;
ts = realloc(s, talloc);
if (!ts) return s;
s = ts;
*alloc = talloc;
}
strncpy(s + *len, s2, l2);
*len += l2;
s[*len] = 0;
return s;
int req_alloc;
req_alloc = *strbuf_len + text_len + 1;
if (!_strbuf_grow_if_required(&strbuf, strbuf_alloc, req_alloc))
return strbuf;
memcpy(strbuf + *strbuf_len, text, text_len);
*strbuf_len += text_len;
strbuf[*strbuf_len] = '\0';
return strbuf;
}
static inline char *
_strbuf_append(char *strbuf, const char *text, int *strbuf_len, int *strbuf_alloc)
{
int text_len;
if ((!text) || (text[0] == '\0'))
return strbuf;
text_len = strlen(text);
return _strbuf_append_int(strbuf, text, text_len, strbuf_len, strbuf_alloc);
}
static inline char *
_strbuf_append_n(char *strbuf, const char *text, int max_text_len, int *strbuf_len, int *strbuf_alloc)
{
const char *p;
int text_len;
if ((!text) || (max_text_len < 1) || (text[0] == '\0'))
return strbuf;
text_len = 0;
for (p = text; (text_len < max_text_len) && (*p != '\0'); p++)
text_len++;
return _strbuf_append_int(strbuf, text, text_len, strbuf_len, strbuf_alloc);
}
static char *
_strbuf_insert(char *s, char *s2, int pos, int *len, int *alloc)
_strbuf_insert(char *strbuf, const char *text, int pos, int *strbuf_len, int *strbuf_alloc)
{
int l2;
int tlen;
char *tbuf;
if (!s2) return s;
else if (pos < 0) pos = 0;
else if (pos > *len) pos = *len;
l2 = strlen(s2);
tlen = *len + l2 + 1;
if (tlen > *alloc)
{
char *ts;
int talloc;
talloc = ((tlen + 31) >> 5) << 5;
ts = realloc(s, talloc);
if (!ts) return s;
s = ts;
*alloc = talloc;
}
tbuf = alloca(*len - pos);
strncpy(tbuf, s + pos, *len - pos);
strncpy(s + pos, s2, l2);
strncpy(s + pos + l2, tbuf, *len - pos);
*len += l2;
s[*len] = 0;
return s;
int req_alloc, text_len, tail_len;
if ((!text) || (text[0] == '\0'))
return strbuf;
if (pos >= *strbuf_len)
return _strbuf_append(strbuf, text, strbuf_len, strbuf_alloc);
else if (pos < 0)
pos = 0;
text_len = strlen(text);
/* ATTENTION: no + 1 is required for req_alloc as text will be
* inserted before the end of the string.
*/
req_alloc = *strbuf_len + text_len;
if (!_strbuf_grow_if_required(&strbuf, strbuf_alloc, req_alloc))
return strbuf;
tail_len = *strbuf_len - pos + 1; /* includes '\0' */
memmove(strbuf + pos + text_len, strbuf + pos, tail_len);
memcpy(strbuf + pos, text, text_len);
*strbuf_len += text_len;
return strbuf;
}
static char *
_strbuf_remove(char *s, int p, int p2, int *len, int *alloc)
_strbuf_remove(char *strbuf, int start, int end, int *strbuf_len, int *strbuf_alloc)
{
int tlen;
char *tbuf;
if ((p == 0) && (p2 == *len))
int remove_len, tail_len, req_alloc;
if (!strbuf)
return NULL;
if (start <= 0)
start = 0;
if (end >= *strbuf_len)
end = *strbuf_len;
remove_len = end - start;
if (remove_len <= 0)
return strbuf;
else if (remove_len == *strbuf_len)
{
free(s);
*len = 0;
*alloc = 0;
free(strbuf);
*strbuf_len = 0;
*strbuf_alloc = 0;
return NULL;
}
tbuf = alloca(*len - p2 + 1);
strcpy(tbuf, s + p2);
strcpy(s + p, tbuf);
tlen = *len - (p2 - p) + 1;
if (tlen < ((*alloc >> 5) << 15))
{
char *ts;
int talloc;
talloc = ((tlen + 31) >> 5) << 5;
ts = realloc(s, talloc);
if (!ts) return s;
s = ts;
*alloc = talloc;
}
*len += (p2 - p);
s[*len] = 0;
return s;
tail_len = *strbuf_len - end + 1; /* includes '\0' */
memmove(strbuf + start, strbuf + end, tail_len);
*strbuf_len -= remove_len;
req_alloc = *strbuf_len + 1;
_strbuf_realloc(&strbuf, strbuf_alloc, req_alloc);
return strbuf;
}
static void