[net.sources] Readline revised for non unix os's

jason@ucbopal.BERKELEY.EDU (Jason Venner) (01/18/86)

I got a complaint from a person who was using vmx and hp-ux,  saying that
they complained if you did a realloc( (char*) 0, size ).
This works fine in 4.x though.

Well, in the interests of portablility,  I have fixed this.

---cut here---

static	char	readline_id[] = "1/17/86 CFC,  Berkeley @(#)readline.c	1.2";
#include	<stdio.h>

/*	This routine reads a line (of arbitrary length), up to a '\n' or 'EOF'
 *	and returns a pointer to the resulting null terminated string.
 *	The '\n' if found, is included in the returned string.
 */

#define	STRGROW	256

char	*
readline( fd )
FILE	*fd;
{

	int	c;
	unsigned	StrLen;
	unsigned	MemLen;
	char	*StrPtr;
	/* This is needed for old dumb mallocs in HP-UX, VMS... */
	char*	malloc();
	char*	realloc();
	
	StrPtr = (char*) 0;
	StrLen = 0;
	MemLen = STRGROW; 
#ifdef	notdef
	if( !(StrPtr = realloc( StrPtr, MemLen )) ) {
		return (char*) 0;
	}
#endif
	if( !(StrPtr = malloc( MemLen )) ) { /* Keep dumb mallocs happy */
		return (char*) 0;
	}
	MemLen -= 1;					  /* Save constant -1's in while loop */
	while( (c = getc( fd )) != EOF ) {
		StrPtr[StrLen] = c;
		StrLen++;
		if( StrLen >= MemLen ) {
			MemLen += STRGROW;
			if( !(StrPtr = realloc( StrPtr, MemLen + 1)) ) {
				return (char*) 0;
			}
		}
		if( c == '\n' ) {
			break;
		}
	}
	if( StrLen == 0 ) {
		(void) free( StrPtr );
		return (char*) 0;
	}
	StrPtr[StrLen] = '\0';
										  /* Trim the string */
	if( !(StrPtr = realloc( StrPtr, StrLen + 1 )) ) {
		return (char*) 0;
	}
	return StrPtr;
}

#ifdef	TEST_READLINE
main( argc, argv )
int	argc;
char	**argv;
{
	char	*string;
	while( (string = readline( stdin )) ) {
		puts( string );
		(void) free( string );
	}
	exit( 0 );
}
#endif