Skip to content

Commit 40fe396

Browse files
committed
商用COBOLに存在するC$LIST-DIRECTORYルーチンを実装しました
* 関数C$LIST-DIRECTORYに対応する「cob_acuw_list_directory」を追加 * TODO:ハンドルについては現在サポートせず、グローバルでの管理となっている
1 parent 38331ec commit 40fe396

7 files changed

Lines changed: 184 additions & 2 deletions

File tree

libcob/fileio.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
#include <fcntl.h>
5757
#endif
5858

59+
#ifndef _WIN32
60+
#include <dirent.h>
61+
#endif
62+
5963
#ifdef _WIN32
6064

6165
#define WIN32_LEAN_AND_MEAN
@@ -199,6 +203,14 @@ struct cobsort {
199203

200204
/* End SORT definitions */
201205

206+
#ifdef _WIN32
207+
HANDLE listdir_handle;
208+
LPWIN32_FIND_DATA listdir_filedata;
209+
#else
210+
DIR *listdir_handle;
211+
struct dirent *listdir_filedata;
212+
#endif
213+
202214
#define OPENMODESIZE 3
203215
#define READOPTSSIZE 4
204216
#define STARTCONDSIZE 2
@@ -5456,6 +5468,124 @@ cob_acuw_file_delete (unsigned char *file_name, unsigned char *file_type)
54565468
return ret;
54575469
}
54585470

5471+
int
5472+
cob_listdir_open(cob_field *f_dirname, cob_field *f_pattern)
5473+
{
5474+
//FIXME: now not use file pattern(ex. *).
5475+
#ifdef _WIN32
5476+
char *dirname = cob_str_from_fld(f_dirname);
5477+
char *pattern = cob_str_from_fld(f_pattern);
5478+
5479+
LPCTSTR lpFileName = cob_malloc(strlen(dirname) + 1 + strlen(pattern) + 1);
5480+
5481+
if (listdir_filedata == NULL){
5482+
listdir_filedata = cob_malloc(sizeof(LPWIN32_FIND_DATA));
5483+
}
5484+
5485+
strcpy (lpFileName, dirname);
5486+
strcat (lpFileName, "\\");
5487+
strcat (lpFileName, pattern);
5488+
listdir_handle = FindFirstFile (lpFileName, listdir_filedata);
5489+
free (dirname);
5490+
free (pattern);
5491+
free (lpFileName);
5492+
if (listdir_handle == INVALID_HANDLE_VALUE) {
5493+
return 0;
5494+
}
5495+
5496+
#else
5497+
char *dirname = cob_str_from_fld(f_dirname);
5498+
listdir_handle = opendir(dirname);
5499+
free(dirname);
5500+
if (listdir_handle == NULL) {
5501+
return 0;
5502+
}
5503+
5504+
#endif
5505+
return listdir_handle;
5506+
}
5507+
5508+
int
5509+
cob_listdir_next(cob_field *f_handle, cob_field *f_filename)
5510+
{
5511+
//FIXME: now not use handle.
5512+
char *filename;
5513+
int length;
5514+
5515+
#ifndef _WIN32
5516+
listdir_filedata = readdir(listdir_handle);
5517+
#endif
5518+
#ifdef _WIN32
5519+
filename = listdir_filedata->cFileName;
5520+
#else
5521+
listdir_filedata = readdir(listdir_handle);
5522+
if (listdir_filedata == NULL){
5523+
filename = " ";
5524+
}else{
5525+
filename = listdir_filedata->d_name;
5526+
}
5527+
#endif
5528+
length = strlen(filename);
5529+
5530+
if (length > f_filename->size) {
5531+
length = f_filename->size;
5532+
}
5533+
memset(f_filename->data, ' ', f_filename->size);
5534+
memcpy(f_filename->data, filename, length);
5535+
#ifdef _WIN32
5536+
if(!FindNextFile (listdir_handle, listdir_filedata)) {
5537+
strcpy(listdir_filedata->cFileName, " ");
5538+
}
5539+
#endif
5540+
return 0;
5541+
}
5542+
5543+
int
5544+
cob_listdir_close(cob_field *f_handle)
5545+
{
5546+
//FIXME: now not use handle.
5547+
#ifdef _WIN32
5548+
FindClose (listdir_handle);
5549+
#else
5550+
closedir (listdir_handle);
5551+
#endif
5552+
return 0;
5553+
}
5554+
5555+
int
5556+
cob_acuw_list_directory (unsigned char *data, ...)
5557+
{
5558+
int operation_code = -1;
5559+
int return_code;
5560+
5561+
COB_CHK_PARMS(C$LIST-DIRECTORY, 1);
5562+
5563+
if (cob_current_module->cob_procedure_parameters[0] == NULL){
5564+
return -1;
5565+
}
5566+
5567+
operation_code = cob_get_int(cob_current_module->cob_procedure_parameters[0]);
5568+
5569+
switch (operation_code)
5570+
{
5571+
case 1://LISTDIR-OPEN(value:1)
5572+
return_code = cob_listdir_open(cob_current_module->cob_procedure_parameters[1],
5573+
cob_current_module->cob_procedure_parameters[2]);
5574+
break;
5575+
case 2://LISTDIR-NEXT(value:2)
5576+
return_code = cob_listdir_next(cob_current_module->cob_procedure_parameters[1],
5577+
cob_current_module->cob_procedure_parameters[2]);
5578+
break;
5579+
case 3://LISTDIR-CLOSE(value:3)
5580+
return_code = cob_listdir_close(cob_current_module->cob_procedure_parameters[1]);
5581+
break;
5582+
default:
5583+
//error
5584+
return -1;
5585+
}
5586+
return return_code;
5587+
}
5588+
54595589
/* SORT */
54605590

