Previous | Table of Contents | Next

### Generating the File List

One of the basic requirements of CARMAN is that it be able to handle lists of files, so that it can perform operations on select groups of files. Every one of the seven CARMAN commands accepts a list of files as an argument, so we need to have a general purpose way to build and manage a list of files. The list function should also be able to accommodate at least some level of wild card pattern matching as well.

Wild card matching needs to be done a little differently under MS-DOS and UNIX. First of all, there are actually two types of wild card matching taking place in CARMAN. File specifications on the command line with the ‘Add’ command, including wild cards, specify external files that are going to be added to the CAR file. File specifications for all of the other commands refer to files stored inside the CAR file. Thus we have to handle these two types of file lists using slightly different methods.

To complicate further, UNIX and MS-DOS differ significantly in the way their command lines handle wild card file specifications. Under either operating system, if we want to add all the C files in a directory to an archive, we would type a similar command:

    carman a c_files.car *.c

Under UNIX, the command interpreter, or shell program, expands the list of wild card file names before the program ever sees it. This means that by the time CARMAN is invoked, it is presented with a command line that might look something like this:

    carman a c_files.car test.c io.c foo.c bar.c

This is one of the nice features of UNIX; an application program doesn’t have to worry about wild card expansion of files from the command line because the shell takes care of the work.

Under MS-DOS, matters are a little more complicated. Wild card expansion is thought of as being the province of an application program, not the command-line interpreter. So code that builds the file name list has to perform the expansion manually using C run-time library functions. Even worse, the function names and structure definitions used to expand wild card listings have not been standardized among compiler vendors, so that each new compiler needs a slightly different implementation.

In CARMAN, the list of the file names is found in an array called FileList[]. FileList is an array of character pointers which is set up via a routine called BuildFileList(). BuildFileList() is called right after the command line is parsed, and is passed a list of command-line arguments, along with a count.

BuildFileList() normally just copies the arguments passed to it into the FileList[] array. If there are no command-line arguments, FileList[0] is set to ‘*’, so that all file names in the archive will be matched as they are processed. This has the effect of converting a command like “CARMAN L TEST.CAR” to “CARMAN L TEST.CAR *”.

BuildFileList() changes its mode of operation if the user has specified that the command is ‘A,’ to add files, and the operating system is MS-DOS. Under these circumstances, a special routine is called to expand a potential wild-card file specification into a list of file names, with the results all being stored in the FileList[].

    void BuildFileList( argc, argv, command )
    int argc;
    char *argv[];
    int command;
    {
     int i;
     int count;
     count = 0;
     if ( argc == 0 )
        FileList[ count++ ] = "*";
     else {
        for ( i = 0 ; < argc ; i++ ) {
    #ifdef MSDOS
          if ( command == 'A' )
           count = ExpandAndMassageMSDOSFileNames (count, argv[ i ]);
          else
           MassageMSDOSFileName( count++, argv[ i ] );
    #endif
    #ifndef MSDOS
      FileList[ count ] = malloc( strlen( argv[ i ] ) + 2);
      if ( FileList[ count ] == NULL )
        FatalError( "Ran out of memory storing file names" );
      strcpy( FileList[ count++ ], argv[ i ];
    #endif
      if ( count > 99 )
        FatalError( "Too many file names" );
      }
     }
     FileList[ count ] = NULL;
    }

In addition, a special routine called MassageMSDOSFileName() is called to normalize all MS-DOS file names. MS-DOS has a couple of complications in its file system. First of all, file names are case insensitive, meaning that “FOO.BAR” and “foo.bar” both refer to the same file, despite the fact that their names are different. Secondly, the 8+3 file naming convention means that “FOO” and “FOO.” both refer to the same file, even though one has a trailing ‘.’ character and the other doesn’t.

Massage MSDOSFileName() gets around this problem by performing two operations on file names. First of all, uppercase characters in file names on the command line are all converted to lowercase, to avoid ambiguities created by case mismatches. Secondly, any file that doesn’t have an extension or a ‘.’ in the name has a ‘.’ character appended to the end of its name. Note that if the file name contains a ‘*’ or ‘?’ character, meaning it is a wild card, the ‘.’ character is not appended to a file name with no extension.

Previous | Table of Contents | Next