/* lp_util.c
 * Neil Moore <neil@cs.uky.edu>
 * 20 Jul 1999
 *
 * Part of liblp.  See COPYRIGHT for copyright information.
 */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <lp_util.h>

/* Allocate size bytes of memory, aborting if memory is exhausted.
 */
void *lp_malloc(size_t size) 
{
	void *mem = malloc(size);

	if(mem != NULL)
		return mem;

	fprintf(stderr, "Out of memory---exiting.\n");
	exit(1);
}


/* Allocate size * nmemb bytes of memory, initialised to zero.  This
 * function aborts if memory is exhausted.
 */
void *lp_calloc(size_t nmemb, size_t size) 
{
	void *mem = calloc(nmemb, size);

	if(mem != NULL)
		return mem;

	fprintf(stderr, "Out of memory---exiting.\n");
	exit(1);
}


/* Reallocate ptr to size bytes.  This function aborts if memory is
 * exhausted.
 */
void *lp_realloc(void *ptr, size_t size) 
{
	void *mem;
	
	mem = realloc(ptr, size);

	if(mem != NULL)
		return mem;

	fprintf(stderr, "Out of memory---exiting.\n");
	exit(1);
}


/* Read whitespace until end-of-line is reached.  If end-of-file or a non-
 * whitespace character is reached before a newline, this function returns
 * nonzero (indicating failure).  Otherwise, it returns zero (indicating
 * success).
 */
int lp_finishline(FILE *f) 
{
	int c;

	do {
		c = getc(f);
		if(c == EOF)
			return -1;
		if(!isspace(c))
			return -1;
	} while(c != '\n');

	return 0;
}


/* Read a non-negative decimal integer, possibly proceeded by whitespace.
 * Whitespace is expected to follow the integer.  If there is an error
 * (a non-numeric, non-whitespace character was found, the number was not
 * followed by a whitespace, or EOF was reached before a number was found),
 * this function returns -1.  Otherwise, it returns the number read.
 *
 */
int lp_getnum(FILE *f) 
{
	int n = 0;
	int c;
	
	do {
		c = getc(f);
		if(feof(f))
			return -1;
	} while(isspace(c));

	ungetc(c, f);
		
	while(!feof(f)) {
		c = getc(f);
		if(isspace(c)) {
			ungetc(c, f);
			break;
		}
		
		if(!isdigit(c))
			return -1;

		n =  n * 10 + c - '0';
	}
	
	return n;
}


/* Read a non-negative decimal integer, possibly proceeded by and followed
 * by whitespace.  Other than whitespace, the number should be on a line
 * by its own (the trailing newline is read).  If there is an error (a non-
 * numeric, non-whitespace character was found or EOF was reached), this
 * function returns -1.  Otherwise, it returns the number read.
 *
 */
int lp_getnumline(FILE *f) 
{
	int n = 0;
	int c;
	
	do {
		c = getc(f);
		if(feof(f))
			return -1;
	} while(isspace(c));

	ungetc(c, f);
		
	while(!feof(f)) {
		c = getc(f);
		if(isspace(c))
			break;
		if(!isdigit(c))
			return -1;

		n =  n * 10 + c - '0';
	}

	while(c != '\n' && !feof(f)) {
		c = getc(f);
		if(!isspace(c))
			return -1;
	}

	if(feof(f))
		return -1;
	
	return n;
}


/* This function copies an array of integers of size nelts.  It allocates
 * the copy with lp_malloc().
 *
 */
int *lp_copy_array(int *array, int nelts) 
{
	int i;
	int *result = lp_malloc(sizeof(int) * nelts);
	
	for(i=0; i<nelts; i++)
		result[i] = array[i];

	return result;
}


/* This function tests the equality of two arrays of integers of size nelts.
 * It returns 1 for true, 0 for false.
 *
 */
int lp_eq_array(int *a, int *b, int len)
{
	int i;
	
	for(i=0; i<len; i++)
		if(a[i] != b[i])
			return 0;

	return 1;
}
