/*
 *  dirdes.h from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
/*  dirdes.h   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include "error.h"

#include "portable.h"
#include "filename.h"
#include "newaloc.h"

class ostream ;

class FileDesc ;
class PackageDesc ;
class OutTokens ;
class GetBits ;


class DirNames ;

enum MakeDirOption {MakeDirH, MakeDirC, MakeDirUsr, MakeDirBase, MakeDirExpand};

class DirContents {
	const char * DirName ;
	int NumFiles;
	FileDesc * FileEntry ;
	const char * Suffix ;
	ostream * MakeOut ;
	const char * MakeFileName ;
	uint32 Flags ;
	int MainDir ;
	int BaseLibFlag ; 
	int LibFlag ;	// indicates if OBJS needed in master collect or make
	int MakeWritten ; 	// indicates if local processing done
	int InLocalCollect ;	// indicate if objs collected in local lib
	int Index ;
	GetBits * KeepDirs ;

	char * MakeTargetDirName(const PackageDesc*pkg,const char*FileName=0);
	void WriteDirs(PackageDesc * pkg, int MainDir) ;
	void WriteObjs();
	void WriteCDepen(PackageDesc *pkg) ;
	void WriteCollectSourceDirectoryList(ostream& Out,
		const PackageDesc * pkg) ;
	void WriteExecutableDirectoryList();
	void ReadDependentLibraryFiles();
	int CheckDir(DirNames * Dirs, const char * name) ;
	                  // check if directory has been output as macro
                          // name (if not output it)
	int IsLibraryDirectory(const PackageDesc *pkg) const ;
		// will only check for main collect library directory
		// if package is set
	enum add_flags {null_flags, specific_first = 1, only_once = 2} ;
public:
	void ClearPrintDir();
	void SetPrintDir();
	int TestPrintDir();
	void Display() ;
	DirContents (const char *name, const char * suf, int mn, int index,
		int lib_flg=0);
	void SetDirContents(int num) ;
	void SetName(int index, char * name) ;
	const char *GetName (int i) ;
	const char *GetDir() const { return DirName ;}
	void FindFiles() ;
	int ValidFile(char * name) ;
	int Size() { return NumFiles; }
	void SetDependencies(PackageDesc * pkg) ;
	void WriteMake(PackageDesc * pkg) ;
	void write_make_head(PackageDesc * pkg) ;
	int cond_append(const char * dir, const char * base, const char * suf = 0);
	int cond_append_base(const char * dir, const char * base,
		const char * sub_dir, const char * suf, add_flags flags) ;
	void copy_file(istream * from, ostream * to, const char * to_name,
		const char * from_name = 0);
	char * GetFullName(int i) ;
	void AppendTail(PackageDesc*) ;
	void EmitExecutable(PackageDesc * pkg, OutTokens& ListOut) ;
	void MainOut(PackageDesc *pkg) ;
	void ListForeignLibs(class OutTokens *, int DirIndex, PackageDesc *pkg,
		MakeDirOption = MakeDirC);
	void ListForeignObjs(class OutTokens *, int DirIndex,
		MakeDirOption, PackageDesc * pkg);
	int IsLibrary() { return LibFlag;}
	void WriteUsrDepends(PackageDesc * pkg);
	void WriteMenuDepends(PackageDesc * pkg);
	int GetThisIndex() const {return Index;}
	void SetIndex(int index) {Index=index;}
	DirContents * GetUsrContents(PackageDesc * pkg) ;
	void WriteUsrDependsMacro(PackageDesc * pkg) ;
	void WriteMenuDependsMacro(PackageDesc * pkg) ;
	void MainUsrOut(PackageDesc * pkg) ;
	int IsMenuDir(PackageDesc * pkg) ;
	void OutAllNodFiles(OutTokens& Out, PackageDesc * pkg) ;
	int OutMakeLocalUsr(PackageDesc * pkg,const char * Object) ;
	void EmitObjs(ostream& MakeOut, int& line_use, const char * SubDir);
	void EmitDirObjList(ostream * MakeOut, PackageDesc *pkg);

	const GetBits * GetHeaderBits() const {return KeepDirs;}
	int IsMainDir() const {return MainDir;}
	void WriteSourceDirectoryList(const PackageDesc * pkg);
	int add_files(const char * base, add_flags flags, PackageDesc * pkg) ;
	int contains_directories() const {return FileEntry != 0;}
	const char * MakeLibName(PackageDesc *pkg, int CollectFlag=0) ;
} ;


class DirNames {
	int MaxSize ;
	DirContents ** DirEntrys ;
	int TheNext ;
	const char * Suffix ;
	const char * SubDir ;
	const char * CollLibName ;
	enum {BufSize=512} ;
	char Sub[BufSize+1] ;

	int OpAddName(const char * name, int Main, int LibFlag=0) ;
public:
	void SetSubDir(const char * sbdr) { SubDir = sbdr ; }
	const char * GetSubDir() const { return SubDir ; }
	void ClearAllPrintFlags() ;
	void Init();
	DirNames (int n, const char * suf) ;
	void Display() ;
	DirContents * GetDirEntry(int i) const {return DirEntrys[i]; }
	const char * GetDirName(int i) const ;

	int AddName(const char *name,int LibFlag=0)
		{return OpAddName(name,0,LibFlag);}
	void AddMainName(const char *name) {OpAddName(name,1);}

	int Size() {return TheNext;}
	void Decrement() { MaxSize--; }
	int Next() { return TheNext;}
	void FindFiles();
	void SetDependencies(PackageDesc *pkg) ;
	void WriteMake(PackageDesc * pkg);
	void WriteCDirs(ostream * MakeOut, const char * dirname,
		const char * Objective = 0, PackageDesc * pkg=0);
	void WriteCDirMacros(ostream * Out) ;
	void ListForeignLibs(const char *dirname, class OutTokens * Out,
		PackageDesc * pkg, MakeDirOption=MakeDirC) ;
	void ListForeignObjs(const char *dirname, class OutTokens * Out,
		MakeDirOption, PackageDesc *pkg) ;
	void ListObjsNotCollected(const char * name, OutTokens * out,
		PackageDesc * pkg, MakeDirOption = MakeDirC) ;
	void ListCollObjs(const char * name, const char ** Exclude,
		OutTokens * out, MakeDirOption, PackageDesc * pkg ) ;
	void PrintMake(ostream * out,const char *,const char *,MakeDirOption);
	void PrintMacro(ostream * out, const char * Obj, MakeDirOption Opt) ;
	int Included(const char * Name);
	DirContents * GetUsrContents(const char * Name);
	const char * GetSubSuffix() ;
	int IsMember(const char * Name) const ;
	int GetMemberIndex(const char * Name) const ;
	void MakeSureDependentCdirsAreFirst(int index, const char **DirList);
	void WriteSourceDirs(ostream& Out, const char * dir_name,
		const char ** NoCollNames, const PackageDesc * pkg,
		GetBits& Bits) const;
	void WriteSourceDirectoryList(const PackageDesc * pkg);
	void WriteMakeDir(ostream& Out, const char * Name,
        	const char *Objective=0) ;
	const char * GetCollLibName(PackageDesc * pkg);
	int check_add(const char * name);
} ;

char * MakeDirName(int DirIndex, const char * FileName, MakeDirOption,
	DirNames * = 0) ;

#define LongPage2(ParamFirst,ParamSecond) ParamFirst,ParamSecond," \\"," ", \
	"   ",80,32767
#define LongPage(o) LongPage2(o,0)

char * TailUpName(const char * FullName) ;
const char * TailName(const char * FullName) ;
extern char * ObjSuffix ;
char * MakeObjName(const char *Name) ;

extern int Use_makemake_link ;

extern const char * DirListFileName ;

