#ifndef	lint
static	char	Id[] = "@Id: file2argv.c,v 11.0 91/10/03 08:47:45 ste_cm Rel @";
#endif

/*
 * Title:	file2argv.c (file to argv-conversion)
 * Author:	T.E.Dickey
 * Created:	06 Apr 1989
 *
 * Function:	Reads a file and converts it to an argv-style array of pointers
 *		to strings.
 *
 * Arguments:	name -	the name of the file to read from.  If "-", then we
 *			read from the standard input.
 *		vec -	the address of a pointer to array-of-pointers to
 *			strings.
 *
 * Returns:	the number of lines read from the input file (or -1 if an error
 *		prevents reading the file).  The return value should never be
 *		exactly zero.
 *
 * Assumptions:	The file contains no embedded nulls.
 *		The newline character ends each (except possibly the last) line.
 */

#include "ptypes.h"

#define	AVG_LINE	25		/* nominal line-length */
#define	AMOUNT(n)	(unsigned)(n)

file2argv(
_ARX(char *,	name)
_AR1(char ***,	vec)
	)
_DCL(char *,	name)
_DCL(char ***,	vec)
{
	auto	 int	j,
			length,
			newlines,	/* number of newlines found */
			lines;		/* number of newlines found */
	auto	 char	**p, *blob;
	register char	*s, *d;

	*vec = 0;	/* in case we find an error */
	if (!(blob = file2mem(name)))
		return (-1);

	for (s = blob, lines = 0; *s; ++s)
		if (*s == '\n')
			lines++;
	newlines = lines;
	length   = s - blob;
	if (length > 0 && blob[length-1] != '\n')
		lines++;

	/*
	 * Reallocate space for the file counting the nulls inserted
	 * after each newline.
	 */
	if (!(blob = doalloc(blob, AMOUNT(length + lines + 1))))
		return (-1);

	/*
	 * Allocate space for the vector pointing to the strings
	 */
	*vec = p = vecalloc((unsigned)((lines + 1) * sizeof(char *)));

	/*
	 * Recopy the blob onto itself, putting a null after each newline.
	 */
	for (j = newlines, s = blob + length, d = s + newlines; d != s; ) {
		if (*s == '\n') {
			p[j--] = d + 1;
			*d-- = '\0';
		}
		*d-- = *s--;
	}

	p[lines] = 0;		/* always supply a null-pointer */
	p[0] = blob;
	return (lines);
}
