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
  
#define BEGIN 32 
 
/* 
 * Implode an array of strings to an english 'list' 
 * ie. ({"foo","bar","gazonk"}) beomces "foo, bar and gazonk" 
 */ 
string implode_nicely(string *foo, string|void and) 
{ 
  if(!and) and="and"; 
  switch(sizeof(foo)) 
  { 
  case 0: return ""; 
  case 1: return foo[0]; 
  default: return foo[0..sizeof(foo)-2]*", "+" "+and+" "+foo[-1]; 
  } 
} 
 
string capitalize(string s) 
{ 
  return upper_case(s[0..0])+s[1..sizeof(s)]; 
} 
 
string strmult(string str, int num) 
{ 
#if 1 
  num*=strlen(str); 
  while(strlen(str) < num) str+=str; 
  return str[0..num-1]; 
#endif 
#if 0 
  return sprintf("%~n",str,strlen(str)*num); 
#endif 
} 
 
class String_buffer { 
  string *buffer=allocate(BEGIN); 
  int ptr=0; 
   
  static void fix() 
    { 
      string tmp=buffer*""; 
      buffer=allocate(strlen(tmp)/128+BEGIN); 
      buffer[0]=tmp; 
      ptr=1; 
    } 
   
  string get_buffer() 
    { 
      if(ptr != 1) fix(); 
      return buffer[0]; 
    } 
   
  void append(string s) 
    { 
      if(ptr==sizeof(buffer)) fix(); 
      buffer[ptr++]=s; 
    } 
   
  mixed cast(string to) 
    { 
      if(to=="string") return get_buffer(); 
      return 0; 
    } 
   
  void flush() 
    { 
      buffer=allocate(BEGIN); 
      ptr=0; 
    } 
}; 
 
 
// Do a fuzzy matching between two different strings and return a 
// "similarity index". The higher, the closer the strings match. 
 
static int low_fuzzymatch(string str1, string str2) 
{ 
  string tmp1, tmp2; 
  int offset, length; 
  int fuzz; 
  fuzz = 0; 
  while(strlen(str1) && strlen(str2)) 
  { 
    /* Now we will look for the first character of tmp1 in tmp2 */ 
    if((offset = search(str2, str1[0..0])) != -1) 
    { 
      tmp2 = str2[offset..]; 
      /* Ok, so we have found one character, let's check how many more */ 
      tmp1 = str1; 
      length = 1; 
      while(1) 
      { 
        //*(++tmp1)==*(++tmp2) && *tmp1 
        if(length < strlen(tmp1) && length < strlen(tmp2) && 
           tmp1[length] == tmp2[length]) 
          length++; 
        else 
          break; 
      } 
      if(length >= offset) 
      { 
        fuzz += length; 
        str1 = str1[length..]; 
        str2 = str2[length + offset..]; 
        continue; 
      } 
    } 
    if(strlen(str1)) 
      str1 = str1[1..]; 
  } 
  return fuzz; 
} 
 
int fuzzymatch(string a, string b) 
{ 
  int fuzz; 
 
  if(a == b) 
  { 
    fuzz = 100; 
  } else { 
    fuzz = low_fuzzymatch(a, b); 
    fuzz += low_fuzzymatch(b, a); 
    fuzz = fuzz*100/(strlen(a)+strlen(b)); 
  } 
 
  return fuzz; 
}