Technical Capabilities
Having trouble finding what you need?
Get in touch with us, so we can answer your specific questions directly.
Get In Touch

VX/FDL – File Description Language Routines

Overview

VX/FDL is an implementation of the OpenVMS File Definition Language (FDL) for Linux and Windows. It is the callable library that describes RMS file structure: it parses an FDL text into RMS control blocks, creates an RMS file from an FDL specification, and generates an FDL description back from an existing RMS file, so file definitions carry over to the migrated platform with identical structure and behaviour.

The product ships as four public FDL$ routines compiled into the shared VX/RT runtime, plus two VX/DCL command front ends (CREATE/FDL and ANALYZE/RMS_FILE). There is no separate daemon or binary: VX/FDL is a library and DCL surface that recompiled OpenVMS applications link and call without source changes, handling all Indexed, Relative, and Sequential organizations.

Architecture and components

FDL is a small text description language for RMS file structure. An .FDL file is a sequence of primary sections (FILE, RECORD, KEY, AREA and others) whose indented attribute lines describe a file's organization, record format, sizes, and index keys. VX/FDL is the callable library that reads and writes that description: it parses an FDL text into RMS control blocks (a FAB plus a RAB), creates an RMS file from an FDL, and generates an FDL text back from an existing RMS file.

VX/FDL is a library plus a DCL command surface, not a long-running service. The routines compile into the shared VX/RT runtime archive (libvxrt.a) that a migrated application links directly, and two VX/DCL commands provide the operator front end. There is no daemon to administer and no separate binary to deploy.

Translation unitPublic entry pointRoleStatus
FDL_CREFDL$CREATERead an FDL, build and SYS$CREATE the matching RMS file.live
FDL_GENFDL$GENERATEOpen an RMS file and emit an FDL text describing it.live
FDL_PARFDL$PARSEParse an FDL into freshly allocated FAB and RAB blocks.live
FDL_RELFDL$RELEASEFree the FAB and RAB (and their FNA and XAB) that FDL$PARSE allocated.live
No server to administer. VX/FDL adds no process to the runtime. The four FDL$ routines are entry points inside libvxrt.a, and the DCL commands call them in-process. The only surface is the four routines plus CREATE/FDL, ANALYZE/RMS_FILE, and CONVERT/FDL.

Call lifecycle

The three operations share one internal flow: parse an FDL description into control blocks, act on those blocks (create a file, or the reverse: read a file and emit its description), then release any blocks that were allocated.

Parse and release control blocks
.FDL textFile structure description
FDL$PARSEAllocates FAB and RAB control blocks
FDL$RELEASEFrees the FAB, RAB, FNA, and XAB blocks
Create an RMS file
.FDL textOrganization, format, size, and keys
FDL$CREATEParses the description and calls SYS$CREATE
New RMS fileBuilt from the parsed control blocks
Generate an FDL description
RMS fileExisting file and attributes
FDL$GENERATEReads the file's FAB and RAB values
.FDL textOrganization, format, size, and keys

The FDL text format

An FDL file is a flat, line-oriented text tokenised on whitespace, semicolons, and newlines. The parser dispatches on a primary keyword; each primary section is followed by indented secondary attribute lines, and inside KEY and AREA sections a further set of key-specific keywords applies. There is no nesting beyond primary, secondary, and an optional qualifier value.

Primary sections

The 13 primary sections VX/FDL recognises:

TITLE
IDENT
SYSTEM
FILE
DATE
RECORD
ACCESS
SHARING
CONNECT
AREA
KEY
ANALYSIS_OF_AREA
ANALYSIS_OF_KEY

FILE and RECORD attribute keywords

The secondary keywords accepted under FILE, RECORD, and related sections cover organization, record format, allocation, and file-handling options:

