From 8f57b3306435cbd99b3eb8ef0431b8f50709d418 Mon Sep 17 00:00:00 2001 From: Rick Bird Date: Fri, 25 Mar 2011 14:05:56 -0400 Subject: [PATCH] PennMUSH Incorporation from 182p2 * list2arr in C now removes markup. list2arr_ansi() was added. [GM] --- game/txt/hlp/cobra_chat.hlp | 2 +- hdrs/parse.h | 9 ++- src/funlist.c | 143 +++++++++++++++++++++++++++++------- 3 files changed, 125 insertions(+), 29 deletions(-) diff --git a/game/txt/hlp/cobra_chat.hlp b/game/txt/hlp/cobra_chat.hlp index 2d0d308..95319a1 100644 --- a/game/txt/hlp/cobra_chat.hlp +++ b/game/txt/hlp/cobra_chat.hlp @@ -33,7 +33,7 @@ as normal, preventing user-defined commands like "+last" from being clobbered by the chat system. - See also: chat + See also: chat, CHAN_USEFIRSTMATCH & @cemit @cemit[/noisy][/noeval] = diff --git a/hdrs/parse.h b/hdrs/parse.h index dd84c81..df0bc10 100644 --- a/hdrs/parse.h +++ b/hdrs/parse.h @@ -82,9 +82,12 @@ extern int list2arr(char *r[], int max, char *list, char sep); extern int elist2arr(char *r[], int max, char *list, char sep); /* The reverse */ extern void arr2list(char *r[], int max, char *list, char **lp, char *sep); - - - +/* Split a sep-delimited string into individual elements. + * Uses mush_strdup, so freearr() is required on all + * list2arr_ansi()'d arrays (r) */ +extern int list2arr_ansi(char *r[], int max, char *list, char sep); +/* Free an array generated by list2arr_ansi */ +extern void freearr(char *r[], int size); /* All function declarations follow the format: */ #ifndef HAVE_FUN_DEFINED diff --git a/src/funlist.c b/src/funlist.c index 7439d6c..f4b6a73 100644 --- a/src/funlist.c +++ b/src/funlist.c @@ -72,7 +72,8 @@ next_token(char *str, char sep) /** Convert list to array. * Chops up a list of words into an array of words. The list is - * destructively modified. + * destructively modified. The array returned consists of + * mush_strdup'd strings. * \param r pointer to array to store words. * \param max maximum number of words to split out. * \param list list of words as a string. @@ -80,7 +81,7 @@ next_token(char *str, char sep) * \return number of words split out. */ int -list2arr(char *r[], int max, char *list, char sep) { +list2arr_ansi(char *r[], int max, char *list, char sep) { char *p, *lp; int i; int first; @@ -96,14 +97,45 @@ list2arr(char *r[], int max, char *list, char sep) { p = split_token(&aptr, sep); first = 0; for (i = 0; p && (i < max); i++, p = split_token(&aptr, sep)) { - r[i] = lp; - safe_ansi_string(as, p - (as->text), strlen(p), list, &lp); - *(lp++) = '\0'; + lp = list; + safe_ansi_string2(as, p - (as->text), strlen(p), list, &lp); + *lp = '\0'; + r[i] = mush_strdup(list, "list2arr_item"); } free_ansi_string(as); return i; } +/** Convert list to array. + * Chops up a list of words into an array of words. The list is + * destructively modified. + * \param r pointer to array to store words. + * \param max maximum number of words to split out. + * \param list list of words as a string. + * \param sep separator character between list items. + * \return number of words split out. + */ +int +list2arr(char *r[], int max, char *list, char sep) +{ + char *p, *lp; + int i; + int first; + char *aptr; + + memcpy(list, remove_markup(list, NULL), BUFFER_LEN); + + aptr = trim_space_sep(list, sep); + + lp = list; + p = split_token(&aptr, sep); + first = 0; + for (i = 0; p && (i < max); i++, p = split_token(&aptr, sep)) { + r[i] = p; + } + return i; +} + /* convert a character into an array and acknowledge a seperator character that may be escaped */ /* String is not destruviely modified like list2arr does */ int elist2arr(char *r[], int max, char *list, char sep) { @@ -182,6 +214,20 @@ arr2list(char *r[], int max, char *list, char **lp, char *sep) **lp = '\0'; } +/** Free an array generated by list2arr. + * Takes an array of words and frees it. + * \param r pointer to array of words. + * \param size The number of items in the list. + */ +void +freearr(char *r[], int size) +{ + int i; + for (i = 0; i < size; i++) { + mush_free(r[i], "list2arr_item"); + } +} + /* ARGSUSED */ FUNCTION(fun_munge) { @@ -196,6 +242,7 @@ FUNCTION(fun_munge) char list1[BUFFER_LEN], *lp, rlist[BUFFER_LEN], *rp; char **ptrs1, **ptrs2, **results; + char **ptrs3; int i, j, nptrs1, nptrs2, nresults; dbref thing; ATTR *attrib; @@ -236,15 +283,24 @@ FUNCTION(fun_munge) ptrs1 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); ptrs2 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); + + /* ptrs3 is destructively modified, but it's a copy of ptrs2, so we + * make it a straight copy of ptrs2 and freearr() on ptrs2. */ + ptrs3 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); + if (!ptrs1 || !ptrs2) mush_panic("Unable to allocate memory in fun_munge"); - nptrs1 = list2arr(ptrs1, MAX_SORTSIZE, args[1], sep); - nptrs2 = list2arr(ptrs2, MAX_SORTSIZE, args[2], sep); + nptrs1 = list2arr_ansi(ptrs1, MAX_SORTSIZE, args[1], sep); + nptrs2 = list2arr_ansi(ptrs2, MAX_SORTSIZE, args[2], sep); + memcpy(ptrs3, ptrs2, MAX_SORTSIZE * sizeof(char *)); if (nptrs1 != nptrs2) { safe_str(T("#-1 LISTS MUST BE OF EQUAL SIZE"), buff, bp); + freearr(ptrs1, nptrs1); + freearr(ptrs2, nptrs2); mush_free((Malloc_t) ptrs1, "ptrarray"); mush_free((Malloc_t) ptrs2, "ptrarray"); + mush_free((Malloc_t) ptrs3, "ptrarray"); free_anon_attrib(attrib); return; } @@ -266,24 +322,28 @@ FUNCTION(fun_munge) results = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); if (!results) mush_panic("Unable to allocate memory in fun_munge"); - nresults = list2arr(results, MAX_SORTSIZE, rlist, sep); + nresults = list2arr_ansi(results, MAX_SORTSIZE, rlist, sep); first = 1; for (i = 0; i < nresults; i++) { for (j = 0; j < nptrs1; j++) { - if (ptrs2[j] && !strcmp(results[i], ptrs1[j])) { + if (ptrs3[j] && !strcmp(results[i], ptrs1[j])) { if (first) first = 0; else safe_str(osep, buff, bp); - safe_str(ptrs2[j], buff, bp); - ptrs2[j] = NULL; + safe_str(ptrs3[j], buff, bp); + ptrs3[j] = NULL; break; } } } + freearr(ptrs1, nptrs1); + freearr(ptrs2, nptrs2); + freearr(results, nresults); mush_free((Malloc_t) ptrs1, "ptrarray"); mush_free((Malloc_t) ptrs2, "ptrarray"); + mush_free((Malloc_t) ptrs3, "ptrarray"); mush_free((Malloc_t) results, "ptrarray"); free_anon_attrib(attrib); } @@ -319,7 +379,7 @@ FUNCTION(fun_elements) /* Turn the first list into an array. */ strcpy(wordlist, args[0]); - nwords = list2arr(ptrs, MAX_SORTSIZE, wordlist, sep); + nwords = list2arr_ansi(ptrs, MAX_SORTSIZE, wordlist, sep); s = trim_space_sep(args[1], ' '); @@ -339,6 +399,7 @@ FUNCTION(fun_elements) safe_str(ptrs[cur], buff, bp); } } + freearr(ptrs, nwords); mush_free((Malloc_t) ptrs, "ptrarray"); mush_free((Malloc_t) wordlist, "string"); } @@ -588,7 +649,7 @@ FUNCTION(fun_shuffle) * Will take an optional delimiter argument. */ - char *words[BUFFER_LEN / 2]; + char *words[MAX_SORTSIZE]; int n, i, j; char sep; char *osep, osepd[2] = { '\0', '\0' }; @@ -606,7 +667,7 @@ FUNCTION(fun_shuffle) /* split the list up, or return if the list is empty */ if (!*args[0]) return; - n = list2arr(words, BUFFER_LEN / 2, args[0], sep); + n = list2arr_ansi(words, MAX_SORTSIZE, args[0], sep); /* shuffle it */ for (i = 0; i < n; i++) { @@ -618,6 +679,7 @@ FUNCTION(fun_shuffle) } arr2list(words, n, buff, bp, osep); + freearr(words, n); } typedef enum { @@ -1118,10 +1180,11 @@ FUNCTION(fun_sort) } else strcpy(outsep, args[3]); - nptrs = list2arr(ptrs, MAX_SORTSIZE, args[0], sep); + nptrs = list2arr_ansi(ptrs, MAX_SORTSIZE, args[0], sep); sort_type = get_list_type(args, nargs, 2, ptrs, nptrs); do_gensort(executor, ptrs, NULL, nptrs, sort_type); arr2list(ptrs, nptrs, buff, bp, outsep); + freearr(ptrs, nptrs); } static void @@ -1234,7 +1297,7 @@ FUNCTION(fun_sortkey) safe_str(atr_value(attrib), tbuff, &tp); *tp = '\0'; - nptrs = list2arr(ptrs, MAX_SORTSIZE, args[1], sep); + nptrs = list2arr_ansi(ptrs, MAX_SORTSIZE, args[1], sep); /* Now we make a list of keys */ for (i = 0; i < nptrs; i++) { @@ -1251,6 +1314,7 @@ FUNCTION(fun_sortkey) sort_type = get_list_type(args, nargs, 3, keys, nptrs); do_gensort(executor, keys, ptrs, nptrs, sort_type); arr2list(ptrs, nptrs, buff, bp, outsep); + freearr(ptrs, nptrs); for (i = 0; i < nptrs; i++) { mush_free(keys[i], "sortkey"); } @@ -1301,11 +1365,12 @@ FUNCTION(fun_sortby) save_global_env("sortby", tptr); /* Split up the list, sort it, reconstruct it. */ - nptrs = list2arr(ptrs, MAX_SORTSIZE, args[1], sep); + nptrs = list2arr_ansi(ptrs, MAX_SORTSIZE, args[1], sep); if (nptrs > 1) /* pointless to sort less than 2 elements */ sane_qsort((void *) ptrs, 0, nptrs - 1, u_comp); arr2list(ptrs, nptrs, buff, bp, osep); + freearr(ptrs, nptrs); restore_global_env("sortby", tptr); free_anon_attrib(attrib); @@ -1334,8 +1399,8 @@ FUNCTION(fun_setinter) mush_panic("Unable to allocate memory in fun_setinter"); /* make arrays out of the lists */ - n1 = list2arr(a1, MAX_SORTSIZE, args[0], sep); - n2 = list2arr(a2, MAX_SORTSIZE, args[1], sep); + n1 = list2arr_ansi(a1, MAX_SORTSIZE, args[0], sep); + n2 = list2arr_ansi(a2, MAX_SORTSIZE, args[1], sep); if (nargs < 4) { osepd[0] = sep; @@ -1369,6 +1434,8 @@ FUNCTION(fun_setinter) if (val < 0) { x1++; if (x1 >= n1) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1376,6 +1443,8 @@ FUNCTION(fun_setinter) } else { x2++; if (x2 >= n2) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1386,6 +1455,8 @@ FUNCTION(fun_setinter) while (!gencomp(executor, a1[x1], a2[x2], sort_type)) { x1++; if (x1 >= n1) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1398,6 +1469,8 @@ FUNCTION(fun_setinter) if (val < 0) { x1++; if (x1 >= n1) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1405,6 +1478,8 @@ FUNCTION(fun_setinter) } else { x2++; if (x2 >= n2) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1416,12 +1491,16 @@ FUNCTION(fun_setinter) while (!gencomp(executor, a1[x1], a2[x2], sort_type)) { x1++; if (x1 >= n1) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; } } } + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); } @@ -1450,8 +1529,8 @@ FUNCTION(fun_setunion) mush_panic("Unable to allocate memory in fun_diff"); /* make arrays out of the lists */ - n1 = list2arr(a1, MAX_SORTSIZE, args[0], sep); - n2 = list2arr(a2, MAX_SORTSIZE, args[1], sep); + n1 = list2arr_ansi(a1, MAX_SORTSIZE, args[0], sep); + n2 = list2arr_ansi(a2, MAX_SORTSIZE, args[1], sep); if (nargs < 4) { osepd[0] = sep; @@ -1559,6 +1638,8 @@ FUNCTION(fun_setunion) } } } + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); } @@ -1586,8 +1667,8 @@ FUNCTION(fun_setdiff) mush_panic("Unable to allocate memory in fun_diff"); /* make arrays out of the lists */ - n1 = list2arr(a1, MAX_SORTSIZE, args[0], sep); - n2 = list2arr(a2, MAX_SORTSIZE, args[1], sep); + n1 = list2arr_ansi(a1, MAX_SORTSIZE, args[0], sep); + n2 = list2arr_ansi(a2, MAX_SORTSIZE, args[1], sep); if (nargs < 4) { osepd[0] = sep; @@ -1627,6 +1708,8 @@ FUNCTION(fun_setdiff) if (!val) { x1++; if (x1 >= n1) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1637,6 +1720,8 @@ FUNCTION(fun_setdiff) do { x1++; if (x1 >= n1) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1653,6 +1738,8 @@ FUNCTION(fun_setdiff) do { x1++; if (x1 >= n1) { + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); return; @@ -1671,6 +1758,8 @@ FUNCTION(fun_setdiff) x1++; } while ((x1 < n1) && !gencomp(executor, a1[x1], a1[x1 - 1], sort_type)); } + freearr(a1, n1); + freearr(a2, n2); mush_free((Malloc_t) a1, "ptrarray"); mush_free((Malloc_t) a2, "ptrarray"); } @@ -1699,7 +1788,7 @@ FUNCTION(fun_unique) mush_panic("Unable to allocate memory in fun_unique"); /* make array out of the list */ - n1 = list2arr(a1, MAX_SORTSIZE, args[0], sep); + n1 = list2arr_ansi(a1, MAX_SORTSIZE, args[0], sep); a2 = mush_malloc(n1 * sizeof(char *), "ptrarray"); if (!a2) @@ -1736,6 +1825,9 @@ FUNCTION(fun_unique) safe_str(a2[x1], buff, bp); } + freearr(a1, n1); + /* We don't freearr(a2) since it wasn't generated by + * list2arr, and is instead just pointers into a1 */ mush_free(a1, "ptrarray"); mush_free(a2, "ptrarray"); @@ -2562,7 +2654,7 @@ FUNCTION(fun_revwords) words = (char **) mush_malloc(sizeof(char *) * BUFFER_LEN, "wordlist"); - count = list2arr(words, BUFFER_LEN, args[0], sep); + count = list2arr_ansi(words, BUFFER_LEN, args[0], sep); if (count == 0) { mush_free((Malloc_t) words, "wordlist"); return; @@ -2573,6 +2665,7 @@ FUNCTION(fun_revwords) safe_str(osep, buff, bp); safe_str(words[--count], buff, bp); } + freearr(words, count); mush_free((Malloc_t) words, "wordlist"); } -- 2.30.2