installed latest gtac version of sequencer

This commit is contained in:
Bob Zieman
1991-06-07 18:31:41 +00:00
parent 77b7843a03
commit 1f980e64f5
14 changed files with 2048 additions and 1635 deletions

View File

@@ -1 +1 @@
1.6.4
1.7.3

View File

@@ -3,12 +3,13 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)gen_ss_code.c 1.3 1/16/91
@(#)gen_ss_code.c 1.4 4/17/91
DESCRIPTION: gen_ss_code.c -- routines to generate state set code
ENVIRONMENT: UNIX
***************************************************************************/
#include <stdio.h>
#include "parse.h"
#include "cadef.h"
#include "seq.h"
/*+************************************************************************
@@ -28,19 +29,23 @@
#define EVENT_STMT 1
#define ACTION_STMT 2
#define DELAY_STMT 3
#define EXIT_STMT 4
gen_ss_code()
{
extern LIST ss_list;
StateSet *ssp;
State *sp;
extern Expr *ss_list;
Expr *ssp;
Expr *sp;
/* For each state set ... */
for (ssp = firstSS(&ss_list); ssp != NULL; ssp = nextSS(ssp))
for (ssp = ss_list; ssp != NULL; ssp = ssp->next)
{
/* For each state ... */
for (sp = firstState(&ssp->S_list); sp != NULL; sp = nextState(sp))
for (sp = ssp->left; sp != NULL; sp = sp->next)
{
printf("\f/* Code for state \"%s\" in state set \"%s\" */\n",
sp->value, ssp->value);
/* Generate delay processing function */
gen_delay_func(sp, ssp);
@@ -51,6 +56,9 @@ gen_ss_code()
gen_action_func(sp, ssp);
}
}
/* Generate exit handler code */
gen_exit_handler();
}
@@ -59,44 +67,35 @@ gen_ss_code()
state set name and the state name.
*/
gen_action_func(sp, ssp)
State *sp;
StateSet *ssp; /* Parent state set */
Expr *sp;
Expr *ssp; /* Parent state set */
{
Trans *tp;
Action *ap;
int trans_num;
extern char *prog_name;
Expr *tp;
Expr *ap;
int trans_num;
extern char *prog_name;
printf("\n/* Action function for state \"%s\" in state set \"%s\" */\n",
sp->state_name, ssp->ss_name);
sp->value, ssp->value);
/* action function declaration with ss_ptr as parameter */
printf("static a_%s_%s(sprog, ss_ptr)\nSPROG *sprog;\nSSCB\t*ss_ptr;\n{\n",
ssp->ss_name, sp->state_name);
/* "switch" stmt based on the transition number */
printf("static A_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("SPROG\t*sprog;\n");
printf("SSCB\t*ss_ptr;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
/* "switch" statment based on the transition number */
printf("\tswitch(ss_ptr->trans_num)\n\t{\n");
trans_num = 0;
/* For each transition (when statement) ... */
for (tp = firstTrans(&sp->T_list); tp != NULL; tp = nextTrans(tp))
/* For each transition ("when" statement) ... */
for (tp = sp->left; tp != NULL; tp = tp->next)
{
/* "case" for each transition */
printf("\tcase %d:\n", trans_num);
/* For each action statement insert action code */
for (ap = firstAction(&tp->A_list); ap != NULL;
ap = nextAction(ap))
for (ap = tp->right; ap != NULL; ap = ap->next)
{
print_line_num(ap->line_num);
switch (ap->type)
{
case A_STMT:
printf("\t\t");
/* Evaluate statements */
eval_expr(ACTION_STMT, ap->stmt.expr, sp);
printf(";\n");
break;
case A_CCODE:
printf("%s\n", ap->stmt.c_code);
break;
}
print_line_num(ap->line_num, ap->src_file);
/* Evaluate statements */
eval_expr(ACTION_STMT, ap, sp, 2);
}
/* end of case */
printf("\t\treturn;\n");
@@ -111,39 +110,39 @@ StateSet *ssp; /* Parent state set */
/* Generate a C function that checks events for a particular state */
gen_event_func(sp, ssp)
State *sp;
StateSet *ssp;
Expr *sp;
Expr *ssp;
{
Trans *tp;
int index, trans_num;
Expr *tp;
int index, trans_num;
printf("\n/* Event function for state \"%s\" in state set \"%s\" */\n",
sp->state_name, ssp->ss_name);
printf("static e_%s_%s(sprog, ss_ptr)\n", ssp->ss_name, sp->state_name);
sp->value, ssp->value);
printf("static E_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("SPROG\t*sprog;\n");
printf("SSCB\t*ss_ptr;\n{\n");
printf("SSCB\t*ss_ptr;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
trans_num = 0;
sp->ndelay = 0;
/* For each transition generate an "if" statement ... */
for (tp = firstTrans(&sp->T_list); tp != NULL; tp = nextTrans(tp))
for (tp = sp->left; tp != NULL; tp = tp->next)
{
print_line_num(tp->line_num);
print_line_num(tp->line_num, tp->src_file);
printf("\tif (");
eval_expr(EVENT_STMT, tp->event_expr, sp);
eval_expr(EVENT_STMT, tp->left, sp, 0);
/* an event triggered, set next state */
printf(")\n\t{\n");
/* index is the transition number (0, 1, ...) */
index = state_block_index_from_name(ssp, tp->new_state_name);
index = state_block_index_from_name(ssp, tp->value);
if (index < 0)
{
fprintf(stderr, "Line %d: ", tp->line_num);
fprintf(stderr, "No state %s in state set %s\n",
tp->new_state_name, ssp->ss_name);
tp->value, ssp->value);
index = 0; /* default to 1-st state */
printf("\t\t/* state %s does not exist */\n",
tp->new_state_name);
tp->value);
}
printf("\t\tss_ptr->next_state = ss_ptr->states + %d;\n", index);
printf("\t\tss_ptr->next_state = %d;\n", index);
printf("\t\tss_ptr->trans_num = %d;\n", trans_num);
printf("\t\treturn TRUE;\n\t}\n");
trans_num++;
@@ -152,89 +151,162 @@ StateSet *ssp;
printf("}\n");
}
/* Generate delay processing function for a state */
gen_delay_func(sp, ssp)
State *sp;
StateSet *ssp;
/* Given a state name and state set struct, find the corresponding
state struct and return its index (1-st one is 0) */
state_block_index_from_name(ssp, state_name)
Expr *ssp;
char *state_name;
{
Trans *tp;
Expr *sp;
int index;
printf("\n/* Delay function for state \"%s\" in state set \"%s\" */\n",
sp->state_name, ssp->ss_name);
printf("static d_%s_%s(sprog, ss_ptr)\n", ssp->ss_name, sp->state_name);
printf("SPROG\t*sprog;\n");
printf("SSCB\t*ss_ptr;\n{\n");
sp->ndelay = 0;
/* For each transition ... */
for (tp = firstTrans(&sp->T_list); tp != NULL; tp = nextTrans(tp))
index = 0;
for (sp = ssp->left; sp != NULL; sp = sp->next)
{
print_line_num(tp->line_num);
eval_delay(tp->event_expr, sp);
if (strcmp(state_name, sp->value) == 0)
return index;
index++;
}
printf("}\n");
if (sp->ndelay > ssp->ndelay)
ssp->ndelay = sp->ndelay; /* max # delay calls in ss */
return;
return -1; /* State name non-existant */
}
/* Evaluate an expression.
Checks for special functions:
efSet(ef) and efGet(ef) -> set corresponding bit in ef_mask.
pvPut() & pvGet -> replace variable with ptr to db struct.
*/
eval_expr(stmt_type, ep, sp)
int stmt_type; /* EVENT_STMT, ACTION_STMT, or DELAY_STMT */
Expr *ep; /* ptr to expression */
State *sp; /* ptr to current State struct */
/* Generate delay processing function for a state */
gen_delay_func(sp, ssp)
Expr *sp;
Expr *ssp;
{
Expr *epf;
int nparams;
Expr *tp;
int eval_delay();
printf("\n/* Delay function for state \"%s\" in state set \"%s\" */\n",
sp->value, ssp->value);
printf("static D_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("SPROG\t*sprog;\n");
printf("SSCB\t*ss_ptr;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
/* For each transition ... */
for (tp = sp->left; tp != NULL; tp = tp->next)
{
print_line_num(tp->line_num, tp->src_file);
traverseExprTree(tp, E_FUNC, "delay", eval_delay, sp);
}
printf("}\n");
return;
}
/* Evaluate an expression.
*/
eval_expr(stmt_type, ep, sp, level)
int stmt_type; /* EVENT_STMT, ACTION_STMT, or DELAY_STMT */
Expr *ep; /* ptr to expression */
Expr *sp; /* ptr to current State struct */
int level; /* indentation level */
{
Expr *epf;
int nparams;
extern int reent_flag;
if (ep == 0)
return;
switch(ep->type)
{
case E_CMPND:
indent(level);
printf("{\n");
for (epf = ep->left; epf != 0; epf = epf->next)
{
eval_expr(stmt_type, epf, sp, level+1);
}
indent(level);
printf("}\n");
break;
case E_STMT:
indent(level);
eval_expr(stmt_type, ep->left, sp, 0);
printf(";\n");
break;
case E_IF:
case E_WHILE:
indent(level);
if (ep->type == E_IF)
printf("if (");
else
printf("while (");
eval_expr(stmt_type, ep->left, sp, 0);
printf(")\n");
epf = ep->right;
if (epf->type == E_CMPND)
eval_expr(stmt_type, ep->right, sp, level);
else
eval_expr(stmt_type, ep->right, sp, level+1);
break;
case E_ELSE:
indent(level);
printf("else\n");
epf = ep->left;
/* Is it "else if" ? */
if (epf->type == E_IF || epf->type == E_CMPND)
eval_expr(stmt_type, ep->left, sp, level);
else
eval_expr(stmt_type, ep->left, sp, level+1);
break;
case E_VAR:
printf("%s", ep->value.var->name);
if(reent_flag)
{ /* Make variables point to allocated structure */
Var *vp;
vp = (Var *)ep->left;
if (vp->type != V_NONE && vp->type != V_EVFLAG)
printf("(var_ptr->%s)", ep->value);
else
printf("%s", ep->value);
}
else
printf("%s", ep->value);
break;
case E_CONST:
printf("%s", ep->value.const);
printf("%s", ep->value);
break;
case E_STRING:
printf("\"%s\"", ep->value.const);
printf("\"%s\"", ep->value);
break;
case E_FUNC:
if (special_func(stmt_type, ep, sp))
break;
printf("%s(", ep->value.const);
for (epf = ep->right, nparams = 0; epf != 0;
printf("%s(", ep->value);
for (epf = ep->left, nparams = 0; epf != 0;
epf = epf->next, nparams++)
{
if (nparams > 0)
printf(" ,");
eval_expr(stmt_type, epf, sp);
eval_expr(stmt_type, epf, sp, 0);
}
printf(") ");
break;
case E_ASGNOP:
case E_BINOP:
eval_expr(stmt_type, ep->left, sp);
printf("%s", ep->value.const);
eval_expr(stmt_type, ep->right, sp);
eval_expr(stmt_type, ep->left, sp, 0);
printf(" %s ", ep->value);
eval_expr(stmt_type, ep->right, sp, 0);
break;
case E_PAREN:
printf("(");
eval_expr(stmt_type, ep->right, sp);
eval_expr(stmt_type, ep->left, sp, 0);
printf(")");
break;
case E_UNOP:
printf("%s", ep->value.const);
eval_expr(stmt_type, ep->right, sp);
printf("%s", ep->value);
eval_expr(stmt_type, ep->left, sp, 0);
break;
case E_SUBSCR:
eval_expr(stmt_type, ep->left, sp);
eval_expr(stmt_type, ep->left, sp, 0);
printf("[");
eval_expr(stmt_type, ep->right, sp);
eval_expr(stmt_type, ep->right, sp, 0);
printf("]");
break;
case E_TEXT:
printf("%s\n", ep->left);
break;
default:
if (stmt_type == EVENT_STMT)
printf("TRUE"); /* empty event statement defaults to TRUE */
@@ -244,45 +316,64 @@ State *sp; /* ptr to current State struct */
}
}
enum fcode { F_NONE, F_EFSET, F_EFTEST, F_PVGET, F_PVPUT, F_DELAY };
indent(level)
int level;
{
while (level-- > 0)
printf("\t");
}
/* func_name_to_code - convert function name to a code */
enum fcode { F_DELAY, F_EFSET, F_EFTEST, F_PVGET, F_PVPUT,
F_PVMONITOR, F_PVSTOPMONITOR, F_PVCOUNT, F_PVINDEX,
F_PVSTATUS, F_PVSEVERITY, F_PVFLUSH, F_PVERROR, F_PVGETCOMPLETE,
F_PVCONNECTED, F_PVCHANNELCOUNT, F_PVCONNECTCOUNT, F_NONE };
char *fcode_str[] = { "delay", "efSet", "efTest", "pvGet", "pvPut",
"pvMonitor", "pvStopMonitor", "pvCount", "pvIndex",
"pvStatus", "pvSeverity", "pvFlush", "pvError", "pvGetComplete",
"pvConnected", "pvChannelCount", "pvConnectCount", NULL };
enum fcode func_name_to_code(fname)
char *fname;
{
if (strcmp(fname, "efSet") == 0)
return F_EFSET;
if (strcmp(fname, "efTest") == 0)
return F_EFTEST;
if (strcmp(fname, "pvPut") == 0)
return F_PVPUT;
if (strcmp(fname, "pvGet") == 0)
return F_PVGET;
if (strcmp(fname, "delay") == 0)
return F_DELAY;
int i;
for (i = 0; fcode_str[i] != NULL; i++)
{
if (strcmp(fname, fcode_str[i]) == 0)
return (enum fcode)i;
}
return F_NONE;
}
/* Process special function (returns TRUE if this is a special function) */
/* Process special function (returns TRUE if this is a special function)
Checks for special functions:
efSet(ef) and efGet(ef) -> set corresponding bit in ef_mask.
pvPut() & pvGet -> replace variable with ptr to db struct.
delay() - replaces delay time with delay index.
*/
special_func(stmt_type, ep, sp)
int stmt_type; /* ACTION_STMT or EVENT_STMT */
Expr *ep; /* ptr to function in the expression */
State *sp; /* current State struct */
int stmt_type; /* ACTION_STMT or EVENT_STMT */
Expr *ep; /* ptr to function in the expression */
Expr *sp; /* current State struct */
{
char *fname; /* function name */
Expr *ep1; /* 1-st parameter */
Chan *cp;
Var *vp;
enum fcode func_code;
char *fname; /* function name */
Expr *ep1; /* 1-st parameter */
Chan *cp;
Var *vp;
enum fcode func_code;
int ndelay;
fname = ep->value.const;
fname = ep->value;
func_code = func_name_to_code(fname);
if (func_code == F_NONE)
return FALSE; /* not a special function */
ep1 = ep->right; /* ptr to 1-st parameters */
ep1 = ep->left; /* ptr to 1-st parameters */
if ( (ep1 != 0) && (ep1->type == E_VAR) )
{
vp = ep1->value.var;
vp = (Var *)find_var(ep1->value);
cp = vp->chan;
}
else
@@ -291,13 +382,15 @@ State *sp; /* current State struct */
cp = 0;
}
if (func_code == F_EFSET || func_code == F_EFTEST)
switch (func_code)
{
case F_EFSET:
case F_EFTEST:
if (vp->type != V_EVFLAG)
{
fprintf(stderr, "Line %d: ", ep->line_num);
fprintf(stderr,
"Parameter to efSet() and efTest() must be an event flag\n");
"Parameter to \"%s\" must be an event flag\n", fname);
}
else if (func_code == F_EFSET && stmt_type == EVENT_STMT)
{
@@ -308,93 +401,83 @@ State *sp; /* current State struct */
else
{
printf("%s(%s)", fname, vp->name);
/* OR the ef bit with ef mask in State struct */
sp->event_flag_mask |= 1 << (vp->ef_num);
}
return TRUE;
}
else if (func_code == F_PVPUT || func_code == F_PVGET)
{
case F_PVPUT:
case F_PVGET:
case F_PVGETCOMPLETE:
case F_PVSTATUS:
case F_PVSEVERITY:
case F_PVCONNECTED:
case F_PVMONITOR:
case F_PVSTOPMONITOR:
case F_PVCOUNT:
case F_PVINDEX:
/* DB functions requiring a channel structure */
if (cp == 0)
{
fprintf(stderr, "Line %d: ", ep->line_num);
fprintf(stderr,
"Parameter to pvPut/pvGet must be DB variable.\n");
}
else if (stmt_type == EVENT_STMT)
{
fprintf(stderr,
"pvPut/pvGet cannot be used as an event.\n");
"Parameter to \"%s\" must be DB variable.\n", fname);
}
else
{
printf("%s(%d)", fname, cp->index);
}
return TRUE;
}
else if (func_code == F_DELAY)
{ /* Test for delay: "test_delay(delay_id)" */
printf("test_delay(%d)", sp->ndelay++);
case F_PVFLUSH:
case F_PVERROR:
case F_PVCHANNELCOUNT:
case F_PVCONNECTCOUNT:
/* DB functions not requiring a channel structure */
printf("%s()", fname);
return TRUE;
}
else
case F_DELAY:
/* Test for delay: "test_delay(delay_id)" */
printf("test_delay(%d)", (int)ep->right);
return TRUE;
default:
return FALSE; /* not a special function */
}
/* Evaluate delay expression.
This is similar to eval_expr() except that all output
is supressed until a delay() function is found. All
parameters are then processed with eval_expr().
*/
eval_delay(ep, sp)
Expr *ep; /* ptr to expression */
State *sp; /* ptr to current State struct */
{
Expr *epf;
#ifdef DEBUG
fprintf(stderr, "eval_delay: type=%d\n", ep->type);
#endif DEBUG
switch(ep->type)
{
case E_FUNC:
#ifdef DEBUG
fprintf(stderr, "fn=%s\n", ep->value.const);
#endif DEBUG
if (strcmp(ep->value.const, "delay") == 0)
{ /* delay function found: replace with special
function & parameters, then evaluate 1-st
parameter only
*/
printf("\tstart_delay(%d, ", sp->ndelay++);
epf = ep->right; /* paramter */
eval_expr(EVENT_STMT, epf, sp);
printf(");\n");
}
else
{
for (epf = ep->right; epf != 0; epf = epf->next)
{
eval_delay(epf, sp);
}
}
break;
case E_BINOP:
eval_delay(ep->left, sp);
eval_delay(ep->right, sp);
break;
case E_PAREN:
eval_delay(ep->right, sp);
break;
case E_UNOP:
eval_delay(ep->right, sp);
break;
case E_SUBSCR:
eval_delay(ep->left, sp);
eval_delay(ep->right, sp);
break;
default:
break;
}
}
/* Evaluate delay expression. */
eval_delay(ep, sp)
Expr *ep; /* ptr to expression */
Expr *sp; /* ptr to current State struct */
{
Expr *epf;
int delay_id;
extern char *stype[];
#ifdef DEBUG
fprintf(stderr, "eval_delay: type=%s\n", stype[ep->type]);
#endif
delay_id = (int)ep->right;
printf("\tstart_delay(%d, ", delay_id);
/* Output each parameter */
eval_expr(EVENT_STMT, ep->left, sp, 0);
printf(");\n");
}
/* Generate exit handler code */
gen_exit_handler()
{
extern Expr *exit_code_list;
Expr *ep;
printf("/* Exit handler */\n");
printf("static exit_handler(sprog, var_ptr)\n");
printf("SPROG\t*sprog;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
for (ep = exit_code_list; ep != 0; ep = ep->next)
{
eval_expr(EXIT_STMT, ep, 0, 1);
}
printf("}\n\n");
}

View File

@@ -3,7 +3,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
$Id$
@(#)gen_tables.c 1.1 5/30/91
DESCRIPTION: Generate tables for run-time sequencer.
See also: phase2.c & gen_ss_code.c
ENVIRONMENT: UNIX

View File

@@ -1,10 +1,10 @@
/* #define DEBUG 1 */
/*#define DEBUG 1*/
/**************************************************************************
GTA PROJECT AT division
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)parse.c 1.1 10/16/90
@(#)parse.c 1.3 5/1/91
DESCRIPTION: Parsing support routines for state notation compiler.
The 'yacc' parser calls these routines to build the tables
and linked lists, which are then passed on to the phase 2 routines.
@@ -26,27 +26,21 @@
int debug_print_flag = 0; /* Debug level (set by source file) */
int line_num; /* Current line number */
char *prog_name; /* ptr to program name (string) */
char *prog_param; /* parameter string for program stmt */
LIST defn_c_list; /* definition C code */
Expr *defn_c_list; /* definition C code list */
LIST ss_list; /* start of state-set list */
Expr *ss_list; /* Start of state set list */
Expr *exit_code_list; /* Start of exit code list */
LIST var_list; /* start of variable list */
LIST chan_list; /* start of DB channel list */
LIST state_list; /* temporary state list */
LIST action_list; /* temporary action list */
LIST trans_list; /* temporary transition list */
char *global_c_code; /* global C code following state program */
Expr *global_c_list; /* global C code following state program */
/*+************************************************************************
* NAME: snc_init
*
@@ -60,13 +54,11 @@ char *global_c_code; /* global C code following state program */
*-*************************************************************************/
init_snc()
{
lstInit(&defn_c_list);
lstInit(&ss_list);
extern char in_file[], *src_file;
lstInit(&var_list);
lstInit(&chan_list);
lstInit(&state_list);
lstInit(&action_list);
lstInit(&trans_list);
src_file = &in_file[0];
return;
}
/*+************************************************************************
@@ -90,7 +82,7 @@ char *pname, *pparam;
prog_name = pname;
prog_param = pparam;
#ifdef DEBUG
printf("program name = %s\n", prog_name);
fprintf(stderr, "program name = %s\n", prog_name);
#endif
return;
}
@@ -102,13 +94,14 @@ char *name; /* ptr to variable name */
char *s_length; /* array lth (NULL=single element) */
char *value; /* initial value or NULL */
{
Var *vp;
int length;
Var *vp;
int length;
extern int line_num;
if (s_length == 0)
length = 0;
else if (type == V_STRING)
length = MAX_STRING_SIZE;
length = 0;
else
{
length = atoi(s_length);
@@ -116,7 +109,7 @@ char *value; /* initial value or NULL */
length = 0;
}
#ifdef DEBUG
printf("variable decl: type=%d, name=%s, length=%d\n", type, name, length);
fprintf(stderr, "variable decl: type=%d, name=%s, length=%d\n", type, name, length);
#endif
/* See if variable already declared */
vp = (Var *)find_var(name);
@@ -138,15 +131,13 @@ char *value; /* initial value or NULL */
/* "Assign" statement: assign a variable to a DB channel.
elem_num is ignored in this version) */
assign_stmt(name, lower_lim, upper_lim, db_name)
assign_stmt(name, db_name)
char *name; /* ptr to variable name */
char *lower_lim; /* ptr to lower array limit */
char *upper_lim; /* ptr to upper array limit */
char *db_name; /* ptr to db name */
{
Chan *cp;
Var *vp;
int range_low, range_high, length;
Chan *cp;
Var *vp;
extern int line_num;
/* Find the variable */
vp = (Var *)find_var(name);
@@ -163,53 +154,27 @@ char *db_name; /* ptr to db name */
cp->var = vp; /* make connection to variable */
vp->chan = cp; /* reverse ptr */
cp->db_name = db_name; /* DB name */
cp->count = vp->length; /* default count is variable length */
/* convert specified range REMOVED********* */
length = vp->length;
if (length == 0)
length = 1; /* not an array */
if (vp->type == V_STRING)
length = 1; /* db treats strings as length 1 */
cp->length = length;
cp->offset = 0;
cp->mon_flag = FALSE; /* assume no monitor */
cp->ef_var = NULL; /* assume no sync event flag */
return;
}
/* Build the range string, e.g. "0", and "9" into "0,9" */
char *
range(low, high)
char *low, *high;
{
static char range_str[30];
sprintf(range_str, "%s,%s", low, high);
return range_str;
}
/* Parsing a "monitor" statement */
monitor_stmt(name, offset, delta)
monitor_stmt(name, delta)
char *name; /* variable name (should be assigned) */
char *offset; /* array offset */
char *delta; /* monitor delta */
{
Chan *cp;
int offs;
extern int line_num;
/* Pick up array offset */
if (offset == 0)
offs = 0;
else
offs = atoi(offset);
if (offs < 0)
offs = 0;
/* Find a channel assigned to this variable */
cp = (Chan *)find_chan(name, offs);
cp = (Chan *)find_chan(name);
if (cp == 0)
{
fprintf(stderr, "monitor: variable %s[%s] not assigned, line %d\n",
name, offset, line_num);
fprintf(stderr, "monitor: variable %s not assigned, line %d\n",
name, line_num);
return;
}
@@ -220,29 +185,22 @@ char *delta; /* monitor delta */
}
/* Parsing "sync" statement */
sync_stmt(name, offset, ef_name)
sync_stmt(name, ef_name)
char *name;
char *offset;
char *ef_name;
{
Chan *cp;
Var *vp;
int offs;
Chan *cp;
Var *vp;
extern int line_num;
/* Find the variable */
if (offset == 0)
offs = 0;
else
offs = atoi(offset);
if (offs < 0)
offs = 0;
cp = (Chan *)find_chan(name, offs);
cp = (Chan *)find_chan(name);
if (cp == 0)
{
fprintf(stderr, "sync: variable %s[%s] not assigned, line %d\n",
name, offset, line_num);
fprintf(stderr, "sync: variable %s not assigned, line %d\n",
name, line_num);
return;
}
/* Find the event flag varible */
vp = (Var *)find_var(ef_name);
if (vp == 0 || vp->type != V_EVFLAG)
@@ -251,142 +209,41 @@ char *ef_name;
ef_name, line_num);
return;
}
/* Insert pointers between Var & Chan structures */
cp->ef_var = vp;
vp->chan = cp;
return;
}
/* Definition C code */
defn_c_stmt(c_str)
char *c_str;
char *c_str; /* ptr to C code string */
{
Action *ap;
Expr *ep;
#ifdef DEBUG
printf("defn_c_stmt\n");
fprintf(stderr, "defn_c_stmt\n");
#endif
ap = allocAction();
lstAdd(&defn_c_list, (NODE *)ap);
ap->type = A_CCODE;
ap->stmt.c_code = c_str;
ap->line_num = line_num;
ep = expression(E_TEXT, "", c_str, 0);
if (defn_c_list == 0)
defn_c_list = ep;
else
link_expr(defn_c_list, ep);
return;
}
/* Parsing "ss" statement */
state_set(ss_name)
char *ss_name;
/* Global C code (follows state program) */
global_c_stmt(c_str)
char *c_str; /* ptr to C code */
{
StateSet *ssp;
# ifdef DEBUG
printf("state_set: ss_name=%s\n", ss_name);
#endif
/* Is this state set already declared ? */
if (find_state_set(ss_name) != NULL)
{
fprintf(stderr, "Duplicate state set name: %s, line %d\n",
ss_name, line_num);
return;
}
/* create and fill in state-set block */
ssp = allocSS();
lstAdd(&ss_list, (NODE *)ssp);
ssp->ss_name = ss_name;
/* move temporary state list into this node */
#ifdef DEBUG
printf(" # states = %d\n", lstCount(&state_list));
#endif DEBUG
ssp->S_list = state_list;
lstInit(&state_list);
global_c_list = expression(E_TEXT, "", c_str, 0);
return;
}
state_block(state_name)
char *state_name;
{
State *sp;
#ifdef DEBUG
printf("state_block: state_name=%s\n", state_name);
#endif
sp = firstState(&state_list);
if (find_state(state_name, sp) != NULL)
{
fprintf(stderr, "Duplicate state name: %s, line %d\n",
state_name, line_num);
return;
}
sp = allocState();
lstAdd(&state_list, (NODE *)sp);
sp->state_name = state_name;
/* move tmp transition list into this node */
sp->T_list = trans_list;
lstInit(&trans_list);
return;
}
/* Parsing transition part of "when" clause */
transition(new_state_name, event_expr)
char *new_state_name;
Expr *event_expr; /* event expression */
{
Trans *tp;
#ifdef DEBUG
printf("transition: new_state_name=%s\n", new_state_name);
#endif
tp = allocTrans();
lstAdd(&trans_list, (NODE *)tp);
tp->new_state_name = new_state_name;
tp->line_num = line_num;
/* move tmp action list into this node */
tp->A_list = action_list;
tp->event_expr = event_expr;
lstInit(&action_list);
return;
}
/* Action statement (lvalue = expression;) or (function())*/
action_stmt(ep)
Expr *ep; /* ptr to expression */
{
Action *ap;
#ifdef DEBUG
printf("action_function\n");
#endif
ap = allocAction();
lstAdd(&action_list, (NODE *)ap);
ap->type = A_STMT;
ap->stmt.expr = ep;
ap->line_num = line_num;
return;
}
/* Action statement: in-line C code */
action_c_stmt(c_str)
char *c_str;
{
Action *ap;
#ifdef DEBUG
printf("action_c_stmt\n");
#endif
ap = allocAction();
lstAdd(&action_list, (NODE *)ap);
ap->type = A_CCODE;
ap->stmt.c_code = c_str;
ap->line_num = line_num;
return;
}
/* Find a variable by name; returns a pointer to the Var struct;
returns 0 if the variable is not found. */
find_var(name)
@@ -395,7 +252,7 @@ char *name;
Var *vp;
#ifdef DEBUG
printf("find_var, name=%s: ", name);
fprintf(stderr, "find_var, name=%s: ", name);
#endif
vp = firstVar(&var_list);
while (vp != NULL)
@@ -403,38 +260,31 @@ char *name;
if (strcmp(vp->name, name) == 0)
{
#ifdef DEBUG
printf("found\n");
fprintf(stderr, "found\n");
#endif
return (int)vp;
}
vp = nextVar(vp);
}
#ifdef DEBUG
printf("not found\n");
fprintf(stderr, "not found\n");
#endif
return 0;
}
/* Find channel with same variable name and same offset */
find_chan(name, offset)
find_chan(name)
char *name; /* variable name */
int offset;/* array offset */
{
Chan *cp;
Var *vp;
int chan_offs;
if (offset < 0)
offset = 0;
for (cp = firstChan(&chan_list); cp != NULL; cp = nextChan(cp))
{
vp = cp->var;
if (vp == 0)
continue;
chan_offs = cp->offset;
if (chan_offs < 0)
chan_offs = 0;
if (strcmp(vp->name, name) == 0 && chan_offs == offset)
if (strcmp(vp->name, name) == 0)
{
return (int)cp;
}
@@ -442,34 +292,6 @@ int offset;/* array offset */
return 0;
}
/* Given the name of a state, find ptr to the state struct */
find_state(state_name, sp)
char *state_name; /* state name we're looking for */
State *sp; /* start of state list */
{
for (; sp != NULL; sp = nextState(sp))
{
if (strcmp(sp->state_name, state_name) == 0)
return (int)sp;
}
return NULL; /* not found */
}
/* Given the name of a state set, find ptr to state set struc */
find_state_set(ss_name)
char *ss_name; /* state set name we're looking for */
{
StateSet *ssp;
extern LIST ss_list;
for (ssp = firstSS(&ss_list); ssp != NULL; ssp = nextSS(ssp))
{
if (strcmp(ssp->ss_name, ss_name) == 0)
return (int)ssp;
}
return NULL; /* not found */
}
/* Set debug print flag */
set_debug_print(flag)
char *flag;
@@ -478,117 +300,114 @@ char *flag;
}
/* Parsing "program" statement */
program(c_code)
char *c_code;
program(prog_list)
Expr *prog_list;
{
global_c_code = c_code;
phase2();
ss_list = prog_list;
#ifdef DEBUG
print_struct(ss_list);
#endif
phase2(ss_list);
exit(0);
}
/* Build an expression list (hierarchical) */
Expr *expression(type, value, left, right)
int type;
char *value;
Expr *left, *right;
/* Exit code */
exit_code(ep)
Expr *ep;
{
Expr *ep;
exit_code_list = ep;
return 0;
}
/* alloc a block for this item or expression */
/* Build an expression list (hierarchical):
Builds a node on a binary tree for each expression primitive.
*/
Expr *expression(type, value, left, right)
int type; /* E_BINOP, E_ASGNOP, etc */
char *value; /* "==", "+=", var name, contstant, etc. */
Expr *left; /* LH side */
Expr *right; /* RH side */
{
Expr *ep;
extern int line_num, c_line_num;
extern char *src_file;
#ifdef DEBUG
fprintf(stderr, "expression: type=%d, value=%s, left=%d, right=%d\n",
type, value, left, right);
extern char *stype[];
#endif
/* Allocate a structure for this item or expression */
ep = allocExpr();
#ifdef DEBUG
fprintf(stderr, "expression: ep=%d, type=%s, value=\"%s\", left=%d, right=%d\n",
ep, stype[type], value, left, right);
#endif
/* Fill in the structure */
ep->next = (Expr *)0;
ep->last = ep;
ep->type = type;
ep->value.const = value;
ep->value = value;
ep->left = left;
ep->right = right;
ep->line_num = line_num;
switch (type)
{
case E_VAR: /* variable or pre-defined constant */
if (pre_defined_const(ep))
{
ep->type = E_CONST;
break; /* defined constant */
}
/* find the variable */
ep->value.var = (Var *)find_var(value);
if (ep->value.var == 0)
{
fprintf(stderr, "variable \"%s\" not declared, line no. %d\n",
value, ep->line_num);
}
break;
case E_CONST: /* number const */
break;
case E_STRING: /* string const */
break;
case E_BINOP: /* binary op. ( left_expr OP rt_expr ) */
break;
case E_UNOP: /* unary op. */
break;
case E_PAREN: /* parenthetical expr. */
break;
case E_FUNC:
break;
case E_EMPTY: /* empty */
break;
case E_SUBSCR: /* subscript */
break;
default: /* any other */
fprintf(stderr, "? %d: %s, line no. %d\n", type, value, line_num);
break;
}
if (type == E_TEXT)
ep->line_num = c_line_num;
else
ep->line_num = line_num;
ep->src_file = src_file;
return ep;
}
/* Check for defined constant */
pre_defined_const(ep)
Expr *ep;
/* Link two expression structures and/or lists. Returns ptr to combined list.
Note: ->last ptrs are correct only for 1-st and last structures in the list */
Expr *link_expr(ep1, ep2)
Expr *ep1; /* beginning of 1-st structure or list */
Expr *ep2; /* beginning 2-nd (append it to 1-st) */
{
if ( (strcmp(ep->value.const, "TRUE") == 0)
|| (strcmp(ep->value.const, "FALSE") == 0) )
return TRUE;
else
return FALSE;
}
Expr *ep;
/* Add a parameter (expression) to end of list */
Expr *parameter(ep, p_list)
Expr *ep;
Expr *p_list; /* current list */
{
Expr *ep1;
if (ep1 == 0)
return ep2; /* shouldn't happen */
else if (ep2 == 0)
return ep1;
ep->next = 0;
if (p_list == 0)
return ep;
ep1 = p_list;
while (ep1->next != 0)
ep1 = ep1->next;
ep1->next = ep;
return p_list;
(ep1->last)->next = ep2;
ep1->last = ep2->last;
#ifdef DEBUG
fprintf(stderr, "link_expr(");
for (ep = ep1; ; ep = ep->next)
{
fprintf(stderr, "%d, ", ep);
if (ep == ep1->last)
break;
}
fprintf(stderr, ")\n");
#endif DEBUG
return ep1;
}
/*#define PHASE2*/
/* Interpret pre-processor code */
pp_code(line, fname)
char *line;
char *fname;
{
extern int line_num;
line_num = atoi(line);
src_file = fname;
}
char *stype[] = {
"E_EMPTY", "E_CONST", "E_VAR", "E_FUNC", "E_STRING", "E_UNOP", "E_BINOP",
"E_ASGNOP", "E_PAREN", "E_SUBSCR", "E_TEXT", "E_STMT", "E_CMPND",
"E_IF", "E_ELSE", "E_WHILE", "E_SS", "E_STATE", "E_WHEN" };
/* #define PHASE2*/
#ifdef PHASE2
phase2()
phase2(ss_list)
Expr *ss_list;
{
fprintf(stderr, "phase2() - dummy\07\n");
/* Print structures */
print_struct(ss_list);
}
#endif PHASE2

View File

@@ -3,7 +3,7 @@
Copyright, 1989, The Regents of the University of California.
Los Alamos National Laboratory
@(#)parse.h 1.1 10/16/90
@(#)parse.h 1.2 4/17/91
DESCRIPTION: Structures for parsing the state notation language.
ENVIRONMENT: UNIX
***************************************************************************/
@@ -15,63 +15,19 @@
#include "lstLib.h" /* VxWorks "list" routines & definitions */
struct state_set /* state-set block */
{
NODE SS_link; /* link to next state set block */
char *ss_name; /* state set name */
LIST S_list; /* link to first state block */
int ndelay; /* Max # delay calls in state set */
};
typedef struct state_set StateSet;
struct state /* State block */
{
NODE S_link; /* link to next state in this SS */
char *state_name; /* state name */
int event_flag_mask; /* event flag mask for this state */
int ndelay; /* # delay calls */
LIST T_list; /* start of transition list */
};
typedef struct state State;
struct trans /* Transition Block */
{
NODE T_link; /* link to next transition block */
int trans_num; /* transition number */
int line_num;
char *new_state_name; /* new state name */
struct expression *event_expr; /* event expression */
LIST A_list; /* start of action list */
};
typedef struct trans Trans;
struct expression /* Expression block */
{
struct expression *next; /* link to next expression */
struct expression *last; /* link to last in list */
struct expression *left; /* ptr to left expression */
struct expression *right; /* ptr to right expression */
int type; /* operator or expression type */
union { /* for variables, functions, & constants */
struct var *var; /* ptr to variable definition */
char *name; /* ptr to function name */
char *const; /* ptr to constant */
} value;
int type; /* expression type (E_*) */
char *value; /* operator or value string */
int line_num; /* line number */
char *src_file; /* effective source file */
};
typedef struct expression Expr;
struct action /* Action block */
{
NODE A_link; /* link to next action (or NULL) */
int line_num; /* line number of statement */
int type; /* A_CCODE, A_FUNC, A_STMT */
union stmt {
Expr *expr; /* ptr to expression (A_STMT) */
char *c_code; /* ptr to imbedded C code (A_CCODE) */
} stmt;
};
typedef struct action Action;
struct var /* Variable or function definition */
{
NODE V_link; /* next variable in list */
@@ -87,62 +43,63 @@ typedef struct var Var;
struct db_chan /* DB channel */
{
NODE D_link; /* next db chan in list */
char *db_name; /* db name if assigned */
char *db_name; /* database name */
int index; /* channel array index */
Var *var; /* ptr to variable definition */
int offset; /* array offset (normally 0) */
int length; /* sub-array length */
Var *ef_var; /* ptr to event flag variable for sync */
int count; /* count for db access */
int mon_flag; /* TRUE if channel is "monitored" */
float delta; /* monitor dead-band */
float timeout; /* monitor timeout (seconds) */
Var *ef_var; /* ptr to event flag variable for sync */
float timeout; /* monitor timeout */
};
typedef struct db_chan Chan;
Expr *expression(), *link_expr();
/* Linked list definitions to get rid of yucky in-line code */
#define nextSS(node) (StateSet *)lstNext( (NODE *)node )
#define firstSS(head) (StateSet *)lstFirst( (LIST *)head )
#define allocSS() (StateSet *)malloc(sizeof(StateSet));
#define nextState(node) (State *)lstNext( (NODE *)node )
#define firstState(head) (State *)lstFirst( (LIST *)head )
#define allocState() (State *)malloc(sizeof(State));
#define nextTrans(node) (Trans *)lstNext( (NODE *)node )
#define firstTrans(head) (Trans *)lstFirst( (LIST *)head )
#define allocTrans() (Trans *)malloc(sizeof(Trans));
#define allocExpr() (Expr *)malloc(sizeof(Expr));
#define nextAction(node) (Action *)lstNext( (NODE *)node )
#define firstAction(head) (Action *)lstFirst( (LIST *)head )
#define allocAction() (Action *)malloc(sizeof(Action));
#define nextVar(node) (Var *)lstNext( (NODE *)node )
#define allocVar() (Var *)malloc(sizeof(Var));
#define nextVar(node) (Var *)lstNext( (NODE *)node )
#define firstVar(head) (Var *)lstFirst( (LIST *)head )
#define allocChan() (Chan *)malloc(sizeof(Chan));
#define nextChan(node) (Chan *)lstNext( (NODE *)node )
#define firstChan(head) (Chan *)lstFirst( (LIST *)head )
#define allocChan() (Chan *)malloc(sizeof(Chan));
/* Variable types */
#define V_NONE 0 /* not defined */
#define V_FLOAT 1 /* float */
#define V_INT 2 /* int */
#define V_SHORT 3 /* short */
#define V_CHAR 4 /* char */
#define V_DOUBLE 5 /* double */
#define V_STRING 6 /* strings (array of char) */
#define V_EVFLAG 7 /* event flag */
#define V_FUNC 8 /* function (not a variable) */
#define V_CHAR 1 /* char */
#define V_SHORT 2 /* short */
#define V_INT 3 /* int (but converted to long) */
#define V_LONG 4 /* long */
#define V_FLOAT 5 /* float */
#define V_DOUBLE 6 /* double */
#define V_STRING 7 /* strings (array of char) */
#define V_EVFLAG 8 /* event flag */
#define V_FUNC 9 /* function (not a variable) */
#define V_UCHAR 11 /* unsigned char */
#define V_USHORT 12 /* unsigned short */
#define V_UINT 13 /* unsigned int (converted to unsigned long) */
#define V_ULONG 14 /* unsigned long */
/* Expression type */
/* Expression types */
#define E_EMPTY 0 /* empty expression */
#define E_CONST 1 /* numeric constant */
#define E_VAR 2 /* variable */
#define E_FUNC 3 /* function */
#define E_STR 4 /* ptr to string consatant */
#define E_STRING 4 /* ptr to string consatant */
#define E_UNOP 5 /* unary operator: OP expr (-, +, or !) */
#define E_BINOP 6 /* binary operator: expr OP expr */
#define E_PAREN 7 /* parenthesis around expression */
#define E_SUBSCR 8 /* subscript */
#define E_STRING 9 /* string const */
#define E_EMPTY 0 /* empty expression */
/* Action types */
#define A_CCODE 1 /* imbedded C code: %% or %{...}% */
#define A_STMT 2 /* lvalue = expression; or function();*/
#define E_ASGNOP 7 /* assign operatro: (=, +=, *=, etc.) */
#define E_PAREN 8 /* parenthesis around an expression */
#define E_SUBSCR 9 /* subscript */
#define E_TEXT 10 /* C code or other text to be inserted */
#define E_STMT 11 /* simple statement */
#define E_CMPND 12 /* begin compound statement: {...} */
#define E_IF 13 /* if statement */
#define E_ELSE 14 /* if statement */
#define E_WHILE 15 /* while statement */
#define E_SS 16 /* state set statement */
#define E_STATE 17 /* state statement */
#define E_WHEN 18 /* when statement */

View File

@@ -3,7 +3,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)phase2.c 1.4 1/16/91
@(#)phase2.c 1.5 4/17/91
DESCRIPTION: Phase 2 code generation routines for SNC.
Produces code and tables in C output file.
See also: gen_ss_code.c
@@ -13,8 +13,12 @@
#include <stdio.h>
#include "parse.h"
#include "seq.h"
/*+************************************************************************
int num_channels = 0; /* number of db channels */
int num_ss = 0; /* number of state sets */
int num_errors = 0; /* number of errors detected in phase 2 processing */
/*+************************************************************************
* NAME: phase2
*
* CALLING SEQUENCE
@@ -27,22 +31,21 @@
*
* NOTES: All inputs are external globals.
*-*************************************************************************/
int num_vars = 0; /* number of variables declared */
int num_channels = 0; /* number of db channels */
int num_ss = 0; /* number of state sets */
int num_errors = 0; /* number of errors detected in phase 2 processing */
phase2()
{
extern LIST var_list; /* variables (from parse) */
extern LIST ss_list; /* state sets (from parse) */
extern char *prog_name; /* program name (from parse) */
extern char *global_c_code; /* global C code */
extern Expr *ss_list; /* state sets (from parse) */
extern Expr *global_c_list; /* global C code */
/* Count number of variables, db channels, and state sets defined */
num_vars = lstCount((NODE *)&var_list);
/* Count number of db channels and state sets defined */
num_channels = db_chan_count();
num_ss = lstCount((NODE *)&ss_list);
num_ss = exprCount(ss_list);
/* Reconcile all variable and tie each to the appropriate VAR struct */
reconcile_variables();
/* reconcile all state names, including next state in transitions */
reconcile_states();
/* Generate preamble code */
gen_preamble();
@@ -56,30 +59,26 @@ phase2()
/* Assign bits for event flags */
assign_ef_bits();
/* Generate DB blocks */
gen_db_blocks();
/* Assign delay id's */
assign_delay_ids();
/* Generate code for each state set */
gen_ss_code();
/* Generate State Blocks */
gen_state_blocks();
/* Generate State Set control blocks as an array */
gen_sscb_array();
/* Generate state program table */
gen_state_prog_table();
/* Generate tables */
gen_tables();
/* Output global C code */
printf("%s\n", global_c_code);
gen_global_c_code();
exit(0);
}
/* Generate preamble (includes, defines, etc.) */
/* Generate preamble (includes, defines, etc.) */
gen_preamble()
{
extern char *prog_name;
/* Program name (comment) */
printf("/* Program \"%s\" */\n", prog_name);
/* Include files */
@@ -87,30 +86,124 @@ gen_preamble()
/* Local definitions */
printf("\n#define NUM_SS %d\n", num_ss);
printf("#define NUM_VARS %d\n", num_vars);
printf("#define NUM_CHANNELS %d\n", num_channels);
/* Forward definition of SPROG structure */
/* Forward references of tables: */
printf("\nextern SPROG %s;\n", prog_name);
printf("extern CHAN db_channels[];\n");
return;
}
int printTree = FALSE;
/* Reconcile all variables in an expression,
and tie each to the appropriate VAR struct */
reconcile_variables()
{
extern Expr *ss_list, *exit_code_list;
Expr *ssp, *ep;
int connect_variable();
for (ssp = ss_list; ssp != 0; ssp = ssp->next)
{
#ifdef DEBUG
fprintf(stderr, "reconcile_variables: ss=%s\n", ssp->value);
#endif DEBUG
traverseExprTree(ssp, E_VAR, 0, connect_variable, 0);
}
/* Same for exit procedure */
for (ep = exit_code_list; ep != 0; ep = ep->next)
{
traverseExprTree(ep, E_VAR, 0, connect_variable, 0);
}
}
/* Connect a variable in an expression to the the Var structure */
int connect_variable(ep)
Expr *ep;
{
Var *vp;
extern char *stype[];
extern int warn_flag;
vp = (Var *)find_var(ep->value);
if (vp == 0)
{ /* variable not declared; enter into variable list */
if (warn_flag)
fprintf(stderr,
"Warning: variable \"%s\" is used but not declared.\n",
ep->value);
vp = allocVar();
lstAdd(&var_list, (NODE *)vp);
vp->name = ep->value;
vp->type = V_NONE; /* undeclared type */
vp->length = 0;
vp->value = 0;
}
ep->left = (Expr *)vp; /* make connection */
#ifdef DEBUG
fprintf(stderr, "connect_variable: %s\n", ep->value);
#endif
return;
}
/* Reconcile state names */
reconcile_states()
{
extern LIST var_list;
extern int num_errors;
Expr *ssp, *sp, *sp1, tr;
for (ssp = ss_list; ssp != 0; ssp = ssp->next)
{
for (sp = ssp->left; sp != 0; sp = sp->next)
{
/* Check for duplicate state names in this state set */
for (sp1 = sp->next; sp1 != 0; sp1 = sp1->next)
{
if (strcmp(sp->value, sp1->value) == 0)
{
fprintf(stderr,
"State \"%s\" is duplicated in state set \"%s\"\n",
sp->value, ssp->value);
num_errors++;
}
}
}
}
}
/* Find a state by name */
Expr *find_state(name, sp)
char *name; /* state name */
Expr *sp; /* beginning of state list */
{
while (sp != 0)
{
if (strcmp(name, sp->value) == 0)
return sp;
sp = sp->next;
}
return 0;
}
/* Generate a C variable declaration for each variable declared in SNL */
gen_var_decl()
{
extern LIST var_list;
Var *vp;
char *vstr, *vname="User_Var_";
int nv;
extern LIST var_list;
Var *vp;
char *vstr;
int nv;
extern int reent_flag;
printf("\n/* Variable declarations */\n");
for (nv=0, vp = firstVar(&var_list); vp != NULL; nv++, vp = nextVar(vp))
{
if (vp->type != V_EVFLAG)
printf("#define %s %s.var%d\n", vp->name, vname, nv);
}
printf("static struct %s {\n", vname);
/* Convert internal type to `C' type */
if (reent_flag)
printf("static struct UserVar {\n");
for (nv=0, vp = firstVar(&var_list); vp != NULL; nv++, vp = nextVar(vp))
{
switch (vp->type)
@@ -119,7 +212,8 @@ gen_var_decl()
vstr = "char";
break;
case V_INT:
vstr = "int";
case V_LONG:
vstr = "long";
break;
case V_SHORT:
vstr = "short";
@@ -134,290 +228,74 @@ gen_var_decl()
vstr = "char";
break;
case V_EVFLAG:
case V_NONE:
vstr = NULL;
break;
default:
vstr = "int";
break;
}
if (vstr != NULL)
{
printf("\t%s\tvar%d", vstr, nv);
/* Array? */
if (vp->length > 0)
printf("[%d];\n", vp->length);
else if (vp->type == V_STRING)
printf("[MAX_STRING_SIZE];\n");
if (reent_flag)
printf("\t");
else
printf(";\n");
printf("static ");
printf("%s\t%s", vstr, vp->name);
if (vp->length > 0)
printf("[%d]", vp->length);
else if (vp->type == V_STRING)
printf("[MAX_STRING_SIZE]");
printf(";\n");
}
}
printf("} %s;\n", vname);
if (reent_flag)
printf("};\n");
return;
}
/* Generate definition C code (C code in definition section) */
gen_defn_c_code()
{
extern LIST defn_c_list;
Action *ap;
extern Expr *defn_c_list;
Expr *ep;
ap = firstAction(&defn_c_list);
if (ap != NULL)
ep = defn_c_list;
if (ep != NULL)
{
printf("\n\t/* C code definitions */\n");
for (; ap != NULL; ap = nextAction(ap))
for (; ep != NULL; ep = ep->next)
{
print_line_num(ap->line_num);
printf("%s\n", ap->stmt.c_code);
print_line_num(ep->line_num, ep->src_file);
printf("%s\n", ep->left);
}
}
return;
}
/* Generate the structure with data for a state program table (SPROG) */
gen_state_prog_table()
/* Generate global C code (C code following state program) */
gen_global_c_code()
{
extern char *prog_param;
extern Expr *global_c_list;
Expr *ep;
printf("\n/* Program parameter list */\n");
printf("static char prog_param[] = \"%s\";\n", prog_param);
printf("\n/* State Program table (global) */\n");
printf("SPROG %s = {\n", prog_name);
printf("\t%d,\t/* magic number */\n", MAGIC);
printf("\t0,\t/* task id */\n");
printf("\t0,\t/* task_is_deleted */\n");
printf("\t1,\t/* relative task priority */\n");
printf("\t0,\t/* sem_id */\n");
printf("\tdb_channels,\t/* *channels */\n");
printf("\tNUM_CHANNELS,\t/* nchan */\n");
printf("\tsscb,\t/* *sscb */\n");
printf("\tNUM_SS,\t/* nss */\n");
printf("\t&User_Var_,\t/* ptr to user area */\n");
printf("\t4,\t/* user area size */\n");
printf("\t\"%s\",\t/* *name */\n", prog_name);
printf("\tprog_param\t/* *params */\n");
printf("};\n");
return;
}
/* Generate database blocks with structure and data for each defined channel */
gen_db_blocks()
{
extern LIST chan_list;
Chan *cp;
int nchan;
printf("\n/* Database Blocks */\n");
printf("static CHAN db_channels[NUM_CHANNELS] = {\n");
nchan = 0;
for (cp = firstChan(&chan_list); cp != NULL; cp = nextChan(cp))
ep = global_c_list;
if (ep != NULL)
{
/* Only process db variables */
if (cp->db_name != NULL)
printf("\f\t/* Global C code */\n");
for (; ep != NULL; ep = ep->next)
{
if (nchan > 0)
printf(",\n");
fill_db_block(cp);
nchan++;
print_line_num(ep->line_num, ep->src_file);
printf("%s\n", ep->left);
}
}
printf("\n};\n");
return;
}
/* Fill in a db block with data (all elements for "CHAN" struct) */
fill_db_block(cp)
Chan *cp;
{
Var *vp;
char *dbr_type_string;
extern char *prog_name;
int size, ev_flag;
vp = cp->var;
switch (vp->type)
{
case V_SHORT:
dbr_type_string = "DBR_INT";
size = sizeof(short);
break;
case V_INT:
dbr_type_string = "DBR_INT";
size = sizeof(int);
break;
case V_CHAR:
dbr_type_string = "DBR_INT";
size = sizeof(char);
break;
case V_FLOAT:
dbr_type_string = "DBR_FLOAT";
size = sizeof(float);
break;
case V_DOUBLE:
dbr_type_string = "DBR_FLOAT";
size = sizeof(double);
break;
case V_STRING:
dbr_type_string = "DBR_STRING";
size = sizeof(char);
break;
}
/* fill in the CHAN structure */
printf("\t\"%s\"", cp->db_name);/* unexpanded db channel name */
printf(", (char *) 0"); /* ch'l name after macro expansion */
printf(", (chid)0"); /* reserve place for chid */
if (vp->type == V_STRING)
printf(", %s", vp->name); /* variable ptr */
else
printf(", &%s", vp->name); /* variable ptr */
if (vp->length != 0)
printf("[%d]", cp->offset); /* array offset */
printf(", %d", size); /* element size (bytes) */
printf(",\n\t %s", dbr_type_string);/* DB request conversion type */
printf(", %d", vp->length); /* array length (of the variable) */
printf(", %d", cp->mon_flag); /* monitor flag */
printf(", %d", cp->length); /* count for db requests */
printf(", %g", cp->delta); /* monitor delta */
printf(", %g", cp->timeout); /* monitor timeout */
printf(", &%s", prog_name); /* ptr to state program structure */
vp = cp->ef_var;
if (vp == 0)
ev_flag = 0;
else
ev_flag = 1 << vp->ef_num;
printf(", %d", ev_flag); /* sync event flag */
return;
}
/* Generate structure and data for state blocks (STATE) */
gen_state_blocks()
{
extern LIST ss_list;
StateSet *ssp;
State *sp;
int nstates;
printf("\n/* State Blocks */\n");
printf("/* action_func, event_func, delay_func, event_flag_mask");
printf(", *delay, *name */\n");
for (ssp = firstSS(&ss_list); ssp != NULL; ssp = nextSS(ssp))
{
printf("\nstatic STATE state_%s[] = {\n", ssp->ss_name);
nstates = 0;
for (sp = firstState(&ssp->S_list); sp != NULL; sp = nextState(sp))
{
if (nstates > 0)
printf(",\n\n");
nstates++;
fill_state_block(sp, ssp->ss_name);
}
printf("\n};\n");
}
return;
}
/* Fill in data for a the state block */
fill_state_block(sp, ss_name)
State *sp;
char *ss_name;
{
printf("\t/* State \"%s\"*/\n", sp->state_name);
printf("\ta_%s_%s,\t/* action_function */\n", ss_name, sp->state_name);
printf("\te_%s_%s,\t/* event_function */\n", ss_name, sp->state_name);
printf("\td_%s_%s,\t/* delay_function */\n", ss_name, sp->state_name);
printf("\t%d,\t/* event_flag_mask */\n", sp->event_flag_mask);
printf("\t\"%s\"\t/* *name */", sp->state_name);
return;
}
/* Generate a state set control block (SSCB) for each state set */
gen_sscb_array()
{
extern LIST ss_list;
StateSet *ssp;
int nss, nstates, n;
printf("\n/* State Set Control Blocks */\n");
printf("static SSCB sscb[NUM_SS] = {\n");
nss = 0;
for (ssp = firstSS(&ss_list); ssp != NULL; ssp = nextSS(ssp))
{
if (nss > 0)
printf(",\n\n");
nss++;
nstates = lstCount((NODE *)&ssp->S_list);
printf("\t/* State set \"%s\"*/\n", ssp->ss_name);
printf("\t0, 1, 0,\t/* task_id, task_prioity, sem_id */\n");
printf("\t0, 0,\t\t/* event_flag, event_flag_mask */\n");
printf("\t%d, state_%s,\t/* num_states, *states */\n", nstates,
ssp->ss_name);
printf("\tNULL, NULL,\t/* *current_state, *next_state */\n");
printf("\t0, FALSE,\t/* trans_number, action_complete */\n");
printf("\t%d,\t/* number of time-out structures */\n", ssp->ndelay);
printf("\t/* array of time-out values: */\n\t");
for (n = 0; n < MAX_NDELAY; n++)
printf("0,");
printf("\n");
printf("\t0,\t/* time (ticks) when state was entered */\n");
printf("\t\"%s\"\t\t/* ss_name */", ssp->ss_name);
}
printf("\n};\n");
return;
}
/* Returns number of db channels defined & inserts index into each channel struct */
db_chan_count()
{
extern LIST var_list;
extern LIST chan_list;
int nchan;
Chan *cp;
@@ -428,48 +306,156 @@ db_chan_count()
{
cp->index = nchan;
nchan++;
#ifdef DEBUG
fprintf(stderr, "db_name=%s, index=%d\n",
cp->db_name, cp->index);
#endif
}
}
return nchan;
}
/* Given a state name and state set struct, find the corresponding
state struct and return its index (1-st one is 0) */
state_block_index_from_name(ssp, state_name)
StateSet *ssp;
char *state_name;
{
State *sp;
int index;
index = 0;
for (sp = firstState(&ssp->S_list); sp != NULL; sp = nextState(sp))
{
if (strcmp(state_name, sp->state_name) == 0)
return index;
index++;
}
return -1; /* State name non-existant */
}
/* Assign bits to event flags */
/* Assign bits to event flags and database variables */
assign_ef_bits()
{
extern LIST var_list;
Var *vp;
int ef_num;
extern LIST var_list;
Var *vp;
Chan *cp;
int ef_num;
extern int num_channels;
ef_num = 0;
ef_num = num_channels + 1; /* start with 1-st avail mask bit */
printf("\n/* Event flags */\n");
#ifdef DEBUG
fprintf(stderr, "\nAssign values to event flags\n");
#endif
for (vp = firstVar(&var_list); vp != NULL; vp = nextVar(vp))
{
cp = vp->chan;
/* First see if this is an event flag */
if (vp->type == V_EVFLAG)
{
vp->ef_num = ef_num;
printf("#define %s (1<<%d)\n", vp->name, ef_num);
ef_num++;
if (cp != 0)
vp->ef_num = cp->index + 1; /* sync'ed */
else
vp->ef_num = ef_num++;
printf("#define %s\t%d\n", vp->name, vp->ef_num);
}
else
{
if (cp != 0)
vp->ef_num = cp->index + 1;
}
#ifdef DEBUG
fprintf(stderr, "%s: ef_num=%d\n", vp->name, vp->ef_num);
#endif
}
return;
}
/* Assign a delay id to each "delay()" in an event (when()) expression */
assign_delay_ids()
{
extern Expr *ss_list;
Expr *ssp, *sp, *tp;
int delay_id;
int assign_next_delay_id();
for (ssp = ss_list; ssp != 0; ssp = ssp->next)
{
for (sp = ssp->left; sp != 0; sp = sp->next)
{
/* Each state has it's own delay id's */
delay_id = 0;
for (tp = sp->left; tp != 0; tp = tp->next)
{ /* traverse event expression only */
traverseExprTree(tp->left, E_FUNC, "delay",
assign_next_delay_id, &delay_id);
}
}
}
}
assign_next_delay_id(ep, delay_id)
Expr *ep;
int *delay_id;
{
ep->right = (Expr *)*delay_id;
*delay_id += 1;
}
/* Traverse the expression tree, and call the supplied
* function on matched conditions */
traverseExprTree(ep, type, value, funcp, argp)
Expr *ep; /* ptr to start of expression */
int type; /* to search for */
char *value; /* with optional matching value */
void (*funcp)(); /* function to call */
void *argp; /* ptr to argument to pass on to function */
{
Expr *ep1;
extern char *stype[];
if (ep == 0)
return;
if (printTree)
fprintf(stderr, "traverseExprTree: type=%s, value=%s\n",
stype[ep->type], ep->value);
/* Call the function? */
if ((ep->type == type) &&
(value == 0 || strcmp(ep->value, value) == 0) )
{
funcp(ep, argp);
}
/* Continue traversing the expression tree */
switch(ep->type)
{
case E_EMPTY:
case E_VAR:
case E_CONST:
case E_STRING:
case E_TEXT:
break;
case E_PAREN:
case E_UNOP:
case E_SS:
case E_STATE:
case E_FUNC:
case E_CMPND:
case E_STMT:
case E_ELSE:
for (ep1 = ep->left; ep1 != 0; ep1 = ep1->next)
{
traverseExprTree(ep1, type, value, funcp, argp);
}
break;
case E_WHEN:
case E_ASGNOP:
case E_BINOP:
case E_SUBSCR:
case E_IF:
case E_WHILE:
for (ep1 = ep->left; ep1 != 0; ep1 = ep1->next)
{
traverseExprTree(ep1, type, value, funcp, argp);
}
for (ep1 = ep->right; ep1 != 0; ep1 = ep1->next)
{
traverseExprTree(ep1, type, value, funcp, argp);
}
break;
default:
fprintf(stderr, "traverseExprTree: type=%d???\n", ep->type);
}
}

View File

@@ -3,7 +3,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)seq_ca.c 1.7 2/4/91
@(#)seq_ca.c 1.10 4/24/91
DESCRIPTION: Seq_ca.c: Channel access interface for sequencer
ENVIRONMENT: VxWorks
@@ -13,140 +13,354 @@
#include "vxWorks.h"
#include "taskLib.h"
/*#define DEBUG*/
#define MACRO_STR_LEN (MAX_STRING_SIZE+1)
/* Connect to the database channels through channel access */
connect_db_channels(sp_ptr, macro_tbl)
SPROG *sp_ptr;
struct macro *macro_tbl;
connect_db_channels(sp_ptr)
SPROG *sp_ptr;
{
CHAN *db_ptr;
int status, i;
CHAN *db_ptr;
int status, i;
MACRO *macro_tbl;
extern seq_conn_handler();
/* Initialize CA task */
ca_task_initialize();
sp_ptr->conn_count = 0;
macro_tbl = sp_ptr->mac_ptr;
/* Search for all channels */
db_ptr = sp_ptr->channels;
for (i = 0; i < sp_ptr->nchan; i++)
{
/* Do macro substitution */
db_ptr->db_name = seqAlloc(MACRO_STR_LEN);
macEval(db_ptr->db_uname, db_ptr->db_name, MACRO_STR_LEN,
/* Do macro substitution on channel name */
db_ptr->db_name = seqAlloc(sp_ptr, MACRO_STR_LEN);
seqMacEval(db_ptr->db_uname, db_ptr->db_name, MACRO_STR_LEN,
macro_tbl);
printf(" %d: %s\n", i, db_ptr->db_name);
status = ca_search(db_ptr->db_name, &(db_ptr->chid));
#ifdef DEBUG
printf("connect to \"%s\"\n", db_ptr->db_name);
#endif DEBUG
/* Connect to it */
status = ca_build_and_connect(
db_ptr->db_name, /* DB channel name */
TYPENOTCONN, /* Don't get initial value */
0, /* get count (n/a) */
&(db_ptr->chid), /* ptr to chid */
0, /* ptr to value (n/a) */
seq_conn_handler, /* connection handler routine */
db_ptr); /* user ptr is CHAN structure */
if (status != ECA_NORMAL)
{
SEVCHK(status, "ca_search");
ca_task_exit();
return -1;
}
db_ptr++;
}
/* Clear monitor indicator */
db_ptr->monitored = FALSE;
/* Wait for returns from "ca_search" */
status = ca_pend_io(10.0);
if (status != ECA_NORMAL)
{
SEVCHK(status, "ca_pend_io");
return -1;
}
#ifdef DEBUG
db_ptr = sp_ptr->channels;
for (i = 0; i < sp_ptr->nchan; i++)
{
printf("\"%s\" ca_search() returned: chid=0x%x\n",
db_ptr->db_name, db_ptr->chid);
db_ptr++;
}
#endif
printf("All db channels connected\n");
return 0;
}
/* Issue monitor requests */
issue_monitor_requests(sp_ptr)
SPROG *sp_ptr;
{
CHAN *db_ptr;
int status, i;
int seq_event_handler();
db_ptr = sp_ptr->channels;
for (i = 0; i < sp_ptr->nchan; i++)
{
/* Issue monitor requests */
if (db_ptr->mon_flag)
{
status = ca_add_general_event(
db_ptr->dbr_type, /* requested type */
db_ptr->chid, /* chid */
seq_event_handler, /* function to call */
db_ptr, /* user arg is db entry */
db_ptr->delta, /* pos. delta value */
db_ptr->delta, /* neg. delta value */
db_ptr->timeout, /* timeout */
0 /* no event id */);
if (status != ECA_NORMAL)
{
SEVCHK(status, "ca_search");
ca_task_exit();
return -1;
}
seq_pvMonitor(sp_ptr, 0, db_ptr);
}
db_ptr++;
}
ca_flush_io();
if (sp_ptr->conn_flag)
{ /* Wait for all connections to complete */
while (sp_ptr->conn_count < sp_ptr->nchan)
taskDelay(30);
}
return 0;
}
/* Channel access events (monitors) come here */
seq_event_handler(args)
struct event_handler_args args;
{
SPROG *sp_ptr;
SSCB *ss_ptr;
CHAN *db_ptr;
int i, nbytes, count;
int nss;
SPROG *sp_ptr;
CHAN *db_ptr;
struct dbr_sts_char *dbr_sts_ptr;
int i, nbytes;
/* User arg is ptr to db channel structure */
db_ptr = (CHAN *)args.usr;
/* Get ptr to data & status structure */
dbr_sts_ptr = (struct dbr_sts_char *)args.dbr;
/* Copy value returned into user variable */
count = db_ptr->count;
if (count == 0)
count = 1;
nbytes = db_ptr->size * count;
bcopy(args.dbr, db_ptr->var, nbytes);
#ifdef DEBUG
printf("seq_event_handler: ");
if (db_ptr->dbr_type == DBR_FLOAT)
printf("%s=%g\n", db_ptr->db_name, *(float *)db_ptr->var);
else if (db_ptr->dbr_type == DBR_INT)
{
i = *(short *)args.dbr;
printf("%s=%d\n", db_ptr->db_name, i);
}
else
printf("?\n");
#endif DEBUG
nbytes = db_ptr->size * db_ptr->count;
bcopy(&(dbr_sts_ptr->value), db_ptr->var, nbytes);
/* Copy status & severity */
db_ptr->status = dbr_sts_ptr->status;
db_ptr->severity = dbr_sts_ptr->severity;
/* Process event handling in each state set */
sp_ptr = db_ptr->sprog; /* State program that owns this db entry */
/* Set synchronization event flag (if it exists) for each state set */
if (db_ptr->ev_flag != 0)
seq_efSet(sp_ptr, 0, db_ptr->ev_flag);
/* Wake up each state set that is waiting for event processing */
ss_ptr = sp_ptr->sscb;
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
seq_efSet(sp_ptr, 0, db_ptr->index + 1);
return 0;
}
/* Sequencer connection handler:
Called each time a connection is established or broken */
seq_conn_handler(args)
struct connection_handler_args args;
{
CHAN *db_ptr;
SPROG *sp_ptr;
/* user argument (from ca_search() */
db_ptr = (CHAN *)ca_puser(args.chid);
/* State program that owns this db entry */
sp_ptr = db_ptr->sprog;
/* Check for connected */
if (ca_field_type(args.chid) == TYPENOTCONN)
{
if (ss_ptr->action_complete)
db_ptr->connected = FALSE;
sp_ptr->conn_count--;
seqLog(sp_ptr, "Channel \"%s\" disconnected\n", db_ptr->db_name);
}
else
{
db_ptr->connected = TRUE;
sp_ptr->conn_count++;
seqLog(sp_ptr, "Channel \"%s\" connected\n", db_ptr->db_name);
if (db_ptr->count > ca_element_count(args.chid))
{
semGive(ss_ptr->sem_id);
db_ptr->count = ca_element_count(args.chid);
seqLog(sp_ptr, "\"%s\": reset count to %d\n",
db_ptr->db_name, db_ptr->count);
}
}
/* Wake up each state set that is waiting for event processing */
seq_efSet(sp_ptr, 0, 0);
return;
}
/* Wake up each state set that is waiting for event processing */
seq_efSet(sp_ptr, dummy, ev_flag)
SPROG *sp_ptr;
void *dummy;
int ev_flag; /* event flag */
{
SSCB *ss_ptr;
int nss;
ss_ptr = sp_ptr->sscb;
/* For all state sets: */
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
{
/* Apply resource lock */
semTake(sp_ptr->sem_id, 0);
/* Test for possible event trig based on bit mask for this state */
if ( (ev_flag == 0) || bitTest(ss_ptr->pMask, ev_flag) )
{
bitSet(ss_ptr->events, ev_flag);
semGive(ss_ptr->sem_id); /* wake up the ss task */
}
/* Unlock resource */
semGive(sp_ptr->sem_id);
}
}
/* Test event flag against outstanding events */
seq_efTest(sp_ptr, ss_ptr, ev_flag)
SPROG *sp_ptr;
SSCB *ss_ptr;
int ev_flag; /* event flag */
{
return bitTest(ss_ptr->events, ev_flag);
}
/* Get DB value (uses channel access) */
seq_pvGet(sp_ptr, ss_ptr, db_ptr)
SPROG *sp_ptr; /* ptr to state program */
SSCB *ss_ptr; /* ptr to current state set */
CHAN *db_ptr; /* ptr to channel struct */
{
int status;
extern seq_callback_handler();
extern int async_flag;
/* Check for channel connected */
if (!db_ptr->connected)
return ECA_DISCONN;
db_ptr->get_complete = 0;
/* Asynchronous get? */
if (sp_ptr->async_flag)
{
status = ca_array_get_callback(
db_ptr->get_type, /* db request type */
db_ptr->count, /* element count */
db_ptr->chid, /* chid */
seq_callback_handler, /* callback handler */
db_ptr); /* user arg */
/* Note: CA buffer is not flushed */
return status;
}
/* Synchronous get (wait for completion) */
status = ca_array_get(
db_ptr->put_type, /* db request type */
db_ptr->count, /* element count */
db_ptr->chid, /* chid */
db_ptr->var); /* value */
if (status == ECA_BADTYPE)
{
seqLog(sp_ptr, "Bad type: pvGet() on %s\n", db_ptr->db_name);
return status;
}
if (status == ECA_BADCHID)
{
seqLog(sp_ptr, "Disconencted: pvGet() on %s\n", db_ptr->db_name);
return status;
}
/* Wait for completion */
status = ca_pend_io(10.0);
db_ptr->get_complete = TRUE;
if (status != ECA_NORMAL)
{
seqLog(sp_ptr, "time-out: pvGet() on %s\n", db_ptr->db_name);
}
return status;
}
/* Sequencer callback handler - called when a "get" completes */
seq_callback_handler(args)
struct event_handler_args args;
{
SPROG *sp_ptr;
CHAN *db_ptr;
struct dbr_sts_char *dbr_sts_ptr;
int i, nbytes;
/* User arg is ptr to db channel structure */
db_ptr = (CHAN *)args.usr;
/* Get ptr to data & status structure */
dbr_sts_ptr = (struct dbr_sts_char *)args.dbr;
/* Copy value returned into user variable */
nbytes = db_ptr->size * db_ptr->count;
bcopy(&(dbr_sts_ptr->value), db_ptr->var, nbytes);
/* Copy status & severity */
db_ptr->status = dbr_sts_ptr->status;
db_ptr->severity = dbr_sts_ptr->severity;
/* Set get complete flag */
db_ptr->get_complete = TRUE;
return 0;
}
/* Flush requests */
seq_pvFlush()
{
ca_flush_io();
}
/* Put DB value (uses channel access) */
seq_pvPut(sp_ptr, ss_ptr, db_ptr)
SPROG *sp_ptr; /* ptr to state program */
SSCB *ss_ptr; /* ptr to current state set */
CHAN *db_ptr; /* ptr to channel struct */
{
int status;
if (!db_ptr->connected)
return ECA_DISCONN;
status = ca_array_put(db_ptr->put_type, db_ptr->count,
db_ptr->chid, db_ptr->var);
if (status != ECA_NORMAL)
{
seqLog(sp_ptr, "pvPut on \"%s\" failed (%d)\n",
db_ptr->db_name, status);
seqLog(sp_ptr, " put_type=%d\n", db_ptr->put_type);
seqLog(sp_ptr, " size=%d, count=%d\n", db_ptr->size, db_ptr->count);
}
return status;
}
/* Initiate a monitor on a channel */
seq_pvMonitor(sp_ptr, ss_ptr, db_ptr)
SPROG *sp_ptr; /* ptr to state program */
SSCB *ss_ptr; /* ptr to current state set */
CHAN *db_ptr; /* ptr to channel struct */
{
int status;
extern seq_event_handler();
#ifdef DEBUG
printf("monitor \"%s\"\n", db_ptr->db_name);
#endif DEBUG
if (db_ptr->monitored)
return -1;
status = ca_add_array_event(
db_ptr->get_type, /* requested type */
db_ptr->count, /* element count */
db_ptr->chid, /* chid */
seq_event_handler, /* function to call */
db_ptr, /* user arg (db struct) */
db_ptr->delta, /* pos. delta value */
db_ptr->delta, /* neg. delta value */
db_ptr->timeout, /* timeout */
&db_ptr->evid); /* where to put event id */
if (status != ECA_NORMAL)
{
SEVCHK(status, "ca_add_array_event");
ca_task_exit(); /* this is serious */
return -1;
}
ca_flush_io();
db_ptr->monitored = TRUE;
return 0;
}
/* Cancel a monitor */
seq_pvStopMonitor(sp_ptr, ss_ptr, db_ptr)
SPROG *sp_ptr; /* ptr to state program */
SSCB *ss_ptr; /* ptr to current state set */
CHAN *db_ptr; /* ptr to channel struct */
{
int status;
if (!db_ptr->monitored)
return -1;
status = ca_clear_event(db_ptr->evid);
if (status != ECA_NORMAL)
{
SEVCHK(status, "ca_clear_event");
return status;
}
db_ptr->monitored = FALSE;
return 0;
}

View File

@@ -3,7 +3,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)seq_mac.c 1.1 11/9/90
@(#)seq_mac.c 1.3 4/23/91
DESCRIPTION: Macro routines for Sequencer.
ENVIRONMENT: VxWorks
@@ -13,17 +13,10 @@
#include "vxWorks.h"
#include "seq.h"
LOCAL int macNameLth();
LOCAL int macParseName();
LOCAL int macParseValue();
LOCAL char *skipBlanks();
/*#define DEBUG*/
/* #define DEBUG */
/* macTblInit - initialize macro table */
macTblInit(mac_ptr)
/* seqMacTblInit - initialize macro table */
seqMacTblInit(mac_ptr)
MACRO *mac_ptr;
{
int i;
@@ -35,17 +28,17 @@ MACRO *mac_ptr;
}
}
/* macEval - substitute macro value into a string */
macEval(pInStr, pOutStr, maxChar, macTbl)
/* seqMacEval - substitute macro value into a string */
seqMacEval(pInStr, pOutStr, maxChar, macTbl)
char *pInStr;
char *pOutStr;
MACRO *macTbl;
{
char *pMacVal, *pTmp;
int nameLth, valLth;
char *pMacVal, *pTmp;
int nameLth, valLth;
#ifdef DEBUG
printf("macEval: InStr=%s\n", pInStr);
printf("seqMacEval: InStr=%s\n", pInStr);
#endif
pTmp = pOutStr;
while (*pInStr != 0 && maxChar > 0)
@@ -58,7 +51,7 @@ MACRO *macTbl;
printf("Name=%s[%d]\n", pInStr, nameLth);
#endif
/* Find macro value from macro name */
pMacVal = macValGet(pInStr, nameLth, macTbl);
pMacVal = seqMacValGet(pInStr, nameLth, macTbl);
if (pMacVal != NULL)
{ /* Substitute macro value */
valLth = strlen(pMacVal);
@@ -89,8 +82,8 @@ MACRO *macTbl;
*pOutStr == 0;
}
/* macValGet - given macro name, return pointer to its value */
char *macValGet(macName, macNameLth, macTbl)
/* seqMacValGet - given macro name, return pointer to its value */
char *seqMacValGet(macName, macNameLth, macTbl)
char *macName;
int macNameLth;
MACRO *macTbl;
@@ -125,20 +118,22 @@ char *pstr;
}
return nchar;
}
/* macParse - parse the macro definition string and build
/* 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.
*/
int macParse(pMacStr, macTbl)
char *pMacStr; /* macro definition string */
MACRO *macTbl; /* macro table */
int seqMacParse(pMacStr, sp_ptr)
char *pMacStr; /* macro definition string */
SPROG *sp_ptr;
{
int nMac, nChar;
char *skipBlanks();
MACRO *pMacTbl;
MACRO *macTbl; /* macro table */
MACRO *pMacTbl; /* macro tbl entry */
char *name, *value;
macTbl = sp_ptr->mac_ptr;
for ( ;; )
{
/* Skip blanks */
@@ -146,10 +141,10 @@ MACRO *macTbl; /* macro table */
/* Parse the macro name */
nChar = macParseName(pMacStr);
nChar = seqMacParseName(pMacStr);
if (nChar == 0)
break; /* finished or error */
name = seqAlloc(nChar+1);
name = seqAlloc(sp_ptr, nChar+1);
if (name == NULL)
break;
bcopy(pMacStr, name, nChar);
@@ -160,7 +155,7 @@ MACRO *macTbl; /* macro table */
pMacStr += nChar;
/* Find a slot in the table */
pMacTbl = macTblGet(name, macTbl);
pMacTbl = seqMacTblGet(name, macTbl);
if (pMacTbl == NULL)
break; /* table is full */
if (pMacTbl->name == NULL)
@@ -180,10 +175,10 @@ MACRO *macTbl; /* macro table */
pMacStr = skipBlanks(pMacStr);
/* Parse the value */
nChar = macParseValue(pMacStr);
nChar = seqMacParseValue(pMacStr);
if (nChar == 0)
break;
value = seqAlloc(nChar+1);
value = seqAlloc(sp_ptr, nChar+1);
if (value == NULL)
break;
bcopy(pMacStr, value, nChar);
@@ -208,7 +203,7 @@ MACRO *macTbl; /* macro table */
}
LOCAL int macParseName(pStr)
LOCAL int seqMacParseName(pStr)
char *pStr;
{
int nChar;
@@ -228,7 +223,7 @@ char *pStr;
return nChar;
}
LOCAL int macParseValue(pStr)
LOCAL int seqMacParseValue(pStr)
char *pStr;
{
int nChar;
@@ -251,9 +246,9 @@ char *pChar;
return pChar;
}
/* macTblGet - find a match for the specified name, otherwise
/* seqMacTblGet - find a match for the specified name, otherwise
return an empty slot in macro table */
LOCAL MACRO *macTblGet(name, macTbl)
LOCAL MACRO *seqMacTblGet(name, macTbl)
char *name; /* macro name */
MACRO *macTbl;
{
@@ -261,7 +256,7 @@ MACRO *macTbl;
MACRO *pMacTbl;
#ifdef DEBUG
printf("macTblGet: name=%s\n", name);
printf("seqMacTblGet: name=%s\n", name);
#endif
for (i = 0, pMacTbl = macTbl; i < MAX_MACROS; i++, pMacTbl++)
{

View File

@@ -3,15 +3,18 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)seq.c 1.8 2/1/91
@(#)seq_main.c 1.2 4/23/91
DESCRIPTION: Seq() initiates a sequence as a group of cooperating
tasks. An optional string parameter specifies the values for
macros.
ENVIRONMENT: VxWorks
HISTORY:
23apr91,ajk Fixed problem with state program invoking the sequencer.
***************************************************************************/
/* #define DEBUG 1 */
/*#define DEBUG 1*/
#include "seq.h"
#include "vxWorks.h"
@@ -19,6 +22,8 @@
#define SCRATCH_SIZE (MAX_MACROS*(MAX_STRING_SIZE+1)*12)
/*#define DEBUG*/
/* The following variable points to the area allocated for the
parent state program and its corresponding state sets.
It is declared a "task variable" and is shared by only these
@@ -26,94 +31,52 @@
It is also used as a flag to indicate that the "taskDeleteHookAdd()"
routine has been called (we only want to do that once after VxWorks boots).
*/
LOCAL TASK *alloc_task_area();
LOCAL count_states();
LOCAL copy_sprog();
LOCAL init_sprog();
LOCAL init_sscb();
TASK *task_area_ptr = NULL;
SPROG *seq_task_ptr = NULL;
/* User entry routine to initiate a state program */
seq(sp_ptr, macro_def, stack_size)
SPROG *sp_ptr; /* ptr to state program table */
char *macro_def; /* macro def'n string */
int stack_size; /* stack size */
seq(sp_ptr_orig, macro_def, stack_size)
SPROG *sp_ptr_orig; /* ptr to original state program table */
char *macro_def; /* macro def'n string */
int stack_size; /* stack size */
{
int status;
extern sequencer(), sprog_delete();
extern char *seqVersion;
int status;
extern sequencer(), sprog_delete();
extern char *seqVersion;
SPROG *sp_ptr, *alloc_task_area();
extern SPROG *seq_task_ptr;
char *seqMacValGet(), *pname, *pvalue, *ptask_name;
/* If no parameters specified, print version info. */
if (sp_ptr == 0)
if (sp_ptr_orig == 0)
{
printf("%s\n", seqVersion);
return 0;
}
/* Check for correct state program format */
if (sp_ptr->magic != MAGIC)
if (sp_ptr_orig->magic != MAGIC)
{ /* Oops */
printf("Illegal magic number in state program\n");
logMsg("Illegal magic number in state program\n");
return -1;
}
/* Specify a routine to run at task delete */
if (task_area_ptr == NULL)
{
taskDeleteHookAdd(sprog_delete);
task_area_ptr = (TASK *)ERROR;
}
/* Specify stack size */
if (stack_size < SPAWN_STACK_SIZE)
stack_size = SPAWN_STACK_SIZE;
/* Spawn the sequencer main task */
printf("Spawning state program \"%s\"\n", sp_ptr->name);
status = taskSpawn(sp_ptr->name, SPAWN_PRIORITY,
SPAWN_OPTIONS, stack_size,
sequencer, sp_ptr, macro_def, stack_size);
return status;
}
/* Sequencer main task entry point */
sequencer(sp_ptr_orig, macro_def, stack_size)
SPROG *sp_ptr_orig; /* ptr to original (global) state program table */
char *macro_def; /* macro def'n string */
int stack_size; /* stack size */
{
int tid, nmac, nss, nstates, nchannels, user_size;
TASK *alloc_task_area();
extern TASK *task_area_ptr;
SPROG *sp_ptr;
MACRO *mac_ptr;
char macroTmp[100]; /* for macro names & values */
tid = taskIdSelf(); /* my task id */
/* Allocate a contiguous space for all task structures */
task_area_ptr = alloc_task_area(sp_ptr_orig);
#ifdef DEBUG
printf("task_area_ptr=%d, *task_area_ptr=%d\n", task_area_ptr, *task_area_ptr);
print_sp_info(sp_ptr_orig);
#endif DEBUG
/* Make "task_area_ptr" a task variable */
if (taskVarAdd(tid, &task_area_ptr) != OK)
/* Specify a routine to run at task delete */
if (seq_task_ptr == NULL)
{
printf("taskVarAdd failed\n");
return -1;
taskDeleteHookAdd(sprog_delete);
seq_task_ptr = (SPROG *)ERROR;
}
sp_ptr_orig->task_id = tid;
sp_ptr = task_area_ptr->sp_ptr;
mac_ptr = task_area_ptr->mac_ptr;
/* Allocate a contiguous space for all dynamic structures */
sp_ptr = alloc_task_area(sp_ptr_orig);
/* Make a private copy of original structures (but change pointers!) */
copy_sprog(sp_ptr_orig, task_area_ptr);
if (sp_ptr_orig->reent_flag)
copy_sprog(sp_ptr_orig, sp_ptr);
/* Initialize state program block */
init_sprog(sp_ptr);
@@ -122,132 +85,204 @@ int stack_size; /* stack size */
init_sscb(sp_ptr);
/* Initialize the macro definition table */
macTblInit(mac_ptr); /* Init macro table */
seqMacTblInit(sp_ptr->mac_ptr); /* Init macro table */
/* Parse the macro definitions */
macParse(macro_def, mac_ptr);
/* Parse the macro definitions from the "program" statement */
seqMacParse(sp_ptr->params, sp_ptr);
/* Connect to DB channels */
connect_db_channels(sp_ptr, mac_ptr);
/* Issue monitor requests */
issue_monitor_requests(sp_ptr);
/* Create the state set tasks */
create_ss_tasks(sp_ptr, stack_size);
/* Note: No return from task */
}
/* Allocate the task area. This area will hold all state program structures:
|***************|
| TASK |---|
|***************| |
| SPROG | |
|***************| V Ptrs to start of SPROG, SSCB[0], STATE[0],
| SSCB [0] | USER AREA, and SCRATCH AREA
|***************|
| SSCB [1] |
|***************|
| ..... [n] |
|***************|
| STATE [0] |
|***************|
| STATE [1] |
|***************|
| ..... [n] |
|***************|
| USER AREA | - user variables (a structure)
|***************|
| MACRO TBL |
|***************|
| SCRATCH AREA | - for parsing channel names
|***************|
The pointer to the allocated area is saved for task delete hook routine.
*/
LOCAL TASK *alloc_task_area(sp_ptr_orig)
SPROG *sp_ptr_orig; /* original state program area */
{
int size, nss, nstates, nchannels, user_size, mac_size, scr_size;
TASK *ta_ptr; /* ptr to task area */
/* Calc. size of task area */
nss = sp_ptr_orig->nss;
nstates = count_states(sp_ptr_orig);
nchannels = sp_ptr_orig->nchan;
user_size = sp_ptr_orig->user_size;
mac_size = MAX_MACROS*sizeof(MACRO);
scr_size = SCRATCH_SIZE;
size = sizeof(TASK) + sizeof(SPROG) + nss*sizeof(SSCB) +
nstates*sizeof(STATE) + nchannels*sizeof(CHAN) + user_size +
mac_size + scr_size;
/* Parse the macro definitions from the command line */
seqMacParse(macro_def, sp_ptr);
#ifdef DEBUG
printf("nss=%d, nstates=%d, nchannels=%d, user_size=%d, scr_size=%d\n",
nss, nstates, nchannels, user_size, scr_size);
printf("sizes: SPROG=%d, SSCB=%d, STATE=%d, CHAN=%d\n",
sizeof(SPROG), sizeof(SSCB), sizeof(STATE), sizeof(CHAN));
#endif DEBUG
/* Alloc the task area & set up pointers */
ta_ptr = (TASK *)malloc(size);
ta_ptr->task_area_size = size;
ta_ptr->sp_ptr = (SPROG *)(ta_ptr + 1);
ta_ptr->ss_ptr = (SSCB *)(ta_ptr->sp_ptr+1);
ta_ptr->st_ptr = (STATE *)(ta_ptr->ss_ptr + nss);
ta_ptr->db_ptr = (CHAN *)(ta_ptr->st_ptr + nstates);
ta_ptr->user_ptr = (char *)(ta_ptr->db_ptr + nchannels);
ta_ptr->mac_ptr = (MACRO *)ta_ptr->user_ptr + user_size;
ta_ptr->scr_ptr = (char *)ta_ptr->mac_ptr + mac_size;
ta_ptr->scr_nleft = scr_size;
#ifdef DEBUG
printf("ta_ptr=%d, size=%d\n", ta_ptr, size);
printf("sp_ptr=%d, ss_ptr=%d, st_ptr=%d, db_ptr=%d, user_ptr=%d\n",
ta_ptr->sp_ptr, ta_ptr->ss_ptr, ta_ptr->st_ptr, ta_ptr->db_ptr, ta_ptr->user_ptr);
printf("scr_ptr=%d, scr_nleft=%d\n", ta_ptr->scr_ptr, ta_ptr->nleft);
print_macro_defs(sp_ptr->mac_ptr);
#endif DEBUG
return ta_ptr;
/* Initialize sequencer logging */
seqLogInit(sp_ptr);
/* Specify stack size */
pname = "stack";
pvalue = seqMacValGet(pname, strlen(pname), sp_ptr->mac_ptr);
if (pvalue != NULL && strlen(pvalue) > 0)
{
sscanf(pvalue, "%d", &stack_size);
}
if (stack_size < SPAWN_STACK_SIZE)
stack_size = SPAWN_STACK_SIZE;
/* Specify task name */
pname = "name";
pvalue = seqMacValGet(pname, strlen(pname), sp_ptr->mac_ptr);
if (pvalue != NULL && strlen(pvalue) > 0)
ptask_name = pvalue;
else
ptask_name = sp_ptr->name;
/* Spawn the sequencer main task */
seqLog(sp_ptr, "Spawning state program \"%s\", task name = \"%s\"\n",
sp_ptr->name, ptask_name);
status = taskSpawn(ptask_name, SPAWN_PRIORITY, SPAWN_OPTIONS,
stack_size, sequencer, sp_ptr, stack_size, ptask_name);
seqLog(sp_ptr, " Task id = %d = 0x%x\n", status, status);
return status;
}
/* Count the total number of states in ALL state sets */
LOCAL count_states(sp_ptr)
SPROG *sp_ptr;
#ifdef DEBUG
print_macro_defs(mac_ptr)
MACRO *mac_ptr;
{
SSCB *ss_ptr;
int nss, nstates;
int i;
printf("Macro definitions:\n");
for (i = 0; i < MAX_MACROS; i++, mac_ptr++)
{
if (mac_ptr->name != NULL)
{
printf(" %s = %s\n", mac_ptr->name, mac_ptr->value);
}
}
}
print_sp_info(sp_ptr)
SPROG *sp_ptr;
{
int nss, nstates;
STATE *st_ptr;
SSCB *ss_ptr;
printf("State Program: \"%s\"\n", sp_ptr->name);
printf(" sp_ptr=%d=0x%x\n", sp_ptr, sp_ptr);
printf(" sp_ptr=%d=0x%x\n", sp_ptr, sp_ptr);
printf(" task id=%d=0x%x\n", sp_ptr->task_id, sp_ptr->task_id);
printf(" task pri=%d\n", sp_ptr->task_priority);
printf(" number of state sets=%d\n", sp_ptr->nss);
printf(" number of channels=%d\n", sp_ptr->nchan);
printf(" async flag=%d, debug flag=%d, reent flag=%d\n",
sp_ptr->async_flag, sp_ptr->debug_flag, sp_ptr->reent_flag);
nstates = 0;
ss_ptr = sp_ptr->sscb;
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
{
nstates += ss_ptr->num_states;
printf(" State Set: \"%s\"\n", ss_ptr->name);
printf(" Num states=\"%d\"\n", ss_ptr->num_states);
printf(" State names:\n");
st_ptr = ss_ptr->states;
for (nstates = 0; nstates < ss_ptr->num_states; nstates++)
{
printf(" \"%s\"\n", st_ptr->name);
st_ptr++;
}
}
return nstates;
return 0;
}
/* Copy the SPROG, SSCB, STATE, and CHAN structures into this task.
Note: we have to change the pointers in the SPROG struct and all SSCB structs */
LOCAL copy_sprog(sp_ptr_orig, ta_ptr)
TASK *ta_ptr;
SPROG *sp_ptr_orig;
#endif DEBUG
/* Allocate a single block for all dynamic structures. The size allocated
will depend on whether or not the reentrant flag is set.
The pointer to the allocated area is saved for task delete hook routine.
*/
LOCAL SPROG *alloc_task_area(sp_ptr_orig)
SPROG *sp_ptr_orig; /* original state program structure */
{
SPROG *sp_ptr;
SSCB *ss_ptr, *ss_ptr_orig;
STATE *st_ptr, *st_ptr_orig;
CHAN *db_ptr, *db_ptr_orig;
int nss, nstates, nchan;
int size, nss, nstates, nchannels, user_size,
prog_size, ss_size, state_size, chan_size, mac_size, scr_size;
SPROG *sp_ptr_new; /* ptr to new state program struct */
char *dyn_ptr, *dyn_ptr_start; /* ptr to allocated area */
sp_ptr = ta_ptr->sp_ptr;
nss = sp_ptr_orig->nss;
nstates = sp_ptr_orig->nstates;
nchannels = sp_ptr_orig->nchan;
/* Calc. # of bytes to allocate for all structures */
prog_size = sizeof(SPROG);
ss_size = nss*sizeof(SSCB);
state_size = nstates*sizeof(STATE);
chan_size = nchannels*sizeof(CHAN);
user_size = sp_ptr_orig->user_size;
mac_size = MAX_MACROS*sizeof(MACRO);
scr_size = SCRATCH_SIZE;
/* Total # bytes to allocate */
if (sp_ptr_orig->reent_flag)
{
size = prog_size + ss_size + state_size +
chan_size + user_size + mac_size + scr_size;
}
else
{
size = mac_size + scr_size;
}
/* Alloc the task area */
dyn_ptr = dyn_ptr_start = (char *)calloc(size, 1);
#ifdef DEBUG
printf("Allocate task area:\n");
printf(" nss=%d, nstates=%d, nchannels=%d\n", nss, nstates, nchannels);
printf(" prog_size=%d, ss_size=%d, state_size=%d\n",
prog_size, ss_size, state_size);
printf(" user_size=%d, mac_size=%d, scr_size=%d\n",
user_size, mac_size, scr_size);
printf(" size=%d=0x%x\n", size, size);
printf(" dyn_ptr=%d=0x%x\n", dyn_ptr, dyn_ptr);
#endif DEBUG
/* Set ptrs in the PROG structure */
if (sp_ptr_orig->reent_flag)
{ /* Reentry flag set: create a new structures */
sp_ptr_new = (SPROG *)dyn_ptr;
/* Copy the SPROG struct contents */
*sp_ptr_new = *sp_ptr_orig;
/* Allocate space for the other structures */
dyn_ptr += prog_size;
sp_ptr_new->sscb = (SSCB *)dyn_ptr;
dyn_ptr += ss_size;
sp_ptr_new->states = (STATE *)dyn_ptr;
dyn_ptr += state_size;
sp_ptr_new->channels = (CHAN *)dyn_ptr;
dyn_ptr += chan_size;
sp_ptr_new->user_area = (char *)dyn_ptr;
dyn_ptr += user_size;
}
else
{ /* Reentry flag not set: keep original structures */
sp_ptr_new = sp_ptr_orig;
}
/* Create dynamic structures for macros and scratch area */
sp_ptr_new->mac_ptr = (MACRO *)dyn_ptr;
dyn_ptr += mac_size;
sp_ptr_new->scr_ptr = (char *)dyn_ptr;
sp_ptr_new->scr_nleft = scr_size;
/* Save ptr to allocated area so we can free it at task delete */
sp_ptr_new->dyn_ptr = dyn_ptr_start;
return sp_ptr_new;
}
/* Copy the SSCB, STATE, and CHAN structures into this task.
Note: we have to change the pointers in the SPROG struct, user variables,
and all SSCB structs */
LOCAL copy_sprog(sp_ptr_orig, sp_ptr)
SPROG *sp_ptr_orig; /* original ptr to program struct */
SPROG *sp_ptr; /* new ptr */
{
SSCB *ss_ptr, *ss_ptr_orig;
STATE *st_ptr, *st_ptr_orig;
CHAN *db_ptr, *db_ptr_orig;
int nss, nstates, nchan;
char *var_ptr;
/* Copy the entire SPROG struct */
*sp_ptr = *sp_ptr_orig;
/* Ptr to 1-st SSCB in original SPROG */
ss_ptr_orig = sp_ptr_orig->sscb;
/* Ptr to 1-st SSCB in new SPROG */
ss_ptr = ta_ptr->ss_ptr;
sp_ptr->sscb = ss_ptr; /* Fix ptr to 1-st SSCB */
st_ptr = ta_ptr->st_ptr;
ss_ptr = sp_ptr->sscb;
/* Copy structures for each state set */
st_ptr = sp_ptr->states;
for (nss = 0; nss < sp_ptr->nss; nss++)
{
*ss_ptr = *ss_ptr_orig; /* copy SSCB */
@@ -255,33 +290,47 @@ SPROG *sp_ptr_orig;
st_ptr_orig = ss_ptr_orig->states;
for (nstates = 0; nstates < ss_ptr->num_states; nstates++)
{
*st_ptr++ = *st_ptr_orig++; /* copy STATE struct */
*st_ptr = *st_ptr_orig; /* copy STATE struct */
st_ptr++;
st_ptr_orig++;
}
ss_ptr++;
ss_ptr_orig++;
}
/* Copy database channel structures */
db_ptr = ta_ptr->db_ptr;
sp_ptr->channels = db_ptr;
db_ptr = sp_ptr->channels;
db_ptr_orig = sp_ptr_orig->channels;
var_ptr = sp_ptr->user_area;
for (nchan = 0; nchan < sp_ptr->nchan; nchan++)
{
*db_ptr = *db_ptr_orig;
/* Reset ptr to SPROG structure */
db_ptr->sprog = sp_ptr;
/* Convert offset to address of the user variable */
db_ptr->var += (int)var_ptr;
db_ptr++;
db_ptr_orig++;
}
/* Note: user area is not copied; it should be all zeros */
return 0;
}
/* Initialize state program block */
LOCAL init_sprog(sp_ptr)
SPROG *sp_ptr;
{
/* Semaphore for resource locking on events */
sp_ptr->sem_id = semCreate();
semInit(sp_ptr->sem_id);
semGive(sp_ptr->sem_id);
sp_ptr->task_is_deleted = FALSE;
sp_ptr->logFd = 0;
return;
}
@@ -291,130 +340,105 @@ LOCAL init_sscb(sp_ptr)
SPROG *sp_ptr;
{
SSCB *ss_ptr;
STATE *st_ptr;
int nss;
char task_name[20];
int nss, i;
ss_ptr = sp_ptr->sscb;
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
{
st_ptr = ss_ptr->states; /* 1-st state */
ss_ptr->task_id = 0;
ss_ptr->sem_id = semCreate();
semInit(ss_ptr->sem_id);
semGive(ss_ptr->sem_id);
ss_ptr->ev_flag = 0;
ss_ptr->ev_flag_mask = st_ptr->event_flag_mask;
ss_ptr->current_state = st_ptr; /* initial state */
ss_ptr->next_state = NULL;
ss_ptr->current_state = 0; /* initial state */
ss_ptr->next_state = 0;
ss_ptr->action_complete = TRUE;
for (i = 0; i < NWRDS; i++)
ss_ptr->events[i] = 0; /* clear events */
}
return 0;
}
/* Get DB value (uses channel access) */
seq_pvGet(sp_ptr, ss_ptr, db_ptr)
SPROG *sp_ptr; /* ptr to state program */
SSCB *ss_ptr; /* ptr to current state set */
CHAN *db_ptr; /* ptr to channel struct */
{
int status;
ca_array_get(db_ptr->dbr_type, db_ptr->count, db_ptr->chid, db_ptr->var);
/********** In this version we wait for each db_get() **********/
status = ca_pend_io(10.0);
if (status != ECA_NORMAL)
{
printf("time-out: db_get() on %s\n", db_ptr->db_name);
return -1;
}
/********** We should have an event handler for this call ************/
/********** Then we could use event flags on "db_get" calls **********/
return 0;
}
/* Put DB value (uses channel access) */
seq_pvPut(sp_ptr, ss_ptr, db_ptr)
SPROG *sp_ptr; /* ptr to state program */
SSCB *ss_ptr; /* ptr to current state set */
CHAN *db_ptr; /* ptr to channel struct */
{
int status;
status = ca_array_put(db_ptr->dbr_type, db_ptr->count,
db_ptr->chid, db_ptr->var);
if (status != ECA_NORMAL)
{
SEVCHK(status, "ca_array_put");
return -1;
}
ca_flush_io();
}
/* Set event flag bits for each state set */
seq_efSet(sp_ptr, ss_ptr, ev_flag)
SPROG *sp_ptr; /* state program where ev flags are to be set */
SSCB *ss_ptr; /* not currently used */
int ev_flag; /* bits to set */
{
int nss;
SSCB *ssp;
EVFLAG ev_flag_chk;
#ifdef DEBUG
char *name;
name = "?";
if (ss_ptr != NULL)
name = ss_ptr->name;
printf("seq_efSet: bits 0x%x from ss %s\n", ev_flag, name);
#endif
ssp = sp_ptr->sscb; /* 1-st state set */
for (nss = 0; nss < sp_ptr->nss; nss++, ssp++)
{ /********** need some resource locking here ***************/
/* Set event flag only if "action" is complete */
if (ssp->action_complete)
{ /* Only set ev flag if contained in mask & bit(s) get set */
ev_flag_chk = (ev_flag & ssp->ev_flag_mask) | ssp->ev_flag;
if (ev_flag_chk != ssp->ev_flag) /* did bit get set? */
{ /* set the bit(s) & wake up the ss task */
ssp->ev_flag = ev_flag_chk;
semGive(ssp->sem_id);
}
}
}
return;
}
/* Test event flag for matching bits */
seq_efTest(sp_ptr, ss_ptr, ev_flag)
SPROG *sp_ptr;
SSCB *ss_ptr;
int ev_flag; /* bit(s) to test */
{
int nss;
SSCB *ssp;
if ( (ss_ptr->ev_flag & ev_flag) != 0 )
return TRUE;
return FALSE;
}
/* Allocate memory from scratch area (always round up to even no. bytes) */
char *seqAlloc(nChar)
char *seqAlloc(sp_ptr, nChar)
SPROG *sp_ptr;
int nChar;
{
char *pStr;
extern TASK *task_area_ptr;
pStr = task_area_ptr->scr_ptr;
pStr = sp_ptr->scr_ptr;
/* round to even no. bytes */
if ((nChar & 1) != 0)
nChar++;
if (task_area_ptr->scr_nleft >= nChar)
if (sp_ptr->scr_nleft >= nChar)
{
task_area_ptr->scr_ptr += nChar;
task_area_ptr->scr_nleft -= nChar;
sp_ptr->scr_ptr += nChar;
sp_ptr->scr_nleft -= nChar;
return pStr;
}
else
return NULL;
}
/* Initialize logging */
seqLogInit(sp_ptr)
SPROG *sp_ptr;
{
char *pname, *pvalue, *seqMacValGet();
int fd;
/* Create a resource locking semaphore */
sp_ptr->logSemId = semCreate();
semInit(sp_ptr->logSemId);
semGive(sp_ptr->logSemId);
sp_ptr->logFd = ioGlobalStdGet(1); /* default fd is std out */
/* Check for logfile spec. */
pname = "logfile";
pvalue = seqMacValGet(pname, strlen(pname), sp_ptr->mac_ptr);
if (pvalue != NULL && strlen(pvalue) > 0)
{ /* Create & open file for write only */
fd = open(pvalue, O_CREAT | O_WRONLY, 0664);
if (fd != ERROR)
sp_ptr->logFd = fd;
printf("logfile=%s, fd=%d\n", pvalue, fd);
}
}
/* Log a message to the console or a file with time of day and task id */
#include "tsDefs.h"
seqLog(sp_ptr, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
SPROG *sp_ptr;
char *fmt; /* format string */
int arg1, arg2, arg3, arg4, arg5, arg6; /* arguments */
{
int fd;
TS_STAMP timeStamp;
char timeBfr[28];
/* Get time of day */
tsLocalTime(&timeStamp); /* time stamp format */
/* Convert to mm/dd/yy hh:mm:ss.nano-sec */
tsStampToText(&timeStamp, TS_TEXT_MMDDYY, timeBfr);
/* Truncate the .nano-secs part */
timeBfr[17] = 0;
/* Lock seqLog resource */
semTake(sp_ptr->logSemId, 0);
/* Print the message: e.g. "10:23:28 T13: ...." */
fd = sp_ptr->logFd;
fdprintf(fd, "%s %s: ", taskName(taskIdSelf()), &timeBfr[9]);
fdprintf(fd, fmt, arg1, arg2, arg3, arg4, arg5, arg6);
/* Unlock the resource */
semGive(sp_ptr->logSemId);
/* If NSF file then flush the buffer */
if (fd != ioGlobalStdGet(1) )
{
ioctl(fd, FIOSYNC);
}
return 0;
}

View File

@@ -3,7 +3,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)seq_qry.c 1.3 11/9/90
@(#)seq_qry.c 1.4 4/17/91
DESCRIPTION: Task querry & debug routines for run-time sequencer
ENVIRONMENT: VxWorks
@@ -15,71 +15,136 @@
#include "vxWorks.h"
#include "taskLib.h"
/* querry the sequencer */
seqQry(tid)
/* Querry the sequencer for state information */
seqShow(tid)
int tid;
{
extern TASK *task_area_ptr;
TASK *ta_ptr;
SPROG *sp_ptr;
SSCB *ss_ptr;
STATE *st_ptr;
CHAN *db_ptr;
int nss, nst, nch;
float time;
extern SPROG *seq_task_ptr;
SPROG *sp_ptr;
SSCB *ss_ptr;
STATE *st_ptr;
CHAN *db_ptr;
int nss, nst, nch;
float time;
/* Info? */
if (tid == 0)
{
printf("Usage: seqShow <task id>\n");
return 0;
}
/* Get the seq_task_ptr (it's task variable) */
sp_ptr = (SPROG *)taskVarGet(tid, &seq_task_ptr);
ta_ptr = (TASK *)taskVarGet(tid, &task_area_ptr); /* task_area_ptr is task variable */
sp_ptr = ta_ptr->sp_ptr;
if (sp_ptr->magic != MAGIC)
{
printf("tqry: wrong magic number\n");
printf("seqShow: wrong magic number\n");
return -1;
}
/* Print info about state program */
printf("State Program: \"%s\"\n", sp_ptr->name);
printf(" ta_ptr=%d=0x%x\n", ta_ptr, ta_ptr);
printf(" sp_ptr=%d=0x%x\n", sp_ptr, sp_ptr);
printf(" initial task id=%d=0x%x\n", sp_ptr->task_id, sp_ptr->task_id);
printf(" task priority=%d\n", sp_ptr->task_priority);
printf(" number of state sets=%d\n", sp_ptr->nss);
printf(" number of channels=%d\n", sp_ptr->nchan);
printf(" async flag=%d, debug flag=%d, reent flag=%d, conn flag=%d\n",
sp_ptr->async_flag, sp_ptr->debug_flag, sp_ptr->reent_flag, sp_ptr->conn_flag);
ss_ptr = sp_ptr->sscb;
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
{
printf(" State Set: \"%s\"\n", ss_ptr->name);
printf("\tss_ptr=%d=0x%x\n", ss_ptr, ss_ptr);
st_ptr = ss_ptr->current_state;
if (st_ptr != NULL) {
printf("\tcurrent state: \"%s\"\n", st_ptr->name);
}
time = ss_ptr->time/60.0;
printf("\ttime state was entered=%d tics (%g seconds)\n",
ss_ptr->time, time);
st_ptr = ss_ptr->next_state;
printf("\tevent flag=%d\n", ss_ptr->ev_flag);
printf("\tevent flag mask=0x%x\n", ss_ptr->ev_flag_mask);
printf("\tnumer delays queued=%d\n", ss_ptr->ndelay);
if (st_ptr != NULL)
printf("\tnext state: \"%s\"\n", st_ptr->name);
}
wait_rtn();
/* Print info about db channels */
db_ptr = sp_ptr->channels;
for (nch = 0; nch < sp_ptr->nchan; nch++, db_ptr++)
{
printf("\nChannel name: \"%s\"\n", db_ptr->db_name);
printf(" unexpanded name: \"%s\"\n", db_ptr->db_uname);
printf(" size=%d bytes\n", db_ptr->size);
printf(" length=%d elements\n", db_ptr->length);
printf(" DB request type=%d\n", db_ptr->dbr_type);
printf(" monitor flag=%d\n", db_ptr->mon_flag);
printf(" count=%d\n", db_ptr->count);
printf(" event flag=%d=0x%x\n", db_ptr->ev_flag, db_ptr->ev_flag);
printf(" delta=%g\n", db_ptr->delta);
printf(" timeout=%g\n", db_ptr->timeout);
printf(" task id=%d=0x%x\n", ss_ptr->task_id, ss_ptr->task_id);
st_ptr = ss_ptr->states;
printf(" First state = \"%s\"\n", ss_ptr->states->name);
st_ptr = ss_ptr->states + ss_ptr->current_state;
printf(" Current state = \"%s\"\n", st_ptr->name);
st_ptr = ss_ptr->states + ss_ptr->prev_state;
printf(" Previous state = \"%s\"\n", st_ptr->name);
time = (tickGet() - ss_ptr->time)/60.0;
printf("\tTime since state was entered = %.1f seconds)\n", time);
printf("\tNumber delays queued=%d\n", ss_ptr->ndelay);
wait_rtn();
}
return 0;
}
/* Querry the sequencer for channel information */
seqChanShow(tid)
int tid;
{
extern SPROG *seq_task_ptr;
SPROG *sp_ptr;
CHAN *db_ptr;
int nch;
float time;
/* Info? */
if (tid == 0)
{
printf("Usage: seqChanShow <task id>\n");
return 0;
}
sp_ptr = (SPROG *)taskVarGet(tid, &seq_task_ptr); /* seq_task_ptr is task variable */
if (sp_ptr->magic != MAGIC)
{
printf("seqChanQry: wrong magic number\n");
return -1;
}
db_ptr = sp_ptr->channels;
printf("State Program: \"%s\"\n", sp_ptr->name);
printf("Number of channels=%d\n", sp_ptr->nchan);
for (nch = 0; nch < sp_ptr->nchan; nch++, db_ptr++)
{
printf("\nChannel name: \"%s\"\n", db_ptr->db_name);
printf(" Unexpanded name: \"%s\"\n", db_ptr->db_uname);
printf(" Variable=%d=0x%x\n", db_ptr->var, db_ptr->var);
printf(" Size=%d bytes\n", db_ptr->size);
printf(" Count=%d\n", db_ptr->count);
printf(" DB get request type=%d\n", db_ptr->get_type);
printf(" DB put request type=%d\n", db_ptr->put_type);
printf(" monitor flag=%d\n", db_ptr->mon_flag);
if (db_ptr->monitored)
printf(" Monitored\n");
else
printf(" Not monitored\n");
if(db_ptr->connected)
printf(" Connected\n");
else
printf(" Not connected\n");
if(db_ptr->get_complete)
printf(" Last get completed\n");
else
printf(" Get not completed\n");
printf(" Status=%d\n", db_ptr->status);
printf(" Severity=%d\n", db_ptr->severity);
printf(" Delta=%g\n", db_ptr->delta);
printf(" Timeout=%g\n", db_ptr->timeout);
wait_rtn();
}
return 0;
}
wait_rtn()
{

View File

@@ -3,7 +3,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)seq_task.c 1.4 2/1/91
@(#)seq_task.c 1.7 4/23/91
DESCRIPTION: Seq_tasks.c: Task creation and control for sequencer
state sets.
@@ -14,50 +14,63 @@
#include "vxWorks.h"
#include "taskLib.h"
LOCAL ss_task_init();
LOCAL ULONG get_timeout();
LOCAL VOID semTake();
extern TASK *task_area_ptr;
/* Create state set tasks. Set task variable for each task */
#define TASK_NAME_SIZE 25
create_ss_tasks(sp_ptr, stack_size)
SPROG *sp_ptr;
int stack_size;
#define TASK_NAME_SIZE 10
/* Sequencer main task entry point */
sequencer(sp_ptr, stack_size, ptask_name)
SPROG *sp_ptr; /* ptr to original (global) state program table */
int stack_size; /* stack size */
char *ptask_name; /* Parent task name */
{
SSCB *ss_ptr;
int nss;
char task_name[2*TASK_NAME_SIZE+2];
extern TASK *task_area_ptr;
extern ss_entry();
extern SPROG *seq_task_ptr;
SSCB *ss_ptr;
STATE *st_ptr;
int nss, task_id;
char task_name[TASK_NAME_SIZE+10];
extern ss_entry();
sp_ptr->task_id = taskIdSelf(); /* my task id */
/* Make "seq_task_ptr" a task variable */
if (taskVarAdd(sp_ptr->task_id, &seq_task_ptr) != OK)
{
seqLog(sp_ptr, "%s: taskVarAdd failed\n", sp_ptr->name);
return -1;
}
seq_task_ptr = sp_ptr;
/* Initilaize state set to first task, and set event mask */
ss_ptr = sp_ptr->sscb;
task_name[0] = 0;
strncat(task_name, sp_ptr->name, TASK_NAME_SIZE);
strcat(task_name, "_");
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
{
if (nss != 0)
{ /* Spawn the ss task */
/* Form task name from program name + state set name */
strncat(task_name, ss_ptr->name, TASK_NAME_SIZE);
ss_ptr->task_id = taskSpawn(task_name,
SPAWN_PRIORITY+ss_ptr->task_priority,
SPAWN_OPTIONS, stack_size, ss_entry, sp_ptr, ss_ptr);
#ifdef DEBUG
printf("task %d: %s\n", ss_ptr->task_id, task_name);
#endif DEBUG
}
st_ptr = ss_ptr->states;
ss_ptr->current_state = 0;
ss_ptr->pMask = (st_ptr->eventMask);
}
/* Connect to database channels & initiate monitor requests.
Returns here immediately if "connect" switch is not set */
connect_db_channels(sp_ptr);
/* Create the state set tasks */
if (strlen(ptask_name) > TASK_NAME_SIZE);
ptask_name[TASK_NAME_SIZE] = 0;
ss_ptr = sp_ptr->sscb + 1;
for (nss = 1; nss < sp_ptr->nss; nss++, ss_ptr++)
{
/* Form task name from program name + state set number */
sprintf(task_name, "%s_%d", ptask_name, nss);
/* Spawn the task */
task_id = taskSpawn(task_name,
SPAWN_PRIORITY+ss_ptr->task_priority,
SPAWN_OPTIONS, stack_size, ss_entry, sp_ptr, ss_ptr);
seqLog(sp_ptr, "Spawning task %d: \"%s\"\n", task_id, task_name);
}
/* Main task handles first state set */
ss_ptr = sp_ptr->sscb;
ss_ptr->task_id = sp_ptr->task_id;
ss_entry(sp_ptr, ss_ptr);
ss_entry(sp_ptr, sp_ptr->sscb);
}
/* Task entry point for state sets */
/* Provides main loop for state set processing (common, re-entrant code) */
@@ -65,32 +78,28 @@ ss_entry(sp_ptr, ss_ptr)
SPROG *sp_ptr;
SSCB *ss_ptr;
{
BOOL ev_trig;
STATE *st_ptr;
ULONG delay, get_timeout();
BOOL ev_trig;
STATE *st_ptr, *st_pNext;
ULONG delay, get_timeout();
int i;
char *var_ptr;
/* Initialize all tasks except the main task */
ss_ptr->task_id = taskIdSelf();
if (ss_ptr->task_id != sp_ptr->task_id)
ss_task_init(sp_ptr, ss_ptr);
/* Start in first state */
st_ptr = ss_ptr->current_state;
/* Initialize for event flag processing */
ss_ptr->ev_flag_mask = st_ptr->event_flag_mask;
ss_ptr->ev_flag = 0;
var_ptr = sp_ptr->user_area;
st_ptr = ss_ptr->states;
/* Main loop */
while (1)
{
#ifdef DEBUG
printf("State set %s, state %s\n", ss_ptr->name, st_ptr->name);
#endif DEBUG
ss_ptr->time = tickGet(); /* record time we entered this state */
/* Call delay function to set up delays */
ss_ptr->ndelay = 0;
st_ptr->delay_func(sp_ptr, ss_ptr);
st_ptr->delay_func(sp_ptr, ss_ptr, var_ptr);
/* On 1-st pass fall thru w/o wake up */
semGive(ss_ptr->sem_id);
@@ -100,23 +109,45 @@ SSCB *ss_ptr;
/* Wake up on CA event, event flag, or expired time delay */
semTake(ss_ptr->sem_id, get_timeout(ss_ptr, st_ptr));
#ifdef DEBUG
printf("%s: semTake returned\n", ss_ptr->name);
printf("%s: semTake returned, events[0]=0x%x\n",
ss_ptr->name, ss_ptr->events[0]);
#endif DEBUG
ss_ptr->time = tickGet();
/* Call event function to check for event trigger */
ev_trig = st_ptr->event_func(sp_ptr, ss_ptr);
} while (!ev_trig);
/* Event triggered, execute the corresponding action */
/* Apply resource lock: any new events coming in will
be deferred until next state is entered */
semTake(sp_ptr->sem_id, 0);
/* Call event function to check for event trigger */
ev_trig = st_ptr->event_func(sp_ptr, ss_ptr, var_ptr);
if (!ev_trig)
semGive(sp_ptr->sem_id); /* Unlock resource */
} while (!ev_trig);
/* Event triggered */
/* Change event mask ptr for next state */
st_pNext = ss_ptr->states + ss_ptr->next_state;
ss_ptr->pMask = (st_pNext->eventMask);
/* Clear event bits */
for (i = 0; i < NWRDS; i++)
ss_ptr->events[i] = 0;
/* Unlock resource */
semGive(sp_ptr->sem_id);
/* Execute the action for this event */
ss_ptr->action_complete = FALSE;
st_ptr->action_func(sp_ptr, ss_ptr);
st_ptr->action_func(sp_ptr, ss_ptr, var_ptr);
/* Flush any outstanding DB requests */
ca_flush_io();
/* Change to next state */
ss_ptr->prev_state = ss_ptr->current_state;
ss_ptr->current_state = ss_ptr->next_state;
ss_ptr->next_state = NULL;
st_ptr = ss_ptr->current_state;
ss_ptr->ev_flag_mask = st_ptr->event_flag_mask;
ss_ptr->ev_flag = 0;
st_ptr = ss_ptr->states + ss_ptr->current_state;
ss_ptr->action_complete = TRUE;
}
}
@@ -125,9 +156,12 @@ LOCAL ss_task_init(sp_ptr, ss_ptr)
SPROG *sp_ptr;
SSCB *ss_ptr;
{
extern SPROG *seq_task_ptr;
/* Import task variable context from main task */
taskVarAdd(ss_ptr->task_id, &task_area_ptr);
taskVarGet(sp_ptr->task_id, &task_area_ptr); /* main task's id */
taskVarAdd(ss_ptr->task_id, &seq_task_ptr);
seq_task_ptr = sp_ptr;
/* Import Channel Access context from main task */
ca_import(sp_ptr->task_id);
@@ -168,7 +202,12 @@ SSCB *ss_ptr;
int delay_id; /* delay id */
float delay;
{
ss_ptr->timeout[delay_id] = ss_ptr->time + delay*60.0;
int td_tics;
/* Note: the following 2 lines could be combined, but doing so produces
* the undefined symbol "Mund", which is not in VxWorks library */
td_tics = delay*60.0;
ss_ptr->timeout[delay_id] = ss_ptr->time + td_tics;
delay_id += 1;
if (delay_id > ss_ptr->ndelay)
ss_ptr->ndelay = delay_id;
@@ -187,49 +226,79 @@ int delay_id;
sprog_delete(pTcbX)
TCBX *pTcbX; /* ptr to TCB of task to be deleted */
{
int tid, nss, val, tid_ss;
SPROG *sp_ptr;
SSCB *ss_ptr;
extern TASK *task_area_ptr;
TASK *ta_ptr;
int tid, nss, val, tid_ss;
SPROG *sp_ptr;
SSCB *ss_ptr;
extern SPROG *seq_task_ptr;
tid = pTcbX->taskId;
/* Note: task_area_ptr is a task variable */
val = taskVarGet(tid, &task_area_ptr);
/* Note: seq_task_ptr is a task variable */
val = taskVarGet(tid, &seq_task_ptr);
if (val == ERROR)
return 0; /* not one of our tasks */
ta_ptr = (TASK *)val;
printf(" ta_ptr=0x%x, tid=%d=0x%x\n", ta_ptr, tid, tid);
sp_ptr = ta_ptr->sp_ptr;
sp_ptr = (SPROG *)val;
logMsg("Delete %s: sp_ptr=%d=0x%x, tid=%d\n",
sp_ptr->name, sp_ptr, sp_ptr, tid);
/* Is this a real sequencer task? */
if (sp_ptr->magic != MAGIC)
{
printf(" Not main state program task\n");
logMsg(" Not main state program task\n");
return -1;
}
/* Delete state set tasks */
/* Suspend state set tasks */
ss_ptr = sp_ptr->sscb;
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
{
tid_ss = ss_ptr->task_id;
if ( tid_ss > 0)
{
/* Don't delete self yet */
/* Don't suspend self */
if (tid != tid_ss)
{
printf(" delete ss task: tid=%d=0x%x\n",
tid_ss, tid_ss);
taskVarSet(tid_ss, &task_area_ptr, ERROR);
taskDelete(tid_ss);
logMsg(" suspend ss task: tid=%d\n", tid_ss);
taskVarSet(tid_ss, &seq_task_ptr, ERROR);
taskSuspend(tid_ss);
}
}
}
printf("free ta_ptr=0x%x\n", ta_ptr);
taskDelay(60);
free(ta_ptr);
/* Call user exit routine */
sp_ptr->exit_func(sp_ptr, sp_ptr->user_area);
/* Close the log file */
if (sp_ptr->logFd > 0 && sp_ptr->logFd != ioGlobalStdGet(1))
{
logMsg("Closing log fd=%d\n", sp_ptr->logFd);
close(sp_ptr->logFd);
sp_ptr->logFd = ioGlobalStdGet(1);
}
/* Delete state set tasks & delete semaphores */
ss_ptr = sp_ptr->sscb;
for (nss = 0; nss < sp_ptr->nss; nss++, ss_ptr++)
{
tid_ss = ss_ptr->task_id;
if ( tid_ss > 0)
{
/* Don't delete self */
if (tid != tid_ss)
{
logMsg(" delete ss task: tid=%d\n", tid_ss);
taskVarSet(tid_ss, &seq_task_ptr, ERROR);
taskDelete(tid_ss);
}
semDelete(ss_ptr->sem_id);
}
}
/* Delete semaphores & free the task area */
semDelete(sp_ptr->sem_id);
semDelete(sp_ptr->logSemId);
logMsg("free sp_ptr->dyn_ptr=0x%x\n", sp_ptr->dyn_ptr);
taskDelay(5);
free(sp_ptr->dyn_ptr);
return 0;
}

View File

@@ -4,7 +4,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)snc.y 1.1 10/16/90
@(#)snc.y 1.2 4/17/91
ENVIRONMENT: UNIX
***************************************************************************/
/* SNC - State Notation Compiler.
@@ -31,9 +31,6 @@
#include <ctype.h>
#include "parse.h"
Expr *expression();
Expr *parameter();
extern int line_num; /* input file line no. */
%}
@@ -44,27 +41,33 @@ extern int line_num; /* input file line no. */
int ival;
char *pchar;
void *pval;
Expr *expr;
Expr *pexpr;
}
%token <pchar> STATE STATE_SET
%token <pchar> NUMBER NAME DBNAME
%token <pchar> NUMBER NAME
%token <pchar> DEBUG_PRINT
%token PROGRAM DEFINE
%token PROGRAM EXIT
%token R_SQ_BRACKET L_SQ_BRACKET
%token BAD_CHAR L_BRACKET R_BRACKET
%token COLON SEMI_COLON EQUAL
%token L_PAREN R_PAREN PERIOD COMMA OR AND
%token MONITOR ASSIGN TO WHEN INT FLOAT DOUBLE SHORT CHAR STRING_DECL
%token MONITOR ASSIGN TO WHEN CHAR SHORT INT LONG FLOAT DOUBLE STRING_DECL
%token EVFLAG SYNC
%token ASTERISK AMPERSAND
%token PLUS MINUS SLASH GT GE EQ LE LT NE NOT
%token PLUS MINUS SLASH GT GE EQ LE LT NE NOT BIT_OR BIT_AND
%token L_SHIFT R_SHIFT COMPLEMENT MODULO
%token PLUS_EQUAL MINUS_EQUAL MULT_EQUAL DIV_EQUAL AND_EQUAL OR_EQUAL
%token MODULO_EQUAL LEFT_EQUAL RIGHT_EQUAL CMPL_EQUAL
%token <pchar> STRING
%token <pchar> C_STMT
%token IF ELSE WHILE
%token PP_SYMBOL CR
%type <ival> type
%type <pchar> subscript
%type <expr> parameter function expression
/* precidence rules for expression evaluation */
%type <pchar> subscript binop asgnop unop
%type <pexpr> state_set_list state_set state_list state transition_list transition
%type <pexpr> parameter expr
%type <pexpr> statement stmt_list compound_stmt if_stmt else_stmt while_stmt
/* precidence rules for expr evaluation */
%left OR AND
%left GT GE EQ NE LE LT
%left PLUS MINUS
@@ -75,9 +78,11 @@ extern int line_num; /* input file line no. */
%% /* Begin rules */
state_program /* define a state program */
: program_name definitions program_body { program(""); }
| program_name definitions program_body C_STMT { program($4); }
| error { snc_err("state program", line_num, 12); }
: program_name definitions state_set_list { program($3); }
| program_name definitions state_set_list global_c { program($3); }
| pp_code program_name definitions state_set_list { program($4); }
| pp_code program_name definitions state_set_list global_c{ program($4); }
| error { snc_err("state program"); }
;
program_name /* program name */
@@ -97,21 +102,17 @@ defn_stmt /* individual definitions for SNL (preceeds state sets) */
| debug_stmt
| sync_stmt
| C_STMT { defn_c_stmt($1); }
| error { snc_err("definitions", line_num, 1); }
| pp_code
| error { snc_err("definitions/declarations"); }
;
assign_stmt /* 'assign <var name>[<lower lim>,<upper lim>] to <db name>;' */
/* subscript range is optional */
: ASSIGN NAME TO STRING SEMI_COLON { assign_stmt($2, (char *)0, (char *)0, $4); }
| ASSIGN NAME L_SQ_BRACKET NUMBER R_SQ_BRACKET TO STRING SEMI_COLON
{ assign_stmt($2, $4, (char *)0, $7); }
| ASSIGN NAME L_SQ_BRACKET NUMBER COMMA NUMBER R_SQ_BRACKET TO STRING SEMI_COLON
{ assign_stmt($2, $4, $6, $9); }
assign_stmt /* 'assign <var name> to <db name>;' */
: ASSIGN NAME TO STRING SEMI_COLON { assign_stmt($2, $4); }
;
monitor_stmt /* variable to be monitored; subscript & delta are optional */
: MONITOR NAME subscript SEMI_COLON { monitor_stmt($2, $3, "0"); }
| MONITOR NAME subscript COMMA NUMBER SEMI_COLON { monitor_stmt($2, $3, $5); }
monitor_stmt /* variable to be monitored; delta is optional */
: MONITOR NAME SEMI_COLON { monitor_stmt($2, "0"); }
| MONITOR NAME COMMA NUMBER SEMI_COLON { monitor_stmt($2, $4); }
;
subscript /* e.g. [10] */
@@ -130,110 +131,164 @@ decl_stmt /* variable declarations (e.g. float x[20];) */
;
type /* types for variables defined in SNL */
: FLOAT { $$ = V_FLOAT; }
| DOUBLE { $$ = V_DOUBLE; }
| INT { $$ = V_INT; }
: CHAR { $$ = V_CHAR; }
| SHORT { $$ = V_SHORT; }
| CHAR { $$ = V_CHAR; }
| INT { $$ = V_INT; }
| LONG { $$ = V_LONG; }
| FLOAT { $$ = V_FLOAT; }
| DOUBLE { $$ = V_DOUBLE; }
| STRING_DECL { $$ = V_STRING; }
| EVFLAG { $$ = V_EVFLAG; }
;
sync_stmt /* sync <variable> <event flag> */
: SYNC NAME subscript NAME SEMI_COLON { sync_stmt($2, $3, $4); }
| SYNC NAME subscript TO NAME SEMI_COLON { sync_stmt($2, $3, $5); }
: SYNC NAME TO NAME SEMI_COLON { sync_stmt($2, $4); }
| SYNC NAME NAME SEMI_COLON { sync_stmt($2, $3); /* archaic syntax */ }
;
program_body /* a program body is one or more state sets */
: state_set
| program_body state_set
state_set_list /* a program body is one or more state sets */
: state_set { $$ = $1; }
| state_set_list state_set { $$ = link_expr($1, $2); }
;
state_set /* define a state set */
: STATE_SET NAME L_BRACKET state_set_body R_BRACKET { state_set($2); }
| error { snc_err("state set", line_num, 3); }
: STATE_SET NAME L_BRACKET state_list R_BRACKET
{ $$ = expression(E_SS, $2, $4, 0); }
| EXIT L_BRACKET stmt_list R_BRACKET
{ exit_code($3); $$ = 0; }
| error { snc_err("state set"); }
;
state_set_body /* define a state set body (one or more state blocks) */
: state_block
| state_set_body state_block
| error { snc_err("state set body", line_num, 4); }
state_list /* define a state set body (one or more states) */
: state { $$ = $1; }
| state_list state { $$ = link_expr($1, $2); }
| error { snc_err("state set"); }
;
state_block /* a block that defines a single state */
: STATE NAME L_BRACKET trans_list R_BRACKET
{ state_block($2); }
| error { snc_err("state block", line_num, 11); }
state /* a block that defines a single state */
: STATE NAME L_BRACKET transition_list R_BRACKET
{ $$ = expression(E_STATE, $2, $4, 0); }
| error { snc_err("state block"); }
;
trans_list /* all transitions for one state */
: transition
| trans_list transition
| error { snc_err("transition", line_num, 5); }
transition_list /* all transitions for one state */
: transition { $$ = $1; }
| transition_list transition { $$ = link_expr($1, $2); }
| error { snc_err("transition"); }
;
transition /* define a transition (e.g. "when (abc(x) | def(y, z)) state 2;" ) */
: WHEN L_PAREN expression R_PAREN L_BRACKET action R_BRACKET STATE NAME
{ transition($9, $3); }
transition /* define a transition ("when" statment ) */
: WHEN L_PAREN expr R_PAREN L_BRACKET stmt_list R_BRACKET STATE NAME
{ $$ = expression(E_WHEN, $9, $3, $6); }
;
expression /* general expression: e.g. (-b+2*a/(c+d)) != 0 || (func1(x,y) < 5.0) */
/* Expr *expression(int type, char *value, Expr *left, Expr *right) */
: NUMBER { $$ = expression(E_CONST, $1, (Expr *)0, (Expr *)0); }
| STRING { $$ = expression(E_STRING, $1, (Expr *)0, (Expr *)0); }
| NAME { $$ = expression(E_VAR, $1, (Expr *)0, (Expr *)0); }
| function { $$ = $1; }
| expression PLUS expression { $$ = expression(E_BINOP, "+", $1, $3); }
| expression MINUS expression { $$ = expression(E_BINOP, "-", $1, $3); }
| expression ASTERISK expression { $$ = expression(E_BINOP, "*", $1, $3); }
| expression SLASH expression { $$ = expression(E_BINOP, "/", $1, $3); }
| expression GT expression { $$ = expression(E_BINOP, ">", $1, $3); }
| expression GE expression { $$ = expression(E_BINOP, ">=", $1, $3); }
| expression EQ expression { $$ = expression(E_BINOP, "==", $1, $3); }
| expression NE expression { $$ = expression(E_BINOP, "!=", $1, $3); }
| expression LE expression { $$ = expression(E_BINOP, "<=", $1, $3); }
| expression LT expression { $$ = expression(E_BINOP, "<", $1, $3); }
| expression OR expression { $$ = expression(E_BINOP, "||", $1, $3); }
| expression AND expression { $$ = expression(E_BINOP, "&&", $1, $3); }
| expression EQUAL expression { $$ = expression(E_BINOP, "=", $1, $3); }
| expression PLUS_EQUAL expression { $$ = expression(E_BINOP, "+=", $1, $3); }
| expression MINUS_EQUAL expression { $$ = expression(E_BINOP, "-=", $1, $3); }
| expression AND_EQUAL expression { $$ = expression(E_BINOP, "&=", $1, $3); }
| expression OR_EQUAL expression { $$ = expression(E_BINOP, "|=", $1, $3); }
| expression DIV_EQUAL expression { $$ = expression(E_BINOP, "/=", $1, $3); }
| expression MULT_EQUAL expression { $$ = expression(E_BINOP, "*=", $1, $3); }
| L_PAREN expression R_PAREN { $$ = expression(E_PAREN, "", (Expr *)0, $2); }
| PLUS expression %prec UOP { $$ = expression(E_UNOP, "+", (Expr *)0, $2); }
| MINUS expression %prec UOP { $$ = expression(E_UNOP, "-", (Expr *)0, $2); }
| NOT expression { $$ = expression(E_UNOP, "!", (Expr *)0, $2); }
| ASTERISK expression %prec UOP { $$ = expression(E_UNOP, "*", (Expr *)0, $2); }
| AMPERSAND expression %prec UOP { $$ = expression(E_UNOP, "&", (Expr *)0, $2); }
| expression L_SQ_BRACKET expression R_SQ_BRACKET %prec SUBSCRIPT
expr /* general expr: e.g. (-b+2*a/(c+d)) != 0 || (func1(x,y) < 5.0) */
/* Expr *expression(int type, char *value, Expr *left, Expr *right) */
: expr binop expr { $$ = expression(E_BINOP, $2, $1, $3); }
| expr asgnop expr { $$ = expression(E_ASGNOP, $2, $1, $3); }
| unop expr %prec UOP { $$ = expression(E_UNOP, $1, $2, 0); }
| NUMBER { $$ = expression(E_CONST, $1, 0, 0); }
| STRING { $$ = expression(E_STRING, $1, 0, 0); }
| NAME { $$ = expression(E_VAR, $1, 0, 0); }
| NAME L_PAREN parameter R_PAREN { $$ = expression(E_FUNC, $1, $3, 0); }
| EXIT L_PAREN parameter R_PAREN { $$ = expression(E_FUNC, "exit", $3, 0); }
| L_PAREN expr R_PAREN { $$ = expression(E_PAREN, "", $2, 0); }
| expr L_SQ_BRACKET expr R_SQ_BRACKET %prec SUBSCRIPT
{ $$ = expression(E_SUBSCR, "", $1, $3); }
| /* empty */ { $$ = expression(E_EMPTY, ""); }
| /* empty */ { $$ = expression(E_EMPTY, "", 0, 0); }
;
function /* function */
: NAME L_PAREN parameter R_PAREN { $$ = expression(E_FUNC, $1, (Expr *)0, $3); }
unop /* Unary operators */
: PLUS { $$ = "+"; }
| MINUS { $$ = "-"; }
| ASTERISK { $$ = "*"; }
| AMPERSAND { $$ = "&"; }
| NOT { $$ = "!"; }
;
binop /* Binary operators */
: MINUS { $$ = "-"; }
| PLUS { $$ = "+"; }
| ASTERISK { $$ = "*"; }
| SLASH { $$ = "/"; }
| GT { $$ = ">"; }
| GE { $$ = ">="; }
| EQ { $$ = "=="; }
| NE { $$ = "!="; }
| LE { $$ = "<="; }
| LT { $$ = "<"; }
| OR { $$ = "||"; }
| AND { $$ = "&&"; }
| L_SHIFT { $$ = "<<"; }
| R_SHIFT { $$ = ">>"; }
| BIT_OR { $$ = "|"; }
| BIT_AND { $$ = "&"; }
| COMPLEMENT { $$ = "^"; }
| MODULO { $$ = "%"; }
;
asgnop /* Assignment operators */
: EQUAL { $$ = "="; }
| PLUS_EQUAL { $$ = "+="; }
| MINUS_EQUAL { $$ = "-="; }
| AND_EQUAL { $$ = "&="; }
| OR_EQUAL { $$ = "|="; }
| DIV_EQUAL { $$ = "/="; }
| MULT_EQUAL { $$ = "*="; }
| MODULO_EQUAL { $$ = "%="; }
| LEFT_EQUAL { $$ = "<<="; }
| RIGHT_EQUAL { $$ = ">>="; }
| CMPL_EQUAL { $$ = "^="; }
;
parameter /* expr, expr, .... */
: expression { $$ = parameter($1, 0); }
| parameter COMMA expression { $$ = parameter($3, $1); }
| /* empty */ { $$ = 0; }
: expr { $$ = $1; }
| parameter COMMA expr { $$ = link_expr($1, $3); }
| /* empty */ { $$ = 0; }
;
action /* action block for a single state */
: /* Empty */
| action_item
| action action_item
| error { snc_err("action", line_num, 8); }
compound_stmt /* compound statement e.g. { ...; ...; ...; } */
: L_BRACKET stmt_list R_BRACKET { $$ = expression(E_CMPND, "",$2, 0); }
| error { snc_err("action statements"); }
;
action_item /* define an action */
: expression SEMI_COLON { action_stmt($1); }
| C_STMT { action_c_stmt($1); }
| error { snc_err("action statement", line_num, 9); }
stmt_list
: statement { $$ = $1; }
| stmt_list statement { $$ = link_expr($1, $2); }
| /* empty */ { $$ = 0; }
;
statement
: compound_stmt { $$ = $1; }
| expr SEMI_COLON { $$ = expression(E_STMT, "",$1, 0); }
| if_stmt { $$ = $1; }
| else_stmt { $$ = $1; }
| while_stmt { $$ = $1; }
| C_STMT { $$ = expression(E_TEXT, "", $1, 0); }
| pp_code { $$ = 0; }
| error { snc_err("action statement"); }
;
if_stmt
: IF L_PAREN expr R_PAREN statement { $$ = expression(E_IF, "", $3, $5); }
;
else_stmt
: ELSE statement { $$ = expression(E_ELSE, "", $2, 0); }
;
while_stmt
: WHILE L_PAREN expr R_PAREN statement { $$ = expression(E_WHILE, "", $3, $5); }
;
pp_code /* pre-processor code (e.g. # 1 "test.st") */
: PP_SYMBOL NUMBER STRING CR { pp_code($2, $3, ""); }
| PP_SYMBOL NUMBER STRING NUMBER CR { pp_code($2, $3, $4); }
;
global_c
: C_STMT { global_c_stmt($1); }
;
%%

View File

@@ -4,7 +4,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)snc_lex.l 1.1 10/16/90
$Id$
ENVIRONMENT: UNIX
***************************************************************************/
/* Lexical analyzer for State Notation Compiler (snc).
@@ -18,80 +18,114 @@
#include "parse.h"
#include "y.tab.h" /* output from yacc */
#include "stdio.h"
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/*#define DEBUG 1*/
#ifdef DEBUG
#define RETURN(param) { printf("return(param)\n"); return(param); }
#define RETURN(param) { fprintf(stderr, "return(param)\n"); return(param); }
#else
#define RETURN(param) return(param);
#endif
#define STR_BFR_SIZE 30000
extern int line_num; /* input line number */
char str_bfr[STR_BFR_SIZE]; /* holding place for strings */
char *str_next = str_bfr; /* current ptr to str_bfr */
char *c_str; /* Start of current string in str_bfr */
int nc;
double atof();
int one_line_c_code;
extern int line_num, c_line_num; /* input line number */
extern int warn_flag; /* compiler warning flag */
char str_bfr[STR_BFR_SIZE]; /* holding place for strings */
char *str_next = str_bfr; /* current ptr to str_bfr */
char *c_str; /* Start of current string in str_bfr */
int nc;
double atof();
int one_line_c_code;
%}
/* Start conditions (SNL, C code, comment, and string) */
%Start SNL C_CODE COMMENT STR
/* Start conditions (SNL, C code, comment, string, pre-processor, pre-proc. string) */
%Start SNL C_CODE COMMENT STR PP PP_STR
NAME [a-zA-Z][a-zA-Z0-9_]*
FPNUM (\-?(([0-9]+)(\.[0-9]*)?)|(\.[0-9]+))
%% /* Begin rules */
<C_CODE>. *str_next++ = yytext[0];
<C_CODE>\n {
*str_next++ = '\n';
line_num++;
if (one_line_c_code)
{
*str_next++ = 0;
yylval.pchar = c_str;
BEGIN SNL;
RETURN(C_STMT);
}
}
<C_CODE>"}%" {
<C_CODE>\n {
*str_next++ = '\n';
line_num++;
if (one_line_c_code)
{
*str_next++ = 0;
yylval.pchar = c_str;
BEGIN SNL;
RETURN(C_STMT);
}
}
<C_CODE>"}%" {
*str_next++ = 0;
yylval.pchar = c_str;
BEGIN SNL;
RETURN(C_STMT);
}
<COMMENT>\n line_num++;
<COMMENT>"*/" BEGIN SNL;
<COMMENT>. ;
<STR>"\\\"" {
*str_next++ = yytext[0];
*str_next++ = yytext[1];
}
<STR>\" {
*str_next++ = 0;
yylval.pchar = c_str;
BEGIN SNL;
RETURN(STRING);
}
<STR>"\\\"" {
*str_next++ = yytext[0];
*str_next++ = yytext[1];
}
<STR>\" {
*str_next++ = 0;
yylval.pchar = c_str;
BEGIN SNL;
RETURN(STRING);
}
<STR>. { *str_next++ = yytext[0]; }
<STR>\n { *str_next++ = '?'; line_num++; }
<STR>\n { *str_next++ = '?';
if (warn_flag)
fprintf(stderr, "Warning: newline in string, line %d\n",
line_num);
line_num++;
}
<PP>{FPNUM} { nc = strlen(yytext);
bcopy(yytext, str_next, nc+1);
yylval.pchar = str_next;
str_next += nc+1;
RETURN(NUMBER);
}
<PP>\" { c_str = str_next; BEGIN PP_STR; }
<PP>\n {
BEGIN SNL;
RETURN(CR);
}
<PP>[\t\ ]* /* no action */ ;
<PP>. {
}
<PP_STR>\" {
*str_next++ = 0;
yylval.pchar = c_str;
BEGIN PP;
RETURN(STRING);
}
<PP_STR>. { *str_next++ = yytext[0]; }
<PP_STR>\n { *str_next++ = '?'; line_num++; }
<SNL>\n { line_num++; }
<SNL>"%{" {
c_str = str_next;
one_line_c_code = FALSE;
BEGIN C_CODE;
}
<SNL>"%%" {
c_str = str_next;
one_line_c_code = TRUE;
BEGIN C_CODE;
}
<SNL>"%{" {
c_str = str_next;
one_line_c_code = FALSE;
c_line_num = line_num;
BEGIN C_CODE;
}
<SNL>"%%" {
c_str = str_next;
one_line_c_code = TRUE;
c_line_num = line_num;
BEGIN C_CODE;
}
<SNL>^# {
BEGIN PP;
RETURN(PP_SYMBOL);
}
<SNL>"/*" BEGIN COMMENT;
<SNL>\" { c_str = str_next; BEGIN STR; }
<SNL>"ss" RETURN(STATE_SET);
@@ -99,46 +133,41 @@ FPNUM (\-?(([0-9]+)(\.[0-9]*)?)|(\.[0-9]+))
<SNL>"when" RETURN(WHEN);
<SNL>"monitor" RETURN(MONITOR);
<SNL>"assign" RETURN(ASSIGN);
<SNL>"char" RETURN(CHAR);
<SNL>"short" RETURN(SHORT);
<SNL>"int" RETURN(INT);
<SNL>"long" RETURN(LONG);
<SNL>"float" RETURN(FLOAT);
<SNL>"double" RETURN(DOUBLE);
<SNL>"short" RETURN(SHORT);
<SNL>"char" RETURN(CHAR);
<SNL>"string" RETURN(STRING_DECL);
<SNL>"to" RETURN(TO);
<SNL>"define" RETURN(DEFINE);
<SNL>"program" RETURN(PROGRAM);
<SNL>"debug" RETURN(DEBUG_PRINT);
<SNL>"evflag" RETURN(EVFLAG);
<SNL>"sync" RETURN(SYNC);
<SNL>"if" RETURN(IF);
<SNL>"else" RETURN(ELSE);
<SNL>"while" RETURN(WHILE);
<SNL>"exit" RETURN(EXIT);
<SNL>"TRUE" { yylval.pchar = "1";
RETURN(NUMBER);
}
<SNL>"FALSE" {
yylval.pchar = "0";
RETURN(NUMBER);
}
<SNL>{NAME} {
nc = strlen(yytext);
bcopy(yytext, str_next, nc+1);
yylval.pchar = str_next;
str_next += nc+1;
RETURN(NAME);
}
<SNL>\= RETURN(EQUAL);
<SNL>\: RETURN(COLON);
<SNL>\& RETURN(AMPERSAND);
<SNL>\* RETURN(ASTERISK);
<SNL>\{ RETURN(L_BRACKET);
<SNL>\} RETURN(R_BRACKET);
<SNL>\[ RETURN(L_SQ_BRACKET);
<SNL>\] RETURN(R_SQ_BRACKET);
<SNL>\; RETURN(SEMI_COLON);
<SNL>\. RETURN(PERIOD);
<SNL>\( RETURN(L_PAREN);
<SNL>\) RETURN(R_PAREN);
<SNL>\, RETURN(COMMA);
<SNL>"|" RETURN(OR);
<SNL>"&" RETURN(AND);
}
<SNL>"<<=" RETURN(LEFT_EQUAL);
<SNL>">>=" RETURN(RIGHT_EQUAL);
<SNL>"||" RETURN(OR);
<SNL>"&&" RETURN(AND);
<SNL>"+" RETURN(PLUS);
<SNL>"-" RETURN(MINUS);
<SNL>"/" RETURN(SLASH);
<SNL>">" RETURN(GT);
<SNL>">>" RETURN(R_SHIFT);
<SNL>">=" RETURN(GE);
<SNL>"==" RETURN(EQ);
<SNL>"+=" RETURN(PLUS_EQUAL);
@@ -148,17 +177,44 @@ FPNUM (\-?(([0-9]+)(\.[0-9]*)?)|(\.[0-9]+))
<SNL>"&=" RETURN(AND_EQUAL);
<SNL>"|=" RETURN(OR_EQUAL);
<SNL>"!=" RETURN(NE);
<SNL>"<<" RETURN(L_SHIFT);
<SNL>"<=" RETURN(LE);
<SNL>"%=" RETURN(MODULO_EQUAL);
<SNL>"^=" RETURN(CMPL_EQUAL);
<SNL>"+" RETURN(PLUS);
<SNL>"-" RETURN(MINUS);
<SNL>"/" RETURN(SLASH);
<SNL>"<" RETURN(LT);
<SNL>"!" RETURN(NOT);
<SNL>">" RETURN(GT);
<SNL>"|" RETURN(BIT_OR);
<SNL>"&" RETURN(BIT_AND);
<SNL>"^" RETURN(COMPLEMENT);
<SNL>"%" RETURN(MODULO);
<SNL>"=" RETURN(EQUAL);
<SNL>"&" RETURN(AMPERSAND);
<SNL>"*" RETURN(ASTERISK);
<SNL>"{" RETURN(L_BRACKET);
<SNL>"}" RETURN(R_BRACKET);
<SNL>"[" RETURN(L_SQ_BRACKET);
<SNL>"]" RETURN(R_SQ_BRACKET);
<SNL>":" RETURN(COLON);
<SNL>";" RETURN(SEMI_COLON);
<SNL>"." RETURN(PERIOD);
<SNL>"(" RETURN(L_PAREN);
<SNL>")" RETURN(R_PAREN);
<SNL>"," RETURN(COMMA);
<SNL>{FPNUM} {
nc = strlen(yytext);
bcopy(yytext, str_next, nc+1);
yylval.pchar = str_next;
str_next += nc+1;
RETURN(NUMBER);
}
<SNL>[\t\ ]* ;
}
<SNL>[\t\ ]* /* no action */ ;
<SNL>. RETURN(BAD_CHAR);
# { /* somehow "^#" doesn't work if it's first char */
BEGIN PP;
RETURN(PP_SYMBOL)
}
.|\n { line_num = 1; BEGIN SNL; yyless(0); }

