OSDN Git Service

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