OSDN Git Service

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