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