[comp.lang.c] VAXC wildcard expansion routine enclosed

LC.YRS@forsythe.stanford.edu (Richard Stanton) (02/17/90)

I just received this from Scott Henderson, to whom I'm extremely
grateful. It is a VAXC replacement for the MSC setargv.obj.

#if defined(VAXC)
static char buffer[128];
static char *av[1024];
static int  ac;

/* setargv()
 *
 * Make a copy of argv[].  All wildcards starting with argv[start]
 * are expanded and all matching file specifications are stored
 * back in the new argv[].
 */
void    setargv(argc, argv, start)
int     *argc;
char    **argv[];
int     start;
{
    char    *p;
    int     i;
    long    context = 0L;

    /* string descriptors (yeecch!) */
    struct dsc$descriptor_s mask_descr;
    $DESCRIPTOR(buffer_descr, buffer);

    /* set descriptor class and type - these don't change */
    mask_descr.dsc$b_class = DSC$K_CLASS_S;
    mask_descr.dsc$b_dtype = DSC$K_DTYPE_T;

    /* copy all parameters up to 'start' */
    for (i = 0; i < start; ++i) {
        av[i] = (char *) malloc((strlen((*argv)[i]) + 1) * sizeof(char));
        if (av[i] == NULL) {
            fprintf(stderr, "Error: setargv: out of memory\n");
            exit(1);
        }
        strcpy(av[i], (*argv)[i]);
    }

    /* expand all wildcards found in argv[], starting at argv[start] */
    ac = start;
    for (i = 1; i < *argc; ++i) {

        /* set up a descriptor for argv[i] */
        mask_descr.dsc$w_length = strlen((*argv)[i]);
        mask_descr.dsc$a_pointer = (*argv)[i];

        /* find all matching file specifications */
        do {
            lib$find_file(&mask_descr, &buffer_descr, &context);
            if (context) {
                /* since the buffer was passed by descriptor, the length will */
                /* always be equal to the size of the buffer - so remove the */
                /* inevitable trailing whitespace */
                for (p = &(buffer[0]); !isspace(*p); ++p); *p = '\0';

                /* make a copy of the buffer */
                av[ac] = (char *) malloc((strlen(buffer) + 1) * sizeof(char));
                if (av[ac] == NULL) {
                    fprintf(stderr, "Error: setargv: out of memory\n");
                    exit(1);
                }
                strcpy(av[ac++], buffer);
            }
        }
        while (context);
    }

    /* save new argc and argv */
    *argc = ac;
    *argv = av;
}
#endif /* VAXC */

Hope this helps other people as much as it helps me.

Richard Stanton