/*
    LIB - a librarian for compatible OBJ/LIB files
    Copyright (C) 1995,1996  Steffen Kaiser

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    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 the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: LIB.H 3.3 1999/02/17 05:18:08 ska Rel ska $
   $Locker: ska $	$Name: v3_2 $	$State: Rel $

	Declaractions of library and object file structure

*/

#ifndef __LIB_H
#define __LIB_H

#include <stdio.h>
#include <portable.h>
#include "list.h"
#include "types.h"

#define NR_LIB_HEADER 0xF0
#define NR_LIB_TRAILER 0xF1
#define NR_LIB_THEADR 0x80
#define NR_LIB_COMMENT 0x88
#define NR_LIB_MODEND 0x8A
#define NR_LIB_PUBDEF 0x90

extern FLAG8 returnNumber; /* Some warnings will produce an ERRORLEVEL */
extern FLAG skipModule;		/* do not accept any information of the current
								module */
extern FLAG modifyTHEADR;	/* modify the module name */
extern FLAG addModule;	/* this is a newly-added module */
extern FLAG dispDoing;	/* display the actions performed on modules */
extern FLAG dblMod;	/* dis§allow to add a module with the same nàme twice */
extern FLAG alignDir;	/* align library directory */

extern FILE *xtractFile;	/* special extraction mode report file */
extern char *xtractFnam;	/* special extraction mode report file name */
extern unsigned xtractCnt;	/* special extraction mode substitution counter */

extern unsigned newPageSize;	/* 0 == page size manually set */

#ifndef _MICROC_
#include <algnbyte.h>
#endif
#define tModule(name) struct name { 	/* start T-Module definition */ \
	byte type; 					/* T-Module type */	\
	word length;				/* record length including CRC */

tModule(LIB_HEADER)
	dword dirOff;	/* file position */
	word dirPag;	/* prime */
};

tModule(LIB_TRAILER)
};

tModule(LIB_MODHEAD)
	byte nameLength;
	unsigned char name[1];
};

#define DIR_PAGE_SIZE 512	/* page size within the directory area is fixed */
#define BUCKETS 37			/* max items per page */
#define PAGELEFT ((DIR_PAGE_SIZE - BUCKETS) & ~1)	/* dito free bytes of a page */

struct LIB_INFO {
	struct _LIB_INFO {
		dword _dirOffset;	/* start file position of the directory */
		word _dirPages;		/* # of pages of the directory */
		word _pageSize;		/* size of a single page */
	} file;
	char *_name;
	FILEP _fp;
};
extern struct LIB_INFO libHeaderOld, libHeaderNew;
#ifndef _MICROC_
#include <algndflt.h>
#endif

/* straight through to the items of the input (old) lib */
#define dirOffsetOld libHeaderOld.file._dirOffset
#define dirPagesOld libHeaderOld.file._dirPages
#define pageSizeOld libHeaderOld.file._pageSize
#define libNameOld libHeaderOld._name
#define libIn libHeaderOld._fp
#define libOld aS(libHeaderOld)

/* straight through to the items of the output (new) lib */
#define dirOffsetNew libHeaderNew.file._dirOffset
#define dirPagesNew libHeaderNew.file._dirPages
#define pageSizeNew libHeaderNew.file._pageSize
#define libNameNew libHeaderNew._name
#define libOut libHeaderNew._fp
#define libNew aS(libHeaderNew)

/* straight through to the items of the current lib */
#define dirOffset lib->file._dirOffset
#define dirPages lib->file._dirPages
#define pageSize lib->file._pageSize
#define libName lib->_name
#define libFp lib->_fp

int Lcreate(char *name, struct LIB_INFO *lib);
/* creates library, initialize the library variables and 
   return 0 if successful */
int Lopen(char *name, struct LIB_INFO *lib);
/* open library, initialize the library variables and 
   return 0 if successful */
void Lcloseup(struct LIB_INFO *lib);
/* close library without modifying the library data */
void Lclose(struct LIB_INFO *lib);
/* close library, rewrite LIB header */
void Lread(void *buf, unsigned len, struct LIB_INFO *lib);
/* read len bytes from the library into the buffer buf and
   emit an error message, if necessary */
void LreadMod(struct LIB_TRAILER *buf, struct LIB_INFO *lib);
/* read len bytes from the library into the buffer buf, then
   advance pointer to the next module and
   emit an error message, if necessary */
void Lwrite(void *buf, int len, struct LIB_INFO *lib);
/* read len bytes from the library into the buffer buf and
   emit an error message, if necessary */
void Lseek(int delta, struct LIB_INFO *lib);
/* seek delta bytes from the current position of the library and
   emit an error message, if necessary */
#ifndef _MICROC_
void Lset(dword offset, struct LIB_INFO *lib);
#else
void Lset(dword *offset, struct LIB_INFO *lib);
#endif
/* set the file pointer of the library to offset and
   emit an error message, if necessary */
void Lcopy(void);
/* copy the modules of the BAK library in the new library.
   While this process the temporary list is made. */
void Ldir(struct LIB_INFO *lib);
/* write the LIB directory to the library */
void writeLibEnd(void);
/* write the LIBEND module to libNew */
int LaddMod(struct cmdList *mod);
/* add the module mod to libNew */

#endif
