OSDN Git Service

618bee3b8de656a90b4114c7f3b21cb27919a103
[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_init] >>> \r
24 ************************************************************************/\r
25 int  Globals_init()\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_finish] >>> \r
41 ************************************************************************/\r
42 int  Globals_finish( 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 /* <<< [Locale/Locale.c] >>> */ \r
388 /*=================================================================*/\r
389  \r
390 /***********************************************************************\r
391   <<< [g_LocaleSymbol] >>> \r
392 ************************************************************************/\r
393 char*  g_LocaleSymbol = "";\r
394 \r
395 \r
396  \r
397 /***********************************************************************\r
398   <<< [Locale_init] >>> \r
399 ************************************************************************/\r
400 int  Locale_init()\r
401 {\r
402   g_LocaleSymbol = ".OCP";\r
403   setlocale( LC_ALL, ".OCP" );\r
404   return  0;\r
405 }\r
406 \r
407  \r
408 /***********************************************************************\r
409   <<< [Locale_isInited] >>> \r
410 ************************************************************************/\r
411 int  Locale_isInited()\r
412 {\r
413   return  ( g_LocaleSymbol[0] != '\0' );\r
414    // \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
415 }\r
416 \r
417  \r
418 /*=================================================================*/\r
419 /* <<< [FileT/FileT.c] >>> */ \r
420 /*=================================================================*/\r
421  \r
422 /***********************************************************************\r
423   <<< [FileT_isExist] >>> \r
424 ************************************************************************/\r
425 bool  FileT_isExist( const TCHAR* path )\r
426 {\r
427  #if ! FileT_isExistWildcard\r
428 \r
429         DWORD  r;\r
430 \r
431         if ( path[0] == _T('\0') )  return  false;\r
432         r = GetFileAttributes( path );\r
433         return  r != (DWORD)-1;\r
434 \r
435  #else\r
436 \r
437         HANDLE  find;\r
438         WIN32_FIND_DATA  data;\r
439 \r
440         find = FindFirstFileEx( path, FindExInfoStandard, &data,\r
441                 FindExSearchNameMatch, NULL, 0 );\r
442 \r
443         if ( find == INVALID_HANDLE_VALUE ) {\r
444                 return  false;\r
445         }\r
446         else {\r
447                 FindClose( find );\r
448                 return  true;\r
449         }\r
450 \r
451  #endif\r
452 }\r
453 \r
454 \r
455  \r
456 /***********************************************************************\r
457   <<< [FileT_isFile] >>> \r
458 ************************************************************************/\r
459 bool  FileT_isFile( const TCHAR* path )\r
460 {\r
461         DWORD  r = GetFileAttributes( path );\r
462         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;\r
463                 // 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
464 }\r
465 \r
466 \r
467  \r
468 /***********************************************************************\r
469   <<< [FileT_isDir] >>> \r
470 ************************************************************************/\r
471 bool  FileT_isDir( const TCHAR* path )\r
472 {\r
473         DWORD  r = GetFileAttributes( path );\r
474         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;\r
475                 // 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
476 }\r
477 \r
478 \r
479  \r
480 /***********************************************************************\r
481   <<< [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
482 ************************************************************************/\r
483 typedef struct {\r
484         /*--- inherit from FileT_CallByNestFindData */\r
485         void*     CallerArgument;\r
486         TCHAR*    AbsPath;  // abstruct path\r
487         TCHAR*    StepPath;\r
488         TCHAR*    FileName;\r
489         DWORD     FileAttributes;\r
490 \r
491         /*---*/\r
492         BitField  Flags;\r
493         FuncType  CallbackFromNestFind;\r
494         TCHAR     AbsPathMem[4096];\r
495 } FileT_CallByNestFindDataIn;\r
496 \r
497 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );\r
498 \r
499 \r
500 int  FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )\r
501 {\r
502         int  e;\r
503         FileT_CallByNestFindDataIn  data;\r
504 \r
505         {\r
506                 TCHAR*  p;\r
507 \r
508                 e= StrT_cpy( data.AbsPathMem, sizeof(data.AbsPathMem), Path ); IF(e)goto fin;\r
509 \r
510 \r
511                 /* AbsPathMem \82Ì\8dÅ\8cã\82É \ \82ª\96³\82¢\82È\82ç\92Ç\89Á\82·\82é */\r
512                 p = _tcschr( data.AbsPathMem, _T('\0') );\r
513                 p--;\r
514                 if ( *p != _T('\\') ) {\r
515                         p++;\r
516                         IF( p >= data.AbsPathMem + (sizeof(data.AbsPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;\r
517                         *p = _T('\\');\r
518                 }\r
519 \r
520 \r
521                 /* data \82ð\8f\89\8aú\89»\82·\82é */\r
522                 data.CallerArgument = Argument;\r
523                 data.AbsPath = data.AbsPathMem;\r
524                 data.StepPath = p + 1;\r
525                 data.FileName = p + 1;\r
526                 data.Flags = Flags;\r
527                 data.CallbackFromNestFind = Callback;\r
528         }\r
529 \r
530         /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ\8aÖ\90\94\82Ö */\r
531         e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;\r
532 \r
533         e=0;\r
534 fin:\r
535         return  e;\r
536 err_fa: e= E_FEW_ARRAY; goto fin;\r
537 }\r
538 \r
539 \r
540 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )\r
541 {\r
542         int  e;\r
543         HANDLE  find;\r
544         WIN32_FIND_DATA  data;\r
545         TCHAR*  p;\r
546         int  done;\r
547 \r
548 \r
549         /* 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
550         if ( m->Flags & FileT_FolderBeforeFiles ) {\r
551                 *( m->FileName - 1 ) = _T('\0');  // m->AbsPath \82Ì\8dÅ\8cã\82Ì \ \82ð\88ê\8e\9e\93I\82É\83J\83b\83g\r
552                 *( m->FileName ) = _T('\0');  // m->FileName, m->StepPath \82ð "" \82É\82·\82é\r
553                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
554 \r
555                 if ( m->StepPath[0] == _T('\0') ) {\r
556                         TCHAR*  step_path = m->StepPath;\r
557                         TCHAR*  fname     = m->FileName;\r
558 \r
559                         m->StepPath = _T(".");\r
560                         m->FileName = StrT_refFName( m->AbsPath );\r
561                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
562                         m->StepPath = step_path;\r
563                         m->FileName = fname;\r
564                 }\r
565                 else if ( m->FileName[0] == _T('\0') ) {\r
566                         TCHAR*  fname = m->FileName;\r
567 \r
568                         m->FileName = StrT_refFName( m->AbsPath );\r
569                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
570                         m->FileName = fname;\r
571                 }\r
572                 else {\r
573                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
574                 }\r
575                 *( m->FileName - 1 ) = _T('\\');\r
576         }\r
577 \r
578 \r
579         /* * \82ð\92Ç\89Á */\r
580         p = m->FileName;\r
581         IF( p >= m->AbsPathMem + (sizeof(m->AbsPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
582         *p = _T('*');  *(p+1) = _T('\0');\r
583 \r
584 \r
585         /* \83t\83@\83C\83\8b\82©\83t\83H\83\8b\83_\82ð\97ñ\8b\93\82µ\82Ü\82· */\r
586         find = FindFirstFileEx( m->AbsPathMem, FindExInfoStandard, &data,\r
587                 FindExSearchNameMatch, NULL, 0 );\r
588         done = ( find == INVALID_HANDLE_VALUE );\r
589 \r
590         while (!done)\r
591         {\r
592                 if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||\r
593                                  _tcscmp( data.cFileName, _T("..") ) == 0 ) {\r
594                         done = ! FindNextFile( find, &data );\r
595                         continue;\r
596                 }\r
597 \r
598                 StrT_cpy( m->FileName,\r
599                         sizeof(m->AbsPathMem) - ( (char*)m->FileName - (char*)m->AbsPathMem ),\r
600                         data.cFileName );\r
601                 m->FileAttributes = data.dwFileAttributes;\r
602 \r
603                 if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
604                         TCHAR*  prev_fname = m->FileName;\r
605 \r
606                         p = _tcschr( m->FileName, _T('\0') );\r
607 \r
608                         IF( p >= m->AbsPathMem + (sizeof(m->AbsPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
609                         *p = _T('\\');  *(p+1) = _T('\0');\r
610                         m->FileName = p + 1;\r
611 \r
612                         e= FileT_callByNestFind_sub( m ); IF(e)goto fin;  /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ */\r
613 \r
614                         m->FileName = prev_fname;\r
615                 }\r
616                 else {\r
617                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
618                 }\r
619 \r
620                 done = ! FindNextFile( find, &data );\r
621         }\r
622         FindClose( find );\r
623 \r
624 \r
625         /* 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
626         if ( m->Flags & FileT_FolderAfterFiles ) {\r
627                 TCHAR*  step_path = m->StepPath;\r
628                 TCHAR*  fname     = m->FileName;\r
629 \r
630                 *( m->FileName - 1 ) = _T('\0');\r
631                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
632                 if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->AbsPath ) ) {\r
633                         m->StepPath = _T(".");\r
634                 }\r
635                 m->FileName = StrT_refFName( m->AbsPath );\r
636 \r
637                 e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
638 \r
639                 m->StepPath = step_path;\r
640                 m->FileName = fname;\r
641         }\r
642 \r
643         e=0;\r
644 fin:\r
645         return  e;\r
646 err_fa: e= E_FEW_ARRAY; goto fin;\r
647 }\r
648 \r
649 \r
650  \r
651 /***********************************************************************\r
652   <<< [FileT_openForRead] >>> \r
653 ************************************************************************/\r
654 int  FileT_openForRead( FILE** out_pFile, const TCHAR* Path )\r
655 {\r
656         errno_t  en;\r
657 \r
658         assert( Locale_isInited() );\r
659 \r
660         #if DEBUGTOOLS_USES\r
661                 { int e= Debug_onOpen( Path ); if(e) return e; }\r
662         #endif\r
663 \r
664         en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );\r
665         if ( en == ENOENT ) {\r
666                 _tprintf( _T("not found \"%s\"\n"), Path );\r
667 \r
668                 #ifndef UNDER_CE\r
669                 {\r
670                         TCHAR  cwd[512];\r
671 \r
672                         if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )\r
673                                 _tprintf( _T("current = \"%s\"\n"), cwd );\r
674                 }\r
675                 #endif\r
676 \r
677                 return  E_NOT_FOUND_SYMBOL;\r
678         }\r
679         if ( en == EACCES ) {\r
680                 _tprintf( _T("access denied \"%s\"\n"), Path );\r
681                 return  E_ACCESS_DENIED;\r
682         }\r
683         IF(en)return  E_OTHERS;\r
684 \r
685         return  0;\r
686 }\r
687 \r
688 \r
689  \r
690 /***********************************************************************\r
691   <<< [FileT_openForWrite] >>> \r
692 ************************************************************************/\r
693 int  FileT_openForWrite( FILE** out_pFile, const TCHAR* Path, int Flags )\r
694 {\r
695         int      e;\r
696         errno_t  en;\r
697         TCHAR*   open_type;\r
698         BOOL     b;\r
699         int      retry_count;\r
700 \r
701         IF_D( ! Locale_isInited() )  return  E_NOT_INIT_GLOBAL;\r
702 \r
703         #if Uses_AppKey\r
704                 e= AppKey_addNewWritableFolder( Path ); IF(e)goto fin;\r
705         #endif\r
706 \r
707         if ( Flags & F_Append )\r
708                 open_type = ( Flags & F_Unicode ? _T("a")_T(fopen_ccs) : _T("at") );\r
709         else\r
710                 open_type = ( Flags & F_Unicode ? _T("w")_T(fopen_ccs) : _T("wt") );\r
711 \r
712         #if DEBUGTOOLS_USES\r
713                 { int e= Debug_onOpen( Path ); if(e) return e; }\r
714         #endif\r
715 \r
716         for ( retry_count = 0;  ;  retry_count ++ ) {\r
717                 en = _tfopen_s( out_pFile, Path, open_type );\r
718                 if ( en != EACCES )  break;\r
719 \r
720                 retry_count += 1;\r
721                 if ( retry_count == 15 )  break;\r
722                 Sleep( 1000 );\r
723         }\r
724         if ( en == 2 ) {  // ENOENT\r
725                 e= FileT_mkdir( Path ); IF(e)goto fin;\r
726                 b= RemoveDirectory( Path ); IF(!b)goto err_gt;\r
727                 en = _tfopen_s( out_pFile, Path, open_type );\r
728 \r
729                 IF ( en == 2 ) {\r
730                         _tprintf( _T("cannot open \"%s\"\n"), Path );\r
731 \r
732                         #ifndef UNDER_CE\r
733                         {\r
734                                 TCHAR  cwd[512];\r
735 \r
736                                 if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )\r
737                                         _tprintf( _T("current = \"%s\"\n"), cwd );\r
738                         }\r
739                         #endif\r
740 \r
741                         e = E_NOT_FOUND_SYMBOL;\r
742                         goto fin;\r
743                 }\r
744         }\r
745         IF(en)goto err;\r
746 \r
747         e=0;\r
748 fin:\r
749         return  e;\r
750 \r
751 err:  e = E_OTHERS;  goto fin;\r
752 err_gt:  e = SaveWindowsLastError();  goto fin;\r
753 }\r
754 \r
755 \r
756  \r
757 /***********************************************************************\r
758   <<< [FileT_close] >>> \r
759 ************************************************************************/\r
760 int  FileT_close( FILE* File, int e )\r
761 {\r
762         if ( File != NULL ) {\r
763                 int r = fclose( File );\r
764                 IF(r&&!e)e=E_ERRNO;\r
765         }\r
766         return e;\r
767 }\r
768 \r
769 \r
770 \r
771  \r
772 /***********************************************************************\r
773   <<< [FileT_writePart] >>> \r
774 ************************************************************************/\r
775 errnum_t  FileT_writePart( FILE* File, TCHAR* Start, TCHAR* Over )\r
776 {\r
777         errnum_t  e;\r
778         TCHAR     back_char;\r
779         int       r;\r
780 \r
781         back_char = *Over;\r
782         *Over = _T('\0');\r
783 \r
784         r= _ftprintf_s( File, _T("%s"), Start ); IF(r<0){ e=E_ERRNO; goto fin; }\r
785 \r
786         e=0;\r
787 fin:\r
788         *Over = back_char;\r
789         return  e;\r
790 }\r
791 \r
792 \r
793  \r
794 /***********************************************************************\r
795   <<< [FileT_mkdir] >>> \r
796 ************************************************************************/\r
797 int  FileT_mkdir( const TCHAR* Path )\r
798 {\r
799         int    e;\r
800         DWORD  r;\r
801         TCHAR* p = (TCHAR*) DUMMY_INITIAL_VALUE;\r
802         BOOL   b;\r
803         int    n_folder = 0;\r
804         TCHAR  path2[MAX_PATH];\r
805 \r
806 \r
807         e= StrT_getAbsPath( path2, sizeof(path2), Path, NULL ); IF(e)goto fin;\r
808         #if Uses_AppKey\r
809                 e= AppKey_addNewWritableFolder( path2 ); IF(e)goto fin;\r
810         #endif\r
811 \r
812 \r
813         //=== \91\8dÝ\82·\82é\83t\83H\83\8b\83_\82ð\92T\82·\r
814         for (;;) {\r
815                 r = GetFileAttributes( path2 );\r
816                 if ( r != (DWORD)-1 ) break;  // "C:" \82à\83t\83H\83\8b\83_\82Æ\94»\92è\82³\82ê\82é\r
817 \r
818                 p = StrT_refFName( path2 ) - 1;  // \90â\91Î\83p\83X\82È\82Ì\82Å\95K\82¸ *p=='\\'\r
819                 *p = _T('\0');\r
820                 n_folder ++;\r
821         }\r
822         IF ( ! (r & FILE_ATTRIBUTE_DIRECTORY) ) goto err;  // \83t\83@\83C\83\8b\82È\82ç\83G\83\89\81[\r
823 \r
824 \r
825         //=== \83t\83H\83\8b\83_\82ð\8dì\90¬\82·\82é\r
826         for ( ;  n_folder > 0;  n_folder -- ) {\r
827                 *p = _T('\\');\r
828                 b= CreateDirectory( path2, NULL ); IF(!b)goto err;\r
829                 p = _tcschr( p, _T('\0') );\r
830         }\r
831 \r
832         e=0;\r
833 fin:\r
834         return  e;\r
835 \r
836 err:  e = E_OTHERS;  goto fin;\r
837 }\r
838 \r
839 \r
840 \r
841  \r
842 /***********************************************************************\r
843   <<< [FileT_copy] >>> \r
844 ************************************************************************/\r
845 int  FileT_copy_sub( FileT_CallByNestFindData* m );\r
846 \r
847 int  FileT_copy( const TCHAR* SrcPath, const TCHAR* DstPath )\r
848 {\r
849         const TCHAR*  p_last;\r
850         int    e;\r
851         BOOL   b;\r
852         TCHAR  path[MAX_PATH*4];\r
853 \r
854 \r
855         #if Uses_AppKey\r
856                 e= AppKey_addNewWritableFolder( DstPath ); IF(e)goto fin;\r
857         #endif\r
858 \r
859         p_last = _tcschr( SrcPath, _T('\0') );\r
860         IF_D( p_last <= SrcPath + 1 )goto err_ni;\r
861 \r
862 \r
863         //=== \83t\83H\83\8b\83_\82ð\83R\83s\81[\82·\82é\r
864         if ( *(p_last - 1) == _T('*') ) {\r
865                 IF_D( *(p_last - 2) != _T('\\') ) goto err_ni;\r
866 \r
867                 e= StrT_getParentAbsPath( path, sizeof(path), SrcPath, NULL ); IF(e)goto fin;\r
868                 IF_D( ! FileT_isDir( path ) )goto err_nf;\r
869 \r
870                 e= FileT_callByNestFind( path, FileT_FolderBeforeFiles, (void*) DstPath, (FuncType) FileT_copy_sub );\r
871                 IF(e)goto fin;\r
872         }\r
873 \r
874 \r
875         //=== \83t\83@\83C\83\8b\82ð\83R\83s\81[\82·\82é\r
876         else {\r
877                 IF_D( _tcschr( SrcPath, _T('*') ) != NULL )goto err_ni;\r
878                 IF_D( ! FileT_isFile( SrcPath ) ) goto err_nf;\r
879 \r
880                 b= CopyFile( SrcPath, DstPath, FALSE );\r
881                 if (!b) {\r
882                         if ( FileT_isDir( DstPath ) ) {\r
883                                 e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
884                                 b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
885                         }\r
886                         else {\r
887                                 int  ee;\r
888 \r
889                                 p_last = _tcschr( DstPath, _T('\0') ) - 1;\r
890                                 IF_D( p_last < DstPath )goto err;\r
891                                 if ( *p_last == _T('\\') ) {\r
892                                         ee= FileT_mkdir( DstPath ); IF(ee)goto fin;\r
893                                         e= stprintf_r( path, sizeof(path), _T("%s%s"), DstPath, StrT_refFName( SrcPath ) ); IF(e)goto fin;\r
894                                         b= CopyFile( SrcPath, path, FALSE ); IF(!b)goto err_gt;\r
895                                 }\r
896                                 else {\r
897                                         e = E_ACCESS_DENIED;\r
898                                         ee= StrT_getParentAbsPath( path, sizeof(path), DstPath, NULL ); IF(ee)goto fin;\r
899                                         ee= FileT_mkdir( path ); IF(ee)goto fin;\r
900                                         b= CopyFile( SrcPath, DstPath, FALSE ); IF(!b)goto err_gt;\r
901                                 }\r
902                         }\r
903                 }\r
904         }\r
905 \r
906         e=0;\r
907 fin:\r
908         return  e;\r
909 \r
910 err_ni:  e = E_NOT_IMPLEMENT_YET;  goto fin;\r
911 err_nf:  e = E_PATH_NOT_FOUND;  goto fin;\r
912 err_gt:  e = SaveWindowsLastError();  goto fin;\r
913 err:  e = E_OTHERS;  goto fin;\r
914 }\r
915 \r
916 \r
917 int  FileT_copy_sub( FileT_CallByNestFindData* m )\r
918 {\r
919         const  TCHAR*  DstPath = (const TCHAR*) m->CallerArgument;\r
920         int    e;\r
921         BOOL   b;\r
922         TCHAR  path[MAX_PATH*4];\r
923 \r
924         e= stprintf_r( path, sizeof(path), _T("%s\\%s"), DstPath, m->StepPath ); IF(e)goto fin;\r
925 \r
926         if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
927                 if ( ! FileT_isDir( path ) )\r
928                         { b= CreateDirectory( path, NULL ); IF(!b)goto err_gt; }\r
929         }\r
930         else {\r
931                 b= CopyFile( m->AbsPath, path, FALSE ); IF(!b)goto err_gt;\r
932         }\r
933 \r
934         e=0;\r
935 fin:\r
936         return  e;\r
937 \r
938 err_gt:  e = SaveWindowsLastError();  goto fin;\r
939 }\r
940 \r
941 \r
942 \r
943  \r
944 /***********************************************************************\r
945   <<< [FileT_del] >>> \r
946 ************************************************************************/\r
947 int  FileT_del_sub( FileT_CallByNestFindData* m );\r
948 \r
949 int  FileT_del( const TCHAR* Path )\r
950 {\r
951         int    e;\r
952         DWORD  r;\r
953         TCHAR  abs_path[MAX_PATH];\r
954 \r
955         e= StrT_getAbsPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto fin;\r
956         #if Uses_AppKey\r
957                 e= AppKey_addNewWritableFolder( abs_path ); IF(e)goto fin;\r
958         #endif\r
959 \r
960         r= GetFileAttributes( Path );\r
961         if ( r != (DWORD)-1 ) {\r
962                 if ( r & FILE_ATTRIBUTE_DIRECTORY ) {\r
963                         e= FileT_callByNestFind( Path, FileT_FolderAfterFiles, NULL, (FuncType) FileT_del_sub );\r
964                 }\r
965                 else {\r
966                         BOOL  b= DeleteFile( Path ); IF(!b)goto err_gt;\r
967                 }\r
968         }\r
969         IF_D( FileT_isExist( Path ) )goto err_ad;\r
970 \r
971         e=0;\r
972 fin:\r
973         return  e;\r
974 \r
975 err_gt:  e = SaveWindowsLastError();  goto fin;\r
976 err_ad:  e = E_ACCESS_DENIED;  goto fin;\r
977 }\r
978 \r
979 \r
980 int  FileT_del_sub( FileT_CallByNestFindData* m )\r
981 {\r
982         int   e;\r
983         BOOL  b;\r
984 \r
985         if ( m->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
986                 b= RemoveDirectory( m->AbsPath ); IF(!b)goto err_gt;\r
987         }\r
988         else {\r
989                 b= DeleteFile( m->AbsPath ); IF(!b)goto err_gt;\r
990         }\r
991 \r
992         e=0;\r
993 fin:\r
994         return  e;\r
995 \r
996 err_gt:  e = SaveWindowsLastError();  goto fin;\r
997 }\r
998  \r
999 /***********************************************************************\r
1000   <<< [AppKey] >>> \r
1001 ************************************************************************/\r
1002 static errnum_t  AppKey_create( AppKey** out_m );\r
1003 static bool      AppKey_isSame( AppKey* m );\r
1004 static void      Writables_initConst( Writables* m );\r
1005 static errnum_t  Writables_init( Writables* m, AppKey* Key );\r
1006 static errnum_t  Writables_finish( Writables* m, int e );\r
1007 static bool      Writables_isInited( Writables* m );\r
1008 static errnum_t  Writables_clearPaths( Writables* m );\r
1009 static errnum_t  Writables_create( Writables** out_m, AppKey* Key );\r
1010 static errnum_t  Writables_copyToConst( Writables* To, Writables* From );\r
1011 \r
1012 \r
1013 typedef struct _CurrentWritables  CurrentWritables;\r
1014 struct _CurrentWritables {\r
1015         Writables  m_CurrentWritables;\r
1016         TCHAR*   m_ProgramFiles;  size_t  m_ProgramFiles_Len;\r
1017         TCHAR*   m_windir;        size_t  m_windir_Len;\r
1018         TCHAR*   m_APPDATA;       size_t  m_APPDATA_Len;\r
1019         TCHAR*   m_LOCALAPPDATA;  size_t  m_LOCALAPPDATA_Len;\r
1020 };\r
1021 static void      CurrentWritables_initConst( CurrentWritables* m );\r
1022 static errnum_t  CurrentWritables_init( CurrentWritables* m );\r
1023 static errnum_t  CurrentWritables_finish( CurrentWritables* m, int e );\r
1024 static errnum_t  CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* AbsPath );\r
1025 \r
1026 \r
1027 //////////////////////////////\r
1028 \r
1029 static  AppKey   g_AppKey;\r
1030 static  AppKey*  g_AppKeyPrivate;\r
1031 \r
1032 // under g_AppKey\r
1033 Writables  g_DefaultWritables;\r
1034 Writables  g_CurrentWritables; // public\r
1035 static CurrentWritables  g_CurrentWritablesPrivate;\r
1036 \r
1037 \r
1038 static errnum_t  AppKey_create( AppKey** out_m )\r
1039 {\r
1040         errnum_t  e;\r
1041 \r
1042         IF( g_AppKeyPrivate != NULL ) { e=1; goto fin; }\r
1043                 // 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
1044 \r
1045         Writables_initConst( &g_DefaultWritables );\r
1046         CurrentWritables_initConst( &g_CurrentWritablesPrivate );\r
1047 \r
1048         e= CurrentWritables_init( &g_CurrentWritablesPrivate ); IF(e)goto fin;\r
1049         e= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(e)goto fin;\r
1050 \r
1051         *out_m = &g_AppKey;\r
1052         g_AppKeyPrivate = &g_AppKey;\r
1053 \r
1054         e=0;\r
1055 fin:\r
1056         return  e;\r
1057 }\r
1058 \r
1059 \r
1060 static bool  AppKey_isSame( AppKey* m )\r
1061 {\r
1062         return  ( m == g_AppKeyPrivate );\r
1063 }\r
1064 \r
1065 \r
1066 void  AppKey_initGlobal_const()\r
1067 {\r
1068         Writables_initConst( &g_DefaultWritables );\r
1069 }\r
1070 \r
1071 \r
1072 errnum_t  AppKey_finishGlobal( errnum_t e )\r
1073 {\r
1074         errnum_t  ee;\r
1075 \r
1076         e= Writables_finish( &g_DefaultWritables, e );\r
1077         e= CurrentWritables_finish( &g_CurrentWritablesPrivate, e );\r
1078         ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
1079 \r
1080         return  e;\r
1081 }\r
1082 \r
1083 \r
1084  \r
1085 /***********************************************************************\r
1086   <<< [AppKey_newWritable] >>> \r
1087 ************************************************************************/\r
1088 errnum_t  AppKey_newWritable( AppKey** in_out_m,  Writables** out_Writable,  ... )\r
1089 {\r
1090         errnum_t    e;\r
1091         AppKey*     m = NULL;\r
1092         Writables*  wr = NULL;\r
1093  #if Uses_OutMallocIDTool\r
1094         bool  is_prev_out_malloc;\r
1095 \r
1096         is_prev_out_malloc = OutMallocID_setEnable( false );\r
1097  #endif\r
1098 \r
1099 \r
1100         //=== AppKey* m \82ð\97L\8cø\82É\82·\82é\r
1101         if ( in_out_m == NULL ) {  // \8d¡\89ñ\82Ì\8aÖ\90\94\82Ì\92\86\82¾\82¯\82Å\8eQ\8fÆ\82·\82é\r
1102                 e= AppKey_create( &m ); IF(e)goto resume;\r
1103         }\r
1104         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
1105                 e= AppKey_create( &m ); IF(e)goto resume;\r
1106                 *in_out_m = m;\r
1107         }\r
1108         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
1109                 m = *in_out_m;\r
1110         }\r
1111 \r
1112 \r
1113         //=== \90³\8bK\82Ì AppKey \82©\83`\83F\83b\83N\82·\82é\r
1114         IF( ! AppKey_isSame( m ) )goto err;\r
1115 \r
1116 \r
1117         //=== Writable \82ð\90\90¬\82·\82é\r
1118         if ( out_Writable == NULL ) {\r
1119                 wr = &g_DefaultWritables;\r
1120                 e= Writables_finish( wr, 0 ); IF(e)goto resume;\r
1121                 e= Writables_init( wr, m ); IF(e)goto resume;\r
1122         }\r
1123         else {\r
1124                 e= Writables_create( &wr, m ); IF(e)goto resume;\r
1125                 *out_Writable = wr;\r
1126         }\r
1127 \r
1128 \r
1129         //=== Writable \82É\83p\83X\82ð\93o\98^\82·\82é\r
1130         {\r
1131                 va_list  va;\r
1132                 TCHAR*   path;\r
1133                 int  i;\r
1134 \r
1135                 va_start( va, out_Writable );\r
1136                 for ( i=0; ; i++ ) {\r
1137                         path = va_arg( va, TCHAR* );\r
1138                         if ( path == NULL )  break;\r
1139                         IF( i == 5 ) goto err;  // \8dÅ\8cã\82Ì NULL \96Y\82ê\91Î\8dô\r
1140 \r
1141                         e= Writables_add( wr, m, path ); IF(e)goto resume;\r
1142                 }\r
1143                 va_end( va );\r
1144         }\r
1145         #if defined(TempFile_get)\r
1146         {\r
1147                 TempFile*   temp;\r
1148 \r
1149                 e= TempFile_get( &temp ); IF(e)goto resume;\r
1150                 e= Writables_add( wr, m, temp->TempPath ); IF(e)goto resume;\r
1151         }\r
1152         #endif\r
1153 \r
1154 \r
1155         //=== \82·\82®\82É Writable \82ð\97L\8cø\82É\82·\82é\r
1156         if ( out_Writable == NULL ) {\r
1157                 e= Writables_enable( wr ); IF(e)goto resume;\r
1158         }\r
1159 \r
1160         e=0;\r
1161 fin:\r
1162         #if Uses_OutMallocIDTool\r
1163                 OutMallocID_setEnable( is_prev_out_malloc );\r
1164         #endif\r
1165         return  e;\r
1166 \r
1167 err:  e = E_OTHERS;  goto resume;\r
1168 resume:\r
1169         if ( wr != NULL ) {\r
1170                 if ( out_Writable == NULL )\r
1171                         e= Writables_finish( wr, e );  // g_DefaultWritables\r
1172                 else\r
1173                         e= Writables_delete( wr, e );\r
1174         }\r
1175         goto fin;\r
1176 }\r
1177 \r
1178 \r
1179  \r
1180 /***********************************************************************\r
1181   <<< [AppKey_addNewWritableFolder] \83`\83F\83b\83N\82·\82é\81A\82Ü\82½\82Í\92Ç\89Á\82·\82é >>> \r
1182 \81i\92Ç\89Á\82Í\96¢\91Î\89\9e\81j\r
1183 ************************************************************************/\r
1184 errnum_t  AppKey_addNewWritableFolder( const TCHAR* Path )\r
1185 {\r
1186         errnum_t    e;\r
1187         TCHAR**     pp;\r
1188         TCHAR**     pp_over;\r
1189         Writables*  wr = &g_CurrentWritablesPrivate.m_CurrentWritables;\r
1190         size_t      path_len;\r
1191         TCHAR       abs_path[MAX_PATH];\r
1192 \r
1193         if ( g_AppKeyPrivate == NULL ) {\r
1194                 e= AppKey_newWritable( NULL, NULL, ".", NULL ); IF(e){goto fin;}\r
1195         }\r
1196 \r
1197         e= StrT_getAbsPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e){goto fin;}\r
1198 \r
1199         pp_over = wr->m_Paths + wr->m_nPath;\r
1200         for ( pp = wr->m_Paths;  ;  pp++ ) {\r
1201                 IF ( pp >= pp_over ) { e=E_OUT_OF_WRITABLE; goto fin; }\r
1202                         // Path (abs_path) \82Í\81AAppKey_newWritable \82Å\8b\96\89Â\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B\r
1203                         // \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
1204                         // \8b\96\89Â\82³\82ê\82Ä\82¢\82é\83p\83X\82ð\8am\94F\82µ\82Ä\82­\82¾\82³\82¢\81B\r
1205 \r
1206                 path_len = _tcslen( *pp );\r
1207                 if ( _tcsnicmp( *pp, abs_path, path_len ) == 0 &&\r
1208                      ( abs_path[ path_len ] == _T('\\') || abs_path[ path_len ] == _T('\0') ) )  break;\r
1209         }\r
1210 \r
1211         e=0;\r
1212 fin:\r
1213         return  e;\r
1214 }\r
1215 \r
1216 \r
1217  \r
1218 /***********************************************************************\r
1219   <<< [AppKey_checkWritable] >>> \r
1220 ************************************************************************/\r
1221 errnum_t  AppKey_checkWritable( const TCHAR* Path )\r
1222 {\r
1223         return  AppKey_addNewWritableFolder( Path );\r
1224 }\r
1225 \r
1226 \r
1227  \r
1228 /***********************************************************************\r
1229   <<< [Writables_init] >>> \r
1230 ************************************************************************/\r
1231 static void  Writables_initConst( Writables* m )\r
1232 {\r
1233         m->m_Paths = NULL;\r
1234         m->m_nPath = -1;\r
1235 }\r
1236 \r
1237 \r
1238 static errnum_t  Writables_init( Writables* m, AppKey* Key )\r
1239 {\r
1240         IF( ! AppKey_isSame( Key ) ) return E_OTHERS;\r
1241 \r
1242         m->m_Paths = NULL;\r
1243         m->m_nPath = 0;\r
1244         return  0;\r
1245 }\r
1246 \r
1247 \r
1248 static errnum_t  Writables_finish( Writables* m, int e )\r
1249 {\r
1250         errnum_t  ee;\r
1251 \r
1252         ee= Writables_clearPaths( m ); IF(ee&&!e) e=ee;\r
1253         m->m_nPath = -1;\r
1254         return  e;\r
1255 }\r
1256 \r
1257 \r
1258 static bool  Writables_isInited( Writables* m )\r
1259 {\r
1260         return  ( m->m_nPath != -1 );\r
1261 }\r
1262 \r
1263 \r
1264 static errnum_t  Writables_clearPaths( Writables* m )\r
1265 {\r
1266         TCHAR**  p;\r
1267         TCHAR**  p_over;\r
1268 \r
1269         if ( m->m_Paths != NULL ) {\r
1270                 p_over = m->m_Paths + m->m_nPath;\r
1271                 for ( p = m->m_Paths;  p < p_over;  p++ ) {\r
1272                         free( *p );\r
1273                 }\r
1274                 free( m->m_Paths );  m->m_Paths = NULL;\r
1275         }\r
1276         m->m_nPath = 0;\r
1277         return  0;\r
1278 }\r
1279 \r
1280 \r
1281 static errnum_t  Writables_create( Writables** out_m, AppKey* Key )\r
1282 {\r
1283         errnum_t    e;\r
1284         Writables*  m;\r
1285 \r
1286         m = (Writables*) malloc( sizeof(*m) ); IF(m==NULL)return E_FEW_MEMORY;\r
1287         Writables_initConst( m );\r
1288         e= Writables_init( m, Key ); IF(e)goto resume;\r
1289         *out_m = m;\r
1290         return  0;\r
1291 resume: Writables_delete( m, 0 ); free(m); return  e;\r
1292 }\r
1293 \r
1294 \r
1295 errnum_t  Writables_delete( Writables* m, errnum_t e )\r
1296 {\r
1297         if ( m == NULL ) goto fin;\r
1298         e= Writables_finish( m, e );\r
1299         free( m );\r
1300 fin:\r
1301         return  e;\r
1302 }\r
1303 \r
1304 \r
1305  \r
1306 /***********************************************************************\r
1307   <<< [Writables_add] >>> \r
1308 ************************************************************************/\r
1309 int  Writables_add( Writables* m, AppKey* Key, TCHAR* Path )\r
1310 {\r
1311         int  e;\r
1312         TCHAR**   pp;\r
1313         TCHAR*    p  = NULL;\r
1314         size_t    path_size;\r
1315         TCHAR     abs_path[MAX_PATH];\r
1316 \r
1317         IF( ! AppKey_isSame( Key ) )goto err;\r
1318         if ( Path[0] == _T('\0') ) return 0;\r
1319 \r
1320         e= StrT_getAbsPath( abs_path, sizeof(abs_path), Path, NULL ); IF(e)goto resume;\r
1321 \r
1322         e= CurrentWritables_askFileAccess( &g_CurrentWritablesPrivate, abs_path ); IF(e)goto resume;\r
1323 \r
1324         pp = (TCHAR**) realloc( m->m_Paths, (m->m_nPath + 1) * sizeof(TCHAR*) );\r
1325         IF( pp == NULL ) goto err;\r
1326         m->m_Paths = pp;\r
1327 \r
1328         path_size = (_tcslen( abs_path ) + 1) * sizeof(TCHAR);\r
1329         p = (TCHAR*) malloc( path_size );\r
1330         m->m_Paths[ m->m_nPath ] = p;\r
1331         IF( p == NULL )goto err;\r
1332 \r
1333         memcpy( p, abs_path, path_size );\r
1334         if ( p[ path_size/sizeof(TCHAR) - 2 ] == _T('\\') )\r
1335                          p[ path_size/sizeof(TCHAR) - 2 ] =  _T('\0');\r
1336         m->m_nPath ++;\r
1337 \r
1338         e=0;\r
1339 fin:\r
1340         return  e;\r
1341 \r
1342 err:  e = E_OTHERS;  goto resume;\r
1343 resume:\r
1344         if ( p != NULL )  free( p );\r
1345         goto fin;\r
1346 }\r
1347 \r
1348 \r
1349 int  Writables_remove( Writables* m, TCHAR* Path )\r
1350 {\r
1351         TCHAR**  pp;\r
1352         TCHAR**  pp_over;\r
1353 \r
1354         pp_over = m->m_Paths + m->m_nPath;\r
1355         for ( pp = m->m_Paths;  ;  pp++ ) {\r
1356                 if ( pp >= pp_over )  return  0;\r
1357                 if ( _tcscmp( *pp, Path ) == 0 )  break;\r
1358         }\r
1359         free( *pp );\r
1360         memmove( pp, pp+1, (char*)pp - (char*)pp_over - sizeof(TCHAR) );\r
1361         m->m_nPath --;\r
1362 \r
1363         #if _DEBUG\r
1364                 *( pp_over - 1 ) = NULL;\r
1365         #endif\r
1366 \r
1367         return  0;\r
1368 }\r
1369 \r
1370 \r
1371  \r
1372 /***********************************************************************\r
1373   <<< [Writables_enable] >>> \r
1374 ************************************************************************/\r
1375 int  Writables_enable( Writables* m )\r
1376 {\r
1377         int  e;\r
1378 \r
1379         e= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, m ); IF(e)goto fin;\r
1380         e= Writables_copyToConst( &g_CurrentWritables, &g_CurrentWritablesPrivate.m_CurrentWritables ); IF(e)goto fin;\r
1381 \r
1382         e=0;\r
1383 fin:\r
1384         return  e;\r
1385 }\r
1386 \r
1387 \r
1388 int  Writables_disable( Writables* m, int e )\r
1389 {\r
1390         int  ee;\r
1391 \r
1392         UNREFERENCED_VARIABLES( m );\r
1393 \r
1394         ee= Writables_copyToConst( &g_CurrentWritablesPrivate.m_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
1395         ee= Writables_copyToConst( &g_CurrentWritables, NULL ); IF(ee&&!e)goto fin;\r
1396 \r
1397         e=0;\r
1398 fin:\r
1399         return  e;\r
1400 }\r
1401 \r
1402 \r
1403 static int  Writables_copyToConst( Writables* To, Writables* From )\r
1404 {\r
1405         int  e;\r
1406         TCHAR**  pp;\r
1407         TCHAR**  pp_over;\r
1408         TCHAR*   p2;\r
1409         TCHAR**  pp2;\r
1410         size_t   path_size;\r
1411 \r
1412         if ( To->m_Paths != NULL ) {\r
1413                 free( To->m_Paths );\r
1414                 To->m_Paths = NULL;\r
1415                 To->m_nPath = 0;\r
1416         }\r
1417 \r
1418         if ( From != NULL && From->m_nPath > 0 ) {\r
1419 \r
1420                 path_size = 0;\r
1421                 pp_over = From->m_Paths + From->m_nPath;\r
1422                 for ( pp = From->m_Paths;  pp < pp_over;  pp++ ) {\r
1423                         path_size += _tcslen( *pp ) + 1;\r
1424                 }\r
1425 \r
1426                 path_size = From->m_nPath * sizeof(TCHAR*) + path_size * sizeof(TCHAR);\r
1427                 To->m_Paths = (TCHAR**) malloc( path_size );\r
1428                 IF( To->m_Paths == NULL ) goto err;\r
1429 \r
1430                 p2 = (TCHAR*)( (char*)To->m_Paths + From->m_nPath * sizeof(TCHAR*) );\r
1431                 pp2 = To->m_Paths;\r
1432                 for ( pp = From->m_Paths;  pp < pp_over;  pp++ ) {\r
1433                         *pp2 = p2;\r
1434                         path_size = (_tcslen( *pp ) + 1) * sizeof(TCHAR);\r
1435                         memcpy( p2, *pp, path_size );\r
1436                         p2 = (TCHAR*)( (char*)p2 + path_size );\r
1437                         pp2 ++;\r
1438                 }\r
1439                 To->m_nPath = From->m_nPath;\r
1440         }\r
1441 \r
1442         e=0;\r
1443 fin:\r
1444         return  e;\r
1445 \r
1446 err:  e = E_OTHERS;  goto fin;\r
1447 }\r
1448 \r
1449  \r
1450 /***********************************************************************\r
1451   <<< [CurrentWritables] >>> \r
1452 ************************************************************************/\r
1453 static void  CurrentWritables_initConst( CurrentWritables* m )\r
1454 {\r
1455         Writables_initConst( &m->m_CurrentWritables );\r
1456         m->m_ProgramFiles = NULL;\r
1457         m->m_windir = NULL;\r
1458         m->m_APPDATA = NULL;\r
1459         m->m_LOCALAPPDATA = NULL;\r
1460 }\r
1461 \r
1462 \r
1463 static int  CurrentWritables_init( CurrentWritables* m )\r
1464 {\r
1465         int    e;\r
1466  #if Uses_OutMallocIDTool\r
1467         bool  is_prev_out_malloc;\r
1468 \r
1469         is_prev_out_malloc = OutMallocID_setEnable( false );\r
1470  #endif\r
1471 \r
1472         e= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(e)goto fin;\r
1473 \r
1474         e= env_malloc( &m->m_ProgramFiles, &m->m_ProgramFiles_Len, _T("ProgramFiles") ); IF(e)goto fin;\r
1475         e= env_malloc( &m->m_windir,       &m->m_windir_Len,       _T("windir") ); IF(e)goto fin;\r
1476         e= env_malloc( &m->m_APPDATA,      &m->m_APPDATA_Len,      _T("APPDATA") ); IF(e)goto fin;\r
1477         // e= env_malloc( &m->m_LOCALAPPDATA, &m->m_LOCALAPPDATA_Len, _T("LOCALAPPDATA") ); IF(e)goto fin;\r
1478 \r
1479         e=0;\r
1480 fin:\r
1481  #if Uses_OutMallocIDTool\r
1482         OutMallocID_setEnable( is_prev_out_malloc );\r
1483  #endif\r
1484         return  e;\r
1485 }\r
1486 \r
1487 \r
1488 static int  CurrentWritables_finish( CurrentWritables* m, int e )\r
1489 {\r
1490         int  ee;\r
1491 \r
1492         ee= Writables_copyToConst( &m->m_CurrentWritables, NULL ); IF(ee&&!e)e=ee;\r
1493 \r
1494         if ( m->m_ProgramFiles != NULL )  free( m->m_ProgramFiles );\r
1495         if ( m->m_windir != NULL )        free( m->m_windir );\r
1496         if ( m->m_APPDATA != NULL )       free( m->m_APPDATA );\r
1497         if ( m->m_LOCALAPPDATA != NULL )  free( m->m_LOCALAPPDATA );\r
1498 \r
1499         m->m_ProgramFiles = NULL;\r
1500         m->m_windir = NULL;\r
1501         m->m_APPDATA = NULL;\r
1502         m->m_LOCALAPPDATA = NULL;\r
1503 \r
1504         return  e;\r
1505 }\r
1506 \r
1507 \r
1508 static int  CurrentWritables_askFileAccess_sub(\r
1509         const TCHAR* SystemPath,  size_t SystemPath_Len,  const TCHAR* AbsPath, size_t AbsPath_Len );\r
1510 \r
1511 static int  CurrentWritables_askFileAccess( CurrentWritables* m, const TCHAR* AbsPath )\r
1512 {\r
1513         int  e;\r
1514         size_t  abs_len;\r
1515 \r
1516         abs_len = _tcslen( AbsPath );\r
1517         e= CurrentWritables_askFileAccess_sub( m->m_ProgramFiles, m->m_ProgramFiles_Len, AbsPath, abs_len ); IF(e)goto fin;\r
1518         e= CurrentWritables_askFileAccess_sub( m->m_windir,       m->m_windir_Len,       AbsPath, abs_len ); IF(e)goto fin;\r
1519         e= CurrentWritables_askFileAccess_sub( m->m_APPDATA,      m->m_APPDATA_Len,      AbsPath, abs_len ); IF(e)goto fin;\r
1520         e= CurrentWritables_askFileAccess_sub( m->m_LOCALAPPDATA, m->m_LOCALAPPDATA_Len, AbsPath, abs_len ); IF(e)goto fin;\r
1521 \r
1522         e=0;\r
1523 fin:\r
1524         return  e;\r
1525 }\r
1526 \r
1527 \r
1528 static int  CurrentWritables_askFileAccess_sub(\r
1529         const TCHAR* SystemPath,  size_t SystemPath_Len,  const TCHAR* AbsPath, size_t AbsPath_Len )\r
1530 {\r
1531         if ( SystemPath == NULL )  return  0;\r
1532 \r
1533         IF ( _tcsncmp( SystemPath, AbsPath, SystemPath_Len ) == 0 )\r
1534                 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
1535 \r
1536         IF ( _tcsncmp( SystemPath, AbsPath, AbsPath_Len ) == 0 )\r
1537                 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
1538 \r
1539         return  0;\r
1540 }\r
1541 \r
1542 \r
1543  \r
1544 /*=================================================================*/\r
1545 /* <<< [StrT/StrT.c] >>> */ \r
1546 /*=================================================================*/\r
1547  \r
1548 /***********************************************************************\r
1549   <<< [StrT_cpy] >>> \r
1550 - _tcscpy is raising exception, if E_FEW_ARRAY\r
1551 ************************************************************************/\r
1552 errnum_t  StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )\r
1553 {\r
1554         size_t  size;\r
1555 \r
1556         size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);\r
1557         if ( size <= DstSize ) {\r
1558                 memcpy( Dst, Src, size );\r
1559                 return  0;\r
1560         }\r
1561         else {\r
1562                 memcpy( Dst, Src, DstSize - sizeof(TCHAR) );\r
1563                 *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');\r
1564                 return  E_FEW_ARRAY;\r
1565         }\r
1566 }\r
1567 \r
1568  \r
1569 /***********************************************************************\r
1570   <<< [MallocAndCopyString] >>> \r
1571 ************************************************************************/\r
1572 errnum_t  MallocAndCopyString( TCHAR** out_NewString, const TCHAR* SourceString )\r
1573 {\r
1574         TCHAR*  str;\r
1575         size_t  size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);\r
1576 \r
1577         ASSERT_D( *out_NewString == NULL, __noop() );\r
1578 \r
1579         str = (TCHAR*) malloc( size );\r
1580         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
1581 \r
1582         memcpy( str, SourceString, size );\r
1583 \r
1584         *out_NewString = str;\r
1585         return  0;\r
1586 }\r
1587 \r
1588 \r
1589  \r
1590 /***********************************************************************\r
1591   <<< [MallocAndCopyString_char] >>> \r
1592 ************************************************************************/\r
1593 #ifdef _UNICODE\r
1594 errnum_t  MallocAndCopyString_char( TCHAR** out_NewString, const char* SourceString )\r
1595 {\r
1596         TCHAR*  str;\r
1597         size_t  size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);\r
1598         int     r;\r
1599 \r
1600         str = (TCHAR*) malloc( size );\r
1601         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
1602 \r
1603         r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );\r
1604         IF ( r == 0 ) {\r
1605                 free( str );\r
1606                 return  E_GET_LAST_ERROR;\r
1607         }\r
1608         *out_NewString = str;\r
1609         return  0;\r
1610 }\r
1611 #endif\r
1612 \r
1613 \r
1614  \r
1615 /***********************************************************************\r
1616   <<< [MallocAndCopyStringByLength] >>> \r
1617 ************************************************************************/\r
1618 errnum_t  MallocAndCopyStringByLength( TCHAR** out_NewString, const TCHAR* SourceString,\r
1619         unsigned CountOfCharacter )\r
1620 {\r
1621         TCHAR*  str;\r
1622         size_t  size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);\r
1623 \r
1624         ASSERT_D( *out_NewString == NULL, __noop() );\r
1625 \r
1626         str = (TCHAR*) malloc( size );\r
1627         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
1628 \r
1629         memcpy( str, SourceString, size - sizeof(TCHAR) );\r
1630         str[ CountOfCharacter ] = _T('\0');\r
1631 \r
1632         *out_NewString = str;\r
1633         return  0;\r
1634 }\r
1635 \r
1636 \r
1637  \r
1638 /***********************************************************************\r
1639   <<< [StrT_chrs] >>> \r
1640 ************************************************************************/\r
1641 TCHAR*  StrT_chrs( const TCHAR* s, const TCHAR* keys )\r
1642 {\r
1643         if ( *keys == _T('\0') )  return  NULL;\r
1644 \r
1645         for ( ; *s != _T('\0'); s++ ) {\r
1646                 if ( _tcschr( keys, *s ) != NULL )\r
1647                         return  (TCHAR*) s;\r
1648         }\r
1649         return  NULL;\r
1650 }\r
1651 \r
1652 \r
1653  \r
1654 /***********************************************************************\r
1655   <<< [StrT_skip] >>> \r
1656 ************************************************************************/\r
1657 TCHAR*  StrT_skip( const TCHAR* s, const TCHAR* keys )\r
1658 {\r
1659         if ( *keys == _T('\0') )  return  (TCHAR*) s;\r
1660 \r
1661         for ( ; *s != _T('\0'); s++ ) {\r
1662                 if ( _tcschr( keys, *s ) == NULL )\r
1663                         break;\r
1664         }\r
1665         return  (TCHAR*) s;\r
1666 }\r
1667 \r
1668 \r
1669  \r
1670 /***********************************************************************\r
1671   <<< [StrT_refFName] >>> \r
1672 ************************************************************************/\r
1673 TCHAR*  StrT_refFName( const TCHAR* s )\r
1674 {\r
1675         const TCHAR*  p;\r
1676         TCHAR  c;\r
1677 \r
1678         p = _tcschr( s, _T('\0') );\r
1679 \r
1680         if ( p == s )  return  (TCHAR*) s;\r
1681 \r
1682         for ( p--; p>s; p-- ) {\r
1683                 c = *p;\r
1684                 if ( c == _T('\\') || c == _T('/') )  return  (TCHAR*) p+1;\r
1685         }\r
1686         if ( *p == _T('\\') || *p == _T('/') )  return  (TCHAR*) p+1;\r
1687 \r
1688         return  (TCHAR*) s;\r
1689 }\r
1690  \r
1691 /***********************************************************************\r
1692   <<< [StrT_refExt] >>> \r
1693 ************************************************************************/\r
1694 TCHAR*  StrT_refExt( const TCHAR* s )\r
1695 {\r
1696         const TCHAR*  p;\r
1697 \r
1698         p = _tcschr( s, _T('\0') );\r
1699 \r
1700         if ( p == s )  return  (TCHAR*) s;\r
1701 \r
1702         for ( p--; p>s; p-- ) {\r
1703                 if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
1704                 if ( *p == _T('/') || *p == _T('\\') )  return  (TCHAR*) _tcschr( p, _T('\0') );\r
1705         }\r
1706         if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
1707 \r
1708         return  (TCHAR*) _tcschr( s, _T('\0') );\r
1709 }\r
1710 \r
1711 \r
1712  \r
1713 /***********************************************************************\r
1714   <<< [StrT_replace1] >>> \r
1715 ************************************************************************/\r
1716 errnum_t  StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,\r
1717         unsigned Opt )\r
1718 {\r
1719         TCHAR*  p;\r
1720 \r
1721         UNREFERENCED_VARIABLE( Opt );\r
1722 \r
1723         IF ( FromCharacter == _T('\0') )  { return  E_OTHERS; }\r
1724 \r
1725         p = in_out_String;\r
1726         for (;;) {\r
1727                 p = _tcschr( p, FromCharacter );\r
1728                 if ( p == NULL )  { break; }\r
1729                 *p = ToCharacter;\r
1730                 p += 1;\r
1731         }\r
1732 \r
1733         return  0;\r
1734 }\r
1735 \r
1736 \r
1737  \r
1738 /***********************************************************************\r
1739   <<< [StrT_trim] >>> \r
1740 ************************************************************************/\r
1741 errnum_t  StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )\r
1742 {\r
1743         const TCHAR*  p1;\r
1744         const TCHAR*  p2;\r
1745         TCHAR   c;\r
1746 \r
1747         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
1748         for ( p2 = _tcschr( p1, _T('\0') ) - 1;  p2 >= p1;  p2-- ) {\r
1749                 c = *p2;\r
1750                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
1751                         break;\r
1752         }\r
1753         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
1754 }\r
1755 \r
1756 \r
1757  \r
1758 /***********************************************************************\r
1759   <<< [StrT_cutLastOf] >>> \r
1760 ************************************************************************/\r
1761 errnum_t  StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )\r
1762 {\r
1763         TCHAR*  last = _tcschr( in_out_Str, _T('\0') );\r
1764 \r
1765         if ( last > in_out_Str ) {\r
1766                 if ( *( last - 1 ) == Charactor )\r
1767                         { *( last - 1 ) = _T('\0'); }\r
1768         }\r
1769         return  0;\r
1770 }\r
1771 \r
1772 \r
1773  \r
1774 /***********************************************************************\r
1775   <<< [StrT_cutLineComment] >>> \r
1776 ************************************************************************/\r
1777 errnum_t  StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )\r
1778 {\r
1779         const TCHAR*  p1;\r
1780         const TCHAR*  p2;\r
1781         TCHAR   c;\r
1782 \r
1783         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
1784 \r
1785         p2 = _tcsstr( p1, CommentSign );\r
1786         if ( p2 == NULL )  p2 = _tcschr( p1, _T('\0') );\r
1787 \r
1788         for ( p2 = p2 - 1;  p2 >= p1;  p2-- ) {\r
1789                 c = *p2;\r
1790                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
1791                         break;\r
1792         }\r
1793         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
1794 }\r
1795 \r
1796 \r
1797  \r
1798 /**************************************************************************\r
1799   <<< [StrT_meltCSV] >>> \r
1800 *************************************************************************/\r
1801 errnum_t  StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )\r
1802 {\r
1803         errnum_t  e = 0;\r
1804         TCHAR*  t;\r
1805         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
1806         const TCHAR*  s;\r
1807         TCHAR  dummy[2];\r
1808         TCHAR  c;\r
1809 \r
1810         t = out_Str;\r
1811         s = *pCSV;\r
1812         if ( out_Str_Size <= 1 )  { t = dummy;  t_last = dummy; }\r
1813 \r
1814         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
1815 \r
1816 \r
1817         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
1818         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
1819 \r
1820         switch ( *s ) {\r
1821 \r
1822                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
1823                 case _T('"'):\r
1824                         s++;\r
1825                         c = *s;\r
1826                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
1827                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
1828                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
1829                                 if ( c == _T('\0') )  break;\r
1830                                 *t = c;  t++;  s++;  c = *s;\r
1831                         }\r
1832                         *t = _T('\0');\r
1833 \r
1834                         s++;\r
1835                         for (;;) {\r
1836                                 if ( *s == _T(',') )  { s = s+1;  break; }\r
1837                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
1838                                 s++;\r
1839                         }\r
1840                         *pCSV = s;\r
1841                         return  e;\r
1842 \r
1843                 /* \8bó\82Ì\8d\80\96Ú\82Ì\8fê\8d\87 */\r
1844                 case ',':\r
1845                         *t = _T('\0');\r
1846                         *pCSV = s+1;\r
1847                         return  0;\r
1848 \r
1849                 case '\0':\r
1850                         *t = _T('\0');\r
1851                         *pCSV = NULL;\r
1852                         return  0;\r
1853 \r
1854                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
1855                 default: {\r
1856                         TCHAR*  sp = NULL;  /* \8dÅ\8cã\82Ì\98A\91±\82µ\82½\8bó\94\92\82Ì\90æ\93ª */\r
1857 \r
1858                         c = *s;\r
1859                         while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* , \95\8e\9a\82Ü\82Å */\r
1860 \r
1861                                 /* sp \82ð\90Ý\92è\82·\82é */\r
1862                                 if ( c == ' ' ) {\r
1863                                         if ( sp == NULL )  sp = t;\r
1864                                 }\r
1865                                 else  sp = NULL;\r
1866 \r
1867                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
1868 \r
1869                                 /* \83R\83s\81[\82·\82é */\r
1870                                 *t = c;  t++;  s++;  c = *s;\r
1871                         }\r
1872 \r
1873                         /* \95Ô\82è\92l\82ð\8c\88\92è\82·\82é */\r
1874                         if ( c == _T(',') )  s = s + 1;\r
1875                         else  s = NULL;\r
1876 \r
1877                         /* \96\96\94ö\82Ì\8bó\94\92\82ð\8eæ\82è\8f\9c\82­ */\r
1878                         if ( sp != NULL )  *sp = '\0';\r
1879                         else  *t = _T('\0');\r
1880 \r
1881                         *pCSV = s;\r
1882                         return  e;\r
1883                 }\r
1884         }\r
1885 }\r
1886 \r
1887 \r
1888  \r
1889 /***********************************************************************\r
1890   <<< [StrT_getExistSymbols] >>> \r
1891 ************************************************************************/\r
1892 errnum_t  StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )\r
1893 {\r
1894         errnum_t  e;\r
1895         int       i;\r
1896         TCHAR** syms = NULL;\r
1897         bool*   syms_exists = NULL;\r
1898         bool    b_nosym = false;\r
1899         TCHAR*  sym = NULL;\r
1900         size_t  sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);\r
1901         int     n_sym = 0;\r
1902         const TCHAR*  p;\r
1903 \r
1904         UNREFERENCED_VARIABLES(( bCase ));\r
1905 \r
1906         sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;\r
1907 \r
1908 \r
1909         //=== Get Symbols\r
1910         p = Symbols;\r
1911         do {\r
1912                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
1913                 if ( sym[0] != _T('\0') )  n_sym ++;\r
1914         } while ( p != NULL );\r
1915 \r
1916         syms = (TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;\r
1917         memset( syms, 0, n_sym * sizeof(TCHAR*) );\r
1918         syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;\r
1919         memset( syms_exists, 0, n_sym * sizeof(bool) );\r
1920 \r
1921         p = Symbols;  i = 0;\r
1922         do {\r
1923                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
1924                 if ( sym[0] != _T('\0') ) {\r
1925                         e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;\r
1926                         i++;\r
1927                 }\r
1928         } while ( p != NULL );\r
1929 \r
1930 \r
1931         //=== Check Str whether having Symbols\r
1932         p = Str;\r
1933         do {\r
1934                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
1935                 if ( sym[0] != _T('\0') ) {\r
1936                         for ( i = 0; i < n_sym; i++ ) {\r
1937                                 if ( _tcscmp( sym, syms[i] ) == 0 )  { syms_exists[i] = true;  break; }\r
1938                         }\r
1939                         if ( i == n_sym )  b_nosym = true;\r
1940                 }\r
1941         } while ( p != NULL );\r
1942 \r
1943 \r
1944         //=== Sum numbers\r
1945         {\r
1946                 va_list   va;\r
1947                 unsigned  num;\r
1948 \r
1949                 va_start( va, Symbols );\r
1950                 *out = 0;\r
1951                 for ( i = 0; i < n_sym; i++ ) {\r
1952                         num = va_arg( va, unsigned );\r
1953                         if ( syms_exists[i] )  *out |= num;\r
1954                 }\r
1955                 va_end( va );\r
1956         }\r
1957 \r
1958         e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );\r
1959 fin:\r
1960         if ( syms != NULL ) {\r
1961                 for ( i = 0; i < n_sym; i++ ) {\r
1962                         if ( syms[i] != NULL )  free( syms[i] );\r
1963                 }\r
1964                 free( syms );\r
1965         }\r
1966         if ( syms_exists != NULL )  free( syms_exists );\r
1967         if ( sym != NULL )  free( sym );\r
1968         return  e;\r
1969 err_fm: e= E_FEW_MEMORY; goto fin;\r
1970 }\r
1971 \r
1972  \r
1973 /**************************************************************************\r
1974   <<< [StrT_meltCmdLine] >>> \r
1975 *************************************************************************/\r
1976 errnum_t  StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )\r
1977 {\r
1978         errnum_t  e = 0;\r
1979         TCHAR*  t;\r
1980         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
1981         const TCHAR*  s;\r
1982         TCHAR  dummy;\r
1983         TCHAR  c;\r
1984 \r
1985         t = out_Str;\r
1986         s = *pLine;\r
1987         if ( out_Str_Size <= 1 )  { t = &dummy;  t_last = &dummy; }\r
1988 \r
1989         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
1990 \r
1991 \r
1992         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
1993         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
1994 \r
1995         switch ( *s ) {\r
1996 \r
1997                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
1998                 case _T('"'):\r
1999                         s++;\r
2000                         c = *s;\r
2001                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
2002                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
2003                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
2004                                 if ( c == _T('\0') )  break;\r
2005                                 *t = c;  t++;  s++;  c = *s;\r
2006                         }\r
2007                         *t = _T('\0');\r
2008 \r
2009                         s++;\r
2010                         for (;;) {\r
2011                                 if ( *s == _T(' ') )  { s = s+1;  break; }\r
2012                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
2013                                 s++;\r
2014                         }\r
2015                         *pLine = s;\r
2016                         return  e;\r
2017 \r
2018                 case '\0':\r
2019                         *t = _T('\0');\r
2020                         *pLine = NULL;\r
2021                         return  0;\r
2022 \r
2023                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
2024                 default: {\r
2025                         c = *s;\r
2026                         while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* \8bó\94\92\95\8e\9a\82Ü\82Å */\r
2027 \r
2028                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
2029 \r
2030                                 /* \83R\83s\81[\82·\82é */\r
2031                                 *t = c;  t++;  s++;  c = *s;\r
2032                         }\r
2033 \r
2034                         /* *pLine\82ð\8c\88\92è\82·\82é */\r
2035                         while ( *s == _T(' ') )  s = s + 1;\r
2036                         if ( *s == _T('\0') )  s = NULL;\r
2037 \r
2038                         /* \96\96\94ö */\r
2039                         *t = _T('\0');\r
2040 \r
2041                         *pLine = s;\r
2042                         return  e;\r
2043                 }\r
2044         }\r
2045 }\r
2046 \r
2047 \r
2048  \r
2049 /***********************************************************************\r
2050   <<< [StrT_isAbsPath] >>> \r
2051 ************************************************************************/\r
2052 bool  StrT_isAbsPath( const TCHAR* s )\r
2053 {\r
2054         const TCHAR*  bs = _tcschr( s, _T('\\') );\r
2055         const TCHAR*  sl = _tcschr( s, _T('/') );\r
2056         const TCHAR*  co = _tcschr( s, _T(':') );\r
2057 \r
2058         return  ( co != NULL  && ( bs == co+1  ||  sl == co+1 ) );\r
2059 }\r
2060 \r
2061  \r
2062 /**************************************************************************\r
2063   <<< [StrT_getAbsPath_part] >>> \r
2064 *************************************************************************/\r
2065 errnum_t  StrT_getAbsPath_part( TCHAR* out_AbsPath, size_t AbsPathSize, TCHAR* OutStart,\r
2066         TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
2067 {\r
2068         errnum_t      e;\r
2069         TCHAR         separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;\r
2070         const TCHAR*  separator_path;\r
2071         TCHAR*        out_abs_path_over = (TCHAR*)( (uint8_t*) out_AbsPath + AbsPathSize );\r
2072         TCHAR*        null_position = NULL;\r
2073 \r
2074 \r
2075         #if  CHECK_ARG\r
2076                 /* "BasePath" must be out of "out_AbsPath" */\r
2077                 ASSERT_R( BasePath < out_AbsPath  ||\r
2078                         (uint8_t*) BasePath >= (uint8_t*) out_AbsPath + AbsPathSize,\r
2079                         goto err );\r
2080         #endif\r
2081 \r
2082 \r
2083         /* If "StepPath" == "", out_AbsPath = "" */\r
2084         if ( StepPath[0] == _T('\0') ) {\r
2085                 ASSERT_R( AbsPathSize >= sizeof(TCHAR), goto err_fm );\r
2086                 out_AbsPath[0] = _T('\0');\r
2087                 e=0;  goto fin;\r
2088         }\r
2089 \r
2090 \r
2091         /* Set "OutStart" */\r
2092         if ( OutStart == NULL )\r
2093                 { OutStart = out_AbsPath; }\r
2094 \r
2095 \r
2096         /* Set "separator" : \ or / from "BasePath" */\r
2097         if ( StrT_isAbsPath( StepPath ) ) {\r
2098                 separator_path = StepPath;\r
2099         }\r
2100         else if ( BasePath == NULL ) {\r
2101                 separator = _T('\\');\r
2102                 separator_path = NULL;\r
2103         }\r
2104         else {\r
2105                 separator_path = BasePath;\r
2106         }\r
2107         if ( separator_path != NULL ) {\r
2108                 const TCHAR*    p;\r
2109                 const TCHAR*    p2;\r
2110 \r
2111                 p  = _tcschr( separator_path, _T('\\') );\r
2112                 p2 = _tcschr( separator_path, _T('/') );\r
2113                 if ( p == NULL ) {\r
2114                         if ( p2 == NULL )\r
2115                                 { separator = _T('\\'); }\r
2116                         else\r
2117                                 { separator = _T('/'); }\r
2118                 } else {\r
2119                         if ( p2 == NULL )\r
2120                                 { separator = _T('\\'); }\r
2121                         else {\r
2122                                 if ( p < p2 )\r
2123                                         { separator = _T('\\'); }\r
2124                                 else\r
2125                                         { separator = _T('/'); }\r
2126                         }\r
2127                 }\r
2128         }\r
2129 \r
2130 \r
2131         /* Set "OutStart" : "BasePath" + / + "StepPath" */\r
2132         if ( StrT_isAbsPath( StepPath ) ) {\r
2133                 size_t  step_path_length = _tcslen( StepPath );\r
2134 \r
2135                 IF( OutStart + step_path_length >= out_abs_path_over ) goto err_fa;\r
2136                 memmove( OutStart,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
2137 \r
2138                 /* Set "null_position" */\r
2139                 null_position = OutStart + step_path_length;\r
2140         }\r
2141         else {\r
2142                 TCHAR   c;\r
2143                 TCHAR*  p;\r
2144                 size_t  base_path_length;\r
2145                 size_t  step_path_length = _tcslen( StepPath );\r
2146 \r
2147                 if ( BasePath == NULL ) {\r
2148                         base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
2149                 }\r
2150                 else {\r
2151                         base_path_length = _tcslen( BasePath );\r
2152                         c = BasePath[ base_path_length - 1 ];\r
2153                         if ( c == _T('\\')  ||  c == _T('/') )\r
2154                                 { base_path_length -= 1; }\r
2155                 }\r
2156 \r
2157                 p = OutStart + base_path_length + 1;\r
2158                 IF( p + step_path_length >= out_abs_path_over ) goto err_fa;\r
2159                 memmove( p,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
2160                         /* memmove is for "out_AbsPath" == "StepPath" */\r
2161 \r
2162                 if ( BasePath == NULL ) {\r
2163                         GetCurrentDirectory( base_path_length + 1, OutStart );\r
2164                         if ( OutStart[ base_path_length - 1 ] == _T('\\') )\r
2165                                 { base_path_length -= 1; }\r
2166                 } else {\r
2167                         memcpy( OutStart,  BasePath,  base_path_length * sizeof(TCHAR) );\r
2168                 }\r
2169                 OutStart[ base_path_length ] = separator;\r
2170 \r
2171 \r
2172                 /* Set "null_position" */\r
2173                 null_position = p + step_path_length;\r
2174         }\r
2175 \r
2176 \r
2177         /* Replace \ and / to "separator" in "OutStart" */\r
2178         {\r
2179                 TCHAR  other_separator;\r
2180 \r
2181                 if ( separator == _T('/') )\r
2182                         { other_separator = _T('\\'); }\r
2183                 else\r
2184                         { other_separator = _T('/'); }\r
2185 \r
2186                 e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;\r
2187         }\r
2188 \r
2189 \r
2190         /* Replace \*\..\ to \ */\r
2191         {\r
2192                 enum  { length = 4 };\r
2193                 TCHAR   parent[ length + 1 ];  /* \..\ or /../ */\r
2194                 TCHAR*  parent_position;\r
2195                 TCHAR*  p;\r
2196 \r
2197                 parent[0] = separator;\r
2198                 parent[1] = _T('.');\r
2199                 parent[2] = _T('.');\r
2200                 parent[3] = separator;\r
2201                 parent[4] = _T('\0');\r
2202 \r
2203                 for (;;) {\r
2204                         parent_position = _tcsstr( OutStart, parent );\r
2205                         if ( parent_position == NULL )  { break; }\r
2206 \r
2207                         p = parent_position - 1;\r
2208                         for (;;) {\r
2209                                 IF( p < OutStart ) goto err;  /* "../" are too many */\r
2210                                 if ( *p == separator )  { break; }\r
2211                                 p -= 1;\r
2212                         }\r
2213 \r
2214                         memmove( p + 1,\r
2215                                 parent_position + length,\r
2216                                 ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );\r
2217 \r
2218                         null_position -= ( parent_position + length ) - ( p + 1 );\r
2219                 }\r
2220         }\r
2221 \r
2222 \r
2223         /* Cut last \*\.. */\r
2224         {\r
2225                 enum  { length = 3 };\r
2226                 TCHAR*  p;\r
2227 \r
2228                 while ( null_position - length >= OutStart ) {\r
2229                         if ( *( null_position - 3 ) != separator  ||\r
2230                              *( null_position - 2 ) != _T('.')  ||\r
2231                              *( null_position - 1 ) != _T('.') )\r
2232                                 { break; }\r
2233 \r
2234                         p = null_position - 4;\r
2235                         for (;;) {\r
2236                                 IF( p < OutStart ) goto err;  /* "../" are too many */\r
2237                                 if ( *p == separator )  { break; }\r
2238                                 p -= 1;\r
2239                         }\r
2240 \r
2241                         *p = _T('\0');\r
2242 \r
2243                         null_position = p;\r
2244                 }\r
2245         }\r
2246 \r
2247 \r
2248         /* Replace \.\ to \ */\r
2249         {\r
2250                 enum  { length = 3 };\r
2251                 TCHAR   current[ length + 1 ];  /* \.\ or /./ */\r
2252                 TCHAR*  current_position;\r
2253 \r
2254                 current[0] = separator;\r
2255                 current[1] = _T('.');\r
2256                 current[2] = separator;\r
2257                 current[3] = _T('\0');\r
2258 \r
2259                 for (;;) {\r
2260                         current_position = _tcsstr( OutStart, current );\r
2261                         if ( current_position == NULL )  { break; }\r
2262 \r
2263                         memmove( current_position + 1,\r
2264                                 current_position + length,\r
2265                                 ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );\r
2266 \r
2267                         null_position -= length - 1;\r
2268                 }\r
2269         }\r
2270 \r
2271 \r
2272         /* Cut last \. */\r
2273         {\r
2274                 TCHAR*  over = _tcschr( OutStart, _T('\0') );\r
2275 \r
2276                 while ( over - 2 >= OutStart  &&\r
2277                                 *( over - 1 ) == _T('.')  &&  *( over - 2 ) == separator ) {\r
2278                         over -= 2;\r
2279                         *over = _T('\0');\r
2280                 }\r
2281         }\r
2282 \r
2283 \r
2284         /* Add root / */\r
2285         if ( null_position - 1 >= OutStart ) {\r
2286                 if ( *( null_position - 1 ) == _T(':') ) {\r
2287                         IF( null_position + 1 >= out_abs_path_over ) goto err_fa;\r
2288 \r
2289                         *( null_position + 0 ) = separator;\r
2290                         *( null_position + 1 ) = _T('\0');\r
2291                         null_position += 1;\r
2292                 }\r
2293         }\r
2294 \r
2295 \r
2296         /* Set "*out_OutLast" */\r
2297         if ( out_OutLast != NULL )\r
2298                 { *out_OutLast = null_position; }\r
2299 \r
2300         e=0;\r
2301 fin:\r
2302         return  e;\r
2303 \r
2304 err:     e = E_OTHERS;      goto fin;\r
2305 err_fa:  e = E_FEW_ARRAY;   goto fin;\r
2306 err_fm:  e = E_FEW_MEMORY;  goto fin;\r
2307 }\r
2308 \r
2309 \r
2310  \r
2311 /***********************************************************************\r
2312   <<< [StrT_getParentAbsPath_part] >>> \r
2313 ************************************************************************/\r
2314 errnum_t  StrT_getParentAbsPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
2315         TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
2316 {\r
2317         errnum_t  e;\r
2318         TCHAR*  p;\r
2319 \r
2320         IF_D( StrStart < Str ||  (char*) StrStart >= (char*)Str + StrSize )goto err;\r
2321 \r
2322         if ( StepPath[0] == _T('\0') ) {\r
2323                 *StrStart = _T('\0');\r
2324                 return  0;\r
2325         }\r
2326 \r
2327         /* \90â\91Î\83p\83X\82É\82·\82é */\r
2328         e= StrT_getAbsPath( StrStart,\r
2329                 StrSize - ( (char*)StrStart - (char*)Str ),\r
2330                 StepPath, BasePath ); IF(e)goto fin;\r
2331 \r
2332 \r
2333         /* Cut last \ */\r
2334         p = _tcschr( StrStart, _T('\0') );\r
2335         if ( p > StrStart ) {\r
2336                 TCHAR  c = *( p - 1 );\r
2337                 if ( c == _T('\\')  ||  c == _T('/') )\r
2338                         { *( p - 1 ) = _T('\0'); }\r
2339         }\r
2340 \r
2341 \r
2342         /* \90e\82Ö */\r
2343         p = StrT_refFName( StrStart );\r
2344         if ( p > StrStart )  p--;\r
2345         *p = _T('\0');\r
2346 \r
2347 \r
2348         /* \83\8b\81[\83g\82È\82ç \ \82ð\95t\82¯\82é */\r
2349         if ( p == StrStart + 2 ) {\r
2350                 *p = _T('\\');  p++;  *p = _T('\0');\r
2351         }\r
2352 \r
2353         if ( out_StrLast != NULL )  *out_StrLast = p;\r
2354 \r
2355         e=0;\r
2356 fin:\r
2357         return  e;\r
2358 \r
2359 err:  e = E_OTHERS;  goto fin;\r
2360 }\r
2361 \r
2362 \r
2363  \r
2364 /***********************************************************************\r
2365   <<< [StrT_isOverOfFileName] >>> \r
2366 - "" or "\" or "/"\r
2367 ************************************************************************/\r
2368 inline bool  StrT_isOverOfFileName( const TCHAR* PointerInPath )\r
2369 {\r
2370         return  PointerInPath == NULL  ||\r
2371                 *PointerInPath == _T('\0')  ||\r
2372                 ( ( *PointerInPath == _T('\\')  ||  *PointerInPath == _T('/') )  &&\r
2373                         *(PointerInPath + 1) == _T('\0') );\r
2374 }\r
2375 \r
2376 \r
2377  \r
2378 /***********************************************************************\r
2379   <<< [StrT_getStepPath] >>> \r
2380 ************************************************************************/\r
2381 errnum_t  StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,\r
2382         const TCHAR* AbsPath, const TCHAR* BasePath )\r
2383 {\r
2384         errnum_t      e;\r
2385         const TCHAR*  abs_pointer;\r
2386         const TCHAR*  base_pointer;\r
2387         TCHAR         abs_char;\r
2388         TCHAR         base_char;\r
2389         TCHAR         separator;\r
2390         const TCHAR*  abs_separator_pointer  = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
2391         const TCHAR*  base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
2392         TCHAR*        step_pointer;\r
2393         TCHAR         parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };\r
2394         TCHAR         base_path_2[ MAX_PATH ];\r
2395 \r
2396 \r
2397         ASSERT_D( out_StepPath != AbsPath, goto err );\r
2398 \r
2399         abs_pointer = AbsPath;\r
2400 \r
2401 \r
2402         /* Set "base_pointer" */\r
2403         if ( BasePath == NULL ) {\r
2404                 base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );\r
2405                 IF( base_pointer == NULL ) goto err;\r
2406         }\r
2407         else {\r
2408                 base_pointer = BasePath;\r
2409         }\r
2410 \r
2411 \r
2412         /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */\r
2413         separator = 0;\r
2414         for (;;) {  /* while abs_char == base_char */\r
2415                 abs_char  = *abs_pointer;\r
2416                 base_char = *base_pointer;\r
2417 \r
2418                 abs_char  = (TCHAR) _totlower( abs_char );\r
2419                 base_char = (TCHAR) _totlower( base_char );\r
2420 \r
2421                 if ( abs_char == _T('\0') ) {\r
2422 \r
2423                         /* out_StepPath = ".", if AbsPath == BasePath */\r
2424                         if ( base_char == _T('\0') ) {\r
2425                                 e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;\r
2426                                 e=0; goto fin;\r
2427                         }\r
2428                         break;\r
2429                 }\r
2430                 if ( base_char == _T('\0') )  { break; }\r
2431 \r
2432                 if ( abs_char != base_char ) {\r
2433                         if ( ( abs_char  == _T('/')  ||  abs_char  == _T('\\') ) &&\r
2434                              ( base_char == _T('/')  ||  base_char == _T('\\') ) )\r
2435                                 { /* Do nothing */ }\r
2436                         else\r
2437                                 { break; }\r
2438                 }\r
2439 \r
2440                 /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */\r
2441                 if (  base_char == _T('/')  ||  base_char == _T('\\')  ) {\r
2442                         if ( separator == 0 )\r
2443                                 { separator = base_char; }\r
2444 \r
2445                         abs_separator_pointer = abs_pointer;\r
2446                         base_separator_pointer = base_pointer;\r
2447                 }\r
2448 \r
2449                 abs_pointer  += 1;\r
2450                 base_pointer += 1;\r
2451         }\r
2452 \r
2453 \r
2454         /* AbsPath \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
2455         if (  abs_char == _T('/')  ||  abs_char == _T('\\')  ||\r
2456              base_char == _T('/')  || base_char == _T('\\')  ) {\r
2457              /* other character is '\0' */\r
2458 \r
2459                 if ( separator == 0 )\r
2460                         { separator = abs_char; }\r
2461 \r
2462                 abs_separator_pointer = abs_pointer;\r
2463                 base_separator_pointer = base_pointer;\r
2464         }\r
2465 \r
2466 \r
2467         /* out_StepPath = AbsPath, if there is not same folder */\r
2468         if ( separator == 0 ) {\r
2469                 e= StrT_cpy( out_StepPath, StepPathSize, AbsPath ); IF(e)goto fin;\r
2470                 e=0; goto fin;\r
2471         }\r
2472 \r
2473 \r
2474         /* Add "..\" to "out_StepPath" */\r
2475         parent_symbol[2] = separator;\r
2476         step_pointer = out_StepPath;\r
2477         for (;;) {\r
2478                 const TCHAR*  p1;\r
2479                 const TCHAR*  p2;\r
2480 \r
2481                 if ( StrT_isOverOfFileName( base_separator_pointer ) )\r
2482                         { break; }\r
2483 \r
2484 \r
2485                 /* Set "base_separator_pointer" : next separator */\r
2486                 p1 = _tcschr( base_separator_pointer + 1, _T('/') );\r
2487                 p2 = _tcschr( base_separator_pointer + 1, _T('\\') );\r
2488 \r
2489                 if ( p1 == NULL ) {\r
2490                         if ( p2 == NULL )\r
2491                                 { base_separator_pointer = NULL; }\r
2492                         else\r
2493                                 { base_separator_pointer = p2; }\r
2494                 }\r
2495                 else {\r
2496                         if ( p2 == NULL ) {\r
2497                                 base_separator_pointer = p1;\r
2498                         } else {\r
2499                                 if ( p1 < p2 )\r
2500                                         { base_separator_pointer = p1; }\r
2501                                 else\r
2502                                         { base_separator_pointer = p2; }\r
2503                         }\r
2504                 }\r
2505 \r
2506 \r
2507                 /* Add "..\" to "out_StepPath" */\r
2508                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,\r
2509                         parent_symbol, NULL ); IF(e)goto fin;\r
2510         }\r
2511 \r
2512 \r
2513         /* Copy a part of "AbsPath" to "out_StepPath" */\r
2514         if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {\r
2515                 ASSERT_D( step_pointer > out_StepPath, goto err );\r
2516                 *( step_pointer - 1 ) = _T('\0');\r
2517         }\r
2518         else {\r
2519                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,\r
2520                         abs_separator_pointer + 1, NULL ); IF(e)goto fin;\r
2521         }\r
2522 \r
2523         e=0;\r
2524 fin:\r
2525         return  e;\r
2526 \r
2527 err:  e = E_OTHERS;  goto fin;\r
2528 }\r
2529 \r
2530 \r
2531  \r
2532 /***********************************************************************\r
2533   <<< [StrT_getBaseName_part] >>> \r
2534 ************************************************************************/\r
2535 errnum_t  StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
2536         TCHAR** out_StrLast, const TCHAR* SrcPath )\r
2537 {\r
2538         const TCHAR*  p1;\r
2539         const TCHAR*  p2;\r
2540         const TCHAR*  p3;\r
2541         const TCHAR*  ps;\r
2542 \r
2543         p1 = StrT_refFName( SrcPath );\r
2544 \r
2545 \r
2546         //=== # \82ª\96³\82¢\82Æ\82«\81A\8dÅ\8cã\82Ì\83s\83\8a\83I\83h\82Ì\91O\82Ü\82Å\82ª\81ABaseName\r
2547         ps = _tcschr( p1, _T('#') );\r
2548         if ( ps == NULL ) {\r
2549                 p2 = _tcsrchr( p1, _T('.') );\r
2550                 if ( p2 == NULL )  p2 = _tcsrchr( p1, _T('\0') );\r
2551         }\r
2552 \r
2553         //=== # \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
2554         else {\r
2555                 p2 = ps;\r
2556 \r
2557                 p3 = p1;\r
2558                 for (;;) {\r
2559                         p3 = _tcschr( p3, _T('.') );\r
2560                         if ( p3 == NULL || p3 > ps )  break;\r
2561                         p2 = p3;\r
2562                         p3 ++;\r
2563                 }\r
2564         }\r
2565 \r
2566         return  stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );\r
2567 }\r
2568 \r
2569  \r
2570 /***********************************************************************\r
2571   <<< [StrT_addLastOfFileName] >>> \r
2572 ************************************************************************/\r
2573 errnum_t  StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,\r
2574                              const TCHAR* BasePath, const TCHAR* AddName )\r
2575 {\r
2576         TCHAR           c;\r
2577         size_t          copy_size;\r
2578         size_t          free_size;\r
2579         char*           out_pos;\r
2580         const TCHAR*    last_pos_in_base = _tcschr( BasePath, _T('\0') );\r
2581         const TCHAR*    term_pos_in_base;\r
2582         const TCHAR*     add_pos_in_base;\r
2583         const TCHAR*  period_pos_in_base = _tcsrchr( BasePath, _T('.') );  // > term_pos_in_base\r
2584         const TCHAR*    last_pos_in_add  = _tcschr( AddName, _T('\0') );\r
2585         const TCHAR*    term_pos_in_add;\r
2586         const TCHAR*  period_pos_in_add  = _tcsrchr( AddName,  _T('.') );  // > term_pos_in_add\r
2587 \r
2588 \r
2589         MEMSET_TO_NOT_INIT( out_Path, PathSize );\r
2590 \r
2591 \r
2592         //=== term_pos_in_base\r
2593         for ( term_pos_in_base = last_pos_in_base;  term_pos_in_base >= BasePath;  term_pos_in_base -- ) {\r
2594                 c = *term_pos_in_base;\r
2595                 if ( c == _T('/') || c == _T('\\') )  break;\r
2596         }\r
2597 \r
2598 \r
2599         //=== term_pos_in_add\r
2600         for ( term_pos_in_add = last_pos_in_add;  term_pos_in_add >= AddName;  term_pos_in_add -- ) {\r
2601                 c = *term_pos_in_add;\r
2602                 if ( c == _T('/') || c == _T('\\') )  break;\r
2603         }\r
2604 \r
2605 \r
2606         //=== add_pos_in_base\r
2607         if ( term_pos_in_base < period_pos_in_base ) {\r
2608                 add_pos_in_base = period_pos_in_base;\r
2609         }\r
2610         else {\r
2611                 if ( term_pos_in_base < BasePath )\r
2612                         add_pos_in_base = _tcschr( BasePath, _T('\0') );\r
2613                 else\r
2614                         add_pos_in_base = _tcschr( term_pos_in_base, _T('\0') );\r
2615         }\r
2616 \r
2617 \r
2618         //=== setup output parameters\r
2619         out_pos   = (char*) out_Path;\r
2620         free_size = PathSize;\r
2621 \r
2622 \r
2623         //=== copy BasePath .. add_pos_in_base\r
2624         copy_size = (char*)add_pos_in_base - (char*)BasePath;\r
2625         if ( copy_size > free_size ) goto err_fa;\r
2626         memcpy( out_pos,  BasePath,  copy_size );\r
2627         out_pos   += copy_size;\r
2628         free_size -= copy_size;\r
2629 \r
2630 \r
2631         //=== copy AddName .. last_pos_in_add\r
2632         copy_size = (char*)last_pos_in_add - (char*)AddName;\r
2633         if ( copy_size > free_size ) goto err_fa;\r
2634         memcpy( out_pos,  AddName,  copy_size );\r
2635         out_pos   += copy_size;\r
2636         free_size -= copy_size;\r
2637 \r
2638 \r
2639         //=== add name and not change extension\r
2640         if ( period_pos_in_add == NULL ) {\r
2641 \r
2642                 //=== copy period_pos_in_base .. last_pos_in_base\r
2643                 if ( period_pos_in_base > term_pos_in_base ) {\r
2644                         copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);\r
2645                         if ( copy_size > free_size ) goto err_fa;\r
2646                         memcpy( out_pos,  period_pos_in_base,  copy_size );\r
2647                 }\r
2648                 else {\r
2649                         *(TCHAR*)out_pos = _T('\0');\r
2650                 }\r
2651         }\r
2652 \r
2653 \r
2654         //=== add name and change extension\r
2655         else {\r
2656 \r
2657                 if ( *(period_pos_in_add + 1) == _T('\0') )\r
2658                         *( (TCHAR*)out_pos - 1 ) = _T('\0');\r
2659                 else\r
2660                         *(TCHAR*)out_pos = _T('\0');\r
2661         }\r
2662 \r
2663         return  0;\r
2664 \r
2665 err_fa:\r
2666         return  E_FEW_ARRAY;\r
2667 }\r
2668 \r
2669 \r
2670  \r
2671 /***********************************************************************\r
2672   <<< [Strs_init] >>> \r
2673 ************************************************************************/\r
2674 enum { Strs_FirstSize = 0x0F00 };\r
2675 \r
2676 errnum_t  Strs_init( Strs* self )\r
2677 {\r
2678         char*  p;\r
2679 \r
2680         self->MemoryAddress = NULL;\r
2681 \r
2682         p = (char*) malloc( Strs_FirstSize );\r
2683         IF( p == NULL )  return  E_FEW_MEMORY;\r
2684 \r
2685         self->MemoryAddress = p;\r
2686         self->MemoryOver    = p + Strs_FirstSize;\r
2687         self->NextElem      = p + sizeof(TCHAR*);\r
2688         self->PointerToNextStrInPrevElem = (TCHAR**) p;\r
2689         self->Prev_PointerToNextStrInPrevElem = NULL;\r
2690         *(TCHAR**) p = NULL;\r
2691 \r
2692         self->FirstOfStrs = self;\r
2693         self->NextStrs = NULL;\r
2694 \r
2695         return  0;\r
2696 }\r
2697 \r
2698 \r
2699  \r
2700 /***********************************************************************\r
2701   <<< [Strs_finish] >>> \r
2702 ************************************************************************/\r
2703 errnum_t  Strs_finish( Strs* self, errnum_t e )\r
2704 {\r
2705         Strs*  mp;\r
2706         Strs*  next_mp;\r
2707 \r
2708         if ( self->MemoryAddress == NULL )  return 0;\r
2709 \r
2710         mp = self->FirstOfStrs;\r
2711         for (;;) {\r
2712                 free( mp->MemoryAddress );\r
2713                 if ( mp == self )  break;\r
2714 \r
2715                 next_mp = mp->NextStrs;\r
2716                 free( mp );\r
2717                 mp = next_mp;\r
2718         }\r
2719         self->MemoryAddress = NULL;\r
2720 \r
2721         return  e;\r
2722 }\r
2723 \r
2724 \r
2725  \r
2726 /***********************************************************************\r
2727   <<< [Strs_toEmpty] >>> \r
2728 ************************************************************************/\r
2729 errnum_t  Strs_toEmpty( Strs* self )\r
2730 {\r
2731         Strs_finish( self, 0 );\r
2732         return  Strs_init( self );\r
2733 }\r
2734 \r
2735 \r
2736  \r
2737 /***********************************************************************\r
2738   <<< [Strs_add] >>> \r
2739 ************************************************************************/\r
2740 errnum_t  Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )\r
2741 {\r
2742         return  Strs_addBinary( self, Str, _tcschr( Str, _T('\0') ) + 1, out_AllocStr );\r
2743 }\r
2744 \r
2745 \r
2746 errnum_t  Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )\r
2747 {\r
2748         errnum_t  e;\r
2749         size_t  str_size;\r
2750         size_t  elem_size;\r
2751 \r
2752         str_size  = ( (char*) StrOver - (char*) Str );\r
2753         elem_size = ( sizeof(TCHAR*) + str_size + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
2754 \r
2755         if ( self->NextElem + elem_size > self->MemoryOver )\r
2756                 { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }\r
2757 \r
2758 \r
2759         // [ NULL     | ... ]\r
2760         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
2761         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
2762         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
2763 \r
2764         if ( out_AllocStr != NULL )  *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
2765 \r
2766         //=== fill elem\r
2767         *(TCHAR**) self->NextElem = NULL;\r
2768         memcpy( self->NextElem + sizeof(TCHAR*),  Str,  str_size );\r
2769 \r
2770         //=== link to elem from previous elem\r
2771         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
2772 \r
2773         //=== update self\r
2774         self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;\r
2775         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
2776         self->NextElem = self->NextElem + elem_size;\r
2777 \r
2778         e=0;\r
2779 fin:\r
2780         return  e;\r
2781 }\r
2782 \r
2783 \r
2784  \r
2785 /***********************************************************************\r
2786   <<< [Strs_freeLast] >>> \r
2787 ************************************************************************/\r
2788 errnum_t  Strs_freeLast( Strs* self, TCHAR* AllocStr )\r
2789 {\r
2790         errnum_t  e;\r
2791         TCHAR*  str;\r
2792         TCHAR*  last_str;\r
2793         TCHAR*  prev_of_last_str;\r
2794         Strs*   mp;\r
2795         Strs*   prev_of_last_mp;\r
2796 \r
2797         if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {\r
2798                 prev_of_last_str = NULL;\r
2799                 last_str = NULL;\r
2800                 for ( Strs_forEach( self, &str ) ) {\r
2801                         prev_of_last_str = last_str;\r
2802                         last_str = str;\r
2803                 }\r
2804         }\r
2805         else {\r
2806                 prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );\r
2807                 last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );\r
2808         }\r
2809 \r
2810         // [ NULL     | ... ]\r
2811         IF( last_str != AllocStr ) goto err;\r
2812 \r
2813         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
2814         if ( prev_of_last_str == NULL ) {\r
2815                 self->NextElem = self->MemoryAddress + sizeof(TCHAR*);\r
2816                 self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;\r
2817         }\r
2818 \r
2819         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
2820         else if ( (char*) prev_of_last_str >= self->MemoryAddress  &&\r
2821                   (char*) prev_of_last_str <  self->MemoryOver ) {\r
2822                 self->NextElem = (char*)last_str - sizeof(TCHAR*);\r
2823                 self->PointerToNextStrInPrevElem = (TCHAR**)( (char*)prev_of_last_str - sizeof(TCHAR*) );\r
2824         }\r
2825 \r
2826         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
2827         else {\r
2828                 prev_of_last_mp = NULL;\r
2829                 for ( mp = self->FirstOfStrs;  mp->NextStrs != self;  mp = mp->NextStrs ) {\r
2830                         prev_of_last_mp = mp;\r
2831                 }\r
2832 \r
2833                 free( self->MemoryAddress );\r
2834 \r
2835                 *self = *mp;\r
2836 \r
2837                 if ( prev_of_last_mp == NULL ) {\r
2838                         self->FirstOfStrs = self;\r
2839                         self->NextStrs = NULL;\r
2840                 }\r
2841                 else {\r
2842                         prev_of_last_mp->NextStrs = self;\r
2843                 }\r
2844 \r
2845                 free( mp );\r
2846         }\r
2847         *self->PointerToNextStrInPrevElem = NULL;\r
2848         self->Prev_PointerToNextStrInPrevElem = NULL;\r
2849 \r
2850         e=0;\r
2851 fin:\r
2852         return  e;\r
2853 \r
2854 err:  e = E_OTHERS;  goto fin;\r
2855 }\r
2856 \r
2857 \r
2858  \r
2859 /***********************************************************************\r
2860   <<< [Strs_expandSize] >>> \r
2861 ************************************************************************/\r
2862 errnum_t  Strs_expandSize( Strs* self, size_t FreeSize )\r
2863 {\r
2864         Strs*   mp;\r
2865         Strs*   mp2;\r
2866         size_t  elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
2867         size_t  memory_size;\r
2868         char*   new_memory;\r
2869 \r
2870         // [ NULL     | ... ]\r
2871         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
2872         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
2873         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
2874 \r
2875         while ( self->NextElem + elem_size > self->MemoryOver ) {\r
2876 \r
2877                 //=== alloc\r
2878                 mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;\r
2879                 memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;\r
2880                 new_memory = (char*) malloc( memory_size );\r
2881                 IF( new_memory == NULL )  { free( mp );  goto err_fm; }\r
2882 \r
2883                 //=== move old memory\r
2884                 if ( self->FirstOfStrs == self ) {\r
2885                         self->FirstOfStrs = mp;\r
2886                 }\r
2887                 else {\r
2888                         for ( mp2 = self->FirstOfStrs;  mp2->NextStrs != self;  mp2 = mp2->NextStrs );\r
2889                         mp2->NextStrs = mp;\r
2890                 }\r
2891                 *mp = *self;\r
2892                 mp->NextStrs = self;\r
2893 \r
2894                 //=== setup new memory\r
2895                 self->MemoryAddress = new_memory;\r
2896                 self->MemoryOver    = new_memory + memory_size;\r
2897                 self->NextElem      = new_memory;\r
2898                 // self->PointerToNextStrInPrevElem is same value\r
2899                 // self->FirstOfStrs is same value\r
2900                 // self->NextStrs is always NULL\r
2901         }\r
2902         return  0;\r
2903 \r
2904 err_fm:  return  E_FEW_ARRAY;\r
2905 }\r
2906 \r
2907 \r
2908 /***********************************************************************\r
2909   <<< [Strs_commit] >>>\r
2910 ************************************************************************/\r
2911 errnum_t  Strs_commit( Strs* self, TCHAR* StrOver )\r
2912 {\r
2913         size_t  elem_size;\r
2914 \r
2915         if ( StrOver == NULL )\r
2916                 { StrOver = _tcschr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }\r
2917         elem_size = ( ( (char*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
2918 \r
2919         //=== fill elem\r
2920         *(TCHAR**) self->NextElem = NULL;\r
2921 \r
2922         //=== link to elem from previous elem\r
2923         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
2924 \r
2925         //=== update self\r
2926         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
2927         self->NextElem = self->NextElem + elem_size;\r
2928 \r
2929         return  0;\r
2930 }\r
2931 \r
2932 \r
2933  \r
2934 /***********************************************************************\r
2935   <<< [StrArr] >>> \r
2936 ************************************************************************/\r
2937 \r
2938 /*[StrArr_init]*/\r
2939 errnum_t  StrArr_init( StrArr* self )\r
2940 {\r
2941         errnum_t  e;\r
2942 \r
2943         Set2_initConst( &self->Array );\r
2944         Strs_initConst( &self->Chars );\r
2945 \r
2946         e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;\r
2947         e= Strs_init( &self->Chars ); IF(e)goto cancel;\r
2948         return  0;\r
2949 \r
2950 cancel:  StrArr_finish( self, e );  return  e;\r
2951 }\r
2952 \r
2953 \r
2954 /*[StrArr_finish]*/\r
2955 errnum_t  StrArr_finish( StrArr* self, errnum_t e )\r
2956 {\r
2957         if ( ! Set2_isInited( &self->Array ) )  return  0;\r
2958 \r
2959         e= Set2_finish( &self->Array, e );\r
2960         e= Strs_finish( &self->Chars, e );\r
2961         return  e;\r
2962 }\r
2963 \r
2964 \r
2965 /*[StrArr_add]*/\r
2966 errnum_t  StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )\r
2967 {\r
2968         errnum_t  e;\r
2969 \r
2970         e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;\r
2971         _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );\r
2972         e= StrArr_commit( self ); IF(e)goto fin;\r
2973         if ( out_I != NULL )  *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;\r
2974 \r
2975         e=0;\r
2976 fin:\r
2977         return  e;\r
2978 }\r
2979 \r
2980 \r
2981 /*[StrArr_commit]*/\r
2982 errnum_t  StrArr_commit( StrArr* self )\r
2983 {\r
2984         errnum_t  e;\r
2985         TCHAR*   p;\r
2986         TCHAR**  pp  = NULL;\r
2987         Set2*    arr = &self->Array;\r
2988         Strs*    ss  = &self->Chars;\r
2989 \r
2990         p = Strs_getFreeAddr( ss );\r
2991         e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;\r
2992         e= Strs_commit( ss, NULL ); IF(e)goto fin;\r
2993         *pp = p;\r
2994 \r
2995         e=0;\r
2996 fin:\r
2997         if ( e &&  pp != NULL )  e= Set2_freeLast( arr, pp, TCHAR*, e );\r
2998         return  e;\r
2999 }\r
3000 \r
3001 \r
3002 /*[StrArr_fillTo]*/\r
3003 errnum_t  StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )\r
3004 {\r
3005         errnum_t  e;\r
3006         const TCHAR*   p;\r
3007         const TCHAR**  pp;\r
3008         const TCHAR**  pp_over;\r
3009 \r
3010         n -= Set2_getCount( &self->Array, TCHAR* );\r
3011         if ( n <= 0 ) return 0;\r
3012 \r
3013         if ( Str == NULL ) {\r
3014                 p = NULL;\r
3015         }\r
3016         else {\r
3017                 e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;\r
3018         }\r
3019 \r
3020         e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;\r
3021         pp_over = pp + n;\r
3022         for ( ;  pp < pp_over;  pp++ )\r
3023                 *pp = p;\r
3024 \r
3025         e=0;\r
3026 fin:\r
3027         return  e;\r
3028 }\r
3029 \r
3030 \r
3031 /*[StrArr_toEmpty]*/\r
3032 errnum_t  StrArr_toEmpty( StrArr* self )\r
3033 {\r
3034         errnum_t  e, ee;\r
3035 \r
3036         e=0;\r
3037         ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;\r
3038         ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;\r
3039         return  e;\r
3040 }\r
3041 \r
3042 \r
3043  \r
3044 /***********************************************************************\r
3045   <<< [StrArr_parseCSV] >>> \r
3046 ************************************************************************/\r
3047 errnum_t  StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )\r
3048 {\r
3049         errnum_t      e;\r
3050         const TCHAR*  p = CSVLine;\r
3051 \r
3052         e= StrArr_toEmpty( self ); IF(e)goto fin;\r
3053 \r
3054         do {\r
3055                 e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );\r
3056                 if ( e == E_FEW_ARRAY ) {\r
3057                         e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;\r
3058                         continue;\r
3059                 }\r
3060                 IF(e)goto fin;\r
3061 \r
3062                 e = StrArr_commit( self ); IF(e)goto fin;\r
3063         } while ( p != NULL );\r
3064 \r
3065         e=0;\r
3066 fin:\r
3067         return  e;\r
3068 }\r
3069 \r
3070 \r
3071  \r
3072 /*=================================================================*/\r
3073 /* <<< [SetX/SetX.c] >>> */ \r
3074 /*=================================================================*/\r
3075  \r
3076 /***********************************************************************\r
3077   <<< [Set2_init] >>> \r
3078 ************************************************************************/\r
3079 int  Set2_init( Set2* m, int FirstSize )\r
3080 {\r
3081         m->First = malloc( FirstSize );\r
3082         if ( m->First == NULL )  return  E_FEW_MEMORY;\r
3083         m->Next = m->First;\r
3084         m->Over = (char*)m->First + FirstSize;\r
3085 \r
3086         #ifdef _DEBUG\r
3087         m->PointerOfDebugArray = NULL;\r
3088         #endif\r
3089 \r
3090         return  0;\r
3091 }\r
3092  \r
3093 /***********************************************************************\r
3094   <<< [Set2_finish] >>> \r
3095 ************************************************************************/\r
3096 int  Set2_finish( Set2* m, int e )\r
3097 {\r
3098         if ( m->First != NULL )  { free( m->First );  m->First = NULL; }\r
3099         return  e;\r
3100 }\r
3101 \r
3102  \r
3103 /***********************************************************************\r
3104   <<< [Set2_ref_imp] >>> \r
3105 ************************************************************************/\r
3106 int  Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )\r
3107 {\r
3108         int    e;\r
3109         char*  p;\r
3110 \r
3111         IF( iElem < 0 ) goto err_ns;\r
3112         p = (char*) m->First + ( (unsigned)iElem * ElemSize );\r
3113         IF( p >= (char*)m->Next ) goto err_ns;\r
3114         *(char**)out_pElem = p;\r
3115 \r
3116         e=0;\r
3117 fin:\r
3118         return  e;\r
3119 \r
3120 err_ns:  e = E_NOT_FOUND_SYMBOL;  goto fin;\r
3121 }\r
3122 \r
3123 \r
3124  \r
3125 /***********************************************************************\r
3126   <<< [Set2_alloc_imp] >>> \r
3127 ************************************************************************/\r
3128 int  Set2_alloc_imp( Set2* m, void* pp, size_t size )\r
3129 {\r
3130         int  e;\r
3131 \r
3132         e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;\r
3133         *(void**)pp = m->Next;\r
3134         m->Next = (char*) m->Next + size;\r
3135 \r
3136         MEMSET_TO_NOT_INIT( *(void**)pp, size );\r
3137 \r
3138         e=0;\r
3139 fin:\r
3140         return  e;\r
3141 }\r
3142 \r
3143 \r
3144 int  Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )\r
3145 {\r
3146         int    e;\r
3147         char*  p;\r
3148 \r
3149         e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;\r
3150         p = (char*) m->Next;\r
3151         m->Next = p + ElemsSize;\r
3152         *(char**)out_pElem = p;\r
3153 \r
3154         e=0;\r
3155 fin:\r
3156         return  e;\r
3157 }\r
3158 \r
3159 \r
3160  \r
3161 /***********************************************************************\r
3162   <<< [Set2_expandIfOverByAddr_imp] >>> \r
3163 ************************************************************************/\r
3164 int  Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )\r
3165 {\r
3166         void*     new_first;\r
3167         unsigned  offset_of_over;\r
3168         unsigned  offset_of_next;\r
3169 \r
3170         if ( OverAddrBasedOnNowFirst <= m->Over )  return  E_OTHERS;\r
3171 \r
3172         offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );\r
3173         offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;\r
3174         IF_D( offset_of_next >= 0x80000000 ) goto err;\r
3175         while ( offset_of_over < offset_of_next )  offset_of_over *= 2;\r
3176         IF( offset_of_over >= 0x10000000 ) goto err;\r
3177 \r
3178         new_first = realloc( m->First, offset_of_over * 2 );\r
3179         IF( new_first == NULL ) goto err_fm;\r
3180 \r
3181         m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );\r
3182         m->Over = (char*) new_first + offset_of_over * 2;\r
3183         m->First = new_first;\r
3184 \r
3185         #ifdef _DEBUG\r
3186         if ( m->PointerOfDebugArray != NULL )\r
3187                 { *m->PointerOfDebugArray = m->First; }\r
3188         #endif\r
3189 \r
3190         return  0;\r
3191 \r
3192 err:     return  E_OTHERS;\r
3193 err_fm:  return  E_FEW_MEMORY;\r
3194 }\r
3195 \r
3196  \r
3197 /***********************************************************************\r
3198   <<< [Set2_separate] >>> \r
3199 ************************************************************************/\r
3200 int  Set2_separate( Set2* m, int NextSize, void** allocate_Array )\r
3201 {\r
3202         int    e;\r
3203         void*  p = m->First;\r
3204 \r
3205         if ( NextSize == 0 ) {\r
3206                 MEMSET_TO_NOT_INIT( m, sizeof(*m) );\r
3207                 m->First = NULL;\r
3208         }\r
3209         else {\r
3210                 e= Set2_init( m, NextSize ); IF(e)goto fin;\r
3211         }\r
3212         *allocate_Array = p;\r
3213 \r
3214         e=0;\r
3215 fin:\r
3216         return  e;\r
3217 }\r
3218 \r
3219 \r
3220  \r
3221 /***********************************************************************\r
3222   <<< [Set2_setDebug] >>> \r
3223 ************************************************************************/\r
3224 #ifdef _DEBUG\r
3225 void  Set2_setDebug( Set2* m, void** PointerOfDebugArray )\r
3226 {\r
3227         m->PointerOfDebugArray = PointerOfDebugArray;\r
3228         *m->PointerOfDebugArray = m->First;\r
3229 }\r
3230 #endif\r
3231 \r
3232 \r
3233  \r
3234 /*=================================================================*/\r
3235 /* <<< [Print/Print2.c] >>> */ \r
3236 /*=================================================================*/\r
3237  \r
3238 /***********************************************************************\r
3239   <<< [PrintfCounterClass] >>> \r
3240 ************************************************************************/\r
3241 #if USE_PRINTF_COUNTER\r
3242         PrintfCounterClass  g_PrintfCounter;\r
3243 #endif\r
3244 \r
3245 \r
3246  \r
3247 /***********************************************************************\r
3248   <<< [printf_to_debugger] >>> \r
3249 ************************************************************************/\r
3250 #ifdef  _MSC_VER\r
3251 void  printf_to_debugger( const char* format, ... )\r
3252 {\r
3253   va_list  va;\r
3254   char     s[1024];\r
3255 \r
3256   va_start( va, format );\r
3257   vsprintf_r( s, sizeof(s), format, va );\r
3258   va_end( va );\r
3259 \r
3260   OutputDebugStringA( s );\r
3261 }\r
3262 #endif\r
3263 \r
3264 \r
3265  \r
3266 /***********************************************************************\r
3267   <<< [wprintf_to_debugger] >>> \r
3268 ************************************************************************/\r
3269 #ifdef  _MSC_VER\r
3270 void  wprintf_to_debugger( const wchar_t* format, ... )\r
3271 {\r
3272   va_list  va;\r
3273   wchar_t  s[1024];\r
3274 \r
3275   va_start( va, format );\r
3276   vswprintf_r( s, sizeof(s), format, va );\r
3277   va_end( va );\r
3278 \r
3279   OutputDebugStringW( s );\r
3280 }\r
3281 #endif\r
3282 \r
3283 \r
3284  \r
3285 /***********************************************************************\r
3286   <<< [vsprintf_r] >>> \r
3287 ************************************************************************/\r
3288 errnum_t  vsprintf_r( char* s, size_t s_size, const char* format, va_list va )\r
3289 {\r
3290         #if _MSC_VER\r
3291                 #pragma warning(push)\r
3292                 #pragma warning(disable: 4996)\r
3293         #endif\r
3294 \r
3295         int  r = _vsnprintf( s, s_size, format, va );\r
3296 \r
3297         #if _MSC_VER\r
3298                 #pragma warning(pop)\r
3299         #endif\r
3300 \r
3301         IF( r == (int) s_size )\r
3302                 { s[s_size-1] = '\0';  return E_FEW_ARRAY; }\r
3303         IF( r == -1 )\r
3304                 { return E_NOT_FOUND_SYMBOL; }  /* Bad character code */\r
3305 \r
3306         return  0;\r
3307 }\r
3308 \r
3309 \r
3310  \r
3311 /***********************************************************************\r
3312   <<< [vswprintf_r] >>> \r
3313 ************************************************************************/\r
3314 #ifndef  __linux__\r
3315 errnum_t  vswprintf_r( wchar_t* s, size_t s_size, const wchar_t* format, va_list va )\r
3316 {\r
3317         size_t  tsize = s_size / sizeof(wchar_t);\r
3318 \r
3319         #pragma warning(push)\r
3320         #pragma warning(disable: 4996)\r
3321                 int  r = _vsnwprintf( s, tsize, format, va );\r
3322         #pragma warning(pop)\r
3323 \r
3324         if ( r == (int) tsize || r == -1 ) { s[tsize-1] = '\0';  return E_FEW_ARRAY; }\r
3325         else  return  0;\r
3326 }\r
3327 #endif\r
3328 \r
3329 \r
3330  \r
3331 /***********************************************************************\r
3332   <<< [stprintf_r] >>> \r
3333 ************************************************************************/\r
3334 errnum_t  stprintf_r( TCHAR* s, size_t s_size, const TCHAR* format, ... )\r
3335 {\r
3336         errnum_t  e;\r
3337         va_list   va;\r
3338 \r
3339         va_start( va, format );\r
3340         e = vstprintf_r( s, s_size, format, va );\r
3341         va_end( va );\r
3342         return  e;\r
3343 }\r
3344 \r
3345 \r
3346  \r
3347 /***********************************************************************\r
3348   <<< [stcpy_part_r] >>> \r
3349 ************************************************************************/\r
3350 errnum_t  stcpy_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
3351                    const TCHAR* src, const TCHAR* src_over )\r
3352 {\r
3353         size_t  s_space = (char*)s + s_size - (char*)s_start;\r
3354         size_t  src_size;\r
3355 \r
3356         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size )  { return 1; }\r
3357 \r
3358         if ( src_over == NULL )  { src_over = _tcschr( src, _T('\0') ); }\r
3359         src_size = (char*)src_over - (char*)src;\r
3360         IF ( src_size >= s_space ) {\r
3361                 s_space -= sizeof(TCHAR);\r
3362                 memcpy( s, src, s_space );\r
3363 \r
3364                 s_start = (TCHAR*)((char*)s_start + s_space );\r
3365                 *s_start = '\0';\r
3366 \r
3367                 if ( p_s_last != NULL ) { *p_s_last=s_start; }\r
3368                 return  E_FEW_ARRAY;\r
3369         }\r
3370 \r
3371         memcpy( s_start, src, src_size + sizeof(TCHAR) );\r
3372         s_start = (TCHAR*)((char*)s_start + src_size);  *s_start = _T('\0');\r
3373         if ( p_s_last != NULL )  { *p_s_last = s_start; }\r
3374 \r
3375         return  0;\r
3376 }\r
3377 \r
3378 \r
3379  \r
3380 /***********************************************************************\r
3381   <<< [stprintf_part_r] >>> \r
3382 ************************************************************************/\r
3383 errnum_t  stprintf_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
3384                       const TCHAR* format, ... )\r
3385 {\r
3386         errnum_t  e;\r
3387         va_list   va;\r
3388         va_start( va, format );\r
3389 \r
3390         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) {return E_OTHERS;}\r
3391 \r
3392         e = vstprintf_r( s_start, s_size - ( (char*)s_start - (char*)s), format, va );\r
3393         va_end( va );  if ( p_s_last != NULL )  *p_s_last = _tcschr( s_start, '\0' );\r
3394         return  e;\r
3395 }\r
3396 \r
3397  \r
3398 /*=================================================================*/\r
3399 /* <<< [Error4/Error4.c] >>> */ \r
3400 /*=================================================================*/\r
3401  \r
3402 /***********************************************************************\r
3403   <<< [Get_Error4_Variables] >>> \r
3404 ************************************************************************/\r
3405 static Error4_VariablesClass  gs;\r
3406 #ifdef _DEBUG\r
3407         extern Error4_VariablesClass*  g_Error4_Variables = &gs;\r
3408 #endif\r
3409 \r
3410 Error4_VariablesClass*  Get_Error4_Variables()\r
3411 {\r
3412         return  &gs;\r
3413 }\r
3414 \r
3415 \r
3416  \r
3417 /***********************************************************************\r
3418   <<< [SetBreakErrorID] >>> \r
3419 ************************************************************************/\r
3420 #if ERR2_ENABLE_ERROR_BREAK\r
3421 \r
3422 dll_global_g_DebugBreakCount Err2  g_Err2;  /* \8f\89\8aú\92l\82Í\82·\82×\82Ä\83[\83\8d */\r
3423 \r
3424 void  SetBreakErrorID( int ID )\r
3425 {\r
3426         Err2*  m = &g_Err2;\r
3427 \r
3428         m->BreakErrID = ID;\r
3429 }\r
3430 \r
3431 \r
3432 int  TryOnIfTrue_imp( const char* FilePath, int LineNum )\r
3433  // \95Ô\82è\92l\82Í\81A\83u\83\8c\81[\83N\82·\82é\82©\82Ç\82¤\82©\r
3434 {\r
3435         //=== \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«\r
3436         if ( g_Err2.IsErr )  return  0;\r
3437 \r
3438 \r
3439         //=== \83G\83\89\81[\82ª\8f\89\82ß\82Ä\8bN\82«\82½\82Æ\82«\r
3440         else {\r
3441                 Err2*  m = &g_Err2;\r
3442 \r
3443                 m->IsErr = 1;\r
3444                 m->ErrID ++;\r
3445                 m->FilePath = FilePath;\r
3446                 m->LineNum = LineNum;\r
3447 \r
3448                 #if ERR2_ENABLE_ERROR_LOG\r
3449                         printf( "<ERRORLOG msg=\"raised\" err_id=\"%d\" g_err2=\"0x%08X\"/>\n", m->ErrID, (int) m );\r
3450                 #endif\r
3451 \r
3452                 return  ( m->ErrID == m->BreakErrID );\r
3453         }\r
3454 }\r
3455 \r
3456 \r
3457 //[ClearError]\r
3458 void  ClearError()\r
3459 {\r
3460         Err2*  m = &g_Err2;\r
3461 \r
3462         #if ERR2_ENABLE_ERROR_LOG\r
3463         if ( m->IsErr != 0 )\r
3464                 printf( "<ERRORLOG msg=\"cleared\" err_id=\"%d\" g_err2=\"0x%08X\"/>\n", m->ErrID, (int) m );\r
3465         #endif\r
3466 \r
3467         m->IsErr = 0;\r
3468 }\r
3469 \r
3470 \r
3471 //[IsErrorMode]\r
3472 bool  IsErrorMode()\r
3473 {\r
3474         return  ( g_Err2.IsErr != 0 );\r
3475 }\r
3476 \r
3477 \r
3478 //[IfErrThenBreak]\r
3479 void  IfErrThenBreak()\r
3480 {\r
3481         if ( g_Err2.IsErr && ( g_Err2.ErrID != g_Err2.BreakErrID || g_Err2.BreakErrID == 0 ) ) {  TestableDebugBreak();\r
3482                 // \83E\83H\83b\83`\82Å\81Ag_Err2.ErrID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
3483                 // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\r
3484                 // \83G\83\89\81[\82ª\94­\90\82µ\82½\8fê\8f\8a\82Í\81Ag_Err2.FilePath, g_Err2.LineNum \82Å\82·\81B\r
3485                 // \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
3486                 // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
3487                 #if ERR2_ENABLE_ERROR_LOG\r
3488                         printf( "<ERRORLOG msg=\"IfErrThenBreak\" ErrID=\"%d\" BreakErrID=\"%d\"/>\n", g_Err2.ErrID, g_Err2.BreakErrID );\r
3489                 #endif\r
3490 \r
3491                 {\r
3492                         char  str[512];\r
3493                         sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n", g_Err2.FilePath, g_Err2.LineNum );\r
3494                         OutputDebugStringA( str );\r
3495                 }\r
3496         }\r
3497         ClearError();\r
3498 }\r
3499 \r
3500 //[PushErr]\r
3501 void  PushErr( ErrStackAreaClass* ErrStackArea )\r
3502 {\r
3503         ErrStackArea->ErrID = g_Err2.ErrID;\r
3504         ErrStackArea->IsErr = g_Err2.IsErr;\r
3505         g_Err2.IsErr = 0;\r
3506 }\r
3507 \r
3508 //[PopErr]\r
3509 void  PopErr(  ErrStackAreaClass* ErrStackArea )\r
3510 {\r
3511         if ( ErrStackArea->IsErr )\r
3512                 g_Err2.IsErr = 1;\r
3513 }\r
3514 \r
3515 \r
3516 #endif // ERR2_ENABLE_ERROR_BREAK\r
3517 \r
3518  \r
3519 /***********************************************************************\r
3520   <<< [g_Error4_String] >>> \r
3521 ************************************************************************/\r
3522 TCHAR  g_Error4_String[4096];\r
3523 \r
3524 \r
3525  \r
3526 /***********************************************************************\r
3527   <<< [Error4_printf] >>> \r
3528 ************************************************************************/\r
3529 void  Error4_printf( const TCHAR* format, ... )\r
3530 {\r
3531         va_list  va;\r
3532         va_start( va, format );\r
3533         vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );\r
3534         va_end( va );\r
3535 }\r
3536 \r
3537 \r
3538  \r
3539 /***********************************************************************\r
3540   <<< [Error4_getErrStr] >>> \r
3541 ************************************************************************/\r
3542 void  Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )\r
3543 {\r
3544         switch ( ErrNum ) {\r
3545 \r
3546                 case  0:\r
3547                         stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );\r
3548                         break;\r
3549 \r
3550                 #ifndef  __linux__\r
3551                 case  E_GET_LAST_ERROR: {\r
3552                         DWORD   err_win;\r
3553                         TCHAR*  str_pointer;\r
3554 \r
3555                         err_win = gs.WindowsLastError;\r
3556                         if ( err_win == 0 ) { err_win = GetLastError(); }\r
3557 \r
3558                         stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,\r
3559                                 _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );\r
3560                         FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,\r
3561                                 NULL, err_win, LANG_USER_DEFAULT,\r
3562                                 str_pointer,  (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );\r
3563                         str_pointer = _tcschr( str_pointer, _T('\0') );\r
3564                         if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )\r
3565                                 str_pointer -= 2;\r
3566                         stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );\r
3567                         break;\r
3568                 }\r
3569                 #endif\r
3570 \r
3571                 default:\r
3572                         if ( g_Error4_String[0] != '\0' )\r
3573                                 stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );\r
3574                         else\r
3575                                 stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );\r
3576                         break;\r
3577         }\r
3578 }\r
3579 \r
3580 \r
3581  \r
3582 /***********************************************************************\r
3583   <<< [SaveWindowsLastError] >>> \r
3584 ************************************************************************/\r
3585 errnum_t  SaveWindowsLastError()\r
3586 {\r
3587         gs.WindowsLastError = GetLastError();\r
3588         return  E_GET_LAST_ERROR;\r
3589 }\r
3590 \r
3591 \r
3592  \r
3593 /*=================================================================*/\r
3594 /* <<< [DebugTools/DebugTools.c] >>> */ \r
3595 /*=================================================================*/\r
3596  \r
3597 /***********************************************************************\r
3598   <<< [TestableDebugBreak] >>> \r
3599 ************************************************************************/\r
3600 dll_global_g_DebugBreakCount int  g_bTestableDebugBreak_Disable;\r
3601 dll_global_g_DebugBreakCount int  g_DebugBreakCount;\r
3602 \r
3603 \r
3604  \r
3605 /***********************************************************************\r
3606   <<< [TestableDebugBreak_isEnabled] >>> \r
3607 ************************************************************************/\r
3608 int  TestableDebugBreak_isEnabled()\r
3609 {\r
3610         return  g_bTestableDebugBreak_Disable == 0;\r
3611 }\r
3612 \r
3613 \r
3614  \r