/******************************************************************************

    MODUL
	$Id: spc.c 1.1 1994/09/20 11:14:01 b_noll Exp b_noll $

    DESCRIPTION
	That module represents ab interface to all
	variables, which have a special meaning for
	XDME's behaviour; strictl speaking the current
	file is the interface part, while the implementation
	of the access functions is done via a automatically
	generated file (called _SPC_.c), which is created
	from a file in a meta language (SPC.pre)

    NOTES

    $Log: spc.c $
 * Revision 1.1  1994/09/20  11:14:01  b_noll
 * Initial revision
 *


******************************************************************************/

/**************************************
		Includes
**************************************/

#include "defs.h"
//#include "null.h"


/**************************************
	    Globale Variable
**************************************/



/**************************************
      Interne Defines & Strukturen
**************************************/

static int   spc_set (long, char *);
static char *spc_get (long);

/**************************************
	    Interne Variable
**************************************/

struct genflags genflags;

/**************************************
	   Interne Prototypes
**************************************/

// extern int VSTK_Internal;
extern UBYTE Fstr[];
extern UBYTE Rstr[];



#include "gen_spc.h"


Prototype UBYTE *ltostr (long l);
UBYTE *ltostr (long l) {
    static UBYTE buffer[16];
    sprintf (buffer, "%ld", l);
    return buffer;
}

Prototype char *strrep (char *old, const char *new);
char * strrep (char *old, const char *new) {
    char *dup;
    if (dup = strdup(new)) {
	free (old);
	return dup;
    } else {
	nomemory();
	return old;
    } /* if */
} /* strrep */


#if 0
// the advantage of that function is, we can reuse it for any kind of
// tables ...
static
unsigned long Bin_access(const void *array, long E_size, long A_size, const char *find) {
    long high, low, mid;
    int  diff;
    const char **cptr;

    high = A_size -1;
    low  = 0;

    do {
	mid  = (high + low) >> 1;
	cptr = (void *)(mid * E_size + (unsigned long) array);
	diff = strcmp (*cptr, find);
	if (diff > 0)
	    high = mid;
	else if (diff)
	    high = mid;
	else
	    return (unsigned long)mid;
    } while (low <= high);

    return (unsigned long)~0;
} /* Bin_access */
#else
static
unsigned long Bin_access(const char **array, long NUPE, long A_size, const char *find) {
    long low, high, mid;
    int  diff;

    high = A_size -1;
    low  = 0;

    do {
	mid  = (low + high) >> 1;
	diff = stricmp (find, array[mid]);
	if (diff < 0)
	    high = mid-1;
	else if (diff)
	    low  = mid+1;
	else
	    return (unsigned long)mid;
    } while (low <= high);

    return (unsigned long)~0;
} /* Bin_access */
#endif


DEFVARTREE( 20, "SPC_", VAR_SV, 4, 4, 0, NULL, NULL, SPC_set, SPC_get )

static long spc_lock(const char *name) {
    if (!name)
	return 0;
    return ~(long)Bin_access (spc_names,
			      sizeof (char *),
			      spc_num_vars,
			      name);
}

Prototype char SPC_set (const char *name, const char *value);
char SPC_set (const char *name, const char *value) {
    long lock;
    if ((lock = spc_lock(name))) {
	if (!spc_set(~lock, value))
	    SET_ABORTION( 1 );
	return 1;
    } /* if */
    return 0;
} /* spc_set */


Prototype char *SPC_get (const char *name);
char *SPC_get (const char *name) {
    long lock;
    if ((lock = spc_lock(name))) {
	char * str;
	if (!(str = spc_get(~lock))) {
	    SET_ABORTION( 1 );
	    return NULL;
	} /* if */
	if (str = strdup(str))
	    return str;
	nomemory();
    } /* if */
    return NULL;
} /* spc_get */

int SPC_setloud (const char *name, const char *value)
{
    long lock;
    if ((lock = spc_lock(name))) {
	if (!spc_set(~lock, value))
	    SET_ABORTION( 1 );
	spc_say(~lock);
	return 1;
    } /* if */
    return 0;
} /* SPC_say */




