289 lines
5.5 KiB
C
289 lines
5.5 KiB
C
/**************************************************************************
|
||
GTA PROJECT AT division
|
||
Copyright, 1990, The Regents of the University of California.
|
||
Los Alamos National Laboratory
|
||
|
||
@(#)seq_mac.c 1.1 11/9/90
|
||
DESCRIPTION: Macro routines for Sequencer.
|
||
|
||
ENVIRONMENT: VxWorks
|
||
***************************************************************************/
|
||
#include <stdio.h>
|
||
#include <ctype.h>
|
||
#include "vxWorks.h"
|
||
#include "seq.h"
|
||
|
||
LOCAL int macNameLth();
|
||
LOCAL int macParseName();
|
||
LOCAL int macParseValue();
|
||
LOCAL char *skipBlanks();
|
||
|
||
|
||
|
||
/* #define DEBUG */
|
||
|
||
/* macTblInit - initialize macro table */
|
||
macTblInit(mac_ptr)
|
||
MACRO *mac_ptr;
|
||
{
|
||
int i;
|
||
|
||
for (i = 0 ; i < MAX_MACROS; i++, mac_ptr++)
|
||
{
|
||
mac_ptr->name = NULL;
|
||
mac_ptr->value = NULL;
|
||
}
|
||
}
|
||
|
||
/* macEval - substitute macro value into a string */
|
||
macEval(pInStr, pOutStr, maxChar, macTbl)
|
||
char *pInStr;
|
||
char *pOutStr;
|
||
MACRO *macTbl;
|
||
{
|
||
char *pMacVal, *pTmp;
|
||
int nameLth, valLth;
|
||
|
||
#ifdef DEBUG
|
||
printf("macEval: InStr=%s\n", pInStr);
|
||
#endif
|
||
pTmp = pOutStr;
|
||
while (*pInStr != 0 && maxChar > 0)
|
||
{
|
||
if (*pInStr == '{')
|
||
{ /* Macro substitution */
|
||
pInStr++; /* points to macro name */
|
||
nameLth = macNameLth(pInStr);
|
||
#ifdef DEBUG
|
||
printf("Name=%s[%d]\n", pInStr, nameLth);
|
||
#endif
|
||
/* Find macro value from macro name */
|
||
pMacVal = macValGet(pInStr, nameLth, macTbl);
|
||
if (pMacVal != NULL)
|
||
{ /* Substitute macro value */
|
||
valLth = strlen(pMacVal);
|
||
if (valLth > maxChar)
|
||
valLth = maxChar;
|
||
#ifdef DEBUG
|
||
printf("Val=%s[%d]\n", pMacVal, valLth);
|
||
#endif
|
||
strncpy(pOutStr, pMacVal, valLth);
|
||
maxChar -= valLth;
|
||
pOutStr += valLth;
|
||
}
|
||
pInStr += nameLth;
|
||
if (*pInStr != 0)
|
||
pInStr++; /* skip '}' */
|
||
|
||
}
|
||
else
|
||
{ /* Straight susbstitution */
|
||
*pOutStr++ = *pInStr++;
|
||
maxChar--;
|
||
}
|
||
*pOutStr = 0;
|
||
#ifdef DEBUG
|
||
printf("OutStr=%s\n", pTmp);
|
||
#endif
|
||
}
|
||
*pOutStr == 0;
|
||
}
|
||
|
||
/* macValGet - given macro name, return pointer to its value */
|
||
char *macValGet(macName, macNameLth, macTbl)
|
||
char *macName;
|
||
int macNameLth;
|
||
MACRO *macTbl;
|
||
{
|
||
int i;
|
||
|
||
for (i = 0 ; i < MAX_MACROS; i++, macTbl++)
|
||
{
|
||
if ((macTbl->name != NULL) &&
|
||
(strlen(macTbl->name) == macNameLth))
|
||
{
|
||
if (strncmp(macName, macTbl->name, macNameLth) == 0)
|
||
{
|
||
return macTbl->value;
|
||
}
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
/* Return number of characters in a macro name */
|
||
LOCAL int macNameLth(pstr)
|
||
char *pstr;
|
||
{
|
||
int nchar;
|
||
|
||
nchar = 0;
|
||
while ( (*pstr != 0) && (*pstr != '}') )
|
||
{
|
||
pstr++;
|
||
nchar++;
|
||
}
|
||
return nchar;
|
||
}
|
||
/* macParse - 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.
|
||
*/
|
||
int macParse(pMacStr, macTbl)
|
||
char *pMacStr; /* macro definition string */
|
||
MACRO *macTbl; /* macro table */
|
||
{
|
||
int nMac, nChar;
|
||
char *skipBlanks();
|
||
MACRO *pMacTbl;
|
||
char *name, *value;
|
||
|
||
for ( ;; )
|
||
{
|
||
/* Skip blanks */
|
||
pMacStr = skipBlanks(pMacStr);
|
||
|
||
/* Parse the macro name */
|
||
|
||
nChar = macParseName(pMacStr);
|
||
if (nChar == 0)
|
||
break; /* finished or error */
|
||
name = seqAlloc(nChar+1);
|
||
if (name == NULL)
|
||
break;
|
||
bcopy(pMacStr, name, nChar);
|
||
name[nChar] = 0;
|
||
#ifdef DEBUG
|
||
printf("name=%s, nChar=%d\n", name, nChar);
|
||
#endif
|
||
pMacStr += nChar;
|
||
|
||
/* Find a slot in the table */
|
||
pMacTbl = macTblGet(name, macTbl);
|
||
if (pMacTbl == NULL)
|
||
break; /* table is full */
|
||
if (pMacTbl->name == NULL)
|
||
{ /* Empty slot, insert macro name */
|
||
pMacTbl->name = name;
|
||
}
|
||
|
||
/* 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 = macParseValue(pMacStr);
|
||
if (nChar == 0)
|
||
break;
|
||
value = seqAlloc(nChar+1);
|
||
if (value == NULL)
|
||
break;
|
||
bcopy(pMacStr, value, nChar);
|
||
value[nChar] = 0;
|
||
pMacStr += nChar;
|
||
#ifdef DEBUG
|
||
printf("value=%s, nChar=%d\n", value, nChar);
|
||
#endif
|
||
|
||
/* Insert or replace macro value */
|
||
pMacTbl->value = value;
|
||
|
||
/* Skip blanks and comma */
|
||
pMacStr = skipBlanks(pMacStr);
|
||
if (*pMacStr++ != ',')
|
||
break;
|
||
}
|
||
if (*pMacStr == 0)
|
||
return 0;
|
||
else
|
||
return -1;
|
||
}
|
||
|
||
|
||
LOCAL int macParseName(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;
|
||
}
|
||
|
||
LOCAL int macParseValue(pStr)
|
||
char *pStr;
|
||
{
|
||
int nChar;
|
||
|
||
nChar = 0;
|
||
/* Character string terminates on blank, comma, or EOS */
|
||
while ( (*pStr != ' ') && (*pStr != ',') && (*pStr != 0) )
|
||
{
|
||
pStr++;
|
||
nChar++;
|
||
}
|
||
return nChar;
|
||
}
|
||
|
||
LOCAL char *skipBlanks(pChar)
|
||
char *pChar;
|
||
{
|
||
while (*pChar == ' ')
|
||
pChar++;
|
||
return pChar;
|
||
}
|
||
|
||
/* macTblGet - find a match for the specified name, otherwise
|
||
return an empty slot in macro table */
|
||
LOCAL MACRO *macTblGet(name, macTbl)
|
||
char *name; /* macro name */
|
||
MACRO *macTbl;
|
||
{
|
||
int i;
|
||
MACRO *pMacTbl;
|
||
|
||
#ifdef DEBUG
|
||
printf("macTblGet: name=%s\n", name);
|
||
#endif
|
||
for (i = 0, pMacTbl = macTbl; i < MAX_MACROS; i++, pMacTbl++)
|
||
{
|
||
if (pMacTbl->name != NULL)
|
||
{
|
||
if (strcmp(name, pMacTbl->name) == 0)
|
||
{
|
||
return pMacTbl;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Not found, find an empty slot */
|
||
for (i = 0, pMacTbl = macTbl; i < MAX_MACROS; i++, pMacTbl++)
|
||
{
|
||
if (pMacTbl->name == NULL)
|
||
{
|
||
return pMacTbl;
|
||
}
|
||
}
|
||
|
||
/* No empty slots available */
|
||
return NULL;
|
||
}
|