]> jfr.im git - solanum.git/blobdiff - ircd/substitution.c
Resolve shfit/reduce conflict in timespec production (#54)
[solanum.git] / ircd / substitution.c
index bb935510f567c78a3c55d3b72e0ed25fe9dd823c..3301fd26459ad258f3624340c6a590359548a299 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * charybdis: an advanced ircd
+ * Solanum: a slightly advanced ircd
  * substitution.c: parses substitution-keyword expansions
  *
  * Copyright (c) 2006-2007 William Pitcock <nenolod@nenolod.net>
@@ -29,8 +29,6 @@
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
  */
 
 #include "stdinc.h"
@@ -83,7 +81,7 @@ void substitution_free(rb_dlink_list *varlist)
        {
                struct substitution_variable *tmp = (struct substitution_variable *) nptr->data;
 
-               rb_dlinkDelete(nptr, varlist);
+               rb_dlinkDestroy(nptr, varlist);
                rb_free(tmp->name);
                rb_free(tmp->value);
                rb_free(tmp);
@@ -103,48 +101,44 @@ char *substitution_parse(const char *fmt, rb_dlink_list *varlist)
        const char *ptr;
        char *bptr = buf;
 
-       for (ptr = fmt; *ptr != '\0' && bptr - buf < BUFSIZE; ptr++)
-               if (*ptr != '$')
+       for (ptr = fmt; *ptr != '\0' && bptr - buf < BUFSIZE; ptr++) {
+               if (*ptr != '$') {
                        *bptr++ = *ptr;
-               else if (*(ptr + 1) == '{')
-               {
-                       static char varname[BUFSIZE];
+               } else if (*(ptr + 1) == '{') {
+                       char varname[BUFSIZE] = { 0 };
                        char *vptr = varname;
-                       const char *pptr;
                        rb_dlink_node *nptr;
 
-                       *vptr = '\0';
-
                        /* break out ${var} */
-                       for (pptr = ptr + 2; *pptr != '\0'; pptr++)
-                       {
-                               if (*pptr != '}')
-                                       *vptr++ = *pptr;
-                               else
-                               {
-                                       *vptr++ = '\0';
+                       for (ptr += 2; *ptr != '\0'; ptr++) {
+                               if (*ptr == '$') {
+                                       ptr--;
                                        break;
+                               } else if (*ptr == '}') {
+                                       break;
+                               } else if (vptr < &varname[sizeof(varname) - 1]) {
+                                       *vptr++ = *ptr;
                                }
                        }
 
-                       s_assert(*varname != '\0');
-                       s_assert(*pptr != '\0');
-
-                       /* advance ptr by length of variable */
-                       ptr += (pptr - ptr);
-
-                       RB_DLINK_FOREACH(nptr, varlist->head)
-                       {
+                       RB_DLINK_FOREACH(nptr, varlist->head) {
                                struct substitution_variable *val = (struct substitution_variable *) nptr->data;
 
-                               if (!strcasecmp(varname, val->name))
-                               {
-                                       rb_strlcpy(bptr, val->value, BUFSIZE - (bptr - buf));
+                               if (!rb_strcasecmp(varname, val->name)) {
+                                       rb_strlcpy(bptr, val->value, sizeof(buf) - (bptr - buf));
                                        bptr += strlen(val->value);
+                                       if (bptr >= &buf[sizeof(buf)]) {
+                                               bptr = &buf[sizeof(buf) - 1];
+                                       }
                                        break;
                                }
                        }
+
+                       /* don't increment ptr into a following string if the '}' is missing */
+                       if (*ptr == '\0')
+                               break;
                }
+       }
 
        *bptr = '\0';
        return buf;