File: utils.h

package info (click to toggle)
xevil 2.02r2-11
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,888 kB
  • sloc: cpp: 47,789; makefile: 189; csh: 4
file content (508 lines) | stat: -rw-r--r-- 14,151 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
/* 
 * XEvil(TM) Copyright (C) 1994,2000 Steve Hardt and Michael Judge
 * http://www.xevil.com
 * satan@xevil.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program, the file "gpl.txt"; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA, or visit http://www.gnu.org.
 */

// "utils.h" Misc. utilities. to be included by ALL files.


#ifndef UTILS_H
#define UTILS_H

#if X11
	#ifndef NO_PRAGMAS
	#pragma interface
	#endif
#endif


#if WIN32
#define Boolean BOOL
#define False FALSE
#define True TRUE

// Uncomment this to enable modeless dialogs for XEvil.
//#define MODELESS_DIALOGS
#endif



// math.h
#ifdef MATH_CLASS_HACK 
// Lame-ass AIX math.h has a function called class()
#define class fakeclass
#endif 
#if X11
#ifndef MATH_H_IS_CC
extern "C" {
#endif
#include <math.h>
#ifndef MATH_H_IS_CC
}
#endif
#endif 
#ifdef MATH_CLASS_HACK
#undef class
#endif 
#if WIN32
	#include <math.h>
#endif


// For some odd-ball linux machines, needed before <stdio.h>
#ifdef IO_COOKIE_HACK  
#define _IO_cookie_io_functions_t int
#endif

extern "C" {
#include <stdio.h>
#include <stdlib.h> // For exit().
#include <time.h> // For seed to srandom and clock().

#if X11
#include <sys/time.h> // for clock_t and gettimeofday().
#include <X11/X.h>
#include <X11/Xlib.h>
#endif

#if WIN32
#include <sys/utime.h>
#endif
}
#include <assert.h>

#include <sys/types.h>  // for u_char, u_int, etc.
#include <string.h>
#include <limits.h>



// Defines
#ifndef MSEC_PER_CLOCK
#define MSEC_PER_CLOCK (1.0e3 / CLOCKS_PER_SEC) 
#endif

#ifndef MAX
#define MAX(a,b)               (a<b ? b : a)
#endif
#ifndef MIN
#define MIN(a,b)               (a>b ? b : a)
#endif

#if X11
typedef char Boolean;
#endif

typedef int ColorNum;

#if X11
typedef struct timeval CMN_TIME;
#endif
#if WIN32
// milliseconds
typedef int CMN_TIME;
#endif 


// So we can do "new charP[n]".
typedef char *charP;
typedef const char* constCharP;


// Network stuff.
#if X11
#define CMN_SOCKET int
#define CMN_PORT u_short
#endif
#if WIN32
#define CMN_SOCKET SOCKET
#define CMN_PORT USHORT
#endif

#if X11
#include <netinet/in.h>
#endif
typedef struct sockaddr CMN_SOCKADDR;
typedef struct sockaddr_in CMN_SOCKADDR_IN;


#ifdef RANDOM_NEEDS_PROTOTYPES
extern "C" {
long random();
void srandom(int);
}
#endif 


class InStream;
typedef InStream *InStreamP;
class OutStream;
typedef OutStream *OutStreamP;



typedef int GameStyleType;
// Possible values of GameStyleType.
enum {SCENARIOS,LEVELS_ONLY,KILL,DUEL,EXTENDED,TRAINING,LEVELS,NUM_GAME_STYLES};



// Data Structures
class Timer {
 public:
  Timer() {remaining = maxx = 0;}
  // Starts out ready.
  Timer(int t) {assert (t >= 0); maxx = t; remaining = 0;} 
  Boolean ready() {return remaining == 0;}
  int get_remaining() {return remaining;}
  void set() {remaining = maxx;}
  void set(int time) {remaining = time;}
  void set_max(int m) {maxx = m; remaining = 0;}
  void reset() {remaining = 0;}
  void clock() {if (remaining) remaining--;}

 private:
  int remaining;
  int maxx;
};



class Utils {
 public:
  static void seed_random();
  /* REQUIRES: Must be called at startup. */
  /* EFFECTS: Seed the random number generator based on the current time. */

  static Boolean coin_flip();
  /* EFFECTS: Randomly returns True or False; */

  static int choose(int x);
  /* EFFECTS: Randomly return a number from 0 to x-1. */
  
  static int weighted_choose(int n,int* weights);
  /* REQUIRES: weights is an array of length n.  Each weight is >= 0. */
  /* EFFECTS: Randomly choose a number from 0 to n-1.  Probabitly of returning
     m is weights[m]/sum(weights). */

  static void insertion_sort(int arry[],int numElements);

  static void random_list(int arry[],int numElements);
  /* EFFECTS: Fills arry the first numElements of arry with the numbers in 
     {0..(numElements-1)} in a random order. */

