PennMUSH Incorporation from 182p2
authorRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 18:05:56 +0000 (14:05 -0400)
committerRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 18:05:56 +0000 (14:05 -0400)
 * list2arr in C now removes markup. list2arr_ansi() was added. [GM]

game/txt/hlp/cobra_chat.hlp
hdrs/parse.h
src/funlist.c

index 2d0d3084f5589810e1dc3768aded0d7d7a396c9a..95319a1ff43cfb537ccf41b8e68f31e2f2a98994 100644 (file)
@@ -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] <channel>=<message>
 
index dd84c81a591080b30ff33fba2dccae427cee3b63..df0bc10d809ea61d992d7c2dcf8073cf3046bae0 100644 (file)
@@ -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
index 7439d6c3cc07a48817d1dadb865638001b9e678a..f4b6a7376553745d6c2aeb917edcb17338ae456e 100644 (file)
@@ -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");
 }