home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1820.lha
/
XDME
/
vars.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-09
|
19KB
|
787 lines
/*
** VARS.C
**
** Variable Support for [X]DME
**
** (C)Copyright 1992 by Bernd Noll for null/zero-soft
** All Rights Reserved
**
** RCS Header: $Id: vars.c,v 1.65 92/11/09 12:47:10 b_noll Exp $
**
** compiling with
** "#define PATCH_NULL"
** "#define PATCH_VARS"
** "#define PATCH_FLAGS"
** causes that module to be used (and var.c not to be used)
**
*!***************************************************************
*!
*! PATCH_VARS - OVERVIEW
*!
*!
*! the vars-module shall support access to different types of
*! variables
*! which are currently "global" vars/flags, "textlocal" vars/flags,
*! "macrolocal" vars and "env" vars
** (there are some other types used for DME, but not for XDME yet)
*!
*!
*! WARNING:
*! as this module is written very close
*! to DME's internal hierachy, it will be object of major changes,
*! as soon as Packages are introduced as a new concept for management
*! of macros, menues, keys, flags and variables
*!
**
**
** GetTypedVar / SetTypedVar / VAR_...types/prefixes
**
** the "Highlevel" interface to most other variable modules,
** which should most times be used in Programming -
** Cleanest Possiblility of Access to Variables of any Type.
**
** We have put all variable functions, which do not need access
** to certain structures (rexx.../argstack...), together in that
** module and try to export only a very small interface, which
** should allow information hiding
**
** this module should completely cover the "old" module var.c
** so I put var.c into '#ifndef PATCH_VARS'
**
*****************************************************************
**
** Implementor's note
**
** The module looks pretty ugly,
** I am not ready documenting and porting all
** functions which had been written for DME
** into XDME partly as many differences have occurred
** partly as I have started designing a Packages-concept
**
** XDME NOTE - the flags - routines are not used yet for XDME
*/
/**************************************
Includes
**************************************/
#include "defs.h"
/**************************************
Internal Prototypes
**************************************/
Prototype void init_variables (void);
Prototype CHAR * GetTypedVar (CHAR *, int *);
Prototype void SetTypedVar (CHAR *, CHAR *, int);
extern void SetDMEVar (CHAR *, CHAR *); /* Proto'd for access from scanf.c */
extern void SetTextVar (CHAR *, CHAR *);
extern void SetDEnv (CHAR *, CHAR *);
extern CHAR * GetDMEVar (CHAR *);
extern CHAR * GetTextVar (CHAR *);
extern CHAR * GetEnvVar (CHAR *);
extern CHAR * GetDEnv (CHAR *);
Prototype void do_set (void);
Prototype void do_unset (void);
Prototype void do_setenv (void);
Prototype void do_unsetenv (void);
Prototype void do_settvar (void);
Prototype void do_unsettvar (void);
Prototype int is_tflagset (int); /* Proto'd for access from control.c */
Prototype int is_gflagset (int); /* Proto'd for access from control.c */
extern CHAR * GetTextFlag (CHAR *);
extern CHAR * GetGlobalFlag (CHAR *);
extern char SetAnyFlag (CHAR *, CHAR *);
extern char SetGlobalFlag (CHAR *, CHAR *);
extern char SetTextFlag (CHAR *, CHAR *);
Prototype void do_flag (void);
Prototype void do_toggleflag (void);
Prototype CHAR * getvar (CHAR *);
/**************************************
Internal Variables
**************************************/
#ifndef VAR_NUM
#define VAR_NUM 8
#endif
#ifndef SIGN_LOCAL_FLAG
# define SIGN_LOCAL_FLAG 't'
#endif
#ifdef DBASE
# define SList DmeBase.SList
# define VarsTree DmeBase.SList
#else
APTR VarsTree = NULL;
#endif
/*
** init_variables()
** initialize the "global" variables structures
** call that function from main or make it '__autoinit'
*/
void
init_variables (void)
{
VarsTree = NULL;
} /* init_variables */
/***************************************************************
**
** Access to the different kinds of Named Variables
**
***************************************************************/
/**************************************
** Handling of DME "global" Variables
** (if we are using Packages "global" might be the wrong name)
**************************************/
CHAR *
GetDMEVar (CHAR * name)
{
return (GetVarFromTree(&VarsTree, name));
} /* GetDMEVar */
void
SetDMEVar (CHAR * name, CHAR * value)
{
SetVarIntoTree (&VarsTree, name, value);
} /* SetDMEVar */
/*
*! >SET name value
*! >UNSET name
*!
*! set a std DME variable to a new value or drop it and its contents
*! if the name is only a number, set the according dme std flag
*!
*! NOTE that if packages are ready, SET should default to PVars/PFlags,
*! not to GVars/GFlags
*!
*/
void
do_set (void)
{
if (!SetGlobalFlag(av[1], av[2]))
SetDMEVar (av[1],av[2]);
} /* do_set */
void
do_unset (void)
{
DelVarFromTree (&VarsTree, av[1]);
} /* do_unset */
/**************************************
** Handling of Text Local Variables
**************************************/
CHAR *
GetTextVar (CHAR * name)
{
return (GetVarFromTree (&Ep->textvars, name));
} /* GetTextVar */
void
SetTextVar (CHAR * name, CHAR * value)
{
SetVarIntoTree (&Ep->textvars, name, value);
} /* SetTextVar */
/*
*! >SETTVAR name value
*! >UNSETTVAR name
*!
*! set a text local variable to a new value or drop it and its contents
*! if the name is only a "t"number, set the according text local flag
*!
*/
void
do_settvar (void)
{
if (!SetTextFlag(av[1], av[2]))
SetTextVar (av[1],av[2]);
} /* do_settvar */
void
do_unsettvar (void)
{
DelVarFromTree (&Ep->textvars, av[1]);
} /* do_unsettvar */
/***************************************************************
**
** Access to Environment variables
**
***************************************************************/
CHAR *
GetDEnv (CHAR * ename)
{
long envLock = Lock("env:", SHARED_LOCK);
CHAR * str = NULL;
if (envLock)
{
long oldLock = CurrentDir (envLock);
FILE * fi = fopen (ename, "r");
long siz;
if (fi)
{
fseek (fi, 0L, 2);
siz = ftell (fi);
fseek (fi, 0L, 0);
if (siz > 0 && (str = malloc (siz + 1)))
{
fread (str, siz, 1, fi);
str[siz] = 0;
} /* if malloced */
fclose (fi);
} /* if opened */
UnLock (CurrentDir (oldLock));
} /* if locked */
return (str);
} /* GetDEnv */
void
SetDEnv (CHAR * ename, CHAR * econt)
{
long envLock = Lock ("env:", SHARED_LOCK);
if (envLock)
{
long oldLock = CurrentDir (envLock);
FILE * fi = fopen (ename, "w");
if (fi)
{
fwrite (econt, strlen(econt), 1, fi);
fclose (fi);
} /* if opened */
UnLock (CurrentDir(oldLock));
} /* if locked */
} /* SetDEnv */
CHAR *
GetEnvVar(CHAR * name)
{
CHAR * str;
mountrequest(0);
str = GetDEnv(name);
mountrequest(1);
return(str);
} /* GetEnvVar */
/*
*! >SETENV name value
*! >UNSETENV name
*!
*! set an Environment variable to a new value or drop it and its contents
*/
void do_setenv (void)
{
SetDEnv ((char *)av[1], (char *)av[2]);
} /* do_setenv */
void do_unsetenv (void)
{
char * tmp = malloc(4+1+strlen(av[1]));
if (tmp)
{
strcpy(tmp, "ENV:");
strcat(tmp, av[1]);
mountrequest (0);
DeleteFile ((STRPTR)tmp);
mountrequest (1);
free (tmp);
} /* if */
} /* do_unsetenv */
/***************************************************************
**
** Access to the different kinds of Flags
**
***************************************************************/
/**************************************
** Handling of TEXT Local Flags
**************************************/
int is_tflagset(int num)
{
return (IsFlagSet(Ep->textflags, num, 32));
} /* is_tflagset */
char SetTextFlag(CHAR * name, CHAR * value)
{
return (SetFlag(Ep->textflags, name, value, 32, "t"));
} /* SetTextFlag */
/*
* GetTextFlag: get a variable of a text's internal flags
*/
CHAR * GetTextFlag (CHAR * name)
{
return (GetFlag(Ep->textflags, name, 32, "t"));
} /* GetTextFlag */
#ifdef DBASE
# define tg DmeBase.gflags
#else
char tg[MAXTOGGLE/8]; /* test purposes */
#endif /* DBASE */
/**************************************
** Handling of DME Global Flags
**************************************/
int is_gflagset (int num)
{
return(IsFlagSet(tg, num, MAXTOGGLE));
} /* is_gflagset */
/*
* GetGlobalFlag : get a variable from dme's flag-list
*/
char SetGlobalFlag(CHAR * name, CHAR * value)
{
return(SetFlag(tg, name, value, MAXTOGGLE, "")); /* "g" */
} /* SetGlobalFlag */
CHAR * GetGlobalFlag (CHAR * name)
{
return(GetFlag(tg, name, MAXTOGGLE, "")); /* "g" */
} /* GetGlobalFlag */
/**************************************
** Interface to come around with all types of flags
**************************************/
char
SetAnyFlag(CHAR * name, CHAR * qual)
{
if (name && qual)
{
if (is_number(name))
{
return(SetGlobalFlag(name, qual));
/* } if (!is_digit(name[1]))
{ // Commented out for XDME */
// return(SetSpecialFlag(name, qual)); /* Commented out for XDME */
} else if (name[0] == SIGN_LOCAL_FLAG)
{
return(SetTextFlag(name, qual));
} else
{
/* abort(); */
return(0);
} /* if */
} else
{
abort(0);
} /* if */
} /* SetAnyFlag */
/*
*! >FLAG flagname on/off/toggle/switch/0/1/set/reset/true/false
*!
*! set any flag that is controlled by DME
*! with flagname is number, "t"number or specialflagname
*!
*/
void
do_flag (void)
{
if (!SetAnyFlag(av[1],av[2]))
abort();
} /* do_flag */
/*
*! >[[RE]SET]TOGGLE flagname
*!
*! modify any flag, that is controlled by DME
*! with flagname is number, "i"number or specialflag
*!
*/
void
do_toggleflag (void)
{
SetAnyFlag(av[1], av[0]);
} /* do_toggleflag */
/***************************************************************
**
** Interface to be used for external functions and commands
**
***************************************************************/
/*
** the different types of "variables",
** which seem to be possible to be recognized
**
** these definitions must be visible to all modules
*/
// #define VAR_NEX 0 /* not existing variable */
// #define VAR_FPK 1 /* explicite access to another ("foreign") package */
// #define VAR_SF 2 /* dme special flags */
// #define VAR_SI 3 /* dme special integer variable */
// #define VAR_SV 4 /* dme special vars scanf/filename/... */
// #define VAR_MF 5 /* dme macro flag */
// #define VAR_TF 6 /* dme text flag */
// #define VAR_PF 7 /* dme package flag */
// #define VAR_GF 8 /* dme global flag */
// #define VAR_TV 9 /* dme text variable */
// #define VAR_MV 10 /* dme macro variable */
// #define VAR_PV 11 /* dme package variable */
// #define VAR_GV 12 /* dme global variable */
// #define VAR_ARG 13 /* dme macro parameter */
// #define VAR_ENV 14 /* CBM env: variable */
// #define VAR_SH 15 /* CBM local shell-var (FUTURE) */
// #define VAR_CLP 16 /* rexx cliplist - entry */
// #define VAR_RXX 17 /* rexx variable via RVI */
// #define VAR_RXF 18 /* rexx result of functioncall */
// #define VAR_MAP 19 /* dme package key-mapping */
// #define VAR_MEN 20 /* dme package menu */
// #define VAR_MNX 21 /* Arp shell-var (FUTURE) */
// #define VAR_DME VAR_GV /* alias */
#define VF_COP 1 /* duplicate the result */
#define VF_PAW 2 /* Prefix AlWays: dont use without Prefix (FUTURE) */
typedef struct _vtype
{
const CHAR * name; /* prefix */
int id; /* number for communication */
int len; /* size of prefix for comparison */
int offset; /* offset to cut prefix */
int flags; /* flags (e.g. duplicate result ...) */
CHAR* replace; /* if prefix matches, replace w/that prefix */
void (*do_set)(CHAR*,CHAR*); /* set-function */
CHAR* (*do_get)(CHAR*); /* get-function */
} VTYPE;
static CONST VTYPE vartypes[] =
{
#ifdef N_DEF
{"SHVAR_", VAR_SH , 6, 6, 0, NULL, NULL, NULL},
{"ARP_", VAR_MNX, 4, 4, 0, NULL, NULL, NULL},
{"RXFUNC ", VAR_RXF, 7, 7, 0, NULL, NULL, getQ},
{"RXSFUNC ",VAR_RXF, 8, 8, 0, NULL, NULL, getQ},
#endif
{"SFLAG_", VAR_SF, 6, 6, 0, NULL, SetSpecialFlag, GetSpecialFlag}, /* we need 3 names */
{"SINT_", VAR_SI, 5, 5, 0, NULL, SetSpecialInt, GetSpecialInt}, /* for the 3 different types (or we have to put them together) */
{"SPC_", VAR_SV, 4, 4, 0, NULL, SetSpecialVar, GetSpecialVar}, /* of special vars else there are big problems */
{"TFLAG_", VAR_TF, 6, 6, 0, "t%s", SetTextFlag, GetTextFlag},
{"GFLAG_", VAR_GF, 6, 6, 0, NULL, SetGlobalFlag, GetGlobalFlag}, /* ifdef PATCH_PACK set replace to "g%s" */
{"ARG_", VAR_ARG, 4, 4, 0, "arg%s", NULL, getmacroarg},
{"arg", VAR_ARG, 3, 0, 0, NULL, NULL, getmacroarg},
{"MVAR_", VAR_MV, 5, 5, 0, NULL, SetMacroVar, getmacrovar},
{"TVAR_", VAR_TV, 5, 5, 0, NULL, SetTextVar, GetTextVar},
{"GVAR_", VAR_GV, 5, 5, 0, NULL, SetDMEVar, GetDMEVar},
{"ENV_", VAR_ENV, 4, 4, 0, NULL, SetDEnv, GetEnvVar},
#ifdef PATCH_RXCLIPS
{"RXCLP_", VAR_CLP, 6, 6, 0, NULL, SetRexxClip, GetRexxClip},
#endif /* PATCH_RXCLIPS */
#ifdef PATCH_RXVARS
{"RXVAR_", VAR_RXX, 6, 6, 0, NULL, setrexxvar, getrexxvar},
#endif /* PATCH_RXVARS */
{"KEY_", VAR_MAP, 4, 4,VF_COP, NULL, mapkey, keyspectomacro},
{"MENU_", VAR_MEN, 5, 5,VF_COP, NULL, NULL, menutomacro},
{NULL, VAR_NEX, 0, 0, 0, NULL, NULL, NULL}
};
/*
** GetTypedVar()
** this function is nearly the same as getvar from cmd2.c
** major differences:
** * it tells where it has found a variable;
** * first we check if the search-name matches a certain
** type-prefix and if it does, we use that type and its
** result (w/out respect if result != NULL)
** * then we check all types until we get a non-NULL result
** or an abortion
** * the end of the vartypes-list means - there is no variable
** of that name
** (type may be NULL)
*/
CHAR *
GetTypedVar (CHAR * find, int * type)
{
CHAR * found = NULL;
int itype = VAR_NEX;
VTYPE * vt;
char inter_abort = globalflags.Abortcommand;
if (type)
*type = VAR_NEX;
if (find == NULL)
{ /* is there a name ? */
abort (NULL);
} else
if (find[0] == '\0')
{ /* is it really a name ? */
return (NULL);
} /* if name corrupt */
globalflags.Abortcommand = 0;
/* if (globalflags.debug) printf("\tgetvar %s ? prefix...", find); */
for (vt = vartypes; vt->id != VAR_NEX && globalflags.Abortcommand == 0; vt++)
{
/* if (globalflags.debug) printf("p"); */
if (strncmp(find, vt->name, vt->len) == 0)
{
CHAR* ptr = find+vt->offset;
if (vt->replace)
{
sprintf(tmp_buffer, vt->replace, ptr);
ptr = tmp_buffer;
} /* if prefix replacement */
itype = vt->id;
found = (*vt->do_get)(ptr);
if (found)
{
/* if (globalflags.debug) printf(" found prefix %s\n", vt->name); */
if (vt->flags & VF_COP)
{
found = strdup(found);
} /* if dup'd */
} else
{
/* if (globalflags.debug) printf ("Aborting\n"); */
globalflags.Abortcommand = 1;
} /* if res(!)=0 */
goto gv_quit;
} /* if matching prefix */
} /* for all types */
/* if (globalflags.debug) printf(" direct..."); */
for (vt = vartypes; vt->id != VAR_NEX && globalflags.Abortcommand == 0; vt++)
{
/* if (globalflags.debug) printf("c"); */
if (vt->do_get)
{
if (found = (*vt->do_get)(find))
{
/* if (globalflags.debug) printf("found type %s\n", vt->name); */
itype = vt->id;
if (vt->flags & VF_COP)
{
found = strdup(found);
} /* if dup'd */
goto gv_quit;
} /* if res#0 */
} /* if ex det-func */
} /* for all types */
gv_quit:
/* if (globalflags.debug) printf("\tgetvar:prefix/err/oerr/val == %s/%d/%d/%s\n",vt->name, (int)Abortcommand, (int)inter_abort, found); */
globalflags.Abortcommand |= inter_abort;
if (type)
{
*type = itype;
}
return(found);
} /* GetTypedVar */
/*
** Set a Variable
** if it has a known type, use the associated set-command
** else check if there is a matching prefix
** if nothing fits - abort
*/
void
SetTypedVar (CHAR * name, CHAR * value, int type)
{
VTYPE* vt;
if ((name == NULL) || (name[0] == '\0'))
{ /* is it a name ? */
abort ();
} /* if name corrupt */
if (type == VAR_NEX)
{
for (vt = vartypes; vt->id != VAR_NEX && globalflags.Abortcommand == 0; vt++)
{
if (strncmp(name, vt->name, vt->len) == 0)
{
CHAR* ptr = name+vt->offset;
/* printf("setting ano type %s\n", vt->name); */
if (vt->do_set != NULL && name[vt->offset] != 0)
{
if (vt->replace)
{
sprintf(tmp_buffer, vt->replace, ptr);
ptr = tmp_buffer;
} /* if prefix replacement */
(*vt->do_set)(ptr, value);
return;
} else
{
abort();
} /* if (no) set-function */
} /* if matching prefix */
} /* for all types */
abort();
} /* if unknown type */
for (vt = vartypes; vt->id != VAR_NEX; vt++)
{
if (vt->id == type)
{
if (vt->do_set)
{
/* printf("setting ok type %s\n", vt->name); */
if (strncmp(name, vt->name, vt->len) == 0)
{
CHAR* ptr = name+vt->offset;
if (vt->replace)
{
sprintf(tmp_buffer, vt->replace, ptr);
ptr = tmp_buffer;
} /* if prefix replacement */
(*vt->do_set)(ptr, value);
} else
{
(*vt->do_set)(name, value);
} /* if (no) matching prefix */
return;
} else
{
abort();
} /* if (no) set-function */
} /* if id found */
} /* for all types */
abort();
} /* SetTypedVar */
/*
** Search
** (1) special Variables (2) Flags (3) macro's list,
** (4) text's list, (5) internal list, (6) enviroment,
** (7) Rexx cliplist (8) macros. The variable is allocated
** with malloc(). NULL if not found. ENV: need not exist.
*/
CHAR * getvar (CHAR * find)
{
return (GetTypedVar(find,NULL));
} /* getvar */
/******************************************************************************
***** END vars.c
******************************************************************************/