Commit 1f3fbd8e authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Make VSC/varnishstat sorta-work again.

parent 6cc6f23f
......@@ -52,7 +52,9 @@ do_xml_cb(void *priv, const struct VSC_point * const pt)
uint64_t val;
(void)priv;
assert(!strcmp(pt->fmt, "uint64_t"));
if (pt == NULL)
return (0);
assert(!strcmp(pt->desc->fmt, "uint64_t"));
val = *(const volatile uint64_t*)pt->ptr;
printf("\t<stat>\n");
......@@ -60,10 +62,10 @@ do_xml_cb(void *priv, const struct VSC_point * const pt)
printf("\t\t<type>%s</type>\n", pt->class);
if (strcmp(pt->ident, ""))
printf("\t\t<ident>%s</ident>\n", pt->ident);
printf("\t\t<name>%s</name>\n", pt->name);
printf("\t\t<name>%s</name>\n", pt->desc->name);
printf("\t\t<value>%ju</value>\n", val);
printf("\t\t<flag>%c</flag>\n", pt->flag);
printf("\t\t<description>%s</description>\n", pt->desc);
printf("\t\t<flag>%c</flag>\n", pt->desc->flag);
printf("\t\t<description>%s</description>\n", pt->desc->sdesc);
printf("\t</stat>\n");
return (0);
}
......@@ -91,9 +93,11 @@ do_json_cb(void *priv, const struct VSC_point * const pt)
uint64_t val;
int *jp;
jp = priv;
if (pt == NULL)
return (0);
assert(!strcmp(pt->fmt, "uint64_t"));
jp = priv;
assert(!strcmp(pt->desc->fmt, "uint64_t"));
val = *(const volatile uint64_t*)pt->ptr;
if (*jp) *jp = 0; else printf(",\n");
......@@ -104,15 +108,15 @@ do_json_cb(void *priv, const struct VSC_point * const pt)
printf("%s.", pt->class);
if (pt->ident[0])
printf("%s.", pt->ident);
printf("%s\": {", pt->name);
printf("%s\": {", pt->desc->name);
if (strcmp(pt->class, "")) printf("\"type\": \"%s\", ", pt->class);
if (strcmp(pt->ident, "")) printf("\"ident\": \"%s\", ", pt->ident);
printf("\"value\": %ju, ", val);
printf("\"flag\": \"%c\", ", pt->flag);
printf("\"description\": \"%s\"", pt->desc);
printf("\"flag\": \"%c\", ", pt->desc->flag);
printf("\"description\": \"%s\"", pt->desc->sdesc);
printf("}");
if (*jp) printf("\n");
......@@ -153,22 +157,24 @@ do_once_cb(void *priv, const struct VSC_point * const pt)
uint64_t val;
int i;
if (pt == NULL)
return (0);
op = priv;
assert(!strcmp(pt->fmt, "uint64_t"));
assert(!strcmp(pt->desc->fmt, "uint64_t"));
val = *(const volatile uint64_t*)pt->ptr;
i = 0;
if (strcmp(pt->class, ""))
i += printf("%s.", pt->class);
if (strcmp(pt->ident, ""))
i += printf("%s.", pt->ident);
i += printf("%s", pt->name);
i += printf("%s", pt->desc->name);
if (i > op->pad)
op->pad = i + 1;
printf("%*.*s", op->pad - i, op->pad - i, "");
if (pt->flag == 'a' || pt->flag == 'c')
printf("%12ju %12.2f %s\n", val, val / op->up, pt->desc);
if (pt->desc->flag == 'a' || pt->desc->flag == 'c')
printf("%12ju %12.2f %s\n", val, val / op->up, pt->desc->sdesc);
else
printf("%12ju %12s %s\n", val, ". ", pt->desc);
printf("%12ju %12s %s\n", val, ". ", pt->desc->sdesc);
return (0);
}
......@@ -197,10 +203,10 @@ do_list_cb(void *priv, const struct VSC_point * const pt)
i += fprintf(stderr, "%s.", pt->class);
if (strcmp(pt->ident, ""))
i += fprintf(stderr, "%s.", pt->ident);
i += fprintf(stderr, "%s", pt->name);
i += fprintf(stderr, "%s", pt->desc->name);
if (i < 30)
fprintf(stderr, "%*s", i - 30, "");
fprintf(stderr, " %s\n", pt->desc);
fprintf(stderr, " %s\n", pt->desc->sdesc);
return (0);
}
......@@ -253,7 +259,6 @@ main(int argc, char * const *argv)
int delay = 1, once = 0, xml = 0, json = 0, do_repeat = 0;
vd = VSM_New();
VSC_Setup(vd);
while ((c = getopt(argc, argv, VSC_ARGS "1f:lVw:xjt:")) != -1) {
switch (c) {
......@@ -261,8 +266,6 @@ main(int argc, char * const *argv)
once = 1;
break;
case 'l':
if (VSC_Open(vd, 1))
exit(1);
list_fields(vd);
exit(0);
case 'V':
......@@ -285,9 +288,6 @@ main(int argc, char * const *argv)
}
}
if (VSC_Open(vd, 1))
exit(1);
VSC_C_main = VSC_Main(vd);
AN(VSC_C_main);
......
......@@ -81,7 +81,9 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
char buf[128];
(void)priv;
assert(!strcmp(sp->fmt, "uint64_t"));
if (sp == NULL)
return (0);
assert(!strcmp(sp->desc->fmt, "uint64_t"));
pt = calloc(sizeof *pt, 1);
AN(pt);
......@@ -89,7 +91,7 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
pt->ptr = sp->ptr;
pt->ref = *pt->ptr;
pt->flag = sp->flag;
pt->flag = sp->desc->flag;
*buf = '\0';
if (strcmp(sp->class, "")) {
......@@ -100,9 +102,9 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
strcat(buf, sp->ident);
strcat(buf, ".");
}
strcat(buf, sp->name);
strcat(buf, sp->desc->name);
strcat(buf, " - ");
strcat(buf, sp->desc);
strcat(buf, sp->desc->sdesc);
pt->name = strdup(buf);
AN(pt->name);
return (0);
......@@ -144,7 +146,6 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
int ch, line;
struct pt *pt;
double act, lact;
unsigned seq;
(void)initscr();
AC(raw());
......@@ -157,7 +158,6 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
/*
* Initialization goes in outher loop
*/
seq = VSM_Seq(vd);
prep_pts(vd);
AC(erase());
AC(refresh());
......@@ -170,15 +170,11 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
lact = 0;
while (1) {
if (seq != VSM_Seq(vd))
break;
/*
* Break to outher loop if we need to re-read file.
* Only check if it looks like nothing is happening.
*/
act = VSC_C_main->cache_hit + VSC_C_main->cache_miss + 1;
if (act == lact && VSM_ReOpen(vd, 1))
break;
lact = act;
AZ(gettimeofday(&tv, NULL));
......
......@@ -26,6 +26,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This is the public API for the VSC access.
*
* VSC is a "subclass" of VSM.
*
*/
#ifndef VAPI_VSC_H_INCLUDED
......@@ -34,17 +38,12 @@
#include "vapi/vsc_int.h"
struct VSM_data;
struct VSM_fantom;
/*---------------------------------------------------------------------
* VSC level access functions
*/
void VSC_Setup(struct VSM_data *vd);
/*
* Setup vd for use with VSC functions.
* Must be called once before any other VSC function is called
*/
#define VSC_ARGS "f:n:"
#define VSC_n_USAGE VSM_n_USAGE
#define VSC_f_USAGE "[-f field_name,...]"
......@@ -55,39 +54,58 @@ int VSC_Arg(struct VSM_data *vd, int arg, const char *opt);
/*
* Handle standard stat-presenter arguments
* Return:
* -1 error
* -1 error, VSM_Error() returns diagnostic string
* 0 not handled
* 1 Handled.
*/
int VSC_Open(struct VSM_data *vd, int diag);
/*
* Open shared memory for VSC processing.
* args and returns as VSM_Open()
*/
struct VSC_C_main *VSC_Main(const struct VSM_data *vd);
struct VSC_C_main *VSC_Main(struct VSM_data *vd);
/*
* return Main stats structure
* returns NULL until child has been started.
*/
struct VSC_desc {
const char *name; /* field name */
const char *fmt; /* field format ("uint64_t") */
int flag; /* 'c' = counter, 'g' = gauge */
const char *sdesc; /* short description */
const char *ldesc; /* long description */
};
struct VSC_point {
const char *class; /* stat struct type */
const char *ident; /* stat struct ident */
const char *name; /* field name */
const char *fmt; /* field format ("uint64_t") */
int flag; /* 'a' = counter, 'i' = gauge */
const char *desc; /* description */
const struct VSC_desc *desc; /* point description */
const volatile void *ptr; /* field value */
struct VSM_fantom *vf;
};
typedef int VSC_iter_f(void *priv, const struct VSC_point *const pt);
int VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv);
int VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv);
/*
* Iterate over all statistics counters, calling "func" for
* each counter not suppressed by any "-f" arguments.
*
* Func is called with pt == NULL, whenever VSM allocations
* change (child restart, allocations/deallocations)
*
* Returns:
* !=0: func returned non-zero
* -1: No VSC's available
* 0: Done
*/
/**********************************************************************
* Precompiled VSC_desc's for all know VSCs.
*/
#define VSC_F(n,t,l,f,d,e)
#define VSC_DO(U,l,t) extern const struct VSC_desc VSC_desc_##l[];
#define VSC_DONE(U,l,t)
#include "tbl/vsc_all.h"
#undef VSC_F
#undef VSC_DO
#undef VSC_DONE
#endif /* VAPI_VSC_H_INCLUDED */
......@@ -47,15 +47,22 @@
#include "vqueue.h"
#include "vsm_api.h"
struct vsc_pt {
unsigned magic;
#define VSC_PT_MAGIC 0xa4ff159a
struct VSC_point point;
VTAILQ_ENTRY(vsc_pt) list;
};
struct vsc_sf {
unsigned magic;
#define VSL_SF_MAGIC 0x558478dd
VTAILQ_ENTRY(vsc_sf) next;
#define VSC_SF_MAGIC 0x558478dd
VTAILQ_ENTRY(vsc_sf) list;
int flags;
#define VSL_SF_EXCL (1 << 0)
#define VSL_SF_CL_WC (1 << 1)
#define VSL_SF_ID_WC (1 << 2)
#define VSL_SF_NM_WC (1 << 3)
#define VSC_SF_EXCL (1 << 0)
#define VSC_SF_CL_WC (1 << 1)
#define VSC_SF_ID_WC (1 << 2)
#define VSC_SF_NM_WC (1 << 3)
char *class;
char *ident;
char *name;
......@@ -65,40 +72,56 @@ struct vsc {
unsigned magic;
#define VSC_MAGIC 0x3373554a
int sf_init;
VTAILQ_HEAD(, vsc_pt) pt_list;
VTAILQ_HEAD(, vsc_sf) sf_list;
struct VSM_fantom main_fantom;
struct VSM_fantom iter_fantom;
};
/*--------------------------------------------------------------------*/
void
VSC_Setup(struct VSM_data *vd)
static struct vsc *
vsc_setup(struct VSM_data *vd)
{
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
AZ(vd->vsc);
ALLOC_OBJ(vd->vsc, VSC_MAGIC);
AN(vd->vsc);
VTAILQ_INIT(&vd->vsc->sf_list);
if (vd->vsc == NULL) {
ALLOC_OBJ(vd->vsc, VSC_MAGIC);
VTAILQ_INIT(&vd->vsc->sf_list);
VTAILQ_INIT(&vd->vsc->pt_list);
}
CHECK_OBJ_NOTNULL(vd->vsc, VSC_MAGIC);
return (vd->vsc);
}
/*--------------------------------------------------------------------*/
void
VSC_Delete(struct VSM_data *vd)
static void
vsc_delete_pts(struct vsc *vsc)
{
struct vsc_pt *pt;
struct VSM_fantom *vf = NULL;
while(!VTAILQ_EMPTY(&vsc->pt_list)) {
pt = VTAILQ_FIRST(&vsc->pt_list);
VTAILQ_REMOVE(&vsc->pt_list, pt, list);
if (pt->point.vf != vf) {
vf = pt->point.vf;
free(vf);
}
FREE_OBJ(pt);
}
}
static void
vsc_delete_sfs(struct vsc *vsc)
{
struct vsc_sf *sf;
struct vsc *vsc;
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
vsc = vd->vsc;
vd->vsc = NULL;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
while(!VTAILQ_EMPTY(&vsc->sf_list)) {
sf = VTAILQ_FIRST(&vsc->sf_list);
VTAILQ_REMOVE(&vsc->sf_list, sf, next);
VTAILQ_REMOVE(&vsc->sf_list, sf, list);
free(sf->class);
free(sf->ident);
free(sf->name);
......@@ -106,39 +129,42 @@ VSC_Delete(struct VSM_data *vd)
}
}
/*--------------------------------------------------------------------*/
static int
vsc_sf_arg(const struct VSM_data *vd, const char *opt)
void
VSC_Delete(struct VSM_data *vd)
{
struct vsc *vsc;
struct vsc_sf *sf;
char **av, *q, *p;
int i;
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
vsc = vd->vsc;
vd->vsc = NULL;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
vsc_delete_sfs(vsc);
vsc_delete_pts(vsc);
FREE_OBJ(vsc);
}
if (VTAILQ_EMPTY(&vsc->sf_list)) {
if (*opt == '^')
vsc->sf_init = 1;
}
/*--------------------------------------------------------------------*/
static int
vsc_f_arg(struct VSM_data *vd, const char *opt)
{
struct vsc *vsc = vsc_setup(vd);
struct vsc_sf *sf;
char **av, *q, *p;
int i;
av = VAV_Parse(opt, NULL, ARGV_COMMA);
AN(av);
if (av[0] != NULL) {
vd->diag(vd->priv, "Parse error: %s", av[0]);
return (-1);
}
if (av[0] != NULL)
return (vsm_diag(vd, "Parse error: %s", av[0]));
for (i = 1; av[i] != NULL; i++) {
ALLOC_OBJ(sf, VSL_SF_MAGIC);
ALLOC_OBJ(sf, VSC_SF_MAGIC);
AN(sf);
VTAILQ_INSERT_TAIL(&vsc->sf_list, sf, next);
VTAILQ_INSERT_TAIL(&vsc->sf_list, sf, list);
p = av[i];
if (*p == '^') {
sf->flags |= VSL_SF_EXCL;
sf->flags |= VSC_SF_EXCL;
p++;
}
......@@ -167,21 +193,21 @@ vsc_sf_arg(const struct VSM_data *vd, const char *opt)
q = strchr(sf->class, '*');
if (q != NULL && q[1] == '\0') {
*q = '\0';
sf->flags |= VSL_SF_CL_WC;
sf->flags |= VSC_SF_CL_WC;
}
}
if (sf->ident != NULL) {
q = strchr(sf->ident, '*');
if (q != NULL && q[1] == '\0') {
*q = '\0';
sf->flags |= VSL_SF_ID_WC;
sf->flags |= VSC_SF_ID_WC;
}
}
if (sf->name != NULL) {
q = strchr(sf->name, '*');
if (q != NULL && q[1] == '\0') {
*q = '\0';
sf->flags |= VSL_SF_NM_WC;
sf->flags |= VSC_SF_NM_WC;
}
}
}
......@@ -195,10 +221,8 @@ int
VSC_Arg(struct VSM_data *vd, int arg, const char *opt)
{
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
AN(vd->vsc);
switch (arg) {
case 'f': return (vsc_sf_arg(vd, opt));
case 'f': return (vsc_f_arg(vd, opt));
case 'n': return (VSM_n_Arg(vd, opt));
default:
return (0);
......@@ -207,33 +231,19 @@ VSC_Arg(struct VSM_data *vd, int arg, const char *opt)
/*--------------------------------------------------------------------*/
int
VSC_Open(struct VSM_data *vd, int diag)
{
int i;
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
AN(vd->vsc);
i = VSM_Open(vd, diag);
return (i);
}
/*--------------------------------------------------------------------*/
struct VSC_C_main *
VSC_Main(const struct VSM_data *vd)
VSC_Main(struct VSM_data *vd)
{
struct VSM_fantom vf;
struct vsc *vsc = vsc_setup(vd);
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
CHECK_OBJ_NOTNULL(vd->vsc, VSC_MAGIC);
if (!VSM_Get(vd, &vf, VSC_CLASS, "", ""))
if (!vd->head && VSM_Open(vd))
return (NULL);
return ((void*)vf.b);
if (!VSM_Get(vd, &vsc->main_fantom, VSC_CLASS, "", ""))
return (NULL);
return ((void*)vsc->main_fantom.b);
}
#if 0
/*--------------------------------------------------------------------
* -1 -> unknown stats encountered.
*/
......@@ -256,23 +266,28 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
const struct VSC_point *const sp)
{
struct vsc_sf *sf;
struct vsc_pt *pt;
int good;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
if (VTAILQ_EMPTY(&vsc->sf_list))
return (func(priv, sp));
ALLOC_OBJ(pt, VSC_PT_MAGIC);
AN(pt);
good = vsc->sf_init;
if (VTAILQ_EMPTY(&vsc->sf_list)) {
VTAILQ_INSERT_TAIL(&vsc->pt_list, pt, list);
return (func(priv, sp));
}
VTAILQ_FOREACH(sf, &vsc->sf_list, next) {
if (iter_test(sf->class, sp->class, sf->flags & VSL_SF_CL_WC))
good = 0;
VTAILQ_FOREACH(sf, &vsc->sf_list, list) {
if (iter_test(sf->class, sp->class, sf->flags & VSC_SF_CL_WC))
continue;
if (iter_test(sf->ident, sp->ident, sf->flags & VSL_SF_ID_WC))
if (iter_test(sf->ident, sp->ident, sf->flags & VSC_SF_ID_WC))
continue;
if (iter_test(sf->name, sp->name, sf->flags & VSL_SF_NM_WC))
if (iter_test(sf->name, sp->desc->name, sf->flags & VSC_SF_NM_WC))
continue;
if (sf->flags & VSL_SF_EXCL)
if (sf->flags & VSC_SF_EXCL)
good = 0;
else
good = 1;
......@@ -283,26 +298,27 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
}
#define VSC_DO(U,l,t) \
static int \
static void \
iter_##l(const struct vsc *vsc, struct VSM_fantom *vf, \
VSC_iter_f *func, void *priv) \
const struct VSC_desc *descs) \
{ \
struct VSC_C_##l *st; \
struct VSC_point sp; \
struct VSM_fantom *vf2; \
int i; \
\
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC); \
st = vf->b; \
sp.class = t; \
sp.ident = vf->chunk->ident;
sp.ident = vf->chunk->ident; \
sp.desc = descs++; \
vf2 = malloc(sizeof *vf2); \
AN(vf2); \
memcpy(vf2, vf, sizeof *vf2);
#define VSC_F(nn,tt,ll,ff,dd,ee) \
sp.name = #nn; \
sp.fmt = #tt; \
sp.flag = ff; \
sp.desc = dd; \
sp.ptr = &st->nn; \
i = iter_call(vsc, func, priv, &sp); \
sp.vf = vf2; \
i = iter_call(vsc, &sp); \
if (i) \
return(i);
......@@ -315,19 +331,14 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
#undef VSC_F
#undef VSC_DONE
int
VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
static void
vsc_build_pt_list(struct VSM_data *vd)
{
struct vsc *vsc;
struct vsc *vsc = vsc_setup(vd);
struct VSM_fantom vf;
int i;
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
vsc = vd->vsc;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
i = 0;
if (!VSM_StillValid(vd, NULL))
return (-1);
vsc_delete_pts(vsc *vsc);
VSM_FOREACH_SAFE(&vf, vd) {
if (strcmp(vf.chunk->class, VSC_CLASS))
continue;
......@@ -335,11 +346,8 @@ VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
#define VSC_F(n,t,l,f,d,e)
#define VSC_DONE(a,b,c)
#define VSC_DO(U,l,t) \
if (!strcmp(vf.chunk->type, t)) { \
i = iter_##l(vsc, &vf, func, priv); \
if (!i) \
continue; \
}
if (!strcmp(vf.chunk->type, t)) \
iter_##l(vsc, &vf, VSC_desc_##l);
#include "tbl/vsc_all.h"
#undef VSC_F
#undef VSC_DO
......@@ -349,3 +357,127 @@ VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
}
return (i);
}
#endif
/*--------------------------------------------------------------------
*/
static void
vsc_add_pt(struct vsc *vsc, const char *class, const char *ident,
const struct VSC_desc *desc, const volatile void *ptr,
struct VSM_fantom *vf)
{
struct vsc_pt *pt;
ALLOC_OBJ(pt, VSC_PT_MAGIC);
AN(pt);
pt->point.class = class;
pt->point.ident = ident;
pt->point.desc = desc;
pt->point.ptr = ptr;
pt->point.vf = vf;
VTAILQ_INSERT_TAIL(&vsc->pt_list, pt, list);
}
#define VSC_DO(U,l,t) \
static void \
iter_##l(struct vsc *vsc, struct VSM_fantom *vf, \
const struct VSC_desc *descs) \
{ \
struct VSC_C_##l *st; \
struct VSM_fantom *vf2; \
const char *class = t; \
\
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC); \
st = vf->b; \
vf2 = malloc(sizeof *vf2); \
AN(vf2); \
memcpy(vf2, vf, sizeof *vf2);
#define VSC_F(nn,tt,ll,ff,dd,ee) \
vsc_add_pt(vsc, class, vf->chunk->ident, descs++, \
&st->nn, vf2);
#define VSC_DONE(U,l,t) \
}
#include "tbl/vsc_all.h"
#undef VSC_DO
#undef VSC_F
#undef VSC_DONE
/*--------------------------------------------------------------------
*/
static void
vsc_build_pt_list(struct VSM_data *vd)
{
struct vsc *vsc = vsc_setup(vd);
struct VSM_fantom vf;
vsc_delete_pts(vsc);
VSM_FOREACH_SAFE(&vf, vd) {
if (strcmp(vf.chunk->class, VSC_CLASS))
continue;
/*lint -save -e525 -e539 */
#define VSC_F(n,t,l,f,d,e)
#define VSC_DONE(a,b,c)
#define VSC_DO(U,l,t) \
if (!strcmp(vf.chunk->type, t)) \
iter_##l(vsc, &vf, VSC_desc_##l);
#include "tbl/vsc_all.h"
#undef VSC_F
#undef VSC_DO
#undef VSC_DONE
/*lint -restore */
}
/* XXX: filter pt list */
}
/*--------------------------------------------------------------------
*/
int
VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv)
{
struct vsc *vsc = vsc_setup(vd);
struct vsc_pt *pt;
int i;
if (1 != VSM_StillValid(vd, &vsc->iter_fantom)) {
if (!VSM_Get(vd, &vsc->iter_fantom, VSC_CLASS, "", "")) {
VSM_Close(vd);
if (!vd->head && VSM_Open(vd))
return (-1);
if (!VSM_Get(vd, &vsc->iter_fantom, VSC_CLASS, "", "")) {
return (-1);
}
}
AN(vd->head);
func(priv, NULL);
vsc_build_pt_list(vd);
}
AN(vd->head);
VTAILQ_FOREACH(pt, &vsc->pt_list, list) {
i = func(priv, &pt->point);
if (i)
return (i);
}
return (0);
}
/*--------------------------------------------------------------------
* Build the static point descriptions
*/
#define VSC_F(n,t,l,f,d,e) {#n,#t,f,d,e},
#define VSC_DO(U,l,t) const struct VSC_desc VSC_desc_##l[] = {
#define VSC_DONE(U,l,t) };
#include "tbl/vsc_all.h"
#undef VSC_F
#undef VSC_DO
#undef VSC_DONE
......@@ -113,7 +113,7 @@ VSM_n_Arg(struct VSM_data *vd, const char *opt)
{
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
AN(vd->n_opt);
AN(opt);
REPLACE(vd->n_opt, opt);
if (VIN_N_Arg(vd->n_opt, NULL, NULL, &vd->fname))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment