OSDN Git Service

Version 5.91
[vbslib/main.git] / _src / Test / tools / feq / _setup_generated / clib.c
1 /* Character Code Encoding: "WHITE SQUARE" is \81  */\r
2 /* The source file was composed by module mixer */ \r
3 \r
4 #include  "include_c.h"\r
5 \r
6 \r
7  \r
8 /*=================================================================*/\r
9 /* <<< [Global0/Global0.c] >>> */ \r
10 /*=================================================================*/\r
11  \r
12 /***********************************************************************\r
13   <<< [Globals_initConst] >>> \r
14 ************************************************************************/\r
15 \r
16 void  Globals_initConst()\r
17 {\r
18 }\r
19 \r
20 \r
21  \r
22 /***********************************************************************\r
23   <<< [Globals_initialize] >>> \r
24 ************************************************************************/\r
25 int  Globals_initialize()\r
26 {\r
27   int  e;\r
28 \r
29     e= Locale_init(); IF(e)goto fin;\r
30 \r
31   e=0;\r
32   goto fin;  // for avoid warning of no goto fin\r
33 fin:\r
34   return  e;\r
35 }\r
36 \r
37 \r
38  \r
39 /***********************************************************************\r
40   <<< [Globals_finalize] >>> \r
41 ************************************************************************/\r
42 int  Globals_finalize( int e )\r
43 {\r
44 \r
45   return  e;\r
46 }\r
47 \r
48 \r
49  \r
50 /*=================================================================*/\r
51 /* <<< [PlatformSDK_plus/PlatformSDK_plus.c] >>> */ \r
52 /*=================================================================*/\r
53  \r
54 /***********************************************************************\r
55   <<< [GetCommandLineUnnamed] >>> \r
56 ************************************************************************/\r
57 int  GetCommandLineUnnamed( int Index1, TCHAR* out_AParam, size_t AParamSize )\r
58 {\r
59         TCHAR*  line = GetCommandLine();\r
60         int     index;\r
61         TCHAR*  p;\r
62         TCHAR*  p2;\r
63         TCHAR   c;\r
64 \r
65         #if UNDER_CE\r
66                 Index1 --;\r
67         #endif\r
68         IF( Index1 < 0 ) goto err_nf;\r
69         index = Index1;\r
70 \r
71         p = line;\r
72 \r
73         for (;;) {\r
74                 while ( *p == _T(' ') )  p++;\r
75 \r
76                 c = *p;\r
77 \r
78                 if ( c == _T('\0') )  goto err_nf;  // Here is not decided to error or not\r
79 \r
80 \r
81                 //=== Skip named option\r
82                 else if ( c == _T('/') ) {\r
83                         p++;\r
84                         for (;;) {\r
85                                 c = *p;\r
86                                 if ( c == _T('"') || c == _T(' ') || c == _T('\0') )  break;\r
87                                 p++;\r
88                         }\r
89 \r
90                         if ( c == _T('"') ) {\r
91                                 p++;\r
92                                 while ( *p != _T('"') && *p != _T('\0') )  p++;\r
93                                 if ( *p == _T('"') )  p++;\r
94                         }\r
95                 }\r
96 \r
97                 //=== Skip or Get unnamed parameter\r
98                 else {\r
99                         while ( *p == _T(' ') )  p++;\r
100 \r
101                         c = *p;\r
102                         p2 = p + 1;\r
103 \r
104                         if ( c == _T('"') ) {\r
105                                 p ++;\r
106                                 while ( *p2 != _T('"') && *p2 != _T('\0') )  p2++;\r
107                         }\r
108                         else {\r
109                                 while ( *p2 != _T(' ') && *p2 != _T('\0') )  p2++;\r
110                         }\r
111 \r
112                         if ( index == 0 ) {\r
113                                 int  e;\r
114 \r
115                                 e= stcpy_part_r( out_AParam, AParamSize, out_AParam, NULL, p, p2 );\r
116                                         ASSERT_D( !e, __noop() );\r
117                                 return  e;\r
118                         }\r
119                         else {\r
120                                 p = ( *p2 == _T('"') ) ? p2+1 : p2;\r
121                                 index --;\r
122                         }\r
123                 }\r
124         }\r
125 \r
126 err_nf:\r
127         if ( AParamSize >= sizeof(TCHAR) )  *out_AParam = _T('\0');\r
128         IF ( Index1 >= 2 )  return  E_NOT_FOUND_SYMBOL;\r
129         return  0;\r
130 }\r
131 \r
132 \r
133  \r
134 /***********************************************************************\r
135   <<< [GetCommandLineNamed] >>> \r
136 ************************************************************************/\r
137 int  GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize );\r
138 \r
139 int  GetCommandLineNamed( const TCHAR* Name, bool bCase, TCHAR* out_Value, size_t ValueSize )\r
140 {\r
141         bool  is_exist;\r
142         return  GetCommandLineNamed_sub( Name, bCase, &is_exist, out_Value, ValueSize );\r
143 }\r
144 \r
145 \r
146 int  GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize )\r
147 {\r
148         TCHAR*  line = GetCommandLine();\r
149         TCHAR*  p;\r
150         TCHAR*  p2;\r
151         TCHAR   c;\r
152         const size_t  name_len = _tcslen( Name );\r
153         bool    bMatch;\r
154 \r
155         *out_IsExist = true;\r
156 \r
157         p = line;\r
158         for (;;) {\r
159                 c = *p;\r
160 \r
161                 //=== Compare option name\r
162                 if ( c == _T('/') ) {\r
163                         p++;\r
164                         p2 = p;\r
165                         for (;;) {\r
166                                 c = *p2;\r
167                                 if ( c == _T(':') || c == _T(' ') || c == _T('\0') )  break;\r
168                                 p2++;\r
169                         }\r
170                         if ( bCase )\r
171                                 bMatch = ( p2-p == (int)name_len && _tcsncmp( p, Name, p2-p ) == 0 );\r
172                         else\r
173                                 bMatch = ( p2-p == (int)name_len && _tcsnicmp( p, Name, p2-p ) == 0 );\r
174 \r
175 \r
176                         //=== Get the value\r
177                         if ( c == _T(':') ) {\r
178                                 p = p2 + 1;\r
179                                 if ( *p == _T('"') ) {\r
180                                         p++;\r
181                                         p2 = p;\r
182                                         while ( *p2 != _T('"') && *p2 != _T('\0') )  p2++;\r
183                                         if ( bMatch )\r
184                                                 return  stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );\r
185                                         else\r
186                                                 p = p2+1;\r
187                                 }\r
188                                 else {\r
189                                         p2 = p;\r
190                                         while ( *p2 != _T(' ') && *p2 != _T('\0') )  p2++;\r
191                                         if ( bMatch )\r
192                                                 return  stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );\r
193                                         else\r
194                                                 p = p2;\r
195                                 }\r
196                         }\r
197                         else {\r
198                                 IF( bMatch ) return  E_NOT_FOUND_SYMBOL;  // no value error\r
199                         }\r
200                 }\r
201 \r
202                 else if ( c == _T('\0') )  break;\r
203 \r
204                 //=== Skip\r
205                 else if ( c == _T('"') ) {\r
206                         p++;\r
207                         while ( *p != _T('"') && *p != _T('\0') )  p++;\r
208                         while ( *p != _T(' ') && *p != _T('\0') )  p++;\r
209                 }\r
210                 else {\r
211                         while ( *p != _T(' ') && *p != _T('\0') )  p++;\r
212                 }\r
213                 while ( *p == _T(' ') )  p++;\r
214         }\r
215 \r
216         *out_IsExist = false;\r
217         return  E_NOT_FOUND_SYMBOL;\r
218 }\r
219 \r
220 \r
221  \r
222 /***********************************************************************\r
223   <<< [GetCommandLineNamedI] >>> \r
224 ************************************************************************/\r
225 int  GetCommandLineNamedI( const TCHAR* Name, bool bCase, int* out_Value )\r
226 {\r
227         int    e;\r
228         bool   is_exist;\r
229         TCHAR  s[20];\r
230 \r
231         e= GetCommandLineNamed_sub( Name, bCase, &is_exist, s, sizeof(s) ); IF(e)goto fin;  //[out] s\r
232         if ( s[0] == _T('0') && s[1] == _T('x') )\r
233                 *out_Value = _tcstoul( s, NULL, 16 );\r
234         else\r
235                 *out_Value = _ttoi( s );\r
236         //e=0;\r
237 fin:\r
238         return  e;\r
239 }\r
240 \r
241 \r
242  \r
243 /***********************************************************************\r
244   <<< [GetCommandLineNamedC8] >>> \r
245 ************************************************************************/\r
246 #if  _UNICODE\r
247 int  GetCommandLineNamedC8( const TCHAR* Name, bool bCase, char* out_Value, size_t ValueSize )\r
248 {\r
249         int     e;\r
250         bool    is_exist;\r
251         TCHAR*  s = NULL;\r
252 \r
253         s = (TCHAR*) malloc( ValueSize * sizeof(TCHAR) );\r
254         e= GetCommandLineNamed_sub( Name, bCase, &is_exist, (TCHAR*) s, ValueSize * sizeof(TCHAR) ); IF(e)goto fin;\r
255 \r
256         sprintf_s( out_Value, ValueSize, "%S", s );\r
257 fin:\r
258         if ( s != NULL )  free( s );\r
259         return  e;\r
260 }\r
261 #endif\r
262 \r
263 \r
264  \r
265 /***********************************************************************\r
266   <<< [GetCommandLineExist] >>> \r
267 ************************************************************************/\r
268 bool  GetCommandLineExist( const TCHAR* Name, bool bCase )\r
269 {\r
270         int     e;\r
271         bool    is_exist;\r
272         TCHAR   v[1];\r
273 \r
274         e = GetCommandLineNamed_sub( Name, bCase, &is_exist, v, sizeof(v) );\r
275         if ( e == E_NOT_FOUND_SYMBOL )  ClearError();\r
276         return  is_exist;\r
277 }\r
278 \r
279 \r
280  \r
281 /*=================================================================*/\r
282 /* <<< [Locale/Locale.c] >>> */ \r
283 /*=================================================================*/\r
284  \r
285 /***********************************************************************\r
286   <<< [g_LocaleSymbol] >>> \r
287 ************************************************************************/\r
288 char*  g_LocaleSymbol = "";\r
289 \r
290 \r
291  \r
292 /***********************************************************************\r
293   <<< [Locale_init] >>> \r
294 ************************************************************************/\r
295 int  Locale_init()\r
296 {\r
297         g_LocaleSymbol = ".OCP";\r
298         setlocale( LC_ALL, ".OCP" );\r
299         return  0;\r
300 }\r
301 \r
302 \r
303  \r
304 /***********************************************************************\r
305   <<< [Locale_isInited] >>> \r
306 ************************************************************************/\r
307 int  Locale_isInited()\r
308 {\r
309         return  ( g_LocaleSymbol[0] != '\0' );\r
310                 // \82±\82±\82ª false \82ð\95Ô\82·\82Æ\82«\82Ì\91Î\8f\88\96@\82Í\81ALocale_isInited \82Ì\83w\83\8b\83v\82ð\8eQ\8fÆ\82µ\82Ä\82­\82¾\82³\82¢\81B\r
311 }\r
312 \r
313 \r
314  \r
315 /*=================================================================*/\r
316 /* <<< [FileT/FileT.c] >>> */ \r
317 /*=================================================================*/\r
318  \r
319 /***********************************************************************\r
320   <<< [FileT_isExist] >>> \r
321 ************************************************************************/\r
322 bool  FileT_isExist( const TCHAR* path )\r
323 {\r
324  #if ! FileT_isExistWildcard\r
325 \r
326         DWORD  r;\r
327 \r
328         if ( path[0] == _T('\0') )  return  false;\r
329         r = GetFileAttributes( path );\r
330         return  r != (DWORD)-1;\r
331 \r
332  #else\r
333 \r
334         HANDLE  find;\r
335         WIN32_FIND_DATA  data;\r
336 \r
337         find = FindFirstFileEx( path, FindExInfoStandard, &data,\r
338                 FindExSearchNameMatch, NULL, 0 );\r
339 \r
340         if ( find == INVALID_HANDLE_VALUE ) {\r
341                 return  false;\r
342         }\r
343         else {\r
344                 FindClose( find );\r
345                 return  true;\r
346         }\r
347 \r
348  #endif\r
349 }\r
350 \r
351 \r
352  \r
353 /***********************************************************************\r
354   <<< [FileT_isFile] >>> \r
355 ************************************************************************/\r
356 bool  FileT_isFile( const TCHAR* path )\r
357 {\r
358         DWORD  r = GetFileAttributes( path );\r
359         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;\r
360                 // 0x80000000 \82Í\81A\83t\83@\83C\83\8b\82â\83t\83H\83\8b\83_\82ª\91\8dÝ\82µ\82È\82¢\82±\82Æ\82ð\94»\92è\82·\82é\82½\82ß\r
361 }\r
362 \r
363 \r
364  \r
365 /***********************************************************************\r
366   <<< [FileT_isDir] >>> \r
367 ************************************************************************/\r
368 bool  FileT_isDir( const TCHAR* path )\r
369 {\r
370         DWORD  r = GetFileAttributes( path );\r
371         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;\r
372                 // 0x80000000 \82Í\81A\83t\83@\83C\83\8b\82â\83t\83H\83\8b\83_\82ª\91\8dÝ\82µ\82È\82¢\82±\82Æ\82ð\94»\92è\82·\82é\82½\82ß\r
373 }\r
374 \r
375 \r
376  \r
377 /***********************************************************************\r
378   <<< [FileT_isDiff] >>> \r
379 ************************************************************************/\r
380 int  FileT_isDiff( const TCHAR* Path1, const TCHAR* Path2, bool* bDiff )\r
381 {\r
382         int    e;\r
383         bool   b;\r
384         FILE*  f1 = NULL;\r
385         FILE*  f2 = NULL;\r
386         char*  buf1 = NULL;\r
387         char*  buf2 = NULL;\r
388         errno_t  en;\r
389 \r
390 \r
391         //=== Open files\r
392         en= _tfopen_s( &f1, Path1, _T("r") );\r
393         if ( en == ENOENT )  { f1 = NULL; en = 0; }\r
394         IF(en)goto err_no;\r
395 \r
396         en= _tfopen_s( &f2, Path2, _T("r") );\r
397         if ( en == ENOENT )  { f2 = NULL; en = 0; }\r
398         IF(en)goto err_no;\r
399 \r
400 \r
401         //=== Whether exists or not\r
402         if ( f1 == NULL ) {\r
403                 if ( f2 == NULL )  { *bDiff = false; e=0; goto fin; }\r
404                 else  { *bDiff = true; e=0; goto fin; }\r
405         }\r
406         else {\r
407                 if ( f2 == NULL )  { *bDiff = true; e=0; goto fin; }\r
408         }\r
409 \r
410 \r
411         //=== Compare the contents in files\r
412         {\r
413                 enum { size = 0x100000 };\r
414                 size_t  size1, size2;\r
415 \r
416                 buf1 = (char*) malloc( size ); IF(buf1==NULL)goto err_fm;\r
417                 buf2 = (char*) malloc( size ); IF(buf2==NULL)goto err_fm;\r
418 \r
419                 b = true;\r
420                 for (;;) {\r
421                         size1 = fread( buf1, 1, size, f1 );\r
422                         size2 = fread( buf2, 1, size, f2 );\r
423 \r
424                         if ( size1 != size2 )  break;\r
425                         if ( memcmp( buf1, buf2, size1 ) != 0 )  break;\r
426                         if ( size1 != size )  { b = false; break; }\r
427                 }\r
428                 *bDiff = b;\r
429         }\r
430 \r
431         e=0;\r
432 fin:\r
433         if ( buf1 !=NULL)free(buf1);\r
434         if ( buf2 !=NULL)free(buf2);\r
435         if( f1 !=NULL){en=fclose(f1);IF(en)b=true;}\r
436         if( f2 !=NULL){en=fclose(f2);IF(en)b=true;}\r
437         return  e;\r
438 err_no: e = E_ERRNO; goto fin;\r
439 err_fm: e = E_FEW_MEMORY; goto fin;\r
440 }\r
441 \r
442  \r
443 /***********************************************************************\r
444   <<< [FileT_isSameText] >>> \r
445 ************************************************************************/\r
446 int  FileT_isSameText( TCHAR* Path1, TCHAR* Path2, int Format1, int Format2, bool* out_bSame )\r
447 {\r
448         int    e;\r
449         FILE*  f1 = NULL;\r
450         FILE*  f2 = NULL;\r
451         TCHAR  line1[4096];\r
452         TCHAR  line2[4096];\r
453 \r
454         ASSERT_R( Format1 == 0, goto err );\r
455         ASSERT_R( Format2 == 0, goto err );\r
456 \r
457         e= FileT_openForRead( &f1, Path1 ); IF(e)goto fin;\r
458         e= FileT_openForRead( &f2, Path2 ); IF(e)goto fin;\r
459         for (;;) {\r
460                 line1[0] = _T('\0');\r
461                 line2[0] = _T('\0');\r
462                 _fgetts( line1, _countof(line1), f1 );\r
463                 _fgetts( line2, _countof(line2), f2 );\r
464                 if ( _tcscmp( line1, line2 ) != 0 ) {\r
465                         *out_bSame = false;  e=0;  goto fin;\r
466                 }\r
467                 if ( feof( f1 ) ) {\r
468                         if ( feof( f2 ) )  break;\r
469                         else {\r
470                                 *out_bSame = false;  e=0;  goto fin;\r
471                         }\r
472                 }\r
473         }\r
474         *out_bSame = true;\r
475 \r
476         e=0;\r
477 fin:\r
478         e= FileT_closeAndNULL( &f1, e );\r
479         e= FileT_closeAndNULL( &f2, e );\r
480         return  e;\r
481 \r
482 err:  e = E_OTHERS;  goto fin;\r
483 }\r
484 \r
485 \r
486  \r
487 /***********************************************************************\r
488   <<< [FileT_isSameBinaryFile] >>> \r
489 ************************************************************************/\r
490 errnum_t  FileT_isSameBinaryFile( const TCHAR* PathA, const TCHAR* PathB, int Flags, bool* out_IsSame )\r
491 {\r
492         errnum_t  e;\r
493         HANDLE    file_a = INVALID_HANDLE_VALUE;\r
494         HANDLE    file_b = INVALID_HANDLE_VALUE;\r
495         HANDLE    mem_a  = INVALID_HANDLE_VALUE;\r
496         HANDLE    mem_b  = INVALID_HANDLE_VALUE;\r
497         void*     ptr_a = NULL;\r
498         void*     ptr_b = NULL;\r
499         size_t    size_a;\r
500         size_t    size_b;\r
501         BOOL      b;\r
502         bool      is_same = false;\r
503 \r
504         UNREFERENCED_VARIABLE( Flags );\r
505 \r
506 \r
507         // file_a,  file_b : open PathA,  PathB\r
508         file_a = CreateFile( PathA, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
509                 FILE_ATTRIBUTE_NORMAL, 0 );\r
510         IF( file_a == INVALID_HANDLE_VALUE ) goto err_gt;\r
511 \r
512         file_b = CreateFile( PathB, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
513                 FILE_ATTRIBUTE_NORMAL, 0 );\r
514         IF( file_b == INVALID_HANDLE_VALUE ) goto err_gt;\r
515 \r
516         // size_a,  size_b : size of file_a, file_b\r
517         size_a = GetFileSize( file_a, NULL );\r
518         size_b = GetFileSize( file_b, NULL );\r
519 \r
520         if ( size_a == size_b  &&  size_a == 0 ) {\r
521                 is_same = true;\r
522         }\r
523         else if ( size_a == size_b ) {\r
524 \r
525                 // mem_a,  mem_b : map to memory from file_a,  file_b\r
526                 mem_a = CreateFileMapping( file_a, NULL, PAGE_READONLY, 0, size_a, NULL );\r
527                 IF( mem_a == INVALID_HANDLE_VALUE ) goto err_gt;\r
528                 mem_b = CreateFileMapping( file_b, NULL, PAGE_READONLY, 0, size_b, NULL );\r
529                 IF( mem_b == INVALID_HANDLE_VALUE ) goto err_gt;\r
530 \r
531                 // ptr_a,  ptr_b : pointer of contents in file_a, file_b\r
532                 ptr_a = MapViewOfFile( mem_a, FILE_MAP_READ, 0, 0, 0 ); IF(ptr_a==NULL)goto err_gt;\r
533                 ptr_b = MapViewOfFile( mem_b, FILE_MAP_READ, 0, 0, 0 ); IF(ptr_b==NULL)goto err_gt;\r
534 \r
535                 // is_same : is same file_a and file_b\r
536                 if ( memcmp( ptr_a, ptr_b, size_a ) == 0 )  is_same = true;\r
537         }\r
538         e=0;\r
539 fin:\r
540         if ( ptr_a != NULL )                  { b= UnmapViewOfFile( ptr_a ); IF(!b&&!e) e=SaveWindowsLastError(); }\r
541         if ( mem_a  != INVALID_HANDLE_VALUE ) { b= CloseHandle( mem_a );     IF(!b&&!e) e=SaveWindowsLastError(); }\r
542         if ( file_a != INVALID_HANDLE_VALUE ) { b= CloseHandle( file_a );    IF(!b&&!e) e=SaveWindowsLastError(); }\r
543         if ( ptr_b != NULL )                  { b= UnmapViewOfFile( ptr_b ); IF(!b&&!e) e=SaveWindowsLastError(); }\r
544         if ( mem_b  != INVALID_HANDLE_VALUE ) { b= CloseHandle( mem_b );     IF(!b&&!e) e=SaveWindowsLastError(); }\r
545         if ( file_b != INVALID_HANDLE_VALUE ) { b= CloseHandle( file_b );    IF(!b&&!e) e=SaveWindowsLastError(); }\r
546         *out_IsSame = is_same;\r
547         return  e;\r
548 \r
549 err_gt:  e = SaveWindowsLastError();  goto fin;\r
550 }\r
551 \r
552 \r
553  \r
554 /***********************************************************************\r
555   <<< [FileT_callByNestFind] \83T\83u\83t\83H\83\8b\83_\82à\8aÜ\82ß\82Ä\8ae\83t\83@\83C\83\8b\82Ì\83p\83X\82ð\93n\82· >>> \r
556 ************************************************************************/\r
557 typedef struct {\r
558         /*--- inherit from FileT_CallByNestFindData */\r
559         void*     CallerArgument;\r
560         TCHAR*    FullPath;  // abstruct path\r
561         TCHAR*    StepPath;\r
562         TCHAR*    FileName;\r
563         DWORD     FileAttributes;\r
564 \r
565         /*---*/\r
566         BitField  Flags;\r
567         FuncType  CallbackFromNestFind;\r
568         TCHAR     FullPathMem[4096];\r
569 } FileT_CallByNestFindDataIn;\r
570 \r
571 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );\r
572 \r
573 \r
574 int  FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )\r
575 {\r
576         int  e;\r
577         FileT_CallByNestFindDataIn  data;\r
578 \r
579         {\r
580                 TCHAR*  p;\r
581 \r
582                 e= StrT_cpy( data.FullPathMem, sizeof(data.FullPathMem), Path ); IF(e)goto fin;\r
583 \r
584 \r
585                 /* FullPathMem \82Ì\8dÅ\8cã\82É \ \82ª\96³\82¢\82È\82ç\92Ç\89Á\82·\82é */\r
586                 p = StrT_chr( data.FullPathMem, _T('\0') );\r
587                 p--;\r
588                 if ( *p != _T('\\') ) {\r
589                         p++;\r
590                         IF( p >= data.FullPathMem + (sizeof(data.FullPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;\r
591                         *p = _T('\\');\r
592                 }\r
593 \r
594 \r
595                 /* data \82ð\8f\89\8aú\89»\82·\82é */\r
596                 data.CallerArgument = Argument;\r
597                 data.FullPath = data.FullPathMem;\r
598                 data.StepPath = p + 1;\r
599                 data.FileName = p + 1;\r
600                 data.Flags = Flags;\r
601                 data.CallbackFromNestFind = Callback;\r
602         }\r
603 \r
604         /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ\8aÖ\90\94\82Ö */\r
605         e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;\r
606 \r
607         e=0;\r
608 fin:\r
609         return  e;\r
610 err_fa: e= E_FEW_ARRAY; goto fin;\r
611 }\r
612 \r
613 \r
614 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )\r
615 {\r
616         int  e;\r
617         HANDLE  find;\r
618         WIN32_FIND_DATA  data;\r
619         TCHAR*  p;\r
620         int  done;\r
621 \r
622 \r
623         /* Path \82É\8ew\92è\82µ\82½\83t\83H\83\8b\83_\82É\91Î\82µ\82Ä\83R\81[\83\8b\83o\83b\83N\82·\82é */\r
624         if ( m->Flags & FileT_FolderBeforeFiles ) {\r
625                 *( m->FileName - 1 ) = _T('\0');  // m->FullPath \82Ì\8dÅ\8cã\82Ì \ \82ð\88ê\8e\9e\93I\82É\83J\83b\83g\r
626                 *( m->FileName ) = _T('\0');  // m->FileName, m->StepPath \82ð "" \82É\82·\82é\r
627                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
628 \r
629                 if ( m->StepPath[0] == _T('\0') ) {\r
630                         TCHAR*  step_path = m->StepPath;\r
631                         TCHAR*  fname     = m->FileName;\r
632 \r
633                         m->StepPath = _T(".");\r
634                         m->FileName = StrT_refFName( m->FullPath );\r
635                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
636                         m->StepPath = step_path;\r
637                         m->FileName = fname;\r
638                 }\r
639                 else if ( m->FileName[0] == _T('\0') ) {\r
640                         TCHAR*  fname = m->FileName;\r
641 \r
642                         m->FileName = StrT_refFName( m->FullPath );\r
643                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
644                         m->FileName = fname;\r
645                 }\r
646                 else {\r
647                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
648                 }\r
649                 *( m->FileName - 1 ) = _T('\\');\r
650         }\r
651 \r
652 \r
653         /* * \82ð\92Ç\89Á */\r
654         p = m->FileName;\r
655         IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
656         *p = _T('*');  *(p+1) = _T('\0');\r
657 \r
658 \r
659         /* \83t\83@\83C\83\8b\82©\83t\83H\83\8b\83_\82ð\97ñ\8b\93\82µ\82Ü\82· */\r
660         find = FindFirstFileEx( m->FullPathMem, FindExInfoStandard, &data,\r
661                 FindExSearchNameMatch, NULL, 0 );\r
662         done = ( find == INVALID_HANDLE_VALUE );\r
663 \r
664         while (!done)\r
665         {\r
666                 if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||\r
667                                  _tcscmp( data.cFileName, _T("..") ) == 0 ) {\r
668                         done = ! FindNextFile( find, &data );\r
669                         continue;\r
670                 }\r
671 \r
672                 StrT_cpy( m->FileName,\r
673                         sizeof(m->FullPathMem) - ( (char*)m->FileName - (char*)m->FullPathMem ),\r
674                         data.cFileName );\r
675                 m->FileAttributes = data.dwFileAttributes;\r
676 \r
677                 if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
678                         TCHAR*  prev_fname = m->FileName;\r
679 \r
680                         p = StrT_chr( m->FileName, _T('\0') );\r
681 \r
682                         IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
683                         *p = _T('\\');  *(p+1) = _T('\0');\r
684                         m->FileName = p + 1;\r
685 \r
686                         e= FileT_callByNestFind_sub( m ); IF(e)goto fin;  /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ */\r
687 \r
688                         m->FileName = prev_fname;\r
689                 }\r
690                 else {\r
691                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
692                 }\r
693 \r
694                 done = ! FindNextFile( find, &data );\r
695         }\r
696         FindClose( find );\r
697 \r
698 \r
699         /* Path \82É\8ew\92è\82µ\82½\83t\83H\83\8b\83_\82É\91Î\82µ\82Ä\83R\81[\83\8b\83o\83b\83N\82·\82é */\r
700         if ( m->Flags & FileT_FolderAfterFiles ) {\r
701                 TCHAR*  step_path = m->StepPath;\r
702                 TCHAR*  fname     = m->FileName;\r
703 \r
704                 *( m->FileName - 1 ) = _T('\0');\r
705                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
706                 if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->FullPath ) ) {\r
707                         m->StepPath = _T(".");\r
708                 }\r
709                 m->FileName = StrT_refFName( m->FullPath );\r
710 \r
711                 e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
712 \r
713                 m->StepPath = step_path;\r
714                 m->FileName = fname;\r
715         }\r
716 \r
717         e=0;\r
718 fin:\r
719         return  e;\r
720 err_fa: e= E_FEW_ARRAY; goto fin;\r
721 }\r
722 \r
723 \r
724  \r
725 /***********************************************************************\r
726   <<< [FileT_openForRead] >>> \r
727 ************************************************************************/\r
728 int  FileT_openForRead( FILE** out_pFile, const TCHAR* Path )\r
729 {\r
730         errno_t  en;\r
731 \r
732         assert( Locale_isInited() );\r
733 \r
734         #if DEBUGTOOLS_USES\r
735                 { int e= Debug_onOpen( Path ); if(e) return e; }\r
736         #endif\r
737 \r
738         en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );\r
739         if ( en == ENOENT ) {\r
740                 #ifndef UNDER_CE\r
741                 {\r
742                         TCHAR  cwd[512];\r
743 \r
744                         if ( _tgetcwd( cwd, _countof(cwd) ) == NULL ) {\r
745                                 cwd[0] = _T('\0');\r
746                         }\r
747                         Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\" current=\"%s\"/>"),\r
748                                 Path, cwd );\r
749                 }\r
750                 #else\r
751                         Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\"/>"), Path );\r
752                 #endif\r
753 \r
754                 return  E_PATH_NOT_FOUND;\r
755         }\r
756         if ( en == EACCES ) {\r
757                 Error4_printf( _T("access denied \"%s\"\n"), Path );\r
758                 return  E_ACCESS_DENIED;\r
759         }\r
760         IF(en)return  E_OTHERS;\r
761 \r
762         return  0;\r
763 }\r
764 \r
765 \r
766  \r
767 /***********************************************************************\r
768   <<< [FileT_close] >>> \r
769 ************************************************************************/\r
770 int  FileT_close( FILE* File, int e )\r
771 {\r
772         if ( File != NULL ) {\r
773                 int r = fclose( File );\r
774                 IF(r&&!e)e=E_ERRNO;\r
775         }\r
776         return e;\r
777 }\r
778 \r
779 \r
780 \r
781  \r
782 /***********************************************************************\r
783   <<< [FileT_closeAndNULL] >>> \r
784 ************************************************************************/\r
785 errnum_t  FileT_closeAndNULL( FILE** in_out_File, errnum_t e )\r
786 {\r
787         FILE*  file = *in_out_File;\r
788 \r
789         if ( file != NULL ) {\r
790                 int  r = fclose( file );\r
791                 IF ( r && e == 0 ) { e = E_ERRNO; }\r
792                 *in_out_File = NULL;\r
793         }\r
794 \r
795         return  e;\r
796 }\r
797 \r
798 \r
799 \r
800  \r
801 /***********************************************************************\r
802 * Class: ViewOfFileClass\r
803 ************************************************************************/\r
804 \r
805 /***********************************************************************\r
806 * Function: ViewOfFileClass_initConst\r
807 ************************************************************************/\r
808 void  ViewOfFileClass_initConst( ViewOfFileClass* self )\r
809 {\r
810         self->Data   = NULL;\r
811         self->File   = INVALID_HANDLE_VALUE;\r
812         self->Memory = INVALID_HANDLE_VALUE;\r
813 }\r
814 \r
815 \r
816  \r
817 /***********************************************************************\r
818 * Function: ViewOfFileClass_initializeFromBinaryFile\r
819 ************************************************************************/\r
820 errnum_t  ViewOfFileClass_initializeFromBinaryFile( ViewOfFileClass* self,\r
821         const TCHAR* Path )\r
822 {\r
823         errnum_t  e;\r
824 \r
825 \r
826         self->File = CreateFile( Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
827                 FILE_ATTRIBUTE_NORMAL, 0 );\r
828         IF( self->File == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }\r
829 \r
830         self->Size = GetFileSize( self->File, NULL );\r
831 \r
832         self->Memory = CreateFileMapping( self->File, NULL, PAGE_READONLY, 0, self->Size, NULL );\r
833                 IF( self->Memory == INVALID_HANDLE_VALUE ) { e=E_GET_LAST_ERROR; goto fin; }\r
834 \r
835         self->Data = MapViewOfFile( self->Memory, FILE_MAP_READ, 0, 0, 0 );\r
836                 IF ( self->Data == NULL ) { e=E_GET_LAST_ERROR; goto fin; }\r
837 \r
838 \r
839         e=0;\r
840 fin:\r
841         if ( e != 0 ) {\r
842                 e= ViewOfFileClass_finalize( self, e );\r
843         }\r
844         return  e;\r
845 }\r
846 \r
847 \r
848  \r
849 /***********************************************************************\r
850 * Function: ViewOfFileClass_finalize\r
851 ************************************************************************/\r
852 errnum_t  ViewOfFileClass_finalize( ViewOfFileClass* self,  errnum_t e )\r
853 {\r
854         BOOL  b;\r
855 \r
856         if ( self->Data != NULL )                 { b= UnmapViewOfFile( self->Data ); IF(!b&&!e) e=SaveWindowsLastError(); }\r
857         if ( self->Memory != INVALID_HANDLE_VALUE ) { b= CloseHandle( self->Memory ); IF(!b&&!e) e=SaveWindowsLastError(); }\r
858         if ( self->File   != INVALID_HANDLE_VALUE ) { b= CloseHandle( self->File );   IF(!b&&!e) e=SaveWindowsLastError(); }\r
859         self->Data   = NULL;\r
860         self->File   = INVALID_HANDLE_VALUE;\r
861         self->Memory = INVALID_HANDLE_VALUE;\r
862 \r
863         return  e;\r
864 }\r
865 \r
866 \r
867 /* Section: Global */\r
868  \r
869 /*=================================================================*/\r
870 /* <<< [Error4/Error4.c] >>> */ \r
871 /*=================================================================*/\r
872  \r
873 /***********************************************************************\r
874   <<< [Get_Error4_Variables] >>> \r
875 ************************************************************************/\r
876 static Error4_VariablesClass  gs;\r
877 #ifdef _DEBUG\r
878         extern Error4_VariablesClass*  g_Error4_Variables = &gs;\r
879 #endif\r
880 \r
881 Error4_VariablesClass*  Get_Error4_Variables()\r
882 {\r
883         return  &gs;\r
884 }\r
885 \r
886 \r
887  \r
888 /***********************************************************************\r
889   <<< (SetBreakErrorID) >>> \r
890 ************************************************************************/\r
891 \r
892 /*[DebugBreakR]*/\r
893 void  DebugBreakR()\r
894 {\r
895         printf( "\83u\83\8c\81[\83N\82µ\82Ü\82·\81B\82à\82µ\83f\83o\83b\83K\81[\82ª\90Ú\91±\82³\82ê\82Ä\82¢\82È\82¯\82ê\82Î\8b­\90§\8fI\97¹\82µ\82Ü\82·\81B\n" );\r
896         DebugBreak();\r
897                 // Visual Studio 2008 \82Å\82Í\81A\82±\82±\82Å [ \83f\83o\83b\83O > \83X\83e\83b\83\83A\83E\83g ] \82µ\82È\82¢\82Æ\r
898                 // \8cÄ\82Ñ\8fo\82µ\97\9a\97ð\82â\83E\83H\83b\83`\82Ì\93à\97e\82ª\90³\82µ\82­\82È\82è\82Ü\82¹\82ñ\81B\r
899 }\r
900 \r
901 \r
902 #if ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
903 \r
904 \r
905 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
906         dll_global_g_DebugBreakCount  ErrorClass  g_Error;  /* \8f\89\8aú\92l\82Í\82·\82×\82Ä\83[\83\8d */\r
907 #else\r
908         dll_global_g_DebugBreakCount  GlobalErrorClass  g_GlobalError;\r
909 \r
910         static errnum_t  ErrorClass_initializeIfNot_Sub( ErrorClass** out_Error );\r
911         static errnum_t  ErrorClass_initializeIfNot_Sub2(void);\r
912 #endif\r
913 \r
914 \r
915 #define  IF_  if  /* Error check for in "IF" macro */\r
916 \r
917 \r
918 /*[SetBreakErrorID]*/\r
919 void  SetBreakErrorID( int ErrorID )\r
920 {\r
921 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
922 \r
923         ErrorClass*  err = &g_Error;\r
924         bool         is_print;\r
925 \r
926         is_print = ( err->BreakErrorID != ErrorID );\r
927 \r
928         err->BreakErrorID = ErrorID;\r
929                 /* printf \82Ì\92\86\82Å\94­\90\82·\82é\83G\83\89\81[\82Å\8e~\82ß\82é\82½\82ß */\r
930 \r
931         if ( is_print )\r
932                 { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
933 \r
934 #else\r
935 \r
936         GlobalErrorClass*  err_global = &g_GlobalError;\r
937 \r
938         if ( err_global->BreakGlobalErrorID != ErrorID )\r
939                 { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
940         err_global->BreakGlobalErrorID = ErrorID;\r
941 \r
942 #endif\r
943 }\r
944 \r
945 \r
946 \r
947 bool  OnRaisingError_Sub( const char* FilePath, int LineNum )\r
948  // \96{\8aÖ\90\94\82Í\81AIF \83}\83N\83\8d\82Ì\92\86\82©\82ç\8cÄ\82Î\82ê\82Ü\82·\r
949  // \95Ô\82è\92l\82Í\81A\83u\83\8c\81[\83N\82·\82é\82©\82Ç\82¤\82©\r
950 {\r
951 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
952 \r
953         ErrorClass*  err = &g_Error;\r
954         bool  is_break;\r
955 \r
956         /* \83G\83\89\81[\8e\9e\82Ì\92\86\92f\8f\88\97\9d\81i\83W\83\83\83\93\83v\81j\82ð\82µ\82Ä\82¢\82é\82Æ\82«\81i\8d\82\91¬\83\8a\83^\81[\83\93\81j */\r
957         if ( err->IsError ) {\r
958                 return  false;\r
959         }\r
960 \r
961         /* \83G\83\89\81[\82ª\94­\90\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
962         err->ErrorID += 1;\r
963         err->IsError = true;\r
964         err->FilePath = FilePath;\r
965         err->LineNum  = LineNum;\r
966 \r
967         #if ERR2_ENABLE_ERROR_LOG\r
968                 printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
969                         err->ErrorID, (int) err );\r
970         #endif\r
971 \r
972         is_break = ( err->ErrorID == err->BreakErrorID );\r
973 \r
974         if ( is_break ) {\r
975                 printf( "Break in (%d) %s\n", LineNum, FilePath );\r
976         }\r
977         return  ( err->ErrorID == err->BreakErrorID );\r
978 \r
979 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
980 \r
981         errnum_t           e;\r
982         bool               is_break = false;\r
983         ErrorClass*        err;\r
984 \r
985         e= ErrorClass_initializeIfNot_Sub( &err ); IF_(e){goto fin;}\r
986 \r
987 \r
988         /* \83G\83\89\81[\8e\9e\82Ì\92\86\92f\8f\88\97\9d\81i\83W\83\83\83\93\83v\81j\82ð\82µ\82Ä\82¢\82é\82Æ\82«\81i\8d\82\91¬\83\8a\83^\81[\83\93\81j */\r
989         if ( err->IsError ) {\r
990                 return  false;\r
991         }\r
992 \r
993         /* \83G\83\89\81[\82ª\94­\90\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
994         else {\r
995                 GlobalErrorClass*  err_global = &g_GlobalError;\r
996 \r
997                 EnterCriticalSection( &err_global->CriticalSection );\r
998 \r
999 \r
1000                 err_global->ErrorThreadCount += 1;\r
1001                 err_global->RaisedGlobalErrorID += 1;\r
1002                 err->GlobalErrorID = err_global->RaisedGlobalErrorID;\r
1003 \r
1004                 err->ErrorID += 1;\r
1005                 err->IsError = true;\r
1006                 err->FilePath = FilePath;\r
1007                 err->LineNum  = LineNum;\r
1008 \r
1009                 is_break = ( err->ErrorID == err->BreakErrorID ) ||\r
1010                         ( err->GlobalErrorID == err_global->BreakGlobalErrorID );\r
1011 \r
1012 \r
1013                 /* \82±\82±\82æ\82è\88È\8d~\82Í\81AIF \83}\83N\83\8d\82È\82Ç\82ð\8cÄ\82Ñ\8fo\82µ\89Â\94\\81i\83\8a\83G\83\93\83g\83\89\83\93\83g\89Â\94\\81j */\r
1014                 /* \8fã\8bL\82Ì if ( err->IsError ) \82Å\81A\82·\82®\96ß\82é\82½\82ß */\r
1015 \r
1016 \r
1017                 #if ERR2_ENABLE_ERROR_LOG\r
1018                         printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
1019                                 err->GlobalErrorID, (int) err );\r
1020                 #endif\r
1021 \r
1022 \r
1023                 if ( err->ErrorID == 1 ) {\r
1024                         FinalizerClass_initConst( &err->Finalizer, err, ErrorClass_finalize );\r
1025                         e= AddThreadLocalFinalizer( &err->Finalizer );\r
1026                 }\r
1027                 else {\r
1028                         e = 0;\r
1029                 }\r
1030                 LeaveCriticalSection( &err_global->CriticalSection );\r
1031                 IF(e){goto fin;}\r
1032         }\r
1033 \r
1034         e=0;\r
1035 fin:\r
1036         if ( is_break ) {\r
1037                 printf( "Break in (%d) %s\n", LineNum, FilePath );\r
1038         }\r
1039         return  is_break;\r
1040 \r
1041 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1042 }\r
1043 \r
1044 \r
1045 //[ClearError]\r
1046 void  ClearError()\r
1047 {\r
1048 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
1049 \r
1050         ErrorClass*  err = &g_Error;\r
1051 \r
1052         #if ERR2_ENABLE_ERROR_LOG\r
1053         if ( err->IsError ) {\r
1054                 printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
1055                         err->ErrorID, (int) err );\r
1056         }\r
1057         #endif\r
1058 \r
1059         err->IsError = false;\r
1060 \r
1061 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1062 \r
1063         errnum_t     e;\r
1064         ErrorClass*  err;\r
1065 \r
1066         e= ErrorClass_initializeIfNot_Sub( &err );\r
1067         if ( e == 0 ) {\r
1068                 #if ERR2_ENABLE_ERROR_LOG\r
1069                 if ( err->IsError )\r
1070                         printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
1071                                 err->GlobalErrorID, (int) err );\r
1072                 #endif\r
1073 \r
1074                 if ( err->IsError ) {\r
1075                         GlobalErrorClass*  err_global = &g_GlobalError;\r
1076 \r
1077                         EnterCriticalSection( &err_global->CriticalSection );\r
1078                         err_global->ErrorThreadCount -= 1;\r
1079                         LeaveCriticalSection( &err_global->CriticalSection );\r
1080 \r
1081                         err->IsError = false;\r
1082                 }\r
1083         }\r
1084         else {\r
1085                 #if ERR2_ENABLE_ERROR_LOG\r
1086                         printf( "<ERROR_LOG msg=\"clear_miss\"/>\n" );\r
1087                 #endif\r
1088         }\r
1089 \r
1090 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1091 }\r
1092 \r
1093 \r
1094 //[IfErrThenBreak]\r
1095 void  IfErrThenBreak()\r
1096 {\r
1097 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
1098 \r
1099         ErrorClass*  err = &g_Error;\r
1100 \r
1101         if ( err->IsError  &&\r
1102                 ( err->ErrorID != err->BreakErrorID || err->BreakErrorID == 0 )\r
1103         ) {\r
1104                 printf( "in IfErrThenBreak\n" );\r
1105                 DebugBreakR();\r
1106 \r
1107                 // \83E\83H\83b\83`\82Å\81Aerr->ErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
1108                 // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\r
1109                 // \83G\83\89\81[\82ª\94­\90\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
1110                 // \90³\8fí\8fI\97¹\82µ\82Ä\82¢\82é\82Â\82à\82è\82È\82Ì\82É\82±\82±\82Å\83u\83\8c\81[\83N\82·\82é\82Æ\82«\82Í\81A\r
1111                 // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
1112                 #if ERR2_ENABLE_ERROR_LOG\r
1113                         printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
1114                                 err->ErrorID, err->BreakErrorID );\r
1115                 #endif\r
1116 \r
1117                 {\r
1118                         char  str[512];\r
1119                         sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
1120                                 err->FilePath, err->LineNum );\r
1121                         OutputDebugStringA( str );\r
1122                 }\r
1123         }\r
1124         ClearError();\r
1125 \r
1126 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1127 \r
1128         errnum_t           e;\r
1129         GlobalErrorClass*  err_global = &g_GlobalError;\r
1130         ErrorClass*        err;\r
1131 \r
1132         e= ErrorClass_initializeIfNot_Sub( &err );\r
1133         if ( e ) { DebugBreakR();  ClearError();  return; }  /* \93à\95\94\83G\83\89\81[ */\r
1134 \r
1135         if ( err_global->ErrorThreadCount != 0  &&\r
1136                 ( err->GlobalErrorID != err_global->BreakGlobalErrorID || err_global->BreakGlobalErrorID == 0 )\r
1137         ) {\r
1138                 printf( "in IfErrThenBreak\n" );\r
1139                 DebugBreakR();\r
1140 \r
1141                 // \83E\83H\83b\83`\82Å\81Aerr->GlobalErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
1142                 // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\r
1143                 // \83G\83\89\81[\82ª\94­\90\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
1144                 // \90³\8fí\8fI\97¹\82µ\82Ä\82¢\82é\82Â\82à\82è\82È\82Ì\82É\82±\82±\82Å\83u\83\8c\81[\83N\82·\82é\82Æ\82«\82Í\81A\r
1145                 // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
1146                 #if ERR2_ENABLE_ERROR_LOG\r
1147                         printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
1148                                 err->ErrorID, err->BreakErrorID );\r
1149                 #endif\r
1150 \r
1151                 {\r
1152                         char  str[512];\r
1153                         sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
1154                                 err->FilePath, err->LineNum );\r
1155                         OutputDebugStringA( str );\r
1156                 }\r
1157         }\r
1158         ClearError();\r
1159 \r
1160 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1161 }\r
1162 \r
1163 \r
1164 //[PushErr]\r
1165 void  PushErr( ErrStackAreaClass* ErrStackArea )\r
1166 {\r
1167 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
1168 \r
1169         ErrorClass*  err = &g_Error;\r
1170 \r
1171         ErrStackArea->ErrorID = err->ErrorID;\r
1172         ErrStackArea->IsError = err->IsError;\r
1173         err->IsError = false;\r
1174 \r
1175 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1176 \r
1177         errnum_t     e;\r
1178         ErrorClass*  err;\r
1179 \r
1180         e= ErrorClass_initializeIfNot_Sub( &err );\r
1181         if ( e == 0 ) {\r
1182                 ErrStackArea->ErrorID = err->ErrorID;\r
1183                 ErrStackArea->IsError = err->IsError;\r
1184                 err->IsError = false;\r
1185         }\r
1186 \r
1187 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1188 }\r
1189 \r
1190 //[PopErr]\r
1191 void  PopErr(  ErrStackAreaClass* ErrStackArea )\r
1192 {\r
1193 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
1194 \r
1195         ErrorClass*  err = &g_Error;\r
1196 \r
1197         if ( ErrStackArea->IsError )\r
1198                 { err->IsError = true; }\r
1199 \r
1200 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1201 \r
1202         errnum_t     e;\r
1203         ErrorClass*  err;\r
1204 \r
1205         e= ErrorClass_initializeIfNot_Sub( &err );\r
1206         if ( e == 0 ) {\r
1207                 if ( ErrStackArea->IsError )\r
1208                         { err->IsError = true; }\r
1209         }\r
1210 \r
1211 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
1212 }\r
1213 \r
1214 \r
1215  \r
1216 /*[SetBreakErrorID:2]*/\r
1217 #undef  IF_\r
1218 \r
1219 \r
1220 #endif // ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
1221 \r
1222 \r
1223 //[MergeError]\r
1224 errnum_t  MergeError( errnum_t e, errnum_t ee )\r
1225 {\r
1226         if ( e == 0 ) { return  ee; }\r
1227         else          { /* ErrorLog_add( ee ); */ return  e; }\r
1228 }\r
1229 \r
1230 \r
1231  \r
1232 /***********************************************************************\r
1233   <<< [g_Error4_String] >>> \r
1234 ************************************************************************/\r
1235 TCHAR  g_Error4_String[4096];\r
1236 \r
1237 \r
1238  \r
1239 /***********************************************************************\r
1240   <<< [Error4_printf] >>> \r
1241 ************************************************************************/\r
1242 void  Error4_printf( const TCHAR* format, ... )\r
1243 {\r
1244         va_list  va;\r
1245         va_start( va, format );\r
1246         vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );\r
1247         va_end( va );\r
1248 }\r
1249 \r
1250 \r
1251  \r
1252 /***********************************************************************\r
1253   <<< [Error4_getErrStr] >>> \r
1254 ************************************************************************/\r
1255 void  Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )\r
1256 {\r
1257         switch ( ErrNum ) {\r
1258 \r
1259                 case  0:\r
1260                         stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );\r
1261                         break;\r
1262 \r
1263                 case  E_FEW_ARRAY:\r
1264                         stprintf_r( out_ErrStr, ErrStrSize,\r
1265                                 _T("<ERROR msg=\"\83v\83\8d\83O\83\89\83\80\93à\95\94\82Ì\94z\97ñ\83\81\83\82\83\8a\81[\82ª\95s\91«\82µ\82Ü\82µ\82½\81B\"/>") );\r
1266                         break;\r
1267 \r
1268                 case  E_FEW_MEMORY:\r
1269                         stprintf_r( out_ErrStr, ErrStrSize,\r
1270                                 _T("<ERROR msg=\"\83q\81[\83v\81E\83\81\83\82\83\8a\81[\82ª\95s\91«\82µ\82Ü\82µ\82½\81B\"/>") );\r
1271                         break;\r
1272 \r
1273                 #ifndef  __linux__\r
1274                 case  E_GET_LAST_ERROR: {\r
1275                         DWORD   err_win;\r
1276                         TCHAR*  str_pointer;\r
1277 \r
1278                         err_win = gs.WindowsLastError;\r
1279                         if ( err_win == 0 ) { err_win = GetLastError(); }\r
1280 \r
1281                         stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,\r
1282                                 _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );\r
1283                         FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,\r
1284                                 NULL, err_win, LANG_USER_DEFAULT,\r
1285                                 str_pointer,  (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );\r
1286                         str_pointer = StrT_chr( str_pointer, _T('\0') );\r
1287                         if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )\r
1288                                 str_pointer -= 2;\r
1289                         stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );\r
1290                         break;\r
1291                 }\r
1292                 #endif\r
1293 \r
1294                 default:\r
1295                         if ( g_Error4_String[0] != '\0' )\r
1296                                 stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );\r
1297                         else\r
1298                                 stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );\r
1299                         break;\r
1300         }\r
1301 }\r
1302 \r
1303 \r
1304  \r
1305 /***********************************************************************\r
1306   <<< [SaveWindowsLastError] >>> \r
1307 ************************************************************************/\r
1308 errnum_t  SaveWindowsLastError()\r
1309 {\r
1310         gs.WindowsLastError = GetLastError();\r
1311         return  E_GET_LAST_ERROR;\r
1312 }\r
1313 \r
1314 \r
1315  \r
1316 /***********************************************************************\r
1317   <<< [Error4_showToStdErr] >>> \r
1318 ************************************************************************/\r
1319 void  Error4_showToStdErr( int err_num )\r
1320 {\r
1321         Error4_showToStdIO( stderr, err_num );\r
1322 }\r
1323 \r
1324 \r
1325  \r
1326 /***********************************************************************\r
1327   <<< [Error4_showToStdIO] >>> \r
1328 ************************************************************************/\r
1329 void  Error4_showToStdIO( FILE* out, int err_num )\r
1330 {\r
1331         TCHAR  msg[1024];\r
1332         #if _UNICODE\r
1333                 char  msg2[1024];\r
1334         #endif\r
1335 \r
1336         if ( err_num != 0 ) {\r
1337                 Error4_getErrStr( err_num, msg, sizeof(msg) );\r
1338                 #if _UNICODE\r
1339                         setlocale( LC_ALL, ".OCP" );\r
1340                         sprintf_s( msg2, sizeof(msg2), "%S", msg );\r
1341                         fprintf( out, "%s\n", msg2 );  // _ftprintf_s \82Å\82Í\93ú\96{\8cê\82ª\8fo\82Ü\82¹\82ñ\r
1342                 #else\r
1343                         fprintf( out, "%s\n", msg );\r
1344                 #endif\r
1345 \r
1346                 #if ERR2_ENABLE_ERROR_BREAK\r
1347                         fprintf( out, "\81i\8aJ\94­\8eÒ\82Ö\81j\83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( %d ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\n",\r
1348                                 g_Err2.ErrID );\r
1349                 #else\r
1350 #if 0\r
1351                         if ( err_num == E_FEW_MEMORY  ||  gs.WindowsLastError == ERROR_NOT_ENOUGH_MEMORY ) {\r
1352                                 /* Not show the message for developper */\r
1353                         }\r
1354                         else {\r
1355                                 fprintf( out, "\81i\8aJ\94­\8eÒ\82Ö\81jERR2_ENABLE_ERROR_BREAK \82ð\92è\8b`\82µ\82Ä\8dÄ\83R\83\93\83p\83C\83\8b\82µ\82Ä\82­\82¾\82³\82¢\81B\n" );\r
1356                         }\r
1357 #endif\r
1358                 #endif\r
1359         }\r
1360         IfErrThenBreak();\r
1361 }\r
1362 \r
1363 \r
1364  \r
1365 /***********************************************************************\r
1366   <<< [Error4_raiseErrno] >>> \r
1367 ************************************************************************/\r
1368 #include <errno.h>\r
1369 \r
1370 int  Error4_raiseErrno()\r
1371 {\r
1372         int   e, e2;\r
1373         TCHAR  msg[256];\r
1374 \r
1375         e2 = _get_errno( &e );\r
1376         if ( e2 != 0 )  { Error4_printf( _T("ERROR in _get_errno") );  return  E_UNKNOWN; }\r
1377         e2 = _tcserror_s( msg, sizeof(msg)/sizeof(TCHAR), e );\r
1378         if ( e2 != 0 )  { Error4_printf( _T("ERROR in strerror_s") );  return  E_UNKNOWN; }\r
1379 \r
1380         Error4_printf( _T("ERROR (%d) %s\n"), e, msg );\r
1381         return  E_ERRNO;\r
1382 }\r
1383 \r
1384 \r
1385  \r
1386 /*=================================================================*/\r
1387 /* <<< [StrT/StrT.c] >>> */ \r
1388 /*=================================================================*/\r
1389  \r
1390 /***********************************************************************\r
1391   <<< [StrT_cpy] >>> \r
1392 - _tcscpy is raising exception, if E_FEW_ARRAY\r
1393 ************************************************************************/\r
1394 errnum_t  StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )\r
1395 {\r
1396         size_t  size;\r
1397 \r
1398         size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);\r
1399         if ( size <= DstSize ) {\r
1400                 memcpy( Dst, Src, size );\r
1401                 return  0;\r
1402         }\r
1403         else {\r
1404                 memcpy( Dst, Src, DstSize - sizeof(TCHAR) );\r
1405                 *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');\r
1406                 return  E_FEW_ARRAY;\r
1407         }\r
1408 }\r
1409 \r
1410  \r
1411 /***********************************************************************\r
1412   <<< [StrT_chr] >>> \r
1413 ************************************************************************/\r
1414 TCHAR*  StrT_chr( const TCHAR* String, TCHAR Key )\r
1415 {\r
1416         const TCHAR*  return_value = _tcschr( String, Key );\r
1417 \r
1418         if ( return_value == NULL  &&  Key == _T('\0') ) {\r
1419                 return_value = String + _tcslen( String );\r
1420         }\r
1421 \r
1422         return  (TCHAR*) return_value;\r
1423 }\r
1424 \r
1425  \r
1426 /***********************************************************************\r
1427   <<< [StrT_chrNext] >>> \r
1428 ************************************************************************/\r
1429 TCHAR*  StrT_chrNext( const TCHAR* in_Start, TCHAR in_KeyCharactor )\r
1430 {\r
1431         const TCHAR*  p = _tcschr( in_Start, in_KeyCharactor );\r
1432 \r
1433         if ( p != NULL )\r
1434                 { p += 1; }\r
1435 \r
1436         return  (TCHAR*) p;\r
1437 }\r
1438 \r
1439  \r
1440 /***********************************************************************\r
1441   <<< [MallocAndCopyString] >>> \r
1442 ************************************************************************/\r
1443 errnum_t  MallocAndCopyString( const TCHAR** out_NewString, const TCHAR* SourceString )\r
1444 {\r
1445         TCHAR*  str;\r
1446         size_t  size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);\r
1447 \r
1448         ASSERT_D( *out_NewString == NULL, __noop() );\r
1449 \r
1450         str = (TCHAR*) malloc( size );\r
1451         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
1452 \r
1453         memcpy( str, SourceString, size );\r
1454 \r
1455         *out_NewString = str;\r
1456         return  0;\r
1457 }\r
1458 \r
1459 \r
1460  \r
1461 /***********************************************************************\r
1462   <<< [MallocAndCopyString_char] >>> \r
1463 ************************************************************************/\r
1464 #ifdef _UNICODE\r
1465 errnum_t  MallocAndCopyString_char( const TCHAR** out_NewString, const char* SourceString )\r
1466 {\r
1467         TCHAR*  str;\r
1468         size_t  size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);\r
1469         int     r;\r
1470 \r
1471         str = (TCHAR*) malloc( size );\r
1472         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
1473 \r
1474         r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );\r
1475         IF ( r == 0 ) {\r
1476                 free( str );\r
1477                 return  E_GET_LAST_ERROR;\r
1478         }\r
1479         *out_NewString = str;\r
1480         return  0;\r
1481 }\r
1482 #endif\r
1483 \r
1484 \r
1485  \r
1486 /***********************************************************************\r
1487   <<< [MallocAndCopyStringByLength] >>> \r
1488 ************************************************************************/\r
1489 errnum_t  MallocAndCopyStringByLength( const TCHAR** out_NewString, const TCHAR* SourceString,\r
1490         unsigned CountOfCharacter )\r
1491 {\r
1492         TCHAR*  str;\r
1493         size_t  size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);\r
1494 \r
1495         ASSERT_D( *out_NewString == NULL, __noop() );\r
1496         ASSERT_D( CountOfCharacter < 0x7FFFFFFF, __noop() );\r
1497 \r
1498         str = (TCHAR*) malloc( size );\r
1499         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
1500 \r
1501         memcpy( str, SourceString, size - sizeof(TCHAR) );\r
1502         str[ CountOfCharacter ] = _T('\0');\r
1503 \r
1504         *out_NewString = str;\r
1505         return  0;\r
1506 }\r
1507 \r
1508 \r
1509  \r
1510 /***********************************************************************\r
1511   <<< [StrT_chrs] >>> \r
1512 ************************************************************************/\r
1513 TCHAR*  StrT_chrs( const TCHAR* s, const TCHAR* keys )\r
1514 {\r
1515         if ( *keys == _T('\0') )  return  NULL;\r
1516 \r
1517         for ( ; *s != _T('\0'); s++ ) {\r
1518                 if ( _tcschr( keys, *s ) != NULL )\r
1519                         return  (TCHAR*) s;\r
1520         }\r
1521         return  NULL;\r
1522 }\r
1523 \r
1524 \r
1525  \r
1526 /***********************************************************************\r
1527   <<< [StrT_rstr] >>> \r
1528 ************************************************************************/\r
1529 TCHAR*  StrT_rstr( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keyword,\r
1530         void* NullConfig )\r
1531 {\r
1532         const TCHAR*  p;\r
1533         int           keyword_length = _tcslen( Keyword );\r
1534         TCHAR         keyword_first = Keyword[0];\r
1535 \r
1536         UNREFERENCED_VARIABLE( NullConfig );\r
1537 \r
1538         p = SearchStart;\r
1539         while ( p >= String ) {\r
1540                 if ( *p == keyword_first ) {\r
1541                         if ( _tcsncmp( p, Keyword, keyword_length ) == 0 ) {\r
1542                                 return  (TCHAR*) p;\r
1543                         }\r
1544                 }\r
1545                 p -= 1;\r
1546         }\r
1547 \r
1548         return  NULL;\r
1549 }\r
1550 \r
1551 \r
1552  \r
1553 /***********************************************************************\r
1554   <<< [StrT_skip] >>> \r
1555 ************************************************************************/\r
1556 TCHAR*  StrT_skip( const TCHAR* String, const TCHAR* Keys )\r
1557 {\r
1558         if ( *Keys == _T('\0') ) { return  (TCHAR*) String; }\r
1559 \r
1560         for ( ; *String != _T('\0'); String += 1 ) {\r
1561                 if ( _tcschr( Keys, *String ) == NULL )\r
1562                         break;\r
1563         }\r
1564         return  (TCHAR*) String;\r
1565 }\r
1566 \r
1567 \r
1568  \r
1569 /***********************************************************************\r
1570   <<< [StrT_rskip] >>> \r
1571 ************************************************************************/\r
1572 TCHAR*  StrT_rskip( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keys,\r
1573         void* NullConfig )\r
1574 {\r
1575         const TCHAR*  pointer;\r
1576 \r
1577         UNREFERENCED_VARIABLE( NullConfig );\r
1578 \r
1579         if ( *Keys == _T('\0') ) { return  (TCHAR*) SearchStart; }\r
1580 \r
1581         for ( pointer = SearchStart;  pointer >= String;  pointer -= 1 ) {\r
1582                 if ( _tcschr( Keys, *pointer ) == NULL )\r
1583                         { return  (TCHAR*) pointer; }\r
1584         }\r
1585         return  NULL;\r
1586 }\r
1587 \r
1588 \r
1589  \r
1590 /***********************************************************************\r
1591   <<< [StrT_isCIdentifier] >>> \r
1592 ************************************************************************/\r
1593 bool  StrT_isCIdentifier( TCHAR Character )\r
1594 {\r
1595         const TCHAR  c = Character;\r
1596 \r
1597         return  (\r
1598                 ( c >= _T('A')  &&  c <= _T('Z') ) ||\r
1599                 ( c >= _T('a')  &&  c <= _T('z') ) ||\r
1600                 ( c >= _T('0')  &&  c <= _T('9') ) ||\r
1601                 c == _T('_') );\r
1602 }\r
1603 \r
1604 \r
1605  \r
1606 /***********************************************************************\r
1607   <<< [StrT_searchOverOfCIdentifier] >>> \r
1608 ************************************************************************/\r
1609 TCHAR*  StrT_searchOverOfCIdentifier( const TCHAR* Text )\r
1610 {\r
1611         const TCHAR*  p;\r
1612 \r
1613         for ( p = Text;\r
1614                 StrT_isCIdentifier( *p );\r
1615                 p += 1 )\r
1616         {\r
1617         }\r
1618         return  (TCHAR*) p;\r
1619 }\r
1620 \r
1621 \r
1622  \r
1623 /***********************************************************************\r
1624   <<< [StrT_searchOverOfIdiom] >>> \r
1625 ************************************************************************/\r
1626 TCHAR*  StrT_searchOverOfIdiom( const TCHAR* Text )\r
1627 {\r
1628         const TCHAR*  p;\r
1629 \r
1630         p = Text;\r
1631         for ( p = Text;\r
1632                 StrT_isCIdentifier( *p )  ||  *p == _T(' ');\r
1633                 p += 1 )\r
1634         {\r
1635         }\r
1636 \r
1637         for ( p -= 1;\r
1638                 *p == _T(' ')  &&  p >= Text;\r
1639                 p -= 1 )\r
1640         {\r
1641         }\r
1642 \r
1643         return  (TCHAR*) p + 1;\r
1644 }\r
1645 \r
1646 \r
1647  \r
1648 /***********************************************************************\r
1649   <<< [StrT_cmp_part] >>> \r
1650 ************************************************************************/\r
1651 int  StrT_cmp_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
1652         const TCHAR* in_StringB )\r
1653 {\r
1654         const TCHAR*  a;\r
1655         const TCHAR*  b;\r
1656         TCHAR  aa;\r
1657         TCHAR  bb;\r
1658 \r
1659         a = in_StringA_Start;\r
1660         b = in_StringB;\r
1661 \r
1662         for (;;) {\r
1663                 if ( a >= in_StringA_Over ) {\r
1664                         bb = *b;\r
1665                         if ( bb == _T('\0') )\r
1666                                 { return  0; }\r
1667                         else\r
1668                                 { return  -bb; }\r
1669                 }\r
1670 \r
1671                 aa = *a;\r
1672                 bb = *b;\r
1673 \r
1674                 if ( bb == _T('\0') )\r
1675                         { return  aa; }\r
1676 \r
1677                 if ( aa != bb )\r
1678                         { return  aa - bb; }\r
1679 \r
1680                 a += 1;\r
1681                 b += 1;\r
1682         }\r
1683 }\r
1684 \r
1685 \r
1686  \r
1687 /***********************************************************************\r
1688   <<< [StrT_cmp_i_part] >>> \r
1689 ************************************************************************/\r
1690 int  StrT_cmp_i_part( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
1691         const TCHAR* in_StringB )\r
1692 {\r
1693         const TCHAR*  a;\r
1694         const TCHAR*  b;\r
1695         TCHAR  aa;\r
1696         TCHAR  bb;\r
1697 \r
1698         a = in_StringA_Start;\r
1699         b = in_StringB;\r
1700 \r
1701         for (;;) {\r
1702                 if ( a >= in_StringA_Over ) {\r
1703                         bb = *b;\r
1704                         if ( bb == _T('\0') )\r
1705                                 { return  0; }\r
1706                         else\r
1707                                 { return  -bb; }\r
1708                 }\r
1709 \r
1710                 aa = *a;\r
1711                 bb = *b;\r
1712 \r
1713                 if ( bb == _T('\0') )\r
1714                         { return  aa; }\r
1715 \r
1716                 if ( aa != bb ) {\r
1717                         if ( _totlower( aa ) != _totlower( bb ) )\r
1718                                 { return  aa - bb; }\r
1719                 }\r
1720 \r
1721                 a += 1;\r
1722                 b += 1;\r
1723         }\r
1724 }\r
1725 \r
1726 \r
1727  \r
1728 /***********************************************************************\r
1729   <<< [StrT_cmp_part2] >>> \r
1730 ************************************************************************/\r
1731 int  StrT_cmp_part2( const TCHAR* in_StringA_Start, const TCHAR* in_StringA_Over,\r
1732         const TCHAR* in_StringB_Start, const TCHAR* in_StringB_Over )\r
1733 {\r
1734         int  length_A = in_StringA_Over - in_StringA_Start;\r
1735         int  length_B = in_StringB_Over - in_StringB_Start;\r
1736 \r
1737         if ( length_A != length_B ) {\r
1738                 return  length_A - length_B;\r
1739         }\r
1740         else {\r
1741                 return  _tcsncmp( in_StringA_Start, in_StringB_Start, length_A );\r
1742         }\r
1743 }\r
1744 \r
1745 \r
1746  \r
1747 /***********************************************************************\r
1748   <<< [StrT_refFName] >>> \r
1749 ************************************************************************/\r
1750 TCHAR*  StrT_refFName( const TCHAR* s )\r
1751 {\r
1752         const TCHAR*  p;\r
1753         TCHAR  c;\r
1754 \r
1755         p = StrT_chr( s, _T('\0') );\r
1756 \r
1757         if ( p == s )  return  (TCHAR*) s;\r
1758 \r
1759         for ( p--; p>s; p-- ) {\r
1760                 c = *p;\r
1761                 if ( c == _T('\\') || c == _T('/') )  return  (TCHAR*) p+1;\r
1762         }\r
1763         if ( *p == _T('\\') || *p == _T('/') )  return  (TCHAR*) p+1;\r
1764 \r
1765         return  (TCHAR*) s;\r
1766 }\r
1767  \r
1768 /***********************************************************************\r
1769   <<< [StrT_refExt] >>> \r
1770 ************************************************************************/\r
1771 TCHAR*  StrT_refExt( const TCHAR* s )\r
1772 {\r
1773         const TCHAR*  p;\r
1774 \r
1775         p = StrT_chr( s, _T('\0') );\r
1776 \r
1777         if ( p == s )  { return  (TCHAR*) s; }\r
1778 \r
1779         for ( p--; p>s; p-- ) {\r
1780                 if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
1781                 if ( *p == _T('/') || *p == _T('\\') )\r
1782                         { return  (TCHAR*) StrT_chr( p, _T('\0') ); }\r
1783         }\r
1784         if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
1785 \r
1786         return  (TCHAR*) StrT_chr( s, _T('\0') );\r
1787 }\r
1788 \r
1789 \r
1790  \r
1791 /***********************************************************************\r
1792 * Function: StrT_cutFragmentInPath\r
1793 ************************************************************************/\r
1794 void  StrT_cutFragmentInPath( TCHAR* in_out_Path )\r
1795 {\r
1796         TCHAR*  p;\r
1797 \r
1798         p = _tcschr( in_out_Path, _T('#') );\r
1799         if ( p != NULL ) {\r
1800                 *p = _T('\0');\r
1801         }\r
1802 }\r
1803 \r
1804 \r
1805  \r
1806 /***********************************************************************\r
1807   <<< [StrT_replace1] >>> \r
1808 ************************************************************************/\r
1809 errnum_t  StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,\r
1810         unsigned Opt )\r
1811 {\r
1812         TCHAR*  p;\r
1813 \r
1814         UNREFERENCED_VARIABLE( Opt );\r
1815 \r
1816         IF ( FromCharacter == _T('\0') )  { return  E_OTHERS; }\r
1817 \r
1818         p = in_out_String;\r
1819         for (;;) {\r
1820                 p = _tcschr( p, FromCharacter );\r
1821                 if ( p == NULL )  { break; }\r
1822                 *p = ToCharacter;\r
1823                 p += 1;\r
1824         }\r
1825 \r
1826         return  0;\r
1827 }\r
1828 \r
1829 \r
1830  \r
1831 /***********************************************************************\r
1832   <<< [StrT_trim] >>> \r
1833 ************************************************************************/\r
1834 errnum_t  StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )\r
1835 {\r
1836         const TCHAR*  p1;\r
1837         const TCHAR*  p2;\r
1838         TCHAR   c;\r
1839 \r
1840         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
1841         for ( p2 = StrT_chr( p1, _T('\0') ) - 1;  p2 >= p1;  p2-- ) {\r
1842                 c = *p2;\r
1843                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
1844                         break;\r
1845         }\r
1846         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
1847 }\r
1848 \r
1849 \r
1850  \r
1851 /***********************************************************************\r
1852   <<< [StrT_cutPart] >>> \r
1853 ************************************************************************/\r
1854 errnum_t  StrT_cutPart( TCHAR*  in_out_String,  TCHAR*  in_StartOfCut,  TCHAR*  in_OverOfCut )\r
1855 {\r
1856         errnum_t  e;\r
1857         TCHAR*    over_of_cut = StrT_chr( in_StartOfCut, _T('\0') );\r
1858 \r
1859 #ifndef  NDEBUG\r
1860         TCHAR*    over_of_string = StrT_chr( in_out_String, _T('\0') );\r
1861 \r
1862         ASSERT_D( over_of_cut == over_of_string,   e=E_OTHERS; goto fin );\r
1863         ASSERT_D( in_StartOfCut >= in_out_String,   e=E_OTHERS; goto fin );\r
1864         ASSERT_D( in_StartOfCut <= over_of_string,  e=E_OTHERS; goto fin );\r
1865         ASSERT_D( in_OverOfCut  >= in_out_String,   e=E_OTHERS; goto fin );\r
1866         ASSERT_D( in_OverOfCut  <= over_of_string,  e=E_OTHERS; goto fin );\r
1867         ASSERT_D( in_StartOfCut <= in_OverOfCut,    e=E_OTHERS; goto fin );\r
1868 #endif\r
1869         UNREFERENCED_VARIABLE( in_out_String );\r
1870 \r
1871         memmove( in_StartOfCut,  in_OverOfCut,\r
1872                 PointerType_diff( over_of_cut + 1,  in_OverOfCut ) );\r
1873 \r
1874         e=0;\r
1875 #ifndef  NDEBUG\r
1876 fin:\r
1877 #endif\r
1878         return  e;\r
1879 }\r
1880 \r
1881 \r
1882  \r
1883 /***********************************************************************\r
1884   <<< [StrT_cutLastOf] >>> \r
1885 ************************************************************************/\r
1886 errnum_t  StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )\r
1887 {\r
1888         TCHAR*  last = StrT_chr( in_out_Str, _T('\0') );\r
1889 \r
1890         if ( last > in_out_Str ) {\r
1891                 if ( *( last - 1 ) == Charactor )\r
1892                         { *( last - 1 ) = _T('\0'); }\r
1893         }\r
1894         return  0;\r
1895 }\r
1896 \r
1897 \r
1898  \r
1899 /***********************************************************************\r
1900   <<< [StrT_cutLineComment] >>> \r
1901 ************************************************************************/\r
1902 errnum_t  StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )\r
1903 {\r
1904         const TCHAR*  p1;\r
1905         const TCHAR*  p2;\r
1906         TCHAR   c;\r
1907 \r
1908         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
1909 \r
1910         p2 = _tcsstr( p1, CommentSign );\r
1911         if ( p2 == NULL )  p2 = StrT_chr( p1, _T('\0') );\r
1912 \r
1913         for ( p2 = p2 - 1;  p2 >= p1;  p2-- ) {\r
1914                 c = *p2;\r
1915                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
1916                         break;\r
1917         }\r
1918         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
1919 }\r
1920 \r
1921 \r
1922  \r
1923 /***********************************************************************\r
1924   <<< [StrT_insert] >>> \r
1925 ************************************************************************/\r
1926 errnum_t  StrT_insert( TCHAR*  in_out_WholeString,  size_t  in_MaxSize_of_WholeString,\r
1927         TCHAR*  in_out_Target_in_WholeString,  TCHAR**  out_NextTarget_in_WholeString,\r
1928         const TCHAR*  in_InsertString )\r
1929 {\r
1930         errnum_t  e;\r
1931         TCHAR*    over_of_whole_string = StrT_chr( in_out_WholeString, _T('\0') );\r
1932         size_t    insert_length = _tcslen( in_InsertString );\r
1933 \r
1934         ASSERT_D( in_out_Target_in_WholeString >= in_out_WholeString,   e=E_OTHERS; goto fin );\r
1935         ASSERT_D( in_out_Target_in_WholeString <= over_of_whole_string, e=E_OTHERS; goto fin );\r
1936 \r
1937         ASSERT_R( PointerType_diff( over_of_whole_string + 1,  in_out_WholeString ) + ( insert_length * sizeof(TCHAR) )\r
1938                 <= in_MaxSize_of_WholeString,  e=E_FEW_ARRAY; goto fin );\r
1939 \r
1940         memmove( in_out_Target_in_WholeString + insert_length,  in_out_Target_in_WholeString,\r
1941                 PointerType_diff( over_of_whole_string + 1,  in_out_Target_in_WholeString ) );\r
1942 \r
1943         memcpy( in_out_Target_in_WholeString,  in_InsertString,  insert_length * sizeof(TCHAR) );\r
1944 \r
1945         if ( out_NextTarget_in_WholeString != NULL ) {\r
1946                 *out_NextTarget_in_WholeString = in_out_Target_in_WholeString + insert_length;\r
1947         }\r
1948 \r
1949         e=0;\r
1950 fin:\r
1951         return  e;\r
1952 }\r
1953 \r
1954 \r
1955  \r
1956 /***********************************************************************\r
1957   <<< [StrHS_insert] >>> \r
1958 ************************************************************************/\r
1959 errnum_t  StrHS_insert( TCHAR**  in_out_WholeString,\r
1960         int  in_TargetIndexInWholeString,  int*  out_NextWholeInWholeString,\r
1961         const TCHAR*  in_InsertString )\r
1962 {\r
1963         errnum_t  e;\r
1964         TCHAR*    string = *in_out_WholeString;\r
1965         size_t    target_length = _tcslen( string );\r
1966         size_t    insert_length = _tcslen( in_InsertString );\r
1967         size_t    max_size = _msize( string ) / sizeof( TCHAR );\r
1968         size_t    new_max_size = target_length + insert_length + 1;\r
1969         TCHAR*    next_target;\r
1970 \r
1971 \r
1972         if ( max_size < new_max_size ) {\r
1973                 TCHAR*  new_string = (TCHAR*) realloc( string,  new_max_size * sizeof( TCHAR ) );\r
1974 \r
1975                 IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
1976                 max_size = new_max_size;\r
1977                 string = new_string;\r
1978         }\r
1979 \r
1980         e= StrT_insert( string,  max_size * sizeof( TCHAR ),\r
1981                 string + in_TargetIndexInWholeString,  &next_target,\r
1982                 in_InsertString ); IF(e){goto fin;}\r
1983 \r
1984         if ( out_NextWholeInWholeString != NULL ) {\r
1985                 *out_NextWholeInWholeString = next_target - string;\r
1986         }\r
1987 \r
1988         e=0;\r
1989 fin:\r
1990         *in_out_WholeString = string;\r
1991         return  e;\r
1992 }\r
1993 \r
1994 \r
1995  \r
1996 /***********************************************************************\r
1997   <<< [StrHS_printfPartV] >>> \r
1998 ************************************************************************/\r
1999 errnum_t  StrHS_printfPartV( TCHAR**  in_out_String,\r
2000         int  in_IndexInString,  int*  out_NextIndexInString,\r
2001         const TCHAR*  in_Format,  va_list  in_VaList )\r
2002 {\r
2003         enum { first_max_size = 40 };\r
2004         enum { size_times = 4 };\r
2005 \r
2006         errnum_t  e;\r
2007         size_t    max_size;\r
2008         TCHAR*    string = *in_out_String;\r
2009 \r
2010 \r
2011         if ( string == NULL ) {\r
2012                 max_size = 0;\r
2013 \r
2014                 ASSERT_R( in_IndexInString == 0,  e=E_OTHERS; goto fin );\r
2015         }\r
2016         else {\r
2017                 max_size = _msize( string ) / sizeof( TCHAR );\r
2018 \r
2019                 ASSERT_R( in_IndexInString >= 0  &&  (size_t) in_IndexInString < max_size,\r
2020                         e=E_OTHERS; goto fin );\r
2021                 ASSERT_D( (size_t) in_IndexInString <= _tcslen( string ), __noop() );\r
2022         }\r
2023 \r
2024 \r
2025         if ( string == NULL ) {\r
2026                 string = (TCHAR*) malloc( first_max_size * sizeof( TCHAR ) );\r
2027                 max_size = first_max_size;\r
2028         }\r
2029 \r
2030 \r
2031         for (;;) {\r
2032 \r
2033                 #if _MSC_VER\r
2034                         #pragma warning(push)\r
2035                         #pragma warning(disable: 4996)\r
2036                 #endif\r
2037 \r
2038                 #ifdef  _UNICODE\r
2039                         int  r = _vsnwprintf( string + in_IndexInString,  max_size - in_IndexInString,\r
2040                                 in_Format,  in_VaList );\r
2041                 #else\r
2042                         int  r = _vsnprintf( string + in_IndexInString,  max_size - in_IndexInString,\r
2043                                 in_Format,  in_VaList );\r
2044                 #endif\r
2045 \r
2046                 #if _MSC_VER\r
2047                         #pragma warning(pop)\r
2048                 #endif\r
2049 \r
2050                 if ( r >= 0 ) {\r
2051                         if ( out_NextIndexInString != NULL ) {\r
2052                                 *out_NextIndexInString = in_IndexInString + r;\r
2053                         }\r
2054 \r
2055                         break;\r
2056                 }\r
2057 \r
2058                 {\r
2059                         size_t  new_max_size = max_size * size_times + first_max_size;\r
2060                         TCHAR*  new_string = (TCHAR*) realloc( string,  new_max_size * sizeof( TCHAR ) );\r
2061 \r
2062                         IF ( new_string == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
2063                         max_size = new_max_size;\r
2064                         string = new_string;\r
2065                 }\r
2066         }\r
2067 \r
2068         e=0;\r
2069 fin:\r
2070         *in_out_String = string;\r
2071         return  e;\r
2072 }\r
2073 \r
2074 \r
2075  \r
2076 /***********************************************************************\r
2077   <<< [StrHS_printfPart] >>> \r
2078 ************************************************************************/\r
2079 errnum_t  StrHS_printfPart( TCHAR**  in_out_String,\r
2080         int  in_IndexInString,  int*  out_NextIndexInString,\r
2081         const TCHAR*  in_Format,  ... )\r
2082 {\r
2083         errnum_t  e;\r
2084         va_list   va;\r
2085         va_start( va, in_Format );\r
2086 \r
2087         e = StrHS_printfPartV( in_out_String,  in_IndexInString,  out_NextIndexInString,  in_Format,  va );\r
2088 \r
2089         va_end( va );\r
2090         return  e;\r
2091 }\r
2092 \r
2093 \r
2094  \r
2095 /***********************************************************************\r
2096   <<< [StrHS_printfV] >>> \r
2097 ************************************************************************/\r
2098 errnum_t  StrHS_printfV( TCHAR**  in_out_String,\r
2099         const TCHAR*  in_Format,  va_list  in_VaList )\r
2100 {\r
2101         return  StrHS_printfPartV( in_out_String,  0,  NULL,  in_Format,  in_VaList );\r
2102 }\r
2103 \r
2104 \r
2105  \r
2106 /***********************************************************************\r
2107   <<< [StrHS_printf] >>> \r
2108 ************************************************************************/\r
2109 errnum_t  StrHS_printf( TCHAR**  in_out_String,\r
2110         const TCHAR*  in_Format,  ... )\r
2111 {\r
2112         errnum_t  e;\r
2113         va_list   va;\r
2114         va_start( va, in_Format );\r
2115 \r
2116         e = StrHS_printfPartV( in_out_String,  0,  NULL,  in_Format,  va );\r
2117 \r
2118         va_end( va );\r
2119         return  e;\r
2120 }\r
2121 \r
2122 \r
2123  \r
2124 /**************************************************************************\r
2125   <<< [StrT_meltCSV] >>> \r
2126 *************************************************************************/\r
2127 errnum_t  StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )\r
2128 {\r
2129         errnum_t  e = 0;\r
2130         TCHAR*  t;\r
2131         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
2132         const TCHAR*  s;\r
2133         TCHAR  dummy[2];\r
2134         TCHAR  c;\r
2135 \r
2136         t = out_Str;\r
2137         s = *pCSV;\r
2138         if ( out_Str_Size <= 1 )  { t = dummy;  t_last = dummy; }\r
2139 \r
2140         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
2141 \r
2142 \r
2143         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
2144         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
2145 \r
2146         switch ( *s ) {\r
2147 \r
2148                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
2149                 case _T('"'):\r
2150                         s++;\r
2151                         c = *s;\r
2152                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
2153                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
2154                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
2155                                 if ( c == _T('\0') )  break;\r
2156                                 *t = c;  t++;  s++;  c = *s;\r
2157                         }\r
2158                         *t = _T('\0');\r
2159 \r
2160                         s++;\r
2161                         for (;;) {\r
2162                                 if ( *s == _T(',') )  { s = s+1;  break; }\r
2163                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
2164                                 s++;\r
2165                         }\r
2166                         *pCSV = s;\r
2167                         return  e;\r
2168 \r
2169                 /* \8bó\82Ì\8d\80\96Ú\82Ì\8fê\8d\87 */\r
2170                 case ',':\r
2171                         *t = _T('\0');\r
2172                         *pCSV = s+1;\r
2173                         return  0;\r
2174 \r
2175                 case '\0':\r
2176                         *t = _T('\0');\r
2177                         *pCSV = NULL;\r
2178                         return  0;\r
2179 \r
2180                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
2181                 default: {\r
2182                         TCHAR*  sp = NULL;  /* \8dÅ\8cã\82Ì\98A\91±\82µ\82½\8bó\94\92\82Ì\90æ\93ª */\r
2183 \r
2184                         c = *s;\r
2185                         while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* , \95\8e\9a\82Ü\82Å */\r
2186 \r
2187                                 /* sp \82ð\90Ý\92è\82·\82é */\r
2188                                 if ( c == ' ' ) {\r
2189                                         if ( sp == NULL )  sp = t;\r
2190                                 }\r
2191                                 else  sp = NULL;\r
2192 \r
2193                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
2194 \r
2195                                 /* \83R\83s\81[\82·\82é */\r
2196                                 *t = c;  t++;  s++;  c = *s;\r
2197                         }\r
2198 \r
2199                         /* \95Ô\82è\92l\82ð\8c\88\92è\82·\82é */\r
2200                         if ( c == _T(',') )  s = s + 1;\r
2201                         else  s = NULL;\r
2202 \r
2203                         /* \96\96\94ö\82Ì\8bó\94\92\82ð\8eæ\82è\8f\9c\82­ */\r
2204                         if ( sp != NULL )  *sp = '\0';\r
2205                         else  *t = _T('\0');\r
2206 \r
2207                         *pCSV = s;\r
2208                         return  e;\r
2209                 }\r
2210         }\r
2211 }\r
2212 \r
2213 \r
2214  \r
2215 /***********************************************************************\r
2216   <<< [StrT_parseCSV_f] >>> \r
2217 ************************************************************************/\r
2218 errnum_t  StrT_parseCSV_f( const TCHAR* StringOfCSV, bit_flags32_t* out_ReadFlags, const TCHAR* Types, ... )\r
2219 {\r
2220         errnum_t       e;\r
2221         TCHAR          type;\r
2222         int            types_index;\r
2223         va_list        va;\r
2224         bool           is_next_omittable;\r
2225         bool           is_next_omit;\r
2226         const TCHAR*   column_pointer;\r
2227         TCHAR          a_char;\r
2228         TCHAR          column[ 32 ];\r
2229         bit_flags32_t  read_flags;\r
2230         bit_flags32_t  next_read_flag;\r
2231         TCHAR*         out_str;\r
2232         size_t         str_size = SIZE_MAX;  /* SIZE_MAX = Avoid warning */\r
2233 \r
2234 \r
2235         va_start( va, Types );\r
2236         types_index = 0;\r
2237         is_next_omittable = false;\r
2238         column_pointer = StringOfCSV;\r
2239         read_flags = 0;\r
2240         next_read_flag = 1;\r
2241         while ( column_pointer != NULL ) {\r
2242                 out_str = NULL;\r
2243 \r
2244                 type = Types[ types_index ];\r
2245                 switch ( type ) {\r
2246                         case  _T('\0'):\r
2247                                 goto exit_for;\r
2248 \r
2249                         case  _T('+'):\r
2250                                 is_next_omittable = true;\r
2251                                 break;\r
2252 \r
2253                         case  _T('s'):\r
2254                                 out_str = va_arg( va, TCHAR* );\r
2255                                 str_size = va_arg( va, size_t );\r
2256                                 ASSERT_D( str_size >= 1,  e=E_OTHERS; goto fin );\r
2257                                 break;\r
2258 \r
2259                         default:\r
2260                                 out_str = column;\r
2261                                 str_size = sizeof( column );\r
2262                                 break;\r
2263                 }\r
2264 \r
2265                 if ( out_str != NULL ) {\r
2266 \r
2267                         // Set "out_str" : Column string in CSV\r
2268                         column_pointer = StrT_skip( column_pointer, _T(" \t") );\r
2269                         a_char = *column_pointer;\r
2270                         if ( is_next_omittable  &&  ( a_char == _T('\0')  ||  a_char == _T(',') ) ) {\r
2271                                 column_pointer = StrT_chrs( column_pointer, _T(",") );\r
2272                                 if ( column_pointer != NULL ) { column_pointer += 1; }\r
2273                                 is_next_omit = true;\r
2274                         } else {\r
2275                                 e= StrT_meltCSV( out_str, str_size, &column_pointer ); IF(e){goto fin;}\r
2276 \r
2277                                 is_next_omit = false;\r
2278                                 read_flags |= next_read_flag;\r
2279                         }\r
2280 \r
2281                         switch ( type ) {\r
2282                                 case  _T('s'):\r
2283                                         /* "va_arg" was already called */\r
2284                                         break;\r
2285 \r
2286                                 case  _T('i'): {\r
2287                                         int*  pointer_of_int = va_arg( va, int* );\r
2288 \r
2289                                         if ( ! is_next_omit ) {\r
2290                                                 *pointer_of_int = ttoi_ex( column, 0 );\r
2291                                         }\r
2292                                         break;\r
2293                                 }\r
2294                                 case  _T('f'): {\r
2295                                         double*  pointer_of_double = va_arg( va, double* );\r
2296 \r
2297                                         if ( ! is_next_omit ) {\r
2298                                                 *pointer_of_double = _tstof( column );\r
2299                                         }\r
2300                                         break;\r
2301                                 }\r
2302                                 case  _T('b'): {\r
2303                                         bool*  pointer_of_bool = va_arg( va, bool* );\r
2304                                         int    strings_index;\r
2305                                         static const TCHAR*  strings[] = {\r
2306                                                 _T("1"), _T("true"), _T("yes"),\r
2307                                         };\r
2308 \r
2309                                         if ( ! is_next_omit ) {\r
2310                                                 *pointer_of_bool = false;\r
2311                                                 for ( strings_index = 0;\r
2312                                                         strings_index < _countof( strings );\r
2313                                                         strings_index += 1 )\r
2314                                                 {\r
2315                                                         if ( _tcsicmp( column, strings[ strings_index ] ) == 0 ) {\r
2316                                                                 *pointer_of_bool = true;\r
2317                                                                 break;\r
2318                                                         }\r
2319                                                 }\r
2320                                         }\r
2321                                         break;\r
2322                                 }\r
2323                                 case  _T('t'): {\r
2324                                         SYSTEMTIME*  pointer_of_time = va_arg( va, SYSTEMTIME* );\r
2325                                         int*         pointer_of_bias = va_arg( va, int* );\r
2326 \r
2327                                         if ( ! is_next_omit ) {\r
2328                                                 e= W3CDTF_toSYSTEMTIME( column, pointer_of_time, pointer_of_bias );\r
2329                                                         IF(e){goto fin;}\r
2330                                         }\r
2331                                         break;\r
2332                                 }\r
2333 \r
2334                                 default:\r
2335                                         ASSERT_R( false, e=E_OTHERS; goto fin );\r
2336                         }\r
2337 \r
2338                         is_next_omittable = false;\r
2339                         next_read_flag <<= 1;\r
2340                 }\r
2341 \r
2342                 types_index += 1;\r
2343         }\r
2344 exit_for:\r
2345         if ( out_ReadFlags != NULL ) {\r
2346                 *out_ReadFlags = read_flags;\r
2347         }\r
2348 \r
2349         e=0;\r
2350 fin:\r
2351         va_end( va );\r
2352         return  e;\r
2353 }\r
2354 \r
2355 \r
2356  \r
2357 /***********************************************************************\r
2358   <<< [StrT_getExistSymbols] >>> \r
2359 ************************************************************************/\r
2360 errnum_t  StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )\r
2361 {\r
2362         errnum_t  e;\r
2363         int       i;\r
2364         bool*   syms_exists = NULL;\r
2365         bool    b_nosym = false;\r
2366         TCHAR*  sym = NULL;\r
2367         size_t  sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);\r
2368         int     n_sym = 0;\r
2369         const TCHAR** syms = NULL;\r
2370         const TCHAR*  p;\r
2371 \r
2372         UNREFERENCED_VARIABLE( bCase );\r
2373 \r
2374         sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;\r
2375 \r
2376 \r
2377         //=== Get Symbols\r
2378         p = Symbols;\r
2379         do {\r
2380                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
2381                 if ( sym[0] != _T('\0') )  n_sym ++;\r
2382         } while ( p != NULL );\r
2383 \r
2384         syms = (const TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;\r
2385         memset( (TCHAR**) syms, 0, n_sym * sizeof(TCHAR*) );\r
2386         syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;\r
2387         memset( syms_exists, 0, n_sym * sizeof(bool) );\r
2388 \r
2389         p = Symbols;  i = 0;\r
2390         do {\r
2391                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
2392                 if ( sym[0] != _T('\0') ) {\r
2393                         e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;\r
2394                         i++;\r
2395                 }\r
2396         } while ( p != NULL );\r
2397 \r
2398 \r
2399         //=== Check Str whether having Symbols\r
2400         p = Str;\r
2401         do {\r
2402                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
2403                 if ( sym[0] != _T('\0') ) {\r
2404                         for ( i = 0; i < n_sym; i++ ) {\r
2405                                 if ( _tcscmp( sym, syms[i] ) == 0 )  { syms_exists[i] = true;  break; }\r
2406                         }\r
2407                         if ( i == n_sym )  b_nosym = true;\r
2408                 }\r
2409         } while ( p != NULL );\r
2410 \r
2411 \r
2412         //=== Sum numbers\r
2413         {\r
2414                 va_list   va;\r
2415                 unsigned  num;\r
2416 \r
2417                 va_start( va, Symbols );\r
2418                 *out = 0;\r
2419                 for ( i = 0; i < n_sym; i++ ) {\r
2420                         num = va_arg( va, unsigned );\r
2421                         if ( syms_exists[i] )  *out |= num;\r
2422                 }\r
2423                 va_end( va );\r
2424         }\r
2425 \r
2426         e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );\r
2427 fin:\r
2428         if ( syms != NULL ) {\r
2429                 for ( i = 0; i < n_sym; i++ ) {\r
2430                         e= HeapMemory_free( &syms[i], e );\r
2431                 }\r
2432                 free( (TCHAR**) syms );\r
2433         }\r
2434         e= HeapMemory_free( &syms_exists, e );\r
2435         e= HeapMemory_free( &sym, e );\r
2436         return  e;\r
2437 err_fm: e= E_FEW_MEMORY; goto fin;\r
2438 }\r
2439 \r
2440  \r
2441 /**************************************************************************\r
2442   <<< [StrT_meltCmdLine] >>> \r
2443 *************************************************************************/\r
2444 errnum_t  StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )\r
2445 {\r
2446         errnum_t  e = 0;\r
2447         TCHAR*  t;\r
2448         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
2449         const TCHAR*  s;\r
2450         TCHAR  dummy;\r
2451         TCHAR  c;\r
2452 \r
2453         t = out_Str;\r
2454         s = *pLine;\r
2455         if ( out_Str_Size <= 1 )  { t = &dummy;  t_last = &dummy; }\r
2456 \r
2457         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
2458 \r
2459 \r
2460         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
2461         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
2462 \r
2463         switch ( *s ) {\r
2464 \r
2465                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
2466                 case _T('"'):\r
2467                         s++;\r
2468                         c = *s;\r
2469                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
2470                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
2471                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
2472                                 if ( c == _T('\0') )  break;\r
2473                                 *t = c;  t++;  s++;  c = *s;\r
2474                         }\r
2475                         *t = _T('\0');\r
2476 \r
2477                         s++;\r
2478                         for (;;) {\r
2479                                 if ( *s == _T(' ') )  { s = s+1;  break; }\r
2480                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
2481                                 s++;\r
2482                         }\r
2483                         *pLine = s;\r
2484                         return  e;\r
2485 \r
2486                 case '\0':\r
2487                         *t = _T('\0');\r
2488                         *pLine = NULL;\r
2489                         return  0;\r
2490 \r
2491                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
2492                 default: {\r
2493                         c = *s;\r
2494                         while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* \8bó\94\92\95\8e\9a\82Ü\82Å */\r
2495 \r
2496                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
2497 \r
2498                                 /* \83R\83s\81[\82·\82é */\r
2499                                 *t = c;  t++;  s++;  c = *s;\r
2500                         }\r
2501 \r
2502                         /* *pLine\82ð\8c\88\92è\82·\82é */\r
2503                         while ( *s == _T(' ') )  s = s + 1;\r
2504                         if ( *s == _T('\0') )  s = NULL;\r
2505 \r
2506                         /* \96\96\94ö */\r
2507                         *t = _T('\0');\r
2508 \r
2509                         *pLine = s;\r
2510                         return  e;\r
2511                 }\r
2512         }\r
2513 }\r
2514 \r
2515 \r
2516  \r
2517 /***********************************************************************\r
2518   <<< [W3CDTF_fromSYSTEMTIME] >>> \r
2519 ************************************************************************/\r
2520 errnum_t  W3CDTF_fromSYSTEMTIME( TCHAR* out_W3CDTF, size_t W3CDTF_ByteSize,\r
2521         const SYSTEMTIME* Time, int TimeZoneMinute )\r
2522 {\r
2523         errnum_t  e;\r
2524         TCHAR*    char_pointer = out_W3CDTF;\r
2525 \r
2526         e= stprintf_part_r( out_W3CDTF, W3CDTF_ByteSize, char_pointer, &char_pointer,\r
2527                 _T("%04d-%02d-%02dT%02d:%02d:%02d.%03d"),\r
2528                 Time->wYear, Time->wMonth,  Time->wDay,\r
2529                 Time->wHour, Time->wMinute, Time->wSecond, Time->wMilliseconds );\r
2530                 IF(e){goto fin;}\r
2531 \r
2532         e= W3CDTF_getTimeZoneDesignator( char_pointer,\r
2533                 GetStringSizeFromPointer( out_W3CDTF, W3CDTF_ByteSize, char_pointer ),\r
2534                 TimeZoneMinute ); IF(e){goto fin;}\r
2535 \r
2536         e=0;\r
2537 fin:\r
2538         return  e;\r
2539 }\r
2540 \r
2541 \r
2542  \r
2543 /***********************************************************************\r
2544   <<< [W3CDTF_toSYSTEMTIME] >>> \r
2545 ************************************************************************/\r
2546 errnum_t  W3CDTF_toSYSTEMTIME( const TCHAR* String, SYSTEMTIME* out_Time, int* out_BiasMinute )\r
2547 {\r
2548         errnum_t  e;\r
2549         size_t    string_length = _tcslen( String );\r
2550 \r
2551         /* 01234567890123456789012345678 */\r
2552         /*"yyyy-mm-ddThh:mm:ss.sss+00:00"*/\r
2553         /*"0000-00-00T00:00+00:00"*/\r
2554 \r
2555         IF_D( out_BiasMinute == NULL ) { e=E_OTHERS; goto fin; }\r
2556 \r
2557         /* With time */\r
2558         if ( string_length >= 11 ) {\r
2559                 TCHAR         a_char;\r
2560                 const TCHAR*  time_zone;\r
2561                 int           number;\r
2562 \r
2563                 IF ( String[10] != _T('T') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2564                 IF ( String[4] != _T('-')  ||  String[7] != _T('-') )\r
2565                         { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2566 \r
2567                 IF ( string_length < 16 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2568                 IF ( String[13] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2569 \r
2570                 out_Time->wYear      = (WORD) _ttoi( &String[0] );\r
2571                 out_Time->wMonth     = (WORD) _ttoi( &String[5] );\r
2572                 out_Time->wDayOfWeek = 0;\r
2573                 out_Time->wDay       = (WORD) _ttoi( &String[8] );\r
2574                 out_Time->wHour      = (WORD) _ttoi( &String[11] );\r
2575                 out_Time->wMinute    = (WORD) _ttoi( &String[14] );\r
2576 \r
2577                 a_char = String[16];\r
2578                 if ( a_char == _T('+')  ||  a_char == _T('-')  ||  a_char == _T('Z') ) {\r
2579                         time_zone = &String[16];\r
2580                         out_Time->wSecond = 0;\r
2581                         out_Time->wMilliseconds = 0;\r
2582                 } else {\r
2583                         /* Second */\r
2584                         IF ( string_length < 19 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2585                         IF ( a_char != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2586                         out_Time->wSecond = (WORD) _ttoi( &String[17] );\r
2587 \r
2588 \r
2589                         /* \8f¬\90\94\93_ */\r
2590                         a_char = String[19];\r
2591                         if ( a_char == _T('+')  ||  a_char == _T('-')  ||  a_char == _T('Z') ) {\r
2592                                 time_zone = &String[19];\r
2593                                 out_Time->wMilliseconds = 0;\r
2594                         }\r
2595                         else {\r
2596                                 IF ( a_char != _T('.') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2597 \r
2598                                 out_Time->wMilliseconds = 0;\r
2599 \r
2600                                 number = String[20] - _T('0');\r
2601                                 if ( number < 0  ||  number > 9 ) {\r
2602                                         time_zone = &String[20];\r
2603                                 } else {\r
2604                                         out_Time->wMilliseconds += (WORD)( number * 100 );\r
2605 \r
2606                                         number = String[21] - _T('0');\r
2607                                         if ( number < 0  ||  number > 9 ) {\r
2608                                                 time_zone = &String[21];\r
2609                                         } else {\r
2610                                                 out_Time->wMilliseconds += (WORD)( number * 10 );\r
2611 \r
2612                                                 number = String[22] - _T('0');\r
2613                                                 if ( number < 0  ||  number > 9 ) {\r
2614                                                         time_zone = &String[22];\r
2615                                                 } else {\r
2616                                                         const TCHAR*  pointer = &String[23];\r
2617 \r
2618                                                         out_Time->wMilliseconds += (WORD)( number * 1 );\r
2619 \r
2620                                                         for (;;) {\r
2621                                                                 number = *pointer - _T('0');\r
2622                                                                 if ( number < 0  ||  number > 9 )\r
2623                                                                         { break; }\r
2624 \r
2625                                                                 pointer += 1;\r
2626                                                         }\r
2627                                                         time_zone = pointer;\r
2628                                                 }\r
2629                                         }\r
2630                                 }\r
2631 \r
2632                                 a_char = *time_zone;\r
2633                                 IF ( ! ( a_char == _T('+')  ||  a_char == _T('-')  ||  a_char == _T('Z') ) )\r
2634                                         { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2635                         }\r
2636                 }\r
2637 \r
2638                 /* Time zone */\r
2639                 if ( a_char == _T('Z') ) {\r
2640                         *out_BiasMinute = 0;\r
2641                 }\r
2642                 else {\r
2643                         size_t  time_zone_length = string_length - ( time_zone - String );\r
2644                         int     bias_minute;\r
2645 \r
2646                         IF ( time_zone_length < 6 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2647                         IF ( time_zone[3] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2648 \r
2649                         bias_minute = _ttoi( &time_zone[1] ) * 60 + _ttoi( &time_zone[4] );\r
2650                         if ( a_char == _T('-') ) { bias_minute = -bias_minute; }\r
2651                         *out_BiasMinute = bias_minute;\r
2652                 }\r
2653         }\r
2654 \r
2655         /* Without time */\r
2656         else {\r
2657                 out_Time->wDayOfWeek    = 0;\r
2658                 out_Time->wHour         = 0;\r
2659                 out_Time->wMinute       = 0;\r
2660                 out_Time->wSecond       = 0;\r
2661                 out_Time->wMilliseconds = 0;\r
2662                 *out_BiasMinute         = 0;\r
2663 \r
2664                 IF ( string_length < 4 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2665 \r
2666                 /* Year */\r
2667                 out_Time->wYear = (WORD) _ttoi( &String[0] );\r
2668 \r
2669                 /* Month */\r
2670                 if ( string_length > 4 ) {\r
2671                         IF ( string_length < 7 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2672                         IF ( String[4] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2673                         out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
2674                 } else {\r
2675                         out_Time->wMonth = 1;\r
2676                 }\r
2677 \r
2678                 /* Day */\r
2679                 if ( string_length > 7 ) {\r
2680                         IF ( string_length < 10 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2681                         IF ( String[7] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
2682                         out_Time->wDay = (WORD) _ttoi( &String[8] );\r
2683                 } else {\r
2684                         out_Time->wDay = 1;\r
2685                 }\r
2686         }\r
2687 \r
2688         e=0;\r
2689 fin:\r
2690         return  e;\r
2691 }\r
2692 \r
2693 \r
2694  \r
2695 /***********************************************************************\r
2696   <<< [W3CDTF_getTimeZoneDesignator] >>> \r
2697 ************************************************************************/\r
2698 errnum_t  W3CDTF_getTimeZoneDesignator( TCHAR* out_TZD, size_t TZD_ByteSize,\r
2699         int  BiasMinute )\r
2700 {\r
2701         errnum_t  e;\r
2702         TCHAR     sign;\r
2703         TIME_ZONE_INFORMATION  time_zone;\r
2704 \r
2705 \r
2706         /* Set "BiasMinute" */\r
2707         if ( BiasMinute == W3CDTF_CURRENT_TIME_ZONE ) {\r
2708                 GetTimeZoneInformation( &time_zone );\r
2709                 BiasMinute = -time_zone.Bias;\r
2710         }\r
2711         else {\r
2712                 enum { minute_1day = 1440 };\r
2713 \r
2714                 IF_D ( BiasMinute < -minute_1day  ||  BiasMinute > minute_1day )\r
2715                         { e=E_OTHERS; goto fin; }\r
2716         }\r
2717 \r
2718 \r
2719         /* Set "sign" */\r
2720         if ( BiasMinute >= 0 ) {\r
2721                 sign = _T('+');\r
2722         } else {\r
2723                 sign = _T('-');\r
2724                 BiasMinute = -BiasMinute;\r
2725         }\r
2726 \r
2727 \r
2728         /* Set "out_TZD" */\r
2729         _stprintf_s( out_TZD, TZD_ByteSize / sizeof(TCHAR), _T("%c%02d:%02d"),\r
2730                 sign,  BiasMinute / 60,  BiasMinute % 60 );\r
2731 \r
2732         e=0;\r
2733 fin:\r
2734         return  e;\r
2735 }\r
2736 \r
2737 \r
2738  \r
2739 /***********************************************************************\r
2740   <<< [StrT_isFullPath] >>> \r
2741 ************************************************************************/\r
2742 bool  StrT_isFullPath( const TCHAR* path )\r
2743 {\r
2744         bool  ret;\r
2745 \r
2746         if ( path[0] == _T('\\')  &&  path[1] == _T('\\') ) {\r
2747                 ret = true;\r
2748         } else {\r
2749                 const TCHAR*  back_slash = _tcschr( path, _T('\\') );\r
2750                 const TCHAR*  slash = _tcschr( path, _T('/') );\r
2751                 const TCHAR*  colon = _tcschr( path, _T(':') );\r
2752 \r
2753                 if ( colon != NULL ) {\r
2754                         const TCHAR*  p;\r
2755 \r
2756                         for ( p = path;  p < colon;  p += 1 ) {\r
2757                                 if ( ! _istalnum( *p ) ) {\r
2758                                         colon = NULL;\r
2759                                         break;\r
2760                                 }\r
2761                         }\r
2762                 }\r
2763 \r
2764                 ret = ( colon != NULL ) &&\r
2765                         ( back_slash == colon + 1  ||  slash == colon + 1 );\r
2766         }\r
2767 \r
2768         return  ret;\r
2769 }\r
2770 \r
2771  \r
2772 /**************************************************************************\r
2773   <<< [StrT_getFullPath_part] >>> \r
2774 *************************************************************************/\r
2775 errnum_t  StrT_getFullPath_part( TCHAR* out_FullPath, size_t FullPathSize, TCHAR* OutStart,\r
2776         TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
2777 {\r
2778         errnum_t      e;\r
2779         TCHAR         separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;\r
2780         const TCHAR*  separator_path;\r
2781         TCHAR*        out_full_path_over = (TCHAR*)( (uint8_t*) out_FullPath + FullPathSize );\r
2782         TCHAR*        null_position = NULL;\r
2783 \r
2784         #if  CHECK_ARG\r
2785                 /* "BasePath" must be out of "out_FullPath" */\r
2786                 ASSERT_R( BasePath < out_FullPath  ||\r
2787                         (uint8_t*) BasePath >= (uint8_t*) out_FullPath + FullPathSize,\r
2788                         goto err );\r
2789         #endif\r
2790 \r
2791 \r
2792         /* If "StepPath" == "", out_FullPath = "" */\r
2793         if ( StepPath[0] == _T('\0') ) {\r
2794                 ASSERT_R( FullPathSize >= sizeof(TCHAR), goto err_fm );\r
2795                 out_FullPath[0] = _T('\0');\r
2796                 e=0;  goto fin;\r
2797         }\r
2798 \r
2799 \r
2800         /* Set "OutStart" */\r
2801         if ( OutStart == NULL )\r
2802                 { OutStart = out_FullPath; }\r
2803 \r
2804 \r
2805         /* Set "separator" : \ or / from "BasePath" */\r
2806         if ( StrT_isFullPath( StepPath ) ) {\r
2807                 separator_path = StepPath;\r
2808         }\r
2809         else if ( BasePath == NULL ) {\r
2810                 separator = _T('\\');\r
2811                 separator_path = NULL;\r
2812         }\r
2813         else {\r
2814                 separator_path = BasePath;\r
2815         }\r
2816         if ( separator_path != NULL ) {\r
2817                 const TCHAR*    p;\r
2818                 const TCHAR*    p2;\r
2819 \r
2820                 p  = _tcschr( separator_path, _T('\\') );\r
2821                 p2 = _tcschr( separator_path, _T('/') );\r
2822                 if ( p == NULL ) {\r
2823                         if ( p2 == NULL )\r
2824                                 { separator = _T('\\'); }\r
2825                         else\r
2826                                 { separator = _T('/'); }\r
2827                 } else {\r
2828                         if ( p2 == NULL )\r
2829                                 { separator = _T('\\'); }\r
2830                         else {\r
2831                                 if ( p < p2 )\r
2832                                         { separator = _T('\\'); }\r
2833                                 else\r
2834                                         { separator = _T('/'); }\r
2835                         }\r
2836                 }\r
2837         }\r
2838 \r
2839 \r
2840         /* Set "OutStart" : "BasePath" + / + "StepPath" */\r
2841         if ( StrT_isFullPath( StepPath ) ) {\r
2842                 size_t  step_path_length = _tcslen( StepPath );\r
2843 \r
2844                 IF( OutStart + step_path_length >= out_full_path_over ) goto err_fa;\r
2845                 memmove( OutStart,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
2846 \r
2847                 /* Set "null_position" */\r
2848                 null_position = OutStart + step_path_length;\r
2849         }\r
2850         else {\r
2851                 TCHAR   c;\r
2852                 TCHAR*  p;\r
2853                 size_t  base_path_length;\r
2854                 size_t  step_path_length = _tcslen( StepPath );\r
2855 \r
2856                 if ( BasePath == NULL ) {\r
2857                         base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
2858                 }\r
2859                 else {\r
2860                         base_path_length = _tcslen( BasePath );\r
2861                         c = BasePath[ base_path_length - 1 ];\r
2862                         if ( c == _T('\\')  ||  c == _T('/') )\r
2863                                 { base_path_length -= 1; }\r
2864                 }\r
2865 \r
2866                 p = OutStart + base_path_length + 1;\r
2867                 IF( p + step_path_length >= out_full_path_over ) goto err_fa;\r
2868                 memmove( p,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
2869                         /* memmove is for "out_FullPath" == "StepPath" */\r
2870 \r
2871                 if ( BasePath == NULL ) {\r
2872                         GetCurrentDirectory( base_path_length + 1, OutStart );\r
2873                         if ( OutStart[ base_path_length - 1 ] == _T('\\') )\r
2874                                 { base_path_length -= 1; }\r
2875                 } else {\r
2876                         memcpy( OutStart,  BasePath,  base_path_length * sizeof(TCHAR) );\r
2877                 }\r
2878                 OutStart[ base_path_length ] = separator;\r
2879 \r
2880 \r
2881                 /* Set "null_position" */\r
2882                 null_position = p + step_path_length;\r
2883         }\r
2884 \r
2885 \r
2886         /* Replace \ and / to "separator" in "OutStart" */\r
2887         {\r
2888                 TCHAR  other_separator;\r
2889 \r
2890                 if ( separator == _T('/') )\r
2891                         { other_separator = _T('\\'); }\r
2892                 else\r
2893                         { other_separator = _T('/'); }\r
2894 \r
2895                 e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;\r
2896         }\r
2897 \r
2898 \r
2899         /* Replace \*\..\ to \ */\r
2900         {\r
2901                 enum  { length = 4 };\r
2902                 TCHAR   parent[ length + 1 ];  /* \..\ or /../ */\r
2903                 TCHAR*  parent_position;\r
2904                 TCHAR*  p;\r
2905 \r
2906                 parent[0] = separator;\r
2907                 parent[1] = _T('.');\r
2908                 parent[2] = _T('.');\r
2909                 parent[3] = separator;\r
2910                 parent[4] = _T('\0');\r
2911 \r
2912                 for (;;) {\r
2913                         parent_position = _tcsstr( OutStart, parent );\r
2914                         if ( parent_position == NULL )  { break; }\r
2915 \r
2916                         p = parent_position - 1;\r
2917                         for (;;) {\r
2918                                 IF( p < OutStart ) {goto err;}  /* "../" are too many */\r
2919                                 if ( *p == separator )  { break; }\r
2920                                 p -= 1;\r
2921                         }\r
2922 \r
2923                         memmove( p + 1,\r
2924                                 parent_position + length,\r
2925                                 ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );\r
2926 \r
2927                         null_position -= ( parent_position + length ) - ( p + 1 );\r
2928                 }\r
2929         }\r
2930 \r
2931 \r
2932         /* Cut last \*\.. */\r
2933         {\r
2934                 enum  { length = 3 };\r
2935                 TCHAR*  p;\r
2936 \r
2937                 while ( null_position - length >= OutStart ) {\r
2938                         if ( *( null_position - 3 ) != separator  ||\r
2939                              *( null_position - 2 ) != _T('.')  ||\r
2940                              *( null_position - 1 ) != _T('.') )\r
2941                                 { break; }\r
2942 \r
2943                         p = null_position - 4;\r
2944                         for (;;) {\r
2945                                 IF( p < OutStart ) {goto err;}  /* "../" are too many */\r
2946                                 if ( *p == separator )  { break; }\r
2947                                 p -= 1;\r
2948                         }\r
2949 \r
2950                         *p = _T('\0');\r
2951 \r
2952                         null_position = p;\r
2953                 }\r
2954         }\r
2955 \r
2956 \r
2957         /* Replace \.\ to \ */\r
2958         {\r
2959                 enum  { length = 3 };\r
2960                 TCHAR   current[ length + 1 ];  /* \.\ or /./ */\r
2961                 TCHAR*  current_position;\r
2962 \r
2963                 current[0] = separator;\r
2964                 current[1] = _T('.');\r
2965                 current[2] = separator;\r
2966                 current[3] = _T('\0');\r
2967 \r
2968                 for (;;) {\r
2969                         current_position = _tcsstr( OutStart, current );\r
2970                         if ( current_position == NULL )  { break; }\r
2971 \r
2972                         memmove( current_position + 1,\r
2973                                 current_position + length,\r
2974                                 ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );\r
2975 \r
2976                         null_position -= length - 1;\r
2977                 }\r
2978         }\r
2979 \r
2980 \r
2981         /* Cut last \. */\r
2982         {\r
2983                 TCHAR*  over = StrT_chr( OutStart, _T('\0') );\r
2984 \r
2985                 while ( over - 2 >= OutStart  &&\r
2986                                 *( over - 1 ) == _T('.')  &&  *( over - 2 ) == separator ) {\r
2987                         over -= 2;\r
2988                         *over = _T('\0');\r
2989                 }\r
2990         }\r
2991 \r
2992 \r
2993         /* Add root / */\r
2994         if ( null_position - 1 >= OutStart ) {\r
2995                 if ( *( null_position - 1 ) == _T(':') ) {\r
2996                         IF( null_position + 1 >= out_full_path_over ) goto err_fa;\r
2997 \r
2998                         *( null_position + 0 ) = separator;\r
2999                         *( null_position + 1 ) = _T('\0');\r
3000                         null_position += 1;\r
3001                 }\r
3002         }\r
3003 \r
3004 \r
3005         /* Set "*out_OutLast" */\r
3006         if ( out_OutLast != NULL )\r
3007                 { *out_OutLast = null_position; }\r
3008 \r
3009         e=0;\r
3010 fin:\r
3011         return  e;\r
3012 \r
3013 err:     e = E_OTHERS;      goto fin;\r
3014 err_fa:  e = E_FEW_ARRAY;   goto fin;\r
3015 err_fm:  e = E_FEW_MEMORY;  goto fin;\r
3016 }\r
3017 \r
3018 \r
3019  \r
3020 /***********************************************************************\r
3021   <<< [StrT_allocateFullPath] >>> \r
3022 ************************************************************************/\r
3023 errnum_t  StrT_allocateFullPath( TCHAR** out_FullPath, const TCHAR* StepPath, TCHAR* BasePath )\r
3024 {\r
3025         errnum_t  e;\r
3026         int  step_path_length = _tcslen( StepPath );\r
3027         int  base_path_length;\r
3028         int  full_path_size;\r
3029 \r
3030         if ( BasePath == NULL ) {\r
3031                 base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
3032         } else {\r
3033                 base_path_length = _tcslen( BasePath );\r
3034         }\r
3035 \r
3036         full_path_size = ( step_path_length + 1 + base_path_length + 1 ) * sizeof(TCHAR);\r
3037 \r
3038         e= HeapMemory_allocateBytes( out_FullPath, full_path_size ); IF(e){goto fin;}\r
3039         e= StrT_getFullPath( *out_FullPath, full_path_size, StepPath, BasePath ); IF(e){goto fin;}\r
3040 \r
3041         e=0;\r
3042 fin:\r
3043         return  e;\r
3044 }\r
3045 \r
3046 \r
3047  \r
3048 /***********************************************************************\r
3049   <<< [StrT_getParentFullPath_part] >>> \r
3050 ************************************************************************/\r
3051 errnum_t  StrT_getParentFullPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
3052         TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
3053 {\r
3054         errnum_t  e;\r
3055         TCHAR*  p;\r
3056 \r
3057         IF_D( StrStart < Str ||  (char*) StrStart >= (char*)Str + StrSize ){goto err;}\r
3058 \r
3059         if ( StepPath[0] == _T('\0') ) {\r
3060                 *StrStart = _T('\0');\r
3061                 return  0;\r
3062         }\r
3063 \r
3064         /* \90â\91Î\83p\83X\82É\82·\82é */\r
3065         e= StrT_getFullPath( StrStart,\r
3066                 StrSize - ( (char*)StrStart - (char*)Str ),\r
3067                 StepPath, BasePath ); IF(e)goto fin;\r
3068 \r
3069 \r
3070         /* Cut last \ */\r
3071         p = StrT_chr( StrStart, _T('\0') );\r
3072         if ( p > StrStart ) {\r
3073                 TCHAR  c = *( p - 1 );\r
3074                 if ( c == _T('\\')  ||  c == _T('/') )\r
3075                         { *( p - 1 ) = _T('\0'); }\r
3076         }\r
3077 \r
3078 \r
3079         /* \90e\82Ö */\r
3080         p = StrT_refFName( StrStart );\r
3081         if ( p > StrStart )  p--;\r
3082         *p = _T('\0');\r
3083 \r
3084 \r
3085         /* \83\8b\81[\83g\82È\82ç \ \82ð\95t\82¯\82é */\r
3086         if ( p == StrStart + 2 ) {\r
3087                 *p = _T('\\');  p++;  *p = _T('\0');\r
3088         }\r
3089 \r
3090         if ( out_StrLast != NULL )  *out_StrLast = p;\r
3091 \r
3092         e=0;\r
3093 fin:\r
3094         return  e;\r
3095 \r
3096 err:  e = E_OTHERS;  goto fin;\r
3097 }\r
3098 \r
3099 \r
3100  \r
3101 /***********************************************************************\r
3102   <<< [StrT_isOverOfFileName] >>> \r
3103 - "" or "\" or "/"\r
3104 ************************************************************************/\r
3105 inline bool  StrT_isOverOfFileName( const TCHAR* PointerInPath )\r
3106 {\r
3107         return  PointerInPath == NULL  ||\r
3108                 *PointerInPath == _T('\0')  ||\r
3109                 ( ( *PointerInPath == _T('\\')  ||  *PointerInPath == _T('/') )  &&\r
3110                         *(PointerInPath + 1) == _T('\0') );\r
3111 }\r
3112 \r
3113 \r
3114  \r
3115 /***********************************************************************\r
3116   <<< [StrT_getStepPath] >>> \r
3117 ************************************************************************/\r
3118 errnum_t  StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,\r
3119         const TCHAR* FullPath, const TCHAR* BasePath )\r
3120 {\r
3121         errnum_t      e;\r
3122         const TCHAR*  abs_pointer;\r
3123         const TCHAR*  base_pointer;\r
3124         TCHAR         abs_char;\r
3125         TCHAR         base_char;\r
3126         TCHAR         separator;\r
3127         const TCHAR*  abs_separator_pointer  = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
3128         const TCHAR*  base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
3129         TCHAR*        step_pointer;\r
3130         TCHAR         parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };\r
3131         TCHAR         base_path_2[ MAX_PATH ];\r
3132 \r
3133 \r
3134         ASSERT_D( out_StepPath != FullPath, goto err );\r
3135 \r
3136         abs_pointer = FullPath;\r
3137 \r
3138 \r
3139         /* Set "base_pointer" */\r
3140         if ( BasePath == NULL ) {\r
3141                 base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );\r
3142                 IF( base_pointer == NULL ) {goto err;}\r
3143         }\r
3144         else {\r
3145                 base_pointer = BasePath;\r
3146         }\r
3147 \r
3148 \r
3149         /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */\r
3150         separator = 0;\r
3151         for (;;) {  /* while abs_char == base_char */\r
3152                 abs_char  = *abs_pointer;\r
3153                 base_char = *base_pointer;\r
3154 \r
3155                 abs_char  = (TCHAR) _totlower( abs_char );\r
3156                 base_char = (TCHAR) _totlower( base_char );\r
3157 \r
3158                 if ( abs_char == _T('\0') ) {\r
3159 \r
3160                         /* out_StepPath = ".", if FullPath == BasePath */\r
3161                         if ( base_char == _T('\0') ) {\r
3162                                 e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;\r
3163                                 e=0; goto fin;\r
3164                         }\r
3165                         break;\r
3166                 }\r
3167                 if ( base_char == _T('\0') )  { break; }\r
3168 \r
3169                 if ( abs_char != base_char ) {\r
3170                         if ( ( abs_char  == _T('/')  ||  abs_char  == _T('\\') ) &&\r
3171                              ( base_char == _T('/')  ||  base_char == _T('\\') ) )\r
3172                                 { /* Do nothing */ }\r
3173                         else\r
3174                                 { break; }\r
3175                 }\r
3176 \r
3177                 /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */\r
3178                 if (  base_char == _T('/')  ||  base_char == _T('\\')  ) {\r
3179                         if ( separator == 0 )\r
3180                                 { separator = base_char; }\r
3181 \r
3182                         abs_separator_pointer = abs_pointer;\r
3183                         base_separator_pointer = base_pointer;\r
3184                 }\r
3185 \r
3186                 abs_pointer  += 1;\r
3187                 base_pointer += 1;\r
3188         }\r
3189 \r
3190 \r
3191         /* FullPath \82Æ BasePath \82Ì\8aÖ\8cW\82ª\81A\95Ð\95û\82Ì\88ê\95\94\82ª\82à\82¤\95Ð\95û\82Ì\91S\91Ì\82Å\82 \82é\82Æ\82« */\r
3192         if ( ( ( abs_char == _T('/')  ||  abs_char == _T('\\') )  &&  base_char == _T('\0') ) ||\r
3193              (  base_char == _T('/')  || base_char == _T('\\') )  &&   abs_char == _T('\0') ) {\r
3194 \r
3195                 if ( separator == 0 )\r
3196                         { separator = abs_char; }\r
3197 \r
3198                 abs_separator_pointer = abs_pointer;\r
3199                 base_separator_pointer = base_pointer;\r
3200         }\r
3201 \r
3202 \r
3203         /* out_StepPath = FullPath, if there is not same folder */\r
3204         if ( separator == 0 ) {\r
3205                 e= StrT_cpy( out_StepPath, StepPathSize, FullPath ); IF(e)goto fin;\r
3206                 e=0; goto fin;\r
3207         }\r
3208 \r
3209 \r
3210         /* Add "..\" to "out_StepPath" */\r
3211         parent_symbol[2] = separator;\r
3212         step_pointer = out_StepPath;\r
3213         for (;;) {\r
3214                 const TCHAR*  p1;\r
3215                 const TCHAR*  p2;\r
3216 \r
3217                 if ( StrT_isOverOfFileName( base_separator_pointer ) )\r
3218                         { break; }\r
3219 \r
3220 \r
3221                 /* Set "base_separator_pointer" : next separator */\r
3222                 p1 = _tcschr( base_separator_pointer + 1, _T('/') );\r
3223                 p2 = _tcschr( base_separator_pointer + 1, _T('\\') );\r
3224 \r
3225                 if ( p1 == NULL ) {\r
3226                         if ( p2 == NULL )\r
3227                                 { base_separator_pointer = NULL; }\r
3228                         else\r
3229                                 { base_separator_pointer = p2; }\r
3230                 }\r
3231                 else {\r
3232                         if ( p2 == NULL ) {\r
3233                                 base_separator_pointer = p1;\r
3234                         } else {\r
3235                                 if ( p1 < p2 )\r
3236                                         { base_separator_pointer = p1; }\r
3237                                 else\r
3238                                         { base_separator_pointer = p2; }\r
3239                         }\r
3240                 }\r
3241 \r
3242 \r
3243                 /* Add "..\" to "out_StepPath" */\r
3244                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,\r
3245                         parent_symbol, NULL ); IF(e)goto fin;\r
3246         }\r
3247 \r
3248 \r
3249         /* Copy a part of "FullPath" to "out_StepPath" */\r
3250         if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {\r
3251                 ASSERT_D( step_pointer > out_StepPath, goto err );\r
3252                 *( step_pointer - 1 ) = _T('\0');\r
3253         }\r
3254         else {\r
3255                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,\r
3256                         abs_separator_pointer + 1, NULL ); IF(e)goto fin;\r
3257         }\r
3258 \r
3259         e=0;\r
3260 fin:\r
3261         return  e;\r
3262 \r
3263 err:  e = E_OTHERS;  goto fin;\r
3264 }\r
3265 \r
3266 \r
3267  \r
3268 /***********************************************************************\r
3269   <<< [StrT_getBaseName_part] >>> \r
3270 ************************************************************************/\r
3271 errnum_t  StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
3272         TCHAR** out_StrLast, const TCHAR* SrcPath )\r
3273 {\r
3274         const TCHAR*  p1;\r
3275         const TCHAR*  p2;\r
3276         const TCHAR*  p3;\r
3277         const TCHAR*  ps;\r
3278 \r
3279         p1 = StrT_refFName( SrcPath );\r
3280 \r
3281 \r
3282         //=== # \82ª\96³\82¢\82Æ\82«\81A\8dÅ\8cã\82Ì\83s\83\8a\83I\83h\82Ì\91O\82Ü\82Å\82ª\81ABaseName\r
3283         ps = _tcschr( p1, _T('#') );\r
3284         if ( ps == NULL ) {\r
3285                 p2 = _tcsrchr( p1, _T('.') );\r
3286                 if ( p2 == NULL )  p2 = _tcsrchr( p1, _T('\0') );\r
3287         }\r
3288 \r
3289         //=== # \82ª\82 \82é\82Æ\82«\81A# \82æ\82è\91O\82Å\81A\8dÅ\8cã\82Ì\83s\83\8a\83I\83h\82Ì\91O\82Ü\82Å\82ª\81ABaseName\r
3290         else {\r
3291                 p2 = ps;\r
3292 \r
3293                 p3 = p1;\r
3294                 for (;;) {\r
3295                         p3 = _tcschr( p3, _T('.') );\r
3296                         if ( p3 == NULL || p3 > ps )  break;\r
3297                         p2 = p3;\r
3298                         p3 ++;\r
3299                 }\r
3300         }\r
3301 \r
3302         return  stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );\r
3303 }\r
3304 \r
3305  \r
3306 /***********************************************************************\r
3307   <<< [StrT_addLastOfFileName] >>> \r
3308 ************************************************************************/\r
3309 errnum_t  StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,\r
3310                              const TCHAR* BasePath, const TCHAR* AddName )\r
3311 {\r
3312         TCHAR           c;\r
3313         size_t          copy_size;\r
3314         size_t          free_size;\r
3315         char*           out_pos;\r
3316         const TCHAR*    last_pos_in_base = StrT_chr( BasePath, _T('\0') );\r
3317         const TCHAR*    term_pos_in_base;\r
3318         const TCHAR*     add_pos_in_base;\r
3319         const TCHAR*  period_pos_in_base = _tcsrchr( BasePath, _T('.') );  // > term_pos_in_base\r
3320         const TCHAR*    last_pos_in_add  = StrT_chr( AddName, _T('\0') );\r
3321         const TCHAR*    term_pos_in_add;\r
3322         const TCHAR*  period_pos_in_add  = _tcsrchr( AddName,  _T('.') );  // > term_pos_in_add\r
3323 \r
3324 \r
3325         DISCARD_BYTES( out_Path, PathSize );\r
3326 \r
3327 \r
3328         //=== term_pos_in_base\r
3329         for ( term_pos_in_base = last_pos_in_base;  term_pos_in_base >= BasePath;  term_pos_in_base -- ) {\r
3330                 c = *term_pos_in_base;\r
3331                 if ( c == _T('/') || c == _T('\\') )  break;\r
3332         }\r
3333 \r
3334 \r
3335         //=== term_pos_in_add\r
3336         for ( term_pos_in_add = last_pos_in_add;  term_pos_in_add >= AddName;  term_pos_in_add -- ) {\r
3337                 c = *term_pos_in_add;\r
3338                 if ( c == _T('/') || c == _T('\\') )  break;\r
3339         }\r
3340 \r
3341 \r
3342         //=== add_pos_in_base\r
3343         if ( term_pos_in_base < period_pos_in_base ) {\r
3344                 add_pos_in_base = period_pos_in_base;\r
3345         }\r
3346         else {\r
3347                 if ( term_pos_in_base < BasePath )\r
3348                         add_pos_in_base = StrT_chr( BasePath, _T('\0') );\r
3349                 else\r
3350                         add_pos_in_base = StrT_chr( term_pos_in_base, _T('\0') );\r
3351         }\r
3352 \r
3353 \r
3354         //=== setup output parameters\r
3355         out_pos   = (char*) out_Path;\r
3356         free_size = PathSize;\r
3357 \r
3358 \r
3359         //=== copy BasePath .. add_pos_in_base\r
3360         copy_size = (char*)add_pos_in_base - (char*)BasePath;\r
3361         if ( copy_size > free_size ) goto err_fa;\r
3362         memcpy( out_pos,  BasePath,  copy_size );\r
3363         out_pos   += copy_size;\r
3364         free_size -= copy_size;\r
3365 \r
3366 \r
3367         //=== copy AddName .. last_pos_in_add\r
3368         copy_size = (char*)last_pos_in_add - (char*)AddName;\r
3369         if ( copy_size > free_size ) goto err_fa;\r
3370         memcpy( out_pos,  AddName,  copy_size );\r
3371         out_pos   += copy_size;\r
3372         free_size -= copy_size;\r
3373 \r
3374 \r
3375         //=== add name and not change extension\r
3376         if ( period_pos_in_add == NULL ) {\r
3377 \r
3378                 //=== copy period_pos_in_base .. last_pos_in_base\r
3379                 if ( period_pos_in_base > term_pos_in_base ) {\r
3380                         copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);\r
3381                         if ( copy_size > free_size ) goto err_fa;\r
3382                         memcpy( out_pos,  period_pos_in_base,  copy_size );\r
3383                 }\r
3384                 else {\r
3385                         *(TCHAR*)out_pos = _T('\0');\r
3386                 }\r
3387         }\r
3388 \r
3389 \r
3390         //=== add name and change extension\r
3391         else {\r
3392 \r
3393                 if ( *(period_pos_in_add + 1) == _T('\0') )\r
3394                         *( (TCHAR*)out_pos - 1 ) = _T('\0');\r
3395                 else\r
3396                         *(TCHAR*)out_pos = _T('\0');\r
3397         }\r
3398 \r
3399         return  0;\r
3400 \r
3401 err_fa:\r
3402         return  E_FEW_ARRAY;\r
3403 }\r
3404 \r
3405 \r
3406  \r
3407 /***********************************************************************\r
3408   <<< [StrT_encodeToValidPath] >>> \r
3409 ************************************************************************/\r
3410 errnum_t  StrT_encodeToValidPath( TCHAR* out_Path,  size_t in_OutPathSize,  const TCHAR* in_Path,  bool  in_IsName )\r
3411 {\r
3412         errnum_t  e;\r
3413 \r
3414         int  i_in;   /* index of "in_Path" */\r
3415         int  i_out = 0;  /* index of "out_Path" */\r
3416         int  i_out_over = (int)( in_OutPathSize / sizeof(TCHAR) );\r
3417         bool is_colon = in_IsName;\r
3418 \r
3419         ASSERT_R( in_Path != out_Path,  e=E_OTHERS; goto fin );\r
3420 \r
3421         for ( i_in = 0;  ;  i_in += 1 ) {\r
3422                 bool  is_percent;\r
3423                 int   chara = in_Path[ i_in ];  /* a character */\r
3424 \r
3425                 if ( chara == _T('\0') )\r
3426                         { break; }\r
3427 \r
3428 \r
3429                 /* Set "is_percent" */\r
3430                 switch ( chara ) {\r
3431                         case _T(','):  case _T(';'):  case _T('*'):  case _T('?'):  case _T('"'):\r
3432                         case _T('<'):  case _T('>'):  case _T('|'):  case _T('%'):\r
3433                                 is_percent = true;\r
3434                                 break;\r
3435                         case _T(':'):\r
3436                                 is_percent = is_colon;\r
3437                                 is_colon = true;\r
3438                                 break;\r
3439                         case _T('\\'):  case _T('/'):\r
3440                                 is_percent = in_IsName;\r
3441                                 is_colon = true;\r
3442                                 break;\r
3443                         default:\r
3444                                 is_percent = false;\r
3445                                 break;\r
3446                 }\r
3447 \r
3448 \r
3449                 /* Set "out_Path[ i_out ]" */\r
3450                 if ( is_percent ) {\r
3451                         int  high = chara / 0x10;\r
3452                         int  low  = chara & 0xF;\r
3453 \r
3454                         if ( high <= 9 ) {\r
3455                                 high += _T('0');\r
3456                         } else {\r
3457                                 high = ( high - 0xA ) + _T('a');\r
3458                         }\r
3459 \r
3460                         if ( low <= 9 ) {\r
3461                                 low += _T('0');\r
3462                         } else {\r
3463                                 low = ( low - 0xA ) + _T('a');\r
3464                         }\r
3465 \r
3466                         ASSERT_R( i_out + 3 < i_out_over,  e=E_FEW_ARRAY; goto fin );\r
3467 \r
3468                         out_Path[ i_out + 0 ] = _T('%');\r
3469                         out_Path[ i_out + 1 ] = (TCHAR) high;\r
3470                         out_Path[ i_out + 2 ] = (TCHAR) low;\r
3471                         i_out += 3;\r
3472                 }\r
3473                 else {\r
3474                         ASSERT_R( i_out + 1 < i_out_over,  e=E_FEW_ARRAY; goto fin );\r
3475 \r
3476                         out_Path[ i_out ] = (TCHAR) chara;\r
3477                         i_out += 1;\r
3478                 }\r
3479         }\r
3480 \r
3481         e=0;\r
3482 fin:\r
3483         out_Path[ i_out ] = _T('\0');\r
3484 \r
3485         return  e;\r
3486 }\r
3487 \r
3488 \r
3489  \r
3490 /***********************************************************************\r
3491   <<< [Strs_init] >>> \r
3492 ************************************************************************/\r
3493 enum { Strs_FirstSize = 0x0F00 };\r
3494 \r
3495 errnum_t  Strs_init( Strs* self )\r
3496 {\r
3497         byte_t*  p;\r
3498 \r
3499         self->MemoryAddress = NULL;\r
3500 \r
3501         p = (byte_t*) malloc( Strs_FirstSize );\r
3502         IF( p == NULL )  return  E_FEW_MEMORY;\r
3503 \r
3504         self->MemoryAddress = p;\r
3505         self->MemoryOver    = p + Strs_FirstSize;\r
3506         self->NextElem      = p + sizeof(TCHAR*);\r
3507         self->PointerToNextStrInPrevElem = (TCHAR**) p;\r
3508         self->Prev_PointerToNextStrInPrevElem = NULL;\r
3509         *(TCHAR**) p = NULL;\r
3510 \r
3511         self->FirstOfStrs = self;\r
3512         self->NextStrs = NULL;\r
3513 \r
3514         return  0;\r
3515 }\r
3516 \r
3517 \r
3518  \r
3519 /***********************************************************************\r
3520   <<< [Strs_finish] >>> \r
3521 ************************************************************************/\r
3522 errnum_t  Strs_finish( Strs* self, errnum_t e )\r
3523 {\r
3524         Strs*  mp;\r
3525         Strs*  next_mp;\r
3526 \r
3527         if ( self->MemoryAddress == NULL )  return 0;\r
3528 \r
3529         mp = self->FirstOfStrs;\r
3530         for (;;) {\r
3531                 free( mp->MemoryAddress );\r
3532                 if ( mp == self )  break;\r
3533 \r
3534                 next_mp = mp->NextStrs;\r
3535                 free( mp );\r
3536                 mp = next_mp;\r
3537         }\r
3538         self->MemoryAddress = NULL;\r
3539 \r
3540         return  e;\r
3541 }\r
3542 \r
3543 \r
3544  \r
3545 /***********************************************************************\r
3546   <<< [Strs_toEmpty] >>> \r
3547 ************************************************************************/\r
3548 errnum_t  Strs_toEmpty( Strs* self )\r
3549 {\r
3550         Strs_finish( self, 0 );\r
3551         return  Strs_init( self );\r
3552 }\r
3553 \r
3554 \r
3555  \r
3556 /***********************************************************************\r
3557   <<< [Strs_add] >>> \r
3558 ************************************************************************/\r
3559 errnum_t  Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )\r
3560 {\r
3561         return  Strs_addBinary( self, Str, StrT_chr( Str, _T('\0') ) + 1, out_AllocStr );\r
3562 }\r
3563 \r
3564 \r
3565 errnum_t  Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )\r
3566 {\r
3567         errnum_t  e;\r
3568         size_t  str_size;\r
3569         size_t  elem_size;\r
3570 \r
3571         str_size  = ( (byte_t*) StrOver - (byte_t*) Str );\r
3572         elem_size = ( sizeof(TCHAR*) + str_size + ( sizeof(void*) - 1 ) ) & ~(sizeof(void*) - 1);\r
3573 \r
3574         if ( self->NextElem + elem_size > self->MemoryOver )\r
3575                 { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }\r
3576 \r
3577 \r
3578         // [ NULL     | ... ]\r
3579         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
3580         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
3581         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
3582 \r
3583         if ( out_AllocStr != NULL )  *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
3584 \r
3585         //=== fill elem\r
3586         *(TCHAR**) self->NextElem = NULL;\r
3587         memcpy( self->NextElem + sizeof(TCHAR*),  Str,  str_size );\r
3588 \r
3589         //=== link to elem from previous elem\r
3590         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
3591 \r
3592         //=== update self\r
3593         self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;\r
3594         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
3595         self->NextElem = self->NextElem + elem_size;\r
3596 \r
3597         e=0;\r
3598 fin:\r
3599         return  e;\r
3600 }\r
3601 \r
3602 \r
3603  \r
3604 /***********************************************************************\r
3605   <<< [Strs_freeLast] >>> \r
3606 ************************************************************************/\r
3607 errnum_t  Strs_freeLast( Strs* self, TCHAR* AllocStr )\r
3608 {\r
3609         errnum_t  e;\r
3610         TCHAR*  str;\r
3611         TCHAR*  last_str;\r
3612         TCHAR*  prev_of_last_str;\r
3613         Strs*   mp;\r
3614         Strs*   prev_of_last_mp;\r
3615 \r
3616         if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {\r
3617                 prev_of_last_str = NULL;\r
3618                 last_str = NULL;\r
3619                 for ( Strs_forEach( self, &str ) ) {\r
3620                         prev_of_last_str = last_str;\r
3621                         last_str = str;\r
3622                 }\r
3623         }\r
3624         else {\r
3625                 prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );\r
3626                 last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );\r
3627         }\r
3628 \r
3629         // [ NULL     | ... ]\r
3630         IF( last_str != AllocStr ) {goto err;}\r
3631 \r
3632         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
3633         if ( prev_of_last_str == NULL ) {\r
3634                 self->NextElem = self->MemoryAddress + sizeof(TCHAR*);\r
3635                 self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;\r
3636         }\r
3637 \r
3638         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
3639         else if ( (byte_t*) prev_of_last_str >= self->MemoryAddress  &&\r
3640                   (byte_t*) prev_of_last_str <  self->MemoryOver ) {\r
3641                 self->NextElem = (byte_t*)last_str - sizeof(TCHAR*);\r
3642                 self->PointerToNextStrInPrevElem = (TCHAR**)( (byte_t*)prev_of_last_str - sizeof(TCHAR*) );\r
3643         }\r
3644 \r
3645         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
3646         else {\r
3647                 prev_of_last_mp = NULL;\r
3648                 for ( mp = self->FirstOfStrs;  mp->NextStrs != self;  mp = mp->NextStrs ) {\r
3649                         prev_of_last_mp = mp;\r
3650                 }\r
3651 \r
3652                 free( self->MemoryAddress );\r
3653 \r
3654                 *self = *mp;\r
3655 \r
3656                 if ( prev_of_last_mp == NULL ) {\r
3657                         self->FirstOfStrs = self;\r
3658                         self->NextStrs = NULL;\r
3659                 }\r
3660                 else {\r
3661                         prev_of_last_mp->NextStrs = self;\r
3662                 }\r
3663 \r
3664                 free( mp );\r
3665         }\r
3666         *self->PointerToNextStrInPrevElem = NULL;\r
3667         self->Prev_PointerToNextStrInPrevElem = NULL;\r
3668 \r
3669         e=0;\r
3670 fin:\r
3671         return  e;\r
3672 \r
3673 err:  e = E_OTHERS;  goto fin;\r
3674 }\r
3675 \r
3676 \r
3677  \r
3678 /***********************************************************************\r
3679   <<< [Strs_expandSize] >>> \r
3680 ************************************************************************/\r
3681 errnum_t  Strs_expandSize( Strs* self, size_t FreeSize )\r
3682 {\r
3683         Strs*   mp;\r
3684         Strs*   mp2;\r
3685         size_t  elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
3686         size_t  memory_size;\r
3687         byte_t* new_memory;\r
3688 \r
3689         // [ NULL     | ... ]\r
3690         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
3691         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
3692         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
3693 \r
3694         while ( self->NextElem + elem_size > self->MemoryOver ) {\r
3695 \r
3696                 //=== alloc\r
3697                 mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;\r
3698                 memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;\r
3699                 new_memory = (byte_t*) malloc( memory_size );\r
3700                 IF( new_memory == NULL )  { free( mp );  goto err_fm; }\r
3701 \r
3702                 //=== move old memory\r
3703                 if ( self->FirstOfStrs == self ) {\r
3704                         self->FirstOfStrs = mp;\r
3705                 }\r
3706                 else {\r
3707                         for ( mp2 = self->FirstOfStrs;  mp2->NextStrs != self;  mp2 = mp2->NextStrs );\r
3708                         mp2->NextStrs = mp;\r
3709                 }\r
3710                 *mp = *self;\r
3711                 mp->NextStrs = self;\r
3712 \r
3713                 //=== setup new memory\r
3714                 self->MemoryAddress = new_memory;\r
3715                 self->MemoryOver    = new_memory + memory_size;\r
3716                 self->NextElem      = new_memory;\r
3717                 // self->PointerToNextStrInPrevElem is same value\r
3718                 // self->FirstOfStrs is same value\r
3719                 // self->NextStrs is always NULL\r
3720         }\r
3721         return  0;\r
3722 \r
3723 err_fm:  return  E_FEW_ARRAY;\r
3724 }\r
3725 \r
3726 \r
3727 /***********************************************************************\r
3728   <<< [Strs_commit] >>>\r
3729 ************************************************************************/\r
3730 errnum_t  Strs_commit( Strs* self, TCHAR* StrOver )\r
3731 {\r
3732         size_t  elem_size;\r
3733 \r
3734         if ( StrOver == NULL )\r
3735                 { StrOver = StrT_chr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }\r
3736         elem_size = ( ( (byte_t*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
3737 \r
3738         //=== fill elem\r
3739         *(TCHAR**) self->NextElem = NULL;\r
3740 \r
3741         //=== link to elem from previous elem\r
3742         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
3743 \r
3744         //=== update self\r
3745         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
3746         self->NextElem = self->NextElem + elem_size;\r
3747 \r
3748         return  0;\r
3749 }\r
3750 \r
3751 \r
3752  \r
3753 /***********************************************************************\r
3754   <<< [Strs_allocateArray] >>> \r
3755 ************************************************************************/\r
3756 errnum_t  Strs_allocateArray( Strs* self,  TCHAR*** out_PointerArray,  int* out_Count )\r
3757 {\r
3758         errnum_t  e;\r
3759         TCHAR*    p;\r
3760         TCHAR**   pp;\r
3761         int       count;\r
3762 \r
3763         count = 0;\r
3764         for ( Strs_forEach( self, &p ) ) {\r
3765                 count += 1;\r
3766         }\r
3767 \r
3768         e= HeapMemory_allocateArray( &pp, count ); IF(e){goto fin;}\r
3769 \r
3770         count = 0;\r
3771         for ( Strs_forEach( self, &p ) ) {\r
3772                 pp[ count ] = p;\r
3773                 count += 1;\r
3774         }\r
3775 \r
3776         *out_PointerArray = pp;\r
3777         *out_Count = count;\r
3778 \r
3779         e=0;\r
3780 fin:\r
3781         return  e;\r
3782 }\r
3783 \r
3784 \r
3785  \r
3786 /***********************************************************************\r
3787   <<< [StrArr] >>> \r
3788 ************************************************************************/\r
3789 \r
3790 /*[StrArr_init]*/\r
3791 errnum_t  StrArr_init( StrArr* self )\r
3792 {\r
3793         errnum_t  e;\r
3794 \r
3795         Set2_initConst( &self->Array );\r
3796         Strs_initConst( &self->Chars );\r
3797 \r
3798         e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;\r
3799         e= Strs_init( &self->Chars ); IF(e)goto cancel;\r
3800         return  0;\r
3801 \r
3802 cancel:  StrArr_finish( self, e );  return  e;\r
3803 }\r
3804 \r
3805 \r
3806 /*[StrArr_finish]*/\r
3807 errnum_t  StrArr_finish( StrArr* self, errnum_t e )\r
3808 {\r
3809         if ( ! Set2_isInited( &self->Array ) )  return  e;\r
3810 \r
3811         e= Set2_finish( &self->Array, e );\r
3812         e= Strs_finish( &self->Chars, e );\r
3813         return  e;\r
3814 }\r
3815 \r
3816 \r
3817 /*[StrArr_add]*/\r
3818 errnum_t  StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )\r
3819 {\r
3820         errnum_t  e;\r
3821 \r
3822         e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;\r
3823         _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );\r
3824         e= StrArr_commit( self ); IF(e)goto fin;\r
3825         if ( out_I != NULL )  *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;\r
3826 \r
3827         e=0;\r
3828 fin:\r
3829         return  e;\r
3830 }\r
3831 \r
3832 \r
3833 /*[StrArr_commit]*/\r
3834 errnum_t  StrArr_commit( StrArr* self )\r
3835 {\r
3836         errnum_t  e;\r
3837         TCHAR*   p;\r
3838         TCHAR**  pp  = NULL;\r
3839         Set2*    arr = &self->Array;\r
3840         Strs*    ss  = &self->Chars;\r
3841 \r
3842         p = Strs_getFreeAddr( ss );\r
3843         e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;\r
3844         e= Strs_commit( ss, NULL ); IF(e)goto fin;\r
3845         *pp = p;\r
3846 \r
3847         e=0;\r
3848 fin:\r
3849         if ( e &&  pp != NULL )  e= Set2_freeLast( arr, pp, TCHAR*, e );\r
3850         return  e;\r
3851 }\r
3852 \r
3853 \r
3854 /*[StrArr_fillTo]*/\r
3855 errnum_t  StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )\r
3856 {\r
3857         errnum_t  e;\r
3858         const TCHAR*   p;\r
3859         const TCHAR**  pp;\r
3860         const TCHAR**  pp_over;\r
3861 \r
3862         n -= Set2_getCount( &self->Array, TCHAR* );\r
3863         if ( n <= 0 ) return 0;\r
3864 \r
3865         if ( Str == NULL ) {\r
3866                 p = NULL;\r
3867         }\r
3868         else {\r
3869                 e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;\r
3870         }\r
3871 \r
3872         e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;\r
3873         pp_over = pp + n;\r
3874         for ( ;  pp < pp_over;  pp++ )\r
3875                 *pp = p;\r
3876 \r
3877         e=0;\r
3878 fin:\r
3879         return  e;\r
3880 }\r
3881 \r
3882 \r
3883 /*[StrArr_toEmpty]*/\r
3884 errnum_t  StrArr_toEmpty( StrArr* self )\r
3885 {\r
3886         errnum_t  e, ee;\r
3887 \r
3888         e=0;\r
3889         ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;\r
3890         ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;\r
3891         return  e;\r
3892 }\r
3893 \r
3894 \r
3895  \r
3896 /***********************************************************************\r
3897   <<< [StrArr_parseCSV] >>> \r
3898 ************************************************************************/\r
3899 errnum_t  StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )\r
3900 {\r
3901         errnum_t      e;\r
3902         const TCHAR*  p = CSVLine;\r
3903 \r
3904         e= StrArr_toEmpty( self ); IF(e)goto fin;\r
3905 \r
3906         do {\r
3907                 e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );\r
3908                 if ( e == E_FEW_ARRAY ) {\r
3909                         e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;\r
3910                         continue;\r
3911                 }\r
3912                 IF(e)goto fin;\r
3913 \r
3914                 e = StrArr_commit( self ); IF(e)goto fin;\r
3915         } while ( p != NULL );\r
3916 \r
3917         e=0;\r
3918 fin:\r
3919         return  e;\r
3920 }\r
3921 \r
3922 \r
3923  \r
3924 /*=================================================================*/\r
3925 /* <<< [DebugTools/DebugTools.c] >>> */ \r
3926 /*=================================================================*/\r
3927  \r
3928 /***********************************************************************\r
3929   <<< [TestableDebugBreak] >>> \r
3930 ************************************************************************/\r
3931 typedef struct _TestableDebugBreakClass  TestableDebugBreakClass;\r
3932 struct _TestableDebugBreakClass {\r
3933         bool              IsDisableTestableDebugBreak;\r
3934         volatile int      DebugBreakCount;\r
3935         CRITICAL_SECTION  Critical;\r
3936         SingletonInitializerClass  Initializer;\r
3937 };\r
3938 static TestableDebugBreakClass  gs_TestableDebugBreak = { false, 0 };\r
3939 \r
3940 \r
3941 /*[SetTestableDebugBreak]*/\r
3942 void  SetTestableDebugBreak( bool IsEnableBreak )\r
3943 {\r
3944         TestableDebugBreakClass*  self = &gs_TestableDebugBreak;\r
3945         self->IsDisableTestableDebugBreak = ! IsEnableBreak;\r
3946 }\r
3947 \r
3948 /*[TestableDebugBreak_Sub]*/\r
3949 int  TestableDebugBreak_Sub()\r
3950 {\r
3951         TestableDebugBreakClass*  self = &gs_TestableDebugBreak;\r
3952 \r
3953         if ( ! SingletonInitializerClass_isInitialized( &self->Initializer ) ) {\r
3954                 if ( SingletonInitializerClass_isFirst( &self->Initializer ) ) {\r
3955 \r
3956                         InitializeCriticalSection( &self->Critical );\r
3957 \r
3958                         SingletonInitializerClass_onFinishedInitialize( &self->Initializer, 0 );\r
3959                 }\r
3960         }\r
3961 \r
3962         EnterCriticalSection( &self->Critical );\r
3963         self->DebugBreakCount += 1;\r
3964         LeaveCriticalSection( &self->Critical );\r
3965 \r
3966         return  ! self->IsDisableTestableDebugBreak;\r
3967 }\r
3968 \r
3969 /*[GetDebugBreakCount]*/\r
3970 int  GetDebugBreakCount()\r
3971 {\r
3972         TestableDebugBreakClass*  self = &gs_TestableDebugBreak;\r
3973         return  self->DebugBreakCount;\r
3974 }\r
3975 \r
3976 \r
3977  \r
3978 /*=================================================================*/\r
3979 /* <<< [SetX/SetX.c] >>> */ \r
3980 /*=================================================================*/\r
3981  \r
3982 /***********************************************************************\r
3983   <<< [Set2_init] >>> \r
3984 ************************************************************************/\r
3985 errnum_t  Set2_init( Set2* m, int FirstSize )\r
3986 {\r
3987         m->First = malloc( FirstSize );\r
3988         if ( m->First == NULL )  return  E_FEW_MEMORY;\r
3989         m->Next = m->First;\r
3990         m->Over = (char*)m->First + FirstSize;\r
3991 \r
3992         #ifdef _DEBUG\r
3993         m->PointerOfDebugArray = NULL;\r
3994         #endif\r
3995 \r
3996         return  0;\r
3997 }\r
3998  \r
3999 /***********************************************************************\r
4000   <<< [Set2_finish] >>> \r
4001 ************************************************************************/\r
4002 errnum_t  Set2_finish( Set2* m, errnum_t e )\r
4003 {\r
4004         if ( m->First != NULL )  { free( m->First );  m->First = NULL; }\r
4005         return  e;\r
4006 }\r
4007 \r
4008  \r
4009 /***********************************************************************\r
4010   <<< [Set2_ref_imp] >>> \r
4011 ************************************************************************/\r
4012 errnum_t  Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )\r
4013 {\r
4014         int    e;\r
4015         char*  p;\r
4016 \r
4017         IF( iElem < 0 ) goto err_ns;\r
4018         p = (char*) m->First + ( (unsigned)iElem * ElemSize );\r
4019         IF( p >= (char*)m->Next ) goto err_ns;\r
4020         *(char**)out_pElem = p;\r
4021 \r
4022         e=0;\r
4023 fin:\r
4024         return  e;\r
4025 \r
4026 err_ns:  e = E_NOT_FOUND_SYMBOL;  goto fin;\r
4027 }\r
4028 \r
4029 \r
4030  \r
4031 /***********************************************************************\r
4032   <<< [Set2_getIterator] >>> \r
4033 ************************************************************************/\r
4034 errnum_t  Set2_getIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
4035 {\r
4036         out_Iterator->Parent = self;\r
4037         out_Iterator->ElementSize = ElementSize;\r
4038         out_Iterator->Current = (uint8_t*) self->First - ElementSize;\r
4039         return  0;\r
4040 }\r
4041 \r
4042 \r
4043  \r
4044 /***********************************************************************\r
4045   <<< [Set2_getDescendingIterator] >>> \r
4046 ************************************************************************/\r
4047 errnum_t  Set2_getDescendingIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
4048 {\r
4049         out_Iterator->Parent = self;\r
4050         out_Iterator->ElementSize = ElementSize;\r
4051         out_Iterator->Current = (uint8_t*) self->Next;\r
4052         return  0;\r
4053 }\r
4054 \r
4055 \r
4056  \r
4057 /***********************************************************************\r
4058   <<< [Set2_IteratorClass_getNext] >>> \r
4059 ************************************************************************/\r
4060 void*  Set2_IteratorClass_getNext( Set2_IteratorClass* self )\r
4061 {\r
4062         uint8_t*  next = self->Current + self->ElementSize;\r
4063 \r
4064         if ( next >= (uint8_t*) self->Parent->Next ) {\r
4065                 return  NULL;\r
4066         } else {\r
4067                 self->Current = next;\r
4068                 return  next;\r
4069         }\r
4070 }\r
4071 \r
4072 \r
4073  \r
4074 /***********************************************************************\r
4075   <<< [Set2_IteratorClass_getPrevious] >>> \r
4076 ************************************************************************/\r
4077 void*  Set2_IteratorClass_getPrevious( Set2_IteratorClass* self )\r
4078 {\r
4079         uint8_t*  previous = self->Current - self->ElementSize;\r
4080 \r
4081         if ( previous < (uint8_t*) self->Parent->First ) {\r
4082                 return  NULL;\r
4083         } else {\r
4084                 self->Current = previous;\r
4085                 return  previous;\r
4086         }\r
4087 }\r
4088 \r
4089 \r
4090  \r
4091 /***********************************************************************\r
4092   <<< [Set2_alloc_imp] >>> \r
4093 ************************************************************************/\r
4094 errnum_t  Set2_alloc_imp( Set2* m, void* pp, size_t size )\r
4095 {\r
4096         errnum_t  e;\r
4097 \r
4098         e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;\r
4099         *(void**)pp = m->Next;\r
4100         m->Next = (char*) m->Next + size;\r
4101 \r
4102         DISCARD_BYTES( *(void**)pp, size );\r
4103 \r
4104         e=0;\r
4105 fin:\r
4106         return  e;\r
4107 }\r
4108 \r
4109 \r
4110 /***********************************************************************\r
4111   <<< [Set2_allocMulti_sub] >>> \r
4112 ************************************************************************/\r
4113 errnum_t  Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )\r
4114 {\r
4115         errnum_t  e;\r
4116         char*     p;\r
4117 \r
4118         e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;\r
4119         p = (char*) m->Next;\r
4120         m->Next = p + ElemsSize;\r
4121         *(char**)out_pElem = p;\r
4122 \r
4123         e=0;\r
4124 fin:\r
4125         return  e;\r
4126 }\r
4127 \r
4128 \r
4129  \r
4130 /***********************************************************************\r
4131   <<< [Set2_expandIfOverByAddr_imp] >>> \r
4132 ************************************************************************/\r
4133 errnum_t  Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )\r
4134 {\r
4135         errnum_t  e;\r
4136         void*     new_first;\r
4137         unsigned  offset_of_over;\r
4138         unsigned  offset_of_next;\r
4139 \r
4140         if ( OverAddrBasedOnNowFirst <= m->Over ) { e=E_OTHERS; goto fin; }\r
4141 \r
4142         offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );\r
4143         offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;\r
4144         IF_D( offset_of_next >= 0x80000000 ) { e=E_OTHERS; goto fin; }\r
4145         if ( offset_of_over == 0 ) { offset_of_over = 0x100; }\r
4146         while ( offset_of_over < offset_of_next ) { offset_of_over *= 2; }\r
4147         IF( offset_of_over >= 0x10000000 ) { e=E_OTHERS; goto fin; }\r
4148 \r
4149         new_first = realloc( m->First, offset_of_over * 2 );\r
4150                 IF( new_first == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
4151 \r
4152         m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );\r
4153         m->Over = (char*) new_first + offset_of_over * 2;\r
4154         m->First = new_first;\r
4155 \r
4156         #ifdef _DEBUG\r
4157         if ( m->PointerOfDebugArray != NULL )\r
4158                 { *m->PointerOfDebugArray = m->First; }\r
4159         #endif\r
4160 \r
4161         e=0;\r
4162 fin:\r
4163         return  e;\r
4164 }\r
4165 \r
4166 \r
4167  \r
4168 /***********************************************************************\r
4169   <<< [Set2_free_imp] >>> \r
4170 ************************************************************************/\r
4171 errnum_t  Set2_free_imp( Set2* self,  void* in_PointerOfPointer,  size_t  in_Size_ofElement,  errnum_t  e )\r
4172 {\r
4173         void*  element;\r
4174 \r
4175         element = *(void**) in_PointerOfPointer;\r
4176 \r
4177         if ( element != NULL ) {\r
4178                 if ( element != ( (byte_t*) self->Next - in_Size_ofElement ) ) {\r
4179                         if ( e == 0 ) { e=E_OTHERS; }\r
4180                 }\r
4181                 else {\r
4182                         #ifndef NDEBUG\r
4183                                 memset( element, 0xFE, in_Size_ofElement );\r
4184                         #endif\r
4185 \r
4186                         self->Next = element;\r
4187 \r
4188                         *(void**) in_PointerOfPointer = NULL;\r
4189                 }\r
4190         }\r
4191         return  e;\r
4192 }\r
4193 \r
4194 \r
4195  \r
4196 /***********************************************************************\r
4197   <<< [Set2_separate] >>> \r
4198 ************************************************************************/\r
4199 errnum_t  Set2_separate( Set2* m, int NextSize, void** allocate_Array )\r
4200 {\r
4201         errnum_t  e;\r
4202         void*     p = m->First;\r
4203 \r
4204         if ( NextSize == 0 ) {\r
4205                 m->First = NULL;\r
4206                 m->Next  = NULL;\r
4207                 m->Over  = NULL;\r
4208         }\r
4209         else {\r
4210                 e= Set2_init( m, NextSize ); IF(e)goto fin;\r
4211         }\r
4212         *allocate_Array = p;\r
4213 \r
4214         e=0;\r
4215 fin:\r
4216         return  e;\r
4217 }\r
4218 \r
4219 \r
4220  \r
4221 /***********************************************************************\r
4222   <<< [Set2_pop_imp] >>> \r
4223 ************************************************************************/\r
4224 errnum_t  Set2_pop_imp( Set2* m, void* pp, size_t size )\r
4225 {\r
4226         errnum_t  e;\r
4227         void*     p;\r
4228 \r
4229         p = (char*) m->Next - size;\r
4230 \r
4231         IF ( p < m->First ) { e=E_OTHERS; goto fin; }\r
4232 \r
4233         m->Next = p;\r
4234         *(void**)pp = p;\r
4235 \r
4236         e=0;\r
4237 fin:\r
4238         return  e;\r
4239 }\r
4240 \r
4241 \r
4242  \r
4243 /***********************************************************************\r
4244   <<< [Set2_setDebug] >>> \r
4245 ************************************************************************/\r
4246 #ifdef _DEBUG\r
4247 void  Set2_setDebug( Set2* m, void* PointerOfDebugArray )\r
4248 {\r
4249         m->PointerOfDebugArray = (void**) PointerOfDebugArray;\r
4250         *m->PointerOfDebugArray = m->First;\r
4251 }\r
4252 #endif\r
4253 \r
4254 \r
4255  \r
4256 /*=================================================================*/\r
4257 /* <<< [Print/Print2.c] >>> */ \r
4258 /*=================================================================*/\r
4259  \r
4260 /***********************************************************************\r
4261   <<< [vsprintf_r] >>> \r
4262 ************************************************************************/\r
4263 errnum_t  vsprintf_r( char* s, size_t s_size, const char* format, va_list va )\r
4264 {\r
4265         #if _MSC_VER\r
4266                 #pragma warning(push)\r
4267                 #pragma warning(disable: 4996)\r
4268         #endif\r
4269 \r
4270         int  r = _vsnprintf( s, s_size, format, va );\r
4271 \r
4272         #if _MSC_VER\r
4273                 #pragma warning(pop)\r
4274         #endif\r
4275 \r
4276         IF( r == (int) s_size )\r
4277                 { s[s_size-1] = '\0';  return E_FEW_ARRAY; }\r
4278         IF( r == -1 )\r
4279                 { return E_NOT_FOUND_SYMBOL; }  /* Bad character code */\r
4280 \r
4281         return  0;\r
4282 }\r
4283 \r
4284 \r
4285  \r
4286 /***********************************************************************\r
4287   <<< [vswprintf_r] >>> \r
4288 ************************************************************************/\r
4289 #ifndef  __linux__\r
4290 errnum_t  vswprintf_r( wchar_t* s, size_t s_size, const wchar_t* format, va_list va )\r
4291 {\r
4292         size_t  tsize = s_size / sizeof(wchar_t);\r
4293 \r
4294         #if _MSC_VER\r
4295                 #pragma warning(push)\r
4296                 #pragma warning(disable: 4996)\r
4297         #endif\r
4298 \r
4299         int  r = _vsnwprintf( s, tsize, format, va );\r
4300 \r
4301         #if _MSC_VER\r
4302                 #pragma warning(pop)\r
4303         #endif\r
4304 \r
4305         if ( r == (int) tsize || r == -1 ) { s[tsize-1] = '\0';  return E_FEW_ARRAY; }\r
4306         else  return  0;\r
4307 }\r
4308 #endif\r
4309 \r
4310 \r
4311  \r
4312 /***********************************************************************\r
4313   <<< [stprintf_r] >>> \r
4314 ************************************************************************/\r
4315 errnum_t  stprintf_r( TCHAR* s, size_t s_size, const TCHAR* format, ... )\r
4316 {\r
4317         errnum_t  e;\r
4318         va_list   va;\r
4319 \r
4320         va_start( va, format );\r
4321         e = vstprintf_r( s, s_size, format, va );\r
4322         va_end( va );\r
4323         return  e;\r
4324 }\r
4325 \r
4326 \r
4327  \r
4328 /***********************************************************************\r
4329   <<< [stcpy_part_r] >>> \r
4330 ************************************************************************/\r
4331 errnum_t  stcpy_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
4332                    const TCHAR* src, const TCHAR* src_over )\r
4333 {\r
4334         size_t  s_space = (char*)s + s_size - (char*)s_start;\r
4335         size_t  src_size;\r
4336 \r
4337         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size )  { return 1; }\r
4338 \r
4339         if ( src_over == NULL )  { src_over = StrT_chr( src, _T('\0') ); }\r
4340         IF_D( src > src_over )  { return 1; }\r
4341         src_size = (char*)src_over - (char*)src;\r
4342         IF ( src_size >= s_space ) {\r
4343                 s_space -= sizeof(TCHAR);\r
4344                 memcpy( s, src, s_space );\r
4345 \r
4346                 s_start = (TCHAR*)((char*)s_start + s_space );\r
4347                 *s_start = '\0';\r
4348 \r
4349                 if ( p_s_last != NULL ) { *p_s_last=s_start; }\r
4350                 return  E_FEW_ARRAY;\r
4351         }\r
4352 \r
4353         memcpy( s_start, src, src_size + sizeof(TCHAR) );\r
4354         s_start = (TCHAR*)((char*)s_start + src_size);  *s_start = _T('\0');\r
4355         if ( p_s_last != NULL )  { *p_s_last = s_start; }\r
4356 \r
4357         return  0;\r
4358 }\r
4359 \r
4360 \r
4361  \r
4362 /***********************************************************************\r
4363   <<< [stprintf_part_r] >>> \r
4364 ************************************************************************/\r
4365 errnum_t  stprintf_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
4366                       const TCHAR* format, ... )\r
4367 {\r
4368         errnum_t  e;\r
4369         va_list   va;\r
4370         va_start( va, format );\r
4371 \r
4372         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) {return E_OTHERS;}\r
4373 \r
4374         e = vstprintf_r( s_start, s_size - ( (char*)s_start - (char*)s), format, va );\r
4375         va_end( va );  if ( p_s_last != NULL )  *p_s_last = StrT_chr( s_start, '\0' );\r
4376         return  e;\r
4377 }\r
4378 \r
4379 \r
4380  \r
4381 /*=================================================================*/\r
4382 /* <<< [Lock_1/Lock_1.c] >>> */ \r
4383 /*=================================================================*/\r
4384  \r
4385 /*-------------------------------------------------------------------------*/\r
4386 /* <<<< ### (SingletonInitializerClass) implement >>>> */ \r
4387 /*-------------------------------------------------------------------------*/\r
4388 \r
4389 \r
4390 volatile int  g_SingletonInitializerClass_FailSleepTime = SingletonInitializerClass_FailSleepTime;\r
4391 \r
4392 \r
4393 /*[SingletonInitializerClass_isFirst]*/\r
4394 bool  SingletonInitializerClass_isFirst( SingletonInitializerClass* self )\r
4395 {\r
4396         for (;;) {\r
4397                 if ( InterlockedCompareExchange( &self->InitializeStep, 1, 0 ) == 0 ) {\r
4398                         return  true;\r
4399                 }\r
4400                 else {\r
4401                         while ( self->InitializeStep == 1 ) {\r
4402                                 Sleep( 0 );  /* Wait for initialized by other thread. */\r
4403                         }\r
4404 \r
4405                         if ( self->InitializeStep == 2 ) {\r
4406                                 return  false;\r
4407                         }\r
4408 \r
4409                         Sleep( g_SingletonInitializerClass_FailSleepTime );\r
4410                         g_SingletonInitializerClass_FailSleepTime = 0;\r
4411                 }\r
4412         }\r
4413 }\r
4414 \r
4415 \r
4416 /*[SingletonInitializerClass_onFinishedInitialize]*/\r
4417 void  SingletonInitializerClass_onFinishedInitialize( SingletonInitializerClass* self, errnum_t e )\r
4418 {\r
4419         if ( e == 0 )\r
4420                 { self->InitializeStep = 2; }\r
4421         else\r
4422                 { self->InitializeStep = 0; }\r
4423 }\r
4424 \r
4425 \r
4426 /*[SingletonInitializerClass_isInitialized]*/\r
4427 bool  SingletonInitializerClass_isInitialized( SingletonInitializerClass* self )\r
4428 {\r
4429         return  ( self->InitializeStep == 2 );\r
4430 }\r
4431 \r
4432 \r
4433 /*-------------------------------------------------------------------------*/\r
4434 /* <<< End of Class implement >>> */ \r
4435 /*-------------------------------------------------------------------------*/\r
4436 \r
4437 \r
4438  \r
4439 /*=================================================================*/\r
4440 /* <<< [CRT_plus_1/CRT_plus_1.c] >>> */ \r
4441 /*=================================================================*/\r
4442  \r
4443 /***********************************************************************\r
4444   <<< [ttoi_ex] >>> \r
4445 ************************************************************************/\r
4446 int  ttoi_ex( const TCHAR* string,  bit_flags_fast32_t options )\r
4447 {\r
4448         int  return_value;\r
4449 \r
4450         UNREFERENCED_VARIABLE( options);\r
4451 \r
4452         if ( string[0] == _T('0')  &&\r
4453                 ( string[1] == _T('x')  ||  string[1] == _T('X') ) )\r
4454         {\r
4455                 return_value = (int) _tcstoul( &string[2], NULL, 16 );\r
4456         }\r
4457         else {\r
4458                 return_value = _ttoi( string );\r
4459         }\r
4460 \r
4461         return  return_value;\r
4462 }\r
4463 \r
4464 \r
4465  \r