Define Alias M.Z.
This commit is contained in:
16
SCinter.c
16
SCinter.c
@ -35,6 +35,8 @@
|
|||||||
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||||
MODIFICATIONS.
|
MODIFICATIONS.
|
||||||
|
|
||||||
|
M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -51,6 +53,8 @@
|
|||||||
#include "devexec.h"
|
#include "devexec.h"
|
||||||
#include "servlog.h"
|
#include "servlog.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
/* M.Z. */
|
||||||
|
#include "definealias.h"
|
||||||
|
|
||||||
#define MAXLEN 256
|
#define MAXLEN 256
|
||||||
#define MAXPAR 100
|
#define MAXPAR 100
|
||||||
@ -68,6 +72,7 @@
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pInter->pCList = NULL;
|
pInter->pCList = NULL;
|
||||||
|
pInter->AList.pFirst = NULL; /* M.Z. */
|
||||||
pInter->pTcl = (void *)MacroInit(pInter);
|
pInter->pTcl = (void *)MacroInit(pInter);
|
||||||
if(!pInter->pTcl)
|
if(!pInter->pTcl)
|
||||||
{
|
{
|
||||||
@ -91,6 +96,7 @@
|
|||||||
|
|
||||||
strcpy(pBueffel,pName);
|
strcpy(pBueffel,pName);
|
||||||
strtolower(pBueffel);
|
strtolower(pBueffel);
|
||||||
|
RemoveAlias(&pInterp->AList,pBueffel); /* M.Z. */
|
||||||
if(FindCommand(pInterp,pBueffel) != NULL)
|
if(FindCommand(pInterp,pBueffel) != NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -276,7 +282,7 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
CommandList *FindCommand(SicsInterp *self, char *pName)
|
CommandList *FindCommand(SicsInterp *self, char *pName)
|
||||||
{
|
{
|
||||||
CommandList *pCurrent = NULL;
|
CommandList *pCurrent = NULL;
|
||||||
char pBueffel[256];
|
char pBueffel[256], *pCmd;
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
@ -287,12 +293,15 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
|
|
||||||
strcpy(pBueffel,pName);
|
strcpy(pBueffel,pName);
|
||||||
strtolower(pBueffel);
|
strtolower(pBueffel);
|
||||||
|
|
||||||
|
pCmd=TranslateAlias(&self->AList, pBueffel); /* M.Z. */
|
||||||
|
|
||||||
pCurrent = self->pCList;
|
pCurrent = self->pCList;
|
||||||
while(pCurrent)
|
while(pCurrent)
|
||||||
{
|
{
|
||||||
if(pCurrent->pName != NULL)
|
if(pCurrent->pName != NULL)
|
||||||
{
|
{
|
||||||
if(strcmp(pCurrent->pName, pBueffel) == 0 )
|
if(strcmp(pCurrent->pName, pCmd) == 0 ) /* M.Z. */
|
||||||
{
|
{
|
||||||
return pCurrent;
|
return pCurrent;
|
||||||
}
|
}
|
||||||
@ -371,6 +380,8 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
pCurrent = pTemp;
|
pCurrent = pTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeAliasList(&self->AList); /* M.Z. */
|
||||||
|
|
||||||
/* clear Tcl_Interpreter. Must be AFTER deleting command list because
|
/* clear Tcl_Interpreter. Must be AFTER deleting command list because
|
||||||
some devices may have Tcl drivers which need to be accessed for
|
some devices may have Tcl drivers which need to be accessed for
|
||||||
proper closing of devices.
|
proper closing of devices.
|
||||||
@ -512,3 +523,4 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#ifndef SICSINTERPRETER
|
#ifndef SICSINTERPRETER
|
||||||
#define SICSINTERPRETER
|
#define SICSINTERPRETER
|
||||||
#include "Scommon.h"
|
#include "Scommon.h"
|
||||||
|
/* M.Z. */
|
||||||
|
#include "definealias.i"
|
||||||
|
|
||||||
typedef struct __SConnection *pSConnection;
|
typedef struct __SConnection *pSConnection;
|
||||||
typedef struct __SINTER *pSicsInterp;
|
typedef struct __SINTER *pSicsInterp;
|
||||||
@ -35,6 +37,7 @@ typedef struct __SINTER
|
|||||||
OutCode eOut;
|
OutCode eOut;
|
||||||
void *pTcl;
|
void *pTcl;
|
||||||
int iDeleting;
|
int iDeleting;
|
||||||
|
AliasList AList; /* M.Z. */
|
||||||
}SicsInterp;
|
}SicsInterp;
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -128,5 +131,6 @@ typedef struct __SINTER
|
|||||||
to the commands data structure is retuned. Else NULL
|
to the commands data structure is retuned. Else NULL
|
||||||
*/
|
*/
|
||||||
void *FindCommandData(SicsInterp *pSics, char *name, char *comclass);
|
void *FindCommandData(SicsInterp *pSics, char *name, char *comclass);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
217
definealias.c
Normal file
217
definealias.c
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
One more approach for the implementation of Aliases
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Markus Zolliker, September 2000
|
||||||
|
|
||||||
|
Copyright:
|
||||||
|
|
||||||
|
Labor fuer Neutronenstreuung
|
||||||
|
Paul Scherrer Institut
|
||||||
|
CH-5423 Villigen-PSI
|
||||||
|
|
||||||
|
|
||||||
|
The authors hereby grant permission to use, copy, modify, distribute,
|
||||||
|
and license this software and its documentation for any purpose, provided
|
||||||
|
that existing copyright notices are retained in all copies and that this
|
||||||
|
notice is included verbatim in any distributions. No written agreement,
|
||||||
|
license, or royalty fee is required for any of the authorized uses.
|
||||||
|
Modifications to this software may be copyrighted by their authors
|
||||||
|
and need not follow the licensing terms described here, provided that
|
||||||
|
the new terms are clearly indicated on the first page of each file where
|
||||||
|
they apply.
|
||||||
|
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
||||||
|
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
||||||
|
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
|
||||||
|
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||||
|
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||||
|
MODIFICATIONS.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "fortify.h"
|
||||||
|
#include "definealias.h"
|
||||||
|
|
||||||
|
typedef struct __Aitem {
|
||||||
|
struct __Aitem *pNext;
|
||||||
|
char *pName;
|
||||||
|
char *pCmd;
|
||||||
|
} AliasItem;
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
char *TranslateAlias(AliasList *pAList, char *pCmd)
|
||||||
|
{
|
||||||
|
AliasItem *pAlias;
|
||||||
|
|
||||||
|
assert(pAList!=NULL && pCmd!=NULL);
|
||||||
|
|
||||||
|
pAlias=pAList->pFirst;
|
||||||
|
while (pAlias!=NULL)
|
||||||
|
{
|
||||||
|
if (0 == strcmp(pAlias->pName, pCmd))
|
||||||
|
{
|
||||||
|
pCmd = pAlias->pCmd; /* note that there may be cascaded translations */
|
||||||
|
}
|
||||||
|
pAlias = pAlias->pNext;
|
||||||
|
}
|
||||||
|
return(pCmd);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int RemoveAlias(AliasList *pAList, char *pCmd)
|
||||||
|
{
|
||||||
|
AliasItem *pAlias = NULL, *pPrev = NULL;
|
||||||
|
|
||||||
|
assert(pAList!=NULL && pCmd!=NULL);
|
||||||
|
|
||||||
|
pPrev=(AliasItem *)pAList;
|
||||||
|
pAlias=pAList->pFirst;
|
||||||
|
while (pAlias != NULL && 0 != strcmp(pAlias->pName, pCmd))
|
||||||
|
{
|
||||||
|
pPrev = pAlias;
|
||||||
|
pAlias = pAlias->pNext;
|
||||||
|
}
|
||||||
|
if (pAlias==NULL)
|
||||||
|
{
|
||||||
|
return 0; /* not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove it */
|
||||||
|
pPrev->pNext = pAlias->pNext;
|
||||||
|
free(pAlias->pName);
|
||||||
|
free(pAlias->pCmd);
|
||||||
|
free(pAlias);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
void FreeAliasList(AliasList *pAList)
|
||||||
|
{
|
||||||
|
AliasItem *pAlias = NULL, *pNext = NULL;
|
||||||
|
|
||||||
|
assert(pAList!=NULL);
|
||||||
|
|
||||||
|
pAlias=pAList->pFirst;
|
||||||
|
while (pAlias != NULL)
|
||||||
|
{
|
||||||
|
pNext=pAlias->pNext;
|
||||||
|
free(pAlias->pName);
|
||||||
|
free(pAlias->pCmd);
|
||||||
|
free(pAlias);
|
||||||
|
pAlias = pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
char *CreateAlias(AliasList *pAList, char *pName, char *pTranslation)
|
||||||
|
{ /* arguments must be lower case */
|
||||||
|
AliasItem *pAlias = NULL, *pNew = NULL, *pTail = NULL;
|
||||||
|
char *pCmd;
|
||||||
|
|
||||||
|
/* translate 2nd argument */
|
||||||
|
pCmd=TranslateAlias(pAList, pTranslation);
|
||||||
|
if (0==strcmp(pName, pCmd)) /* translation matches */
|
||||||
|
{
|
||||||
|
return "recursive alias not allowed";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find last element pTail and check that alias does not yet exist */
|
||||||
|
pTail = (AliasItem *)pAList;
|
||||||
|
pAlias = pAList->pFirst;
|
||||||
|
while (pAlias!=NULL)
|
||||||
|
{
|
||||||
|
pTail=pAlias;
|
||||||
|
if (0 == strcmp(pAlias->pName, pName))
|
||||||
|
{
|
||||||
|
return "alias already exists";
|
||||||
|
}
|
||||||
|
pAlias = pAlias->pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate the list entry */
|
||||||
|
pNew = malloc(sizeof(AliasItem));
|
||||||
|
if (pNew!=NULL)
|
||||||
|
{
|
||||||
|
pNew->pNext = NULL;
|
||||||
|
pNew->pName = strdup(pName);
|
||||||
|
if (pNew->pName!=NULL)
|
||||||
|
{
|
||||||
|
pNew->pCmd = strdup(pCmd);
|
||||||
|
if (pNew->pCmd!=NULL)
|
||||||
|
{
|
||||||
|
/* insert at tail */
|
||||||
|
pTail->pNext = pNew;
|
||||||
|
return NULL; /* o.k. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "not enough memory to create an alias";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int DefineAlias(pSConnection pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char pBueffel[256];
|
||||||
|
int iRet;
|
||||||
|
CommandList *pCom = NULL;
|
||||||
|
char *pErr;
|
||||||
|
|
||||||
|
if(!SCMatchRights(pCon,usMugger))
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: only managers may define aliases",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
argtolower(argc,argv);
|
||||||
|
|
||||||
|
if(argc == 2) /* remove case */
|
||||||
|
{
|
||||||
|
iRet=RemoveAlias(&pSics->AList, argv[1]);
|
||||||
|
if (iRet==0)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: alias not found",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(argc != 3)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: illegal number of arguments to DefineAlias",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCom = FindCommand(pSics, argv[1]);
|
||||||
|
if (pCom!=NULL)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: an alias must not overwrite a command",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove the old alias, if any */
|
||||||
|
RemoveAlias(&pSics->AList, argv[1]);
|
||||||
|
|
||||||
|
pErr=CreateAlias(&pSics->AList, argv[1], argv[2]);
|
||||||
|
if (pErr!=NULL)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: %s", pErr);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
93
definealias.h
Normal file
93
definealias.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
D E F I N E A L I A S E S . C
|
||||||
|
|
||||||
|
Markus Zolliker, September 2000
|
||||||
|
|
||||||
|
copyright: see implementation file
|
||||||
|
|
||||||
|
More general and safe Aliases:
|
||||||
|
|
||||||
|
- an alias may be defined even if the corresponding command
|
||||||
|
does not yet exist
|
||||||
|
|
||||||
|
- SICS does not crash when the original command of an alias is
|
||||||
|
removed
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
#ifndef DEFINE_ALIAS
|
||||||
|
#define DEFINE_ALIAS
|
||||||
|
#include "conman.h"
|
||||||
|
#include "definealias.i"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
char *TranslateAlias(AliasList *pAList, char *pCmd);
|
||||||
|
/*
|
||||||
|
translate the command *pCmd
|
||||||
|
- the translation may go through several steps
|
||||||
|
- if no translation is found, the return value is equal to pCmd
|
||||||
|
- no strings are copied
|
||||||
|
- the return value becomes invalid when the corresponding alias is removed
|
||||||
|
- *pCmd must be lowercase
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int RemoveAlias(AliasList *pAList, char *pCmd);
|
||||||
|
/*
|
||||||
|
remove the alias *pCmd
|
||||||
|
- returns 1 when the alias existed, 0 otherwise
|
||||||
|
- *pCmd must be lowercase
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void FreeAliasList(AliasList *pAList);
|
||||||
|
/*
|
||||||
|
dispose the alias list
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
char *CreateAlias(AliasList *pAList, char *pName, char *pTranslation);
|
||||||
|
|
||||||
|
/*
|
||||||
|
create a new alias *pName with the translation *pTranslation
|
||||||
|
|
||||||
|
- the alias *pName must not yet exist
|
||||||
|
- *pTranslation is translated first
|
||||||
|
- recursive definitions are prohibited
|
||||||
|
- *pName and *pTranslation must be lowercase
|
||||||
|
|
||||||
|
if the creation is successful, the return value is NULL, otherwise
|
||||||
|
it points to one of the following error messages:
|
||||||
|
|
||||||
|
"recursive alias not allowed"
|
||||||
|
"alias already exists"
|
||||||
|
"not enough memory to create an alias"
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int DefineAlias(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
/* this command requires manager privileges
|
||||||
|
|
||||||
|
argv[1]: the alias to define
|
||||||
|
- must not be a proper SICS command
|
||||||
|
- if an alias with this name exists already, it is removed first
|
||||||
|
|
||||||
|
argv[2]: the original command
|
||||||
|
- if omitted, the alias is removed
|
||||||
|
- if it is an alias the definiton refers to it's translation
|
||||||
|
- may be an unknown command (probably defined later)
|
||||||
|
|
||||||
|
- AddCommand removes an eventual alias matching the command name
|
||||||
|
|
||||||
|
- RemoveCommand does not remove it's aliases
|
||||||
|
Trying to use an alias of a removed command leads to the error message
|
||||||
|
"object > ... < NOT found"
|
||||||
|
|
||||||
|
- trying to define a recursive alias leads the error message
|
||||||
|
"recursive alias not allowed"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
20
definealias.i
Normal file
20
definealias.i
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AliasList datastructure
|
||||||
|
|
||||||
|
Markus Zolliker, September 2000
|
||||||
|
|
||||||
|
copyright: see implementation file
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
#ifndef DEFINE_ALIAS_I
|
||||||
|
#define DEFINE_ALIAS_I
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *pFirst;
|
||||||
|
} AliasList;
|
||||||
|
|
||||||
|
/*
|
||||||
|
initialize pFirst to NULL to create an empty list
|
||||||
|
*/
|
||||||
|
#endif
|
1
ofac.c
1
ofac.c
@ -248,6 +248,7 @@
|
|||||||
AddCommand(pInter,"MakeRuenBuffer",InitBufferSys,NULL,NULL);
|
AddCommand(pInter,"MakeRuenBuffer",InitBufferSys,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeO2T",CreateO2T,NULL,NULL);
|
AddCommand(pInter,"MakeO2T",CreateO2T,NULL,NULL);
|
||||||
AddCommand(pInter,"SicsAlias",SicsAlias,NULL,NULL);
|
AddCommand(pInter,"SicsAlias",SicsAlias,NULL,NULL);
|
||||||
|
AddCommand(pInter,"DefineAlias",DefineAlias,NULL,NULL); /* M.Z. */
|
||||||
AddCommand(pInter,"InitDMC",InitDmc,NULL,NULL);
|
AddCommand(pInter,"InitDMC",InitDmc,NULL,NULL);
|
||||||
AddCommand(pInter,"InitSANS",InitSANS,NULL,NULL);
|
AddCommand(pInter,"InitSANS",InitSANS,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeHM",MakeHistMemory,NULL,NULL);
|
AddCommand(pInter,"MakeHM",MakeHistMemory,NULL,NULL);
|
||||||
|
Reference in New Issue
Block a user