54615591
static int

libcob/fileio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ COB_EXPIMP int cob_acuw_mkdir (unsigned char *);
337337
COB_EXPIMP int cob_acuw_copyfile (unsigned char *, unsigned char *, unsigned char *);
338338
COB_EXPIMP int cob_acuw_file_info (unsigned char *, unsigned char *);
339339
COB_EXPIMP int cob_acuw_file_delete (unsigned char *, unsigned char *);
340+
COB_EXPIMP int cob_acuw_list_directory (unsigned char *, ...);
340341

341342
/* SORT routines */
342343
COB_EXPIMP void cob_file_sort_init (cob_file *, const int,

libcob/system.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ COB_SYSTEM_GEN ("C$CHDIR", 2, cob_acuw_chdir)
5555
COB_SYSTEM_GEN ("C$COPY", 3, cob_acuw_copyfile)
5656
COB_SYSTEM_GEN ("C$DELETE", 2, cob_acuw_file_delete)
5757
COB_SYSTEM_GEN ("C$FILEINFO", 2, cob_acuw_file_info)
58+
COB_SYSTEM_GEN ("C$LIST-DIRECTORY", 1, cob_acuw_list_directory)
5859
COB_SYSTEM_GEN ("C$GETPID", 0, cob_acuw_getpid)
5960
COB_SYSTEM_GEN ("C$JUSTIFY", 1, cob_acuw_justify)
6061
COB_SYSTEM_GEN ("C$MAKEDIR", 1, cob_acuw_mkdir)

tests/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ jp_compat_DEPENDENCIES = \
133133
jp-compat.src/io-control.at \
134134
jp-compat.src/greater-less-than-equal.at \
135135
jp-compat.src/file-desc.at \
136-
jp-compat.src/abort-on-file-error.at
136+
jp-compat.src/abort-on-file-error.at \
137+
jp-compat.src/system-routine.at
137138

138139
EXTRA_DIST = $(srcdir)/package.m4 $(TESTS) \
139140
$(syntax_DEPENDENCIES) \

tests/Makefile.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ jp_compat_DEPENDENCIES = \
328328
jp-compat.src/io-control.at \
329329
jp-compat.src/greater-less-than-equal.at \
330330
jp-compat.src/file-desc.at \
331-
jp-compat.src/abort-on-file-error.at
331+
jp-compat.src/abort-on-file-error.at \
332+
jp-compat.src/system-routine.at
332333

333334
EXTRA_DIST = $(srcdir)/package.m4 $(TESTS) \
334335
$(syntax_DEPENDENCIES) \

tests/jp-compat.at

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ m4_include([io-control.at])
4949
m4_include([greater-less-than-equal.at])
5050
m4_include([file-desc.at])
5151
m4_include([abort-on-file-error.at])
52+
m4_include([system-routine.at])
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
AT_SETUP([CALL C$LIST-DIRECTORY])
2+
3+
AT_DATA([prog.cob], [
4+
IDENTIFICATION DIVISION.
5+
PROGRAM-ID. prog.
6+
DATA DIVISION.
7+
WORKING-STORAGE SECTION.
8+
01 PATTERN PIC X(5) VALUE "*".
9+
01 DIRECTORY PIC X(256) VALUE
10+
"./list".
11+
01 FILENAME PIC X(30).
12+
01 MYDIR PIC 9(8) COMP-5.
13+
PROCEDURE DIVISION.
14+
CALL "C$LIST-DIRECTORY" USING 1,
15+
DIRECTORY,
16+
PATTERN
17+
END-CALL.
18+
MOVE RETURN-CODE TO MYDIR.
19+
CALL "C$LIST-DIRECTORY" USING 2,
20+
MYDIR,
21+
FILENAME
22+
END-CALL.
23+
PERFORM WITH TEST AFTER UNTIL FILENAME = SPACES
24+
DISPLAY FILENAME "/"
25+
CALL "C$LIST-DIRECTORY" USING 2,
26+
MYDIR,
27+
FILENAME
28+
END-CALL
29+
END-PERFORM.
30+
CALL "C$LIST-DIRECTORY" USING 3, MYDIR
31+
END-CALL.
32+
MOVE 0 TO RETURN-CODE.
33+
EXIT PROGRAM.
34+
])
35+
36+
AT_CHECK([mkdir list])
37+
AT_CHECK([echo -n 1 >list/input1.txt])
38+
AT_CHECK([echo -n 1 >list/input2.txt])
39+
40+
AT_CHECK([${COMPILE} prog.cob])
41+
AT_CHECK([./prog], [0],
42+
[input1.txt /
43+
input2.txt /
44+
])
45+
46+
AT_CLEANUP
47+

0 commit comments

Comments
 (0)