/*
 * wildargs.c - routine to expand arguments with wildcards (as UNIX shells)
 *
 * Bruno Costa - 15 Mar 91 - 19 Mar 91
 *
 * (Requires AmigaDOS 2.0)
 */

#include <exec/types.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include <stdlib.h>
#include <string.h>
#include "wildargs.h"

extern struct DosLibrary *DOSBase;
static int wildopt = WILD_FILES | WILD_DIRS;

#define MAXPATH 100
#define MAXARGS 256

#define memclear(area,size) memset(area, 0, size)
#define isfile(anchor)	((anchor)->ap_Info.fib_DirEntryType < 0)
#define isdir(anchor)	((anchor)->ap_Info.fib_DirEntryType > 0)

static int haswild (char *pattern)
{
 static char buffer[MAXPATH];
 return (int)ParsePattern (pattern, buffer, MAXPATH);
}


static char *nextfile (char *pattern)
{
 long err;
 char *pathname = NULL;
 static struct AnchorPath *anchor = NULL;

 if (pattern == NULL)
   err = -1;
 else
   do
   {
     if (anchor == NULL)
     {
       anchor = malloc (sizeof (struct AnchorPath) + MAXPATH);
       memclear (anchor, sizeof (struct AnchorPath) + MAXPATH);

       anchor->ap_BreakBits = SIGBREAKF_CTRL_C;
       anchor->ap_Strlen = MAXPATH;
       anchor->ap_Flags = APF_DOWILD | APF_DODOT;

       if (!(wildopt & WILD_KEEPSTAR)  &&  strcmp (pattern, "*") == 0)
         err = MatchFirst ("#?", anchor);
       else
         err = MatchFirst (pattern, anchor);
     }
     else
       err = MatchNext (anchor);

     if (isfile (anchor)  &&  wildopt & WILD_FILES)
       pathname = anchor->ap_Buf;
     if (isdir (anchor)  &&  wildopt & WILD_DIRS)
       pathname = anchor->ap_Buf;

   } while (err == 0  &&  pathname == NULL);

 if (err)
 {
   MatchEnd (anchor);
   free (anchor);
   anchor = NULL;

   return NULL;
 }
 else
   return pathname;
}


void wildoptions (int options)
{
 wildopt = options;
}


int wildargs (int *oargc, char ***oargv)
{
 int i;
 char *str;
 int argc = 0;
 char **argv = calloc (MAXARGS, sizeof (char *));

 if (!argv)
   return FALSE;

 for (i = 0; i < *oargc; i++)
 {
   if (haswild ((*oargv)[i]))
   {
     while (str = nextfile ((*oargv)[i]))
       if (argc >= MAXARGS)
       {
         nextfile (NULL);
         return FALSE;
       }
       else
         argv[argc++] = strdup (str);
   }
   else
     if (argc >= MAXARGS)
       return FALSE;
     else
       argv[argc++] = (*oargv)[i];
 }

 *oargc = argc;
 *oargv = argv;

 return TRUE;
}


#ifdef TEST
#include <stdio.h>

void main (int argc, char *argv[])
{
 int i;

 if (!wildargs (&argc, &argv))
   printf ("error expanding args!\n");

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