[comp.sys.ibm.pc] Turbo C cmd line wild-cards

richardh@killer.UUCP (Richard Hargrove) (08/01/87)

For those who need a way to expand wid-card filespec command line 
arguments in Turbo C, see below. The only known problem is that
there is no way to get the string "*.*" into the program code (or 
any string containing wild-card characters that match a filespec)
because the quoting supported in c0.asm has already been stripped 
off. I think that is a very minor problem and is easily solved in 
the user's code.

save as exparg.h:

*---*---* cut here *---*---* cut here *---*---* cut here *---*---* cut here *-*

/*	exparg.h	header file for exparg(), the routine that performs
 *			wild-card expansion on filespecs in the command line
 *			parameters
 */
 
#ifndef EXP_ARG
#define EXP_ARG

char **exparg (int *pargc, char *argv []);

#endif
*---*---* cut here *---*---* cut here *---*---* cut here *---*---* cut here *-*

save as exparg.c:

*---*---* cut here *---*---* cut here *---*---* cut here *---*---* cut here *-*

/*	exparg.c	source code for exparg()
 */

/******************************************************************************

	NAME		exparg - expand filespec command line parameters
				 containing wild-card characters

	USAGE		#include "exparg.h"
			char **exparg (int *pargc, char *argv []);

	PROTOTYPE IN	exparg.h

	DESCRIPTION	Exparg is used to explicitly process the filespec
			command line parameters containing wild-card
			characters. It takes a pointer to an integer 
			containing the count of the parameters and a pointer
			to an array of pointers to the strings copied from 
			the comamnd line. It is anticipated that most of the 
			time exparg() will be called immediately upon entry
			to main(), with the call looking like

				argv = exparg (&argc, argv);

			See the test program included in this file for an
			example usage.

			When exparg() finds a filespec parameter string 
			containing wild-card characters, it replaces the 
			string with the name of the first file that matches 
			it and adds the names of subsequent matches to the
			list of parameter string pointers. If no matching file
			names are found, the original string is left in place.

			Upon return from exparg() argc will be updated to 
			indicate the new number of command line parameters
			and argv will point to a different array of string 
			pointers. Command line parameter processing can then
			proceed as it would have been done before.

	RETURN VALUE	A pointer to an array of string pointers that point 
			to the expanded filespec command line parameters. The
			int containing the parameter count is modified as a
			side-affect.

	PORTABILITY	MS-DOS specific, Turbo-C specific
	
	AUTHOR		Richard Hargrove
			Texas Instruments, Inc.
			P.O. Box 869305, m/s 8473
			Plano, Texas 75086
			214/575-4128

 *****************************************************************************/

#include <stdio.h>
#include <string.h>
#include <dir.h>
#include <dos.h>
#include <alloc.h>

#define	MAXARGS		100	/* maximum number of entries the new argv */
				/* array can contain			  */

#define TRUE		1
#define FALSE		0
#define NIL(type)	((type *) NULL)

typedef int BOOLEAN;

/*****************************************************************************/

char **exparg (int *pargc, char *argv [])
{
	static char *newargv [MAXARGS];	
	char path [MAXPATH];		/* if the stack doesn't overflow, */
	char drive [MAXDRIVE];		/* we have less lasting impact    */
	char dir [MAXDIR];		/* on the static data segment     */

	char far *olddta = getdta ();
	struct ffblk fblk;
	register int args = 0;
	register int newargc = 0;
	BOOLEAN err = FALSE;
	
	while (!err && args < *pargc) {
	  if ((fnsplit(argv[args],drive,dir,NIL(char),NIL(char))& WILDCARDS) &&
	     (!findfirst (argv [args], &fblk, 0))) {
	    do {
	      char *localcptr = (char *)malloc (
		(unsigned)(stpcpy (stpcpy (stpcpy (path, drive), 
					   dir), 
				   fblk.ff_name) - path) + 1);
	      if (localcptr != NIL(char)) {
		newargv [newargc++] = strcpy (localcptr, path);
	      }
	      else {
	 	fputs ("\n_exparg error : no memory for filenames\n", stderr);
		exit (1);
	      }
	    } while ((newargc < MAXARGS) && !findnext (&fblk));
	  }
	  else {
	    newargv [newargc++] = argv [args];
	  }
	  err = (newargc == MAXARGS);
	  args++;
	}

	if (err) fputs ("\n_exparg error : too many filenames\n", stderr);
	setdta (olddta);
	*pargc = newargc;
	return (&newargv [0]);
}

#ifdef TEST

/*****************************************************************************/

main (int argc, char *argv [])
{
	/*	test exparg()
	 */
	 
	int i = 0;
	
	printf ("original command line parameters : argc: %d\n", argc);
	for (; i < argc; i++) {
	  printf ("%s\n", argv [i]);
	}

	argv = exparg (&argc, argv);

	printf ("new command line parameters : argc: %d\n", argc);
	for (i = 0; i < argc; i++) {
	  printf ("%s\n", argv [i]);
	}
}
#endif
*---*---* cut here *---*---* cut here *---*---* cut here *---*---* cut here *-*

enjoy,
richard hargrove
------------------------------------
cis:    74756,664
usenet: ...!killer!xenixwar!richardh
------------------------------------