data-driven loop instead of repeated macro expansions.
bk: 4d204853adS9ECVdNbaDREfNZ4Rq3g
/*
* Sizes of things
*/
-#define LIB_NUMBUFS 200
-#define LIB_BUFLENGTH 80
+#define LIB_NUMBUF 16
+typedef char libbufstr[128];
+extern libbufstr lib_stringbuf[LIB_NUMBUF];
+extern int lib_nextbuf;
+extern int lib_inited;
+
+#define LIB_BUFLENGTH (sizeof(lib_stringbuf) / COUNTOF(lib_stringbuf))
/*
* Macro to get a pointer to the next buffer
*/
-#define LIB_GETBUF(buf) \
- do { \
- if (!lib_inited) \
- init_lib(); \
- buf = &lib_stringbuf[lib_nextbuf][0]; \
- if (++lib_nextbuf >= LIB_NUMBUFS) \
- lib_nextbuf = 0; \
- memset(buf, 0, LIB_BUFLENGTH); \
- } while (0)
-
-extern char lib_stringbuf[LIB_NUMBUFS][LIB_BUFLENGTH];
-extern int lib_nextbuf;
-extern int lib_inited;
+#define LIB_GETBUF(bufp) \
+ do { \
+ if (!lib_inited) \
+ init_lib(); \
+ (bufp) = &lib_stringbuf[lib_nextbuf++][0]; \
+ lib_nextbuf %= COUNTOF(lib_stringbuf); \
+ memset((bufp), '\0', sizeof(lib_stringbuf[0])); \
+ } while (FALSE)
# undef SO_SNDBUF
# endif
#endif
-#ifndef TRUE
-# define TRUE 1
-#endif /* TRUE */
-#ifndef FALSE
-# define FALSE 0
-#endif /* FALSE */
/*
* NTP protocol parameters. See section 3.2.6 of the specification.
extern char * mfptoa (u_long, u_long, short);
extern char * mfptoms (u_long, u_long, short);
extern const char * modetoa (int);
-extern const char * eventstr (int);
-extern const char * ceventstr (int);
+extern const char * eventstr (int);
+extern const char * ceventstr (int);
+extern const char * k_st_flags (u_int32);
extern char * statustoa (int, int);
-extern const char * sysstatstr (int);
-extern const char * peerstatstr (int);
-extern const char * clockstatstr (int);
extern sockaddr_u * netof (sockaddr_u *);
extern char * numtoa (u_int32);
extern char * numtohost (u_int32);
#include "ntp_machine.h"
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
/*
* This is another naming conflict.
* On NetBSD for MAC the macro "mac" is defined as 1
/*
* Storage declarations
*/
-char lib_stringbuf[LIB_NUMBUFS][LIB_BUFLENGTH];
+libbufstr lib_stringbuf[LIB_NUMBUF];
int lib_nextbuf;
int ipv4_works;
int ipv6_works;
#include "ntp_refclock.h"
#include "ntp_control.h"
#include "ntp_string.h"
+#ifdef KERNEL_PLL
+# include "ntp_syscall.h"
+#endif
+
/*
* Structure for turning various constants into a readable string.
{ -1, "" }
};
+/*
+ * Peer status bits
+ */
+static const struct codestring peer_st_bits[] = {
+ { CTL_PST_CONFIG, "conf" },
+ { CTL_PST_AUTHENABLE, "authenb" },
+ { CTL_PST_AUTHENTIC, "auth" },
+ { CTL_PST_REACH, "reach" },
+ { CTL_PST_BCAST, "bcast" },
+ /* not used with getcode(), no terminating entry needed */
+};
+
#ifdef AUTOKEY
/*
* Crypto events (cryp)
};
#endif /* AUTOKEY */
+#ifdef KERNEL_PLL
+/*
+ * kernel discipline status bits
+ */
+static const struct codestring k_st_bits[] = {
+# ifdef STA_PLL
+ { STA_PLL, "pll" },
+# endif
+# ifdef STA_PPSFREQ
+ { STA_PPSFREQ, "ppsfreq" },
+# endif
+# ifdef STA_PPSTIME
+ { STA_PPSTIME, "ppstime" },
+# endif
+# ifdef STA_FLL
+ { STA_FLL, "fll" },
+# endif
+# ifdef STA_INS
+ { STA_INS, "ins" },
+# endif
+# ifdef STA_DEL
+ { STA_DEL, "del" },
+# endif
+# ifdef STA_UNSYNC
+ { STA_UNSYNC, "unsync" },
+# endif
+# ifdef STA_FREQHOLD
+ { STA_FREQHOLD, "freqhold" },
+# endif
+# ifdef STA_PPSSIGNAL
+ { STA_PPSSIGNAL, "ppssignal" },
+# endif
+# ifdef STA_PPSJITTER
+ { STA_PPSJITTER, "ppsjitter" },
+# endif
+# ifdef STA_PPSWANDER
+ { STA_PPSWANDER, "ppswander" },
+# endif
+# ifdef STA_PPSERROR
+ { STA_PPSERROR, "ppserror" },
+# endif
+# ifdef STA_CLOCKERR
+ { STA_CLOCKERR, "clockerr" },
+# endif
+# ifdef STA_NANO
+ { STA_NANO, "nano" },
+# endif
+# ifdef STA_MODE
+ { STA_MODE, "mode=fll" },
+# endif
+# ifdef STA_CLK
+ { STA_CLK, "src=B" },
+# endif
+ /* not used with getcode(), no terminating entry needed */
+};
+#endif /* KERNEL_PLL */
+
/* Forwards */
static const char * getcode(int, const struct codestring *);
static const char * getevents(int);
}
+/*
+ * decode_bitflags()
+ *
+ * returns a human-readable string with a keyword from tab for each bit
+ * set in bits, separating multiple entries with text of sep2.
+ */
static const char *
-peer_st_flags(u_char pst)
+decode_bitflags(
+ int bits,
+ const char * sep2,
+ const struct codestring * tab,
+ size_t tab_ct
+ )
{
- static const char toosmall[] = "buffer too small!";
- static const char csp[] = ", ";
- const char * sep;
- char * buf;
- char * pch;
- char * lim;
- int rc;
+ const char * sep;
+ char * buf;
+ char * pch;
+ char * lim;
+ size_t b;
+ int rc;
LIB_GETBUF(buf);
pch = buf;
lim = buf + LIB_BUFLENGTH;
sep = "";
-#define EXPAND_PEERST_BIT(b, text) \
-do { \
- if ((b) & pst) { \
- rc = snprintf(pch, (lim - pch), "%s" text, sep);\
- if (rc < 0) \
- return toosmall; \
- pch += (u_int)rc; \
- if (pch >= lim) \
- return toosmall; \
- sep = csp; \
- } \
-} while (0)
-
- EXPAND_PEERST_BIT(CTL_PST_CONFIG, "conf");
- EXPAND_PEERST_BIT(CTL_PST_AUTHENABLE, "authenb");
- EXPAND_PEERST_BIT(CTL_PST_AUTHENTIC, "auth");
- EXPAND_PEERST_BIT(CTL_PST_REACH, "reach");
- EXPAND_PEERST_BIT(CTL_PST_BCAST, "bcast");
+ for (b = 0; b < tab_ct; b++) {
+ if (tab[b].code & bits) {
+ rc = snprintf(pch, (lim - pch), "%s%s", sep,
+ tab[b].string);
+ if (rc < 0)
+ goto toosmall;
+ pch += (u_int)rc;
+ if (pch >= lim)
+ goto toosmall;
+ sep = sep2;
+ }
+ }
return buf;
+
+ toosmall:
+ snprintf(buf, LIB_BUFLENGTH,
+ "decode_bitflags(%s) can't decode 0x%x in %d bytes",
+ (tab == peer_st_bits)
+ ? "peer_st"
+ :
+#ifdef KERNEL_PLL
+ (tab == k_st_bits)
+ ? "kern_st"
+ :
+#endif
+ "",
+ bits, (int)LIB_BUFLENGTH);
+
+ return buf;
+}
+
+
+static const char *
+peer_st_flags(
+ u_char pst
+ )
+{
+ return decode_bitflags(pst, ", ", peer_st_bits,
+ COUNTOF(peer_st_bits));
+}
+
+
+#ifdef KERNEL_PLL
+const char *
+k_st_flags(
+ u_int32 st
+ )
+{
+ return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits));
}
+#endif /* KERNEL_PLL */
/*
sockaddr_u *);
static void ctl_putid (const char *, char *);
static void ctl_putarray (const char *, double *, int);
-#ifdef KERNEL_PLL
-static void kstatus_to_text (u_int32, char *, size_t);
-#endif
static void ctl_putsys (int);
static void ctl_putpeer (int, struct peer *);
static void ctl_putfs (const char *, tstamp_t);
ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
}
-/*
- * kstatus_to_text - convert ntp_adjtime() status bits to text
- */
-#ifdef KERNEL_PLL
-void
-kstatus_to_text(
- u_int32 status,
- char * str,
- size_t str_sz
- )
-{
- char * pch;
- const char *lim;
-
- pch = str;
- lim = pch + str_sz;
-
-# define XLATE_KST_BIT(bitval, text) \
-do { \
- if (((bitval) & status) && \
- (pch + sizeof(text) <= lim)) { \
- memcpy(pch, (text), sizeof(text)); \
- pch += (u_int)(sizeof(text) - 1); \
- } \
-} while (0)
-
-# ifdef STA_PLL
- {
- const char spll[] = "pll ";
- XLATE_KST_BIT(STA_PLL, spll);
- }
-# endif
-# ifdef STA_PPSFREQ
- {
- const char sppsfreq[] = "ppsfreq ";
- XLATE_KST_BIT(STA_PPSFREQ, sppsfreq);
- }
-# endif
-# ifdef STA_PPSTIME
- {
- const char sppstime[] = "ppstime ";
- XLATE_KST_BIT(STA_PPSTIME, sppstime);
- }
-# endif
-# ifdef STA_FLL
- {
- const char sfll[] = "fll ";
- XLATE_KST_BIT(STA_FLL, sfll);
- }
-# endif
-# ifdef STA_INS
- {
- const char sins[] = "ins ";
- XLATE_KST_BIT(STA_INS, sins);
- }
-# endif
-# ifdef STA_DEL
- {
- const char sdel[] = "del ";
- XLATE_KST_BIT(STA_DEL, sdel);
- }
-# endif
-# ifdef STA_UNSYNC
- {
- const char sunsync[] = "unsync ";
- XLATE_KST_BIT(STA_UNSYNC, sunsync);
- }
-# endif
-# ifdef STA_FREQHOLD
- {
- const char sfreqhold[] = "freqhold ";
- XLATE_KST_BIT(STA_FREQHOLD, sfreqhold);
- }
-# endif
-# ifdef STA_PPSSIGNAL
- {
- const char sppssignal[] = "ppssignal ";
- XLATE_KST_BIT(STA_PPSSIGNAL, sppssignal);
- }
-# endif
-# ifdef STA_PPSJITTER
- {
- const char sppsjitter[] = "ppsjitter ";
- XLATE_KST_BIT(STA_PPSJITTER, sppsjitter);
- }
-# endif
-# ifdef STA_PPSWANDER
- {
- const char sppswander[] = "ppswander ";
- XLATE_KST_BIT(STA_PPSWANDER, sppswander);
- }
-# endif
-# ifdef STA_PPSERROR
- {
- const char sppserror[] = "ppserror ";
- XLATE_KST_BIT(STA_PPSERROR, sppserror);
- }
-# endif
-# ifdef STA_CLOCKERR
- {
- const char sclockerr[] = "clockerr ";
- XLATE_KST_BIT(STA_CLOCKERR, sclockerr);
- }
-# endif
-# ifdef STA_NANO
- {
- const char snano[] = "nano ";
- XLATE_KST_BIT(STA_NANO, snano);
- }
-# endif
-# ifdef STA_MODE
- {
- const char smodefll[] = "mode=fll ";
- XLATE_KST_BIT(STA_MODE, smodefll);
- }
-# endif
-# ifdef STA_CLK
- {
- const char ssrcb[] = "src=B ";
- XLATE_KST_BIT(STA_CLK, ssrcb);
- }
-# endif
- if (pch > str && ' ' == pch[-1])
- pch[-1] = '\0';
-}
-#endif /* KERNEL_PLL */
-
/*
* ctl_putsys - output a system variable
case CS_K_STFLAGS:
#ifndef KERNEL_PLL
- str[0] = '\0';
+ ss = "";
#else
- kstatus_to_text(ntx.status, str, sizeof(str));
+ ss = k_st_flags(ntx.status);
#endif
- ctl_putstr(sys_var[varid].text, str, strlen(str));
+ ctl_putstr(sys_var[varid].text, ss, strlen(ss));
break;
case CS_K_TIMECONST:
* the retrieved values.
*/
while (nextvar(&rsize, &rdata, &tag, &val)) {
+ if (NULL == val)
+ continue;
for (pvdc = table; pvdc->tag != NULL; pvdc++) {
len = strlen(pvdc->tag);
if (strncmp(tag, pvdc->tag, len))