/* Make a table of contents from all autodoc files */

#include "global.h"
#include "misc.h"
#include "adfile.h"
#include "readdir.h"

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

struct AutodocNode **AutodocArray;
struct AutodocNode *AutodocList;
struct AutodocFileNode *AutodocFileList;

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

BOOL AddAutodoc(char *Name, char *File, long Type)
{
	struct AutodocNode *NewNode;
	int Length;
	char *Temp;

	NewNode = AutodocList;
	while (NewNode && strcmp(NewNode->Node.Name, Name))
	{
		NewNode = (struct AutodocNode *) (NewNode->Node.Next);
	}
	if (NewNode)
	{
		printf("Error: AutoDoc %s already defined in %s\n", Name, NewNode->File);
		return (FALSE);
	}
	Length = 0;
	for (Temp = File + strlen(File); *Temp != '.'; Temp--)
		Length++;
	if (NewNode = AllocVec(sizeof(struct AutodocNode) + strlen(Name) + strlen(File) + strlen(Arguments.Extension) - Length + 2, 0))
	{
		NewNode->ShortLink = NULL;
		NewNode->Node.Name = (char *) (NewNode + 1);
		NewNode->File = stpcpy(NewNode->Node.Name, Name) + 1;
		stpcpy(stpcpy(NewNode->File, File) - Length, Arguments.Extension);
		Name = FindSlash(Name);
		if (!*(Name++))
		{
			WriteError("Warning: Improper autodoc entry.\n"
					   "         Expected format: xxx/yyy  (e.g. exec.library/AllocMem)\n"
					   "         Ignoring entry.\n");
			FreeVec(NewNode);
			return (TRUE);
		}
		if (Type == -1)
		{
			if (*Name == '-')
			{
				NewNode->Type = 0;
			}
			else
			{
				Length = strlen(Name);
				if (Length >= 9 && !stricmp(&Name[Length - 9], ".datatype"))
				{
					NewNode->Type = 0;
				}
				else
				{
					NewNode->Type = 2;
					while (*Name)
					{
						if (*Name != toupper(*Name))
						{
							NewNode->Type = 1;
							break;
						}
						Name++;
					}
				}
			}
		}
		else
		{
			NewNode->Type = Type;
		}
		NewNode->Node.Next = (struct AnyNode *) AutodocList;
		AutodocList = NewNode;
		return (TRUE);
	}
	else
	{
		PrintFault(ERROR_NO_FREE_STORE, NULL);
		return (FALSE);
	}
}

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

static BOOL AddAutodocContents(char *File)
{
	BOOL Success;

	CurrentSource = FileList->Node.Name;
	printf("      Reading %s\n", CurrentSource);
	Success = FALSE;
	if (CurrentFile = Open(File, MODE_OLDFILE))
	{
		do
		{
			Success = ReadLine(FALSE, FALSE);
		}
		while (!Buffer[0] && Success);
		if (Success)
		{
			if (!stricmp(Buffer, "TABLE OF CONTENTS"))
			{
				do
				{
					if (Success = ReadLine(FALSE, FALSE))
					{
						if (Buffer[0] != '\x0c' && Buffer[0])
						{
							Success = AddAutodoc(Buffer, CurrentSource, -1);
						}
					}
				}
				while (Success && Buffer[0] != '\x0c');
			}
			else
			{
				WriteError("Error: First line in autodoc file must read\n"
						   "       \x22TABLE OF CONTENTS\x22\n"
						   "       File: %s\n"
						   "       Operation aborted.\n", CurrentSource);
			}
		}
		Close(CurrentFile);
	}
	else
	{
		PrintFault(IoErr(), CurrentSource);
	}
	return (Success);
}

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

BOOL ReadAutodocs(void)
{
	FileList = NULL;
	if (ReadDir(AutodocDir, "", ".doc", AddAutodocContents))
	{
		AutodocFileList = FileList;
		FileList = NULL;
		if (AutodocArray = (struct AutodocNode **) ListToArray((struct AnyNode *) AutodocList))
		{
			return (TRUE);
		}
	}
	return (FALSE);
}

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

#if 0
BOOL PrintAutodocList(void)
{
	int Index;

	printf("      %ld autodoc entries found\n", (int) AutodocArray[0]);
	if (FPrintf(XRefFile, "\n/* Functions and Commands */\n") == -1)
	{
		PrintFault(IoErr(), Arguments.XRefFile);
		return (FALSE);
	}
	for (Index = 1; Index <= (int) AutodocArray[0]; Index++)
	{
		if (FPrintf(XRefFile, "\x22%s\x22 \x22%s\x22 0 %ld\n", AutodocArray[Index]->Node.Name, AutodocArray[Index]->File, AutodocArray[Index]->Type) == -1)
		{
			PrintFault(IoErr(), Arguments.XRefFile);
			return (FALSE);
		}
	}
	return (TRUE);
}
#endif
