many sequnecer changes from Andy Kozubal

This commit is contained in:
Jeff Hill
1996-08-13 15:39:22 +00:00
parent 070673fa89
commit 0b3df30c4f
17 changed files with 187 additions and 197 deletions
-1
View File
@@ -9,7 +9,6 @@ YACCOPT = -d -v
INC += seq.h
INC += seqCom.h
INC += seqU.h
SRCS.c = ../snc_main.c ../parse.c ../phase2.c ../gen_ss_code.c \
../gen_tables.c sncVersion.c snc.c
+1 -1
View File
@@ -1,3 +1,3 @@
1.9.1
1.9.2
+5 -5
View File
@@ -108,7 +108,7 @@ Expr *sp;
#ifdef DEBUG
fprintf(stderr, "eval_delay: type=%s\n", stype[ep->type]);
#endif DEBUG
#endif /*DEBUG*/
/* Generate 1-st part of function w/ 1-st 2 parameters */
delay_id = (int)ep->right; /* delay id was previously assigned */
@@ -323,7 +323,7 @@ int level; /* indentation level */
case E_VAR:
#ifdef DEBUG
fprintf(stderr, "E_VAR: %s\n", ep->value);
#endif DEBUG
#endif /*DEBUG*/
if(reent_opt)
{ /* Make variables point to allocated structure */
Var *vp;
@@ -350,7 +350,7 @@ int level; /* indentation level */
case E_FUNC:
#ifdef DEBUG
fprintf(stderr, "E_FUNC: %s\n", ep->value);
#endif DEBUG
#endif /*DEBUG*/
if (special_func(stmt_type, ep, sp))
break;
printf("%s(", ep->value);
@@ -470,7 +470,7 @@ Expr *sp; /* current State struct */
#ifdef DEBUG
fprintf(stderr, "special_func: func_code=%d\n", func_code);
#endif DEBUG
#endif /*DEBUG*/
switch (func_code)
{
case F_DELAY:
@@ -621,7 +621,7 @@ char *fname; /* function name */
{
#ifdef DEBUG
fprintf(stderr, "gen_pv_func: var=%s\n", ep1->value);
#endif DEBUG
#endif /*DEBUG*/
cp = vp->chan;
index = cp->index;
}
+12 -11
View File
@@ -14,6 +14,7 @@
01mar94,ajk Implemented assignment of array elements to db channels.
17may94,ajk removed old event flag (-e) option.
20jul95,ajk Added unsigned types.
22jul96,ajk Added castS to action, event, delay, and exit functions.
***************************************************************************/
/*#define DEBUG 1*/
@@ -76,7 +77,7 @@ gen_db_blocks()
#ifdef DEBUG
fprintf(stderr, "gen_db_blocks: index=%d, num_elem=%d\n",
cp->index, cp->num_elem);
#endif DEBUG
#endif /*DEBUG*/
if (cp->num_elem == 0)
{ /* Variable assigned to single pv */
@@ -254,11 +255,11 @@ char *ss_name;
printf("\t/* state name */ \"%s\",\n", sp->value);
printf("\t/* action function */ A_%s_%s,\n", ss_name, sp->value);
printf("\t/* action function */ (ACTION_FUNC) A_%s_%s,\n", ss_name, sp->value);
printf("\t/* event function */ E_%s_%s,\n", ss_name, sp->value);
printf("\t/* event function */ (EVENT_FUNC) E_%s_%s,\n", ss_name, sp->value);
printf("\t/* delay function */ D_%s_%s,\n", ss_name, sp->value);
printf("\t/* delay function */ (DELAY_FUNC) D_%s_%s,\n", ss_name, sp->value);
printf("\t/* event mask array */ EM_%s_%s,\n\n", ss_name, sp->value);
@@ -312,7 +313,7 @@ gen_prog_table()
printf("\t/* encoded options */ ");
encode_options();
printf("\t/* exit handler */ exit_handler,\n");
printf("\t/* exit handler */ (EXIT_FUNC) exit_handler,\n");
printf("};\n");
@@ -420,7 +421,7 @@ int numEventWords;
for (n = 0; n < numEventWords; n++)
fprintf(stderr, " 0x%x", pEventWords[n]);
fprintf(stderr, "\n");
#endif DEBUG
#endif /*DEBUG*/
}
/* Evaluate the event mask for a given transition (when() statement).
@@ -444,7 +445,7 @@ bitMask *pEventWords;
#ifdef DEBUG
fprintf(stderr, " eval_event_mask: %s, ef_num=%d\n",
vp->name, vp->ef_num);
#endif
#endif /*DEBUG*/
bitSet(pEventWords, vp->ef_num);
return;
}
@@ -456,7 +457,7 @@ bitMask *pEventWords;
#ifdef DEBUG
fprintf(stderr, " eval_event_mask: %s, db event bit=%d\n",
vp->name, cp->index + 1);
#endif
#endif /*DEBUG*/
bitSet(pEventWords, cp->index + num_events + 1);
}
@@ -495,7 +496,7 @@ bitMask *pEventWords;
#ifdef DEBUG
fprintf(stderr, " eval_event_mask_subscr: %s, db event bit=%d\n",
vp->name, cp->index);
#endif
#endif /*DEBUG*/
bitSet(pEventWords, cp->index + num_events + 1);
return;
}
@@ -512,7 +513,7 @@ bitMask *pEventWords;
#ifdef DEBUG
fprintf(stderr, " eval_event_mask_subscr: %s, db event bit=%d\n",
vp->name, cp->index + subscr + 1);
#endif
#endif /*DEBUG*/
bitSet(pEventWords, cp->index + subscr + num_events + 1);
return;
}
@@ -521,7 +522,7 @@ bitMask *pEventWords;
#ifdef DEBUG
fprintf(stderr, " eval_event_mask_subscr: %s, db event bits=%d..%d\n",
vp->name, cp->index + 1, cp->index + vp->length1);
#endif
#endif /*DEBUG*/
for (n = 0; n < vp->length1; n++)
{
bitSet(pEventWords, cp->index + n + num_events + 1);
+10 -10
View File
@@ -30,7 +30,7 @@
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif TRUE
#endif /*TRUE*/
int debug_print_opt = 0; /* Debug level (set by source file) */
@@ -187,7 +187,7 @@ char *db_name; /* ptr to db name */
#ifdef DEBUG
fprintf(stderr, "assign %s to \"%s\";\n", name, db_name);
#endif DEBUG
#endif /*DEBUG*/
/* Find the variable */
vp = (Var *)findVar(name);
if (vp == 0)
@@ -230,7 +230,7 @@ char *db_name; /* ptr to db name */
#ifdef DEBUG
fprintf(stderr, "assign %s[%s] to \"%s\";\n", name, subscript, db_name);
#endif DEBUG
#endif /*DEBUG*/
/* Find the variable */
vp = (Var *)findVar(name);
if (vp == 0)
@@ -303,7 +303,7 @@ Expr *db_name_list; /* ptr to db name list */
#ifdef DEBUG
fprintf(stderr, "assign %s to {", name);
#endif DEBUG
#endif /*DEBUG*/
/* Find the variable */
vp = (Var *)findVar(name);
if (vp == 0)
@@ -342,7 +342,7 @@ Expr *db_name_list; /* ptr to db name list */
#ifdef DEBUG
fprintf(stderr, "\"%s\", ", db_name_list->value);
#endif DEBUG
#endif /*DEBUG*/
cp->db_name_list[elem_num] = db_name_list->value; /* DB name */
cp->count = vp->length2;
@@ -350,7 +350,7 @@ Expr *db_name_list; /* ptr to db name list */
}
#ifdef DEBUG
fprintf(stderr, "};\n");
#endif DEBUG
#endif /*DEBUG*/
return;
}
@@ -418,7 +418,7 @@ char *subscript; /* element number or NULL */
#ifdef DEBUG
fprintf(stderr, "monitor_stmt: name=%s[%s]\n", name, subscript);
#endif DEBUG
#endif /*DEBUG*/
/* Find the variable */
vp = (Var *)findVar(name);
@@ -488,7 +488,7 @@ char *ef_name;
#ifdef DEBUG
fprintf(stderr, "sync_stmt: name=%s, subNum=%s, ef_name=%s\n",
name, subscript, ef_name);
#endif DEBUG
#endif /*DEBUG*/
vp = (Var *)findVar(name);
if (vp == 0)
@@ -625,7 +625,7 @@ Expr *prog_list;
ss_list = prog_list;
#ifdef DEBUG
fprintf(stderr, "----Phase2---\n");
#endif DEBUG
#endif /*DEBUG*/
phase2(ss_list);
exit(0);
@@ -701,7 +701,7 @@ Expr *ep2; /* beginning 2-nd (append it to 1-st) */
break;
}
fprintf(stderr, ")\n");
#endif DEBUG
#endif /*DEBUG*/
return ep1;
}
+2 -2
View File
@@ -144,7 +144,7 @@ reconcile_variables()
{
#ifdef DEBUG
fprintf(stderr, "reconcile_variables: ss=%s\n", ssp->value);
#endif DEBUG
#endif /*DEBUG*/
traverseExprTree(ssp, E_VAR, 0, connect_variable, 0);
}
@@ -444,7 +444,7 @@ assign_delay_ids()
#ifdef DEBUG
fprintf(stderr, "assign_delay_ids:\n");
#endif DEBUG
#endif /*DEBUG*/
for (ssp = ss_list; ssp != 0; ssp = ssp->next)
{
for (sp = ssp->left; sp != 0; sp = sp->next)
+15 -15
View File
@@ -1,4 +1,4 @@
/* base/include $Id$
/* /share/epicsH %W% %G%
*
* DESCRIPTION: Definitions for the run-time sequencer.
*
@@ -177,20 +177,20 @@ typedef struct state_program SPROG;
#define SPAWN_PRIORITY 100
/* Function declarations for internal sequencer funtions */
long seqConnect(SPROG *);
VOID seqEventHandler(struct event_handler_args);
VOID seqConnHandler(struct connection_handler_args);
long seqConnect (SPROG *);
VOID seqEventHandler (struct event_handler_args);
VOID seqConnHandler (struct connection_handler_args);
VOID seqCallbackHandler(struct event_handler_args);
VOID seqWakeup(SPROG *, long);
long seq(struct seqProgram *, char *, long);
VOID seqFree(SPROG *);
long sequencer(SPROG *, long, char *);
VOID ssEntry(SPROG *, SSCB *);
long sprogDelete(long);
long seqMacParse(char *, SPROG *);
char *seqMacValGet(MACRO *, char *);
VOID seqMacEval(char *, char *, long, MACRO *);
STATUS seq_log();
SPROG *seqFindProg(long);
VOID seqWakeup (SPROG *, long);
long seq (struct seqProgram *, char *, long);
VOID seqFree (SPROG *);
long sequencer (SPROG *, long, char *);
VOID ssEntry (SPROG *, SSCB *);
long sprogDelete (long);
long seqMacParse (char *, SPROG *);
char *seqMacValGet (MACRO *, char *);
VOID seqMacEval (char *, char *, long, MACRO *);
STATUS seq_log ();
SPROG *seqFindProg (long);
#endif /*INCLseqh*/
+13 -9
View File
@@ -1,4 +1,4 @@
/* * base/include $Id$
/* * base/include seqCom.h,v 1.3 1995/10/10 01:25:08 wright Exp
*
* DESCRIPTION: Common definitions for state programs and run-time sequencer.
*
@@ -21,15 +21,17 @@
* Los Alamos National Laboratory
* Modification Log:
* -----------------
* 09aug95,ajk added PVOIDFUNC type, added <stdio.h>, and fixed #endif.
* 11jul96,ajk Changed all int types to long.
* 22jul96,ajk Changed PFUNC to ACTION_FUNC, EVENT_FUNC, DELAY_FUNC, & EXIT_FUNC.
*
*/
#ifndef INCLseqComh
#define INCLseqComh
#define MAGIC 940501 /* current magic number for SPROG */
#include <stdio.h> /* standard i/o defs */
#include "tsDefs.h" /* time stamp defs */
#include "stdio.h" /* standard i/o defs */
/* Bit encoding for run-time options */
#define OPT_DEBUG (1<<0) /* turn on debugging */
@@ -53,11 +55,14 @@ typedef long bitMask;
#define FALSE 0
#endif /*TRUE*/
typedef long SS_ID; /* state set id */
/* Prototype for action, event, delay, and exit functions */
typedef long (*PFUNC)();
typedef void (*ACTION_FUNC)();
typedef long (*EVENT_FUNC)();
typedef void (*DELAY_FUNC)();
typedef void (*EXIT_FUNC)();
typedef long SS_ID; /* state set id */
typedef void (*EXIT_FUNC)();
#ifdef OFFSET
#undef OFFSET
@@ -123,8 +128,6 @@ struct seqProgram
* These functions appear in the module seq_if.c.
* The SNC must generate these modules--see gen_ss_code.c.
*/
/*#define ANSI*/
#ifdef ANSI
void seq_efSet(SS_ID, long); /* set an event flag */
long seq_efTest(SS_ID, long); /* test an event flag */
long seq_efClear(SS_ID, long); /* clear an event flag */
@@ -143,12 +146,13 @@ long seq_pvGetComplete(SS_ID, long); /* TRUE if last get completed */
long seq_pvChannelCount(SS_ID); /* returns number of channels */
long seq_pvConnectCount(SS_ID); /* returns number of channels connected */
long seq_pvAssignCount(SS_ID); /* returns number of channels assigned */
long seq_pvCount(SS_ID, long); /* returns number of elements in array */
long seq_pvCount(SS_ID, long); /* returns number of elements in array */
void seq_pvFlush(); /* flush put/get requests */
long seq_pvIndex(SS_ID, long); /* returns index of pv */
long seq_seqLog(); /* Logging: variable number of parameters */
void seq_delayInit(SS_ID, long, float);/* initialize a delay entry */
long seq_delay(SS_ID, long); /* test a delay entry */
char *seq_macValueGet(SS_ID, char *); /* Given macro name, return ptr to value */
#endif /*ANSI*/
long seq_optGet (SS_ID ssId, char *opt); /* check an option for TRUE/FALSE */
#endif /*INCLseqComh*/
-13
View File
@@ -1,13 +0,0 @@
/* $Id$ */
typedef long bitMask;
#define bitSet(word, bitnum) (word[bitnum/NBITS] |= (1<<(bitnum%NBITS)))
#define NBITS 32 /* # bits in bit mask word */
#define NWRDS 8 /* # words in bit fields */
#define MAGIC 920505 /* magic number for SPROG */
/* Bit encoding for run-time options */
#define OPT_DEBUG (1<<0)
#define OPT_ASYNC (1<<1)
#define OPT_CONN (1<<2)
#define OPT_REENT (1<<3)
#define OPT_NEWEF (1<<4)
#define MAX_NDELAY 20 /* max # delays allowed in each SS */
+10 -10
View File
@@ -49,6 +49,8 @@
#define ANSI
#include "seq.h"
#include "string.h"
#include "taskVarLib.h"
LOCAL VOID proc_db_events(union db_access_val *, CHAN *, long);
@@ -57,7 +59,7 @@ LOCAL VOID proc_db_events(union db_access_val *, CHAN *, long);
#ifdef DEBUG
#undef LOCAL
#define LOCAL
#endif DEBUG
#endif /*DEBUG*/
/*
* seq_connect() - Connect to all database channels through channel access.
*/
@@ -66,7 +68,6 @@ long seq_connect(SPROG *pSP)
CHAN *pDB;
int status, i;
extern VOID seq_conn_handler();
extern int seqInitialTaskId;
/*
* For each channel: connect to db & isssue monitor (if monFlag is TRUE).
@@ -80,7 +81,7 @@ long seq_connect(SPROG *pSP)
#ifdef DEBUG
logMsg("seq_connect: connect %s to %s\n",
pDB->pVarName, pDB->dbName);
#endif DEBUG
#endif /*DEBUG*/
/* Connect to it */
status = ca_build_and_connect(
pDB->dbName, /* DB channel name */
@@ -146,14 +147,13 @@ LOCAL VOID proc_db_events(union db_access_val *pAccess, CHAN *pDB, long complete
{
SPROG *pSP;
void *pVal;
int i;
#ifdef DEBUG
logMsg("proc_db_events: var=%s, pv=%s\n", pDB->VarName, pDB->dbName);
#endif DEBUG
#endif /*DEBUG*/
/* Copy value returned into user variable */
pVal = (void *)pAccess + pDB->dbOffset; /* ptr to data in CA structure */
pVal = (void *)((long)pAccess + pDB->dbOffset); /* ptr to data in CA structure */
bcopy(pVal, pDB->pVar, pDB->size * pDB->dbCount);
/* Copy status & severity */
@@ -238,8 +238,8 @@ long seq_disconnect(SPROG *pSP)
#ifdef DEBUG_DISCONNECT
logMsg("seq_disconnect: ca_import_cancel\n");
#endif /*DEBUG_DISCONNECT*/
SEVCHK(ca_import_cancel(taskIdSelf()),
"seq_disconnect: ca_import_cancel() failed?");
SEVCHK(ca_import_cancel(taskIdSelf()),
"seq_disconnect: ca_import_cancel() failed!");
}
return 0;
@@ -268,7 +268,7 @@ VOID seq_conn_handler(struct connection_handler_args args)
pDB->monitored = FALSE;
#ifdef DEBUG
logMsg("%s disconnected from %s\n", pDB->VarName, pDB->dbName);
#endif DEBUG
#endif /*DEBUG*/
}
else /* PV connected */
{
@@ -278,7 +278,7 @@ VOID seq_conn_handler(struct connection_handler_args args)
pDB->monitored = TRUE;
#ifdef DEBUG
logMsg("%s connected to %s\n", pDB->VarName, pDB->dbName);
#endif DEBUG
#endif /*DEBUG*/
pDB->dbCount = ca_element_count(args.chid);
if (pDB->dbCount > pDB->count)
pDB->dbCount = pDB->count;
+15 -23
View File
@@ -34,6 +34,8 @@
#define ANSI
#include "seq.h"
#include "tickLib.h"
#include "logLib.h"
/* See seqCom.h for function prototypes (ANSI standard) */
@@ -121,7 +123,7 @@ long seq_pvGet(SS_ID ssId, long pvId)
sem_status = semTake(pSS->getSemId, 600);
if (sem_status != OK)
{
logMsg ("semTake error=%d\n", sem_status);
logMsg ("semTake error=%d\n", sem_status, 0,0,0,0,0);
return ECA_TIMEOUT;
}
@@ -135,7 +137,6 @@ long seq_pvGetComplete(SS_ID ssId, long pvId)
{
SPROG *pSP; /* ptr to state program */
CHAN *pDB; /* ptr to channel struct */
int status;
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
@@ -155,8 +156,8 @@ long seq_pvPut(SS_ID ssId, long pvId)
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
#ifdef DEBUG
logMsg("seq_pvPut: pv name=%s, pVar=0x%x\n", pDB->dbName, pDB->pVar);
#endif DEBUG
logMsg("seq_pvPut: pv name=%s, pVar=0x%x\n", pDB->dbName, pDB->pVar, 0,0,0,0);
#endif /*DEBUG*/
if (!pDB->connected)
return ECA_DISCONN;
@@ -167,7 +168,7 @@ long seq_pvPut(SS_ID ssId, long pvId)
status = ca_array_put(pDB->putType, count, pDB->chid, pDB->pVar);
#ifdef DEBUG
logMsg("seq_pvPut: status=%d\n", status);
logMsg("seq_pvPut: status=%d\n", status, 0,0,0,0,0);
if (status != ECA_NORMAL)
{
seq_log(pSP, "pvPut on \"%s\" failed (%d)\n",
@@ -175,7 +176,7 @@ long seq_pvPut(SS_ID ssId, long pvId)
seq_log(pSP, " putType=%d\n", pDB->putType);
seq_log(pSP, " size=%d, count=%d\n", pDB->size, count);
}
#endif DEBUG
#endif /*DEBUG*/
return status;
}
@@ -195,7 +196,7 @@ long seq_pvAssign(SS_ID ssId, long pvId, char *pvName)
#ifdef DEBUG
printf("Assign %s to \"%s\"\n", pDB->pVarName, pvName);
#endif DEBUG
#endif /*DEBUG*/
if (pDB->assigned)
{ /* Disconnect this channel */
status = ca_clear_channel(pDB->chid);
@@ -261,7 +262,7 @@ long seq_pvMonitor(SS_ID ssId, long pvId)
#ifdef DEBUG
printf("monitor \"%s\"\n", pDB->dbName);
#endif DEBUG
#endif /*DEBUG*/
if (pDB->monitored || !pDB->assigned)
return ECA_NORMAL;
@@ -321,7 +322,6 @@ long seq_pvStopMonitor(SS_ID ssId, long pvId)
long seq_pvChannelCount(SS_ID ssId)
{
SPROG *pSP; /* ptr to state program */
int status;
pSP = ((SSCB *)ssId)->sprog;
return pSP->numChans;
@@ -333,7 +333,6 @@ long seq_pvChannelCount(SS_ID ssId)
long seq_pvConnectCount(SS_ID ssId)
{
SPROG *pSP; /* ptr to state program */
int status;
pSP = ((SSCB *)ssId)->sprog;
return pSP->connCount;
@@ -345,7 +344,6 @@ long seq_pvConnectCount(SS_ID ssId)
long seq_pvAssignCount(SS_ID ssId)
{
SPROG *pSP; /* ptr to state program */
int status;
pSP = ((SSCB *)ssId)->sprog;
return pSP->assignCount;
@@ -358,7 +356,6 @@ long seq_pvConnected(SS_ID ssId, long pvId)
{
SPROG *pSP; /* ptr to state program */
CHAN *pDB;
int status;
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
@@ -372,7 +369,6 @@ long seq_pvAssigned(SS_ID ssId, long pvId)
{
SPROG *pSP; /* ptr to state program */
CHAN *pDB;
int status;
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
@@ -387,7 +383,6 @@ long seq_pvCount(SS_ID ssId, long pvId)
{
SPROG *pSP; /* ptr to state program */
CHAN *pDB; /* ptr to channel struct */
int status;
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
@@ -401,7 +396,6 @@ long seq_pvStatus(SS_ID ssId, long pvId)
{
SPROG *pSP; /* ptr to state program */
CHAN *pDB; /* ptr to channel struct */
int status;
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
@@ -415,7 +409,6 @@ long seq_pvSeverity(SS_ID ssId, long pvId)
{
SPROG *pSP; /* ptr to state program */
CHAN *pDB; /* ptr to channel struct */
int status;
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
@@ -437,7 +430,6 @@ TS_STAMP seq_pvTimeStamp(SS_ID ssId, long pvId)
{
SPROG *pSP; /* ptr to state program */
CHAN *pDB; /* ptr to channel struct */
int status;
pSP = ((SSCB *)ssId)->sprog;
pDB = pSP->pChan + pvId;
@@ -451,15 +443,15 @@ VOID seq_efSet(SS_ID ssId, long ev_flag)
{
SPROG *pSP;
SSCB *pSS;
int nss;
pSS = (SSCB *)ssId;
pSP = pSS->sprog;
#ifdef DEBUG
logMsg("seq_efSet: pSP=0x%x, pSS=0x%x, ev_flag=0x%x\n", pSP, pSS, ev_flag);
logMsg("seq_efSet: pSP=0x%x, pSS=0x%x, ev_flag=0x%x\n", pSP, pSS, ev_flag,
0,0,0);
taskDelay(10);
#endif DEBUG
#endif /*DEBUG*/
/* Set this bit (apply resource lock) */
semTake(pSP->caSemId, WAIT_FOREVER);
@@ -487,8 +479,8 @@ long seq_efTest(SS_ID ssId, long ev_flag)
isSet = bitTest(pSP->pEvents, ev_flag);
#ifdef DEBUG
logMsg("seq_efTest: ev_flag=%d, event=0x%x, isSet=%d\n",
ev_flag, pSP->pEvents[0], isSet);
#endif DEBUG
ev_flag, pSP->pEvents[0], isSet, 0,0,0,0);
#endif /*DEBUG*/
return isSet;
}
@@ -568,7 +560,7 @@ VOID seq_delayInit(SS_ID ssId, long delayId, float delay)
* seq_optGet: return the value of an option (e.g. "a").
* FALSE means "-" and TRUE means "+".
*/
BOOL seq_optGet(SS_ID ssId, char *opt)
long seq_optGet(SS_ID ssId, char *opt)
{
SPROG *pSP;
+5 -4
View File
@@ -18,6 +18,7 @@
***************************************************************************/
#define ANSI
#include "seq.h"
#include "string.h"
LOCAL int seqMacParseName(char *);
LOCAL int seqMacParseValue(char *);
@@ -119,7 +120,7 @@ char *pName;
#ifdef DEBUG
logMsg("seqMacValGet: name=%s", pName);
#endif DEBUG
#endif /*DEBUG*/
for (i = 0 ; i < MAX_MACROS; i++, pMac++)
{
if (pMac->pName != NULL)
@@ -128,14 +129,14 @@ char *pName;
{
#ifdef DEBUG
logMsg(", value=%s\n", pMac->pValue);
#endif DEBUG
#endif /*DEBUG*/
return pMac->pValue;
}
}
}
#ifdef DEBUG
logMsg(", no value\n");
#endif DEBUG
#endif /*DEBUG*/
return NULL;
}
/*
@@ -148,7 +149,7 @@ long seqMacParse(pMacStr, pSP)
char *pMacStr; /* macro definition string */
SPROG *pSP;
{
int nMac, nChar;
int nChar;
char *skipBlanks();
MACRO *pMac; /* macro table */
MACRO *pMacTbl; /* macro tbl entry */
+46 -58
View File
@@ -46,21 +46,27 @@
parameters.
19jul95,ajk Added unsigned types (unsigned char, short, int, long).
20jul95,ajk Added priority specification at run time.
03aug95,ajk Fix problem with +r option: user variable space (pSP->pVar)
03aug95,ajk Fixed problem with +r option: user variable space (pSP->pVar)
was not being allocated.
03jun96,ajk Now compiles with -wall and -pedantic switches.
***************************************************************************/
/*#define DEBUG 1*/
#include "seqCom.h"
#include "seq.h"
#include "taskLib.h"
#include "taskHookLib.h"
#include "logLib.h"
#include "errnoLib.h"
#include "usrLib.h"
#ifdef DEBUG
#undef LOCAL
#define LOCAL
#endif DEBUG
#endif /*DEBUG*/
/* ANSI functional prototypes for local routines */
LOCAL SPROG *seqInitTables(struct seqProgram *);
LOCAL SPROG *alloc_task_area(struct seqProgram *);
LOCAL VOID init_sprog(struct seqProgram *, SPROG *);
LOCAL VOID init_sscb(struct seqProgram *, SPROG *);
LOCAL VOID init_chan(struct seqProgram *, SPROG *);
@@ -68,8 +74,6 @@ LOCAL VOID init_mac(SPROG *);
LOCAL VOID seq_logInit(SPROG *);
LOCAL VOID seqChanNameEval(SPROG *);
LOCAL int countStates(struct seqProgram *);
LOCAL int roundUp(int);
LOCAL VOID selectDBtype(char *, short *, short *, short *, short *);
#define SCRATCH_SIZE (MAX_MACROS*(MAX_STRING_SIZE+1)*12)
@@ -90,13 +94,12 @@ int seqAuxTaskId = 0;
* Creates the initial state program task and returns its task id.
* Most initialization is performed here.
*/
long seq(pSeqProg, macro_def, stack_size)
long seq (pSeqProg, macro_def, stack_size)
struct seqProgram *pSeqProg; /* state program info generated by snc */
char *macro_def; /* optional macro def'n string */
long stack_size; /* optional stack size (bytes) */
{
int tid;
extern long sequencer();/* Sequencer task entry point */
extern sprog_delete(); /* Task delete routine */
extern char *seqVersion;
SPROG *pSP;
@@ -114,8 +117,8 @@ long stack_size; /* optional stack size (bytes) */
while (seqAuxTaskId == 0)
taskDelay(5); /* wait for task to init. ch'l access */
#ifdef DEBUG
logMsg("task seqAux spawned, tid=0x%x\n", seqAuxTaskId);
#endif DEBUG
logMsg("task seqAux spawned, tid=0x%x\n", seqAuxTaskId, 0,0,0,0,0);
#endif /*DEBUG*/
}
/* Specify a routine to run at task delete */
@@ -134,9 +137,9 @@ long stack_size; /* optional stack size (bytes) */
/* Check for correct state program format */
if (pSeqProg->magic != MAGIC)
{ /* Oops */
logMsg("Illegal magic number in state program.\n");
logMsg(" - Possible mismatch between SNC & SEQ versions\n");
logMsg(" - Re-compile your program?\n");
logMsg("Illegal magic number in state program.\n", 0,0,0,0,0,0);
logMsg(" - Possible mismatch between SNC & SEQ versions\n", 0,0,0,0,0,0);
logMsg(" - Re-compile your program?\n", 0,0,0,0,0,0);
return -1;
}
@@ -175,8 +178,8 @@ long stack_size; /* optional stack size (bytes) */
/* Spawn the initial sequencer task */
#ifdef DEBUG
logMsg("Spawing task %s, stack_size=%d\n", ptask_name, stack_size);
#endif
logMsg("Spawning task %s, stack_size=%d\n", ptask_name, stack_size, 0,0,0,0);
#endif /*DEBUG*/
/* Specify task priority */
pSP->taskPriority = SPAWN_PRIORITY;
pValue = seqMacValGet(pSP->pMacros, "priority");
@@ -223,18 +226,6 @@ struct seqProgram *pSeqProg;
return pSP;
}
/* Count the total number of states in a state program */
LOCAL int countStates(pSeqProg)
struct seqProgram *pSeqProg;
{
struct seqSS *pSeqSS;
int nstates, nss;
nstates = 0;
for (nss = 0, pSeqSS = pSeqProg->pSS; nss < pSeqProg->numSS; nss++, pSeqSS++)
nstates += pSeqSS->numStates;
}
/*
* Copy data from seqCom.h structures into this task's dynamic structures as defined
* in seq.h.
@@ -243,10 +234,6 @@ LOCAL VOID init_sprog(pSeqProg, pSP)
struct seqProgram *pSeqProg;
SPROG *pSP;
{
SSCB *pSS;
STATE *pState;
CHAN *pDB;
char *pVar;
int i, nWords;
/* Copy information for state program */
@@ -255,7 +242,7 @@ SPROG *pSP;
pSP->numEvents = pSeqProg->numEvents;
pSP->options = pSeqProg->options;
pSP->pProgName = pSeqProg->pProgName;
pSP->exitFunc = pSeqProg->exitFunc;
pSP->exitFunc = (EXIT_FUNC)pSeqProg->exitFunc;
pSP->varSize = pSeqProg->varSize;
/* Allocate user variable area if reentrant option (+r) is set */
if ((pSP->options & OPT_REENT) != 0)
@@ -264,13 +251,13 @@ SPROG *pSP;
#ifdef DEBUG
logMsg("init_sprog: num SS=%d, num Chans=%d, num Events=%d, Prog Name=%s, var Size=%d\n",
pSP->numSS, pSP->numChans, pSP->numEvents, pSP->pProgName, pSP->varSize);
#endif DEBUG
#endif /*DEBUG*/
/* Create a semaphore for resource locking on CA events */
pSP->caSemId = semBCreate(SEM_Q_FIFO, SEM_FULL);
if (pSP->caSemId == NULL)
{
logMsg("can't create caSemId\n");
logMsg("can't create caSemId\n", 0,0,0,0,0,0);
return;
}
@@ -298,7 +285,7 @@ SPROG *pSP;
{
SSCB *pSS;
STATE *pState;
int nss, i, nstates;
int nss, nstates;
struct seqSS *pSeqSS;
struct seqState *pSeqState;
@@ -321,13 +308,13 @@ SPROG *pSP;
pSS->sprog = pSP;
#ifdef DEBUG
logMsg("init_sscb: SS Name=%s, num States=%d, pSS=0x%x\n",
pSS->pSSName, pSS->numStates, pSS);
#endif DEBUG
pSS->pSSName, pSS->numStates, pSS, 0,0,0);
#endif /*DEBUG*/
/* Create a binary semaphore for synchronizing events in a SS */
pSS->syncSemId = semBCreate(SEM_Q_FIFO, SEM_FULL);
if (pSS->syncSemId == NULL)
{
logMsg("can't create syncSemId\n");
logMsg("can't create syncSemId\n", 0,0,0,0,0,0);
return;
}
@@ -338,7 +325,7 @@ SPROG *pSP;
semBCreate(SEM_Q_FIFO, SEM_FULL);
if (pSS->getSemId == NULL)
{
logMsg("can't create getSemId\n");
logMsg("can't create getSemId\n", 0,0,0,0,0,0);
return;
}
@@ -352,20 +339,20 @@ SPROG *pSP;
nstates++, pState++, pSeqState++)
{
pState->pStateName = pSeqState->pStateName;
pState->actionFunc = pSeqState->actionFunc;
pState->eventFunc = pSeqState->eventFunc;
pState->delayFunc = pSeqState->delayFunc;
pState->actionFunc = (ACTION_FUNC)pSeqState->actionFunc;
pState->eventFunc = (EVENT_FUNC)pSeqState->eventFunc;
pState->delayFunc = (DELAY_FUNC)pSeqState->delayFunc;
pState->pEventMask = pSeqState->pEventMask;
#ifdef DEBUG
logMsg("init_sscb: State Name=%s, Event Mask=0x%x\n",
pState->pStateName, *pState->pEventMask);
#endif DEBUG
pState->pStateName, *pState->pEventMask, 0,0,0,0);
#endif /*DEBUG*/
}
}
#ifdef DEBUG
logMsg("init_sscb: numSS=%d\n", pSP->numSS);
#endif DEBUG
logMsg("init_sscb: numSS=%d\n", pSP->numSS, 0,0,0,0,0);
#endif /*DEBUG*/
return;
}
@@ -388,8 +375,8 @@ SPROG *pSP;
for (nchan = 0; nchan < pSP->numChans; nchan++, pDB++, pSeqChan++)
{
#ifdef DEBUG
logMsg("init_chan: pDB=0x%x\n", pDB);
#endif DEBUG
logMsg("init_chan: pDB=0x%x\n", pDB, 0,0,0,0,0);
#endif /*DEBUG*/
pDB->sprog = pSP;
pDB->dbAsName = pSeqChan->dbAsName;
pDB->pVarName = pSeqChan->pVarName;
@@ -410,11 +397,11 @@ SPROG *pSP;
pDB->pVar += (int)pSP->pVar;
#ifdef DEBUG
logMsg(" Assigned Name=%s, VarName=%s, VarType=%s, count=%d\n",
pDB->dbAsName, pDB->pVarName, pDB->pVarType, pDB->count);
logMsg(" size=%d, dbOffset=%d\n", pDB->size, pDB->dbOffset);
pDB->dbAsName, pDB->pVarName, pDB->pVarType, pDB->count, 0,0);
logMsg(" size=%d, dbOffset=%d\n", pDB->size, pDB->dbOffset, 0,0,0,0);
logMsg(" efId=%d, monFlag=%d, eventNum=%d\n",
pDB->efId, pDB->monFlag, pDB->eventNum);
#endif DEBUG
pDB->efId, pDB->monFlag, pDB->eventNum, 0,0,0);
#endif /*DEBUG*/
}
}
@@ -429,8 +416,8 @@ SPROG *pSP;
pSP->pMacros = pMac = (MACRO *)calloc(MAX_MACROS, sizeof (MACRO));
#ifdef DEBUG
logMsg("init_mac: pMac=0x%x\n", pMac);
#endif
logMsg("init_mac: pMac=0x%x\n", pMac, 0,0,0,0,0);
#endif /*DEBUG*/
for (i = 0 ; i < MAX_MACROS; i++, pMac++)
{
@@ -455,8 +442,8 @@ SPROG *pSP;
seqMacEval(pDB->dbAsName, pDB->dbName, MACRO_STR_LEN, pSP->pMacros);
#ifdef DEBUG
logMsg("seqChanNameEval: \"%s\" evaluated to \"%s\"\n",
pDB->dbAsName, pDB->dbName);
#endif DEBUG
pDB->dbAsName, pDB->dbName, 0,0,0,0);
#endif /*DEBUG*/
}
}
/*
@@ -546,7 +533,7 @@ SPROG *pSP;
pSP->logSemId = semBCreate(SEM_Q_FIFO, SEM_FULL);
if (pSP->logSemId == NULL)
{
logMsg("can't create logSemId\n");
logMsg("can't create logSemId\n", 0,0,0,0,0,0);
return;
}
pSP->logFd = ioGlobalStdGet(1); /* default fd is std out */
@@ -611,7 +598,8 @@ int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; /* arguments */
semGive(pSP->logSemId);
if (status != count)
{
logMsg("Log file error, fd=%d, error no.=%d\n", fd, errnoGet());
logMsg("Log file error, fd=%d, error no.=%d\n", fd, errnoGet(),
0,0,0,0);
printErrno(errnoGet());
return ERROR;
}
@@ -627,7 +615,7 @@ int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; /* arguments */
* seq_seqLog() - State program interface to seq_log().
* Does not require ptr to state program block.
*/
STATUS seq_seqLog(ssId, fmt, arg1,arg2, arg3, arg4, arg5, arg6, arg7, arg8)
long seq_seqLog(ssId, fmt, arg1,arg2, arg3, arg4, arg5, arg6, arg7, arg8)
SS_ID ssId;
char *fmt; /* format string */
int arg1,arg2, arg3, arg4, arg5, arg6, arg7, arg8; /* arguments */
+16 -11
View File
@@ -27,13 +27,18 @@
/*#define DEBUG 1*/
#include "seq.h"
#include "usrLib.h"
#include "tickLib.h"
#include "string.h"
/* User functions */
int seqShow(int);
int seqChanShow(int, char *);
LOCAL int wait_rtn();
LOCAL VOID printValue(char *, int, int);
LOCAL SPROG *seqQryFind(int);
LOCAL seqShowAll();
LOCAL void seqShowAll();
/*
* seqShow() - Querry the sequencer for state information.
@@ -46,8 +51,7 @@ int tid;
SPROG *pSP;
SSCB *pSS;
STATE *pST;
CHAN *pDB;
int nss, nst, nch, status, n;
int nss, status;
float time;
char file_name[100];
@@ -76,7 +80,7 @@ int tid;
((pSP->options & OPT_CONN) != 0) );
if ((pSP->options & OPT_REENT) != 0)
printf(" user variables: address=%d=0x%x, length=%d=0x%x bytes\n",
pSP->pVar, pSP->pVar, pSP->varSize, pSP->varSize);
(long)pSP->pVar, (long)pSP->pVar, pSP->varSize, pSP->varSize);
printf(" log file fd=%d\n", pSP->logFd);
status = ioctl(pSP->logFd, FIOGETNAME, (int)file_name);
if (status != ERROR)
@@ -114,7 +118,7 @@ int tid;
printf(" - expired");
printf("\n");
}
#endif DEBUG
#endif /*DEBUG*/
printf("\n");
}
@@ -130,7 +134,6 @@ char *pStr; /* optional pattern matching string */
SPROG *pSP;
CHAN *pDB;
int nch, n;
float time;
char tsBfr[50], connQual;
int match, showAll;
@@ -186,7 +189,7 @@ char *pStr; /* optional pattern matching string */
printf("Channel name: \"%s\"\n", pDB->dbName);
printf(" Unexpanded (assigned) name: \"%s\"\n", pDB->dbAsName);
printf(" Variable name: \"%s\"\n", pDB->pVarName);
printf(" address = %d = 0x%x\n", pDB->pVar, pDB->pVar);
printf(" address = %d = 0x%x\n", (long)pDB->pVar, (long)pDB->pVar);
printf(" type = %s\n", pDB->pVarType);
printf(" count = %d\n", pDB->count);
printValue(pDB->pVar, pDB->putType, pDB->count);
@@ -355,7 +358,7 @@ int tid;
LOCAL int seqProgCount;
/* This routine is called by seqTraverseProg() for seqShowAll() */
LOCAL seqShowSP(pSP)
LOCAL void seqShowSP(pSP)
SPROG *pSP;
{
SSCB *pSS;
@@ -379,14 +382,16 @@ SPROG *pSP;
printf("\n");
}
/* The seqTraverseProg function is in seq_prog.c */
STATUS seqTraverseProg(VOID (*pFunc)(), VOID *param);
/* Print a brief summary of all state programs */
LOCAL seqShowAll()
LOCAL void seqShowAll()
{
SPROG *pSP;
seqProgCount = 0;
seqTraverseProg(seqShowSP, 0);
if (seqProgCount == 0)
printf("No active state programs\n");
return 0;
return;
}
+27 -23
View File
@@ -32,28 +32,36 @@
#define ANSI
#include "seqCom.h"
#include "seq.h"
#include <taskwd.h>
#include "taskwd.h"
#include "logLib.h"
#include "tickLib.h"
#include "taskVarLib.h"
/* Function declarations */
LOCAL VOID seq_waitConnect(SPROG *pSP, SSCB *pSS);
LOCAL VOID ss_task_init(SPROG *, SSCB *);
LOCAL VOID seq_clearDelay(SSCB *);
LOCAL long seq_getTimeout(SSCB *);
LOCAL long seq_cleanup(int tid, SPROG *pSP, SEM_ID cleanupSem);
#define TASK_NAME_SIZE 10
#define MAX_DELAY (10000000) /* max delay time pending for events */
/*
STATUS seqAddProg(SPROG *pSP);
long seq_connect(SPROG *pSP);
long seq_disconnect(SPROG *pSP);
/*
* sequencer() - Sequencer main task entry point.
*/
long sequencer(pSP, stack_size, pTaskName)
long sequencer (pSP, stack_size, pTaskName)
SPROG *pSP; /* ptr to original (global) state program table */
long stack_size; /* stack size */
char *pTaskName; /* Parent task name */
{
SSCB *pSS;
STATE *pST;
int nss, task_id, i;
int nss, task_id;
char task_name[TASK_NAME_SIZE+10];
extern VOID ss_entry();
extern int seqAuxTaskId;
@@ -95,6 +103,8 @@ char *pTaskName; /* Parent task name */
/* First state set jumps directly to entry point */
ss_entry(pSP, pSP->pSS);
return 0;
}
/*
* ss_entry() - Task entry point for all state sets.
@@ -108,7 +118,6 @@ SSCB *pSS;
STATE *pST, *pStNext;
long delay;
char *pVar;
LOCAL VOID seq_waitConnect();
int nWords;
SS_ID ssId;
@@ -220,9 +229,7 @@ SSCB *pSS;
}
/* Wait for all channels to connect */
LOCAL VOID seq_waitConnect(pSP, pSS)
SPROG *pSP;
SSCB *pSS;
LOCAL VOID seq_waitConnect(SPROG *pSP, SSCB *pSS)
{
STATUS status;
long delay;
@@ -234,7 +241,7 @@ SSCB *pSS;
if ((status != OK) && (pSP-> taskId == pSS->taskId))
{
logMsg("%d of %d assigned channels have connected\n",
pSP->connCount, pSP->assignCount);
pSP->connCount, pSP->assignCount, 0,0,0,0);
}
if (delay < 2400)
delay = delay + 600;
@@ -318,11 +325,10 @@ SSCB *pSS;
* when executed in the context of ExcTask. ExcTask is not spawned with
* floating point option, and fp is required to do the cleanup.
*/
sprog_delete(tid)
long sprog_delete(tid)
int tid; /* task being deleted */
{
SPROG *pSP;
extern int seq_cleanup();
SEM_ID cleanupSem;
int status;
@@ -334,8 +340,8 @@ int tid; /* task being deleted */
cleanupSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
/* Spawn the cleanup task */
taskSpawn("tSeqCleanup", SPAWN_PRIORITY-1, VX_FP_TASK, 8000, seq_cleanup,
tid, (int)pSP, (int)cleanupSem, 0,0,0,0,0,0,0);
taskSpawn("tSeqCleanup", SPAWN_PRIORITY-1, VX_FP_TASK, 8000,
(FUNCPTR)seq_cleanup, tid, (int)pSP, (int)cleanupSem, 0,0,0,0,0,0,0);
/* Wait for cleanup task completion */
for (;;)
@@ -343,7 +349,7 @@ int tid; /* task being deleted */
status = semTake(cleanupSem, 600);
if (status == OK)
break;
logMsg("sprog_delete waiting for seq_cleanup\n");
logMsg("sprog_delete waiting for seq_cleanup\n", 0,0,0,0,0,0);
}
semDelete(cleanupSem);
@@ -352,17 +358,15 @@ int tid; /* task being deleted */
/* Cleanup task */
/*#define DEBUG_CLEANUP*/
STATUS seqDelProg(SPROG *pSP);
seq_cleanup(tid, pSP, cleanupSem)
int tid; /* tid of 1-st SS to be deleted */
SPROG *pSP;
SEM_ID cleanupSem; /* indicate cleanup is finished */
LOCAL long seq_cleanup(int tid, SPROG *pSP, SEM_ID cleanupSem)
{
int nss;
SSCB *pSS;
#ifdef DEBUG_CLEANUP
logMsg("Delete %s: pSP=%d=0x%x, tid=%d\n", pSP->pProgName, pSP, pSP, tid);
logMsg("Delete %s: pSP=%d=0x%x, tid=%d\n", pSP->pProgName, pSP, pSP, tid, 0,0);
#endif /*DEBUG_CLEANUP*/
/* Wait for log semaphore (in case a task is doing a write) */
@@ -415,8 +419,8 @@ SEM_ID cleanupSem; /* indicate cleanup is finished */
#ifdef DEBUG_CLEANUP
logMsg(" ca_import_cancel(0x%x)\n", pSS->taskId);
#endif /*DEBUG_CLEANUP*/
SEVCHK(ca_import_cancel(pSS->taskId),
"CA import cancel failed!");
SEVCHK (ca_import_cancel(pSS->taskId),
"seq_cleanup:ca_import_cancel() failed")
}
/* Close the log file */
@@ -511,7 +515,7 @@ SPROG *pSP;
/*
* Sequencer auxillary task -- loops on ca_pend_event().
*/
seqAuxTask()
long seqAuxTask()
{
extern int seqAuxTaskId;
+3
View File
@@ -13,6 +13,7 @@
qualifications to some "expr" definitions.
31may94,ajk Changed method for handling global C code.
20jul95,ajk Added "unsigned" types (see UNSIGNED token).
11jul96,ajk Added character constants (CHAR_CONST).
***************************************************************************/
/* SNC - State Notation Compiler.
* The general structure of a state program is:
@@ -57,6 +58,7 @@ extern int line_num; /* input file line no. */
}
%token <pchar> STATE STATE_SET
%token <pchar> NUMBER NAME
%token <pchar> CHAR_CONST
%token <pchar> DEBUG_PRINT
%token PROGRAM EXIT OPTION
%token R_SQ_BRACKET L_SQ_BRACKET
@@ -253,6 +255,7 @@ expr /* general expr: e.g. (-b+2*a/(c+d)) != 0 || (func1(x,y) < 5.0) */
| expr AUTO_INCR %prec UOP { $$ = expression(E_POST, "++", $1, 0); }
| expr AUTO_DECR %prec UOP { $$ = expression(E_POST, "--", $1, 0); }
| NUMBER { $$ = expression(E_CONST, $1, 0, 0); }
| CHAR_CONST { $$ = expression(E_CONST, $1, 0, 0); }
| STRING { $$ = expression(E_STRING, $1, 0, 0); }
| NAME { $$ = expression(E_VAR, $1, 0, 0); }
| NAME L_PAREN expr R_PAREN { $$ = expression(E_FUNC, $1, $3, 0); }
+7 -1
View File
@@ -20,7 +20,8 @@
31may94,ajk Changed handling of escaped C code.
17feb95,ajk Removed includes "parse.h" & "snc.h", because this module
now gets included in snc.y.
20jul95,ajk Added unsigned types.
20jul95,ajk Added unsigned types.
11jul96,ajk Added character constants
***************************************************************************/
/* Lexical analyzer for State Notation Compiler (snc).
*
@@ -61,6 +62,7 @@ NAME [a-zA-Z][a-zA-Z0-9_]*
FPNUM (([0-9]+)(\.[0-9]*)?)|(\.[0-9]+)
OCTAL 0[0-7]+
HEX 0x([0-9a-fA-F])+
CCONST \'.\'
%% /* Begin rules */
<C_CODE>. *pStr++ = yytext[0];
@@ -230,6 +232,10 @@ HEX 0x([0-9a-fA-F])+
yylval.pchar = strdup(yytext);
RETURN(NUMBER);
}
<SNL>{CCONST} {
yylval.pchar = strdup(yytext);
RETURN(CHAR_CONST);
}
<SNL>[\t\ ]* /* no action */ ;
<SNL>. RETURN(BAD_CHAR);
# { /* somehow "^#" doesn't work if it's first char */