/*******************************************************************************
* mbk     : system dependant functions                                         *
*                                                                              *
* version : 3.08                                                               *
* date    : 30/11/92                                                           *
*******************************************************************************/

#include <stdio.h>
#include <malloc.h>
#include MUT_H
#include "mbk_sys.h"

static char filename[BUFSIZ];

long mbkalloc_stat = 0; /* statistics on maximun allocated memory */

void *mbkalloc(nbytes)
unsigned int nbytes;
{
void 	*pt;

	mbkalloc_stat += nbytes;
	if (!(pt = malloc(nbytes))) {
		(void)fflush(stdout);
  		(void)fprintf(stderr,"*** mbk error ***\n");
  		(void)fprintf(stderr,"fatal mbkalloc error : not enough memory\n");
  		EXIT(1);
  	}
	return pt;
}

void *mbkrealloc(pt, nbytes)
void 	*pt;
unsigned int nbytes;
{

	mbkalloc_stat += nbytes;
	if (!(pt = realloc(pt, nbytes))) {
		(void)fflush(stdout);
  		(void)fprintf(stderr,"*** mbk error ***\n");
  		(void)fprintf(stderr,"fatal mbkrealloc error : not enough memory\n");
  		EXIT(1);
  	}
	return pt;
}

void mbkfree(ptr)
void *ptr;
{
#ifdef lint
	(void)free((char *)ptr);
#else
	(void)free(ptr); /* lint makes a mistake here : expects (char *) */
#endif
}

/* file opening :
   defines the strategy used for searching and opening file in the
   mbk environement. */
FILE *mbkfopen(name, extension, mode)
char *name, *extension, *mode;
{
FILE *in;
register int i = 0;

	if (!CATA_LIB || !WORK_LIB)
		mbkenv(); /* not done yet */

	if (extension) /* if extension is null, no dot is required */
		(void)sprintf(filename, "%s/%s.%s", WORK_LIB, name, extension);
	else
		(void)sprintf(filename, "%s/%s", WORK_LIB, name);

	switch (*mode) {
		case 'w' :  /* one shall save only in WORK_LIB */
			return fopen(filename, WRITE_TEXT);
		case 'r' :
			if (in = fopen(filename, READ_TEXT))
				return in;
			while (CATA_LIB[i]) {
				if (extension)
					(void)sprintf(filename, "%s/%s.%s", CATA_LIB[i++],
										name, extension);
				else
					(void)sprintf(filename, "%s/%s", CATA_LIB[i++], name);
				if (in = fopen(filename, READ_TEXT))
					return in;
			}
			return NULL;
		default :
			(void)fflush(stdout);
			(void)fprintf(stderr, "*** mbk error ***\n");
			(void)fprintf(stderr, "unknown file opening mode %s\n", mode);
			EXIT(1);
	}
}

/* unlink :
   ensures that only files in the working library may be erased. */
int mbkunlink(name, extension)
char *name, *extension;
{
	if (!CATA_LIB || !WORK_LIB)
		mbkenv(); /* not done yet */

	if (extension) /* if extension is null, no dot is required */
		(void)sprintf(filename, "%s/%s.%s", WORK_LIB, name, extension);
	else
		(void)sprintf(filename, "%s/%s", WORK_LIB, name);

	return unlink(filename);
}
	
/* filepath :
   find the complete path of file from mbkfopen point of view. */
char *filepath(name, extension)
char *name, *extension;
{
FILE *in;
register int i = 0;

	if (!CATA_LIB || !WORK_LIB)
		mbkenv(); /* not done yet */

	if (extension) /* if extension is null, no dot is required */
		(void)sprintf(filename, "%s/%s.%s", WORK_LIB, name, extension);
	else
		(void)sprintf(filename, "%s/%s", WORK_LIB, name);

	if ((in = fopen(filename, READ_TEXT))) {
		(void)fclose(in);
		return filename;
	}
	while (CATA_LIB[i]) {
		if (extension)
			(void)sprintf(filename, "%s/%s.%s", CATA_LIB[i++],
								name, extension);
		else
			(void)sprintf(filename, "%s/%s", CATA_LIB[i++], name);
		if ((in = fopen(filename, READ_TEXT))) {
			(void)fclose(in);
			return filename;
		}
	}
	return NULL;
}

#ifdef sparc
/* process state :
   this gives some information on allocated memory, time spend, and so on. */
void mbkps()
{
#include <sys/time.h>
#include <sys/resource.h>
struct rusage rusage;
static int pagesize;
extern long mbkalloc_stat;
static int times;

	if (!times)
		pagesize = getpagesize() / 1024;
	(void)getrusage(RUSAGE_SELF, &rusage);
	(void)fprintf(stdout, "mbk stats          : %d call\n", ++times);
	(void)fprintf(stdout, "user     time      : %ld sec\n",
									rusage.ru_utime.tv_sec);
	(void)fprintf(stdout, "system   time      : %d sec\n",
									rusage.ru_stime.tv_usec);
	(void)fprintf(stdout, "real     size      : %ld k\n",
									rusage.ru_maxrss * pagesize);
	(void)fprintf(stdout, "mbkalloc peak size : %ld k\n",
									mbkalloc_stat / 1024);
	(void)fprintf(stdout, "mallinfo size      : %ld k\n",
									mallinfo().arena / 1024);
}
#endif
