/* Copyright (c) 1993 Stephen F. White */ #include "cool.h" #include "proto.h" char *str_ndup (const char *s, int n) { char *r; if (!s || !*s || n <= 0) { r = MALLOC (char, 1); *r = '\0'; } else { r = MALLOC (char, n + 1); strncpy (r, s, n); r[n] = '\0'; } return r; } char *str_dup (const char *s) { char *r; if (!s || !*s) { r = MALLOC (char, 1); *r = '\0'; } else { r = MALLOC (char, strlen (s) + 1); strcpy (r, s); } return r; } int hasparent (Object * o, Objid pid) { int i, r = 0; Object *p; List *parents = list_dup (o->parents); for (i = 0; i < parents->len; i++) { if (parents->el[i].v.obj.id == pid.id) { r = 1; break; } else if ((p = retrieve (parents->el[i].v.obj)) && hasparent (p, pid)) { r = 1; break; } } list_free (parents); return r; } Error check_parents (Objid player, Object * o, List * newparents) { int i, j; Objid parent; Object *p; #ifdef ROOT_OBJ if (newparents->len == 0) { if (o->id.id != ROOT_OBJ) { return E_RANGE; } } #endif /* ROOT_OBJ */ for (i = 0; i < newparents->len; i++) { parent = newparents->el[i].v.obj; if (parent.server) { /* parent is not local */ return E_INVIND; } else if (!(p = retrieve (parent))) { return E_OBJNF; } else if (p->id.id == o->id.id) { /* parent is this! */ return E_MAXREC; } else if (!can_clone (player, parent)) { return E_PERM; } for (j = 0; j < newparents->len; j++) { if (hasparent (p, newparents->el[j].v.obj)) { /* parents form a loop */ return E_MAXREC; } } } return E_NONE; } /* * NB: These versions of strcasecmp() and strncasecmp() depend on ASCII. */ static char cmap[257] = "\ \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\ \020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ \040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\ \060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\ \100\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\ \160\161\162\163\164\165\166\167\170\171\172\133\134\135\136\137\ \140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\ \160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\ \200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\ \220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\ \240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\ \260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\ \300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\ \320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\ \340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\ \360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"; int match (register const char *template, register const char *tomatch, char marker) { register const char *t; register int l; while (*tomatch == marker) { /* skip leading markers in string */ tomatch++; } if ((t = index (tomatch, marker))) { l = t - tomatch; } else { l = strlen (tomatch); } while (template && *template) { /* * skip leading markers in template */ while (*template == marker) { /* skip tokens in template */ template++; } /* * if substring of this word in template matches word, return 1 */ while( *template != marker && *template ) { if (!strncasecmp(template, tomatch, l)) { return 1; } template++; } /* * skip to next marker */ template = index (template, marker); } return 0; } int match_full (register const char *template, register const char *tomatch, char marker) { register const char *t; register int l1, l2; while (*tomatch == marker) { /* skip leading markers in string */ tomatch++; } l1 = strlen (tomatch); while (template && *template) { while (*template == marker) { /* skip leading markers in template */ template++; } if ((t = index (template, marker))) { l2 = t - template; } else { l2 = strlen (template); } if (l1 == l2 && !strncasecmp (template, tomatch, l2)) { /* got a match */ return 1; } template = t; /* skip to next marker */ } return 0; } int str_in (const char *s1, const char *s2) { const char *t2; int len = strlen (s1); for (t2 = s2; *t2; t2++) { if (!strncasecmp (s1, t2, len)) { return t2 - s2 + 1; } } return 0; } int verb_match (register const char *verb, register const char *word) { register const char *w; register short star; register char *c = cmap; while (*verb) { w = word; star = 0; while (1) { if (*verb == '*') { verb++; star = 1; } if (!*verb || isspace ((int)*verb) || !*w || c[(int)*w] != c[(int)*verb]) break; w++; verb++; } if (star && !*w) return 1; if (!*w && (!*verb || isspace ((int)*verb))) return 1; while (*verb && !isspace ((int)*verb)) verb++; while (isspace ((int)*verb)) verb++; } return 0; } int prep_match (const char *preplist, const char *argstr, const char **dobj, const char **prep, const char **iobj, int *dobjlen, int *preplen) { register const char *c = cmap; register const char *p; register const char *a = argstr; register const char *dend = a, *pstart; int dobj_quoted = 0; while (isspace ((int)*a)) { a++; } if (*a == '"') { *dobj = ++a; while (*a && *a != '"') { /* skip quoted dobj */ if( *a == '\\' ) /* Quote " with \ */ { switch( a[1] ) { case '"': a++; break; default: break; } } a++; } dend = a; dobj_quoted = 1; } else { *dobj = a; } while (*a) { if (!dobj_quoted) { dend = a; } while (isspace ((int)*a)) /* skip whitespace before prep */ a++; pstart = a; p = preplist; while (*p) { a = pstart; while (isspace ((int)*p)) /* skip whitespace */ p++; while (c[(int)*p++] == c[(int)*a++]) { if (*p == '_') { while (isspace ((int)*a)) a++; p++; } if (isspace ((int)*p) || (!*p && isspace ((int)*a)) || !*a) { if( !*p || !*a || c[(int)*p] == c[(int)*a] ) { *prep = pstart; *preplen = a - pstart; *dobjlen = dend - *dobj; while (isspace ((int)*a)) a++; *iobj = a; return 1; /* found a match, quit */ } else break; } } while (*p && !isspace ((int)*p)) /* skip to next preposition */ p++; } while (*a && !isspace ((int)*a)) /* no match, skip to next word */ a++; } return 0; } int valid_ident (const char *s) { if (!isalpha ((int)s[0]) && *s != '_') { return 0; } for (++s; *s; s++) { if (!isalnum ((int)*s) && *s != '_') { return 0; } } return 1; } String *strsub (const char *source, const char *what, const char *with, int case_matters) { register const char *s; String *r; int lwhat = strlen (what); if (lwhat == 0) { return string_cpy(source); } /* if */ r = string_new (0); s = source; while (*s) { if (case_matters ? !strncmp (s, what, lwhat) : !strncasecmp (s, what, lwhat)) { r = string_cat (r, with); s += lwhat; } else { r = string_catc (r, *s); s++; } } return r; } const char *addr_htoa (unsigned long l) { static char buf[32]; sprintf (buf, "%ld.%ld.%ld.%ld", (l >> 24) & 0xFF, (l >> 16) & 0xFF, (l >> 8) & 0xFF, l & 0xFF); return buf; } int count_words(const char *s, const char *sep) { int nwords = 0; while (*s) { /* skip leading separators */ while ( *s && strncmp( s, sep, strlen( sep ) ) == 0 ) s++; if (!*s) /* if that's it, bug out */ return nwords; /* skip to next separator */ while (*s && strncmp( s, sep, strlen( sep ) ) != 0 ) s++; nwords++; } return nwords; } /* simple substring search routines, courtesy of clay luther */ int strindex(const char *source, const char *what, int case_counts) { const char *s, *e; int lwhat = strlen(what); for (s = source, e = source + strlen(source) - lwhat; s <= e; s++) { if (! (case_counts ? strncmp(s, what, lwhat) : strncasecmp(s, what, lwhat))) { return s - source + 1; } } return 0; } int strrindex(const char *source, const char *what, int case_counts) { const char *s; int lwhat = strlen(what); for (s = source + strlen(source) - lwhat; s >= source; s--) { if (! (case_counts ? strncmp(s, what, lwhat) : strncasecmp(s, what, lwhat))) { return s - source + 1; } } return 0; }