#include <stdio.h> #include <string.h> #include <ctype.h> #include "db.h" #include "config.h" #include "externs.h" #define DOWNCASE(x) tolower(x) int string_compare(char *s1, char *s2) { while(*s1 && *s2 && DOWNCASE(*s1) == DOWNCASE(*s2)) { s1++; s2++; } return(DOWNCASE(*s1) - DOWNCASE(*s2)); } int string_prefix(char *string, char *prefix) { while(*string && *prefix && DOWNCASE(*string) == DOWNCASE(*prefix)) { string++; prefix++; } return(!*prefix); } /* Accepts only nonempty matches starting at the beginning of a word */ char *string_match(char *src, char *sub) { if(*sub) { while(*src) { if(string_prefix(src, sub)) return(src); while(*src && isalnum(*src)) src++; while(*src && !isalnum(*src)) src++; } } return(NULL); } char *str_index(char *what, int chr) { char *x; for(x = what;*x;x++) if(chr == *x) return(x); return((char *)0); } char *my_ljust(char *str, int field) { int colorlen, textlen, len = 0; char buf[4096]; char colorbuf[1024]; char *b = buf; char *c = colorbuf; char *p = str; if(field > 80) return("FIELD LENGTH OUT OF RANGE!"); colorlen = str_colorlen(str); textlen = strlen(str)-colorlen; if(textlen <= field) { strcpy(buf, str); len = strlen(buf); b = buf+len; field += colorlen; while(len < field) { *b++ = ' '; len++; } *b = '\0'; return(stack_string_alloc(buf, 0)); } if(!strchr(str, '|')) { while(b-buf < field) *b++ = *p++; *b = '\0'; return(stack_string_alloc(buf, 0)); } while(*p && len < field) { while(*p && *p != '|' && len < field) { *b++ = *p++; len++; } *b = '\0'; if(!*p || len == field) break; *b++ = *p++; while(*p && *p != '|') *b++ = *p++; if(*p) *b++ = *p++; *b = '\0'; } p = str+strlen(str)-1; if(*p != '|') return(stack_string_alloc(buf, 0)); p--; while(p != str && *p != '|') p--; if(p == str) return(stack_string_alloc(buf, 0)); *c++ = *p++; while(*p != '|') *c++ = *p++; *c = '\0'; if(!my_is_color(colorbuf+1)) return(stack_string_alloc(buf, 0)); *c++ = '|'; *c = '\0'; strcat(buf, colorbuf); return(stack_string_alloc(buf, 0)); } char *my_rjust(char *str, int len) { char buf[4096]; char *b; int nocolorlen = strlen(strip_color(str)); for(b = buf;b-buf < len-nocolorlen;b++) *b = ' '; strcpy(b, str); return(stack_string_alloc(buf, 0)); } char *my_string(char *str, int num) { int i, j, k = 0; char buffer[4096]; if(num > 250) return("NUM OUT OF RANGE"); for(i = 0;i < num;i++) { for(j = 0;j < strlen(str);++j) buffer[k+j] = str[j]; k += strlen(str); } buffer[k] = '\0'; return(stack_string_alloc(buffer, 0)); } char *my_center(char *str, int width) { int i; int num = (width/2)-(strlen(str)/2); int color_len = str_colorlen(str); char buffer[4096]; char *b = buffer; if(width > 80) return("WIDTH OUT OF RANGE"); for(i = 0;i < num+color_len/2;++i) *b++ = ' '; while(*str) *b++ = *str++; *b = '\0'; for(i = strlen(buffer)-color_len;i < width;++i) *b++ = ' '; *b = '\0'; return(stack_string_alloc(buffer, 0)); } char *comma(char *num) { char buf[4096], buf2[4096]; char array[(strlen(num)/3)+3][5]; char *p = num; int i, len, ctr = 0, negative = 0; if(*p == '-') negative = 1; if(strchr(p, '.')) { p = strchr(p, '.'); strcpy(buf2, p); *p = '\0'; p = num; } else strcpy(buf2, ""); p = (negative)?num+1:num; if(strlen(p) < 4) { sprintf(buf, "%s%s", num, buf2); return(stack_string_alloc(buf, 0)); } if((len = strlen(p)%3)) { for(i = 0;i < len;++i) array[0][i] = *p++; array[0][i] = '\0'; ctr = 1; } while(*p) { for(i = 0;i < 3;++i) array[ctr][i] = *p++; array[ctr++][i] = '\0'; } strcpy(buf, (num[0] == '-')?"-":""); for(i = 0;i < ctr-1;++i) strcat(buf, tprintf("%s,", array[i])); strcat(buf, array[i]); strcat(buf, buf2); return(stack_string_alloc(buf, 0)); } char *strip_color(char *str) { char buffer[4096], buf[4096]; char *p, *b = buffer; char *s = str; if(!*str || !strchr(str, '|')) { strcpy(buffer, str); return(stack_string_alloc(buffer, 0)); } *buffer = '\0'; while(*s) { b = buffer+strlen(buffer); while(*s != '|' && *s) *b++ = *s++; *b = '\0'; if(!*s) /* Done searching the string, ready to return */ break; p = buf; *p++ = *s++; /* Point to the character right after the '|' */ if(!strchr(s, '|')) /* If there's only 1 '|' there can't be color */ { while(*s) *p++ = *s++; *p = '\0'; strcat(buffer, buf); return(stack_string_alloc(buffer, 0)); } while(*s != '|') /* Don't need to check for \0 since we just */ *p++ = *s++; /* determined that there's another '|' in str */ *p = '\0'; /* Let's make buf a null-terminated string */ if(my_is_color(buf+1)) /* Was the stuff between |'s really a color? */ { s++; continue; } *p++ = *s++; /* Get the '|' */ *p = '\0'; strcat(buffer, buf); } return(stack_string_alloc(buffer, 0)); } int str_colorlen(char *str) { return(strlen(str)-strlen(strip_color(str))); } char *box_header(char *str, char *color, int len) { char buff[4096]; sprintf(buff, "|%s|.%s.", color, my_string("-", len)); sprintf(buff+strlen(buff), "\n|%s||%s|%s||", color, my_center(str, len), color); sprintf(buff+strlen(buff), "\n|%s||%s|", color, my_string("-", len)); return(stack_string_alloc(buff, 0)); } void extract_char(char *start) { char *p, *q; if(!*start) return; for(p = start, q = start+1;*q;p++, q++) *p = *q; *p = '\0'; } char *check_plural(int amt, char *singular, char *plural) { return((amt == 1)?singular:plural); } void del_whitespace(char **str) { char *p; while(isspace(**str)) (*str)++; for(p = *str;*p;p++) while(isspace(*p) && isspace(*(p+1))) strcpy(p, p+1); p--; while(p > *str && isspace(*p)) *p-- = '\0'; } char *first_word(char *str) { char buf[4096]; char *b; while(isspace(*str)) str++; for(b = buf;*str && !isspace(*str);str++, b++) *b = *str; *b = '\0'; return(stack_string_alloc(buf, 0)); } char *rest(char *str) { while(*str && !isspace(*str)) str++; while(isspace(*str)) str++; return(str); } char *last_char(char *str) { return(str+strlen(str)-1); } /* Help will be set to one of the following */ /* 0 - Normal match */ /* 1 - subcommand matches "help" */ /* 2 - subcommand is blank ("") */ SUBCOMMAND *subcommand_match(OBJ *player, char *str, SUBCOMMAND *commands, int *help) { SUBCOMMAND *sc, **sclist; int ctr = 0; if(!*str || !string_compare(str, "help")) { if(help) *help = (*str)?1:2; return(NULL); } if(help) *help = 0; for(sc = commands;sc->name;sc++) { if(sc->admin_only && !Wizard(player)) continue; if(string_prefix(sc->name, str)) { if(strlen(sc->name) == strlen(str)) return(sc); if(!ctr) sclist = (SUBCOMMAND **)stack_alloc(sizeof(SUBCOMMAND *), 0, 0); else sclist = (SUBCOMMAND **)stack_realloc_tmp(sclist, sizeof(SUBCOMMAND *)*(ctr+1)); sclist[ctr++] = sc; } } if(ctr != 1) return(NULL); if(sc->admin_only && !Wizard(player)) { notify(player, perm_denied()); return(NULL); } return(*sclist); } void subcommand_print(OBJ *player, char *name, SUBCOMMAND *commands) { SUBCOMMAND *sc; bool init = 0; for(sc = commands;sc->name;sc++) if(!sc->admin_only || Wizard(player)) { if(!init) { notify(player, tprintf("|+Y|%s Subcommands|+W|:", name)); init++; } notify(player, tprintf("|+B| %s", sc->name)); } if(!init) notify(player, tprintf("There are no %s subcommands available to you.", name)); }