321 lines
6.4 KiB
C
321 lines
6.4 KiB
C
/**************************************************************************
|
||
GTA PROJECT AT division
|
||
Copyright, 1990, The Regents of the University of California.
|
||
Los Alamos National Laboratory
|
||
|
||
|
||
seq_mac.c,v 1.2 1995/06/27 15:25:56 wright Exp
|
||
|
||
DESCRIPTION: Macro routines for Sequencer.
|
||
The macro table contains name & value pairs. These are both pointers
|
||
to strings.
|
||
|
||
ENVIRONMENT: VxWorks
|
||
|
||
HISTORY:
|
||
01mar94,ajk Added seq_macValueGet() as state program interface routine.
|
||
|
||
***************************************************************************/
|
||
#define ANSI
|
||
#include "seq.h"
|
||
|
||
LOCAL int seqMacParseName(char *);
|
||
LOCAL int seqMacParseValue(char *);
|
||
LOCAL char *skipBlanks(char *);
|
||
LOCAL MACRO *seqMacTblGet(MACRO *, char *);
|
||
|
||
/*#define DEBUG*/
|
||
|
||
/*
|
||
*seqMacEval - substitute macro value into a string containing:
|
||
* ....{mac_name}....
|
||
*/
|
||
VOID seqMacEval(pInStr, pOutStr, maxChar, pMac)
|
||
char *pInStr;
|
||
char *pOutStr;
|
||
long maxChar;
|
||
MACRO *pMac;
|
||
{
|
||
char name[50], *pValue, *pTmp;
|
||
int nameLth, valLth;
|
||
|
||
#ifdef DEBUG
|
||
logMsg("seqMacEval: InStr=%s\n", pInStr);
|
||
taskDelay(30);
|
||
#endif
|
||
pTmp = pOutStr;
|
||
while (*pInStr != 0 && maxChar > 0)
|
||
{
|
||
if (*pInStr == '{')
|
||
{ /* Do macro substitution */
|
||
pInStr++; /* points to macro name */
|
||
/* Copy the macro name */
|
||
nameLth = 0;
|
||
while (*pInStr != '}' && *pInStr != 0)
|
||
{
|
||
name[nameLth] = *pInStr++;
|
||
if (nameLth < (sizeof(name) - 1))
|
||
nameLth++;
|
||
}
|
||
name[nameLth] = 0;
|
||
if (*pInStr != 0)
|
||
pInStr++;
|
||
|
||
#ifdef DEBUG
|
||
logMsg("Macro name=%s\n", name);
|
||
taskDelay(30);
|
||
#endif
|
||
/* Find macro value from macro name */
|
||
pValue = seqMacValGet(pMac, name);
|
||
if (pValue != NULL)
|
||
{ /* Substitute macro value */
|
||
valLth = strlen(pValue);
|
||
if (valLth > maxChar)
|
||
valLth = maxChar;
|
||
#ifdef DEBUG
|
||
logMsg("Value=%s\n", pValue);
|
||
#endif
|
||
strncpy(pOutStr, pValue, valLth);
|
||
maxChar -= valLth;
|
||
pOutStr += valLth;
|
||
}
|
||
|
||
}
|
||
else
|
||
{ /* Straight susbstitution */
|
||
*pOutStr++ = *pInStr++;
|
||
maxChar--;
|
||
}
|
||
}
|
||
*pOutStr = 0;
|
||
#ifdef DEBUG
|
||
logMsg("OutStr=%s\n", pTmp);
|
||
taskDelay(30);
|
||
#endif
|
||
}
|
||
/*
|
||
* seq_macValueGet - given macro name, return pointer to its value.
|
||
*/
|
||
char *seq_macValueGet(ssId, pName)
|
||
SS_ID ssId;
|
||
char *pName;
|
||
{
|
||
SPROG *pSP;
|
||
MACRO *pMac;
|
||
|
||
pSP = ((SSCB *)ssId)->sprog;
|
||
pMac = pSP->pMacros;
|
||
|
||
return seqMacValGet(pMac, pName);
|
||
}
|
||
/*
|
||
* seqMacValGet - internal routine to convert macro name to macro value.
|
||
*/
|
||
char *seqMacValGet(pMac, pName)
|
||
MACRO *pMac;
|
||
char *pName;
|
||
{
|
||
int i;
|
||
|
||
#ifdef DEBUG
|
||
logMsg("seqMacValGet: name=%s", pName);
|
||
#endif DEBUG
|
||
for (i = 0 ; i < MAX_MACROS; i++, pMac++)
|
||
{
|
||
if (pMac->pName != NULL)
|
||
{
|
||
if (strcmp(pName, pMac->pName) == 0)
|
||
{
|
||
#ifdef DEBUG
|
||
logMsg(", value=%s\n", pMac->pValue);
|
||
#endif DEBUG
|
||
return pMac->pValue;
|
||
}
|
||
}
|
||
}
|
||
#ifdef DEBUG
|
||
logMsg(", no value\n");
|
||
#endif DEBUG
|
||
return NULL;
|
||
}
|
||
/*
|
||
* seqMacParse - parse the macro definition string and build
|
||
* the macro table (name/value pairs). Returns number of macros parsed.
|
||
* Assumes the table may already contain entries (values may be changed).
|
||
* String for name and value are allocated dynamically from pool.
|
||
*/
|
||
long seqMacParse(pMacStr, pSP)
|
||
char *pMacStr; /* macro definition string */
|
||
SPROG *pSP;
|
||
{
|
||
int nMac, nChar;
|
||
char *skipBlanks();
|
||
MACRO *pMac; /* macro table */
|
||
MACRO *pMacTbl; /* macro tbl entry */
|
||
char *pName, *pValue;
|
||
|
||
pMac = pSP->pMacros;
|
||
for ( ;; )
|
||
{
|
||
/* Skip blanks */
|
||
pMacStr = skipBlanks(pMacStr);
|
||
|
||
/* Parse the macro name */
|
||
|
||
nChar = seqMacParseName(pMacStr);
|
||
if (nChar == 0)
|
||
break; /* finished or error */
|
||
pName = (char *)calloc(nChar+1, 1);
|
||
if (pName == NULL)
|
||
break;
|
||
bcopy(pMacStr, pName, nChar);
|
||
pName[nChar] = 0;
|
||
#ifdef DEBUG
|
||
logMsg("name=%s, nChar=%d\n", pName, nChar);
|
||
taskDelay(30);
|
||
#endif
|
||
pMacStr += nChar;
|
||
|
||
/* Find a slot in the table */
|
||
pMacTbl = seqMacTblGet(pMac, pName);
|
||
if (pMacTbl == NULL)
|
||
break; /* table is full */
|
||
if (pMacTbl->pName == NULL)
|
||
{ /* Empty slot, insert macro name */
|
||
pMacTbl->pName = pName;
|
||
}
|
||
|
||
/* Skip over blanks and equal sign or comma */
|
||
pMacStr = skipBlanks(pMacStr);
|
||
if (*pMacStr == ',')
|
||
{ /* no value after the macro name */
|
||
pMacStr++;
|
||
continue;
|
||
}
|
||
if (*pMacStr++ != '=')
|
||
break;
|
||
pMacStr = skipBlanks(pMacStr);
|
||
|
||
/* Parse the value */
|
||
nChar = seqMacParseValue(pMacStr);
|
||
if (nChar == 0)
|
||
break;
|
||
|
||
/* Remove previous value if it exists */
|
||
pValue = pMacTbl->pValue;
|
||
if (pValue != NULL)
|
||
free(pValue);
|
||
|
||
/* Copy value string into newly allocated space */
|
||
pValue = (char *)calloc(nChar+1, 1);
|
||
if (pValue == NULL)
|
||
break;
|
||
pMacTbl->pValue = pValue;
|
||
bcopy(pMacStr, pValue, nChar);
|
||
pValue[nChar] = 0;
|
||
#ifdef DEBUG
|
||
logMsg("value=%s, nChar=%d\n", pValue, nChar);
|
||
taskDelay(30);
|
||
#endif
|
||
|
||
/* Skip past last value and over blanks and comma */
|
||
pMacStr += nChar;
|
||
pMacStr = skipBlanks(pMacStr);
|
||
if (*pMacStr++ != ',')
|
||
break;
|
||
}
|
||
if (*pMacStr == 0)
|
||
return 0;
|
||
else
|
||
return -1;
|
||
}
|
||
|
||
/*
|
||
* seqMacParseName() - Parse a macro name from the input string.
|
||
*/
|
||
LOCAL int seqMacParseName(pStr)
|
||
char *pStr;
|
||
{
|
||
int nChar;
|
||
|
||
/* First character must be [A-Z,a-z] */
|
||
if (!isalpha(*pStr))
|
||
return 0;
|
||
pStr++;
|
||
nChar = 1;
|
||
/* Character must be [A-Z,a-z,0-9,_] */
|
||
while ( isalnum(*pStr) || *pStr == '_' )
|
||
{
|
||
pStr++;
|
||
nChar++;
|
||
}
|
||
/* Loop terminates on any non-name character */
|
||
return nChar;
|
||
}
|
||
|
||
/*
|
||
* seqMacParseValue() - Parse a macro value from the input string.
|
||
*/
|
||
LOCAL int seqMacParseValue(pStr)
|
||
char *pStr;
|
||
{
|
||
int nChar;
|
||
|
||
nChar = 0;
|
||
/* Character string terminates on blank, comma, or EOS */
|
||
while ( (*pStr != ' ') && (*pStr != ',') && (*pStr != 0) )
|
||
{
|
||
pStr++;
|
||
nChar++;
|
||
}
|
||
return nChar;
|
||
}
|
||
|
||
/* skipBlanks() - skip blank characters */
|
||
LOCAL char *skipBlanks(pChar)
|
||
char *pChar;
|
||
{
|
||
while (*pChar == ' ')
|
||
pChar++;
|
||
return pChar;
|
||
}
|
||
|
||
/*
|
||
* seqMacTblGet - find a match for the specified name, otherwise
|
||
* return an empty slot in macro table.
|
||
*/
|
||
LOCAL MACRO *seqMacTblGet(pMac, pName)
|
||
MACRO *pMac;
|
||
char *pName; /* macro name */
|
||
{
|
||
int i;
|
||
MACRO *pMacTbl;
|
||
|
||
#ifdef DEBUG
|
||
logMsg("seqMacTblGet: name=%s\n", pName);
|
||
taskDelay(30);
|
||
#endif
|
||
for (i = 0, pMacTbl = pMac; i < MAX_MACROS; i++, pMacTbl++)
|
||
{
|
||
if (pMacTbl->pName != NULL)
|
||
{
|
||
if (strcmp(pName, pMacTbl->pName) == 0)
|
||
{
|
||
return pMacTbl;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Not found, find an empty slot */
|
||
for (i = 0, pMacTbl = pMac; i < MAX_MACROS; i++, pMacTbl++)
|
||
{
|
||
if (pMacTbl->pName == NULL)
|
||
{
|
||
return pMacTbl;
|
||
}
|
||
}
|
||
|
||
/* No empty slots available */
|
||
return NULL;
|
||
}
|