/*   ---------------------------------      -------     
 *   |\  | | | | |  |.| |   \|  |/ /|\      |||||||     
 *   | | | |/  | |\ |/  |/|  |\ |/  |    ?  ---+---  =< 
 *   | | | |   | |  |     |  |  |   |     \qqqqqqqqq/   
 *   ---------------------------------  ~~~~~~~~~~~~~~~~
 *  foreach() - Calls a function for each of the file names given.
 *              Patterns are expanded to the matching file names.
 *              Directories and soft links are ignored.
 *              The user supplied function is called with the full
 *              path name of each matched file. This may lead to
 *              unexpected results if two or more available volumes
 *              have the same name. The canonical way to do it, is to
 *              pass a lock on the directory containing the file and
 *              have the function temporarily CurrentDir() to it.
 *              Alas, doing that will require a rewrite of almost the
 *              entire package so we will just have to live with it
 *              for now. Maybe in a future release... ;-)
 *
 *  Copyright (C) 1993 Torsten Poulin
 *
 *  This file is part of "Torsten's AmigaDOS Shell Commands" package.
 *  The package is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  The package is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  The author can be contacted by s-mail at
 *    Torsten Poulin
 *    Banebrinken 99, 2, 77
 *    DK-2400 Copenhagen NV
 *    DENMARK
 *
 * $Id: foreach.c,v 1.2 93/03/01 12:59:08 Torsten Rel $
 * $Log:	foreach.c,v $
 * Revision 1.2  93/03/01  12:59:08  Torsten
 * Changed all occurrences of "struct DosBase *" to "struct DosLibrary *"
 * 
 * Revision 1.1  93/03/01  10:59:15  Torsten
 * Initial revision
 * 
 */

#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dosasl.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#ifdef __SASC
#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#endif
#include "tastlib.h"

struct Global {
  struct DosLibrary *DOSBase;
};


LONG foreach(UBYTE **arg, LONG (*func)(UBYTE *, VOID *), VOID *global)
{
  struct DosLibrary *DOSBase = ((struct Global *) global)->DOSBase;
  struct AnchorPath *ap;
  LONG rc;

  if (!(ap = AllocVec(sizeof(struct AnchorPath) + MAXNAMELEN + 1,
		      MEMF_PUBLIC | MEMF_CLEAR)))
    return ERROR_NO_FREE_STORE;
  ap->ap_Strlen = MAXNAMELEN;
  ap->ap_BreakBits = SIGBREAKF_CTRL_C;

  for (; *arg; arg++)
  {
    if ((rc = MatchFirst(*arg, ap)) == 0)
      do
      {
	if (ap->ap_Info.fib_DirEntryType < 0)
	{
	  rc = func(ap->ap_Buf, global);
	  if (rc == ERROR_BREAK || rc == ERROR_NO_FREE_STORE)
	    break;
	}
      } while ((rc = MatchNext(ap)) == 0);
    MatchEnd(ap);
  }
  FreeVec(ap);

  if (rc == ERROR_NO_MORE_ENTRIES)
    rc = RETURN_OK;
  return rc;
}
