Check-in [cc583a95b7]
Not logged in
Overview
Comment:Improved performance in string concatenations.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: cc583a95b7f1bdb25e17c85d9f69889c33066a56
User & Date: peter 2023-02-26 10:56:39
Context
2023-02-26
11:03:36
[d507ea8f6e] Added FTYPE keyword to list in Shell version. (user: peter tags: trunk)
10:56:39
[cc583a95b7] Improved performance in string concatenations. (user: peter tags: trunk)
2023-02-23
18:42:44
[dc03c7b8a0] Updated Docker file. Small code optimization in internal string handling. (user: peter tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to bacon_trunk/bacon.bac.

8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984

8985
8986
8987
8988
8989
8990
8991
8992
8993
ENDIF

IF TALLY(total$, "concat") OR nolex THEN
	WRITELN "char *__b2c__concat(int n, ...) { static char *buf[__b2c_STRING_FUNC] = { NULL }; static int idx = 0; long length = 0, buflen = 0, cnew; char *next; va_list ap; if (n == 0) { return (EmptyString); } idx++;" TO g_FUNCTIONS
	WRITELN "if (idx == __b2c_STRING_FUNC) { idx = 0; } va_start (ap, n); if(buf[idx]) { buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } while (n) { next = va_arg (ap, char *); if (next) { cnew = __b2c__len (next);" TO g_FUNCTIONS
	WRITELN "if(length+cnew >= buflen) { buf[idx] = (char *) __b2c_str_realloc (buf[idx], length + cnew); buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } memcpy(buf[idx] + length, next, cnew); length += cnew; }" TO g_FUNCTIONS
	WRITELN "n--; } va_end (ap); __b2c__SETLEN (buf[idx], length); buf[idx][length] = '\\0'; return ((char *) buf[idx]); }" TO g_FUNCTIONS
	WRITELN "char *__b2c__concat2(int total, ...) { long length = 0, buflen = 0, cnew; char *first, *ptr, *next, *dup = NULL; va_list ap, copy; int m, n; va_start (ap, total); va_copy (copy, ap); m = total; first = va_arg (ap, char *);" TO g_FUNCTIONS
	WRITELN "m--; if (m == 0) { return (EmptyString); } if (first) { ptr = va_arg (ap, char *); m--; if (m == 0) { return (first); } while (m) { ptr = va_arg (ap, char *); if (ptr == first) { dup = __b2c__strdup (first); break; } m--; } }" TO g_FUNCTIONS
	WRITELN "va_end(ap); if (((uintptr_t) first & 1) && __b2c__INRANGE (first)) { buflen = *(uint32_t *) (first - __b2c__BUFOFFSET + 4); } else { buflen = __b2c__len (first); } n = total; ptr = va_arg (copy, char *); n--;" TO g_FUNCTIONS
	WRITELN "next = va_arg (copy, char *); n--; if(next == ptr) { length = __b2c__len(ptr); next = va_arg (copy, char *); n--; } while(1) { if (next) { if (next == first && n <= m) { next = dup; } cnew = __b2c__len (next);" TO g_FUNCTIONS

	WRITELN "if (length + cnew >= buflen) { ptr = (char *) __b2c_str_realloc (ptr, length + cnew); buflen = *(uint32_t *) (ptr - __b2c__BUFOFFSET + 4); } memmove (ptr + length, next, cnew); length += cnew; } if(n)" TO g_FUNCTIONS
	WRITELN "{ next = va_arg (copy, char *); n--; } else { break; } } va_end (copy); if (dup) { free (dup); } __b2c__SETLEN (ptr, length); ptr[length] = '\\0'; return ((char *) ptr); }" TO g_FUNCTIONS
ENDIF

IF TALLY(total$, "count") OR nolex THEN
	WRITELN "long __b2c__count (int l, char *k, char *x, unsigned int y) { long i, z = 0; if (__b2c__option_utf8) { while (*x) { if (__b2c__utf8toasc (x) == y) { z++; } if ((*x & 0xF0) == 0xF0) { x += 4; }" TO g_FUNCTIONS
	WRITELN "else if ((*x & 0xE0) == 0xE0) { x += 3; } else if ((*x & 0xC0) == 0xC0) { x += 2; } else if ((*x & 0x80) == 0) { x++; } else { ERROR = 38; RUNTIMEFERR (\"COUNT\", ERROR, k, l); return(0); } } } else " TO g_FUNCTIONS
	WRITELN "{ for (i = 0; x[i] != '\\0'; i++) { if (x[i] == y) { z++; } } } return z; }" TO g_FUNCTIONS
ENDIF







|
<
|
|
>
|
|







8974
8975
8976
8977
8978
8979
8980
8981

8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
ENDIF

IF TALLY(total$, "concat") OR nolex THEN
	WRITELN "char *__b2c__concat(int n, ...) { static char *buf[__b2c_STRING_FUNC] = { NULL }; static int idx = 0; long length = 0, buflen = 0, cnew; char *next; va_list ap; if (n == 0) { return (EmptyString); } idx++;" TO g_FUNCTIONS
	WRITELN "if (idx == __b2c_STRING_FUNC) { idx = 0; } va_start (ap, n); if(buf[idx]) { buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } while (n) { next = va_arg (ap, char *); if (next) { cnew = __b2c__len (next);" TO g_FUNCTIONS
	WRITELN "if(length+cnew >= buflen) { buf[idx] = (char *) __b2c_str_realloc (buf[idx], length + cnew); buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } memcpy(buf[idx] + length, next, cnew); length += cnew; }" TO g_FUNCTIONS
	WRITELN "n--; } va_end (ap); __b2c__SETLEN (buf[idx], length); buf[idx][length] = '\\0'; return ((char *) buf[idx]); }" TO g_FUNCTIONS
	WRITELN "char *__b2c__concat2 (int total, ...) { long length = 0, state = 0, offset = 0, buflen, cnew, flen; char *first, *next, *buffer, *forg; va_list ap; va_start (ap, total); buffer = va_arg (ap, char *); total--; if (total == 0) { return (EmptyString); }" TO g_FUNCTIONS

	WRITELN "first = buffer; flen = __b2c__len (first); forg = first; if (((uintptr_t) buffer & 1) && __b2c__INRANGE (buffer)) { buflen = *(uint32_t *) (buffer - __b2c__BUFOFFSET + 4); } else { buflen = flen; } next = va_arg (ap, char *); total--; if (total == 0)" TO g_FUNCTIONS
	WRITELN "{ return (first); } while (1) { if (next) { if (next == forg) { cnew = flen; } else { cnew = __b2c__len (next); } if (flen + length + cnew >= buflen) { buffer = (char *) __b2c_str_realloc (buffer, flen + length + cnew); buflen = *(uint32_t *) (buffer - __b2c__BUFOFFSET + 4);" TO g_FUNCTIONS
	WRITELN "first = buffer + offset; } if (next != forg) { if (state == 0) { memmove (buffer + length + cnew, first, flen); offset = length + cnew; first = buffer + offset; memmove (buffer + length, next, cnew); } else { memmove (buffer + flen + length, next, cnew); }" TO g_FUNCTIONS
	WRITELN "length += cnew; } else { if (state == 0) { state++; } else { memmove (buffer + flen + length, first, flen); length += cnew; } } } if (total) { next = va_arg (ap, char *); total--; } else { break; } } va_end (ap); if (state) { length += flen; }" TO g_FUNCTIONS
	WRITELN "__b2c__SETLEN (buffer, length); buffer[length] = '\\0'; return ((char *) buffer); }" TO g_FUNCTIONS
ENDIF

IF TALLY(total$, "count") OR nolex THEN
	WRITELN "long __b2c__count (int l, char *k, char *x, unsigned int y) { long i, z = 0; if (__b2c__option_utf8) { while (*x) { if (__b2c__utf8toasc (x) == y) { z++; } if ((*x & 0xF0) == 0xF0) { x += 4; }" TO g_FUNCTIONS
	WRITELN "else if ((*x & 0xE0) == 0xE0) { x += 3; } else if ((*x & 0xC0) == 0xC0) { x += 2; } else if ((*x & 0x80) == 0) { x++; } else { ERROR = 38; RUNTIMEFERR (\"COUNT\", ERROR, k, l); return(0); } } } else " TO g_FUNCTIONS
	WRITELN "{ for (i = 0; x[i] != '\\0'; i++) { if (x[i] == y) { z++; } } } return z; }" TO g_FUNCTIONS
ENDIF

Changes to bacon_trunk/bacon.sh.

9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413

9414
9415
9416
9417
9418
9419
9420
9421
9422

if [[ ${TOTAL//concat/} != ${TOTAL} || ${NOLEX} -eq 1 ]]
then
    echo "char *__b2c__concat(int n, ...) { static char *buf[__b2c_STRING_FUNC] = { NULL }; static int idx = 0; long length = 0, buflen = 0, cnew; char *next; va_list ap; if (n == 0) { return (EmptyString); } idx++;" >> $g_FUNCTIONS
    echo "if (idx == __b2c_STRING_FUNC) { idx = 0; } va_start (ap, n); if(buf[idx]) { buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } while (n) { next = va_arg (ap, char *); if (next) { cnew = __b2c__len (next);" >> $g_FUNCTIONS
    echo "if(length+cnew >= buflen) { buf[idx] = (char *) __b2c_str_realloc (buf[idx], length + cnew); buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } memcpy(buf[idx] + length, next, cnew); length += cnew; }" >> $g_FUNCTIONS
    echo "n--; } va_end (ap); __b2c__SETLEN (buf[idx], length); buf[idx][length] = '\0'; return ((char *) buf[idx]); }" >> $g_FUNCTIONS
    echo "char *__b2c__concat2(int total, ...) { long length = 0, buflen = 0, cnew; char *first, *ptr, *next, *dup = NULL; va_list ap, copy; int m, n; va_start (ap, total); va_copy (copy, ap); m = total; first = va_arg (ap, char *);" >> $g_FUNCTIONS
    echo "m--; if (m == 0) { return (EmptyString); } if (first) { ptr = va_arg (ap, char *); m--; if (m == 0) { return (first); } while (m) { ptr = va_arg (ap, char *); if (ptr == first) { dup = __b2c__strdup (first); break; } m--; } }" >> $g_FUNCTIONS
    echo "va_end(ap); if (((uintptr_t) first & 1) && __b2c__INRANGE (first)) { buflen = *(uint32_t *) (first - __b2c__BUFOFFSET + 4); } else { buflen = __b2c__len (first); } n = total; ptr = va_arg (copy, char *); n--;" >> $g_FUNCTIONS
    echo "next = va_arg (copy, char *); n--; if(next == ptr) { length = __b2c__len(ptr); next = va_arg (copy, char *); n--; } while(1) { if (next) { if (next == first && n <= m) { next = dup; } cnew = __b2c__len (next);" >> $g_FUNCTIONS

    echo "if (length + cnew >= buflen) { ptr = (char *) __b2c_str_realloc (ptr, length + cnew); buflen = *(uint32_t *) (ptr - __b2c__BUFOFFSET + 4); } memmove (ptr + length, next, cnew); length += cnew; } if(n)" >> $g_FUNCTIONS
    echo "{ next = va_arg (copy, char *); n--; } else { break; } } va_end (copy); if (dup) { free (dup); } __b2c__SETLEN (ptr, length); ptr[length] = '\0'; return ((char *) ptr); }" >> $g_FUNCTIONS
fi

if [[ ${TOTAL//count/} != ${TOTAL} || ${NOLEX} -eq 1 ]]
then
    echo "long __b2c__count (int l, char *k, char *x, unsigned int y) { long i, z = 0; if (__b2c__option_utf8) { while (*x) { if (__b2c__utf8toasc (x) == y) { z++; } if ((*x & 0xF0) == 0xF0) { x += 4; }" >> $g_FUNCTIONS
    echo "else if ((*x & 0xE0) == 0xE0) { x += 3; } else if ((*x & 0xC0) == 0xC0) { x += 2; } else if ((*x & 0x80) == 0) { x++; } else { ERROR = 38; RUNTIMEFERR (\"COUNT\", ERROR, k, l); return(0); } } } else " >> $g_FUNCTIONS
    echo "{ for (i = 0; x[i] != '\0'; i++) { if (x[i] == y) { z++; } } } return z; }" >> $g_FUNCTIONS







|
<
|
|
>
|
|







9403
9404
9405
9406
9407
9408
9409
9410

9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422

if [[ ${TOTAL//concat/} != ${TOTAL} || ${NOLEX} -eq 1 ]]
then
    echo "char *__b2c__concat(int n, ...) { static char *buf[__b2c_STRING_FUNC] = { NULL }; static int idx = 0; long length = 0, buflen = 0, cnew; char *next; va_list ap; if (n == 0) { return (EmptyString); } idx++;" >> $g_FUNCTIONS
    echo "if (idx == __b2c_STRING_FUNC) { idx = 0; } va_start (ap, n); if(buf[idx]) { buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } while (n) { next = va_arg (ap, char *); if (next) { cnew = __b2c__len (next);" >> $g_FUNCTIONS
    echo "if(length+cnew >= buflen) { buf[idx] = (char *) __b2c_str_realloc (buf[idx], length + cnew); buflen = *(uint32_t*)(buf[idx]-__b2c__BUFOFFSET + 4); } memcpy(buf[idx] + length, next, cnew); length += cnew; }" >> $g_FUNCTIONS
    echo "n--; } va_end (ap); __b2c__SETLEN (buf[idx], length); buf[idx][length] = '\0'; return ((char *) buf[idx]); }" >> $g_FUNCTIONS
    echo "char *__b2c__concat2 (int total, ...) { long length = 0, state = 0, offset = 0, buflen, cnew, flen; char *first, *next, *buffer, *forg; va_list ap; va_start (ap, total); buffer = va_arg (ap, char *); total--; if (total == 0) { return (EmptyString); }" >> $g_FUNCTIONS

    echo "first = buffer; flen = __b2c__len (first); forg = first; if (((uintptr_t) buffer & 1) && __b2c__INRANGE (buffer)) { buflen = *(uint32_t *) (buffer - __b2c__BUFOFFSET + 4); } else { buflen = flen; } next = va_arg (ap, char *); total--; if (total == 0)" >> $g_FUNCTIONS
    echo "{ return (first); } while (1) { if (next) { if (next == forg) { cnew = flen; } else { cnew = __b2c__len (next); } if (flen + length + cnew >= buflen) { buffer = (char *) __b2c_str_realloc (buffer, flen + length + cnew); buflen = *(uint32_t *) (buffer - __b2c__BUFOFFSET + 4);" >> $g_FUNCTIONS
    echo "first = buffer + offset; } if (next != forg) { if (state == 0) { memmove (buffer + length + cnew, first, flen); offset = length + cnew; first = buffer + offset; memmove (buffer + length, next, cnew); } else { memmove (buffer + flen + length, next, cnew); }" >> $g_FUNCTIONS
    echo "length += cnew; } else { if (state == 0) { state++; } else { memmove (buffer + flen + length, first, flen); length += cnew; } } } if (total) { next = va_arg (ap, char *); total--; } else { break; } } va_end (ap); if (state) { length += flen; }" >> $g_FUNCTIONS
    echo "__b2c__SETLEN (buffer, length); buffer[length] = '\0'; return ((char *) buffer); }" >> $g_FUNCTIONS
fi

if [[ ${TOTAL//count/} != ${TOTAL} || ${NOLEX} -eq 1 ]]
then
    echo "long __b2c__count (int l, char *k, char *x, unsigned int y) { long i, z = 0; if (__b2c__option_utf8) { while (*x) { if (__b2c__utf8toasc (x) == y) { z++; } if ((*x & 0xF0) == 0xF0) { x += 4; }" >> $g_FUNCTIONS
    echo "else if ((*x & 0xE0) == 0xE0) { x += 3; } else if ((*x & 0xC0) == 0xC0) { x += 2; } else if ((*x & 0x80) == 0) { x++; } else { ERROR = 38; RUNTIMEFERR (\"COUNT\", ERROR, k, l); return(0); } } } else " >> $g_FUNCTIONS
    echo "{ for (i = 0; x[i] != '\0'; i++) { if (x[i] == y) { z++; } } } return z; }" >> $g_FUNCTIONS

Changes to bacon_trunk/doc-pak/CHANGES.

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
+-------------------------------+
| 4.6.1 beta
+-------------------------------+
- Imp: added support for Haiku OS (all versions)
- Imp: extended BETWEEN functionality with BEYOND (all versions)
- Imp: added command line parameter '-r' to execute resulting binary after succesfull compilation (all versions)
- Imp: GUI functions now support TK as a backend (BaCon version)
- Imp: performance improvements in REGEX, WALK$, REPLACE$, EXTRACT$ (all versions)
- Imp: GETFILE can use optional FTYPE keyword to retrieve filetype (all versions)

- Fix: check on duplicate SUB or FUNCTION names (all versions - kudos rikky)
- Fix: memory leak in handling local string arrays (BaCon version)
- Fix: regression and improvement in RUN statement (BaCon resp. Shell version)
- Fix: type check in DECLARE/GLOBAL/LOCAL too strict (all versions - kudos rikky)
- Fix: syntax highlighting fixes (BaCon version, FLTK version)

November 1, 2022 - 4.6 stable









>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
+-------------------------------+
| 4.6.1 beta
+-------------------------------+
- Imp: added support for Haiku OS (all versions)
- Imp: extended BETWEEN functionality with BEYOND (all versions)
- Imp: added command line parameter '-r' to execute resulting binary after succesfull compilation (all versions)
- Imp: GUI functions now support TK as a backend (BaCon version)
- Imp: performance improvements in REGEX, WALK$, REPLACE$, EXTRACT$ (all versions)
- Imp: GETFILE can use optional FTYPE keyword to retrieve filetype (all versions)
- Imp: performance improvements in string concatenation (all versions)
- Fix: check on duplicate SUB or FUNCTION names (all versions - kudos rikky)
- Fix: memory leak in handling local string arrays (BaCon version)
- Fix: regression and improvement in RUN statement (BaCon resp. Shell version)
- Fix: type check in DECLARE/GLOBAL/LOCAL too strict (all versions - kudos rikky)
- Fix: syntax highlighting fixes (BaCon version, FLTK version)

November 1, 2022 - 4.6 stable