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
|
||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
MODIFICATIONS.
|
||||
|
||||
M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z
|
||||
---------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -51,6 +53,8 @@
|
||||
#include "devexec.h"
|
||||
#include "servlog.h"
|
||||
#include "macro.h"
|
||||
/* M.Z. */
|
||||
#include "definealias.h"
|
||||
|
||||
#define MAXLEN 256
|
||||
#define MAXPAR 100
|
||||
@ -68,6 +72,7 @@
|
||||
return NULL;
|
||||
}
|
||||
pInter->pCList = NULL;
|
||||
pInter->AList.pFirst = NULL; /* M.Z. */
|
||||
pInter->pTcl = (void *)MacroInit(pInter);
|
||||
if(!pInter->pTcl)
|
||||
{
|
||||
@ -91,6 +96,7 @@
|
||||
|
||||
strcpy(pBueffel,pName);
|
||||
strtolower(pBueffel);
|
||||
RemoveAlias(&pInterp->AList,pBueffel); /* M.Z. */
|
||||
if(FindCommand(pInterp,pBueffel) != NULL)
|
||||
{
|
||||
return 0;
|
||||
@ -276,7 +282,7 @@ extern char *SkipSpace(char *pPtr);
|
||||
CommandList *FindCommand(SicsInterp *self, char *pName)
|
||||
{
|
||||
CommandList *pCurrent = NULL;
|
||||
char pBueffel[256];
|
||||
char pBueffel[256], *pCmd;
|
||||
|
||||
assert(self);
|
||||
|
||||
@ -287,12 +293,15 @@ extern char *SkipSpace(char *pPtr);
|
||||
|
||||
strcpy(pBueffel,pName);
|
||||
strtolower(pBueffel);
|
||||
|
||||
pCmd=TranslateAlias(&self->AList, pBueffel); /* M.Z. */
|
||||
|
||||
pCurrent = self->pCList;
|
||||
while(pCurrent)
|
||||
{
|
||||
if(pCurrent->pName != NULL)
|
||||
{
|
||||
if(strcmp(pCurrent->pName, pBueffel) == 0 )
|
||||
if(strcmp(pCurrent->pName, pCmd) == 0 ) /* M.Z. */
|
||||
{
|
||||
return pCurrent;
|
||||
}
|
||||
@ -371,6 +380,8 @@ extern char *SkipSpace(char *pPtr);
|
||||
pCurrent = pTemp;
|
||||
}
|
||||
|
||||
FreeAliasList(&self->AList); /* M.Z. */
|
||||
|
||||
/* clear Tcl_Interpreter. Must be AFTER deleting command list because
|
||||
some devices may have Tcl drivers which need to be accessed for
|
||||
proper closing of devices.
|
||||
@ -512,3 +523,4 @@ extern char *SkipSpace(char *pPtr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#ifndef SICSINTERPRETER
|
||||
#define SICSINTERPRETER
|
||||
#include "Scommon.h"
|
||||
/* M.Z. */
|
||||
#include "definealias.i"
|
||||
|
||||
typedef struct __SConnection *pSConnection;
|
||||
typedef struct __SINTER *pSicsInterp;
|
||||
@ -35,6 +37,7 @@ typedef struct __SINTER
|
||||
OutCode eOut;
|
||||
void *pTcl;
|
||||
int iDeleting;
|
||||
AliasList AList; /* M.Z. */
|
||||
}SicsInterp;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -128,5 +131,6 @@ typedef struct __SINTER
|
||||
to the commands data structure is retuned. Else NULL
|
||||
*/
|
||||
void *FindCommandData(SicsInterp *pSics, char *name, char *comclass);
|
||||
|
||||
#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,"MakeO2T",CreateO2T,NULL,NULL);
|
||||
AddCommand(pInter,"SicsAlias",SicsAlias,NULL,NULL);
|
||||
AddCommand(pInter,"DefineAlias",DefineAlias,NULL,NULL); /* M.Z. */
|
||||
AddCommand(pInter,"InitDMC",InitDmc,NULL,NULL);
|
||||
AddCommand(pInter,"InitSANS",InitSANS,NULL,NULL);
|
||||
AddCommand(pInter,"MakeHM",MakeHistMemory,NULL,NULL);
|
||||
|
Reference in New Issue
Block a user