Initial revision

This commit is contained in:
Bob Zieman
1991-05-30 11:41:33 +00:00
parent 9052a05c48
commit c04f211454

421
src/sequencer/gen_tables.c Normal file
View File

@@ -0,0 +1,421 @@
/**************************************************************************
GTA PROJECT AT division
Copyright, 1990, The Regents of the University of California.
Los Alamos National Laboratory
$Id$
DESCRIPTION: Generate tables for run-time sequencer.
See also: phase2.c & gen_ss_code.c
ENVIRONMENT: UNIX
***************************************************************************/
#include <stdio.h>
#include "parse.h"
#include "seq.h"
/*+************************************************************************
* NAME: gen_tables
*
* CALLING SEQUENCE
* type argument I/O description
* ---------------------------------------------------
*
* RETURNS: n/a
*
* FUNCTION: Generate C code from tables.
*
* NOTES: All inputs are external globals.
*-*************************************************************************/
int nstates; /* total # states in all state sets */
gen_tables()
{
extern LIST var_list; /* variables (from parse) */
extern Expr *ss_list; /* state sets (from parse) */
extern char *global_c_code; /* global C code */
printf("\f/************************ Tables ***********************/\n");
/* Generate DB blocks */
gen_db_blocks();
/* 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();
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))
{
/* Only process db variables */
if (cp->db_name != NULL)
{
if (nchan > 0)
printf(",\n");
fill_db_block(cp, nchan);
nchan++;
}
}
printf("\n};\n");
return;
}
/* Fill in a db block with data (all elements for "CHAN" struct) */
fill_db_block(cp, index)
Chan *cp;
int index;
{
Var *vp;
char *get_type_string, *put_type_string, *postfix;
extern char *prog_name;
extern int reent_flag;
int size, ev_flag, count;
vp = cp->var;
/* Convert variable type to a DB request type */
switch (vp->type)
{
case V_SHORT:
get_type_string = "DBR_STS_INT";
put_type_string = "DBR_INT";
size = sizeof(short);
break;
case V_INT:
case V_LONG:
/* Assume "long" & "int" are same size */
get_type_string = "DBR_STS_LONG";
put_type_string = "DBR_LONG";
size = sizeof(int);
break;
case V_CHAR:
get_type_string = "DBR_STS_CHAR";
put_type_string = "DBR_CHAR";
size = sizeof(char);
break;
case V_FLOAT:
get_type_string = "DBR_STS_FLOAT";
put_type_string = "DBR_FLOAT";
size = sizeof(float);
break;
case V_DOUBLE:
get_type_string = "DBR_STS_DOUBLE";
put_type_string = "DBR_DOUBLE";
size = sizeof(double);
break;
case V_STRING:
get_type_string = "DBR_STS_STRING";
put_type_string = "DBR_STRING";
size = sizeof(char);
break;
}
/* fill in the CHAN structure */
printf("\t%d, ", index); /* index for this channel */
printf("\"%s\", ", cp->db_name);/* unexpanded db channel name */
printf("(char *)0, "); /* ch'l name after macro expansion */
/* Ptr or offset to user variable */
printf("(char *)");
if (vp->type == V_STRING || cp->count > 0)
postfix = "[0]";
else
postfix = "";
if (reent_flag)
printf("OFFSET(struct UserVar, %s%s), ", vp->name, postfix);
else
printf("&%s%s, ", vp->name, postfix); /* variable ptr */
printf("(chid)0, "); /* reserve place for chid */
printf("0, 0, 0, 0, "); /* connected, get_complete, status, severity */
printf("%d,\n", size); /* element size (bytes) */
printf("\t%s, ", get_type_string);/* DB request conversion type (get/mon) */
printf("%s, ", put_type_string);/* DB request conversion type (put) */
count = cp->count;
if (count == 0)
count = 1;
printf("%d, ", count); /* count for db requests */
printf("%d, ", cp->mon_flag); /* monitor flag */
printf("0, "); /* monitored */
printf("%g, ", cp->delta); /* monitor delta */
printf("%g, ", cp->timeout); /* monitor timeout */
printf("0, "); /* event id supplied by CA */
printf("&%s", prog_name); /* ptr to state program structure */
return;
}
/* Generate structure and data for state blocks (STATE) */
gen_state_blocks()
{
extern Expr *ss_list;
Expr *ssp;
Expr *sp;
int ns;
extern int nstates;
printf("\n/* State Blocks:\n");
printf(" action_func, event_func, delay_func, event_flag_mask");
printf(", *delay, *name */\n");
nstates = 0;
for (ssp = ss_list; ssp != NULL; ssp = ssp->next)
{
printf("\nstatic STATE state_%s[] = {\n", ssp->value);
ns = 0;
for (sp = ssp->left; sp != NULL; sp = sp->next)
{
if (ns > 0)
printf(",\n\n");
ns++;
nstates++;
fill_state_block(sp, ssp->value);
}
printf("\n};\n");
}
return;
}
/* Fill in data for a the state block */
fill_state_block(sp, ss_name)
Expr *sp;
char *ss_name;
{
bitMask events[NWRDS];
int n;
printf("\t/* State \"%s\"*/\n", sp->value);
printf("\tA_%s_%s,\t/* action_function */\n", ss_name, sp->value);
printf("\tE_%s_%s,\t/* event_function */\n", ss_name, sp->value);
printf("\tD_%s_%s,\t/* delay_function */\n", ss_name, sp->value);
eval_state_event_mask(sp, events);
printf("\t/* Event mask for this state: */\n");
for (n = 0; n < NWRDS; n++)
printf("\t0x%08x,\n", events[n]);
printf("\t\"%s\"\t/* *name */", sp->value);
return;
}
/* Generate the structure with data for a state program table (SPROG) */
gen_state_prog_table()
{
extern char *prog_name, *prog_param;
extern int async_flag, debug_flag, reent_flag, conn_flag;
extern int nstates;
extern Expr exit_code_list;
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/* dyn_ptr */\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("\t0,\t/* conn_count */\n");
printf("\tsscb,\t/* *sscb */\n");
printf("\tNUM_SS,\t/* nss */\n");
printf("\tNULL,\t/* ptr to states */\n");
printf("\t%d,\t/* number of states */\n", nstates);
printf("\tNULL,\t/* ptr to user area (not used) */\n");
if (reent_flag)
printf("\tsizeof(struct UserVar),\t/* user area size */\n");
else
printf("\t0,\t/* user area size (not used) */\n");
printf("\tNULL,\t/* mac_ptr */\n");
printf("\tNULL,\t/* scr_ptr */\n");
printf("\t0,\t/* scr_nleft */\n");
printf("\t\"%s\",\t/* *name */\n", prog_name);
printf("\tprog_param,\t/* *params */\n");
printf("\t%d, %d, %d, %d,\t/* async, debug, & reent flags */\n",
async_flag, debug_flag, reent_flag, conn_flag);
printf("\texit_handler,\t/* exit handler */\n");
printf("\t0, 0\t/* logSemId & logFd */\n");
printf("};\n");
return;
}
/* Generate an array of state set control blocks (SSCB),
one entry for each state set */
gen_sscb_array()
{
extern Expr *ss_list;
Expr *ssp;
int nss, nstates, n;
bitMask events[NWRDS];
printf("\n/* State Set Control Blocks */\n");
printf("static SSCB sscb[NUM_SS] = {\n");
nss = 0;
for (ssp = ss_list; ssp != NULL; ssp = ssp->next)
{
if (nss > 0)
printf(",\n\n");
nss++;
printf("\t/* State set \"%s\"*/\n", ssp->value);
printf("\t0, 1, 0,\t/* task_id, task_prioity, sem_id */\n");
nstates = exprCount(ssp->left);
printf("\t%d, state_%s,\t/* num_states, *states */\n", nstates,
ssp->value);
printf("\t0, 0, 0,");
printf("\t/* current_state, next_state, prev_state */\n");
printf("\t%d,\t/* error_state */\n", find_error_state(ssp));
printf("\t0, FALSE,\t/* trans_number, action_complete */\n");
printf("\t/* outstanding events */\n\t");
for (n = 0; n < NWRDS; n++)
printf("0, ");
printf("\n");
printf("\t0,\t/* pMask - ptr to current event mask */\n");
printf("\t0,\t/* number of delays in use */\n");
printf("\t/* array of delay 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->value);
}
printf("\n};\n");
return;
}
/* Find the state named "error" in a state set */
find_error_state(ssp)
Expr *ssp;
{
Expr *sp;
int error_state;
for (sp = ssp->left, error_state = 0; sp != 0; sp = sp->next, error_state++)
{
if (strcmp(sp->value, "error") == 0)
return error_state;
}
return -1; /* no state named "error" in this state set */
}
/* Evaluate composite event mask for a single state */
eval_state_event_mask(sp, events)
Expr *sp;
bitMask events[NWRDS];
{
int n;
int eval_tr_event_mask();
Expr *tp;
/* Clear all bits in mask */
for (n = 0; n < NWRDS; n++)
events[n] = 0;
/* Set appropriate bits based on transition expressions */
for (tp = sp->left; tp != 0; tp = tp->next)
traverseExprTree(tp->left, E_VAR, 0,
eval_tr_event_mask, events);
}
/* Evaluate the event mask for a given transition. */
eval_tr_event_mask(ep, events)
Expr *ep;
bitMask events[NWRDS];
{
Chan *cp;
Var *vp;
vp = (Var *)ep->left;
if (vp == 0)
return; /* this shouldn't happen */
#ifdef DEBUG
fprintf(stderr, "eval_tr_event_mask: %s, ef_num=%d\n",
vp->name, vp->ef_num);
#endif
if (vp->ef_num != 0)
bitSet(events, vp->ef_num);
}
/* Count the number of linked expressions */
exprCount(ep)
Expr *ep;
{
int count;
for (count = 0; ep != 0; ep = ep->next)
count++;
return count;
}