OSDN Git Service

[cmake] Prefer `string APPEND`
[timidity41/timidity41.git] / kbtim / kbstr.cpp
1 //#include "StdAfx.h"
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif /* HAVE_CONFIG_H */
5 #include <windows.h>
6 #pragma hdrstop
7
8 #include "kbstr.h"
9 /*
10     \95\8e\9a\97ñ\8aÖ\8cW
11 */
12 BYTE g_byLeadByteTable[256];
13 BYTE g_byToLowerTable[256];
14 BYTE g_byToUpperTable[256];
15
16 static const char gcszEmpty[] = "";//\8bó\95\8e\9a\97ñ
17 ///////////////////////////////////////////////////////////////////////////////
18 void __fastcall kbStr_Initialize(void)
19 {//\83e\81[\83u\83\8b\8f\89\8aú\89»
20  //\8eg\97p\91O\82É\82P\93x\82¾\82¯\8cÄ\82Î\82È\82¯\82ê\82Î\82È\82ç\82È\82¢
21     static LONG uInit = -1; //\8f\89\8aú\89»\8aJ\8en\8cã\82Í 0
22     if (InterlockedIncrement(&uInit) == 0) {
23         char szLowerUpper[4] = {0};
24         int i;
25         for (i = 0; i < 256; i++) {
26             g_byLeadByteTable[i] = (BYTE) IsDBCSLeadByte((BYTE) i);
27             szLowerUpper[0] = i;
28             CharLower(szLowerUpper);
29             g_byToLowerTable[i] = szLowerUpper[0];
30             CharUpper(szLowerUpper);
31             g_byToUpperTable[i] = szLowerUpper[0];
32         }
33     }
34     else {
35         InterlockedDecrement(&uInit);
36     }
37 }
38 ///////////////////////////////////////////////////////////////////////////////
39 int __fastcall kbStrLen(const char *cszString)
40 {//cszString \82Ì\92·\82³\82ð\95Ô\82·
41  //cszString \82Ì\8fI\92[\82ª\93r\92\86\82Å\93r\90Ø\82ê\82Ä\82¢\82é\8fê\8d\87\82Í\81A\97L\8cø\82È\95\94\95ª\82Ü\82Å\82Ì\92·\82³\82ð\95Ô\82·
42     const char *s = cszString;
43     while (*s) {
44         if (kbIsLeadByte(*s)) {
45             if (!*(s+1)) {
46                 break;
47             }
48             s += 2;
49         }
50         else {
51             s++;
52         }
53     }
54     return s - cszString;
55 }
56 ///////////////////////////////////////////////////////////////////////////////
57 int __fastcall kbStrLCpy(char *szDest, const char *cszSrc, int nBufSize)
58 {// cszSrc \82ð szDest \82É nBufSize \83o\83C\83g\95ª\83R\83s\81[
59  // \95\8e\9a\97ñ\82Ì\92·\82³\82ª\91«\82è\82È\82¢\8fê\8d\87\82Í nBufSize-1 \83o\83C\83g\83R\83s\81[\82µ\82Ä\8fI\92[\82É \0 \82ð\95t\89Á
60  // \8fI\92[\95\8e\9a\82ª\93r\90Ø\82ê\82Ä\82¢\82é\82æ\82¤\82È\8fê\8d\87\82É\82à\91Î\89\9e
61  // cszSrc \82Ì\97L\8cø\82È\92·\82³(kbStrLen(cszSrc))\82ð\95Ô\82·
62  // \96ß\82è\92l >= nBufSize \82Ì\8fê\8d\87\81A\95\8e\9a\97ñ\82ð\90Ø\82è\8eÌ\82Ä\82½\82±\82Æ\82ð\88Ó\96¡\82·\82é
63     int p = 0;
64     while (*cszSrc) {
65         if (kbIsLeadByte(*cszSrc)) {
66             if (!*(cszSrc+1)) {
67                 break;
68             }
69             p += 2;
70             if (p < nBufSize) {
71                 *(WORD*) szDest = *(const WORD*) cszSrc;
72                 szDest += 2;
73             }
74             cszSrc += 2;
75         }
76         else if (++p < nBufSize) {
77             *szDest++ = *cszSrc++;
78         }
79         else {
80             cszSrc++;
81         }
82     }
83     if (nBufSize > 0) {
84         *szDest = 0;
85     }
86     return p;
87 }
88 ///////////////////////////////////////////////////////////////////////////////
89 int __fastcall kbStrLCat(char *szDest, const char *cszSrc, int nBufSize)
90 {// cszSrc \82ð szDest \82É\98A\8c\8b
91  // nBufSize \82Í szDest \82Ì\83T\83C\83Y\81i\8fI\92[\82Ì '\0' \82ð\8aÜ\82Þ\81j
92  // \8fI\92[\95\8e\9a\82ª\93r\90Ø\82ê\82Ä\82¢\82é\82æ\82¤\82È\8fê\8d\87\82É\82à\91Î\89\9e
93  // kbStrLen(cszSrc) + min(kbStrLen(szDest), nBufSize) \82ð\95Ô\82·
94  // \96ß\82è\92l\82ª >= nBufSize \82Ì\8fê\8d\87\81A\98A\8c\8b\95\8e\9a\97ñ\82ð\90Ø\82è\8eÌ\82Ä\82½\82±\82Æ\82ð\88Ó\96¡\82·\82é
95  //
96     //min(kbStrLen(szDest) + nBufSize) \82Æ\83R\83s\81[\90æ\83o\83b\83t\83@\82Ö\82Ì\83|\83C\83\93\83^\82ð\93¾\82é
97     int nDestLen = 0;
98     while (*szDest && nDestLen < nBufSize) {
99         if (kbIsLeadByte(*szDest)) {
100             if (!*(szDest+1) || nDestLen >= nBufSize-2) {
101                 break;
102             }
103             else {
104                 szDest += 2;
105                 nDestLen += 2;
106             }
107         }
108         else {
109             szDest++;
110             nDestLen++;
111         }
112     }
113     return kbStrLCpy(szDest, cszSrc, nBufSize - nDestLen) + nDestLen;
114 }
115 ///////////////////////////////////////////////////////////////////////////////
116 //static const WORD wWSpace = 0x4081;//\91S\8ap\83X\83y\81[\83X
117 char* __fastcall kbStrTrimRight(char* szString)
118 {//\95\8e\9a\97ñlpszString\82Ì\8fI\92[\82©\82ç\8bó\94\92\95\8e\9a\82ð\8eæ\82è\8f\9c\82­
119     register char *p = szString;
120     if (p) {
121         char *Space = NULL;
122         while (*p) {
123             if (kbIsLeadByte(*p)) {//\91S\8ap
124                 /*if (*(WORD*) p == wWSpace) {
125                 //\91S\8ap\83X\83y\81[\83X\82ª\8c©\82Â\82©\82Á\82½
126                     if (!Space) {
127                         Space = p;
128                     }
129                 }
130                 else*/ if (p[1]) {
131                     Space = NULL;//\8bó\94\92\88È\8aO\82ª\8c©\82Â\82©\82Á\82½
132                 }
133                 else {//\95\8e\9a\97ñ\82ª\93r\92\86\82Å\93r\90Ø\82ê\82Ä\82µ\82Ü\82Á\82Ä\82¢\82é\81H
134                     *p = 0;//\91S\8ap\82P\83o\83C\83g\96Ú\82Ì\95\94\95ª\82Í\90Ø\82è\8eÌ\82Ä\82é
135                     break;
136                 }
137                 p += 2;
138             }
139             else {//\94¼\8ap
140                 if (*p == ' ') {
141                 //\94¼\8ap\83X\83y\81[\83X
142                     if (!Space) {
143                         Space = p;
144                     }
145                 }
146                 else {
147                     Space = NULL;//\8bó\94\92\88È\8aO\82ª\8c©\82Â\82©\82Á\82½
148                 }
149                 p++;
150             }
151         }
152         if (Space) {
153             *Space = 0;
154         }
155     }
156     return szString;
157 }
158 ///////////////////////////////////////////////////////////////////////////////
159 char* __fastcall kbStrTrimLeft(char* szString)
160 {//\95\8e\9a\97ñlpszString\82Ì\90æ\93ª\82©\82ç\8bó\94\92\95\8e\9a\82ð\8eæ\82è\8f\9c\82­
161     register char *src = szString;
162     if (src) {
163         while (*src) {
164             if (*src == ' ') {//\94¼\8ap\83X\83y\81[\83X
165                 src++;
166             }
167             else {
168                 if (src != szString) {
169                     register char *dst = szString;
170                     do{
171                         *dst++ = *src++;
172                     }while (*src);
173                     *dst = 0;
174                 }
175                 return szString;
176             }
177         }
178         *szString = 0;//\82·\82×\82Ä\8bó\94\92
179     }
180     return szString;
181 }
182 ///////////////////////////////////////////////////////////////////////////////
183 char* __fastcall kbStrTrim(char *szString)
184 {//\95\8e\9a\97ñlpszString\82Ì\90æ\93ª\82Æ\8fI\92[\82©\82ç\8bó\94\92\95\8e\9a\82ð\8eæ\82è\8f\9c\82­
185     return kbStrTrimLeft(kbStrTrimRight(szString));
186 }
187 ///////////////////////////////////////////////////////////////////////////////
188 char* __fastcall kbCRLFtoSpace(char *szString)
189 {//\89ü\8ds\81E\95\9c\8bA\95\8e\9a\82Æ\83^\83u\95\8e\9a\82ð\94¼\8ap\83X\83y\81[\83X\82É\95Ï\8a·\82·\82é
190     register char* p = szString;
191     if (p) {
192         while (*p) {
193             if (kbIsLeadByte(*p)) {//\91S\8ap
194                 if (!p[1]) {//\95\8e\9a\97ñ\82ª\93r\92\86\82Å\93r\90Ø\82ê\82Ä\82¢\82é
195                     *p = 0;
196                     break;
197                 }
198                 p += 2;
199             }
200             else {//\94¼\8ap
201                 if (*p == '\n' || *p == '\r' || *p == '\t') {
202                     *p = ' ';
203                 }
204                 p++;
205             }
206         }
207     }
208     return szString;
209 }
210 ///////////////////////////////////////////////////////////////////////////////
211 int __fastcall kbStrCmp(const char *cszStr1, const char *cszStr2)
212 {
213     while (*cszStr1) {
214         if (!*cszStr2) {
215             break;
216         }
217         if (kbIsLeadByte(*cszStr1)) {
218             if (kbIsLeadByte(*cszStr2)) {
219                 int cmp = *(WORD*) cszStr1 - *(WORD*) cszStr2;
220                 if (cmp == 0 && cszStr1[1]) {
221                     cszStr1 += 2;
222                     cszStr2 += 2;
223                 }
224                 else {
225                     if (*cszStr1 == *cszStr2) {
226                         return (BYTE) cszStr1[1] - (BYTE) cszStr2[1];
227                     }
228                     return (BYTE) cszStr1[0] - (BYTE) cszStr2[0];
229                 }
230             }
231             else {
232                 break;
233             }
234         }
235         else {
236             if (kbIsLeadByte(*cszStr2)) {
237                 break;
238             }
239             int cmp = (BYTE)(*cszStr1) - (BYTE)(*cszStr2);
240             if (cmp) {
241                 return cmp;
242             }
243             cszStr1++;
244             cszStr2++;
245         }
246     }
247     return (BYTE) *cszStr1 - (BYTE) *cszStr2;
248 }
249 ///////////////////////////////////////////////////////////////////////////////
250 //#define KBSTRCMPI_DEBUG
251 #ifdef KBSTRCMPI_DEBUG
252 static int __fastcall kbStrCmpI_(const char *cszStr1, const char *cszStr2);
253 int __fastcall kbStrCmpI(const char *cszStr1, const char *cszStr2)
254 {
255     int ret;
256     int ret1  = kbStrCmpI_(cszStr1, cszStr2);
257     int ret2 = strcmpi(cszStr1, cszStr2);
258     ret = ret1;
259     if (ret1) {
260         ret1 /= abs(ret1);
261     }
262     if (ret2) {
263         ret2 /= abs(ret2);
264     }
265     if (ret1 != ret2) {
266         if (!ret1 || !ret2) {
267         //\92v\96½\93I\83G\83\89\81[
268             int t = 0;
269         }
270     }
271     return ret;
272 }
273 ///////////////////////////////////////////////////////////////////////////////
274 static int __fastcall kbStrCmpI_(const char *cszStr1, const char *cszStr2)
275 #else
276 int __fastcall kbStrCmpI(const char *cszStr1, const char *cszStr2)
277 #endif
278 {
279     while (*cszStr1) {
280         if (!*cszStr2) {
281             break;
282         }
283         if (kbIsLeadByte(*cszStr1)) {
284             if (kbIsLeadByte(*cszStr2)) {
285                 int cmp = *(WORD*) cszStr1 - *(WORD*) cszStr2;
286                 if (cmp == 0 && cszStr1[1]) {
287                     cszStr1 += 2;
288                     cszStr2 += 2;
289                 }
290                 else {
291                     if (*cszStr1 == *cszStr2) {
292                         return (BYTE) cszStr1[1] - (BYTE) cszStr2[1];
293                     }
294                     return (BYTE) cszStr1[0] - (BYTE) cszStr2[0];
295                 }
296             }
297             else {
298                 break;
299             }
300         }
301         else {
302             if (kbIsLeadByte(*cszStr2)) {
303                 break;
304             }
305             int cmp = kbToLower(*cszStr1) - kbToLower(*cszStr2);
306             //int cmp = tolower(*cszStr1) - tolower(*cszStr2);
307             if (cmp) {
308                 return cmp;
309             }
310             cszStr1++;
311             cszStr2++;
312         }
313     }
314     return (BYTE) *cszStr1 - (BYTE) *cszStr2;
315 }
316 ///////////////////////////////////////////////////////////////////////////////
317 int __fastcall kbStrNCmp(const char *cszStr1, const char *cszStr2, int nLen)
318 {
319     while (nLen > 0 && *cszStr1) {
320         if (!*cszStr2) {
321             return 0;
322         }
323         if (kbIsLeadByte(*cszStr1)) {
324             if (kbIsLeadByte(*cszStr2)) {
325                 int cmp = *(WORD*) cszStr1 - *(WORD*) cszStr2;
326                 if (cmp == 0 && cszStr1[1]) {
327                     cszStr1 += 2;
328                     cszStr2 += 2;
329                     nLen -= 2;
330                 }
331                 else {
332                     if (*cszStr1 == *cszStr2) {
333                         return (BYTE) cszStr1[1] - (BYTE) cszStr2[1];
334                     }
335                     return (BYTE) cszStr1[0] - (BYTE) cszStr2[0];
336                 }
337             }
338             else {
339                 break;
340             }
341         }
342         else {
343             if (kbIsLeadByte(*cszStr2)) {
344                 break;
345             }
346             int cmp = (BYTE)(*cszStr1) - (BYTE)(*cszStr2);
347             //int cmp = tolower(*cszStr1) - tolower(*cszStr2);
348             if (cmp) {
349                 return cmp;
350             }
351             cszStr1++;
352             cszStr2++;
353             nLen--;
354         }
355     }
356     if (nLen > 0) {
357         return (BYTE) *cszStr1 - (BYTE) *cszStr2;
358     }
359     else {
360         return 0;
361     }
362 }
363 ///////////////////////////////////////////////////////////////////////////////
364 int __fastcall kbStrNCmpI(const char *cszStr1, const char *cszStr2, int nLen)
365 {
366     while (nLen > 0 && *cszStr1) {
367         if (!*cszStr2) {
368             return 0;
369         }
370         if (kbIsLeadByte(*cszStr1)) {
371             if (kbIsLeadByte(*cszStr2)) {
372                 int cmp = *(WORD*) cszStr1 - *(WORD*) cszStr2;
373                 if (cmp == 0 && cszStr1[1]) {
374                     cszStr1 += 2;
375                     cszStr2 += 2;
376                     nLen -= 2;
377                 }
378                 else {
379                     if (*cszStr1 == *cszStr2) {
380                         return (BYTE) cszStr1[1] - (BYTE) cszStr2[1];
381                     }
382                     return (BYTE) cszStr1[0] - (BYTE) cszStr2[0];
383                 }
384             }
385             else {
386                 break;
387             }
388         }
389         else {
390             if (kbIsLeadByte(*cszStr2)) {
391                 break;
392             }
393             int cmp = kbToLower(*cszStr1) - kbToLower(*cszStr2);
394             //int cmp = tolower(*cszStr1) - tolower(*cszStr2);
395             if (cmp) {
396                 return cmp;
397             }
398             cszStr1++;
399             cszStr2++;
400             nLen--;
401         }
402     }
403     if (nLen > 0) {
404         return (BYTE) *cszStr1 - (BYTE) *cszStr2;
405     }
406     else {
407         return 0;
408     }
409 }
410 ///////////////////////////////////////////////////////////////////////////////
411 const char* __fastcall kbStrChr(const char *cszString, char cFind)
412 {//\95\8e\9a\97ñ cszString \82©\82ç \95\8e\9a cFind \82ð\8c\9f\8dõ\82µ\81A\8dÅ\8f\89\82É\8c©\82Â\82©\82Á\82½\95\8e\9a\82Ö\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·
413  //\8c©\82Â\82©\82ç\82È\82¢\8fê\8d\87\82Í NULL \82ð\95Ô\82·
414  //cFind \82Í '\0' \82à\97L\8cø
415  //cFind == '\0' \82Å\95\8e\9a\97ñ\82ª\93r\90Ø\82ê\82Ä\82¢\82é\82Æ\82«\81A\93r\90Ø\82ê\82½\8dÅ\8f\89\82Ì\95\8e\9a\82Ö\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·
416     if (!cszString) return NULL;
417     while (1) {
418         if ((BYTE) *cszString == (BYTE) cFind) {
419             return cszString;
420         }
421         else if (kbIsLeadByte((BYTE) *cszString)) {
422             if (cszString[1]) {
423                 cszString += 2;
424             }
425             else if (cFind) {//\95\8e\9a\97ñ\82ª\93r\90Ø\82ê\82Ä\82¢\82é
426                 return NULL;
427             }
428             else {//\93r\90Ø\82ê\82½\8dÅ\8f\89\82Ì\95\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
429                 return cszString;
430             }
431         }
432         else if (*cszString) {
433             cszString++;
434         }
435         else {
436             return NULL;
437         }
438     }
439 }
440 ///////////////////////////////////////////////////////////////////////////////
441 const char* __fastcall kbStrRChr(const char *cszString, char cFind)
442 {//\95\8e\9a\97ñ cszString \82©\82ç \95\8e\9a cFind \82ð\8c\9f\8dõ\82µ\81A\8dÅ\8cã\82É\8c©\82Â\82©\82Á\82½\95\8e\9a\82Ö\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·
443  //\8c©\82Â\82©\82ç\82È\82¢\8fê\8d\87\82Í NULL \82ð\95Ô\82·
444  //cFind \82Í '\0' \82à\97L\8cø
445  //cFind == '\0' \82Å\95\8e\9a\97ñ\82ª\93r\90Ø\82ê\82Ä\82¢\82é\82Æ\82«\81A\93r\90Ø\82ê\82½\8dÅ\8f\89\82Ì\95\8e\9a\82Ö\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·
446     if (!cszString) return NULL;
447     const char *cszRet = NULL;
448     while (1) {
449         if ((BYTE) *cszString == (BYTE) cFind) {
450             cszRet = cszString;
451         }
452         else if (kbIsLeadByte((BYTE) *cszString)) {
453             if (cszString[1]) {
454                 cszString += 2;
455                 continue;
456             }
457             else if (cFind) {//\95\8e\9a\97ñ\82ª\93r\90Ø\82ê\82Ä\82¢\82é
458                 return cszRet;
459             }
460             else {//\93r\90Ø\82ê\82½\8dÅ\8f\89\82Ì\95\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
461                 return cszString;
462             }
463         }
464         if (*cszString) {
465             cszString++;
466         }
467         else {
468             break;
469         }
470     }
471     return cszRet;
472 }
473 ///////////////////////////////////////////////////////////////////////////////
474 const char* __fastcall kbStrStr(const char *cszString, const char *cszSearch)
475 {
476     int nSearchLen = -1;
477     while (*cszString) {
478         if (*cszString == *cszSearch) {
479             if (nSearchLen < 0) {
480                 nSearchLen = kbStrLen(cszSearch);
481             }
482             //if (strncmp(cszString, cszSearch, nSearchLen) == 0) {
483             if (kbStrNCmp(cszString, cszSearch, nSearchLen) == 0) {
484                 return cszString;
485             }
486         }
487         if (kbIsLeadByte(*cszString)) {
488             if (!cszString[1]) {
489                 break;
490             }
491             cszString += 2;
492         }
493         else {
494             cszString++;
495         }
496     }
497     return NULL;
498 }
499 ///////////////////////////////////////////////////////////////////////////////
500 const char* __fastcall kbStrStrI(const char *cszString, const char *cszSearch)
501 {
502     int nSearchLen = kbStrLen(cszSearch);
503     while (*cszString) {
504         //if (strnicmp(cszString, cszSearch, nSearchLen) == 0) {
505         //    return cszString;
506         //}
507         if (kbStrNCmpI(cszString, cszSearch, nSearchLen) == 0) {
508             return cszString;
509         }
510         if (kbIsLeadByte(*cszString)) {
511             if (!cszString[1]) {
512                 break;
513             }
514             cszString += 2;
515         }
516         else {
517             cszString++;
518         }
519     }
520     return NULL;
521 }
522 ///////////////////////////////////////////////////////////////////////////////
523 char* __fastcall kbStrUpr(char *pszString)
524 {
525     char *p = pszString;
526     while (*p) {
527         *p = kbToUpper(*p);
528         p++;
529     }
530     return pszString;
531 }
532 ///////////////////////////////////////////////////////////////////////////////
533 char* __fastcall kbStrLwr(char *pszString)
534 {
535     char *p = pszString;
536     while (*p) {
537         *p = kbToLower(*p);
538         p++;
539     }
540     return pszString;
541 }
542 ///////////////////////////////////////////////////////////////////////////////
543 char* __fastcall kbStrTok(char *pszString, const char *cszDelimiter, char **ppszNext)
544 {
545     *ppszNext = NULL;
546     char *p = pszString;
547     if (p) {
548         while (*p) {
549             if (kbIsLeadByte(*p)) {
550                 if (!p[1]) {//\95\8e\9a\97ñ\82ª\93r\90Ø\82ê\82Ä\82¢\82é
551                     *p = 0;
552                     return pszString;
553                 }
554                 p += 2;
555                 continue;
556             }
557             const char *delim = cszDelimiter;
558             while (*delim) {
559                 if (*p == *delim++) {
560                     *p++ = 0;
561                     *ppszNext = p;
562                     return pszString;
563                 }
564             }
565             p++;
566         }
567         if (*pszString) {
568             return pszString;
569         }
570     }
571     return NULL;
572 }
573 ///////////////////////////////////////////////////////////////////////////////
574 #if 1
575 static inline bool __fastcall is_digit(char c)
576 {
577     return ('0' <= c && c <= '9');
578 }
579 int __fastcall kbStrToIntDef(const char* p, int nDefault)
580 {//\95\8e\9a\97ñ\82ð\90®\90\94\82É\95Ï\8a·\82Å\82«\82½\8fê\8d\87\82Í\82»\82Ì\92l\82ð\95Ô\82·
581  //\95Ï\8a·\82Å\82«\82È\82¢\8fê\8d\87\82Í nDefault \82ð\95Ô\82·
582     int nSign = 1;//\95\84\8d\86
583     //\8bó\94\92\82ð\82Æ\82Î\82·
584         while (*p == ' ') {
585         p++;
586     }
587     //\95\84\8d\86
588         switch (*p) {
589                 case '-':
590                         nSign = -1;
591             p++;
592             break;
593                 case '+':
594                         p++;
595             break;
596         }
597     if (is_digit(*p)) {
598         //\90®\90\94\95\94\95ª
599         int nReturn = (*p++ - '0');
600         while (is_digit(*p)) {
601             nReturn *= 10;
602             nReturn += (*p++ - '0');
603         }
604         //\8f¬\90\94\95\94\95ª
605         if (*p == '.') {
606             while (is_digit(*++p));//\8f¬\90\94\95\94\95ª\82Í\82·\82×\82Ä\96³\8e\8b
607         }
608         //\90\94\92l\82Ì\95\94\95ª\88È\8d~\82É\8bó\94\92\88È\8aO\82Ì\95\8e\9a\82ª\8c©\82Â\82©\82Á\82½\8fê\8d\87\82Í nDefault \82ð\95Ô\82·
609         while (*p == ' ') {
610             p++;
611         }
612         if (!*p) {
613             return nSign*nReturn;
614         }
615     }
616     return nDefault;
617 }
618 double __fastcall kbStrToDoubleDef(const char* p, double nDefault)
619 {//\95\8e\9a\97ñ\82ð\8f¬\90\94\82É\95Ï\8a·\82Å\82«\82½\8fê\8d\87\82Í\82»\82Ì\92l\82ð\95Ô\82·
620  //\95Ï\8a·\82Å\82«\82È\82¢\8fê\8d\87\82Í nDefault \82ð\95Ô\82·
621     int nSign = 1;//\95\84\8d\86
622     //\8bó\94\92\82ð\82Æ\82Î\82·
623         while (*p == ' ') {
624         p++;
625     }
626     //\95\84\8d\86
627         switch (*p) {
628                 case '-':
629                         nSign = -1;
630             p++;
631             break;
632                 case '+':
633                         p++;
634             break;
635         }
636     if (is_digit(*p)) {
637         //\90®\90\94\95\94\95ª
638         double nReturn = (*p++ - '0');
639         while (is_digit(*p)) {
640             nReturn *= 10;
641             nReturn += (*p++ - '0');
642         }
643         //\8f¬\90\94\95\94\95ª
644         if (*p == '.') {
645             int multi = 1;
646             ++p;
647             while (is_digit(*p)) {
648               multi *= 10;
649               nReturn += (double)(*p++ - '0') / multi;
650             }
651         }
652         //\90\94\92l\82Ì\95\94\95ª\88È\8d~\82É\8bó\94\92\88È\8aO\82Ì\95\8e\9a\82ª\8c©\82Â\82©\82Á\82½\8fê\8d\87\82Í nDefault \82ð\95Ô\82·
653         while (*p == ' ') {
654             p++;
655         }
656         if (!*p) {
657             return nSign*nReturn;
658         }
659     }
660     return nDefault;
661 }
662 #else
663 int __fastcall kbStrToIntDef(const char* cszStr, int nDefault)
664 {//cszStr \82ð\90®\90\94\82É\95Ï\8a·\82·\82é
665  //\95Ï\8a·\82Å\82«\82È\82¢\8fê\8d\87\82Í nDefault \82ð\95Ô\82·
666     if (!cszStr) {
667         return nDefault;
668     }
669     const int cMaxLen = 1024;
670     const int len = kbStrLen(cszStr) + 1;
671     if (len > cMaxLen) {
672         return nDefault;//\95\8e\9a\97ñ\82ª\92·\82·\82¬\82é
673     }
674     char szCopy[cMaxLen];
675     memcpy(szCopy, cszStr, len);
676     kbStrTrim(szCopy);
677     int ret;
678     if (szCopy[0]) {
679         char *szEndStr = NULL;
680         ret = strtol(szCopy, &szEndStr, 10);
681         if (szEndStr && szEndStr[0]) {
682             ret = nDefault;
683         }
684     }
685     else {
686         ret = nDefault;
687     }
688     return ret;
689 }
690 double __fastcall kbStrToDoubleDef(const char* cszStr, double nDefault)
691 {//cszStr \82ð\8f¬\90\94\82É\95Ï\8a·\82·\82é
692  //\95Ï\8a·\82Å\82«\82È\82¢\8fê\8d\87\82Í nDefault \82ð\95Ô\82·
693     if (!cszStr) {
694         return nDefault;
695     }
696     const int cMaxLen = 1024;
697     const int len = kbStrLen(cszStr) + 1;
698     if (len > cMaxLen) {
699         return nDefault;//\95\8e\9a\97ñ\82ª\92·\82·\82¬\82é
700     }
701     char szCopy[cMaxLen];
702     memcpy(szCopy, cszStr, len);
703     kbStrTrim(szCopy);
704     int ret;
705     if (szCopy[0]) {
706         char *szEndStr = NULL;
707         ret = strtof(szCopy, &szEndStr, 10);
708         if (szEndStr && szEndStr[0]) {
709             ret = nDefault;
710         }
711     }
712     else {
713         ret = nDefault;
714     }
715     return ret;
716 }
717 #endif
718 ///////////////////////////////////////////////////////////////////////////////
719 int __fastcall kbStringReplace(char *dst,
720                                int   size,
721                                const char *src,
722                                const char *old_pattern,
723                                const char *new_pattern)
724 {//\95\8e\9a\97ñ src \82Ì old_pattern \82ð new_pattern \82É\92u\8a·\82·\82é
725  //size \82Í dst \82Ì\83o\83b\83t\83@\83T\83C\83Y
726  //old_pattern == "" \81i\8bó\95\8e\9a\97ñ\81j\82Ì\8fê\8d\87\81AkbStrLCat(dst, size, new_pattern) \82Æ\93¯\82
727  //\83o\83b\83t\83@\83T\83C\83Y\82ª\91«\82è\82È\82¢\8fê\8d\87\82Í\81Asize-1 \83o\83C\83g\82Ü\82Å\92u\8a·\82·\82é
728  //\8a®\91S\92u\8a·\82³\82ê\82½\82Æ\82µ\82½\82Æ\82«\82Ì\95\8e\9a\97ñ\82Ì\92·\82³\82ð\95Ô\82·
729  //\96ß\82è\92l >= size \82Ì\8fê\8d\87\81A\92u\8a·\8cã\82Ì\95\8e\9a\97ñ\82ª\88ê\95\94\90Ø\82è\8eÌ\82Ä\82ç\82ê\82½\82±\82Æ\82ð\88Ó\96¡\82·\82é
730     int ret = 0;
731     const int old_pattern_len = kbStrLen(old_pattern);
732     while (1) {
733         if (ret < size &&
734            *src == *old_pattern &&
735            kbStrNCmp(src, old_pattern, old_pattern_len) == 0) {
736             const int new_pattern_len = kbStrLCpy(dst, new_pattern, size - ret);
737             if (new_pattern_len < size - ret) {
738                 dst += new_pattern_len;
739             }
740             else {
741                 dst += (size - ret);
742             }
743             ret += new_pattern_len;
744             if (!*src) {
745                 break;
746             }
747             src += old_pattern_len;
748             continue;
749         }
750         if (kbIsLeadByte(*src)) {
751             if (src[1]) {
752                 ret += 2;
753                 if (ret < size) {
754                     *((WORD*) dst) = *((WORD*) src);
755                     dst += 2;
756                 }
757                 src += 2;
758             }
759             else {
760                 break;
761             }
762         }
763         else if (*src) {
764             if (++ret < size) {
765                 *dst++ = *src++;
766             }
767             else {
768                 src++;
769             }
770         }
771         else {
772             break;
773         }
774     }
775     if (size > 0) {
776         *dst = 0;
777     }
778     return ret;
779 }
780 ///////////////////////////////////////////////////////////////////////////////
781 int __fastcall kbMultiByteToWideChar(const char *cszMultiByte,
782                                      wchar_t* wszWideChar,
783                                      int cchWideChar)
784 {//cchWideChar == 0 \82Ì\82Æ\82«\82Í\95K\97v\82È\83o\83b\83t\83@\82Ì\83T\83C\83Y(\95\8e\9a\90\94\92P\88Ê)\82ð\95Ô\82·
785     int ret = MultiByteToWideChar(CP_ACP, 0, cszMultiByte, -1,
786                                       wszWideChar, cchWideChar);
787     //\83o\83b\83t\83@\83T\83C\83Y\82ª\91«\82è\82È\82¢\8fê\8d\87\81AwszWideChar \82Ì\8fI\92[\95\8e\9a\82Í \0 \82É\82È\82ç\82È\82¢
788     if (cchWideChar) {
789         wszWideChar[cchWideChar-1] = 0;//\8fI\92[\82ð \0 \82É\82·\82é
790     }
791     return ret;
792 }
793 ///////////////////////////////////////////////////////////////////////////////
794 int __fastcall kbWideCharToMultiByte(const wchar_t *wcszWideChar,
795                                      char *szMultiByte,
796                                      int cchMultiByte)
797 {//cchMultiByte \82ª 0 \82Ì\82Æ\82«\82Í\95K\97v\82È\83o\83b\83t\83@\82Ì\83T\83C\83Y\82ð\95Ô\82·
798     int ret = WideCharToMultiByte(CP_ACP, 0, wcszWideChar, -1,
799                                 szMultiByte, cchMultiByte, NULL, NULL);
800     //\83o\83b\83t\83@\83T\83C\83Y\82ª\91«\82è\82È\82¢\8fê\8d\87\81AszMultiByte \82Ì\8fI\92[\95\8e\9a\82Í \0 \82É\82È\82ç\82È\82¢
801     if (cchMultiByte) {
802         szMultiByte[cchMultiByte-1] = 0;//\8fI\92[\82ð \0 \82É\82·\82é
803         if (ret == 0) {//\83T\83C\83Y\82ª\91«\82è\82È\82¢(\81ª\82Å\8fI\92[\95\8e\9a\82ª\83}\83\8b\83`\83o\83C\83g\82Ì2\83o\83C\83g\96Ú\82¾\82Á\82½\8fê\8d\87\82É\91Î\8f\88\81j
804             int nLen = kbStrLen(szMultiByte);//\95\8e\9a\97ñ\82ª\93r\90Ø\82ê\82Ä\82é\8fê\8d\87\82Í\97L\8cø\82È\95\94\95ª\82Ü\82Å\82Ì\92·\82³\82ð\95Ô\82·
805             szMultiByte[nLen] = 0;           //\93r\90Ø\82ê\82Ä\82é\8fê\8d\87\82Í\93r\90Ø\82ê\82½\95\94\95ª\82ª\8f\9c\8b\8e\82³\82ê\82é
806         }
807     }
808     return ret;
809 }
810 ///////////////////////////////////////////////////////////////////////////////
811 //
812 //\83t\83@\83C\83\8b\96¼\8aÖ\8cW
813 //
814 ///////////////////////////////////////////////////////////////////////////////
815 const char* __fastcall kbExtractFileExt(const char* cszSrc)
816 {//cszSrc \93à\82Ì\8ag\92£\8eq\95\94\95ª\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·
817  //\8c©\82Â\82©\82ç\82È\82¢\8fê\8d\87\82Í\8bó\95\8e\9a\97ñ\82ð\95Ô\82·\81iNULL \82Å\82Í\82È\82¢\81j
818     if (!cszSrc) return gcszEmpty;
819     const BYTE* LastPeriod = NULL;
820     const BYTE* LastPathDelimiter = NULL;
821     while (*cszSrc) {
822         if (kbIsLeadByte((*((const BYTE*) cszSrc)))) {
823             if (cszSrc[1]) {
824                 cszSrc+=2;
825                 continue;
826             }
827             else {//\95\8e\9a\97ñ\82ª\93r\92\86\82Å\93r\90Ø\82ê\82Ä\82¢\82é
828                 break;
829             }
830         }
831         if ((BYTE) *cszSrc == (BYTE)'.') {
832             LastPeriod = (BYTE*) cszSrc;
833         }
834         else if ((BYTE) *cszSrc == (BYTE)'\\') {
835             LastPathDelimiter = (BYTE*) cszSrc;
836         }
837         cszSrc++;
838     }
839     if (LastPeriod && (DWORD) LastPeriod > (DWORD) LastPathDelimiter) {
840         //\83s\83\8a\83I\83h\82ª\8c©\82Â\82©\82Á\82Ä\82à\81A\8ag\92£\8eq\82Æ\82Í\8cÀ\82ç\82È\82¢
841         //\97á\81FC:\\hoge.hoge\\hogehoge
842         return (const char*) LastPeriod;
843     }
844     return gcszEmpty;
845 }
846 ///////////////////////////////////////////////////////////////////////////////
847 const char* __fastcall kbExtractFileName(const char* cszFileName)
848 {//cszFileName \82©\82ç\83p\83X\82ð\8eæ\82è\8f\9c\82¢\82½\82à\82Ì\81i\83t\83@\83C\83\8b\96¼\95\94\95ª\81j\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·
849     const char *cszLastDelimiter = kbStrRChr(cszFileName, '\\');
850     if (cszLastDelimiter) {
851         return cszLastDelimiter + 1;
852     }
853     if (cszFileName) return cszFileName;
854     return gcszEmpty;
855 }
856 ///////////////////////////////////////////////////////////////////////////////
857 char* __fastcall kbExtractFilePath(char *szDest, const char *cszFileName, int nSize)
858 {//cszFileName \82©\82ç\83p\83X\82ð\8eæ\93¾\82µ\82Ä\83|\83C\83\93\83^\82ð\95Ô\82·
859  //szDest == cszFileName \82Å\82 \82Á\82Ä\82Í\82È\82ç\82È\82¢
860     szDest[0] = 0;
861     const char *cszLastPathDelimiter = kbStrRChr(cszFileName, '\\');
862     if (cszLastPathDelimiter) {
863         int nLen = cszLastPathDelimiter - cszFileName + 1;
864         if (nLen < nSize) {
865             memcpy(szDest, cszFileName, nLen);
866             szDest[nLen] =0;
867         }
868     }
869     return szDest;
870 }
871 ///////////////////////////////////////////////////////////////////////////////
872 const char* __fastcall kbExtractFileNameInArc(const char *cszFileName)
873 {//\8f\91\8cÉ\83t\83@\83C\83\8b\93à\82Ì\83t\83@\83C\83\8b\96¼\82©\82ç\83p\83X\82ð\8eæ\82è\8f\9c\82¢\82½\82à\82Ì\82ð\95Ô\82·
874  //\97á\82P\81FC:\hoge\hoge.lzh>test.mid \82Ì\96ß\82è\92l = test.mid
875  //\97á\82Q\81FC:\hoge\hoge.lzh>test/test2.mid \82Ì\96ß\82è\92l\81\81test2.mid
876  //\97á\82R\81FC:\hoge\hoge.lzh>test/testzip.zip>test3.mid \82Ì\96ß\82è\92l = test3.mid
877  //\97á\82S\81FC:\hoge\hoge.lzh>test/testzip.zip>test/test4.mid \82Ì\96ß\82è\92l = test4.mid
878     if (!cszFileName) return gcszEmpty;
879     const char *cszDelimiter = kbStrRChr(cszFileName, '>');
880     if (cszDelimiter) {
881         cszFileName = cszDelimiter + 1;
882     }
883     cszDelimiter = kbStrRChr(cszFileName, '/');
884     if (cszDelimiter) {
885         return cszDelimiter + 1;
886     }
887     return cszFileName;
888 }
889 ///////////////////////////////////////////////////////////////////////////////
890 const char* __fastcall kbExtractFilePathInArc(char *szDest, const char *cszFileName)
891 {//\8f\91\8cÉ\83t\83@\83C\83\8b\93à\82Ì\83t\83@\83C\83\8b\96¼\82©\82ç\83t\83@\83C\83\8b\96¼\82ð\8eæ\82è\8f\9c\82¢\82½\82à\82Ì\82ð\95Ô\82·
892  //\97á\82P\81FC:\hoge\hoge.lzh>test.mid \82Ì\96ß\82è\92l = C:\hoge\hoge.lzh>
893  //\97á\82Q\81FC:\hoge\hoge.lzh>test/test2.mid \82Ì\96ß\82è\92l = C:\hoge\hoge.lzh>test/
894  //\97á\82R\81FC:\hoge\hoge.lzh>test/testzip.zip>test3.mid \82Ì\96ß\82è\92l = C:\hoge\hoge.lzh>test/testzip.zip>
895  //\97á\82S\81FC:\hoge\hoge.lzh>test/testzip.zip>test/test4.mid \82Ì\96ß\82è\92l = C:\hoge\hoge.lzh>test/testzip.zip>test/
896     if (!szDest) return NULL;
897     szDest[0] = 0;
898     if (!cszFileName) return szDest;
899     const char *cszFirst = cszFileName;
900     const char *cszDelimiter = kbStrRChr(cszFileName, '>');
901     if (cszDelimiter) {
902         cszFileName = cszDelimiter + 1;
903     }
904     cszDelimiter = kbStrRChr(cszFileName, '/');
905     if (cszDelimiter) {
906         cszFileName = cszDelimiter + 1;
907     }
908     int nCopySize = cszFileName - cszFirst;
909     if (nCopySize > 0) {
910         memcpy(szDest, cszFirst, nCopySize);
911         szDest[nCopySize] = 0;
912     }
913     return szDest;
914 }
915 ///////////////////////////////////////////////////////////////////////////////
916 char* __fastcall kbExtractReplacedFileExt(char *szDest,
917                                           const char *cszFileName,
918                                           const char *cszExt)
919 {//cszFileName \82Ì\8ag\92£\8eq\82ð cszExt \82É\92u\82«\8a·\82¦\82Ä szDest \82É\83R\83s\81[\82·\82é
920  //szDest \82Ì\83T\83C\83Y\82Í cszFileName \82Æ cszExt \82Ì\8d\87\8cv\82æ\82è\91å\82«\82¢\82±\82Æ\82ª\91O\92ñ
921     if (!szDest) {
922         return NULL;
923     }
924     if (!cszExt) {
925         cszExt = gcszEmpty;
926     }
927     if (!cszFileName) {
928         strcpy(szDest, cszExt);
929         return szDest;
930     }
931     const char *ext =  kbStrRChr(cszFileName, '.');
932     const char *path = kbStrRChr(cszFileName, '\\');
933     if (ext && ext > path) {
934         const int len = ext - cszFileName;
935         memcpy(szDest, cszFileName, len);
936         strcpy(szDest + len, cszExt);
937     }
938     else {
939         strcpy(szDest, cszFileName);
940         strcat(szDest, cszExt);
941     }
942
943     return szDest;
944 }
945 ///////////////////////////////////////////////////////////////////////////////
946 void __fastcall kbAddPathDelimiter(char *szPath)
947 {//\95\8e\9a\97ñ\82Ì\8fI\92[\82É \ \82ð\92Ç\89Á
948  //\82·\82Å\82É\8fI\92[\82ª \ \82Ì\8fê\8d\87\82Í\89½\82à\82µ\82È\82¢
949     char *p = szPath;
950     char *last = p;
951     //\8fI\92[\95\8e\9a\82ð\92T\82·
952     while (*p) {
953         last = p;
954         if (kbIsLeadByte(*p)) {
955             if (!p[1]) {//\95\8e\9a\97ñ\82ª\93r\90Ø\82ê\82Ä\82¢\82é
956                 *p = 0;
957                 p = last = szPath;
958                 continue;//\8dÅ\8f\89\82©\82ç\82â\82è\92¼\82·
959             }
960             p += 2;
961         }
962         else {
963             p++;
964         }
965     }
966     if (*last != '\\') {
967         p[0] = '\\';
968         p[1] = 0;
969     }
970 }
971 ///////////////////////////////////////////////////////////////////////////////
972 void __fastcall kbCombinePath(char *szDest, const char *cszSrc,
973                               const char *cszAdd, int nDestSize)
974 {
975     kbStrLCpy(szDest, cszSrc, nDestSize);
976     char *p = kbStrRChr(szDest, '\\');
977     if (!p || p[1]) {//\ \82ª\8aÜ\82Ü\82ê\82È\82¢ or \8aÜ\82Þ\82ª\8fI\92[\82Å\82Í\82È\82¢
978         kbStrLCat(szDest, "\\", nDestSize);//kbAddPathDelimiter \82¾\82Æ\83o\83b\83t\83@\83T\83C\83Y\82Ì\83`\83F\83b\83N\82ð\82µ\82È\82¢\82Ì\82Å\8eg\97p\95s\89Â
979     }
980     kbStrLCat(szDest, cszAdd, nDestSize);
981 }
982 ///////////////////////////////////////////////////////////////////////////////
983 void __fastcall kbRemovePathDelimiter(char *szPath)
984 {   //\83h\83\89\83C\83u\82Ì\83\8b\81[\83g\82Å\82È\82¢\8fê\8d\87\82Í\8fI\92[\82Ì \ \82ð\8f\9c\82­
985     char *p = kbStrRChr(szPath, '\\');
986     if (p && !p[1] && (p - szPath >= 3)) {
987         *p = 0;
988     }
989 }
990 ///////////////////////////////////////////////////////////////////////////////
991