BEST_TRY_CONTIGUOUS
BLOCK_IO
BLOCK_SPAN
CARRIAGE_CONTROL
CONTIGUOUS
CREATE_IF
DEFAULT_NAME
DELETE
DELETE_ON_CLOSE
FILE_NON_STRUCTURED
FORMAT
GET
MULTISTREAM
NAME
ORGANIZATION
OUTPUT_FILE_PARSE
PRINT_ON_CLOSE
PROHIBIT
PROTECTION
PUT
RECORD_IO
SEQUENTIAL_ONLY
SIZE
SUPERSEDE
TEMPORARY
TRUNCATE
TRUNCATE_ON_CLOSE
UPDATE
USER_INTERLOCK
WINDOW_SIZE

KEY section keywords

The KEY section carries 33 keywords, including the eight segment position and length pairs (SEG0_POSITION and SEG0_LENGTH through SEG7_*) plus area, fill, compression, and prologue attributes:

NAME
POSITION
LENGTH
TYPE
DUPLICATES
CHANGES
NULL_KEY
PROLOG
DATA_AREA
DATA_FILL
INDEX_AREA
INDEX_FILL
LEVEL1_INDEX_AREA
DATA_KEY_COMPRESSION
DATA_RECORD_COMPRESSION
INDEX_COMPRESSION
SEG0_POSITION
SEG0_LENGTH
...
SEG7_LENGTH

KEY data types

The 16 key data types accepted by the TYPE keyword:

BIN2
BIN4
BIN8
DBIN2
DBIN4
DBIN8
INT2
INT4
INT8
DINT2
DINT4
DINT8
DECIMAL
DDECIMAL
STRING
DSTRING

Example: an indexed file

A minimal indexed FDL that VX/FDL round-trips through CREATE/FDL, using the banking demo domain:

TITLE   "Customer master, indexed by account number"

SYSTEM
        SOURCE                  "VAX/VMS"

FILE
        NAME                    "CUSTOMER.DAT"
        ORGANIZATION            indexed

RECORD
        CARRIAGE_CONTROL        none
        FORMAT                  fixed
        SIZE                    180

KEY 0
        NAME                    "ACCOUNT_NUMBER"
        TYPE                    string
        DUPLICATES              no
        CHANGES                 no
        SEG0_POSITION           0
        SEG0_LENGTH             10

The FDL$ routine API

VX/FDL exports the four public OpenVMS FDL$ routines. Each is defined under an internal name and aliased to the VMS spelling, so both FDL$CREATE and lowercase fdl$create resolve to the same symbol and existing object references link unchanged.

RoutineSignaturePurposeStatus
FDL$CREATEFDL$CREATE(fdl, fname)Create an RMS file as defined by an FDL specification.live
FDL$GENERATEFDL$GENERATE(flags, fab, rab, fdl)Open the file named in fab and write an FDL description to fdl (a file spec) or, if empty, to the terminal.live
FDL$PARSEFDL$PARSE(fdl, fab, rab, flags, def, stmt)Parse an FDL, from a file or from a string, into newly allocated FAB and RAB blocks.live
FDL$RELEASEFDL$RELEASE(pfab, prab, flags, badblk)Free the FAB and RAB allocated by FDL$PARSE; nulls the caller's pointers.live

Every routine follows the VMS condition-value convention: the function result is returned by value, an odd value means success and an even value means failure, so callers test ODD(status).

FORTRAN-callable jackets

FDL$CREATE, FDL$GENERATE, and FDL$PARSE also expose FORTRAN-callable jackets (the F4_* variants). These accept FORTRAN string descriptors, unpack them, and call the C entry point, so mixed COBOL, FORTRAN, and C application code links against the same library. FDL$RELEASE has no FORTRAN jacket.

Flag bits

Four public flag bits gate the string-versus-file behaviour of FDL$PARSE and FDL$GENERATE:

SymbolValueMeaning
FDL$M_SIGNAL0x1Signal errors rather than return them. Reserved for source compatibility; not acted on in this release.
FDL$M_FDL_STRING0x2The fdl argument is an in-memory FDL string, not a file spec.
FDL$M_DEFAULT_STRING0x4The def argument is a defaults string, not a file spec.
FDL$M_FULL_OUTPUT0x8Emit the full, non-abbreviated FDL on generate. Reserved for source compatibility; not acted on in this release.