View File

@@ -3,7 +3,7 @@
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
@(#)snc_main.c 1.1 10/16/90
@(#)snc_main.c 1.2 4/17/91
DESCRIPTION: Main program and miscellaneous routines for
State Notation Compiler.
@@ -13,10 +13,24 @@ extern char *sncVersion;
#include <stdio.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/* SNC Globals: */
int line_no = 1; /* input line number */
char in_file[200]; /* input file name */
char out_file[200]; /* output file name */
char in_file[200]; /* input file name */
char out_file[200]; /* output file name */
char *src_file; /* ptr to (effective) source file name */
int line_num; /* current src file line number */
int c_line_num; /* line number for beginning of C code */
/* Flags: */
int async_flag = FALSE; /* do pvGet() asynchronously */
int conn_flag = TRUE; /* wait for all connections to complete */
int debug_flag = FALSE; /* run-time debug */
int line_flag = TRUE; /* line numbering */
int reent_flag = FALSE; /* reentrant at run-time */
int warn_flag = TRUE; /* compiler warnings */
/*+************************************************************************
* NAME: main
@@ -44,11 +58,9 @@ char *argv[];
FILE *infp, *outfp, *freopen();
extern char in_file[], out_file[];
/* Use line buffered output */
setlinebuf(stdout);
/* Get command arguments */
get_args(argc, argv);
/* Redirect input stream from specified file */
infp = freopen(in_file, "r", stdin);
if (infp == NULL)
@@ -67,8 +79,15 @@ char *argv[];
exit(1);
}
#endif REDIRECT
printf(
"/* %s: %s */\n\n", sncVersion, in_file);
/* src_file is used to mark the output file for snc & cc errors */
src_file = in_file;
/* Use line buffered output */
setlinebuf(stdout);
setlinebuf(stderr);
printf("/* %s: %s */\n\n", sncVersion, in_file);
/* Initialize parser */
init_snc();
@@ -96,17 +115,79 @@ get_args(argc, argv)
int argc;
char *argv[];
{
extern char in_file[], out_file[];
int ls;
char *s;
if (argc < 2)
{
fprintf(stderr, "%s\n", sncVersion);
fprintf(stderr, "Usage: snc infile\n");
fprintf(stderr, "Usage: snc +/-flags infile\n");
fprintf(stderr, " +a - do async. pvGet\n");
fprintf(stderr, " -c - don't wait for all connects\n");
fprintf(stderr, " +d - turn on debug run-time option\n");
fprintf(stderr, " -l - supress line numbering\n");
fprintf(stderr, " +r - make reentrant at run-time\n");
fprintf(stderr, " -w - supress compiler warnings\n");
exit(1);
}
s = argv[1];
for (argc--, argv++; argc > 0; argc--, argv++)
{
s = *argv;
if (*s == '+' || *s == '-')
get_flag(s);
else
get_in_file(s);
}
}
get_flag(s)
char *s;
{
int flag_val;
extern int debug_flag, line_flag, reent_flag, warn_flag;
if (*s == '+')
flag_val = TRUE;
else
flag_val = FALSE;
switch (s[1])
{
case 'a':
async_flag = flag_val;
break;
case 'c':
conn_flag = flag_val;
break;
case 'd':
debug_flag = flag_val;
break;
case 'l':
line_flag = flag_val;
break;
case 'r':
reent_flag = flag_val;
break;
case 'w':
warn_flag = flag_val;
break;
default:
fprintf(stderr, "Unknown flag: \"%s\"\n", s);
break;
}
}
get_in_file(s)
char *s;
{
extern char in_file[], out_file[];
int ls;
ls = strlen(s);
bcopy(s, in_file, ls);
@@ -115,15 +196,18 @@ char *argv[];
if ( strcmp(&in_file[ls-3], ".st") == 0 )
{
out_file[ls-2] = 'c';
out_file[ls-1] = '\0';
out_file[ls-1] = 0;
}
else if (in_file[ls-2] == '.')
{ /* change suffix to 'c' */
out_file[ls -1] = 'c';
}
else
{
{ /* append ".c" */
out_file[ls] = '.';
out_file[ls+1] = 'c';
ls += 2;
out_file[ls+2] = 0;
}
out_file[ls] = 0;
return;
}
/*+************************************************************************
@@ -142,13 +226,11 @@ char *argv[];
*
* NOTES:
*-*************************************************************************/
snc_err(err_txt, line, code)
snc_err(err_txt)
char *err_txt;
int line, code;
{
fprintf(stderr, "Syntax error %d (%s) at line %d\n",
code, err_txt, line);
exit(code);
fprintf(stderr, " %s\n", err_txt);
exit(1);
}
/*+************************************************************************
* NAME: yyerror
@@ -167,7 +249,10 @@ int line, code;
yyerror(err)
char *err;
{
fprintf(stderr, "%s: line no. %d\n", err, line_no);
extern char *src_file;
extern int line_num;
fprintf(stderr, "%s: line no. %d (%s)\n", err, line_num, src_file);
return;
}
@@ -178,6 +263,7 @@ char *err;
* type argument I/O description
* ---------------------------------------------------
* int line_num I current line number
* char src_file I effective source file
*
* RETURNS: n/a
*
@@ -186,9 +272,13 @@ char *err;
*
* NOTES:
*-*************************************************************************/
print_line_num(line_num)
int line_num;
print_line_num(line_num, src_file)
int line_num;
char *src_file;
{
printf("# line %d \"%s\"\n", line_num, in_file);
extern int line_flag;
if (line_flag)
printf("# line %d \"%s\"\n", line_num, src_file);
return;
}