/*
 *	For.c - Copyright © 1992 by Devil's child.
 *
 *	Created:	30 Mar 1992  18:26:36
 *	Modified:	14 Mar 1993  12:03:47
 *
 *	Make>> sc <file>.c
 *	Make>> slink LIB:cs.o <file>.o SC SD ND BATCH NOICONS TO <file> LIB LIB:Startup.lib LIB:String.lib
 *	Make>> Protect <file> P ADD
 */


extern struct ExecBase *SysBase;


char *Template = "Args/M,ALL/S,DONTFAIL/S,DO/K/A/F";
char *CliHelp = "\
[32mFor[31m V1.0 © 1992 by [33mS.R. & P.C.[31m\n\
Usage: For <Files | Pattern> [ALL] DO Command [args] [,Command [args] [,...]]\n\
For executes a list of commands for each file given,\n\
replacing each %% in commands with current file name.\n\
ALL: Recursively descends in subirectories.\n\
DONTFAIL: Continue even if a command fails.\n";


#define Arg_All			1
#define Arg_DontFail	2
#define Arg_Command		3

#define MAX_PATHLEN		256


BOOL CheckedRun(char *CmdBuf, long *RC)
{
	if ((*RC = SystemTags(CmdBuf, TAG_DONE)) > Cli()->cli_FailLevel) {
		Printf("ForEach: Command '%s' Failed.\n", CmdBuf);
		return FALSE;
	}
	else
		return TRUE;
}


/*
 *	Parse a line that may contain comas. Backslash ('\') is the override char.
 */

static void __inline ParseCmdLine(char *cmd)
{
	char *s,*d,c;

	s = d = cmd;
	while (c = *d++ = *s++) {
		if (c == '\\')
			*(d-1) = *s++;
		else if (c == ',')
			*(d-1) = '\n';
	}
}


long Main(char *argv[], struct WBStartup *WBenchMsg)
{
	char CmdBuf[512], Fmt[512], ArgBuf[256];
	char **Args, *s;
	struct AnchorPath *AP;
	long RC = 20, len;
	BOOL Found = FALSE, Abort = FALSE;

	strcpy(Fmt, argv[Arg_Command]);
	if ((len = strlen(Fmt)) == 0)
		return 10;
	ParseCmdLine(Fmt);	/* Replace , by \n to separate commands */
	s = Fmt;
	while(*s) {
		if (*s == '%' && *(s+1) == '%') {
			*(s+1) = 's';
			Found = TRUE;
		}
		s++;
	}
	if (!Found)
		strcpy(&Fmt[len], " %s");

	if (Args = (char **)argv[0]) {
		if (AP = AllocVec(sizeof(struct AnchorPath)+MAX_PATHLEN, MEMF_PUBLIC|MEMF_CLEAR)) {
			while (!Abort && *Args) {
				LONG MatchErr;

				AP->ap_BreakBits = SIGBREAKF_CTRL_C;	/* Break on these bits	*/
				AP->ap_Strlen = MAX_PATHLEN;
				AP->ap_Flags = (argv[Arg_All]) ? APF_DODOT : APF_DODOT|APF_DOWILD;	/* allow convertion of '.' to CurrentDir */
				MatchErr = MatchFirst(*Args, AP);
				while (!MatchErr) {
					if (argv[Arg_All] && AP->ap_Info.fib_DirEntryType > 0) {
						if (!(AP->ap_Flags & APF_DIDDIR))
							AP->ap_Flags |= APF_DODIR;
						/* clear the completed directory flag */
						AP->ap_Flags &= ~APF_DIDDIR;
					}
					else {
						s = AP->ap_Buf;
						SPrintf(ArgBuf, StrChr(s, ' ') ? "\"%s\"" : "%s", s);
						/* Allow 5 %% in cmd */
						SPrintf(CmdBuf, Fmt, ArgBuf, ArgBuf, ArgBuf, ArgBuf, ArgBuf);
						if (!CheckedRun(CmdBuf, &RC) && !argv[Arg_DontFail]) {
							Abort = TRUE;
							break;
						}
					}
				    MatchErr = MatchNext(AP);
				}
				MatchEnd(AP);	/* This absolutely, positively must be called, all of the time. */
				if (!Abort && MatchErr != ERROR_NO_MORE_ENTRIES) {
					PrintFault(MatchErr, NULL);
					RC = 20;
					break;
				}
				Args++;
			}
			FreeVec(AP);
		}
	}
	else {
		SPrintf(CmdBuf, Fmt, "", "", "", "", "");	/* Always remove %%'s from command line */
		CheckedRun(CmdBuf, &RC);
	}
	return RC;
}

