Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
misc.h
Go to the documentation of this file.
1 
2 //////////////////////////////////////////////////////////////////////
3 //
4 // FILE: misc.h
5 // Miscellaneous routines (File I/O, etc)
6 //
7 // Part of: Scid (Shane's Chess Information Database)
8 // Version: 3.5
9 //
10 // Notice: Copyright (c) 2001-2003 Shane Hudson. All rights reserved.
11 // Copyright (C) 2015 Fulvio Benini
12 //
13 // Author: Shane Hudson (sgh@users.sourceforge.net)
14 //
15 //////////////////////////////////////////////////////////////////////
16 
17 
18 #ifndef SCID_MISC_H
19 #define SCID_MISC_H
20 
21 #include "common.h"
22 #include <algorithm>
23 #include <string>
24 #include <cstring>
25 #include <stdio.h>
26 #include <ctype.h> // For isspace(), etc
27 #include <cstdlib>
28 #include <vector>
29 
30 /**
31  * class StrRange - parse a string interpreting its content as 1 or 2 integers
32  * separated by whitespace.
33  * The integers represent the min and max value of a range.
34  * If only one integer is provided it will represent both the min and max value.
35  */
36 class StrRange {
37 protected:
38  long min_;
39  long max_;
40 
41 protected:
43  : min_(0), max_(0) {}
44 
45 public:
46  explicit StrRange(const char* range) {
47  char* next;
48  min_ = std::strtol(range, &next, 10);
49  char* end;
50  max_ = std::strtol(next, &end, 10);
51  if (next == end) max_ = min_;
52  if (min_ > max_) std::swap(min_, max_);
53  }
54 
55  /// @returns true if @e val is >= min_ and <= max_
56  bool inRange(long val) const {
57  if (val < min_ || val > max_) return false;
58  return true;
59  }
60 };
61 
62 
63 class Progress {
64 public:
65  struct Impl {
66  virtual ~Impl() {}
67  virtual bool report(size_t done, size_t total, const char* msg) = 0;
68  };
69 
70  Progress(Impl* f = NULL) : f_(f) {}
71  Progress(const Progress&);
72  Progress& operator=(const Progress&);
73  ~Progress() { delete f_; }
74 
75  bool report(size_t done, size_t total) const {
76  return operator()(done, total);
77  }
78  bool operator()(size_t done, size_t total, const char* msg = NULL) const {
79  if (f_) return f_->report(done, total, msg);
80  return true;
81  }
82 
83 private:
84  Impl* f_;
85 };
86 
87 
88 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~
89 // strGetFilterOp:
90 // Converts a string value to a filter operation value.
92 
93 inline filterOpT strGetFilterOp (const char * str)
94 {
95  switch (*str) {
96  // AND:
97  case 'A': case 'a': case '0': return FILTEROP_AND;
98  // OR:
99  case 'O': case 'o': case '1': return FILTEROP_OR;
100  // RESET:
101  case 'R': case 'r': case '2': return FILTEROP_RESET;
102  }
103  // Default is RESET.
104  return FILTEROP_RESET;
105 }
106 
107 // ECO string routines
108 //
109 void eco_ToString (ecoT ecoCode, char * ecoStr, bool extensions = true);
110 inline void eco_ToBasicString (ecoT ecoCode, char * ecoStr) {
111  eco_ToString (ecoCode, ecoStr, false);
112 }
113 inline void eco_ToExtendedString (ecoT ecoCode, char * ecoStr) {
114  eco_ToString (ecoCode, ecoStr, true);
115 }
116 ecoT eco_FromString (const char * ecoStr);
117 ecoT eco_LastSubCode (ecoT ecoCode);
118 ecoT eco_BasicCode (ecoT ecoCode);
119 ecoT eco_Reduce(ecoT eco);
120 
121 // String routines. Some are identical to ANSI standard functions, but
122 // I have included them:
123 // (a) to keep nice consistent naming conventions, e.g. strCopy.
124 // (b) so stats can easily be kept by modifying the functions.
125 // (c) so some can be made inline for speed if necessary.
126 
127 inline uint32_t strStartHash(const char* str) {
128  ASSERT(str != 0);
129  const unsigned char* s = reinterpret_cast<const unsigned char*>(str);
130 
131  uint32_t tmp = static_cast<unsigned char>(tolower(*s));
132  uint32_t result = tmp << 24;
133  if (*s == '\0') return result;
134  tmp = static_cast<unsigned char>(tolower(*++s));
135  result += tmp << 16;
136  if (*s == '\0') return result;
137  tmp = static_cast<unsigned char>(tolower(*++s));
138  result += tmp << 8;
139  if (*s == '\0') return result;
140  result += static_cast<unsigned char>(tolower(*++s));
141  return result;
142 }
143 
144 char * strDuplicate (const char * str);
145 
146 void strCopyExclude (char * target, const char * original,
147  const char * excludeChars);
148 char * strAppend (char * target, const char * extra);
149 uint strPad (char * target, const char * orig, int length, char pad);
150 const char * strFirstChar (const char * target, char matchChar);
151 const char * strLastChar (const char * target, char matchChar);
152 void strStrip (char * str, char ch);
153 
154 const char * strTrimLeft (const char * target, const char * trimChars);
155 inline const char * strTrimLeft (const char * target) {
156  return strTrimLeft (target, " \t\r\n");
157 }
158 uint strTrimSuffix (char * target, char suffixChar);
159 void strTrimDate (char * str);
160 void strTrimMarkCodes (char * str);
161 void strTrimMarkup (char * str);
162 const char * strFirstWord (const char * str);
163 const char * strNextWord (const char * str);
164 
165 // strPlural:
166 // Returns the empty string if its parameter is 1, or "s" otherwise.
167 inline const char *
169  return (x == 1 ? "" : "s");
170 }
171 
172 bool strIsUnknownName (const char * str);
173 
174 // strIsSurnameOnly: returns true if a string appears to only
175 // contain a surname.
176 bool strIsSurnameOnly (const char * name);
177 
178 bool strGetBoolean (const char * str);
179 
180 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
181 // strGetInteger():
182 // Extracts a signed base-10 value from a string.
183 // Defaults to zero (as strtol does) for non-numeric strings.
184 inline int
185 strGetInteger(const char * str)
186 {
187  return std::strtol(str, NULL, 10);
188 }
189 
190 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191 // strGetUnsigned():
192 // Extracts an unsigned base-10 value from a string.
193 // Defaults to zero (as strtoul does) for non-numeric strings.
194 //
195 inline uint32_t strGetUnsigned(const char* str) {
196  ASSERT(str != NULL);
197  return static_cast<uint32_t>(std::strtoul(str, NULL, 10));
198 }
199 
200 inline int strCaseCompare(const char* str1, const char* str2) {
201  ASSERT(str1 != NULL && str2 != NULL);
202  const unsigned char* s1 = reinterpret_cast<const unsigned char*>(str1);
203  const unsigned char* s2 = reinterpret_cast<const unsigned char*>(str2);
204  int c1, c2;
205  do {
206  c1 = tolower(*s1++);
207  c2 = tolower(*s2++);
208  if (c1 == '\0')
209  break;
210  } while (c1 == c2);
211 
212  return c1 - c2;
213 }
214 
215 inline int strCompareRound(const char* str1, const char* str2) {
216  ASSERT(str1 != NULL && str2 != NULL);
217  uint32_t a = strGetUnsigned(str1);
218  uint32_t b = strGetUnsigned(str2);
219  if (a == b)
220  return strCaseCompare(str1, str2);
221  return (a < b) ? -1 : 1;
222 }
223 
224 inline bool strEqual(const char* str1, const char* str2) {
225  ASSERT(str1 != NULL && str2 != NULL);
226  return (std::strcmp(str1, str2) == 0);
227 }
228 
229 void strGetIntegers (const char * str, int * results, uint nResults);
230 void strGetUnsigneds (const char * str, uint * results, uint nResults);
231 resultT strGetResult (const char * str);
232 
233 typedef uint flagT;
234 const flagT FLAG_EMPTY = 0;
235 const flagT FLAG_YES = 1;
236 const flagT FLAG_NO = 2;
237 const flagT FLAG_BOTH = 3;
238 inline bool flag_Yes (flagT t) { return (t & FLAG_YES); }
239 inline bool flag_No (flagT t) { return (t & FLAG_NO); }
240 flagT strGetFlag (const char * str);
241 
242 squareT strGetSquare (const char * str);
243 
244 inline uint
245 strTrimFileSuffix (char * target) { return strTrimSuffix (target, '.'); }
246 
247 inline const char *
248 strFileSuffix (const char * target) { return strLastChar (target, '.'); }
249 
250 
251 
252 int strUniqueExactMatch (const char * keyStr, const char ** strTable,
253  bool exact);
254 
255 inline int strUniqueMatch (const char * keyStr, const char ** strTable) {
256  return strUniqueExactMatch (keyStr, strTable, false);
257 }
258 inline int strExactMatch (const char * keyStr, const char ** strTable) {
259  return strUniqueExactMatch (keyStr, strTable, true);
260 }
261 
262 inline bool
263 strContainsChar (const char * str, char ch)
264 {
265  while (*str) {
266  if (*str == ch) { return true; }
267  str++;
268  }
269  return false;
270 }
271 
272 // WARNING: Avoid this function!
273 // Considering that the sign of a char is implementation-defined [3.9.1], the
274 // int conversion ("[4.7.3] If the destination type is signed, the value is
275 // unchanged if it can be represented in the destination type") can yield
276 // different results on different architectures or compilers.
277 // A better alternative is the standard function strcmp() that returns the
278 // difference between the values of the first pair of characters (both
279 // interpreted as unsigned char) that differ in the strings being compared.
280 inline int strCompare(const char* s1, const char* s2)
281 {
282  ASSERT (s1 != NULL && s2 != NULL);
283  while (1) {
284  if (*s1 != *s2) {
285  return ((int) *s1) - ((int) *s2);
286  }
287  if (*s1 == 0)
288  break;
289  s1++; s2++;
290  }
291  return 0;
292 }
293 
294 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295 // strCopy(): same as strcpy().
296 //
297 inline void
298 strCopy (char * target, const char * original)
299 {
300  ASSERT (target != NULL && original != NULL);
301  while (*original != 0) {
302  *target = *original;
303  target++;
304  original++;
305  }
306  *target = 0;
307 }
308 
309 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310 // strPrefix():
311 // Returns the length of the common prefix of two strings.
312 //
313 inline uint
314 strPrefix (const char * s1, const char * s2)
315 {
316  ASSERT (s1 != NULL && s2 != NULL);
317  uint count = 0;
318  while (*s1 == *s2) {
319  if (*s1 == 0) { // seen end of string, strings are identical
320  return count;
321  }
322  count++; s1++; s2++;
323  }
324  return count;
325 }
326 
327 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
328 // strIsPrefix():
329 // Returns true if the prefix string is a prefix of longStr.
330 inline bool
331 strIsPrefix (const char * prefix, const char * longStr)
332 {
333  while (*prefix) {
334  if (*longStr == 0) { return false; }
335  if (*prefix != *longStr) { return false; }
336  prefix++;
337  longStr++;
338  }
339  return true;
340 }
341 
342 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
343 // strIsCasePrefix():
344 // Returns true if the prefix string is a case-insensitive
345 // prefix of longStr.
346 inline bool
347 strIsCasePrefix (const char * prefix, const char * longStr)
348 {
349  typedef unsigned char U;
350  while (*prefix) {
351  if (*longStr == 0) { return false; }
352  if (tolower(U(*prefix)) != tolower(U(*longStr))) { return false; }
353  prefix++;
354  longStr++;
355  }
356  return true;
357 }
358 
359 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
360 // strIsAlphaPrefix():
361 // Returns true if the prefix string is a prefix of longStr.
362 // Unlike strIsPrexix(), this version is case-insensitive and
363 // spaces are ignored.
364 // Example: strIsAlphaPrefix ("smith,j", "Smith, John") == true.
365 inline bool
366 strIsAlphaPrefix (const char * prefix, const char * longStr)
367 {
368  typedef unsigned char U;
369  while (*prefix) {
370  while (*prefix == ' ') { prefix++; }
371  while (*longStr == ' ') { longStr++; }
372  if (*longStr == 0) { return false; }
373  if (tolower(U(*prefix)) != tolower(U(*longStr))) { return false; }
374  prefix++;
375  longStr++;
376  }
377  return true;
378 }
379 
380 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
381 // strContains():
382 // Returns true if longStr contains an occurrence of keyStr,
383 // case-sensitive and NOT ignoring any characters such as spaces.
384 inline bool
385 strContains (const char * longStr, const char * keyStr)
386 {
387  while (*longStr) {
388  if (strIsPrefix (keyStr, longStr)) { return true; }
389  longStr++;
390  }
391  return false;
392 }
393 
394 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
395 // strAlphaContains():
396 // Returns true if longStr contains an occurrence of keyStr,
397 // case-insensitive and ignoring spaces.
398 // Example: strAlphaContains ("Smith, John", "th,j") == true.
399 //
400 inline bool
401 strAlphaContains (const char * longStr, const char * keyStr)
402 {
403  while (*longStr) {
404  if (strIsAlphaPrefix (keyStr, longStr)) { return true; }
405  longStr++;
406  }
407  return false;
408 }
409 
410 inline uint
411 strLength (const char * str)
412 {
413  ASSERT(str != NULL);
414  uint len = 0;
415  while (*str != 0) { len++; str++; }
416  return len;
417 }
418 
419 
420 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
421 // strTrimRight():
422 // Trims the provided string in-place, removing the
423 // end characters that match the trimChars.
424 // Returns the number of characters trimmed.
425 // E.g., strTrimRight("abcyzyz", "yz") would leave the string
426 // as "abc".
427 inline void strTrimRight(char* target, const char* trimChars, size_t nTrimCh) {
428  const char* endTrim = trimChars + nTrimCh;
429  size_t iCh = strlen(target);
430  for (; iCh > 0; --iCh) {
431  if (std::find(trimChars, endTrim, target[iCh - 1]) == endTrim)
432  break;
433  }
434  target[iCh] = '\0';
435 }
436 inline void strTrimRight(char* target) {
437  return strTrimRight(target, " \t\r\n", 4);
438 }
439 
440 #endif // #ifdef SCID_MISC_H
441 
442 //////////////////////////////////////////////////////////////////////
443 // EOF: misc.h
444 //////////////////////////////////////////////////////////////////////
445 
bool operator()(size_t done, size_t total, const char *msg=NULL) const
Definition: misc.h:78
byte resultT
Definition: common.h:187
uint strLength(const char *str)
Definition: misc.h:411
int strExactMatch(const char *keyStr, const char **strTable)
Definition: misc.h:258
Progress(Impl *f=NULL)
Definition: misc.h:70
uint32_t strStartHash(const char *str)
Definition: misc.h:127
bool strEqual(const char *str1, const char *str2)
Definition: misc.h:224
bool strIsPrefix(const char *prefix, const char *longStr)
Definition: misc.h:331
flagT strGetFlag(const char *str)
Definition: misc.cpp:587
uint strPad(char *target, const char *orig, int length, char pad)
Definition: misc.cpp:235
long min_
Definition: misc.h:38
int strUniqueExactMatch(const char *keyStr, const char **strTable, bool exact)
Definition: misc.cpp:639
#define ASSERT(f)
Definition: common.h:59
Definition: misc.h:63
names
Definition: tablebase.tcl:257
int strUniqueMatch(const char *keyStr, const char **strTable)
Definition: misc.h:255
class StrRange - parse a string interpreting its content as 1 or 2 integers separated by whitespace...
Definition: misc.h:36
char * strAppend(char *target, const char *extra)
Definition: misc.cpp:189
ecoT eco_FromString(const char *ecoStr)
Definition: misc.cpp:36
StrRange(const char *range)
Definition: misc.h:46
uint strPrefix(const char *s1, const char *s2)
Definition: misc.h:314
int strCompareRound(const char *str1, const char *str2)
Definition: misc.h:215
const char * strFileSuffix(const char *target)
Definition: misc.h:248
const flagT FLAG_BOTH
Definition: misc.h:237
const char * strFirstChar(const char *target, char matchChar)
Definition: misc.cpp:264
void strGetIntegers(const char *str, int *results, uint nResults)
Definition: misc.cpp:539
const char * strNextWord(const char *str)
Definition: misc.cpp:451
uint flagT
Definition: misc.h:233
bool flag_Yes(flagT t)
Definition: misc.h:238
int find(const char *filename)
find() - search for a database.
Definition: dbasepool.cpp:51
void strGetUnsigneds(const char *str, uint *results, uint nResults)
Definition: misc.cpp:553
const flagT FLAG_NO
Definition: misc.h:236
ecoT eco_Reduce(ecoT eco)
ecoReduce() - maps eco to a smaller set
Definition: misc.cpp:130
~Progress()
Definition: misc.h:73
const char * strLastChar(const char *target, char matchChar)
Definition: misc.cpp:281
filterOpT strGetFilterOp(const char *str)
Definition: misc.h:93
uint strTrimFileSuffix(char *target)
Definition: misc.h:245
void strTrimRight(char *target, const char *trimChars, size_t nTrimCh)
Definition: misc.h:427
bool strIsCasePrefix(const char *prefix, const char *longStr)
Definition: misc.h:347
uint32_t uint
Definition: common.h:91
const char * strFirstWord(const char *str)
Definition: misc.cpp:438
void strStrip(char *str, char ch)
Definition: misc.cpp:296
filterOpT
Definition: misc.h:91
bool strAlphaContains(const char *longStr, const char *keyStr)
Definition: misc.h:401
ecoT eco_LastSubCode(ecoT ecoCode)
Definition: misc.cpp:143
void strTrimMarkup(char *str)
Definition: misc.cpp:415
int strGetInteger(const char *str)
Definition: misc.h:185
bool strContainsChar(const char *str, char ch)
Definition: misc.h:263
bool strGetBoolean(const char *str)
Definition: misc.cpp:500
bool strIsUnknownName(const char *str)
Definition: misc.cpp:465
ushort ecoT
Definition: common.h:165
char * strDuplicate(const char *str)
Definition: misc.cpp:206
virtual ~Impl()
Definition: misc.h:66
int strCaseCompare(const char *str1, const char *str2)
Definition: misc.h:200
void strCopyExclude(char *target, const char *original, const char *excludeChars)
Definition: misc.cpp:163
void eco_ToExtendedString(ecoT ecoCode, char *ecoStr)
Definition: misc.h:113
uint32_t strGetUnsigned(const char *str)
Definition: misc.h:195
StrRange()
Definition: misc.h:42
bool report(size_t done, size_t total) const
Definition: misc.h:75
void strTrimDate(char *str)
Definition: misc.cpp:356
bool flag_No(flagT t)
Definition: misc.h:239
bool strContains(const char *longStr, const char *keyStr)
Definition: misc.h:385
void strCopy(char *target, const char *original)
Definition: misc.h:298
const flagT FLAG_EMPTY
Definition: misc.h:234
const flagT FLAG_YES
Definition: misc.h:235
resultsreportType fmt
Definition: optable.tcl:629
resultT strGetResult(const char *str)
Definition: misc.cpp:566
bool inRange(long val) const
Definition: misc.h:56
const char * strPlural(uint x)
Definition: misc.h:168
squareT strGetSquare(const char *str)
Definition: misc.cpp:614
void strTrimMarkCodes(char *str)
Definition: misc.cpp:371
uint strTrimSuffix(char *target, char suffixChar)
Definition: misc.cpp:332
long max_
Definition: misc.h:39
void eco_ToBasicString(ecoT ecoCode, char *ecoStr)
Definition: misc.h:110
int strCompare(const char *s1, const char *s2)
Definition: misc.h:280
ecoT eco_BasicCode(ecoT ecoCode)
Definition: misc.cpp:110
const char * strTrimLeft(const char *target, const char *trimChars)
Definition: misc.cpp:314
bool strIsAlphaPrefix(const char *prefix, const char *longStr)
Definition: misc.h:366
byte squareT
Definition: common.h:105
bool strIsSurnameOnly(const char *name)
Definition: misc.cpp:477
void eco_ToString(ecoT ecoCode, char *ecoStr, bool extensions=true)
Definition: misc.cpp:78