/*
 *	C4 -- CVS like front end to the Perforce p4 SCM tool.
 *
 * Copyright (c) 1998 - 2000, Neil Russell.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Neil Russell.
 * 4. The name Neil Russell may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY NEIL RUSSELL ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL NEIL RUSSELL BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *	File name table management.
 */

#include	"defs.h"

/**************************************************/
/*
 *	File information management.
 */

static File	file_root = { 0, "" };


/*
 *	Lookup the file information entry `name'.  If it is not found,
 *	and `create' is set, create an empty entry.
 */
File *
Lookup(char * name, int create)
{
	File *		fp;

	fp = &file_root;
	for (;;)
	{
		File *		xp;
		File *		lp;
		char *		cp;
		int		l;

		/*
		 *	Find the end of a path segment.
		 */
		for (cp = name; *cp && *cp != '/'; cp++)
			;

		l = cp - name;
		if (l == 0)
			return fp;

		/*
		 *	Skip /'s.
		 */
		while (*cp == '/')
			cp++;

		if (l == 1 && *name == '.')
		{
			name = cp;
			continue;
		}

		lp = (File *)0;
		for (xp = fp->children; xp; xp = xp->next)
		{
			if (strncmp(name, xp->name, l) == 0 &&
			    xp->name[l] == '\0')
				break;
			lp = xp;
		}

		if (!xp)
		{
			if (!create)
				return (File *)0;

			xp = Alloc(sizeof (File));

			xp->flag = 0;

			xp->name = Alloc(l + 1);
			strncpy(xp->name, name, l);
			xp->name[l] = '\0';

			xp->children = (File *)0;
			xp->next = (File *)0;

			xp->modtime = 0;
#if 0
			xp->change = 0;
#endif
			xp->ignore = (Ignore *)0;

			if (!lp)
				fp->children = xp;
			else
				lp->next = xp;
		}

		fp = xp;
		name = cp;
	}
}

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

static void
print_tree(char * dir)
{
	File *		fp;
	char		name[1024];
	int		namelen;

	strcpy(name, dir);
	namelen = strlen(name);
	name[namelen++] = '/';

	fp = Lookup(dir, 0);
	fp = fp->children;
	while (fp)
	{
		printf("    %s/%s [", dir, fp->name);

		if (fp->flag & F_DEPOT)
			printf(" depot");
		if (fp->flag & F_HAVE)
			printf(" have");
		if (fp->flag & F_GET)
			printf(" get");
		if (fp->flag & F_SYMLINK)
			printf(" symlink");
		if (fp->flag & F_OPEN)
			printf(" open");
		if (fp->flag & F_DELETE)
			printf(" delete");

		if (fp->flag & F_SDIR)
			printf(" sdir");
		if (fp->flag & F_DIFF0)
			printf(" diff0");
		if (fp->flag & F_DIFF1)
			printf(" diff1");
		if (fp->flag & F_EXISTS)
			printf(" exists");
		if (fp->flag & F_ERROR)
			printf(" error");

		if (fp->flag & F_MODIFIED)
			printf(" modified");

		if (fp->flag & F_EDIT)
			printf(" edit");
		if (fp->flag & F_REVERT)
			printf(" revert");
		if (fp->flag & F_REFRESH)
			printf(" refresh");
		if (fp->flag & F_ADD)
			printf(" add");
		if (fp->flag & F_REMOVE)
			printf(" remove");
		if (fp->flag & F_ADDMAYBE)
			printf(" addmaybe");

		if (fp->flag & F_IGNORELIST)
			printf(" ignorelist");

		printf(" ]\n");

		if (fp->children)
		{
			strcpy(&name[namelen], fp->name);
			print_tree(name);
		}

		fp = fp->next;
	}
}


void
PrintTree(char * msg)
{
	if (Debug >= 2)
	{
		printf("  PrintTree (%s):\n", msg);
		print_tree(".");
		printf("  PrintTree done.\n");
	}
}
