[Git][NTPsec/ntpsec][master] Autogenerate a Python equivalent of ntp_control.h.
Eric S. Raymond
gitlab at mg.gitlab.com
Mon Oct 17 20:50:23 UTC 2016
Eric S. Raymond pushed to branch master at NTPsec / ntpsec
Commits:
9e1e5c1b by Eric S. Raymond at 2016-10-17T16:48:58-04:00
Autogenerate a Python equivalent of ntp_control.h.
- - - - -
5 changed files:
- .gitignore
- pylib/__init__.py
- pylib/packet.py
- pylib/wscript
- + wafhelpers/pythonize-header
Changes:
=====================================
.gitignore
=====================================
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+pylib/ntp_control.py
.lock-waf*
.waf*
*.pyc
=====================================
pylib/__init__.py
=====================================
--- a/pylib/__init__.py
+++ b/pylib/__init__.py
@@ -4,5 +4,7 @@
# Preserve this property!
from __future__ import absolute_import # Ensure Python2 behaves like Python 3
+from .ntp_control import *
+
api_major_version = 1 # bumped on incompatible changes
api_minor_version = 0 # bumped on compatible changes
=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -1,5 +1,5 @@
#
-# packet.py - definitions and classes for ntp-style querying of NTP
+# packet.py - definitions and classes for Python querying of NTP
#
# This code should be Python2-vs-Python-3 agnostic. Keep it that way!
#
@@ -7,8 +7,9 @@
from __future__ import print_function, division
import sys, socket, select, struct, curses.ascii
-# If you don't keep this file in sync with ntp.h, libntpq.h, and ntp_control.h
-# havoc will ensue.
+from ntp_control import *
+
+# If you don't keep this file in sync with ntp.h, havoc will ensue.
# Things from ntp.h
@@ -22,113 +23,6 @@ NTP_VERSION = 4 # Current version
MODE_CONTROL = 6
-# Things from ntp_control.h.
-
-CTL_MAX_DATA_LEN = 468 # Max data in a control packet
-
-CTL_OP_UNSPEC = 0 # unspecified
-CTL_OP_READSTAT = 1 # read status
-CTL_OP_READVAR = 2 # read variables
-CTL_OP_WRITEVAR = 3 # write variables
-CTL_OP_READCLOCK = 4 # read clock variables
-CTL_OP_WRITECLOCK = 5 # write clock variables
-CTL_OP_SETTRAP = 6 # set trap address (obsolete, unused)
-CTL_OP_ASYNCMSG = 7 # asynchronous message
-CTL_OP_CONFIGURE = 8 # runtime configuration
-CTL_OP_READ_MRU = 10 # retrieve MRU (mrulist)
-CTL_OP_READ_ORDLIST_A = 11 # ordered list req. auth.
-CTL_OP_REQ_NONCE = 12 # request a client nonce
-CTL_OP_UNSETTRAP = 31 # unset trap (obsolete, unused)
-
-# {En,De}coding of the system status word
-
-CTL_SST_TS_UNSPEC = 0 # unspec
-CTL_SST_TS_ATOM = 1 # pps
-CTL_SST_TS_LF = 2 # lf radio
-CTL_SST_TS_HF = 3 # hf radio
-CTL_SST_TS_UHF = 4 # uhf radio
-CTL_SST_TS_LOCAL = 5 # local
-CTL_SST_TS_NTP = 6 # ntp
-CTL_SST_TS_UDPTIME = 7 # other
-CTL_SST_TS_WRSTWTCH = 8 # wristwatch
-CTL_SST_TS_TELEPHONE = 9 # telephone
-
-CTL_SYS_MAXEVENTS = 15
-
-def CTL_SYS_STATUS(li, source, nevnt, evnt): return \
- (((((li))<< 14)&0xc000) | \
- (((source)<<8)&0x3f00) | \
- (((nevnt)<<4)&0x00f0) | \
- ((evnt)&0x000f))
-
-def CTL_SYS_LI(status): return (((status)>>14) & 0x3)
-def CTL_SYS_SOURCE(status): return (((status)>>8) & 0x3f)
-def CTL_SYS_NEVNT(status): return (((status)>>4) & 0xf)
-def CTL_SYS_EVENT(status): return ((status) & 0xf)
-
-# {En,De}coding of the peer status word
-CTL_PST_CONFIG = 0x80
-CTL_PST_AUTHENABLE = 0x40
-CTL_PST_AUTHENTIC = 0x20
-CTL_PST_REACH = 0x10
-CTL_PST_BCAST = 0x08
-
-CTL_PST_SEL_REJECT = 0 # reject
-CTL_PST_SEL_SANE = 1 # x falsetick
-CTL_PST_SEL_CORRECT = 2 # . excess
-CTL_PST_SEL_SELCAND = 3 # - outlier
-CTL_PST_SEL_SYNCCAND = 4 # + candidate
-CTL_PST_SEL_EXCESS = 5 # # backup
-CTL_PST_SEL_SYSPEER = 6 # * sys.peer
-CTL_PST_SEL_PPS = 7 # o pps.peer
-
-CTL_PEER_MAXEVENTS = 15
-
-def CTL_PEER_STATUS(status, nevnt, evnt): return \
- ((((status)<<8) & 0xff00) | \
- (((nevnt)<<4) & 0x00f0) | \
- ((evnt) & 0x000f))
-
-def CTL_PEER_STATVAL(status): return (((status)>>8) & 0xff)
-def CTL_PEER_NEVNT(status): return (((status)>>4) & 0xf)
-def CTL_PEER_EVENT(status): return ((status) & 0xf)
-
-# {En,De}coding of the clock status word
-CTL_CLK_OKAY = 0
-CTL_CLK_NOREPLY = 1
-CTL_CLK_BADFORMAT = 2
-CTL_CLK_FAULT = 3
-CTL_CLK_PROPAGATION = 4
-CTL_CLK_BADDATE = 5
-CTL_CLK_BADTIME = 6
-
-def CTL_CLK_STATUS(status, event): return \
- ((((status)<<8) & 0xff00) | \
- ((event) & 0x00ff))
-
-# Things from libntpq.h
-
-# NTP Status codes
-NTP_STATUS_INVALID = 0
-NTP_STATUS_FALSETICKER = 1
-NTP_STATUS_EXCESS = 2
-NTP_STATUS_OUTLYER = 3
-NTP_STATUS_CANDIDATE = 4
-NTP_STATUS_SELECTED = 5
-NTP_STATUS_SYSPEER = 6
-NTP_STATUS_PPSPEER = 7
-
-# NTP association type identifier
-NTP_CLOCKTYPE_UNKNOWN = '-'
-NTP_CLOCKTYPE_BROADCAST = 'b'
-NTP_CLOCKTYPE_LOCAL = 'l'
-NTP_CLOCKTYPE_UNICAST = 'u'
-NTP_CLOCKTYPE_MULTICAST = 'm'
-
-# Variable Sets
-PEERVARS = CTL_OP_READVAR
-#CLOCKVARS = CTL_OP_CLOCKVAR
-
# From ntpq.h:
# Limit on packets in a single response. Increasing this value to
=====================================
pylib/wscript
=====================================
--- a/pylib/wscript
+++ b/pylib/wscript
@@ -6,4 +6,15 @@ def configure(conf):
conf.check_python_version((2,6,0))
def build(ctx):
+ srcnode = ctx.srcnode.make_node('pylib')
+ target = ctx.srcnode.make_node('pylib/ntp_control.py')
+
+ ctx(
+ before = ['pyc', 'pyo'],
+ cwd = srcnode,
+ rule = '../wafhelpers/pythonize-header ${SRC} >${TGT}',
+ source = "../include/ntp_control.h",
+ target = target,
+ )
+
ctx(features='py', source=ctx.path.ant_glob('*.py'), install_from='.',install_path='${PYTHONDIR}/ntp')
=====================================
wafhelpers/pythonize-header
=====================================
--- /dev/null
+++ b/wafhelpers/pythonize-header
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+"""
+Generate a C Python module from a C file of macro definitions.
+
+Uses simple regexp transformations, so weird headers are likely to confuse it.
+Skips #include lines, struct and union declarations. Transforms comments.
+Does not yet handle externs.
+"""
+
+import sys, re
+
+patterns = (
+ (re.compile(r"/\*(.*)\*/"), r"#\1"),
+ (re.compile(r"^/\*"), r"#"),
+ (re.compile(r"^ *\*/"), r"#"),
+ (re.compile(r"^ \*"), r"#"),
+ (re.compile(r"^#define\s+([A-Z0-9_]+\s+)(.*)"), r"\1= \2"),
+ (re.compile(r"^#define\s+([A-Z0-9_]+)\(([a-z_, ]*)\)"),
+ r"def \1(\2): return"),
+ )
+
+skipstarters = ("struct", "union", "typedef struct", "typedef union")
+
+impossibles = ("sizeof", "offsetof")
+
+def pythonize(rfp, wfp):
+ "Pythonize a specified C header file."
+ wfp.write("# This file was generated by pythonize-header;\n")
+ wfp.write("# DO NOT HAND-HACK IT!\n")
+ skipto = False
+ for line in rfp:
+ # Omit include lines
+ if line.startswith("#include"):
+ continue
+ # Omit structure and union declarations
+ for skipstart in skipstarters:
+ if line.startswith(skipstart):
+ skipto = True
+ break
+ if line.startswith("};"):
+ skipto = False
+ continue
+ # Hack remaining content
+ for (regexp, replacement) in patterns:
+ line = regexp.sub(replacement, line)
+ # Omit some expression elents Python cannot evaluate
+ for word in impossibles:
+ if word in line:
+ line = "# " + line
+ # We're done
+ if not skipto:
+ wfp.write(line)
+
+if __name__ == '__main__':
+ if len(sys.argv) == 1:
+ pythonize(sys.stdin, sys.stdout)
+ else:
+ for path in sys.argv[1:]:
+ with open(path) as rfp:
+ sys.stdout.write("#\n# Definitions from %s begin\n#\n" % path)
+ pythonize(rfp, sys.stdout)
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/9e1e5c1b95ac562876998fd5a69f0d127800ce5c
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20161017/c710e891/attachment.html>
More information about the vc
mailing list