/* -*-C-*-
*******************************************************************************
*
* File:         wildcard.c
* RCS:          $Header: $
* Description:  Simple interface to the filename globbing routines.
* Author:       Darryl Okahata
* Created:      Sat Apr 24 22:54:08 1993
* Modified:     Tue Apr  5 01:33:59 1994 (darrylo@home) darrylo@hostigos
* Language:     C
* Package:      N/A
* Status:       Experimental (Do Not Distribute)
*
* (C) Copyright 1993, 1994 Darryl Okahata, all rights reserved.
*
*******************************************************************************
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

#include "dosglob.h"


static int	__orig_argc;
static char	**__orig_argv;


static die_no_mem()
{
    fprintf(stderr, "\r\nOut of memory!\r\n");
    exit(1);
}


/*
 * There is a lot of duplicated code in the following, but I'm too lazy
 * to fix this.  It works, so don't fix it.
 */
__process_wildcards(argc, argv)
int	*argc;
char	*(*argv[]);
{
    int		i, j, status;
    int		new_argc, argv_size;
    char	**new_argv;
    glob_t	gb;

    __orig_argc = *argc;
    __orig_argv = *argv;
    new_argc = 0;
    argv_size = 30;
    if (*argc > argv_size) {
	argv_size = *argc * 2;
    }
    if ((new_argv = malloc(sizeof(char *) * (argv_size + 1))) == NULL) {
	die_no_mem();
    }
    for (i = 0; i < *argc; ++i) {
	memset(&gb, 0, sizeof(gb));
	/*
	 * Unfortunately, with WATCOM C/386, double-quotes are not passed
	 * on to arguments, and so the following code to test for
	 * double-quoted arguments does not work with WATCOM C/386.
	 */
	if ((*((*argv)[i]) != '"') &&
	    strpbrk((*argv)[i], "*[?")) {
	    if ((status = glob((*argv)[i], GLOB_NOCHECK,
			       NULL, &gb)) == 0) {
		if (new_argc + gb.gl_pathc >= argv_size) {
		    if ((new_argv = realloc(new_argv,
					    ((argv_size = (new_argc +
							  gb.gl_pathc) * 2) +
					     1) * sizeof(char *))) == NULL) {
			die_no_mem();
		    }
		}
		for (j = 0; j < gb.gl_pathc; ++j) {
		    new_argv[new_argc++] = gb.gl_pathv[j];
		}
	    } else {
		if (status == GLOB_NOSPACE) {
		    die_no_mem();
		}
		if (new_argc >= argv_size) {
		    if ((new_argv = realloc(new_argv,
					    ((argv_size = new_argc * 2) + 1) *
					    sizeof(char *))) == NULL) {
			die_no_mem();
		    }
		}
		new_argv[new_argc++] = (*argv)[i];
	    }
	} else {
	    if (new_argc >= argv_size) {
		if ((new_argv = realloc(new_argv,
					((argv_size = new_argc * 2) + 1) *
					sizeof(char *))) == NULL) {
		    die_no_mem();
		}
	    }
	    if (*((*argv)[i]) == '"') {
		char	*buf, len;

		if ((buf = malloc(strlen((*argv)[i]))) == NULL) {
		    die_no_mem();
		}
		strcpy(buf, &(((*argv)[i])[1]));
		if (((len = strlen(buf)) > 0) && buf[len - 1] == '"') {
		    /*
		     * Drop closing quote
		     */
		    buf[len - 1] = '\0';
		}
		new_argv[new_argc++] = buf;
	    } else {
		new_argv[new_argc++] = (*argv)[i];
	    }
	}
    }
    new_argv[new_argc] = NULL;
    *argc = new_argc;
    *argv = new_argv;
}

#ifdef TEST_WILDCARDS
main(argc, argv)
int	argc;
char	*argv[];
{
    int		i;

    __process_wildcards(&argc, &argv);
    for (i = 0; i < argc; i++) {
	printf ("argv[%d] = '%s'\n", i, argv[i]);
    }
}
#endif
