/******************************************************************************
 touchall.cc

	Touches all files containing a given string.  This is mainly useful when
	a global compile flag is to be changed:  only the files that actually
	use the flag will be recompiled.

	Copyright © 1996 by John Lindal. All rights reserved.

 ******************************************************************************/

#include <JIPCIOStream.h>
#include <jProcessUtil.h>
#include <JString.h>
#include <iostream.h>
#include <jStreamUtil.h>
#include <stdlib.h>
#include <jAssert.h>

// Constants

static const JCharacter* kVersionStr =
	"touchall 1.0.0\n"
	"Copyright 1996 by John Lindal\n"
	"The shared binary and link-kit versions of this\n"
	"program may be freely distributed at no charge.";

static const JCharacter* kSearchExec    = "grep ";
static const JCharacter* kSearchError   = "grep";
static const JCharacter* kFileDelimiter = ":";

static const JCharacter* kModifyExec    = "touch ";

// Prototypes

void PrintVersion();

/******************************************************************************
 main

 ******************************************************************************/

int
main
	(
	int argc,
	char* argv[]
	)
{
	if (argc == 2 && strcmp(argv[1], "-v") == 0)
		{
		PrintVersion();
		return 0;
		}
	else if (argc < 3)
		{
		cerr << "Usage:  " << argv[0] << " <string> <files>  (same as grep)" << endl;
		return 1;
		}

	JString sysCmd = kSearchExec;
	sysCmd += JPrepArgForExec(argv[1]);
	for (int i=2; i<argc; i++)
		{
		sysCmd += " ";
		sysCmd += JPrepArgForExec(argv[i]);
		}

	pid_t childPID;
	int fromFD;
	const JError err = JExecute(sysCmd, &childPID,
								kJIgnoreConnection, NULL,
								kJCreatePipe, &fromFD);
	if (!err.OK())
		{
		cerr << err.GetMessage() << endl;
		return 1;
		}

	JIPCIOStream input(fromFD, JIPCIos::kRead, kTrue);
	JString prevFile;
	while (input.good())
		{
		const JString line = JReadLine(input);
		JIndex colonIndex;
		const JBoolean found = line.LocateSubstring(kFileDelimiter, &colonIndex);
		if (!found || colonIndex == 1)
			{
			cout << line << endl;
			}
		else
			{
			const JString fileName = line.GetSubstring(1, colonIndex-1);
			if (fileName == kSearchError)
				{
				cout << line << endl;
				}
			else if (fileName != prevFile)
				{
				sysCmd  = kModifyExec;
				sysCmd += JPrepArgForExec(fileName);
				cout << sysCmd << endl;
				const JError err = JExecute(sysCmd, NULL);
				if (!err.OK())
					{
					cerr << err.GetMessage() << endl;
					return 1;
					}
				prevFile = fileName;
				}
			}
		}

	return 0;
}

/******************************************************************************
 PrintVersion

 ******************************************************************************/

void
PrintVersion()
{
	cout << endl;
	cout << kVersionStr << endl;
	cout << endl;
}
