/************************************************************************/ /* */ /* This routine finds and parses a def in the EVEX block. The */ /* low-level routine parse_vexfile() must first have been called. This */ /* routine is normally called only from get_vex(). */ /* */ /* Inputs: key A named def in the $EVEX block */ /* */ /* Output: return value Pointer to evex_struct */ /* (null on error) */ /* */ /* Created 1 December 1998 by CJL */ /* realtime latency added by rjc 2008.7.15 */ /************************************************************************/ #include #include #include "vex.h" #include "mk4_vex.h" #include "mk4_util.h" #define ISNAME(namestring) (strcmp (p_val.name, namestring) == 0) struct evex_struct * evex_info (char *key) { int i, j, nst, st, incomplete, nchar; struct def *edef; struct ref ref; struct block *blk; struct param_val p_val; char stcode, *str, *ptr; static struct evex_struct evex; extern struct statement *stlist; extern struct block blist[]; extern int nstmt, nblock; extern char evex_src[]; extern int do_output, evex_ver; /* Initialize */ evex.exper_num = 0; evex.ovex_name[0] = '\0'; evex.lvex_name[0] = '\0'; evex.cvex_name[0] = '\0'; evex.svex_name[0] = '\0'; evex.ap_length = 0.0; evex.speedup_factor = 0.0; evex.corr_config_key[0] = '\0'; evex.nst = 0; evex.tape_mode = TM_RANDOM; evex.mirror = MIR_ALLOCATE | MIR_COMPARE | MIR_NOSAVE; evex.realtime_latency = 0; /* Get the EVEX version number */ if ((evex_ver = get_version (EVEX)) == V_BAD) { msg ("Failed to get EVEX version number", 2); return (NULL); } /* Locate EVEX block */ for (i=0; indef > 1) { msg ("Multiple keys present in evex file, but none specified", 2); return (NULL); } edef = blk->deflist; } /* Retrieve key def */ else { for (i=0; indef; i++) if (strcmp (blk->deflist[i].name, key) == 0) break; if (i == blk->ndef) { msg ("Could not find key '%s' in $EVEX block", 3, key); return (NULL); } edef = blk->deflist + i; } /* Loop over statements in edef */ nst = 0; for (st=edef->start+1; stend; st++) { str = stlist[st].str; /* parameter and ref statements */ /* may be mixed */ if (strncmp (str, "ref ", 4) == 0) { /* Generic ref parsing */ if (parse_ref (st, &ref) != 0) { msg ("Bad ref statement in EVEX def '%s'", 2, key); return (NULL); } /* corr-config is simple keyword copy */ if (strcmp (ref.blockname, "CORR_CONFIG") == 0) strcpy (evex.corr_config_key, ref.keyword); /* SU config is nasty. We decree that */ /* specified stations override global */ /* config. There must be at most one */ /* global config, and no station may */ /* appear twice. We use correlator */ /* single-character station codes only */ else if (strcmp (ref.blockname, "SU_CONFIG") == 0) { /* This is global config */ if (ref.nargs == 1) { /* Check for previous '*' stations */ for (i=0; iend].end - stlist[edef->start].start + 1; if ((ptr - evex_src + nchar) >= 4096) { msg ("EVEX def too large for output buffer", 2); return (NULL); } memcpy (ptr, stlist[edef->start].start, nchar); ptr[nchar] = '\n'; ptr[nchar+1] = '\0'; } return (&evex); }