OSDN Git Service

14c5e3957856a1b3b8586aea8c7f880240e79654
[vbslib/main.git] / _src / Test / tools / vbslib_helper_src / _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     AppKey_initGlobal_const(); \r
18 }\r
19 \r
20 \r
21  \r
22 /***********************************************************************\r
23   <<< [Globals_initialize] >>> \r
24 ************************************************************************/\r
25 int  Globals_initialize()\r
26 {\r
27   int  e;\r
28 \r
29     e= Locale_init(); IF(e)goto fin;\r
30 \r
31   e=0;\r
32   goto fin;  // for avoid warning of no goto fin\r
33 fin:\r
34   return  e;\r
35 }\r
36 \r
37 \r
38  \r
39 /***********************************************************************\r
40   <<< [Globals_finalize] >>> \r
41 ************************************************************************/\r
42 int  Globals_finalize( int e )\r
43 {\r
44     e= AppKey_finishGlobal( e ); \r
45 \r
46   return  e;\r
47 }\r
48 \r
49 \r
50  \r
51 /*=================================================================*/\r
52 /* <<< [PlatformSDK_plus/PlatformSDK_plus.c] >>> */ \r
53 /*=================================================================*/\r
54  \r
55 /***********************************************************************\r
56   <<< [GetCommandLineUnnamed] >>> \r
57 ************************************************************************/\r
58 int  GetCommandLineUnnamed( int Index1, TCHAR* out_AParam, size_t AParamSize )\r
59 {\r
60         TCHAR*  line = GetCommandLine();\r
61         int     index;\r
62         TCHAR*  p;\r
63         TCHAR*  p2;\r
64         TCHAR   c;\r
65 \r
66         #if UNDER_CE\r
67                 Index1 --;\r
68         #endif\r
69         IF( Index1 < 0 ) goto err_nf;\r
70         index = Index1;\r
71 \r
72         p = line;\r
73 \r
74         for (;;) {\r
75                 while ( *p == _T(' ') )  p++;\r
76 \r
77                 c = *p;\r
78 \r
79                 if ( c == _T('\0') )  goto err_nf;  // Here is not decided to error or not\r
80 \r
81 \r
82                 //=== Skip named option\r
83                 else if ( c == _T('/') ) {\r
84                         p++;\r
85                         for (;;) {\r
86                                 c = *p;\r
87                                 if ( c == _T('"') || c == _T(' ') || c == _T('\0') )  break;\r
88                                 p++;\r
89                         }\r
90 \r
91                         if ( c == _T('"') ) {\r
92                                 p++;\r
93                                 while ( *p != _T('"') && *p != _T('\0') )  p++;\r
94                                 if ( *p == _T('"') )  p++;\r
95                         }\r
96                 }\r
97 \r
98                 //=== Skip or Get unnamed parameter\r
99                 else {\r
100                         while ( *p == _T(' ') )  p++;\r
101 \r
102                         c = *p;\r
103                         p2 = p + 1;\r
104 \r
105                         if ( c == _T('"') ) {\r
106                                 p ++;\r
107                                 while ( *p2 != _T('"') && *p2 != _T('\0') )  p2++;\r
108                         }\r
109                         else {\r
110                                 while ( *p2 != _T(' ') && *p2 != _T('\0') )  p2++;\r
111                         }\r
112 \r
113                         if ( index == 0 ) {\r
114                                 int  e;\r
115 \r
116                                 e= stcpy_part_r( out_AParam, AParamSize, out_AParam, NULL, p, p2 );\r
117                                         ASSERT_D( !e, __noop() );\r
118                                 return  e;\r
119                         }\r
120                         else {\r
121                                 p = ( *p2 == _T('"') ) ? p2+1 : p2;\r
122                                 index --;\r
123                         }\r
124                 }\r
125         }\r
126 \r
127 err_nf:\r
128         if ( AParamSize >= sizeof(TCHAR) )  *out_AParam = _T('\0');\r
129         IF ( Index1 >= 2 )  return  E_NOT_FOUND_SYMBOL;\r
130         return  0;\r
131 }\r
132 \r
133 \r
134  \r
135 /***********************************************************************\r
136   <<< [GetCommandLineNamed] >>> \r
137 ************************************************************************/\r
138 int  GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize );\r
139 \r
140 int  GetCommandLineNamed( const TCHAR* Name, bool bCase, TCHAR* out_Value, size_t ValueSize )\r
141 {\r
142         bool  is_exist;\r
143         return  GetCommandLineNamed_sub( Name, bCase, &is_exist, out_Value, ValueSize );\r
144 }\r
145 \r
146 \r
147 int  GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize )\r
148 {\r
149         TCHAR*  line = GetCommandLine();\r
150         TCHAR*  p;\r
151         TCHAR*  p2;\r
152         TCHAR   c;\r
153         const size_t  name_len = _tcslen( Name );\r
154         bool    bMatch;\r
155 \r
156         *out_IsExist = true;\r
157 \r
158         p = line;\r
159         for (;;) {\r
160                 c = *p;\r
161 \r
162                 //=== Compare option name\r
163                 if ( c == _T('/') ) {\r
164                         p++;\r
165                         p2 = p;\r
166                         for (;;) {\r
167                                 c = *p2;\r
168                                 if ( c == _T(':') || c == _T(' ') || c == _T('\0') )  break;\r
169                                 p2++;\r
170                         }\r
171                         if ( bCase )\r
172                                 bMatch = ( p2-p == (int)name_len && _tcsncmp( p, Name, p2-p ) == 0 );\r
173                         else\r
174                                 bMatch = ( p2-p == (int)name_len && _tcsnicmp( p, Name, p2-p ) == 0 );\r
175 \r
176 \r
177                         //=== Get the value\r
178                         if ( c == _T(':') ) {\r
179                                 p = p2 + 1;\r
180                                 if ( *p == _T('"') ) {\r
181                                         p++;\r
182                                         p2 = p;\r
183                                         while ( *p2 != _T('"') && *p2 != _T('\0') )  p2++;\r
184                                         if ( bMatch )\r
185                                                 return  stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );\r
186                                         else\r
187                                                 p = p2+1;\r
188                                 }\r
189                                 else {\r
190                                         p2 = p;\r
191                                         while ( *p2 != _T(' ') && *p2 != _T('\0') )  p2++;\r
192                                         if ( bMatch )\r
193                                                 return  stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );\r
194                                         else\r
195                                                 p = p2;\r
196                                 }\r
197                         }\r
198                         else {\r
199                                 IF( bMatch ) return  E_NOT_FOUND_SYMBOL;  // no value error\r
200                         }\r
201                 }\r
202 \r
203                 else if ( c == _T('\0') )  break;\r
204 \r
205                 //=== Skip\r
206                 else if ( c == _T('"') ) {\r
207                         p++;\r
208                         while ( *p != _T('"') && *p != _T('\0') )  p++;\r
209                         while ( *p != _T(' ') && *p != _T('\0') )  p++;\r
210                 }\r
211                 else {\r
212                         while ( *p != _T(' ') && *p != _T('\0') )  p++;\r
213                 }\r
214                 while ( *p == _T(' ') )  p++;\r
215         }\r
216 \r
217         *out_IsExist = false;\r
218         return  E_NOT_FOUND_SYMBOL;\r
219 }\r
220 \r
221 \r
222  \r
223 /***********************************************************************\r
224   <<< [GetCommandLineNamedI] >>> \r
225 ************************************************************************/\r
226 int  GetCommandLineNamedI( const TCHAR* Name, bool bCase, int* out_Value )\r
227 {\r
228         int    e;\r
229         bool   is_exist;\r
230         TCHAR  s[20];\r
231 \r
232         e= GetCommandLineNamed_sub( Name, bCase, &is_exist, s, sizeof(s) ); IF(e)goto fin;  //[out] s\r
233         if ( s[0] == _T('0') && s[1] == _T('x') )\r
234                 *out_Value = _tcstoul( s, NULL, 16 );\r
235         else\r
236                 *out_Value = _ttoi( s );\r
237         //e=0;\r
238 fin:\r
239         return  e;\r
240 }\r
241 \r
242 \r
243  \r
244 /***********************************************************************\r
245   <<< [GetCommandLineNamedC8] >>> \r
246 ************************************************************************/\r
247 #if  _UNICODE\r
248 int  GetCommandLineNamedC8( const TCHAR* Name, bool bCase, char* out_Value, size_t ValueSize )\r
249 {\r
250         int     e;\r
251         bool    is_exist;\r
252         TCHAR*  s = NULL;\r
253 \r
254         s = (TCHAR*) malloc( ValueSize * sizeof(TCHAR) );\r
255         e= GetCommandLineNamed_sub( Name, bCase, &is_exist, (TCHAR*) s, ValueSize * sizeof(TCHAR) ); IF(e)goto fin;\r
256 \r
257         sprintf_s( out_Value, ValueSize, "%S", s );\r
258 fin:\r
259         if ( s != NULL )  free( s );\r
260         return  e;\r
261 }\r
262 #endif\r
263 \r
264 \r
265  \r
266 /***********************************************************************\r
267   <<< [GetCommandLineExist] >>> \r
268 ************************************************************************/\r
269 bool  GetCommandLineExist( const TCHAR* Name, bool bCase )\r
270 {\r
271         int     e;\r
272         bool    is_exist;\r
273         TCHAR   v[1];\r
274 \r
275         e = GetCommandLineNamed_sub( Name, bCase, &is_exist, v, sizeof(v) );\r
276         if ( e == E_NOT_FOUND_SYMBOL )  ClearError();\r
277         return  is_exist;\r
278 }\r
279 \r
280 \r
281  \r
282 /***********************************************************************\r
283   <<< [env_part] >>> \r
284 ************************************************************************/\r
285 int  env_part( TCHAR* Str,  unsigned StrSize,  TCHAR* StrStart, TCHAR** out_StrLast,\r
286          const TCHAR* Input )\r
287 {\r
288         int  e;\r
289         const TCHAR*  p;\r
290         const TCHAR*  p2;\r
291         TCHAR*  o;\r
292         TCHAR*  o_last;\r
293         TCHAR   c;\r
294         DWORD   r;\r
295         DWORD   count;\r
296         TCHAR   name[128];\r
297 \r
298         p = Input;  o = StrStart;  o_last = (TCHAR*)( (char*)Str + StrSize - sizeof(TCHAR) );\r
299         IF_D( StrStart < Str || StrStart >= o_last ) goto err;\r
300 \r
301         c = *p;\r
302         IF_D( StrSize <= 2 ) return  E_FEW_ARRAY;\r
303 \r
304         while ( c != _T('\0') ) {\r
305                 if ( c == _T('%') ) {\r
306                         p++;\r
307                         if ( *p == _T('%') ) {\r
308 \r
309                                 //=== % \95\8e\9a\82ð\83R\83s\81[\82·\82é\r
310                                 IF( o == o_last )goto err_fa;\r
311                                 *o = c;\r
312                                 p++;  o++;\r
313                         }\r
314                         else {\r
315 \r
316                                 //=== \8aÂ\8b«\95Ï\90\94\96¼\82ð name \82É\8eæ\93¾\82·\82é\r
317                                 p2 = _tcschr( p, _T('%') ); IF( p2 == NULL )goto err_ns;\r
318                                 e= StrT_cpy( name, sizeof(name), _T("abc") ); IF(e)goto fin;\r
319                                 e= stcpy_part_r( name, sizeof(name), name, NULL, p, p2 ); IF(e)goto fin;\r
320 \r
321                                 //=== \8aÂ\8b«\95Ï\90\94\82Ì\92l\82ð o \82É\8eæ\93¾\82·\82é\r
322                                 count = ( o_last + sizeof(TCHAR) - o ) / sizeof(TCHAR);\r
323                                 r= GetEnvironmentVariable( name, o, count );\r
324                                 IF( r==0 ) goto err_ns;  // \8aÂ\8b«\95Ï\90\94\82ª\8c©\82Â\82©\82ç\82È\82¢\r
325                                 IF( r > count ) goto err_fa;\r
326 \r
327                                 //=== p, o \82ð\8dX\90V\82·\82é\r
328                                 p = p2 + 1;\r
329                                 o = _tcschr( o, _T('\0') );\r
330                         }\r
331                 }\r
332                 else {\r
333 \r
334                         //=== \8aÂ\8b«\95Ï\90\94\82Å\82Í\82È\82¢\95\94\95ª\82ð\83R\83s\81[\82·\82é\r
335                         IF( o == o_last )goto err_fa;\r
336                         *o = c;\r
337                         p++;  o++;\r
338                 }\r
339                 c = *p;\r
340         }\r
341 \r
342         e=0;\r
343 fin:\r
344         *o = _T('\0');\r
345         if ( out_StrLast != NULL )  *out_StrLast = o;\r
346         return  e;\r
347 \r
348 err_fa:  e = E_FEW_ARRAY;  goto fin;\r
349 err_ns:  e = E_NOT_FOUND_SYMBOL; goto fin;\r
350 err:  e = E_OTHERS;  goto fin;\r
351 }\r
352 \r
353 \r
354  \r
355 /***********************************************************************\r
356   <<< [env_malloc] >>> \r
357 ************************************************************************/\r
358 int  env_malloc( TCHAR** out_Value, size_t* out_ValueLen, const TCHAR* Name )\r
359 {\r
360         int     e;\r
361         DWORD   r;\r
362         TCHAR*  value = NULL;\r
363 \r
364         r= GetEnvironmentVariable( Name, NULL, 0 );\r
365         if ( r == 0 ) {\r
366                 *out_Value = NULL;\r
367                 return  0;  // \8aÂ\8b«\95Ï\90\94\82ª\92è\8b`\82³\82ê\82Ä\82¢\82È\82¢\82Æ\82«\82Å\82à\81A\83G\83\89\81[\82É\82µ\82È\82¢\r
368         }\r
369 \r
370         value = (TCHAR*) malloc( r * sizeof(TCHAR) );\r
371         IF( value == NULL ) goto err_fm;\r
372         GetEnvironmentVariable( Name, value, r );\r
373 \r
374         *out_Value = value;\r
375         if ( out_ValueLen != NULL )  *out_ValueLen = r - 1;\r
376 \r
377         e=0;\r
378 fin:\r
379         return  e;\r
380 \r
381 err_fm:  e = E_FEW_MEMORY;  goto fin;\r
382 }\r
383 \r
384 \r
385  \r
386 /*=================================================================*/\r
387 /* <<< [Parse2/Parse2.c] >>> */ \r
388 /*=================================================================*/\r
389  \r
390 /***********************************************************************\r
391   <<< [Parse_PP_Directive] >>> \r
392 ************************************************************************/\r
393 \r
394 errnum_t  Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray );\r
395 errnum_t  Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray );\r
396 errnum_t  Parse_PP_Directive_Parameter( Set2* DirectivePointerArray );\r
397 \r
398 \r
399 errnum_t  Parse_PP_Directive( const TCHAR* Text,\r
400         Set2* /*<PP_DirectiveClass*>*/ DirectivePointerArray )\r
401 {\r
402         errnum_t  e;\r
403 \r
404         e= Parse_PP_Directive_Step1( Text, DirectivePointerArray ); IF(e){goto fin;}\r
405         e= Parse_PP_Directive_ConnectIf( DirectivePointerArray ); IF(e){goto fin;}\r
406         e= Parse_PP_Directive_Parameter( DirectivePointerArray ); IF(e){goto fin;}\r
407 \r
408         e=0;\r
409 fin:\r
410         return  e;\r
411 }\r
412 \r
413 \r
414 /*[Parse_PP_Directive_Step1]*/\r
415 errnum_t  Parse_PP_Directive_Step1( const TCHAR* Text, Set2* DirectivePointerArray )\r
416 {\r
417         errnum_t      e;\r
418         const TCHAR*  pos;\r
419         const TCHAR*  p;\r
420         PP_DirectiveClass*   directive = NULL;\r
421         PP_DirectiveClass    directive_0;\r
422         PP_DirectiveClass**  directive_pp;\r
423         ClassID_Class*       class_ID;\r
424 \r
425         pos = Text;\r
426         PP_DirectiveClass_initConst( &directive_0 );\r
427 \r
428         for (;;) {\r
429 \r
430                 /* Set "DirectiveName_Start" */\r
431                 p = _tcschr( pos, _T('#') );\r
432                 if ( p == NULL )\r
433                         { break; }\r
434                 p = StrT_skip( p + 1, _T(" \t") );\r
435                         ASSERT_R( *p != _T('\0'), e=E_OTHERS; goto fin );\r
436                 directive_0.DirectiveName_Start = p;\r
437 \r
438 \r
439                 /* Set "DirectiveName_Over" */\r
440                 directive_0.DirectiveName_Over =\r
441                         StrT_searchOverOfCIdentifier( directive_0.DirectiveName_Start );\r
442 \r
443 \r
444                 /* Set "Start" */\r
445                 p = StrT_rstr( Text, directive_0.DirectiveName_Start, _T("\n"), NULL );\r
446                 if ( p == NULL )  { p = Text; }\r
447                 else              { p += 1; }\r
448                 directive_0.Start = p;\r
449 \r
450 \r
451                 /* Set "Over" */\r
452                 p = directive_0.DirectiveName_Over;\r
453                 for (;;) {\r
454                         const TCHAR*  p2 = _tcschr( p, _T('\n') );\r
455                         if ( p2 == NULL ) {\r
456                                 p = _tcschr( p, _T('\0') );\r
457                                 break;\r
458                         } else if ( *( p2 - 1 ) == _T('\\') ) {\r
459                                 p = p2 + 1;\r
460                                 continue;\r
461                         } else {\r
462                                 p = p2 + 1;\r
463                                 break;\r
464                         }\r
465                 }\r
466                 directive_0.Over = p;\r
467 \r
468 \r
469                 /* Set "directive" */\r
470                 {\r
471                         static NameOnlyClass  table[] = {\r
472                                 { _T("define"), (void*) &g_PP_SharpDefineClass_ID },\r
473                                 { _T("include"),(void*) &g_PP_SharpIncludeClass_ID },\r
474                                 { _T("if"),     (void*) &g_PP_SharpIfClass_ID },\r
475                                 { _T("else"),   (void*) &g_PP_SharpElseClass_ID },\r
476                                 { _T("endif"),  (void*) &g_PP_SharpEndifClass_ID },\r
477                                 { _T("ifdef"),  (void*) &g_PP_SharpIfdefClass_ID },\r
478                                 { _T("ifndef"), (void*) &g_PP_SharpIfndefClass_ID },\r
479                         };\r
480 \r
481                         class_ID = StrT_convPartStrToPointer(\r
482                                 directive_0.DirectiveName_Start,\r
483                                 directive_0.DirectiveName_Over,\r
484                                 table, sizeof(table), (void*) &g_PP_DirectiveClass_ID );\r
485                 }\r
486 \r
487                 e= ClassID_Class_createObject( class_ID, &directive, NULL ); IF(e){goto fin;}\r
488 \r
489                 directive->DirectiveName_Start = directive_0.DirectiveName_Start;\r
490                 directive->DirectiveName_Over  = directive_0.DirectiveName_Over;\r
491                 directive->Start = directive_0.Start;\r
492                 directive->Over  = directive_0.Over;\r
493 \r
494 \r
495                 /* Add to "DirectivePointerArray" (1) */\r
496                 e= Set2_alloc( DirectivePointerArray, &directive_pp, PP_DirectiveClass* );\r
497                         IF(e){goto fin;}\r
498 \r
499 \r
500                 /* Add to "DirectivePointerArray" (2) */\r
501                 *directive_pp = directive;\r
502                 directive = NULL;\r
503 \r
504 \r
505                 /* Next */\r
506                 pos = directive_0.Over;\r
507                 PP_DirectiveClass_initConst( &directive_0 );\r
508         }\r
509 \r
510         e=0;\r
511 fin:\r
512         if ( directive != NULL )  { e= HeapMemory_free( &directive, e ); }\r
513         return  e;\r
514 }\r
515 \r
516 \r
517 /*[Parse_PP_Directive_ConnectIf]*/\r
518 errnum_t  Parse_PP_Directive_ConnectIf( Set2* DirectivePointerArray )\r
519 {\r
520         errnum_t             e;\r
521         PP_DirectiveClass**  pp;\r
522         PP_DirectiveClass**  pp_over;\r
523         PP_DirectiveClass*   directive;\r
524         PP_SharpIfClass**    pp_sh_if;  /* pp is pointer of pointer, sh = sharp */\r
525         PP_SharpElseClass**  pp_sh_else;\r
526         Set2                 if_stack;\r
527         Set2                 else_stack;\r
528         PP_SharpIfClass*     sh_if;          /* sh = sharp */\r
529         PP_SharpElseClass*   sh_else;        /* sh = sharp */\r
530         PP_SharpEndifClass*  sh_endif;       /* sh = sharp */\r
531         PP_DirectiveClass*   sh_if_or_else;  /* sh = sharp */\r
532 \r
533 \r
534         Set2_initConst( &if_stack );\r
535         Set2_initConst( &else_stack );\r
536         e= Set2_init( &if_stack, 0x10 ); IF(e){goto fin;}\r
537         e= Set2_init( &else_stack, 0x10 ); IF(e){goto fin;}\r
538         sh_if         = NULL;\r
539         sh_else       = NULL;\r
540         sh_endif      = NULL;\r
541         sh_if_or_else = NULL;\r
542 \r
543         for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
544                 directive = *pp;\r
545 \r
546                 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfClass_ID ) ) {\r
547 \r
548                         /* Start of nest */\r
549                         if ( sh_if_or_else != NULL ) {\r
550                                 e= Set2_alloc( &if_stack, &pp_sh_if, PP_SharpIfClass* );\r
551                                         IF(e){goto fin;}\r
552                                 *pp_sh_if = sh_if;\r
553 \r
554                                 e= Set2_alloc( &else_stack, &pp_sh_else, PP_SharpElseClass* );\r
555                                         IF(e){goto fin;}\r
556                                 *pp_sh_else = sh_else;\r
557                         }\r
558 \r
559                         /* Set "sh_if" */\r
560                         sh_if = (PP_SharpIfClass*) directive;\r
561                         sh_if_or_else = directive;\r
562                 }\r
563                 else if ( directive->ClassID == &g_PP_SharpElseClass_ID ) {\r
564                         sh_else = (PP_SharpElseClass*) directive;\r
565 \r
566                         IF ( sh_if == NULL ) {\r
567                                 Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );\r
568                                 e= E_ORIGINAL; goto fin;\r
569                         }\r
570 \r
571                         /* Link #if and #else */\r
572                         sh_if->NextDirective = directive;\r
573                         sh_else->StartDirective = sh_if;\r
574                         sh_if_or_else = directive;\r
575                 }\r
576                 else if ( directive->ClassID == &g_PP_SharpEndifClass_ID ) {\r
577                         sh_endif = (PP_SharpEndifClass*) directive;\r
578 \r
579                         IF ( sh_if_or_else == NULL ) {\r
580                                 Error4_printf( _T("<ERROR msg=\"Not found #if\"/>") );\r
581                                 e= E_ORIGINAL; goto fin;\r
582                         }\r
583 \r
584                         /* Link ( #if or #else ) and #endif */\r
585                         sh_if->EndDirective = sh_endif;\r
586                         if ( sh_else == NULL )\r
587                                 { sh_if->NextDirective = directive; }\r
588                         else\r
589                                 { sh_else->EndDirective = sh_endif; }\r
590                         sh_endif->StartDirective = sh_if;\r
591                         sh_endif->PreviousDirective = sh_if_or_else;\r
592 \r
593                         sh_if         = NULL;\r
594                         sh_else       = NULL;\r
595                         sh_endif      = NULL;\r
596                         sh_if_or_else = NULL;\r
597 \r
598                         /* End of nest */\r
599                         if ( if_stack.Next > if_stack.First ) {\r
600                                 e= Set2_pop( &if_stack, &pp_sh_if, PP_SharpIfClass* );\r
601                                         IF(e){goto fin;}\r
602                                 sh_if = *pp_sh_if;\r
603 \r
604                                 e= Set2_pop( &else_stack, &pp_sh_else, PP_SharpElseClass* );\r
605                                         IF(e){goto fin;}\r
606                                 sh_else = *pp_sh_else;\r
607 \r
608                                 if ( sh_else == NULL ) {\r
609                                         sh_if_or_else = (PP_DirectiveClass*) sh_if;\r
610                                 } else {\r
611                                         sh_if_or_else = (PP_DirectiveClass*) sh_else;\r
612                                 }\r
613                         }\r
614                 }\r
615         }\r
616 \r
617         e=0;\r
618 fin:\r
619         e= Set2_finish( &if_stack, e );\r
620         e= Set2_finish( &else_stack, e );\r
621         return  e;\r
622 }\r
623 \r
624 \r
625 /*[Parse_PP_Directive_Parameter]*/\r
626 errnum_t  Parse_PP_Directive_Parameter( Set2* DirectivePointerArray )\r
627 {\r
628         errnum_t             e;\r
629         TCHAR*               p;\r
630         PP_DirectiveClass**  pp;\r
631         PP_DirectiveClass**  pp_over;\r
632         PP_DirectiveClass*   directive;\r
633 \r
634         for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
635                 directive = *pp;\r
636 \r
637                 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpDefineClass_ID ) ) {\r
638                         PP_SharpDefineClass*  sh_define = (PP_SharpDefineClass*) directive;\r
639 \r
640                         p = StrT_skip( sh_define->DirectiveName_Over, _T(" \t") );\r
641                         IF ( p >= sh_define->Over ) { e=E_OTHERS; goto fin; }\r
642                         sh_define->Symbol_Start = p;\r
643 \r
644                         p = StrT_searchOverOfCIdentifier( p );\r
645                         sh_define->Symbol_Over = p;\r
646                 }\r
647 \r
648                 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIncludeClass_ID ) ) {\r
649                         TCHAR*                 p;\r
650                         TCHAR*                 closers;\r
651                         PP_SharpIncludeClass*  sh_include = (PP_SharpIncludeClass*) directive;\r
652 \r
653                         p = StrT_skip( sh_include->DirectiveName_Over, _T(" \t") );\r
654                         IF ( p >= sh_include->Over ) { e=E_OTHERS; goto fin; }\r
655                         switch ( *p ) {\r
656                                 case  '<':\r
657                                         sh_include->PathBracket = _T('<');\r
658                                         closers = _T(">");\r
659                                         break;\r
660 \r
661                                 case  '"':\r
662                                         sh_include->PathBracket = _T('"');\r
663                                         closers = _T("\"");\r
664                                         break;\r
665 \r
666                                 default:\r
667                                         sh_include->PathBracket = _T('\0');\r
668                                         closers = _T(" \t\n");\r
669                                         break;\r
670                         }\r
671 \r
672                         sh_include->Path_Start = p + 1;\r
673 \r
674                         p = StrT_chrs( p + 1, closers );\r
675                                 IF ( p == NULL ) { e=E_OTHERS; goto fin; }\r
676                         sh_include->Path_Over = p;\r
677                 }\r
678 \r
679                 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {\r
680                         TCHAR*  p;\r
681                         PP_SharpIfdefClass*  sh_ifdef;    /* sh = sharp */\r
682 \r
683                         sh_ifdef = (PP_SharpIfdefClass*) directive;\r
684 \r
685                         p = StrT_skip( sh_ifdef->DirectiveName_Over, _T(" \t") );\r
686                         IF ( p >= sh_ifdef->Over ) { e=E_OTHERS; goto fin; }\r
687                         sh_ifdef->Symbol_Start = p;\r
688 \r
689                         p = StrT_searchOverOfCIdentifier( p );\r
690                         sh_ifdef->Symbol_Over = p;\r
691                 }\r
692         }\r
693 \r
694         e=0;\r
695 fin:\r
696         return  e;\r
697 }\r
698 \r
699 \r
700  \r
701 /***********************************************************************\r
702   <<< [Delete_PP_Directive] >>> \r
703 ************************************************************************/\r
704 errnum_t  Delete_PP_Directive( Set2* DirectivePointerArray, errnum_t e )\r
705 {\r
706         PP_DirectiveClass**    pp;\r
707         PP_DirectiveClass**    pp_over;\r
708         PP_DirectiveClass*     directive;\r
709         FinalizerVTableClass*  finalizer;\r
710 \r
711         if ( Set2_isInited( DirectivePointerArray ) ) {\r
712                 for ( Set2_forEach( DirectivePointerArray, &pp, &pp_over, PP_DirectiveClass* ) ) {\r
713                         directive = *pp;\r
714                         finalizer = ClassID_Class_getVTable( directive->ClassID,\r
715                                 &g_FinalizerInterface_ID );\r
716                         e= finalizer->Finalize( directive, e );\r
717                         e= HeapMemory_free( &directive, e );\r
718                 }\r
719 \r
720                 e= Set2_finish( DirectivePointerArray, e );\r
721         }\r
722         return  e;\r
723 }\r
724 \r
725 \r
726  \r
727 /***********************************************************************\r
728   <<< (PP_DirectiveClass) >>> \r
729 ************************************************************************/\r
730 \r
731 /*[PP_DirectiveClass_initConst]*/\r
732 void  PP_DirectiveClass_initConst( PP_DirectiveClass* self )\r
733 {\r
734         self->ClassID  = &g_PP_DirectiveClass_ID;\r
735         self->Start    = NULL;\r
736         self->Over     = NULL;\r
737         self->DirectiveName_Start = NULL;\r
738         self->DirectiveName_Over  = NULL;\r
739 }\r
740 \r
741 /*[g_PP_DirectiveClass_ID]*/\r
742 static const ClassID_Class*  gs_PP_DirectiveClass_SuperClassIDs[] = {\r
743         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
744 };\r
745 static const FinalizerVTableClass  gs_PP_DirectiveClass_FinalizerVTable = {\r
746         offsetof( PP_DirectiveClass, FinalizerVTable ),\r
747         DefaultFunction_Finalize\r
748 };\r
749 static const InterfaceToVTableClass  gs_PP_DirectiveClass_InterfaceToVTables[] = {\r
750         { &g_FinalizerInterface_ID, &gs_PP_DirectiveClass_FinalizerVTable }\r
751 };\r
752 const ClassID_Class  g_PP_DirectiveClass_ID = {\r
753         "PP_DirectiveClass",\r
754         gs_PP_DirectiveClass_SuperClassIDs,\r
755         _countof( gs_PP_DirectiveClass_SuperClassIDs ),\r
756         sizeof( PP_DirectiveClass ),\r
757         NULL,\r
758         gs_PP_DirectiveClass_InterfaceToVTables,\r
759         _countof( gs_PP_DirectiveClass_InterfaceToVTables )\r
760 };\r
761 \r
762 \r
763 /*[g_PP_SharpDefineClass_ID]*/\r
764 static const ClassID_Class*  gs_PP_SharpDefineClass_SuperClassIDs[] = {\r
765         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
766         &g_PP_DirectiveClass_ID\r
767 };\r
768 static const FinalizerVTableClass  gs_PP_SharpDefineClass_FinalizerVTable = {\r
769         offsetof( PP_SharpDefineClass, FinalizerVTable ),\r
770         DefaultFunction_Finalize\r
771 };\r
772 static const InterfaceToVTableClass  gs_PP_SharpDefineClass_InterfaceToVTables[] = {\r
773         { &g_FinalizerInterface_ID, &gs_PP_SharpDefineClass_FinalizerVTable }\r
774 };\r
775 const ClassID_Class  g_PP_SharpDefineClass_ID = {\r
776         "PP_SharpDefineClass",\r
777         gs_PP_SharpDefineClass_SuperClassIDs,\r
778         _countof( gs_PP_SharpDefineClass_SuperClassIDs ),\r
779         sizeof( PP_SharpDefineClass ),\r
780         NULL,\r
781         gs_PP_SharpDefineClass_InterfaceToVTables,\r
782         _countof( gs_PP_SharpDefineClass_InterfaceToVTables )\r
783 };\r
784 \r
785 \r
786 /*[g_PP_SharpIncludeClass_ID]*/\r
787 static const ClassID_Class*  gs_PP_SharpIncludeClass_SuperClassIDs[] = {\r
788         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
789         &g_PP_DirectiveClass_ID\r
790 };\r
791 static const FinalizerVTableClass  gs_PP_SharpIncludeClass_FinalizerVTable = {\r
792         offsetof( PP_SharpIncludeClass, FinalizerVTable ),\r
793         DefaultFunction_Finalize\r
794 };\r
795 static const InterfaceToVTableClass  gs_PP_SharpIncludeClass_InterfaceToVTables[] = {\r
796         { &g_FinalizerInterface_ID, &gs_PP_SharpIncludeClass_FinalizerVTable }\r
797 };\r
798 const ClassID_Class  g_PP_SharpIncludeClass_ID = {\r
799         "PP_SharpIncludeClass",\r
800         gs_PP_SharpIncludeClass_SuperClassIDs,\r
801         _countof( gs_PP_SharpIncludeClass_SuperClassIDs ),\r
802         sizeof( PP_SharpIncludeClass ),\r
803         NULL,\r
804         gs_PP_SharpIncludeClass_InterfaceToVTables,\r
805         _countof( gs_PP_SharpIncludeClass_InterfaceToVTables )\r
806 };\r
807 \r
808 \r
809 /*[g_PP_SharpIfClass_ID]*/\r
810 static const ClassID_Class*  gs_PP_SharpIfClass_SuperClassIDs[] = {\r
811         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
812         &g_PP_DirectiveClass_ID\r
813 };\r
814 static const FinalizerVTableClass  gs_PP_SharpIfClass_FinalizerVTable = {\r
815         offsetof( PP_SharpIfClass, FinalizerVTable ),\r
816         DefaultFunction_Finalize\r
817 };\r
818 static const InterfaceToVTableClass  gs_PP_SharpIfClass_InterfaceToVTables[] = {\r
819         { &g_FinalizerInterface_ID, &gs_PP_SharpIfClass_FinalizerVTable }\r
820 };\r
821 const ClassID_Class  g_PP_SharpIfClass_ID = {\r
822         "PP_SharpIfClass",\r
823         gs_PP_SharpIfClass_SuperClassIDs,\r
824         _countof( gs_PP_SharpIfClass_SuperClassIDs ),\r
825         sizeof( PP_SharpIfClass ),\r
826         NULL,\r
827         gs_PP_SharpIfClass_InterfaceToVTables,\r
828         _countof( gs_PP_SharpIfClass_InterfaceToVTables )\r
829 };\r
830 \r
831 \r
832 /*[g_PP_SharpElseClass_ID]*/\r
833 static const ClassID_Class*  gs_PP_SharpElseClass_SuperClassIDs[] = {\r
834         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
835         &g_PP_DirectiveClass_ID\r
836 };\r
837 static const FinalizerVTableClass  gs_PP_SharpElseClass_FinalizerVTable = {\r
838         offsetof( PP_SharpElseClass, FinalizerVTable ),\r
839         DefaultFunction_Finalize\r
840 };\r
841 static const InterfaceToVTableClass  gs_PP_SharpElseClass_InterfaceToVTables[] = {\r
842         { &g_FinalizerInterface_ID, &gs_PP_SharpElseClass_FinalizerVTable }\r
843 };\r
844 const ClassID_Class  g_PP_SharpElseClass_ID = {\r
845         "PP_SharpElseClass",\r
846         gs_PP_SharpElseClass_SuperClassIDs,\r
847         _countof( gs_PP_SharpElseClass_SuperClassIDs ),\r
848         sizeof( PP_SharpElseClass ),\r
849         NULL,\r
850         gs_PP_SharpElseClass_InterfaceToVTables,\r
851         _countof( gs_PP_SharpElseClass_InterfaceToVTables )\r
852 };\r
853 \r
854 \r
855 /*[g_PP_SharpEndifClass_ID]*/\r
856 static const ClassID_Class*  gs_PP_SharpEndifClass_SuperClassIDs[] = {\r
857         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
858         &g_PP_DirectiveClass_ID\r
859 };\r
860 static const FinalizerVTableClass  gs_PP_SharpEndifClass_FinalizerVTable = {\r
861         offsetof( PP_SharpEndifClass, FinalizerVTable ),\r
862         DefaultFunction_Finalize\r
863 };\r
864 static const InterfaceToVTableClass  gs_PP_SharpEndifClass_InterfaceToVTables[] = {\r
865         { &g_FinalizerInterface_ID, &gs_PP_SharpEndifClass_FinalizerVTable }\r
866 };\r
867 const ClassID_Class  g_PP_SharpEndifClass_ID = {\r
868         "PP_SharpEndifClass",\r
869         gs_PP_SharpEndifClass_SuperClassIDs,\r
870         _countof( gs_PP_SharpEndifClass_SuperClassIDs ),\r
871         sizeof( PP_SharpEndifClass ),\r
872         NULL,\r
873         gs_PP_SharpEndifClass_InterfaceToVTables,\r
874         _countof( gs_PP_SharpEndifClass_InterfaceToVTables )\r
875 };\r
876 \r
877 \r
878 /*[g_PP_SharpIfdefClass_ID]*/\r
879 static const ClassID_Class*  gs_PP_SharpIfdefClass_SuperClassIDs[] = {\r
880         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
881         &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID\r
882 };\r
883 static const FinalizerVTableClass  gs_PP_SharpIfdefClass_FinalizerVTable = {\r
884         offsetof( PP_SharpIfdefClass, FinalizerVTable ),\r
885         DefaultFunction_Finalize\r
886 };\r
887 static const InterfaceToVTableClass  gs_PP_SharpIfdefClass_InterfaceToVTables[] = {\r
888         { &g_FinalizerInterface_ID, &gs_PP_SharpIfdefClass_FinalizerVTable }\r
889 };\r
890 const ClassID_Class  g_PP_SharpIfdefClass_ID = {\r
891         "PP_SharpIfdefClass",\r
892         gs_PP_SharpIfdefClass_SuperClassIDs,\r
893         _countof( gs_PP_SharpIfdefClass_SuperClassIDs ),\r
894         sizeof( PP_SharpIfdefClass ),\r
895         NULL,\r
896         gs_PP_SharpIfdefClass_InterfaceToVTables,\r
897         _countof( gs_PP_SharpIfdefClass_InterfaceToVTables )\r
898 };\r
899 \r
900 \r
901 /*[g_PP_SharpIfndefClass_ID]*/\r
902 static const ClassID_Class*  gs_PP_SharpIfndefClass_SuperClassIDs[] = {\r
903         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID,\r
904         &g_PP_DirectiveClass_ID, &g_PP_SharpIfClass_ID, &g_PP_SharpIfdefClass_ID\r
905 };\r
906 static const FinalizerVTableClass  gs_PP_SharpIfndefClass_FinalizerVTable = {\r
907         offsetof( PP_SharpIfndefClass, FinalizerVTable ),\r
908         DefaultFunction_Finalize\r
909 };\r
910 static const InterfaceToVTableClass  gs_PP_SharpIfndefClass_InterfaceToVTables[] = {\r
911         { &g_FinalizerInterface_ID, &gs_PP_SharpIfndefClass_FinalizerVTable }\r
912 };\r
913 \r
914 const ClassID_Class  g_PP_SharpIfndefClass_ID = {\r
915         "PP_SharpIfndefClass",\r
916         gs_PP_SharpIfndefClass_SuperClassIDs,\r
917         _countof( gs_PP_SharpIfndefClass_SuperClassIDs ),\r
918         sizeof( PP_SharpIfndefClass ),\r
919         NULL,\r
920         gs_PP_SharpIfndefClass_InterfaceToVTables,\r
921         _countof( gs_PP_SharpIfndefClass_InterfaceToVTables )\r
922 };\r
923 \r
924 \r
925  \r
926 /***********************************************************************\r
927   <<< (ParsedRangeClass) >>> \r
928 ************************************************************************/\r
929 \r
930 /*[ParsedRangeClass_initConst]*/\r
931 void  ParsedRangeClass_initConst( ParsedRangeClass* self )\r
932 {\r
933         self->ClassID = &g_ParsedRangeClass_ID;\r
934         self->FinalizerVTable = NULL;\r
935         self->StaticAddress = NULL;\r
936         self->Start = NULL;\r
937         self->Over = NULL;\r
938 }\r
939 \r
940 \r
941 /*[g_ParsedRangeClass_ID]*/\r
942 static const ClassID_Class*  gs_ParsedRangeClass_SuperClassIDs[] = {\r
943         &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID, &g_ParsedRangeClass_ID\r
944 };\r
945 const ClassID_Class  g_ParsedRangeClass_ID = {\r
946         "ParsedRangeClass",\r
947         gs_ParsedRangeClass_SuperClassIDs,\r
948         _countof( gs_ParsedRangeClass_SuperClassIDs ),\r
949         sizeof( ParsedRangeClass ),\r
950         NULL,\r
951 };\r
952 \r
953 \r
954  \r
955 /***********************************************************************\r
956   <<< [ParsedRanges_getCut_by_PP_Directive] >>> \r
957 ************************************************************************/\r
958 errnum_t  ParsedRanges_getCut_by_PP_Directive(\r
959         Set2* /*<ParsedRangeClass>*/    CutRanges,\r
960         Set2* /*<PP_DirectiveClass*>*/  DirectivePointerArray,\r
961         const TCHAR* Symbol,  bool IsCutDefine )\r
962 {\r
963         errnum_t             e;\r
964         PP_DirectiveClass**  p;\r
965         PP_DirectiveClass**  p_over;\r
966 \r
967         for ( Set2_forEach( DirectivePointerArray, &p, &p_over, PP_DirectiveClass* ) ) {\r
968                 PP_DirectiveClass*  directive = *p;\r
969 \r
970                 if ( ClassID_Class_isSuperClass( directive->ClassID, &g_PP_SharpIfdefClass_ID ) ) {\r
971                         PP_SharpIfdefClass*  sh_ifdef = (PP_SharpIfdefClass*) directive;  /* sh = sharp */\r
972                         PP_SharpElseClass*   sh_else;   /* sh = sharp */\r
973                         PP_SharpEndifClass*  sh_endif;  /* sh = sharp */\r
974 \r
975                         if ( StrT_cmp_part( sh_ifdef->Symbol_Start, sh_ifdef->Symbol_Over, Symbol ) == 0 ) {\r
976                                 ParsedRangeClass*  cut;\r
977                                 bool  is_ifndef = ( sh_ifdef->ClassID == &g_PP_SharpIfndefClass_ID );\r
978 \r
979 \r
980                                 /* Set "sh_else", "sh_endif" */\r
981                                 if ( ClassID_Class_isSuperClass( sh_ifdef->NextDirective->ClassID,\r
982                                                 &g_PP_SharpElseClass_ID ) ) {\r
983                                         sh_else = (PP_SharpElseClass*) sh_ifdef->NextDirective;\r
984                                         sh_endif = sh_ifdef->EndDirective;\r
985                                 } else {\r
986                                         sh_else = NULL;\r
987                                         sh_endif = (PP_SharpEndifClass*) sh_ifdef->NextDirective;\r
988                                 }\r
989 \r
990 \r
991                                 /* Add to "CutRanges" */\r
992                                 e= Set2_alloc( CutRanges, &cut, ParsedRangeClass ); IF(e){goto fin;}\r
993                                 cut->Start = sh_ifdef->Start;\r
994                                 if ( is_ifndef == ! IsCutDefine ) {\r
995                                         if ( sh_else != NULL ) {\r
996                                                 cut->Over = sh_else->Over;\r
997 \r
998                                                 e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
999                                                         IF(e){goto fin;}\r
1000                                                 cut->Start = sh_endif->Start;\r
1001                                         }\r
1002                                         cut->Over = sh_endif->Over;\r
1003                                 }\r
1004                                 else {\r
1005                                         cut->Over = sh_ifdef->Over;\r
1006 \r
1007                                         e= Set2_alloc( CutRanges, &cut, ParsedRangeClass );\r
1008                                                 IF(e){goto fin;}\r
1009                                         if ( sh_else != NULL ) {\r
1010                                                 cut->Start = sh_else->Start;\r
1011                                         } else {\r
1012                                                 cut->Start = sh_endif->Start;\r
1013                                         }\r
1014                                         cut->Over = sh_endif->Over;\r
1015                                 }\r
1016                         }\r
1017                 }\r
1018         }\r
1019 \r
1020         e=0;\r
1021 fin:\r
1022         return  e;\r
1023 }\r
1024 \r
1025 \r
1026  \r
1027 /***********************************************************************\r
1028   <<< [ParsedRangeClass_onInitializedForDebug] >>> \r
1029 ************************************************************************/\r
1030 #if ! defined( NDEBUG )\r
1031 void  ParsedRangeClass_onInitializedForDebug( ParsedRangeClass* self )\r
1032 {\r
1033         /* These code can be modified for Debug. */\r
1034         #if 0  // IS_USED_DEBUG_CHECK_CLASS\r
1035                 TCHAR*     text;\r
1036                 ptrdiff_t  break_diff = 0x1FA6A;\r
1037 \r
1038                 START_D( 10 );\r
1039                 text = GET_D( 1, TCHAR* );\r
1040                 PointerType_plus( &text, break_diff );\r
1041                 if ( text == self->Start ) {\r
1042                         if ( self->ClassID == &g_ParsedRangeClass_ID ) {\r
1043                                 SET_D( 2, self );\r
1044                         }\r
1045                 }\r
1046                 END_D();\r
1047         #else\r
1048                 UNREFERENCED_VARIABLE( self );\r
1049         #endif\r
1050 }\r
1051 #endif\r
1052 \r
1053 \r
1054  \r
1055 /***********************************************************************\r
1056   <<< [ParsedRanges_compareByStart] >>> \r
1057 ************************************************************************/\r
1058 int  ParsedRanges_compareByStart( const void* _a1, const void* _a2 )\r
1059 {\r
1060         ParsedRangeClass*  a1 = (ParsedRangeClass*) _a1;\r
1061         ParsedRangeClass*  a2 = (ParsedRangeClass*) _a2;\r
1062 \r
1063         return  a1->Start - a2->Start;\r
1064 }\r
1065 \r
1066 \r
1067  \r
1068 /***********************************************************************\r
1069   <<< [ParsedRanges_write_by_Cut] >>> \r
1070 ************************************************************************/\r
1071 errnum_t  ParsedRanges_write_by_Cut(\r
1072         Set2* /*<ParsedRangeClass>*/ CutRanges,\r
1073         const TCHAR* Text, FILE* OutFile )\r
1074 {\r
1075         errnum_t           e;\r
1076         const TCHAR*       position;\r
1077         ParsedRangeClass*  p;\r
1078         ParsedRangeClass*  p_over;\r
1079 \r
1080         qsort( CutRanges->First, Set2_getCount( CutRanges, ParsedRangeClass ),\r
1081                 sizeof(ParsedRangeClass), ParsedRanges_compareByStart );\r
1082 \r
1083         position = Text;\r
1084         for ( Set2_forEach( CutRanges, &p, &p_over, ParsedRangeClass ) ) {\r
1085                 const TCHAR*  cut_start_position;\r
1086                 const TCHAR*  cut_over_position;\r
1087 \r
1088                 cut_start_position = p->Start;\r
1089                 if ( position < cut_start_position ) {\r
1090                         e= FileT_writePart( OutFile, (TCHAR*)position, (TCHAR*)cut_start_position );\r
1091                                 IF(e){goto fin;}\r
1092                 }\r
1093 \r
1094                 cut_over_position = p->Over;\r
1095                 if ( position < cut_over_position ) {\r
1096                         position = cut_over_position;\r
1097                 }\r
1098         }\r
1099         _fputts( position, OutFile ); IF(ferror(OutFile)){e=E_ERRNO; goto fin;}\r
1100 \r
1101         e=0;\r
1102 fin:\r
1103         return  e;\r
1104 }\r
1105 \r
1106 \r
1107  \r
1108 /*=================================================================*/\r
1109 /* <<< [Locale/Locale.c] >>> */ \r
1110 /*=================================================================*/\r
1111  \r
1112 /***********************************************************************\r
1113   <<< [g_LocaleSymbol] >>> \r
1114 ************************************************************************/\r
1115 char*  g_LocaleSymbol = "";\r
1116 \r
1117 \r
1118  \r
1119 /***********************************************************************\r
1120   <<< [Locale_init] >>> \r
1121 ************************************************************************/\r
1122 int  Locale_init()\r
1123 {\r
1124         g_LocaleSymbol = ".OCP";\r
1125         setlocale( LC_ALL, ".OCP" );\r
1126         return  0;\r
1127 }\r
1128 \r
1129 \r
1130  \r
1131 /***********************************************************************\r
1132   <<< [Locale_isInited] >>> \r
1133 ************************************************************************/\r
1134 int  Locale_isInited()\r
1135 {\r
1136         return  ( g_LocaleSymbol[0] != '\0' );\r
1137                 // \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
1138 }\r
1139 \r
1140 \r
1141  \r
1142 /*=================================================================*/\r
1143 /* <<< [FileT/FileT.c] >>> */ \r
1144 /*=================================================================*/\r
1145  \r
1146 /***********************************************************************\r
1147   <<< [FileT_isExist] >>> \r
1148 ************************************************************************/\r
1149 bool  FileT_isExist( const TCHAR* path )\r
1150 {\r
1151  #if ! FileT_isExistWildcard\r
1152 \r
1153         DWORD  r;\r
1154 \r
1155         if ( path[0] == _T('\0') )  return  false;\r
1156         r = GetFileAttributes( path );\r
1157         return  r != (DWORD)-1;\r
1158 \r
1159  #else\r
1160 \r
1161         HANDLE  find;\r
1162         WIN32_FIND_DATA  data;\r
1163 \r
1164         find = FindFirstFileEx( path, FindExInfoStandard, &data,\r
1165                 FindExSearchNameMatch, NULL, 0 );\r
1166 \r
1167         if ( find == INVALID_HANDLE_VALUE ) {\r
1168                 return  false;\r
1169         }\r
1170         else {\r
1171                 FindClose( find );\r
1172                 return  true;\r
1173         }\r
1174 \r
1175  #endif\r
1176 }\r
1177 \r
1178 \r
1179  \r
1180 /***********************************************************************\r
1181   <<< [FileT_isFile] >>> \r
1182 ************************************************************************/\r
1183 bool  FileT_isFile( const TCHAR* path )\r
1184 {\r
1185         DWORD  r = GetFileAttributes( path );\r
1186         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;\r
1187                 // 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
1188 }\r
1189 \r
1190 \r
1191  \r
1192 /***********************************************************************\r
1193   <<< [FileT_isDir] >>> \r
1194 ************************************************************************/\r
1195 bool  FileT_isDir( const TCHAR* path )\r
1196 {\r
1197         DWORD  r = GetFileAttributes( path );\r
1198         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;\r
1199                 // 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
1200 }\r
1201 \r
1202 \r
1203  \r
1204 /***********************************************************************\r
1205   <<< [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
1206 ************************************************************************/\r
1207 typedef struct {\r
1208         /*--- inherit from FileT_CallByNestFindData */\r
1209         void*     CallerArgument;\r
1210         TCHAR*    FullPath;  // abstruct path\r
1211         TCHAR*    StepPath;\r
1212         TCHAR*    FileName;\r
1213         DWORD     FileAttributes;\r
1214 \r
1215         /*---*/\r
1216         BitField  Flags;\r
1217         FuncType  CallbackFromNestFind;\r
1218         TCHAR     FullPathMem[4096];\r
1219 } FileT_CallByNestFindDataIn;\r
1220 \r
1221 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );\r
1222 \r
1223 \r
1224 int  FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )\r
1225 {\r
1226         int  e;\r
1227         FileT_CallByNestFindDataIn  data;\r
1228 \r
1229         {\r
1230                 TCHAR*  p;\r
1231 \r
1232                 e= StrT_cpy( data.FullPathMem, sizeof(data.FullPathMem), Path ); IF(e)goto fin;\r
1233 \r
1234 \r
1235                 /* FullPathMem \82Ì\8dÅ\8cã\82É \ \82ª\96³\82¢\82È\82ç\92Ç\89Á\82·\82é */\r
1236                 p = _tcschr( data.FullPathMem, _T('\0') );\r
1237                 p--;\r
1238                 if ( *p != _T('\\') ) {\r
1239                         p++;\r
1240                         IF( p >= data.FullPathMem + (sizeof(data.FullPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;\r
1241                         *p = _T('\\');\r
1242                 }\r
1243 \r
1244 \r
1245                 /* data \82ð\8f\89\8aú\89»\82·\82é */\r
1246                 data.CallerArgument = Argument;\r
1247                 data.FullPath = data.FullPathMem;\r
1248                 data.StepPath = p + 1;\r
1249                 data.FileName = p + 1;\r
1250                 data.Flags = Flags;\r
1251                 data.CallbackFromNestFind = Callback;\r
1252         }\r
1253 \r
1254         /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ\8aÖ\90\94\82Ö */\r
1255         e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;\r
1256 \r
1257         e=0;\r
1258 fin:\r
1259         return  e;\r
1260 err_fa: e= E_FEW_ARRAY; goto fin;\r
1261 }\r
1262 \r
1263 \r
1264 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )\r
1265 {\r
1266         int  e;\r
1267         HANDLE  find;\r
1268         WIN32_FIND_DATA  data;\r
1269         TCHAR*  p;\r
1270         int  done;\r
1271 \r
1272 \r
1273         /* 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
1274         if ( m->Flags & FileT_FolderBeforeFiles ) {\r
1275                 *( m->FileName - 1 ) = _T('\0');  // m->FullPath \82Ì\8dÅ\8cã\82Ì \ \82ð\88ê\8e\9e\93I\82É\83J\83b\83g\r
1276                 *( m->FileName ) = _T('\0');  // m->FileName, m->StepPath \82ð "" \82É\82·\82é\r
1277                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
1278 \r
1279                 if ( m->StepPath[0] == _T('\0') ) {\r
1280                         TCHAR*  step_path = m->StepPath;\r
1281                         TCHAR*  fname     = m->FileName;\r
1282 \r
1283                         m->StepPath = _T(".");\r
1284                         m->FileName = StrT_refFName( m->FullPath );\r
1285                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
1286                         m->StepPath = step_path;\r
1287                         m->FileName = fname;\r
1288                 }\r
1289                 else if ( m->FileName[0] == _T('\0') ) {\r
1290                         TCHAR*  fname = m->FileName;\r
1291 \r
1292                         m->FileName = StrT_refFName( m->FullPath );\r
1293                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
1294                         m->FileName = fname;\r
1295                 }\r
1296                 else {\r
1297                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
1298                 }\r
1299                 *( m->FileName - 1 ) = _T('\\');\r
1300         }\r
1301 \r
1302 \r
1303         /* * \82ð\92Ç\89Á */\r
1304         p = m->FileName;\r
1305         IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
1306         *p = _T('*');  *(p+1) = _T('\0');\r
1307 \r
1308 \r
1309         /* \83t\83@\83C\83\8b\82©\83t\83H\83\8b\83_\82ð\97ñ\8b\93\82µ\82Ü\82· */\r
1310         find = FindFirstFileEx( m->FullPathMem, FindExInfoStandard, &data,\r
1311                 FindExSearchNameMatch, NULL, 0 );\r
1312         done = ( find == INVALID_HANDLE_VALUE );\r
1313 \r
1314         while (!done)\r
1315         {\r
1316                 if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||\r
1317                                  _tcscmp( data.cFileName, _T("..") ) == 0 ) {\r
1318                         done = ! FindNextFile( find, &data );\r
1319                         continue;\r
1320                 }\r
1321 \r
1322                 StrT_cpy( m->FileName,\r
1323                         sizeof(m->FullPathMem) - ( (char*)m->FileName - (char*)m->FullPathMem ),\r
1324                         data.cFileName );\r
1325                 m->FileAttributes = data.dwFileAttributes;\r
1326 \r
1327                 if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
1328                         TCHAR*  prev_fname = m->FileName;\r
1329 \r
1330                         p = _tcschr( m->FileName, _T('\0') );\r
1331 \r
1332                         IF( p >= m->FullPathMem + (sizeof(m->FullPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
1333                         *p = _T('\\');  *(p+1) = _T('\0');\r
1334                         m->FileName = p + 1;\r
1335 \r
1336                         e= FileT_callByNestFind_sub( m ); IF(e)goto fin;  /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ */\r
1337 \r
1338                         m->FileName = prev_fname;\r
1339                 }\r
1340                 else {\r
1341                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
1342                 }\r
1343 \r
1344                 done = ! FindNextFile( find, &data );\r
1345         }\r
1346         FindClose( find );\r
1347 \r
1348 \r
1349         /* 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
1350         if ( m->Flags & FileT_FolderAfterFiles ) {\r
1351                 TCHAR*  step_path = m->StepPath;\r
1352                 TCHAR*  fname     = m->FileName;\r
1353 \r
1354                 *( m->FileName - 1 ) = _T('\0');\r
1355                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
1356                 if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->FullPath ) ) {\r
1357                         m->StepPath = _T(".");\r
1358                 }\r
1359                 m->FileName = StrT_refFName( m->FullPath );\r
1360 \r
1361                 e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
1362 \r
1363                 m->StepPath = step_path;\r
1364                 m->FileName = fname;\r
1365         }\r
1366 \r
1367         e=0;\r
1368 fin:\r
1369         return  e;\r
1370 err_fa: e= E_FEW_ARRAY; goto fin;\r
1371 }\r
1372 \r
1373 \r
1374  \r
1375 /***********************************************************************\r
1376   <<< [FileT_openForRead] >>> \r
1377 ************************************************************************/\r
1378 int  FileT_openForRead( FILE** out_pFile, const TCHAR* Path )\r
1379 {\r
1380         errno_t  en;\r
1381 \r
1382         assert( Locale_isInited() );\r
1383 \r
1384         #if DEBUGTOOLS_USES\r
1385                 { int e= Debug_onOpen( Path ); if(e) return e; }\r
1386         #endif\r
1387 \r
1388         en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );\r
1389         if ( en == ENOENT ) {\r
1390                 #ifndef UNDER_CE\r
1391                 {\r
1392                         TCHAR  cwd[512];\r
1393 \r
1394                         if ( _tgetcwd( cwd, _countof(cwd) ) == NULL ) {\r
1395                                 cwd[0] = _T('\0');\r
1396                         }\r
1397                         Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\" current=\"%s\"/>"),\r
1398                                 Path, cwd );\r
1399                 }\r
1400                 #else\r
1401                         Error4_printf( _T("<ERROR msg=\"Not found\" path=\"%s\"/>"), Path );\r
1402                 #endif\r
1403 \r
1404                 return  E_PATH_NOT_FOUND;\r
1405         }\r
1406         if ( en == EACCES ) {\r
1407                 Error4_printf( _T("access denied \"%s\"\n"), Path );\r
1408                 return  E_ACCESS_DENIED;\r
1409         }\r
1410         IF(en)return  E_OTHERS;\r
1411 \r
1412         return  0;\r
1413 }\r
1414 \r
1415 \r
1416  \r
1417 /***********************************************************************\r
1418   <<< [FileT_openForWrite] >>> \r
1419 ************************************************************************/\r
1420 int  FileT_openForWrite( FILE** out_pFile, const TCHAR* Path, int Flags )\r
1421 {\r
1422         int      e;\r
1423         errno_t  en;\r
1424         TCHAR*   open_type;\r
1425         BOOL     b;\r
1426         int      retry_count;\r
1427 \r
1428         IF_D( ! Locale_isInited() )  return  E_NOT_INIT_GLOBAL;\r
1429 \r
1430         #if Uses_AppKey\r
1431                 e= AppKey_addNewWritableFolder( Path ); IF(e)goto fin;\r
1432         #endif\r
1433 \r
1434         if ( Flags & F_Append )\r
1435                 open_type = ( Flags & F_Unicode ? _T("a")_T(fopen_ccs) : _T("at") );\r
1436         else\r
1437                 open_type = ( Flags & F_Unicode ? _T("w")_T(fopen_ccs) : _T("wt") );\r
1438 \r
1439         #if DEBUGTOOLS_USES\r
1440                 { int e= Debug_onOpen( Path ); if(e) return e; }\r
1441         #endif\r
1442 \r
1443         for ( retry_count = 0;  ;  retry_count ++ ) {\r
1444                 en = _tfopen_s( out_pFile, Path, open_type );\r
1445                 if ( en != EACCES )  break;\r
1446 \r
1447                 retry_count += 1;\r
1448                 if ( retry_count == 15 )  break;\r
1449                 Sleep( 1000 );\r
1450         }\r
1451         if ( en == 2 ) {  // ENOENT\r
1452                 e= FileT_mkdir( Path ); IF(e)goto fin;\r
1453                 b= RemoveDirectory( Path ); IF(!b)goto err_gt;\r
1454                 en = _tfopen_s( out_pFile, Path, open_type );\r
1455 \r
1456                 IF ( en == 2 ) {\r
1457                         _tprintf( _T("cannot open \"%s\"\n"), Path );\r
1458 \r
1459                         #ifndef UNDER_CE\r
1460                         {\r
1461                                 TCHAR  cwd[512];\r
1462 \r
1463                                 if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )\r
1464                                         _tprintf( _T("current = \"%s\"\n"), cwd );\r
1465                         }\r
1466                         #endif\r
1467 \r
1468                         e = E_NOT_FOUND_SYMBOL;\r
1469                         goto fin;\r
1470                 }\r
1471         }\r
1472         IF(en)goto err;\r
1473 \r
1474         e=0;\r
1475 fin:\r
1476         return  e;\r
1477 \r
1478 err:  e = E_OTHERS;  goto fin;\r
1479 err_gt:  e = SaveWindowsLastError();  goto fin;\r
1480 }\r
1481 \r
1482 \r
1483  \r
1484 /***********************************************************************\r
1485   <<< [FileT_close] >>> \r
1486 ************************************************************************/\r
1487 int  FileT_close( FILE* File, int e )\r
1488 {\r
1489         if ( File != NULL ) {\r
1490                 int r = fclose( File );\r
1491                 IF(r&&!e)e=E_ERRNO;\r
1492         }\r
1493         return e;\r
1494 }\r
1495 \r
1496 \r
1497 \r
1498  \r
1499 /***********************************************************************\r
1500   <<< [FileT_closeAndNULL] >>> \r
1501 ************************************************************************/\r
1502 errnum_t  FileT_closeAndNULL( FILE** in_out_File, errnum_t e )\r
1503 {\r
1504         FILE*  file = *in_out_File;\r
1505 \r
1506         if ( file != NULL ) {\r
1507                 int  r = fclose( file );\r
1508                 IF ( r && e == 0 ) { e = E_ERRNO; }\r
1509                 *in_out_File = NULL;\r
1510         }\r
1511 \r
1512         return  e;\r
1513 }\r
1514 \r
1515 \r
1516 \r
1517  \r
1518 /***********************************************************************\r
1519   <<< [FileT_readAll] >>> \r
1520 ************************************************************************/\r
1521 #ifdef  IsTest_FileT_readAll\r
1522         #define _CV(x)  CoverageLogClass_output( x, _T("FileT_readAll") )\r
1523 #else\r
1524         #define _CV(x)\r
1525 #endif\r
1526 \r
1527 errnum_t  FileT_readAll( FILE* File, TCHAR** out_Text, size_t* out_TextLength )\r
1528 {\r
1529 #ifdef  IsTest_FileT_readAll\r
1530         enum { text_max_size_first = 0x10 };\r
1531 #else\r
1532         enum { text_max_size_first = 0xFF00 };\r
1533 #endif\r
1534         errnum_t  e;\r
1535         TCHAR*    text = NULL;\r
1536         TCHAR*    text_over = (TCHAR*) DUMMY_INITIAL_VALUE;\r
1537         size_t    text_max_size = text_max_size_first;\r
1538         TCHAR*    text_max_over;\r
1539 \r
1540 \r
1541         text = (TCHAR*) malloc( text_max_size ); IF( text == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
1542         text_over = text;\r
1543         text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
1544 \r
1545         text[0] = _T('\0');  /* for empty file */\r
1546 \r
1547         for (;;) {\r
1548                 _fgetts( text_over, text_max_over - text_over, File );\r
1549 \r
1550                 if ( *text_over == _T('\0') ) {  /* End of file. If space line, *text_over == _T('\n').  */\r
1551                         _CV(1);\r
1552                         ASSERT_R( feof( File ), e=E_OTHERS; goto fin );\r
1553                         break;\r
1554                 }\r
1555                 text_over = _tcschr( text_over, _T('\0') );\r
1556                 if ( feof( File ) ) { break; }\r
1557 \r
1558                 if ( (uint8_t*) text_over - (uint8_t*) text == (int)( text_max_size - sizeof(TCHAR) ) ) {\r
1559                                 /* if full in text */\r
1560                         TCHAR*  new_text;\r
1561                         size_t  old_text_max_size = text_max_size;\r
1562 \r
1563                         #ifdef  IsTest_FileT_readAll\r
1564                                 EmptyHeapMemoryEmulation( _T("T_FileT_readAll_FewMemory"), 1 );\r
1565                         #endif\r
1566 \r
1567                         text_max_size *= 4;\r
1568                         new_text = (TCHAR*) realloc( text, text_max_size );\r
1569                                 IF( new_text == NULL ) { e=E_FEW_MEMORY; _CV(2); goto fin; }\r
1570                         text = new_text;\r
1571                         text_over = (TCHAR*)( (uint8_t*) new_text + old_text_max_size - sizeof(TCHAR) );\r
1572                         text_max_over = (TCHAR*)( (uint8_t*) text + text_max_size );\r
1573                 }\r
1574                 else {\r
1575                         _CV(3);\r
1576                 }\r
1577         }\r
1578 \r
1579         e=0;\r
1580 fin:\r
1581         if ( e ) {\r
1582                 if ( text != NULL ) { _CV(4); free( text ); }\r
1583         }\r
1584         else {\r
1585                 *out_Text = text;\r
1586                 if ( out_TextLength != NULL ) { *out_TextLength = text_over - text; }\r
1587         }\r
1588         return  e;\r
1589 }\r
1590 #undef _CV\r
1591 \r
1592 \r
1593  \r
1594 /***********************************************************************\r
1595   <<< [FileT_writePart] >>> \r
1596 ************************************************************************/\r
1597 errnum_t  FileT_writePart( FILE* File, const TCHAR* Start, TCHAR* Over )\r
1598 {\r
1599         errnum_t  e;\r
1600         TCHAR     back_char;\r
1601         int       r;\r
1602 \r
1603         back_char = *Over;\r
1604         *Over = _T('\0');\r
1605 \r
1606         IF ( Start > Over ) { e=E_OTHERS; goto fin; }\r
1607 \r
1608         r= _ftprintf_s( File, _T("%s"), Start ); IF(r<0){ e=E_ERRNO; goto fin; }\r
1609 \r
1610         e=0;\r
1611 fin:\r
1612         *Over = back_char;\r
1613         return  e;\r
1614 }\r
1615 \r
1616 \r
1617  \r
1618 /***********************************************************************\r
1619   <<< [FileT_mkdir] >>> \r
1620 ************************************************************************/\r
1621 int  FileT_mkdir( const TCHAR* Path )\r
1622 {\r
1623         int    e;\r
1624         DWORD  r;\r
1625         TCHAR* p = (TCHAR*) DUMMY_INITIAL_VALUE;\r
1626         BOOL   b;\r
1627         int    n_folder = 0;\r
1628         TCHAR  path2[MAX_PATH];\r
1629 \r
1630 \r
1631         e= StrT_getFullPath( path2, sizeof(path2), Path, NULL ); IF(e)goto fin;\r
1632         #if Uses_AppKey\r
1633                 e= AppKey_addNewWritableFolder( path2 ); IF(e)goto fin;\r
1634         #endif\r
1635 \r
1636 \r
1637         //=== \91\8dÝ\82·\82é\83t\83H\83\8b\83_\82ð\92T\82·\r
1638         for (;;) {\r
1639                 r = GetFileAttributes( path2 );\r
1640                 if ( r != (DWORD)-1 ) break;  // "C:" \82à\83t\83H\83\8b\83_\82Æ\94»\92è\82³\82ê\82é\r
1641 \r
1642                 p = StrT_refFName( path2 ) - 1;  // \90â\91Î\83p\83X\82È\82Ì\82Å\95K\82¸ *p=='\\'\r
1643                 *p = _T('\0');\r
1644                 n_folder ++;\r
1645         }\r
1646         IF ( ! (r & FILE_ATTRIBUTE_DIRECTORY) ) goto err;  // \83t\83@\83C\83\8b\82È\82ç\83G\83\89\81[\r
1647 \r
1648 \r
1649         //=== \83t\83H\83\8b\83_\82ð\8dì\90¬\82·\82é\r
1650         for ( ;  n_folder > 0;  n_folder -- ) {\r
1651                 *p = _T('\\');\r
1652                 b= CreateDirectory( path2, NULL ); IF(!b)goto err;\r
1653                 p = _tcschr( p, _T('\0') );\r
1654         }\r
1655 \r
1656         e=0;\r
1657 fin:\r
1658         return  e;\r
1659 \r
1660 err:  e = E_OTHERS;  goto fin;\r
1661 }\r
1662 \r
1663 \r
1664 \r
1665  \r
1666 /***********************************************************************\r
1667   <<< [FileT_copy] >>> \r
1668 ************************************************************************/\r
1669 int  FileT_copy_sub( FileT_CallByNestFindData* m );\r
1670 \r
1671 int  FileT_copy( const TCHAR* SrcPath, const TCHAR* DstPath )\r
1672 {\r
1673         const TCHAR*  p_last;\r
1674         int    e;\r
1675         BOOL   b;\r
1676         TCHAR  path[MAX_PATH*4];\r
1677 \r
1678 \r
1679         #if Uses_AppKey\r
1680                 e= AppKey_addNewWritableFolder( DstPath ); IF(e)goto fin;\r
1681         #endif\r
1682 \r
1683         p_last = _tcschr( SrcPath, _T('\0') );\r
1684         IF_D( p_last <= SrcPath + 1 )goto err_ni;\r
1685 \r
1686 \r
1687         //=== \83t\83H\83\8b\83_\82ð\83R\83s\81[\82·\82é\r
1688         if ( *(p_last - 1) == _T('*') ) {\r
1689                 IF_D( *(p_last - 2) != _T('\\') ) goto err_ni;\r
1690 \r
1691                 e= StrT_getParentFullPath( path, sizeof(path), SrcPath, NULL ); IF(e)goto fin;\r
1692                 IF_D( ! FileT_isDir( path ) )goto err_nf;\r
1693 \r
1694                 e= FileT_callByNestFind( path, FileT_FolderBeforeFiles, (void*) DstPath, (FuncType) FileT_copy_sub );\r
1695                 IF(e)goto fin;\r
1696         }\r
1697 \r
1698 \r
1699         //=== \83t\83@\83C\83\8b\82ð\83R\83s\81[\82·\82é\r
1700         else {\r
1701                 IF_D( _tcschr( SrcPath, _T('*') ) != NULL )goto err_ni;\r
1702                 IF_D( ! FileT_isFile( SrcPath ) ) goto err_nf;\r
1703 \r
1704                 b= CopyFile( SrcPath, DstPath, FALSE );\r
1705                 if (!b) {\r
1706                         if ( FileT_isDir( DstPath ) ) {\r
1707                                 e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
1708                                 b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
1709                         }\r
1710                         else {\r
1711                                 int  ee;\r
1712 \r
1713                                 p_last = _tcschr( DstPath, _T('\0') ) - 1;\r
1714                                 IF_D( p_last < DstPath )goto err;\r
1715                                 if ( *p_last == _T('\\') ) {\r
1716                                         ee= FileT_mkdir( DstPath ); IF(ee)goto fin;\r
1717                                         e= stprintf_r( path, sizeof(path), _T("%s%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
1718                                         b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
1719                                 }\r
1720                                 else {\r
1721                                         e = E_ACCESS_DENIED;\r
1722                                         ee= StrT_getParentFullPath( path, sizeof(path), DstPath, NULL ); IF(ee)goto fin;\r
1723                                         ee= FileT_mkdir( path ); IF(ee)goto fin;\r
1724                                         b= CopyFile( SrcPath, DstPath, FALSE ); IF(!b)goto err_gt;\r
1725                                 }\r
1726                         }\r
1727                 }\r
1728         }\r
1729 \r
1730         e=0;\r
1731 fin:\r
1732         return  e;\r
1733 \r
1734 err_ni:  e = E_NOT_IMPLEMENT_YET;  goto fin;\r
1735 err_nf:  e = E_PATH_NOT_FOUND;  goto fin;\r
1736 err_gt:  e = SaveWindowsLastError();  goto fin;\r
1737 err:  e = E_OTHERS;  goto fin;\r
1738 }\r
1739 \r
1740 \r
1741 int  FileT_copy_sub( FileT_CallByNestFindData* m )\r
1742 {\r
1743         const  TCHAR*  DstPath = (const TCHAR*) m->CallerArgument;\r
1744         int    e;\r
1745         BOOL   b;\r
1746         TCHAR  path[MAX_PATH*4];\r
1747 \r
1748         e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, m->StepPath ); IF(e)goto fin;\r
1749 \r
1750         if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
1751                 if ( ! FileT_isDir( path ) )\r
1752                         { b= CreateDirectory( path, NULL ); IF(!b)goto err_gt; }\r
1753         }\r
1754         else {\r
1755                 b= CopyFile( m->FullPath, path, FALSE ); IF(!b)goto err_gt;\r
1756         }\r
1757 \r
1758         e=0;\r
1759 fin:\r
1760         return  e;\r
1761 \r
1762 err_gt:  e = SaveWindowsLastError();  goto fin;\r
1763 }\r
1764 \r
1765 \r
1766 \r
1767  \r
1768 /***********************************************************************\r
1769   <<< [FileT_del] >>> \r
1770 ************************************************************************/\r
1771 int  FileT_del_sub( FileT_CallByNestFindData* m );\r
1772 \r
1773 int  FileT_del( const TCHAR* Path )\r
1774 {\r
1775         int    e;\r
1776         DWORD  r;\r
1777         TCHAR  abs_path[MAX_PATH];\r
1778 \r
1779         e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto fin;\r
1780         #if Uses_AppKey\r
1781                 e= AppKey_addNewWritableFolder( abs_path ); IF(e)goto fin;\r
1782         #endif\r
1783 \r
1784         r= GetFileAttributes( Path );\r
1785         if ( r != (DWORD)-1 ) {\r
1786                 if ( r & FILE_ATTRIBUTE_DIRECTORY ) {\r
1787                         e= FileT_callByNestFind( Path, FileT_FolderAfterFiles, NULL, (FuncType) FileT_del_sub );\r
1788                 }\r
1789                 else {\r
1790                         BOOL  b= DeleteFile( Path ); IF(!b)goto err_gt;\r
1791                 }\r
1792         }\r
1793         IF_D( FileT_isExist( Path ) )goto err_ad;\r
1794 \r
1795         e=0;\r
1796 fin:\r
1797         return  e;\r
1798 \r
1799 err_gt:  e = SaveWindowsLastError();  goto fin;\r
1800 err_ad:  e = E_ACCESS_DENIED;  goto fin;\r
1801 }\r
1802 \r
1803 \r
1804 int  FileT_del_sub( FileT_CallByNestFindData* m )\r
1805 {\r
1806         int   e;\r
1807         BOOL  b;\r
1808 \r
1809         if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
1810                 b= RemoveDirectory( m->FullPath ); IF(!b)goto err_gt;\r
1811         }\r
1812         else {\r
1813                 b= DeleteFile( m->FullPath ); IF(!b)goto err_gt;\r
1814         }\r
1815 \r
1816         e=0;\r
1817 fin:\r
1818         return  e;\r
1819 \r
1820 err_gt:  e = SaveWindowsLastError();  goto fin;\r
1821 }\r
1822  \r
1823 /***********************************************************************\r
1824   <<< [AppKey] >>> \r
1825 ************************************************************************/\r
1826 static errnum_t  AppKey_create( AppKey** out_m );\r
1827 static bool      AppKey_isSame( AppKey* m );\r
1828 static void      Writables_initConst( Writables* m );\r
1829 static errnum_t  Writables_init( Writables* m, AppKey* Key );\r
1830 static errnum_t  Writables_finish( Writables* m, int e );\r
1831 static bool      Writables_isInited( Writables* m );\r
1832 static errnum_t  Writables_clearPaths( Writables* m );\r
1833 static errnum_t  Writables_create( Writables** out_m, AppKey* Key );\r
1834 static errnum_t  Writables_copyToConst( Writables* To, Writables* From );\r
1835 \r
1836 \r
1837 typedef struct _CurrentWritables  CurrentWritables;\r
1838 struct _CurrentWritables {\r
1839         Writables  m_CurrentWritables;\r
1840         TCHAR*   m_ProgramFiles;  size_t  m_ProgramFiles_Len;\r
1841         TCHAR*   m_windir;        size_t  m_windir_Len;\r
1842         TCHAR*   m_APPDATA;       size_t  m_APPDATA_Len;\r
1843         TCHAR*   m_LOCALAPPDATA;  size_t  m_LOCALAPPDATA_Len;\r
1844 };\r
1845 static void      CurrentWritables_initConst( CurrentWritables* m );\r
1846 static errnum_t  CurrentWritables_init( CurrentWritables* m );\r
1847 static errnum_t  CurrentWritables_finish( CurrentWritables* m, int e );\r
1848 static errnum_t  CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath );\r
1849 \r
1850 \r
1851 //////////////////////////////\r
1852 \r
1853 static  AppKey   g_AppKey;\r
1854 static  AppKey*  g_AppKeyPrivate;\r
1855 \r
1856 // under g_AppKey\r
1857 Writables  g_DefaultWritables;\r
1858 Writables  g_CurrentWritables; // public\r
1859 static CurrentWritables  g_CurrentWritablesPrivate;\r
1860 \r
1861 \r
1862 static errnum_t  AppKey_create( AppKey** out_m )\r
1863 {\r
1864         errnum_t  e;\r
1865 \r
1866         IF( g_AppKeyPrivate != NULL ) { e=1; goto fin; }\r
1867                 // AppKey_newWritable \82Ì in_out_m = NULL \82Ì\82Æ\82«\82Í\81A2\89ñ\8cÄ\82Ñ\8fo\82·\82±\82Æ\82Í\82Å\82«\82Ü\82¹\82ñ\81B\r
1868 \r
1869         Writables_initConst( &g_DefaultWritables );\r
1870         CurrentWritables_initConst( &g_CurrentWritablesPrivate );\r
1871 \r
1872         e= CurrentWritables_init( &g_CurrentWritablesPrivate ); IF(e)goto fin;\r
1873         e= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(e)goto fin;\r
1874 \r
1875         *out_m = &g_AppKey;\r
1876         g_AppKeyPrivate = &g_AppKey;\r
1877 \r
1878         e=0;\r
1879 fin:\r
1880         return  e;\r
1881 }\r
1882 \r
1883 \r
1884 static bool  AppKey_isSame( AppKey* m )\r
1885 {\r
1886         return  ( m == g_AppKeyPrivate );\r
1887 }\r
1888 \r
1889 \r
1890 void  AppKey_initGlobal_const()\r
1891 {\r
1892         Writables_initConst( &g_DefaultWritables );\r
1893 }\r
1894 \r
1895 \r
1896 errnum_t  AppKey_finishGlobal( errnum_t e )\r
1897 {\r
1898         errnum_t  ee;\r
1899 \r
1900         e= Writables_finish( &g_DefaultWritables, e );\r
1901         e= CurrentWritables_finish( &g_CurrentWritablesPrivate, e );\r
1902         ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
1903 \r
1904         return  e;\r
1905 }\r
1906 \r
1907 \r
1908  \r
1909 /***********************************************************************\r
1910   <<< [AppKey_newWritable] >>> \r
1911 ************************************************************************/\r
1912 errnum_t  AppKey_newWritable( AppKey** in_out_m,  Writables** out_Writable,  ... )\r
1913 {\r
1914         errnum_t    e;\r
1915         AppKey*     m = NULL;\r
1916         Writables*  wr = NULL;\r
1917  #if Uses_OutMallocIDTool\r
1918         bool  is_prev_out_malloc;\r
1919 \r
1920         is_prev_out_malloc = OutMallocID_setEnable( false );\r
1921  #endif\r
1922 \r
1923 \r
1924         //=== AppKey* m \82ð\97L\8cø\82É\82·\82é\r
1925         if ( in_out_m == NULL ) {  // \8d¡\89ñ\82Ì\8aÖ\90\94\82Ì\92\86\82¾\82¯\82Å\8eQ\8fÆ\82·\82é\r
1926                 e= AppKey_create( &m ); IF(e)goto resume;\r
1927         }\r
1928         else if ( *in_out_m == NULL ) {  // \82P\89ñ\96Ú\82É\96{\8aÖ\90\94\82ð\8cÄ\82Ñ\8fo\82µ\82½\83\82\83W\83\85\81[\83\8b\82É\93n\82·\r
1929                 e= AppKey_create( &m ); IF(e)goto resume;\r
1930                 *in_out_m = m;\r
1931         }\r
1932         else {  // \96{\8aÖ\90\94\82ð\8cÄ\82Ñ\8fo\82µ\82½\83\82\83W\83\85\81[\83\8b\82©\82ç\93n\82Á\82½\82à\82Ì\82ð\8eg\82¤\r
1933                 m = *in_out_m;\r
1934         }\r
1935 \r
1936 \r
1937         //=== \90³\8bK\82Ì AppKey \82©\83`\83F\83b\83N\82·\82é\r
1938         IF( ! AppKey_isSame( m ) )goto err;\r
1939 \r
1940 \r
1941         //=== Writable \82ð\90\90¬\82·\82é\r
1942         if ( out_Writable == NULL ) {\r
1943                 wr = &g_DefaultWritables;\r
1944                 e= Writables_finish( wr, 0 ); IF(e)goto resume;\r
1945                 e= Writables_init( wr, m ); IF(e)goto resume;\r
1946         }\r
1947         else {\r
1948                 e= Writables_create( &wr, m ); IF(e)goto resume;\r
1949                 *out_Writable = wr;\r
1950         }\r
1951 \r
1952 \r
1953         //=== Writable \82É\83p\83X\82ð\93o\98^\82·\82é\r
1954         {\r
1955                 va_list  va;\r
1956                 TCHAR*   path;\r
1957                 int  i;\r
1958 \r
1959                 va_start( va, out_Writable );\r
1960                 for ( i=0; ; i++ ) {\r
1961                         path = va_arg( va, TCHAR* );\r
1962                         if ( path == NULL )  break;\r
1963                         IF( i == 5 ) goto err;  // \8dÅ\8cã\82Ì NULL \96Y\82ê\91Î\8dô\r
1964 \r
1965                         e= Writables_add( wr, m, path ); IF(e)goto resume;\r
1966                 }\r
1967                 va_end( va );\r
1968         }\r
1969         #if defined(TempFile_get)\r
1970         {\r
1971                 TempFile*   temp;\r
1972 \r
1973                 e= TempFile_get( &temp ); IF(e)goto resume;\r
1974                 e= Writables_add( wr, m, temp->TempPath ); IF(e)goto resume;\r
1975         }\r
1976         #endif\r
1977 \r
1978 \r
1979         //=== \82·\82®\82É Writable \82ð\97L\8cø\82É\82·\82é\r
1980         if ( out_Writable == NULL ) {\r
1981                 e= Writables_enable( wr ); IF(e)goto resume;\r
1982         }\r
1983 \r
1984         e=0;\r
1985 fin:\r
1986         #if Uses_OutMallocIDTool\r
1987                 OutMallocID_setEnable( is_prev_out_malloc );\r
1988         #endif\r
1989         return  e;\r
1990 \r
1991 err:  e = E_OTHERS;  goto resume;\r
1992 resume:\r
1993         if ( wr != NULL ) {\r
1994                 if ( out_Writable == NULL )\r
1995                         e= Writables_finish( wr, e );  // g_DefaultWritables\r
1996                 else\r
1997                         e= Writables_delete( wr, e );\r
1998         }\r
1999         goto fin;\r
2000 }\r
2001 \r
2002 \r
2003  \r
2004 /***********************************************************************\r
2005   <<< [AppKey_addNewWritableFolder] \83`\83F\83b\83N\82·\82é\81A\82Ü\82½\82Í\92Ç\89Á\82·\82é >>> \r
2006 \81i\92Ç\89Á\82Í\96¢\91Î\89\9e\81j\r
2007 ************************************************************************/\r
2008 errnum_t  AppKey_addNewWritableFolder( const TCHAR* Path )\r
2009 {\r
2010         errnum_t    e;\r
2011         TCHAR**     pp;\r
2012         TCHAR**     pp_over;\r
2013         Writables*  wr = &g_CurrentWritablesPrivate.m_CurrentWritables;\r
2014         size_t      path_len;\r
2015         TCHAR       abs_path[MAX_PATH];\r
2016 \r
2017         if ( g_AppKeyPrivate == NULL ) {\r
2018                 e= AppKey_newWritable( NULL, NULL, ".", NULL ); IF(e){goto fin;}\r
2019         }\r
2020 \r
2021         e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e){goto fin;}\r
2022 \r
2023         pp_over = wr->m_Paths + wr->m_nPath;\r
2024         for ( pp = wr->m_Paths;  ;  pp++ ) {\r
2025                 IF ( pp >= pp_over ) { e=E_OUT_OF_WRITABLE; goto fin; }\r
2026                         // Path (abs_path) \82Í\81AAppKey_newWritable \82Å\8b\96\89Â\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B\r
2027                         // \83E\83H\83b\83`\81E\83E\83B\83\93\83h\83E\82É g_CurrentWritables.m_Paths,3 \82È\82Ç\82ð\93ü\97Í\82µ\82Ä\r
2028                         // \8b\96\89Â\82³\82ê\82Ä\82¢\82é\83p\83X\82ð\8am\94F\82µ\82Ä\82­\82¾\82³\82¢\81B\r
2029 \r
2030                 path_len = _tcslen( *pp );\r
2031                 if ( _tcsnicmp( *pp, abs_path, path_len ) == 0 &&\r
2032                      ( abs_path[ path_len ] == _T('\\') || abs_path[ path_len ] == _T('\0') ) )  break;\r
2033         }\r
2034 \r
2035         e=0;\r
2036 fin:\r
2037         return  e;\r
2038 }\r
2039 \r
2040 \r
2041  \r
2042 /***********************************************************************\r
2043   <<< [AppKey_checkWritable] >>> \r
2044 ************************************************************************/\r
2045 errnum_t  AppKey_checkWritable( const TCHAR* Path )\r
2046 {\r
2047         return  AppKey_addNewWritableFolder( Path );\r
2048 }\r
2049 \r
2050 \r
2051  \r
2052 /***********************************************************************\r
2053   <<< [Writables_init] >>> \r
2054 ************************************************************************/\r
2055 static void  Writables_initConst( Writables* m )\r
2056 {\r
2057         m->m_Paths = NULL;\r
2058         m->m_nPath = -1;\r
2059 }\r
2060 \r
2061 \r
2062 static errnum_t  Writables_init( Writables* m, AppKey* Key )\r
2063 {\r
2064         IF( ! AppKey_isSame( Key ) ) return E_OTHERS;\r
2065 \r
2066         m->m_Paths = NULL;\r
2067         m->m_nPath = 0;\r
2068         return  0;\r
2069 }\r
2070 \r
2071 \r
2072 static errnum_t  Writables_finish( Writables* m, int e )\r
2073 {\r
2074         errnum_t  ee;\r
2075 \r
2076         ee= Writables_clearPaths( m ); IF(ee&&!e) e=ee;\r
2077         m->m_nPath = -1;\r
2078         return  e;\r
2079 }\r
2080 \r
2081 \r
2082 static bool  Writables_isInited( Writables* m )\r
2083 {\r
2084         return  ( m->m_nPath != -1 );\r
2085 }\r
2086 \r
2087 \r
2088 static errnum_t  Writables_clearPaths( Writables* m )\r
2089 {\r
2090         TCHAR**  p;\r
2091         TCHAR**  p_over;\r
2092 \r
2093         if ( m->m_Paths != NULL ) {\r
2094                 p_over = m->m_Paths + m->m_nPath;\r
2095                 for ( p = m->m_Paths;  p < p_over;  p++ ) {\r
2096                         free( *p );\r
2097                 }\r
2098                 free( m->m_Paths );  m->m_Paths = NULL;\r
2099         }\r
2100         m->m_nPath = 0;\r
2101         return  0;\r
2102 }\r
2103 \r
2104 \r
2105 static errnum_t  Writables_create( Writables** out_m, AppKey* Key )\r
2106 {\r
2107         errnum_t    e;\r
2108         Writables*  m;\r
2109 \r
2110         m = (Writables*) malloc( sizeof(*m) ); IF(m==NULL)return E_FEW_MEMORY;\r
2111         Writables_initConst( m );\r
2112         e= Writables_init( m, Key ); IF(e)goto resume;\r
2113         *out_m = m;\r
2114         return  0;\r
2115 resume: Writables_delete( m, 0 ); free(m); return  e;\r
2116 }\r
2117 \r
2118 \r
2119 errnum_t  Writables_delete( Writables* m, errnum_t e )\r
2120 {\r
2121         if ( m == NULL ) goto fin;\r
2122         e= Writables_finish( m, e );\r
2123         free( m );\r
2124 fin:\r
2125         return  e;\r
2126 }\r
2127 \r
2128 \r
2129  \r
2130 /***********************************************************************\r
2131   <<< [Writables_add] >>> \r
2132 ************************************************************************/\r
2133 int  Writables_add( Writables* m, AppKey* Key, TCHAR* Path )\r
2134 {\r
2135         int  e;\r
2136         TCHAR**   pp;\r
2137         TCHAR*    p  = NULL;\r
2138         size_t    path_size;\r
2139         TCHAR     abs_path[MAX_PATH];\r
2140 \r
2141         IF( ! AppKey_isSame( Key ) )goto err;\r
2142         if ( Path[0] == _T('\0') ) return 0;\r
2143 \r
2144         e= StrT_getFullPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto resume;\r
2145 \r
2146         e= CurrentWritables_askFileAccess( &g_CurrentWritablesPrivate, abs_path ); IF(e)goto resume;\r
2147 \r
2148         pp = (TCHAR**) realloc( m->m_Paths, (m->m_nPath + 1) * sizeof(TCHAR*) );\r
2149         IF( pp == NULL ) goto err;\r
2150         m->m_Paths = pp;\r
2151 \r
2152         path_size = (_tcslen( abs_path ) + 1) * sizeof(TCHAR);\r
2153         p = (TCHAR*) malloc( path_size );\r
2154         m->m_Paths[ m->m_nPath ] = p;\r
2155         IF( p == NULL )goto err;\r
2156 \r
2157         memcpy( p, abs_path, path_size );\r
2158         if ( p[ path_size/sizeof(TCHAR) - 2 ] == _T('\\') )\r
2159                          p[ path_size/sizeof(TCHAR) - 2 ] =  _T('\0');\r
2160         m->m_nPath ++;\r
2161 \r
2162         e=0;\r
2163 fin:\r
2164         return  e;\r
2165 \r
2166 err:  e = E_OTHERS;  goto resume;\r
2167 resume:\r
2168         if ( p != NULL )  free( p );\r
2169         goto fin;\r
2170 }\r
2171 \r
2172 \r
2173 int  Writables_remove( Writables* m, TCHAR* Path )\r
2174 {\r
2175         TCHAR**  pp;\r
2176         TCHAR**  pp_over;\r
2177 \r
2178         pp_over = m->m_Paths + m->m_nPath;\r
2179         for ( pp = m->m_Paths;  ;  pp++ ) {\r
2180                 if ( pp >= pp_over )  return  0;\r
2181                 if ( _tcscmp( *pp, Path ) == 0 )  break;\r
2182         }\r
2183         free( *pp );\r
2184         memmove( pp, pp+1, (char*)pp - (char*)pp_over - sizeof(TCHAR) );\r
2185         m->m_nPath --;\r
2186 \r
2187         #if _DEBUG\r
2188                 *( pp_over - 1 ) = NULL;\r
2189         #endif\r
2190 \r
2191         return  0;\r
2192 }\r
2193 \r
2194 \r
2195  \r
2196 /***********************************************************************\r
2197   <<< [Writables_enable] >>> \r
2198 ************************************************************************/\r
2199 int  Writables_enable( Writables* m )\r
2200 {\r
2201         int  e;\r
2202 \r
2203         e= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, m ); IF(e)goto fin;\r
2204         e= Writables_copyToConst( &g_CurrentWritables, &g_CurrentWritablesPrivate.m_CurrentWritables ); IF(e)goto fin;\r
2205 \r
2206         e=0;\r
2207 fin:\r
2208         return  e;\r
2209 }\r
2210 \r
2211 \r
2212 int  Writables_disable( Writables* m, int e )\r
2213 {\r
2214         int  ee;\r
2215 \r
2216         UNREFERENCED_VARIABLE( m );\r
2217 \r
2218         ee= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
2219         ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
2220 \r
2221         e=0;\r
2222 fin:\r
2223         return  e;\r
2224 }\r
2225 \r
2226 \r
2227 static int  Writables_copyToConst( Writables* To, Writables* From )\r
2228 {\r
2229         int  e;\r
2230         TCHAR**  pp;\r
2231         TCHAR**  pp_over;\r
2232         TCHAR*   p2;\r
2233         TCHAR**  pp2;\r
2234         size_t   path_size;\r
2235 \r
2236         if ( To->m_Paths != NULL ) {\r
2237                 free( To->m_Paths );\r
2238                 To->m_Paths = NULL;\r
2239                 To->m_nPath = 0;\r
2240         }\r
2241 \r
2242         if ( From != NULL && From->m_nPath > 0 ) {\r
2243 \r
2244                 path_size = 0;\r
2245                 pp_over = From->m_Paths + From->m_nPath;\r
2246                 for ( pp = From->m_Paths;  pp < pp_over;  pp++ ) {\r
2247                         path_size += _tcslen( *pp ) + 1;\r
2248                 }\r
2249 \r
2250                 path_size = From->m_nPath * sizeof(TCHAR*) + path_size * sizeof(TCHAR);\r
2251                 To->m_Paths = (TCHAR**) malloc( path_size );\r
2252                 IF( To->m_Paths == NULL ) goto err;\r
2253 \r
2254                 p2 = (TCHAR*)( (char*)To->m_Paths + From->m_nPath * sizeof(TCHAR*) );\r
2255                 pp2 = To->m_Paths;\r
2256                 for ( pp = From->m_Paths;  pp < pp_over;  pp++ ) {\r
2257                         *pp2 = p2;\r
2258                         path_size = (_tcslen( *pp ) + 1) * sizeof(TCHAR);\r
2259                         memcpy( p2, *pp, path_size );\r
2260                         p2 = (TCHAR*)( (char*)p2 + path_size );\r
2261                         pp2 ++;\r
2262                 }\r
2263                 To->m_nPath = From->m_nPath;\r
2264         }\r
2265 \r
2266         e=0;\r
2267 fin:\r
2268         return  e;\r
2269 \r
2270 err:  e = E_OTHERS;  goto fin;\r
2271 }\r
2272 \r
2273  \r
2274 /***********************************************************************\r
2275   <<< [CurrentWritables] >>> \r
2276 ************************************************************************/\r
2277 static void  CurrentWritables_initConst( CurrentWritables* m )\r
2278 {\r
2279         Writables_initConst( &m->m_CurrentWritables );\r
2280         m->m_ProgramFiles = NULL;\r
2281         m->m_windir = NULL;\r
2282         m->m_APPDATA = NULL;\r
2283         m->m_LOCALAPPDATA = NULL;\r
2284 }\r
2285 \r
2286 \r
2287 static int  CurrentWritables_init( CurrentWritables* m )\r
2288 {\r
2289         int    e;\r
2290  #if Uses_OutMallocIDTool\r
2291         bool  is_prev_out_malloc;\r
2292 \r
2293         is_prev_out_malloc = OutMallocID_setEnable( false );\r
2294  #endif\r
2295 \r
2296         e= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(e)goto fin;\r
2297 \r
2298         e= env_malloc( &m->m_ProgramFiles, &m->m_ProgramFiles_Len, _T("ProgramFiles") ); IF(e)goto fin;\r
2299         e= env_malloc( &m->m_windir,       &m->m_windir_Len,       _T("windir") ); IF(e)goto fin;\r
2300         e= env_malloc( &m->m_APPDATA,      &m->m_APPDATA_Len,      _T("APPDATA") ); IF(e)goto fin;\r
2301         // e= env_malloc( &m->m_LOCALAPPDATA, &m->m_LOCALAPPDATA_Len, _T("LOCALAPPDATA") ); IF(e)goto fin;\r
2302 \r
2303         e=0;\r
2304 fin:\r
2305  #if Uses_OutMallocIDTool\r
2306         OutMallocID_setEnable( is_prev_out_malloc );\r
2307  #endif\r
2308         return  e;\r
2309 }\r
2310 \r
2311 \r
2312 static int  CurrentWritables_finish( CurrentWritables* m, int e )\r
2313 {\r
2314         int  ee;\r
2315 \r
2316         ee= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
2317 \r
2318         if ( m->m_ProgramFiles != NULL )  free( m->m_ProgramFiles );\r
2319         if ( m->m_windir != NULL )        free( m->m_windir );\r
2320         if ( m->m_APPDATA != NULL )       free( m->m_APPDATA );\r
2321         if ( m->m_LOCALAPPDATA != NULL )  free( m->m_LOCALAPPDATA );\r
2322 \r
2323         m->m_ProgramFiles = NULL;\r
2324         m->m_windir = NULL;\r
2325         m->m_APPDATA = NULL;\r
2326         m->m_LOCALAPPDATA = NULL;\r
2327 \r
2328         return  e;\r
2329 }\r
2330 \r
2331 \r
2332 static int  CurrentWritables_askFileAccess_sub(\r
2333         const TCHAR* SystemPath,  size_t SystemPath_Len,  const TCHAR* FullPath, size_t FullPath_Len );\r
2334 \r
2335 static int  CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* FullPath )\r
2336 {\r
2337         int  e;\r
2338         size_t  abs_len;\r
2339 \r
2340         abs_len = _tcslen( FullPath );\r
2341         e= CurrentWritables_askFileAccess_sub( m->m_ProgramFiles, m->m_ProgramFiles_Len, FullPath, abs_len ); IF(e)goto fin;\r
2342         e= CurrentWritables_askFileAccess_sub( m->m_windir,       m->m_windir_Len,       FullPath, abs_len ); IF(e)goto fin;\r
2343         e= CurrentWritables_askFileAccess_sub( m->m_APPDATA,      m->m_APPDATA_Len,      FullPath, abs_len ); IF(e)goto fin;\r
2344         e= CurrentWritables_askFileAccess_sub( m->m_LOCALAPPDATA, m->m_LOCALAPPDATA_Len, FullPath, abs_len ); IF(e)goto fin;\r
2345 \r
2346         e=0;\r
2347 fin:\r
2348         return  e;\r
2349 }\r
2350 \r
2351 \r
2352 static int  CurrentWritables_askFileAccess_sub(\r
2353         const TCHAR* SystemPath,  size_t SystemPath_Len,  const TCHAR* FullPath, size_t FullPath_Len )\r
2354 {\r
2355         if ( SystemPath == NULL )  return  0;\r
2356 \r
2357         IF ( _tcsncmp( SystemPath, FullPath, SystemPath_Len ) == 0 )\r
2358                 return  E_OUT_OF_WRITABLE;  // \83V\83X\83e\83\80\83t\83H\83\8b\83_\82Ì\92\86\82ð\8f\91\82«\8d\9e\82Ý\8b\96\89Â\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\r
2359 \r
2360         IF ( _tcsncmp( SystemPath, FullPath, FullPath_Len ) == 0 )\r
2361                 return  E_OUT_OF_WRITABLE;  // \83V\83X\83e\83\80\83t\83H\83\8b\83_\82ð\8aÜ\82ß\82Ä\8b\96\89Â\8f\91\82«\8d\9e\82Ý\8b\96\89Â\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\r
2362 \r
2363         return  0;\r
2364 }\r
2365 \r
2366 \r
2367  \r
2368 /*=================================================================*/\r
2369 /* <<< [Error4/Error4.c] >>> */ \r
2370 /*=================================================================*/\r
2371  \r
2372 /***********************************************************************\r
2373   <<< [Get_Error4_Variables] >>> \r
2374 ************************************************************************/\r
2375 static Error4_VariablesClass  gs;\r
2376 #ifdef _DEBUG\r
2377         extern Error4_VariablesClass*  g_Error4_Variables = &gs;\r
2378 #endif\r
2379 \r
2380 Error4_VariablesClass*  Get_Error4_Variables()\r
2381 {\r
2382         return  &gs;\r
2383 }\r
2384 \r
2385 \r
2386  \r
2387 /***********************************************************************\r
2388   <<< (SetBreakErrorID) >>> \r
2389 ************************************************************************/\r
2390 \r
2391 /*[DebugBreakR]*/\r
2392 void  DebugBreakR()\r
2393 {\r
2394         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
2395         DebugBreak();\r
2396                 // 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
2397                 // \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
2398 }\r
2399 \r
2400 \r
2401 #if ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
2402 \r
2403 \r
2404 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
2405         dll_global_g_DebugBreakCount  ErrorClass  g_Error;  /* \8f\89\8aú\92l\82Í\82·\82×\82Ä\83[\83\8d */\r
2406 #else\r
2407         dll_global_g_DebugBreakCount  GlobalErrorClass  g_GlobalError;\r
2408 \r
2409         static errnum_t  ErrorClass_initializeIfNot_Sub( ErrorClass** out_Error );\r
2410         static errnum_t  ErrorClass_initializeIfNot_Sub2(void);\r
2411 #endif\r
2412 \r
2413 \r
2414 #define  IF_  if  /* Error check for in "IF" macro */\r
2415 \r
2416 \r
2417 /*[SetBreakErrorID]*/\r
2418 void  SetBreakErrorID( int ErrorID )\r
2419 {\r
2420 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
2421 \r
2422         ErrorClass*  err = &g_Error;\r
2423         bool         is_print;\r
2424 \r
2425         is_print = ( err->BreakErrorID != ErrorID );\r
2426 \r
2427         err->BreakErrorID = ErrorID;\r
2428                 /* printf \82Ì\92\86\82Å\94­\90\82·\82é\83G\83\89\81[\82Å\8e~\82ß\82é\82½\82ß */\r
2429 \r
2430         if ( is_print )\r
2431                 { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
2432 \r
2433 #else\r
2434 \r
2435         GlobalErrorClass*  err_global = &g_GlobalError;\r
2436 \r
2437         if ( err_global->BreakGlobalErrorID != ErrorID )\r
2438                 { printf( ">SetBreakErrorID( %d );\n", ErrorID ); }\r
2439         err_global->BreakGlobalErrorID = ErrorID;\r
2440 \r
2441 #endif\r
2442 }\r
2443 \r
2444 \r
2445 \r
2446 bool  OnRaisingError_Sub( const char* FilePath, int LineNum )\r
2447  // \96{\8aÖ\90\94\82Í\81AIF \83}\83N\83\8d\82Ì\92\86\82©\82ç\8cÄ\82Î\82ê\82Ü\82·\r
2448  // \95Ô\82è\92l\82Í\81A\83u\83\8c\81[\83N\82·\82é\82©\82Ç\82¤\82©\r
2449 {\r
2450 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
2451 \r
2452         ErrorClass*  err = &g_Error;\r
2453         bool  is_break;\r
2454 \r
2455         /* \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
2456         if ( err->IsError ) {\r
2457                 return  false;\r
2458         }\r
2459 \r
2460         /* \83G\83\89\81[\82ª\94­\90\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
2461         err->ErrorID += 1;\r
2462         err->IsError = true;\r
2463         err->FilePath = FilePath;\r
2464         err->LineNum  = LineNum;\r
2465 \r
2466         #if ERR2_ENABLE_ERROR_LOG\r
2467                 printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
2468                         err->ErrorID, (int) err );\r
2469         #endif\r
2470 \r
2471         is_break = ( err->ErrorID == err->BreakErrorID );\r
2472 \r
2473         if ( is_break ) {\r
2474                 printf( "Break in (%d) %s\n", LineNum, FilePath );\r
2475         }\r
2476         return  ( err->ErrorID == err->BreakErrorID );\r
2477 \r
2478 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2479 \r
2480         errnum_t           e;\r
2481         bool               is_break = false;\r
2482         ErrorClass*        err;\r
2483 \r
2484         e= ErrorClass_initializeIfNot_Sub( &err ); IF_(e){goto fin;}\r
2485 \r
2486 \r
2487         /* \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
2488         if ( err->IsError ) {\r
2489                 return  false;\r
2490         }\r
2491 \r
2492         /* \83G\83\89\81[\82ª\94­\90\82µ\82½\92¼\8cã\82Ì\82Æ\82« */\r
2493         else {\r
2494                 GlobalErrorClass*  err_global = &g_GlobalError;\r
2495 \r
2496                 EnterCriticalSection( &err_global->CriticalSection );\r
2497 \r
2498 \r
2499                 err_global->ErrorThreadCount += 1;\r
2500                 err_global->RaisedGlobalErrorID += 1;\r
2501                 err->GlobalErrorID = err_global->RaisedGlobalErrorID;\r
2502 \r
2503                 err->ErrorID += 1;\r
2504                 err->IsError = true;\r
2505                 err->FilePath = FilePath;\r
2506                 err->LineNum  = LineNum;\r
2507 \r
2508                 is_break = ( err->ErrorID == err->BreakErrorID ) ||\r
2509                         ( err->GlobalErrorID == err_global->BreakGlobalErrorID );\r
2510 \r
2511 \r
2512                 /* \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
2513                 /* \8fã\8bL\82Ì if ( err->IsError ) \82Å\81A\82·\82®\96ß\82é\82½\82ß */\r
2514 \r
2515 \r
2516                 #if ERR2_ENABLE_ERROR_LOG\r
2517                         printf( "<ERROR_LOG msg=\"raised\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
2518                                 err->GlobalErrorID, (int) err );\r
2519                 #endif\r
2520 \r
2521 \r
2522                 if ( err->ErrorID == 1 ) {\r
2523                         FinalizerClass_initConst( &err->Finalizer, err, ErrorClass_finalize );\r
2524                         e= AddThreadLocalFinalizer( &err->Finalizer );\r
2525                 }\r
2526                 else {\r
2527                         e = 0;\r
2528                 }\r
2529                 LeaveCriticalSection( &err_global->CriticalSection );\r
2530                 IF(e){goto fin;}\r
2531         }\r
2532 \r
2533         e=0;\r
2534 fin:\r
2535         if ( is_break ) {\r
2536                 printf( "Break in (%d) %s\n", LineNum, FilePath );\r
2537         }\r
2538         return  is_break;\r
2539 \r
2540 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2541 }\r
2542 \r
2543 \r
2544 //[ClearError]\r
2545 void  ClearError()\r
2546 {\r
2547 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
2548 \r
2549         ErrorClass*  err = &g_Error;\r
2550 \r
2551         #if ERR2_ENABLE_ERROR_LOG\r
2552         if ( err->IsError ) {\r
2553                 printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
2554                         err->ErrorID, (int) err );\r
2555         }\r
2556         #endif\r
2557 \r
2558         err->IsError = false;\r
2559 \r
2560 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2561 \r
2562         errnum_t     e;\r
2563         ErrorClass*  err;\r
2564 \r
2565         e= ErrorClass_initializeIfNot_Sub( &err );\r
2566         if ( e == 0 ) {\r
2567                 #if ERR2_ENABLE_ERROR_LOG\r
2568                 if ( err->IsError )\r
2569                         printf( "<ERROR_LOG msg=\"cleared\" ErrorID=\"%d\" ErrorObject=\"0x%08X\"/>\n",\r
2570                                 err->GlobalErrorID, (int) err );\r
2571                 #endif\r
2572 \r
2573                 if ( err->IsError ) {\r
2574                         GlobalErrorClass*  err_global = &g_GlobalError;\r
2575 \r
2576                         EnterCriticalSection( &err_global->CriticalSection );\r
2577                         err_global->ErrorThreadCount -= 1;\r
2578                         LeaveCriticalSection( &err_global->CriticalSection );\r
2579 \r
2580                         err->IsError = false;\r
2581                 }\r
2582         }\r
2583         else {\r
2584                 #if ERR2_ENABLE_ERROR_LOG\r
2585                         printf( "<ERROR_LOG msg=\"clear_miss\"/>\n" );\r
2586                 #endif\r
2587         }\r
2588 \r
2589 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2590 }\r
2591 \r
2592 \r
2593 //[IfErrThenBreak]\r
2594 void  IfErrThenBreak()\r
2595 {\r
2596 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
2597 \r
2598         ErrorClass*  err = &g_Error;\r
2599 \r
2600         if ( err->IsError  &&\r
2601                 ( err->ErrorID != err->BreakErrorID || err->BreakErrorID == 0 )\r
2602         ) {\r
2603                 printf( "in IfErrThenBreak\n" );\r
2604                 DebugBreakR();\r
2605 \r
2606                 // \83E\83H\83b\83`\82Å\81Aerr->ErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
2607                 // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\r
2608                 // \83G\83\89\81[\82ª\94­\90\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
2609                 // \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
2610                 // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
2611                 #if ERR2_ENABLE_ERROR_LOG\r
2612                         printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
2613                                 err->ErrorID, err->BreakErrorID );\r
2614                 #endif\r
2615 \r
2616                 {\r
2617                         char  str[512];\r
2618                         sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
2619                                 err->FilePath, err->LineNum );\r
2620                         OutputDebugStringA( str );\r
2621                 }\r
2622         }\r
2623         ClearError();\r
2624 \r
2625 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2626 \r
2627         errnum_t           e;\r
2628         GlobalErrorClass*  err_global = &g_GlobalError;\r
2629         ErrorClass*        err;\r
2630 \r
2631         e= ErrorClass_initializeIfNot_Sub( &err );\r
2632         if ( e ) { DebugBreakR();  ClearError();  return; }  /* \93à\95\94\83G\83\89\81[ */\r
2633 \r
2634         if ( err_global->ErrorThreadCount != 0  &&\r
2635                 ( err->GlobalErrorID != err_global->BreakGlobalErrorID || err_global->BreakGlobalErrorID == 0 )\r
2636         ) {\r
2637                 printf( "in IfErrThenBreak\n" );\r
2638                 DebugBreakR();\r
2639 \r
2640                 // \83E\83H\83b\83`\82Å\81Aerr->GlobalErrorID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
2641                 // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\r
2642                 // \83G\83\89\81[\82ª\94­\90\82µ\82½\8fê\8f\8a\82Í\81Aerr->FilePath, err->LineNum \82Å\82·\81B\r
2643                 // \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
2644                 // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
2645                 #if ERR2_ENABLE_ERROR_LOG\r
2646                         printf( "<ERROR_LOG msg=\"IfErrThenBreak\" ErrorID=\"%d\" BreakErrorID=\"%d\"/>\n",\r
2647                                 err->ErrorID, err->BreakErrorID );\r
2648                 #endif\r
2649 \r
2650                 {\r
2651                         char  str[512];\r
2652                         sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n",\r
2653                                 err->FilePath, err->LineNum );\r
2654                         OutputDebugStringA( str );\r
2655                 }\r
2656         }\r
2657         ClearError();\r
2658 \r
2659 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2660 }\r
2661 \r
2662 \r
2663 //[PushErr]\r
2664 void  PushErr( ErrStackAreaClass* ErrStackArea )\r
2665 {\r
2666 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
2667 \r
2668         ErrorClass*  err = &g_Error;\r
2669 \r
2670         ErrStackArea->ErrorID = err->ErrorID;\r
2671         ErrStackArea->IsError = err->IsError;\r
2672         err->IsError = false;\r
2673 \r
2674 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2675 \r
2676         errnum_t     e;\r
2677         ErrorClass*  err;\r
2678 \r
2679         e= ErrorClass_initializeIfNot_Sub( &err );\r
2680         if ( e == 0 ) {\r
2681                 ErrStackArea->ErrorID = err->ErrorID;\r
2682                 ErrStackArea->IsError = err->IsError;\r
2683                 err->IsError = false;\r
2684         }\r
2685 \r
2686 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2687 }\r
2688 \r
2689 //[PopErr]\r
2690 void  PopErr(  ErrStackAreaClass* ErrStackArea )\r
2691 {\r
2692 #if ! IS_MULTI_THREAD_ERROR_CLASS\r
2693 \r
2694         ErrorClass*  err = &g_Error;\r
2695 \r
2696         if ( ErrStackArea->IsError )\r
2697                 { err->IsError = true; }\r
2698 \r
2699 #else  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2700 \r
2701         errnum_t     e;\r
2702         ErrorClass*  err;\r
2703 \r
2704         e= ErrorClass_initializeIfNot_Sub( &err );\r
2705         if ( e == 0 ) {\r
2706                 if ( ErrStackArea->IsError )\r
2707                         { err->IsError = true; }\r
2708         }\r
2709 \r
2710 #endif  /* IS_MULTI_THREAD_ERROR_CLASS */\r
2711 }\r
2712 \r
2713 \r
2714  \r
2715 /*[SetBreakErrorID:2]*/\r
2716 #undef  IF_\r
2717 \r
2718 \r
2719 #endif // ENABLE_ERROR_BREAK_IN_ERROR_CLASS\r
2720 \r
2721 \r
2722 //[MergeError]\r
2723 errnum_t  MergeError( errnum_t e, errnum_t ee )\r
2724 {\r
2725         if ( e == 0 ) { return  ee; }\r
2726         else          { /* ErrorLog_add( ee ); */ return  e; }\r
2727 }\r
2728 \r
2729 \r
2730  \r
2731 /***********************************************************************\r
2732   <<< [g_Error4_String] >>> \r
2733 ************************************************************************/\r
2734 TCHAR  g_Error4_String[4096];\r
2735 \r
2736 \r
2737  \r
2738 /***********************************************************************\r
2739   <<< [Error4_printf] >>> \r
2740 ************************************************************************/\r
2741 void  Error4_printf( const TCHAR* format, ... )\r
2742 {\r
2743         va_list  va;\r
2744         va_start( va, format );\r
2745         vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );\r
2746         va_end( va );\r
2747 }\r
2748 \r
2749 \r
2750  \r
2751 /***********************************************************************\r
2752   <<< [Error4_getErrStr] >>> \r
2753 ************************************************************************/\r
2754 void  Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )\r
2755 {\r
2756         switch ( ErrNum ) {\r
2757 \r
2758                 case  0:\r
2759                         stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );\r
2760                         break;\r
2761 \r
2762                 case  E_FEW_ARRAY:\r
2763                         stprintf_r( out_ErrStr, ErrStrSize,\r
2764                                 _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
2765                         break;\r
2766 \r
2767                 case  E_FEW_MEMORY:\r
2768                         stprintf_r( out_ErrStr, ErrStrSize,\r
2769                                 _T("<ERROR msg=\"\83q\81[\83v\81E\83\81\83\82\83\8a\81[\82ª\95s\91«\82µ\82Ü\82µ\82½\81B\"/>") );\r
2770                         break;\r
2771 \r
2772                 #ifndef  __linux__\r
2773                 case  E_GET_LAST_ERROR: {\r
2774                         DWORD   err_win;\r
2775                         TCHAR*  str_pointer;\r
2776 \r
2777                         err_win = gs.WindowsLastError;\r
2778                         if ( err_win == 0 ) { err_win = GetLastError(); }\r
2779 \r
2780                         stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,\r
2781                                 _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );\r
2782                         FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,\r
2783                                 NULL, err_win, LANG_USER_DEFAULT,\r
2784                                 str_pointer,  (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );\r
2785                         str_pointer = _tcschr( str_pointer, _T('\0') );\r
2786                         if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )\r
2787                                 str_pointer -= 2;\r
2788                         stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );\r
2789                         break;\r
2790                 }\r
2791                 #endif\r
2792 \r
2793                 default:\r
2794                         if ( g_Error4_String[0] != '\0' )\r
2795                                 stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );\r
2796                         else\r
2797                                 stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );\r
2798                         break;\r
2799         }\r
2800 }\r
2801 \r
2802 \r
2803  \r
2804 /***********************************************************************\r
2805   <<< [SaveWindowsLastError] >>> \r
2806 ************************************************************************/\r
2807 errnum_t  SaveWindowsLastError()\r
2808 {\r
2809         gs.WindowsLastError = GetLastError();\r
2810         return  E_GET_LAST_ERROR;\r
2811 }\r
2812 \r
2813 \r
2814  \r
2815 /*=================================================================*/\r
2816 /* <<< [CRT_plus_2/CRT_plus_2.c] >>> */ \r
2817 /*=================================================================*/\r
2818  \r
2819 /**************************************************************************\r
2820  <<< [Interface] >>> \r
2821 ***************************************************************************/\r
2822 \r
2823 /*[DefaultFunction]*/\r
2824 errnum_t  DefaultFunction( void* self )\r
2825 {\r
2826         UNREFERENCED_VARIABLE( self );\r
2827         return  0;\r
2828 }\r
2829 \r
2830 /*[DefaultFunction_NotImplementYet]*/\r
2831 errnum_t  DefaultFunction_NotImplementYet( void* self )\r
2832 {\r
2833         UNREFERENCED_VARIABLE( self );\r
2834         return  E_NOT_IMPLEMENT_YET;\r
2835 }\r
2836 \r
2837 /*[DefaultFunction_Finalize]*/\r
2838 errnum_t  DefaultFunction_Finalize( void* self, errnum_t e )\r
2839 {\r
2840         UNREFERENCED_VARIABLE( self );\r
2841         return  e;\r
2842 }\r
2843 \r
2844 /*[VTableDefine_overwrite]*/\r
2845 errnum_t  VTableDefine_overwrite( VTableDefine* aVTable, size_t aVTable_ByteSize, int iMethod, void* Func )\r
2846 {\r
2847         VTableDefine*  p = aVTable;\r
2848         VTableDefine*  p_over = (VTableDefine*)( (char*)aVTable + aVTable_ByteSize );\r
2849 \r
2850         for ( ; p < p_over; p++ ) {\r
2851                 if ( p->m_IMethod == iMethod ) {\r
2852                         p->m_method = Func;\r
2853                         return  0;\r
2854                 }\r
2855         }\r
2856         return  E_NOT_FOUND_SYMBOL;\r
2857 }\r
2858 \r
2859 \r
2860  \r
2861 /*=================================================================*/\r
2862 /* <<< [StrT/StrT.c] >>> */ \r
2863 /*=================================================================*/\r
2864  \r
2865 /***********************************************************************\r
2866   <<< [StrT_cpy] >>> \r
2867 - _tcscpy is raising exception, if E_FEW_ARRAY\r
2868 ************************************************************************/\r
2869 errnum_t  StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )\r
2870 {\r
2871         size_t  size;\r
2872 \r
2873         size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);\r
2874         if ( size <= DstSize ) {\r
2875                 memcpy( Dst, Src, size );\r
2876                 return  0;\r
2877         }\r
2878         else {\r
2879                 memcpy( Dst, Src, DstSize - sizeof(TCHAR) );\r
2880                 *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');\r
2881                 return  E_FEW_ARRAY;\r
2882         }\r
2883 }\r
2884 \r
2885  \r
2886 /***********************************************************************\r
2887   <<< [MallocAndCopyString] >>> \r
2888 ************************************************************************/\r
2889 errnum_t  MallocAndCopyString( const TCHAR** out_NewString, const TCHAR* SourceString )\r
2890 {\r
2891         TCHAR*  str;\r
2892         size_t  size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);\r
2893 \r
2894         ASSERT_D( *out_NewString == NULL, __noop() );\r
2895 \r
2896         str = (TCHAR*) malloc( size );\r
2897         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
2898 \r
2899         memcpy( str, SourceString, size );\r
2900 \r
2901         *out_NewString = str;\r
2902         return  0;\r
2903 }\r
2904 \r
2905 \r
2906  \r
2907 /***********************************************************************\r
2908   <<< [MallocAndCopyString_char] >>> \r
2909 ************************************************************************/\r
2910 #ifdef _UNICODE\r
2911 errnum_t  MallocAndCopyString_char( const TCHAR** out_NewString, const char* SourceString )\r
2912 {\r
2913         TCHAR*  str;\r
2914         size_t  size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);\r
2915         int     r;\r
2916 \r
2917         str = (TCHAR*) malloc( size );\r
2918         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
2919 \r
2920         r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );\r
2921         IF ( r == 0 ) {\r
2922                 free( str );\r
2923                 return  E_GET_LAST_ERROR;\r
2924         }\r
2925         *out_NewString = str;\r
2926         return  0;\r
2927 }\r
2928 #endif\r
2929 \r
2930 \r
2931  \r
2932 /***********************************************************************\r
2933   <<< [MallocAndCopyStringByLength] >>> \r
2934 ************************************************************************/\r
2935 errnum_t  MallocAndCopyStringByLength( const TCHAR** out_NewString, const TCHAR* SourceString,\r
2936         unsigned CountOfCharacter )\r
2937 {\r
2938         TCHAR*  str;\r
2939         size_t  size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);\r
2940 \r
2941         ASSERT_D( *out_NewString == NULL, __noop() );\r
2942 \r
2943         str = (TCHAR*) malloc( size );\r
2944         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
2945 \r
2946         memcpy( str, SourceString, size - sizeof(TCHAR) );\r
2947         str[ CountOfCharacter ] = _T('\0');\r
2948 \r
2949         *out_NewString = str;\r
2950         return  0;\r
2951 }\r
2952 \r
2953 \r
2954  \r
2955 /***********************************************************************\r
2956   <<< [StrT_chrs] >>> \r
2957 ************************************************************************/\r
2958 TCHAR*  StrT_chrs( const TCHAR* s, const TCHAR* keys )\r
2959 {\r
2960         if ( *keys == _T('\0') )  return  NULL;\r
2961 \r
2962         for ( ; *s != _T('\0'); s++ ) {\r
2963                 if ( _tcschr( keys, *s ) != NULL )\r
2964                         return  (TCHAR*) s;\r
2965         }\r
2966         return  NULL;\r
2967 }\r
2968 \r
2969 \r
2970  \r
2971 /***********************************************************************\r
2972   <<< [StrT_rstr] >>> \r
2973 ************************************************************************/\r
2974 TCHAR*  StrT_rstr( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keyword,\r
2975         void* NullConfig )\r
2976 {\r
2977         const TCHAR*  p;\r
2978         int           keyword_length = _tcslen( Keyword );\r
2979         TCHAR         keyword_first = Keyword[0];\r
2980 \r
2981         UNREFERENCED_VARIABLE( NullConfig );\r
2982 \r
2983         p = SearchStart;\r
2984         while ( p >= String ) {\r
2985                 if ( *p == keyword_first ) {\r
2986                         if ( _tcsncmp( p, Keyword, keyword_length ) == 0 ) {\r
2987                                 return  (TCHAR*) p;\r
2988                         }\r
2989                 }\r
2990                 p -= 1;\r
2991         }\r
2992 \r
2993         return  NULL;\r
2994 }\r
2995 \r
2996 \r
2997  \r
2998 /***********************************************************************\r
2999   <<< [StrT_skip] >>> \r
3000 ************************************************************************/\r
3001 TCHAR*  StrT_skip( const TCHAR* String, const TCHAR* Keys )\r
3002 {\r
3003         if ( *Keys == _T('\0') ) { return  (TCHAR*) String; }\r
3004 \r
3005         for ( ; *String != _T('\0'); String += 1 ) {\r
3006                 if ( _tcschr( Keys, *String ) == NULL )\r
3007                         break;\r
3008         }\r
3009         return  (TCHAR*) String;\r
3010 }\r
3011 \r
3012 \r
3013  \r
3014 /***********************************************************************\r
3015   <<< [StrT_rskip] >>> \r
3016 ************************************************************************/\r
3017 TCHAR*  StrT_rskip( const TCHAR* String, const TCHAR* SearchStart, const TCHAR* Keys,\r
3018         void* NullConfig )\r
3019 {\r
3020         const TCHAR*  pointer;\r
3021 \r
3022         UNREFERENCED_VARIABLE( NullConfig );\r
3023 \r
3024         if ( *Keys == _T('\0') ) { return  (TCHAR*) SearchStart; }\r
3025 \r
3026         for ( pointer = SearchStart;  pointer >= String;  pointer -= 1 ) {\r
3027                 if ( _tcschr( Keys, *pointer ) == NULL )\r
3028                         { return  (TCHAR*) pointer; }\r
3029         }\r
3030         return  NULL;\r
3031 }\r
3032 \r
3033 \r
3034  \r
3035 /***********************************************************************\r
3036   <<< [StrT_isCIdentifier] >>> \r
3037 ************************************************************************/\r
3038 bool  StrT_isCIdentifier( TCHAR Character )\r
3039 {\r
3040         const TCHAR  c = Character;\r
3041 \r
3042         return  (\r
3043                 ( c >= _T('A')  &&  c <= _T('Z') ) ||\r
3044                 ( c >= _T('a')  &&  c <= _T('z') ) ||\r
3045                 ( c >= _T('0')  &&  c <= _T('9') ) ||\r
3046                 c == _T('_') );\r
3047 }\r
3048 \r
3049 \r
3050  \r
3051 /***********************************************************************\r
3052   <<< [StrT_searchOverOfCIdentifier] >>> \r
3053 ************************************************************************/\r
3054 TCHAR*  StrT_searchOverOfCIdentifier( const TCHAR* Text )\r
3055 {\r
3056         const TCHAR*  p;\r
3057         TCHAR         c;\r
3058 \r
3059         p = Text;\r
3060         c = *p;\r
3061         for (;;) {\r
3062                 if ( StrT_isCIdentifier( c ) ) {\r
3063                         p += 1;\r
3064                         c = *p;\r
3065                 }\r
3066                 else {\r
3067                         return  (TCHAR*) p;\r
3068                 }\r
3069         }\r
3070 }\r
3071 \r
3072 \r
3073  \r
3074 /***********************************************************************\r
3075   <<< [StrT_convPartStrToPointer] >>> \r
3076 ************************************************************************/\r
3077 void*  StrT_convPartStrToPointer( const TCHAR* StringStart, const TCHAR* StringOver,\r
3078         const NameOnlyClass* Table, size_t TableSize, void* Default )\r
3079 {\r
3080         const NameOnlyClass*  p = Table;\r
3081         const NameOnlyClass*  p_over = (const NameOnlyClass*)( (uint8_t*) Table + TableSize );\r
3082 \r
3083         while ( p < p_over ) {\r
3084                 if ( StrT_cmp_part( StringStart, StringOver, p->Name ) == 0 ) {\r
3085                         return  (void*) p->Delegate;\r
3086                 }\r
3087                 p += 1;\r
3088         }\r
3089         return  Default;\r
3090 }\r
3091 \r
3092 \r
3093  \r
3094 /***********************************************************************\r
3095   <<< [StrT_convertNumToStr] >>> \r
3096 ************************************************************************/\r
3097 TCHAR*  StrT_convertNumToStr( int Number, const NameAndNumClass* Table, int TableCount,\r
3098         const TCHAR* DefaultStr )\r
3099 {\r
3100         const NameAndNumClass*  p;\r
3101         const NameAndNumClass*  p_over = Table + TableCount;\r
3102 \r
3103         for ( p = Table;  p < p_over;  p += 1 ) {\r
3104                 if ( p->Number == Number ) {\r
3105                         return  p->Name;\r
3106                 }\r
3107         }\r
3108         return  (TCHAR*) DefaultStr;\r
3109 }\r
3110 \r
3111 \r
3112  \r
3113 /***********************************************************************\r
3114   <<< [StrT_cmp_part] >>> \r
3115 ************************************************************************/\r
3116 int  StrT_cmp_part( const TCHAR* StringA_Start, const TCHAR* StringA_Over,\r
3117         const TCHAR* StringB )\r
3118 {\r
3119         const TCHAR*  a;\r
3120         const TCHAR*  b;\r
3121         TCHAR  aa;\r
3122         TCHAR  bb;\r
3123 \r
3124         a = StringA_Start;\r
3125         b = StringB;\r
3126 \r
3127         for (;;) {\r
3128                 if ( a >= StringA_Over ) {\r
3129                         bb = *b;\r
3130                         if ( bb == _T('\0') )\r
3131                                 { return  0; }\r
3132                         else\r
3133                                 { return  -bb; }\r
3134                 }\r
3135 \r
3136                 aa = *a;\r
3137                 bb = *b;\r
3138 \r
3139                 if ( bb == _T('\0') )\r
3140                         { return  aa; }\r
3141 \r
3142                 if ( aa != bb )\r
3143                         { return  aa - bb; }\r
3144 \r
3145                 a += 1;\r
3146                 b += 1;\r
3147         }\r
3148 }\r
3149 \r
3150 \r
3151  \r
3152 /***********************************************************************\r
3153   <<< [StrT_cmp_part2] >>> \r
3154 ************************************************************************/\r
3155 int  StrT_cmp_part2( const TCHAR* StringA_Start, const TCHAR* StringA_Over,\r
3156         const TCHAR* StringB_Start, const TCHAR* StringB_Over )\r
3157 {\r
3158         int  length_A = StringA_Over - StringA_Start;\r
3159         int  length_B = StringB_Over - StringB_Start;\r
3160 \r
3161         if ( length_A != length_B ) {\r
3162                 return  length_A - length_B;\r
3163         }\r
3164         else {\r
3165                 return  _tcsncmp( StringA_Start, StringB_Start, length_A );\r
3166         }\r
3167 }\r
3168 \r
3169 \r
3170  \r
3171 /***********************************************************************\r
3172   <<< [StrT_refFName] >>> \r
3173 ************************************************************************/\r
3174 TCHAR*  StrT_refFName( const TCHAR* s )\r
3175 {\r
3176         const TCHAR*  p;\r
3177         TCHAR  c;\r
3178 \r
3179         p = _tcschr( s, _T('\0') );\r
3180 \r
3181         if ( p == s )  return  (TCHAR*) s;\r
3182 \r
3183         for ( p--; p>s; p-- ) {\r
3184                 c = *p;\r
3185                 if ( c == _T('\\') || c == _T('/') )  return  (TCHAR*) p+1;\r
3186         }\r
3187         if ( *p == _T('\\') || *p == _T('/') )  return  (TCHAR*) p+1;\r
3188 \r
3189         return  (TCHAR*) s;\r
3190 }\r
3191  \r
3192 /***********************************************************************\r
3193   <<< [StrT_refExt] >>> \r
3194 ************************************************************************/\r
3195 TCHAR*  StrT_refExt( const TCHAR* s )\r
3196 {\r
3197         const TCHAR*  p;\r
3198 \r
3199         p = _tcschr( s, _T('\0') );\r
3200 \r
3201         if ( p == s )  return  (TCHAR*) s;\r
3202 \r
3203         for ( p--; p>s; p-- ) {\r
3204                 if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
3205                 if ( *p == _T('/') || *p == _T('\\') )  return  (TCHAR*) _tcschr( p, _T('\0') );\r
3206         }\r
3207         if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
3208 \r
3209         return  (TCHAR*) _tcschr( s, _T('\0') );\r
3210 }\r
3211 \r
3212 \r
3213  \r
3214 /***********************************************************************\r
3215   <<< [StrT_convStrToId] >>> \r
3216 ************************************************************************/\r
3217 errnum_t  StrT_convStrToId( const TCHAR* str, const TCHAR** strs, const int* ids,\r
3218         int n, int default_id )\r
3219 {\r
3220         const TCHAR**  p;\r
3221         const TCHAR**  p_over = strs + n;\r
3222 \r
3223         for ( p = strs;  p < p_over;  p++ ) {\r
3224                 if ( _tcsicmp( *p, str ) == 0 )  return  ids[p - strs];\r
3225         }\r
3226         return  default_id;\r
3227 }\r
3228 \r
3229  \r
3230 /***********************************************************************\r
3231   <<< [StrT_convStrLeftToId] >>> \r
3232 ************************************************************************/\r
3233 errnum_t  StrT_convStrLeftToId( const TCHAR* Str, const TCHAR** Strs, const size_t* Lens, const int* Ids,\r
3234                            int CountOfStrs, TCHAR* Separeters, int DefaultId, TCHAR** out_PosOfLastOfStr )\r
3235 {\r
3236         const TCHAR**  pp;\r
3237         const TCHAR**  pp_over = Strs + CountOfStrs;\r
3238         const size_t*  p_len;\r
3239         const int*     p_id;\r
3240         const TCHAR*   p_last_of_str;\r
3241         TCHAR          c;\r
3242 \r
3243         p_len = Lens;\r
3244         p_id  = Ids;\r
3245         for ( pp = Strs;  pp < pp_over;  pp += 1 ) {\r
3246 \r
3247                 ASSERT_D( _tcslen( *pp ) == *p_len, goto err );\r
3248 \r
3249                 if ( _tcsncmp( Str, *pp, *p_len ) == 0 ) {\r
3250                         p_last_of_str = Str + *p_len;\r
3251                         c = *p_last_of_str;\r
3252                         if ( c == _T('\0') || _tcschr( Separeters, c ) != NULL ) {\r
3253                                 *out_PosOfLastOfStr = (TCHAR*) p_last_of_str;\r
3254                                 return  *p_id;\r
3255                         }\r
3256                 }\r
3257                 p_len += 1;\r
3258                 p_id += 1;\r
3259         }\r
3260         return  DefaultId;\r
3261 \r
3262 #if ! NDEBUG\r
3263  err:  return  DefaultId;\r
3264 #endif\r
3265 }\r
3266 \r
3267  \r
3268 /***********************************************************************\r
3269   <<< [StrT_replace1] >>> \r
3270 ************************************************************************/\r
3271 errnum_t  StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,\r
3272         unsigned Opt )\r
3273 {\r
3274         TCHAR*  p;\r
3275 \r
3276         UNREFERENCED_VARIABLE( Opt );\r
3277 \r
3278         IF ( FromCharacter == _T('\0') )  { return  E_OTHERS; }\r
3279 \r
3280         p = in_out_String;\r
3281         for (;;) {\r
3282                 p = _tcschr( p, FromCharacter );\r
3283                 if ( p == NULL )  { break; }\r
3284                 *p = ToCharacter;\r
3285                 p += 1;\r
3286         }\r
3287 \r
3288         return  0;\r
3289 }\r
3290 \r
3291 \r
3292  \r
3293 /***********************************************************************\r
3294   <<< [StrT_trim] >>> \r
3295 ************************************************************************/\r
3296 errnum_t  StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )\r
3297 {\r
3298         const TCHAR*  p1;\r
3299         const TCHAR*  p2;\r
3300         TCHAR   c;\r
3301 \r
3302         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
3303         for ( p2 = _tcschr( p1, _T('\0') ) - 1;  p2 >= p1;  p2-- ) {\r
3304                 c = *p2;\r
3305                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
3306                         break;\r
3307         }\r
3308         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
3309 }\r
3310 \r
3311 \r
3312  \r
3313 /***********************************************************************\r
3314   <<< [StrT_cutLastOf] >>> \r
3315 ************************************************************************/\r
3316 errnum_t  StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )\r
3317 {\r
3318         TCHAR*  last = _tcschr( in_out_Str, _T('\0') );\r
3319 \r
3320         if ( last > in_out_Str ) {\r
3321                 if ( *( last - 1 ) == Charactor )\r
3322                         { *( last - 1 ) = _T('\0'); }\r
3323         }\r
3324         return  0;\r
3325 }\r
3326 \r
3327 \r
3328  \r
3329 /***********************************************************************\r
3330   <<< [StrT_cutLineComment] >>> \r
3331 ************************************************************************/\r
3332 errnum_t  StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )\r
3333 {\r
3334         const TCHAR*  p1;\r
3335         const TCHAR*  p2;\r
3336         TCHAR   c;\r
3337 \r
3338         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
3339 \r
3340         p2 = _tcsstr( p1, CommentSign );\r
3341         if ( p2 == NULL )  p2 = _tcschr( p1, _T('\0') );\r
3342 \r
3343         for ( p2 = p2 - 1;  p2 >= p1;  p2-- ) {\r
3344                 c = *p2;\r
3345                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
3346                         break;\r
3347         }\r
3348         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
3349 }\r
3350 \r
3351 \r
3352  \r
3353 /**************************************************************************\r
3354   <<< [StrT_meltCSV] >>> \r
3355 *************************************************************************/\r
3356 errnum_t  StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )\r
3357 {\r
3358         errnum_t  e = 0;\r
3359         TCHAR*  t;\r
3360         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
3361         const TCHAR*  s;\r
3362         TCHAR  dummy[2];\r
3363         TCHAR  c;\r
3364 \r
3365         t = out_Str;\r
3366         s = *pCSV;\r
3367         if ( out_Str_Size <= 1 )  { t = dummy;  t_last = dummy; }\r
3368 \r
3369         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
3370 \r
3371 \r
3372         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
3373         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
3374 \r
3375         switch ( *s ) {\r
3376 \r
3377                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
3378                 case _T('"'):\r
3379                         s++;\r
3380                         c = *s;\r
3381                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
3382                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
3383                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
3384                                 if ( c == _T('\0') )  break;\r
3385                                 *t = c;  t++;  s++;  c = *s;\r
3386                         }\r
3387                         *t = _T('\0');\r
3388 \r
3389                         s++;\r
3390                         for (;;) {\r
3391                                 if ( *s == _T(',') )  { s = s+1;  break; }\r
3392                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
3393                                 s++;\r
3394                         }\r
3395                         *pCSV = s;\r
3396                         return  e;\r
3397 \r
3398                 /* \8bó\82Ì\8d\80\96Ú\82Ì\8fê\8d\87 */\r
3399                 case ',':\r
3400                         *t = _T('\0');\r
3401                         *pCSV = s+1;\r
3402                         return  0;\r
3403 \r
3404                 case '\0':\r
3405                         *t = _T('\0');\r
3406                         *pCSV = NULL;\r
3407                         return  0;\r
3408 \r
3409                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
3410                 default: {\r
3411                         TCHAR*  sp = NULL;  /* \8dÅ\8cã\82Ì\98A\91±\82µ\82½\8bó\94\92\82Ì\90æ\93ª */\r
3412 \r
3413                         c = *s;\r
3414                         while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* , \95\8e\9a\82Ü\82Å */\r
3415 \r
3416                                 /* sp \82ð\90Ý\92è\82·\82é */\r
3417                                 if ( c == ' ' ) {\r
3418                                         if ( sp == NULL )  sp = t;\r
3419                                 }\r
3420                                 else  sp = NULL;\r
3421 \r
3422                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
3423 \r
3424                                 /* \83R\83s\81[\82·\82é */\r
3425                                 *t = c;  t++;  s++;  c = *s;\r
3426                         }\r
3427 \r
3428                         /* \95Ô\82è\92l\82ð\8c\88\92è\82·\82é */\r
3429                         if ( c == _T(',') )  s = s + 1;\r
3430                         else  s = NULL;\r
3431 \r
3432                         /* \96\96\94ö\82Ì\8bó\94\92\82ð\8eæ\82è\8f\9c\82­ */\r
3433                         if ( sp != NULL )  *sp = '\0';\r
3434                         else  *t = _T('\0');\r
3435 \r
3436                         *pCSV = s;\r
3437                         return  e;\r
3438                 }\r
3439         }\r
3440 }\r
3441 \r
3442 \r
3443  \r
3444 /***********************************************************************\r
3445   <<< [StrT_parseCSV_f] >>> \r
3446 ************************************************************************/\r
3447 errnum_t  StrT_parseCSV_f( const TCHAR* StringOfCSV, bit_flags32_t* out_ReadFlags, const TCHAR* Types, ... )\r
3448 {\r
3449         errnum_t       e;\r
3450         TCHAR          type;\r
3451         int            types_index;\r
3452         va_list        va;\r
3453         bool           is_next_omittable;\r
3454         bool           is_next_omit;\r
3455         const TCHAR*   column_pointer;\r
3456         TCHAR          a_char;\r
3457         TCHAR          column[ 32 ];\r
3458         bit_flags32_t  read_flags;\r
3459         bit_flags32_t  next_read_flag;\r
3460         TCHAR*         out_str;\r
3461         size_t         str_size;\r
3462 \r
3463 \r
3464         va_start( va, Types );\r
3465         types_index = 0;\r
3466         is_next_omittable = false;\r
3467         column_pointer = StringOfCSV;\r
3468         read_flags = 0;\r
3469         next_read_flag = 1;\r
3470         while ( column_pointer != NULL ) {\r
3471                 out_str = NULL;\r
3472 \r
3473                 type = Types[ types_index ];\r
3474                 switch ( type ) {\r
3475                         case  _T('\0'):\r
3476                                 goto exit_for;\r
3477 \r
3478                         case  _T('+'):\r
3479                                 is_next_omittable = true;\r
3480                                 break;\r
3481 \r
3482                         case  _T('s'):\r
3483                                 out_str = va_arg( va, TCHAR* );\r
3484                                 str_size = va_arg( va, size_t );\r
3485                                 ASSERT_D( str_size >= 1,  e=E_OTHERS; goto fin );\r
3486                                 break;\r
3487 \r
3488                         default:\r
3489                                 out_str = column;\r
3490                                 str_size = sizeof( column );\r
3491                                 break;\r
3492                 }\r
3493 \r
3494                 if ( out_str != NULL ) {\r
3495 \r
3496                         // Set "out_str" : Column string in CSV\r
3497                         column_pointer = StrT_skip( column_pointer, _T(" \t") );\r
3498                         a_char = *column_pointer;\r
3499                         if ( is_next_omittable  &&  ( a_char == _T('\0')  ||  a_char == _T(',') ) ) {\r
3500                                 column_pointer = StrT_chrs( column_pointer, _T(",") );\r
3501                                 if ( column_pointer != NULL ) { column_pointer += 1; }\r
3502                                 is_next_omit = true;\r
3503                         } else {\r
3504                                 e= StrT_meltCSV( out_str, str_size, &column_pointer ); IF(e){goto fin;}\r
3505 \r
3506                                 is_next_omit = false;\r
3507                                 read_flags |= next_read_flag;\r
3508                         }\r
3509 \r
3510                         switch ( type ) {\r
3511                                 case  _T('s'):\r
3512                                         /* "va_arg" was already called */\r
3513                                         break;\r
3514 \r
3515                                 case  _T('i'): {\r
3516                                         int*  pointer_of_int = va_arg( va, int* );\r
3517 \r
3518                                         if ( ! is_next_omit ) {\r
3519                                                 *pointer_of_int = ttoi_ex( column, 0 );\r
3520                                         }\r
3521                                         break;\r
3522                                 }\r
3523                                 case  _T('f'): {\r
3524                                         double*  pointer_of_double = va_arg( va, double* );\r
3525 \r
3526                                         if ( ! is_next_omit ) {\r
3527                                                 *pointer_of_double = _tstof( column );\r
3528                                         }\r
3529                                         break;\r
3530                                 }\r
3531                                 case  _T('b'): {\r
3532                                         bool*  pointer_of_bool = va_arg( va, bool* );\r
3533                                         int    strings_index;\r
3534                                         static const TCHAR*  strings[] = {\r
3535                                                 _T("1"), _T("true"), _T("yes"),\r
3536                                         };\r
3537 \r
3538                                         if ( ! is_next_omit ) {\r
3539                                                 *pointer_of_bool = false;\r
3540                                                 for ( strings_index = 0;\r
3541                                                         strings_index < _countof( strings );\r
3542                                                         strings_index += 1 )\r
3543                                                 {\r
3544                                                         if ( _tcsicmp( column, strings[ strings_index ] ) == 0 ) {\r
3545                                                                 *pointer_of_bool = true;\r
3546                                                                 break;\r
3547                                                         }\r
3548                                                 }\r
3549                                         }\r
3550                                         break;\r
3551                                 }\r
3552                                 case  _T('t'): {\r
3553                                         SYSTEMTIME*  pointer_of_time = va_arg( va, SYSTEMTIME* );\r
3554                                         int*         pointer_of_bias = va_arg( va, int* );\r
3555 \r
3556                                         if ( ! is_next_omit ) {\r
3557                                                 e= W3CDTF_toSYSTEMTIME( column, pointer_of_time, pointer_of_bias );\r
3558                                                         IF(e){goto fin;}\r
3559                                         }\r
3560                                         break;\r
3561                                 }\r
3562 \r
3563                                 default:\r
3564                                         ASSERT_R( false, e=E_OTHERS; goto fin );\r
3565                         }\r
3566 \r
3567                         is_next_omittable = false;\r
3568                         next_read_flag <<= 1;\r
3569                 }\r
3570 \r
3571                 types_index += 1;\r
3572         }\r
3573 exit_for:\r
3574         if ( out_ReadFlags != NULL ) {\r
3575                 *out_ReadFlags = read_flags;\r
3576         }\r
3577 \r
3578         e=0;\r
3579 fin:\r
3580         va_end( va );\r
3581         return  e;\r
3582 }\r
3583 \r
3584 \r
3585  \r
3586 /***********************************************************************\r
3587   <<< [StrT_getExistSymbols] >>> \r
3588 ************************************************************************/\r
3589 errnum_t  StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )\r
3590 {\r
3591         errnum_t  e;\r
3592         int       i;\r
3593         bool*   syms_exists = NULL;\r
3594         bool    b_nosym = false;\r
3595         TCHAR*  sym = NULL;\r
3596         size_t  sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);\r
3597         int     n_sym = 0;\r
3598         const TCHAR** syms = NULL;\r
3599         const TCHAR*  p;\r
3600 \r
3601         UNREFERENCED_VARIABLE( bCase );\r
3602 \r
3603         sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;\r
3604 \r
3605 \r
3606         //=== Get Symbols\r
3607         p = Symbols;\r
3608         do {\r
3609                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
3610                 if ( sym[0] != _T('\0') )  n_sym ++;\r
3611         } while ( p != NULL );\r
3612 \r
3613         syms = (const TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;\r
3614         memset( (TCHAR**) syms, 0, n_sym * sizeof(TCHAR*) );\r
3615         syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;\r
3616         memset( syms_exists, 0, n_sym * sizeof(bool) );\r
3617 \r
3618         p = Symbols;  i = 0;\r
3619         do {\r
3620                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
3621                 if ( sym[0] != _T('\0') ) {\r
3622                         e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;\r
3623                         i++;\r
3624                 }\r
3625         } while ( p != NULL );\r
3626 \r
3627 \r
3628         //=== Check Str whether having Symbols\r
3629         p = Str;\r
3630         do {\r
3631                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
3632                 if ( sym[0] != _T('\0') ) {\r
3633                         for ( i = 0; i < n_sym; i++ ) {\r
3634                                 if ( _tcscmp( sym, syms[i] ) == 0 )  { syms_exists[i] = true;  break; }\r
3635                         }\r
3636                         if ( i == n_sym )  b_nosym = true;\r
3637                 }\r
3638         } while ( p != NULL );\r
3639 \r
3640 \r
3641         //=== Sum numbers\r
3642         {\r
3643                 va_list   va;\r
3644                 unsigned  num;\r
3645 \r
3646                 va_start( va, Symbols );\r
3647                 *out = 0;\r
3648                 for ( i = 0; i < n_sym; i++ ) {\r
3649                         num = va_arg( va, unsigned );\r
3650                         if ( syms_exists[i] )  *out |= num;\r
3651                 }\r
3652                 va_end( va );\r
3653         }\r
3654 \r
3655         e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );\r
3656 fin:\r
3657         if ( syms != NULL ) {\r
3658                 for ( i = 0; i < n_sym; i++ ) {\r
3659                         e= HeapMemory_free( &syms[i], e );\r
3660                 }\r
3661                 free( (TCHAR**) syms );\r
3662         }\r
3663         e= HeapMemory_free( &syms_exists, e );\r
3664         e= HeapMemory_free( &sym, e );\r
3665         return  e;\r
3666 err_fm: e= E_FEW_MEMORY; goto fin;\r
3667 }\r
3668 \r
3669  \r
3670 /**************************************************************************\r
3671   <<< [StrT_meltCmdLine] >>> \r
3672 *************************************************************************/\r
3673 errnum_t  StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )\r
3674 {\r
3675         errnum_t  e = 0;\r
3676         TCHAR*  t;\r
3677         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
3678         const TCHAR*  s;\r
3679         TCHAR  dummy;\r
3680         TCHAR  c;\r
3681 \r
3682         t = out_Str;\r
3683         s = *pLine;\r
3684         if ( out_Str_Size <= 1 )  { t = &dummy;  t_last = &dummy; }\r
3685 \r
3686         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
3687 \r
3688 \r
3689         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
3690         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
3691 \r
3692         switch ( *s ) {\r
3693 \r
3694                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
3695                 case _T('"'):\r
3696                         s++;\r
3697                         c = *s;\r
3698                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
3699                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
3700                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
3701                                 if ( c == _T('\0') )  break;\r
3702                                 *t = c;  t++;  s++;  c = *s;\r
3703                         }\r
3704                         *t = _T('\0');\r
3705 \r
3706                         s++;\r
3707                         for (;;) {\r
3708                                 if ( *s == _T(' ') )  { s = s+1;  break; }\r
3709                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
3710                                 s++;\r
3711                         }\r
3712                         *pLine = s;\r
3713                         return  e;\r
3714 \r
3715                 case '\0':\r
3716                         *t = _T('\0');\r
3717                         *pLine = NULL;\r
3718                         return  0;\r
3719 \r
3720                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
3721                 default: {\r
3722                         c = *s;\r
3723                         while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* \8bó\94\92\95\8e\9a\82Ü\82Å */\r
3724 \r
3725                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
3726 \r
3727                                 /* \83R\83s\81[\82·\82é */\r
3728                                 *t = c;  t++;  s++;  c = *s;\r
3729                         }\r
3730 \r
3731                         /* *pLine\82ð\8c\88\92è\82·\82é */\r
3732                         while ( *s == _T(' ') )  s = s + 1;\r
3733                         if ( *s == _T('\0') )  s = NULL;\r
3734 \r
3735                         /* \96\96\94ö */\r
3736                         *t = _T('\0');\r
3737 \r
3738                         *pLine = s;\r
3739                         return  e;\r
3740                 }\r
3741         }\r
3742 }\r
3743 \r
3744 \r
3745  \r
3746 /***********************************************************************\r
3747   <<< [W3CDTF_fromSYSTEMTIME] >>> \r
3748 ************************************************************************/\r
3749 errnum_t  W3CDTF_fromSYSTEMTIME( TCHAR* out_W3CDTF, size_t W3CDTF_ByteSize,\r
3750         const SYSTEMTIME* Time, int TimeZoneMinute )\r
3751 {\r
3752         errnum_t  e;\r
3753         TCHAR*    char_pointer = out_W3CDTF;\r
3754 \r
3755         e= stprintf_part_r( out_W3CDTF, W3CDTF_ByteSize, char_pointer, &char_pointer,\r
3756                 _T("%04d-%02d-%02dT%02d:%02d:%02d.%03d"),\r
3757                 Time->wYear, Time->wMonth,  Time->wDay,\r
3758                 Time->wHour, Time->wMinute, Time->wSecond, Time->wMilliseconds );\r
3759                 IF(e){goto fin;}\r
3760 \r
3761         e= W3CDTF_getTimeZoneDesignator( char_pointer,\r
3762                 GetStringSizeFromPointer( out_W3CDTF, W3CDTF_ByteSize, char_pointer ),\r
3763                 TimeZoneMinute ); IF(e){goto fin;}\r
3764 \r
3765         e=0;\r
3766 fin:\r
3767         return  e;\r
3768 }\r
3769 \r
3770 \r
3771  \r
3772 /***********************************************************************\r
3773   <<< [W3CDTF_toSYSTEMTIME] >>> \r
3774 ************************************************************************/\r
3775 errnum_t  W3CDTF_toSYSTEMTIME( const TCHAR* String, SYSTEMTIME* out_Time, int* out_BiasMinute )\r
3776 {\r
3777         errnum_t  e;\r
3778         size_t    string_length = _tcslen( String );\r
3779 \r
3780         /* 01234567890123456789012345678 */\r
3781         /*"yyyy-mm-ddThh:mm:ss.sss+00:00"*/\r
3782         /*"0000-00-00T00:00+00:00"*/\r
3783 \r
3784         IF_D( out_BiasMinute == NULL ) { e=E_OTHERS; goto fin; }\r
3785 \r
3786         /* With time */\r
3787         if ( string_length >= 11 ) {\r
3788                 TCHAR         a_char;\r
3789                 const TCHAR*  time_zone;\r
3790                 int           number;\r
3791 \r
3792                 IF ( String[10] != _T('T') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3793                 IF ( String[4] != _T('-')  ||  String[7] != _T('-') )\r
3794                         { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3795 \r
3796                 IF ( string_length < 16 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3797                 IF ( String[13] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3798 \r
3799                 out_Time->wYear      = (WORD) _ttoi( &String[0] );\r
3800                 out_Time->wMonth     = (WORD) _ttoi( &String[5] );\r
3801                 out_Time->wDayOfWeek = 0;\r
3802                 out_Time->wDay       = (WORD) _ttoi( &String[8] );\r
3803                 out_Time->wHour      = (WORD) _ttoi( &String[11] );\r
3804                 out_Time->wMinute    = (WORD) _ttoi( &String[14] );\r
3805 \r
3806                 a_char = String[16];\r
3807                 if ( a_char == _T('+')  ||  a_char == _T('-')  ||  a_char == _T('Z') ) {\r
3808                         time_zone = &String[16];\r
3809                         out_Time->wSecond = 0;\r
3810                         out_Time->wMilliseconds = 0;\r
3811                 } else {\r
3812                         /* Second */\r
3813                         IF ( string_length < 19 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3814                         IF ( a_char != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3815                         out_Time->wSecond = (WORD) _ttoi( &String[17] );\r
3816 \r
3817 \r
3818                         /* \8f¬\90\94\93_ */\r
3819                         a_char = String[19];\r
3820                         if ( a_char == _T('+')  ||  a_char == _T('-')  ||  a_char == _T('Z') ) {\r
3821                                 time_zone = &String[19];\r
3822                                 out_Time->wMilliseconds = 0;\r
3823                         }\r
3824                         else {\r
3825                                 IF ( a_char != _T('.') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3826 \r
3827                                 out_Time->wMilliseconds = 0;\r
3828 \r
3829                                 number = String[20] - _T('0');\r
3830                                 if ( number < 0  ||  number > 9 ) {\r
3831                                         time_zone = &String[20];\r
3832                                 } else {\r
3833                                         out_Time->wMilliseconds += (WORD)( number * 100 );\r
3834 \r
3835                                         number = String[21] - _T('0');\r
3836                                         if ( number < 0  ||  number > 9 ) {\r
3837                                                 time_zone = &String[21];\r
3838                                         } else {\r
3839                                                 out_Time->wMilliseconds += (WORD)( number * 10 );\r
3840 \r
3841                                                 number = String[22] - _T('0');\r
3842                                                 if ( number < 0  ||  number > 9 ) {\r
3843                                                         time_zone = &String[22];\r
3844                                                 } else {\r
3845                                                         const TCHAR*  pointer = &String[23];\r
3846 \r
3847                                                         out_Time->wMilliseconds += (WORD)( number * 1 );\r
3848 \r
3849                                                         for (;;) {\r
3850                                                                 number = *pointer - _T('0');\r
3851                                                                 if ( number < 0  ||  number > 9 )\r
3852                                                                         { break; }\r
3853 \r
3854                                                                 pointer += 1;\r
3855                                                         }\r
3856                                                         time_zone = pointer;\r
3857                                                 }\r
3858                                         }\r
3859                                 }\r
3860 \r
3861                                 a_char = *time_zone;\r
3862                                 IF ( ! ( a_char == _T('+')  ||  a_char == _T('-')  ||  a_char == _T('Z') ) )\r
3863                                         { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3864                         }\r
3865                 }\r
3866 \r
3867                 /* Time zone */\r
3868                 if ( a_char == _T('Z') ) {\r
3869                         *out_BiasMinute = 0;\r
3870                 }\r
3871                 else {\r
3872                         size_t  time_zone_length = string_length - ( time_zone - String );\r
3873                         int     bias_minute;\r
3874 \r
3875                         IF ( time_zone_length < 6 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3876                         IF ( time_zone[3] != _T(':') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3877 \r
3878                         bias_minute = _ttoi( &time_zone[1] ) * 60 + _ttoi( &time_zone[4] );\r
3879                         if ( a_char == _T('-') ) { bias_minute = -bias_minute; }\r
3880                         *out_BiasMinute = bias_minute;\r
3881                 }\r
3882         }\r
3883 \r
3884         /* Without time */\r
3885         else {\r
3886                 out_Time->wDayOfWeek    = 0;\r
3887                 out_Time->wHour         = 0;\r
3888                 out_Time->wMinute       = 0;\r
3889                 out_Time->wSecond       = 0;\r
3890                 out_Time->wMilliseconds = 0;\r
3891                 *out_BiasMinute         = 0;\r
3892 \r
3893                 IF ( string_length < 4 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3894 \r
3895                 /* Year */\r
3896                 out_Time->wYear = (WORD) _ttoi( &String[0] );\r
3897 \r
3898                 /* Month */\r
3899                 if ( string_length > 4 ) {\r
3900                         IF ( string_length < 7 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3901                         IF ( String[4] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3902                         out_Time->wMonth = (WORD) _ttoi( &String[5] );\r
3903                 } else {\r
3904                         out_Time->wMonth = 1;\r
3905                 }\r
3906 \r
3907                 /* Day */\r
3908                 if ( string_length > 7 ) {\r
3909                         IF ( string_length < 10 ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3910                         IF ( String[7] != _T('-') ) { e=E_NOT_FOUND_SYMBOL; goto fin; }\r
3911                         out_Time->wDay = (WORD) _ttoi( &String[8] );\r
3912                 } else {\r
3913                         out_Time->wDay = 1;\r
3914                 }\r
3915         }\r
3916 \r
3917         e=0;\r
3918 fin:\r
3919         return  e;\r
3920 }\r
3921 \r
3922 \r
3923  \r
3924 /***********************************************************************\r
3925   <<< [W3CDTF_getTimeZoneDesignator] >>> \r
3926 ************************************************************************/\r
3927 errnum_t  W3CDTF_getTimeZoneDesignator( TCHAR* out_TZD, size_t TZD_ByteSize,\r
3928         int  BiasMinute )\r
3929 {\r
3930         errnum_t  e;\r
3931         TCHAR     sign;\r
3932         TIME_ZONE_INFORMATION  time_zone;\r
3933 \r
3934 \r
3935         /* Set "BiasMinute" */\r
3936         if ( BiasMinute == W3CDTF_CURRENT_TIME_ZONE ) {\r
3937                 GetTimeZoneInformation( &time_zone );\r
3938                 BiasMinute = -time_zone.Bias;\r
3939         }\r
3940         else {\r
3941                 enum { minute_1day = 1440 };\r
3942 \r
3943                 IF_D ( BiasMinute < -minute_1day  ||  BiasMinute > minute_1day )\r
3944                         { e=E_OTHERS; goto fin; }\r
3945         }\r
3946 \r
3947 \r
3948         /* Set "sign" */\r
3949         if ( BiasMinute >= 0 ) {\r
3950                 sign = _T('+');\r
3951         } else {\r
3952                 sign = _T('-');\r
3953                 BiasMinute = -BiasMinute;\r
3954         }\r
3955 \r
3956 \r
3957         /* Set "out_TZD" */\r
3958         _stprintf_s( out_TZD, TZD_ByteSize / sizeof(TCHAR), _T("%c%02d:%02d"),\r
3959                 sign,  BiasMinute / 60,  BiasMinute % 60 );\r
3960 \r
3961         e=0;\r
3962 fin:\r
3963         return  e;\r
3964 }\r
3965 \r
3966 \r
3967  \r
3968 /***********************************************************************\r
3969   <<< [StrT_isFullPath] >>> \r
3970 ************************************************************************/\r
3971 bool  StrT_isFullPath( const TCHAR* path )\r
3972 {\r
3973         bool  ret;\r
3974 \r
3975         if ( path[0] == _T('\\')  &&  path[1] == _T('\\') ) {\r
3976                 ret = true;\r
3977         } else {\r
3978                 const TCHAR*  back_slash = _tcschr( path, _T('\\') );\r
3979                 const TCHAR*  slash = _tcschr( path, _T('/') );\r
3980                 const TCHAR*  colon = _tcschr( path, _T(':') );\r
3981 \r
3982                 ret = ( colon != NULL ) &&\r
3983                         ( back_slash == colon + 1  ||  slash == colon + 1 );\r
3984         }\r
3985 \r
3986         return  ret;\r
3987 }\r
3988 \r
3989  \r
3990 /**************************************************************************\r
3991   <<< [StrT_getFullPath_part] >>> \r
3992 *************************************************************************/\r
3993 errnum_t  StrT_getFullPath_part( TCHAR* out_FullPath, size_t FullPathSize, TCHAR* OutStart,\r
3994         TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
3995 {\r
3996         errnum_t      e;\r
3997         TCHAR         separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;\r
3998         const TCHAR*  separator_path;\r
3999         TCHAR*        out_full_path_over = (TCHAR*)( (uint8_t*) out_FullPath + FullPathSize );\r
4000         TCHAR*        null_position = NULL;\r
4001 \r
4002 \r
4003         #if  CHECK_ARG\r
4004                 /* "BasePath" must be out of "out_FullPath" */\r
4005                 ASSERT_R( BasePath < out_FullPath  ||\r
4006                         (uint8_t*) BasePath >= (uint8_t*) out_FullPath + FullPathSize,\r
4007                         goto err );\r
4008         #endif\r
4009 \r
4010 \r
4011         /* If "StepPath" == "", out_FullPath = "" */\r
4012         if ( StepPath[0] == _T('\0') ) {\r
4013                 ASSERT_R( FullPathSize >= sizeof(TCHAR), goto err_fm );\r
4014                 out_FullPath[0] = _T('\0');\r
4015                 e=0;  goto fin;\r
4016         }\r
4017 \r
4018 \r
4019         /* Set "OutStart" */\r
4020         if ( OutStart == NULL )\r
4021                 { OutStart = out_FullPath; }\r
4022 \r
4023 \r
4024         /* Set "separator" : \ or / from "BasePath" */\r
4025         if ( StrT_isFullPath( StepPath ) ) {\r
4026                 separator_path = StepPath;\r
4027         }\r
4028         else if ( BasePath == NULL ) {\r
4029                 separator = _T('\\');\r
4030                 separator_path = NULL;\r
4031         }\r
4032         else {\r
4033                 separator_path = BasePath;\r
4034         }\r
4035         if ( separator_path != NULL ) {\r
4036                 const TCHAR*    p;\r
4037                 const TCHAR*    p2;\r
4038 \r
4039                 p  = _tcschr( separator_path, _T('\\') );\r
4040                 p2 = _tcschr( separator_path, _T('/') );\r
4041                 if ( p == NULL ) {\r
4042                         if ( p2 == NULL )\r
4043                                 { separator = _T('\\'); }\r
4044                         else\r
4045                                 { separator = _T('/'); }\r
4046                 } else {\r
4047                         if ( p2 == NULL )\r
4048                                 { separator = _T('\\'); }\r
4049                         else {\r
4050                                 if ( p < p2 )\r
4051                                         { separator = _T('\\'); }\r
4052                                 else\r
4053                                         { separator = _T('/'); }\r
4054                         }\r
4055                 }\r
4056         }\r
4057 \r
4058 \r
4059         /* Set "OutStart" : "BasePath" + / + "StepPath" */\r
4060         if ( StrT_isFullPath( StepPath ) ) {\r
4061                 size_t  step_path_length = _tcslen( StepPath );\r
4062 \r
4063                 IF( OutStart + step_path_length >= out_full_path_over ) goto err_fa;\r
4064                 memmove( OutStart,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
4065 \r
4066                 /* Set "null_position" */\r
4067                 null_position = OutStart + step_path_length;\r
4068         }\r
4069         else {\r
4070                 TCHAR   c;\r
4071                 TCHAR*  p;\r
4072                 size_t  base_path_length;\r
4073                 size_t  step_path_length = _tcslen( StepPath );\r
4074 \r
4075                 if ( BasePath == NULL ) {\r
4076                         base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
4077                 }\r
4078                 else {\r
4079                         base_path_length = _tcslen( BasePath );\r
4080                         c = BasePath[ base_path_length - 1 ];\r
4081                         if ( c == _T('\\')  ||  c == _T('/') )\r
4082                                 { base_path_length -= 1; }\r
4083                 }\r
4084 \r
4085                 p = OutStart + base_path_length + 1;\r
4086                 IF( p + step_path_length >= out_full_path_over ) goto err_fa;\r
4087                 memmove( p,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
4088                         /* memmove is for "out_FullPath" == "StepPath" */\r
4089 \r
4090                 if ( BasePath == NULL ) {\r
4091                         GetCurrentDirectory( base_path_length + 1, OutStart );\r
4092                         if ( OutStart[ base_path_length - 1 ] == _T('\\') )\r
4093                                 { base_path_length -= 1; }\r
4094                 } else {\r
4095                         memcpy( OutStart,  BasePath,  base_path_length * sizeof(TCHAR) );\r
4096                 }\r
4097                 OutStart[ base_path_length ] = separator;\r
4098 \r
4099 \r
4100                 /* Set "null_position" */\r
4101                 null_position = p + step_path_length;\r
4102         }\r
4103 \r
4104 \r
4105         /* Replace \ and / to "separator" in "OutStart" */\r
4106         {\r
4107                 TCHAR  other_separator;\r
4108 \r
4109                 if ( separator == _T('/') )\r
4110                         { other_separator = _T('\\'); }\r
4111                 else\r
4112                         { other_separator = _T('/'); }\r
4113 \r
4114                 e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;\r
4115         }\r
4116 \r
4117 \r
4118         /* Replace \*\..\ to \ */\r
4119         {\r
4120                 enum  { length = 4 };\r
4121                 TCHAR   parent[ length + 1 ];  /* \..\ or /../ */\r
4122                 TCHAR*  parent_position;\r
4123                 TCHAR*  p;\r
4124 \r
4125                 parent[0] = separator;\r
4126                 parent[1] = _T('.');\r
4127                 parent[2] = _T('.');\r
4128                 parent[3] = separator;\r
4129                 parent[4] = _T('\0');\r
4130 \r
4131                 for (;;) {\r
4132                         parent_position = _tcsstr( OutStart, parent );\r
4133                         if ( parent_position == NULL )  { break; }\r
4134 \r
4135                         p = parent_position - 1;\r
4136                         for (;;) {\r
4137                                 IF( p < OutStart ) {goto err;}  /* "../" are too many */\r
4138                                 if ( *p == separator )  { break; }\r
4139                                 p -= 1;\r
4140                         }\r
4141 \r
4142                         memmove( p + 1,\r
4143                                 parent_position + length,\r
4144                                 ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );\r
4145 \r
4146                         null_position -= ( parent_position + length ) - ( p + 1 );\r
4147                 }\r
4148         }\r
4149 \r
4150 \r
4151         /* Cut last \*\.. */\r
4152         {\r
4153                 enum  { length = 3 };\r
4154                 TCHAR*  p;\r
4155 \r
4156                 while ( null_position - length >= OutStart ) {\r
4157                         if ( *( null_position - 3 ) != separator  ||\r
4158                              *( null_position - 2 ) != _T('.')  ||\r
4159                              *( null_position - 1 ) != _T('.') )\r
4160                                 { break; }\r
4161 \r
4162                         p = null_position - 4;\r
4163                         for (;;) {\r
4164                                 IF( p < OutStart ) {goto err;}  /* "../" are too many */\r
4165                                 if ( *p == separator )  { break; }\r
4166                                 p -= 1;\r
4167                         }\r
4168 \r
4169                         *p = _T('\0');\r
4170 \r
4171                         null_position = p;\r
4172                 }\r
4173         }\r
4174 \r
4175 \r
4176         /* Replace \.\ to \ */\r
4177         {\r
4178                 enum  { length = 3 };\r
4179                 TCHAR   current[ length + 1 ];  /* \.\ or /./ */\r
4180                 TCHAR*  current_position;\r
4181 \r
4182                 current[0] = separator;\r
4183                 current[1] = _T('.');\r
4184                 current[2] = separator;\r
4185                 current[3] = _T('\0');\r
4186 \r
4187                 for (;;) {\r
4188                         current_position = _tcsstr( OutStart, current );\r
4189                         if ( current_position == NULL )  { break; }\r
4190 \r
4191                         memmove( current_position + 1,\r
4192                                 current_position + length,\r
4193                                 ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );\r
4194 \r
4195                         null_position -= length - 1;\r
4196                 }\r
4197         }\r
4198 \r
4199 \r
4200         /* Cut last \. */\r
4201         {\r
4202                 TCHAR*  over = _tcschr( OutStart, _T('\0') );\r
4203 \r
4204                 while ( over - 2 >= OutStart  &&\r
4205                                 *( over - 1 ) == _T('.')  &&  *( over - 2 ) == separator ) {\r
4206                         over -= 2;\r
4207                         *over = _T('\0');\r
4208                 }\r
4209         }\r
4210 \r
4211 \r
4212         /* Add root / */\r
4213         if ( null_position - 1 >= OutStart ) {\r
4214                 if ( *( null_position - 1 ) == _T(':') ) {\r
4215                         IF( null_position + 1 >= out_full_path_over ) goto err_fa;\r
4216 \r
4217                         *( null_position + 0 ) = separator;\r
4218                         *( null_position + 1 ) = _T('\0');\r
4219                         null_position += 1;\r
4220                 }\r
4221         }\r
4222 \r
4223 \r
4224         /* Set "*out_OutLast" */\r
4225         if ( out_OutLast != NULL )\r
4226                 { *out_OutLast = null_position; }\r
4227 \r
4228         e=0;\r
4229 fin:\r
4230         return  e;\r
4231 \r
4232 err:     e = E_OTHERS;      goto fin;\r
4233 err_fa:  e = E_FEW_ARRAY;   goto fin;\r
4234 err_fm:  e = E_FEW_MEMORY;  goto fin;\r
4235 }\r
4236 \r
4237 \r
4238  \r
4239 /***********************************************************************\r
4240   <<< [StrT_allocateFullPath] >>> \r
4241 ************************************************************************/\r
4242 errnum_t  StrT_allocateFullPath( TCHAR** out_FullPath, const TCHAR* StepPath, TCHAR* BasePath )\r
4243 {\r
4244         errnum_t  e;\r
4245         int  step_path_length = _tcslen( StepPath );\r
4246         int  base_path_length;\r
4247         int  full_path_size;\r
4248 \r
4249         if ( BasePath == NULL ) {\r
4250                 base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
4251         } else {\r
4252                 base_path_length = _tcslen( BasePath );\r
4253         }\r
4254 \r
4255         full_path_size = ( step_path_length + 1 + base_path_length + 1 ) * sizeof(TCHAR);\r
4256 \r
4257         e= HeapMemory_allocateBytes( out_FullPath, full_path_size ); IF(e){goto fin;}\r
4258         e= StrT_getFullPath( *out_FullPath, full_path_size, StepPath, BasePath ); IF(e){goto fin;}\r
4259 \r
4260         e=0;\r
4261 fin:\r
4262         return  e;\r
4263 }\r
4264 \r
4265 \r
4266  \r
4267 /***********************************************************************\r
4268   <<< [StrT_getParentFullPath_part] >>> \r
4269 ************************************************************************/\r
4270 errnum_t  StrT_getParentFullPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
4271         TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
4272 {\r
4273         errnum_t  e;\r
4274         TCHAR*  p;\r
4275 \r
4276         IF_D( StrStart < Str ||  (char*) StrStart >= (char*)Str + StrSize ){goto err;}\r
4277 \r
4278         if ( StepPath[0] == _T('\0') ) {\r
4279                 *StrStart = _T('\0');\r
4280                 return  0;\r
4281         }\r
4282 \r
4283         /* \90â\91Î\83p\83X\82É\82·\82é */\r
4284         e= StrT_getFullPath( StrStart,\r
4285                 StrSize - ( (char*)StrStart - (char*)Str ),\r
4286                 StepPath, BasePath ); IF(e)goto fin;\r
4287 \r
4288 \r
4289         /* Cut last \ */\r
4290         p = _tcschr( StrStart, _T('\0') );\r
4291         if ( p > StrStart ) {\r
4292                 TCHAR  c = *( p - 1 );\r
4293                 if ( c == _T('\\')  ||  c == _T('/') )\r
4294                         { *( p - 1 ) = _T('\0'); }\r
4295         }\r
4296 \r
4297 \r
4298         /* \90e\82Ö */\r
4299         p = StrT_refFName( StrStart );\r
4300         if ( p > StrStart )  p--;\r
4301         *p = _T('\0');\r
4302 \r
4303 \r
4304         /* \83\8b\81[\83g\82È\82ç \ \82ð\95t\82¯\82é */\r
4305         if ( p == StrStart + 2 ) {\r
4306                 *p = _T('\\');  p++;  *p = _T('\0');\r
4307         }\r
4308 \r
4309         if ( out_StrLast != NULL )  *out_StrLast = p;\r
4310 \r
4311         e=0;\r
4312 fin:\r
4313         return  e;\r
4314 \r
4315 err:  e = E_OTHERS;  goto fin;\r
4316 }\r
4317 \r
4318 \r
4319  \r
4320 /***********************************************************************\r
4321   <<< [StrT_isOverOfFileName] >>> \r
4322 - "" or "\" or "/"\r
4323 ************************************************************************/\r
4324 inline bool  StrT_isOverOfFileName( const TCHAR* PointerInPath )\r
4325 {\r
4326         return  PointerInPath == NULL  ||\r
4327                 *PointerInPath == _T('\0')  ||\r
4328                 ( ( *PointerInPath == _T('\\')  ||  *PointerInPath == _T('/') )  &&\r
4329                         *(PointerInPath + 1) == _T('\0') );\r
4330 }\r
4331 \r
4332 \r
4333  \r
4334 /***********************************************************************\r
4335   <<< [StrT_getStepPath] >>> \r
4336 ************************************************************************/\r
4337 errnum_t  StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,\r
4338         const TCHAR* FullPath, const TCHAR* BasePath )\r
4339 {\r
4340         errnum_t      e;\r
4341         const TCHAR*  abs_pointer;\r
4342         const TCHAR*  base_pointer;\r
4343         TCHAR         abs_char;\r
4344         TCHAR         base_char;\r
4345         TCHAR         separator;\r
4346         const TCHAR*  abs_separator_pointer  = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
4347         const TCHAR*  base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
4348         TCHAR*        step_pointer;\r
4349         TCHAR         parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };\r
4350         TCHAR         base_path_2[ MAX_PATH ];\r
4351 \r
4352 \r
4353         ASSERT_D( out_StepPath != FullPath, goto err );\r
4354 \r
4355         abs_pointer = FullPath;\r
4356 \r
4357 \r
4358         /* Set "base_pointer" */\r
4359         if ( BasePath == NULL ) {\r
4360                 base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );\r
4361                 IF( base_pointer == NULL ) {goto err;}\r
4362         }\r
4363         else {\r
4364                 base_pointer = BasePath;\r
4365         }\r
4366 \r
4367 \r
4368         /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */\r
4369         separator = 0;\r
4370         for (;;) {  /* while abs_char == base_char */\r
4371                 abs_char  = *abs_pointer;\r
4372                 base_char = *base_pointer;\r
4373 \r
4374                 abs_char  = (TCHAR) _totlower( abs_char );\r
4375                 base_char = (TCHAR) _totlower( base_char );\r
4376 \r
4377                 if ( abs_char == _T('\0') ) {\r
4378 \r
4379                         /* out_StepPath = ".", if FullPath == BasePath */\r
4380                         if ( base_char == _T('\0') ) {\r
4381                                 e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;\r
4382                                 e=0; goto fin;\r
4383                         }\r
4384                         break;\r
4385                 }\r
4386                 if ( base_char == _T('\0') )  { break; }\r
4387 \r
4388                 if ( abs_char != base_char ) {\r
4389                         if ( ( abs_char  == _T('/')  ||  abs_char  == _T('\\') ) &&\r
4390                              ( base_char == _T('/')  ||  base_char == _T('\\') ) )\r
4391                                 { /* Do nothing */ }\r
4392                         else\r
4393                                 { break; }\r
4394                 }\r
4395 \r
4396                 /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */\r
4397                 if (  base_char == _T('/')  ||  base_char == _T('\\')  ) {\r
4398                         if ( separator == 0 )\r
4399                                 { separator = base_char; }\r
4400 \r
4401                         abs_separator_pointer = abs_pointer;\r
4402                         base_separator_pointer = base_pointer;\r
4403                 }\r
4404 \r
4405                 abs_pointer  += 1;\r
4406                 base_pointer += 1;\r
4407         }\r
4408 \r
4409 \r
4410         /* 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
4411         if (  abs_char == _T('/')  ||  abs_char == _T('\\')  ||\r
4412              base_char == _T('/')  || base_char == _T('\\')  ) {\r
4413              /* other character is '\0' */\r
4414 \r
4415                 if ( separator == 0 )\r
4416                         { separator = abs_char; }\r
4417 \r
4418                 abs_separator_pointer = abs_pointer;\r
4419                 base_separator_pointer = base_pointer;\r
4420         }\r
4421 \r
4422 \r
4423         /* out_StepPath = FullPath, if there is not same folder */\r
4424         if ( separator == 0 ) {\r
4425                 e= StrT_cpy( out_StepPath, StepPathSize, FullPath ); IF(e)goto fin;\r
4426                 e=0; goto fin;\r
4427         }\r
4428 \r
4429 \r
4430         /* Add "..\" to "out_StepPath" */\r
4431         parent_symbol[2] = separator;\r
4432         step_pointer = out_StepPath;\r
4433         for (;;) {\r
4434                 const TCHAR*  p1;\r
4435                 const TCHAR*  p2;\r
4436 \r
4437                 if ( StrT_isOverOfFileName( base_separator_pointer ) )\r
4438                         { break; }\r
4439 \r
4440 \r
4441                 /* Set "base_separator_pointer" : next separator */\r
4442                 p1 = _tcschr( base_separator_pointer + 1, _T('/') );\r
4443                 p2 = _tcschr( base_separator_pointer + 1, _T('\\') );\r
4444 \r
4445                 if ( p1 == NULL ) {\r
4446                         if ( p2 == NULL )\r
4447                                 { base_separator_pointer = NULL; }\r
4448                         else\r
4449                                 { base_separator_pointer = p2; }\r
4450                 }\r
4451                 else {\r
4452                         if ( p2 == NULL ) {\r
4453                                 base_separator_pointer = p1;\r
4454                         } else {\r
4455                                 if ( p1 < p2 )\r
4456                                         { base_separator_pointer = p1; }\r
4457                                 else\r
4458                                         { base_separator_pointer = p2; }\r
4459                         }\r
4460                 }\r
4461 \r
4462 \r
4463                 /* Add "..\" to "out_StepPath" */\r
4464                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,\r
4465                         parent_symbol, NULL ); IF(e)goto fin;\r
4466         }\r
4467 \r
4468 \r
4469         /* Copy a part of "FullPath" to "out_StepPath" */\r
4470         if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {\r
4471                 ASSERT_D( step_pointer > out_StepPath, goto err );\r
4472                 *( step_pointer - 1 ) = _T('\0');\r
4473         }\r
4474         else {\r
4475                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,\r
4476                         abs_separator_pointer + 1, NULL ); IF(e)goto fin;\r
4477         }\r
4478 \r
4479         e=0;\r
4480 fin:\r
4481         return  e;\r
4482 \r
4483 err:  e = E_OTHERS;  goto fin;\r
4484 }\r
4485 \r
4486 \r
4487  \r
4488 /***********************************************************************\r
4489   <<< [StrT_getBaseName_part] >>> \r
4490 ************************************************************************/\r
4491 errnum_t  StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
4492         TCHAR** out_StrLast, const TCHAR* SrcPath )\r
4493 {\r
4494         const TCHAR*  p1;\r
4495         const TCHAR*  p2;\r
4496         const TCHAR*  p3;\r
4497         const TCHAR*  ps;\r
4498 \r
4499         p1 = StrT_refFName( SrcPath );\r
4500 \r
4501 \r
4502         //=== # \82ª\96³\82¢\82Æ\82«\81A\8dÅ\8cã\82Ì\83s\83\8a\83I\83h\82Ì\91O\82Ü\82Å\82ª\81ABaseName\r
4503         ps = _tcschr( p1, _T('#') );\r
4504         if ( ps == NULL ) {\r
4505                 p2 = _tcsrchr( p1, _T('.') );\r
4506                 if ( p2 == NULL )  p2 = _tcsrchr( p1, _T('\0') );\r
4507         }\r
4508 \r
4509         //=== # \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
4510         else {\r
4511                 p2 = ps;\r
4512 \r
4513                 p3 = p1;\r
4514                 for (;;) {\r
4515                         p3 = _tcschr( p3, _T('.') );\r
4516                         if ( p3 == NULL || p3 > ps )  break;\r
4517                         p2 = p3;\r
4518                         p3 ++;\r
4519                 }\r
4520         }\r
4521 \r
4522         return  stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );\r
4523 }\r
4524 \r
4525  \r
4526 /***********************************************************************\r
4527   <<< [StrT_addLastOfFileName] >>> \r
4528 ************************************************************************/\r
4529 errnum_t  StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,\r
4530                              const TCHAR* BasePath, const TCHAR* AddName )\r
4531 {\r
4532         TCHAR           c;\r
4533         size_t          copy_size;\r
4534         size_t          free_size;\r
4535         char*           out_pos;\r
4536         const TCHAR*    last_pos_in_base = _tcschr( BasePath, _T('\0') );\r
4537         const TCHAR*    term_pos_in_base;\r
4538         const TCHAR*     add_pos_in_base;\r
4539         const TCHAR*  period_pos_in_base = _tcsrchr( BasePath, _T('.') );  // > term_pos_in_base\r
4540         const TCHAR*    last_pos_in_add  = _tcschr( AddName, _T('\0') );\r
4541         const TCHAR*    term_pos_in_add;\r
4542         const TCHAR*  period_pos_in_add  = _tcsrchr( AddName,  _T('.') );  // > term_pos_in_add\r
4543 \r
4544 \r
4545         DISCARD_BYTES( out_Path, PathSize );\r
4546 \r
4547 \r
4548         //=== term_pos_in_base\r
4549         for ( term_pos_in_base = last_pos_in_base;  term_pos_in_base >= BasePath;  term_pos_in_base -- ) {\r
4550                 c = *term_pos_in_base;\r
4551                 if ( c == _T('/') || c == _T('\\') )  break;\r
4552         }\r
4553 \r
4554 \r
4555         //=== term_pos_in_add\r
4556         for ( term_pos_in_add = last_pos_in_add;  term_pos_in_add >= AddName;  term_pos_in_add -- ) {\r
4557                 c = *term_pos_in_add;\r
4558                 if ( c == _T('/') || c == _T('\\') )  break;\r
4559         }\r
4560 \r
4561 \r
4562         //=== add_pos_in_base\r
4563         if ( term_pos_in_base < period_pos_in_base ) {\r
4564                 add_pos_in_base = period_pos_in_base;\r
4565         }\r
4566         else {\r
4567                 if ( term_pos_in_base < BasePath )\r
4568                         add_pos_in_base = _tcschr( BasePath, _T('\0') );\r
4569                 else\r
4570                         add_pos_in_base = _tcschr( term_pos_in_base, _T('\0') );\r
4571         }\r
4572 \r
4573 \r
4574         //=== setup output parameters\r
4575         out_pos   = (char*) out_Path;\r
4576         free_size = PathSize;\r
4577 \r
4578 \r
4579         //=== copy BasePath .. add_pos_in_base\r
4580         copy_size = (char*)add_pos_in_base - (char*)BasePath;\r
4581         if ( copy_size > free_size ) goto err_fa;\r
4582         memcpy( out_pos,  BasePath,  copy_size );\r
4583         out_pos   += copy_size;\r
4584         free_size -= copy_size;\r
4585 \r
4586 \r
4587         //=== copy AddName .. last_pos_in_add\r
4588         copy_size = (char*)last_pos_in_add - (char*)AddName;\r
4589         if ( copy_size > free_size ) goto err_fa;\r
4590         memcpy( out_pos,  AddName,  copy_size );\r
4591         out_pos   += copy_size;\r
4592         free_size -= copy_size;\r
4593 \r
4594 \r
4595         //=== add name and not change extension\r
4596         if ( period_pos_in_add == NULL ) {\r
4597 \r
4598                 //=== copy period_pos_in_base .. last_pos_in_base\r
4599                 if ( period_pos_in_base > term_pos_in_base ) {\r
4600                         copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);\r
4601                         if ( copy_size > free_size ) goto err_fa;\r
4602                         memcpy( out_pos,  period_pos_in_base,  copy_size );\r
4603                 }\r
4604                 else {\r
4605                         *(TCHAR*)out_pos = _T('\0');\r
4606                 }\r
4607         }\r
4608 \r
4609 \r
4610         //=== add name and change extension\r
4611         else {\r
4612 \r
4613                 if ( *(period_pos_in_add + 1) == _T('\0') )\r
4614                         *( (TCHAR*)out_pos - 1 ) = _T('\0');\r
4615                 else\r
4616                         *(TCHAR*)out_pos = _T('\0');\r
4617         }\r
4618 \r
4619         return  0;\r
4620 \r
4621 err_fa:\r
4622         return  E_FEW_ARRAY;\r
4623 }\r
4624 \r
4625 \r
4626  \r
4627 /***********************************************************************\r
4628   <<< [Strs_init] >>> \r
4629 ************************************************************************/\r
4630 enum { Strs_FirstSize = 0x0F00 };\r
4631 \r
4632 errnum_t  Strs_init( Strs* self )\r
4633 {\r
4634         char*  p;\r
4635 \r
4636         self->MemoryAddress = NULL;\r
4637 \r
4638         p = (char*) malloc( Strs_FirstSize );\r
4639         IF( p == NULL )  return  E_FEW_MEMORY;\r
4640 \r
4641         self->MemoryAddress = p;\r
4642         self->MemoryOver    = p + Strs_FirstSize;\r
4643         self->NextElem      = p + sizeof(TCHAR*);\r
4644         self->PointerToNextStrInPrevElem = (TCHAR**) p;\r
4645         self->Prev_PointerToNextStrInPrevElem = NULL;\r
4646         *(TCHAR**) p = NULL;\r
4647 \r
4648         self->FirstOfStrs = self;\r
4649         self->NextStrs = NULL;\r
4650 \r
4651         return  0;\r
4652 }\r
4653 \r
4654 \r
4655  \r
4656 /***********************************************************************\r
4657   <<< [Strs_finish] >>> \r
4658 ************************************************************************/\r
4659 errnum_t  Strs_finish( Strs* self, errnum_t e )\r
4660 {\r
4661         Strs*  mp;\r
4662         Strs*  next_mp;\r
4663 \r
4664         if ( self->MemoryAddress == NULL )  return 0;\r
4665 \r
4666         mp = self->FirstOfStrs;\r
4667         for (;;) {\r
4668                 free( mp->MemoryAddress );\r
4669                 if ( mp == self )  break;\r
4670 \r
4671                 next_mp = mp->NextStrs;\r
4672                 free( mp );\r
4673                 mp = next_mp;\r
4674         }\r
4675         self->MemoryAddress = NULL;\r
4676 \r
4677         return  e;\r
4678 }\r
4679 \r
4680 \r
4681  \r
4682 /***********************************************************************\r
4683   <<< [Strs_toEmpty] >>> \r
4684 ************************************************************************/\r
4685 errnum_t  Strs_toEmpty( Strs* self )\r
4686 {\r
4687         Strs_finish( self, 0 );\r
4688         return  Strs_init( self );\r
4689 }\r
4690 \r
4691 \r
4692  \r
4693 /***********************************************************************\r
4694   <<< [Strs_add] >>> \r
4695 ************************************************************************/\r
4696 errnum_t  Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )\r
4697 {\r
4698         return  Strs_addBinary( self, Str, _tcschr( Str, _T('\0') ) + 1, out_AllocStr );\r
4699 }\r
4700 \r
4701 \r
4702 errnum_t  Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )\r
4703 {\r
4704         errnum_t  e;\r
4705         size_t  str_size;\r
4706         size_t  elem_size;\r
4707 \r
4708         str_size  = ( (char*) StrOver - (char*) Str );\r
4709         elem_size = ( sizeof(TCHAR*) + str_size + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
4710 \r
4711         if ( self->NextElem + elem_size > self->MemoryOver )\r
4712                 { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }\r
4713 \r
4714 \r
4715         // [ NULL     | ... ]\r
4716         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
4717         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
4718         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
4719 \r
4720         if ( out_AllocStr != NULL )  *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
4721 \r
4722         //=== fill elem\r
4723         *(TCHAR**) self->NextElem = NULL;\r
4724         memcpy( self->NextElem + sizeof(TCHAR*),  Str,  str_size );\r
4725 \r
4726         //=== link to elem from previous elem\r
4727         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
4728 \r
4729         //=== update self\r
4730         self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;\r
4731         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
4732         self->NextElem = self->NextElem + elem_size;\r
4733 \r
4734         e=0;\r
4735 fin:\r
4736         return  e;\r
4737 }\r
4738 \r
4739 \r
4740  \r
4741 /***********************************************************************\r
4742   <<< [Strs_freeLast] >>> \r
4743 ************************************************************************/\r
4744 errnum_t  Strs_freeLast( Strs* self, TCHAR* AllocStr )\r
4745 {\r
4746         errnum_t  e;\r
4747         TCHAR*  str;\r
4748         TCHAR*  last_str;\r
4749         TCHAR*  prev_of_last_str;\r
4750         Strs*   mp;\r
4751         Strs*   prev_of_last_mp;\r
4752 \r
4753         if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {\r
4754                 prev_of_last_str = NULL;\r
4755                 last_str = NULL;\r
4756                 for ( Strs_forEach( self, &str ) ) {\r
4757                         prev_of_last_str = last_str;\r
4758                         last_str = str;\r
4759                 }\r
4760         }\r
4761         else {\r
4762                 prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );\r
4763                 last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );\r
4764         }\r
4765 \r
4766         // [ NULL     | ... ]\r
4767         IF( last_str != AllocStr ) {goto err;}\r
4768 \r
4769         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
4770         if ( prev_of_last_str == NULL ) {\r
4771                 self->NextElem = self->MemoryAddress + sizeof(TCHAR*);\r
4772                 self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;\r
4773         }\r
4774 \r
4775         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
4776         else if ( (char*) prev_of_last_str >= self->MemoryAddress  &&\r
4777                   (char*) prev_of_last_str <  self->MemoryOver ) {\r
4778                 self->NextElem = (char*)last_str - sizeof(TCHAR*);\r
4779                 self->PointerToNextStrInPrevElem = (TCHAR**)( (char*)prev_of_last_str - sizeof(TCHAR*) );\r
4780         }\r
4781 \r
4782         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
4783         else {\r
4784                 prev_of_last_mp = NULL;\r
4785                 for ( mp = self->FirstOfStrs;  mp->NextStrs != self;  mp = mp->NextStrs ) {\r
4786                         prev_of_last_mp = mp;\r
4787                 }\r
4788 \r
4789                 free( self->MemoryAddress );\r
4790 \r
4791                 *self = *mp;\r
4792 \r
4793                 if ( prev_of_last_mp == NULL ) {\r
4794                         self->FirstOfStrs = self;\r
4795                         self->NextStrs = NULL;\r
4796                 }\r
4797                 else {\r
4798                         prev_of_last_mp->NextStrs = self;\r
4799                 }\r
4800 \r
4801                 free( mp );\r
4802         }\r
4803         *self->PointerToNextStrInPrevElem = NULL;\r
4804         self->Prev_PointerToNextStrInPrevElem = NULL;\r
4805 \r
4806         e=0;\r
4807 fin:\r
4808         return  e;\r
4809 \r
4810 err:  e = E_OTHERS;  goto fin;\r
4811 }\r
4812 \r
4813 \r
4814  \r
4815 /***********************************************************************\r
4816   <<< [Strs_expandSize] >>> \r
4817 ************************************************************************/\r
4818 errnum_t  Strs_expandSize( Strs* self, size_t FreeSize )\r
4819 {\r
4820         Strs*   mp;\r
4821         Strs*   mp2;\r
4822         size_t  elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
4823         size_t  memory_size;\r
4824         char*   new_memory;\r
4825 \r
4826         // [ NULL     | ... ]\r
4827         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
4828         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
4829         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
4830 \r
4831         while ( self->NextElem + elem_size > self->MemoryOver ) {\r
4832 \r
4833                 //=== alloc\r
4834                 mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;\r
4835                 memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;\r
4836                 new_memory = (char*) malloc( memory_size );\r
4837                 IF( new_memory == NULL )  { free( mp );  goto err_fm; }\r
4838 \r
4839                 //=== move old memory\r
4840                 if ( self->FirstOfStrs == self ) {\r
4841                         self->FirstOfStrs = mp;\r
4842                 }\r
4843                 else {\r
4844                         for ( mp2 = self->FirstOfStrs;  mp2->NextStrs != self;  mp2 = mp2->NextStrs );\r
4845                         mp2->NextStrs = mp;\r
4846                 }\r
4847                 *mp = *self;\r
4848                 mp->NextStrs = self;\r
4849 \r
4850                 //=== setup new memory\r
4851                 self->MemoryAddress = new_memory;\r
4852                 self->MemoryOver    = new_memory + memory_size;\r
4853                 self->NextElem      = new_memory;\r
4854                 // self->PointerToNextStrInPrevElem is same value\r
4855                 // self->FirstOfStrs is same value\r
4856                 // self->NextStrs is always NULL\r
4857         }\r
4858         return  0;\r
4859 \r
4860 err_fm:  return  E_FEW_ARRAY;\r
4861 }\r
4862 \r
4863 \r
4864 /***********************************************************************\r
4865   <<< [Strs_commit] >>>\r
4866 ************************************************************************/\r
4867 errnum_t  Strs_commit( Strs* self, TCHAR* StrOver )\r
4868 {\r
4869         size_t  elem_size;\r
4870 \r
4871         if ( StrOver == NULL )\r
4872                 { StrOver = _tcschr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }\r
4873         elem_size = ( ( (char*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
4874 \r
4875         //=== fill elem\r
4876         *(TCHAR**) self->NextElem = NULL;\r
4877 \r
4878         //=== link to elem from previous elem\r
4879         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
4880 \r
4881         //=== update self\r
4882         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
4883         self->NextElem = self->NextElem + elem_size;\r
4884 \r
4885         return  0;\r
4886 }\r
4887 \r
4888 \r
4889  \r
4890 /***********************************************************************\r
4891   <<< [StrArr] >>> \r
4892 ************************************************************************/\r
4893 \r
4894 /*[StrArr_init]*/\r
4895 errnum_t  StrArr_init( StrArr* self )\r
4896 {\r
4897         errnum_t  e;\r
4898 \r
4899         Set2_initConst( &self->Array );\r
4900         Strs_initConst( &self->Chars );\r
4901 \r
4902         e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;\r
4903         e= Strs_init( &self->Chars ); IF(e)goto cancel;\r
4904         return  0;\r
4905 \r
4906 cancel:  StrArr_finish( self, e );  return  e;\r
4907 }\r
4908 \r
4909 \r
4910 /*[StrArr_finish]*/\r
4911 errnum_t  StrArr_finish( StrArr* self, errnum_t e )\r
4912 {\r
4913         if ( ! Set2_isInited( &self->Array ) )  return  e;\r
4914 \r
4915         e= Set2_finish( &self->Array, e );\r
4916         e= Strs_finish( &self->Chars, e );\r
4917         return  e;\r
4918 }\r
4919 \r
4920 \r
4921 /*[StrArr_add]*/\r
4922 errnum_t  StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )\r
4923 {\r
4924         errnum_t  e;\r
4925 \r
4926         e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;\r
4927         _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );\r
4928         e= StrArr_commit( self ); IF(e)goto fin;\r
4929         if ( out_I != NULL )  *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;\r
4930 \r
4931         e=0;\r
4932 fin:\r
4933         return  e;\r
4934 }\r
4935 \r
4936 \r
4937 /*[StrArr_commit]*/\r
4938 errnum_t  StrArr_commit( StrArr* self )\r
4939 {\r
4940         errnum_t  e;\r
4941         TCHAR*   p;\r
4942         TCHAR**  pp  = NULL;\r
4943         Set2*    arr = &self->Array;\r
4944         Strs*    ss  = &self->Chars;\r
4945 \r
4946         p = Strs_getFreeAddr( ss );\r
4947         e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;\r
4948         e= Strs_commit( ss, NULL ); IF(e)goto fin;\r
4949         *pp = p;\r
4950 \r
4951         e=0;\r
4952 fin:\r
4953         if ( e &&  pp != NULL )  e= Set2_freeLast( arr, pp, TCHAR*, e );\r
4954         return  e;\r
4955 }\r
4956 \r
4957 \r
4958 /*[StrArr_fillTo]*/\r
4959 errnum_t  StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )\r
4960 {\r
4961         errnum_t  e;\r
4962         const TCHAR*   p;\r
4963         const TCHAR**  pp;\r
4964         const TCHAR**  pp_over;\r
4965 \r
4966         n -= Set2_getCount( &self->Array, TCHAR* );\r
4967         if ( n <= 0 ) return 0;\r
4968 \r
4969         if ( Str == NULL ) {\r
4970                 p = NULL;\r
4971         }\r
4972         else {\r
4973                 e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;\r
4974         }\r
4975 \r
4976         e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;\r
4977         pp_over = pp + n;\r
4978         for ( ;  pp < pp_over;  pp++ )\r
4979                 *pp = p;\r
4980 \r
4981         e=0;\r
4982 fin:\r
4983         return  e;\r
4984 }\r
4985 \r
4986 \r
4987 /*[StrArr_toEmpty]*/\r
4988 errnum_t  StrArr_toEmpty( StrArr* self )\r
4989 {\r
4990         errnum_t  e, ee;\r
4991 \r
4992         e=0;\r
4993         ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;\r
4994         ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;\r
4995         return  e;\r
4996 }\r
4997 \r
4998 \r
4999  \r
5000 /***********************************************************************\r
5001   <<< [StrArr_parseCSV] >>> \r
5002 ************************************************************************/\r
5003 errnum_t  StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )\r
5004 {\r
5005         errnum_t      e;\r
5006         const TCHAR*  p = CSVLine;\r
5007 \r
5008         e= StrArr_toEmpty( self ); IF(e)goto fin;\r
5009 \r
5010         do {\r
5011                 e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );\r
5012                 if ( e == E_FEW_ARRAY ) {\r
5013                         e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;\r
5014                         continue;\r
5015                 }\r
5016                 IF(e)goto fin;\r
5017 \r
5018                 e = StrArr_commit( self ); IF(e)goto fin;\r
5019         } while ( p != NULL );\r
5020 \r
5021         e=0;\r
5022 fin:\r
5023         return  e;\r
5024 }\r
5025 \r
5026 \r
5027  \r
5028 /*=================================================================*/\r
5029 /* <<< [DebugTools/DebugTools.c] >>> */ \r
5030 /*=================================================================*/\r
5031  \r
5032 /***********************************************************************\r
5033   <<< [TestableDebugBreak] >>> \r
5034 ************************************************************************/\r
5035 typedef struct _TestableDebugBreakClass  TestableDebugBreakClass;\r
5036 struct _TestableDebugBreakClass {\r
5037         bool              IsDisableTestableDebugBreak;\r
5038         volatile int      DebugBreakCount;\r
5039         CRITICAL_SECTION  Critical;\r
5040         SingletonInitializerClass  Initializer;\r
5041 };\r
5042 static TestableDebugBreakClass  gs_TestableDebugBreak = { false, 0 };\r
5043 \r
5044 \r
5045 /*[SetTestableDebugBreak]*/\r
5046 void  SetTestableDebugBreak( bool IsEnableBreak )\r
5047 {\r
5048         TestableDebugBreakClass*  self = &gs_TestableDebugBreak;\r
5049         self->IsDisableTestableDebugBreak = ! IsEnableBreak;\r
5050 }\r
5051 \r
5052 /*[TestableDebugBreak_Sub]*/\r
5053 int  TestableDebugBreak_Sub()\r
5054 {\r
5055         TestableDebugBreakClass*  self = &gs_TestableDebugBreak;\r
5056 \r
5057         if ( ! SingletonInitializerClass_isInitialized( &self->Initializer ) ) {\r
5058                 if ( SingletonInitializerClass_isFirst( &self->Initializer ) ) {\r
5059 \r
5060                         InitializeCriticalSection( &self->Critical );\r
5061 \r
5062                         SingletonInitializerClass_onFinishedInitialize( &self->Initializer, 0 );\r
5063                 }\r
5064         }\r
5065 \r
5066         EnterCriticalSection( &self->Critical );\r
5067         self->DebugBreakCount += 1;\r
5068         LeaveCriticalSection( &self->Critical );\r
5069 \r
5070         return  ! self->IsDisableTestableDebugBreak;\r
5071 }\r
5072 \r
5073 /*[GetDebugBreakCount]*/\r
5074 int  GetDebugBreakCount()\r
5075 {\r
5076         TestableDebugBreakClass*  self = &gs_TestableDebugBreak;\r
5077         return  self->DebugBreakCount;\r
5078 }\r
5079 \r
5080 \r
5081  \r
5082 /*=================================================================*/\r
5083 /* <<< [SetX/SetX.c] >>> */ \r
5084 /*=================================================================*/\r
5085  \r
5086 /***********************************************************************\r
5087   <<< [Set2_init] >>> \r
5088 ************************************************************************/\r
5089 int  Set2_init( Set2* m, int FirstSize )\r
5090 {\r
5091         m->First = malloc( FirstSize );\r
5092         if ( m->First == NULL )  return  E_FEW_MEMORY;\r
5093         m->Next = m->First;\r
5094         m->Over = (char*)m->First + FirstSize;\r
5095 \r
5096         #ifdef _DEBUG\r
5097         m->PointerOfDebugArray = NULL;\r
5098         #endif\r
5099 \r
5100         return  0;\r
5101 }\r
5102  \r
5103 /***********************************************************************\r
5104   <<< [Set2_finish] >>> \r
5105 ************************************************************************/\r
5106 int  Set2_finish( Set2* m, int e )\r
5107 {\r
5108         if ( m->First != NULL )  { free( m->First );  m->First = NULL; }\r
5109         return  e;\r
5110 }\r
5111 \r
5112  \r
5113 /***********************************************************************\r
5114   <<< [Set2_ref_imp] >>> \r
5115 ************************************************************************/\r
5116 int  Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )\r
5117 {\r
5118         int    e;\r
5119         char*  p;\r
5120 \r
5121         IF( iElem < 0 ) goto err_ns;\r
5122         p = (char*) m->First + ( (unsigned)iElem * ElemSize );\r
5123         IF( p >= (char*)m->Next ) goto err_ns;\r
5124         *(char**)out_pElem = p;\r
5125 \r
5126         e=0;\r
5127 fin:\r
5128         return  e;\r
5129 \r
5130 err_ns:  e = E_NOT_FOUND_SYMBOL;  goto fin;\r
5131 }\r
5132 \r
5133 \r
5134  \r
5135 /***********************************************************************\r
5136   <<< [Set2_getIterator] >>> \r
5137 ************************************************************************/\r
5138 errnum_t  Set2_getIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
5139 {\r
5140         out_Iterator->Parent = self;\r
5141         out_Iterator->ElementSize = ElementSize;\r
5142         out_Iterator->Current = (uint8_t*) self->First - ElementSize;\r
5143         return  0;\r
5144 }\r
5145 \r
5146 \r
5147  \r
5148 /***********************************************************************\r
5149   <<< [Set2_getDescendingIterator] >>> \r
5150 ************************************************************************/\r
5151 errnum_t  Set2_getDescendingIterator( Set2* self, Set2_IteratorClass* out_Iterator, int ElementSize )\r
5152 {\r
5153         out_Iterator->Parent = self;\r
5154         out_Iterator->ElementSize = ElementSize;\r
5155         out_Iterator->Current = (uint8_t*) self->Next;\r
5156         return  0;\r
5157 }\r
5158 \r
5159 \r
5160  \r
5161 /***********************************************************************\r
5162   <<< [Set2_IteratorClass_getNext] >>> \r
5163 ************************************************************************/\r
5164 void*  Set2_IteratorClass_getNext( Set2_IteratorClass* self )\r
5165 {\r
5166         uint8_t*  next = self->Current + self->ElementSize;\r
5167 \r
5168         if ( next >= (uint8_t*) self->Parent->Next ) {\r
5169                 return  NULL;\r
5170         } else {\r
5171                 self->Current = next;\r
5172                 return  next;\r
5173         }\r
5174 }\r
5175 \r
5176 \r
5177  \r
5178 /***********************************************************************\r
5179   <<< [Set2_IteratorClass_getPrevious] >>> \r
5180 ************************************************************************/\r
5181 void*  Set2_IteratorClass_getPrevious( Set2_IteratorClass* self )\r
5182 {\r
5183         uint8_t*  previous = self->Current - self->ElementSize;\r
5184 \r
5185         if ( previous < (uint8_t*) self->Parent->First ) {\r
5186                 return  NULL;\r
5187         } else {\r
5188                 self->Current = previous;\r
5189                 return  previous;\r
5190         }\r
5191 }\r
5192 \r
5193 \r
5194  \r
5195 /***********************************************************************\r
5196   <<< [Set2_alloc_imp] >>> \r
5197 ************************************************************************/\r
5198 int  Set2_alloc_imp( Set2* m, void* pp, size_t size )\r
5199 {\r
5200         int  e;\r
5201 \r
5202         e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;\r
5203         *(void**)pp = m->Next;\r
5204         m->Next = (char*) m->Next + size;\r
5205 \r
5206         DISCARD_BYTES( *(void**)pp, size );\r
5207 \r
5208         e=0;\r
5209 fin:\r
5210         return  e;\r
5211 }\r
5212 \r
5213 \r
5214 int  Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )\r
5215 {\r
5216         int    e;\r
5217         char*  p;\r
5218 \r
5219         e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;\r
5220         p = (char*) m->Next;\r
5221         m->Next = p + ElemsSize;\r
5222         *(char**)out_pElem = p;\r
5223 \r
5224         e=0;\r
5225 fin:\r
5226         return  e;\r
5227 }\r
5228 \r
5229 \r
5230  \r
5231 /***********************************************************************\r
5232   <<< [Set2_expandIfOverByAddr_imp] >>> \r
5233 ************************************************************************/\r
5234 errnum_t  Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )\r
5235 {\r
5236         errnum_t  e;\r
5237         void*     new_first;\r
5238         unsigned  offset_of_over;\r
5239         unsigned  offset_of_next;\r
5240 \r
5241         if ( OverAddrBasedOnNowFirst <= m->Over ) { e=E_OTHERS; goto fin; }\r
5242 \r
5243         offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );\r
5244         offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;\r
5245         IF_D( offset_of_next >= 0x80000000 ) { e=E_OTHERS; goto fin; }\r
5246         IF_D( offset_of_over == 0 ) { e=E_OTHERS; goto fin; }\r
5247         while ( offset_of_over < offset_of_next ) { offset_of_over *= 2; }\r
5248         IF( offset_of_over >= 0x10000000 ) { e=E_OTHERS; goto fin; }\r
5249 \r
5250         new_first = realloc( m->First, offset_of_over * 2 );\r
5251                 IF( new_first == NULL ) { e=E_FEW_MEMORY; goto fin; }\r
5252 \r
5253         m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );\r
5254         m->Over = (char*) new_first + offset_of_over * 2;\r
5255         m->First = new_first;\r
5256 \r
5257         #ifdef _DEBUG\r
5258         if ( m->PointerOfDebugArray != NULL )\r
5259                 { *m->PointerOfDebugArray = m->First; }\r
5260         #endif\r
5261 \r
5262         e=0;\r
5263 fin:\r
5264         return  e;\r
5265 }\r
5266 \r
5267 \r
5268  \r
5269 /***********************************************************************\r
5270   <<< [Set2_separate] >>> \r
5271 ************************************************************************/\r
5272 int  Set2_separate( Set2* m, int NextSize, void** allocate_Array )\r
5273 {\r
5274         int    e;\r
5275         void*  p = m->First;\r
5276 \r
5277         if ( NextSize == 0 ) {\r
5278                 m->First = NULL;\r
5279         }\r
5280         else {\r
5281                 e= Set2_init( m, NextSize ); IF(e)goto fin;\r
5282         }\r
5283         *allocate_Array = p;\r
5284 \r
5285         e=0;\r
5286 fin:\r
5287         return  e;\r
5288 }\r
5289 \r
5290 \r
5291  \r
5292 /***********************************************************************\r
5293   <<< [Set2_pop_imp] >>> \r
5294 ************************************************************************/\r
5295 int  Set2_pop_imp( Set2* m, void* pp, size_t size )\r
5296 {\r
5297         int    e;\r
5298         void*  p;\r
5299 \r
5300         p = (char*) m->Next - size;\r
5301 \r
5302         IF ( p < m->First ) { e=E_OTHERS; goto fin; }\r
5303 \r
5304         m->Next = p;\r
5305         *(void**)pp = p;\r
5306 \r
5307         e=0;\r
5308 fin:\r
5309         return  e;\r
5310 }\r
5311 \r
5312 \r
5313  \r
5314 /***********************************************************************\r
5315   <<< [Set2_setDebug] >>> \r
5316 ************************************************************************/\r
5317 #ifdef _DEBUG\r
5318 void  Set2_setDebug( Set2* m, void* PointerOfDebugArray )\r
5319 {\r
5320         m->PointerOfDebugArray = (void**) PointerOfDebugArray;\r
5321         *m->PointerOfDebugArray = m->First;\r
5322 }\r
5323 #endif\r
5324 \r
5325 \r
5326  \r
5327 /***********************************************************************\r
5328   <<< (Variant_SuperClass) >>> \r
5329 ************************************************************************/\r
5330 static const ClassID_Class*  gs_Variant_SuperClass_SuperClassIDs[] = {\r
5331     &g_ClassID_SuperClass_ID, &g_Variant_SuperClass_ID,\r
5332 };\r
5333 \r
5334 /*[g_Variant_SuperClass_ID]*/\r
5335 const ClassID_Class  g_Variant_SuperClass_ID = {\r
5336     "Variant_SuperClass",\r
5337     gs_Variant_SuperClass_SuperClassIDs,\r
5338     _countof( gs_Variant_SuperClass_SuperClassIDs ),\r
5339     sizeof( Variant_SuperClass ),\r
5340     Variant_SuperClass_initialize,\r
5341     NULL,\r
5342     0,\r
5343 };\r
5344 \r
5345 \r
5346 /*[Variant_SuperClass_initialize]*/\r
5347 errnum_t  Variant_SuperClass_initialize( Variant_SuperClass* self, void* Parameter )\r
5348 {\r
5349         self->ClassID = &g_Variant_SuperClass_ID;\r
5350         self->FinalizerVTable = NULL;\r
5351         self->StaticAddress = NULL;\r
5352         UNREFERENCED_VARIABLE( Parameter );\r
5353         return  0;\r
5354 }\r
5355 \r
5356 \r
5357  \r
5358 /*=================================================================*/\r
5359 /* <<< [Print/Print2.c] >>> */ \r
5360 /*=================================================================*/\r
5361  \r
5362 /***********************************************************************\r
5363   <<< [PrintfCounterClass] >>> \r
5364 ************************************************************************/\r
5365 #if USE_PRINTF_COUNTER\r
5366         PrintfCounterClass  g_PrintfCounter;\r
5367 #endif\r
5368 \r
5369 \r
5370  \r
5371 /***********************************************************************\r
5372   <<< [printf_to_debugger] >>> \r
5373 ************************************************************************/\r
5374 #ifdef  _MSC_VER\r
5375 void  printf_to_debugger( const char* format, ... )\r
5376 {\r
5377         va_list  va;\r
5378         char     s[1024];\r
5379 \r
5380         va_start( va, format );\r
5381         vsprintf_r( s, sizeof(s), format, va );\r
5382         va_end( va );\r
5383 \r
5384         OutputDebugStringA( s );\r
5385 }\r
5386 #endif\r
5387 \r
5388 \r
5389  \r
5390 /***********************************************************************\r
5391   <<< [wprintf_to_debugger] >>> \r
5392 ************************************************************************/\r
5393 #ifdef  _MSC_VER\r
5394 void  wprintf_to_debugger( const wchar_t* format, ... )\r
5395 {\r
5396         va_list  va;\r
5397         wchar_t  s[1024];\r
5398 \r
5399         va_start( va, format );\r
5400         vswprintf_r( s, sizeof(s), format, va );\r
5401         va_end( va );\r
5402 \r
5403         OutputDebugStringW( s );\r
5404 }\r
5405 #endif\r
5406 \r
5407 \r
5408  \r
5409 /***********************************************************************\r
5410   <<< [vsprintf_r] >>> \r
5411 ************************************************************************/\r
5412 errnum_t  vsprintf_r( char* s, size_t s_size, const char* format, va_list va )\r
5413 {\r
5414         #if _MSC_VER\r
5415                 #pragma warning(push)\r
5416                 #pragma warning(disable: 4996)\r
5417         #endif\r
5418 \r
5419         int  r = _vsnprintf( s, s_size, format, va );\r
5420 \r
5421         #if _MSC_VER\r
5422                 #pragma warning(pop)\r
5423         #endif\r
5424 \r
5425         IF( r == (int) s_size )\r
5426                 { s[s_size-1] = '\0';  return E_FEW_ARRAY; }\r
5427         IF( r == -1 )\r
5428                 { return E_NOT_FOUND_SYMBOL; }  /* Bad character code */\r
5429 \r
5430         return  0;\r
5431 }\r
5432 \r
5433 \r
5434  \r
5435 /***********************************************************************\r
5436   <<< [vswprintf_r] >>> \r
5437 ************************************************************************/\r
5438 #ifndef  __linux__\r
5439 errnum_t  vswprintf_r( wchar_t* s, size_t s_size, const wchar_t* format, va_list va )\r
5440 {\r
5441         size_t  tsize = s_size / sizeof(wchar_t);\r
5442 \r
5443         #pragma warning(push)\r
5444         #pragma warning(disable: 4996)\r
5445                 int  r = _vsnwprintf( s, tsize, format, va );\r
5446         #pragma warning(pop)\r
5447 \r
5448         if ( r == (int) tsize || r == -1 ) { s[tsize-1] = '\0';  return E_FEW_ARRAY; }\r
5449         else  return  0;\r
5450 }\r
5451 #endif\r
5452 \r
5453 \r
5454  \r
5455 /***********************************************************************\r
5456   <<< [stprintf_r] >>> \r
5457 ************************************************************************/\r
5458 errnum_t  stprintf_r( TCHAR* s, size_t s_size, const TCHAR* format, ... )\r
5459 {\r
5460         errnum_t  e;\r
5461         va_list   va;\r
5462 \r
5463         va_start( va, format );\r
5464         e = vstprintf_r( s, s_size, format, va );\r
5465         va_end( va );\r
5466         return  e;\r
5467 }\r
5468 \r
5469 \r
5470  \r
5471 /***********************************************************************\r
5472   <<< [stcpy_part_r] >>> \r
5473 ************************************************************************/\r
5474 errnum_t  stcpy_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
5475                    const TCHAR* src, const TCHAR* src_over )\r
5476 {\r
5477         size_t  s_space = (char*)s + s_size - (char*)s_start;\r
5478         size_t  src_size;\r
5479 \r
5480         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size )  { return 1; }\r
5481 \r
5482         if ( src_over == NULL )  { src_over = _tcschr( src, _T('\0') ); }\r
5483         src_size = (char*)src_over - (char*)src;\r
5484         IF ( src_size >= s_space ) {\r
5485                 s_space -= sizeof(TCHAR);\r
5486                 memcpy( s, src, s_space );\r
5487 \r
5488                 s_start = (TCHAR*)((char*)s_start + s_space );\r
5489                 *s_start = '\0';\r
5490 \r
5491                 if ( p_s_last != NULL ) { *p_s_last=s_start; }\r
5492                 return  E_FEW_ARRAY;\r
5493         }\r
5494 \r
5495         memcpy( s_start, src, src_size + sizeof(TCHAR) );\r
5496         s_start = (TCHAR*)((char*)s_start + src_size);  *s_start = _T('\0');\r
5497         if ( p_s_last != NULL )  { *p_s_last = s_start; }\r
5498 \r
5499         return  0;\r
5500 }\r
5501 \r
5502 \r
5503  \r
5504 /***********************************************************************\r
5505   <<< [stprintf_part_r] >>> \r
5506 ************************************************************************/\r
5507 errnum_t  stprintf_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
5508                       const TCHAR* format, ... )\r
5509 {\r
5510         errnum_t  e;\r
5511         va_list   va;\r
5512         va_start( va, format );\r
5513 \r
5514         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) {return E_OTHERS;}\r
5515 \r
5516         e = vstprintf_r( s_start, s_size - ( (char*)s_start - (char*)s), format, va );\r
5517         va_end( va );  if ( p_s_last != NULL )  *p_s_last = _tcschr( s_start, '\0' );\r
5518         return  e;\r
5519 }\r
5520 \r
5521 \r
5522  \r
5523 /*=================================================================*/\r
5524 /* <<< [Lock_1/Lock_1.c] >>> */ \r
5525 /*=================================================================*/\r
5526  \r
5527 /*-------------------------------------------------------------------------*/\r
5528 /* <<<< ### (SingletonInitializerClass) implement >>>> */ \r
5529 /*-------------------------------------------------------------------------*/\r
5530 \r
5531 \r
5532 volatile int  g_SingletonInitializerClass_FailSleepTime = SingletonInitializerClass_FailSleepTime;\r
5533 \r
5534 \r
5535 /*[SingletonInitializerClass_isFirst]*/\r
5536 bool  SingletonInitializerClass_isFirst( SingletonInitializerClass* self )\r
5537 {\r
5538         for (;;) {\r
5539                 if ( InterlockedCompareExchange( &self->InitializeStep, 1, 0 ) == 0 ) {\r
5540                         return  true;\r
5541                 }\r
5542                 else {\r
5543                         while ( self->InitializeStep == 1 ) {\r
5544                                 Sleep( 0 );  /* Wait for initialized by other thread. */\r
5545                         }\r
5546 \r
5547                         if ( self->InitializeStep == 2 ) {\r
5548                                 return  false;\r
5549                         }\r
5550 \r
5551                         Sleep( g_SingletonInitializerClass_FailSleepTime );\r
5552                         g_SingletonInitializerClass_FailSleepTime = 0;\r
5553                 }\r
5554         }\r
5555 }\r
5556 \r
5557 \r
5558 /*[SingletonInitializerClass_onFinishedInitialize]*/\r
5559 void  SingletonInitializerClass_onFinishedInitialize( SingletonInitializerClass* self, errnum_t e )\r
5560 {\r
5561         if ( e == 0 )\r
5562                 { self->InitializeStep = 2; }\r
5563         else\r
5564                 { self->InitializeStep = 0; }\r
5565 }\r
5566 \r
5567 \r
5568 /*[SingletonInitializerClass_isInitialized]*/\r
5569 bool  SingletonInitializerClass_isInitialized( SingletonInitializerClass* self )\r
5570 {\r
5571         return  ( self->InitializeStep == 2 );\r
5572 }\r
5573 \r
5574 \r
5575 /*-------------------------------------------------------------------------*/\r
5576 /* <<< End of Class implement >>> */ \r
5577 /*-------------------------------------------------------------------------*/\r
5578 \r
5579 \r
5580  \r
5581 /*=================================================================*/\r
5582 /* <<< [CRT_plus_1/CRT_plus_1.c] >>> */ \r
5583 /*=================================================================*/\r
5584  \r
5585 /***********************************************************************\r
5586   <<< [ttoi_ex] >>> \r
5587 ************************************************************************/\r
5588 int  ttoi_ex( const TCHAR* string,  bit_flags_fast32_t options )\r
5589 {\r
5590         int  return_value;\r
5591 \r
5592         UNREFERENCED_VARIABLE( options);\r
5593 \r
5594         if ( string[0] == _T('0')  &&\r
5595                 ( string[1] == _T('x')  ||  string[1] == _T('X') ) )\r
5596         {\r
5597                 return_value = (int) _tcstoul( &string[2], NULL, 16 );\r
5598         }\r
5599         else {\r
5600                 return_value = _ttoi( string );\r
5601         }\r
5602 \r
5603         return  return_value;\r
5604 }\r
5605 \r
5606 \r
5607  \r
5608 /***********************************************************************\r
5609   <<< (ClassID_Class) >>> \r
5610 ************************************************************************/\r
5611 \r
5612 /*[ClassID_Class_isSuperClass]*/\r
5613 bool  ClassID_Class_isSuperClass( const ClassID_Class* ClassID, const ClassID_Class* SuperClassID )\r
5614 {\r
5615         if ( ClassID == SuperClassID ) {\r
5616                 return  true;\r
5617         }\r
5618         else {\r
5619                 int  i;\r
5620 \r
5621                 for ( i = ClassID->SuperClassID_Array_Count - 1;  i >= 0;  i -= 1 ) {\r
5622                         if ( ClassID->SuperClassID_Array[ i ] == SuperClassID ) {\r
5623                                 return  true;\r
5624                         }\r
5625                 }\r
5626                 return  false;\r
5627         }\r
5628 }\r
5629 \r
5630 \r
5631 /*[ClassID_Class_createObject]*/\r
5632 errnum_t  ClassID_Class_createObject( const ClassID_Class* ClassID, void* out_Object, void* Parameter )\r
5633 {\r
5634         errnum_t  e;\r
5635         ClassID_SuperClass*  object = NULL;\r
5636 \r
5637         e= HeapMemory_allocateBytes( &object, ClassID->Size ); IF(e){goto fin;}\r
5638         if ( ClassID->InitializeFunction != NULL ) {\r
5639                 e= ClassID->InitializeFunction( object, Parameter ); IF(e){goto fin;}\r
5640         }\r
5641         else {\r
5642                 memset( object, 0, ClassID->Size );\r
5643                 object->ClassID = ClassID;\r
5644         }\r
5645         *(void**) out_Object = object;\r
5646         object = NULL;\r
5647 \r
5648         e=0;\r
5649 fin:\r
5650         if ( object != NULL ) { e= HeapMemory_free( &object, e ); }\r
5651         return  e;\r
5652 }\r
5653 \r
5654 \r
5655 /*[ClassID_Class_getVTable]*/\r
5656 void*  ClassID_Class_getVTable( const ClassID_Class* ClassID, const InterfaceID_Class* InterfaceID )\r
5657 {\r
5658         int  i;\r
5659 \r
5660         for ( i = ClassID->InterfaceToVTable_Array_Conut - 1;  i >= 0;  i -= 1 ) {\r
5661                 if ( ClassID->InterfaceToVTable_Array[ i ].InterfaceID == InterfaceID ) {\r
5662                         return  (void*) ClassID->InterfaceToVTable_Array[ i ].VTable;\r
5663                 }\r
5664         }\r
5665         return  NULL;\r
5666 }\r
5667 \r
5668 \r
5669  \r
5670 /***********************************************************************\r
5671   <<< (ClassID_SuperClass) >>> \r
5672 ************************************************************************/\r
5673 \r
5674 /*[g_ClassID_SuperClass_ID]*/\r
5675 const ClassID_Class  g_ClassID_SuperClass_ID = {\r
5676         "ClassID_SuperClass",          /* /ClassName */\r
5677         NULL,                          /* .SuperClassID_Array */\r
5678         0,                             /* .SuperClassID_Array_Count */\r
5679         sizeof( ClassID_SuperClass ),  /* .Size */\r
5680         NULL,                          /* .InitializeFunction */\r
5681         NULL,                          /* .InterfaceToVTable_Array */\r
5682         0                              /* .InterfaceToVTable_Array_Conut */\r
5683 };\r
5684 \r
5685 \r
5686  \r
5687 /***********************************************************************\r
5688   <<< (g_FinalizerInterface_ID) >>> \r
5689 ************************************************************************/\r
5690 \r
5691 const InterfaceID_Class  g_FinalizerInterface_ID = { "FinalizerInterface" };\r
5692 \r
5693 \r
5694 \r
5695  \r
5696 /***********************************************************************\r
5697   <<< (g_PrintXML_Interface_ID) >>> \r
5698 ************************************************************************/\r
5699 \r
5700 const InterfaceID_Class  g_PrintXML_Interface_ID = { "PrintXML_Interface" };\r
5701 \r
5702 \r
5703 \r
5704  \r