  static int minimum(int v1,int v2) {return v1 <= v2 ? v1 : v2;}

  static int maximum(int v1,int v2) {return v1 >= v2 ? v1 : v2;}

  static int minimum(int arry[],int size);
  /* EFFECTS: Return the minimum value in the array arry of size size. */

  static int minimum(int arry[],Boolean oks[],int size);
  /* EFFECTS: Return the minimum value in arry which is ok or -1 if none. */

  static Boolean inList(int key,const int list[],int size);
  /* EFFECTS: Returns whether key is in list list of size size. */

  static void freeif(char *&str);
  /* MODIFIES: str */
  /* EFFECTS: Free memory of str if non-NULL.  Set str to NULL. */

  static char *strdup(const char *str);
  /* EFFECTS: Copy str, allocating new memory.  If str is NULL, return 
     NULL. */

  static int strlen(const char* cs)
    {assert(cs); return ::strlen(cs);}
  /* REQUIRES: cs is non-NULL */
  
  static int strcmp(const char* str1,const char* str2)
    {return ::strcmp(str1,str2);}
  /* EFFECTS: Wrapper for C library strcmp().  Return 0 if strings are the
     same. */

  static const char* strchr(const char* cs,int c)
    {return ::strchr(cs,c);}

  static const char* strrchr(const char* cs,int c)
    {return ::strrchr(cs,c);}

  static const char* strstr(const char* cs,const char* ct)
    {return ::strstr(cs,ct);}

  static void strcpy(char* s,const char* ct)
    {::strcpy(s,ct);}

  static void strncpy(char* s,const char* ct,int n)
    {::strncpy(s,ct,(size_t)n);}

  static void strcat(char* s,const char* ct)
    {::strcat(s,ct);}

  static int atoi(const char*);

  static const char* getenv(const char*);

  static int mod(int n,int m) 
    {return (n >= 0) ? (n % m) : (-(-n % m) + m) % m;} 
  /* EFFECTS: Return (n % m), allowing n to be negative. */

  static int div(int n,int m) {if (n >= 0)
                                 return (n / m);
                               else if (-n % m == 0) 
                                 return (n / m);
                               else 
                                 return (n / m) - 1;}
  /* EFFECTS: Return (n / m), adjust for negative n. */

  static int ceil_div(int n,int m);
  /* EFFECTS: Integer division, rounding up. */

  static Boolean string_equals_ignore_case(char *str1,char *str2);
  /* EFFECTS: Does str1 equal str2 ignoring case. */

  static void string_read(InStreamP,char *buffer,int bufLen);
  /* EFFECTS: Read character string from InStream, put results in buffer.
     buffer will be null-terminated, even if the string read in is truncated.
     String will be completely read in from the InStream no matter what. */

  static char* string_read(InStreamP in);
  /* EFFECTS: Read char string from in, return newly allocated string with 
     entire message.  Use delete to free string when done.  Return 
     empty string if error, never returns NULL. */

  static int get_string_write_length(const char *msg);
  /* EFFECTS: The amount of bytes necessary to write msg to an output 
     stream. */

  static void string_write(OutStreamP,const char *msg);
  /* EFFECTS: Write msg to the output stream. */

  static const char* arg_value_check(int& n,int argc,char** argv,
                                     const char* name);
  /* MODIFIES: n */
  /* EFFECTS: Helper for parsing command line arguments that are of the 
     form "-name value".  Check element n of argv against the supplied 
     name.  If match found, return value, else NULL.  If a match is found, 
     n will be incremented to skip over the value in the command line 
     list. */

  static Boolean arg_name_check(int n,int argc,char** argv,
                                const char* name);
  /* EFFECTS: Helper for parsing Boolean command line switches, of the
     form "-name".  Check element n of argv against the supplied name. */

// Make X11 versions of these when we need them.
#if WIN32
  static Boolean is_dir(const char* fName);
  /* EFFECTS: Return True if fName exists on the filesystem and is a 
     directory.  Will work whether fName ends in '\' or not. */

  static Boolean mkdir(const char* fName);
  /* EFFECTS: Create a new directory.  Return whether successful.  Will only 
     create the last component of fName as a new directory. */
  /* NOTE: We could make a version that will make all the new directories 
     necessary for fName. */
#endif

  static const char* game_style_to_string(GameStyleType);
  /* EFFECTS: Convert GameStyleType to string, return "Unknown" if unknown
     or invalid GameStyleType. */
  /* NOTE: Is here because the GameStyleType enumeration is here. */

  static char* get_OS_info();
  /* EFFECTS: Return a platform-dependent string describing the current 
     operating system.  Caller must free returned value with delete. */


private:
  static void string_read_body(InStreamP,u_short len,char *buffer,int bufLen);
};



/* A generic untyped growable list. */
typedef void *voidP;
class PtrList {
public:
  PtrList();
  /* EFFECTS: Create PtrList of zero initial allocation. */
  /* NOTE: Guaranteed not to allocate/free any memory if 
     no elements are ever added. */

