/* libpbm1.c - pbm utility library part 1
**
** Copyright (C) 1988 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation.  This software is provided "as is" without express or
** implied warranty.
*/

#include <stdio.h>
#include <varargs.h>
#include "pbm.h"
#include "libpbm.h"

/* Variable-sized arrays. */

char *
pm_allocrow( cols, size )
int cols;
    {
    register char *itrow;

    itrow = (char *) malloc( cols * size );
    if ( itrow == (char *) 0 )
	pm_error( "out of memory allocating a row", 0,0,0,0,0 );
    return itrow;
    }

void
pm_freerow( itrow )
char *itrow;
    {
    free( itrow );
    }


char **
pm_allocarray( cols, rows, size )
int cols, rows;
int size;
    {
    char **its;
    int i;

    its = (char **) malloc( rows * sizeof(char *) );
    if ( its == (char **) 0 )
	pm_error( "out of memory allocating an array", 0,0,0,0,0 );
    its[0] = (char *) malloc( rows * cols * size );
    if ( its[0] == (char *) 0 )
	pm_error( "out of memory allocating an array", 0,0,0,0,0 );
    for ( i = 1; i < rows; i++ )
	its[i] = &(its[0][i * cols * size]);
    return its;
    }

void
pm_freearray( its, rows )
char **its;
int rows;
    {
    free( its[0] );
    free( its );
    }


/* Error handling. */

char *pm_progname;

/* I'd use varargs here, but it can't be done portably, because (a) vfprintf()
** is not very widespread, and (b) varargs itself is not powerful enough to
** allow me to include a portable vfprintf().
**
** So instead, we have the gross hack of a fixed number of args.
*/

void
pm_message( fmt, v1, v2, v3, v4, v5 )
char *fmt;
char *v1, *v2, *v3, *v4, *v5;
    {
    fprintf( stderr, "%s: ", pm_progname );
    fprintf( stderr, fmt, v1, v2, v3, v4, v5 );
    fputc( '\n', stderr );
    }

void
pm_error( fmt, v1, v2, v3, v4, v5 )
char *fmt;
char *v1, *v2, *v3, *v4, *v5;
    {
    pm_message( fmt, v1, v2, v3, v4, v5 );
    exit( 1 );
    }

void
pm_usage( usage )
char *usage;
    {
    fprintf( stderr, "usage:  %s %s\n", pm_progname, usage );
    exit( 1 );
    }


/* File open/close that handles "-" as stdin and checks errors. */

FILE *
pm_openr( name )
char *name;
    {
    FILE *f;

    if ( strcmp( name, "-" ) == 0 )
	f = stdin;
    else
	{
	f = fopen( name, "r" );
	if ( f == NULL )
	    {
	    perror( name );
	    exit( 1 );
	    }
	}
    return f;
    }

void
pm_close( f )
FILE *f;
    {
    if ( f != stdin )
	if ( fclose( f ) != 0 )
	    perror( "closing file" );
    }
