This is an update to the previously posted patches. The major differences are:
The update to new_realloc() restores correct behaviour of panic() and
actually frees stuff if the size is 0.
Rewrote uniq and tuned jot and sort. How's this for performance:
*** 100000
*** 2.611273 seconds: eval echo $#uniq($sort($jot(0 99999)))
John.
diff -ruN ../epic4-1.0.1/include/ircaux.h ./include/ircaux.h
--- ../epic4-1.0.1/include/ircaux.h Thu Mar 8 05:03:23 2001
+++ ./include/ircaux.h Thu Sep 20 09:46:08 2001
@@ -20,24 +20,29 @@
#define new_malloc(x) really_new_malloc ((x), __FILE__, __LINE__)
#define new_free(x) really_new_free ((void **)(x), __FILE__, __LINE__)
+#define new_realloc(x,y) really_new_realloc ((x), (y), __FILE__, __LINE__)
#define MUST_BE_MALLOCED(x, y) \
fatal_malloc_check ((void *)(x), (y), __FILE__, __LINE__)
#define RESIZE(x, y, z) new_realloc ((void **)& (x), sizeof(y) * (z))
#define LOCAL_COPY(y) strcpy(alloca(strlen((y)) + 1), y)
+#define m_e3cat(x,y,z) m_ec3cat((x),(y),(z),NULL)
+#define m_s3cat(x,y,z) m_sc3cat((x),(y),(z),NULL)
+#define m_s3cat_s(x,y,z) m_sc3cat_s((x),(y),(z),NULL)
+#define m_3cat(x,y,z) m_c3cat((x),(y),(z),NULL)
extern int need_delayed_free;
void fatal_malloc_check (void *, const char *, char *, int);
void * really_new_malloc (size_t, char *, int);
void * really_new_free (void **, char *, int);
int debug_new_free (void **, char *, int);
-void * new_realloc (void **, size_t);
+void * really_new_realloc (void **, size_t, char *, int);
char * check_nickname (char *, int);
char * next_arg (char *, char **);
char * new_next_arg (char *, char **);
char * new_new_next_arg (char *, char **, char *);
char * s_next_arg (char **);
-char * last_arg (char **);
+char * last_arg (char **, size_t *cluep);
char * expand_twiddle (char *);
char * upper (char *);
char * lower (char *);
@@ -48,10 +53,10 @@
char * malloc_strcpy (char **, const char *);
char * malloc_strcat (char **, const char *);
char * malloc_str2cpy (char **, const char *, const char *);
-char * m_s3cat_s (char **, const char *, const char *);
-char * m_s3cat (char **, const char *, const char *);
-char * m_3cat (char **, const char *, const char *);
-char * m_e3cat (char **, const char *, const char *);
+char * m_sc3cat_s (char **, const char *, const char *, size_t *clue);
+char * m_sc3cat (char **, const char *, const char *, size_t *clue);
+char * m_c3cat (char **, const char *, const char *, size_t *clue);
+char * m_ec3cat (char **, const char *, const char *, size_t *clue);
char * m_2dup (const char *, const char *);
char * m_3dup (const char *, const char *, const char *);
char * m_opendup (const char *, ...) __A(1);
diff -ruN ../epic4-1.0.1/source/alias.c ./source/alias.c
--- ../epic4-1.0.1/source/alias.c Tue Dec 5 11:11:57 2000
+++ ./source/alias.c Thu Sep 20 09:46:08 2001
@@ -2354,6 +2354,7 @@
{
char **mlist = NULL;
char *mylist = NULL;
+ size_t mylistclue = 0;
int num = 0, ctr;
if (!my_stricmp(listc, "*"))
@@ -2368,7 +2369,7 @@
for (ctr = 0; ctr < num; ctr++)
{
- m_s3cat(&mylist, space, mlist[ctr]);
+ m_sc3cat(&mylist, space, mlist[ctr], &mylistclue);
new_free((char **)&mlist[ctr]);
}
new_free((char **)&mlist);
@@ -2380,6 +2381,7 @@
{
char ** mlist = NULL;
char * mylist = NULL;
+ size_t mylistclue = 0;
int num = 0,
ctr;
@@ -2390,7 +2392,7 @@
for (ctr = 0; ctr < num; ctr++)
{
- m_s3cat(&mylist, space, mlist[ctr]);
+ m_sc3cat(&mylist, space, mlist[ctr], &mylistclue);
new_free((char **)&mlist[ctr]);
}
new_free((char **)&mlist);
diff -ruN ../epic4-1.0.1/source/alist.c ./source/alist.c
--- ../epic4-1.0.1/source/alist.c Tue Dec 5 11:11:57 2000
+++ ./source/alist.c Thu Sep 20 09:46:08 2001
@@ -124,6 +124,7 @@
ret = ARRAY_ITEM(array, which);
move_array_items(array, which + 1, array->max, -1);
array->max--;
+ check_array_size(array);
return ret;
}
diff -ruN ../epic4-1.0.1/source/functions.c ./source/functions.c
--- ../epic4-1.0.1/source/functions.c Wed Mar 21 06:42:58 2001
+++ ./source/functions.c Thu Sep 20 09:49:14 2001
@@ -1149,6 +1149,7 @@
if (input && *input)
{
char *retval = NULL;
+ size_t rvclue=0;
char *nick;
const char *userhost;
@@ -1156,9 +1157,9 @@
{
GET_STR_ARG(nick, input);
if ((userhost = fetch_userhost(from_server, nick)))
- m_s3cat(&retval, space, userhost);
+ m_sc3cat(&retval, space, userhost, &rvclue);
else
- m_s3cat(&retval, space, unknown_userhost);
+ m_sc3cat(&retval, space, unknown_userhost, &rvclue);
}
RETURN_MSTR(retval);
}
@@ -1414,6 +1415,7 @@
{
int count;
char *retval = NULL;
+ size_t rvclue=0;
if (!input || !*input)
{
@@ -1424,7 +1426,7 @@
for (count = 0; count < number_of_servers; count++)
{
if (is_server_connected(count))
- m_s3cat(&retval, space, ltoa(count));
+ m_sc3cat(&retval, space, ltoa(count), &rvclue);
}
if (!retval)
RETURN_EMPTY;
@@ -1784,6 +1786,7 @@
*right = (char *) 0, **rightw = NULL, *booya = NULL;
int leftc, lefti,
rightc, righti;
+ size_t rvclue=0;
left = word;
if (!(right = strchr(word,'/')))
@@ -1799,7 +1802,7 @@
{
if (rightw[righti] && !my_stricmp(leftw[lefti],
rightw[righti]))
{
- m_s3cat(&booya, space, leftw[lefti]);
+ m_sc3cat(&booya, space, leftw[lefti], &rvclue);
rightw[righti] = NULL;
}
}
@@ -1825,6 +1828,7 @@
int lefti, leftc,
righti, rightc;
int found;
+ size_t rvclue=0;
left = word;
if ((right = strchr(word, '/')) == (char *) 0)
@@ -1834,7 +1838,7 @@
leftc = splitw(left, &leftw);
rightc = splitw(right, &rightw);
- for (lefti = 0; lefti < leftc; lefti++)
+ for (rvclue = lefti = 0; lefti < leftc; lefti++)
{
found = 0;
for (righti = 0; righti < rightc; righti++)
@@ -1846,13 +1850,13 @@
}
}
if (!found)
- m_s3cat(&booya, space, leftw[lefti]);
+ m_sc3cat(&booya, space, leftw[lefti], &rvclue);
}
- for (righti = 0; righti < rightc; righti++)
+ for (rvclue = righti = 0; righti < rightc; righti++)
{
if (rightw[righti])
- m_s3cat(&booya, space, rightw[righti]);
+ m_sc3cat(&booya, space, rightw[righti], &rvclue);
}
new_free((char **)&leftw);
@@ -1874,12 +1878,13 @@
char *blah;
char *booya = NULL;
char *pattern;
+ size_t rvclue=0;
GET_STR_ARG(pattern, word)
while (((blah = new_next_arg(word, &word)) != NULL))
{
if (wild_match(pattern, blah))
- m_s3cat(&booya, space, blah);
+ m_sc3cat(&booya, space, blah, &rvclue);
}
RETURN_MSTR(booya);
}
@@ -1894,12 +1899,13 @@
char *blah;
char *booya = NULL;
char *pattern;
+ size_t rvclue=0;
GET_STR_ARG(pattern, word)
while ((blah = new_next_arg(word, &word)) != NULL)
{
if (!wild_match(pattern, blah))
- m_s3cat(&booya, space, blah);
+ m_sc3cat(&booya, space, blah, &rvclue);
}
RETURN_MSTR(booya);
}
@@ -1915,13 +1921,14 @@
char *blah;
char *booya = NULL;
char *pattern;
+ size_t rvclue=0;
GET_STR_ARG(blah, word)
while ((pattern = new_next_arg(word, &word)) != NULL)
{
if (wild_match(pattern, blah))
- m_s3cat(&booya, space, pattern);
+ m_sc3cat(&booya, space, pattern, &rvclue);
}
RETURN_MSTR(booya);
}
@@ -1937,12 +1944,13 @@
char *blah;
char *booya = NULL;
char *pattern;
+ size_t rvclue=0;
GET_STR_ARG(blah, word)
while ((pattern = new_next_arg(word, &word)) != NULL)
{
if (!wild_match(pattern, blah))
- m_s3cat(&booya, space, pattern);
+ m_sc3cat(&booya, space, pattern, &rvclue);
}
RETURN_MSTR(booya);
}
@@ -1963,6 +1971,7 @@
*firstl = (char *) 0, *firstlist = (char *) 0, *firstel = (char *) 0,
*secondl = (char *) 0, *secondlist = (char *) 0, *secondel = (char *)
0;
char *sfirstl, *ssecondl;
+ size_t rvclue=0;
GET_STR_ARG(pattern, word);
GET_STR_ARG(firstlist, word);
@@ -1979,7 +1988,7 @@
break;
if (wild_match(pattern, firstel))
- m_s3cat(&booya, space, secondel);
+ m_sc3cat(&booya, space, secondel, &rvclue);
}
new_free(&sfirstl);
new_free(&ssecondl);
@@ -2200,6 +2209,7 @@
char *channel;
char *booya = (char *) 0;
const char *key;
+ size_t rvclue=0;
do
{
@@ -2208,7 +2218,7 @@
break;
key = get_channel_key(channel, current_window->server);
- m_s3cat(&booya, space, (key && *key) ? key : "*");
+ m_sc3cat(&booya, space, (key && *key) ? key : "*", &rvclue);
}
while (word && *word);
@@ -2224,6 +2234,7 @@
char *channel;
char *booya = (char *) 0;
char *mode;
+ size_t rvclue=0;
do
{
@@ -2232,7 +2243,7 @@
break;
mode = get_channel_mode(channel, current_window->server);
- m_s3cat(&booya, space, (mode && *mode) ? mode : "*");
+ m_sc3cat(&booya, space, (mode && *mode) ? mode : "*", &rvclue);
}
while (word && *word);
@@ -2244,9 +2255,10 @@
BUILT_IN_FUNCTION(function_revw, words)
{
char *booya = NULL;
+ size_t rvclue=0, wclue=0;
while (words && *words)
- m_s3cat(&booya, space, last_arg(&words));
+ m_sc3cat(&booya, space, last_arg(&words, &wclue), &rvclue);
if (!booya)
RETURN_EMPTY;
@@ -2279,7 +2291,7 @@
int counter;
char *booya = NULL;
int range;
- size_t size;
+ size_t size, clue = 0;
GET_INT_ARG(start,input)
GET_INT_ARG(stop, input)
@@ -2299,24 +2311,20 @@
if (start < stop)
{
- strlcpy(booya, ltoa(start), size);
- for (counter = start + interval;
+ for (counter = start;
counter <= stop;
counter += interval)
{
- strlcat(booya, space, size);
- strlcat(booya, ltoa(counter), size);
+ m_sc3cat(&booya, space, ltoa(counter), &clue);
}
}
else
{
- strlcpy(booya, ltoa(start), size);
- for (counter = start - interval;
+ for (counter = start;
counter >= stop;
counter -= interval)
{
- strlcat(booya, space, size);
- strlcat(booya, ltoa(counter), size);
+ m_sc3cat(&booya, space, ltoa(counter), &clue);
}
}
@@ -2450,6 +2458,7 @@
char * retval = NULL;
char * (*func) (const char *, const char *) = strstr;
int variable = 0, global = 0;
+ size_t rvclue=0;
/*
* Scan the leading part of the argument list, slurping up any
@@ -2546,7 +2555,7 @@
* is before the string to be replaced, and also
* the string that is to be doing the replacing.
*/
- m_e3cat(&retval, keep_text, replace_with);
+ m_ec3cat(&retval, keep_text, replace_with, &rvclue);
/*
* And now we want to step over the string and get
@@ -2639,13 +2648,14 @@
BUILT_IN_FUNCTION(function_ascii, word)
{
char *aboo = NULL;
+ size_t rvclue=0;
if (!word || !*word)
RETURN_EMPTY;
aboo = m_strdup(ltoa((long)(unsigned char)*word));
while (*++word)
- m_3cat(&aboo, space, ltoa((long)(unsigned char)*word));
+ m_c3cat(&aboo, space, ltoa((long)(unsigned char)*word), &rvclue);
return aboo;
}
@@ -3414,6 +3424,7 @@
*path2,
*retval = NULL;
int numglobs, i;
+ size_t rvclue=0;
glob_t globbers;
memset(&globbers, 0, sizeof(glob_t));
@@ -3435,10 +3446,10 @@
{
char *b = alloca(strlen(globbers.gl_pathv[i]) + 4);
sprintf(b, "\"%s\"", globbers.gl_pathv[i]);
- m_s3cat(&retval, space, b);
+ m_sc3cat(&retval, space, b, &rvclue);
}
else
- m_s3cat(&retval, space, globbers.gl_pathv[i]);
+ m_sc3cat(&retval, space, globbers.gl_pathv[i],
+&rvclue);
}
globfree(&globbers);
new_free(&path2);
@@ -3454,6 +3465,7 @@
*path2,
*retval = NULL;
int numglobs, i;
+ size_t rvclue=0;
glob_t globbers;
memset(&globbers, 0, sizeof(glob_t));
@@ -3476,10 +3488,10 @@
{
char *b = alloca(strlen(globbers.gl_pathv[i]) + 4);
sprintf(b, "\"%s\"", globbers.gl_pathv[i]);
- m_s3cat(&retval, space, b);
+ m_sc3cat(&retval, space, b, &rvclue);
}
else
- m_s3cat(&retval, space, globbers.gl_pathv[i]);
+ m_sc3cat(&retval, space, globbers.gl_pathv[i],
+&rvclue);
}
bsd_globfree(&globbers);
new_free(&path2);
@@ -3562,6 +3574,10 @@
}
+static int unsort_it (const void *one, const void *two)
+{
+ return *(char**)one-*(char**)two;
+}
/*
* Date: Sun, 29 Sep 1996 19:17:25 -0700
* Author: Thomas Morgan <[EMAIL PROTECTED]>
@@ -3575,9 +3591,10 @@
BUILT_IN_FUNCTION(function_uniq, word)
{
char **list = NULL, *booya = NULL;
- int listc, listi;
+ int listc, listi, listo;
char *tval;
char *input;
+ size_t rvclue=0;
RETURN_IF_EMPTY(word);
listc = splitw(word, &list);
@@ -3585,7 +3602,40 @@
/* 'list' is set to NULL if 'word' is empty. Punt in this case. */
if (!list)
RETURN_EMPTY;
-
+
+#if 1
+ /*
+ * Sort followed up with a remove duplicates. Standard stuff,
+ * only, the whacky way we go about it is due to compatibility.
+ *
+ * The major assumption here is that the pointers in list[] are
+ * in ascending order. Since splitw() works by inserting nuls
+ * into the original string, we can be somewhat secure here.
+ */
+ qsort((void *)list, listc, sizeof(char *), sort_it);
+
+ /* Remove _subsequent_ duplicate values wrt the original list
+ * This means, kill the higher valued pointers value.
+ */
+ for (listo = 0, listi = 1; listi < listc; listi++) {
+ if (sort_it(&list[listi],&list[listo])) {
+ listo = listi;
+ } else {
+ if (list[listi]<list[listo]) {
+ list[listo][0] = 0;
+ listo = listi;
+ } else {
+ list[listi][0] = 0;
+ }
+ }
+ }
+
+ /* We want the remaining words to appear in their original order */
+ qsort((void *)list, listc, sizeof(char *), unsort_it);
+ booya = unsplitw(&list, listc);
+
+#else
+
/*
* XXX This algorithm is too expensive. It should be done
* by some other way. Calling function_findw() is a hack.
@@ -3600,10 +3650,12 @@
tval = function_findw(input);
if (my_atol(tval) == -1)
- m_s3cat(&booya, space, list[listi]);
+ m_sc3cat(&booya, space, list[listi], &rvclue);
new_free(&tval);
}
+#endif
+
new_free((char **)&list);
RETURN_MSTR(booya);
}
@@ -4560,9 +4612,10 @@
{
Window *w = NULL;
char *retval = NULL;
+ size_t rvclue=0;
while (traverse_all_windows(&w))
- m_s3cat(&retval, space, ltoa(w->refnum));
+ m_sc3cat(&retval, space, ltoa(w->refnum), &rvclue);
RETURN_MSTR(retval);
}
@@ -4859,6 +4912,7 @@
rightc,
righti;
int found = 0;
+ size_t rvclue=0;
left = word;
if (!(right = strchr(word,'/')))
@@ -4881,7 +4935,7 @@
}
}
if (!found)
- m_s3cat(&booya, space, rhs[righti]);
+ m_sc3cat(&booya, space, rhs[righti], &rvclue);
rhs[righti] = NULL;
}
@@ -5717,12 +5771,13 @@
BUILT_IN_FUNCTION(function_notifywindows, input)
{
char * retval = NULL;
+ size_t rvclue=0;
Window *window;
window = NULL;
while (traverse_all_windows(&window))
if (window->miscflags & WINDOW_NOTIFIED)
- m_s3cat(&retval, space, ltoa(window->refnum));
+ m_sc3cat(&retval, space, ltoa(window->refnum), &rvclue);
RETURN_MSTR(retval);
}
diff -ruN ../epic4-1.0.1/source/ircaux.c ./source/ircaux.c
--- ../epic4-1.0.1/source/ircaux.c Thu Mar 15 07:01:46 2001
+++ ./source/ircaux.c Thu Sep 20 09:46:08 2001
@@ -191,9 +191,37 @@
return ((*ptr = NULL));
}
+#if 1
+
+/* really_new_malloc in disguise */
+void * really_new_realloc (void **ptr, size_t size, char *fn, int line)
+{
+ if (!size) {
+ *ptr=really_new_free(ptr, fn, line);
+ } else if (!*ptr) {
+ *ptr=really_new_malloc(size, fn, line);
+ } else {
+ *ptr -= sizeof(MO);
+ if (!(*ptr = (char *)realloc(*ptr, size + sizeof(MO))))
+ panic("realloc() failed, giving up!");
+
+ /* Store the size of the allocation in the buffer. */
+ *ptr += sizeof(MO);
+ alloc_size(*ptr) = size;
+ }
+ return *ptr;
+}
+
+#else
+
void * new_realloc (void **ptr, size_t size)
{
char *ptr2 = NULL;
+ size_t foo,bar;
+
+ /* Yes the function is ifdefed out, but this serves as a proof of concept. */
+ for (foo=1, bar=size+sizeof(MO); bar; foo<<=1, bar>>=1) /* Nothing */ ;
+ if (foo) {size=foo;}
if (*ptr)
{
@@ -215,6 +243,8 @@
return ((*ptr = ptr2));
}
+#endif
+
/*
* malloc_strcpy: Mallocs enough space for src to be copied in to where
* ptr points to.
@@ -250,6 +280,7 @@
char * malloc_strcat (char **ptr, const char *src)
{
size_t msize;
+ size_t psize;
if (*ptr)
{
@@ -259,9 +290,9 @@
if (!src)
return *ptr;
- msize = strlen(*ptr) + strlen(src) + 1;
+ msize = (psize=strlen(*ptr)) + strlen(src) + 1;
RESIZE(*ptr, char, msize);
- return strcat(*ptr, src);
+ return strcat(psize+*ptr, src)-psize;
}
return (*ptr = m_strdup(src));
@@ -347,40 +378,41 @@
return strcpy(ptr, str);
}
-char * m_e3cat (char **one, const char *yes1, const char *yes2)
+char * m_ec3cat (char **one, const char *yes1, const char *yes2, size_t *clue)
{
if (*one && **one)
- return m_3cat(one, yes1, yes2);
+ return m_c3cat(one, yes1, yes2, clue);
return (*one = m_2dup(yes1, yes2));
}
-char * m_s3cat (char **one, const char *maybe, const char *definitely)
+char * m_sc3cat (char **one, const char *maybe, const char *definitely, size_t *clue)
{
if (*one && **one)
- return m_3cat(one, maybe, definitely);
+ return m_c3cat(one, maybe, definitely, clue);
return malloc_strcpy(one, definitely);
}
-char * m_s3cat_s (char **one, const char *maybe, const char *ifthere)
+char * m_sc3cat_s (char **one, const char *maybe, const char *ifthere, size_t *clue)
{
if (ifthere && *ifthere)
- return m_3cat(one, maybe, ifthere);
+ return m_c3cat(one, maybe, ifthere, clue);
return *one;
}
-char * m_3cat(char **one, const char *two, const char *three)
+char * m_c3cat(char **one, const char *two, const char *three, size_t *clue)
{
- int msize = 0;
+ size_t csize = clue?*clue:0;
+ int msize = csize;
if (*one)
{
if (alloc_size(*one) == FREED_VAL)
panic("free()d pointer passed to m_3cat");
- msize += strlen(*one);
+ msize += strlen(csize+*one);
}
if (two)
msize += strlen(two);
@@ -396,9 +428,10 @@
RESIZE(*one, char, msize + 1);
if (two)
- strcat(*one, two);
+ strcat(csize+*one, two);
if (three)
- strcat(*one, three);
+ strcat(csize+*one, three);
+ if (clue) *clue=msize;
return *one;
}
@@ -559,15 +592,16 @@
* yanks off the last word from 'src'
* kinda the opposite of next_arg
*/
-char * last_arg (char **src)
+char * last_arg (char **src, size_t *cluep)
{
char *ptr;
+ size_t clue=cluep?*cluep:0;
if (!src || !*src)
return NULL;
- remove_trailing_spaces(*src);
- ptr = *src + strlen(*src) - 1;
+ ptr = clue + *src + strlen(clue+*src);
+ while (ptr > *src && *--ptr == ' ') *ptr = 0;
if (*ptr == '"')
{
@@ -598,15 +632,14 @@
}
}
+ if (cluep) *cluep=ptr-*src;
if (ptr == *src)
{
- ptr = *src;
*src = empty_string;
}
else
{
*ptr++ = 0;
- remove_trailing_spaces(*src);
}
return ptr;
}
@@ -2077,13 +2110,14 @@
{
char *retval = NULL;
char **str = *container;
+ size_t clue = 0;
if (!str || !*str)
return NULL;
while (howmany)
{
- m_s3cat(&retval, " ", *str);
+ if (*str && **str) m_sc3cat(&retval, " ", *str, &clue);
str++, howmany--;
}
diff -ruN ../epic4-1.0.1/source/notify.c ./source/notify.c
--- ../epic4-1.0.1/source/notify.c Tue Dec 5 11:11:57 2000
+++ ./source/notify.c Thu Sep 20 09:46:08 2001
@@ -538,6 +538,7 @@
{
char *list = NULL;
int i;
+ size_t rvclue=0;
if (showserver < 0 || showserver >= number_of_servers)
return m_strdup(empty_string);
@@ -545,7 +546,7 @@
for (i = 0; i < NOTIFY_MAX(showserver); i++)
{
if (showon == -1 || showon == NOTIFY_ITEM(showserver, i)->flag)
- m_s3cat(&list, space, NOTIFY_ITEM(showserver, i)->nick);
+ m_sc3cat(&list, space, NOTIFY_ITEM(showserver, i)->nick,
+&rvclue);
}
return (list ? list : m_strdup(empty_string));