OSDN Git Service

Version 4.01
[vbslib/main.git] / _src / Test / tools / feq / clib.c
1 /* The source file was composed by module mixer */ \r
2 \r
3 #include  "include_c.h"\r
4 \r
5 \r
6  \r
7 /*=================================================================*/\r
8 /* <<< [Global0/Global0.c] >>> */ \r
9 /*=================================================================*/\r
10  \r
11 /***********************************************************************\r
12   <<< [Globals_initConst] >>> \r
13 ************************************************************************/\r
14 \r
15 void  Globals_initConst()\r
16 {\r
17 }\r
18 \r
19 \r
20  \r
21 /***********************************************************************\r
22   <<< [Globals_init] >>> \r
23 ************************************************************************/\r
24 int  Globals_init()\r
25 {\r
26   int  e;\r
27 \r
28     e= Locale_init(); IF(e)goto fin;\r
29 \r
30   e=0;\r
31   goto fin;  // for avoid warning of no goto fin\r
32 fin:\r
33   return  e;\r
34 }\r
35 \r
36 \r
37  \r
38 /***********************************************************************\r
39   <<< [Globals_finish] >>> \r
40 ************************************************************************/\r
41 int  Globals_finish( int e )\r
42 {\r
43 \r
44   return  e;\r
45 }\r
46 \r
47 \r
48  \r
49 /*=================================================================*/\r
50 /* <<< [PlatformSDK_plus/PlatformSDK_plus.c] >>> */ \r
51 /*=================================================================*/\r
52  \r
53 /***********************************************************************\r
54   <<< [GetCommandLineUnnamed] >>> \r
55 ************************************************************************/\r
56 int  GetCommandLineUnnamed( int Index1, TCHAR* out_AParam, size_t AParamSize )\r
57 {\r
58   TCHAR*  line = GetCommandLine();\r
59   int     index;\r
60   TCHAR*  p;\r
61   TCHAR*  p2;\r
62   TCHAR   c;\r
63 \r
64   #if UNDER_CE\r
65     Index1 --;\r
66   #endif\r
67   IF( Index1 < 0 ) goto err_nf;\r
68   index = Index1;\r
69 \r
70   p = line;\r
71 \r
72   for (;;) {\r
73     while ( *p == _T(' ') )  p++;\r
74 \r
75     c = *p;\r
76 \r
77     if ( c == _T('\0') )  goto err_nf;  // Here is not decided to error or not\r
78 \r
79 \r
80     //=== Skip named option\r
81     else if ( c == _T('/') ) {\r
82       p++;\r
83       for (;;) {\r
84         c = *p;\r
85         if ( c == _T('"') || c == _T(' ') || c == _T('\0') )  break;\r
86         p++;\r
87       }\r
88 \r
89       if ( c == _T('"') ) {\r
90         p++;\r
91         while ( *p != _T('"') && *p != _T('\0') )  p++;\r
92         if ( *p == _T('"') )  p++;\r
93       }\r
94     }\r
95 \r
96     //=== Skip or Get unnamed parameter\r
97     else {\r
98       while ( *p == _T(' ') )  p++;\r
99 \r
100       c = *p;\r
101       p2 = p + 1;\r
102 \r
103       if ( c == _T('"') ) {\r
104         p ++;\r
105         while ( *p2 != _T('"') && *p2 != _T('\0') )  p2++;\r
106       }\r
107       else {\r
108         while ( *p2 != _T(' ') && *p2 != _T('\0') )  p2++;\r
109       }\r
110 \r
111       if ( index == 0 ) {\r
112         int  e;\r
113 \r
114         e= stcpy_part_r( out_AParam, AParamSize, out_AParam, NULL, p, p2 );\r
115           ASSERT_D( !e, __noop() );\r
116         return  e;\r
117       }\r
118       else {\r
119         p = ( *p2 == _T('"') ) ? p2+1 : p2;\r
120         index --;\r
121       }\r
122     }\r
123   }\r
124 \r
125 err_nf:\r
126   if ( AParamSize >= sizeof(TCHAR) )  *out_AParam = _T('\0');\r
127   IF ( Index1 >= 2 )  return  E_NOT_FOUND_SYMBOL;\r
128   return  0;\r
129 }\r
130 \r
131 \r
132  \r
133 /***********************************************************************\r
134   <<< [GetCommandLineNamed] >>> \r
135 ************************************************************************/\r
136 int  GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize );\r
137 \r
138 int  GetCommandLineNamed( const TCHAR* Name, bool bCase, TCHAR* out_Value, size_t ValueSize )\r
139 {\r
140   bool  is_exist;\r
141   return  GetCommandLineNamed_sub( Name, bCase, &is_exist, out_Value, ValueSize );\r
142 }\r
143 \r
144 \r
145 int  GetCommandLineNamed_sub( const TCHAR* Name, bool bCase, bool* out_IsExist, TCHAR* out_Value, size_t ValueSize )\r
146 {\r
147   TCHAR*  line = GetCommandLine();\r
148   TCHAR*  p;\r
149   TCHAR*  p2;\r
150   TCHAR   c;\r
151   const size_t  name_len = _tcslen( Name );\r
152   bool    bMatch;\r
153 \r
154   *out_IsExist = true;\r
155 \r
156   p = line;\r
157   for (;;) {\r
158     c = *p;\r
159 \r
160     //=== Compare option name\r
161     if ( c == _T('/') ) {\r
162       p++;\r
163       p2 = p;\r
164       for (;;) {\r
165         c = *p2;\r
166         if ( c == _T(':') || c == _T(' ') || c == _T('\0') )  break;\r
167         p2++;\r
168       }\r
169       if ( bCase )\r
170         bMatch = ( p2-p == (int)name_len && _tcsncmp( p, Name, p2-p ) == 0 );\r
171       else\r
172         bMatch = ( p2-p == (int)name_len && _tcsnicmp( p, Name, p2-p ) == 0 );\r
173 \r
174 \r
175       //=== Get the value\r
176       if ( c == _T(':') ) {\r
177         p = p2 + 1;\r
178         if ( *p == _T('"') ) {\r
179           p++;\r
180           p2 = p;\r
181           while ( *p2 != _T('"') && *p2 != _T('\0') )  p2++;\r
182           if ( bMatch )\r
183             return  stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );\r
184           else\r
185             p = p2+1;\r
186         }\r
187         else {\r
188           p2 = p;\r
189           while ( *p2 != _T(' ') && *p2 != _T('\0') )  p2++;\r
190           if ( bMatch )\r
191             return  stcpy_part_r( out_Value, ValueSize, out_Value, NULL, p, p2 );\r
192           else\r
193             p = p2;\r
194         }\r
195       }\r
196       else {\r
197         IF( bMatch ) return  E_NOT_FOUND_SYMBOL;  // no value error\r
198       }\r
199     }\r
200 \r
201     else if ( c == _T('\0') )  break;\r
202 \r
203     //=== Skip\r
204     else if ( c == _T('"') ) {\r
205       p++;\r
206       while ( *p != _T('"') && *p != _T('\0') )  p++;\r
207       while ( *p != _T(' ') && *p != _T('\0') )  p++;\r
208     }\r
209     else {\r
210       while ( *p != _T(' ') && *p != _T('\0') )  p++;\r
211     }\r
212     while ( *p == _T(' ') )  p++;\r
213   }\r
214 \r
215   *out_IsExist = false;\r
216   return  E_NOT_FOUND_SYMBOL;\r
217 }\r
218 \r
219 \r
220  \r
221 /***********************************************************************\r
222   <<< [GetCommandLineNamedI] >>> \r
223 ************************************************************************/\r
224 int  GetCommandLineNamedI( const TCHAR* Name, bool bCase, int* out_Value )\r
225 {\r
226   int    e;\r
227   bool   is_exist;\r
228   TCHAR  s[20];\r
229 \r
230   e= GetCommandLineNamed_sub( Name, bCase, &is_exist, s, sizeof(s) ); IF(e)goto fin;  //[out] s\r
231   if ( s[0] == _T('0') && s[1] == _T('x') )\r
232     *out_Value = _tcstoul( s, NULL, 16 );\r
233   else\r
234     *out_Value = _ttoi( s );\r
235   //e=0;\r
236 fin:\r
237   return  e;\r
238 }\r
239 \r
240 \r
241  \r
242 /***********************************************************************\r
243   <<< [GetCommandLineNamedC8] >>> \r
244 ************************************************************************/\r
245 #if  _UNICODE\r
246 int  GetCommandLineNamedC8( const TCHAR* Name, bool bCase, char* out_Value, size_t ValueSize )\r
247 {\r
248   int     e;\r
249   bool    is_exist;\r
250   TCHAR*  s = NULL;\r
251 \r
252   s = (TCHAR*) malloc( ValueSize * sizeof(TCHAR) );\r
253   e= GetCommandLineNamed_sub( Name, bCase, &is_exist, (TCHAR*) s, ValueSize * sizeof(TCHAR) ); IF(e)goto fin;\r
254 \r
255   sprintf_s( out_Value, ValueSize, "%S", s );\r
256 fin:\r
257   if ( s != NULL )  free( s );\r
258   return  e;\r
259 }\r
260 #endif\r
261 \r
262 \r
263  \r
264 /***********************************************************************\r
265   <<< [GetCommandLineExist] >>> \r
266 ************************************************************************/\r
267 bool  GetCommandLineExist( const TCHAR* Name, bool bCase )\r
268 {\r
269   int     e;\r
270   bool    is_exist;\r
271   TCHAR   v[1];\r
272 \r
273   e = GetCommandLineNamed_sub( Name, bCase, &is_exist, v, sizeof(v) );\r
274   if ( e == E_NOT_FOUND_SYMBOL )  ClearError();\r
275   return  is_exist;\r
276 }\r
277 \r
278 \r
279  \r
280 /*=================================================================*/\r
281 /* <<< [Locale/Locale.c] >>> */ \r
282 /*=================================================================*/\r
283  \r
284 /***********************************************************************\r
285   <<< [g_LocaleSymbol] >>> \r
286 ************************************************************************/\r
287 char*  g_LocaleSymbol = "";\r
288 \r
289 \r
290  \r
291 /***********************************************************************\r
292   <<< [Locale_init] >>> \r
293 ************************************************************************/\r
294 int  Locale_init()\r
295 {\r
296   g_LocaleSymbol = ".OCP";\r
297   setlocale( LC_ALL, ".OCP" );\r
298   return  0;\r
299 }\r
300 \r
301  \r
302 /***********************************************************************\r
303   <<< [Locale_isInited] >>> \r
304 ************************************************************************/\r
305 int  Locale_isInited()\r
306 {\r
307   return  ( g_LocaleSymbol[0] != '\0' );\r
308    // \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
309 }\r
310 \r
311  \r
312 /*=================================================================*/\r
313 /* <<< [FileT/FileT.c] >>> */ \r
314 /*=================================================================*/\r
315  \r
316 /***********************************************************************\r
317   <<< [FileT_isExist] >>> \r
318 ************************************************************************/\r
319 bool  FileT_isExist( const TCHAR* path )\r
320 {\r
321  #if ! FileT_isExistWildcard\r
322 \r
323         DWORD  r;\r
324 \r
325         if ( path[0] == _T('\0') )  return  false;\r
326         r = GetFileAttributes( path );\r
327         return  r != (DWORD)-1;\r
328 \r
329  #else\r
330 \r
331         HANDLE  find;\r
332         WIN32_FIND_DATA  data;\r
333 \r
334         find = FindFirstFileEx( path, FindExInfoStandard, &data,\r
335                 FindExSearchNameMatch, NULL, 0 );\r
336 \r
337         if ( find == INVALID_HANDLE_VALUE ) {\r
338                 return  false;\r
339         }\r
340         else {\r
341                 FindClose( find );\r
342                 return  true;\r
343         }\r
344 \r
345  #endif\r
346 }\r
347 \r
348 \r
349  \r
350 /***********************************************************************\r
351   <<< [FileT_isFile] >>> \r
352 ************************************************************************/\r
353 bool  FileT_isFile( const TCHAR* path )\r
354 {\r
355         DWORD  r = GetFileAttributes( path );\r
356         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == 0;\r
357                 // 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
358 }\r
359 \r
360 \r
361  \r
362 /***********************************************************************\r
363   <<< [FileT_isDir] >>> \r
364 ************************************************************************/\r
365 bool  FileT_isDir( const TCHAR* path )\r
366 {\r
367         DWORD  r = GetFileAttributes( path );\r
368         return  ( r & (FILE_ATTRIBUTE_DIRECTORY | 0x80000000) ) == FILE_ATTRIBUTE_DIRECTORY;\r
369                 // 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
370 }\r
371 \r
372 \r
373  \r
374 /***********************************************************************\r
375   <<< [FileT_isDiff] >>> \r
376 ************************************************************************/\r
377 int  FileT_isDiff( const TCHAR* Path1, const TCHAR* Path2, bool* bDiff )\r
378 {\r
379         int    e;\r
380         bool   b;\r
381         FILE*  f1 = NULL;\r
382         FILE*  f2 = NULL;\r
383         char*  buf1 = NULL;\r
384         char*  buf2 = NULL;\r
385         errno_t  en;\r
386 \r
387 \r
388         //=== Open files\r
389         en= _tfopen_s( &f1, Path1, _T("r") );\r
390         if ( en == ENOENT )  { f1 = NULL; en = 0; }\r
391         IF(en)goto err_no;\r
392 \r
393         en= _tfopen_s( &f2, Path2, _T("r") );\r
394         if ( en == ENOENT )  { f2 = NULL; en = 0; }\r
395         IF(en)goto err_no;\r
396 \r
397 \r
398         //=== Whether exists or not\r
399         if ( f1 == NULL ) {\r
400                 if ( f2 == NULL )  { *bDiff = false; e=0; goto fin; }\r
401                 else  { *bDiff = true; e=0; goto fin; }\r
402         }\r
403         else {\r
404                 if ( f2 == NULL )  { *bDiff = true; e=0; goto fin; }\r
405         }\r
406 \r
407 \r
408         //=== Compare the contents in files\r
409         {\r
410                 enum { size = 0x100000 };\r
411                 size_t  size1, size2;\r
412 \r
413                 buf1 = (char*) malloc( size ); IF(buf1==NULL)goto err_fm;\r
414                 buf2 = (char*) malloc( size ); IF(buf2==NULL)goto err_fm;\r
415 \r
416                 b = true;\r
417                 for (;;) {\r
418                         size1 = fread( buf1, 1, size, f1 );\r
419                         size2 = fread( buf2, 1, size, f2 );\r
420 \r
421                         if ( size1 != size2 )  break;\r
422                         if ( memcmp( buf1, buf2, size1 ) != 0 )  break;\r
423                         if ( size1 != size )  { b = false; break; }\r
424                 }\r
425                 *bDiff = b;\r
426         }\r
427 \r
428         e=0;\r
429 fin:\r
430         if ( buf1 !=NULL)free(buf1);\r
431         if ( buf2 !=NULL)free(buf2);\r
432         if( f1 !=NULL){en=fclose(f1);IF(en)b=true;}\r
433         if( f2 !=NULL){en=fclose(f2);IF(en)b=true;}\r
434         return  e;\r
435 err_no: e = E_ERRNO; goto fin;\r
436 err_fm: e = E_FEW_MEMORY; goto fin;\r
437 }\r
438 \r
439  \r
440 /***********************************************************************\r
441   <<< [FileT_isSameText] >>> \r
442 ************************************************************************/\r
443 int  FileT_isSameText( TCHAR* Path1, TCHAR* Path2, int Format1, int Format2, bool* out_bSame )\r
444 {\r
445         int    e;\r
446         FILE*  f1 = NULL;\r
447         FILE*  f2 = NULL;\r
448         TCHAR  line1[4096];\r
449         TCHAR  line2[4096];\r
450 \r
451         ASSERT_R( Format1 == 0, goto err );\r
452         ASSERT_R( Format2 == 0, goto err );\r
453 \r
454         e= FileT_openForRead( &f1, Path1 ); IF(e)goto fin;\r
455         e= FileT_openForRead( &f2, Path2 ); IF(e)goto fin;\r
456         for (;;) {\r
457                 line1[0] = _T('\0');\r
458                 line2[0] = _T('\0');\r
459                 _fgetts( line1, _countof(line1), f1 );\r
460                 _fgetts( line2, _countof(line2), f2 );\r
461                 if ( _tcscmp( line1, line2 ) != 0 ) {\r
462                         *out_bSame = false;  e=0;  goto fin;\r
463                 }\r
464                 if ( feof( f1 ) ) {\r
465                         if ( feof( f2 ) )  break;\r
466                         else {\r
467                                 *out_bSame = false;  e=0;  goto fin;\r
468                         }\r
469                 }\r
470         }\r
471         *out_bSame = true;\r
472 \r
473         e=0;\r
474 fin:\r
475         e= FileT_close( f1, e );\r
476         e= FileT_close( f2, e );\r
477         return  e;\r
478 \r
479 err:  e = E_OTHERS;  goto fin;\r
480 }\r
481 \r
482 \r
483  \r
484 /***********************************************************************\r
485   <<< [FileT_isSameBinaryFile] >>> \r
486 ************************************************************************/\r
487 int  FileT_isSameBinaryFile( const TCHAR* PathA, const TCHAR* PathB, int Flags, bool* out_IsSame )\r
488 {\r
489         int       e;\r
490         HANDLE    file_a = INVALID_HANDLE_VALUE;\r
491         HANDLE    file_b = INVALID_HANDLE_VALUE;\r
492         HANDLE    mem_a  = INVALID_HANDLE_VALUE;\r
493         HANDLE    mem_b  = INVALID_HANDLE_VALUE;\r
494         void*     ptr_a = NULL;\r
495         void*     ptr_b = NULL;\r
496         size_t    size_a;\r
497         size_t    size_b;\r
498         BOOL      b;\r
499         bool      is_same = false;\r
500 \r
501         UNREFERENCED_VARIABLES(( Flags ));\r
502 \r
503 \r
504         // file_a,  file_b : open PathA,  PathB\r
505         file_a = CreateFile( PathA, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
506                                                                                          FILE_ATTRIBUTE_NORMAL, 0 );\r
507         IF( file_a == INVALID_HANDLE_VALUE ) goto err_gt;\r
508 \r
509         file_b = CreateFile( PathB, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
510                                                                                          FILE_ATTRIBUTE_NORMAL, 0 );\r
511         IF( file_b == INVALID_HANDLE_VALUE ) goto err_gt;\r
512 \r
513         // size_a,  size_b : size of file_a, file_b\r
514         size_a = GetFileSize( file_a, NULL );\r
515         size_b = GetFileSize( file_b, NULL );\r
516 \r
517         if ( size_a == size_b  &&  size_a == 0 ) {\r
518                 is_same = true;\r
519         }\r
520         else if ( size_a == size_b ) {\r
521 \r
522                 // mem_a,  mem_b : map to memory from file_a,  file_b\r
523                 mem_a = CreateFileMapping( file_a, NULL, PAGE_READONLY, 0, size_a, NULL );\r
524                 IF( mem_a == INVALID_HANDLE_VALUE ) goto err_gt;\r
525                 mem_b = CreateFileMapping( file_b, NULL, PAGE_READONLY, 0, size_b, NULL );\r
526                 IF( mem_b == INVALID_HANDLE_VALUE ) goto err_gt;\r
527 \r
528                 // ptr_a,  ptr_b : pointer of contents in file_a, file_b\r
529                 ptr_a = MapViewOfFile( mem_a, FILE_MAP_READ, 0, 0, 0 ); IF(ptr_a==NULL)goto err_gt;\r
530                 ptr_b = MapViewOfFile( mem_b, FILE_MAP_READ, 0, 0, 0 ); IF(ptr_b==NULL)goto err_gt;\r
531 \r
532                 // is_same : is same file_a and file_b\r
533                 if ( memcmp( ptr_a, ptr_b, size_a ) == 0 )  is_same = true;\r
534         }\r
535         e=0;\r
536 fin:\r
537         if ( ptr_a != NULL )                  { b= UnmapViewOfFile( ptr_a ); IF(!b&&!e) e=SaveWindowsLastError(); }\r
538         if ( mem_a  != INVALID_HANDLE_VALUE ) { b= CloseHandle( mem_a );     IF(!b&&!e) e=SaveWindowsLastError(); }\r
539         if ( file_a != INVALID_HANDLE_VALUE ) { b= CloseHandle( file_a );    IF(!b&&!e) e=SaveWindowsLastError(); }\r
540         if ( ptr_b != NULL )                  { b= UnmapViewOfFile( ptr_b ); IF(!b&&!e) e=SaveWindowsLastError(); }\r
541         if ( mem_b  != INVALID_HANDLE_VALUE ) { b= CloseHandle( mem_b );     IF(!b&&!e) e=SaveWindowsLastError(); }\r
542         if ( file_b != INVALID_HANDLE_VALUE ) { b= CloseHandle( file_b );    IF(!b&&!e) e=SaveWindowsLastError(); }\r
543         *out_IsSame = is_same;\r
544         return  e;\r
545 \r
546 err_gt:  e = SaveWindowsLastError();  goto fin;\r
547 }\r
548 \r
549 \r
550  \r
551 /***********************************************************************\r
552   <<< [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
553 ************************************************************************/\r
554 typedef struct {\r
555         /*--- inherit from FileT_CallByNestFindData */\r
556         void*     CallerArgument;\r
557         TCHAR*    AbsPath;  // abstruct path\r
558         TCHAR*    StepPath;\r
559         TCHAR*    FileName;\r
560         DWORD     FileAttributes;\r
561 \r
562         /*---*/\r
563         BitField  Flags;\r
564         FuncType  CallbackFromNestFind;\r
565         TCHAR     AbsPathMem[4096];\r
566 } FileT_CallByNestFindDataIn;\r
567 \r
568 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m );\r
569 \r
570 \r
571 int  FileT_callByNestFind( const TCHAR* Path, BitField Flags, void* Argument, FuncType Callback )\r
572 {\r
573         int  e;\r
574         FileT_CallByNestFindDataIn  data;\r
575 \r
576         {\r
577                 TCHAR*  p;\r
578 \r
579                 e= StrT_cpy( data.AbsPathMem, sizeof(data.AbsPathMem), Path ); IF(e)goto fin;\r
580 \r
581 \r
582                 /* AbsPathMem \82Ì\8dÅ\8cã\82É \ \82ª\96³\82¢\82È\82ç\92Ç\89Á\82·\82é */\r
583                 p = _tcschr( data.AbsPathMem, _T('\0') );\r
584                 p--;\r
585                 if ( *p != _T('\\') ) {\r
586                         p++;\r
587                         IF( p >= data.AbsPathMem + (sizeof(data.AbsPathMem) / sizeof(TCHAR)) - 1 )goto err_fa;\r
588                         *p = _T('\\');\r
589                 }\r
590 \r
591 \r
592                 /* data \82ð\8f\89\8aú\89»\82·\82é */\r
593                 data.CallerArgument = Argument;\r
594                 data.AbsPath = data.AbsPathMem;\r
595                 data.StepPath = p + 1;\r
596                 data.FileName = p + 1;\r
597                 data.Flags = Flags;\r
598                 data.CallbackFromNestFind = Callback;\r
599         }\r
600 \r
601         /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ\8aÖ\90\94\82Ö */\r
602         e= FileT_callByNestFind_sub( &data ); IF(e)goto fin;\r
603 \r
604         e=0;\r
605 fin:\r
606         return  e;\r
607 err_fa: e= E_FEW_ARRAY; goto fin;\r
608 }\r
609 \r
610 \r
611 int  FileT_callByNestFind_sub( FileT_CallByNestFindDataIn* m )\r
612 {\r
613         int  e;\r
614         HANDLE  find;\r
615         WIN32_FIND_DATA  data;\r
616         TCHAR*  p;\r
617         int  done;\r
618 \r
619 \r
620         /* 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
621         if ( m->Flags & FileT_FolderBeforeFiles ) {\r
622                 *( m->FileName - 1 ) = _T('\0');  // m->AbsPath \82Ì\8dÅ\8cã\82Ì \ \82ð\88ê\8e\9e\93I\82É\83J\83b\83g\r
623                 *( m->FileName ) = _T('\0');  // m->FileName, m->StepPath \82ð "" \82É\82·\82é\r
624                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
625 \r
626                 if ( m->StepPath[0] == _T('\0') ) {\r
627                         TCHAR*  step_path = m->StepPath;\r
628                         TCHAR*  fname     = m->FileName;\r
629 \r
630                         m->StepPath = _T(".");\r
631                         m->FileName = StrT_refFName( m->AbsPath );\r
632                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
633                         m->StepPath = step_path;\r
634                         m->FileName = fname;\r
635                 }\r
636                 else if ( m->FileName[0] == _T('\0') ) {\r
637                         TCHAR*  fname = m->FileName;\r
638 \r
639                         m->FileName = StrT_refFName( m->AbsPath );\r
640                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
641                         m->FileName = fname;\r
642                 }\r
643                 else {\r
644                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
645                 }\r
646                 *( m->FileName - 1 ) = _T('\\');\r
647         }\r
648 \r
649 \r
650         /* * \82ð\92Ç\89Á */\r
651         p = m->FileName;\r
652         IF( p >= m->AbsPathMem + (sizeof(m->AbsPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
653         *p = _T('*');  *(p+1) = _T('\0');\r
654 \r
655 \r
656         /* \83t\83@\83C\83\8b\82©\83t\83H\83\8b\83_\82ð\97ñ\8b\93\82µ\82Ü\82· */\r
657         find = FindFirstFileEx( m->AbsPathMem, FindExInfoStandard, &data,\r
658                 FindExSearchNameMatch, NULL, 0 );\r
659         done = ( find == INVALID_HANDLE_VALUE );\r
660 \r
661         while (!done)\r
662         {\r
663                 if ( _tcscmp( data.cFileName, _T(".") ) == 0 ||\r
664                                  _tcscmp( data.cFileName, _T("..") ) == 0 ) {\r
665                         done = ! FindNextFile( find, &data );\r
666                         continue;\r
667                 }\r
668 \r
669                 StrT_cpy( m->FileName,\r
670                         sizeof(m->AbsPathMem) - ( (char*)m->FileName - (char*)m->AbsPathMem ),\r
671                         data.cFileName );\r
672                 m->FileAttributes = data.dwFileAttributes;\r
673 \r
674                 if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {\r
675                         TCHAR*  prev_fname = m->FileName;\r
676 \r
677                         p = _tcschr( m->FileName, _T('\0') );\r
678 \r
679                         IF( p >= m->AbsPathMem + (sizeof(m->AbsPathMem) / sizeof(TCHAR)) - 2 )goto err_fa;\r
680                         *p = _T('\\');  *(p+1) = _T('\0');\r
681                         m->FileName = p + 1;\r
682 \r
683                         e= FileT_callByNestFind_sub( m ); IF(e)goto fin;  /* \8dÄ\8bN\8cÄ\82Ñ\8fo\82µ */\r
684 \r
685                         m->FileName = prev_fname;\r
686                 }\r
687                 else {\r
688                         e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
689                 }\r
690 \r
691                 done = ! FindNextFile( find, &data );\r
692         }\r
693         FindClose( find );\r
694 \r
695 \r
696         /* 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
697         if ( m->Flags & FileT_FolderAfterFiles ) {\r
698                 TCHAR*  step_path = m->StepPath;\r
699                 TCHAR*  fname     = m->FileName;\r
700 \r
701                 *( m->FileName - 1 ) = _T('\0');\r
702                 m->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;\r
703                 if ( ( *( m->StepPath - 1 ) == _T('\0') ) && ( m->StepPath > m->AbsPath ) ) {\r
704                         m->StepPath = _T(".");\r
705                 }\r
706                 m->FileName = StrT_refFName( m->AbsPath );\r
707 \r
708                 e= m->CallbackFromNestFind( m ); IF(e)goto fin;\r
709 \r
710                 m->StepPath = step_path;\r
711                 m->FileName = fname;\r
712         }\r
713 \r
714         e=0;\r
715 fin:\r
716         return  e;\r
717 err_fa: e= E_FEW_ARRAY; goto fin;\r
718 }\r
719 \r
720 \r
721  \r
722 /***********************************************************************\r
723   <<< [FileT_openForRead] >>> \r
724 ************************************************************************/\r
725 int  FileT_openForRead( FILE** out_pFile, const TCHAR* Path )\r
726 {\r
727         errno_t  en;\r
728 \r
729         assert( Locale_isInited() );\r
730 \r
731         #if DEBUGTOOLS_USES\r
732                 { int e= Debug_onOpen( Path ); if(e) return e; }\r
733         #endif\r
734 \r
735         en = _tfopen_s( out_pFile, Path, _T("r")_T(fopen_ccs) );\r
736         if ( en == ENOENT ) {\r
737                 _tprintf( _T("not found \"%s\"\n"), Path );\r
738 \r
739                 #ifndef UNDER_CE\r
740                 {\r
741                         TCHAR  cwd[512];\r
742 \r
743                         if ( _tgetcwd( cwd, _countof(cwd) ) != NULL )\r
744                                 _tprintf( _T("current = \"%s\"\n"), cwd );\r
745                 }\r
746                 #endif\r
747 \r
748                 return  E_NOT_FOUND_SYMBOL;\r
749         }\r
750         if ( en == EACCES ) {\r
751                 _tprintf( _T("access denied \"%s\"\n"), Path );\r
752                 return  E_ACCESS_DENIED;\r
753         }\r
754         IF(en)return  E_OTHERS;\r
755 \r
756         return  0;\r
757 }\r
758 \r
759 \r
760  \r
761 /***********************************************************************\r
762   <<< [FileT_close] >>> \r
763 ************************************************************************/\r
764 int  FileT_close( FILE* File, int e )\r
765 {\r
766         if ( File != NULL ) {\r
767                 int r = fclose( File );\r
768                 IF(r&&!e)e=E_ERRNO;\r
769         }\r
770         return e;\r
771 }\r
772 \r
773 \r
774 \r
775  \r
776 /*=================================================================*/\r
777 /* <<< [StrT/StrT.c] >>> */ \r
778 /*=================================================================*/\r
779  \r
780 /***********************************************************************\r
781   <<< [StrT_cpy] >>> \r
782 - _tcscpy is raising exception, if E_FEW_ARRAY\r
783 ************************************************************************/\r
784 errnum_t  StrT_cpy( TCHAR* Dst, size_t DstSize, const TCHAR* Src )\r
785 {\r
786         size_t  size;\r
787 \r
788         size = ( _tcslen( Src ) + 1 ) * sizeof(TCHAR);\r
789         if ( size <= DstSize ) {\r
790                 memcpy( Dst, Src, size );\r
791                 return  0;\r
792         }\r
793         else {\r
794                 memcpy( Dst, Src, DstSize - sizeof(TCHAR) );\r
795                 *(TCHAR*)( (char*) Dst + DstSize ) = _T('\0');\r
796                 return  E_FEW_ARRAY;\r
797         }\r
798 }\r
799 \r
800  \r
801 /***********************************************************************\r
802   <<< [MallocAndCopyString] >>> \r
803 ************************************************************************/\r
804 errnum_t  MallocAndCopyString( TCHAR** out_NewString, const TCHAR* SourceString )\r
805 {\r
806         TCHAR*  str;\r
807         size_t  size = ( _tcslen( SourceString ) + 1 ) * sizeof(TCHAR);\r
808 \r
809         ASSERT_D( *out_NewString == NULL, __noop() );\r
810 \r
811         str = (TCHAR*) malloc( size );\r
812         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
813 \r
814         memcpy( str, SourceString, size );\r
815 \r
816         *out_NewString = str;\r
817         return  0;\r
818 }\r
819 \r
820 \r
821  \r
822 /***********************************************************************\r
823   <<< [MallocAndCopyString_char] >>> \r
824 ************************************************************************/\r
825 #ifdef _UNICODE\r
826 errnum_t  MallocAndCopyString_char( TCHAR** out_NewString, const char* SourceString )\r
827 {\r
828         TCHAR*  str;\r
829         size_t  size = ( strlen( SourceString ) + 1 ) * sizeof(TCHAR);\r
830         int     r;\r
831 \r
832         str = (TCHAR*) malloc( size );\r
833         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
834 \r
835         r = MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED, SourceString, -1, str, size / sizeof(TCHAR) );\r
836         IF ( r == 0 ) {\r
837                 free( str );\r
838                 return  E_GET_LAST_ERROR;\r
839         }\r
840         *out_NewString = str;\r
841         return  0;\r
842 }\r
843 #endif\r
844 \r
845 \r
846  \r
847 /***********************************************************************\r
848   <<< [MallocAndCopyStringByLength] >>> \r
849 ************************************************************************/\r
850 errnum_t  MallocAndCopyStringByLength( TCHAR** out_NewString, const TCHAR* SourceString,\r
851         unsigned CountOfCharacter )\r
852 {\r
853         TCHAR*  str;\r
854         size_t  size = ( CountOfCharacter + 1 ) * sizeof(TCHAR);\r
855 \r
856         ASSERT_D( *out_NewString == NULL, __noop() );\r
857 \r
858         str = (TCHAR*) malloc( size );\r
859         if ( str == NULL ) { return  E_FEW_MEMORY; }\r
860 \r
861         memcpy( str, SourceString, size - sizeof(TCHAR) );\r
862         str[ CountOfCharacter ] = _T('\0');\r
863 \r
864         *out_NewString = str;\r
865         return  0;\r
866 }\r
867 \r
868 \r
869  \r
870 /***********************************************************************\r
871   <<< [StrT_chrs] >>> \r
872 ************************************************************************/\r
873 TCHAR*  StrT_chrs( const TCHAR* s, const TCHAR* keys )\r
874 {\r
875         if ( *keys == _T('\0') )  return  NULL;\r
876 \r
877         for ( ; *s != _T('\0'); s++ ) {\r
878                 if ( _tcschr( keys, *s ) != NULL )\r
879                         return  (TCHAR*) s;\r
880         }\r
881         return  NULL;\r
882 }\r
883 \r
884 \r
885  \r
886 /***********************************************************************\r
887   <<< [StrT_skip] >>> \r
888 ************************************************************************/\r
889 TCHAR*  StrT_skip( const TCHAR* s, const TCHAR* keys )\r
890 {\r
891         if ( *keys == _T('\0') )  return  (TCHAR*) s;\r
892 \r
893         for ( ; *s != _T('\0'); s++ ) {\r
894                 if ( _tcschr( keys, *s ) == NULL )\r
895                         break;\r
896         }\r
897         return  (TCHAR*) s;\r
898 }\r
899 \r
900 \r
901  \r
902 /***********************************************************************\r
903   <<< [StrT_refFName] >>> \r
904 ************************************************************************/\r
905 TCHAR*  StrT_refFName( const TCHAR* s )\r
906 {\r
907         const TCHAR*  p;\r
908         TCHAR  c;\r
909 \r
910         p = _tcschr( s, _T('\0') );\r
911 \r
912         if ( p == s )  return  (TCHAR*) s;\r
913 \r
914         for ( p--; p>s; p-- ) {\r
915                 c = *p;\r
916                 if ( c == _T('\\') || c == _T('/') )  return  (TCHAR*) p+1;\r
917         }\r
918         if ( *p == _T('\\') || *p == _T('/') )  return  (TCHAR*) p+1;\r
919 \r
920         return  (TCHAR*) s;\r
921 }\r
922  \r
923 /***********************************************************************\r
924   <<< [StrT_refExt] >>> \r
925 ************************************************************************/\r
926 TCHAR*  StrT_refExt( const TCHAR* s )\r
927 {\r
928         const TCHAR*  p;\r
929 \r
930         p = _tcschr( s, _T('\0') );\r
931 \r
932         if ( p == s )  return  (TCHAR*) s;\r
933 \r
934         for ( p--; p>s; p-- ) {\r
935                 if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
936                 if ( *p == _T('/') || *p == _T('\\') )  return  (TCHAR*) _tcschr( p, _T('\0') );\r
937         }\r
938         if ( *p == _T('.') )  return  (TCHAR*) p+1;\r
939 \r
940         return  (TCHAR*) _tcschr( s, _T('\0') );\r
941 }\r
942 \r
943 \r
944  \r
945 /***********************************************************************\r
946   <<< [StrT_replace1] >>> \r
947 ************************************************************************/\r
948 errnum_t  StrT_replace1( TCHAR* in_out_String, TCHAR FromCharacter, TCHAR ToCharacter,\r
949         unsigned Opt )\r
950 {\r
951         TCHAR*  p;\r
952 \r
953         UNREFERENCED_VARIABLE( Opt );\r
954 \r
955         IF ( FromCharacter == _T('\0') )  { return  E_OTHERS; }\r
956 \r
957         p = in_out_String;\r
958         for (;;) {\r
959                 p = _tcschr( p, FromCharacter );\r
960                 if ( p == NULL )  { break; }\r
961                 *p = ToCharacter;\r
962                 p += 1;\r
963         }\r
964 \r
965         return  0;\r
966 }\r
967 \r
968 \r
969  \r
970 /***********************************************************************\r
971   <<< [StrT_trim] >>> \r
972 ************************************************************************/\r
973 errnum_t  StrT_trim( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str )\r
974 {\r
975         const TCHAR*  p1;\r
976         const TCHAR*  p2;\r
977         TCHAR   c;\r
978 \r
979         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
980         for ( p2 = _tcschr( p1, _T('\0') ) - 1;  p2 >= p1;  p2-- ) {\r
981                 c = *p2;\r
982                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
983                         break;\r
984         }\r
985         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
986 }\r
987 \r
988 \r
989  \r
990 /***********************************************************************\r
991   <<< [StrT_cutLastOf] >>> \r
992 ************************************************************************/\r
993 errnum_t  StrT_cutLastOf( TCHAR* in_out_Str, TCHAR Charactor )\r
994 {\r
995         TCHAR*  last = _tcschr( in_out_Str, _T('\0') );\r
996 \r
997         if ( last > in_out_Str ) {\r
998                 if ( *( last - 1 ) == Charactor )\r
999                         { *( last - 1 ) = _T('\0'); }\r
1000         }\r
1001         return  0;\r
1002 }\r
1003 \r
1004 \r
1005  \r
1006 /***********************************************************************\r
1007   <<< [StrT_cutLineComment] >>> \r
1008 ************************************************************************/\r
1009 errnum_t  StrT_cutLineComment( TCHAR* out_Str, size_t out_Str_Size, const TCHAR* in_Str, const TCHAR* CommentSign )\r
1010 {\r
1011         const TCHAR*  p1;\r
1012         const TCHAR*  p2;\r
1013         TCHAR   c;\r
1014 \r
1015         p1 = in_Str;  while ( *p1 == _T(' ') || *p1 == _T('\t') )  p1++;\r
1016 \r
1017         p2 = _tcsstr( p1, CommentSign );\r
1018         if ( p2 == NULL )  p2 = _tcschr( p1, _T('\0') );\r
1019 \r
1020         for ( p2 = p2 - 1;  p2 >= p1;  p2-- ) {\r
1021                 c = *p2;\r
1022                 if ( c != _T(' ') && c != _T('\t') && c != _T('\n') && c != _T('\r') )\r
1023                         break;\r
1024         }\r
1025         return  stcpy_part_r( out_Str, out_Str_Size, out_Str, NULL, p1, p2+1 );\r
1026 }\r
1027 \r
1028 \r
1029  \r
1030 /**************************************************************************\r
1031   <<< [StrT_meltCSV] >>> \r
1032 *************************************************************************/\r
1033 errnum_t  StrT_meltCSV( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pCSV )\r
1034 {\r
1035         errnum_t  e = 0;\r
1036         TCHAR*  t;\r
1037         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
1038         const TCHAR*  s;\r
1039         TCHAR  dummy[2];\r
1040         TCHAR  c;\r
1041 \r
1042         t = out_Str;\r
1043         s = *pCSV;\r
1044         if ( out_Str_Size <= 1 )  { t = dummy;  t_last = dummy; }\r
1045 \r
1046         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
1047 \r
1048 \r
1049         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
1050         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
1051 \r
1052         switch ( *s ) {\r
1053 \r
1054                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
1055                 case _T('"'):\r
1056                         s++;\r
1057                         c = *s;\r
1058                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
1059                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
1060                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
1061                                 if ( c == _T('\0') )  break;\r
1062                                 *t = c;  t++;  s++;  c = *s;\r
1063                         }\r
1064                         *t = _T('\0');\r
1065 \r
1066                         s++;\r
1067                         for (;;) {\r
1068                                 if ( *s == _T(',') )  { s = s+1;  break; }\r
1069                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
1070                                 s++;\r
1071                         }\r
1072                         *pCSV = s;\r
1073                         return  e;\r
1074 \r
1075                 /* \8bó\82Ì\8d\80\96Ú\82Ì\8fê\8d\87 */\r
1076                 case ',':\r
1077                         *t = _T('\0');\r
1078                         *pCSV = s+1;\r
1079                         return  0;\r
1080 \r
1081                 case '\0':\r
1082                         *t = _T('\0');\r
1083                         *pCSV = NULL;\r
1084                         return  0;\r
1085 \r
1086                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
1087                 default: {\r
1088                         TCHAR*  sp = NULL;  /* \8dÅ\8cã\82Ì\98A\91±\82µ\82½\8bó\94\92\82Ì\90æ\93ª */\r
1089 \r
1090                         c = *s;\r
1091                         while ( c != _T(',') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* , \95\8e\9a\82Ü\82Å */\r
1092 \r
1093                                 /* sp \82ð\90Ý\92è\82·\82é */\r
1094                                 if ( c == ' ' ) {\r
1095                                         if ( sp == NULL )  sp = t;\r
1096                                 }\r
1097                                 else  sp = NULL;\r
1098 \r
1099                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = dummy;  t_last = dummy + 1; }\r
1100 \r
1101                                 /* \83R\83s\81[\82·\82é */\r
1102                                 *t = c;  t++;  s++;  c = *s;\r
1103                         }\r
1104 \r
1105                         /* \95Ô\82è\92l\82ð\8c\88\92è\82·\82é */\r
1106                         if ( c == _T(',') )  s = s + 1;\r
1107                         else  s = NULL;\r
1108 \r
1109                         /* \96\96\94ö\82Ì\8bó\94\92\82ð\8eæ\82è\8f\9c\82­ */\r
1110                         if ( sp != NULL )  *sp = '\0';\r
1111                         else  *t = _T('\0');\r
1112 \r
1113                         *pCSV = s;\r
1114                         return  e;\r
1115                 }\r
1116         }\r
1117 }\r
1118 \r
1119 \r
1120  \r
1121 /***********************************************************************\r
1122   <<< [StrT_getExistSymbols] >>> \r
1123 ************************************************************************/\r
1124 errnum_t  StrT_getExistSymbols( unsigned* out, bool bCase, const TCHAR* Str, const TCHAR* Symbols, ... )\r
1125 {\r
1126         errnum_t  e;\r
1127         int       i;\r
1128         TCHAR** syms = NULL;\r
1129         bool*   syms_exists = NULL;\r
1130         bool    b_nosym = false;\r
1131         TCHAR*  sym = NULL;\r
1132         size_t  sym_size = ( _tcslen( Symbols ) + 1 ) * sizeof(TCHAR);\r
1133         int     n_sym = 0;\r
1134         const TCHAR*  p;\r
1135 \r
1136         UNREFERENCED_VARIABLES(( bCase ));\r
1137 \r
1138         sym = (TCHAR*) malloc( sym_size ); IF(sym==NULL)goto err_fm;\r
1139 \r
1140 \r
1141         //=== Get Symbols\r
1142         p = Symbols;\r
1143         do {\r
1144                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
1145                 if ( sym[0] != _T('\0') )  n_sym ++;\r
1146         } while ( p != NULL );\r
1147 \r
1148         syms = (TCHAR**) malloc( n_sym * sizeof(TCHAR*) ); IF(syms==NULL)goto err_fm;\r
1149         memset( syms, 0, n_sym * sizeof(TCHAR*) );\r
1150         syms_exists = (bool*) malloc( n_sym * sizeof(bool) ); IF(syms_exists==NULL)goto err_fm;\r
1151         memset( syms_exists, 0, n_sym * sizeof(bool) );\r
1152 \r
1153         p = Symbols;  i = 0;\r
1154         do {\r
1155                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
1156                 if ( sym[0] != _T('\0') ) {\r
1157                         e= MallocAndCopyString( &syms[i], sym ); IF(e)goto fin;\r
1158                         i++;\r
1159                 }\r
1160         } while ( p != NULL );\r
1161 \r
1162 \r
1163         //=== Check Str whether having Symbols\r
1164         p = Str;\r
1165         do {\r
1166                 e= StrT_meltCSV( sym, sym_size, &p ); IF(e)goto fin;\r
1167                 if ( sym[0] != _T('\0') ) {\r
1168                         for ( i = 0; i < n_sym; i++ ) {\r
1169                                 if ( _tcscmp( sym, syms[i] ) == 0 )  { syms_exists[i] = true;  break; }\r
1170                         }\r
1171                         if ( i == n_sym )  b_nosym = true;\r
1172                 }\r
1173         } while ( p != NULL );\r
1174 \r
1175 \r
1176         //=== Sum numbers\r
1177         {\r
1178                 va_list   va;\r
1179                 unsigned  num;\r
1180 \r
1181                 va_start( va, Symbols );\r
1182                 *out = 0;\r
1183                 for ( i = 0; i < n_sym; i++ ) {\r
1184                         num = va_arg( va, unsigned );\r
1185                         if ( syms_exists[i] )  *out |= num;\r
1186                 }\r
1187                 va_end( va );\r
1188         }\r
1189 \r
1190         e = ( b_nosym ? E_NOT_FOUND_SYMBOL : 0 );\r
1191 fin:\r
1192         if ( syms != NULL ) {\r
1193                 for ( i = 0; i < n_sym; i++ ) {\r
1194                         if ( syms[i] != NULL )  free( syms[i] );\r
1195                 }\r
1196                 free( syms );\r
1197         }\r
1198         if ( syms_exists != NULL )  free( syms_exists );\r
1199         if ( sym != NULL )  free( sym );\r
1200         return  e;\r
1201 err_fm: e= E_FEW_MEMORY; goto fin;\r
1202 }\r
1203 \r
1204  \r
1205 /**************************************************************************\r
1206   <<< [StrT_meltCmdLine] >>> \r
1207 *************************************************************************/\r
1208 errnum_t  StrT_meltCmdLine( TCHAR* out_Str, size_t out_Str_Size, const TCHAR** pLine )\r
1209 {\r
1210         errnum_t  e = 0;\r
1211         TCHAR*  t;\r
1212         TCHAR*  t_last = (TCHAR*)( (char*)out_Str + out_Str_Size - sizeof(TCHAR) );\r
1213         const TCHAR*  s;\r
1214         TCHAR  dummy;\r
1215         TCHAR  c;\r
1216 \r
1217         t = out_Str;\r
1218         s = *pLine;\r
1219         if ( out_Str_Size <= 1 )  { t = &dummy;  t_last = &dummy; }\r
1220 \r
1221         if ( s == NULL ) { *t = _T('\0');  return 0; }\r
1222 \r
1223 \r
1224         /* \93ª\82Ì\8bó\94\92\82ð\8f\9c\82­ */\r
1225         while ( *s == _T(' ') || *s == _T('\t') )  s++;\r
1226 \r
1227         switch ( *s ) {\r
1228 \r
1229                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82é\8fê\8d\87 */\r
1230                 case _T('"'):\r
1231                         s++;\r
1232                         c = *s;\r
1233                         while ( c != _T('"') || *(s+1) == _T('"') ) {  /* " \95\8e\9a\82Ü\82Å */\r
1234                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
1235                                 if ( c == *(s+1) && c == _T('"') )  s++;  /* " \95\8e\9a\8e©\91Ì */\r
1236                                 if ( c == _T('\0') )  break;\r
1237                                 *t = c;  t++;  s++;  c = *s;\r
1238                         }\r
1239                         *t = _T('\0');\r
1240 \r
1241                         s++;\r
1242                         for (;;) {\r
1243                                 if ( *s == _T(' ') )  { s = s+1;  break; }\r
1244                                 if ( *s == _T('\0') ) { s = NULL;  break; }\r
1245                                 s++;\r
1246                         }\r
1247                         *pLine = s;\r
1248                         return  e;\r
1249 \r
1250                 case '\0':\r
1251                         *t = _T('\0');\r
1252                         *pLine = NULL;\r
1253                         return  0;\r
1254 \r
1255                 /* "" \82Å\88Í\82Ü\82ê\82Ä\82¢\82È\82¢\8fê\8d\87 */\r
1256                 default: {\r
1257                         c = *s;\r
1258                         while ( c != _T(' ') && c != _T('\0') && c != _T('\r') && c != _T('\n') ) {  /* \8bó\94\92\95\8e\9a\82Ü\82Å */\r
1259 \r
1260                                 if ( t == t_last ) { e = E_FEW_ARRAY;  t = &dummy;  t_last = &dummy + 1; }\r
1261 \r
1262                                 /* \83R\83s\81[\82·\82é */\r
1263                                 *t = c;  t++;  s++;  c = *s;\r
1264                         }\r
1265 \r
1266                         /* *pLine\82ð\8c\88\92è\82·\82é */\r
1267                         while ( *s == _T(' ') )  s = s + 1;\r
1268                         if ( *s == _T('\0') )  s = NULL;\r
1269 \r
1270                         /* \96\96\94ö */\r
1271                         *t = _T('\0');\r
1272 \r
1273                         *pLine = s;\r
1274                         return  e;\r
1275                 }\r
1276         }\r
1277 }\r
1278 \r
1279 \r
1280  \r
1281 /***********************************************************************\r
1282   <<< [StrT_isAbsPath] >>> \r
1283 ************************************************************************/\r
1284 bool  StrT_isAbsPath( const TCHAR* s )\r
1285 {\r
1286         const TCHAR*  bs = _tcschr( s, _T('\\') );\r
1287         const TCHAR*  sl = _tcschr( s, _T('/') );\r
1288         const TCHAR*  co = _tcschr( s, _T(':') );\r
1289 \r
1290         return  ( co != NULL  && ( bs == co+1  ||  sl == co+1 ) );\r
1291 }\r
1292 \r
1293  \r
1294 /**************************************************************************\r
1295   <<< [StrT_getAbsPath_part] >>> \r
1296 *************************************************************************/\r
1297 errnum_t  StrT_getAbsPath_part( TCHAR* out_AbsPath, size_t AbsPathSize, TCHAR* OutStart,\r
1298         TCHAR** out_OutLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
1299 {\r
1300         errnum_t      e;\r
1301         TCHAR         separator = (TCHAR) DUMMY_INITIAL_VALUE_TCHAR;\r
1302         const TCHAR*  separator_path;\r
1303         TCHAR*        out_abs_path_over = (TCHAR*)( (uint8_t*) out_AbsPath + AbsPathSize );\r
1304         TCHAR*        null_position = NULL;\r
1305 \r
1306 \r
1307         #if  CHECK_ARG\r
1308                 /* "BasePath" must be out of "out_AbsPath" */\r
1309                 ASSERT_R( BasePath < out_AbsPath  ||\r
1310                         (uint8_t*) BasePath >= (uint8_t*) out_AbsPath + AbsPathSize,\r
1311                         goto err );\r
1312         #endif\r
1313 \r
1314 \r
1315         /* If "StepPath" == "", out_AbsPath = "" */\r
1316         if ( StepPath[0] == _T('\0') ) {\r
1317                 ASSERT_R( AbsPathSize >= sizeof(TCHAR), goto err_fm );\r
1318                 out_AbsPath[0] = _T('\0');\r
1319                 e=0;  goto fin;\r
1320         }\r
1321 \r
1322 \r
1323         /* Set "OutStart" */\r
1324         if ( OutStart == NULL )\r
1325                 { OutStart = out_AbsPath; }\r
1326 \r
1327 \r
1328         /* Set "separator" : \ or / from "BasePath" */\r
1329         if ( StrT_isAbsPath( StepPath ) ) {\r
1330                 separator_path = StepPath;\r
1331         }\r
1332         else if ( BasePath == NULL ) {\r
1333                 separator = _T('\\');\r
1334                 separator_path = NULL;\r
1335         }\r
1336         else {\r
1337                 separator_path = BasePath;\r
1338         }\r
1339         if ( separator_path != NULL ) {\r
1340                 const TCHAR*    p;\r
1341                 const TCHAR*    p2;\r
1342 \r
1343                 p  = _tcschr( separator_path, _T('\\') );\r
1344                 p2 = _tcschr( separator_path, _T('/') );\r
1345                 if ( p == NULL ) {\r
1346                         if ( p2 == NULL )\r
1347                                 { separator = _T('\\'); }\r
1348                         else\r
1349                                 { separator = _T('/'); }\r
1350                 } else {\r
1351                         if ( p2 == NULL )\r
1352                                 { separator = _T('\\'); }\r
1353                         else {\r
1354                                 if ( p < p2 )\r
1355                                         { separator = _T('\\'); }\r
1356                                 else\r
1357                                         { separator = _T('/'); }\r
1358                         }\r
1359                 }\r
1360         }\r
1361 \r
1362 \r
1363         /* Set "OutStart" : "BasePath" + / + "StepPath" */\r
1364         if ( StrT_isAbsPath( StepPath ) ) {\r
1365                 size_t  step_path_length = _tcslen( StepPath );\r
1366 \r
1367                 IF( OutStart + step_path_length >= out_abs_path_over ) goto err_fa;\r
1368                 memmove( OutStart,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
1369 \r
1370                 /* Set "null_position" */\r
1371                 null_position = OutStart + step_path_length;\r
1372         }\r
1373         else {\r
1374                 TCHAR   c;\r
1375                 TCHAR*  p;\r
1376                 size_t  base_path_length;\r
1377                 size_t  step_path_length = _tcslen( StepPath );\r
1378 \r
1379                 if ( BasePath == NULL ) {\r
1380                         base_path_length = GetCurrentDirectory( 0, NULL ) - 1;\r
1381                 }\r
1382                 else {\r
1383                         base_path_length = _tcslen( BasePath );\r
1384                         c = BasePath[ base_path_length - 1 ];\r
1385                         if ( c == _T('\\')  ||  c == _T('/') )\r
1386                                 { base_path_length -= 1; }\r
1387                 }\r
1388 \r
1389                 p = OutStart + base_path_length + 1;\r
1390                 IF( p + step_path_length >= out_abs_path_over ) goto err_fa;\r
1391                 memmove( p,  StepPath,  ( step_path_length + 1 ) * sizeof(TCHAR) );\r
1392                         /* memmove is for "out_AbsPath" == "StepPath" */\r
1393 \r
1394                 if ( BasePath == NULL ) {\r
1395                         GetCurrentDirectory( base_path_length + 1, OutStart );\r
1396                         if ( OutStart[ base_path_length - 1 ] == _T('\\') )\r
1397                                 { base_path_length -= 1; }\r
1398                 } else {\r
1399                         memcpy( OutStart,  BasePath,  base_path_length * sizeof(TCHAR) );\r
1400                 }\r
1401                 OutStart[ base_path_length ] = separator;\r
1402 \r
1403 \r
1404                 /* Set "null_position" */\r
1405                 null_position = p + step_path_length;\r
1406         }\r
1407 \r
1408 \r
1409         /* Replace \ and / to "separator" in "OutStart" */\r
1410         {\r
1411                 TCHAR  other_separator;\r
1412 \r
1413                 if ( separator == _T('/') )\r
1414                         { other_separator = _T('\\'); }\r
1415                 else\r
1416                         { other_separator = _T('/'); }\r
1417 \r
1418                 e= StrT_replace1( OutStart, other_separator, separator, 0 ); IF(e)goto fin;\r
1419         }\r
1420 \r
1421 \r
1422         /* Replace \*\..\ to \ */\r
1423         {\r
1424                 enum  { length = 4 };\r
1425                 TCHAR   parent[ length + 1 ];  /* \..\ or /../ */\r
1426                 TCHAR*  parent_position;\r
1427                 TCHAR*  p;\r
1428 \r
1429                 parent[0] = separator;\r
1430                 parent[1] = _T('.');\r
1431                 parent[2] = _T('.');\r
1432                 parent[3] = separator;\r
1433                 parent[4] = _T('\0');\r
1434 \r
1435                 for (;;) {\r
1436                         parent_position = _tcsstr( OutStart, parent );\r
1437                         if ( parent_position == NULL )  { break; }\r
1438 \r
1439                         p = parent_position - 1;\r
1440                         for (;;) {\r
1441                                 IF( p < OutStart ) goto err;  /* "../" are too many */\r
1442                                 if ( *p == separator )  { break; }\r
1443                                 p -= 1;\r
1444                         }\r
1445 \r
1446                         memmove( p + 1,\r
1447                                 parent_position + length,\r
1448                                 ( null_position - ( parent_position + length ) + 1 ) * sizeof(TCHAR) );\r
1449 \r
1450                         null_position -= ( parent_position + length ) - ( p + 1 );\r
1451                 }\r
1452         }\r
1453 \r
1454 \r
1455         /* Cut last \*\.. */\r
1456         {\r
1457                 enum  { length = 3 };\r
1458                 TCHAR*  p;\r
1459 \r
1460                 while ( null_position - length >= OutStart ) {\r
1461                         if ( *( null_position - 3 ) != separator  ||\r
1462                              *( null_position - 2 ) != _T('.')  ||\r
1463                              *( null_position - 1 ) != _T('.') )\r
1464                                 { break; }\r
1465 \r
1466                         p = null_position - 4;\r
1467                         for (;;) {\r
1468                                 IF( p < OutStart ) goto err;  /* "../" are too many */\r
1469                                 if ( *p == separator )  { break; }\r
1470                                 p -= 1;\r
1471                         }\r
1472 \r
1473                         *p = _T('\0');\r
1474 \r
1475                         null_position = p;\r
1476                 }\r
1477         }\r
1478 \r
1479 \r
1480         /* Replace \.\ to \ */\r
1481         {\r
1482                 enum  { length = 3 };\r
1483                 TCHAR   current[ length + 1 ];  /* \.\ or /./ */\r
1484                 TCHAR*  current_position;\r
1485 \r
1486                 current[0] = separator;\r
1487                 current[1] = _T('.');\r
1488                 current[2] = separator;\r
1489                 current[3] = _T('\0');\r
1490 \r
1491                 for (;;) {\r
1492                         current_position = _tcsstr( OutStart, current );\r
1493                         if ( current_position == NULL )  { break; }\r
1494 \r
1495                         memmove( current_position + 1,\r
1496                                 current_position + length,\r
1497                                 ( null_position - ( current_position + length ) + 1 ) * sizeof(TCHAR) );\r
1498 \r
1499                         null_position -= length - 1;\r
1500                 }\r
1501         }\r
1502 \r
1503 \r
1504         /* Cut last \. */\r
1505         {\r
1506                 TCHAR*  over = _tcschr( OutStart, _T('\0') );\r
1507 \r
1508                 while ( over - 2 >= OutStart  &&\r
1509                                 *( over - 1 ) == _T('.')  &&  *( over - 2 ) == separator ) {\r
1510                         over -= 2;\r
1511                         *over = _T('\0');\r
1512                 }\r
1513         }\r
1514 \r
1515 \r
1516         /* Add root / */\r
1517         if ( null_position - 1 >= OutStart ) {\r
1518                 if ( *( null_position - 1 ) == _T(':') ) {\r
1519                         IF( null_position + 1 >= out_abs_path_over ) goto err_fa;\r
1520 \r
1521                         *( null_position + 0 ) = separator;\r
1522                         *( null_position + 1 ) = _T('\0');\r
1523                         null_position += 1;\r
1524                 }\r
1525         }\r
1526 \r
1527 \r
1528         /* Set "*out_OutLast" */\r
1529         if ( out_OutLast != NULL )\r
1530                 { *out_OutLast = null_position; }\r
1531 \r
1532         e=0;\r
1533 fin:\r
1534         return  e;\r
1535 \r
1536 err:     e = E_OTHERS;      goto fin;\r
1537 err_fa:  e = E_FEW_ARRAY;   goto fin;\r
1538 err_fm:  e = E_FEW_MEMORY;  goto fin;\r
1539 }\r
1540 \r
1541 \r
1542  \r
1543 /***********************************************************************\r
1544   <<< [StrT_getParentAbsPath_part] >>> \r
1545 ************************************************************************/\r
1546 errnum_t  StrT_getParentAbsPath_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
1547         TCHAR** out_StrLast, const TCHAR* StepPath, const TCHAR* BasePath )\r
1548 {\r
1549         errnum_t  e;\r
1550         TCHAR*  p;\r
1551 \r
1552         IF_D( StrStart < Str ||  (char*) StrStart >= (char*)Str + StrSize )goto err;\r
1553 \r
1554         if ( StepPath[0] == _T('\0') ) {\r
1555                 *StrStart = _T('\0');\r
1556                 return  0;\r
1557         }\r
1558 \r
1559         /* \90â\91Î\83p\83X\82É\82·\82é */\r
1560         e= StrT_getAbsPath( StrStart,\r
1561                 StrSize - ( (char*)StrStart - (char*)Str ),\r
1562                 StepPath, BasePath ); IF(e)goto fin;\r
1563 \r
1564 \r
1565         /* Cut last \ */\r
1566         p = _tcschr( StrStart, _T('\0') );\r
1567         if ( p > StrStart ) {\r
1568                 TCHAR  c = *( p - 1 );\r
1569                 if ( c == _T('\\')  ||  c == _T('/') )\r
1570                         { *( p - 1 ) = _T('\0'); }\r
1571         }\r
1572 \r
1573 \r
1574         /* \90e\82Ö */\r
1575         p = StrT_refFName( StrStart );\r
1576         if ( p > StrStart )  p--;\r
1577         *p = _T('\0');\r
1578 \r
1579 \r
1580         /* \83\8b\81[\83g\82È\82ç \ \82ð\95t\82¯\82é */\r
1581         if ( p == StrStart + 2 ) {\r
1582                 *p = _T('\\');  p++;  *p = _T('\0');\r
1583         }\r
1584 \r
1585         if ( out_StrLast != NULL )  *out_StrLast = p;\r
1586 \r
1587         e=0;\r
1588 fin:\r
1589         return  e;\r
1590 \r
1591 err:  e = E_OTHERS;  goto fin;\r
1592 }\r
1593 \r
1594 \r
1595  \r
1596 /***********************************************************************\r
1597   <<< [StrT_isOverOfFileName] >>> \r
1598 - "" or "\" or "/"\r
1599 ************************************************************************/\r
1600 inline bool  StrT_isOverOfFileName( const TCHAR* PointerInPath )\r
1601 {\r
1602         return  PointerInPath == NULL  ||\r
1603                 *PointerInPath == _T('\0')  ||\r
1604                 ( ( *PointerInPath == _T('\\')  ||  *PointerInPath == _T('/') )  &&\r
1605                         *(PointerInPath + 1) == _T('\0') );\r
1606 }\r
1607 \r
1608 \r
1609  \r
1610 /***********************************************************************\r
1611   <<< [StrT_getStepPath] >>> \r
1612 ************************************************************************/\r
1613 errnum_t  StrT_getStepPath( TCHAR* out_StepPath, size_t StepPathSize,\r
1614         const TCHAR* AbsPath, const TCHAR* BasePath )\r
1615 {\r
1616         errnum_t      e;\r
1617         const TCHAR*  abs_pointer;\r
1618         const TCHAR*  base_pointer;\r
1619         TCHAR         abs_char;\r
1620         TCHAR         base_char;\r
1621         TCHAR         separator;\r
1622         const TCHAR*  abs_separator_pointer  = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
1623         const TCHAR*  base_separator_pointer = (const TCHAR*) DUMMY_INITIAL_VALUE;\r
1624         TCHAR*        step_pointer;\r
1625         TCHAR         parent_symbol[4] = { _T('.'), _T('.'), _T('\\'), _T('\0') };\r
1626         TCHAR         base_path_2[ MAX_PATH ];\r
1627 \r
1628 \r
1629         ASSERT_D( out_StepPath != AbsPath, goto err );\r
1630 \r
1631         abs_pointer = AbsPath;\r
1632 \r
1633 \r
1634         /* Set "base_pointer" */\r
1635         if ( BasePath == NULL ) {\r
1636                 base_pointer = _tgetcwd( base_path_2, _countof(base_path_2) );\r
1637                 IF( base_pointer == NULL ) goto err;\r
1638         }\r
1639         else {\r
1640                 base_pointer = BasePath;\r
1641         }\r
1642 \r
1643 \r
1644         /* Set "abs_separator_pointer", "base_separator_pointer" : after same parent folder path */\r
1645         separator = 0;\r
1646         for (;;) {  /* while abs_char == base_char */\r
1647                 abs_char  = *abs_pointer;\r
1648                 base_char = *base_pointer;\r
1649 \r
1650                 abs_char  = (TCHAR) _totlower( abs_char );\r
1651                 base_char = (TCHAR) _totlower( base_char );\r
1652 \r
1653                 if ( abs_char == _T('\0') ) {\r
1654 \r
1655                         /* out_StepPath = ".", if AbsPath == BasePath */\r
1656                         if ( base_char == _T('\0') ) {\r
1657                                 e= StrT_cpy( out_StepPath, StepPathSize, _T(".") ); IF(e)goto fin;\r
1658                                 e=0; goto fin;\r
1659                         }\r
1660                         break;\r
1661                 }\r
1662                 if ( base_char == _T('\0') )  { break; }\r
1663 \r
1664                 if ( abs_char != base_char ) {\r
1665                         if ( ( abs_char  == _T('/')  ||  abs_char  == _T('\\') ) &&\r
1666                              ( base_char == _T('/')  ||  base_char == _T('\\') ) )\r
1667                                 { /* Do nothing */ }\r
1668                         else\r
1669                                 { break; }\r
1670                 }\r
1671 \r
1672                 /* Set "separator", "abs_separator_pointer", "base_separator_pointer" */\r
1673                 if (  base_char == _T('/')  ||  base_char == _T('\\')  ) {\r
1674                         if ( separator == 0 )\r
1675                                 { separator = base_char; }\r
1676 \r
1677                         abs_separator_pointer = abs_pointer;\r
1678                         base_separator_pointer = base_pointer;\r
1679                 }\r
1680 \r
1681                 abs_pointer  += 1;\r
1682                 base_pointer += 1;\r
1683         }\r
1684 \r
1685 \r
1686         /* AbsPath \82Æ BasePath \82Ì\8aÖ\8cW\82ª\81A\95Ð\95û\82Ì\88ê\95\94\82ª\82à\82¤\95Ð\95û\82Ì\91S\91Ì\82Å\82 \82é\82Æ\82« */\r
1687         if (  abs_char == _T('/')  ||  abs_char == _T('\\')  ||\r
1688              base_char == _T('/')  || base_char == _T('\\')  ) {\r
1689              /* other character is '\0' */\r
1690 \r
1691                 if ( separator == 0 )\r
1692                         { separator = abs_char; }\r
1693 \r
1694                 abs_separator_pointer = abs_pointer;\r
1695                 base_separator_pointer = base_pointer;\r
1696         }\r
1697 \r
1698 \r
1699         /* out_StepPath = AbsPath, if there is not same folder */\r
1700         if ( separator == 0 ) {\r
1701                 e= StrT_cpy( out_StepPath, StepPathSize, AbsPath ); IF(e)goto fin;\r
1702                 e=0; goto fin;\r
1703         }\r
1704 \r
1705 \r
1706         /* Add "..\" to "out_StepPath" */\r
1707         parent_symbol[2] = separator;\r
1708         step_pointer = out_StepPath;\r
1709         for (;;) {\r
1710                 const TCHAR*  p1;\r
1711                 const TCHAR*  p2;\r
1712 \r
1713                 if ( StrT_isOverOfFileName( base_separator_pointer ) )\r
1714                         { break; }\r
1715 \r
1716 \r
1717                 /* Set "base_separator_pointer" : next separator */\r
1718                 p1 = _tcschr( base_separator_pointer + 1, _T('/') );\r
1719                 p2 = _tcschr( base_separator_pointer + 1, _T('\\') );\r
1720 \r
1721                 if ( p1 == NULL ) {\r
1722                         if ( p2 == NULL )\r
1723                                 { base_separator_pointer = NULL; }\r
1724                         else\r
1725                                 { base_separator_pointer = p2; }\r
1726                 }\r
1727                 else {\r
1728                         if ( p2 == NULL ) {\r
1729                                 base_separator_pointer = p1;\r
1730                         } else {\r
1731                                 if ( p1 < p2 )\r
1732                                         { base_separator_pointer = p1; }\r
1733                                 else\r
1734                                         { base_separator_pointer = p2; }\r
1735                         }\r
1736                 }\r
1737 \r
1738 \r
1739                 /* Add "..\" to "out_StepPath" */\r
1740                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, &step_pointer,\r
1741                         parent_symbol, NULL ); IF(e)goto fin;\r
1742         }\r
1743 \r
1744 \r
1745         /* Copy a part of "AbsPath" to "out_StepPath" */\r
1746         if ( StrT_isOverOfFileName( abs_separator_pointer ) ) {\r
1747                 ASSERT_D( step_pointer > out_StepPath, goto err );\r
1748                 *( step_pointer - 1 ) = _T('\0');\r
1749         }\r
1750         else {\r
1751                 e= stcpy_part_r( out_StepPath, StepPathSize, step_pointer, NULL,\r
1752                         abs_separator_pointer + 1, NULL ); IF(e)goto fin;\r
1753         }\r
1754 \r
1755         e=0;\r
1756 fin:\r
1757         return  e;\r
1758 \r
1759 err:  e = E_OTHERS;  goto fin;\r
1760 }\r
1761 \r
1762 \r
1763  \r
1764 /***********************************************************************\r
1765   <<< [StrT_getBaseName_part] >>> \r
1766 ************************************************************************/\r
1767 errnum_t  StrT_getBaseName_part( TCHAR* Str, size_t StrSize, TCHAR* StrStart,\r
1768         TCHAR** out_StrLast, const TCHAR* SrcPath )\r
1769 {\r
1770         const TCHAR*  p1;\r
1771         const TCHAR*  p2;\r
1772         const TCHAR*  p3;\r
1773         const TCHAR*  ps;\r
1774 \r
1775         p1 = StrT_refFName( SrcPath );\r
1776 \r
1777 \r
1778         //=== # \82ª\96³\82¢\82Æ\82«\81A\8dÅ\8cã\82Ì\83s\83\8a\83I\83h\82Ì\91O\82Ü\82Å\82ª\81ABaseName\r
1779         ps = _tcschr( p1, _T('#') );\r
1780         if ( ps == NULL ) {\r
1781                 p2 = _tcsrchr( p1, _T('.') );\r
1782                 if ( p2 == NULL )  p2 = _tcsrchr( p1, _T('\0') );\r
1783         }\r
1784 \r
1785         //=== # \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
1786         else {\r
1787                 p2 = ps;\r
1788 \r
1789                 p3 = p1;\r
1790                 for (;;) {\r
1791                         p3 = _tcschr( p3, _T('.') );\r
1792                         if ( p3 == NULL || p3 > ps )  break;\r
1793                         p2 = p3;\r
1794                         p3 ++;\r
1795                 }\r
1796         }\r
1797 \r
1798         return  stcpy_part_r( Str, StrSize, StrStart, out_StrLast, p1, p2 );\r
1799 }\r
1800 \r
1801  \r
1802 /***********************************************************************\r
1803   <<< [StrT_addLastOfFileName] >>> \r
1804 ************************************************************************/\r
1805 errnum_t  StrT_addLastOfFileName( TCHAR* out_Path, size_t PathSize,\r
1806                              const TCHAR* BasePath, const TCHAR* AddName )\r
1807 {\r
1808         TCHAR           c;\r
1809         size_t          copy_size;\r
1810         size_t          free_size;\r
1811         char*           out_pos;\r
1812         const TCHAR*    last_pos_in_base = _tcschr( BasePath, _T('\0') );\r
1813         const TCHAR*    term_pos_in_base;\r
1814         const TCHAR*     add_pos_in_base;\r
1815         const TCHAR*  period_pos_in_base = _tcsrchr( BasePath, _T('.') );  // > term_pos_in_base\r
1816         const TCHAR*    last_pos_in_add  = _tcschr( AddName, _T('\0') );\r
1817         const TCHAR*    term_pos_in_add;\r
1818         const TCHAR*  period_pos_in_add  = _tcsrchr( AddName,  _T('.') );  // > term_pos_in_add\r
1819 \r
1820 \r
1821         MEMSET_TO_NOT_INIT( out_Path, PathSize );\r
1822 \r
1823 \r
1824         //=== term_pos_in_base\r
1825         for ( term_pos_in_base = last_pos_in_base;  term_pos_in_base >= BasePath;  term_pos_in_base -- ) {\r
1826                 c = *term_pos_in_base;\r
1827                 if ( c == _T('/') || c == _T('\\') )  break;\r
1828         }\r
1829 \r
1830 \r
1831         //=== term_pos_in_add\r
1832         for ( term_pos_in_add = last_pos_in_add;  term_pos_in_add >= AddName;  term_pos_in_add -- ) {\r
1833                 c = *term_pos_in_add;\r
1834                 if ( c == _T('/') || c == _T('\\') )  break;\r
1835         }\r
1836 \r
1837 \r
1838         //=== add_pos_in_base\r
1839         if ( term_pos_in_base < period_pos_in_base ) {\r
1840                 add_pos_in_base = period_pos_in_base;\r
1841         }\r
1842         else {\r
1843                 if ( term_pos_in_base < BasePath )\r
1844                         add_pos_in_base = _tcschr( BasePath, _T('\0') );\r
1845                 else\r
1846                         add_pos_in_base = _tcschr( term_pos_in_base, _T('\0') );\r
1847         }\r
1848 \r
1849 \r
1850         //=== setup output parameters\r
1851         out_pos   = (char*) out_Path;\r
1852         free_size = PathSize;\r
1853 \r
1854 \r
1855         //=== copy BasePath .. add_pos_in_base\r
1856         copy_size = (char*)add_pos_in_base - (char*)BasePath;\r
1857         if ( copy_size > free_size ) goto err_fa;\r
1858         memcpy( out_pos,  BasePath,  copy_size );\r
1859         out_pos   += copy_size;\r
1860         free_size -= copy_size;\r
1861 \r
1862 \r
1863         //=== copy AddName .. last_pos_in_add\r
1864         copy_size = (char*)last_pos_in_add - (char*)AddName;\r
1865         if ( copy_size > free_size ) goto err_fa;\r
1866         memcpy( out_pos,  AddName,  copy_size );\r
1867         out_pos   += copy_size;\r
1868         free_size -= copy_size;\r
1869 \r
1870 \r
1871         //=== add name and not change extension\r
1872         if ( period_pos_in_add == NULL ) {\r
1873 \r
1874                 //=== copy period_pos_in_base .. last_pos_in_base\r
1875                 if ( period_pos_in_base > term_pos_in_base ) {\r
1876                         copy_size = (char*)last_pos_in_base - (char*)period_pos_in_base + sizeof(TCHAR);\r
1877                         if ( copy_size > free_size ) goto err_fa;\r
1878                         memcpy( out_pos,  period_pos_in_base,  copy_size );\r
1879                 }\r
1880                 else {\r
1881                         *(TCHAR*)out_pos = _T('\0');\r
1882                 }\r
1883         }\r
1884 \r
1885 \r
1886         //=== add name and change extension\r
1887         else {\r
1888 \r
1889                 if ( *(period_pos_in_add + 1) == _T('\0') )\r
1890                         *( (TCHAR*)out_pos - 1 ) = _T('\0');\r
1891                 else\r
1892                         *(TCHAR*)out_pos = _T('\0');\r
1893         }\r
1894 \r
1895         return  0;\r
1896 \r
1897 err_fa:\r
1898         return  E_FEW_ARRAY;\r
1899 }\r
1900 \r
1901 \r
1902  \r
1903 /***********************************************************************\r
1904   <<< [Strs_init] >>> \r
1905 ************************************************************************/\r
1906 enum { Strs_FirstSize = 0x0F00 };\r
1907 \r
1908 errnum_t  Strs_init( Strs* self )\r
1909 {\r
1910         char*  p;\r
1911 \r
1912         self->MemoryAddress = NULL;\r
1913 \r
1914         p = (char*) malloc( Strs_FirstSize );\r
1915         IF( p == NULL )  return  E_FEW_MEMORY;\r
1916 \r
1917         self->MemoryAddress = p;\r
1918         self->MemoryOver    = p + Strs_FirstSize;\r
1919         self->NextElem      = p + sizeof(TCHAR*);\r
1920         self->PointerToNextStrInPrevElem = (TCHAR**) p;\r
1921         self->Prev_PointerToNextStrInPrevElem = NULL;\r
1922         *(TCHAR**) p = NULL;\r
1923 \r
1924         self->FirstOfStrs = self;\r
1925         self->NextStrs = NULL;\r
1926 \r
1927         return  0;\r
1928 }\r
1929 \r
1930 \r
1931  \r
1932 /***********************************************************************\r
1933   <<< [Strs_finish] >>> \r
1934 ************************************************************************/\r
1935 errnum_t  Strs_finish( Strs* self, errnum_t e )\r
1936 {\r
1937         Strs*  mp;\r
1938         Strs*  next_mp;\r
1939 \r
1940         if ( self->MemoryAddress == NULL )  return 0;\r
1941 \r
1942         mp = self->FirstOfStrs;\r
1943         for (;;) {\r
1944                 free( mp->MemoryAddress );\r
1945                 if ( mp == self )  break;\r
1946 \r
1947                 next_mp = mp->NextStrs;\r
1948                 free( mp );\r
1949                 mp = next_mp;\r
1950         }\r
1951         self->MemoryAddress = NULL;\r
1952 \r
1953         return  e;\r
1954 }\r
1955 \r
1956 \r
1957  \r
1958 /***********************************************************************\r
1959   <<< [Strs_toEmpty] >>> \r
1960 ************************************************************************/\r
1961 errnum_t  Strs_toEmpty( Strs* self )\r
1962 {\r
1963         Strs_finish( self, 0 );\r
1964         return  Strs_init( self );\r
1965 }\r
1966 \r
1967 \r
1968  \r
1969 /***********************************************************************\r
1970   <<< [Strs_add] >>> \r
1971 ************************************************************************/\r
1972 errnum_t  Strs_add( Strs* self, const TCHAR* Str, const TCHAR** out_AllocStr )\r
1973 {\r
1974         return  Strs_addBinary( self, Str, _tcschr( Str, _T('\0') ) + 1, out_AllocStr );\r
1975 }\r
1976 \r
1977 \r
1978 errnum_t  Strs_addBinary( Strs* self, const TCHAR* Str, const TCHAR* StrOver, const TCHAR** out_AllocStr )\r
1979 {\r
1980         errnum_t  e;\r
1981         size_t  str_size;\r
1982         size_t  elem_size;\r
1983 \r
1984         str_size  = ( (char*) StrOver - (char*) Str );\r
1985         elem_size = ( sizeof(TCHAR*) + str_size + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
1986 \r
1987         if ( self->NextElem + elem_size > self->MemoryOver )\r
1988                 { e= Strs_expandSize( self, str_size ); IF(e)goto fin; }\r
1989 \r
1990 \r
1991         // [ NULL     | ... ]\r
1992         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
1993         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
1994         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
1995 \r
1996         if ( out_AllocStr != NULL )  *out_AllocStr = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
1997 \r
1998         //=== fill elem\r
1999         *(TCHAR**) self->NextElem = NULL;\r
2000         memcpy( self->NextElem + sizeof(TCHAR*),  Str,  str_size );\r
2001 \r
2002         //=== link to elem from previous elem\r
2003         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
2004 \r
2005         //=== update self\r
2006         self->Prev_PointerToNextStrInPrevElem = self->PointerToNextStrInPrevElem;\r
2007         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
2008         self->NextElem = self->NextElem + elem_size;\r
2009 \r
2010         e=0;\r
2011 fin:\r
2012         return  e;\r
2013 }\r
2014 \r
2015 \r
2016  \r
2017 /***********************************************************************\r
2018   <<< [Strs_freeLast] >>> \r
2019 ************************************************************************/\r
2020 errnum_t  Strs_freeLast( Strs* self, TCHAR* AllocStr )\r
2021 {\r
2022         errnum_t  e;\r
2023         TCHAR*  str;\r
2024         TCHAR*  last_str;\r
2025         TCHAR*  prev_of_last_str;\r
2026         Strs*   mp;\r
2027         Strs*   prev_of_last_mp;\r
2028 \r
2029         if ( self->Prev_PointerToNextStrInPrevElem == NULL ) {\r
2030                 prev_of_last_str = NULL;\r
2031                 last_str = NULL;\r
2032                 for ( Strs_forEach( self, &str ) ) {\r
2033                         prev_of_last_str = last_str;\r
2034                         last_str = str;\r
2035                 }\r
2036         }\r
2037         else {\r
2038                 prev_of_last_str = (TCHAR*)( self->Prev_PointerToNextStrInPrevElem + 1 );\r
2039                 last_str = (TCHAR*)( self->PointerToNextStrInPrevElem + 1 );\r
2040         }\r
2041 \r
2042         // [ NULL     | ... ]\r
2043         IF( last_str != AllocStr ) goto err;\r
2044 \r
2045         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
2046         if ( prev_of_last_str == NULL ) {\r
2047                 self->NextElem = self->MemoryAddress + sizeof(TCHAR*);\r
2048                 self->PointerToNextStrInPrevElem = (TCHAR**) self->MemoryAddress;\r
2049         }\r
2050 \r
2051         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
2052         else if ( (char*) prev_of_last_str >= self->MemoryAddress  &&\r
2053                   (char*) prev_of_last_str <  self->MemoryOver ) {\r
2054                 self->NextElem = (char*)last_str - sizeof(TCHAR*);\r
2055                 self->PointerToNextStrInPrevElem = (TCHAR**)( (char*)prev_of_last_str - sizeof(TCHAR*) );\r
2056         }\r
2057 \r
2058         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
2059         else {\r
2060                 prev_of_last_mp = NULL;\r
2061                 for ( mp = self->FirstOfStrs;  mp->NextStrs != self;  mp = mp->NextStrs ) {\r
2062                         prev_of_last_mp = mp;\r
2063                 }\r
2064 \r
2065                 free( self->MemoryAddress );\r
2066 \r
2067                 *self = *mp;\r
2068 \r
2069                 if ( prev_of_last_mp == NULL ) {\r
2070                         self->FirstOfStrs = self;\r
2071                         self->NextStrs = NULL;\r
2072                 }\r
2073                 else {\r
2074                         prev_of_last_mp->NextStrs = self;\r
2075                 }\r
2076 \r
2077                 free( mp );\r
2078         }\r
2079         *self->PointerToNextStrInPrevElem = NULL;\r
2080         self->Prev_PointerToNextStrInPrevElem = NULL;\r
2081 \r
2082         e=0;\r
2083 fin:\r
2084         return  e;\r
2085 \r
2086 err:  e = E_OTHERS;  goto fin;\r
2087 }\r
2088 \r
2089 \r
2090  \r
2091 /***********************************************************************\r
2092   <<< [Strs_expandSize] >>> \r
2093 ************************************************************************/\r
2094 errnum_t  Strs_expandSize( Strs* self, size_t FreeSize )\r
2095 {\r
2096         Strs*   mp;\r
2097         Strs*   mp2;\r
2098         size_t  elem_size = ( sizeof(TCHAR*) + FreeSize + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
2099         size_t  memory_size;\r
2100         char*   new_memory;\r
2101 \r
2102         // [ NULL     | ... ]\r
2103         // [ FirstStr | NULL    | TCHAR[] | ... ]\r
2104         // [ FirstStr | NextStr | TCHAR[] | NULL    | TCHAR[] | ... ]\r
2105         // [ FirstStr | NextStr | TCHAR[] | NextStr | TCHAR[] ], [ NULL | TCHAR[] | ... ]\r
2106 \r
2107         while ( self->NextElem + elem_size > self->MemoryOver ) {\r
2108 \r
2109                 //=== alloc\r
2110                 mp = (Strs*) malloc( sizeof(Strs) ); IF(mp==NULL) goto err_fm;\r
2111                 memory_size = ( self->MemoryOver - self->MemoryAddress ) * 2;\r
2112                 new_memory = (char*) malloc( memory_size );\r
2113                 IF( new_memory == NULL )  { free( mp );  goto err_fm; }\r
2114 \r
2115                 //=== move old memory\r
2116                 if ( self->FirstOfStrs == self ) {\r
2117                         self->FirstOfStrs = mp;\r
2118                 }\r
2119                 else {\r
2120                         for ( mp2 = self->FirstOfStrs;  mp2->NextStrs != self;  mp2 = mp2->NextStrs );\r
2121                         mp2->NextStrs = mp;\r
2122                 }\r
2123                 *mp = *self;\r
2124                 mp->NextStrs = self;\r
2125 \r
2126                 //=== setup new memory\r
2127                 self->MemoryAddress = new_memory;\r
2128                 self->MemoryOver    = new_memory + memory_size;\r
2129                 self->NextElem      = new_memory;\r
2130                 // self->PointerToNextStrInPrevElem is same value\r
2131                 // self->FirstOfStrs is same value\r
2132                 // self->NextStrs is always NULL\r
2133         }\r
2134         return  0;\r
2135 \r
2136 err_fm:  return  E_FEW_ARRAY;\r
2137 }\r
2138 \r
2139 \r
2140 /***********************************************************************\r
2141   <<< [Strs_commit] >>>\r
2142 ************************************************************************/\r
2143 errnum_t  Strs_commit( Strs* self, TCHAR* StrOver )\r
2144 {\r
2145         size_t  elem_size;\r
2146 \r
2147         if ( StrOver == NULL )\r
2148                 { StrOver = _tcschr( (TCHAR*)( self->NextElem + sizeof(TCHAR*) ), _T('\0') ) + 1; }\r
2149         elem_size = ( ( (char*)StrOver - self->NextElem ) + sizeof(void*) - 1 ) & ~(sizeof(void*) - 1);\r
2150 \r
2151         //=== fill elem\r
2152         *(TCHAR**) self->NextElem = NULL;\r
2153 \r
2154         //=== link to elem from previous elem\r
2155         *self->PointerToNextStrInPrevElem = (TCHAR*)( self->NextElem + sizeof(TCHAR*) );\r
2156 \r
2157         //=== update self\r
2158         self->PointerToNextStrInPrevElem = (TCHAR**) self->NextElem;\r
2159         self->NextElem = self->NextElem + elem_size;\r
2160 \r
2161         return  0;\r
2162 }\r
2163 \r
2164 \r
2165  \r
2166 /***********************************************************************\r
2167   <<< [StrArr] >>> \r
2168 ************************************************************************/\r
2169 \r
2170 /*[StrArr_init]*/\r
2171 errnum_t  StrArr_init( StrArr* self )\r
2172 {\r
2173         errnum_t  e;\r
2174 \r
2175         Set2_initConst( &self->Array );\r
2176         Strs_initConst( &self->Chars );\r
2177 \r
2178         e= Set2_init( &self->Array, 0x100 ); IF(e)goto cancel;\r
2179         e= Strs_init( &self->Chars ); IF(e)goto cancel;\r
2180         return  0;\r
2181 \r
2182 cancel:  StrArr_finish( self, e );  return  e;\r
2183 }\r
2184 \r
2185 \r
2186 /*[StrArr_finish]*/\r
2187 errnum_t  StrArr_finish( StrArr* self, errnum_t e )\r
2188 {\r
2189         if ( ! Set2_isInited( &self->Array ) )  return  0;\r
2190 \r
2191         e= Set2_finish( &self->Array, e );\r
2192         e= Strs_finish( &self->Chars, e );\r
2193         return  e;\r
2194 }\r
2195 \r
2196 \r
2197 /*[StrArr_add]*/\r
2198 errnum_t  StrArr_add( StrArr* self, const TCHAR* Str, int* out_I )\r
2199 {\r
2200         errnum_t  e;\r
2201 \r
2202         e= StrArr_expandCount( self, _tcslen( Str ) ); IF(e)goto fin;\r
2203         _tcscpy_s( StrArr_getFreeAddr( self ), StrArr_getFreeCount( self ), Str );\r
2204         e= StrArr_commit( self ); IF(e)goto fin;\r
2205         if ( out_I != NULL )  *out_I = Set2_getCount( &self->Array, TCHAR* ) - 1;\r
2206 \r
2207         e=0;\r
2208 fin:\r
2209         return  e;\r
2210 }\r
2211 \r
2212 \r
2213 /*[StrArr_commit]*/\r
2214 errnum_t  StrArr_commit( StrArr* self )\r
2215 {\r
2216         errnum_t  e;\r
2217         TCHAR*   p;\r
2218         TCHAR**  pp  = NULL;\r
2219         Set2*    arr = &self->Array;\r
2220         Strs*    ss  = &self->Chars;\r
2221 \r
2222         p = Strs_getFreeAddr( ss );\r
2223         e= Set2_alloc( arr, &pp, TCHAR* ); IF(e)goto fin;\r
2224         e= Strs_commit( ss, NULL ); IF(e)goto fin;\r
2225         *pp = p;\r
2226 \r
2227         e=0;\r
2228 fin:\r
2229         if ( e &&  pp != NULL )  e= Set2_freeLast( arr, pp, TCHAR*, e );\r
2230         return  e;\r
2231 }\r
2232 \r
2233 \r
2234 /*[StrArr_fillTo]*/\r
2235 errnum_t  StrArr_fillTo( StrArr* self, int n, const TCHAR* Str )\r
2236 {\r
2237         errnum_t  e;\r
2238         const TCHAR*   p;\r
2239         const TCHAR**  pp;\r
2240         const TCHAR**  pp_over;\r
2241 \r
2242         n -= Set2_getCount( &self->Array, TCHAR* );\r
2243         if ( n <= 0 ) return 0;\r
2244 \r
2245         if ( Str == NULL ) {\r
2246                 p = NULL;\r
2247         }\r
2248         else {\r
2249                 e= Strs_add( &self->Chars, Str, &p ); IF(e)goto fin;\r
2250         }\r
2251 \r
2252         e= Set2_allocMulti( &self->Array, &pp, TCHAR*, n ); IF(e)goto fin;\r
2253         pp_over = pp + n;\r
2254         for ( ;  pp < pp_over;  pp++ )\r
2255                 *pp = p;\r
2256 \r
2257         e=0;\r
2258 fin:\r
2259         return  e;\r
2260 }\r
2261 \r
2262 \r
2263 /*[StrArr_toEmpty]*/\r
2264 errnum_t  StrArr_toEmpty( StrArr* self )\r
2265 {\r
2266         errnum_t  e, ee;\r
2267 \r
2268         e=0;\r
2269         ee= Set2_toEmpty( &self->Array ); IF(ee&&!e)e=ee;\r
2270         ee= Strs_toEmpty( &self->Chars ); IF(ee&&!e)e=ee;\r
2271         return  e;\r
2272 }\r
2273 \r
2274 \r
2275  \r
2276 /***********************************************************************\r
2277   <<< [StrArr_parseCSV] >>> \r
2278 ************************************************************************/\r
2279 errnum_t  StrArr_parseCSV( StrArr* self, const TCHAR* CSVLine )\r
2280 {\r
2281         errnum_t      e;\r
2282         const TCHAR*  p = CSVLine;\r
2283 \r
2284         e= StrArr_toEmpty( self ); IF(e)goto fin;\r
2285 \r
2286         do {\r
2287                 e= StrT_meltCSV( StrArr_getFreeAddr( self ), StrArr_getFreeSize( self ), &p );\r
2288                 if ( e == E_FEW_ARRAY ) {\r
2289                         e= StrArr_expandSize( self, StrArr_getFreeSize( self ) * 2 ); IF(e)goto fin;\r
2290                         continue;\r
2291                 }\r
2292                 IF(e)goto fin;\r
2293 \r
2294                 e = StrArr_commit( self ); IF(e)goto fin;\r
2295         } while ( p != NULL );\r
2296 \r
2297         e=0;\r
2298 fin:\r
2299         return  e;\r
2300 }\r
2301 \r
2302 \r
2303  \r
2304 /*=================================================================*/\r
2305 /* <<< [SetX/SetX.c] >>> */ \r
2306 /*=================================================================*/\r
2307  \r
2308 /***********************************************************************\r
2309   <<< [Set2_init] >>> \r
2310 ************************************************************************/\r
2311 int  Set2_init( Set2* m, int FirstSize )\r
2312 {\r
2313         m->First = malloc( FirstSize );\r
2314         if ( m->First == NULL )  return  E_FEW_MEMORY;\r
2315         m->Next = m->First;\r
2316         m->Over = (char*)m->First + FirstSize;\r
2317 \r
2318         #ifdef _DEBUG\r
2319         m->PointerOfDebugArray = NULL;\r
2320         #endif\r
2321 \r
2322         return  0;\r
2323 }\r
2324  \r
2325 /***********************************************************************\r
2326   <<< [Set2_finish] >>> \r
2327 ************************************************************************/\r
2328 int  Set2_finish( Set2* m, int e )\r
2329 {\r
2330         if ( m->First != NULL )  { free( m->First );  m->First = NULL; }\r
2331         return  e;\r
2332 }\r
2333 \r
2334  \r
2335 /***********************************************************************\r
2336   <<< [Set2_ref_imp] >>> \r
2337 ************************************************************************/\r
2338 int  Set2_ref_imp( Set2* m, int iElem, void* out_pElem, size_t ElemSize )\r
2339 {\r
2340         int    e;\r
2341         char*  p;\r
2342 \r
2343         IF( iElem < 0 ) goto err_ns;\r
2344         p = (char*) m->First + ( (unsigned)iElem * ElemSize );\r
2345         IF( p >= (char*)m->Next ) goto err_ns;\r
2346         *(char**)out_pElem = p;\r
2347 \r
2348         e=0;\r
2349 fin:\r
2350         return  e;\r
2351 \r
2352 err_ns:  e = E_NOT_FOUND_SYMBOL;  goto fin;\r
2353 }\r
2354 \r
2355 \r
2356  \r
2357 /***********************************************************************\r
2358   <<< [Set2_alloc_imp] >>> \r
2359 ************************************************************************/\r
2360 int  Set2_alloc_imp( Set2* m, void* pp, size_t size )\r
2361 {\r
2362         int  e;\r
2363 \r
2364         e= Set2_expandIfOverByAddr( m, (char*) m->Next + size ); IF(e)goto fin;\r
2365         *(void**)pp = m->Next;\r
2366         m->Next = (char*) m->Next + size;\r
2367 \r
2368         MEMSET_TO_NOT_INIT( *(void**)pp, size );\r
2369 \r
2370         e=0;\r
2371 fin:\r
2372         return  e;\r
2373 }\r
2374 \r
2375 \r
2376 int  Set2_allocMulti_sub( Set2* m, void* out_pElem, size_t ElemsSize )\r
2377 {\r
2378         int    e;\r
2379         char*  p;\r
2380 \r
2381         e= Set2_expandIfOverByAddr( m, (char*) m->Next + ElemsSize ); IF(e)goto fin;\r
2382         p = (char*) m->Next;\r
2383         m->Next = p + ElemsSize;\r
2384         *(char**)out_pElem = p;\r
2385 \r
2386         e=0;\r
2387 fin:\r
2388         return  e;\r
2389 }\r
2390 \r
2391 \r
2392  \r
2393 /***********************************************************************\r
2394   <<< [Set2_expandIfOverByAddr_imp] >>> \r
2395 ************************************************************************/\r
2396 int  Set2_expandIfOverByAddr_imp( Set2* m, void* OverAddrBasedOnNowFirst )\r
2397 {\r
2398         void*     new_first;\r
2399         unsigned  offset_of_over;\r
2400         unsigned  offset_of_next;\r
2401 \r
2402         if ( OverAddrBasedOnNowFirst <= m->Over )  return  E_OTHERS;\r
2403 \r
2404         offset_of_next = (unsigned)( (char*)OverAddrBasedOnNowFirst - (char*)m->First );\r
2405         offset_of_over = (unsigned)( ( (char*)m->Over - (char*)m->First ) ) * 2;\r
2406         IF_D( offset_of_next >= 0x80000000 ) goto err;\r
2407         while ( offset_of_over < offset_of_next )  offset_of_over *= 2;\r
2408         IF( offset_of_over >= 0x10000000 ) goto err;\r
2409 \r
2410         new_first = realloc( m->First, offset_of_over * 2 );\r
2411         IF( new_first == NULL ) goto err_fm;\r
2412 \r
2413         m->Next = (char*) new_first + ( (char*)m->Next - (char*)m->First );\r
2414         m->Over = (char*) new_first + offset_of_over * 2;\r
2415         m->First = new_first;\r
2416 \r
2417         #ifdef _DEBUG\r
2418         if ( m->PointerOfDebugArray != NULL )\r
2419                 { *m->PointerOfDebugArray = m->First; }\r
2420         #endif\r
2421 \r
2422         return  0;\r
2423 \r
2424 err:     return  E_OTHERS;\r
2425 err_fm:  return  E_FEW_MEMORY;\r
2426 }\r
2427 \r
2428  \r
2429 /***********************************************************************\r
2430   <<< [Set2_separate] >>> \r
2431 ************************************************************************/\r
2432 int  Set2_separate( Set2* m, int NextSize, void** allocate_Array )\r
2433 {\r
2434         int    e;\r
2435         void*  p = m->First;\r
2436 \r
2437         if ( NextSize == 0 ) {\r
2438                 MEMSET_TO_NOT_INIT( m, sizeof(*m) );\r
2439                 m->First = NULL;\r
2440         }\r
2441         else {\r
2442                 e= Set2_init( m, NextSize ); IF(e)goto fin;\r
2443         }\r
2444         *allocate_Array = p;\r
2445 \r
2446         e=0;\r
2447 fin:\r
2448         return  e;\r
2449 }\r
2450 \r
2451 \r
2452  \r
2453 /***********************************************************************\r
2454   <<< [Set2_setDebug] >>> \r
2455 ************************************************************************/\r
2456 #ifdef _DEBUG\r
2457 void  Set2_setDebug( Set2* m, void** PointerOfDebugArray )\r
2458 {\r
2459         m->PointerOfDebugArray = PointerOfDebugArray;\r
2460         *m->PointerOfDebugArray = m->First;\r
2461 }\r
2462 #endif\r
2463 \r
2464 \r
2465  \r
2466 /*=================================================================*/\r
2467 /* <<< [Print/Print2.c] >>> */ \r
2468 /*=================================================================*/\r
2469  \r
2470 /***********************************************************************\r
2471   <<< [vsprintf_r] >>> \r
2472 ************************************************************************/\r
2473 errnum_t  vsprintf_r( char* s, size_t s_size, const char* format, va_list va )\r
2474 {\r
2475         #if _MSC_VER\r
2476                 #pragma warning(push)\r
2477                 #pragma warning(disable: 4996)\r
2478         #endif\r
2479 \r
2480         int  r = _vsnprintf( s, s_size, format, va );\r
2481 \r
2482         #if _MSC_VER\r
2483                 #pragma warning(pop)\r
2484         #endif\r
2485 \r
2486         IF( r == (int) s_size )\r
2487                 { s[s_size-1] = '\0';  return E_FEW_ARRAY; }\r
2488         IF( r == -1 )\r
2489                 { return E_NOT_FOUND_SYMBOL; }  /* Bad character code */\r
2490 \r
2491         return  0;\r
2492 }\r
2493 \r
2494 \r
2495  \r
2496 /***********************************************************************\r
2497   <<< [vswprintf_r] >>> \r
2498 ************************************************************************/\r
2499 #ifndef  __linux__\r
2500 errnum_t  vswprintf_r( wchar_t* s, size_t s_size, const wchar_t* format, va_list va )\r
2501 {\r
2502         size_t  tsize = s_size / sizeof(wchar_t);\r
2503 \r
2504         #pragma warning(push)\r
2505         #pragma warning(disable: 4996)\r
2506                 int  r = _vsnwprintf( s, tsize, format, va );\r
2507         #pragma warning(pop)\r
2508 \r
2509         if ( r == (int) tsize || r == -1 ) { s[tsize-1] = '\0';  return E_FEW_ARRAY; }\r
2510         else  return  0;\r
2511 }\r
2512 #endif\r
2513 \r
2514 \r
2515  \r
2516 /***********************************************************************\r
2517   <<< [stprintf_r] >>> \r
2518 ************************************************************************/\r
2519 errnum_t  stprintf_r( TCHAR* s, size_t s_size, const TCHAR* format, ... )\r
2520 {\r
2521         errnum_t  e;\r
2522         va_list   va;\r
2523 \r
2524         va_start( va, format );\r
2525         e = vstprintf_r( s, s_size, format, va );\r
2526         va_end( va );\r
2527         return  e;\r
2528 }\r
2529 \r
2530 \r
2531  \r
2532 /***********************************************************************\r
2533   <<< [stcpy_part_r] >>> \r
2534 ************************************************************************/\r
2535 errnum_t  stcpy_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
2536                    const TCHAR* src, const TCHAR* src_over )\r
2537 {\r
2538         size_t  s_space = (char*)s + s_size - (char*)s_start;\r
2539         size_t  src_size;\r
2540 \r
2541         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size )  { return 1; }\r
2542 \r
2543         if ( src_over == NULL )  { src_over = _tcschr( src, _T('\0') ); }\r
2544         src_size = (char*)src_over - (char*)src;\r
2545         IF ( src_size >= s_space ) {\r
2546                 s_space -= sizeof(TCHAR);\r
2547                 memcpy( s, src, s_space );\r
2548 \r
2549                 s_start = (TCHAR*)((char*)s_start + s_space );\r
2550                 *s_start = '\0';\r
2551 \r
2552                 if ( p_s_last != NULL ) { *p_s_last=s_start; }\r
2553                 return  E_FEW_ARRAY;\r
2554         }\r
2555 \r
2556         memcpy( s_start, src, src_size + sizeof(TCHAR) );\r
2557         s_start = (TCHAR*)((char*)s_start + src_size);  *s_start = _T('\0');\r
2558         if ( p_s_last != NULL )  { *p_s_last = s_start; }\r
2559 \r
2560         return  0;\r
2561 }\r
2562 \r
2563 \r
2564  \r
2565 /***********************************************************************\r
2566   <<< [stprintf_part_r] >>> \r
2567 ************************************************************************/\r
2568 errnum_t  stprintf_part_r( TCHAR* s, size_t s_size, TCHAR* s_start, TCHAR** p_s_last,\r
2569                       const TCHAR* format, ... )\r
2570 {\r
2571         errnum_t  e;\r
2572         va_list   va;\r
2573         va_start( va, format );\r
2574 \r
2575         IF_D( s_start < s || (char*)s_start >= (char*)s + s_size ) {return E_OTHERS;}\r
2576 \r
2577         e = vstprintf_r( s_start, s_size - ( (char*)s_start - (char*)s), format, va );\r
2578         va_end( va );  if ( p_s_last != NULL )  *p_s_last = _tcschr( s_start, '\0' );\r
2579         return  e;\r
2580 }\r
2581 \r
2582  \r
2583 /*=================================================================*/\r
2584 /* <<< [Error4/Error4.c] >>> */ \r
2585 /*=================================================================*/\r
2586  \r
2587 /***********************************************************************\r
2588   <<< [Get_Error4_Variables] >>> \r
2589 ************************************************************************/\r
2590 static Error4_VariablesClass  gs;\r
2591 #ifdef _DEBUG\r
2592         extern Error4_VariablesClass*  g_Error4_Variables = &gs;\r
2593 #endif\r
2594 \r
2595 Error4_VariablesClass*  Get_Error4_Variables()\r
2596 {\r
2597         return  &gs;\r
2598 }\r
2599 \r
2600 \r
2601  \r
2602 /***********************************************************************\r
2603   <<< [SetBreakErrorID] >>> \r
2604 ************************************************************************/\r
2605 #if ERR2_ENABLE_ERROR_BREAK\r
2606 \r
2607 dll_global_g_DebugBreakCount Err2  g_Err2;  /* \8f\89\8aú\92l\82Í\82·\82×\82Ä\83[\83\8d */\r
2608 \r
2609 void  SetBreakErrorID( int ID )\r
2610 {\r
2611         Err2*  m = &g_Err2;\r
2612 \r
2613         m->BreakErrID = ID;\r
2614 }\r
2615 \r
2616 \r
2617 int  TryOnIfTrue_imp( const char* FilePath, int LineNum )\r
2618  // \95Ô\82è\92l\82Í\81A\83u\83\8c\81[\83N\82·\82é\82©\82Ç\82¤\82©\r
2619 {\r
2620         //=== \83G\83\89\81[\8e\9e\82Ì\92\86\92f\8f\88\97\9d\81i\83W\83\83\83\93\83v\81j\82ð\82µ\82Ä\82¢\82é\82Æ\82«\r
2621         if ( g_Err2.IsErr )  return  0;\r
2622 \r
2623 \r
2624         //=== \83G\83\89\81[\82ª\8f\89\82ß\82Ä\8bN\82«\82½\82Æ\82«\r
2625         else {\r
2626                 Err2*  m = &g_Err2;\r
2627 \r
2628                 m->IsErr = 1;\r
2629                 m->ErrID ++;\r
2630                 m->FilePath = FilePath;\r
2631                 m->LineNum = LineNum;\r
2632 \r
2633                 #if ERR2_ENABLE_ERROR_LOG\r
2634                         printf( "<ERRORLOG msg=\"raised\" err_id=\"%d\" g_err2=\"0x%08X\"/>\n", m->ErrID, (int) m );\r
2635                 #endif\r
2636 \r
2637                 return  ( m->ErrID == m->BreakErrID );\r
2638         }\r
2639 }\r
2640 \r
2641 \r
2642 //[ClearError]\r
2643 void  ClearError()\r
2644 {\r
2645         Err2*  m = &g_Err2;\r
2646 \r
2647         #if ERR2_ENABLE_ERROR_LOG\r
2648         if ( m->IsErr != 0 )\r
2649                 printf( "<ERRORLOG msg=\"cleared\" err_id=\"%d\" g_err2=\"0x%08X\"/>\n", m->ErrID, (int) m );\r
2650         #endif\r
2651 \r
2652         m->IsErr = 0;\r
2653 }\r
2654 \r
2655 \r
2656 //[IsErrorMode]\r
2657 bool  IsErrorMode()\r
2658 {\r
2659         return  ( g_Err2.IsErr != 0 );\r
2660 }\r
2661 \r
2662 \r
2663 //[IfErrThenBreak]\r
2664 void  IfErrThenBreak()\r
2665 {\r
2666         if ( g_Err2.IsErr && ( g_Err2.ErrID != g_Err2.BreakErrID || g_Err2.BreakErrID == 0 ) ) {  TestableDebugBreak();\r
2667                 // \83E\83H\83b\83`\82Å\81Ag_Err2.ErrID \82Ì\92l(N\82Æ\82·\82é)\82ð\8am\94F\82µ\82Ä\81A\r
2668                 // \83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( N ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\r
2669                 // \83G\83\89\81[\82ª\94­\90\82µ\82½\8fê\8f\8a\82Í\81Ag_Err2.FilePath, g_Err2.LineNum \82Å\82·\81B\r
2670                 // \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
2671                 // ClearError() \82ð\96Y\82ê\82Ä\82¢\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
2672                 #if ERR2_ENABLE_ERROR_LOG\r
2673                         printf( "<ERRORLOG msg=\"IfErrThenBreak\" ErrID=\"%d\" BreakErrID=\"%d\"/>\n", g_Err2.ErrID, g_Err2.BreakErrID );\r
2674                 #endif\r
2675 \r
2676                 {\r
2677                         char  str[512];\r
2678                         sprintf_s( str, _countof(str), "<ERROR file=\"%s(%d)\"/>\n", g_Err2.FilePath, g_Err2.LineNum );\r
2679                         OutputDebugStringA( str );\r
2680                 }\r
2681         }\r
2682         ClearError();\r
2683 }\r
2684 \r
2685 //[PushErr]\r
2686 void  PushErr( ErrStackAreaClass* ErrStackArea )\r
2687 {\r
2688         ErrStackArea->ErrID = g_Err2.ErrID;\r
2689         ErrStackArea->IsErr = g_Err2.IsErr;\r
2690         g_Err2.IsErr = 0;\r
2691 }\r
2692 \r
2693 //[PopErr]\r
2694 void  PopErr(  ErrStackAreaClass* ErrStackArea )\r
2695 {\r
2696         if ( ErrStackArea->IsErr )\r
2697                 g_Err2.IsErr = 1;\r
2698 }\r
2699 \r
2700 \r
2701 #endif // ERR2_ENABLE_ERROR_BREAK\r
2702 \r
2703  \r
2704 /***********************************************************************\r
2705   <<< [g_Error4_String] >>> \r
2706 ************************************************************************/\r
2707 TCHAR  g_Error4_String[4096];\r
2708 \r
2709 \r
2710  \r
2711 /***********************************************************************\r
2712   <<< [Error4_printf] >>> \r
2713 ************************************************************************/\r
2714 void  Error4_printf( const TCHAR* format, ... )\r
2715 {\r
2716         va_list  va;\r
2717         va_start( va, format );\r
2718         vstprintf_r( g_Error4_String, sizeof(g_Error4_String), format, va );\r
2719         va_end( va );\r
2720 }\r
2721 \r
2722 \r
2723  \r
2724 /***********************************************************************\r
2725   <<< [Error4_getErrStr] >>> \r
2726 ************************************************************************/\r
2727 void  Error4_getErrStr( int ErrNum, TCHAR* out_ErrStr, size_t ErrStrSize )\r
2728 {\r
2729         switch ( ErrNum ) {\r
2730 \r
2731                 case  0:\r
2732                         stprintf_r( out_ErrStr, ErrStrSize, _T("no error") );\r
2733                         break;\r
2734 \r
2735                 #ifndef  __linux__\r
2736                 case  E_GET_LAST_ERROR: {\r
2737                         DWORD   err_win;\r
2738                         TCHAR*  str_pointer;\r
2739 \r
2740                         err_win = gs.WindowsLastError;\r
2741                         if ( err_win == 0 ) { err_win = GetLastError(); }\r
2742 \r
2743                         stprintf_part_r( out_ErrStr, ErrStrSize, out_ErrStr, &str_pointer,\r
2744                                 _T("<ERROR GetLastError=\"0x%08X\" GetLastErrorStr=\""), err_win );\r
2745                         FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,\r
2746                                 NULL, err_win, LANG_USER_DEFAULT,\r
2747                                 str_pointer,  (TCHAR*)( (char*)out_ErrStr + ErrStrSize ) - str_pointer, NULL );\r
2748                         str_pointer = _tcschr( str_pointer, _T('\0') );\r
2749                         if ( *( str_pointer - 2 ) == _T('\r') && *( str_pointer - 1 ) == _T('\n') )\r
2750                                 str_pointer -= 2;\r
2751                         stcpy_part_r( out_ErrStr, ErrStrSize, str_pointer, NULL, _T("\"/>"), NULL );\r
2752                         break;\r
2753                 }\r
2754                 #endif\r
2755 \r
2756                 default:\r
2757                         if ( g_Error4_String[0] != '\0' )\r
2758                                 stprintf_r( out_ErrStr, ErrStrSize, _T("%s"), g_Error4_String );\r
2759                         else\r
2760                                 stprintf_r( out_ErrStr, ErrStrSize, _T("<ERROR errnum=\"%d\"/>"), ErrNum );\r
2761                         break;\r
2762         }\r
2763 }\r
2764 \r
2765 \r
2766  \r
2767 /***********************************************************************\r
2768   <<< [SaveWindowsLastError] >>> \r
2769 ************************************************************************/\r
2770 errnum_t  SaveWindowsLastError()\r
2771 {\r
2772         gs.WindowsLastError = GetLastError();\r
2773         return  E_GET_LAST_ERROR;\r
2774 }\r
2775 \r
2776 \r
2777  \r
2778 /***********************************************************************\r
2779   <<< [Error4_showToStdErr] >>> \r
2780 ************************************************************************/\r
2781 void  Error4_showToStdErr( int err_num )\r
2782 {\r
2783         TCHAR  msg[1024];\r
2784         #if _UNICODE\r
2785                 char  msg2[1024];\r
2786         #endif\r
2787 \r
2788         if ( err_num != 0 ) {\r
2789                 Error4_getErrStr( err_num, msg, sizeof(msg) );\r
2790                 #if _UNICODE\r
2791                         setlocale( LC_ALL, ".OCP" );\r
2792                         sprintf_s( msg2, sizeof(msg2), "%S", msg );\r
2793                         fprintf( stderr, "%s\n", msg2 );  // _ftprintf_s \82Å\82Í\93ú\96{\8cê\82ª\8fo\82Ü\82¹\82ñ\r
2794                 #else\r
2795                         fprintf( stderr, "%s\n", msg );\r
2796                 #endif\r
2797 \r
2798                 #if ERR2_ENABLE_ERROR_BREAK\r
2799                         fprintf( stderr, "\81i\8aJ\94­\8eÒ\82Ö\81j\83\81\83C\83\93\8aÖ\90\94\82Å SetBreakErrorID( %d ); \82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B\n",\r
2800                                 g_Err2.ErrID );\r
2801                 #else\r
2802 #if 0\r
2803                         if ( err_num == E_FEW_MEMORY  ||  gs.WindowsLastError == ERROR_NOT_ENOUGH_MEMORY ) {\r
2804                                 /* Not show the message for developper */\r
2805                         }\r
2806                         else {\r
2807                                 fprintf( stderr, "\81i\8aJ\94­\8eÒ\82Ö\81jERR2_ENABLE_ERROR_BREAK \82ð\92è\8b`\82µ\82Ä\8dÄ\83R\83\93\83p\83C\83\8b\82µ\82Ä\82­\82¾\82³\82¢\81B\n" );\r
2808                         }\r
2809 #endif\r
2810                 #endif\r
2811         }\r
2812         IfErrThenBreak();\r
2813 }\r
2814 \r
2815 \r
2816  \r
2817 /***********************************************************************\r
2818   <<< [Error4_raiseErrno] >>> \r
2819 ************************************************************************/\r
2820 #include <errno.h>\r
2821 \r
2822 int  Error4_raiseErrno()\r
2823 {\r
2824         int   e, e2;\r
2825         TCHAR  msg[256];\r
2826 \r
2827         e2 = _get_errno( &e );\r
2828         if ( e2 != 0 )  { Error4_printf( _T("ERROR in _get_errno") );  return  E_UNKNOWN; }\r
2829         e2 = _tcserror_s( msg, sizeof(msg)/sizeof(TCHAR), e );\r
2830         if ( e2 != 0 )  { Error4_printf( _T("ERROR in strerror_s") );  return  E_UNKNOWN; }\r
2831 \r
2832         Error4_printf( _T("ERROR (%d) %s\n"), e, msg );\r
2833         return  E_ERRNO;\r
2834 }\r
2835 \r
2836 \r
2837  \r
2838 /*=================================================================*/\r
2839 /* <<< [DebugTools/DebugTools.c] >>> */ \r
2840 /*=================================================================*/\r
2841  \r
2842 /***********************************************************************\r
2843   <<< [TestableDebugBreak] >>> \r
2844 ************************************************************************/\r
2845 dll_global_g_DebugBreakCount int  g_bTestableDebugBreak_Disable;\r
2846 dll_global_g_DebugBreakCount int  g_DebugBreakCount;\r
2847 \r
2848 \r
2849  \r
2850 /***********************************************************************\r
2851   <<< [TestableDebugBreak_isEnabled] >>> \r
2852 ************************************************************************/\r
2853 int  TestableDebugBreak_isEnabled()\r
2854 {\r
2855         return  g_bTestableDebugBreak_Disable == 0;\r
2856 }\r
2857 \r
2858 \r
2859  \r