PreviousIntroduction to File Handling COBOL File OrganizationsNext"

Chapter 2: File Naming

This chapter details the file naming conventions used on the various operating systems. It also describes how to associate the logical filename that you use within your program with a physical file.

2.1 File Naming Conventions

This section describes the file naming conventions used by the supported operating systems.

2.1.1 File Naming on DOS, Windows and OS/2

This COBOL system, and applications created with this system under the DOS, Windows and OS/2 operating systems, all use the standard DOS filename convention:

[drive-id:][[pathname\]filename[.[ext]]

where the parameters are:

drive-id A logical disk drive identifier such as A, B, C.
pathname The operating system pathname. If you do not specify drive-id and/or pathname, the current drive and/or path is assumed.
filename The name of one of the following:
  • A disk file
  • A device recognized by the COBOL system
  • A device recognized by the operating system

Device-names must appear by themselves, without any other optional name component. See the chapter Device Handling in your Programmer's Guide to Writing Programs for details.

.[ext] A period (.) followed by up to three characters giving the filename extension. You can specify an extension of spaces by putting just the period.

Windows NT, Windows 95 and OS/2:
The following file systems are available for Windows NT, Windows 95 and OS/2 V2.1 or later:

Windows NT and Windows 95 High Performance File System (HPFS) and New Technology File System (NTFS)
OS/2 V2.1 or later High Performance File System (HPFS)

This COBOL system and applications created with it can use the HPFS or NTFS file naming convention. The full definition of the naming convention is in your operating system documentation. Each file or directory name can consist of up to 254 characters and contain any number of periods (.). This COBOL system regards any text following the final period as an extension (or a trailing period as a space extension) and removes it when creating its own names. Therefore, if you do use multiple periods for a source filename, you must specify an extension.

OS/2:
If you want to use HPFS-style filenames from a 16-bit program on OS/2, see the section Linker Definition Files in the chapter Linking on the 16-bit COBOL System in your Object COBOL User Guide. On 32-bit OS/2 long filenames are supported by default.

This COBOL system accepts any COBOL file for input. The system assigns the default extension .cbl to your source file. If you have named your file with an extension, your assigned extension overrides .cbl.

The Compiler can create a number of files with different extensions added to the name you supply. The extensions include .obj, .lnk, .idy, .gdy, .lst and .Inn, where nn is a two-digit number. The linking process creates .exe or .dll files.

Query data lists created by Animator files are given the extension .ils.

For further details of filenames and extensions, refer to your operating system manuals.

2.1.2 File Naming on UNIX

This COBOL system and applications created with this system under the UNIX operating system use the standard UNIX file naming convention:

[pathname/]filename[.ext]

where the parameters are:

pathname The operating system pathname. If you do not specify a pathname, the current directory is assumed.
filename The name of one of the following:
  • A disk file
  • A device recognized by the COBOL system
  • A device recognized by the operating system

Device-names must appear by themselves, without any other optional name component. See the chapter Device Handling in your Programmer's Guide to Writing Programs for details.

.ext A period (.) followed by the filename extension.

The maximum length of pathname, filename and .ext are set by the UNIX operating system. Typically, the total length of all three component-names is 255 characters. On some UNIX systems, the maximum length of filename plus .ext is 14 characters. See your Release Notes for details of the maximum number of characters permitted in a component-name and a pathname.

This COBOL system detects pathnames which exceed the permitted maximum length for a path when you attempt to open, split/join or map such files. It also detects any component names which exceed their permitted maximum length.

For example:

The run-time error encountered is:

188 Filename too large

In the interests of program portability, we advise you not to build the absolute pathnames of files into your programs. You should use relative pathnames instead. For example, you are recommended to use:

mylib/file1

rather than:

/usr/mylib/file1

2.2 Assigning Filenames

When you write a COBOL program, for each file you define in your program you need to be able to say which physical file on disk it relates to. You do this using the ASSIGN clause in the SELECT statement to assign the logical name that you use in your program to the name of the physical file on disk.

There are three ways of specifying the name of the physical file that you want your program to access:

STATIC The filename is specified as a literal in the ASSIGN clause of the SELECT statement.
DYNAMIC The filename is specified in a data item and can therefore be changed by the program at run time.
EXTERNAL The filename is resolved externally, either through an operating system environment variable or the External File Mapper (Mfextmap).

With all types of filename assignment, filenames can be fully qualified by drive and directory, or specified without qualification, if the current directory is intended.

Operating system device names (such as PRN, LPT1, or COM) can be specified using any of these methods. See the chapter Device Handling in your Programmer's Guide to Writing Programs.

2.2.1 Assigning Filenames Statically

You use static filename assignment when the name of the physical file you want to access is known at compilation and will not change.

Static filename assignment is also known as literal assignment, since the filename is a literal in the SELECT statement. You can either specify a simple filename (if the file is in the current directory), or a full path and filename including drive and directory.

In the File-Control paragraph, you specify the SELECT... ASSIGN TO clause in the following format:

select filename 
    assign to [disk] literal 
              [, literal].

where the parameters are:

filename The logical (internal) filename used in your program. It can be any valid COBOL word.
disk Optional. Enables you to specify the literal either in the SELECT clause, or in the FD entry for the file in the File Section.
literal The operating system pathname of the file. It can be the name of a file on disk, optionally including a drive and/or path identifier and filename extension, or it can be a device-name (see the chapter Device Names in your Programmer's Guide to Writing Programs).

If you do not specify literal with disk in the SELECT clause and do not specify the VALUE OF FILE-ID clause in the file's FD entry, the effect is to use a physical filename that is the same as the logical (internal) filename.

Note that the logical (internal) filename is folded to upper case by the Compiler.

Refer to your operating system manuals for more information on file names and to your Language Reference for the full syntax of the ASSIGN clause.

To change a filename that is assigned in this way, you must modify the source code and recompile the program.

Examples

     select stockfile
        assign to "b:warehs.buy".
     select printfile
        assign to "prn:".
     select input-file
        assign to "data\prog1in".

The logical filename is used in the OPEN statement when the file is needed. Using the first example above, you would specify

    open input stockfile

to open the file warehs.buy on the b: drive.

2.2.2 Assigning Filenames Dynamically

Dynamic filename assignment is the most powerful and flexible type of filename assignment, since the filename can be changed dynamically by the program, possibly based on user input.

The filename is specified as the value of a user-defined data item in the Data Division. If the data item is not explicitly declared, the Compiler creates one for you, with a picture of PIC X(65).

Before the OPEN statement for the file is executed, the program must give a value to the data item.

In the File-Control paragraph, you specify the SELECT ASSIGN TO clause in the following format:

select filename 
    assign to dynamic data-item

where the parameters are:

filename The logical (internal) filename used in your program. It can be any valid COBOL word.
data-item A COBOL data-name.

If you use the ASSIGN"DYNAMIC" Compiler directive, you can omit the word DYNAMIC from this clause.

Example

     select fd-in-name
         assign to dynamic ws-in-file.
     select fd-out-name
         assign to dynamic ws-out-file.
            ...
 working-storage section.
 01 ws-in-file          pic x(30) value "a:\test\input.dat".
 01 ws-out-file         pic x(40).
            ...

 procedure division.
     accept ws-out-file.
     open input fd-in-name fd-out-name
            ...

At run time, when the OPEN statements for fd-in-name and fd-out-name are executed, the values in the data items, ws-in-file and ws-out-file are used to determine the physical files.

2.2.3 Assigning Filenames Externally

You can use external filename assignment if the name of the file to be accessed needs to be changed externally to the program.

External filename assignment is more flexible than static filename assignment, since the end-user can change (or input) the filename before any invocation of the program, without having to make a source code change.

There are two methods of assigning a filename externally. One is to use an operating system environment variable, and the other is to use the External File Mapper (Mfextmap).

2.2.3.1 Environment Variables and External Filename Assignment

To assign a filename using an operating system environment variable, you specify the name of the environment variable as a literal in the SELECT ASSIGN TO clause:

select filename 
    assign to external literal

where the parameters are:

filename The logical (internal) filename used in your program. It can be any valid COBOL word.
literal The name of an operating system environment variable whose value is used as the name of the physical file.

Under DOS, Windows and OS/2, you set the environment variable using the SET command. Under UNIX, you set the environment variable to the appropriate value and export the value to the shell.

16-bit:
With the 16-bit COBOL system, if the environment variable literal does not exist, an error is returned in file status.

32-bit:
With the 32-bit COBOL system, if the environment variable literal does not exist, the unmapped name is used.

If you use the ASSIGN"EXTERNAL" Compiler directive, you can omit the word EXTERNAL from the SELECT ASSIGN TO clause.

See the Language Reference for the full syntax of the SELECT ASSIGN TO clause.

You must issue a SET command before executing the program. If you are running under the control of Workbench, you must issue the SET command before entering Workbench.

For compatibility with IBM mainframes, if literal contains hyphens, only those characters after the last hyphen are used as the name of the environment variable.

Examples

The following examples show how to use environment variables to assign filenames externally.

     select fd-name
         assign to external var1.

In this example, var1 must be an environment variable and so, before executing the program, you must issue a SET command to set the value of var1 to the physical filename you want to use; for example, on DOS, Windows and OS/2:

set var1=c:\test.dat

At run time, the filename fd-name is assigned to the file test.dat in the root directory on the c: drive.

     select fd-name
         assign to external other-chars-var1.

In this example only those characters after the last hyphen are used, so COBOL searches for an environment variable called var1. Before executing the program, you must issue a SET command to assign var1 to the physical filename you want to use, for example:

set var1=c:\test.dat

2.2.3.2 External File Mapper (Mfextmap)

UNIX:
The External File Mapper is not available on UNIX systems.

The External File Mapper (Mfextmap) provides a flexible method of mapping logical filenames used within a COBOL program to physical filenames. Mfextmap reads a text file (the mapper file)to determine the association between logical filenames and physical filenames. This file is called mfextmap.dat and can be created using an ordinary text editor.

2.2.3.2.1 Mapper File Structure

The file used by the External File Mapper is called mfextmap.dat and must be a line sequential file. Records within the file have the following structure:

logical-name physical-name

where the parameters are:

logical-name The logical filename used within your program.
physical-name The actual name of the file, including drive and path.

At least one space must separate the logical and physical names; there can be any number of spaces preceding the logical name and following the physical name. Each record can only contain one logical name and its associated physical name. Only one record is allowed per line. For example:

lname \path\bigdata.dat

maps the logical filename lname to the physical filename \path\bigdata.dat.

You can include comments in the mapper file by making the first character in the record a # character.

2.2.3.2.2 Location of the Mapper File

The mapper file must be in the current directory or on the COBOL system path (pointed to by the environment variable COBDIR). Alternatively, the environment variable MFEXTMAP can be set to specify the path of the mapper file. Both COBDIR and MFEXTMAP are set using the SET command (please refer to your operating system manual for details of this command).

If MFEXTMAP is set but the mapper file does not exist on the specified path, the logical filename used in your program is resolved in the environment space. If MFEXTMAP is not set, this COBOL system searches for the mapper file firstly in the current directory and then along the path specified by COBDIR. . If the file is not found, the logical filename used in your program is resolved in the environment space. Both MFEXTMAP and COBDIR can have multiple paths defined.

2.2.3.2.3 Activating the Mapper File

You cannot use Mfextmap with a statically linked application. With a dynamically linked application, you can use the INITCALL"MFEXTMAP" Compiler directive or the appropriate method of run-time configuration, as described below.

16-bit:
To use Mfextmap in an application on the 16-bit COBOL system, you must put an entry for it in the [MFRUN-INSTALL] section of the run.cfg configuration file. The entry in run.cfg should look like this:

[MFRUN-INSTALL]
\$COBDIR\MFEXTMAP

32-bit:
To use Mfextmap in a built application on 32-bit COBOL systems, you must set the run-time tunable environment_mapper to TRUE. See the chapter Run-time Configuration in your Object COBOL User Guide for details of the run-time tunables.

Once the File Mapper is active, you cannot disable it in favor of returning to just searching the environment space. If you are using the mapper file, you can change it during the execution of the program. The mapping information in the current version of the mapper file is used.

2.2.3.2.4 Disabling Mapper File Support

By disabling the search for the mapper file, you can increase the speed of your system as no disk accesses are required to find the current mapper file.

16-bit:
On the 16-bit COBOL system, to disable the search for the mapper file (mfextmap.dat), specify the following in the environment space via the SET command before starting your application:

set mfextmap=no

32-bit:
On 32-bit COBOL systems, to disable the search for the mapper file (mfextmap.dat), set the run-time tunable environment_mapper to FALSE.

2.3 Filename Mapping

On 32-bit COBOL systems (and on the 16-bit system, if the program is compiled using the CALLFH Compiler directive, or uses indexed files) you can use filename mapping to make use of more advanced file assignment facilities.


Note: Filename mapping overrides any syntax definition or use of the ASSIGN directive.


Throughout this section, if you are using UNIX, read every backslash (\) character as a slash (/).

When your program opens a file, the system prefixes "DD_" to that file's name. The prefix "dd_" is also recognized . The system then extracts the first element of the filename and looks for an environment variable with that name. The first element of the filename consists of either all the text before the first backslash character (\), all the text if the name does not include such a character, or nothing if the filename actually starts with the "\" character. So, for example, if you try to open a file named dir\file1, the system searches for the environment variable dd_dir; if you try to open a file named dir1\dir2\file1, the system searches for dd_dir1; and if the file is named file1, the system searches for dd_file1.

If the system finds the environment variable for which it is searching, it takes the value of that environment variable and prefixes this to the remaining elements of the original filename; that is, the name in the SELECT ASSIGN statement. This name is then considered to be the physical file for which the system is to search.

Consider the following examples:

Filename assigned in program Environment
variable searched for
Environment
variable contents
Physical filename
dir\file1 dd_dir d2 d2\file1
dir\file1 dd_dir d4 d4\file1
dir\file1 dd_dir d2\d4 d2\d4\file1
dir1\dir2\file1 dd_dir1 d2 d2\dir2\file1
dir1\dir2\file1 dd_dir1 d4 d4\dir2\file1
dir1\dir2\file1 dd_dir1 d2\d4 d2\d4\dir2\file1

Following these rules, if the original SELECT ASSIGN filename consists of a single element, the value contained in the associated environment variable is used as the physical filename. For example:

Filename assigned in program Environment
variable searched for
Environment
variable contents
Physical filename
file1 dd_file1 d2 d2

Filenames which begin with a backslash ( \ ), a hyphen (-) or the digits 0 through 9 are not mapped.

You can put all the files connected with one application in the same directory and be certain that this COBOL system will find them by defining each file as application-name\filename and then setting up an environment variable which points to the name of the directory which contains the files.

If the system fails to find an environment variable, or it finds the environment variable but it is not set, the system assumes that the physical name of the file is the same as its logical name. For this reason, you must ensure that the logical filenames do not contain any special characters that cannot be included in environment variable names. Although the period ( . ) is not allowed in the names of environment variables, it is often used in filenames, so you may want to map logical filenames containing this character. In this case, you must replace the "." with the underscore character ( _ ). For example:

dd_file_PNT=\usr\qa\myfile.pnt

refers to the logical filename file.PNT.

UNIX:
On UNIX systems:

2.3.1 Setting up Multiple Paths

For files opened INPUT or I/O, you can use environment variables to specify multiple paths for filename mappings. This causes the system to search for subsequent files if a "file not found" condition is returned for the first file in the path.

If the first component of a path is a directory, the first component of the environment variable searched for must also be a directory. Similarly, if the first component is a file, the dd_ component must also be a file.

Consider the following example contents of an environment variable named dd_dir:

dd_dir=\a\b;\c\d;

This causes the system to search \c\d for the assigned file if a "file not found" condition is returned on \a\b. Consider the following examples:

Filename assigned in program Environment variable searched for Environment variable contents Physical filename
dir1\file1 dd_dir1 d1;d2 d1\file1
if this is not found then:
d2\file1
file1 dd_file1 d1\f1;d2\f2 d1\f1
if this is not found then:
d2\f2
file1 dd_file1 f1;f2 f1
if this is not found then:
f2
dir1\file1 dd_dir1 d1\d2 current directory\file1
if this is not found then:
d1\d2\file1

For files opened I/O, OUTPUT, or EXTEND, if the file is not found on any part of the path, it will be created in the first directory in the search sequence.

The length of each path in a dd_ path list must be less than or equal to the permitted maximum number of characters for a path. See the section File Naming Conventions for more details.

Additionally, you can map files on a global basis by setting the COBDATA environment variable. See the section Global Filename Mapping for further information on the COBDATA environment variable.

2.3.2 Search Sequence

The search sequence employed to find a specified file, depends on the file assignment of that file.

The search order for files assigned as DYNAMIC is:

  1. dd_ environment variables

  2. On 32-bit, environment variables defined in cobconfig

  3. Any COBDATA environment mappings

  4. Unmapped name on disk.

UNIX:
Note:
On UNIX, if you dynamically change environment variables using a call to "SYSTEM", they are not re-accessed by this COBOL system after the start of its run. However, changing them using COBOL syntax causes the updated setting to be used.

For files assigned as EXTERNAL, only the last element of the filename following the final hyphen is significant for filename mapping.

The search order for a file assigned as EXTERNAL is:

  1. dd_ environment variables

  2. On 32-bit, environment variables defined in cobconfig

  3. $filename environment variables

  4. Filename literals (variables which may or may not be preceded by "dd_" but which map external filenames)

  5. Any COBDATA environment mappings

  6. Unmapped name on disk.

In this case, the filename literals are reaccessed by this COBOL system after the start of a run. This is for compatibility with previous versions of the COBOL system.

2.3.3 %NLS% Characters in Filenames

This feature is only available if your COBOL system supports National Language Support.

If the physical filename in your program starts with the characters "%NLS%", the file is processed according to the rules for National Language Support (NLS). Consider the following example:

Select filename assign "%NLS%file1"

This causes the system to process file1 according to NLS rules.

You can then map file1 using the environment variable dd_file1 as described above. In this case, the mapped filename is processed according to NLS rules.

Alternatively, a file assigned without the "%NLS%" characters can be processed according to NLS rules, if you specify a mapping for the file that is preceded by the characters "%NLS%". Consider the following example:

Filename ASSIGNed in program Environment variable searched for Environment variable contents Physical Filename
file2 dd_file2 %NLS%file3 file3


This causes file3 to be processed according to NLS rules.

2.3.4 The "&" Character in Environment Variables

32-bit:
On 32-bit COBOL systems, when you are specifying the contents of an environment variable, you can place an ampersand character (&) at the start to indicate that an indexed file is to have its index and its data files in separate directories (and, by implication, on separate disks). You cannot use this character when specifying multiple paths.


Note: On UNIX, as the "&" character has this special meaning when used in environment variables, if you want to reference any file whose name begins with this character you must precede the name with a backslash ( \ ) character.


DOS, Windows and OS/2:
Consider the following example contents of an environment variable named dd_dir:

dd_dir=&\disk1\data.dat&\disk2\data.idx

This causes the system to place the data part of the original ASSIGNed indexed sequential file in \disk1\data.dat, while the index part of the file is placed in \disk2\data.idx.

UNIX:
Consider the following example contents of an environment variable named dd_dir:

dd_dir=&\disk1\data&\disk2\data.idx

This causes the system to place the data part of the original ASSIGNed indexed sequential file in \disk1\data, while the index part of the file is placed in \disk2\data.idx.

2.3.5 The "$" Character in Filenames

32-bit:
On 32-bit COBOL systems, if the physical filename in your program starts with a dollar sign ($), this forces the system to attempt to map the specified file. If no mapping exists, the system returns a "file not found" condition and does not search for the unmapped filename.

Consider the following example contents of a SELECT statement:

select filename assign "$file1"

This causes the system to search for the environment variable dd_file1 then $file1. If this is found, the system follows the rules for filename mapping given in the previous sections. If this is not found, the system returns a "file not found" condition and does not attempt to search for file1.

Forcing the system to attempt to map the specified file in this way is supported only when mapping is to a filename. It is not supported to a directory path list, pipes or to split index and data-names.

2.3.6 Setting Up Pipes

32-bit:
On 32-bit COBOL systems, when you specify the contents of an environment variable, you can use the following three characters to set up pipes or named pipes:


Notes:


The meanings of these characters when used in the value of an environment variable are described below.

2.3.6.1 The "<" Character

The less than character (<) defines the specified file as a pipe connected to the standard output of the given command. The file assigned within your program must be either sequential or line sequential, and must be opened for input. Its name can be only one element long; that is, it must not contain a backslash character (\).

Consider the following example contents of an environment variable named dd_dir on DOS, Windows and OS/2:

dd_dir="<cmd /c dir"

or on UNIX:

dd_dir="<ls-l..."

This causes every READ statement in the program of the original assigned file to return the value of the next line of the output from the "dir" or "ls-l" command.

2.3.6.2 The ">" Character

The greater than character (>) defines the specified file as a pipe connected to the standard input of the given command. The file assigned within your program must be either sequential or line sequential, and must be opened for output. Its name can be only one element long; that is, it must not contain a backslash character (\).

Consider the following example contents of an environment variable named dd_dir:

dd_dir=">cmd /c pr -h Title"

This causes every write to the file in the program to be passed to the standard input of the pr -h Title command.

2.3.6.3 The "|" Character

The pipe character (|) defines the specified file as a two-way pipe to the specified process. The file assigned within your program must be either sequential or line sequential, and must be opened for I/O.

Consider the following example contents of an environment variable named dd_file:

dd_file="|cmd /c proc"

This defines the file file as a two-way pipe to the process proc; that is, all the READ operations on that file will read the standard output of the process proc.


Note: You will receive an error if you attempt to write to a line sequential file, or sequential file opened for I/O unless the file has been mapped using the "|" character.


2.3.7 Global Filename Mapping

The COBDATA environment variable enables you to globally map groups of files to different filenames and file organizations. This allows you to place working data files in a directory whose name is not known until run-time. See the section Filename Mapping earlier in this chapter for further information on mapping individual files.

The format of the COBDATA environment variable is:

set COBDATA=;directory;directory ...

where the parameter is:

directory The name of a directory to which you want COBDATA to point.

For example:

set COBDATA=;demo;user;progs

COBDATA is considered set if there is an environment variable of this name in your environment space and its value is non-empty.

If you specify an empty directory, it is equivalent to specifying the current directory using the "." character.

For global filename mapping, the search order for files assigned DYNAMIC and EXTERNAL is as described in the section Search Sequence earlier in this chapter. However, for directory paths specified either in the COBDATA environment variable or a dd_ environment variable, the system searches the first directory specified followed by a slash ( / ) on UNIX or a backslash (\) on DOS, Windows and OS/2 as a prefix to the user name. If the file is not found, or is not readable, the search continues until the final directory has been searched. If no file is found and the OPEN mode is I/O or OUTPUT, the first directory is used if a file is to be created.

The COBDATA value string must begin with a colon ( : ) or the search does not work. All mappings are ignored for any filename starting with a hyphen ( - ) or a slash (/) on UNIX or a backslash (\) on DOS, Windows and OS/2. It is also illegal to have a hyphen in an environment variable name.

When using COBDATA for filename mapping, you should not specify a filename that starts with "COB..." as words beginning with this are reserved for the COBOL system.

You can use COBDATA for files OPENed in any mode and for fixed or variable length files. If you are using indexed files, both the data and indexed files is in the same directory.

COBDATA affects file deletions, using the rules given here, and file opens.

If you use COBOL development system programs, we recommend that you first unset COBDATA, as many of these programs open data files and are affected by the value of COBDATA.

2.4 Processing Filenames

The library routines CBL_SPLIT_FILENAME and CBL_JOIN_FILENAME enable you to parse a filename into its component strings and to join strings together to form a filename. They can be used together to replace components of a filename, such as the extension. They can handle both null-terminated and space-terminated filenames.

A filename is split up into path, base-name and extension. For example, in the following DOS filename:

d:\dir1\dir2\file.dat

the path is "d:\dir1\dir2", the base-name is "file", and the extension is "dat"; and in the following UNIX filename:

/dir1/dir2/file.dat

the path is "/dir1/dir2", the base-name is "file", and the extension is "dat".

The routines can work with strings of up to 65,535 characters in length, but your environment or run-time system imposes a limit on the maximum length of a filename:

Operating System

Maximum length
DOS 65 characters
Windows 65 characters
Windows NT 65 characters with the 16-bit COBOL system 100 characters with the 32-bit COBOL system
OS/2 265 characters with the 16-bit COBOL system 100 characters with the 32-bit COBOL system
UNIX 14 or 255 characters depending on the version of UNIX


CBL_JOIN_FILENAME

Forms a filename by joining together its component parts; that is, the path-name, base-name and extension.

Syntax:
call "CBL_JOIN_FILENAME" using     split-join-param 
                                   join-buffer 
                                   path-buffer 
                                   basename-buffer 
                                   extension-buffer 
                         returning status-code
Parameters:

split-join-param    Group item defined as:
    param-length        pic x(2) comp-x.
    splitjoin-flg1      pic x comp-x.
    splitjoin-flg2      pic x comp-x.
    path-strt           pic x(2) comp-x.
    path-len            pic x(2) comp-x.
    basename-strt       pic x(2) comp-x.
    basename-len        pic x(2) comp-x.
    extension-strt      pic x(2) comp-x.
    extension-len       pic x(2) comp-x.
    total-length        pic x(2) comp-x.
    split-buf-len       pic x(2) comp-x.
    join-buf-len        pic x(2) comp-x.
    first-path-len      pic x(2) comp-x.
join-buffer         pic x(n).
path-buffer         pic x(n).
basename-buffer     pic x(n).
extension-buffer    pic x(n).
status-code         pic x(2) comp-x.

On Entry:

param-length Length of split-join-param in bytes, including the two bytes for param-length. The normal value for param-length is 24.
splitjoin-flg1
bit 1 When 1 the strings are null-terminated. When 0 the strings are space-terminated.
bit 0 When 1 the new filename is folded to upper case. When 0 the original case is preserved.
path-strt Offset of the start of the path in path-buffer, indexed from one.
path-len Length of path if not space- or null-terminated.
basename-strt Offset of the start of the base-name in basename-buffer, indexed from one.
basename-len Length of base-name if not space- or null-terminated.
extension-strt Offset of the start of the extension in extension-buffer, indexed from one.
extension-len Length of extension if not space- or null-terminated.
path-buffer Path-name.
basename-buffer Base-name.
extension-buffer Extension.
join-buf-len Length of join-buffer.

On Exit:

total-length Total number of characters in the filename.
join-buffer The joined-up filename.
status-code Return status:

0 Success
1 Filename too big for join-buffer
4 Illegal filename

Comments:

The new filename is formed by concatenating the following:

and is placed in join-buffer with length total-length.

This routine can be made to fold to upper case by setting the least significant bit (bit 0) of splitjoin-flg1. If this bit is not set, the case is preserved. If you are intending to use your program on UNIX systems, we recommend that you do not fold the case.

This routine can accept either null-terminated or space-terminated strings. Setting the second least significant bit (bit 1) of splitjoin-flg1 results in the routine expecting null-terminated strings. If this bit is not set, space-terminated strings are expected.

The path, base-name and extension fields can be shorter than the lengths specified by path-len, basename-len, and extension-len respectively, if they are terminated with either a space or a null, depending on the setting of bit 1 of splitjoin-flg1.

Path-buffer, basename-buffer, extension-buffer, and join-buffer do not have to be four distinct buffers. This means that this routine can be used with CBL_SPLIT_FILENAME to replace one component of a filename.

If path-buffer is not empty and does not have a trailing backslash (\) or slash (/) or colon (:) (DOS, Windows and OS/2), and basename-buffer is not empty, the routine inserts a backslash (\) (DOS, OS/2 and Windows) or slash (/) (UNIX) between the path and base-name in join-buffer.

If the extension is ".", the string returned in join-buffer has an extension of spaces; that is, the filename has a trailing period (.).

If total-length is less than join-buf-len, the characters after the end of the filename are either nulls or spaces, depending on the setting of bit 1 of splitjoin-flg1.

On DOS, Windows and OS/2, if path consists of a valid drive letter, but no colon (:), the routine adds one. It does not do this for a device (for example LPT1) that does not need one. You cannot join a device (as opposed to a drive letter) to a non-empty base-name.


CBL_SPLIT_FILENAME

Splits a filename into its component parts; that is, the path-name, base-name and extension.

Syntax:
call "CBL_SPLIT_FILENAME" using     split-join-param 
                                    split-buffer 
                          returning status-code
Parameters:

split-join-param    Group item defined as:
    param-length        pic x(2) comp-x.
    splitjoin-flg1      pic x comp-x.
    splitjoin-flg2      pic x comp-x.
    path-strt           pic x(2) comp-x.
    path-len            pic x(2) comp-x.
    basename-strt       pic x(2) comp-x.
    basename-len        pic x(2) comp-x.
    extension-strt      pic x(2) comp-x.
    extension-len       pic x(2) comp-x.
    total-length        pic x(2) comp-x.
    split-buf-len       pic x(2) comp-x.
    join-buf-len        pic x(2) comp-x.
    first-path-len      pic x(2) comp-x.
split-buffer        pic x(n).
status-code         pic x(2) comp-x.

On Entry:

param-length Length of split-join-param in bytes, including the two bytes for param-length. The normal value for param-length is 24.
splitjoin-flg1
bit 1 When 1, the strings are null-terminated. When 0, the strings are space-terminated.
bit 0 When 1, the new filename is folded to upper case. When 0, the original case is preserved. We recommend that you do not set this flag if you intend to run your program on UNIX.
split-buf-len Length of split-buffer.
split-buffer The string to split.

On Exit:

splitjoin-flg2
bit 1 Set if there is a wildcard in the path.
bit 0 Set if there is a wildcard in base-name or extension.
path-strt Start of path-name in split-buffer, from one.
path-len Length of path-name; zero if there is none. This includes any following colon (:) (DOS, Windows or OS/2).
basename-strt Start of base-name in split-buffer, from one.
basename-len Length of base-name; zero if there is none. This does not include the following period (.).
extension-strt Start of extension in split-buffer, from one.
extension-len Length of extension; zero if there is none. This does not include the preceding period (.).
total-length Total number of characters in the string.
first-path-len Number of characters up to and including the first backslash (\) or slash (/) or colon (:) (DOS, Windows and OS/2) ; if split-buffer contains none of these, this parameter = path-len.
split-buffer Unchanged unless bit 1 of splitjoin-flg1 is set, when it is folded to upper case.
status-code Return status:

0 Success
4 Illegal filename

Comments:

This routine can be made to fold to upper case by setting the least significant bit (bit 0) of splitjoin-flg1. If this bit is not set, the case is preserved. If you are intending to use your program on UNIX systems, we recommend that you do not fold case.

This routine can accept either null-terminated or space-terminated strings. Setting the second least significant bit (bit 1) of splitjoin-flg1 results in the routine expecting null-terminated strings. If this bit is not set, space-terminated strings are expected.

If there are two or more periods (.) in the filename (not counting periods (.) in the path-name), the extension returned consists of the characters between the last period (.) and the end of the filename. The base-name contains everything up to, but not including, the last period (.).

To distinguish between filenames with no extension and filenames with an extension of spaces (that is, base-names whose last character is a period (.)), extension-len is set to 1 if the extension is spaces and extension-strt points to the last period (.).


2.4.1 Example Program

The following program demonstrates use of the CBL_SPLIT_FILENAME and CBL_JOIN_FILENAME routines.

$set noosvs mf ans85
***************************************************************
*                                                             *
*               (C) Micro Focus Ltd. 1991                     *
*                                                             *
*                     SPLTJOIN.CBL                            *
*                                                             *
*    This program demonstrates the use of the routines that   *
*    enable you to separate a filename into its component     *
*    strings (CBL_SPLIT_FILENAME), and to join strings        *
*    together to form a filename (CBL_JOIN_FILENAME).         *
*                                                             *
***************************************************************

 working-storage section.

 78 environ          value "dos".

 01 split-buffer             pic x(65).
 01 split-params.
     03  param-length        pic xx comp-x   value 24.
     03  splitjoin-flg1      pic x  comp-x   value 0.
     03  splitjoin-flg2      pic x  comp-x.
     03  path-strt           pic xx comp-x.
     03  path-len            pic xx comp-x.
     03  basename-strt       pic xx comp-x.
     03  basename-len        pic xx comp-x.
     03  extension-strt      pic xx comp-x.
     03  extension-len       pic xx comp-x.
     03  total-length        pic xx comp-x.
     03  split-buf-len       pic xx comp-x   value 65.
     03  join-buf-len        pic xx comp-x   value 65.
     03  first-path-len      pic xx comp-x.
 01 join-buffer              pic x(65).
 01 path-buffer              pic x(65).
 01 basename-buffer          pic x(65).
 01 extension-buffer         pic x(3) value "cbl".
 procedure division.

* Set up lengths
     move 65 to split-buf-len
                join-buf-len

* Set flag for space-terminated, fold to upper
     move 1 to splitjoin-flg1

$if environ = "unix"
     move "/dir/file.ext" to split-buffer
$else
     move "a:\dir\file.ext" to split-buffer
$end
     move 1 to splitjoin-flg1
     call "CBL_SPLIT_FILENAME" using split-params
                                     split-buffer

* This sets up most of the parameters you need for a join

* The join below replaces the original extension in split-buffer
* with the extension in extension-buffer, and puts the result in
* join-buffer.
     move 1 to extension-strt
     move 3 to extension-len
     call "CBL_JOIN_FILENAME" using split-params
                                    join-buffer
                                    split-buffer
                                    split-buffer
                                    extension-buffer
$if environ = "unix"
     if join-buffer = "/DIR/FILE.CBL"
$else
     if join-buffer = "A:\DIR\FILE.CBL"
$end
         display "first test passed"
     else
         display "first test failed"
     end-if

* It is harder to set up a join without doing a split first,
* but this is what you would need to do.
     move 1 to path-strt
               basename-strt
               extension-strt

     move length of path-buffer to path-len
     move length of basename-buffer to basename-len
     move length of extension-buffer to extension-len
     move length of join-buffer to join-buf-len

     move 0 to splitjoin-flg1
     move 24 to param-length

$if environ = "unix"
     move "/path" to pat-buffer
$else
     move "c:\path" to pat-buffer
$end
     move "basename" to bas-buffer
     move "ext" to extension-buffer

     call "CBL_JOIN_FILENAME" using split-params
                                    join-buffer
                                    path-buffer
                                    basename-buffer
                                    extension-buffer

$if environ = "unix"
     if join-buffer = "/path/basename.ext"
$else
     if join-buffer = "c:\path\basename.ext"
$end
         display "second test passed"
     else
         display "second test failed"
     end-if
  stop run. 


Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousIntroduction to File Handling COBOL File OrganizationsNext"