src/hcode/btech/mech.partnames.c

Go to the documentation of this file.
00001 /*
00002  * Author: Markus Stenberg <fingon@iki.fi>
00003  *
00004  *  Copyright (c) 1996 Markus Stenberg
00005  *  Copyright (c) 1998-2002 Thomas Wouters
00006  *  Copyright (c) 2000-2002 Cord Awtry
00007  *       All rights reserved
00008  */
00009 
00010 #include <stdio.h>
00011 #include <string.h>
00012 
00013 #include "mech.h"
00014 #include "htab.h"
00015 #include "create.h"
00016 #include "mech.partnames.h"
00017 
00018 void list_hashstat(dbref player, const char *tab_name, HASHTAB * htab);
00019 
00020 /* Main idea: 
00021    Keep 2 sorted tables, one of shortform -> index
00022    longform  -> index
00023    vlongform -> index
00024    Other
00025    index -> {short,long,vlong} form
00026 
00027    Index = ID + NUM_ITEMS * brand
00028  */
00029 
00030 #define BRANDCOUNT 5
00031 static PN *index_sorted[BRANDCOUNT + 1][NUM_ITEMS];
00032 
00033 /* Sorted: short -> index, long -> index */
00034 PN **short_sorted = NULL;
00035 PN **long_sorted = NULL;
00036 PN **vlong_sorted = NULL;
00037 int object_count;
00038 
00039 static void insert_sorted_brandname(int ind, PN * e)
00040 {
00041         int i, j;
00042 
00043 #define UGLY_SORT(b,a) \
00044   for (i = 0 ; i < ind; i++) if (strcmp(e->a, b[i]->a)<0) break; \
00045     for (j = ind ; j > i ; j--) b[j] = b[j-1]; b[i] = e
00046         UGLY_SORT(short_sorted, shorty);
00047         UGLY_SORT(long_sorted, longy);
00048         UGLY_SORT(vlong_sorted, vlongy);
00049 }
00050 
00051 extern char *part_figure_out_name(int i);
00052 extern char *part_figure_out_sname(int i);
00053 extern char *part_figure_out_shname(int i);
00054 extern char *GetPartBrandName(int, int);
00055 extern char *my_shortform(char *);
00056 
00057 int temp_brand_flag;
00058 
00059 static int create_brandname(int id, int b)
00060 {
00061         char buf[MBUF_SIZE];
00062         char buf2[MBUF_SIZE];
00063         char buf3[MBUF_SIZE];
00064         char *c, *brn = NULL;
00065         PN *p;
00066 
00067         if(b)
00068                 if(!(brn = GetPartBrandName(id, b)))
00069                         return 0;
00070         temp_brand_flag = b;
00071         Create(p, PN, 1);
00072 /* \todo Remove this stupid #define and make the code readable */
00073 #define SILLINESS(fun,val,fl) \
00074   if (!(c=fun(id))) \
00075     { free ((void *) p->val); free((void *) p); return 0; } \
00076   if (b) \
00077    { strcpy(buf2, c); \
00078      if (fl) \
00079      strcpy(buf3, my_shortform(brn)); \
00080    sprintf(buf, "%s.%s", fl ? buf3 : brn, buf2); } \
00081   else \
00082     strcpy(buf, c); \
00083   p->val = strdup(buf)
00084         SILLINESS(part_figure_out_name, vlongy, 0);
00085         SILLINESS(part_figure_out_sname, longy, 0);
00086         SILLINESS(part_figure_out_shname, shorty, 1);
00087         p->index = PACKED_PART(id, b);
00088         index_sorted[b][id] = p;
00089         return 1;
00090 }
00091 
00092 static HASHTAB short_hash, vlong_hash;
00093 
00094 void initialize_partname_tables()
00095 {
00096         int i, j, c = 0, m, n;
00097         char tmpbuf[MBUF_SIZE];
00098         char *tmpc1, *tmpc2;
00099 
00100         bzero(index_sorted, sizeof(index_sorted));
00101         for(j = 0; j <= BRANDCOUNT; j++)
00102                 for(i = 0; i < NUM_ITEMS; i++)
00103                         c += create_brandname(i, j);
00104         Create(short_sorted, PN *, c);
00105         Create(long_sorted, PN *, c);
00106         Create(vlong_sorted, PN *, c);
00107         /* bubble-sort 'em and insert to array */
00108         i = 0;
00109         for(m = 0; m <= BRANDCOUNT; m++)
00110                 for(n = 0; n < NUM_ITEMS; n++)
00111                         if(index_sorted[m][n])
00112                                 insert_sorted_brandname(i++, index_sorted[m][n]);
00113         hashinit(&short_hash, 20 * HASH_FACTOR);
00114         hashinit(&vlong_hash, 20 * HASH_FACTOR);
00115 #define DASH(fromval,tohash) \
00116   for (tmpc1 = short_sorted[i]->fromval, tmpc2 = tmpbuf ; *tmpc1 ; tmpc1++, tmpc2++) \
00117     *tmpc2 = ToLower(*tmpc1); \
00118   *tmpc2 = 0; \
00119   hashadd(tmpbuf, (int *) (i+1), &tohash);
00120 
00121         for(i = 0; i < c; i++) {
00122                 DASH(shorty, short_hash);
00123 
00124 /*       DASH(longy, long_hash); */
00125                 DASH(vlongy, vlong_hash);
00126         }
00127         object_count = c;
00128 }
00129 
00130 #define SILLY_GET(fun,value) \
00131 char * fun (int i, int b) { if (!(index_sorted[b][i])) \
00132 { if (b) return fun(i,0); else { SendError(tprintf("No index for %d/%d", i, b)); return NULL; } }\
00133 return index_sorted[b][i]->value; }
00134 
00135 SILLY_GET(get_parts_short_name, shorty);
00136 SILLY_GET(get_parts_long_name, longy);
00137 SILLY_GET(get_parts_vlong_name, vlongy);
00138 
00139 #define wildcard_match quick_wild
00140 extern int wildcard_match(char *, char *);
00141 
00142 int find_matching_vlong_part(char *wc, int *ind, int *id, int *brand)
00143 {
00144         PN *p;
00145         char *tmpc1, *tmpc2;
00146         char tmpbuf[MBUF_SIZE];
00147         int *i;
00148 
00149         if(ind && *ind >= 0)
00150                 return 0;
00151         for(tmpc1 = wc, tmpc2 = tmpbuf; *tmpc1; tmpc1++, tmpc2++) {
00152                 *tmpc2 = ToLower(*tmpc1);
00153         }
00154         *tmpc2 = 0;
00155         if((i = hashfind(tmpbuf, &vlong_hash))) {
00156                 if((p = short_sorted[((int) i) - 1])) {
00157                         if(ind)
00158                                 *ind = ((int) i);
00159                         UNPACK_PART(p->index, *id, *brand);
00160                         return 1;
00161                 }
00162         }
00163         return 0;
00164 }
00165 
00166 int find_matching_long_part(char *wc, int *i, int *id, int *brand)
00167 {
00168         PN *p;
00169 
00170         for((*i)++; *i < object_count; (*i)++)
00171                 if(wildcard_match(wc, (p = long_sorted[*i])->longy)) {
00172                         UNPACK_PART(p->index, *id, *brand);
00173                         return 1;
00174                 }
00175         return 0;
00176 }
00177 
00178 int find_matching_short_part(char *wc, int *ind, int *id, int *brand)
00179 {
00180         PN *p;
00181         char *tmpc1, *tmpc2;
00182         char tmpbuf[MBUF_SIZE];
00183         int *i;
00184 
00185         if(*ind >= 0)
00186                 return 0;
00187         for(tmpc1 = wc, tmpc2 = tmpbuf; *tmpc1; tmpc1++, tmpc2++) {
00188                 *tmpc2 = ToLower(*tmpc1);
00189         }
00190         *tmpc2 = 0;
00191         if((i = hashfind(tmpbuf, &short_hash))) {
00192                 if((p = short_sorted[((int) i) - 1])) {
00193                         *ind = ((int) i);
00194                         UNPACK_PART(p->index, *id, *brand);
00195                         return 1;
00196                 }
00197         }
00198         return 0;
00199 }
00200 
00201 void ListForms(dbref player, void *data, char *buffer)
00202 {
00203         int i;
00204 
00205         notify(player, "Listing of forms:");
00206         for(i = 0; i < object_count; i++)
00207                 notify_printf(player, "%3d %-20s %-25s %s", i,
00208                                           short_sorted[i]->shorty, short_sorted[i]->longy,
00209                                           short_sorted[i]->vlongy);
00210 
00211 }
00212 
00213 void fun_btpartmatch(char *buff, char **bufc, dbref player, dbref cause,
00214                                          char *fargs[], int nfargs, char *cargs[], int ncargs)
00215 {
00216         /* fargs[0] = name to match on
00217          */
00218 
00219         /* Added check to see if anything was found, if not
00220          * send error message
00221          * Dany - 06/2005
00222          */
00223 
00224         int partindex = 0, id = 0, brand = 0;
00225         int part_count = 0;
00226 
00227         FUNCHECK(!WizR(player), "#-1 PERMISSION DENIED");
00228         FUNCHECK(strlen(fargs[0]) >= MBUF_SIZE, "#-1 PARTNAME TOO LONG");
00229         FUNCHECK(!fargs[0], "#-1 NEED PARTNAME");
00230 
00231         partindex = -1;
00232         while (find_matching_short_part(fargs[0], &partindex, &id, &brand)) {
00233                 safe_tprintf_str(buff, bufc, "%d ", PACKED_PART(id, brand));
00234                 part_count++;
00235         }
00236 
00237         partindex = 0;
00238         while (find_matching_long_part(fargs[0], &partindex, &id, &brand)) {
00239                 safe_tprintf_str(buff, bufc, "%d ", PACKED_PART(id, brand));
00240                 part_count++;
00241         }
00242 
00243         partindex = -1;
00244         while (find_matching_vlong_part(fargs[0], &partindex, &id, &brand)) {
00245                 safe_tprintf_str(buff, bufc, "%d ", PACKED_PART(id, brand));
00246                 part_count++;
00247         }
00248 
00249         if(part_count == 0)
00250                 safe_tprintf_str(buff, bufc, "#-1 INVALID PARTNAME");
00251 }
00252 
00253 void fun_btpartname(char *buff, char **bufc, dbref player, dbref cause,
00254                                         char *fargs[], int nfargs, char *cargs[], int ncargs)
00255 {
00256         /* fargs[0] = partnumer to find name for
00257          * fargs[1] = 'short', 'long' or 'vlong'
00258          */
00259 
00260         int index;
00261         char *cptr;
00262         char *infostr;
00263 
00264         FUNCHECK(!WizR(player), "#-1 PERMISSION DENIED");
00265         FUNCHECK(!fargs[0], "#-1 NEED PARTNAME");
00266         index = strtol(fargs[0], &cptr, 10);
00267         FUNCHECK(cptr == fargs[0], "#-1 INVALID PART NUMBER");
00268 
00269         infostr = partname_func(index, fargs[1][0]);
00270         safe_tprintf_str(buff, bufc, "%s", infostr);
00271 }
00272 
00273 char *partname_func(int index, int size)
00274 {
00275 
00276         static char buffer[MBUF_SIZE];
00277         int id, brand;
00278         PN *p;
00279 
00280         UNPACK_PART(index, id, brand);
00281         if(brand < 0 || brand > BRANDCOUNT || id < 0) {
00282                 snprintf(buffer, MBUF_SIZE, "%s", "#-1 INVALID PART NUMBER");
00283                 return buffer;
00284         }
00285 
00286         p = index_sorted[brand][id];
00287         if(!p) {
00288                 snprintf(buffer, MBUF_SIZE, "%s", "#-1 INVALID PART NUMBER");
00289                 return buffer;
00290         }
00291 
00292         switch (size) {
00293         case 's':
00294         case 'S':
00295                 snprintf(buffer, MBUF_SIZE, "%s", p->shorty);
00296                 break;
00297         case 'l':
00298         case 'L':
00299                 snprintf(buffer, MBUF_SIZE, "%s", p->longy);
00300                 break;
00301         case 'v':
00302         case 'V':
00303                 snprintf(buffer, MBUF_SIZE, "%s", p->vlongy);
00304                 break;
00305         default:
00306                 snprintf(buffer, MBUF_SIZE, "%s", "#-1 INVALID NAME TYPE");
00307                 break;
00308         }
00309 
00310         return buffer;
00311 }

Generated on Mon May 28 04:25:22 2007 for BattletechMUX by  doxygen 1.4.7