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:
|
# Check for a few functions:
|
||||||
AC_FUNC_FORK([])
|
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([strchr index], [break])
|
||||||
AC_CHECK_FUNCS([strrchr rindex], [break])
|
AC_CHECK_FUNCS([strrchr rindex], [break])
|
||||||
AC_CHECK_FUNCS([getcwd getwd], [break])
|
AC_CHECK_FUNCS([getcwd getwd], [break])
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,6 @@ void com_alter(wordlist *wl);
|
||||||
void com_altermod(wordlist *wl);
|
void com_altermod(wordlist *wl);
|
||||||
void com_meas(wordlist *wl);
|
void com_meas(wordlist *wl);
|
||||||
void com_sysinfo(wordlist *wl);
|
void com_sysinfo(wordlist *wl);
|
||||||
|
void com_check_ifparm(wordlist *wl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -586,6 +586,12 @@ struct comm spcp_coms[] = {
|
||||||
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
|
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
|
||||||
NULL,
|
NULL,
|
||||||
": Print circuit inventory" },
|
": 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,
|
{ NULL, NULL, FALSE, FALSE,
|
||||||
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
|
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
||||||
|
|
@ -1514,3 +1514,101 @@ com_alter_mod(wordlist *wl)
|
||||||
tfree(arglist[0]);
|
tfree(arglist[0]);
|
||||||
tfree(arglist[3]);
|
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