fnm_util - Filename Utilities

The FNM_UTIL package provides a filename parsing capability inspired by the VAX/VMS lexical function, f$parse(). File specifications have the following structure:

Any field is optional. node is a host name; directory is one or more names separated by "/"s; name follows the last "/" in the pathname. version is a 3-digit number (e.g., 002) and extension follows the last dot before the version dot.

A filename is created as follows:

    #include  "fnm_util.h"			-- Filename utilities.
    FileName  fname ;
    fname = fnmCreate ("fileSpec", NULL) ;
fnmCreate() expands the file specification, translating environment variable references and filling in defaults for missing fields.

fnmCreate() can be passed multiple file specifications, which are then processed from left to right in the calling sequence:

    fname = fnmCreate ("spec1", ..., "specN", NULL) ;
First, the leftmost file specification is examined and any references to environment variables are translated. The next file specification is then examined. Environment variables are translated and fields missing in the first file specification are supplied from the new file specification. Subsequent file specifications are examined, in turn, and "applied" to the results of the processing of the previous file specifications. Finally, system defaults (e.g., the user's home directory) are supplied for missing fields that remain.

Is that clear? I used to have a diagram that showed the file names stacked up, one on top of another:

                          ... System Defaults ...
                               File_Spec_#N    |
                                    ...        |
                               File_Spec_#2    |
                               File_Spec_#1    V
File name components would drop down through holes in lower-level specifications to fill in missing fields in the result.

Specifying multiple file specifications is useful for replacing extensions, concatenating directories, etc.:

    #include  "fnm_util.h"			-- Filename utilities.
    FileName  fname ;
    ...						-- "/usr/me" (current directory)
    fname = fnmCreate (NULL) ;
						-- "/usr/me/prog.lis"
    fname = fnmCreate (".lis", "prog.c", NULL) ;
						-- "/usr/you/tools/dump.o"
    fname = fnmCreate (".o", "tools/dump.c", "/usr/you/", NULL) ;
What can you do with a file name once it is created? You call fnmParse() to get the whole file name or parts of the file name as a string:

    #include  "fnm_util.h"			-- Filename utilities.
    char  *s ;
    FileName  fname ;
    fname = fnmCreate ("host:/usr/who/myprog.c.001", NULL) ;
    s = fnmParse (fname, FnmPath) ;		-- "host:/usr/who/myprog.c.001"
    s = fnmParse (fname, FnmNode) ;		-- "host:"
    s = fnmParse (fname, FnmDirectory) ;	-- "/usr/who"
    s = fnmParse (fname, FnmFile) ;		-- "myprog.c.001"
    s = fnmParse (fname, FnmName) ;		-- "myprog"
    s = fnmParse (fname, FnmExtension) ;	-- ".c"
    s = fnmParse (fname, FnmVersion) ;		-- ".001"
    fnmDestroy (fname) ;
Shorthand macros - fnmPath(), fnmNode(), etc. - are defined for each of the fnmParse() calls above.


The FNM_UTIL package is a repackaging of my FPARSE package, which was inspired by the VAX/VMS lexical function, f$parse().

Public Procedures

fnmCreate() - creates a filename.
fnmDestroy() - destroys a filename.
fnmExists() - checks if a file exists.
fnmParse() - parses a filename.

Macro Definitions

fnmPath() - returns a filename's full pathname.
fnmNode() - returns the node from a filename.
fnmDirectory() - returns the directory from a filename.
fnmFile() - returns the file, extension, and version from a filename.
fnmName() - returns the file from a filename.
fnmExtension() - returns the extension from a filename.
fnmVersion() - returns the version number from a filename.

Source Files


(See libgpl for the complete source, including support routines and build files.)

Alex Measday  /  E-mail