Skip to content

Commit be904a5

Browse files
committed
Merge branch 'addFuncLISTDIRECTORY'
商用COBOLに存在するC$LIST-DIRECTORYルーチンを実装しました #25 Conflicts: tests/jp-compat.src/system-routine.at
2 parents cf2f293 + 976cf2b commit be904a5

4 files changed

Lines changed: 177 additions & 0 deletions

File tree

libcob/fileio.c

Lines changed: 127 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,121 @@ 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+
#ifdef _WIN32
5516+
filename = listdir_filedata->cFileName;
5517+
#else
5518+
listdir_filedata = readdir (listdir_handle);
5519+
if (listdir_filedata == NULL) {
5520+
filename = " ";
5521+
}else{
5522+
filename = listdir_filedata->d_name;
5523+
}
5524+
#endif
5525+
length = strlen (filename);
5526+
5527+
if (length > f_filename->size) {
5528+
length = f_filename->size;
5529+
}
5530+
memset (f_filename->data, ' ', f_filename->size);
5531+
memcpy (f_filename->data, filename, length);
5532+
#ifdef _WIN32
5533+
if (!FindNextFile (listdir_handle, listdir_filedata)) {
5534+
strcpy (listdir_filedata->cFileName, " ");
5535+
}
5536+
#endif
5537+
return 0;
5538+
}
5539+
5540+
int
5541+
cob_listdir_close (cob_field *f_handle)
5542+
{
5543+
//FIXME: now not use handle.
5544+
#ifdef _WIN32
5545+
FindClose (listdir_handle);
5546+
#else
5547+
closedir (listdir_handle);
5548+
#endif
5549+
return 0;
5550+
}
5551+
5552+
int
5553+
cob_acuw_list_directory (unsigned char *data, ...)
5554+
{
5555+
int operation_code = -1;
5556+
int return_code;
5557+
5558+
COB_CHK_PARMS (C$LIST-DIRECTORY, 1);
5559+
5560+
if (cob_current_module->cob_procedure_parameters[0] == NULL) {
5561+
return -1;
5562+
}
5563+
5564+
operation_code = cob_get_int (cob_current_module->cob_procedure_parameters[0]);
5565+
5566+
switch (operation_code)
5567+
{
5568+
case 1://LISTDIR-OPEN(value:1)
5569+
return_code = cob_listdir_open (cob_current_module->cob_procedure_parameters[1],
5570+
cob_current_module->cob_procedure_parameters[2]);
5571+
break;
5572+
case 2://LISTDIR-NEXT(value:2)
5573+
return_code = cob_listdir_next (cob_current_module->cob_procedure_parameters[1],
5574+
cob_current_module->cob_procedure_parameters[2]);
5575+
break;
5576+
case 3://LISTDIR-CLOSE(value:3)
5577+
return_code = cob_listdir_close (cob_current_module->cob_procedure_parameters[1]);
5578+
break;
5579+
default:
5580+
//error
5581+
return -1;
5582+
}
5583+
return return_code;
5584+
}
5585+
54595586
/* SORT */
54605587

54615588
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$CALLEDBY", 1, cob_acuw_calledby)

tests/jp-compat.src/system-routine.at

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,52 @@ AT_CHECK([./caller], [0],
4242
])
4343

4444
AT_CLEANUP
45+
AT_SETUP([CALL C$LIST-DIRECTORY])
46+
47+
AT_DATA([prog.cob], [
48+
IDENTIFICATION DIVISION.
49+
PROGRAM-ID. prog.
50+
DATA DIVISION.
51+
WORKING-STORAGE SECTION.
52+
01 PATTERN PIC X(5) VALUE "*".
53+
01 DIRECTORY PIC X(256) VALUE
54+
"./list".
55+
01 FILENAME PIC X(30).
56+
01 MYDIR PIC 9(8) COMP-5.
57+
PROCEDURE DIVISION.
58+
CALL "C$LIST-DIRECTORY" USING 1,
59+
DIRECTORY,
60+
PATTERN
61+
END-CALL.
62+
MOVE RETURN-CODE TO MYDIR.
63+
CALL "C$LIST-DIRECTORY" USING 2,
64+
MYDIR,
65+
FILENAME
66+
END-CALL.
67+
PERFORM WITH TEST AFTER UNTIL FILENAME = SPACES
68+
DISPLAY FILENAME "/"
69+
CALL "C$LIST-DIRECTORY" USING 2,
70+
MYDIR,
71+
FILENAME
72+
END-CALL
73+
END-PERFORM.
74+
CALL "C$LIST-DIRECTORY" USING 3, MYDIR
75+
END-CALL.
76+
MOVE 0 TO RETURN-CODE.
77+
EXIT PROGRAM.
78+
])
79+
80+
AT_CHECK([mkdir list])
81+
AT_CHECK([echo -n 1 >list/input1.txt])
82+
AT_CHECK([echo -n 1 >list/input2.txt])
83+
84+
AT_CHECK([${COMPILE} prog.cob])
85+
AT_CHECK([./prog], [0],
86+
[. /
87+
.. /
88+
input1.txt /
89+
input2.txt /
90+
])
91+
92+
AT_CLEANUP
4593

0 commit comments

Comments
 (0)