Status reporting

The FDL facility defines 33 FDL$_ message codes for source compatibility, tested with the usual (status & 1) success convention. The shipping library emits FDL$_OPENFDL when a CREATE/FDL input file is not found, and otherwise returns the generic RMS and system status codes (RMS$_NORMAL, RMS$_FNF for file not found, SS$_NORMAL, and related values). FDL-facility status reporting is therefore thinner than the OpenVMS original; see the status matrix below.

Call lifecycle

The routines cooperate through the RMS control blocks. FDL$PARSE allocates and fills a FAB and RAB from an FDL text; FDL$CREATE parses internally and materialises a file; FDL$GENERATE reads a file and emits a text; FDL$RELEASE frees whatever FDL$PARSE allocated.

Create path

FDL$CREATE seeds RMS defaults into a FAB and RAB, parses the FDL text into that FAB, resolves the output file name (from the routine argument or the FDL's DEFAULT_NAME), then runs SYS$PARSE and SYS$SEARCH to compute the next version and SYS$CREATE to materialise the structure, followed by SYS$CONNECT, SYS$DISCONNECT, and SYS$CLOSE. It supports three creation modes: the legacy in-place create, an erase-then-create-in-place mode, and a build-into-a-temporary-file mode used by CONVERT/FDL.

Parse path

FDL$PARSE allocates a fresh FAB and RAB, seeds RMS type, length, and organization defaults, and cross-links the RAB to the FAB. If a defaults source is supplied it is read first (from a string when FDL$M_DEFAULT_STRING is set, otherwise from a file), then the main FDL source is read and overlaid on top (from a string when FDL$M_FDL_STRING is set, otherwise from a file). File resolution tries the VMS-to-unix name, then retries with a .FDL type appended, then retries lowercased, returning RMS$_FNF only after all three miss. The stmt single-statement parameter is accepted for source compatibility but not used in this release.

Release path

FDL$RELEASE takes the address of the FAB and RAB pointers, frees the file-name string and any extended attribute block, then the FAB and the RAB, and nulls the caller's pointers to avoid dangling references. The flags and badblk arguments are accepted but unused.

End-to-end C example

The canonical setup, call, check, and cleanup path for a C caller parsing an FDL file into control blocks. Note the ODD() status test and the address-of-pointer passed to FDL$RELEASE:

/* string descriptor for the FDL spec */
VMS_DESCR fdl;
FABDEF   *fab = 0;
RABDEF   *rab = 0;
U32       flags = 0;          /* 0 means fdl_path is a FILE spec */
U32       status;

vxrt_dsc64t(&fdl, (U16)strlen(fdl_path), (char *)fdl_path);

/* parse the FDL file into freshly allocated FAB / RAB */
status = FDL$PARSE(&fdl, &fab, &rab, &flags, /*def*/ 0, /*stmt*/ 0);
if (!ODD(status))            /* e.g. RMS$_FNF if the .FDL is absent */
    return status;

/* ... use fab / rab: SYS$CREATE, SYS$OPEN, inspect organization ... */

/* free exactly what FDL$PARSE allocated; fab and rab become NULL */
FDL$RELEASE(&fab, &rab, /*flags*/ 0, /*badblk*/ 0);
return SS$_NORMAL;

To parse an in-memory FDL string instead of a file, set flags = FDL$M_FDL_STRING and point the descriptor at the text.

VX/DCL command surface

Two VX/DCL commands are the operator front end to the library, and a third also consumes an FDL. They live in VX/DCL and their syntax matches the OpenVMS originals, so existing .COM procedures and build scripts run with minimal change.

CommandCallsBehaviour
CREATE/FDL=fdl-file [out-file]FDL$CREATEBuild the output spec, defaulting a missing type on the FDL to .FDL, verify the FDL file exists, then create the RMS file. The /FDL= value is required and non-negatable. Emits an open error and a file-not-found status if the FDL is missing.
ANALYZE/RMS_FILE [/OUTPUT=x.FDL] fileFDL$GENERATEScan each file spec, default a missing type to .DAT, verify the file exists, build the output FDL spec, then generate the FDL. A missing output name or type defaults to the input name with a .FDL type.
CONVERT/FDL=fdl-file in... outFDL$CREATECreate the output from the FDL into a temporary file, copy records with SYS$GET and SYS$PUT, then rename to the target. Accepts up to 20 input files; /FDL is required unless /APPEND is given.

CREATE/FDL

The /FDL= value is required and non-negatable; the optional trailing parameter is the output file name. The handler runs a file scan over the FDL spec to fill in device, directory, and name, and supplies .FDL when no type is given. /LOG prints a line reporting whether the file was created.

! FDL to RMS file (FDL$CREATE)
$ CREATE /FDL=CUSTOMER.FDL CUSTOMER.DAT

ANALYZE/RMS_FILE

The ANALYZE/RMS_FILE sub-syntax parses /CHECK, /FDL, /INTERACTIVE, /RU_JOURNAL, /STATISTICS, /SUMMARY, and /OUTPUT, but the handler acts only on /OUTPUT in this release: it writes the generated FDL to the named file. The other analysis qualifiers are accepted by the parser and not yet acted on. Use /OUTPUT=name.FDL to capture the FDL description.

! RMS file to FDL (FDL$GENERATE)
$ ANALYZE /RMS_FILE /OUTPUT=CUSTOMER.FDL CUSTOMER.DAT

CONVERT/FDL

! load records into an FDL-defined output file
$ CONVERT /FDL=CUSTOMER.FDL CUSTOMER.SEQ CUSTOMER.IDX

What FDL$GENERATE emits

FDL$GENERATE (the routine behind ANALYZE/RMS_FILE /OUTPUT) opens the file named in the FAB and writes an FDL text describing it. If the file was created outside RMS and lacks VMS attributes it retries as a variable-format file rather than failing. Output goes to the FDL descriptor when non-empty, otherwise to the terminal.

The generated FDL is written in a fixed order and covers:

Emitted sectionSource
IDENTFile creation time.
SYSTEM SOURCEThe host identity from uname.
FILE NAMEThe resolved file specification.
ORGANIZATIONOne of sequential, relative, or indexed.
RECORD FORMATOne of fixed, stream, variable, or undefined.
SIZEThe maximum record size.
KEY blocksFor indexed files only, one block per key, pulled from the runtime key descriptors.
Scope of the generated FDL. The generator reproduces organization, record format, size, and keys. It does not reconstruct AREA allocations, bucket sizes, ACCESS, SHARING, or CONNECT sections, protections, or the ANALYSIS_OF_* statistics that a native VMS ANALYZE/RMS_FILE would produce. This is the main difference in fidelity from the OpenVMS original, and is enough to recreate a working file structure through CREATE/FDL.

The SYSTEM SOURCE line reflects the Linux or Windows host the generator runs on rather than a VMS node identity, because there is no VMS node lookup on the target platform.

Compatibility and status

VX/FDL covers the create, parse, generate, and release path end to end for all three RMS file organizations. The table records what is live and what is intentionally out of scope in this release.

CapabilityStatus
FDL$CREATE: build an RMS file from an FDLlive
FDL$PARSE: FDL text to FAB and RAB, from a file or a stringlive
FDL$RELEASE: free parsed blockslive
FDL$GENERATE: RMS file to FDL (organization, format, size, keys)live
FORTRAN-callable jackets for CREATE, GENERATE, and PARSElive
Indexed, Relative, and Sequential organizationslive
Record formats fixed, variable, stream, and undefinedlive
CREATE/FDL, ANALYZE/RMS_FILE /OUTPUT, and CONVERT/FDL DCL commandslive
Generation of AREA, ACCESS, SHARING, CONNECT, and ANALYSIS sectionsout of scope
ANALYZE/RMS_FILE qualifiers other than /OUTPUT (/CHECK, /STATISTICS, /SUMMARY and others)parsed, not acted on
Full FDL$_ message-facility reporting (33 codes)partial: codes defined, generic RMS status returned
FDL$PARSE single-statement (stmt) parameteraccepted, not used

Divergences from OpenVMS FDL

  • FDL$GENERATE emits organization, record format, size, and key sections, not the AREA, ACCESS, SHARING, CONNECT, or ANALYSIS statistics blocks. The host RMS layer exposes those attributes through the FAB and key descriptors only.
  • The SYSTEM SOURCE line comes from the Linux or Windows host name rather than a VMS node, because there is no VMS node identity on the target platform.
  • FDL-facility status reporting is reduced to a small set of codes; most work returns the generic RMS and system status values. The full set of FDL$_ symbols exists for source compatibility.
  • ANALYZE/RMS_FILE honours /OUTPUT; the other analysis qualifiers are accepted but inert in this release, which implements the FDL-generation path rather than the full ANALYZE utility family.

Quick reference

Public routines

FDL$CREATE   (fdl, fname)                          // create RMS file from FDL
FDL$GENERATE (flags, fab, rab, fdl)                // RMS file to FDL text
FDL$PARSE    (fdl, fab, rab, flags, def, stmt)     // FDL to FAB / RAB
FDL$RELEASE  (pfab, prab, flags, badblk)           // free parsed FAB / RAB

Return convention: odd means success, even means failure; test ODD(status).

VX/DCL commands

$ CREATE  /FDL=CUSTOMER.FDL CUSTOMER.DAT             ! FDL to RMS file (FDL$CREATE)
$ ANALYZE /RMS_FILE /OUTPUT=CUSTOMER.FDL CUSTOMER.DAT  ! RMS file to FDL (FDL$GENERATE)
$ CONVERT /FDL=CUSTOMER.FDL CUSTOMER.SEQ CUSTOMER.IDX  ! load records into FDL-defined file

Flag bits

FDL$M_SIGNAL 0x1
FDL$M_FDL_STRING 0x2
FDL$M_DEFAULT_STRING 0x4
FDL$M_FULL_OUTPUT 0x8

FDL primary sections

TITLE
IDENT
SYSTEM
FILE
DATE
RECORD
ACCESS
SHARING
CONNECT
AREA
KEY
ANALYSIS_OF_AREA
ANALYSIS_OF_KEY

KEY data types

BIN2
BIN4
BIN8
DBIN2
DBIN4
DBIN8
INT2
INT4
INT8
DINT2
DINT4
DINT8
DECIMAL
DDECIMAL
STRING
DSTRING

File organizations and record formats

Indexed
Relative
Sequential
Fixed
Variable
Stream
Undefined

Frequently Asked Questions

Curious about how Sector7 can facilitate your application migration? Explore our FAQs for expert insights.

What is VX/FDL and how does it help with OpenVMS migration to Linux?

VX/FDL is an implementation of OpenVMS File Description Language (FDL) for Linux that enables the creation, analysis, and management of RMS files with identical structure and behavior to their VMS counterparts. It provides a seamless migration path for legacy RMS data to remain accessible and functional on modern Linux platforms.

The tool allows you to import VMS/OpenVMS FDL files, recreate RMS files with all supported organizations and formats, and leverage VX/DCL commands for comprehensive file management. For organizations looking to modernize their infrastructure, contact us to discuss your specific migration requirements.

What file organizations does VX/FDL support?

VX/FDL handles all Indexed, Relative, and Sequential RMS file organizations with full compatibility.

Which record formats are compatible with VX/FDL?

VX/FDL supports Sequential and Fixed record formats, ensuring 1:1 mapping with VMS files for complete compatibility.

How do I create an RMS file from a VMS FDL specification?

Use the CREATE/FDL command to read your FDL file and generate a matching RMS file on Linux.

Can VX/FDL generate FDL files from existing RMS files?

Yes, VX/FDL includes the ANALYZE/FDL command that extracts an FDL specification from existing RMS files. This reverse capability allows you to document and recreate file structures as needed.

Organizations like Telstra have successfully used similar RMS migration approaches during their OpenVMS modernization projects.

What VX/DCL commands are available for FDL management?

VX/DCL includes CREATE/FDL for creating RMS files from FDL specifications and ANALYZE/FDL for extracting FDL specifications from existing RMS files.

Does VX/FDL provide programming APIs for application integration?

VX/FDL provides a call-compatible library with full implementation of the FDL$() API functions. This includes FDL$CREATE for creating RMS files, FDL$GENERATE for generating FDL files, FDL$PARSE for parsing existing FDL files, and FDL$RELEASE for memory management.

What are the key benefits of using VX/FDL for migration projects?

VX/FDL delivers full compatibility with VMS/OpenVMS FDL, enabling seamless migration of RMS files to Linux while providing identical structure and behavior for RMS data. The tool includes VX/DCL support for automation and supports both command-line and API-based workflows.

Companies like BNY Mellon have leveraged similar file system migration capabilities during their OpenVMS to Linux transitions. VX/FDL ensures legacy RMS data remains accessible, structured, and functional on modern platforms. To explore how VX/FDL can support your migration strategy, contact us for a consultation.

What is VX/FDL?

VX/FDL is an implementation of the OpenVMS File Definition Language (FDL) for Linux and Windows. It lets you create, analyze, and manage RMS files with the same structure and behaviour as their VMS counterparts, so FDL-based file definitions carry over to modern platforms.

Which RMS file organizations and record formats does VX/FDL support?

VX/FDL handles all Indexed, Relative, and Sequential RMS file organizations, and supports Sequential and Fixed record formats, giving a 1:1 mapping with the original VMS files.

How do I create an RMS file from an FDL specification?

Use the CREATE/FDL command (via VX/DCL) or the FDL$CREATE API call to read your FDL file and create a matching RMS file on Linux or Windows.

How do I generate an FDL file from an existing RMS file?

Use the ANALYZE/RMS_FILE command with /OUTPUT (via VX/DCL) or the FDL$GENERATE API call to extract an FDL specification from an RMS file, which can then recreate the file structure.

What VX/DCL commands does VX/FDL provide?

Two main commands: CREATE/FDL, which creates an RMS file from an FDL specification (via FDL$CREATE), and ANALYZE/RMS_FILE, which analyses an RMS file and, with /OUTPUT, writes an FDL specification describing it (via FDL$GENERATE). CONVERT/FDL is also available for loading records into a new FDL-defined RMS file.

Does VX/FDL offer a programming API as well as command-line tools?

Yes. VX/FDL includes a call-compatible library implementing the FDL$() API: FDL$CREATE (create an RMS file from FDL), FDL$GENERATE (generate FDL from an RMS file), FDL$PARSE (parse an existing FDL file), and FDL$RELEASE (release FDL structures from memory), so it fits both scripted and application-integrated workflows.

Can VX/FDL import my existing VMS or OpenVMS FDL files?

Yes. VX/FDL can import VMS and OpenVMS FDL files and recreate the corresponding RMS files with all supported organizations and formats. This preserves the file structure defined on the original VMS system.

How does VX/FDL fit an OpenVMS to Linux migration?

By reproducing RMS file structures with identical behaviour on Linux and Windows, VX/FDL keeps legacy RMS data accessible, structured, and functional on modern platforms. It supports both command-line (VX/DCL) and API-based workflows, providing a migration path for OpenVMS applications that depend on FDL-defined files.

Transform Your Legacy Software Today!

Get In Touch
Unlock the potential of your legacy software with our expert migration services.