Filefind.c
[目次 | 関数 | マクロ]
1|/**************************************************************************
2| 1. <<< ファイル列挙 (FileFind) >>>
3|【役割】
4|・カレントフォルダにあるファイル名を列挙します。
5|【補足】
6|・フォルダをネストして列挙する場合、NestFind クラスを用います。
7|・VC++ 1.5 では使えません。
8|***************************************************************************/
9|
10|#ifdef USES_MXP_AUTOINC
11| #include "filefind.ah" /* Auto include header, Look at mixer-... folder */
12|#else
13| #include "all.h"
14|#endif
15|#ifndef USES_STRX
16|#error need STRX
17|#endif
18|
19|#include <string.h>
20|#ifdef _UNIX
21| #include <stdlib.h>
22| static char CmdLine[256];
23| static char FileName[256];
24| #define BatName "~files_sub.bat" /* 内部で実行するバッチファイル名 */
25| #define OutName "~files_out.txt" /*バッチファイルで出力されるファイル名*/
26| #define TmpName "~nil.txt"/*エラーメッセージ消去用・テンポラリファイル名*/
27|#endif
28|
29|
30|
31|/**************************************************************************
32| 2. <<< [FileFind_init] 列挙するパスを設定して初期化する >>>
33|【引数】
34| ・const char* path; 列挙するファイルを含むフォルダのパス
35|【補足】
36|・初期化しただけでは、FileFind_getFName 関数などを用いてファイル情報を
37| 参照することは出来ません。FileFind_next 関数を呼んでください。
38|***************************************************************************/
39|#ifdef _K_AND_R
40| void FileFind_init( m, path )
41| FileFind* m;
42| char* path;
43|#else
44| void FileFind_init( FileFind* m, const char* path )
45|#endif
46|{
47| #ifdef _MSC_VER
48| static char path2[256];
49|
50| strcpy( path2, path );
51| StrX_setLast( path2, '\\' );
52| strcat( path2, "*.*" );
53| m->handle = _findfirst( path2, &m->data );
54| m->bFirst = true;
55| #endif /* _MSC_VER */
56| /*-----------------------------------------------------*/
57| #ifdef _UNIX
58| FILE* fbat;
59|
60| /* オブジェクトの初期化 */
61| *m->FileName = 0;
62| m->file = NULL; /* 後で open する */
63|
64| /* ファイル名一覧ファイルの作成 */
65| sprintf( FileName, "%s.%p", BatName, m );
66| fbat = fopen( FileName, "wt" );
67|
68| if ( fbat == NULL ) {
69| fprintf( stderr, "Can't create script file in FileFind_New()." );
70| exit(1);
71| }
72|
73| fprintf( fbat, "%s%s%s.%p%s%s%s%s%s%s%s%s%s.%p%s%s%s%s.%p%s%s%s%s%s%s",
74| "#csh\n",
75| "rm ", OutName, m, " >& ", TmpName, "\n",
76| "foreach name ( ", path, " ) \n",
77| " if ( -d $name ) then \n",
78| " echo \"$name/\" >> ", OutName, m, "\n",
79| " else\n",
80| " echo \"$name\" >> ", OutName, m, "\n",
81| " endif\n",
82| "end\n",
83| "rm ", TmpName, "\n" );
84|
85| fclose( fbat );
86|
87| sprintf( CmdLine, "chmod +x %s.%p", BatName, m );
88| system( CmdLine );
89|
90| sprintf( CmdLine, "csh %s.%p", BatName, m );
91| system( CmdLine );
92|
93| sprintf( CmdLine, "rm %s.%p", BatName, m );
94| system( CmdLine );
95|
96| /*--- ファイル名一覧ファイルの open ---*/
97| sprintf( FileName, "%s.%p", OutName, m );
98| m->file = fopen( FileName, "rt" );
99|
100| if ( m->file == NULL ) {
101| fprintf( stderr, "Can't open %s.%p in FileFind_New().\n", OutName, m );
102| exit(1);
103| }
104| #endif /* _UNIX */
105|
106| m->bCutParent = false;
107|}
108|
109|
110|
111|/**************************************************************************
112| 3. <<< [FileFind_init2] . と .. を取得しないように初期化する >>>
113|【補足】
114|・FileFind_next 関数で次のファイル名やフォルダ名を取得するとき、.(カレント)と
115| ..(親ディレクトリ)を取得しません。それ以外は、FileFind_init と同じです。
116|***************************************************************************/
117|#ifdef _K_AND_R
118| void FileFind_init2( m, path )
119| FileFind* m;
120| char* path;
121|#else
122| void FileFind_init2( FileFind* m, const char* path )
123|#endif
124|{
125| FileFind_init( m, path );
126| m->bCutParent = true;
127|}
128|
129|
130|
131|/**************************************************************************
132| 4. <<< [FileFind_next] カレント・ファイルを次のファイルに移動する >>>
133|【引数】
134| ・返り値 : 0=次の候補はある, 1=ない
135|***************************************************************************/
136|#ifdef _K_AND_R
137| int FileFind_next( m )
138| FileFind* m;
139|#else
140| int FileFind_next( FileFind* m )
141|#endif
142|{
143| int ret;
144|
145| do {
146|
147| #ifdef _MSC_VER
148| if ( m->bFirst ) {
149| if ( m->handle == -1 ) return 1;
150| m->bFirst = false;
151| ret = 0;
152| }
153| else {
154| ret = ( _findnext( m->handle, &m->data ) == -1 );
155| }
156| #endif /* _MSC_VER */
157|
158| /*-----------------------------------------------------*/
159|
160| #ifdef _UNIX
161| char* ret;
162|
163| for(;;) {
164| ret = fgets( m->FileName, 256, m->file );
165|
166| if ( ret != NULL ) {
167| char* p;
168|
169| StrX_BS( m->FileName );
170| /* m->FileName[ strlen( m->FileName ) - 1 ] = '\0';*/
171|
172| if ( StrX_Last( m->FileName ) == '/' ) {
173| StrX_BS( m->FileName );
174| m->IsDir = true;
175| }
176| else
177| m->IsDir = false;
178|
179| if ( ( p = StrX_RSearch( m->FileName, "/" ) ) != NULL ) {
180| memmove( m->FileName, p+1, strlen( p+1 ) + 1 );
181| }
182| sprintf( FileName, "%s.%p", OutName, m );
183| if ( strncmp( m->FileName, OutName, strlen(OutName) ) == 0 )
184| continue;
185| ret = 0;
186| }
187| else {
188| ret = 1;
189| }
190| }
191| #endif /* _UNIX */
192|
193| if ( ret == 1 || ! m->bCutParent ) break;
194| } while ( strcmp( FileFind_getFName( m ), "." ) == 0 ||
195| strcmp( FileFind_getFName( m ), ".." ) == 0 );
196|
197| return ret;
198|}
199|
200|
201|
202|/**************************************************************************
203| 5. <<< [FileFind_finish] 後始末する >>>
204|***************************************************************************/
205|#ifdef _K_AND_R
206| void FileFind_finish( m )
207| FileFind* m;
208|#else
209| void FileFind_finish( FileFind* m )
210|#endif
211|{
212| #ifdef _MSC_VER
213| _findclose( m->handle );
214| #endif /* _MSC_VER */
215| #ifdef _UNIX
216| fclose( m->file );
217|
218| sprintf( CmdLine, "rm %s.%p", OutName, m );
219| system( CmdLine );
220| #endif /* _UNIX */
221|}
222|
223|/**************************************************************************
224| 6. <<< [FileFind_getN] フォルダに含まれるファイルやフォルダの数を返す >>>
225|【引数】
226| ・char* path; フォルダパス
227| ・bool bPlusFolder フォルダをカウントするかどうか
228| ・bool bPlusFile ファイルをカウントするかどうか
229| ・int 返り値; フォルダ数、ファイル数またはその合計
230|***************************************************************************/
231|int FileFind_getN( const char* path, bool bPlusFolder, bool bPlusFile )
232|{
233| int i;
234| int handle;
235| struct _finddata_t data;
236| int flag;
237| char path2[_MAX_PATH];
238|
239| /* data.attrib と比較する値 flag を求める */
240| if ( bPlusFolder ) {
241| if ( bPlusFile ) flag = ~_A_SUBDIR; /* xor で必ず 非0 になる値 */
242| else flag = 0;
243| }
244| else {
245| if ( bPlusFile ) flag = _A_SUBDIR;
246| else return 0;
247| }
248|
249| /* ワイルドカード "*.*" を含めたパス path2 を求める */
250| strcpy( path2, path );
251| StrX_setLast( path2, '\\' );
252| strcat( path2, "*.*" );
253|
254| /* ファイル数・フォルダ数をカウントする */
255| i = 0;
256| handle = _findfirst( path2, &data );
257| if ( handle != -1 ) {
258| do {
259| if ( ( ( data.attrib & _A_SUBDIR ) ^ flag ) != 0 &&
260| strcmp( data.name, "." ) != 0 && strcmp( data.name, ".." ) != 0 ) {
261| i++;
262| }
263| } while ( _findnext( handle, &data ) != -1 );
264| }
265| _findclose( handle );
266|
267| return i;
268|}
269|
270|