/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ /* configure all options BEFORE including system stuff. */ #include "config.h" #include "sbuf.h" #include "mud.h" /* WARNING - static stretchy buffers several static stretchy buffers are allocated and kept here. this is the only way to do this efficiently. if the allocations fail, there's really jack-all we can do at this point, so we exit */ /* PRIVATE!! search for 'nam' in list 'l' and return a pointer to it */ static char *lstlookup (char *l, char *nam) { char *np; char *bp; if (l == (char *) 0) return ((char *) 0); while (*l != '\0') { np = nam; bp = l; while (*np != '\0') { if (*l != *np) break; l++, np++; } /* have we found it ? */ if (*np == '\0' && (*l == '\0' || *l == ';')) return (bp); /* no. skip to next semicolon */ while (*l != '\0') { if (*l++ == ';') break; } } return ((char *) 0); } /* user-level access to listlookup() - denied because i want to keep people from directly accessing pointers into the contents of a list */ int lstlook (char *l, char *nam) { if (lstlookup (l, nam)) return (1); return (0); } /* add 'nam' to list 'l' and return a pointer to the result. if 'lp' is not (int *)0, place the length of the result in 'lp. */ char *lstadd (char *l, char *nam, int *lp) { static Sbuf *sp = (Sbuf *) 0; char *xp; if (sp == (Sbuf *) 0 && (sp = sbuf_new ()) == (Sbuf *) 0) fatal ("cannot get list buffer: ", (char *) -1, "\n", (char *) 0); sbuf_reset (sp); xp = l; while (xp != (char *) 0 && *xp != '\0') { if (*xp != ';' || *(xp + 1) != ';') sbuf_put (*xp, sp); xp++; } /* only you can prevent dups */ if (lstlookup (l, nam) == (char *) 0) { /* special case - if the previous list SHOULD have a ; add */ if (xp != (char *) 0 && xp > l && *(xp - 1) != ';') sbuf_put (';', sp); /* copy in new and add a semicolon */ while (*nam != '\0') sbuf_put (*nam, sp), nam++; sbuf_put (';', sp); } sbuf_put ('\0', sp); if (lp != (int *) 0) *lp = sbuf_len (sp); return (sbuf_buf (sp)); } /* return a copy of the next element in list 'l', or null pointer at list end. buffer given is assumed to be large enough to fit an ID. WARNING - do not fiddle with the logic of scanning list next elements. NOTE!!!!! the match code assumes that this routine will "do the right thing" if given a single object-id as well as a list. if you change that, all hell will break loose in matching. */ char *lstnext (char *l, char *buf, int bs) { char *op = buf; if (l == (char *) 0 || *l == '\0') return ((char *) 0); while (*l != '\0') { if (*l == ';') { l++; /* if there is nothing in the buffer, keep going. */ if (op != buf) break; else continue; } /* objid too big */ if (--bs <= 0) { log_printf ("object-id too big\n", (char *) 0); while (*l != ';' && *l != '\0') l++; op = buf; continue; } *op++ = *l++; } *op = '\0'; return (l); } /* return a copy of the next element in list 'l', or null pointer at list end. items are copied out into a stretchy-buf. */ char *lstnextsbuf (char *l, Sbuf * sb) { if (l == (char *) 0 || *l == '\0') return ((char *) 0); sbuf_reset (sb); while (*l != '\0') { if (*l == ';') { l++; /* >= 'cuz we haven't added the null yet */ if (sbuf_len (sb) >= 0) break; else { sbuf_reset (sb); continue; } } sbuf_put (*l, sb), l++; } sbuf_put ('\0', sb); return (l); } /* delete 'nam' from list 'l' and return a pointer to the result if 'lp' is not (int *)0, place the length of the result in 'lp. */ char *lstdel (char *l, char *nam, int *lp) { static Sbuf *sp = (Sbuf *) 0; char *p1; char *p2; if (sp == (Sbuf *) 0 && (sp = sbuf_new ()) == (Sbuf *) 0) fatal ("cannot get list buffer: ", (char *) -1, "\n", (char *) 0); sbuf_reset (sp); /* heh. already not there, you goob */ if ((p1 = lstlookup (l, nam)) == (char *) 0) { (void) sbuf_strcpy (l, sp); goto done; } p2 = l; while (p2 < p1) sbuf_put (*p2, sp), p2++; /* skip the infected part */ while (*p2 != '\0') { /* skip the semicolon if one */ if (*p2 == ';') { p2++; break; } p2++; } /* take the rest */ while (*p2 != '\0') sbuf_put (*p2, sp), p2++; sbuf_put ('\0', sp); done: if (lp != (int *) 0) *lp = sbuf_len (sp); return (sbuf_buf (sp)); } /* return the number of elements in list 'l' */ int lstcnt (char *l) { int ret = 0; if (l == (char *) 0) return (0); while (*l != '\0') { if (*l == ';') ret++; l++; } return (ret); }