/*  inconce.c   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include <stream.h>
#include <string.h>
#include <ctype.h>
#include "inconce.h"
#include "slist.h"

struct IncFileId {
	const char * Name ;
	const ostream * Stream ;
	IncFileId(const char * nm,const ostream * str) {Name=nm;Stream=str;}
} ;

class IncFileIdList: public SingleList {
public:
	ErrCode Insert(IncFileId *nt) {return SingleList::Insert(nt);}
	ErrCode Append(IncFileId *nt) {return SingleList::Append(nt);}
	IncFileId * Get()   {return (IncFileId *) SingleList::Get();}
	IncFileId * Pop() {return (IncFileId *) SingleList::Pop();}
	IncFileId * GetNFromTop(int N) ;
	IncFileId * GetNthEntry(int N) ;
	IncFileIdList(){;}
	int Size(){return SingleList::Size();}
} ;

class IncFileIdListIterator: public SingleListIterator {
public:
	IncFileIdListIterator(IncFileIdList& df):
		SingleListIterator((SingleList&) df){}
	IncFileId * operator()()
		{return (IncFileId *) Next();}
};



static char * ConvertName (const char * name)
{
	const char * Result;
	const char * R ;
	char c;
	Result = R = name ;
	while (c= *R++) {
		if (c == '/') Result = R;
	}
	const char * Temp = Result ;
	char * XR;
	char *XResult ;
	XR = XResult = new char[strlen(Temp)+5];
	while (c = *Temp++) {
		if (!isascii(c)) continue ;
		if (c == '.' ) {
			*XR++ = '_' ;
			*XR++ = 'D' ;
			*XR++ = 'O' ;
			*XR++ = 'T' ;
			*XR++ = '_' ;
		} else {
			if (!islower(c)) *XR++ = c;
			else *XR++ = toupper(c) ;
		}
	}
	*XR++ = '\0' ;
	return XResult ;
}

static IncFileIdList TheList ;

void IncludeOnce(ostream * str)
{
	if (!str) return ;
	IncFileIdListIterator Next(TheList);
	IncFileId * Id ;
	while (Id = Next()) if (str == Id->Stream) {
		*str << "#endif /* #ifndef " << Id->Name << "*/\n" ;
		return ;
	}
	cerr << "IncludeOnce: unknown stream.\n" ;
}
void IncludeOnce(ostream * str, const char * FileName)
{
	char * ConvertedName ;
	ConvertedName = ConvertName(FileName);
	TheList.Append(new IncFileId(ConvertedName,str));
	*str << "#ifndef " << ConvertedName << " \n#define " <<
		ConvertedName << "\n";
}