  PtrList(int);
  /* EFFECTS: Create PtrList of given initial allocation. */
  /* NOTE: Guaranteed not to allocate/free any memory if this constructor
     is called with zero, and no elements are ever added. */

  PtrList(void *);
  PtrList(void *,void *);
  PtrList(void *,void *,void *);
  PtrList(void *,void *,void *,void *);
  PtrList(void *,void *,void *,void *,void *);
  /* EFFECTS: Create a PtrList with length and allocation equal to the number of 
     arguments.  Initialize with the given elements. */
  
  ~PtrList();
  /* NOTE: Does not delete the elements pointed to by the list. */

  PtrList(const PtrList &) {assert(0);}  
  void operator = (const PtrList &) {assert(0);}

  
  //////// PTRLIST IO NOT TESTED /////////
  PtrList(InStreamP);
  /* EFFECTS: Create a list from a stream. */
  
  static int get_write_length(int len);
  /* EFFECTS: write_length of any list of the given length. */

  int get_write_length() const {return get_write_length(len);}
  /* EFFECTS: write_length of this list */

  void write(OutStreamP) const;
  /* EFFECTS: Write to stream. */  
  

  void add(void *);
  /* EFFECTS: Append new value to the end of list. */

  void *get(int) const;
  /* EFFECTS: I'll give you one guess. */

  Boolean contains(void *el) const;
  /* EFFECTS: Is el in the list, using == for comparison. */

  int index(void *el) const;
  /* EFFECTS: Return the index of the first occurance of el in the list or 
     -1 if not found.  Use == for comparison. */
  /* NOTE: Simple linear search. */
  
  void add_unique(void *el) {if (!contains(el)) add(el);}
  /* EFFECTS: Add el to the list if it is not there already.  
     Use == for comparison. */

  void set(int i,void *val);
  /* EFFECTS: Set indexed element to new value. */
  /* REQUIRES: i < length() */ 

  int length() const {return len;}
  /* EFFECTS: Number of elements added to list. */

  void del(int i);
  /* EFFECTS: Delete element i, copy the last element of the list to 
     element i. */
  /* NOTE: Be careful when iterating and deleting elements as del() moves 
     elements around. */

  void clear() {len = 0;}
  /* EFFECTS: Empty the list. */

  void append(const PtrList &other);
  /* EFFECTS: Add all elements of other to the list.  Does not check for
     duplicates. */

  void fill(int n,void *val = NULL);
  /* EFFECTS: Append val to the list n times.  Useful for initializing a List. */

  void set_and_fill(int i,void *val,void *fill = NULL);
  /* EFFECTS: Set element i to val.  Grow the list as necessary, filling in the 
     newly created empty element with "fill". */


private:
  void commonConstructor(int);
  void increaseSize();

  int len;
  int allc;
  void **data;
};



// Iterator over an IDictionary.
class IDictIterator {
public:
  virtual ~IDictIterator();

  virtual void* next(void*& key) = 0;
  /* MODIFIES: key */
  /* EFFECTS: Return the next value in the iteration or NULL if done.  
     Sets key to be the key corresponding to value. */
};



// A key-value lookup system.
class IDictionary {
public:
  virtual ~IDictionary();
  
  virtual void* get(void* key) = 0;
  /* EFFECTS: Return the value assoicated with key, or NULL if none. */

  virtual void *getAtIndex(int index) = 0;
  /* REQUIRES: 0 <= index < size() */
  /* EFFECTS: Return the value stored at the given index. */

  virtual int length() = 0;
  /* EFFECTS: Return the number of associations in the dictionary. */

  virtual IDictIterator* iterate() = 0;
  /* REQUIRES: Don't add new assocations or delete the IDictionary before you
     are done with the IDictIterator.  You may change the value of an existing 
     <key,value> association, however. */
  /* EFFECTS: Return an iterator for the values of the Dictionary. */

  virtual void* put(void* key,void* value) = 0;
  /* REQUIRES: Neither key nor value are NULL */
  /* EFFECTS: Put (key,value) association into the dictionary.  Return the previous
     value stored at key if any, else return NULL. */
};



IDictionary* HashTable_factory(int startAlloc = -1,
                               int (*hashFntn)(void *key,int length) = 0);
/* EFFECTS: Create a HashTable implementation of IDictionary. */



// Print out debug info.
class DebugInfo {
public:
  static void initialize();
  /* EFFECTS: Call once at startup. */

  static Boolean on() {return _on;}  
  /* EFFECTS: Is printing debug info turned on. */

  static void turn_on() {_on = True;}
  /* EFFECTS: Enable printing out debug info. */

  static void print(const char *);
  /* EFFECTS: Print the debug message to the appropriate place if debugging is on. */


private:
  static Boolean _on;  
};

#endif  //UTILS_H