/*
 *				f x i n j e . c
 */

/*)LIBRARY
*/

#ifdef	DOCUMENTATION

title	fxinject	Inject an Item Into a Flex
index			Inject an item into a flex

synopsis

	 #ifdef vms
	 #include "c:flex.h"
	 #else
	 #include <flex.h>
	 #endif

	 FLEX *
	 fxinject(fx,itm,n)
	 FLEX *fx;
	 char *itm;
	 unsigned n;

description

	fxinject(fx,itm,n) injects itm into flex fx so that it becomes item
	number n; items already in the flex are moved to make room.  Another
	way to look at this is that fxinject injects itm before item n in fx,
	and allows the special case of n=1+(greatest item number) for
	injection at the end (which is functionally identical to fxadd()).

	fxinject() returns fx if all went well, otherwise NULL.  fx is never
	expanded or marked damaged if n is out of range.

bugs

author

	Jerry Leichter

#endif

/*
 * )EDITLEVEL=07
 * Edit history
 * 0.0  6-May-81 JSL	Invention
 * 0.1 23-Jun-81 JSL	Conversion to new documentation convention
 * 0.2 29-Jun-81 JSL	Oops - wasn't checking if n was in range!  Also, n
 *			should be unsigned.
 */

#ifdef	vms
#include "c:flex.h"
#else
#include <flex.h>
#endif
#define NULL 0

extern char *realloc();

FLEX *
fxinject(fx,itm,n)
FLEX *fx;
char *itm;
unsigned n;
{	register char *p, *new;
	register unsigned isz;

	if (fx != NULL)
	{	if (n > fx->fxused)
			return(NULL);
		isz = fx->fxisz;
		if (fx->fxdim <= fx->fxused)
		{	fx->fxdim += fx->fxext;
			if (fx->fxdim <= fx->fxused
			||  fx->fxdata == NULL
			||  (fx->fxdata =
				realloc(fx->fxdata,fx->fxdim*isz))
					 == NULL
			   )
			{	fx->fxdim = 0;
				return(fx->fxdata = NULL);
			}
		}
		p = fx->fxdata + isz*fx->fxused - 1;
		new = fx->fxdata + isz*n;
		while (p >= new)
		{	p[isz] = p[0];
			--p;
		}
		copy(new,itm,isz);
		fx->fxused++;
	}
	return(fx);
}
