introduce command "check_ifparm" to check consistency of the device IFparm sets
For developing purpose only, and bound to HAVE_TSEARCH, HAVE_TDESTROY
IFparm descriptors must obey certain contracts,
1) aliases must be grouped together with their associated main descriptor,
and all must have flag IF_REDUNDANT set
2) there shall be no duplicated .id fields except for aliases.
3) aliased entries shall have consistent .dataType fields
check_ifparm will traverse all IFparm sets and report violations
This commit is contained in:
parent
cf9dbff890
commit
1e6b809af8
|
|
@ -712,7 +712,7 @@ AC_CHECK_FUNCS([isatty tcgetattr tcsetattr])
|
|||
|
||||
# Check for a few functions:
|
||||
AC_FUNC_FORK([])
|
||||
AC_CHECK_FUNCS([access qsort dup2 popen])
|
||||
AC_CHECK_FUNCS([access qsort dup2 popen tsearch tdestroy])
|
||||
AC_CHECK_FUNCS([strchr index], [break])
|
||||
AC_CHECK_FUNCS([strrchr rindex], [break])
|
||||
AC_CHECK_FUNCS([getcwd getwd], [break])
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ void com_alter(wordlist *wl);
|
|||
void com_altermod(wordlist *wl);
|
||||
void com_meas(wordlist *wl);
|
||||
void com_sysinfo(wordlist *wl);
|
||||
void com_check_ifparm(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -586,6 +586,12 @@ struct comm spcp_coms[] = {
|
|||
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
|
||||
NULL,
|
||||
": Print circuit inventory" },
|
||||
#ifdef HAVE_TSEARCH
|
||||
{ "check_ifparm", com_check_ifparm, TRUE, FALSE,
|
||||
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
|
||||
NULL,
|
||||
": Check model ifparm descriptors (for developpers)" },
|
||||
#endif
|
||||
{ NULL, NULL, FALSE, FALSE,
|
||||
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
|
||||
NULL,
|
||||
|
|
|
|||
|
|
@ -1514,3 +1514,101 @@ com_alter_mod(wordlist *wl)
|
|||
tfree(arglist[0]);
|
||||
tfree(arglist[3]);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_TSEARCH
|
||||
|
||||
#include <search.h>
|
||||
|
||||
static int
|
||||
check_ifparm_compare(const void *a, const void *b)
|
||||
{
|
||||
IFparm *pa = (IFparm *) a;
|
||||
IFparm *pb = (IFparm *) b;
|
||||
return pa->id - pb->id;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
check_ifparm_freenode(void *node)
|
||||
{
|
||||
NG_IGNORE(node);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
check_ifparm(IFdevice *device, int instance_flag)
|
||||
{
|
||||
int i, xcount;
|
||||
IFparm *plist;
|
||||
|
||||
if (instance_flag) {
|
||||
plist = device->instanceParms;
|
||||
if (!plist)
|
||||
return;
|
||||
fprintf(stderr," checking %s instanceParams\n", device->name);
|
||||
xcount = *device->numInstanceParms;
|
||||
} else {
|
||||
plist = device->modelParms;
|
||||
if (!plist)
|
||||
return;
|
||||
fprintf(stderr," checking %s modelParams\n", device->name);
|
||||
xcount = *device->numModelParms;
|
||||
}
|
||||
|
||||
void *root = NULL;
|
||||
|
||||
for (i = 0; i < xcount; i++) {
|
||||
|
||||
IFparm *psearch = *(IFparm **) tsearch(plist + i, &root,
|
||||
check_ifparm_compare);
|
||||
|
||||
int type_err = (psearch->dataType ^ plist[i].dataType) & ~IF_REDUNDANT;
|
||||
if (type_err)
|
||||
fprintf(stderr,
|
||||
" ERROR, dataType mismatch \"%s\" \"%s\" %08x\n",
|
||||
psearch->keyword, plist[i].keyword, type_err);
|
||||
|
||||
if ((plist[i].dataType & IF_REDUNDANT) &&
|
||||
(i == 0 || plist[i-1].id != plist[i].id)) {
|
||||
fprintf(stderr,
|
||||
"ERROR, alias \"%s\" has non matching predecessor \"%s\"\n",
|
||||
plist[i].keyword, plist[i-1].keyword);
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
continue;
|
||||
|
||||
if (plist[i-1].id != plist[i].id) {
|
||||
if (psearch != plist + i)
|
||||
fprintf(stderr,
|
||||
"ERROR: non neighbored duplicate id: \"%s\" \"%s\"\n",
|
||||
psearch->keyword, plist[i].keyword);
|
||||
} else if (!(plist[i].dataType & IF_REDUNDANT)) {
|
||||
fprintf(stderr,
|
||||
"ERROR: non R duplicate id: \"%s\" \"%s\"\n",
|
||||
plist[i-1].keyword, plist[i].keyword);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_TDESTROY
|
||||
tdestroy (root, check_ifparm_freenode);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
com_check_ifparm(wordlist *wl)
|
||||
{
|
||||
NG_IGNORE(wl);
|
||||
|
||||
int k;
|
||||
|
||||
for (k = 0; k < ft_sim->numDevices; k++)
|
||||
if (ft_sim->devices[k]) {
|
||||
check_ifparm(ft_sim->devices[k], 0);
|
||||
check_ifparm(ft_sim->devices[k], 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue