/*
    This file is part of SUPPL - the supplemental library for DOS
    Copyright (C) 1996-2000 Steffen Kaiser

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $RCSfile: CFG_OMEM.C $
   $Locker: ska $	$Name:  $	$State: Exp $

	Functions for an ostack item dealing with memory

	The _putArg member is a (char **) holding all the arguments.

	There is no special for sequential read.

	void cfg_ostkWrMem(int mode, struct Cfg_Getopt * const optstru
		, struct Cfg_oStackGetopt * const ostk
		, const char * const buf, size_t len);
	char * cfg_ostkRdMem(struct Cfg_Getopt * const optstru
		, struct Cfg_oStackGetopt * const ostk
		, int idx);
	char * cfg_ostkSqMem(struct Cfg_Getopt * const optstru
		, struct Cfg_oStackGetopt * const ostk);
	void cfg_ostkClMem(struct Cfg_Getopt * const optstru
		, struct Cfg_oStackGetopt * const ostk);
	void cfg_ostkInitMem(struct Cfg_oStackGetopt *ostk);


ob(ject): cfg_ostkRdMem
su(bsystem): cmdline
ty(pe): L
sy(nopsis): 
sh(ort description): "read argument" function for memory
he(ader files): 
lo(ng description): Implements the "read argument" function for memory,
	suiteable for the member of the output stack named \tok{C_rdArg}.
pr(erequistes): 
va(lue): NULL: if empty \item else: pointer to static buffer containing
	the next argument
re(lated to): 
se(condary subsystems): 
xr(ef): 
im(port): 
fi(le): cfg_omem.c
in(itialized by): 
wa(rning): 
bu(gs): 

ob(ject): cfg_ostkClMem
su(bsystem): cmdline
ty(pe): L
sy(nopsis): 
sh(ort description): "close output stack item" function for memory
he(ader files): 
lo(ng description): Implements the "close output stack item" function for memory,
	suiteable for the member of the output stack named \tok{C_clArg}.
pr(erequistes): 
va(lue): none
re(lated to): 
se(condary subsystems): 
xr(ef): 
im(port): 
fi(le): cfg_omem.c
in(itialized by): 
wa(rning): 
bu(gs): 

ob(ject): cfg_ostkInitMem
su(bsystem): cmdline
ty(pe): L
sy(nopsis): 
sh(ort description): Initialize an output stack item associated to a memory
he(ader files): 
lo(ng description): Associate an already created output stack item
	with the memory implementation
pr(erequistes): 
va(lue): none
re(lated to): 
se(condary subsystems): 
xr(ef): 
im(port): 
fi(le): cfg_omem.c
in(itialized by): 
wa(rning): 
bu(gs): 

*/

#include "initsupl.loc"

#ifndef _MICROC_
#include <string.h>
#endif
#include <portable.h>
#include "dynstr.h"
#include "cfg.loc"

#include "suppldbg.h"

#ifdef RCS_Version
static char const rcsid[] = 
	"$Id: CFG_OMEM.C 1.7 2001/02/27 01:28:03 ska Exp ska $";
#endif

#pragma argsused
void cfg_ostkWrMem(int mode, struct Cfg_Getopt * const optstru
	, struct Cfg_oStackGetopt * const ostk
	, char * const buf
	, size_t len)
{	DBG_ENTER("cfg_ostkWrMem", Suppl_cmdline)

	assert(optstru);
	assert(ostk);

	if(mode && !O(cnt))
		mode = 0;		/* first entry */

	Eresize(O(putArg), ++O(cnt) * sizeof(char **));
	if(mode) {		/* insert as 2nd last argument */
		((char **)O(putArg))[O(cnt) - 1] = ((char **)O(putArg))[O(cnt) - 2];
		((char **)O(putArg))[O(cnt) - 2] = Estrdup(buf);
	}
	else ((char **)O(putArg))[O(cnt) - 1] = Estrdup(buf);

	DBG_EXIT
}
char * cfg_ostkRdMem(struct Cfg_Getopt * const optstru
	, struct Cfg_oStackGetopt * const ostk
	, int idx)
{	DBG_ENTER("cfg_ostkRdMem", Suppl_cmdline)

	assert(optstru);
	assert(ostk);
	DBG_RETURN_BS((idx >= O(cnt))?	0: ((char **)O(putArg))[idx])
	/** Warning: opstru never used **/
}
char * cfg_ostkSqMem(struct Cfg_Getopt * const optstru
	, struct Cfg_oStackGetopt * const ostk)
{	char *p;

	DBG_ENTER("cfg_ostkSqMem", Suppl_cmdline)

	assert(optstru);
	assert(ostk);
	assert(!C(_removeAfterRead) || O(idx) == 0);
	
	if(C(_removeAfterRead)) {	/* idx always == 0 */
			/* sometime in the near future _hbuf is being used again
				and that way, the string is removed */
		if(!O(cnt))
			DBG_RETURN_S( 0)
		StrRepl(C(_hbuf), p = *((char **)O(putArg)));
		memmove(O(putArg), &((char **)O(putArg))[1], --O(cnt));
		DBG_RETURN_S( p)
	}

	if(O(idx) >= O(cnt))
		DBG_RETURN_S( 0)
	DBG_RETURN_BS(((char **)O(putArg))[O(idx)++])
}
void cfg_ostkClMem(struct Cfg_Getopt * const optstru
	, struct Cfg_oStackGetopt * const ostk)
{	char **p;

	DBG_ENTER("cfg_ostkClMem", Suppl_cmdline)

	assert(optstru);
	assert(ostk);
	
	if(O(putArg)) {
		p = &((char **)O(putArg))[O(cnt)];
		while((void*)(--p) >= O(putArg))
			free(*p);
		free(O(putArg));
	}

	DBG_EXIT
	/** Warning: opstru never used **/
}
void cfg_ostkInitMem(struct Cfg_oStackGetopt *ostk)
{	DBG_ENTER("cfg_ostkInitMem", Suppl_cmdline)

	assert(ostk);

	O(wrArg) = aF(cfg_ostkWrMem);
	O(rdArg) = aF(cfg_ostkRdMem);
	O(sqArg) = aF(cfg_ostkSqMem);
	O(clArg) = aF(cfg_ostkClMem);

	DBG_EXIT
}