/*************************************************
    This function is to be called for all
    setting any special var via a command:
	SPC varname value
   The only thing is - the variable must be
   treated here
*************************************************/
/*DEFLONG #long SPC

This command allows access to almost every XDME internal
variable, that is, it can replace almost every preferences
command; additionally to the funcionality of the current
prefs commands, it cn access some System Variables, which
themselfes have no preferences commands, like the
AppIcon variables, the CmdShell Variables and some more
this is a list of the variables that should be settable
w/ @{B}SPC@{UB}.

activetofront,	    appicon,		appiconclickaction,
appicondropaction,  appiconname,	appicontitle,
autoindent,	    autosplit,		autounblock,
bbpen,		    bgpen,		block,
cmdshell,	    cmdshellname,	cmdshellprompt,
currentdir,	    debug,		dobackup,
ed,		    errorsoncmdshell,	fgpen,
filename,	    findstr,		followcursor,
globalsearch,	    gtbformat,		hgpen,
icon,		    iconactive, 	iconmode,
icontitle,	    ignorecase, 	infixmode,
insertmode,	    keytable,		margin,
menufontname,	    menufontsize,	menustrip,
modified,	    nicepaging, 	norequest,
parcol, 	    pens,		pos,
repstr, 	    reqpattern, 	reqresult,
rexxport,	    rxresult,		saveicons,
savetabs,	    scanf,		shortlines,
showtitle,	    simpletabs, 	sourcebreaks,
tabstop,	    tbpen,		tfpen,
viewmode,	    warningsoncmdshell, window,
windowcycling,	    windowtitles,	wordwrap


Please note, that each variable settable w/ SPC is also usable in
the Varstack; however the ED, POS and BLOCK should be used w/ care.

for the completeness: the following vars cannot be changed w/ SPC
ascii,		    colno,		comlinemode,
currentline,	    currentword,	firstnb,
itemcheck,	    lineno,		numlines,
prevnbline,	    recentword, 	reqresult,
restofline,	    rexxport,		txtfontname,
txtfontsize,	    version
*/

/*DEFHELP #cmd var SPC var value - Modify an internal XDME system variable */
DEFUSERCMD("spc", 2, CF_VWM|CF_COK|CF_ICO, void, do_setspecialvar, (void),)
{
    if (!SPC_setloud(av[1],av[2]))
DEFMESSAGE(_VAR_cant_set_sysvar_2, "%s:\nCannot set system variable `%s'\nto `%s'")
	error (_VAR_cant_set_sysvar_2, av[0], av[1], av[2]);
} /* do_setspecialvar */


/*************************************************
    We could use that function in order to
    emulate any of the functions in prefs.c,
    which has a here settable variable
    (as long, as the variable)/set is not a
    frontend for the prefs function
    like e.g. $path)
*************************************************/
/* Prototype void do_specialvar (void);
void do_specialvar (void)
{
    if (!SPC_setloud(av[0],av[1]))
	SET_ABORTION(1);
} /* do_setspecialvar */








/***************************************************
	 test driver for Lock function
***************************************************/

#ifdef TEST

/*
struct __XDMEArgs XDMEArgs;
UWORD Mx, My;
char MShowTitle, noadj;
struct MsgPort *Sharedport;
*/

UBYTE tmp_buffer[256];

int main(int ac, char ** av) {
    int i;
    for (i = 0; i < spc_num_vars; ++i) {
	printf ("accessing %d/%s -> %d\n", i, spc_names[i], spc_lock(spc_names[i]));
    } /* for */

    printf ("accessing %d/%s -> %d\n", i, "hallo", spc_lock("hallo"));
    printf ("accessing %d/%s -> %d\n", i, "_oops", spc_lock("_oops"));
    printf ("accessing %d/%s -> %d\n", i, "Aetsch", spc_lock("Aetsch"));
    printf ("accessing %d/%s -> %d\n", i, "}{", spc_lock("}{"));
    printf ("accessing %d/%s -> %d\n", i, "00", spc_lock("00"));
    printf ("accessing %d/%s -> %d\n", i, "", spc_lock(""));

    return 0;
}

#endif

/******************************************************************************
*****  ENDE spc.c
******************************************************************************/

