From 01da49766ef4b97802d04b60c9b282dc144a582e Mon Sep 17 00:00:00 2001 From: iamsrinivas Date: Mon, 6 Apr 2015 22:58:56 -0500 Subject: [PATCH 001/325] test_always_seq.py Added new test to increase the coverage of the code. The tests do not reach the full coverage(100%). We need to extend this test to improve the coverage hence forward using this test. --- myhdl/test/core2/test_always_seq.py | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 myhdl/test/core2/test_always_seq.py diff --git a/myhdl/test/core2/test_always_seq.py b/myhdl/test/core2/test_always_seq.py new file mode 100644 index 00000000..95fdfafb --- /dev/null +++ b/myhdl/test/core2/test_always_seq.py @@ -0,0 +1,54 @@ +from random import randrange +from pytest import raises +from myhdl import * + +from myhdl import Signal, Simulation, instances, now + +from myhdl._always_seq import always_seq, _AlwaysSeq, _error, AlwaysSeqError + + + +def test_clock(): + """ check the edge parameter """ + + # should fail without a valid Signal + clock = Signal(bool(0)) + reset = ResetSignal(0, active=0, async=True) + + with raises(AlwaysSeqError) as e: + @always_seq(clock, reset=reset) + def logic1(): + pass + assert e.kind == _error.EdgeType + + # should work with a valid Signal + clock = Signal(bool(0)) + try: + @always_seq(clock.posedge, reset=reset) + def logic2(): + pass + except: + pytest.fail() + +def test_reset(): + """ check the reset parameter """ + + # should fail without a valid ResetSignal + clock = Signal(bool(0)) + reset = Signal(bool(0)) + + with raises(AlwaysSeqError): + @always_seq(clock.posedge, reset=reset) + def logic(): + pass + assert e.kind == _error.ResetType + + # should work with a valid Signal + reset = ResetSignal(0, active=0, async=True) + try: + @always_seq(clock.posedge, reset=reset) + def logic2(): + pass + except: + pytest.fail() + From 044941b7769e8b06848db27474dddb72524bea11 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 04:34:54 -0400 Subject: [PATCH 002/325] use property, setter decorators --- myhdl/_ShadowSignal.py | 16 ++++++------ myhdl/_Signal.py | 59 ++++++++++++++++++++++++------------------ myhdl/_intbv.py | 9 ++++--- myhdl/_tristate.py | 4 +-- 4 files changed, 49 insertions(+), 39 deletions(-) diff --git a/myhdl/_ShadowSignal.py b/myhdl/_ShadowSignal.py index bbb1b67b..b8677d9b 100644 --- a/myhdl/_ShadowSignal.py +++ b/myhdl/_ShadowSignal.py @@ -43,7 +43,9 @@ class _ShadowSignal(_Signal): # self._driven = True # set this in conversion analyzer # remove next attribute assignment - next = property(_Signal._get_next, None, None, "'next' access methods") + @_Signal.next.setter + def next(self, val): + raise AttributeError("ShadowSignals are readonly") @@ -68,14 +70,14 @@ class _SliceSignal(_ShadowSignal): def _genfuncIndex(self): sig, index = self._sig, self._left - set_next = _ShadowSignal._set_next + set_next = _Signal.next.fset while 1: set_next(self, sig[index]) yield sig def _genfuncSlice(self): sig, left, right = self._sig, self._left, self._right - set_next = _Signal._set_next + set_next = _Signal.next.fset while 1: set_next(self, sig[left:right]) yield sig @@ -137,7 +139,7 @@ class ConcatSignal(_ShadowSignal): self._waiter = _SignalTupleWaiter(gen) def genfunc(self): - set_next = _ShadowSignal._set_next + set_next = _Signal.next.fset args = self._args nrbits = self._nrbits newval = intbv(0)[nrbits:] @@ -268,7 +270,8 @@ class _TristateDriver(_Signal): self._next = self._val = self._init = None self._sig = sig - def _set_next(self, val): + @_Signal.next.setter + def next(self, val): if isinstance(val, _Signal): val = val._val if val is None: @@ -278,6 +281,3 @@ class _TristateDriver(_Signal): self._next = self._sig._orival self._setNextVal(val) _siglist.append(self) - - # redefine property because standard inheritance doesn't work for setter/getter functions - next = property(_Signal._get_next, _set_next, None, "'next' access methods") diff --git a/myhdl/_Signal.py b/myhdl/_Signal.py index c27cdc19..81fd32ff 100644 --- a/myhdl/_Signal.py +++ b/myhdl/_Signal.py @@ -204,58 +204,65 @@ class _Signal(object): return [] # support for the 'val' attribute - def _get_val(self): + @property + def val(self): return self._val - val = property(_get_val, None, None, "'val' access methods") # support for the 'next' attribute - def _get_next(self): + @property + def next(self): # if self._next is self._val: # self._next = deepcopy(self._val) _siglist.append(self) return self._next - def _set_next(self, val): + + @next.setter + def next(self, val): if isinstance(val, _Signal): val = val._val self._setNextVal(val) _siglist.append(self) - next = property(_get_next, _set_next, None, "'next' access methods") # support for the 'posedge' attribute - def _get_posedge(self): + @property + def posedge(self): return self._posedgeWaiters - posedge = property(_get_posedge, None, None, "'posedge' access methods") # support for the 'negedge' attribute - def _get_negedge(self): + @property + def negedge(self): return self._negedgeWaiters - negedge = property(_get_negedge, None, None, "'negedge' access methods") # support for the 'min' and 'max' attribute - def _get_max(self): + @property + def max(self): return self._max - max = property(_get_max, None) - def _get_min(self): + + @property + def min(self): return self._min - min = property(_get_min, None) # support for the 'driven' attribute - def _get_driven(self): + @property + def driven(self): return self._driven - def _set_driven(self, val): + + @driven.setter + def driven(self, val): if not val in ("reg", "wire", True): raise ValueError('Expected value "reg", "wire", or True, got "%s"' % val) self._driven = val - driven = property(_get_driven, _set_driven, None, "'driven' access methods") # support for the 'read' attribute - def _get_read(self): + @property + def read(self): return self._read - def _set_read(self, val): + + @read.setter + def read(self, val): if not val in (True, ): raise ValueError('Expected value True, got "%s"' % val) self._markRead() - read = property(_get_read, _set_read, None, "'read' access methods") def _markRead(self): self._read = True @@ -591,12 +598,14 @@ class _DelayedSignal(_Signal): else: return [] - # support for the 'delay' attribute - def _get_delay(self): - return self._delay - def _set_delay(self, delay): - self._delay = delay - delay = property(_get_delay, _set_delay, None, "'delay' access methods") + # support for the 'delay' attribute + @property + def delay(self): + return self._delay + + @delay.setter + def delay(self, delay): + self._delay = delay class _SignalWrap(object): diff --git a/myhdl/_intbv.py b/myhdl/_intbv.py index 05bdc8c3..3b78ae3f 100644 --- a/myhdl/_intbv.py +++ b/myhdl/_intbv.py @@ -62,12 +62,13 @@ class intbv(object): self._handleBounds() # support for the 'min' and 'max' attribute - def _get_max(self): + @property + def max(self): return self._max - max = property(_get_max, None) - def _get_min(self): + + @property + def min(self): return self._min - min = property(_get_min, None) def _handleBounds(self): if self._max is not None: diff --git a/myhdl/_tristate.py b/myhdl/_tristate.py index 5a7b2ae0..c6661c9d 100644 --- a/myhdl/_tristate.py +++ b/myhdl/_tristate.py @@ -54,7 +54,8 @@ class _TristateDriver(_Signal): self._val = None self._bus = bus - def _set_next(self, val): + @_Signal.next.setter + def next(self, val): if isinstance(val, _Signal): val = val._val if val is None: @@ -62,7 +63,6 @@ class _TristateDriver(_Signal): else: self._setNextVal(val) _siglist.append(self._bus) - next = property(_Signal._get_next, _set_next, None, "'next' access methods") class _DelayedTristate(_DelayedSignal, _Tristate): From 5fa590a6329a17c9bf2c5f7ea70325a0db0dd419 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Wed, 8 Apr 2015 16:49:58 -0400 Subject: [PATCH 003/325] use subprocess instead of forking for cosim --- myhdl/_Cosimulation.py | 119 ++++++++++++++------------- myhdl/_Simulation.py | 2 +- myhdl/test/core/test_Cosimulation.py | 2 +- 3 files changed, 63 insertions(+), 60 deletions(-) diff --git a/myhdl/_Cosimulation.py b/myhdl/_Cosimulation.py index 1e4842a9..184901f3 100644 --- a/myhdl/_Cosimulation.py +++ b/myhdl/_Cosimulation.py @@ -21,12 +21,13 @@ from __future__ import absolute_import -import sys import os +import shlex +import subprocess from myhdl._intbv import intbv from myhdl import _simulator, CosimulationError -from myhdl._compat import PY2, to_bytes, to_str +from myhdl._compat import PY2, string_types, to_bytes, to_str _MAXLINE = 4096 @@ -67,67 +68,69 @@ class Cosimulation(object): self._toSizes = toSizes = [] self._toSigs = toSigs = [] self._toSigDict = toSigDict = {} - self._hasChange = 0 self._getMode = 1 - child_pid = self._child_pid = os.fork() - - if child_pid == 0: + def close_rt_wf(): os.close(rt) os.close(wf) - os.environ['MYHDL_TO_PIPE'] = str(wt) - os.environ['MYHDL_FROM_PIPE'] = str(rf) - if isinstance(exe, list): arglist = exe - else: arglist = exe.split() - p = arglist[0] - arglist[0] = os.path.basename(p) - try: - os.execvp(p, arglist) - except OSError as e: - raise CosimulationError(_error.OSError, str(e)) - else: - os.close(wt) - os.close(rf) - while 1: - s = to_str(os.read(rt, _MAXLINE)) - if not s: - raise CosimulationError(_error.SimulationEnd) - e = s.split() - if e[0] == "FROM": - if int(e[1]) != 0: - raise CosimulationError(_error.TimeZero, "$from_myhdl") - for i in range(2, len(e)-1, 2): - n = e[i] - if n in fromSignames: - raise CosimulationError(_error.DuplicateSigNames, n) - if not n in kwargs: - raise CosimulationError(_error.SigNotFound, n) - fromSignames.append(n) - fromSigs.append(kwargs[n]) - fromSizes.append(int(e[i+1])) - os.write(wf, b"OK") - elif e[0] == "TO": - if int(e[1]) != 0: - raise CosimulationError(_error.TimeZero, "$to_myhdl") - for i in range(2, len(e)-1, 2): - n = e[i] - if n in toSignames: - raise CosimulationError(_error.DuplicateSigNames, n) - if not n in kwargs: - raise CosimulationError(_error.SigNotFound, n) - toSignames.append(n) - toSigs.append(kwargs[n]) - toSigDict[n] = kwargs[n] - toSizes.append(int(e[i+1])) - os.write(wf, b"OK") - elif e[0] == "START": - if not toSignames: - raise CosimulationError(_error.NoCommunication) - os.write(wf, b"OK") - break - else: - raise CosimulationError("Unexpected cosim input") + + env = os.environ.copy() + env['MYHDL_TO_PIPE'] = str(wt) + env['MYHDL_FROM_PIPE'] = str(rf) + + if isinstance(exe, string_types): + exe = shlex.split(exe) + + try: + sp = subprocess.Popen(exe, env=env, close_fds=False, + preexec_fn=close_rt_wf) + except OSError as e: + raise CosimulationError(_error.OSError, str(e)) + + self._child = sp + + os.close(wt) + os.close(rf) + while 1: + s = to_str(os.read(rt, _MAXLINE)) + if not s: + raise CosimulationError(_error.SimulationEnd) + e = s.split() + if e[0] == "FROM": + if int(e[1]) != 0: + raise CosimulationError(_error.TimeZero, "$from_myhdl") + for i in range(2, len(e)-1, 2): + n = e[i] + if n in fromSignames: + raise CosimulationError(_error.DuplicateSigNames, n) + if not n in kwargs: + raise CosimulationError(_error.SigNotFound, n) + fromSignames.append(n) + fromSigs.append(kwargs[n]) + fromSizes.append(int(e[i+1])) + os.write(wf, b"OK") + elif e[0] == "TO": + if int(e[1]) != 0: + raise CosimulationError(_error.TimeZero, "$to_myhdl") + for i in range(2, len(e)-1, 2): + n = e[i] + if n in toSignames: + raise CosimulationError(_error.DuplicateSigNames, n) + if not n in kwargs: + raise CosimulationError(_error.SigNotFound, n) + toSignames.append(n) + toSigs.append(kwargs[n]) + toSigDict[n] = kwargs[n] + toSizes.append(int(e[i+1])) + os.write(wf, b"OK") + elif e[0] == "START": + if not toSignames: + raise CosimulationError(_error.NoCommunication) + os.write(wf, b"OK") + break + else: + raise CosimulationError("Unexpected cosim input") def _get(self): if not self._getMode: diff --git a/myhdl/_Simulation.py b/myhdl/_Simulation.py index 4bad6955..80ec07c1 100644 --- a/myhdl/_Simulation.py +++ b/myhdl/_Simulation.py @@ -78,7 +78,7 @@ class Simulation(object): _simulator._cosim = 0 os.close(cosim._rt) os.close(cosim._wf) - os.waitpid(cosim._child_pid, 0) + cosim._child.wait() if _simulator._tracing: _simulator._tracing = 0 _simulator._tf.close() diff --git a/myhdl/test/core/test_Cosimulation.py b/myhdl/test/core/test_Cosimulation.py index 3cbbe2f5..9d66dcdb 100644 --- a/myhdl/test/core/test_Cosimulation.py +++ b/myhdl/test/core/test_Cosimulation.py @@ -60,7 +60,7 @@ class CosimulationTest(TestCase): try: Cosimulation("bla -x 45") except CosimulationError as e: - self.assertTrue(e.kind in(_error.OSError, _error.SimulationEnd)) + self.assertEqual(e.kind, _error.OSError) else: self.fail() From 49beb8086e6a733db50f0ac533f6138253e0eaab Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 11:18:45 -0400 Subject: [PATCH 004/325] merge icarus cosim test makefile into main makefile --- cosimulation/icarus/Makefile | 2 +- cosimulation/icarus/test/Makefile | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 cosimulation/icarus/test/Makefile diff --git a/cosimulation/icarus/Makefile b/cosimulation/icarus/Makefile index 6b7a8a63..c8400eb9 100644 --- a/cosimulation/icarus/Makefile +++ b/cosimulation/icarus/Makefile @@ -5,7 +5,7 @@ myhdl.vpi: myhdl.c myhdl_table.c .PHONY: test test: myhdl.vpi - make -C test + cd test && python test_all.py clean: -rm *.o *.vpi diff --git a/cosimulation/icarus/test/Makefile b/cosimulation/icarus/test/Makefile deleted file mode 100644 index 7bda0e01..00000000 --- a/cosimulation/icarus/test/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - python test_all.py From 32c8b7f3e81b7c6aa679de92077bcf67272d60da Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 11:24:54 -0400 Subject: [PATCH 005/325] simplify modelsim cosim test process - Use myhdl_vpi.so from parent directory - Automatically delete and create work library - Add test target to main makefile --- cosimulation/modelsim/Makefile | 3 ++- cosimulation/modelsim/test/Makefile | 2 -- cosimulation/modelsim/test/bin2gray.py | 2 +- cosimulation/modelsim/test/dff.py | 2 +- cosimulation/modelsim/test/dff_clkout.py | 2 +- cosimulation/modelsim/test/inc.py | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) delete mode 100644 cosimulation/modelsim/test/Makefile diff --git a/cosimulation/modelsim/Makefile b/cosimulation/modelsim/Makefile index 84bb4349..fa21f85c 100644 --- a/cosimulation/modelsim/Makefile +++ b/cosimulation/modelsim/Makefile @@ -31,4 +31,5 @@ clean: .PHONY: test test: myhdl_vpi.so - make -C test + rm -rf test/work + cd test && vlib work && python test_all.py diff --git a/cosimulation/modelsim/test/Makefile b/cosimulation/modelsim/test/Makefile deleted file mode 100644 index 7bda0e01..00000000 --- a/cosimulation/modelsim/test/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - python test_all.py diff --git a/cosimulation/modelsim/test/bin2gray.py b/cosimulation/modelsim/test/bin2gray.py index 0fbb5d9c..23c3e728 100644 --- a/cosimulation/modelsim/test/bin2gray.py +++ b/cosimulation/modelsim/test/bin2gray.py @@ -2,7 +2,7 @@ import os from myhdl import Cosimulation -cmd = 'vsim -c -quiet -pli myhdl_vpi.so -do cosim.do dut_bin2gray' +cmd = 'vsim -c -quiet -pli ../myhdl_vpi.so -do cosim.do dut_bin2gray' def bin2gray(B, G, width): os.system('vlog -quiet +define+width=%s ../../test/verilog/bin2gray.v' % (width)) diff --git a/cosimulation/modelsim/test/dff.py b/cosimulation/modelsim/test/dff.py index b02c45bd..1ec6e45c 100644 --- a/cosimulation/modelsim/test/dff.py +++ b/cosimulation/modelsim/test/dff.py @@ -2,7 +2,7 @@ import os from myhdl import Cosimulation -cmd = 'vsim -c -quiet -pli myhdl_vpi.so -do cosim.do dut_dff' +cmd = 'vsim -c -quiet -pli ../myhdl_vpi.so -do cosim.do dut_dff' def dff(q, d, clk, reset): os.system('vlog -quiet ../../test/verilog/dff.v') diff --git a/cosimulation/modelsim/test/dff_clkout.py b/cosimulation/modelsim/test/dff_clkout.py index 5ec0e431..a6fad00f 100644 --- a/cosimulation/modelsim/test/dff_clkout.py +++ b/cosimulation/modelsim/test/dff_clkout.py @@ -3,7 +3,7 @@ import os.path as path from myhdl import Cosimulation -cmd = 'vsim -c -quiet -pli myhdl_vpi.so -do cosim.do dut_dff_clkout' +cmd = 'vsim -c -quiet -pli ../myhdl_vpi.so -do cosim.do dut_dff_clkout' def dff_clkout(clkout, q, d, clk, reset): os.system('vlog -quiet ../../test/verilog/dff_clkout.v') diff --git a/cosimulation/modelsim/test/inc.py b/cosimulation/modelsim/test/inc.py index d8adb5e6..a8644439 100644 --- a/cosimulation/modelsim/test/inc.py +++ b/cosimulation/modelsim/test/inc.py @@ -2,7 +2,7 @@ import os from myhdl import Cosimulation -cmd = 'vsim -c -quiet -pli myhdl_vpi.so -do cosim.do dut_inc' +cmd = 'vsim -c -quiet -pli ../myhdl_vpi.so -do cosim.do dut_inc' def inc(count, enable, clock, reset, n): os.system('vlog -quiet +define+n=%s ../../test/verilog/inc.v' % (n)) From f7e1f0cfe023bd7b5471f3908e5d3867cd833585 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 11:47:35 -0400 Subject: [PATCH 006/325] travis: remove core and bugs from allowed py3k failures --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index c8f87d93..2b34990c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,9 @@ env: matrix: allow_failures: - python: "3.4" + env: CI_TARGET=icarus + - python: "3.4" + env: CI_TARGET=ghdl script: ./ci.sh From e817eaa4dd013bc540c076ef2b4c752f72d5f54e Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 11:33:06 -0400 Subject: [PATCH 007/325] use pytest to run core tests --- ci.sh | 1 - myhdl/test/core/Makefile | 2 +- .../test/{core2 => core}/test_ShadowSignal.py | 0 myhdl/test/core/test_all.py | 50 ------------------- myhdl/test/core2/Makefile | 2 - 5 files changed, 1 insertion(+), 54 deletions(-) rename myhdl/test/{core2 => core}/test_ShadowSignal.py (100%) delete mode 100644 myhdl/test/core/test_all.py delete mode 100644 myhdl/test/core2/Makefile diff --git a/ci.sh b/ci.sh index 862d98c5..701ba485 100755 --- a/ci.sh +++ b/ci.sh @@ -23,7 +23,6 @@ echo -e "Running $CI_TARGET tests\n" CI_TARGET=${CI_TARGET:-core} if [ "$CI_TARGET" == "core" ]; then run_test make -C myhdl/test/core - run_test make -C myhdl/test/core2 elif [ "$CI_TARGET" == "icarus" ]; then run_test make -C "myhdl/test/conversion/general" icarus run_test make -C cosimulation/icarus test diff --git a/myhdl/test/core/Makefile b/myhdl/test/core/Makefile index 72ddf460..15beb8c0 100644 --- a/myhdl/test/core/Makefile +++ b/myhdl/test/core/Makefile @@ -1,5 +1,5 @@ all: - python test_all.py + py.test clean: - rm *.pyc *~ diff --git a/myhdl/test/core2/test_ShadowSignal.py b/myhdl/test/core/test_ShadowSignal.py similarity index 100% rename from myhdl/test/core2/test_ShadowSignal.py rename to myhdl/test/core/test_ShadowSignal.py diff --git a/myhdl/test/core/test_all.py b/myhdl/test/core/test_all.py deleted file mode 100644 index 56acc97c..00000000 --- a/myhdl/test/core/test_all.py +++ /dev/null @@ -1,50 +0,0 @@ -# This file is part of the myhdl library, a Python package for using -# Python as a Hardware Description Language. -# -# Copyright (C) 2003-2008 Jan Decaluwe -# -# The myhdl library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation; either version 2.1 of the -# License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -""" Run all myhdl unit tests. """ -from __future__ import absolute_import - - -import test_Simulation, test_Signal, test_intbv, test_Cosimulation, test_misc, \ - test_always_comb, test_bin, test_traceSignals, test_enum, test_concat, \ - test_inferWaiter, test_always, test_instance, test_signed, \ - test_modbv - -modules = (test_Simulation, test_Signal, test_intbv, test_misc, test_always_comb, - test_bin, test_traceSignals, test_enum, test_concat, - test_inferWaiter, test_always, test_instance, test_signed, - test_modbv - ) - -import unittest - -tl = unittest.defaultTestLoader -def suite(): - alltests = unittest.TestSuite() - for m in modules: - alltests.addTest(tl.loadTestsFromModule(m)) - return alltests - -def main(): - unittest.main(defaultTest='suite', - testRunner=unittest.TextTestRunner(verbosity=2)) - - -if __name__ == '__main__': - main() diff --git a/myhdl/test/core2/Makefile b/myhdl/test/core2/Makefile deleted file mode 100644 index d4b3a03d..00000000 --- a/myhdl/test/core2/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - py.test From 9a7d8796b3644dd4891acb8a94b21654933dfbca Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 06:45:23 -0400 Subject: [PATCH 008/325] remove test of non existant unparse --- myhdl/test/core/test_unparse.py | 76 --------------------------------- 1 file changed, 76 deletions(-) delete mode 100644 myhdl/test/core/test_unparse.py diff --git a/myhdl/test/core/test_unparse.py b/myhdl/test/core/test_unparse.py deleted file mode 100644 index f4acf72a..00000000 --- a/myhdl/test/core/test_unparse.py +++ /dev/null @@ -1,76 +0,0 @@ -# This file is part of the myhdl library, a Python package for using -# Python as a Hardware Description Language. -# -# Copyright (C) 2003-2008 Jan Decaluwe -# -# The myhdl library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation; either version 2.1 of the -# License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -""" Run the unit tests for _unparse """ -from __future__ import absolute_import - - -import unittest -from unittest import TestCase -import compiler -from myhdl._unparse import _unparse - -class UnparseTest(TestCase): - - expressions = [ "a + b", - "a - b", - "(a + b)", - "(a - b) - ( c + d) + 1", - "a & b", - "a | b", - "a ^ b", - "a < b", - "a < c > 1", - "a == b <= c >= d != e", - "a // b", - "~c", - "a << b", - "c % d", - "e * f + c", - "not e", - "d or a", - "a and b or c and d", - "a ** b", - "a >> b", - "a[m:n]", - "a[m+1:m-2]", - "a[n]", - "+e", - "-f", - "a(b)", - "f(g, h, i)", - "f(g, h, *args)", - "f(g, h, **kwargs)", - "f(g, h, *args, **kwargs)", - "f.attr", - "f.attr + 1 * h(g[k//2:3] & b[m])" - ] - - def testUnparse(self): - for expr in self.expressions: - ast = compiler.parse(expr) - s = _unparse(ast ) - ast_unparse = compiler.parse(s) - self.assertEqual(str(ast), str(ast_unparse)) - -if __name__ == "__main__": - unittest.main() - - - From 3e4a2119d906060edd45226d50be73229a386d94 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 11:58:19 -0400 Subject: [PATCH 009/325] travis: move bugs to icarus, ghdl targets --- .travis.yml | 1 - ci.sh | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2b34990c..711654f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,6 @@ env: - CI_TARGET=core - CI_TARGET=icarus - CI_TARGET=ghdl - - CI_TARGET=bugs matrix: allow_failures: diff --git a/ci.sh b/ci.sh index 701ba485..11b8b5db 100755 --- a/ci.sh +++ b/ci.sh @@ -27,11 +27,10 @@ elif [ "$CI_TARGET" == "icarus" ]; then run_test make -C "myhdl/test/conversion/general" icarus run_test make -C cosimulation/icarus test run_test make -C myhdl/test/conversion/toVerilog + run_test make -C "myhdl/test/bugs" icarus elif [ "$CI_TARGET" == "ghdl" ]; then run_test make -C "myhdl/test/conversion/general" GHDL run_test make -C myhdl/test/conversion/toVHDL GHDL -elif [ "$CI_TARGET" == "bugs" ]; then - run_test make -C "myhdl/test/bugs" icarus run_test make -C "myhdl/test/bugs" GHDL fi From e40e301764f1aa4a72551e4bf4dfacb7f4fd2c28 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 12:10:57 -0400 Subject: [PATCH 010/325] make test_cosimulation py3 compatible --- myhdl/test/core/test_Cosimulation.py | 59 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/myhdl/test/core/test_Cosimulation.py b/myhdl/test/core/test_Cosimulation.py index 9d66dcdb..f628f3dd 100644 --- a/myhdl/test/core/test_Cosimulation.py +++ b/myhdl/test/core/test_Cosimulation.py @@ -35,6 +35,7 @@ MAXLINE = 4096 from myhdl import Signal from myhdl._Cosimulation import Cosimulation, CosimulationError, _error +from myhdl._compat import to_bytes exe = "python test_Cosimulation.py CosimulationTest" @@ -76,11 +77,11 @@ class CosimulationTest(TestCase): def cosimNotUnique(self): wt = int(os.environ['MYHDL_TO_PIPE']) rf = int(os.environ['MYHDL_FROM_PIPE']) - os.write(wt, "TO 00 a 1") + os.write(wt, b"TO 00 a 1") os.read(rf, MAXLINE) - os.write(wt, "FROM 00 d 1") + os.write(wt, b"FROM 00 d 1") os.read(rf, MAXLINE) - os.write(wt, "START") + os.write(wt, b"START") os.read(rf, MAXLINE) def testFromSignals(self): @@ -94,11 +95,11 @@ class CosimulationTest(TestCase): buf = "FROM 00 " for s, w in zip(fromSignames, fromSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) - os.write(wt, "TO 0000 a 1") + os.write(wt, b"TO 0000 a 1") os.read(rf, MAXLINE) - os.write(wt, "START") + os.write(wt, b"START") os.read(rf, MAXLINE) def testToSignals(self): @@ -114,11 +115,11 @@ class CosimulationTest(TestCase): buf = "TO 00 " for s, w in zip(toSignames, toSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) - os.write(wt, "FROM 0000") + os.write(wt, b"FROM 0000") os.read(rf, MAXLINE) - os.write(wt, "START") + os.write(wt, b"START") os.read(rf, MAXLINE) def testFromToSignals(self): @@ -134,14 +135,14 @@ class CosimulationTest(TestCase): buf = "FROM 00 " for s, w in zip(fromSignames, fromSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) buf = "TO 00 " for s, w in zip(toSignames, toSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) - os.write(wt, "START") + os.write(wt, b"START") os.read(rf, MAXLINE) def testTimeZero(self): @@ -158,7 +159,7 @@ class CosimulationTest(TestCase): buf = "TO 01 " for s, w in zip(fromSignames, fromSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) def testNoComm(self): try: @@ -171,11 +172,11 @@ class CosimulationTest(TestCase): def cosimNoComm(self): wt = int(os.environ['MYHDL_TO_PIPE']) rf = int(os.environ['MYHDL_FROM_PIPE']) - os.write(wt, "FROM 0000") + os.write(wt, b"FROM 0000") os.read(rf, MAXLINE) - os.write(wt, "TO 0000") + os.write(wt, b"TO 0000") os.read(rf, MAXLINE) - os.write(wt, "START ") + os.write(wt, b"START ") os.read(rf, MAXLINE) def testFromSignalsDupl(self): @@ -193,7 +194,7 @@ class CosimulationTest(TestCase): for s, w in zip(fromSignames, fromSizes): buf += "%s %s " % (s, w) buf += "bb 5" - os.write(wt, buf) + os.write(wt, to_bytes(buf)) def testToSignalsDupl(self): try: @@ -210,7 +211,7 @@ class CosimulationTest(TestCase): for s, w in zip(toSignames, toSizes): buf += "%s %s " % (s, w) buf += "fff 6" - os.write(wt, buf) + os.write(wt, to_bytes(buf)) def testFromSignalVals(self): cosim = Cosimulation(exe + ".cosimFromSignalVals", **allSigs) @@ -224,15 +225,15 @@ class CosimulationTest(TestCase): buf = "FROM 00 " for s, w in zip(fromSignames, fromSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) - os.write(wt, "TO 0000 a 1") + os.write(wt, b"TO 0000 a 1") os.read(rf, MAXLINE) - os.write(wt, "START") + os.write(wt, b"START") os.read(rf, MAXLINE) - os.write(wt, "DUMMY") + os.write(wt, b"DUMMY") s = os.read(rf, MAXLINE) - vals = [long(e, 16) for e in s.split()[1:]] + vals = [int(e, 16) for e in s.split()[1:]] self.assertEqual(vals, fromVals) def testToSignalVals(self): @@ -242,7 +243,7 @@ class CosimulationTest(TestCase): cosim._get() for n, v in zip(toSignames, toVals): self.assertEqual(toSigs[n].next, v) - os.write(cosim._wf, "DUMMY") + os.write(cosim._wf, b"DUMMY") cosim._getMode = 1 cosim._get() for n in toSignames: @@ -255,14 +256,14 @@ class CosimulationTest(TestCase): buf = "FROM 00 " for s, w in zip(fromSignames, fromSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) buf = "TO 00 " for s, w in zip(toSignames, toSizes): buf += "%s %s " % (s, w) - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) - os.write(wt, "START") + os.write(wt, b"START") os.read(rf, MAXLINE) buf = "0 " for s, v in zip(toSignames, toVals): @@ -270,7 +271,7 @@ class CosimulationTest(TestCase): buf += " " buf += hex(v)[2:] buf += " " - os.write(wt, buf) + os.write(wt, to_bytes(buf)) os.read(rf, MAXLINE) buf = "0 " for s, v in zip(toSignames, toXVals): @@ -278,7 +279,7 @@ class CosimulationTest(TestCase): buf += " " buf += v buf += " " - os.write(wt, buf) + os.write(wt, to_bytes(buf)) def suite(): return unittest.makeSuite(CosimulationTest, 'test') From 88cb76b5c3b24d1df11069082d06e0dd04b58232 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 14 Apr 2015 14:24:49 -0400 Subject: [PATCH 011/325] mark test_Cosimulation as expected failure on pypy --- myhdl/_compat.py | 1 + myhdl/test/core/test_Cosimulation.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/myhdl/_compat.py b/myhdl/_compat.py index 43312e58..63818c62 100644 --- a/myhdl/_compat.py +++ b/myhdl/_compat.py @@ -2,6 +2,7 @@ import sys import types PY2 = sys.version_info[0] == 2 +PYPY = hasattr(sys, 'pypy_translation_info') _identity = lambda x: x diff --git a/myhdl/test/core/test_Cosimulation.py b/myhdl/test/core/test_Cosimulation.py index f628f3dd..2d6ad579 100644 --- a/myhdl/test/core/test_Cosimulation.py +++ b/myhdl/test/core/test_Cosimulation.py @@ -32,10 +32,11 @@ random.seed(1) # random, but deterministic MAXLINE = 4096 +import pytest from myhdl import Signal from myhdl._Cosimulation import Cosimulation, CosimulationError, _error -from myhdl._compat import to_bytes +from myhdl._compat import to_bytes, PYPY exe = "python test_Cosimulation.py CosimulationTest" @@ -55,6 +56,7 @@ toXVals = ["X00", "FZ3", "34XZ", "56U"] allSigs = fromSigs.copy() allSigs.update(toSigs) +@pytest.mark.xfail(PYPY, reason="This test does not work on pypy") class CosimulationTest(TestCase): def testWrongExe(self): From 08519b452f153885d3cc43038111b7779e2bb2f1 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Wed, 15 Apr 2015 23:07:12 -0400 Subject: [PATCH 012/325] Rename attribute references in the AST before analysis fixes #33 --- myhdl/_resolverefs.py | 18 +++++++++++------- myhdl/conversion/_analyze.py | 9 --------- .../conversion/general/test_interfaces3.py | 1 - 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/myhdl/_resolverefs.py b/myhdl/_resolverefs.py index b3b2e3e6..cba6c83e 100644 --- a/myhdl/_resolverefs.py +++ b/myhdl/_resolverefs.py @@ -1,5 +1,6 @@ from __future__ import absolute_import import ast +import itertools from types import FunctionType from myhdl._util import _flatten, _makeAST, _genfunc @@ -25,6 +26,10 @@ def _resolveRefs(symdict, arg): #TODO: Refactor this into two separate nodetransformers, since _resolveRefs #needs only the names, not the objects +def _suffixer(name): + suffixed_names = (name+'_renamed{0}'.format(i) for i in itertools.count()) + return itertools.chain([name], suffixed_names) + class _AttrRefTransformer(ast.NodeTransformer): def __init__(self, data): @@ -52,13 +57,12 @@ class _AttrRefTransformer(ast.NodeTransformer): return node attrobj = getattr(obj, node.attr) - new_name = node.value.id+'.'+node.attr - if new_name not in self.data.symdict: - self.data.symdict[new_name] = attrobj - self.data.objlist.append(new_name) - else: - pass - #assert self.data.symdict[new_name] == attrobj + + name = node.value.id + '_' + node.attr + new_name = next(s for s in _suffixer(name) if s not in self.data.symdict) + self.data.symdict[new_name] = attrobj + self.data.objlist.append(new_name) + new_node = ast.Name(id=new_name, ctx=node.value.ctx) return ast.copy_location(new_node, node) diff --git a/myhdl/conversion/_analyze.py b/myhdl/conversion/_analyze.py index 45085a9f..42502a55 100644 --- a/myhdl/conversion/_analyze.py +++ b/myhdl/conversion/_analyze.py @@ -57,15 +57,6 @@ _extConstDict = {} def _makeName(n, prefixes, namedict): - #Take care of names with periods - #For attribute references, periods are replaced with '_'. - if '.' in n: - n = n.replace('.', '_') - if n in namedict: - i = 0 - while (n + '_{0}'.format(i)) in namedict: - i += 1 - n += '_{0}'.format(i) # trim empty prefixes prefixes = [p for p in prefixes if p] if len(prefixes) > 1: diff --git a/myhdl/test/conversion/general/test_interfaces3.py b/myhdl/test/conversion/general/test_interfaces3.py index 8a86a76b..d5c391b4 100644 --- a/myhdl/test/conversion/general/test_interfaces3.py +++ b/myhdl/test/conversion/general/test_interfaces3.py @@ -188,7 +188,6 @@ def test_three_analyze(): intf = IntfWithConstant2() analyze(m_top_const, clock, reset, x, y, intf) -@bug('33', 'vhdl') def test_three_verify(): assert verify(c_testbench_three) == 0 From 6fe06849a47fe6026c4604fd4e64c35c654ac53a Mon Sep 17 00:00:00 2001 From: iamsrinivas Date: Fri, 17 Apr 2015 11:10:16 -0500 Subject: [PATCH 013/325] Update test_always_seq.py Fixed bugs --- myhdl/test/core2/test_always_seq.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/myhdl/test/core2/test_always_seq.py b/myhdl/test/core2/test_always_seq.py index 95fdfafb..1506ac0c 100644 --- a/myhdl/test/core2/test_always_seq.py +++ b/myhdl/test/core2/test_always_seq.py @@ -28,7 +28,7 @@ def test_clock(): def logic2(): pass except: - pytest.fail() + assert False def test_reset(): """ check the reset parameter """ @@ -37,7 +37,7 @@ def test_reset(): clock = Signal(bool(0)) reset = Signal(bool(0)) - with raises(AlwaysSeqError): + with raises(AlwaysSeqError) as e: @always_seq(clock.posedge, reset=reset) def logic(): pass @@ -50,5 +50,5 @@ def test_reset(): def logic2(): pass except: - pytest.fail() + assert False From f8825dd92c13151a75486feb6a09675ef9f32ce1 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Wed, 15 Apr 2015 16:49:24 -0400 Subject: [PATCH 014/325] added tox.ini, autobuild target for docs makefile --- .gitignore | 1 + Makefile | 6 ++++++ doc/Makefile | 5 +++++ tox.ini | 12 ++++++++++++ 4 files changed, 24 insertions(+) create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 783f07d7..d69b2262 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ build/ __pycache__/ *egg-info/ dist/ +.tox # Cosim *.o diff --git a/Makefile b/Makefile index ce777ea6..2f00ea29 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,12 @@ install: localinstall: python setup.py install --home=$(HOME) +docs: + tox -e docs html + +livedocs: + tox -e docs livehtml + release: - rm MANIFEST - rm CHANGELOG.txt diff --git a/doc/Makefile b/doc/Makefile index 5a310c53..e776f544 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -19,6 +19,7 @@ I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" + @echo " livehtml to make continuously updating standalone HTML files" @echo " web to make files usable by Sphinx.web" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @@ -41,6 +42,10 @@ html: @echo @echo "Build finished. The HTML pages are in build/html." +livehtml: + mkdir -p build/html build/doctrees + sphinx-autobuild -b html $(ALLSPHINXOPTS) build/html + web: mkdir -p build/web build/doctrees $(SPHINXBUILD) -b web $(ALLSPHINXOPTS) build/web diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..2f1dbc8c --- /dev/null +++ b/tox.ini @@ -0,0 +1,12 @@ +[tox] +envlist = py27,py34 + +[testenv] +deps = pytest +commands = py.test [] + +[testenv:docs] +whitelist_externals = make +changedir = doc +deps = sphinx-autobuild +commands = make [] From 905cc11298b2311e661e626b9e43e58490470765 Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Sat, 18 Apr 2015 18:31:04 -0400 Subject: [PATCH 015/325] move benchmarks to scripts folder --- {myhdl/test => scripts}/benchmark/Makefile | 0 {myhdl/test => scripts}/benchmark/convert.py | 0 {myhdl/test => scripts}/benchmark/cvcrun.sh | 0 {myhdl/test => scripts}/benchmark/cvcstats.dat | 0 {myhdl/test => scripts}/benchmark/glibc_random.py | 0 {myhdl/test => scripts}/benchmark/jitrun.sh | 0 {myhdl/test => scripts}/benchmark/jitstats.dat | 0 {myhdl/test => scripts}/benchmark/lfsr24.py | 0 {myhdl/test => scripts}/benchmark/long_divider.py | 0 {myhdl/test => scripts}/benchmark/pypyrun.sh | 0 {myhdl/test => scripts}/benchmark/pypystats.dat | 0 {myhdl/test => scripts}/benchmark/random_generator.py | 0 {myhdl/test => scripts}/benchmark/run.do | 0 {myhdl/test => scripts}/benchmark/run.sh | 0 {myhdl/test => scripts}/benchmark/run_rand.sh | 0 {myhdl/test => scripts}/benchmark/stats.dat | 0 {myhdl/test => scripts}/benchmark/test_findmax.py | 0 {myhdl/test => scripts}/benchmark/test_findmax_sigs.py | 0 {myhdl/test => scripts}/benchmark/test_lfsr24.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_10.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_11.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_12.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_13.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_14.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_15.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_16.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_17.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_18.py | 0 {myhdl/test => scripts}/benchmark/test_longdiv_9.py | 0 {myhdl/test => scripts}/benchmark/test_randgen.py | 0 {myhdl/test => scripts}/benchmark/test_timer.py | 0 {myhdl/test => scripts}/benchmark/test_timer_array.py | 0 {myhdl/test => scripts}/benchmark/testrun.sh | 0 {myhdl/test => scripts}/benchmark/teststats.dat | 0 {myhdl/test => scripts}/benchmark/timer.py | 0 36 files changed, 0 insertions(+), 0 deletions(-) rename {myhdl/test => scripts}/benchmark/Makefile (100%) rename {myhdl/test => scripts}/benchmark/convert.py (100%) rename {myhdl/test => scripts}/benchmark/cvcrun.sh (100%) rename {myhdl/test => scripts}/benchmark/cvcstats.dat (100%) rename {myhdl/test => scripts}/benchmark/glibc_random.py (100%) rename {myhdl/test => scripts}/benchmark/jitrun.sh (100%) rename {myhdl/test => scripts}/benchmark/jitstats.dat (100%) rename {myhdl/test => scripts}/benchmark/lfsr24.py (100%) rename {myhdl/test => scripts}/benchmark/long_divider.py (100%) rename {myhdl/test => scripts}/benchmark/pypyrun.sh (100%) rename {myhdl/test => scripts}/benchmark/pypystats.dat (100%) rename {myhdl/test => scripts}/benchmark/random_generator.py (100%) rename {myhdl/test => scripts}/benchmark/run.do (100%) rename {myhdl/test => scripts}/benchmark/run.sh (100%) rename {myhdl/test => scripts}/benchmark/run_rand.sh (100%) rename {myhdl/test => scripts}/benchmark/stats.dat (100%) rename {myhdl/test => scripts}/benchmark/test_findmax.py (100%) rename {myhdl/test => scripts}/benchmark/test_findmax_sigs.py (100%) rename {myhdl/test => scripts}/benchmark/test_lfsr24.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_10.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_11.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_12.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_13.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_14.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_15.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_16.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_17.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_18.py (100%) rename {myhdl/test => scripts}/benchmark/test_longdiv_9.py (100%) rename {myhdl/test => scripts}/benchmark/test_randgen.py (100%) rename {myhdl/test => scripts}/benchmark/test_timer.py (100%) rename {myhdl/test => scripts}/benchmark/test_timer_array.py (100%) rename {myhdl/test => scripts}/benchmark/testrun.sh (100%) rename {myhdl/test => scripts}/benchmark/teststats.dat (100%) rename {myhdl/test => scripts}/benchmark/timer.py (100%) diff --git a/myhdl/test/benchmark/Makefile b/scripts/benchmark/Makefile similarity index 100% rename from myhdl/test/benchmark/Makefile rename to scripts/benchmark/Makefile diff --git a/myhdl/test/benchmark/convert.py b/scripts/benchmark/convert.py similarity index 100% rename from myhdl/test/benchmark/convert.py rename to scripts/benchmark/convert.py diff --git a/myhdl/test/benchmark/cvcrun.sh b/scripts/benchmark/cvcrun.sh similarity index 100% rename from myhdl/test/benchmark/cvcrun.sh rename to scripts/benchmark/cvcrun.sh diff --git a/myhdl/test/benchmark/cvcstats.dat b/scripts/benchmark/cvcstats.dat similarity index 100% rename from myhdl/test/benchmark/cvcstats.dat rename to scripts/benchmark/cvcstats.dat diff --git a/myhdl/test/benchmark/glibc_random.py b/scripts/benchmark/glibc_random.py similarity index 100% rename from myhdl/test/benchmark/glibc_random.py rename to scripts/benchmark/glibc_random.py diff --git a/myhdl/test/benchmark/jitrun.sh b/scripts/benchmark/jitrun.sh similarity index 100% rename from myhdl/test/benchmark/jitrun.sh rename to scripts/benchmark/jitrun.sh diff --git a/myhdl/test/benchmark/jitstats.dat b/scripts/benchmark/jitstats.dat similarity index 100% rename from myhdl/test/benchmark/jitstats.dat rename to scripts/benchmark/jitstats.dat diff --git a/myhdl/test/benchmark/lfsr24.py b/scripts/benchmark/lfsr24.py similarity index 100% rename from myhdl/test/benchmark/lfsr24.py rename to scripts/benchmark/lfsr24.py diff --git a/myhdl/test/benchmark/long_divider.py b/scripts/benchmark/long_divider.py similarity index 100% rename from myhdl/test/benchmark/long_divider.py rename to scripts/benchmark/long_divider.py diff --git a/myhdl/test/benchmark/pypyrun.sh b/scripts/benchmark/pypyrun.sh similarity index 100% rename from myhdl/test/benchmark/pypyrun.sh rename to scripts/benchmark/pypyrun.sh diff --git a/myhdl/test/benchmark/pypystats.dat b/scripts/benchmark/pypystats.dat similarity index 100% rename from myhdl/test/benchmark/pypystats.dat rename to scripts/benchmark/pypystats.dat diff --git a/myhdl/test/benchmark/random_generator.py b/scripts/benchmark/random_generator.py similarity index 100% rename from myhdl/test/benchmark/random_generator.py rename to scripts/benchmark/random_generator.py diff --git a/myhdl/test/benchmark/run.do b/scripts/benchmark/run.do similarity index 100% rename from myhdl/test/benchmark/run.do rename to scripts/benchmark/run.do diff --git a/myhdl/test/benchmark/run.sh b/scripts/benchmark/run.sh similarity index 100% rename from myhdl/test/benchmark/run.sh rename to scripts/benchmark/run.sh diff --git a/myhdl/test/benchmark/run_rand.sh b/scripts/benchmark/run_rand.sh similarity index 100% rename from myhdl/test/benchmark/run_rand.sh rename to scripts/benchmark/run_rand.sh diff --git a/myhdl/test/benchmark/stats.dat b/scripts/benchmark/stats.dat similarity index 100% rename from myhdl/test/benchmark/stats.dat rename to scripts/benchmark/stats.dat diff --git a/myhdl/test/benchmark/test_findmax.py b/scripts/benchmark/test_findmax.py similarity index 100% rename from myhdl/test/benchmark/test_findmax.py rename to scripts/benchmark/test_findmax.py diff --git a/myhdl/test/benchmark/test_findmax_sigs.py b/scripts/benchmark/test_findmax_sigs.py similarity index 100% rename from myhdl/test/benchmark/test_findmax_sigs.py rename to scripts/benchmark/test_findmax_sigs.py diff --git a/myhdl/test/benchmark/test_lfsr24.py b/scripts/benchmark/test_lfsr24.py similarity index 100% rename from myhdl/test/benchmark/test_lfsr24.py rename to scripts/benchmark/test_lfsr24.py diff --git a/myhdl/test/benchmark/test_longdiv.py b/scripts/benchmark/test_longdiv.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv.py rename to scripts/benchmark/test_longdiv.py diff --git a/myhdl/test/benchmark/test_longdiv_10.py b/scripts/benchmark/test_longdiv_10.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_10.py rename to scripts/benchmark/test_longdiv_10.py diff --git a/myhdl/test/benchmark/test_longdiv_11.py b/scripts/benchmark/test_longdiv_11.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_11.py rename to scripts/benchmark/test_longdiv_11.py diff --git a/myhdl/test/benchmark/test_longdiv_12.py b/scripts/benchmark/test_longdiv_12.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_12.py rename to scripts/benchmark/test_longdiv_12.py diff --git a/myhdl/test/benchmark/test_longdiv_13.py b/scripts/benchmark/test_longdiv_13.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_13.py rename to scripts/benchmark/test_longdiv_13.py diff --git a/myhdl/test/benchmark/test_longdiv_14.py b/scripts/benchmark/test_longdiv_14.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_14.py rename to scripts/benchmark/test_longdiv_14.py diff --git a/myhdl/test/benchmark/test_longdiv_15.py b/scripts/benchmark/test_longdiv_15.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_15.py rename to scripts/benchmark/test_longdiv_15.py diff --git a/myhdl/test/benchmark/test_longdiv_16.py b/scripts/benchmark/test_longdiv_16.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_16.py rename to scripts/benchmark/test_longdiv_16.py diff --git a/myhdl/test/benchmark/test_longdiv_17.py b/scripts/benchmark/test_longdiv_17.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_17.py rename to scripts/benchmark/test_longdiv_17.py diff --git a/myhdl/test/benchmark/test_longdiv_18.py b/scripts/benchmark/test_longdiv_18.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_18.py rename to scripts/benchmark/test_longdiv_18.py diff --git a/myhdl/test/benchmark/test_longdiv_9.py b/scripts/benchmark/test_longdiv_9.py similarity index 100% rename from myhdl/test/benchmark/test_longdiv_9.py rename to scripts/benchmark/test_longdiv_9.py diff --git a/myhdl/test/benchmark/test_randgen.py b/scripts/benchmark/test_randgen.py similarity index 100% rename from myhdl/test/benchmark/test_randgen.py rename to scripts/benchmark/test_randgen.py diff --git a/myhdl/test/benchmark/test_timer.py b/scripts/benchmark/test_timer.py similarity index 100% rename from myhdl/test/benchmark/test_timer.py rename to scripts/benchmark/test_timer.py diff --git a/myhdl/test/benchmark/test_timer_array.py b/scripts/benchmark/test_timer_array.py similarity index 100% rename from myhdl/test/benchmark/test_timer_array.py rename to scripts/benchmark/test_timer_array.py diff --git a/myhdl/test/benchmark/testrun.sh b/scripts/benchmark/testrun.sh similarity index 100% rename from myhdl/test/benchmark/testrun.sh rename to scripts/benchmark/testrun.sh diff --git a/myhdl/test/benchmark/teststats.dat b/scripts/benchmark/teststats.dat similarity index 100% rename from myhdl/test/benchmark/teststats.dat rename to scripts/benchmark/teststats.dat diff --git a/myhdl/test/benchmark/timer.py b/scripts/benchmark/timer.py similarity index 100% rename from myhdl/test/benchmark/timer.py rename to scripts/benchmark/timer.py From fcf450dcaa8ea059cc53383e63f7b6a14f45a46b Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Sat, 18 Apr 2015 18:33:04 -0400 Subject: [PATCH 016/325] move ci.sh to scripts folder --- .travis.yml | 2 +- ci.sh => scripts/ci.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename ci.sh => scripts/ci.sh (100%) diff --git a/.travis.yml b/.travis.yml index 711654f7..f525fcce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ matrix: - python: "3.4" env: CI_TARGET=ghdl -script: ./ci.sh +script: ./scripts/ci.sh notifications: email: false diff --git a/ci.sh b/scripts/ci.sh similarity index 100% rename from ci.sh rename to scripts/ci.sh From 55df36f4bb2b1c260cc8ec12d255e2d56fec474e Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Thu, 23 Apr 2015 10:53:13 -0400 Subject: [PATCH 017/325] Convert olddoc whatsnew to rst and move to doc --- doc/source/whatsnew/0.3.rst | 398 ++++++++++++++++++ doc/source/whatsnew/0.4.rst | 791 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1189 insertions(+) create mode 100644 doc/source/whatsnew/0.3.rst create mode 100644 doc/source/whatsnew/0.4.rst diff --git a/doc/source/whatsnew/0.3.rst b/doc/source/whatsnew/0.3.rst new file mode 100644 index 00000000..4d62a0c9 --- /dev/null +++ b/doc/source/whatsnew/0.3.rst @@ -0,0 +1,398 @@ +======================= +What’s New in MyHDL 0.3 +======================= + +:Author: Jan Decaluwe + +VCD output for waveform viewing +=============================== + +|image| + +MyHDL now has support for waveform viewing. During simulation, signal +changes can be written to a VCD output file that can be loaded into a +waveform viewer tool such as **gtkwave**. + +The user interface of this feature consists of a single function, +:func:`traceSignals()`. To explain how it works, recall that in MyHDL, +an instance is created by assigning the result of a function call to an +instance name. For example: + +:: + + tb_fsm = testbench() + +To enable VCD tracing, the instance should be created as follows +instead: + +:: + + tb_fsm = traceSignals(testbench) + +All signals in the instance hierarchy will be traced in a VCD file +called . Note that first the argument of :func:`traceSignals()` consists +of the uncalled function. By calling the function under its control, +:func:`traceSignals()` gathers information about the hierarchy and the +signals to be traced. In addition to a function argument, +:func:`traceSignals()` accepts an arbitrary number of non-keyword and +keyword arguments that will be passed to the function call. + +Signals are dumped in a suitable format. This format is inferred at the +:class:`Signal` construction time, from the type of the initial value. +In particular, :class:`bool` signals are dumped as single bits. (This +only works starting with Python 2.3, when :class:`bool` has become a +separate type). Likewise, :class:`intbv` signals with a defined bit +width are dumped as bit vectors. To support the general case, other +types of signals are dumped as a string representation, as returned by +the standard :func:`str()` function. + +[warning] Support for literal string representations is not part of the +VCD standard. It is specific to **gtkwave**. To generate a standard VCD +file, you need to use signals with a defined bit width only. + +Enumeration types +================= + +It is often desirable to define a set of identifiers. A standard Python +idiom for this purpose is to assign a range of integers to a tuple of +identifiers, like so: + +:: + + >>> SEARCH, CONFIRM, SYNC = range(3) + >>> CONFIRM + 1 + +However, this technique has some drawbacks. Though it is clearly the +intention that the identifiers belong together, this information is lost +as soon as they are defined. Also, the identifiers evaluate to integers, +whereas a string representation of the identifiers would be preferable. +To solve these issues, we need an *enumeration type*. + +MyHDL 0.3 supports enumeration types by providing a function +:func:`enum()`. The arguments to :func:`enum()` are the string +representations of the identifiers, and its return value is an +enumeration type. The identifiers are available as attributes of the +type. For example: + +:: + + >>> from myhdl import enum + >>> t_State = enum('SEARCH', 'CONFIRM', 'SYNC') + >>> t_State + + >>> t_State.CONFIRM + CONFIRM + +Enumeration types are often used for the state variable in a finite +state machine. In the waveform in +Section \ `1 <#vcd-output-for-waveform-viewing>`__, you see a +:class:`Signal` called ``state``. Note how the waveforms show the string +representation of the enumeration type identifiers The ``state`` signal +has been constructed with an enumeration type identifier as its initial +value, as follows: + +:: + + state = Signal(t_State.SEARCH) + +Inferring the sensitivity list for combinatorial logic +====================================================== + +In MyHDL, combinatorial logic is described by a generator function with +a sensitivity list that contains all inputs signals (the signals that +are read inside the function). + +It may be easy to forget some input signals, especially it there are a +lot of them or if the code is being modified. There are various ways to +solve this. One way is to use a sophisticated editor. Another way is +direct language support. For example, recent versions of Verilog have +the ``always @*`` construct, that infers all input signals. The +SystemVerilog 3.1 standard improves on this by introducing the +``always_comb`` block with slightly enhanced semantics. + +MyHDL 0.3 provides a function called :func:`always_comb()` which is +named and modeled after the SystemVerilog counterpart. +:func:`always_comb()` takes a classic local function as its argument. +This function should specify the combinatorial logic behavior. +:func:`always_comb()` returns a generator that is sensitive to all +inputs, and that will run the function whenever an input changes. + +For example, suppose that we have a mux module described as follows: + +:: + + def mux(z, a, b, sel): + """ Multiplexer. + + z -- mux output + a, b -- data inputs + sel -- control input + + """ + def logic() + while 1: + yield a, b, sel + if sel == 1: + z.next = a + else: + z.next = b + mux_logic = logic() + return mux_logic + +Using :func:`always_comb()`, we can describe it as follows instead: + +:: + + def mux(z, a, b, sel): + """ Multiplexer. + + z -- mux output + a, b -- data inputs + sel -- control input + + """ + def logic() + if sel == 1: + z.next = a + else: + z.next = b + mux_logic = always_comb(logic) + return mux_logic + +Note that in the first version, the sensitivity list is at the beginning +of the generator function code. This is traditionally done in +synthesizable RTL style modeling. However, the semantics of this style +are not entirely correct: at the start of the simulation, the +combinatorial output will not reflect the initial state of the inputs. +:func:`always_comb()` solves this by putting the sensitivity list at the +end of the code. + +Inferring the list of instances +=============================== + +In MyHDL, the instances defined in a top level function need to be +returned explicitly. The following is a schematic example: + +:: + + def top(...): + ... + instance_1 = module_1(...) + instance_2 = module_2(...) + ... + instance_n = module_n(...) + ... + return instance_1, instance_2, ... , instance_n + +It may be convenient to assemble the list of instances automatically, +especially if there are many instances. For this purpose, MyHDL 0.3 +provides the function :func:`instances()`. It is used as follows: + +:: + + from myhdl import instances + + def top(...): + ... + instance_1 = module_1(...) + instance_2 = module_2(...) + ... + instance_n = module_n(...) + ... + return instances() + +Function :func:`instances()` uses introspection to inspect the type of +the local variables defined by the calling function. All variables that +comply with the definition of an instance are assembled in a list, and +that list is returned. + +Inferring the list of processes +=============================== + +In addition to instances, a top level function may also define local +generators functions, which I will call *processes* because of the +analogy with VHDL. Like instances, processes need to be returned +explicitly, with the qualification that they have to be called first to +turn them into generators. The following is a schematic example: + +:: + + def top(...): + ... + def process_1(): + ... + def process_2(): + ... + ... + def process_n(): + ... + ... + return process_1(), process_2(), ..., process_n() + +As for instances, it may be more convenient to assemble the list of +processes automatically. One option is to turn each process into an +instance by calling it and assigning the returned generator to a local +variable. Those instances will then be found by the :func:`instances()` +function described in +Section \ `4 <#inferring-the-list-of-instances>`__. + +Another option is to use the function :func:`processes()` provided by +MyHDL 0.3. This function uses introspection to find the processes, calls +each of them, and assembles the returned generators into a list. It can +be used as follows: + +:: + + from myhdl import processes + + def top(...): + ... + def process_1(): + ... + def process_2(): + ... + ... + def process_n(): + ... + ... + return processes() + +To conclude, a top level function with both instances and processes can +use the following idiomatic code to return all of them: + +:: + + return instances(), processes() + +Class :class:`intbv` enhancements +================================= + +Class :class:`intbv` has been enhanced with new features. + +It is now possible to leave the left index of a slicing operation +unspecified. The meaning is to access “all” higher order bits. For +example: + +:: + + >>> from myhdl import intbv + >>> n = intbv() + >>> hex(n) + '0x0' + >>> n[:] = 0xde + >>> hex(n) + '0xde' + >>> n[:8] = 0xfa + >>> hex(n) + '0xfade' + >>> n[8:] = 0xb4 + >>> hex(n) + '0xfab4' + +:class:`intbv` objects now have ``min`` and ``max`` attributes that can +be specified at construction time. The meaning is that only values +within ``range(min, max)`` are permitted. The default value for these +attributes is ``None``, meaning “infinite”. For example (traceback +output shortened for clarity): + +:: + + >>> n = intbv(min=-17, max=53) + >>> n + intbv(0) + >>> n.min + -17 + >>> n.max + 53 + >>> n[:] = 28 + >>> n + intbv(28) + >>> n[:] = -18 + Traceback (most recent call last): + .... + ValueError: intbv value -18 < minimum -17 + >>> n[:] = 53 + Traceback (most recent call last): + .... + ValueError: intbv value 53 >= maximum 53 + +When a slice is taken from an :class:`intbv` object, the return value is +a new :class:`intbv` object with a defined bit width. As in Verilog, the +value of the new :class:`intbv` object is always positive, regardless of +the sign of the original value. In addition, the ``min`` and ``max`` +attributes are set implicitly: + +:: + + >>> v = intbv()[6:] + >>> v + intbv(0) + >>> v.min + 0 + >>> v.max + 64 + +Lastly, a small change was implemented with regard to binary operations. +In previous versions, both numeric and bit-wise operations always +returned a new :class:`intbv` object, even in mixed-mode operations with +:class:`int` objects. This has changed: numeric operations return an +:class:`int`, and bitwise operations return a :class:`intbv`. In this +way, the return value corresponds better to the nature of the operation. + +Function :func:`concat()` +========================== + +In previous versions, the :class:`intbv` class provided a method. This +method is no longer available. Instead, there is now a :func:`concat()` +function that supports a much broader range of objects. + +A function is more natural because MyHDL objects of various types can be +concatenated: :class:`intbv` objects with a defined bit width, +:class:`bool` objects, the corresponding signal objects, and bit +strings. All these objects have a defined bit width. Moreover, the first +argument doesn’t need to have a defined bit width. It can also be an +unsized :class:`intbv`, an :class:`int`, a :class:`long`, or a +corresponding signal object. Function :func:`concat()` returns an +:class:`intbv` object. + +Python 2.3 support +================== + +Python 2.3 was released on July 29, 2003, and as of this writing, it is +the latest stable Python release. MyHDL 0.3 works with both Python 2.2 +and Python 2.3. In good Python tradition, MyHDL code developed with +Python 2.2 should run without changes or problems in Python 2.3. + +In general, I am not that keen on early upgrading. However, as it +happens, the evolution of Python enables features that are really +important or even crucial to MyHDL. Python 2.2 generators are the best +example: they are the cornerstone of MyHDL. But Python 2.3 also has +significant benefits, which I will summarize below. + +First, generators and the ``yield`` statement are a default Python 2.3 +feature. This means that statements are no longer required. + +Second, Python 2.3 has a :class:`bool` type, which is implemented as a +subtype of :class:`int`. For general Python use, the implications are +rather limited - the main difference is that logical result values will +print as ``False`` and ``True`` instead of ``0`` and ``1``. However, in +MyHDL, I can use the :class:`bool` type to infer a bit width. If a +:class:`Signal` is constructed with a :class:`bool` value, it is a +single bit :class:`Signal`. One application is waveform viewing as in +Section \ `1 <#vcd-output-for-waveform-viewing>`__ In the waveform, note +how single bit signals are displayed as level changes. With Python 2.2, +the waveforms of these signals would only show value changes, which is +not as clear for single bits. + +Finally, Python 2.3 is significantly faster. MyHDL code runs 25–35% +faster in Python 2.3. This is a very nice speedup compared to the small +burden of a straightforward upgrade. + +Python is a very stable language, so upgrading to Python 2.3 is +virtually risk free. Given the additional benefits, I recommend +MyHDL users to do so as soon as possible. For the next major +MyHDLrelease, the new features will become required and only Python 2.3 +(and higher) will be supported. + +.. |image| image:: ../manual/tbfsm.png diff --git a/doc/source/whatsnew/0.4.rst b/doc/source/whatsnew/0.4.rst new file mode 100644 index 00000000..392b928a --- /dev/null +++ b/doc/source/whatsnew/0.4.rst @@ -0,0 +1,791 @@ +======================================= +New in MyHDL 0.4: Conversion to Verilog +======================================= + +:Author: Jan Decaluwe + +Introduction +============ + +MyHDL 0.4 supports the automatic conversion of a subset of MyHDL code to +synthesizable Verilog code. This feature provides a direct path from +Python to an FPGA or ASIC implementation. + +MyHDL aims to be a complete design language, for tasks such as high +level modeling and verification, but also for implementation. However, +prior to 0.4 a user had to translate MyHDL code manually to Verilog or +VHDL. Needless to say, this was inconvenient. With MyHDL0.4, this manual +step is no longer necessary. + +Solution description +==================== + +The solution works as follows. The hardware description should be +modeled in MyHDL style, and satisfy certain constraints that are typical +for implementation-oriented hardware modeling. Subsequently, such a +design is converted to an equivalent model in the Verilog language, +using the function :func:`toVerilog` from the MyHDLlibrary. Finally, a +third-party *synthesis tool* is used to convert the Verilog design to a +gate implementation for an ASIC or FPGA. There are a number of Verilog +synthesis tools available, varying in price, capabilities, and target +implementation technology. + +The conversion does not start from source files, but from a design that +has been *elaborated* by the Python interpreter. The converter uses the +Python profiler to track the interpreter’s operation and to infer the +design structure and name spaces. It then selectively compiles pieces of +source code for additional analysis and for conversion. This is done +using the Python compiler package. + +Features +======== + +The design is converted after elaboration +----------------------------------------- + +*Elaboration* refers to the initial processing of a hardware description +to achieve a representation of a design instance that is ready for +simulation or synthesis. In particular, structural parameters and +constructs are processed in this step. In MyHDL, the Python interpreter +itself is used for elaboration. A :class:`Simulation` object is +constructed with elaborated design instances as arguments. Likewise, the +Verilog conversion works on an elaborated design instance. The Python +interpreter is thus used as much as possible. + +The structural description can be arbitrarily complex and hierarchical +---------------------------------------------------------------------- + +As the conversion works on an elaborated design instance, any modeling +constraints only apply to the leaf elements of the design structure, +that is, the co-operating generators. In other words, there are no +restrictions on the description of the design structure: Python’s full +power can be used for that purpose. Also, the design hierarchy can be +arbitrarily deep. + +Generators are mapped to Verilog always or initial blocks +--------------------------------------------------------- + +The converter analyzes the code of each generator and maps it to a +Verilog ``always`` blocks if possible, and to an ``initial`` block +otherwise. The converted Verilog design will be a flat “net list of +blocks”. + +The Verilog module interface is inferred from signal usage +---------------------------------------------------------- + +In MyHDL, the input or output direction of interface signals is not +explicitly declared. The converter investigates signal usage in the +design hierarchy to infer whether a signal is used as input, output, or +as an internal signal. Internal signals are given a hierarchical name in +the Verilog output. + +Function calls are mapped to a unique Verilog function or task call +------------------------------------------------------------------- + +The converter analyzes function calls and function code to see if they +should be mapped to Verilog functions or to tasks. Python functions are +much more powerful than Verilog subprograms; for example, they are +inherently generic, and they can be called with named association. To +support this power in Verilog, a unique Verilog function or task is +generated per Python function call. + +If-then-else structures may be mapped to Verilog case statements +---------------------------------------------------------------- + +Python does not provide a case statement. However, the converter +recognizes if-then-else structures in which a variable is sequentially +compared to items of an enumeration type, and maps such a structure to a +Verilog case statement with the appropriate synthesis attributes. + +Choice of encoding schemes for enumeration types +------------------------------------------------ + +The :func:`enum` function in MyHDL returns an enumeration type. This +function takes an additional parameter ``encoding`` that specifies the +desired encoding in the implementation: binary, one hot, or one cold. +The Verilog converter generates the appropriate code. + +The convertible subset +====================== + +Introduction +------------ + +Unsurprisingly, not all MyHDL code can be converted to Verilog. In fact, +there are very important restrictions. As the goal of the conversion +functionality is implementation, this should not be a big issue: anyone +familiar with synthesis is used to similar restrictions in the +*synthesizable subset* of Verilog and VHDL. The converter attempts to +issue clear error messages when it encounters a construct that cannot be +converted. + +In practice, the synthesizable subset usually refers to RTL synthesis, +which is by far the most popular type of synthesis today. There are +industry standards that define the RTL synthesis subset. However, those +were not used as a model for the restrictions of the MyHDL converter, +but as a minimal starting point. On that basis, whenever it was judged +easy or useful to support an additional feature, this was done. For +example, it is actually easier to convert :keyword:`while` loops than +:keyword:`for` loops even though they are not RTL-synthesizable. As +another example, :keyword:`print` is supported because it’s so useful +for debugging, even though it’s not synthesizable. In summary, the +convertible subset is a superset of the standard RTL synthesis subset, +and supports synthesis tools with more advanced capabilities, such as +behavioral synthesis. + +Recall that any restrictions only apply to the design post elaboration. +In practice, this means that they apply only to the code of the +generators, that are the leaf functional blocks in a MyHDL design. + +Coding style +------------ + +A natural restriction on convertible code is that it should be written +in MyHDL style: cooperating generators, communicating through signals, +and with ``yield`` statements specifying wait points and resume +conditions. Supported resume conditions are a signal edge, a signal +change, or a tuple of such conditions. + +Supported types +--------------- + +The most important restriction regards object types. Verilog is an +almost typeless language, while Python is strongly (albeit dynamically) +typed. The converter has to infer the types of names used in the code, +and map those names to Verilog variables. + +Only a limited amount of types can be converted. Python :class:`int` and +:class:`long` objects are mapped to Verilog integers. All other +supported types are mapped to Verilog regs (or wires), and therefore +need to have a defined bit width. The supported types are the Python +:class:`bool` type, the MyHDL :class:`intbv` type, and MyHDL enumeration +types returned by function :func:`enum`. The latter objects can also be +used as the base object of a :class:`Signal`. + +:class:`intbv` objects must be constructed so that a bit width can be +inferred. This can be done by specifying minimum and maximum values, +e.g. as follows: + +:: + + index = intbv(0, min=0, max=2**N) + +Alternatively, a slice can be taken from an :class:`intbv` object as +follows: + +:: + + index = intbv(0)[N:] + +Such as slice returns a new :class:`intbv` object, with minimum value +``0`` , and maximum value ``2**N``. + +Supported statements +-------------------- + +The following is a list of the statements that are supported by the +Verilog converter, possibly qualified with restrictions or usage notes. + +The :keyword:`break` statement. +The :keyword:`continue` statement. +The :keyword:`def` statement. +The :keyword:`for` statement. + The only supported iteration scheme is iterating through sequences + of integers returned by built-in function :func:`range` or + MyHDLfunction :func:`downrange`. The optional :keyword:`else` clause + is not supported. + +The :keyword:`if` statement. + :keyword:`if`, :keyword:`elif`, and :keyword:`else` clauses are + fully supported. + +The :keyword:`pass` statement. +The :keyword:`print` statement. + When printing an interpolated string, the format specifiers are + copied verbatim to the Verilog output. Printing to a file (with + syntax ``’>>’``) is not supported. + +The :keyword:`raise` statement. + This statement is mapped to Verilog statements that end the + simulation with an error message. + +The :keyword:`return` statement. +The :keyword:`yield` statement. + The yielded expression can be a signal, a signal edge as specified + by MyHDL functions :func:`posedge` or :func:`negedge`, or a tuple of + signals and edge specifications. + +The :keyword:`while` statement. + The optional :keyword:`else` clause is not supported. + +Methodology notes +================= + +Simulation +---------- + +In the Python philosophy, the run-time rules. The Python compiler +doesn’t attempt to detect a lot of errors beyond syntax errors, which +given Python’s ultra-dynamic nature would be an almost impossible task +anyway. To verify a Python program, one should run it, preferably using +unit testing to verify each feature. + +The same philosophy should be used when converting a MyHDL description +to Verilog: make sure the simulation runs fine first. Although the +converter checks many things and attempts to issue clear error messages, +there is no guarantee that it does a meaningful job unless the +simulation runs fine. + +Conversion output verification +------------------------------ + +It is always prudent to verify the converted Verilog output. To make +this task easier, the converter also generates a test bench that makes +it possible to simulate the Verilog design using the Verilog +co-simulation interface. This permits to verify the Verilog code with +the same test bench used for the MyHDL code. This is also how the +Verilog converter development is being verified. + +Assignment issues +----------------- + +Name assignment in Python +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Name assignment in Python is a different concept than in many other +languages. This point is very important for effective modeling in +Python, and even more so for synthesizable MyHDL code. Therefore, the +issues are discussed here explicitly. + +Consider the following name assignments: + +:: + + a = 4 + a = ``a string'' + a = False + +In many languages, the meaning would be that an existing variable ``a`` +gets a number of different values. In Python, such a concept of a +variable doesn’t exist. Instead, assignment merely creates a new binding +of a name to a certain object, that replaces any previous binding. So in +the example, the name ``a`` is bound a number of different objects in +sequence. + +The Verilog converter has to investigate name assignment and usage in +MyHDL code, and to map names to Verilog variables. To achieve that, it +tries to infer the type and possibly the bit width of each expression +that is assigned to a name. + +Multiple assignments to the same name can be supported if it can be +determined that a consistent type and bit width is being used in the +assignments. This can be done for boolean expressions, numeric +expressions, and enumeration type literals. In Verilog, the +corresponding name is mapped to a single bit ``reg``, an ``integer``, or +a ``reg`` with the appropriate width, respectively. + +In other cases, a single assignment should be used when an object is +created. Subsequent value changes are then achieved by modification of +an existing object. This technique should be used for :class:`Signal` +and :class:`intbv` objects. + +Signal assignment +~~~~~~~~~~~~~~~~~ + +Signal assignment in MyHDL is implemented using attribute assignment to +attribute ``next``. Value changes are thus modeled by modification of +the existing object. The converter investigates the :class:`Signal` +object to infer the type and bit width of the corresponding Verilog +variable. + +:class:`intbv` objects +~~~~~~~~~~~~~~~~~~~~~~ + +Type :class:`intbv` is likely to be the workhorse for synthesizable +modeling in MyHDL. An :class:`intbv` instance behaves like a (mutable) +integer whose individual bits can be accessed and modified. Also, it is +possible to constrain its set of values. In addition to error checking, +this makes it possible to infer a bit width, which is required for +implementation. + +In Verilog, an :class:`intbv` instance will be mapped to a ``reg`` with +an appropriate width. As noted before, it is not possible to modify its +value using name assignment. In the following, we will show how it can +be done instead. Consider: + +:: + + a = intbv(0)[8:] + +This is an :class:`intbv` object with initial value ``0`` and bit width +8. The change its value to ``5``, we can use slice assignment: + +:: + + a[8:] = 5 + +The same can be achieved by leaving the bit width unspecified, which has +the meaning to change “all” bits: + +:: + + a[:] = 5 + +Often the new value will depend on the old one. For example, to +increment an :class:`intbv` with the technique above: + +:: + + a[:] = a + 1 + +Python also provides *augmented* assignment operators, which can be used +to implement in-place operations. These are supported on :class:`intbv` +objects and by the converter, so that the increment can also be done as +follows: + +:: + + a += 1 + +Converter usage +=============== + +We will demonstrate the conversion process by showing some examples. + +A small design with a single generator +-------------------------------------- + +Consider the following MyHDL code for an incrementer module: + +:: + + def inc(count, enable, clock, reset, n): + """ Incrementer with enable. + + count -- output + enable -- control input, increment when 1 + clock -- clock input + reset -- asynchronous reset input + n -- counter max value + """ + def incProcess(): + while 1: + yield posedge(clock), negedge(reset) + if reset == ACTIVE_LOW: + count.next = 0 + else: + if enable: + count.next = (count + 1) % n + return incProcess() + +In Verilog terminology, function :func:`inc` corresponds to a module, +while generator function :func:`incProcess` roughly corresponds to an +always block. + +Normally, to simulate the design, we would “elaborate” an instance as +follows: + +:: + + m = 8 + n = 2 ** m + + count = Signal(intbv(0)[m:]) + enable = Signal(bool(0)) + clock, reset = [Signal(bool()) for i in range(2)] + + inc_inst = inc(count, enable, clock, reset, n=n) + +``incinst`` is an elaborated design instance that can be simulated. To +convert it to Verilog, we change the last line as follows: + +:: + + inc_inst = toVerilog(inc, count, enable, clock, reset, n=n) + +Again, this creates an instance that can be simulated, but as a side +effect, it also generates an equivalent Verilog module in file . The +Verilog code looks as follows: + +:: + + module inc_inst ( + count, + enable, + clock, + reset + ); + + output [7:0] count; + reg [7:0] count; + input enable; + input clock; + input reset; + + + always @(posedge clock or negedge reset) begin: _MYHDL1_BLOCK + if ((reset == 0)) begin + count <= 0; + end + else begin + if (enable) begin + count <= ((count + 1) % 256); + end + end + end + + endmodule + +You can see the module interface and the always block, as expected from +the MyHDL design. + +Converting a generator directly +------------------------------- + +It is also possible to convert a generator directly. For example, +consider the following generator function: + +:: + + def bin2gray(B, G, width): + """ Gray encoder. + + B -- input intbv signal, binary encoded + G -- output intbv signal, gray encoded + width -- bit width + """ + Bext = intbv(0)[width+1:] + while 1: + yield B + Bext[:] = B + for i in range(width): + G.next[i] = Bext[i+1] ^ Bext[i] + +As before, you can create an instance and convert to Verilog as follows: + +:: + + width = 8 + + B = Signal(intbv(0)[width:]) + G = Signal(intbv(0)[width:]) + + bin2gray_inst = toVerilog(bin2gray, B, G, width) + + +The generated Verilog code looks as follows: + +:: + + module bin2gray_inst ( + B, + G + ); + + input [7:0] B; + output [7:0] G; + reg [7:0] G; + + always @(B) begin: _MYHDL1_BLOCK + integer i; + reg [9-1:0] Bext; + Bext[9-1:0] = B; + for (i=0; i<8; i=i+1) begin + G[i] <= (Bext[(i + 1)] ^ Bext[i]); + end + end + + endmodule + +A hierarchical design +--------------------- + +The hierarchy of convertible designs can be arbitrarily deep. + +For example, suppose we want to design an incrementer with Gray code +output. Using the designs from previous sections, we can proceed as +follows: + +:: + + def GrayInc(graycnt, enable, clock, reset, width): + + bincnt = Signal(intbv()[width:]) + + INC_1 = inc(bincnt, enable, clock, reset, n=2**width) + BIN2GRAY_1 = bin2gray(B=bincnt, G=graycnt, width=width) + + return INC_1, BIN2GRAY_1 + +According to Gray code properties, only a single bit will change in +consecutive values. However, as the ``bin2gray`` module is +combinatorial, the output bits may have transient glitches, which may +not be desirable. To solve this, let’s create an additional level of +hierarchy and add an output register to the design. (This will create an +additional latency of a clock cycle, which may not be acceptable, but we +will ignore that here.) + +:: + + def GrayIncReg(graycnt, enable, clock, reset, width): + + graycnt_comb = Signal(intbv()[width:]) + + GRAY_INC_1 = GrayInc(graycnt_comb, enable, clock, reset, width) + + def reg(): + while 1: + yield posedge(clock) + graycnt.next = graycnt_comb + REG_1 = reg() + + return GRAY_INC_1, REG_1 + +We can convert this hierarchical design as before: + +:: + + width = 8 + graycnt = Signal(intbv()[width:]) + enable, clock, reset = [Signal(bool()) for i in range(3)] + + GRAY_INC_REG_1 = toVerilog(GrayIncReg, graycnt, enable, clock, reset, width) + +The Verilog output code looks as follows: + +:: + + module GRAY_INC_REG_1 ( + graycnt, + enable, + clock, + reset + ); + + output [7:0] graycnt; + reg [7:0] graycnt; + input enable; + input clock; + input reset; + + reg [7:0] graycnt_comb; + reg [7:0] _GRAY_INC_1_bincnt; + + always @(posedge clock or negedge reset) begin: _MYHDL1_BLOCK + if ((reset == 0)) begin + _GRAY_INC_1_bincnt <= 0; + end + else begin + if (enable) begin + _GRAY_INC_1_bincnt <= ((_GRAY_INC_1_bincnt + 1) % 256); + end + end + end + + always @(_GRAY_INC_1_bincnt) begin: _MYHDL4_BLOCK + integer i; + reg [9-1:0] Bext; + Bext[9-1:0] = _GRAY_INC_1_bincnt; + for (i=0; i<8; i=i+1) begin + graycnt_comb[i] <= (Bext[(i + 1)] ^ Bext[i]); + end + end + + always @(posedge clock) begin: _MYHDL9_BLOCK + graycnt <= graycnt_comb; + end + + endmodule + +Note that the output is a flat “net list of blocks”, and that +hierarchical signal names are generated as necessary. + +Optimizations for finite state machines +--------------------------------------- + +As often in hardware design, finite state machines deserve special +attention. + +In Verilog and VHDL, finite state machines are typically described using +case statements. Python doesn’t have a case statement, but the converter +recognizes particular if-then-else structures and maps them to case +statements. This optimization occurs when a variable whose type is an +enumerated type is sequentially tested against enumeration items in an +if-then-else structure. Also, the appropriate synthesis pragmas for +efficient synthesis are generated in the Verilog code. + +As a further optimization, function :func:`enum` was enhanced to support +alternative encoding schemes elegantly, using an additional parameter +``encoding``. For example: + +:: + + t_State = enum('SEARCH', 'CONFIRM', 'SYNC', encoding='one_hot') + +The default encoding is ``’binary’``; the other possibilities are +``’onehot’`` and ``’onecold’``. This parameter only affects the +conversion output, not the behavior of the type. The generated Verilog +code for case statements is optimized for an efficient implementation +according to the encoding. Note that in contrast, a Verilog designer has +to make nontrivial code changes to implement a different encoding +scheme. + +As an example, consider the following finite state machine, whose state +variable uses the enumeration type defined above: + +:: + + FRAME_SIZE = 8 + + def FramerCtrl(SOF, state, syncFlag, clk, reset_n): + + """ Framing control FSM. + + SOF -- start-of-frame output bit + state -- FramerState output + syncFlag -- sync pattern found indication input + clk -- clock input + reset_n -- active low reset + + """ + + index = intbv(0, min=0, max=8) # position in frame + while 1: + yield posedge(clk), negedge(reset_n) + if reset_n == ACTIVE_LOW: + SOF.next = 0 + index[:] = 0 + state.next = t_State.SEARCH + else: + SOF.next = 0 + if state == t_State.SEARCH: + index[:] = 0 + if syncFlag: + state.next = t_State.CONFIRM + elif state == t_State.CONFIRM: + if index == 0: + if syncFlag: + state.next = t_State.SYNC + else: + state.next = t_State.SEARCH + elif state == t_State.SYNC: + if index == 0: + if not syncFlag: + state.next = t_State.SEARCH + SOF.next = (index == FRAME_SIZE-1) + else: + raise ValueError("Undefined state") + index[:]= (index + 1) % FRAME_SIZE + +The conversion is done as before: + +:: + + SOF = Signal(bool(0)) + syncFlag = Signal(bool(0)) + clk = Signal(bool(0)) + reset_n = Signal(bool(1)) + state = Signal(t_State.SEARCH) + framerctrl_inst = toVerilog(FramerCtrl, SOF, state, syncFlag, clk, reset_n) + +The Verilog output looks as follows: + +:: + + module framerctrl_inst ( + SOF, + state, + syncFlag, + clk, + reset_n + ); + output SOF; + reg SOF; + output [2:0] state; + reg [2:0] state; + input syncFlag; + input clk; + input reset_n; + + always @(posedge clk or negedge reset_n) begin: _MYHDL1_BLOCK + reg [3-1:0] index; + if ((reset_n == 0)) begin + SOF <= 0; + index[3-1:0] = 0; + state <= 3'b001; + end + else begin + SOF <= 0; + // synthesis parallel_case full_case + casez (state) + 3'b??1: begin + index[3-1:0] = 0; + if (syncFlag) begin + state <= 3'b010; + end + end + 3'b?1?: begin + if ((index == 0)) begin + if (syncFlag) begin + state <= 3'b100; + end + else begin + state <= 3'b001; + end + end + end + 3'b1??: begin + if ((index == 0)) begin + if ((!syncFlag)) begin + state <= 3'b001; + end + end + SOF <= (index == (8 - 1)); + end + default: begin + $display("Verilog: ValueError(Undefined state)"); + $finish; + end + endcase + index[3-1:0] = ((index + 1) % 8); + end + end + endmodule + +Known issues +============ + +Negative values of :class:`intbv` instances are not supported. + The :class:`intbv` class is quite capable of representing negative + values. However, the ``signed`` type support in Verilog is + relatively recent and mapping to it may be tricky. In my judgment, + this was not the most urgent requirement, so I decided to leave this + for later. + +Verilog integers are 32 bit wide + Usually, Verilog integers are 32 bit wide. In contrast, Python is + moving toward integers with undefined width. Python :class:`int` and + :class:`long` variables are mapped to Verilog integers; so for + values wider than 32 bit this mapping is incorrect. + +Synthesis pragmas are specified as Verilog comments. + The recommended way to specify synthesis pragmas in Verilog is + through attribute lists. However, my Verilog simulator (Icarus) + doesn’t support them for ``case`` statements (to specify + ``parallelcase`` and ``fullcase`` pragmas). Therefore, I still used + the old but deprecated method of synthesis pragmas in Verilog + comments. + +Inconsistent place of the sensitivity list inferred from ``alwayscomb``. + The semantics of ``alwayscomb``, both in Verilog and MyHDL, is to + have an implicit sensitivity list at the end of the code. However, + this may not be synthesizable. Therefore, the inferred sensitivity + list is put at the top of the corresponding ``always`` block. This + may cause inconsistent behavior at the start of the simulation. The + workaround is to create events at time 0. + +Non-blocking assignments to task arguments don’t work. + I didn’t get non-blocking (signal) assignments to task arguments to + work. I don’t know yet whether the issue is my own, a Verilog issue, + or an issue with my Verilog simulator Icarus. I’ll need to check + this further. From 0c30e0c830e01c1f3d7693771cfad22a25b3fa6f Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Thu, 23 Apr 2015 10:55:18 -0400 Subject: [PATCH 018/325] remove olddoc --- olddoc/Makefile | 426 ------ olddoc/Makefile.deps | 34 - olddoc/README | 231 --- olddoc/README.txt | 8 - olddoc/html/about.dat | 24 - olddoc/html/icons/blank.gif | Bin 1958 -> 0 bytes olddoc/html/icons/blank.png | Bin 1031 -> 0 bytes olddoc/html/icons/contents.gif | Bin 438 -> 0 bytes olddoc/html/icons/contents.png | Bin 649 -> 0 bytes olddoc/html/icons/index.gif | Bin 289 -> 0 bytes olddoc/html/icons/index.png | Bin 529 -> 0 bytes olddoc/html/icons/modules.gif | Bin 385 -> 0 bytes olddoc/html/icons/modules.png | Bin 598 -> 0 bytes olddoc/html/icons/next.gif | Bin 253 -> 0 bytes olddoc/html/icons/next.png | Bin 511 -> 0 bytes olddoc/html/icons/previous.gif | Bin 252 -> 0 bytes olddoc/html/icons/previous.png | Bin 511 -> 0 bytes olddoc/html/icons/pyfav.gif | Bin 125 -> 0 bytes olddoc/html/icons/up.gif | Bin 316 -> 0 bytes olddoc/html/icons/up.png | Bin 577 -> 0 bytes olddoc/html/myabout.dat | 38 - olddoc/html/style.css | 157 -- olddoc/info/.cvsignore | 2 - olddoc/info/Makefile | 70 - olddoc/info/README | 21 - olddoc/info/python.dir | 12 - olddoc/manual/MyHDL.tex | 101 -- olddoc/manual/background.tex | 167 -- olddoc/manual/conversion.tex | 1049 ------------- olddoc/manual/cosimulation.tex | 416 ----- olddoc/manual/intro.tex | 555 ------- olddoc/manual/modeling.tex | 1197 --------------- olddoc/manual/reference.tex | 554 ------- olddoc/manual/tbfsm.png | Bin 9150 -> 0 bytes olddoc/manual/unittest.tex | 379 ----- olddoc/paper-a4/pypaper.sty | 18 - olddoc/paper-letter/pypaper.sty | 18 - olddoc/perl/SynopsisTable.pm | 95 -- olddoc/perl/distutils.perl | 21 - olddoc/perl/howto.perl | 12 - olddoc/perl/isilo.perl | 12 - olddoc/perl/l2hinit.perl | 672 -------- olddoc/perl/ltxmarkup.perl | 67 - olddoc/perl/manual.perl | 15 - olddoc/perl/python.perl | 2123 -------------------------- olddoc/setup | 4 - olddoc/texinputs/boilerplate.tex | 9 - olddoc/texinputs/copyright.tex | 2 - olddoc/texinputs/distutils.sty | 33 - olddoc/texinputs/fancyhdr.sty | 329 ---- olddoc/texinputs/fncychap.sty | 433 ------ olddoc/texinputs/howto.cls | 106 -- olddoc/texinputs/license.tex | 274 ---- olddoc/texinputs/ltxmarkup.sty | 40 - olddoc/texinputs/manual.cls | 152 -- olddoc/texinputs/pypaper.sty | 18 - olddoc/texinputs/python.ist | 11 - olddoc/texinputs/python.sty | 1277 ---------------- olddoc/texinputs/reportingbugs.tex | 61 - olddoc/texinputs/tmp | 171 --- olddoc/texinputs/typestruct.h | 76 - olddoc/tools/anno-api.py | 71 - olddoc/tools/buildindex.py | 377 ----- olddoc/tools/checkargs.pm | 112 -- olddoc/tools/cklatex | 26 - olddoc/tools/custlib.py | 78 - olddoc/tools/cvsinfo.py | 81 - olddoc/tools/findacks | 161 -- olddoc/tools/findcsyms | 136 -- olddoc/tools/findmodrefs | 63 - olddoc/tools/findsyms | 128 -- olddoc/tools/fix_hack | 2 - olddoc/tools/fix_libaux.sed | 3 - olddoc/tools/fixinfo.el | 15 - olddoc/tools/getpagecounts | 97 -- olddoc/tools/html2texi.pl | 1750 --------------------- olddoc/tools/indfix.py | 100 -- olddoc/tools/keywords.py | 19 - olddoc/tools/listmodules | 183 --- olddoc/tools/makesec.sh | 129 -- olddoc/tools/mkackshtml | 66 - olddoc/tools/mkhowto | 665 -------- olddoc/tools/mkinfo | 63 - olddoc/tools/mkmodindex | 158 -- olddoc/tools/mkpkglist | 90 -- olddoc/tools/mksourcepkg | 164 -- olddoc/tools/node2label.pl | 71 - olddoc/tools/prechm.py | 471 ------ olddoc/tools/push-docs.sh | 90 -- olddoc/tools/py2texi.el | 920 ----------- olddoc/tools/refcounts.py | 98 -- olddoc/tools/rewrite.py | 54 - olddoc/tools/sgmlconv/Makefile | 67 - olddoc/tools/sgmlconv/README | 58 - olddoc/tools/sgmlconv/conversion.xml | 914 ----------- olddoc/tools/sgmlconv/docfixer.py | 1073 ------------- olddoc/tools/sgmlconv/esis2sgml.py | 264 ---- olddoc/tools/sgmlconv/esistools.py | 312 ---- olddoc/tools/sgmlconv/latex2esis.py | 565 ------- olddoc/tools/sgmlconv/make.rules | 48 - olddoc/tools/support.py | 198 --- olddoc/tools/toc2bkm.py | 143 -- olddoc/tools/undoc_symbols.py | 94 -- olddoc/tools/update-docs.sh | 31 - olddoc/tools/whichlibs | 2 - olddoc/whatsnew03/tbfsm.png | Bin 9150 -> 0 bytes olddoc/whatsnew03/whatsnew03.tex | 424 ----- olddoc/whatsnew04/conversion.tex | 778 ---------- olddoc/whatsnew04/whatsnew04.tex | 22 - 109 files changed, 22924 deletions(-) delete mode 100644 olddoc/Makefile delete mode 100644 olddoc/Makefile.deps delete mode 100644 olddoc/README delete mode 100644 olddoc/README.txt delete mode 100644 olddoc/html/about.dat delete mode 100644 olddoc/html/icons/blank.gif delete mode 100644 olddoc/html/icons/blank.png delete mode 100644 olddoc/html/icons/contents.gif delete mode 100644 olddoc/html/icons/contents.png delete mode 100644 olddoc/html/icons/index.gif delete mode 100644 olddoc/html/icons/index.png delete mode 100644 olddoc/html/icons/modules.gif delete mode 100644 olddoc/html/icons/modules.png delete mode 100644 olddoc/html/icons/next.gif delete mode 100644 olddoc/html/icons/next.png delete mode 100644 olddoc/html/icons/previous.gif delete mode 100644 olddoc/html/icons/previous.png delete mode 100644 olddoc/html/icons/pyfav.gif delete mode 100644 olddoc/html/icons/up.gif delete mode 100644 olddoc/html/icons/up.png delete mode 100644 olddoc/html/myabout.dat delete mode 100644 olddoc/html/style.css delete mode 100644 olddoc/info/.cvsignore delete mode 100644 olddoc/info/Makefile delete mode 100644 olddoc/info/README delete mode 100644 olddoc/info/python.dir delete mode 100644 olddoc/manual/MyHDL.tex delete mode 100644 olddoc/manual/background.tex delete mode 100644 olddoc/manual/conversion.tex delete mode 100644 olddoc/manual/cosimulation.tex delete mode 100644 olddoc/manual/intro.tex delete mode 100644 olddoc/manual/modeling.tex delete mode 100644 olddoc/manual/reference.tex delete mode 100644 olddoc/manual/tbfsm.png delete mode 100644 olddoc/manual/unittest.tex delete mode 100644 olddoc/paper-a4/pypaper.sty delete mode 100644 olddoc/paper-letter/pypaper.sty delete mode 100644 olddoc/perl/SynopsisTable.pm delete mode 100644 olddoc/perl/distutils.perl delete mode 100644 olddoc/perl/howto.perl delete mode 100644 olddoc/perl/isilo.perl delete mode 100644 olddoc/perl/l2hinit.perl delete mode 100644 olddoc/perl/ltxmarkup.perl delete mode 100644 olddoc/perl/manual.perl delete mode 100644 olddoc/perl/python.perl delete mode 100644 olddoc/setup delete mode 100644 olddoc/texinputs/boilerplate.tex delete mode 100644 olddoc/texinputs/copyright.tex delete mode 100644 olddoc/texinputs/distutils.sty delete mode 100644 olddoc/texinputs/fancyhdr.sty delete mode 100644 olddoc/texinputs/fncychap.sty delete mode 100644 olddoc/texinputs/howto.cls delete mode 100644 olddoc/texinputs/license.tex delete mode 100644 olddoc/texinputs/ltxmarkup.sty delete mode 100644 olddoc/texinputs/manual.cls delete mode 100644 olddoc/texinputs/pypaper.sty delete mode 100644 olddoc/texinputs/python.ist delete mode 100644 olddoc/texinputs/python.sty delete mode 100644 olddoc/texinputs/reportingbugs.tex delete mode 100644 olddoc/texinputs/tmp delete mode 100644 olddoc/texinputs/typestruct.h delete mode 100755 olddoc/tools/anno-api.py delete mode 100755 olddoc/tools/buildindex.py delete mode 100644 olddoc/tools/checkargs.pm delete mode 100755 olddoc/tools/cklatex delete mode 100644 olddoc/tools/custlib.py delete mode 100644 olddoc/tools/cvsinfo.py delete mode 100755 olddoc/tools/findacks delete mode 100755 olddoc/tools/findcsyms delete mode 100755 olddoc/tools/findmodrefs delete mode 100755 olddoc/tools/findsyms delete mode 100755 olddoc/tools/fix_hack delete mode 100755 olddoc/tools/fix_libaux.sed delete mode 100644 olddoc/tools/fixinfo.el delete mode 100755 olddoc/tools/getpagecounts delete mode 100755 olddoc/tools/html2texi.pl delete mode 100755 olddoc/tools/indfix.py delete mode 100644 olddoc/tools/keywords.py delete mode 100755 olddoc/tools/listmodules delete mode 100755 olddoc/tools/makesec.sh delete mode 100755 olddoc/tools/mkackshtml delete mode 100755 olddoc/tools/mkhowto delete mode 100755 olddoc/tools/mkinfo delete mode 100755 olddoc/tools/mkmodindex delete mode 100755 olddoc/tools/mkpkglist delete mode 100755 olddoc/tools/mksourcepkg delete mode 100755 olddoc/tools/node2label.pl delete mode 100644 olddoc/tools/prechm.py delete mode 100755 olddoc/tools/push-docs.sh delete mode 100644 olddoc/tools/py2texi.el delete mode 100644 olddoc/tools/refcounts.py delete mode 100644 olddoc/tools/rewrite.py delete mode 100644 olddoc/tools/sgmlconv/Makefile delete mode 100644 olddoc/tools/sgmlconv/README delete mode 100644 olddoc/tools/sgmlconv/conversion.xml delete mode 100755 olddoc/tools/sgmlconv/docfixer.py delete mode 100755 olddoc/tools/sgmlconv/esis2sgml.py delete mode 100644 olddoc/tools/sgmlconv/esistools.py delete mode 100755 olddoc/tools/sgmlconv/latex2esis.py delete mode 100644 olddoc/tools/sgmlconv/make.rules delete mode 100644 olddoc/tools/support.py delete mode 100755 olddoc/tools/toc2bkm.py delete mode 100644 olddoc/tools/undoc_symbols.py delete mode 100755 olddoc/tools/update-docs.sh delete mode 100755 olddoc/tools/whichlibs delete mode 100644 olddoc/whatsnew03/tbfsm.png delete mode 100644 olddoc/whatsnew03/whatsnew03.tex delete mode 100644 olddoc/whatsnew04/conversion.tex delete mode 100644 olddoc/whatsnew04/whatsnew04.tex diff --git a/olddoc/Makefile b/olddoc/Makefile deleted file mode 100644 index 8362b83b..00000000 --- a/olddoc/Makefile +++ /dev/null @@ -1,426 +0,0 @@ -# Makefile for Python documentation -# --------------------------------- -# -# See also the README file. -# -# This is a bit of a mess. The documents are identified by short names: -# api -- Python/C API Reference Manual -# doc -- Documenting Python -# ext -- Extending and Embedding the Python Interpreter -# lib -- Library Reference Manual -# mac -- Macintosh Library Modules -# ref -- Python Reference Manual -# tut -- Python Tutorial -# inst -- Installing Python Modules -# dist -- Distributing Python Modules -# -# The LaTeX sources for each of these documents are in subdirectories -# with the three-letter designations above as the directory names. -# -# The main target creates HTML for each of the documents. You can -# also do "make lib" (etc.) to create the HTML versions of individual -# documents. -# -# The document classes and styles are in the texinputs/ directory. -# These define a number of macros that are similar in name and intent -# as macros in Texinfo (e.g. \code{...} and \emph{...}), as well as a -# number of environments for formatting function and data definitions. -# Documentation for the macros is included in "Documenting Python"; see -# http://www.python.org/doc/current/doc/doc.html, or the sources for -# this document in the doc/ directory. -# -# Everything is processed by LaTeX. See the file `README' for more -# information on the tools needed for processing. -# -# There's a problem with generating the index which has been solved by -# a sed command applied to the index file. The shell script fix_hack -# does this (the Makefile takes care of calling it). -# -# Additional targets attempt to convert selected LaTeX sources to -# various other formats. These are generally site specific because -# the tools used are all but universal. These targets are: -# -# ps -- convert all documents from LaTeX to PostScript -# pdf -- convert all documents from LaTeX to the -# Portable Document Format -# -# See the README file for more information on these targets. -# -# The formatted output is located in subdirectories. For PDF and -# PostScript, look in the paper-$(PAPER)/ directory. For HTML, look in -# the html/ directory. If you want to fix the GNU info process, look -# in the info/ directory; please send patches to python-docs@python.org. - -# This Makefile only includes information on how to perform builds; for -# dependency information, see Makefile.deps. - -# Customization -- you *may* have to edit this - -# You could set this to a4: -PAPER=a4 - -# Ideally, you shouldn't need to edit beyond this point - -INFODIR= info -TOOLSDIR= tools - -# This is the *documentation* release, and is used to construct the file -# names of the downloadable tarballs. -RELEASE=0.2 - -PYTHON= python -DVIPS= dvips -N0 -t $(PAPER) - -MKDVI= $(PYTHON) ../tools/mkhowto --paper=$(PAPER) --dvi -MKHTML= $(PYTHON) tools/mkhowto --html --about html/myabout.dat \ - --iconserver ../icons --favicon ../icons/pyfav.gif \ - --address $(MYHDLDOCS) --up-link ../Overview.html \ - --up-title "Overview" \ - --dvips-safe -MKPDF= $(PYTHON) ../tools/mkhowto -l --paper=$(PAPER) --pdf -MKPS= $(PYTHON) ../tools/mkhowto --paper=$(PAPER) --ps - -BUILDINDEX=$(TOOLSDIR)/buildindex.py - -MYHDLDOCS="About this document" -HTMLBASE= file:`pwd` - -# The emacs binary used to build the info docs. GNU Emacs 21 is required. -EMACS= emacs - -# The end of this should reflect the major/minor version numbers of -# the release: -WHATSNEW=whatsnew04 - -# what's what -MANDVIFILES= paper-$(PAPER)/MyHDL.dvi - -HOWTODVIFILES= paper-$(PAPER)/whatsnew03.dvi \ - paper-$(PAPER)/whatsnew04.dvi - -MANPDFFILES= paper-$(PAPER)/MyHDL.pdf - -HOWTOPDFFILES= paper-$(PAPER)/whatsnew03.pdf \ - paper-$(PAPER)/whatsnew04.pdf - -MANPSFILES= paper-$(PAPER)/MyHDL.ps - -HOWTOPSFILES= paper-$(PAPER)/whatsnew03.ps \ - paper-$(PAPER)/whatsnew04.ps - -DVIFILES= $(MANDVIFILES) $(HOWTODVIFILES) -PDFFILES= $(MANPDFFILES) $(HOWTOPDFFILES) -PSFILES= $(MANPSFILES) $(HOWTOPSFILES) - -HTMLCSSFILES=html/manual/MyHDL.css \ - html/whatsnew03/whatsnew03.css \ - html/whatsnew04/whatsnew04.css - -ALLCSSFILES=$(HTMLCSSFILES) - -INDEXFILES=html/manual/MyHDL.html \ - html/whatsnew03/whatsnew03.html \ - html/whatsnew04/whatsnew04.html - -ALLHTMLFILES=$(INDEXFILES) - -COMMONPERL= perl/manual.perl perl/python.perl perl/l2hinit.perl - -include Makefile.deps - -# These must be declared phony since there -# are directories with matching names: -.PHONY: manual -.PHONY: html info - - -# Main target -default: all -all: html pdf -full: all ps - -dvi: $(DVIFILES) -pdf: $(PDFFILES) -ps: $(PSFILES) - -world: ps pdf html distfiles - - -# Rules to build PostScript and PDF formats -.SUFFIXES: .pdf .dvi .ps - -#.dvi.ps: -# $(DVIPS) -o $@ $< - -#.pdf.ps: -# pdf2ps $< $@ - -.pdf.ps: - xpdf $< - - -# Targets for each document: - - - -# MyHDL Manual -paper-$(PAPER)/MyHDL.dvi: $(MANUALFILES) - cd paper-$(PAPER) && $(MKDVI) ../manual/MyHDL.tex - -paper-$(PAPER)/MyHDL.pdf: $(MANUALFILES) - cd paper-$(PAPER) && $(MKPDF) ../manual/MyHDL.tex - - -# What's new -# in 0.3 -paper-$(PAPER)/whatsnew03.dvi: whatsnew03/whatsnew03.tex - cd paper-$(PAPER) && $(MKDVI) ../whatsnew03/whatsnew03.tex - -paper-$(PAPER)/whatsnew03.pdf: whatsnew03/whatsnew03.tex - cd paper-$(PAPER) && $(MKPDF) ../whatsnew03/whatsnew03.tex - -# What's new -# in 0.4 -paper-$(PAPER)/whatsnew04.dvi: whatsnew04/whatsnew04.tex whatsnew04/conversion.tex - cd paper-$(PAPER) && $(MKDVI) ../whatsnew04/whatsnew04.tex - -paper-$(PAPER)/whatsnew04.pdf: whatsnew04/whatsnew04.tex whatsnew04/conversion.tex - cd paper-$(PAPER) && $(MKPDF) ../whatsnew04/whatsnew04.tex - -# The remaining part of the Makefile is concerned with various -# conversions, as described above. See also the README file. - -info: - cd $(INFODIR) && $(MAKE) EMACS=$(EMACS) - -# Targets to convert the manuals to HTML using Nikos Drakos' LaTeX to -# HTML converter. For more info on this program, see -# . - -# Note that LaTeX2HTML inserts references to an icons directory in -# each page that it generates. I have placed a copy of this directory -# in the distribution to simplify the process of creating a -# self-contained HTML distribution; for this purpose I have also added -# a (trivial) index.html. Change the definition of $ICONSERVER in -# perl/l2hinit.perl to use a different location for the icons directory. - -# If you have the standard LaTeX2HTML icons installed, the versions shipped -# with this documentation should be stored in a separate directory and used -# instead. The standard set does *not* include all the icons used in the -# Python documentation. - -$(ALLCSSFILES): html/style.css - cp $< $@ - -$(INDEXFILES): $(COMMONPERL) html/about.dat tools/node2label.pl - -html/acks.html: ACKS $(TOOLSDIR)/support.py $(TOOLSDIR)/mkackshtml - $(PYTHON) $(TOOLSDIR)/mkackshtml --address $(PYTHONDOCS) \ - --favicon icons/pyfav.gif \ - --output html/acks.html $@ - -html/modindex.html: - touch html/modindex.html - -html: $(ALLHTMLFILES) $(HTMLCSSFILES) - - - - -manual: html/manual/MyHDL.html html/manual/MyHDL.css -html/manual/MyHDL.html: $(MANUALFILES) - $(MKHTML) --dir html/manual manual/MyHDL.tex - -whatsnew03: html/whatsnew03/whatsnew03.html -html/whatsnew03/whatsnew03.html: whatsnew03/whatsnew03.tex - $(MKHTML) --dir html/whatsnew03 whatsnew03/whatsnew03.tex - -whatsnew04: html/whatsnew04/whatsnew04.html -html/whatsnew04/whatsnew04.html: whatsnew04/whatsnew04.tex whatsnew04/conversion.tex - $(MKHTML) --dir html/whatsnew04 whatsnew04/whatsnew04.tex - - - -# webchecker needs an extra flag to process the huge index from the libref -WEBCHECKER=$(PYTHON) ../Tools/webchecker/webchecker.py -HTMLBASE= file:`pwd`/html - -webcheck: $(ALLHTMLFILES) - $(WEBCHECKER) $(HTMLBASE)/manual/ - $(WEBCHECKER) $(HTMLBASE)/doc/ - -fastwebcheck: $(ALLHTMLFILES) - $(WEBCHECKER) -x $(HTMLBASE)/manual/ - $(WEBCHECKER) -x $(HTMLBASE)/doc/ - - -# Release packaging targets: - -paper-$(PAPER)/README: $(PSFILES) $(TOOLSDIR)/getpagecounts - cd paper-$(PAPER) && ../$(TOOLSDIR)/getpagecounts -r $(RELEASE) >../$@ - -info-$(RELEASE).tgz: info - cd $(INFODIR) && tar cf - README python.dir python-*.info* \ - | gzip -9 >$@ - -info-$(RELEASE).tar.bz2: info - cd $(INFODIR) && tar cf - README python.dir python-*.info* \ - | bzip2 -9 >$@ - -latex-$(RELEASE).tgz: - $(PYTHON) $(TOOLSDIR)/mksourcepkg --gzip $(RELEASE) - -latex-$(RELEASE).tar.bz2: - $(PYTHON) $(TOOLSDIR)/mksourcepkg --bzip2 $(RELEASE) - -latex-$(RELEASE).zip: - rm -f $@ - $(PYTHON) $(TOOLSDIR)/mksourcepkg --zip $(RELEASE) - -pdf-$(PAPER)-$(RELEASE).tar: $(PDFFILES) - rm -f $@ - mkdir Python-Docs-$(RELEASE) - cp paper-$(PAPER)/*.pdf Python-Docs-$(RELEASE) - tar cf $@ Python-Docs-$(RELEASE) - rm -r Python-Docs-$(RELEASE) - -pdf-$(PAPER)-$(RELEASE).tgz: pdf-$(PAPER)-$(RELEASE).tar - gzip -9 <$? >$@ - -pdf-$(PAPER)-$(RELEASE).tar.bz2: pdf-$(PAPER)-$(RELEASE).tar - bzip2 -9 <$? >$@ - -pdf-$(PAPER)-$(RELEASE).zip: pdf - rm -f $@ - mkdir Python-Docs-$(RELEASE) - cp paper-$(PAPER)/*.pdf Python-Docs-$(RELEASE) - zip -q -r -9 $@ Python-Docs-$(RELEASE) - rm -r Python-Docs-$(RELEASE) - -postscript-$(PAPER)-$(RELEASE).tar: $(PSFILES) paper-$(PAPER)/README - rm -f $@ - mkdir Python-Docs-$(RELEASE) - cp paper-$(PAPER)/*.ps Python-Docs-$(RELEASE) - cp paper-$(PAPER)/README Python-Docs-$(RELEASE) - tar cf $@ Python-Docs-$(RELEASE) - rm -r Python-Docs-$(RELEASE) - -postscript-$(PAPER)-$(RELEASE).tar.bz2: postscript-$(PAPER)-$(RELEASE).tar - bzip2 -9 <$< >$@ - -postscript-$(PAPER)-$(RELEASE).tgz: postscript-$(PAPER)-$(RELEASE).tar - gzip -9 <$< >$@ - -postscript-$(PAPER)-$(RELEASE).zip: $(PSFILES) paper-$(PAPER)/README - rm -f $@ - mkdir Python-Docs-$(RELEASE) - cp paper-$(PAPER)/*.ps Python-Docs-$(RELEASE) - cp paper-$(PAPER)/README Python-Docs-$(RELEASE) - zip -q -r -9 $@ Python-Docs-$(RELEASE) - rm -r Python-Docs-$(RELEASE) - -HTMLPKGFILES=*.html */*.css */*.html */*.gif */*.txt - -html-$(RELEASE).tar: $(ALLHTMLFILES) $(HTMLCSSFILES) - mkdir Python-Docs-$(RELEASE) - cd html && tar cf ../temp.tar $(HTMLPKGFILES) - cd Python-Docs-$(RELEASE) && tar xf ../temp.tar - rm temp.tar - tar cf html-$(RELEASE).tar Python-Docs-$(RELEASE) - rm -r Python-Docs-$(RELEASE) - -html-$(RELEASE).tgz: html-$(RELEASE).tar - gzip -9 <$? >$@ - -html-$(RELEASE).tar.bz2: html-$(RELEASE).tar - bzip2 -9 <$? >$@ - -html-$(RELEASE).zip: $(ALLHTMLFILES) $(HTMLCSSFILES) - rm -f $@ - mkdir Python-Docs-$(RELEASE) - cd html && tar cf ../temp.tar $(HTMLPKGFILES) - cd Python-Docs-$(RELEASE) && tar xf ../temp.tar - rm temp.tar - zip -q -r -9 $@ Python-Docs-$(RELEASE) - rm -r Python-Docs-$(RELEASE) - - - -# convenience targets: - -tarhtml: html-$(RELEASE).tgz -tarinfo: info-$(RELEASE).tgz -tarps: postscript-$(PAPER)-$(RELEASE).tgz -tarpdf: pdf-$(PAPER)-$(RELEASE).tgz -tarlatex: latex-$(RELEASE).tgz - -tarballs: tarpdf tarps tarhtml - -ziphtml: html-$(RELEASE).zip -zipps: postscript-$(PAPER)-$(RELEASE).zip -zippdf: pdf-$(PAPER)-$(RELEASE).zip -ziplatex: latex-$(RELEASE).zip - -zips: zippdf zipps ziphtml - -bziphtml: html-$(RELEASE).tar.bz2 -bzipinfo: info-$(RELEASE).tar.bz2 -bzipps: postscript-$(PAPER)-$(RELEASE).tar.bz2 -bzippdf: pdf-$(PAPER)-$(RELEASE).tar.bz2 -bziplatex: latex-$(RELEASE).tar.bz2 - -bzips: bzippdf bzipps bziphtml - -disthtml: tarhtml bziphtml ziphtml -distinfo: tarinfo bzipinfo -distps: tarps bzipps zipps -distpdf: tarpdf bzippdf zippdf -distlatex: tarlatex bziplatex ziplatex - -paperdist: distpdf distps -edist: disthtml - -distfiles: paperdist edist - $(TOOLSDIR)/mksourcepkg --all $(RELEASE) - $(TOOLSDIR)/mkpkglist >pkglist.html - - -# Housekeeping targets - -# Remove temporary files; all except the following: -# - sources: .tex, .bib, .sty, *.cls -# - useful results: .dvi, .pdf, .ps, .texi, .info -clean: - rm -f html-$(RELEASE).tar - cd $(INFODIR) && $(MAKE) clean - -# Remove temporaries as well as final products -clobber: - rm -f html-$(RELEASE).tar - rm -f html-$(RELEASE).tgz info-$(RELEASE).tgz - rm -f pdf-$(RELEASE).tgz postscript-$(RELEASE).tgz - rm -f latex-$(RELEASE).tgz html-$(RELEASE).zip - rm -f pdf-$(RELEASE).zip postscript-$(RELEASE).zip - rm -f $(DVIFILES) $(PSFILES) $(PDFFILES) - cd $(INFODIR) && $(MAKE) clobber - rm -f paper-$(PAPER)/*.tex paper-$(PAPER)/*.ind paper-$(PAPER)/*.idx - rm -f paper-$(PAPER)/*.l2h paper-$(PAPER)/*.how paper-$(PAPER)/README - rm -rf html/index.html html/modindex.html html/acks.html - rm -rf html/manual/ - rm -rf html/whatsnew03/ - rm -rf html/whatsnew04/ - -realclean distclean: clobber diff --git a/olddoc/Makefile.deps b/olddoc/Makefile.deps deleted file mode 100644 index b690a653..00000000 --- a/olddoc/Makefile.deps +++ /dev/null @@ -1,34 +0,0 @@ -# LaTeX source dependencies. - -COMMONSTYLES= texinputs/python.sty \ - texinputs/pypaper.sty - -INDEXSTYLES=texinputs/python.ist - -COMMONTEX= texinputs/copyright.tex \ - texinputs/license.tex \ - texinputs/boilerplate.tex - -MANSTYLES= texinputs/fncychap.sty \ - texinputs/manual.cls \ - $(COMMONSTYLES) - -HOWTOSTYLES= texinputs/howto.cls \ - $(COMMONSTYLES) - - -DOCFILES= $(HOWTOSTYLES) \ - texinputs/boilerplate.tex \ - texinputs/ltxmarkup.sty \ - doc/doc.tex - -# LaTeX source files for the MyHDL Manual -MANUALFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \ - manual/MyHDL.tex \ - manual/background.tex \ - manual/intro.tex \ - manual/modeling.tex \ - manual/unittest.tex \ - manual/cosimulation.tex \ - manual/conversion.tex \ - manual/reference.tex diff --git a/olddoc/README b/olddoc/README deleted file mode 100644 index aee8fb6b..00000000 --- a/olddoc/README +++ /dev/null @@ -1,231 +0,0 @@ -Python standard documentation -- in LaTeX ------------------------------------------ - -This directory contains the LaTeX sources to the Python documentation -and tools required to support the formatting process. The documents -now require LaTeX2e; LaTeX 2.09 compatibility has been dropped. - -If you don't have LaTeX, or if you'd rather not format the -documentation yourself, you can ftp a tar file containing HTML, PDF, -or PostScript versions of all documents. Additional formats may be -available. These should be in the same place where you fetched the -main Python distribution (try or -). - -The following are the LaTeX source files: - - api/*.tex Python/C API Reference Manual - doc/*.tex Documenting Python - ext/*.tex Extending and Embedding the Python Interpreter - lib/*.tex Python Library Reference - mac/*.tex Macintosh Library Modules - ref/*.tex Python Reference Manual - tut/*.tex Python Tutorial - inst/*.tex Installing Python Modules - dist/*.tex Distributing Python Modules - -Most use the "manual" document class and "python" package, derived from -the old "myformat.sty" style file. The Macintosh Library Modules -document uses the "howto" document class instead. These contains many -macro definitions useful in documenting Python, and set some style -parameters. - -There's a Makefile to call LaTeX and the other utilities in the right -order and the right number of times. By default, it will build the -HTML version of the documnetation, but DVI, PDF, and PostScript can -also be made. To view the generated HTML, point your favorite browser -at the top-level index (html/index.html) after running "make". - -The Makefile can also produce DVI files for each document made; to -preview them, use xdvi. PostScript is produced by the same Makefile -target that produces the DVI files. This uses the dvips tool. -Printing depends on local conventions; at our site, we use lpr. For -example: - - make paper-letter/lib.ps # create lib.dvi and lib.ps - xdvi paper-letter/lib.dvi # preview lib.dvi - lpr paper-letter/lib.ps # print on default printer - - -What if I find a bug? ---------------------- - -First, check that the bug is present in the development version of the -documentation at ; we may -have already fixed it. - -If we haven't, tell us about it. We'd like the documentation to be -complete and accurate, but have limited time. If you discover any -inconsistencies between the documentation and implementation, or just -have suggestions as to how to improve the documentation, let is know! -Specific bugs and patches should be reported using our bug & patch -databases at: - - http://sourceforge.net/projects/python - -Other suggestions or questions should be sent to the Python -Documentation Team: - - python-docs@python.org - -Thanks! - - -What happened to the Macintosh chapter of the Python Library Reference? ------------------------------------------------------------------------ - -The directory mac/ contains the LaTeX sources for the "Macintosh -Library Modules" manual; this is built using the standard build -targets, so check the proper output directory for your chosen format -and paper size. - - -What tools do I need? ---------------------- - -You need to install Python; some of the scripts used to produce the -documentation are written in Python. You don't need this -documentation to install Python; instructions are included in the -README file in the Python distribution. - -The simplest way to get the rest of the tools in the configuration we -used is to install the teTeX TeX distribution, versions 0.9 or newer. -More information is available on teTeX at . -This is a Unix-only TeX distribution at this time. This documentation -release was tested with the 1.0.7 release, but there have been no -substantial changes since late in the 0.9 series, which we used -extensively for previous versions without any difficulty. - -If you don't want to get teTeX, here is what you'll need: - -To create DVI, PDF, or PostScript files: - - - LaTeX2e, 1995/12/01 or newer. Older versions are likely to - choke. - - - makeindex. This is used to produce the indexes for the - library reference and Python/C API reference. - -To create PDF files: - - - pdflatex. We used the one in the teTeX distribution (pdfTeX - version 3.14159-13d (Web2C 7.3.1) at the time of this - writing). Versions even a couple of patchlevels earlier are - highly likely to fail due to syntax changes for some of the - pdftex primitives. - -To create PostScript files: - - - dvips. Most TeX installations include this. If you don't - have one, check CTAN (). - -To create info files: - - Note that info support is currently being revised using new - conversion tools by Michael Ernst . - - - makeinfo. This is available from any GNU mirror. - - - emacs or xemacs. Emacs is available from the same place as - makeinfo, and xemacs is available from ftp.xemacs.org. - - - Perl. Find the software at - . - - - HTML::Element. If you don't have this installed, you can get - this from CPAN. Use the command: - - perl -e 'use CPAN; CPAN::install("HTML::Element");' - - You may need to be root to do this. - -To create HTML files: - - - Perl 5.004_04 or newer. Find the software at - . - - - LaTeX2HTML 99.2b8 or newer. Older versions are not - supported; each version changes enough that supporting - multiple versions is not likely to work. Many older - versions don't work with Perl 5.6 as well. This also screws - up code fragments. ;-( Releases are available at: - . - - -What if Times fonts are not available? --------------------------------------- - -As distributed, the LaTeX documents use PostScript Times fonts. This -is done since they are much better looking and produce smaller -PostScript files. If, however, your TeX installation does not support -them, they may be easily disabled. Edit the file -texinputs/pypaper.sty and comment out the line that starts -"\RequirePackage{times}" by inserting a "%" character at the beginning -of the line. If you're formatting the docs for A4 paper instead of -US-Letter paper, change paper-a4/pypaper.sty instead. An alternative -is to install the right fonts and LaTeX style file. - - -What if I want to use A4 paper? -------------------------------- - -Instead of building the PostScript by giving the command "make ps", -give the command "make PAPER=a4 ps"; the output will be produced in -the paper-a4/ subdirectory. (You can use "make PAPER=a4 pdf" if you'd -rather have PDF output.) - - -Making HTML files ------------------ - -The LaTeX documents can be converted to HTML using Nikos Drakos' -LaTeX2HTML converter. See the Makefile; after some twiddling, "make" -should do the trick. - - -What else is in here? ---------------------- - -There is a new LaTeX document class called "howto". This is used for -the new series of Python HOWTO documents which is being coordinated by -Andrew Kuchling . The file -templates/howto.tex is a commented example which may be used as a -template. A Python script to "do the right thing" to format a howto -document is included as tools/mkhowto. These documents can be -formatted as HTML, PDF, PostScript, or ASCII files. Use "mkhowto ---help" for information on using the formatting tool. - -For authors of module documentation, there is a file -templates/module.tex which may be used as a template for a module -section. This may be used in conjunction with either the howto or -manual document class. Create the documentation for a new module by -copying the template to lib.tex and editing according to the -instructions in the comments. - -Documentation on the authoring Python documentation, including -information about both style and markup, is available in the -"Documenting Python" manual. - - -Copyright notice -================ - -The Python source is copyrighted, but you can freely use and copy it -as long as you don't change or remove the copyright notice: - ----------------------------------------------------------------------- -Copyright (c) 2000-2002 Python Software Foundation. -All rights reserved. - -Copyright (c) 2000 BeOpen.com. -All rights reserved. - -Copyright (c) 1995-2000 Corporation for National Research Initiatives. -All rights reserved. - -Copyright (c) 1991-1995 Stichting Mathematisch Centrum. -All rights reserved. - -See the file "texinputs/license.tex" for information on usage and -redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. ----------------------------------------------------------------------- diff --git a/olddoc/README.txt b/olddoc/README.txt deleted file mode 100644 index 10516792..00000000 --- a/olddoc/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -Printing problems with pdf --------------------------- - -Apparently there is a problem with Acrobat5 and the Python -documentation flow I am using. The symptom is that the some pages of -the MyHDL.pdf file don't print correctly. The workaround is to print -from Acrobat4, xpdf or ghostview. Alternatively, you can try the -postscript file MyHDL.ps. diff --git a/olddoc/html/about.dat b/olddoc/html/about.dat deleted file mode 100644 index e6f8b55c..00000000 --- a/olddoc/html/about.dat +++ /dev/null @@ -1,24 +0,0 @@ -

This document was generated using the - LaTeX2HTML translator. -

- -

- LaTeX2HTML is Copyright © - 1993, 1994, 1995, 1996, 1997, Nikos - Drakos, Computer Based Learning Unit, University of - Leeds, and Copyright © 1997, 1998, Ross - Moore, Mathematics Department, Macquarie University, - Sydney. -

- -

The application of - LaTeX2HTML to the Python - documentation has been heavily tailored by Fred L. Drake, - Jr. Original navigation icons were contributed by Christopher - Petrilli. -

diff --git a/olddoc/html/icons/blank.gif b/olddoc/html/icons/blank.gif deleted file mode 100644 index 2e31f4ed50ee9a3dc57f62d88392e7928d262c07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1958 zcmd^;Id0QY5XQ&xnu0s{08ottNHkO+&OieNQ*j77iu8!N21s0jxd3hAE%Cm@juXej z&#$6Ofg-WI%J0q0H{as_%U3U+K6%@gwtSSssZ=UQM@Q9awN|Uu>-9#X(QGzbt=94J zF;x{Y5f=%OEO%8g6;}zBEM+w@6E_KyEZyp2F76U8S%x*lLOdiwvS4Y7rFcrDWPw%z ziBWnfayuMTb=6SKvY5M>x@nkZ;X&D4-8EdZ(4yNyJv2hIuw>X$JvCCZkVXWop$RXD zu$fh01I9G%)Op~zS(s%}$YSp97H(Mt!-KMiMOYU7(4yPZA}xy@xP?9VfdME+BAO5Z zYiPm?B5Vd4Y`~bNojMPkaL-~T3R%oO!m~JwV0ciD^ejdb3prpsPGc=zVjgZ`4}M?( zijfFuuwV^MctM2CK!Xh!)3j6Pfs-XOtVAJ;xo3%x{0W?diIfZpjg*Lm955cIu@*0} z1C|Wq2L_-RiI4^h*3g6(MA!^8*nlxjJ9Qp7r>Cc9XJ?&Gr`zrJdcA(XKNt+o&(AL| zE{4P5Xfzs+$CJrqI-SmDv-y0!SS*&ygsB{-Ckc`-`w2ncDvi# z+x>nI^25UyaQGIUw^F{o`~Ku>LWeEA=LKALIe|!wxvrN0~ja~uAbC*@nW(^ z6HX>_CjJ4Q_HN>lukuZyd>2@M-AUSJc4pqZ_a^;3Ix^JJ-q|i99ogZ`D}E!5PdLbT zX6efxk)Vve7#}1J1OiP>O~GKWxw$zM3bnMfw6?Z}!{N5JHmXWQix?3r;(V@@XeCC8 zRpNYEY0+AY7OTbiZe>IpF-EKr=ZBRQZN*rzR-DIDPP7x_#5!>vS_w#u(o2!75n3su zlvT?4#pGHmqm|Xlc^;ItQN}21l=HOc)>av-tX0mlWLP_8oU%?iPZ|-hh9|?r7Lz-FLhjGOxiBZ?h8&G6aTe}?@i>jO zc!?dbWEej%0L4gzG+3~PCcGfRW}v|ajA`1b^FXYwuCA@Et*@_dY;0_9ZdNLlt*x!? z?d_eNo!#Bty}iBt{r!W3gTuqaYPEWFbaZ@tT&vYiPEJlwPtVTI&d<*;E-o%FFR!ky z>h=2d_4Uoo&F$?i$OHYIe;faS{PUrVd)6k?OI;$r znkJ%wAC+Y~2FinP%40LS{2@16l)lH0o@A$Tlf{?0$x`86BoU2Adn4&|Ppr2m_B2wM zEzOk|`=%D>%B4cII2WCme?K!_juvL7zWsi<0$i7eD@{)4%JbmGa)neXR!pSQI0C0IOr??&Iv!8t68U27&i6V~cNY($TQaJwElDoXb{P z{iKTTfktP#y~XC0jUJp#lZSML7^`tb6&=(bvdv16}%BLs@B+A z<>Fo^)a#KlQRA*qPm^bZhl&`J&_aPqkqo6nizOUfc$PGUJ}H>O;jEeB*fqn|dMO8! zrs_UrMq4YPw9CrO%&LwxjNF18D$I3^j?G$mjZSThY=S(D8Tp#iV;HS@RXc3sEVQ@; zix|u2GxjW6Be+hTuaqq?ZXLJ41ncEWOc6>OSQ6GZED$(c#b3i5(CxI2U4WC7>!J#q zKr~mE8p{M#*464y?Owimt;fVYla;rNrHhN5mzRZ$m+K4Tw;x|>oe~<_m>GGN*%Tb{ z^3*ZpS)XVu;yquLCFGH5iiE=A71_)dg*pK(DU58~cGgxo1rJhA^>SBrR78A=Vq({F yzjww`;hH^D;28~#=PK%FS+o}ac$3N2$Xvl$m3PG4WR({a-;E8oZz-`bSOWl(s*7p> diff --git a/olddoc/html/icons/contents.png b/olddoc/html/icons/contents.png deleted file mode 100644 index 3429be0c1d45d9b1f0816da78621c029f512de1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 649 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy2?0JKuK)l4pLyng|DmsKJKxl- ze^k8eX6Bsp@so~*b?))0-{f4j(kgd>LGm=U$R62%W?{EVF53bI<20adB0;ac!CIhF z#w2fd7oqAsIUu&Ir;B4q#jUfG?oK+az|q>>#C1&m-v3l_L(kpjZ++9#jb~Q4+3_XR z9B6<3v7g}&LrNuo%Gvh}Ijg4ntJ`I`J0-45WM0x7CTzi@Ju7TZTjSpMLMyILf7xB8 zzpLlj9fsp zeuu2_;)6`NKZ_-)w2oSBzJ<5*SaeU1+jXReym>iyYq)M&223n3t=3{GA}JF@a0-?ty6= z4|59K_IAJPaC-WhpW+ApmRY3ca0~EUaO{{dzu`0k-;rwzOJ=t`j&$K^?=t zlYFakZp7OHL&~QrB%&lZKdq!Zu_%>+q2gBYg@9{c&iMNHfA#e_?{hB9;G*#*uns|DeZt?IkVPWWX<(OZvdC7C2 sc5#sQfW&mLlZ?$)8JJx%yI{t^z%`5Ur+fKfQJ@kAPgg&ebxsLQ0It{kg8%>k diff --git a/olddoc/html/icons/index.gif b/olddoc/html/icons/index.gif deleted file mode 100644 index 32eecfb4fd4bca98f6601e677fa0e667c3a1efe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 289 zcmZ?wbhEHbRA5kGIP#z2|Ns9p&;0K{^tEm0o0|2HikIEYoO3>Y($TQaJwElDoXb{P z{iKTTfktP#y~XC0jUJp#lX5OL7^`tb6&=(bvdu+v3=SX7;-^cMjqsd~%GA9>CT~(zvt(6O}bg@iq3s31#ImX!PTkxTXwIj7u zuu$NF+mpyDJ&b7+7!9W=aq$;v&*J5q z+r!Bh!kW~b&dV*pn6%1`o1b~Z)}XD7+$;+i`8kYcZalJe4dd!&Zf5_Q%c_bD)&L0t BTp0iW diff --git a/olddoc/html/icons/index.png b/olddoc/html/icons/index.png deleted file mode 100644 index cd918afe76ca2913a4de7ac7663211878b0c263f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 529 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy2?0JKuK)l4pLyng|DmsKJKxl- ze^k8eX6Bsp@so~*b?))0-{f4j(kgd>LGm=U$R62%W?{EVF53bI<20adB0;ac!CIhF z#w2fd7oqAsIUsFIJzX3_DsFAPbdm3{0tf4bMXs#u)BgXzdFjnr%UL?B*Ux+KwT(CL z+_(CGTf7E`B|d1|N*Rg2lJF1kHncD~*Ko{GLECVG&NY_%=9 z{C8Qq4_rQDCxf4A&_I-XbVGq#3K2;$RCBgY=CFO}l zsSFGiw~8+WT>Emy*T?^>ug`g(b72M-jV~DoZP;?f+~BIYL5PRmDIL9)B`4PE=$-Vr z=B<0pTT}PMdF_kd=gzY-eDM})_;UA19MD{2u(_G(d5I;Z5QB|P{fzyM{7ijK%?(U_ zOiT@p{I+=*d;1vs7`C(C@5(ZCKKbLh*2~7a755D*S diff --git a/olddoc/html/icons/modules.gif b/olddoc/html/icons/modules.gif deleted file mode 100644 index f5860b6bb9c4ce21e25ca74b0fb90faaaf231993..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 385 zcmZ?wbhEHbRA5kGIP#z2|Ns9p&;0K{^tEm0o0|2HikIEYoO3>Y($TQaJwElDoXb{P z{iKTTfktP#y~XC0jUJp#lZSML7^`tb6&=(bvdv173iEV$-Q4T zQKc)wfV=U<1&+oZeq4N_(o)_}U;aU1zf@uM5%DzVY0=106wfVe;%z`}1(`G1DaWJ*(c(i+zDK$Cj z^Moj`3SCwmZ=u4vY3n8yH_mu&o=`4ce|8p@LutIck+YRq1(*d`IXGBm@G|i-bFx}l zDNRZ5x8vvKvv-;@g^lCp?V@{p>rQjJvfg{nX!ZJLkpS-zZdI#-i?7+9-Q&ys#nDy3 w&^OzT`5Kp=zzM&F4LO^OLLGm=U$R62%W?{EVF53bI<20adB0;ac!CIhF z#w2fd7oqAsIUsGXJY5_^DsH{Kbg<}%0tedzR@WmO6TjErOqz6e*=(Qco5{sL_|KUi z`tyvjzNWwa1E0qd*Ke$h5l^47ePi1*Lp&q*YYFS4R?A6IY+q+fpXp4$#$@n@>w@pL zH5)yBb~ilI&fDp~yXn~?`hzbNux0)FaWKvLDLKtM7)-DE-S)yE@JP zqv`*DVqYF!Kf^RB@g?Uhu?KT3kMCP`rk360(t@aBc2{2~6_L5_!foskS63vV}1V#`3H2Y)7~&VTJeCz+m2D>7h8tgf@=yhm)_9gPYwR#5E##Q zl4sT2ou>~2eeF{f5>XPIpH@ zSIiBrnj3_8=$+EhTUl~qt&ZMFpKIQ_*Ss}#Pn_4j=zZ=yE5jFWp@uJakHi7ZH3plT znVy$eQVKEHdy|2wx3RaOk%@<)k(rsdmyfZpsfm%nHWSY+2IgB07#O-=aOh>eQs4n< s7YAt%NK6Mi$=Ga_f!QUq3uX)qT(cN|x|bgo1u9|iboFyt=akR{0EAiRtN;K2 diff --git a/olddoc/html/icons/next.gif b/olddoc/html/icons/next.gif deleted file mode 100644 index 5dcaff8b2429e50aad5de34344459cebef9e0957..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 253 zcmZ?wbhEHbRA5kGIP#z2|Ns9p&;0K{^tEm0o0|2HikIEYoO3>Y($TQaJwElDoXb{P zg2lA{-J z-=104^TCI&GE5IMJ{UMjoDw|98R+85{_3GrKtS>JHenB~pz|5ZMN{&Yi!WMP{Z5Bv z)0aPH6Hc6$Pq1Q2%5rpKPP60nbYk&!EAV3Px8n$`b>n9Xw3*px?BbW*&Sh@K)f2O7 O^_sQo)~hNqSOWl>6;&qy diff --git a/olddoc/html/icons/next.png b/olddoc/html/icons/next.png deleted file mode 100644 index cfe5e51ca619b357fc22d618fa2cb132036da31f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 511 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy2?0JKuK)l4pLyng|DmsKJKxl- ze^k8eX6Bsp@so~*b?))0-{f4j(kgd>LGm=U$R62%W-i+T2IDlKR^mbIJX?@mj7i?^ zE`pD?+U^2!CVRR#hE&`-JNcl{Ap;JVWQUcVoIn4spW0L=b9UR~wbf63)8v=FESgZ_ z<}j=MBX{YVz$S-xeqVU3Cs=(vpn9`0a6>DLV#H>agBAR_!G;P^{>fTwJ##~tEBGa@ ze_3bKe}lW+CX7wYQpJkVmuvmBgNq{KnG&uFeP*qF_hOBCi9zXVd)9q@PuUkd`W|8T z?D?OO|E6o##^(5>XPIpH@SIiBrnj3_8=$+EhTUl~qt&ZMFpKIQ_*Ss}#Pn_4j=zZ=yE5jFWp@uJa zkHi7ZH3plTnVy$eQVKEH*vQy$^A;Zyb7ON8Z$m>9BQrlAW5ewRranf71|B}fEDSYy z>=#b%J8=Z4T^yu6ATb^6BxAEx240W+V6sUy3)78&qol`;+0AXLa A&;S4c diff --git a/olddoc/html/icons/previous.gif b/olddoc/html/icons/previous.gif deleted file mode 100644 index de1da16023d2b5c20e6f1c8546c04e434136ac6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252 zcmZ?wbhEHbRA5kGIP#z2|Ns9p&;0K{^tEm0o0|2HikIEYoO3>Y($TQaJwElDoXb{P z{iKTTfktP#y~XC0jUJp#lYH_pwO3+IWJ??x}4Yh3Ut`rlkXq( z(F?rq%re*Gz=y9gjt>tc_L#67Vqm-!=z}!6qV*&EihG9 zIC1R#*_Ia#?|<_sbJf*)D!C>zhnM8L2ZS@1*%o)PWN>wvWF&MoCAS9h#`UH0n43+X Qv2xYwHEY*tD>7IE016OT9smFU diff --git a/olddoc/html/icons/previous.png b/olddoc/html/icons/previous.png deleted file mode 100644 index 497def42a0cf47e012bcd69599c2d3c405c3bca4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 511 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy2?0JKuK)l4pLyng|DmsKJKxl- ze^k8eX6Bsp@so~*b?))0-{f4j(kgd>LGm=U$R62%W?{EVF53bI<20adB0;ac!CIhF z#w2fd7oqAsIUsG5JzX3_DsEk!wRyY zCEWY>_i=7wnwQ?Thv7!lk3Q3b_hn3_6cyBDCqA^@uz$wKgFRYIje)6~-oBPwCCtL8 zRn{-bS5|{;$vbCgx;QBrpAU_J-m#4jD3wv4E??ROxPGE zh;n@Sv(s`4P`fxtdq843*h$7_s|?I8nO!hrVBng?_|v`ouqaRogQu&X%Q~loCID!* Bwsrsj diff --git a/olddoc/html/icons/pyfav.gif b/olddoc/html/icons/pyfav.gif deleted file mode 100644 index 58271edec49353382f935ada2de138a1f5b35d9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125 zcmZ?wbhEHbY($TQaJwElDoXb{P z{iKTTfktP#y~XC0jUJp#lU(nL7^|jk}GZ1DyGA0K4@74E;;hU z!=beHi6QfP@kW7$Rm>AP92GsgpI-VXvUSO&qs0z~y#x=;y`FtQwrwxVN5NFNRPPfD z9dcN9?Y-S~&zMcXg_DsfL(pD3%aqTL%cVWZl+_@Y$B&WMWs;JYso{($6>rrne#16Z zW|t6E?lPlP)f!WMRi+L8ou*BpT0Ab>_o!9~G9T1jbWD|{^rR}A%Yw5?I|X-Nnm+To e62Hr|OFp+4Hwmu0-cb3FmGd>{tcS-G8LR>07;De~ diff --git a/olddoc/html/icons/up.png b/olddoc/html/icons/up.png deleted file mode 100644 index a90e0284436f3823439ae6c00a5fdd692a0663ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 577 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy2?0JKuK)l4pLyng|DmsKJKxl- ze^k8eX6Bsp@so~*b?))0-{f4j(kgd>LGm=U$R62%W?{EVF53bI<20adB0;ac!CIhF z#w2fd7oqAsIUsFUJzX3_DsI(Ix-HhKz~M64NIU=IfBR~Y$X4|dxhzrZ1U2!`f+hZ^ zm&+UyX=thNZFqZ3$(*HZ)#JUq4DD;ALk>J%yo5m@;6#0cY2xz7{28yk-^xCS`nzWO zo266P9IBt@>~+1oES71*pOcQcJRLiv0-~2c`um6}H-$A|S=%gM7riSdo=lopdpYOb zOw|LQ!vq)gGckPg+5M@o!H)g&n<$?iejfqORSc|K{2H#e@a5>fFx*hi?#O5&Ec=1Q zmZ^v}f$4(1dGdiQHI;%r$1^TG)Y&BLaGk%ULbzhlI&Nd22YsqSB1(eu(@M${i&7aF zDsB~D2)Op;jIWRXS6`p=KIg&=E*f7l4%)Egin+m6bAu2My;C}RD@#tS)zLfYbIn`# znzyFziSybQz0aLzW%%MP)bQo*kvO2a#$a@ip=GH1RMs z+iK#o&Bw&V#KXj3tBH{z6GLwqhx7L6v&}&5;vnq-iRoY`8Jn##FuP=S!Hj`{YZl{A T_wvJ{KqU;Gu6{1-oD!M This document was generated using the - LaTeX2HTML translator. -

- -

- LaTeX2HTML is Copyright © - 1993, 1994, 1995, 1996, 1997, Nikos - Drakos, Computer Based Learning Unit, University of - Leeds, and Copyright © 1997, 1998, Ross - Moore, Mathematics Department, Macquarie University, - Sydney. -

- -

The application of - LaTeX2HTML to the Python - documentation has been heavily tailored by Fred L. Drake, - Jr. Original navigation icons were contributed by Christopher - Petrilli. -

- -

Jan Decaluwe reused the Python documentation flow to generate -the MyHDL documentation as much as he could; his sincere thanks and -appreciation go out to all who contributed to this flow and -made this part of his life so much easier. -

- -
- -

Comments and Questions

- -

General comments, questions and bug reports regarding this document - may be sent to Jan Decaluwe. -

diff --git a/olddoc/html/style.css b/olddoc/html/style.css deleted file mode 100644 index 3de8b0f8..00000000 --- a/olddoc/html/style.css +++ /dev/null @@ -1,157 +0,0 @@ -/* - * The first part of this is the standard CSS generated by LaTeX2HTML, - * with the "empty" declarations removed. - */ - -/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ -.math { font-family: "Century Schoolbook", serif; } -.math i { font-family: "Century Schoolbook", serif; - font-weight: bold } -.boldmath { font-family: "Century Schoolbook", serif; - font-weight: bold } - -/* - * Implement both fixed-size and relative sizes. - * - * I think these can be safely removed, as it doesn't appear that - * LaTeX2HTML ever generates these, even though these are carried - * over from the LaTeX2HTML stylesheet. - */ -small.xtiny { font-size : xx-small; } -small.tiny { font-size : x-small; } -small.scriptsize { font-size : smaller; } -small.footnotesize { font-size : small; } -big.xlarge { font-size : large; } -big.xxlarge { font-size : x-large; } -big.huge { font-size : larger; } -big.xhuge { font-size : xx-large; } - -/* - * Document-specific styles come next; - * these are added for the Python documentation. - * - * Note that the size specifications for the H* elements are because - * Netscape on Solaris otherwise doesn't get it right; they all end up - * the normal text size. - */ - -body { color: #000000; - background-color: #ffffff; } - -a:active { color: #ff0000; } -a:link:hover { background-color: #bbeeff; } -a:visited:hover { background-color: #bbeeff; } -a:visited { color: #551a8b; } -a:link { color: #0000bb; } - -h1, h2, h3, h4, h5, h6 { font-family: avantgarde, sans-serif; - font-weight: bold; } -h1 { font-size: 180%; } -h2 { font-size: 150%; } -h3, h4 { font-size: 120%; } - -/* LaTeX2HTML insists on inserting
elements into headers which - * are marked with \label. This little bit of CSS magic ensures that - * these elements don't cause spurious whitespace to be added. - */ -h1>br, h2>br, h3>br, -h4>br, h5>br, h6>br { display: none; } - -code, tt { font-family: "lucida typewriter", lucidatypewriter, - monospace; } -var { font-family: times, serif; - font-style: italic; - font-weight: normal; } - -.typelabel { font-family: lucida, sans-serif; } - -.navigation td { background-color: #99ccff; - font-weight: bold; - font-family: avantgarde, sans-serif; - font-size: 110%; } - -div.warning { background-color: #fffaf0; - border: thin solid black; - padding: 1em; - margin-left: 2em; - margin-right: 2em; } - -div.warning .label { font-family: sans-serif; - font-size: 110%; - margin-right: 0.5em; } - -div.note { background-color: #fffaf0; - border: thin solid black; - padding: 1em; - margin-left: 2em; - margin-right: 2em; } - -div.note .label { margin-right: 0.5em; - font-family: sans-serif; } - -.release-info { font-style: italic; } - -.titlegraphic { vertical-align: top; } - -.verbatim pre { color: #00008b; - font-family: monospace; - font-size: 100%; } -.verbatim { margin-left: 2em; } -.verbatim .footer { padding: 0.05in; - font-size: 85%; - background-color: #99ccff; - margin-right: 0.5in; } - -.grammar { background-color: #99ccff; - margin-right: 0.5in; - padding: 0.05in; } -.grammar-footer { padding: 0.05in; - font-size: 85%; } - -.productions { background-color: #bbeeff; } -.productions a:active { color: #ff0000; } -.productions a:link:hover { background-color: #99ccff; } -.productions a:visited:hover { background-color: #99ccff; } -.productions a:visited { color: #551a8b; } -.productions a:link { color: #0000bb; } -.productions table { vertical-align: baseline; } - -.email { font-family: avantgarde, sans-serif; } -.mailheader { font-family: avantgarde, sans-serif; } -.mimetype { font-family: avantgarde, sans-serif; } -.newsgroup { font-family: avantgarde, sans-serif; } -.url { font-family: avantgarde, sans-serif; } -.file { font-family: avantgarde, sans-serif; } -.menuselection { font-family: avantgarde, sans-serif; } - -.tableheader { background-color: #99ccff; - font-family: avantgarde, sans-serif; } - -.refcount-info { font-style: italic; } -.refcount-info .value { font-weight: bold; - color: #006600; } - -/* - * Some decoration for the "See also:" blocks, in part inspired by some of - * the styling on Lars Marius Garshol's XSA pages. - * (The blue in the navigation bars is #99CCFF.) - */ -.seealso { background-color: #fffaf0; - border: thin solid black; - padding: 0pt 1em 4pt 1em; } - -.seealso .heading { font-size: 110%; } - -/* - * Class 'availability' is used for module availability statements at - * the top of modules. - */ -.availability .platform { font-weight: bold; } - - -/* - * Some specialization for printed output. - */ -@media print { - .online-navigation { display: none; } - } diff --git a/olddoc/info/.cvsignore b/olddoc/info/.cvsignore deleted file mode 100644 index e8db0b5b..00000000 --- a/olddoc/info/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -*.info* -*.texi diff --git a/olddoc/info/Makefile b/olddoc/info/Makefile deleted file mode 100644 index 008e3692..00000000 --- a/olddoc/info/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# Generate the Python "info" documentation. - -TOPDIR=.. -TOOLSDIR=$(TOPDIR)/tools -HTMLDIR=$(TOPDIR)/html - -# The emacs binary used to build the info docs. GNU Emacs 21 is required. -EMACS=emacs - -MKINFO=$(TOOLSDIR)/mkinfo -SCRIPTS=$(TOOLSDIR)/checkargs.pm $(TOOLSDIR)/mkinfo $(TOOLSDIR)/py2texi.el - -# set VERSION to code the VERSION number into the info file name -# allowing installation of more than one set of python info docs -# into the same directory -VERSION= - -all: check-emacs-version \ - python$(VERSION)-api.info python$(VERSION)-ext.info \ - python$(VERSION)-lib.info python$(VERSION)-ref.info \ - python$(VERSION)-tut.info python$(VERSION)-dist.info - -# python$(VERSION)-doc.info python$(VERSION)-inst.info -# python$(VERSION)-mac.info - -check-emacs-version: - @v="`$(EMACS) --version 2>&1 | egrep '^(GNU |X)Emacs [12]*'`"; \ - if `echo "$$v" | grep '^GNU Emacs 21' >/dev/null 2>&1`; then \ - echo "Using $(EMACS) to build the info docs"; \ - else \ - echo "GNU Emacs 21 is required to build the info docs"; \ - echo "Found $$v"; \ - false; \ - fi - -python$(VERSION)-api.info: ../api/api.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -python$(VERSION)-ext.info: ../ext/ext.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -python$(VERSION)-lib.info: ../lib/lib.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -# Not built by default; the conversion doesn't really handle it well. -python$(VERSION)-mac.info: ../mac/mac.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -python$(VERSION)-ref.info: ../ref/ref.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -python$(VERSION)-tut.info: ../tut/tut.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -# Not built by default; the conversion doesn't handle it at all. -python$(VERSION)-doc.info: ../doc/doc.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -python$(VERSION)-dist.info: ../dist/dist.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -# Not built by default; the conversion chokes on two @end multitable's -python$(VERSION)-inst.info: ../inst/inst.tex $(SCRIPTS) - EMACS=$(EMACS) $(MKINFO) $< $*.texi $@ - -clean: - rm -f *.texi~ *.texi - -clobber: clean - rm -f *.texi python*-*.info python*-*.info-[0-9]* diff --git a/olddoc/info/README b/olddoc/info/README deleted file mode 100644 index 80231441..00000000 --- a/olddoc/info/README +++ /dev/null @@ -1,21 +0,0 @@ -This archive contains the standard Python documentation in GNU info -format. Five manuals are included: - - python-ref.info* Python Reference Manual - python-mac.info* Python Macintosh Modules - python-lib.info* Python Library Reference - python-ext.info* Extending and Embedding the Python Interpreter - python-api.info* Python/C API Reference - python-tut.info* Python Tutorial - -The file python.dir is a fragment of a "dir" file that can be used to -incorporate these documents into an existing GNU info installation: -insert the contents of this file into the "dir" or "localdir" file at -an appropriate point and copy the python-*.info* files to the same -directory. - -Thanks go to Milan Zamazal for providing this -conversion to the info format. - -Questions and comments on these documents should be directed to -python-docs@python.org. diff --git a/olddoc/info/python.dir b/olddoc/info/python.dir deleted file mode 100644 index dce2bb32..00000000 --- a/olddoc/info/python.dir +++ /dev/null @@ -1,12 +0,0 @@ - -Python Standard Documentation - -* Python Library: (python-lib). Python Library Reference -* Python Mac Modules: (python-mac). Python Macintosh Modules -* Python Reference: (python-ref). Python Reference Manual -* Python API: (python-api). Python/C API Reference Manual -* Python Extending: (python-ext). Extending & Embedding Python -* Python Tutorial: (python-tut). Python Tutorial -* Documenting Python: (python-doc). Documenting Python -* Installing Modules: (python-inst). Installing Python Modules -* Distributing Modules: (python-dist). Distributing Python Modules diff --git a/olddoc/manual/MyHDL.tex b/olddoc/manual/MyHDL.tex deleted file mode 100644 index 218445cb..00000000 --- a/olddoc/manual/MyHDL.tex +++ /dev/null @@ -1,101 +0,0 @@ -\documentclass{manual} -\usepackage{palatino} -\renewcommand{\ttdefault}{cmtt} -\renewcommand{\sfdefault}{cmss} -\newcommand{\myhdl}{\protect \mbox{MyHDL}} -\usepackage{graphicx} - -\title{The \myhdl\ manual} - -\input{boilerplate} - -\makeindex - -\begin{document} - -\maketitle - -\input{copyright} - -\begin{abstract} - -\noindent - -The goal of the \myhdl{} project is to empower hardware designers with -the elegance and simplicity of the Python language. - -\myhdl{} is a free, open-source (LGPL) package for using Python as a -hardware description and verification language. Python is a very high -level language, and hardware designers can use its full power to model -and simulate their designs. Moreover, \myhdl{} can convert a design to -Verilog. In combination with an external synthesis tool, it provides a -complete path from Python to a silicon implementation. - -\emph{Modeling} - - -Python's power and clarity make \myhdl{} an ideal solution for high level -modeling. Python is famous for enabling elegant solutions to complex -modeling problems. Moreover, Python is outstanding for rapid -application development and experimentation. - -The key idea behind \myhdl{} is the use of Python generators to model -hardware concurrency. Generators are best described as resumable -functions. In \myhdl{}, generators are used in a specific way so that -they become similar to always blocks in Verilog or processes in VHDL. - -A hardware module is modeled as a function that returns any number of -generators. This approach makes it straightforward to support features -such as arbitrary hierarchy, named port association, arrays of -instances, and conditional instantiation. - -Furthermore, \myhdl{} provides classes that implement traditional -hardware description concepts. It provides a signal class to support -communication between generators, a class to support bit oriented -operations, and a class for enumeration types. - -\emph{Simulation and Verification} - -The built-in simulator runs on top of the Python interpreter. It -supports waveform viewing by tracing signal changes in a VCD file. - -With \myhdl{}, the Python unit test framework can be used on hardware -designs. Although unit testing is a popular modern software -verification technique, it is not yet common in the hardware design -world, making it one more area in which \myhdl{} innovates. - -\myhdl{} can also be used as hardware verification language for VHDL and -Verilog designs, by co-simulation with traditional HDL simulators. - -\emph{Conversion to Verilog} - -The converter to Verilog works on an instantiated design that has been -fully elaborated. Consequently, the original design structure can be -arbitrarily complex. - -The converter automates certain tasks that are tedious or hard in -Verilog directly. Notable features are the possibility to choose -between various FSM state encodings based on a single attribute, the -mapping of certain high-level objects to RAM and ROM descriptions, and -the automated handling of signed arithmetic issues. - - - -\end{abstract} - -\tableofcontents - -\input{background.tex} -\input{intro.tex} -\input{modeling.tex} -\input{unittest.tex} -\input{cosimulation.tex} - -\chapter{Conversion to Verilog\label{conv}} -\input{conversion.tex} - -\input{reference.tex} - -\input{MyHDL.ind} - -\end{document} diff --git a/olddoc/manual/background.tex b/olddoc/manual/background.tex deleted file mode 100644 index d304559f..00000000 --- a/olddoc/manual/background.tex +++ /dev/null @@ -1,167 +0,0 @@ -\chapter{Background information \label{background}} - -\section{Prerequisites \label{prerequisites}} - -You need a basic understanding of Python to use \myhdl{}. -If you don't know Python, don't worry: it -it is one of the easiest programming languages to -learn~\footnote{You must be bored by such claims, but in Python's -case it's true.}. Learning Python is one of the best time -investments that engineering professionals can make~\footnote{I am not -biased.}. - -For starters, \url{http://www.python.org/doc/current/tut/tut.html} is -probably the best choice for an on-line tutorial. For alternatives, -see \url{http://www.python.org/doc/Newbies.html}. - -A working knowledge of a hardware description language such as Verilog -or VHDL is helpful. - -Code examples in this manual are sometimes shortened for clarity. - Complete executable examples can be found in the distribution directory at -\file{example/manual/}. - -\section{A small tutorial on generators \label{tutorial}} -\index{generators!tutorial on} - -Generators are a relatively recent Python feature. They -were introduced in Python~2.2. -Because generators are the key concept in -\myhdl{}, a small tutorial is included a here. - -Consider the following nonsensical function: - -\begin{verbatim} -def function(): - for i in range(5): - return i -\end{verbatim} - -You can see why it doesn't make a lot of sense. As soon as the first -loop iteration is entered, the function returns: - -\begin{verbatim} ->>> function() -0 -\end{verbatim} - -Returning is fatal for the function call. Further loop iterations -never get a chance, and nothing is left over from the function call -when it returns. - -To change the function into a generator function, we replace -\keyword{return} with \keyword{yield}: - -\begin{verbatim} -def generator(): - for i in range(5): - yield i -\end{verbatim} - -Now we get: - -\begin{verbatim} ->>> generator() - -\end{verbatim} - -When a generator function is called, it returns a generator object. A -generator object supports the iterator protocol, which is an expensive -way of saying that you can let it generate subsequent values by -calling its \function{next()} method: - -\begin{verbatim} ->>> g = generator() ->>> g.next() -0 ->>> g.next() -1 ->>> g.next() -2 ->>> g.next() -3 ->>> g.next() -4 ->>> g.next() -Traceback (most recent call last): - File "", line 1, in ? -StopIteration -\end{verbatim} - -Now we can generate the subsequent values from the for loop on demand, -until they are exhausted. What happens is that the -\keyword{yield} statement is like a -\keyword{return}, except that it is non-fatal: the generator remembers -its state and the point in the code when it yielded. A higher order -agent can decide when to get the next value by calling the -generator's \function{next()} method. We say that generators are -\dfn{resumable functions}. - -If you are familiar with hardware description languages, this may ring -a bell. In hardware simulations, there is also a higher order agent, -the Simulator, that interacts with such resumable functions; they are -called -\index{VHDL!process}% -\dfn{processes} in VHDL and -\index{Verilog!always block}% -\dfn{always blocks} in -Verilog. Similarly, Python generators provide an elegant -and efficient method to model concurrency, without having to resort to -some form of threading. - -The use of generators to model concurrency is the first key concept in -\myhdl{}. The second key concept is a related one: in \myhdl{}, the -yielded values are used to specify the conditions on which the -generator should wait before resuming. In other words, \keyword{yield} -statements work as general - \index{sensitivity list}% -sensitivity lists. - -For more info about generators, consult the on-line Python -documentation, e.g. at \url{http://www.python.org/doc/2.2.2/whatsnew}. - - -\section{About decorators \label{deco}} -\index{decorators!about} - -Python 2.4 introduced a new feature called decorators. MyHDL 0.5 takes -advantage of this new feature by defining a number of decorators that -facilitate hardware descriptions. However, many users may not yet be familiar with -decorators. Therefore, an introduction is included here. - -A decorator consists of special syntax in front of a function -declaration. It refers to a decorator function. The decorator function -automatically transforms the declared function into some other -callable object. - -A decorator function \function{deco} is used in a decorator statement as follows: - -\begin{verbatim} -@deco -def func(arg1, arg2, ...): - -\end{verbatim} - -This code is equivalent to the following: - -\begin{verbatim} -def func(arg1, arg2, ...): - -func = deco(func) -\end{verbatim} - -Note that the decorator statement goes directly in front of the -function declaration, and that the function name \function{func} is automatically -reused for the final result. - -MyHDL 0.5 uses decorators to create ready-to-simulate generators -from local function definitions. Their functionality -and usage will be described extensively in this manual. - -For more info about Python decorators, consult the on-line Python -documentation, e.g. at \url{http://www.python.org/doc/2.4/whatsnew/node6.html}. - -\begin{notice}[warning] -Because MyHDL 0.5 uses decorators, it requires Python 2.4 or a -later version. -\end{notice} diff --git a/olddoc/manual/conversion.tex b/olddoc/manual/conversion.tex deleted file mode 100644 index c28c69eb..00000000 --- a/olddoc/manual/conversion.tex +++ /dev/null @@ -1,1049 +0,0 @@ -\section{Introduction\label{conv-intro}} - -\myhdl\ supports the automatic conversion of implementation-oriented -\myhdl\ code to Verilog code. This feature provides a -direct path from Python to an FPGA or ASIC implementation. - -\section{Solution description\label{conv-solution}} - -The solution works as follows. The hardware description should -satisfy certain constraints that are typical for -implementation-oriented hardware modeling. Subsequently, such a -design is converted to an equivalent model in the Verilog language, -using the function \function{toVerilog} from the \myhdl\ -library. Finally, a third-party \emph{synthesis tool} is used to -convert the Verilog design to a gate implementation for an ASIC or -FPGA. There are a number of Verilog synthesis tools available, varying -in price, capabilities, and target implementation technology. - -The conversion does not start from source files, but from an -instantiated design that has been \emph{elaborated} by the Python -interpreter. The converter uses the Python profiler to track the -interpreter's operation and to infer the design structure and name -spaces. It then selectively compiles pieces of source code for -additional analysis and for conversion. This is done using the Python -compiler package. - -\section{Features\label{conv-features}} - -\subsection{The design is converted after elaboration\label{conv-features-elab}} -\emph{Elaboration} refers to the initial processing of a hardware -description to achieve a representation of a design instance that is -ready for simulation or synthesis. In particular, structural -parameters and constructs are processed in this step. In \myhdl{}, the -Python interpreter itself is used for elaboration. A -\class{Simulation} object is constructed with elaborated design -instances as arguments. Likewise, the Verilog conversion works on an -elaborated design instance. The Python interpreter is thus used as -much as possible. - -\subsection{The structural description can be arbitrarily complex and hierarchical\label{conv-features-struc}} -As the conversion works on an elaborated design instance, any modeling -constraints only apply to the leaf elements of the design structure, -that is, the co-operating generators. In other words, there are no -restrictions on the description of the design structure: Python's full -power can be used for that purpose. Also, the design hierarchy can be -arbitrarily deep. - -\subsection{Generators are mapped to Verilog always or initial blocks\label{conv-features-gen}} -The converter analyzes the code of each generator and maps it -to a Verilog \code{always} blocks if possible, and to -an \code{initial} block otherwise. -The converted Verilog design will be a flat -"net list of blocks". - -\subsection{The Verilog module interface is inferred from signal usage\label{conv-features-intf}} -In \myhdl{}, the input or output direction of interface signals -is not explicitly declared. The converter investigates signal usage -in the design hierarchy to infer whether a signal is used as -input, output, or as an internal signal. Internal signals are -given a hierarchical name in the Verilog output. - -\subsection{Function calls are mapped to a unique Verilog function or task call\label{conv-features-func}} -The converter analyzes function calls and function code to see if they -should be mapped to Verilog functions or to tasks. Python functions -are much more powerful than Verilog subprograms; for example, they are -inherently generic, and they can be called with named association. To -support this power in Verilog, a unique Verilog function or task is -generated per Python function call. - -\subsection{If-then-else structures may be mapped to Verilog case statements\label{conv-features-if}} -Python does not provide a case statement. However, -the converter recognizes if-then-else structures in which a variable is -sequentially compared to items of an enumeration type, and maps -such a structure to a Verilog case statement with the appropriate -synthesis attributes. - -\subsection{Choice of encoding schemes for enumeration types\label{conv-features-enum}} -The \function{enum} function in \myhdl\ returns an enumeration type. This -function takes an additional parameter \var{encoding} that specifies the -desired encoding in the implementation: binary, one hot, or one cold. -The Verilog converter generates the appropriate code. - -\subsection{Support for RAM inference \label{conf-features-ram}} -Certain synthesis tools can map Verilog memories to RAM -structures. To support this interesting feature, the Verilog converter -maps lists of signals to Verilog memories. - -\subsection{Support for ROM memory \label{conf-features-rom}} -Some synthesis tools can infer a ROM -from a case statement. The Verilog converter does the expansion into -a case statement automatically, based on a higher level -description. The ROM access is described in a single line, by -indexing into a tuple of integers. - -\subsection{Support for signed arithmetic \label{conf-features-signed}} -In MyHDL, working with negative numbers is trivial: one just uses -\code{intbv} objects with negative values. -By contrast, negative numbers are tricky in Verilog. The language -makes a difference between an unsigned and a signed representation, -and the user has to declare signed variables explicitly. When the two -representations are mixed in an expression, all operands are -interpreted as unsigned, which typically leads to unexpected results. - -The Verilog converter handles negative \code{intbv} objects by using -a signed Verilog representation. Also, it automatically performs sign -extension and casting to a signed representation when unsigned numbers -are used in a mixed expression. In this way, it automates a task which -is notoriously hard to get right in Verilog directly. - -\subsection{Support for user-defined Verilog code \label{conf-features-udfv}} -If desired, the user can bypass the regular Verilog conversion -and describe user-defined code to be inserted instead. - -\section{The convertible subset\label{conv-subset}} - -\subsection{Introduction\label{conv-subset-intro}} - -Unsurprisingly, not all \myhdl\ code can be converted to Verilog. In -fact, there are very important restrictions. As the goal of the -conversion functionality is implementation, this should not be a big -issue: anyone familiar with synthesis is used to similar restrictions -in the \emph{synthesizable subset} of Verilog and VHDL. The converter -attempts to issue clear error messages when it encounters a construct -that cannot be converted. - -In practice, the synthesizable subset usually refers to RTL synthesis, -which is by far the most popular type of synthesis today. There are -industry standards that define the RTL synthesis subset. However, -those were not used as a model for the restrictions of the MyHDL -converter, but as a minimal starting point. On that basis, whenever -it was judged easy or useful to support an additional feature, this -was done. For example, it is actually easier to convert -\keyword{while} loops than \keyword{for} loops even though they are -not RTL-synthesizable. As another example, \keyword{print} is -supported because it's so useful for debugging, even though it's not -synthesizable. In summary, the convertible subset is a superset of -the standard RTL synthesis subset, and supports synthesis tools with -more advanced capabilities, such as behavioral synthesis. - -Recall that any restrictions only apply to the design post -elaboration. In practice, this means that they apply only to the code -of the generators, that are the leaf functional blocks in a MyHDL -design. - -\subsection{Coding style\label{conv-subset-style}} - -A natural restriction on convertible code is that it should be -written in MyHDL style: cooperating generators, communicating through -signals, and with sensitivity lists specifying wait points and resume -conditions. Supported resume conditions are a signal edge, a signal -change, or a tuple of such conditions. - -\subsection{Supported types\label{conv-subset-types}} - -The most important restriction regards object types. Verilog is an -almost typeless language, while Python is strongly (albeit -dynamically) typed. The converter has to infer the types of names -used in the code, and map those names to Verilog variables. - -Only a limited amount of types can be converted. -Python \class{int} and \class{long} objects are mapped to Verilog -integers. All other supported types are mapped to Verilog regs (or -wires), and therefore need to have a defined bit width. The supported -types are the Python \class{bool} type, the MyHDL \class{intbv} type, -and MyHDL enumeration types returned by function \function{enum}. The -latter objects can also be used as the base object of a -\class{Signal}. - -\class{intbv} objects must be constructed so that a bit -width can be inferred. This can be done by specifying minimum -and maximum values, e.g. as follows: - -\begin{verbatim} -index = intbv(0, min=MIN, max=MAX) -\end{verbatim} - -The Verilog converter supports \class{intbv} objects that -can take negative values. - -Alternatively, a slice can be taken from an \class{intbv} object -as follows: - -\begin{verbatim} -index = intbv(0)[N:] -\end{verbatim} - -Such as slice returns a new \class{intbv} object, with minimum -value \code{0} , and maximum value \code{2**N}. - - -\subsection{Supported statements\label{conv-subset-statements}} - -The following is a list of the statements that are supported by the -Verilog converter, possibly qualified with restrictions -or usage notes. - -\begin{description} - -\item[\keyword{break}] - -\item[\keyword{continue}] - -\item[\keyword{def}] - -\item[\keyword{for}] -The only supported iteration scheme is iterating through sequences of -integers returned by built-in function \function{range} or \myhdl\ -function \function{downrange}. The optional \keyword{else} clause is -not supported. - -\item[\keyword{if}] -\keyword{if}, \keyword{elif}, and \keyword{else} clauses -are fully supported. - -\item[\keyword{pass}] - -\item[\keyword{print}] -When printing an interpolated string, the format specifiers are copied -verbatim to the Verilog output. Printing to a file (with syntax -\code{'>>'}) is not supported. - -\item[\keyword{raise}] -This statement is mapped to Verilog statements -that end the simulation with an error message. - -\item[\keyword{return}] - -\item[\keyword{yield}] -The yielded expression can be a signal, a signal edge -as specified by \myhdl\ functions \function{posedge} -or \function{negedge}, or a tuple of signals and -edge specifications. - -\item[\keyword{while}] -The optional \keyword{else} -clause is not supported. - -\end{description} - -\subsection{Supported built-in functions\label{conv-subset-builtin}} - -The following is a list of the built-in functions that are supported by the -Verilog converter. - -\begin{description} -\item[\function{bool()}] -This function can be used to typecast an object explictly to -its boolean interpretation. - -\item[\function{len()}] -For \class{Signal} and \class{intbv} objects, function \function{len()} -returns the bit width. - -\item[\function{int()}] -This function can be used to typecast an object explictly to -its integer interpretation. - -\end{description} - -\subsection{Excluding code from conversion \label{conv-subset-exclude}} -For some tasks, such as debugging, it may be useful to insert arbitratry -Python code that should not be converted. - -The Verilog convertor supports this by ignoring all code that is -embedded in a \code{if __debug__} test. The value of the -\code{__debug__} variable is not taken into account. - -\section{Methodology notes\label{conv-meth}} - -\subsection{Simulation\label{conv-meth-sim}} - -In the Python philosophy, the run-time rules. The Python compiler -doesn't attempt to detect a lot of errors beyond syntax errors, which -given Python's ultra-dynamic nature would be an almost impossible task -anyway. To verify a Python program, one should run it, preferably -using unit testing to verify each feature. - -The same philosophy should be used when converting a MyHDL description -to Verilog: make sure the simulation runs fine first. Although the -converter checks many things and attempts to issue clear error -messages, there is no guarantee that it does a meaningful job unless -the simulation runs fine. - -\subsection{Conversion output verification\label{conv-meth-conv}} -It is always prudent to verify the converted Verilog output. -To make this task easier, the converter also generates a -test bench that makes it possible to simulate the Verilog -design using the Verilog co-simulation interface. This -permits to verify the Verilog code with the same test -bench used for the \myhdl\ code. This is also how -the Verilog converter development is being verified. - -\subsection{Assignment issues\label{conv-meth-assign}} - -\subsubsection{Name assignment in Python\label{conv-meth-assign-python}} - -Name assignment in Python is a different concept than in -many other languages. This point is very important for -effective modeling in Python, and even more so -for synthesizable \myhdl\ code. Therefore, the issues are -discussed here explicitly. - -Consider the following name assignments: - -\begin{verbatim} -a = 4 -a = ``a string'' -a = False -\end{verbatim} - -In many languages, the meaning would be that an -existing variable \var{a} gets a number of different values. -In Python, such a concept of a variable doesn't exist. Instead, -assignment merely creates a new binding of a name to a -certain object, that replaces any previous binding. -So in the example, the name \var{a} is bound a -number of different objects in sequence. - -The Verilog converter has to investigate name -assignment and usage in \myhdl\ code, and to map -names to Verilog variables. To achieve that, -it tries to infer the type and possibly the -bit width of each expression that is assigned -to a name. - -Multiple assignments to the same name can be supported if it can be -determined that a consistent type and bit width is being used in the -assignments. This can be done for boolean expressions, numeric -expressions, and enumeration type literals. In Verilog, the -corresponding name is mapped to a single bit \code{reg}, an -\code{integer}, or a \code{reg} with the appropriate width, respectively. - -In other cases, a single assignment should be used when an object is -created. Subsequent value changes are then achieved by modification of -an existing object. This technique should be used for \class{Signal} -and \class{intbv} objects. - -\subsubsection{Signal assignment\label{conv-meth-assign-signal}} - -Signal assignment in \myhdl\ is implemented using attribute assignment -to attribute \code{next}. Value changes are thus modeled by -modification of the existing object. The converter investigates the -\class{Signal} object to infer the type and bit width of the -corresponding Verilog variable. - -\subsubsection{\class{intbv} objects\label{conv-meth-assign-intbv}} - -Type \class{intbv} is likely to be the workhorse for synthesizable -modeling in \myhdl{}. An \class{intbv} instance behaves like a -(mutable) integer whose individual bits can be accessed and -modified. Also, it is possible to constrain its set of values. In -addition to error checking, this makes it possible to infer a bit -width, which is required for implementation. - -In Verilog, an \class{intbv} instance will be mapped to a \code{reg} -with an appropriate width. As noted before, it is not possible -to modify its value using name assignment. In the following, we -will show how it can be done instead. Consider: - -\begin{verbatim} -a = intbv(0)[8:] -\end{verbatim} - -This is an \class{intbv} object with initial value \code{0} and -bit width 8. The change its value to \code{5}, we can use -slice assignment: - -\begin{verbatim} -a[8:] = 5 -\end{verbatim} - -The same can be achieved by leaving the bit width unspecified, -which has the meaning to change ``all'' bits: - -\begin{verbatim} -a[:] = 5 -\end{verbatim} - -Often the new value will depend on the old one. For example, -to increment an \class{intbv} with the technique above: - -\begin{verbatim} -a[:] = a + 1 -\end{verbatim} - -Python also provides \emph{augmented} assignment operators, -which can be used to implement in-place operations. These are supported -on \class{intbv} objects and by the converter, so that the increment -can also be done as follows: - -\begin{verbatim} -a += 1 -\end{verbatim} - -\section{Converter usage\label{conv-usage}} - -We will demonstrate the conversion process by showing some examples. - -\subsection{A small sequential design\label{conv-usage-seq}} - -Consider the following MyHDL code for an incrementer module: - -\begin{verbatim} -ACTIVE_LOW, INACTIVE_HIGH = 0, 1 - -def inc(count, enable, clock, reset, n): - - """ Incrementer with enable. - - count -- output - enable -- control input, increment when 1 - clock -- clock input - reset -- asynchronous reset input - n -- counter max value - - """ - - @always(clock.posedge, reset.negedge) - def incProcess(): - if reset == ACTIVE_LOW: - count.next = 0 - else: - if enable: - count.next = (count + 1) % n - - return incProcess -\end{verbatim} - -In Verilog terminology, function \function{inc} corresponds to a -module, while the decorated function \function{incProcess} -roughly corresponds to an always block. - -Normally, to simulate the design, we would "elaborate" an instance -as follows: - -\begin{verbatim} -m = 8 -n = 2 ** m - -count = Signal(intbv(0)[m:]) -enable = Signal(bool(0)) -clock, reset = [Signal(bool()) for i in range(2)] - -inc_inst = inc(count, enable, clock, reset, n=n) -\end{verbatim} - -\code{inc_inst} is an elaborated design instance that can be simulated. To -convert it to Verilog, we change the last line as follows: - -\begin{verbatim} -inc_inst = toVerilog(inc, count, enable, clock, reset, n=n) -\end{verbatim} - -Again, this creates an instance that can be simulated, but as a side -effect, it also generates an equivalent Verilog module in file \file{inc.v}. -The Verilog code looks as follows: - -\begin{verbatim} -module inc_inst ( - count, - enable, - clock, - reset -); - -output [7:0] count; -reg [7:0] count; -input enable; -input clock; -input reset; - - -always @(posedge clock or negedge reset) begin: _MYHDL1_BLOCK - if ((reset == 0)) begin - count <= 0; - end - else begin - if (enable) begin - count <= ((count + 1) % 256); - end - end -end - -endmodule -\end{verbatim} - -You can see the module interface and the always block, as expected -from the MyHDL design. - -\subsection{A small combinatorial design\label{conv-usage-comb}} - -The second example is a small combinatorial design, more -specifically the binary to Gray code converter from previous chapters: - -\begin{verbatim} -def bin2gray(B, G, width): - - """ Gray encoder. - - B -- input intbv signal, binary encoded - G -- output intbv signal, gray encoded - width -- bit width - - """ - - @always_comb - def logic(): - Bext = intbv(0)[width+1:] - Bext[:] = B - for i in range(width): - G.next[i] = Bext[i+1] ^ Bext[i] - - return logic -\end{verbatim} - -As before, you can create an instance and convert to -Verilog as follows: - -\begin{verbatim} -width = 8 - -B = Signal(intbv(0)[width:]) -G = Signal(intbv(0)[width:]) - -bin2gray_inst = toVerilog(bin2gray, B, G, width) - \end{verbatim} - -The generated Verilog code looks as follows: - -\begin{verbatim} -module bin2gray ( - B, - G -); - -input [7:0] B; -output [7:0] G; -reg [7:0] G; - -always @(B) begin: _bin2gray_logic - integer i; - reg [9-1:0] Bext; - Bext = 9'h0; - Bext = B; - for (i=0; i<8; i=i+1) begin - G[i] <= (Bext[(i + 1)] ^ Bext[i]); - end -end - -endmodule -\end{verbatim} - -\subsection{A hierarchical design\label{conv-usage-hier}} -The Verilog converter can handle designs with an -arbitrarily deep hierarchy. - -For example, suppose we want to design an -incrementer with Gray code output. Using the -designs from previous sections, we can proceed -as follows: - -\begin{verbatim} -ACTIVE_LOW, INACTIVE_HIGH = 0, 1 - -def GrayInc(graycnt, enable, clock, reset, width): - - bincnt = Signal(intbv(0)[width:]) - - inc_1 = inc(bincnt, enable, clock, reset, n=2**width) - bin2gray_1 = bin2gray(B=bincnt, G=graycnt, width=width) - - return inc_1, bin2gray_1 -\end{verbatim} - -According to Gray code properties, only a single bit -will change in consecutive values. However, as the -\code{bin2gray} module is combinatorial, the output bits -may have transient glitches, which may not be desirable. -To solve this, let's create an additional level of -hierarchy and add an output register to the design. -(This will create an additional latency of a clock -cycle, which may not be acceptable, but we will -ignore that here.) - -\begin{verbatim} - - -def GrayIncReg(graycnt, enable, clock, reset, width): - - graycnt_comb = Signal(intbv(0)[width:]) - - gray_inc_1 = GrayInc(graycnt_comb, enable, clock, reset, width) - - @always(clock.posedge) - def reg_1(): - graycnt.next = graycnt_comb - - return gray_inc_1, reg_1 -\end{verbatim} - -We can convert this hierarchical design as before: - -\begin{verbatim} -width = 8 -graycnt = Signal(intbv()[width:]) -enable, clock, reset = [Signal(bool()) for i in range(3)] - -gray_inc_reg_1 = toVerilog(GrayIncReg, graycnt, enable, clock, reset, width) -\end{verbatim} - -The Verilog output code looks as follows: - -\begin{verbatim} -module GrayIncReg ( - graycnt, - enable, - clock, - reset -); - -output [7:0] graycnt; -reg [7:0] graycnt; -input enable; -input clock; -input reset; - -reg [7:0] graycnt_comb; -reg [7:0] _gray_inc_1_bincnt; - - -always @(posedge clock or negedge reset) begin: _GrayIncReg_gray_inc_1_inc_1_incProcess - if ((reset == 0)) begin - _gray_inc_1_bincnt <= 0; - end - else begin - if (enable) begin - _gray_inc_1_bincnt <= ((_gray_inc_1_bincnt + 1) % 256); - end - end -end - -always @(_gray_inc_1_bincnt) begin: _GrayIncReg_gray_inc_1_bin2gray_1_logic - integer i; - reg [9-1:0] Bext; - Bext = 9'h0; - Bext = _gray_inc_1_bincnt; - for (i=0; i<8; i=i+1) begin - graycnt_comb[i] <= (Bext[(i + 1)] ^ Bext[i]); - end -end - -always @(posedge clock) begin: _GrayIncReg_reg_1 - graycnt <= graycnt_comb; -end - -endmodule -\end{verbatim} - -Note that the output is a flat ``net list of blocks'', and -that hierarchical signal names are generated as necessary. - -\subsection{Optimizations for finite state machines\label{conv-usage-fsm}} -As often in hardware design, finite state machines deserve special attention. - -In Verilog and VHDL, finite state machines are typically described -using case statements. Python doesn't have a case statement, but the -converter recognizes particular if-then-else structures and maps them -to case statements. This optimization occurs when a variable whose -type is an enumerated type is sequentially tested against enumeration -items in an if-then-else structure. Also, the appropriate synthesis -pragmas for efficient synthesis are generated in the Verilog code. - -As a further optimization, function \function{enum} was enhanced to support -alternative encoding schemes elegantly, using an additional parameter -\var{encoding}. For example: - -\begin{verbatim} -t_State = enum('SEARCH', 'CONFIRM', 'SYNC', encoding='one_hot') -\end{verbatim} - -The default encoding is \code{'binary'}; the other possibilities are -\code{'one_hot'} and \code{'one_cold'}. This parameter only affects -the conversion output, not the behavior of the type. The generated -Verilog code for case statements is optimized for an efficient -implementation according to the encoding. Note that in contrast, a -Verilog designer has to make nontrivial code changes to implement a -different encoding scheme. - -As an example, consider the following finite state machine, whose -state variable uses the enumeration type defined above: - -\begin{verbatim} -ACTIVE_LOW = 0 -FRAME_SIZE = 8 - -def FramerCtrl(SOF, state, syncFlag, clk, reset_n, t_State): - - """ Framing control FSM. - - SOF -- start-of-frame output bit - state -- FramerState output - syncFlag -- sync pattern found indication input - clk -- clock input - reset_n -- active low reset - - """ - - index = Signal(intbv(0)[8:]) # position in frame - - @always(clk.posedge, reset_n.negedge) - def FSM(): - if reset_n == ACTIVE_LOW: - SOF.next = 0 - index.next = 0 - state.next = t_State.SEARCH - else: - index.next = (index + 1) % FRAME_SIZE - SOF.next = 0 - if state == t_State.SEARCH: - index.next = 1 - if syncFlag: - state.next = t_State.CONFIRM - elif state == t_State.CONFIRM: - if index == 0: - if syncFlag: - state.next = t_State.SYNC - else: - state.next = t_State.SEARCH - elif state == t_State.SYNC: - if index == 0: - if not syncFlag: - state.next = t_State.SEARCH - SOF.next = (index == FRAME_SIZE-1) - else: - raise ValueError("Undefined state") - - return FSM -\end{verbatim} - -The conversion is done as before: - -\begin{verbatim} -SOF = Signal(bool(0)) -syncFlag = Signal(bool(0)) -clk = Signal(bool(0)) -reset_n = Signal(bool(1)) -state = Signal(t_State.SEARCH) -framerctrl_inst = toVerilog(FramerCtrl, SOF, state, syncFlag, clk, reset_n) -\end{verbatim} - -The Verilog output looks as follows: - -\begin{verbatim} -module FramerCtrl ( - SOF, - state, - syncFlag, - clk, - reset_n -); - -output SOF; -reg SOF; -output [2:0] state; -reg [2:0] state; -input syncFlag; -input clk; -input reset_n; - -reg [7:0] index; - - -always @(posedge clk or negedge reset_n) begin: _FramerCtrl_FSM - if ((reset_n == 0)) begin - SOF <= 0; - index <= 0; - state <= 3'b001; - end - else begin - index <= ((index + 1) % 8); - SOF <= 0; - // synthesis parallel_case full_case - casez (state) - 3'b??1: begin - index <= 1; - if (syncFlag) begin - state <= 3'b010; - end - end - 3'b?1?: begin - if ((index == 0)) begin - if (syncFlag) begin - state <= 3'b100; - end - else begin - state <= 3'b001; - end - end - end - 3'b1??: begin - if ((index == 0)) begin - if ((!syncFlag)) begin - state <= 3'b001; - end - end - SOF <= (index == (8 - 1)); - end - default: begin - $display("ValueError(Undefined state)"); - $finish; - end - endcase - end -end - -endmodule -\end{verbatim} - -\subsection{RAM inference \label{conf-usage-RAM}} - -Certain synthesis tools can map Verilog memories to RAM -structures. To support this interesting feature, the Verilog converter -maps lists of signals in MyHDL to Verilog memories. - -The following MyHDL example is a ram model that uses a list of signals -to model the internal memory. - -\begin{verbatim} -def RAM(dout, din, addr, we, clk, depth=128): - """ Ram model """ - - mem = [Signal(intbv(0)[8:]) for i in range(depth)] - - @always(clk.posedge) - def write(): - if we: - mem[int(addr)].next = din - - @always_comb - def read(): - dout.next = mem[int(addr)] - - return write, read -\end{verbatim} - -With the appropriate signal definitions for the interface ports, it is -converted to the following Verilog code. Note how the -list of signals \code{mem} is mapped to a Verilog memory. - -\begin{verbatim} -module RAM ( - dout, - din, - addr, - we, - clk -); - -output [7:0] dout; -wire [7:0] dout; -input [7:0] din; -input [6:0] addr; -input we; -input clk; - -reg [7:0] mem [0:128-1]; - -always @(posedge clk) begin: _RAM_write - if (we) begin - mem[addr] <= din; - end -end - -assign dout = mem[addr]; - -endmodule -\end{verbatim} - - -\subsection{ROM inference \label{conf-usage-ROM}} -Some synthesis tools can infer a ROM memory from a case statement. The -Verilog converter can perform the expansion into a case statement -automatically, based on a higher level description. The ROM access is -described in a single line, by indexing into a tuple of integers. The -tuple can be described manually, but also by programmatical -means. Note that a tuple is used instead of a list to stress the -read-only character of the memory. - -The following example illustrates this functionality. ROM access -is described as follows: - -\begin{verbatim} -def rom(dout, addr, CONTENT): - - @always_comb - def read(): - dout.next = CONTENT[int(addr)] - - return read -\end{verbatim} - -The ROM content is described as a tuple of integers. When the -ROM content is defined, the conversion can be performed: - -\begin{verbatim} -CONTENT = (17, 134, 52, 9) -dout = Signal(intbv(0)[8:]) -addr = Signal(intbv(0)[4:]) - -toVerilog(rom, dout, addr, CONTENT) -\end{verbatim} - -The Verilog output code is as follows: - -\begin{verbatim} -module rom ( - dout, - addr -); - -output [7:0] dout; -reg [7:0] dout; -input [3:0] addr; - -always @(addr) begin: _rom_read - // synthesis parallel_case full_case - case (addr) - 0: dout <= 17; - 1: dout <= 134; - 2: dout <= 52; - default: dout <= 9; - endcase -end - -endmodule -\end{verbatim} - -\subsection{User-defined Verilog code \label{conf-usage-custom}} - -MyHDL provides a way to include user-defined Verilog -code during the conversion process. - -MyHDL defines a hook that is understood by the converter but ignored by -the simulator. The hook is called \code{__verilog__}. It operates -like a special return value. When a MyHDL function defines -\code{__verilog__}, the Verilog converter will use its value instead of the -regular return value. - -The value of \code{__verilog__} should be a format string that uses keys in -its format specifiers. The keys refer to the variable names in the -context of the string. - -Example: - -\begin{verbatim} -def inc_comb(nextCount, count, n): - - @always_comb - def logic(): - # note: '-' instead of '+' - nextCount.next = (count - 1) % n - - nextCount.driven = "wire" - - __verilog__ =\ -""" -assign %(nextCount)s = (%(count)s + 1) %% %(n)s; -""" - - return logic -\end{verbatim} - -The converted code looks as follows: - -\begin{verbatim} -module inc_comb ( - nextCount, - count -); - -output [7:0] nextCount; -wire [7:0] nextCount; -input [7:0] count; - -assign nextCount = (count + 1) % 128; - -endmodule -\end{verbatim} - -In this example, conversion of the \function{inc_comb} function is bypassed and -the user-defined Verilog code is inserted instead. Note that the -user-defined code refers to signals and parameters in the MyHDL -context by using format specifiers. During conversion, the appropriate -hierarchical names and parameter values will be filled in. Note also -that the format specifier indicator \% needs to be escaped (by doubling -it) if it is required in the user-defined code. - -There is one more issue that needs user attention. Normally, the -Verilog converter infers inputs, internal signals, and outputs. It -also detects undriven and multiple driven signals. To do this, it -assumes that signals are not driven by default. It then processes the -code to find out which signals are driven from where. However, it -cannot do this for user-defined code. Without additional help, this -will result in warnings or errors during the inference process, or in -compilation errors from invalid Verilog code. The user should solve -this by setting the \code{driven} attribute for signals that are driven from -the user-defined code. In the example code above, note the following -assignment: - -\begin{verbatim} -nextCount.driven = "wire" -\end{verbatim} - -This specifies that the nextCount signal is driven as a Verilog wire -from this module. The allowed values of the driven attribute are -\code{'wire'} and \code{'reg'}. The value specifies how the -user-defined Verilog code drives the signal in Verilog. To decide -which value to use, consider how the signal should be declared in -Verilog after the user-defined code is inserted. - - -\section{Known issues\label{conv-issues}} -\begin{description} -\item[Verilog integers are 32 bit wide] -Usually, Verilog integers are 32 bit wide. In contrast, Python is -moving toward integers with undefined width. Python \class{int} -and \class{long} variables are mapped to Verilog integers; so for values -wider than 32 bit this mapping is incorrect. - -\item[Synthesis pragmas are specified as Verilog comments.] The recommended -way to specify synthesis pragmas in Verilog is through attribute -lists. However, the Icarus simulator doesn't support them -for \code{case} statements (to specify \code{parallel_case} and -\code{full_case} pragmas). Therefore, the old -but deprecated method of synthesis pragmas in Verilog comments -is still used. - -\item[Inconsistent place of the sensitivity list inferred from \code{always_comb}.] -The semantics of \code{always_comb}, both in Verilog and \myhdl{}, is to -have an implicit sensitivity list at the end of the code. However, this -may not be synthesizable. Therefore, the inferred sensitivity list is -put at the top of the corresponding \code{always} block. -This may cause inconsistent behavior at the start of the -simulation. The workaround is to create events at time 0. - -\item[Non-blocking assignments to task arguments don't work.] -Non-blocking (signal) assignments to task arguments don't work -for an as yet unknown reason. -\end{description} diff --git a/olddoc/manual/cosimulation.tex b/olddoc/manual/cosimulation.tex deleted file mode 100644 index f6babae0..00000000 --- a/olddoc/manual/cosimulation.tex +++ /dev/null @@ -1,416 +0,0 @@ -\chapter{Co-simulation with Verilog and VHDL \label{cosim}} - -\section{Introduction \label{cosim-intro}} - -One of the most exciting possibilities of \myhdl\ -is to use it as a hardware verification language (HVL). -A HVL is a language used to write test benches and -verification environments, and to control simulations. - -Nowadays, it is generally acknowledged that HVLs should be equipped -with modern software techniques, such as object orientation. The -reason is that verification it the most complex and time-consuming -task of the design process. Consequently, every useful technique is -welcome. Moreover, test benches are not required to be -implementable. Therefore, unlike with synthesizable code, there -are no constraints on creativity. - -Technically, verification of a design implemented in -another language requires co-simulation. \myhdl\ is -enabled for co-simulation with any HDL simulator that -has a procedural language interface (PLI). The \myhdl\ -side is designed to be independent of a particular -simulator, On the other hand, for each HDL simulator a specific -PLI module will have to be written in C. Currently, -the \myhdl\ release contains a PLI module for -two Verilog simulators: Icarus and Cver. - -\section{The HDL side \label{cosim-hdl}} - -To introduce co-simulation, we will continue to use the Gray encoder -example from the previous chapters. Suppose that we want to -synthesize it and write it in Verilog for that purpose. Clearly we would -like to reuse our unit test verification environment. - -To start, let's recall how the Gray encoder in \myhdl{} looks like: - -\begin{verbatim} -def bin2gray(B, G, width): - """ Gray encoder. - - B -- input intbv signal, binary encoded - G -- output intbv signal, gray encoded - width -- bit width - """ - - @always_comb - def logic(): - for i in range(width): - G.next[i] = B[i+1] ^ B[i] - - return logic -\end{verbatim} - -To show the co-simulation flow, we don't need the Verilog -implementation yet, but only the interface. Our Gray encoder in -Verilog would have the following interface: - -\begin{verbatim} -module bin2gray(B, G); - - parameter width = 8; - input [width-1:0] B; - output [width-1:0] G; - .... -\end{verbatim} - -To write a test bench, one creates a new module that instantiates the -design under test (DUT). The test bench declares nets and -regs (or signals in VHDL) that are attached to the DUT, and to -stimulus generators and response checkers. In an all-HDL flow, the -generators and checkers are written in the HDL itself, but we will -want to write them in \myhdl{}. To make the connection, we need to -declare which regs \& nets are driven and read by the \myhdl\ -simulator. For our example, this is done as follows: - -\begin{verbatim} -module dut_bin2gray; - - reg [`width-1:0] B; - wire [`width-1:0] G; - - initial begin - $from_myhdl(B); - $to_myhdl(G); - end - - bin2gray dut (.B(B), .G(G)); - defparam dut.width = `width; - -endmodule -\end{verbatim} - -The \code{\$from_myhdl} task call declares which regs are driven by -\myhdl{}, and the \code{\$to_myhdl} task call which regs \& nets are read -by it. These tasks take an arbitrary number of arguments. They are -defined in a PLI module written in C and made available in a -simulator-dependent manner. In Icarus Verilog, the tasks are defined -in a \code{myhdl.vpi} module that is compiled from C source code. - -\section{The \myhdl\ side \label{cosim-myhdl}} - -\myhdl\ supports co-simulation by a \code{Cosimulation} object. -A \code{Cosimulation} object must know how to run a HDL simulation. -Therefore, the first argument to its constructor is a command string -to execute a simulation. - -The way to generate and run an simulation executable is simulator -dependent. For example, in Icarus Verilog, a simulation executable -for our example can be obtained obtained by running the -\code{iverilog} compiler as follows: - -\begin{verbatim} -% iverilog -o bin2gray -Dwidth=4 bin2gray.v dut_bin2gray.v -\end{verbatim} - -This generates a \code{bin2gray} executable for a parameter \code{width} -of 4, by compiling the contributing verilog files. - -The simulation itself is run by the \code{vvp} command: - -\begin{verbatim} -% vvp -m ./myhdl.vpi bin2gray -\end{verbatim} - -This runs the \code{bin2gray} simulation, and specifies to use the -\code{myhdl.vpi} PLI module present in the current directory. (This is -just a command line usage example; actually simulating with the -\code{myhdl.vpi} module is only meaningful from a -\code{Cosimulation} object.) - -We can use a \code{Cosimulation} object to provide a HDL -version of a design to the \myhdl\ simulator. Instead of a generator -function, we write a function that returns a \code{Cosimulation} -object. For our example and the Icarus Verilog simulator, this is done -as follows: - -\begin{verbatim} -import os - -from myhdl import Cosimulation - -cmd = "iverilog -o bin2gray -Dwidth=%s bin2gray.v dut_bin2gray.v" - -def bin2gray(B, G, width): - os.system(cmd % width) - return Cosimulation("vvp -m ./myhdl.vpi bin2gray", B=B, G=G) -\end{verbatim} - -After the executable command argument, the \code{Cosimulation} -constructor takes an arbitrary number of keyword arguments. Those -arguments make the link between \myhdl\ Signals and HDL nets, regs, or -signals, by named association. The keyword is the name of an argument -in a \code{\$to_myhdl} or \code{\$from_myhdl} call; the argument is -a \myhdl\ Signal. - -With all this in place, we can now use the existing unit test -to verify the Verilog implementation. Note that we kept the -same name and parameters for the the \code{bin2gray} function: -all we need to do is to provide this alternative definition -to the existing unit test. - -Let's try it on the Verilog design: - -\begin{verbatim} -module bin2gray(B, G); - - parameter width = 8; - input [width-1:0] B; - output [width-1:0] G; - reg [width-1:0] G; - integer i; - wire [width:0] extB; - - assign extB = {1'b0, B}; // zero-extend input - - always @(extB) begin - for (i=0; i < width; i=i+1) - G[i] <= extB[i+1] ^ extB[i]; - end - -endmodule -\end{verbatim} - -When we run our unit test, we get: - -\begin{verbatim} -% python test_bin2gray.py -Check that only one bit changes in successive codewords ... ok -Check that all codewords occur exactly once ... ok -Check that the code is an original Gray code ... ok - ----------------------------------------------------------------------- -Ran 3 tests in 2.729s - -OK -\end{verbatim} - - -\section{Restrictions \label{cosim-restr}} - -In the ideal case, it should be possible to simulate -any HDL description seamlessly with \myhdl{}. Moreover -the communicating signals at each side should act -transparently as a single one, enabling fully race free -operation. - -For various reasons, it may not be possible or desirable -to achieve full generality. As anyone that has developed -applications with the Verilog PLI can testify, the -restrictions in a particular simulator, and the -differences over various simulators, can be quite -frustrating. Moreover, full generality may require -a disproportionate amount of development work compared -to a slightly less general solution that may -be sufficient for the target application. - -Consequently, I have tried to achieve a solution -which is simple enough so that one can reasonably -expect that any PLI-enabled simulator can support it, -and that is relatively easy to verify and maintain. -At the same time, the solution is sufficiently general -to cover the target application space. - -The result is a compromise that places certain restrictions -on the HDL code. In this section, these restrictions -are presented. - -\subsection{Only passive HDL can be co-simulated \label{cosim-pass}} - -The most important restriction of the \myhdl\ co-simulation solution is -that only ``passive'' HDL can be co-simulated. This means that the HDL -code should not contain any statements with time delays. In other -words, the \myhdl\ simulator should be the master of time; in -particular, any clock signal should be generated at the \myhdl\ side. - -At first this may seem like an important restriction, but if one -considers the target application for co-simulation, it probably -isn't. - -\myhdl\ supports co-simulation so that test benches for HDL -designs can be written in Python. Let's consider the nature of the -target HDL designs. For high-level, behavioral models that are not -intended for implementation, it should come as no surprise that I -would recommend to write them in \myhdl\ directly; that is one of the -goals of the \myhdl\ effort. Likewise, gate level designs with -annotated timing are not the target application: static timing -analysis is a much better verification method for such designs. - -Rather, the targeted HDL designs are naturally models that are -intended for implementation, most likely through synthesis. As time -delays are meaningless in synthesizable code, the restriction is -compatible with the target application. - -\subsection{Race sensitivity issues \label{cosim-race}} - -In a typical RTL code, some events cause other events to occur in the -same time step. For example, when a clock signal triggers some signals -may change in the same time step. For race-free operation, an HDL -must differentiate between such events within a time step. This is done -by the concept of ``delta'' cycles. In a fully general, race free -co-simulation, the co-simulators would communicate at the level of delta -cycles. However, in \myhdl\ co-simulation, this is not entirely the -case. - -Delta cycles from the \myhdl\ simulator toward the HDL co-simulator are -preserved. However, in the opposite direction, they are not. The -signals changes are only returned to the \myhdl\ simulator after all delta -cycles have been performed in the HDL co-simulator. - -What does this mean? Let's start with the good news. As explained in -the previous section, the concept behind \myhdl\ co-simulation implies -that clocks are generated at the \myhdl\ side. \emph{When using a -\myhdl\ clock and its corresponding HDL signal directly as a clock, -co-simulation is race free.} In other words, the case -that most closely reflects the \myhdl\ co-simulation approach, is race free. - -The situation is different when you want to use a signal driven by the -HDL (and the corresponding MyHDL signal) as a clock. -Communication triggered by such a clock is not race free. The solution -is to treat such an interface as a chip interface instead of an RTL -interface. For example, when data is triggered at positive clock -edges, it can safely be sampled at negative clock edges. -Alternatively, the \myhdl\ data signals can be declared with a delay -value, so that they are guaranteed to change after the clock -edge. - - -\section{Implementation notes \label{cosim-impl}} - -\begin{quote} -\em -This section requires some knowledge of PLI terminology. -\end{quote} - -Enabling a simulator for co-simulation requires a PLI module written -in C. In Verilog, the PLI is part of the ``standard''. However, -different simulators implement different versions and portions of the -standard. Worse yet, the behavior of certain PLI callbacks is not -defined on some essential points. As a result, one should plan to -write or at least customize a specific PLI module for any simulator. -The release contains a PLI module for the open source Icarus -and Cver simulators. - -This section documents the current approach and status of the PLI -module implementation and some reflections on future -implementations. - -\subsection{Icarus Verilog \label{cosim-icarus}} - -\subsubsection{Delta cycle implementation \label{cosim-icarus-delta}} - -To make co-simulation work, a specific type of PLI callback is -needed. The callback should be run when all pending events have been -processed, while allowing the creation of new events in the current -time step (e.g. by the \myhdl\ simulator). In some Verilog -simulators, the \code{cbReadWriteSync} callback does exactly -that. However, in others, including Icarus, it does not. The -callback's behavior is not fully standardized; some simulators run the -callback before non-blocking assignment events have been processed. - -Consequently, I had to look for a workaround. One half of the solution -is to use the \code{cbReadOnlySync} callback. This callback runs -after all pending events have been processed. However, it does not -permit to create new events in the current time step. The second half -of the solution is to map \myhdl\ delta cycles onto real Verilog time -steps. Note that fortunately I had some freedom here because of the -restriction that only passive HDL code can be co-simulated. - -I chose to make the time granularity in the Verilog simulator a 1000 -times finer than in the \myhdl{} simulator. For each \myhdl\ time -step, 1000 Verilog time steps are available for \myhdl\ delta -cycles. In practice, only a few delta cycles per time step should be -needed. Exceeding this limit almost certainly indicates a design error; -the limit is checked at run-time. The factor 1000 also makes it -easy to distinguish ``real'' time from delta cycle time when printing -out the Verilog time. - -\subsubsection{Passive Verilog check \label{cosim-icarus-pass}} - -As explained before, co-simulated Verilog should not contain delay -statements. Ideally, there should be a run-time check to flag -non-compliant code. However, there is currently no such check in the -Icarus module. - -The check can be written using the \code{cbNextSimTime} VPI callback -in Verilog. However, Icarus 0.7 doesn't support this callback. In the -meantime, support for it has been added to the Icarus development -branch. When Icarus 0.8 is released, a check will be added. - -In the mean time, just don't do this. It may appear to ``work'' but it -really won't as events will be missed over the co-simulation -interface. - - -\subsection{Cver \label{cosim-cver}} - -MyHDL co-simulation is supported with the open source Verilog -simulator Cver. The PLI module is based on the one for Icarus -and basically has the same functionality. Only some cosmetic -modifications were required. - -\subsection{Other Verilog simulators \label{cosim-impl-verilog}} - -The Icarus module is written with VPI calls, which are provided by the -most recent generation of the Verilog PLI. Some simulators may only -support TF/ACC calls, requiring a complete redesign of the interface -module. - -If the simulator supports VPI, the Icarus module should be reusable to -a large extent. However, it may be possible to improve on it. The -workaround to support delta cycles described in -Section~\ref{cosim-icarus-delta} may not be necessary. In some -simulators, the \code{cbReadWriteSync} callback occurs after all -events (including non-blocking assignments) have been processed. In -that case, the functionality can be supported without a finer time -granularity in the Verilog simulator. - -There are also Verilog standardization efforts underway to resolve the -ambiguity of the \code{cbReadWriteSync} callback. The solution will be -to introduce new, well defined callbacks. From reading some proposals, -I conclude that the \code{cbEndOfSimTime} callback would provide the -required functionality. - -The MyHDL project currently has no access to commercial Verilog -simulators, so progress in co-simulation support depends on external -interest and participation. Users have reported that they are using -MyHDL co-simulation with the simulators from Aldec and Modelsim. - - -\subsection{Interrupted system calls \label{cosim-impl-syscalls}} - -The PLI module uses \code{read} and \code{write} system calls to -communicate between the co-simulators. The implementation assumes that -these calls are restarted automatically by the operating system when -interrupted. This is apparently what happens on the Linux box on which -MyHDL is developed. - -It is known how non-restarted interrupted system calls should be -handled, but currently such code cannot be tested on the MyHDL -development platform. Also, it is not clear whether this is still a -relevant issue with modern operating systems. Therefore, this issue -has not been addressed at this moment. However, assertions have been -included that should trigger when this situation occurs. - -Whenever an assertion fires in the PLI module, please report it. The -same holds for Python exceptions that cannot be easily explained. - -\subsection{VHDL \label{cosim-impl-vhdl}} - -It would be nice to have an interface to VHDL simulators such as the -Modelsim VHDL simulator. This will require a PLI module using the -PLI of the VHDL simulator. - -The MyHDL project currently has no access to commercial VHDL -simulators, so progress in co-simulation support will depend on -external interest and participation. diff --git a/olddoc/manual/intro.tex b/olddoc/manual/intro.tex deleted file mode 100644 index 857c58c1..00000000 --- a/olddoc/manual/intro.tex +++ /dev/null @@ -1,555 +0,0 @@ -\chapter{Introduction to \myhdl\ \label{intro}} - -\section{A basic \myhdl\ simulation \label{intro-basic}} - -We will introduce \myhdl\ with a classic \code{Hello World} style -example. All example code can be found in the distribution directory -under \file{example/manual/}. Here are the contents of a \myhdl\ -simulation script called \file{hello1.py}: - -\begin{verbatim} -from myhdl import Signal, delay, always, now, Simulation - -def HelloWorld(): - - interval = delay(10) - - @always(interval) - def sayHello(): - print "%s Hello World!" % now() - - return sayHello - - -inst = HelloWorld() -sim = Simulation(inst) -sim.run(30) -\end{verbatim} - -When we run this simulation, we get the following output: - -\begin{verbatim} -% python hello1.py -10 Hello World! -20 Hello World! -30 Hello World! -_SuspendSimulation: Simulated 30 timesteps -\end{verbatim} - -The first line of the script imports a number of objects from the -\code{myhdl} package. In Python we can only use identifiers that are -literally defined in the source file -\footnote{The exception is the \samp{from module import *} syntax, -that imports all the symbols from a module. Although this is generally -considered bad practice, it can be tolerated for large modules that -export a lot of symbols. One may argue that -\code{myhdl} falls into that category.}. - -Then, we define a function called \function{HelloWorld}. In MyHDL, -classic functions are used to model hardware modules. In particular, -the parameter list is used to define the interface. In this first -example, the interface is empty. - -Inside the top level function we declare a local function called -\function{sayHello} that defines the desired behavior. This function -is decorated with an \function{always} decorator that has a delay - \index{decorator!\function{always}} -object as its parameter. The meaning is that the function will be -executed whenever the specified delay interval has expired. - -Behind the curtains, the \function{always} decorator creates a Python -\emph{generator} and reuses the name of the decorated function for -it. Generators are the fundamental objects in MyHDL, and we will say -much more about them further on. - -Finally, the top level function returns the local generator. This is -the simplest case of the basic MyHDL code pattern -to define the contents of a hardware module. We will describe the -general case further on. - -In MyHDL, we create an \emph{instance} of a hardware module by calling -the corresponding function. In the example, variable \code{inst} refers -to an instance of \function{HelloWorld}. To simulate the instance, we -pass it as an argument to a \class{Simulation} object constructor. We -then run the simulation for the desired amount of timesteps. - -\section{Signals, ports, and concurrency \label{intro-conc}} - -In the previous section, we simulated a design with a single -generator and no concurrency. On the other hand, real hardware -descriptions are typically massively concurrent. -\myhdl\ supports this by allowing an -arbitrary number of concurrently running generators. - -With concurrency comes the problem of deterministic -communication. Hardware languages use special objects to -support deterministic communication between concurrent code. -In particular, \myhdl\ -has a \class{Signal} object which is roughly modeled after VHDL -signals. - -We will demonstrate signals and concurrency -by extending and modifying our first example. We define two hardware -modules, one that drives a clock signal, and one that is sensitive -to a positive edge on a clock signal: - - -\begin{verbatim} -from myhdl import Signal, delay, always, now, Simulation - - -def ClkDriver(clk): - - halfPeriod = delay(10) - - @always(halfPeriod) - def driveClk(): - clk.next = not clk - - return driveClk - - -def HelloWorld(clk): - - @always(clk.posedge) - def sayHello(): - print "%s Hello World!" % now() - - return sayHello - - -clk = Signal(0) -clkdriver_inst = ClkDriver(clk) -hello_inst = HelloWorld(clk) -sim = Simulation(clkdriver_inst, hello_inst) -sim.run(50) -\end{verbatim} - -The clock driver function \function{ClkDriver} has a -clock signal as its parameter. This is how a -\emph{port} is modeled in MyHDL. The function -defines a generator -that continuously toggles a clock signal after a certain delay. -A new value of a signal is specified by assigning to its -\code{next} attribute. This is the \myhdl\ equivalent of - \index{VHDL!signal assignment}% -the VHDL signal assignment and the - \index{Verilog!non-blocking assignment}% -Verilog non-blocking assignment. - -The \function{HelloWorld} function is modified from the -first example. It now also takes a clock signal as parameter. -Its generator is made sensitive to a rising - \index{wait!for a rising edge}% -edge of the clock signal. This is specified by the -\code{posedge} attribute of a signal. The edge -specifier is the argument of the \code{always} -decorator. As a result, the decorated function -will be executed on every rising clock edge. - -The \code{clk} signal is constructed with an initial value -\code{0}. When creating an instance of each -hardware module, the same clock signal is passed as -the argument. The result is that the instances -are now connected through the clock signal. -The \class{Simulation} object is constructed with the -two instances. - -When we run the simulation, we get: - -\begin{verbatim} -% python hello2.py -10 Hello World! -30 Hello World! -50 Hello World! -_SuspendSimulation: Simulated 50 timesteps -\end{verbatim} - - -\section{Parameters and hierarchy \label{intro-hier}} - -We have seen that MyHDL uses functions to model hardware -modules. We have also seen that ports are modeled by using -signals as parameters. To make designs reusable we will also -want to use other objects as parameters. For example, we can -change the clock generator function to make it more general -and reusable, by making the clock period parameterizable, as -follows: - -\begin{verbatim} -from myhdl import Signal, delay, instance, always, now, Simulation - -def ClkDriver(clk, period=20): - - lowTime = int(period/2) - highTime = period - lowTime - - @instance - def driveClk(): - while True: - yield delay(lowTime) - clk.next = 1 - yield delay(highTime) - clk.next = 0 - - return driveClk -\end{verbatim} - -In addition to the clock signal, the clock -period is a parameter, with a default value of \code{20}. - -As the low time of the clock may differ from the high time in case of -an odd period, we cannot use the \function{always} decorator with a -single delay value anymore. Instead, the \function{driveClk} function -is now a generator function with an explicit definition of the desired -behavior. It is decorated with the \function{instance} decorator. - \index{decorator!\function{instance}} -You can see that \function{driveClk} is a generator function -because it contains \code{yield} statements. - -When a generator function is called, it returns a generator object. -This is basically what the \function{instance} decorator does. It -is less sophisticated than the \function{always} decorator, -but it can be used to create a generator from any local generator -function. - -The \code{yield} statement is a general Python construct, but MyHDL -uses it in a dedicated way. In MyHDL, it has a similar meaning as the -wait statement in VHDL: the statement suspends execution of a -generator, and its clauses specify the conditions on which the -generator should wait before resuming. In this case, the generator -waits for a certain delay. - -Note that to make sure that the generator runs ``forever'', we wrap its -behavior in a \code{while True} loop. - -Similarly, we can define a general \function{Hello} function as follows: - -\begin{verbatim} -def Hello(clk, to="World!"): - - @always(clk.posedge) - def sayHello(): - print "%s Hello %s" % (now(), to) - - return sayHello -\end{verbatim} - - -We can create any number of instances by calling the functions with -the appropriate parameters. Hierarchy can be modeled by defining the -instances in a higher-level function, and returning them. -This pattern can be repeated for an arbitrary number of -hierarchical levels. Consequently, the general definition -of a \myhdl\ instance is recursive: an instance - \index{instance!defined}% -is either a sequence of instances, or a generator. - -As an example, we will create a higher-level function with -four instances of the lower-level functions, and simulate it: - -\begin{verbatim} -def greetings(): - - clk1 = Signal(0) - clk2 = Signal(0) - - clkdriver_1 = ClkDriver(clk1) # positional and default association - clkdriver_2 = ClkDriver(clk=clk2, period=19) # named association - hello_1 = Hello(clk=clk1) # named and default association - hello_2 = Hello(to="MyHDL", clk=clk2) # named association - - return clkdriver_1, clkdriver_2, hello_1, hello_2 - - -inst = greetings() -sim = Simulation(inst) -sim.run(50) -\end{verbatim} - -As in standard Python, positional or named parameter association can -be used in instantiations, or a mix of both\footnote{All positional -parameters have to go before any named parameter.}. All these styles -are demonstrated in the example above. Named association can be very -useful if there are a lot of parameters, as the argument order in the -call does not matter in that case. - -The simulation produces the following output: - -\begin{verbatim} -% python greetings.py -9 Hello MyHDL -10 Hello World! -28 Hello MyHDL -30 Hello World! -47 Hello MyHDL -50 Hello World! -_SuspendSimulation: Simulated 50 timesteps -\end{verbatim} - - -\begin{notice}[warning] -Some commonly used terminology has different meanings -in Python versus hardware design. Rather than artificially -changing terminology, I think it's best to keep it -and explicitly describing the differences. - -A \dfn{module} in Python refers to all source code -in a particular file. A module can be reused by -other modules by importing. In hardware design, -\index{module!in Python versus hardware design}% -a module is a reusable block of hardware with -a well defined interface. It can be reused in -another module by \dfn{instantiating} it. - -An \dfn{instance} in Python (and other object-oriented -languages) refers to the object created by a -\index{instance!in Python versus hardware design}% -class constructor. In hardware design, an instance -is a particular incarnation of a hardware module. - -Normally, the meaning should be clear from -the context. Occasionally, I may qualify terms -with the words 'hardware' or '\myhdl{}' to -avoid ambiguity. -\end{notice} - - -\section{Bit oriented operations \label{intro-bit}} - -Hardware design involves dealing with bits and bit-oriented -operations. The standard Python type \class{int} has most of the -desired features, but lacks support for indexing and slicing. For this -reason, \myhdl\ provides the \class{intbv} class. The name was chosen -to suggest an integer with bit vector flavor. - -Class \class{intbv} works transparently with other -integer-like types. Like class \class{int}, it provides access to the -underlying two's complement representation for bitwise -operations. In addition, it is a mutable type that provides indexing -and slicing operations, and some additional bit-oriented support such -as concatenation. - -\subsection{Bit indexing \label{intro-indexing}} -\index{bit indexing} - -As an example, we will consider the design of a Gray encoder. The -following code is a Gray encoder modeled in \myhdl{}: - -\begin{verbatim} -from myhdl import Signal, delay, Simulation, always_comb, instance, intbv, bin - -def bin2gray(B, G, width): - """ Gray encoder. - - B -- input intbv signal, binary encoded - G -- output intbv signal, gray encoded - width -- bit width - """ - - @always_comb - def logic(): - for i in range(width): - G.next[i] = B[i+1] ^ B[i] - - return logic -\end{verbatim} - -This code introduces a few new concepts. The string in triple quotes -at the start of the function is a \dfn{doc string}. This is standard -Python practice for structured documentation of code. - -Furthermore, we introduce a third decorator: \function{always_comb}. - \index{decorator!\function{always_comb}} -It is used with a classic function and specifies that the -resulting generator should - \index{wait!for a signal value change}% -wait for a value change on any input signal. This is typically used to -describe - \index{combinatorial logic}% -combinatorial logic. The \function{always_comb} decorator -automatically infers which signals are used as inputs. - -Finally, the code contains bit indexing operations and an exclusive-or -operator as required for a Gray encoder. By convention, the lsb of an -\class{intbv} object has index~\code{0}. - -To verify the Gray encoder, we write a test bench that prints input -and output for all possible input values: - -\begin{verbatim} -def testBench(width): - - B = Signal(intbv(0)) - G = Signal(intbv(0)) - - dut = bin2gray(B, G, width) - - @instance - def stimulus(): - for i in range(2**width): - B.next = intbv(i) - yield delay(10) - print "B: " + bin(B, width) + "| G: " + bin(G, width) - - return dut, stimulus -\end{verbatim} - -We use the conversion function \code{bin} to get a binary -string representation of the signal values. This function is exported -by the \code{myhdl} package and supplements the standard Python -\code{hex} and \code{oct} conversion functions. - -As a demonstration, we set up a simulation for a small width: - -\begin{verbatim} -sim = Simulation(testBench(width=3)) -sim.run() -\end{verbatim} - -The simulation produces the following output: - -\begin{verbatim} -% python bin2gray.py -B: 000 | G: 000 -B: 001 | G: 001 -B: 010 | G: 011 -B: 011 | G: 010 -B: 100 | G: 110 -B: 101 | G: 111 -B: 110 | G: 101 -B: 111 | G: 100 -StopSimulation: No more events -\end{verbatim} - -\subsection{Bit slicing \label{intro-slicing}} -\index{bit slicing} - -For a change, we will use a traditional function as an example to illustrate -slicing. The following function calculates the HEC byte of an ATM -header. - -\begin{verbatim} -from myhdl import intbv, concat - -COSET = 0x55 - -def calculateHec(header): - """ Return hec for an ATM header, represented as an intbv. - - The hec polynomial is 1 + x + x**2 + x**8. - """ - hec = intbv(0) - for bit in header[32:]: - hec[8:] = concat(hec[7:2], - bit ^ hec[1] ^ hec[7], - bit ^ hec[0] ^ hec[7], - bit ^ hec[7] - ) - return hec ^ COSET -\end{verbatim} - -The code shows how slicing access and assignment is supported on the -\class{intbv} data type. In accordance with the most common hardware -convention, and unlike standard Python, slicing ranges are -downward. The code also demonstrates concatenation of \class{intbv} -objects. - -As in standard Python, the slicing range is half-open: the highest -index bit is not included. Unlike standard Python however, this index -corresponds to the \emph{leftmost} item. Both indices can be omitted -from the slice. If the leftmost index is omitted, the meaning is to -access ``all'' higher order bits. If the rightmost index is omitted, -it is \code{0} by default. - -The half-openness of a slice may seem awkward at first, but it helps -to avoid one-off count issues in practice. For example, the slice -\code{hex[8:]} has exactly \code{8} bits. Likewise, the slice -\code{hex[7:2]} has \code{7-2=5} bits. You can think about it as -follows: for a slice \code{[i:j]}, only bits below index \code{i} are -included, and the bit with index \code{j} is the last bit included. - -When an intbv object is sliced, a new intbv object is returned. This -new intbv object is always positive, even when the original object -was negative. - - -\section{Some remarks on \myhdl\ and Python \label{intro-python}} - -To conclude this introductory chapter, it is useful to stress that -\myhdl\ is not a language in itself. The underlying language is Python, -and \myhdl\ is implemented as a Python package called \code{myhdl}. -Moreover, it is a design goal to keep the \code{myhdl} package as -minimalistic as possible, so that \myhdl\ descriptions are very much -``pure Python''. - -To have Python as the underlying language is significant in several -ways: - -\begin{itemize} - -\item Python is a very powerful high level language. This translates -into high productivity and elegant solutions to complex problems. - -\item Python is continuously improved by some very clever -minds, supported by a large and fast growing user base. Python profits -fully from the open source development model. - -\item Python comes with an extensive standard library. Some -functionality is likely to be of direct interest to \myhdl\ users: -examples include string handling, regular expressions, random number -generation, unit test support, operating system interfacing and GUI -development. In addition, there are modules for mathematics, database -connections, networking programming, internet data handling, and so -on. - -\item Python has a powerful C extension model. All built-in types are -written with the same C API that is available for custom -extensions. To a module user, there is no difference between a -standard Python module and a C extension module --- except -performance. The typical Python development model is to prototype -everything in Python until the application is stable, and (only) then -rewrite performance critical modules in C if necessary. - -\end{itemize} - - -\section{Summary and perspective \label{intro-summary}} -Here is an overview of what we have learned in this chapter: - -\begin{itemize} -\item Generators are the basic building blocks of MyHDL models. They -provide the way to model massive concurrency and sensitiviy lists. - -\item MyHDL provides decorators that create useful generators from local functions. - -\item Hardware structure and hierarchy is described with classic Python functions. - -\item \code{Signal} objects are used to communicate between concurrent generators. - -\item \code{intbv} objects are used to describe bit-oriented operations. - -\item A \code{Simulation} object is used to simulate MyHDL models. -\end{itemize} - -These concepts are sufficient to start describing and simulating MyHDL models. - -However, there is much more to MyHDL. Here is an overview of what can -be learned from the following chapters: - -\begin{itemize} -\item MyHDL supports sophisticated and high level modeling techniques. -This is described in Chapter~\ref{model} - -\item MyHDL enables the use of modern software verfication techniques, -such as unit testing, on hardware designs. This is the topic of -Chapter~\ref{unittest}. - -\item It is possible to co-simulate MyHDL models with other HDL -languages such as Verilog and VHDL. This is described in -Chapter~\ref{cosim}. - -\item Last but not least, MyHDL models can be converted to -Verilog, providing a path to a silicon implementation. This -is the topic of Chapter~\ref{conv}. -\end{itemize} diff --git a/olddoc/manual/modeling.tex b/olddoc/manual/modeling.tex deleted file mode 100644 index f6ef72bd..00000000 --- a/olddoc/manual/modeling.tex +++ /dev/null @@ -1,1197 +0,0 @@ -\chapter{Modeling techniques \label{model}} - -\section{Structural modeling \label{model-structure}} -\index{modeling!structural} - -Hardware descriptions need to support the concepts of module -instantiation and hierarchy. In \myhdl{}, an instance is recursively -defined as being either a sequence of instances, or a generator. -Hierarchy is modeled by defining instances in a higher-level -function, and returning them. The following is a schematic example -of the basic case. - -\begin{verbatim} -def top(...): - ... - instance_1 = module_1(...) - instance_2 = module_2(...) - ... - instance_n = module_n(...) - ... - return instance_1, instance_2, ... , instance_n -\end{verbatim} - -Note that \myhdl\ uses conventional procedural techniques -for modeling structure. This makes it straightforward -to model more complex cases. - -\subsection{Conditional instantiation \label{model-conf}} -\index{conditional instantiation} - -To model conditional instantiation, we can -select the returned instance under parameter control. -For example: - -\begin{verbatim} -SLOW, MEDIUM, FAST = range(3) - -def top(..., speed=SLOW): - ... - def slowAndSmall(): - ... - ... - def fastAndLarge(): - ... - if speed == SLOW: - return slowAndSmall() - elif speed == FAST: - return fastAndLarge() - else: - raise NotImplementedError -\end{verbatim} - - -\subsection{Arrays of instances \label{model-instarray}} -\index{arrays of instances} - -Python lists are easy to create. We can use them -to model arrays of instances. - -Suppose we have a top module that instantiates a -single \code{channel} submodule, as follows: - -\begin{verbatim} -def top(...): - - din = Signal(0) - dout = Signal(0) - clk = Signal(bool(0)) - reset = Signal(bool(0)) - - channel_inst = channel(dout, din, clk, reset) - - return channel_inst -\end{verbatim} - -If we wanted to support an arbitrary number of channels, -we can use lists of signals and a list of instances, -as follows: - -\begin{verbatim} -def top(..., n=8): - - din = [Signal(0) for i in range(n)] - dout = [Signal(0) for in range(n)] - clk = Signal(bool(0)) - reset = Signal(bool(0)) - channel_inst = [None for i in range(n)] - - for i in range(n): - channel_inst[i] = channel(dout[i], din[i], clk, reset) - - return channel_inst -\end{verbatim} - -\subsection{Inferring the list of instances \label{model-infer-instlist}} - -In \myhdl{}, instances have to be returned explicitly by -a top level function. It may be convenient to assemble -the list of instances automatically. For this purpose, -\myhdl provides the function \function{instances()}. -Using the first example in this section, it is used as follows: - -\begin{verbatim} -from myhdl import instances - -def top(...): - ... - instance_1 = module_1(...) - instance_2 = module_2(...) - ... - instance_n = module_n(...) - ... - return instances() -\end{verbatim} - -Function \function{instances()} uses introspection to inspect the type -of the local variables defined by the calling function. All variables -that comply with the definition of an instance are assembled in -a list, and that list is returned. - -\section{RTL modeling \label{model-rtl}} -\index{modeling!RTL style} - -The present section describes how \myhdl\ supports RTL style modeling -as is typically used for synthesizable models. - -\subsection{Combinatorial logic \label{model-comb}} -\index{combinatorial logic} - -\subsubsection{Template \label{model-comb-templ}} - -Combinatorial logic is described with a code pattern as -follows: - -\begin{verbatim} -def top(): - ... - @always_comb - def combLogic(): - - ... - return combLogic, ... -\end{verbatim} - -The \function{always_comb} decorator describes -combinatorial logic. -\footnote{The name \function{always_comb} refers to a construct with -similar semantics in SystemVerilog.}. -The decorated function is a local function that specifies what -happens when one of the input signals of the logic changes. The -\function{always_comb} decorator infers the input signals -automatically. It returns a generator that is sensitive to all inputs, -and that executes the function whenever an input changes. - - -\subsubsection{Example \label{model-comb-ex}} - -The following is an example of a combinatorial multiplexer: - -\begin{verbatim} -from myhdl import Signal, Simulation, delay, always_comb - -def Mux(z, a, b, sel): - - """ Multiplexer. - - z -- mux output - a, b -- data inputs - sel -- control input: select a if asserted, otherwise b - - """ - - @always_comb - def muxLogic(): - if sel == 1: - z.next = a - else: - z.next = b - - return muxLogic -\end{verbatim} - - -To verify it, we will simulate the logic with some random patterns. The -\code{random} module in Python's standard library comes in handy for -such purposes. The function \code{randrange(\var{n})} returns a random -natural integer smaller than \var{n}. It is used in the test bench -code to produce random input values: - -\begin{verbatim} -from random import randrange - -z, a, b, sel = [Signal(0) for i in range(4)] - -mux_1 = Mux(z, a, b, sel) - -def test(): - print "z a b sel" - for i in range(8): - a.next, b.next, sel.next = randrange(8), randrange(8), randrange(2) - yield delay(10) - print "%s %s %s %s" % (z, a, b, sel) - -test_1 = test() - -sim = Simulation(mux_1, test_1) -sim.run() -\end{verbatim} - -Because of the randomness, the simulation output varies between runs -\footnote{It also possible to have a reproducible random output, by -explicitly providing a seed value. See the documentation of the -\code{random} module.}. One particular run produced the following -output: - -\begin{verbatim} -% python mux.py -z a b sel -6 6 1 1 -7 7 1 1 -7 3 7 0 -1 2 1 0 -7 7 5 1 -4 7 4 0 -4 0 4 0 -3 3 5 1 -StopSimulation: No more events -\end{verbatim} - - -\subsection{Sequential logic \label{model-seq}} -\index{sequential logic} - -\subsubsection{Template \label{model-seq-templ}} -Sequential RTL models are sensitive to a clock edge. In addition, they -may be sensitive to a reset signal. We will describe one of the most -common patterns: a template with a rising clock edge and an -asynchronous reset signal. Other templates are similar. - -\begin{verbatim} -def top(, clock, ..., reset, ...): - ... - @always(clock.posedge, reset.negedge) - def seqLogic(): - if reset == : - - else: - - ... - return seqLogic, ... -\end{verbatim} - - -\subsubsection{Example \label{model-seq-ex}} -The following code is a description of an incrementer with enable, and -an asynchronous reset. - -\begin{verbatim} -from random import randrange -from myhdl import * - -ACTIVE_LOW, INACTIVE_HIGH = 0, 1 - -def Inc(count, enable, clock, reset, n): - - """ Incrementer with enable. - - count -- output - enable -- control input, increment when 1 - clock -- clock input - reset -- asynchronous reset input - n -- counter max value - - """ - - @always(clock.posedge, reset.negedge) - def incLogic(): - if reset == ACTIVE_LOW: - count.next = 0 - else: - if enable: - count.next = (count + 1) % n - - return incLogic -\end{verbatim} - -For the test bench, we will use an independent clock generator, stimulus -generator, and monitor. After applying enough stimulus patterns, we -can raise the \code{StopSimulation} exception to stop the -simulation run. The test bench for a small incrementer and a small -number of patterns is a follows: - -\begin{verbatim} -def testbench(): - count, enable, clock, reset = [Signal(intbv(0)) for i in range(4)] - - inc_1 = Inc(count, enable, clock, reset, n=4) - - HALF_PERIOD = delay(10) - - @always(HALF_PERIOD) - def clockGen(): - clock.next = not clock - - @instance - def stimulus(): - reset.next = ACTIVE_LOW - yield clock.negedge - reset.next = INACTIVE_HIGH - for i in range(12): - enable.next = min(1, randrange(3)) - yield clock.negedge - raise StopSimulation - - @instance - def monitor(): - print "enable count" - yield reset.posedge - while 1: - yield clock.posedge - yield delay(1) - print " %s %s" % (enable, count) - - return clockGen, stimulus, inc_1, monitor - - -tb = testbench() - -def main(): - Simulation(tb).run() -\end{verbatim} - -The simulation produces the following output: -\begin{verbatim} -% python inc.py -enable count - 0 0 - 1 1 - 0 1 - 1 2 - 1 3 - 1 0 - 0 0 - 1 1 - 0 1 - 0 1 - 0 1 - 1 2 -StopSimulation -\end{verbatim} - - -\subsection{Finite State Machine modeling \label{model-fsm}} -\index{modeling!Finite State Machine} - -Finite State Machine (FSM) modeling is very common in RTL -design and therefore deserves special attention. - -For code clarity, the state values are typically represented by a set -of identifiers. A standard Python idiom for this purpose is to assign -a range of integers to a tuple of identifiers, like so: - -\begin{verbatim} ->>> SEARCH, CONFIRM, SYNC = range(3) ->>> CONFIRM -1 -\end{verbatim} - -However, this technique has some drawbacks. Though it is clearly -the intention that the identifiers belong together, this information -is lost as soon as they are defined. Also, the identifiers evaluate to -integers, whereas a string representation of the identifiers -would be preferable. To solve these issues, we need an -\emph{enumeration type}. - -\myhdl\ supports enumeration types by providing a function -\function{enum()}. The arguments to \function{enum()} are the string -representations of the identifiers, and its return value is an -enumeration type. The identifiers are available as attributes of the -type. For example: - -\begin{verbatim} ->>> from myhdl import enum ->>> t_State = enum('SEARCH', 'CONFIRM', 'SYNC') ->>> t_State - ->>> t_State.CONFIRM -CONFIRM -\end{verbatim} - -We can use this type to construct a state signal as follows: - -\begin{verbatim} -state = Signal(t_State.SEARCH) -\end{verbatim} - -As an example, we will use a framing controller FSM. It is an -imaginary example, but similar control structures are often found in -telecommunication applications. Suppose that we need to find the -Start Of Frame (SOF) position of an incoming frame of bytes. -A sync pattern detector continuously looks for a framing -pattern and indicates it to the FSM with a \code{syncFlag} signal. When -found, the FSM moves from the initial \code{SEARCH} state to the -\code{CONFIRM} state. When the \code{syncFlag} -is confirmed on the expected position, the FSM declares \code{SYNC}, -otherwise it falls back to the \code{SEARCH} state. This FSM can be -coded as follows: - -\begin{verbatim} -from myhdl import * - -ACTIVE_LOW = 0 -FRAME_SIZE = 8 -t_State = enum('SEARCH', 'CONFIRM', 'SYNC') - -def FramerCtrl(SOF, state, syncFlag, clk, reset_n): - - """ Framing control FSM. - - SOF -- start-of-frame output bit - state -- FramerState output - syncFlag -- sync pattern found indication input - clk -- clock input - reset_n -- active low reset - - """ - - index = Signal(0) # position in frame - - @always(clk.posedge, reset_n.negedge) - def FSM(): - if reset_n == ACTIVE_LOW: - SOF.next = 0 - index.next = 0 - state.next = t_State.SEARCH - - else: - index.next = (index + 1) % FRAME_SIZE - SOF.next = 0 - - if state == t_State.SEARCH: - index.next = 1 - if syncFlag: - state.next = t_State.CONFIRM - - elif state == t_State.CONFIRM: - if index == 0: - if syncFlag: - state.next = t_State.SYNC - else: - state.next = t_State.SEARCH - - elif state == t_State.SYNC: - if index == 0: - if not syncFlag: - state.next = t_State.SEARCH - SOF.next = (index == FRAME_SIZE-1) - - else: - raise ValueError("Undefined state") - - return FSM -\end{verbatim} - -At this point, we will use the example to demonstrate -the \myhdl\ support for -\index{waveform viewing}% -waveform viewing. -During simulation, signal -changes can be written to a VCD output file. The VCD file can then be -loaded and viewed in a waveform viewer tool such as \program{gtkwave}. - -The user interface of this feature consists of a single function, -\function{traceSignals()}. To explain how it works, recall that in -\myhdl{}, an instance is created by assigning -the result of a function call to an instance name. -For example: - -\begin{verbatim} -tb_fsm = testbench() -\end{verbatim} - -To enable VCD tracing, the instance should be created as follows -instead: - -\begin{verbatim} -tb_fsm = traceSignals(testbench) -\end{verbatim} - -Note that the first argument of -\function{traceSignals()} consists of the uncalled function. By -calling the function under its control, \function{traceSignals()} -gathers information about the hierarchy and the signals to be traced. -In addition to a function argument, \function{traceSignals()} accepts -an arbitrary number of non-keyword and keyword arguments that will be -passed to the function call. - -A small test bench for our framing controller example, -with signal tracing enabled, is shown below: - -\begin{verbatim} -def testbench(): - - SOF = Signal(bool(0)) - syncFlag = Signal(bool(0)) - clk = Signal(bool(0)) - reset_n = Signal(bool(1)) - state = Signal(t_State.SEARCH) - - framectrl = FramerCtrl(SOF, state, syncFlag, clk, reset_n) - - @always(delay(10)) - def clkgen(): - clk.next = not clk - - @instance - def stimulus(): - for i in range(3): - yield clk.posedge - for n in (12, 8, 8, 4): - syncFlag.next = 1 - yield clk.posedge - syncFlag.next = 0 - for i in range(n-1): - yield clk.posedge - raise StopSimulation - - return framectrl, clkgen, stimulus - - -tb_fsm = traceSignals(testbench) -sim = Simulation(tb_fsm) -sim.run() -\end{verbatim} - -When we run the test bench, it generates a VCD file -called \file{testbench.vcd}. When we load this file into -\program{gtkwave}, we can view the waveforms: - -\ifpdf -\includegraphics{tbfsm.png} -\fi - -Signals are dumped in a suitable format. This format is inferred at -the \class{Signal} construction time, from the type of the initial -value. In particular, \class{bool} signals are dumped as single -bits. (This only works starting with Python~2.3, when \class{bool} has -become a separate type). Likewise, \class{intbv} signals with a -defined bit width are dumped as bit vectors. To support the general -case, other types of signals are dumped as a string representation, as -returned by the standard \function{str()} function. - -\begin{notice}[warning] -Support for literal string representations is not part of the VCD -standard. It is specific to \program{gtkwave}. To generate a -standard VCD file, you need to use signals with a defined bit width -only. -\end{notice} - - -\section{High level modeling \label{model-hl}} -\index{modeling!high level} - -\subsection{Modeling with bus-functional procedures \label{model-bfm}} - -\index{bus-functional procedure}% -A \dfn{bus-functional procedure} is a reusable encapsulation of the -low-level operations needed to implement some abstract transaction on -a physical interface. Bus-functional procedures are typically used in -flexible verification environments. - -Once again, \myhdl\ uses generator functions to support -bus-functional procedures. In \myhdl\, the difference between -instances and bus-functional procedure calls comes from the way in -which a generator function is used. - -As an example, we will design a bus-functional procedure of a -simplified UART transmitter. We assume 8 data bits, no parity bit, and -a single stop bit, and we add print statements to follow the -simulation behavior: - -\begin{verbatim} -T_9600 = int(1e9 / 9600) - -def rs232_tx(tx, data, duration=T_9600): - - """ Simple rs232 transmitter procedure. - - tx -- serial output data - data -- input data byte to be transmitted - duration -- transmit bit duration - - """ - - print "-- Transmitting %s --" % hex(data) - print "TX: start bit" - tx.next = 0 - yield delay(duration) - - for i in range(8): - print "TX: %s" % data[i] - tx.next = data[i] - yield delay(duration) - - print "TX: stop bit" - tx.next = 1 - yield delay(duration) -\end{verbatim} - -This looks exactly like the generator functions in previous sections. It -becomes a bus-functional procedure when we use it differently. Suppose -that in a test bench, we want to generate a number of data bytes to be -transmitted. This can be modeled as follows: - - -\begin{verbatim} -testvals = (0xc5, 0x3a, 0x4b) - -def stimulus(): - tx = Signal(1) - for val in testvals: - txData = intbv(val) - yield rs232_tx(tx, txData) -\end{verbatim} - -We use the bus-functional procedure call as a clause in a -\code{yield} statement. This introduces a fourth form of the -\code{yield} statement: using a generator as a clause. Although this is -a more dynamic usage than in the previous cases, the meaning is -actually very similar: at that point, -the original generator should - \index{wait!for the completion of a generator}% -wait for the completion of a generator. -In this case, the original generator resumes when the -\code{rs232_tx(tx, txData)} generator returns. - -When simulating this, we get: - -\begin{verbatim} --- Transmitting 0xc5 -- -TX: start bit -TX: 1 -TX: 0 -TX: 1 -TX: 0 -TX: 0 -TX: 0 -TX: 1 -TX: 1 -TX: stop bit --- Transmitting 0x3a -- -TX: start bit -TX: 0 -TX: 1 -TX: 0 -TX: 1 -... -\end{verbatim} - -We will continue with this example by designing the corresponding UART -receiver bus-functional procedure. This will allow us to introduce -further capabilities of \myhdl\ and its use of the \code{yield} -statement. - -Until now, the \code{yield} statements had a single clause. However, -they can have multiple clauses as well. In that case, the generator -resumes as soon as the wait condition specified by one -of the clauses is satisfied. This corresponds to the functionality of - \index{sensitivity list}% -sensitivity lists in Verilog and VHDL. - -For example, suppose we want to design an UART receive procedure with -a timeout. We can specify the timeout condition while waiting for the -start bit, as in the following generator function: - -\begin{verbatim} -def rs232_rx(rx, data, duration=T_9600, timeout=MAX_TIMEOUT): - - """ Simple rs232 receiver procedure. - - rx -- serial input data - data -- data received - duration -- receive bit duration - - """ - - # wait on start bit until timeout - yield rx.negedge, delay(timeout) - if rx == 1: - raise StopSimulation, "RX time out error" - - # sample in the middle of the bit duration - yield delay(duration // 2) - print "RX: start bit" - - for i in range(8): - yield delay(duration) - print "RX: %s" % rx - data[i] = rx - - yield delay(duration) - print "RX: stop bit" - print "-- Received %s --" % hex(data) -\end{verbatim} - -If the timeout condition is triggered, the receive bit \code{rx} -will still be \code{1}. In that case, we raise an exception to stop -the simulation. The \code{StopSimulation} exception is predefined in -\myhdl\ for such purposes. In the other case, we proceed by -positioning the sample point in the middle of the bit duration, and -sampling the received data bits. - -When a \code{yield} statement has multiple clauses, they can be of any -type that is supported as a single clause, including generators. For -example, we can verify the transmitter and receiver generator against -each other by yielding them together, as follows: - -\begin{verbatim} -def test(): - tx = Signal(1) - rx = tx - rxData = intbv(0) - for val in testvals: - txData = intbv(val) - yield rs232_rx(rx, rxData), rs232_tx(tx, txData) -\end{verbatim} - -Both forked generators will run concurrently, and the original -generator will resume as soon as one of them finishes (which will be -the transmitter in this case). The simulation output shows how -the UART procedures run in lockstep: - -\begin{verbatim} --- Transmitting 0xc5 -- -TX: start bit -RX: start bit -TX: 1 -RX: 1 -TX: 0 -RX: 0 -TX: 1 -RX: 1 -TX: 0 -RX: 0 -TX: 0 -RX: 0 -TX: 0 -RX: 0 -TX: 1 -RX: 1 -TX: 1 -RX: 1 -TX: stop bit -RX: stop bit --- Received 0xc5 -- --- Transmitting 0x3a -- -TX: start bit -RX: start bit -TX: 0 -RX: 0 -... -\end{verbatim} - -For completeness, we will verify the timeout behavior with a test -bench that disconnects the \code{rx} from the \code{tx} signal, and we -specify a small timeout for the receive procedure: - -\begin{verbatim} -def testTimeout(): - tx = Signal(1) - rx = Signal(1) - rxData = intbv(0) - for val in testvals: - txData = intbv(val) - yield rs232_rx(rx, rxData, timeout=4*T_9600-1), rs232_tx(tx, txData) -\end{verbatim} - -The simulation now stops with a timeout exception after a few -transmit cycles: - -\begin{verbatim} --- Transmitting 0xc5 -- -TX: start bit -TX: 1 -TX: 0 -TX: 1 -StopSimulation: RX time out error -\end{verbatim} - -Recall that the original generator resumes as soon as one of the -forked generators returns. In the previous cases, this is just fine, -as the transmitter and receiver generators run in lockstep. However, -it may be desirable to resume the caller only when \emph{all} of the -forked generators have finished. For example, suppose that we want to -characterize the robustness of the transmitter and receiver design to -bit duration differences. We can adapt our test bench as follows, to -run the transmitter at a faster rate: - -\begin{verbatim} -T_10200 = int(1e9 / 10200) - -def testNoJoin(): - tx = Signal(1) - rx = tx - rxData = intbv(0) - for val in testvals: - txData = intbv(val) - yield rs232_rx(rx, rxData), rs232_tx(tx, txData, duration=T_10200) -\end{verbatim} - -Simulating this shows how the transmission of the new byte starts -before the previous one is received, potentially creating additional -transmission errors: - -\begin{verbatim} --- Transmitting 0xc5 -- -TX: start bit -RX: start bit -... -TX: 1 -RX: 1 -TX: 1 -TX: stop bit -RX: 1 --- Transmitting 0x3a -- -TX: start bit -RX: stop bit --- Received 0xc5 -- -RX: start bit -TX: 0 -\end{verbatim} - -It is more likely that we want to characterize the design on a byte -by byte basis, and align the two generators before transmitting each -byte. In \myhdl{}, this is done with the \function{join} function. By -joining clauses together in a \code{yield} statement, we create a new -clause that triggers only when all of its clause arguments have -triggered. For example, we can adapt the test bench as follows: - -\begin{verbatim} -def testJoin(): - tx = Signal(1) - rx = tx - rxData = intbv(0) - for val in testvals: - txData = intbv(val) - yield join(rs232_rx(rx, rxData), rs232_tx(tx, txData, duration=T_10200)) -\end{verbatim} - -Now, transmission of a new byte only starts when the previous one is received: - -\begin{verbatim} --- Transmitting 0xc5 -- -TX: start bit -RX: start bit -... -TX: 1 -RX: 1 -TX: 1 -TX: stop bit -RX: 1 -RX: stop bit --- Received 0xc5 -- --- Transmitting 0x3a -- -TX: start bit -RX: start bit -TX: 0 -RX: 0 -\end{verbatim} - - - -\subsection{Modeling memories with built-in types \label{model-mem}} -\index{modeling!memories} - -Python has powerful built-in data types that can be useful to model -hardware memories. This can be merely a matter of putting an interface -around some data type operations. - -For example, a \dfn{dictionary} comes in handy to model sparse memory -structures. (In other languages, this data type is called -\dfn{associative array}, or \dfn{hash table}.) A sparse memory is one in -which only a small part of the addresses is used in a particular -application or simulation. Instead of statically allocating the full -address space, which can be large, it is better to dynamically -allocate the needed storage space. This is exactly what a dictionary -provides. The following is an example of a sparse memory model: - -\begin{verbatim} -def sparseMemory(dout, din, addr, we, en, clk): - - """ Sparse memory model based on a dictionary. - - Ports: - dout -- data out - din -- data in - addr -- address bus - we -- write enable: write if 1, read otherwise - en -- interface enable: enabled if 1 - clk -- clock input - - """ - - memory = {} - - @always(clk.posedge) - def access(): - if en: - if we: - memory[addr.val] = din.val - else: - dout.next = memory[addr.val] - - return access -\end{verbatim} - -Note how we use the \code{val} attribute of the \code{din} signal, as -we don't want to store the signal object itself, but its current -value. Similarly, we use the \code{val} attribute of the \code{addr} -signal as the dictionary key. - -In many cases, \myhdl\ code uses a signal's current value -automatically when there is no ambiguity: for example, when a signal -is used in an expression. However, in other cases such as in this -example you have to refer to the value explicitly: for example, when -the Signal is used as an index, or when it is not used in an -expression. One option is to use the \code{val} attribute, as in this -example. Another possibility is to use the \code{int()} or -\code{bool()} functions to typecast the Signal to an integer or a -boolean value. These functions are also useful with \class{intbv} -objects. - -As a second example, we will demonstrate how to use a list to model a -synchronous fifo: - -\begin{verbatim} -def fifo(dout, din, re, we, empty, full, clk, maxFilling=sys.maxint): - - """ Synchronous fifo model based on a list. - - Ports: - dout -- data out - din -- data in - re -- read enable - we -- write enable - empty -- empty indication flag - full -- full indication flag - clk -- clock input - - Optional parameter: - maxFilling -- maximum fifo filling, "infinite" by default - - """ - - memory = [] - - @always(clk.posedge) - def access(): - if we: - memory.insert(0, din.val) - if re: - dout.next = memory.pop() - filling = len(memory) - empty.next = (filling == 0) - full.next = (filling == maxFilling) - - return access -\end{verbatim} - -Again, the model is merely a \myhdl\ interface around some operations -on a list: \function{insert()} to insert entries, \function{pop()} to -retrieve them, and \function{len()} to get the size of a Python -object. - -\subsection{Modeling errors using exceptions \label{model-err}} - -In the previous section, we used Python data types for modeling. If -such a type is used inappropriately, Python's run time error system -will come into play. For example, if we access an address in the -\function{sparseMemory} model that was not initialized before, we will -get a traceback similar to the following (some lines omitted for -clarity): - -\begin{verbatim} -Traceback (most recent call last): -... - File "sparseMemory.py", line 31, in access - dout.next = memory[addr.val] -KeyError: Signal(51) -\end{verbatim} - -Similarly, if the \code{fifo} is empty, and we attempt to read from -it, we get: - -\begin{verbatim} -Traceback (most recent call last): -... - File "fifo.py", line 34, in fifo - dout.next = memory.pop() -IndexError: pop from empty list -\end{verbatim} - -Instead of these low level errors, it may be preferable to define -errors at the functional level. In Python, this is typically done by -defining a custom \code{Error} exception, by subclassing the standard -\code{Exception} class. This exception is then raised explicitly when -an error condition occurs. - -For example, we can change the \function{sparseMemory} function as -follows (with the doc string is omitted for brevity): - -\begin{verbatim} -class Error(Exception): - pass - -def sparseMemory2(dout, din, addr, we, en, clk): - - memory = {} - - @always(clk.posedge) - def access(): - if en: - if we: - memory[addr.val] = din.val - else: - try: - dout.next = memory[addr.val] - except KeyError: - raise Error, "Uninitialized address %s" % hex(addr) - - return access - -\end{verbatim} - -This works by catching the low level data type exception, and raising -the custom exception with an appropriate error message instead. If -the \function{sparseMemory} function is defined in a module with the -same name, an access error is now reported as follows: - -\begin{verbatim} -Traceback (most recent call last): -... - File "sparseMemory.py", line 61, in access - raise Error, "Uninitialized address %s" % hex(addr) -Error: Uninitialized address 0x33 - -\end{verbatim} - -Likewise, the \function{fifo} function can be adapted as follows, to -report underflow and overflow errors: - -\begin{verbatim} -class Error(Exception): - pass - - -def fifo2(dout, din, re, we, empty, full, clk, maxFilling=sys.maxint): - - memory = [] - - @always(clk.posedge) - def access(): - if we: - memory.insert(0, din.val) - if re: - try: - dout.next = memory.pop() - except IndexError: - raise Error, "Underflow -- Read from empty fifo" - filling = len(memory) - empty.next = (filling == 0) - full.next = (filling == maxFilling) - if filling > maxFilling: - raise Error, "Overflow -- Max filling %s exceeded" % maxFilling - - return access -\end{verbatim} - -In this case, the underflow error is detected as before, by catching a -low level exception on the list data type. On the other hand, the -overflow error is detected by a regular check on the length of the -list. - - -\subsection{Object oriented modeling \label{model-obj}} -\index{modeling!object oriented} - -The models in the previous sections used high-level built-in data -types internally. However, they had a conventional RTL-style -interface. Communication with such a module is done through signals -that are attached to it during instantiation. - -A more advanced approach is to model hardware blocks as -objects. Communication with objects is done through method calls. -A method encapsulates all details of a certain task performed -by the object. As an object has a method interface instead -of an RTL-style hardware interface, this is a much -higher level approach. - -As an example, we will design a synchronized queue object. -Such an object can be filled by producer, and independently -read by a consumer. When the queue is empty, the consumer -should wait until an item is available. The queue can be modeled -as an object with a \method{put(item)} and a \method{get()} -method, as follows: - -\begin{verbatim} -from myhdl import * - -def trigger(event): - event.next = not event - -class queue: - def __init__(self): - self.l = [] - self.sync = Signal(0) - self.item = None - def put(self,item): - # non time-consuming method - self.l.append(item) - trigger(self.sync) - def get(self): - # time-consuming method - if not self.l: - yield self.sync - self.item = self.l.pop(0) -\end{verbatim} - -The \class{queue} object constructor initializes an internal list to -hold items, and a \var{sync} signal to synchronize the operation -between the methods. Whenever \method{put()} puts an item in the -queue, the signal is triggered. When the \method{get()} method sees -that the list is empty, it waits on the trigger first. -\method{get()} is a generator method because -it may consume time. As the \code{yield} statement is used in \myhdl\ -for timing control, the method cannot ``yield'' the item. Instead, it -makes it available in the \var{item} instance variable. - -To test the queue operation, we will model a producer and a consumer -in the test bench. As a waiting consumer should not block a whole -system, it should run in a concurrent ``thread''. As always in -\myhdl{}, concurrency is modeled by Python generators. Producer -and consumer will thus run independently, and we will monitor -their operation through some print statements: - -\begin{verbatim} -q = queue() - -def Producer(q): - yield delay(120) - for i in range(5): - print "%s: PUT item %s" % (now(), i) - q.put(i) - yield delay(max(5, 45 - 10*i)) - -def Consumer(q): - yield delay(100) - while 1: - print "%s: TRY to get item" % now() - yield q.get() - print "%s: GOT item %s" % (now(), q.item) - yield delay(30) - -def main(): - P = Producer(q) - C = Consumer(q) - return P, C - -sim = Simulation(main()) -sim.run() -\end{verbatim} - -Note that the generator method \method{get()} is called in a -\code{yield} statement in the \function{Consumer} function. The new -generator will take over from \function{Consumer}, until it is done. -Running this test bench produces the following output: - -\begin{verbatim} -% python queue.py -100: TRY to get item -120: PUT item 0 -120: GOT item 0 -150: TRY to get item -165: PUT item 1 -165: GOT item 1 -195: TRY to get item -200: PUT item 2 -200: GOT item 2 -225: PUT item 3 -230: TRY to get item -230: GOT item 3 -240: PUT item 4 -260: TRY to get item -260: GOT item 4 -290: TRY to get item -StopSimulation: No more events -\end{verbatim} diff --git a/olddoc/manual/reference.tex b/olddoc/manual/reference.tex deleted file mode 100644 index 50e71953..00000000 --- a/olddoc/manual/reference.tex +++ /dev/null @@ -1,554 +0,0 @@ -\chapter{Reference \label{ref}} - - -\myhdl\ is implemented as a Python package called \code{myhdl}. This -chapter describes the objects that are exported by this package. - -\section{Simulation \label{ref-sim}} - -\subsection{The \class{Simulation} class \label{ref-simclass}} -\declaremodule{}{myhdl} - -\begin{classdesc}{Simulation}{arg \optional{, arg \moreargs}} -Class to construct a new simulation. Each argument should be a -\myhdl\ instance. In \myhdl{}, an instance is recursively defined -as being either a sequence of instances, or a \myhdl\ generator, or a -Cosimulation object. See section~\ref{ref-gen} for the definition of -\myhdl\ generators and their interaction with a -\class{Simulation} object. See Section~\ref{ref-cosim} -for the \class{Cosimulation} object. At most one \class{Cosimulation} -object can be passed to a \class{Simulation} constructor. - -\end{classdesc} - -A \class{Simulation} object has the following method: - -\begin{methoddesc}[Simulation]{run}{\optional{duration}} -Run the simulation forever (by default) or for a specified duration. -\end{methoddesc} - - -\subsection{Simulation support functions\label{ref-simsupport}} -\declaremodule{}{myhdl} - -\begin{funcdesc}{now}{} -Returns the current simulation time. -\end{funcdesc} - -\begin{excclassdesc}{StopSimulation}{} -Base exception that is caught by the \code{Simulation.run()} method to -stop a simulation. -\end{excclassdesc} - - -\subsection{Waveform tracing\label{ref-trace}} - - -\begin{funcdesc}{traceSignals}{func \optional{, *args} \optional{, **kwargs}} -Enables signal tracing to a VCD file for waveform viewing. -\var{func} is a function that returns an instance. -\function{traceSignals()} calls \var{func} under its control -and passes \var{*args} and \var{**kwargs} to the call. In this way, it -finds the hierarchy and the signals to be traced. - -The return value is the same as would be returned by the call -\code{func(*args, **kwargs)}. The top-level instance name and the -basename of the VCD output filename is \code{func.func_name} by -default. If the VCD file exists already, it will be moved to a backup -file by attaching a timestamp to it, before creating the new file. -\end{funcdesc} - -The \code{traceSignals} callable has the following attribute: - -\begin{memberdesc}[traceSignals]{name} - -This attribute is used to overwrite the default top-level instance -name and the basename of the VCD output filename. -\end{memberdesc} - -\section{Modeling \label{ref-model}} - -\subsection{The \class{Signal} class \label{ref-sig}} -\declaremodule{}{myhdl} - -\begin{classdesc}{Signal}{\optional{val=None} \optional{, delay=0}} -This class is used to construct a new signal and to initialize its -value to \var{val}. Optionally, a delay can be specified. -\end{classdesc} - -A \class{Signal} object has the following attributes: - -\begin{memberdesc}[Signal]{posedge} -Attribute that represents the positive edge of a signal, to be -used in sensitivity lists. -\end{memberdesc} -\begin{memberdesc}[Signal]{negedge} -Attribute that represents the negative edge of a signal, to be -used in sensitivity lists. -\end{memberdesc} - -\begin{memberdesc}[Signal]{next} -Read-write attribute that represents the next value of the signal. -\end{memberdesc} - -\begin{memberdesc}[Signal]{val} -Read-only attribute that represents the current value of the signal. - -This attribute is always available to access the current value; -however in many practical case it will not be needed. Whenever there -is no ambiguity, the Signal object's current value is used -implicitly. In particular, all Python's standard numeric, bit-wise, -logical and comparison operators are implemented on a Signal object by -delegating to its current value. The exception is augmented -assignment. These operators are not implemented as they would break -the rule that the current value should be a read-only attribute. In -addition, when a Signal object is assigned to the \code{next} -attribute of another Signal object, its current value is assigned -instead. -\end{memberdesc} - -\begin{memberdesc}[Signal]{min} -Read-only attribute that is the minimum value (inclusive) of a -numeric signal, or \var{None} for no minimum. -\end{memberdesc} -\begin{memberdesc}[Signal]{max} -Read-only attribute that is the maximum value -(exclusive) of a numeric signal, or \var{None} for no -maximum. -\end{memberdesc} - -\begin{memberdesc}[Signal]{driven} -Writable attribute that can be used to indicate that the signal -is supposed to be driven from the MyHDL code, and how it should -be declared in Verilog after conversion. The allowed values -are \code{'reg'} and \code{'wire'}. - -This attribute is useful when the Verilog converter cannot -infer automatically whether and how a signal is driven. This -occurs when the signal is driven from user-defined Verilog code. -\end{memberdesc} - - - - -\subsection{\myhdl\ generators and trigger objects \label{ref-gen}} -\declaremodule{}{myhdl} - -\myhdl\ generators are standard Python generators with specialized -\keyword{yield} statements. In hardware description languages, the equivalent -statements are called - \index{sensitivity list}% -\emph{sensitivity lists}. The general format -of \keyword{yield} statements in in \myhdl\ generators is: - -\hspace{\leftmargin}\keyword{yield} \var{clause \optional{, clause ...}} - -When a generator executes a \keyword{yield} statement, its -execution is suspended at that point. At the same time, each -\var{clause} is a \emph{trigger object} which defines the condition -upon which the generator should be resumed. However, per invocation of a -\keyword{yield} statement, the generator resumes exactly once, -regardless of the number of clauses. This happens on the -first trigger that occurs. - -In this section, the trigger objects and their functionality will be -described. - -Some MyHDL objects that are described elsewhere can directly be used -as trigger objects. In particular, a signal can be used as -a trigger object. Whenever a signal changes value, the generator -resumes. Likewise, the objects referred to by the signal attributes -\code{posedge} and \code{negedge} are trigger objects. The generator -resumes on the occurrence of a positive or a negative edge on the -signal, respectively. An edge occurs when there is a change from -false to true (positive) or vice versa (negative). -For the full description of the \class{Signal} class and its -attributes, see section~\ref{ref-sig}. - -Furthermore, \myhdl\ generators can be used as clauses in \code{yield} -statements. Such a generator is forked, and starts operating -immediately, while the original generator -waits for it to complete. The original generator resumes when the -forked generator returns. - - -In addition, the following functions return trigger objects: - -\begin{funcdesc}{delay}{t} -Return a trigger object that specifies that the generator should -resume after a delay \var{t}. -\end{funcdesc} - -\begin{funcdesc}{join}{arg \optional{, arg \moreargs}} -Join a number of trigger objects together and return a joined -trigger object. The effect is that the joined trigger object will -trigger when \emph{all} of its arguments have triggered. -\end{funcdesc} - - -Finally, as a special case, the Python \code{None} object can be -present in a \code{yield} statement. It is the do-nothing -trigger object. The generator immediately resumes, as if no -\code{yield} statement were present. This can be useful if the -\code{yield} statement also has generator clauses: those generators -are forked, while the original generator resumes immediately. - -\subsection{Decorator functions \label{ref-deco}} -\declaremodule{}{myhdl} - -MyHDL defines a number of decorator functions, that make it easier to -create generators from local generator functions. - -\begin{funcdesc}{instance}{} -The \function{instance} decorator is the most general decorator. It -automatically creates a generator by calling the decorated generator function. - -It is used as follows: - -\begin{verbatim} -def top(...): - ... - @instance - def inst(): - - ... - return inst, ... -\end{verbatim} - -This is equivalent to: - -\begin{verbatim} -def top(...): - ... - def _gen_func(): - - ... - inst = _gen_func() - ... - return inst, ... -\end{verbatim} - -\end{funcdesc} - - -\begin{funcdesc}{always}{arg \optional{, *args}} - -The \function{always} decorator is a specialized decorator that targets a widely used -coding pattern. It is used as follows: - -\begin{verbatim} -def top(...): - ... - @always(event1, event2, ...) - def inst() - - ... - return inst, ... -\end{verbatim} - -This is equivalent to the following: - -\begin{verbatim} -def top(...): - ... - def _func(): - - - def _gen_func() - while True: - yield event1, event2, ... - _func() - ... - inst = _gen_func() - ... - return inst, ... -\end{verbatim} - - -The argument list of the decorator corresponds to the sensitivity -list. Only signals, edge specifiers, or delay objects are allowed. -The decorated function should be a classic function. - - -\end{funcdesc} - - -\begin{funcdesc}{always_comb}{} - - -The \function{always_comb} decorator is used to describe combinatorial -logic. - - -\begin{verbatim} -def top(...): - ... - @always_comb - def comb_inst(): - - ... - return comb_inst, ... -\end{verbatim} - - -The \function{always_comb} decorator infers the inputs of the combinatorial -logic and the corresponding sensitivity list automatically. -The decorated function should be a classic function. - -\end{funcdesc} - - -\subsection{The \class{intbv} class \label{ref-intbv}} -\declaremodule{}{myhdl} - -\begin{classdesc}{intbv}{\optional{val=None} \optional{, min=None} -\optional{, max=None}} -This class represents \class{int}-like objects with some additional -features that make it suitable for hardware design. The \var{val} -argument can be an \class{int}, a \class{long}, an \class{intbv} or a -bit string (a string with only '0's or '1's). For a bit string -argument, the value is calculated as in \code{int(\var{bitstring}, -2)}. The optional \var{min} and \var{max} arguments can be used to -specify the minimum and maximum value of the \class{intbv} object. As -in standard Python practice for ranges, the minimum value is inclusive -and the maximum value is exclusive. -\end{classdesc} - -The minimum and maximum values of an \class{intbv} object -are available as attributes: - -\begin{memberdesc}[intbv]{min} -Read-only attribute that is the minimum value (inclusive) of an -\class{intbv}, or \var{None} for no minimum. -\end{memberdesc} -\begin{memberdesc}[intbv]{max} -Read-only attribute that is the maximum value -(exclusive) of an \class{intbv}, or \var{None} for no -maximum. -\end{memberdesc} - -Unlike \class{int} objects, \class{intbv} objects are mutable; this is -also the reason for their existence. Mutability is needed to support -assignment to indexes and slices, as is common in hardware design. For -the same reason, \class{intbv} is not a subclass from \class{int}, -even though \class{int} provides most of the desired -functionality. (It is not possible to derive a mutable subtype from -an immutable base type.) - -An \class{intbv} object supports the same comparison, numeric, -bitwise, logical, and conversion operations as \class{int} objects. See -\url{http://www.python.org/doc/current/lib/typesnumeric.html} for more -information on such operations. In all binary operations, -\class{intbv} objects can work together with \class{int} objects. -For mixed-type numeric operations, the result type is an \class{int} -or a \class{long}. For mixed-type bitwise operations, the result -type is an \class{intbv}. - -In addition, \class{intbv} objects support indexing and slicing -operations: - -\begin{tableiii}{clc}{code}{Operation}{Result}{Notes} - \lineiii{\var{bv}[\var{i}]} - {item \var{i} of \var{bv}} - {(1)} - \lineiii{\var{bv}[\var{i}] = \var{x}} - {item \var{i} of \var{bv} is replaced by \var{x}} - {(1)} - \lineiii{\var{bv}[\var{i}:\var{j}]} - {slice of \var{bv} from \var{i} downto \var{j}} - {(2)(3)} - \lineiii{\var{bv}[\var{i}:\var{j}] = \var{t}} - {slice of \var{bv} from \var{i} downto \var{j} is replaced - by \var{t}} - {(2)(4)} -\end{tableiii} - -\begin{description} -\item[(1)] Indexing follows the most common hardware design - conventions: the lsb bit is the rightmost bit, and it has - index 0. This has the following desirable property: if the - \class{intbv} value is decomposed as a sum of powers of 2, - the bit with index \var{i} corresponds to the term - \code{2**i}. - -\item[(2)] In contrast to standard Python sequencing conventions, - slicing range are downward. This is a consequence of the - indexing convention, combined with the common convention - that the most significant digits of a number are the - leftmost ones. The Python convention of half-open ranges is - followed: the bit with the highest index is not - included. However, it is the \emph{leftmost} bit in this - case. As in standard Python, this takes care of one-off - issues in many practical cases: in particular, - \code{bv[\var{i}:]} returns \var{i} bits; - \code{bv[\var{i}:\var{j}]} has \code{\var{i}-\var{j}} - bits. When the low index \var{j} is omitted, it defaults - to \code{0}. When the high index \var{i} is omitted, it - means ``all'' higher order bits. - -\item[(3)] The object returned from a slicing access operation is always a - positive \class{intbv}; higher order bits are implicitly - assumed to be zero. The bit width is implicitly stored in - the return object, so that it can be used in concatenations - and as an iterator. In addition, for a bit width w, the - \var{min} and \var{max} attributes are implicitly set to - \code{0} and \code{2**w}, respectively. - -\item[(4)] When setting a slice to a value, it is checked whether the - slice is wide enough. -\end{description} - -In addition, an \class{intbv} object supports the iterator protocol. This -makes it possible to iterate over all its bits, from the high index to -index 0. This is only possible for \class{intbv} objects with a -defined bit width. - - - -\subsection{Miscellaneous modeling support functions\label{ref-model-misc}} -\declaremodule{}{myhdl} - -\begin{funcdesc}{bin}{num \optional{, width}} -Returns a bit string representation. If the optional \var{width} -is provided, and if it is larger than the width of the default -representation, the bit string is padded with the sign bit. - -This function complements the standard Python conversion functions -\code{hex} and \code{oct}. A binary string representation is often -useful in hardware design. -\end{funcdesc} - -\begin{funcdesc}{concat}{base \optional{, arg \moreargs}} -Returns an \class{intbv} object formed by concatenating the arguments. - -The following argument types are supported: \class{intbv} objects with -a defined bit width, \class{bool} objects, signals of the previous -objects, and bit strings. All these objects have a defined bit -width. The first argument \var{base} is special as it doesn't need to -have a defined bit width. In addition to the previously mentioned -objects, unsized \class{intbv}, \class{int} and \class{long} objects -are supported, as well as signals of such objects. -\end{funcdesc} - -\begin{funcdesc}{downrange}{high \optional{, low=0}} -Generates a downward range list of integers. - -This function is modeled after the standard \code{range} function, but -works in the downward direction. The returned interval is half-open, -with the \var{high} index not included. \var{low} is optional and -defaults to zero. This function is especially useful in conjunction -with the \class{intbv} class, that also works with downward indexing. -\end{funcdesc} - -\begin{funcdesc}{enum}{arg \optional{, arg \moreargs} \optional{, encoding='binary'}} -Returns an enumeration type. - -The arguments should be string literals that represent the desired -names of the enumeration type attributes. The returned type should be -assigned to a type name. For example: -\begin{verbatim} -t_EnumType = enum('ATTR_NAME_1', 'ATTR_NAME_2', ...) -\end{verbatim} -The enumeration type identifiers are available as attributes of -the type name, for example: \code{t_EnumType.ATTR_NAME_1} - -The optional keyword argument \var{encoding} specifies the encoding -scheme used in Verilog output. The available encodings are \code{'binary'}, -\code{'one_hot'}, and \code{'one_cold'}. -\end{funcdesc} - -\begin{funcdesc}{instances}{} -Looks up all \myhdl\ instances in the local name space and returns them -in a list. - -\end{funcdesc} - - -\section{Co-simulation\label{ref-cosim}} -\declaremodule{}{myhdl} - -\subsection{\myhdl\ \label{ref-cosim-myhdl}} - -\begin{classdesc}{Cosimulation}{exe, **kwargs} -Class to construct a new Cosimulation object. - -The \var{exe} argument is a command string to -execute an HDL simulation. The \var{kwargs} keyword -arguments provide a named association between signals -(regs \& nets) in the HDL simulator and signals in the -\myhdl\ simulator. Each keyword should be a name listed -in a \code{\$to_myhdl} or \code{\$from_myhdl} call in -the HDL code. Each argument should be a \class{Signal} -declared in the \myhdl\ code. - -\end{classdesc} - -\subsection{Verilog \label{ref-cosim-verilog}} - -\begin{funcdesc}{\$to_myhdl}{arg, \optional{, arg \moreargs}} -Task that defines which signals (regs \& nets) should be -read by the \myhdl\ simulator. -This task should be called at the start of the simulation. -\end{funcdesc} - -\begin{funcdesc}{\$from_myhdl}{arg, \optional{, arg \moreargs}} -Task that defines which signals should be -driven by the \myhdl\ simulator. In Verilog, only regs -can be specified. -This task should be called at the start of the simulation. -\end{funcdesc} - - -\subsection{VHDL \label{ref-cosim-vhdl}} - -Not implemented yet. - -\section{Conversion to Verilog\label{ref-conv}} -\declaremodule{}{myhdl} - -\subsection{Conversion \label{ref-conv-conv}} - -\begin{funcdesc}{toVerilog}{func \optional{, *args} \optional{, **kwargs}} -Converts a \myhdl\ design instance to equivalent Verilog -code, and also generates a test bench to verify it. -\var{func} is a function that returns an instance. -\function{toVerilog()} calls \var{func} under its control -and passes \var{*args} and \var{**kwargs} to the call. - -The return value is the same as would be returned by the call -\code{func(*args, **kwargs)}. It should be assigned -to an instance name. - -The top-level instance name and the basename of the Verilog output -filename is \code{func.func_name} by default. - -For more information about the restrictions on convertible -\myhdl\ code, see section~\ref{conv-subset} in -Chapter~\ref{conv}. -\end{funcdesc} - -The \function{toVerilog} callable has the following attribute: - -\begin{memberdesc}[toVerilog]{name} - -This attribute is used to overwrite the default top-level instance -name and the basename of the Verilog output filename. - -\end{memberdesc} - -\subsection{User-defined Verilog code \label{ref-conv-user}} - -A user can insert user-defined code in the Verilog output -by using the \code{__verilog__} hook. - -\begin{datadesc}{__verilog__} -When defined within a function under elaboration, the -\code{__verilog__} hook variable specifies user-defined code that -should be used instead of converted code for that function. The -user-defined code should be a Python format string that uses keys to -refer to the variables that should be interpolated in the string. Any -variable in the function context can be referred to. - -Note that this hook cannot be used inside generator functions or -decorated local functions, as these are not elaborated. -\end{datadesc} diff --git a/olddoc/manual/tbfsm.png b/olddoc/manual/tbfsm.png deleted file mode 100644 index 5d4ca254544cbe74afcd726ee2b405cc87367a9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9150 zcmeHtc|26_`}bHfC?VNniX>S|qwI`5*=8bZmcm#=F~~NSOm=OSp|LL`TS!8dQiMS` zBg&GH93f?r3G*C%Ki}_f`TzOrdCu!~&wZ|QU)TG3U)OcceV_ZhCJ}9J#KkGX34_77 zj4$Y4g29+U7>uckodvq`0(~R3H=%yeL|y7c|qSNFkSEHJdGl>u~}!C+X06u@9e z7z_)85n(V2bZt*UB4J1@3`v9`DKI2sZxD-wVX-hQ5r(C}u#7!jA`(W#!iYo|kpd$! z_Dm^A7zGQX5MdMwjKYABU<@RTfrT-MFa`y3wgAYBR;Ng*OB6eNWKafD2f3@nmCL^3Ey z2ILiD4S_+VA(jv=Xbf@;VMEXm7G%uW3usS<4k8vy!D1PE@j-4OiAcl}DOe(7FIQJJg zXrWX>`G9Cb)=)YiPEf#5gb-^83?dC#LbMXP{u}Tf<-alP75^`-y$Jq# zf}kNRs7g@spqM&4J2NseqG7P;=)E5a35mabv~Es0Oj!dK4HI$pfWcNTizLs_&wG1& z7Z(?gjg4hyX7=~@cXf5`?Cc~YB!D1TQc^N9G6I7=g2DQEc&@OsKg8j1cs#zgwl?%p zx1N=!V`vr+kK^LvqQAd?+s}9z=ow(TW@4ldOV}rN0TMU@F4zUaV26VC8q+iuvG?@A zgN)4#;G=NfL)?-oWoJEMu%j?zeI2XNM=KhdYa&MU_^7&i_iFdKizJbeA88-Zk zWvQsBPvyr}7!n170ix^gk9`nuV;CIL=u*wuREJ;bVe~An{D@P7KRbC z=9NAOcBaJP1Fr1EygE8~+W`KYj?)=zp1dwe~XXEzN zHraJSuGcP0PEPOQW&4S{p&o3do1^*^d~0*cq!>%!{>J%n{2Rd+<^ox~ZifhhQYix? z_}ey&Mf&`YA6JQ@9a?gq5q1DcVWj5nERnpnbpPj(MaTMt+fv^S1n|F6KF>4CuXL)S z*qWRs!;RNf>+ z=5by45tJ9I@QItHjyarjtI(qB!>;@ZqQzifFJ~|E%30c5|HEi=?5BvC<8Ma1@s1OW z4Ez-9H(#0AQI;l!tQT}s@h;~P4~8&bL`UBpvrs&uL+f*0STxl`J z*)5iBnL12vs}%G(=J&|_!I4_!W$LXLKNK(sMg0A!fj1y9u={IH@@Lu~A<%;E`Qs}A zpMJ7KwQS{i{u4{%tZ$c+BkN%rU(!oIE+|YK>Q~GRAUteeAC{C%VeM7k%3!ujc^4pg zG^6VKsj~v{M|VHMHEf>wR@r$Qe&2bd`K zuBm@M+o)K&H%odn>)w+d&OGB$Q+1Jjjw)BF(r~5zJWlFM!aagW@NukPv2DOHiR2Uu ztS#H|2Gg1dGq=krpG93SJ(4(Hb|j#lNB!nuI>LGMb}Dr$@+hX(k0o25o6@5m(&^tP zDBNteJ1)g1hcI={+nDYSo#WX0-8>=O#Idzr@TC7jf@^kQ3F60ft?9B>%zkf>FXMu1 z_#3@D?l0qyZ=Diqd1H)S)z-LMVzZc*t-kU#I^_ul5BrKA{gmYy?^J5D`SOoYZTTPS zjPH?a#?Mq7j^rCR^()kg%>;7mZJId6dEPrOK)k607R{O~U?c=%Em9FI- zQmN*A+p}@y6t9 zbxeESM74@v{sulcm*p#*_^PHh#$5Hc%B$OYORbuHyife{PIu5{|FE;$UAx=&J~-8^ z{ou2mAAEgB?t}$!EQvT-ejbjfawh3>F%5zV7neS+2t*4jeN|$FALu@KIwW%u7SHfI z>e4X<{CsAypmpVJ)gXHsJ5#-(@73v?~<_4_}PFTG}$%R51fpyImsB0-g9%(i;R&+`(LmFq(jQp zv03NCoQrdKCFkIC%)v^Z#~qofMpF;R6|BA=yr|_a*#Blnw2SZQ<9ChS`?)Wd=>jy( zp_EHZDac=yXJ^Un^x@8IH${zspp4rSR_ksPoaoJ8!>{x*WW*|G0?B`(wRkHX@XPP7 z&Ren3zVR*!OZhYSG=vqC*>TKrO^#ovIQ2k}`CF$gek6GC9Uh*f)*#a9q%8}L{bR=MwCTs__(NpGxbQ|Sf$`hKhM^f&smp({ zC@Scdz!Ds%#sM5NU;^p=6+H|uo)Uy?B3&BoZ)w>8hDgs_1h8o418+?an~IKFKeB68 z+{JtV=ANIc{LW=PHePz%Ir*FjoSYshvfuq-U4XZv9U#v$Qn_{~?3Uk&^Tddv7iaL# zo)Itz>2kf`9Cok=(U_k|m-Q4+XbGHU#%;AThqXA^M1_n`7Ufa@NV$H^+C9j;S;Jia zo=^5%NYi6Y3-9Fwf~4z`UFp{H1zmuTKdnIPSCi1k)oo$ilX`*2>te|6;2w>|-?crT zP(Z1AL3t}}^H6_xUUvB|B6f5r8dwn;F&i zKMY^x*-7g*J!&C95V>2Y$t=_q7=_0B_Pz8Mh-t|c8XI@-itI~kIow>{{esytjjo9` zvtE)7%EE5`(YzvKHz9F7__E@qqfRj{wbh8ucTPdmh2lKP5CFOPi-xeCLDvicFc#4=2%|LIg6~9Ep6m5RBE_z&iOkiy3#n6?>gOG$$iZi z4jAjtqBs41MI8VotSxftB~Fd$%obx&j+cwzgd*`&s+UrfOVwZ(>Q2iIMa8w42?5&D zYtdhw`ljW2y6vy-+kO;!yYCEm(W|4yXiBBhovMxmUB?ycuHV!=v)UEzLMVV^kslCb zhC4lEE01(KHmCkpzu97SXpP;gS6eKRI`vI9Q$G9!H8Rda@>9WvjYWeFXyegavQF1B zbv4_LYQC&(ejiPbpeBWli=vgm?WS?xuxPc`b^qojIJn=ssFZVS7+5zaKn&A!hTm-0&^TkUaK>;N2wC6Tpv!M_29r z9I@Cw=Ild2`6?XW>sFYA;bt?jbH3@}>Q>WBnYpM4{QMZe&zEc;Wto+m>5xUNPHcJM zRv%O=Z#Xp&piJej@v2rA?Oh*c1@mvE^_yPYBK-yZ)hq#q_kdaf#1H*NUYMx(l5c~C z;ekcV$CO!2nvzqxJR}^0i)-v!hcA(Ra<6`fw@BkMdC|a{+|q0!S+3%ZG;O@pUFDu{ ze$P%7{2`Ic@rTO&HD+CbH2Hg}->xOIUR`u&;oYato?j_(?#@B5=G07mO_dJe;sU>f zhJf5lMKwx^MdXZJ&`f?x?OVItS(D;CYc3lT4lpE<-p_R4x|0v!y?qvl8=gaZe0*hQ z2~_YlvkzfxYGn*Dxj3uCMK!jW#Ksi08`EmwGV7VHalk1_&8KwHp*30AUH~^(r>}YK z6=uJwUef?aIBsFapYvd@x%OgP^ zP&>tmPX8Bnhh@59&M$ntxKNr8Pf58eO-EHLnA^ql$}tf0AbWs4_LH)AMWMKI=9nS` zUWRctlL|R6QVqu*M)nV;)WLu_xcK)#mINmdRLr$jYO`HXi>BX<{oqo9TD;{UIbjsaY227o z?uz!{(Qb`cS*G@yy&yQAZNzSjnc}F@ksgw0?&>cUhkzAr;zOrMQ{`sCs{CK1)X+}~ zPm=lxs>i@@N7}J7H|uOX7;c>y>3lJaa#>Qy`7e{U?ct@AlIISkWAN3g#CIOg8Sf__ z1Y!`}Z#2M{$Chm(GegdgMBW}Wq@I#_Uok5<^6Qz!jg=?y;n&-3I$V(CxQG(dN&Q{7&K z2_^@ZU(6s&yt;lQ4TjYtiQ%T3P-VwKtN=Ln#tn12@RH)7;*ndilGmOc11sTYJ}ym? zMZ0(h5CbS~iWoUv?HKsgCJSp;Y-LiK1)7|F*c}?by*KBM|ST4uX z56hS*j4Bj0t8s%RFB8LEtSWEOuYA+$S1LvkB878RhMnyPk;Qr8MO@sIrBA2!yG%yO zx&wGiU_cX}Ea))cg$@~pi$71cJ$FivjbM=#7^Te*p3m#Dyue#|{>=xwW1uG689zx4 z%nXJb7*m#SQb79fI1_j?rAE{nh=Hu}`b81@zh}Ys6uou))*Ud$KEv zCe9*Ma4_Q}s?8ui~cf!bel@%J%s=6pKdoz?6 zsQ>SF17L_(hbOcs8VP#eqZCgLIS7`m*A|;Rz3`NcHs<dAj3f89L`ciPFmU!?%Js`COX#a=(rg4Jss z>bJ3|wlJzKcRKy>gNNOq_+nz{4Euyy*)aM}L5j7}l%x5$AWoUjRcN$FV6*czM%kfB zFIufzAmw^AeWrRJp!m$i7YD2u#C3e+AiMg$%+@2l_(o>Mja2$c3WRfo{*1CJNUPiD z$_ElEUW&3znxhgZF&FO-J01~VdM@0&N*z$qK#^^A6L+|c-RNE;g+SB`f5EyCQw0_W@0MV&2v>fhkfTGUyNxzCk#*d|Y{b z)vDf&xGvH9^J{o{#3yRyrF0s3yb@uihOTu+iIF`3SIua;2C%5~#x6W+B35>Zy6te9 zVc8JolDVuwKCL=9aHiHH_j)R?qsHsvmg0lMYVZJp~S>YDRL8mSyFm z3pwn1&bVbpIhyo4x^Jb5uI@z!1(CEb<$g?Q&tN<4Kj_sMX@JdQmtN zXZI=7$E(>#mT~5Hgqki%!sL(&sAa5fzRinCX$kw1kLYA2A1E&WK;Du52ihOweDk1} zFb*zDn@zGQ?}9vR+-@zmC=>`OKlPYO*mSU%3cD z%dWdmz%16aDCXHtgAbiZD0$3cjiZj(4tVEe4qlnuI{w-go$5i_c$2U&J{MYJqWP_k z2^?Msv0fwl*HF^@g?Q75s{3`D+Wl(TGj?^b6qWF}Y7annc|U1QMw%pXo8 zUCfk2ia%FR|K90XPx%hwmXAB_c#gz`?Jz@kV6pfz6A%;D^?&1BjRREAkh8;T1cZps z#$XnMOK8oz}j-P~#`cjj_QQ|QS3 zkCq=9po4vS=*5YI8hrYcr##+>32K@{8i1$q1)uX!BaX?YC?5%IOQEO=tJR zMidj}8M(m>DVGr`hQAgjl=4X1XDcAg5#W~Z$Yt<1a{pX(iX?3}F3F?wU-5KJKVFS` zo4lQ8^WEV>ZIQyG?g&jm_m2wM=i?@y9oLq;$(^NaSc5kJxKDR9GLjS!|9Ht{O5uo- zjN3VwvK_C!vbZk|<>=eO6F*;;_4O_7dOH2yLenTK&3AW3biS5~cK|w6rsPyh?00wP z6v@d*HRr2B8ib#tt=9tgXbotuQoFXLKp#lg-vc1Q(-k9CK-F61w~kqQ2EO!ajP|qb z;J-2E>qKIpAeo#Z>pyjDc#hvU!8Dn>%6uyvo#j%Nd{#Xo$NB9|-rb+K2tG~b1|(y z*|{gB`VZ7PHJN{=rk@ZazyI&^aj9d9q4#L2y0fZ&ngZTy*P(Ft;!e1pCNlDAJ=vqI z$=Yi-x6moOqf8TxKN49=KxtMK_j3cT(GG9>dA=y$X2Ka5Wg*BtZ{3xn2A;q{Ug#zh z$K-1~TTka6E?=f(4WmPx^0ZRmKw>mqZOg|#AuK?)WjBa)Q&7#hQ%stTtj!9%?{yxP zC0A0ymCfyoML;GhG?&(9bd+T=XP?#$`CWqfN_AA{Cma1s^AaGFdjr@a7aU3yRhYq-?7N^oMX>#|Kp440BwB# z(@>oPaniIsY9|yhky5_wqt>!5I?o^}+etBOF!&lb-o<3&9M9aW*h!!}NN7Gx#GhFCeD^#RA zz+3tL)V~))&2+V#QYt68HU;V%p+5OP@->?Mf1cn)j8Vf=`#m_Qw`QW@{!6ZMsx*(K zn@gEw3Ug1AjG%3b9ahQYpIM;T&c0*MH`G^0)BDJOY^T~ejoL-vqcjWr+QXR%bkCFK z*-i7UZ^`tz-#LVPTY+flff12lVFJoA#?Jl2>$GSgu-(qSOQDO0oK>XtzVZRqi>vj3 zUcoAUBdxIJ_xG%s+O(_TU6zIBoxjKqRplqnqStVtCjgoG`8!HQnWd2Lu%y{7w8z|X zK^k^Rm{4vMnF?bY7(pHwx~<00)W|9dNVRS2nyo;GXiK_^Jy*2nK5%0V)s{cojCQv1 z%*^v<2lnr=;_~Nvwef6pMt$M^S@3yclRatv#Pt81dqY!N{7A3=*IKLweOCMTy8Qpo z|Mh(2F zu6UsQgbZ5y(%urvLL*#O1~(If3Ze?as(N_q=oi$`+Gx$Oxx3g3orVn;=-J=sg#E|( zUl!-U=M8mi(9q-rJ0NQPhRo>C&~IZihITD=(Q43S_`lj`G9%>a>M_trkmIql3EHDA z1G}DfmBa|M{*M)58@h>!IyE8B?W&$kKmHbUTej* zOdxPuDo16$K68)FxsM{b@YPuq`$21`#=IG4%XMNw*>TL~xc;|UYT^0DdK;svgVe{3 zuDFd(RE9TAT&R_Eqf!s&wG&12;zx-+HmNK!&u_+B%3d&VjC`AWIB4#yj#=;PC&bj2 z3F~8EM0*mw8}f7MK<)&Y5&lF8NLS#qY7;1Miu>-#_B7|;$q51~d3D5MogNVAI^1Zl zn`DF|4>?kXtoP1%A5dt{3KaHKKFWdq9&mE+zX0a1p}h}Za=}3zX~BQC!^14JO>TCz iw%sEi?V}5JHt^qhKAmz7mTQ7+V8#aK`Zc;PvHu5jfyCbc diff --git a/olddoc/manual/unittest.tex b/olddoc/manual/unittest.tex deleted file mode 100644 index e3622196..00000000 --- a/olddoc/manual/unittest.tex +++ /dev/null @@ -1,379 +0,0 @@ -\chapter{Unit testing \label{unittest}} - -\section{Introduction \label{unittest-intro}} - -Many aspects in the design flow of modern digital hardware design can -be viewed as a special kind of software development. From that -viewpoint, it is a natural question whether advances in software -design techniques can not also be applied to hardware design. - -One software design approach that gets a lot of attention recently is -\index{extreme programming}% -\emph{Extreme Programming} (XP). It is a fascinating set of techniques and -guidelines that often seems to go against the conventional wisdom. On -other occasions, XP just seems to emphasize the common sense, which -doesn't always coincide with common practice. For example, XP stresses -the importance of normal workweeks, if we are to have the -fresh mind needed for good software development. - -It is not my intention nor qualification to present a tutorial on -Extreme Programming. Instead, in this section I will highlight one XP -concept which I think is very relevant to hardware design: the -importance and methodology of unit testing. - -\section{The importance of unit tests \label{unittest-why}} - -Unit testing is one of the corner stones of Extreme Programming. Other -XP concepts, such as collective ownership of code and continuous -refinement, are only possible by having unit tests. Moreover, XP -emphasizes that writing unit tests should be automated, that they should -test everything in every class, and that they should run perfectly all -the time. - -I believe that these concepts apply directly to hardware design. In -addition, unit tests are a way to manage simulation time. For example, -a state machine that runs very slowly on infrequent events may be -impossible to verify at the system level, even on the fastest -simulator. On the other hand, it may be easy to verify it exhaustively -in a unit test, even on the slowest simulator. - -It is clear that unit tests have compelling advantages. On the other -hand, if we need to test everything, we have to write -lots of unit tests. So it should be easy and pleasant -to create, manage and run them. Therefore, XP emphasizes the need for -a unit test framework that supports these tasks. In this chapter, -we will explore the use of the \code{unittest} module from -the standard Python library for creating unit tests for hardware -designs. - - -\section{Unit test development \label{unittest-dev}} - -In this section, we will informally explore the application of unit -test techniques to hardware design. We will do so by a (small) -example: testing a binary to Gray encoder as introduced in -section~\ref{intro-indexing}. - -\subsection{Defining the requirements \label{unittest-req}} - -We start by defining the requirements. For a Gray encoder, we want to -the output to comply with Gray code characteristics. Let's define a -\dfn{code} as a list of \dfn{codewords}, where a codeword is a bit -string. A code of order \code{n} has \code{2**n} codewords. - -A well-known characteristic is the one that Gray codes are all about: - -\newtheorem{reqGray}{Requirement} -\begin{reqGray} -Consecutive codewords in a Gray code should differ in a single bit. -\end{reqGray} - -Is this sufficient? Not quite: suppose for example that an -implementation returns the lsb of each binary input. This would comply -with the requirement, but is obviously not what we want. Also, we don't -want the bit width of Gray codewords to exceed the bit width of the -binary codewords. - -\begin{reqGray} -Each codeword in a Gray code of order n must occur exactly once in the -binary code of the same order. -\end{reqGray} - -With the requirements written down we can proceed. - -\subsection{Writing the test first \label{unittest-first}} - -A fascinating guideline in the XP world is to write the unit test -first. That is, before implementing something, first write the test -that will verify it. This seems to go against our natural inclination, -and certainly against common practices. Many engineers like to -implement first and think about verification afterwards. - -But if you think about it, it makes a lot of sense to deal with -verification first. Verification is about the requirements only --- so -your thoughts are not yet cluttered with implementation details. The -unit tests are an executable description of the requirements, so they -will be better understood and it will be very clear what needs to be -done. Consequently, the implementation should go smoother. Perhaps -most importantly, the test is available when you are done -implementing, and can be run anytime by anybody to verify changes. - -Python has a standard \code{unittest} module that facilitates writing, -managing and running unit tests. With \code{unittest}, a test case is -written by creating a class that inherits from -\code{unittest.TestCase}. Individual tests are created by methods of -that class: all method names that start with \code{test} are -considered to be tests of the test case. - -We will define a test case for the Gray code properties, and then -write a test for each of the requirements. The outline of the test -case class is as follows: - -\begin{verbatim} -from unittest import TestCase - -class TestGrayCodeProperties(TestCase): - - def testSingleBitChange(self): - """ Check that only one bit changes in successive codewords """ - .... - - - def testUniqueCodeWords(self): - """ Check that all codewords occur exactly once """ - .... -\end{verbatim} - -Each method will be a small test bench that tests a single -requirement. To write the tests, we don't need an implementation of -the Gray encoder, but we do need the interface of the design. We can -specify this by a dummy implementation, as follows: - -\begin{verbatim} -def bin2gray(B, G, width): - ### NOT IMPLEMENTED YET! ### - yield None -\end{verbatim} - -For the first requirement, we will write a test bench that applies all -consecutive input numbers, and compares the current output with the -previous one for each input. Then we check that the difference is a -single bit. We will test all Gray codes up to a certain order -\code{MAX_WIDTH}. - -\begin{verbatim} - def testSingleBitChange(self): - """ Check that only one bit changes in successive codewords """ - - def test(B, G, width): - B.next = intbv(0) - yield delay(10) - for i in range(1, 2**width): - G_Z.next = G - B.next = intbv(i) - yield delay(10) - diffcode = bin(G ^ G_Z) - self.assertEqual(diffcode.count('1'), 1) - - for width in range(1, MAX_WIDTH): - B = Signal(intbv(-1)) - G = Signal(intbv(0)) - G_Z = Signal(intbv(0)) - dut = bin2gray(B, G, width) - check = test(B, G, width) - sim = Simulation(dut, check) - sim.run(quiet=1) -\end{verbatim} - -Note how the actual check is performed by a \code{self.assertEqual} -method, defined by the \code{unittest.TestCase} class. - -Similarly, we write a test bench for the second requirement. Again, we -simulate all numbers, and put the result in a list. The requirement -implies that if we sort the result list, we should get a range of -numbers: - -\begin{verbatim} - def testUniqueCodeWords(self): - """ Check that all codewords occur exactly once """ - - def test(B, G, width): - actual = [] - for i in range(2**width): - B.next = intbv(i) - yield delay(10) - actual.append(int(G)) - actual.sort() - expected = range(2**width) - self.assertEqual(actual, expected) - - for width in range(1, MAX_WIDTH): - B = Signal(intbv(-1)) - G = Signal(intbv(0)) - dut = bin2gray(B, G, width) - check = test(B, G, width) - sim = Simulation(dut, check) - sim.run(quiet=1) -\end{verbatim} - - -\subsection{Test-driven implementation \label{unittest-impl}} - -With the test written, we begin with the implementation. For -illustration purposes, we will intentionally write some incorrect -implementations to see how the test behaves. - -The easiest way to run tests defined with the \code{unittest} -framework, is to put a call to its \code{main} method at the end of -the test module: - -\begin{verbatim} -unittest.main() -\end{verbatim} - -Let's run the test using the dummy Gray encoder shown earlier: - -\begin{verbatim} -% python test_gray.py -v -Check that only one bit changes in successive codewords ... FAIL -Check that all codewords occur exactly once ... FAIL - -\end{verbatim} - -As expected, this fails completely. Let us try an incorrect -implementation, that puts the lsb of in the input on the output: - -\begin{verbatim} -def bin2gray(B, G, width): - ### INCORRECT - DEMO PURPOSE ONLY! ### - - @always_comb - def logic(): - G.next = B[0] - - return logic -\end{verbatim} - - -Running the test produces: - -\begin{verbatim} -% python test_gray.py -v -Check that only one bit changes in successive codewords ... ok -Check that all codewords occur exactly once ... FAIL - -====================================================================== -FAIL: Check that all codewords occur exactly once ----------------------------------------------------------------------- -Traceback (most recent call last): - File "test_gray.py", line 109, in testUniqueCodeWords - sim.run(quiet=1) -... - File "test_gray.py", line 104, in test - self.assertEqual(actual, expected) - File "/usr/local/lib/python2.2/unittest.py", line 286, in failUnlessEqual - raise self.failureException, \ -AssertionError: [0, 0, 1, 1] != [0, 1, 2, 3] - ----------------------------------------------------------------------- -Ran 2 tests in 0.785s -\end{verbatim} - -Now the test passes the first requirement, as expected, but fails the -second one. After the test feedback, a full traceback is shown that -can help to debug the test output. - -Finally, if we use the correct implementation as in -section~\ref{intro-indexing}, the output is: - -\begin{verbatim} -% python test_gray.py -v -Check that only one bit changes in successive codewords ... ok -Check that all codewords occur exactly once ... ok - ----------------------------------------------------------------------- -Ran 2 tests in 6.364s - -OK -\end{verbatim} - - - -\subsection{Changing requirements \label{unittest-change}} - -In the previous section, we concentrated on the general requirements -of a Gray code. It is possible to specify these without specifying the -actual code. It is easy to see that there are several codes -that satisfy these requirements. In good XP style, we only tested -the requirements and nothing more. - -It may be that more control is needed. For example, the requirement -may be for a particular code, instead of compliance with general -properties. As an illustration, we will show how to test for -\emph{the} original Gray code, which is one specific instance that -satisfies the requirements of the previous section. In this particular -case, this test will actually be easier than the previous one. - -We denote the original Gray code of order \code{n} as \code{Ln}. Some -examples: - -\begin{verbatim} -L1 = ['0', '1'] -L2 = ['00', '01', '11', '10'] -L3 = ['000', '001', '011', '010', '110', '111', '101', 100'] -\end{verbatim} - -It is possible to specify these codes by a recursive algorithm, as -follows: - -\begin{enumerate} -\item L1 = ['0', '1'] -\item Ln+1 can be obtained from Ln as follows. Create a new code Ln0 by -prefixing all codewords of Ln with '0'. Create another new code Ln1 by -prefixing all codewords of Ln with '1', and reversing their -order. Ln+1 is the concatenation of Ln0 and Ln1. -\end{enumerate} - -Python is well-known for its elegant algorithmic -descriptions, and this is a good example. We can write the algorithm -in Python as follows: - -\begin{verbatim} -def nextLn(Ln): - """ Return Gray code Ln+1, given Ln. """ - Ln0 = ['0' + codeword for codeword in Ln] - Ln1 = ['1' + codeword for codeword in Ln] - Ln1.reverse() - return Ln0 + Ln1 -\end{verbatim} - -The code \samp{['0' + codeword for ...]} is called a \dfn{list -comprehension}. It is a concise way to describe lists built by short -computations in a for loop. - -The requirement is now that the output code matches the -expected code Ln. We use the \code{nextLn} function to compute the -expected result. The new test case code is as follows: - -\begin{verbatim} -class TestOriginalGrayCode(TestCase): - - def testOriginalGrayCode(self): - """ Check that the code is an original Gray code """ - - Rn = [] - - def stimulus(B, G, n): - for i in range(2**n): - B.next = intbv(i) - yield delay(10) - Rn.append(bin(G, width=n)) - - Ln = ['0', '1'] # n == 1 - for n in range(2, MAX_WIDTH): - Ln = nextLn(Ln) - del Rn[:] - B = Signal(intbv(-1)) - G = Signal(intbv(0)) - dut = bin2gray(B, G, n) - stim = stimulus(B, G, n) - sim = Simulation(dut, stim) - sim.run(quiet=1) - self.assertEqual(Ln, Rn) -\end{verbatim} - -As it happens, our implementation is apparently an original Gray code: - -\begin{verbatim} -% python test_gray.py -v TestOriginalGrayCode -Check that the code is an original Gray code ... ok - ----------------------------------------------------------------------- -Ran 1 tests in 3.091s - -OK -\end{verbatim} - - - - diff --git a/olddoc/paper-a4/pypaper.sty b/olddoc/paper-a4/pypaper.sty deleted file mode 100644 index 0ae96180..00000000 --- a/olddoc/paper-a4/pypaper.sty +++ /dev/null @@ -1,18 +0,0 @@ -% -% Change this to say a4paper instead of letterpaper if you want A4. These -% are the latex defaults. -% -\newcommand{\py@paper}{a4paper} -\newcommand{\py@ptsize}{11pt} - -% These set up the fonts for the documents. -% -% The "times" package makes the default font the PostScript Times -% font, which makes for smaller PostScript and a font that more people -% like. -% -% The "avant" package causes the AvantGarde font to be used for -% sans-serif text, instead of the uglier Helvetica set up by the "times" -% package. -% -% \RequirePackage{times}\typeout{Using Times instead of Computer Modern.} diff --git a/olddoc/paper-letter/pypaper.sty b/olddoc/paper-letter/pypaper.sty deleted file mode 100644 index be46451f..00000000 --- a/olddoc/paper-letter/pypaper.sty +++ /dev/null @@ -1,18 +0,0 @@ -% -% Change this to say a4paper instead of letterpaper if you want A4. These -% are the latex defaults. -% -\newcommand{\py@paper}{letterpaper} -\newcommand{\py@ptsize}{10pt} - -% These set up the fonts for the documents. -% -% The "times" package makes the default font the PostScript Times -% font, which makes for smaller PostScript and a font that more people -% like. -% -% The "avant" package causes the AvantGarde font to be used for -% sans-serif text, instead of the uglier Helvetica set up by the "times" -% package. -% -% \RequirePackage{times}\typeout{Using Times instead of Computer Modern.} diff --git a/olddoc/perl/SynopsisTable.pm b/olddoc/perl/SynopsisTable.pm deleted file mode 100644 index a77a016a..00000000 --- a/olddoc/perl/SynopsisTable.pm +++ /dev/null @@ -1,95 +0,0 @@ -package SynopsisTable; - -sub new{ - return bless {names=>'', info=>{}, file=>''}; -} - -sub declare{ - my($self,$name,$key,$type) = @_; - if ($self->{names}) { - $self->{names} .= ",$name"; - } - else { - $self->{names} .= "$name"; - } - $self->{info}{$name} = "$key,$type,"; -} - -# The 'file' attribute is used to store the filename of the node in which -# the table will be presented; this assumes that each table will be presented -# only once, which works for the current use of this object. - -sub set_file{ - my($self, $filename) = @_; - $self->{file} = "$filename"; -} - -sub get_file{ - my $self = shift; - return $self->{file}; -} - -sub set_synopsis{ - my($self,$name,$synopsis) = @_; - my($key,$type,$unused) = split ',', $self->{info}{$name}, 3; - $self->{info}{$name} = "$key,$type,$synopsis"; -} - -sub get{ - my($self,$name) = @_; - return split /,/, $self->{info}{$name}, 3; -} - -sub show{ - my $self = shift; - my $name; - print "names: ", $self->{names}, "\n\n"; - foreach $name (split /,/, $self->{names}) { - my($key,$type,$synopsis) = $self->get($name); - print "$name($key) is $type: $synopsis\n"; - } -} - -sub tohtml{ - my $self = shift; - my $oddrow = 1; - my $data = "\n"; - my $name; - foreach $name (split /,/, $self->{names}) { - my($key,$type,$synopsis) = $self->get($name); - my $link = ""; - $synopsis =~ s//%/g; - $synopsis =~ s//\&/g; - $data .= (' \n " : '>') - . "\n" - . " \n" - . " \n"); - $oddrow = !$oddrow; - } - $data .= "
$link$name$synopsis
\n"; - $data; -} - - -package testSynopsisTable; - -sub test{ - # this little test is mostly to debug the stuff above, since this is - # my first Perl "object". - my $st = SynopsisTable->new(); - $st->declare("sample", "sample", "standard"); - $st->set_synopsis("sample", "This is a little synopsis...."); - $st->declare("copy_reg", "copyreg", "standard"); - $st->set_synopsis("copy_reg", "pickle support stuff"); - $st->show(); - - print "\n\n"; - - my $st2 = SynopsisTable->new(); - $st2->declare("st2module", "st2module", "built-in"); - $st2->set_synopsis("st2module", "silly little synopsis"); - $st2->show(); -} - -1; # This must be the last line -- Perl is bogus! diff --git a/olddoc/perl/distutils.perl b/olddoc/perl/distutils.perl deleted file mode 100644 index 0bcd6ee9..00000000 --- a/olddoc/perl/distutils.perl +++ /dev/null @@ -1,21 +0,0 @@ -# LaTeX2HTML support for distutils.sty. - -package main; - -sub do_cmd_command { - return use_wrappers(@_[0], '', ''); -} - -sub do_cmd_option { - return use_wrappers(@_[0], '', ''); -} - -sub do_cmd_filevar { - return use_wrappers(@_[0], '', ''); -} - -sub do_cmd_XXX { - return use_wrappers(@_[0], '** ', ' **'); -} - -1; diff --git a/olddoc/perl/howto.perl b/olddoc/perl/howto.perl deleted file mode 100644 index 76791ebb..00000000 --- a/olddoc/perl/howto.perl +++ /dev/null @@ -1,12 +0,0 @@ -# -*- perl -*- -# -# This implements the Python howto class. All it really needs to do it -# load the "python" style. - -package main; - -do_require_package("article"); -do_require_package("alltt"); -do_require_package("python"); - -1; # sheesh.... diff --git a/olddoc/perl/isilo.perl b/olddoc/perl/isilo.perl deleted file mode 100644 index e990b36c..00000000 --- a/olddoc/perl/isilo.perl +++ /dev/null @@ -1,12 +0,0 @@ -package main; - -$USING_STYLES = 0; -$NO_NAVIGATION = 1; -$INDEX_COLUMNS = 1; -$MODULE_INDEX_COLUMNS = 1; - -sub child_line { - return ''; -} - -1; # stupid perl... diff --git a/olddoc/perl/l2hinit.perl b/olddoc/perl/l2hinit.perl deleted file mode 100644 index 6da39268..00000000 --- a/olddoc/perl/l2hinit.perl +++ /dev/null @@ -1,672 +0,0 @@ -# LaTeX2HTML support base for use with Python documentation. - -package main; - -use L2hos; - -$HTML_VERSION = 4.0; - -$MAX_LINK_DEPTH = 2; -$ADDRESS = ''; - -$NO_FOOTNODE = 1; -$NUMBERED_FOOTNOTES = 1; - -# Python documentation uses section numbers to support references to match -# in the printed and online versions. -# -$SHOW_SECTION_NUMBERS = 1; - -$ICONSERVER = '.'; -$IMAGE_TYPE = 'gif'; - -# Control where the navigation bars should show up: -$TOP_NAVIGATION = 1; -$BOTTOM_NAVIGATION = 1; -$AUTO_NAVIGATION = 0; - -$BODYTEXT = ''; -$CHILDLINE = "\n


\n"; -$VERBOSITY = 0; - -# default # of columns for the indexes -$INDEX_COLUMNS = 2; -$MODULE_INDEX_COLUMNS = 4; - -$HAVE_MODULE_INDEX = 0; -$HAVE_GENERAL_INDEX = 0; -$HAVE_TABLE_OF_CONTENTS = 0; - -$AESOP_META_TYPE = 'information'; - - -# A little painful, but lets us clean up the top level directory a little, -# and not be tied to the current directory (as far as I can tell). Testing -# an existing definition of $mydir is needed since it cannot be computed when -# run under mkhowto with recent versions of LaTeX2HTML, since this file is -# not read directly by LaTeX2HTML any more. mkhowto is required to prepend -# the required definition at the top of the actual input file. -# -if (!defined $mydir) { - use Cwd; - use File::Basename; - ($myname, $mydir, $myext) = fileparse(__FILE__, '\..*'); - chop $mydir; # remove trailing '/' - $mydir = getcwd() . "$dd$mydir" - unless $mydir =~ s|^/|/|; -} -$LATEX2HTMLSTYLES = "$mydir$envkey$LATEX2HTMLSTYLES"; -push (@INC, $mydir); - -($myrootname, $myrootdir, $myext) = fileparse($mydir, '\..*'); -chop $myrootdir; - - -# Hackish way to get the appropriate paper-*/ directory into $TEXINPUTS; -# pass in the paper size (a4 or letter) as the environment variable PAPER -# to add the right directory. If not given, the current directory is -# added instead for use with HOWTO processing. -# -if (defined $ENV{'PAPER'}) { - $mytexinputs = "$myrootdir${dd}paper-$ENV{'PAPER'}$envkey"; -} -else { - $mytexinputs = getcwd() . $envkey; -} -$mytexinputs .= "$myrootdir${dd}texinputs"; - - -# Change this variable to change the text added in "About this document..."; -# this should be an absolute pathname to get it right. -# -$ABOUT_FILE = "$myrootdir${dd}html${dd}stdabout.dat"; - - -sub custom_driver_hook { - # - # This adds the directory of the main input file to $TEXINPUTS; it - # seems to be sufficiently general that it should be fine for HOWTO - # processing. - # - my $file = $_[0]; - my($jobname, $dir, $ext) = fileparse($file, '\..*'); - $dir = L2hos->Make_directory_absolute($dir); - $dir =~ s/$dd$//; - $TEXINPUTS = "$dir$envkey$mytexinputs"; - print "\nAdding $dir to \$TEXINPUTS\n"; -} - - -$CUSTOM_BUTTONS = ''; - -sub make_nav_sectref($$) { - my($label, $title) = @_; - if ($title) { - if ($title =~ /\<[aA] /) { - $title =~ s/\<[aA] /
$title"; - } - return "$label: $title\n"; - } - return ''; -} - -@my_icon_tags = (); -$my_icon_tags{'next'} = 'Next Page'; -$my_icon_tags{'next_page'} = 'Next Page'; -$my_icon_tags{'previous'} = 'Previous Page'; -$my_icon_tags{'previous_page'} = 'Previous Page'; -$my_icon_tags{'up'} = 'Up One Level'; -$my_icon_tags{'contents'} = 'Contents'; -$my_icon_tags{'index'} = 'Index'; -$my_icon_tags{'modules'} = 'Module Index'; - -@my_icon_names = (); -$my_icon_names{'previous_page'} = 'previous'; -$my_icon_names{'next_page'} = 'next'; - -sub get_my_icon($) { - my $name = $_[0]; - my $text = $my_icon_tags{$name}; - if ($my_icon_names{$name}) { - $name = $my_icon_names{$name}; - } - if ($text eq '') { - $name = 'blank'; - } - my $iconserver = ($ICONSERVER eq '.') ? '' : "$ICONSERVER/"; - return "$text"; -} - -sub use_my_icon($) { - my $s = $_[0]; - if ($s =~ /\/) { - my $r = get_my_icon($1); - $s =~ s/\/$r/; - } - return $s; -} - -sub make_nav_panel() { - my $s; - my $BLANK_ICON = get_my_icon('blank'); - $NEXT = $NEXT_TITLE ? use_my_icon("$NEXT") : $BLANK_ICON; - $UP = $UP_TITLE ? use_my_icon("$UP") : $BLANK_ICON; - $PREVIOUS = $PREVIOUS_TITLE ? use_my_icon("$PREVIOUS") : $BLANK_ICON; - $CONTENTS = use_my_icon("$CONTENTS"); - $INDEX = $INDEX ? use_my_icon("$INDEX") : $BLANK_ICON; - if (!$CUSTOM_BUTTONS) { - $CUSTOM_BUTTONS = $BLANK_ICON; - } - $s = ('' - . "\n" - # left-hand side - . "\n" - . "\n" - . "\n" - # title box - . "\n" - # right-hand side - . "\n" - . "\n" # module index - . "\n" - . "\n
$PREVIOUS$UP$NEXT$t_title$CONTENTS$CUSTOM_BUTTONS$INDEX
\n" - # textual navigation - . make_nav_sectref("Previous", $PREVIOUS_TITLE) - . make_nav_sectref("Up", $UP_TITLE) - . make_nav_sectref("Next", $NEXT_TITLE) - ); - # remove these; they are unnecessary and cause errors from validation - $s =~ s/ NAME="tex2html\d+"\n */ /g; - return $s; -} - -sub add_child_links { - my $toc = add_real_child_links(@_); - $toc =~ s|\s*|
|g; - $toc =~ s/ NAME=\"tex2html\d+\"\s*href=/ href=/gi; - $toc =~ s|(\s*
)?||gi; - return $toc; -} - -sub get_version_text() { - if ($PACKAGE_VERSION ne '' && $t_date) { - return ("" - . "Release $PACKAGE_VERSION$RELEASE_INFO," - . " documentation updated on $t_date."); - } - if ($PACKAGE_VERSION ne '') { - return ("" - . "Release $PACKAGE_VERSION$RELEASE_INFO."); - } - if ($t_date) { - return ("Documentation released on " - . "$t_date."); - } - return ''; -} - - -sub top_navigation_panel() { - return "\n" - . make_nav_panel() - . "

\n"; -} - -sub bot_navigation_panel() { - return "\n


\n" - . make_nav_panel() - . "
\n" - . get_version_text() - . "\n"; -} - -sub add_link { - # Returns a pair (iconic link, textual link) - my($icon, $current_file, @link) = @_; - my($dummy, $file, $title) = split($delim, - $section_info{join(' ',@link)}); - if ($icon =~ /\/) { - my $r = get_my_icon($1); - $icon =~ s/\/$r/; - } - if ($title && ($file ne $current_file)) { - $title = purify($title); - $title = get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES); - return (make_href($file, $icon), make_href($file, "$title")) - } - elsif ($icon eq get_my_icon('up') && $EXTERNAL_UP_LINK) { - return (make_href($EXTERNAL_UP_LINK, $icon), - make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE")) - } - elsif ($icon eq get_my_icon('previous') - && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) { - return (make_href($EXTERNAL_PREV_LINK, $icon), - make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE")) - } - elsif ($icon eq get_my_icon('next') - && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) { - return (make_href($EXTERNAL_DOWN_LINK, $icon), - make_href($EXTERNAL_DOWN_LINK, "$EXTERNAL_DOWN_TITLE")) - } - return (&inactive_img($icon), ""); -} - -sub add_special_link($$$) { - my($icon, $file, $current_file) = @_; - if ($icon =~ /\/) { - my $r = get_my_icon($1); - $icon =~ s/\/$r/; - } - return (($file && ($file ne $current_file)) - ? make_href($file, $icon) - : undef) -} - -# The img_tag() function seems only to be called with the parameter -# 'anchor_invisible_mark', which we want to turn into ''. Since -# replace_icon_marks() is the only interesting caller, and all it really -# does is call img_tag(), we can just define the hook alternative to be -# a no-op instead. -# -sub replace_icons_hook {} - -sub do_cmd_arabic { - # get rid of that nasty ... - my($ctr, $val, $id, $text) = &read_counter_value($_[0]); - return ($val ? farabic($val) : "0") . $text; -} - - -sub gen_index_id($$) { - # this is used to ensure common index key generation and a stable sort - my($str, $extra) = @_; - sprintf('%s###%s%010d', $str, $extra, ++$global{'max_id'}); -} - -sub insert_index($$$$$) { - my($mark, $datafile, $columns, $letters, $prefix) = @_; - my $prog = "$myrootdir/tools/buildindex.py"; - my $index; - if ($letters) { - $index = `$prog --columns $columns --letters $datafile`; - } - else { - $index = `$prog --columns $columns $datafile`; - } - if (!s/$mark/$prefix$index/) { - print "\nCould not locate index mark: $mark"; - } -} - -sub add_idx() { - print "\nBuilding HTML for the index ..."; - close(IDXFILE); - insert_index($idx_mark, 'index.dat', $INDEX_COLUMNS, 1, ''); -} - - -$idx_module_mark = ''; -$idx_module_title = 'Module Index'; - -sub add_module_idx() { - print "\nBuilding HTML for the module index ..."; - my $key; - my $first = 1; - my $prevplat = ''; - my $allthesame = 1; - my $prefix = ''; - foreach $key (keys %Modules) { - $key =~ s/([a-zA-Z0-9._]*)<\/tt>/$1/; - my $plat = "$ModulePlatforms{$key}"; - $plat = '' - if ($plat eq $IGNORE_PLATFORM_ANNOTATION); - if (!$first) { - $allthesame = 0 - if ($prevplat ne $plat); - } - else { $first = 0; } - $prevplat = $plat; - } - open(MODIDXFILE, '>modindex.dat') || die "\n$!\n"; - foreach $key (keys %Modules) { - # dump the line in the data file; just use a dummy seqno field - my $nkey = $1; - my $moditem = "$Modules{$key}"; - my $plat = ''; - $key =~ s/([a-zA-Z0-9._]*)<\/tt>/$1/; - if ($ModulePlatforms{$key} && !$allthesame) { - $plat = (" ($ModulePlatforms{$key}" - . ')'); - } - print MODIDXFILE $moditem . $IDXFILE_FIELD_SEP - . "$key$plat###\n"; - } - close(MODIDXFILE); - - if ($GLOBAL_MODULE_INDEX) { - $prefix = < This index only lists modules documented in this manual. - The Global Module - Index lists all modules that are documented in this set - of manuals.

-MODULE_INDEX_PREFIX - } - if (!$allthesame) { - $prefix .= < Some module names are followed by an annotation indicating what -platform they are available on.

- -PLAT_DISCUSS - } - insert_index($idx_module_mark, 'modindex.dat', $MODULE_INDEX_COLUMNS, 0, - $prefix); -} - -# replace both indexes as needed: -sub add_idx_hook { - add_idx() if (/$idx_mark/); - process_python_state(); - if ($MODULE_INDEX_FILE) { - local ($_); - open(MYFILE, "<$MODULE_INDEX_FILE"); - sysread(MYFILE, $_, 1024*1024); - close(MYFILE); - add_module_idx(); - open(MYFILE,">$MODULE_INDEX_FILE"); - print MYFILE $_; - close(MYFILE); - } -} - - -# In addition to the standard stuff, add label to allow named node files and -# support suppression of the page complete (for HTML Help use). -sub do_cmd_tableofcontents { - local($_) = @_; - $TITLE = $toc_title; - $tocfile = $CURRENT_FILE; - my($closures, $reopens) = preserve_open_tags(); - anchor_label('contents', $CURRENT_FILE, $_); # this is added - join('', "
\n\\tableofchildlinks[off]", $closures - , make_section_heading($toc_title, 'H2'), $toc_mark - , $reopens, $_); -} -# In addition to the standard stuff, add label to allow named node files. -sub do_cmd_listoffigures { - local($_) = @_; - $TITLE = $lof_title; - $loffile = $CURRENT_FILE; - my($closures, $reopens) = preserve_open_tags(); - anchor_label('lof', $CURRENT_FILE, $_); # this is added - join('', "
\n", $closures - , make_section_heading($lof_title, 'H2'), $lof_mark - , $reopens, $_); -} -# In addition to the standard stuff, add label to allow named node files. -sub do_cmd_listoftables { - local($_) = @_; - $TITLE = $lot_title; - $lotfile = $CURRENT_FILE; - my($closures, $reopens) = preserve_open_tags(); - anchor_label('lot', $CURRENT_FILE, $_); # this is added - join('', "
\n", $closures - , make_section_heading($lot_title, 'H2'), $lot_mark - , $reopens, $_); -} -# In addition to the standard stuff, add label to allow named node files. -sub do_cmd_textohtmlinfopage { - local($_) = @_; - if ($INFO) { # - anchor_label("about",$CURRENT_FILE,$_); # this is added - } # - my $the_version = ''; # and the rest is - if ($t_date) { # mostly ours - $the_version = ",\n$t_date"; - if ($PACKAGE_VERSION) { - $the_version .= ", Release $PACKAGE_VERSION$RELEASE_INFO"; - } - } - my $about; - open(ABOUT, "<$ABOUT_FILE") || die "\n$!\n"; - sysread(ABOUT, $about, 1024*1024); - close(ABOUT); - $_ = (($INFO == 1) - ? join('', - $close_all, - "$t_title$the_version\n", - $about, - $open_all, $_) - : join('', $close_all, $INFO,"\n", $open_all, $_)); - $_; -} - -# $idx_mark will be replaced with the real index at the end -sub do_cmd_textohtmlindex { - local($_) = @_; - $TITLE = $idx_title; - $idxfile = $CURRENT_FILE; - if (%index_labels) { make_index_labels(); } - if (($SHORT_INDEX) && (%index_segment)) { make_preindex(); } - else { $preindex = ''; } - my $heading = make_section_heading($idx_title, 'h2') . $idx_mark; - my($pre, $post) = minimize_open_tags($heading); - anchor_label('genindex',$CURRENT_FILE,$_); # this is added - return "
\n" . $pre . $_; -} - -$MODULE_INDEX_FILE = ''; - -# $idx_module_mark will be replaced with the real index at the end -sub do_cmd_textohtmlmoduleindex { - local($_) = @_; - $TITLE = $idx_module_title; - anchor_label('modindex', $CURRENT_FILE, $_); - $MODULE_INDEX_FILE = "$CURRENT_FILE"; - $_ = ('

' . make_section_heading($idx_module_title, 'h2') - . $idx_module_mark . $_); - return $_; -} - -# The bibliography and the index should be treated as separate -# sections in their own HTML files. The \bibliography{} command acts -# as a sectioning command that has the desired effect. But when the -# bibliography is constructed manually using the thebibliography -# environment, or when using the theindex environment it is not -# possible to use the normal sectioning mechanism. This subroutine -# inserts a \bibliography{} or a dummy \textohtmlindex command just -# before the appropriate environments to force sectioning. - -# XXX This *assumes* that if there are two {theindex} environments, -# the first is the module index and the second is the standard -# index. This is sufficient for the current Python documentation, -# but that's about it. - -sub add_bbl_and_idx_dummy_commands { - my $id = $global{'max_id'}; - - if (/[\\]tableofcontents/) { - $HAVE_TABLE_OF_CONTENTS = 1; - } - s/([\\]begin\s*$O\d+$C\s*thebibliography)/$bbl_cnt++; $1/eg; - s/([\\]begin\s*$O\d+$C\s*thebibliography)/$id++; "\\bibliography$O$id$C$O$id$C $1"/geo; - my(@parts) = split(/\\begin\s*$O\d+$C\s*theindex/); - if (scalar(@parts) == 3) { - # Be careful to re-write the string in place, since $_ is *not* - # returned explicity; *** nasty side-effect dependency! *** - print "\nadd_bbl_and_idx_dummy_commands ==> adding general index"; - print "\nadd_bbl_and_idx_dummy_commands ==> adding module index"; - my $rx = "([\\\\]begin\\s*$O\\d+$C\\s*theindex[\\s\\S]*)" - . "([\\\\]begin\\s*$O\\d+$C\\s*theindex)"; - s/$rx/\\textohtmlmoduleindex $1 \\textohtmlindex $2/o; - # Add a button to the navigation areas: - $CUSTOM_BUTTONS .= ('' - . get_my_icon('modules') - . ''); - $HAVE_MODULE_INDEX = 1; - $HAVE_GENERAL_INDEX = 1; - } - elsif (scalar(@parts) == 2) { - print "\nadd_bbl_and_idx_dummy_commands ==> adding general index"; - my $rx = "([\\\\]begin\\s*$O\\d+$C\\s*theindex)"; - s/$rx/\\textohtmlindex $1/o; - $HAVE_GENERAL_INDEX = 1; - } - elsif (scalar(@parts) == 1) { - print "\nadd_bbl_and_idx_dummy_commands ==> no index found"; - $CUSTOM_BUTTONS .= get_my_icon('blank'); - $global{'max_id'} = $id; # not sure why.... - s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o; - s/[\\]printindex/\\textohtmlindex /o; - } - else { - die "\n\nBad number of index environments!\n\n"; - } - #---------------------------------------------------------------------- - lib_add_bbl_and_idx_dummy_commands() - if defined(&lib_add_bbl_and_idx_dummy_commands); -} - -# The bibliographic references, the appendices, the lists of figures -# and tables etc. must appear in the contents table at the same level -# as the outermost sectioning command. This subroutine finds what is -# the outermost level and sets the above to the same level; - -sub set_depth_levels { - # Sets $outermost_level - my $level; - #RRM: do not alter user-set value for $MAX_SPLIT_DEPTH - foreach $level ("part", "chapter", "section", "subsection", - "subsubsection", "paragraph") { - last if (($outermost_level) = /\\($level)$delimiter_rx/); - } - $level = ($outermost_level ? $section_commands{$outermost_level} : - do {$outermost_level = 'section'; 3;}); - - #RRM: but calculate value for $MAX_SPLIT_DEPTH when a $REL_DEPTH was given - if ($REL_DEPTH && $MAX_SPLIT_DEPTH) { - $MAX_SPLIT_DEPTH = $level + $MAX_SPLIT_DEPTH; - } elsif (!($MAX_SPLIT_DEPTH)) { $MAX_SPLIT_DEPTH = 1 }; - - %unnumbered_section_commands = ('tableofcontents' => $level, - 'listoffigures' => $level, - 'listoftables' => $level, - 'bibliography' => $level, - 'textohtmlindex' => $level, - 'textohtmlmoduleindex' => $level); - $section_headings{'textohtmlmoduleindex'} = 'h1'; - - %section_commands = (%unnumbered_section_commands, - %section_commands); - - make_sections_rx(); -} - - -# This changes the markup used for {verbatim} environments, and is the -# best way I've found that ensures the

goes on the outside of the -#
...
. -# -# Note that this *must* be done in the init file, not the python.perl -# style support file. The %declarations must be set before -# initialize() is called in the main LaTeX2HTML script (which happens -# before style files are loaded). -# -%declarations = ('preform' => '
', - %declarations); - - -# This is added to get rid of the long comment that follows the -# doctype declaration; MSIE5 on NT4 SP4 barfs on it and drops the -# content of the page. -$MY_PARTIAL_HEADER = ''; -sub make_head_and_body($$) { - my($title, $body) = @_; - $body = " $body" unless ($body eq ''); - my $DTDcomment = ''; - my($version, $isolanguage) = ($HTML_VERSION, 'EN'); - my %isolanguages = ( 'english', 'EN' , 'USenglish', 'EN.US' - , 'original', 'EN' , 'german' , 'DE' - , 'austrian', 'DE.AT', 'french' , 'FR' - , 'spanish', 'ES'); - $isolanguage = $isolanguages{$default_language}; - $isolanguage = 'EN' unless $isolanguage; - $title = &purify($title,1); - eval("\$title = ". $default_title ) unless ($title); - - # allow user-modification of the tag; thanks Dan Young - if (defined &custom_TITLE_hook) { - $title = &custom_TITLE_hook($title, $toc_sec_title); - } - - if ($DOCTYPE =~ /\/\/[\w\.]+\s*$/) { # language spec included - $DTDcomment = "<!DOCTYPE html PUBLIC \"$DOCTYPE\">\n"; - } else { - $DTDcomment = "<!DOCTYPE html PUBLIC \"$DOCTYPE//" - . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . "\">\n"; - } - if ($MY_PARTIAL_HEADER eq '') { - $STYLESHEET = $FILE.".css" unless $STYLESHEET; - $MY_PARTIAL_HEADER = join('', - ($DOCTYPE ? $DTDcomment : ''), - "<html>\n<head>\n", - ($BASE ? "<base href=\"$BASE\">\n" : ''), - "<link rel=\"STYLESHEET\" href=\"$STYLESHEET\" type='text/css'>\n", - ($FAVORITES_ICON - ? ('<link rel="SHORTCUT ICON" href="' . "$FAVORITES_ICON\">\n") - : ''), - ($EXTERNAL_UP_LINK - ? ('<link rel="start" href="' . "$EXTERNAL_UP_LINK\"" - . ($EXTERNAL_UP_TITLE ? " title='$EXTERNAL_UP_TITLE'" : '') - . ">\n") - : ''), - "<link rel=\"first\" href=\"$FILE.html\"", - ($t_title ? " title='$t_title'" : ''), - ">\n", - ($HAVE_TABLE_OF_CONTENTS - ? ('<link rel="contents" href="contents.html" title="Contents">' - . ($HAVE_GENERAL_INDEX ? "\n" : '')) - : ''), - ($HAVE_GENERAL_INDEX - ? '<link rel="index" href="genindex.html" title="Index">' . "\n" - : ''), - # disable for now -- Mozilla doesn't do well with multiple indexes - # ($HAVE_MODULE_INDEX - # ? '<link rel="index" href="modindex.html" title="Module Index">' - # . "\n" - # : ''), - ($INFO - # XXX We can do this with the Python tools since the About... - # page always gets copied to about.html, even when we use the - # generated node###.html page names. Won't work with the - # rest of the Python doc tools. - ? ("<link rel='last' href='about.html'" - . " title='About this document...'>\n" - . "<link rel='help' href='about.html'" - . " title='About this document...'>\n") - : ''), - $more_links_mark, - "\n", - ($CHARSET && $HTML_VERSION ge "2.1" - ? ('<meta http-equiv="Content-Type" content="text/html; ' - . "charset=$CHARSET\">\n") - : ''), - ($AESOP_META_TYPE - ? "<meta name='aesop' content='$AESOP_META_TYPE'>\n" : '')); - } - if (!$charset && $CHARSET) { - $charset = $CHARSET; - $charset =~ s/_/\-/go; - } - join('', - $MY_PARTIAL_HEADER, - &meta_information($title), - "<title>", $title, "\n\n"); -} - -1; # This must be the last line diff --git a/olddoc/perl/ltxmarkup.perl b/olddoc/perl/ltxmarkup.perl deleted file mode 100644 index 290e79b4..00000000 --- a/olddoc/perl/ltxmarkup.perl +++ /dev/null @@ -1,67 +0,0 @@ -# LaTeX2HTML support for the ltxmarkup package. Doesn't do indexing. - -package main; - - -sub ltx_next_argument{ - my $param; - $param = missing_braces() - unless ((s/$next_pair_pr_rx/$param=$2;''/eo) - ||(s/$next_pair_rx/$param=$2;''/eo)); - return $param; -} - - -sub do_cmd_macro{ - local($_) = @_; - my $macro = ltx_next_argument(); - return "\$macro" . $_; -} - -sub do_cmd_env{ - local($_) = @_; - my $env = ltx_next_argument(); - return "\$env" . $_; -} - -sub ltx_process_params{ - # Handle processing of \p and \op for parameter specifications for - # envdesc and macrodesc. It's done this way to avoid defining do_cmd_p() - # and do_cmd_op() functions, which would be interpreted outside the context - # in which these commands are legal, and cause LaTeX2HTML to think they're - # defined. This way, other uses of \p and \op are properly flagged as - # unknown macros. - my $s = @_[0]; - $s =~ s%\\op<<(\d+)>>(.+)<<\1>>%[$2]%; - while ($s =~ /\\p<<(\d+)>>(.+)<<\1>>/) { - $s =~ s%\\p<<(\d+)>>(.+)<<\1>>%{$2}%; - } - return $s; -} - -sub do_env_macrodesc{ - local($_) = @_; - my $macro = ltx_next_argument(); - my $params = ltx_process_params(ltx_next_argument()); - return "\n
" - . "\n
\$macro" - . "\n $params" - . "\n
" - . $_ - . "
"; -} - -sub do_env_envdesc{ - local($_) = @_; - my $env = ltx_next_argument(); - my $params = ltx_process_params(ltx_next_argument()); - return "\n
" - . "\n
\begin{$env}" - . "\n $params" - . "\n
\end{$env}" - . "\n
" - . $_ - . "
"; -} - -1; # Must end with this, because Perl is bogus. diff --git a/olddoc/perl/manual.perl b/olddoc/perl/manual.perl deleted file mode 100644 index ea65b36e..00000000 --- a/olddoc/perl/manual.perl +++ /dev/null @@ -1,15 +0,0 @@ -# -*- perl -*- -# -# This implements the Python manual class. All it really needs to do it -# load the "python" style. The style code is not moved into the class code -# at this time, since we expect additional document class to be developed -# for the Python documentation in the future. Appropriate relocations will -# be made at that time. - -package main; - -do_require_package("report"); -do_require_package("alltt"); -do_require_package("python"); - -1; # sheesh.... diff --git a/olddoc/perl/python.perl b/olddoc/perl/python.perl deleted file mode 100644 index 1459076a..00000000 --- a/olddoc/perl/python.perl +++ /dev/null @@ -1,2123 +0,0 @@ -# python.perl by Fred L. Drake, Jr. -*- perl -*- -# -# Heavily based on Guido van Rossum's myformat.perl (now obsolete). -# -# Extension to LaTeX2HTML for documents using myformat.sty. -# Subroutines of the form do_cmd_ here define translations -# for LaTeX commands \ defined in the corresponding .sty file. - -package main; - -use warnings; -use File::Basename; - - -sub next_argument{ - my $param; - $param = missing_braces() - unless ((s/$next_pair_pr_rx/$param=$2;''/eo) - ||(s/$next_pair_rx/$param=$2;''/eo)); - return $param; -} - -sub next_optional_argument{ - my($param, $rx) = ('', "^\\s*(\\[([^]]*)\\])?"); - s/$rx/$param=$2;''/eo; - return $param; -} - -sub make_icon_filename($){ - my($myname, $mydir, $myext) = fileparse($_[0], '\..*'); - chop $mydir; - if ($mydir eq '.') { - $mydir = $ICONSERVER; - } - $myext = ".$IMAGE_TYPE" - unless $myext; - return "$mydir$dd$myname$myext"; -} - -sub get_link_icon($){ - my $url = $_[0]; - if ($OFF_SITE_LINK_ICON && ($url =~ /^[-a-zA-Z0-9.]+:/)) { - # absolute URL; assume it points off-site - my $icon = make_icon_filename($OFF_SITE_LINK_ICON); - return (" \"[off-site"); - } - return ''; -} - -# This is a fairly simple hack; it supports \let when it is used to create -# (or redefine) a macro to exactly be some other macro: \let\newname=\oldname. -# Many possible uses of \let aren't supported or aren't supported correctly. -# -sub do_cmd_let{ - local($_) = @_; - my $matched = 0; - s/[\\]([a-zA-Z]+)\s*(=\s*)?[\\]([a-zA-Z]*)/$matched=1; ''/e; - if ($matched) { - my($new, $old) = ($1, $3); - eval "sub do_cmd_$new { do_cmd_$old" . '(@_); }'; - print "\ndefining handler for \\$new using \\$old\n"; - } - else { - s/[\\]([a-zA-Z]+)\s*(=\s*)?([^\\])/$matched=1; ''/es; - if ($matched) { - my($new, $char) = ($1, $3); - eval "sub do_cmd_$new { \"\\$char\" . \$_[0]; }"; - print "\ndefining handler for \\$new to insert '$char'\n"; - } - else { - write_warnings("Could not interpret \\let construct..."); - } - } - return $_; -} - - -# the older version of LaTeX2HTML we use doesn't support this, but we use it: - -sub do_cmd_textasciitilde{ '~' . $_[0]; } -sub do_cmd_textasciicircum{ '^' . $_[0]; } -sub do_cmd_textbar{ '|' . $_[0]; } -sub do_cmd_textgreater{ '>' . $_[0]; } -sub do_cmd_textless{ '<' . $_[0]; } -sub do_cmd_textunderscore{ '_' . $_[0]; } -sub do_cmd_infinity{ '∞' . $_[0]; } -sub do_cmd_plusminus{ '±' . $_[0]; } -sub do_cmd_menuselection{ $_[0]; } -sub do_cmd_sub{ ' > ' . $_[0]; } - - -# words typeset in a special way (not in HTML though) - -sub do_cmd_ABC{ 'ABC' . $_[0]; } -sub do_cmd_UNIX{ 'Unix' - . $_[0]; } -sub do_cmd_ASCII{ 'ASCII' . $_[0]; } -sub do_cmd_POSIX{ 'POSIX' . $_[0]; } -sub do_cmd_C{ 'C' . $_[0]; } -sub do_cmd_Cpp{ 'C++' . $_[0]; } -sub do_cmd_EOF{ 'EOF' . $_[0]; } -sub do_cmd_NULL{ 'NULL' . $_[0]; } - -sub do_cmd_e{ '\' . $_[0]; } - -$DEVELOPER_ADDRESS = ''; -$SHORT_VERSION = ''; -$RELEASE_INFO = ''; -$PACKAGE_VERSION = ''; - -sub do_cmd_version{ $PACKAGE_VERSION . $_[0]; } -sub do_cmd_shortversion{ $SHORT_VERSION . $_[0]; } -sub do_cmd_release{ - local($_) = @_; - $PACKAGE_VERSION = next_argument(); - return $_; -} - -sub do_cmd_setreleaseinfo{ - local($_) = @_; - $RELEASE_INFO = next_argument(); - return $_; -} - -sub do_cmd_setshortversion{ - local($_) = @_; - $SHORT_VERSION = next_argument(); - return $_; -} - -sub do_cmd_authoraddress{ - local($_) = @_; - $DEVELOPER_ADDRESS = next_argument(); - return $_; -} - -#sub do_cmd_developer{ do_cmd_author($_[0]); } -#sub do_cmd_developers{ do_cmd_author($_[0]); } -#sub do_cmd_developersaddress{ do_cmd_authoraddress($_[0]); } - -sub do_cmd_hackscore{ - local($_) = @_; - next_argument(); - return '_' . $_; -} - -sub use_wrappers($$$){ - local($_,$before,$after) = @_; - my $stuff = next_argument(); - return $before . $stuff . $after . $_; -} - -$IN_DESC_HANDLER = 0; -sub do_cmd_optional{ - if ($IN_DESC_HANDLER) { - return use_wrappers($_[0], "\[", - "\]"); - } - else { - return use_wrappers($_[0], "\[", "\]"); - } -} - -# Logical formatting (some based on texinfo), needs to be converted to -# minimalist HTML. The "minimalist" is primarily to reduce the size of -# output files for users that read them over the network rather than -# from local repositories. - -sub do_cmd_pytype{ return $_[0]; } -sub do_cmd_makevar{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_code{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_module{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_keyword{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_exception{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_class{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_function{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_constant{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_member{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_method{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_cfunction{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_cdata{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_ctype{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_regexp{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_character{ - return use_wrappers($_[0], '"', '"'); } -sub do_cmd_program{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_programopt{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_longprogramopt{ - # note that the --- will be later converted to -- by LaTeX2HTML - return use_wrappers($_[0], '---', ''); } -sub do_cmd_email{ - return use_wrappers($_[0], ''); } -sub do_cmd_mailheader{ - return use_wrappers($_[0], '', ':'); } -sub do_cmd_mimetype{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_var{ - return use_wrappers($_[0], "", ""); } -sub do_cmd_dfn{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_emph{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_file{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_filenq{ - return do_cmd_file($_[0]); } -sub do_cmd_samp{ - return use_wrappers($_[0], '"', '"'); } -sub do_cmd_kbd{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_strong{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_textbf{ - return use_wrappers($_[0], '', ''); } -sub do_cmd_textit{ - return use_wrappers($_[0], '', ''); } -# This can be changed/overridden for translations: -%NoticeNames = ('note' => 'Note:', - 'warning' => 'Warning:', - ); - -sub do_cmd_note{ - my $label = $NoticeNames{'note'}; - return use_wrappers( - $_[0], - "$label\n", - ''); } -sub do_cmd_warning{ - my $label = $NoticeNames{'warning'}; - return use_wrappers( - $_[0], - "$label\n", - ''); } - -sub do_env_notice{ - local($_) = @_; - my $notice = next_optional_argument(); - if (!$notice) { - $notice = 'note'; - } - my $label = $NoticeNames{$notice}; - return ("
$label\n" - . $_ - . '
'); -} - -sub do_cmd_moreargs{ - return '...' . $_[0]; } -sub do_cmd_unspecified{ - return '...' . $_[0]; } - - -sub do_cmd_refmodule{ - # Insert the right magic to jump to the module definition. - local($_) = @_; - my $key = next_optional_argument(); - my $module = next_argument(); - $key = $module - unless $key; - return "$module" - . $_; -} - -sub do_cmd_newsgroup{ - local($_) = @_; - my $newsgroup = next_argument(); - my $icon = get_link_icon("news:$newsgroup"); - my $stuff = ("" - . "$newsgroup$icon"); - return $stuff . $_; -} - -sub do_cmd_envvar{ - local($_) = @_; - my $envvar = next_argument(); - my($name, $aname, $ahref) = new_link_info(); - # The here is really to keep buildindex.py from making - # the variable name case-insensitive. - add_index_entry("environment variables!$envvar@$envvar", - $ahref); - add_index_entry("$envvar (environment variable)", $ahref); - $aname =~ s/" . $_; -} - -sub do_cmd_url{ - # use the URL as both text and hyperlink - local($_) = @_; - my $url = next_argument(); - my $icon = get_link_icon($url); - $url =~ s/~/~/g; - return "$url$icon" . $_; -} - -sub do_cmd_manpage{ - # two parameters: \manpage{name}{section} - local($_) = @_; - my $page = next_argument(); - my $section = next_argument(); - return "$page($section)" . $_; -} - -$PEP_FORMAT = "http://www.python.org/peps/pep-%04d.html"; -#$RFC_FORMAT = "http://www.ietf.org/rfc/rfc%04d.txt"; -$RFC_FORMAT = "http://www.faqs.org/rfcs/rfc%d.html"; - -sub get_rfc_url($$){ - my($rfcnum, $format) = @_; - return sprintf($format, $rfcnum); -} - -sub do_cmd_pep{ - local($_) = @_; - my $rfcnumber = next_argument(); - my $id = "rfcref-" . ++$global{'max_id'}; - my $href = get_rfc_url($rfcnumber, $PEP_FORMAT); - my $icon = get_link_icon($href); - # Save the reference - my $nstr = gen_index_id("Python Enhancement Proposals!PEP $rfcnumber", ''); - $index{$nstr} .= make_half_href("$CURRENT_FILE#$id"); - return ("PEP $rfcnumber" - . "$icon" . $_); -} - -sub do_cmd_rfc{ - local($_) = @_; - my $rfcnumber = next_argument(); - my $id = "rfcref-" . ++$global{'max_id'}; - my $href = get_rfc_url($rfcnumber, $RFC_FORMAT); - my $icon = get_link_icon($href); - # Save the reference - my $nstr = gen_index_id("RFC!RFC $rfcnumber", ''); - $index{$nstr} .= make_half_href("$CURRENT_FILE#$id"); - return ("RFC $rfcnumber" - . "$icon" . $_); -} - -sub do_cmd_ulink{ - local($_) = @_; - my $text = next_argument(); - my $url = next_argument(); - return "$text" . $_; -} - -sub do_cmd_citetitle{ - local($_) = @_; - my $url = next_optional_argument(); - my $title = next_argument(); - my $icon = get_link_icon($url); - my $repl = ''; - if ($url) { - $repl = ("$title$icon"); - } - else { - $repl = "$title"; - } - return $repl . $_; -} - -sub do_cmd_deprecated{ - # two parameters: \deprecated{version}{whattodo} - local($_) = @_; - my $release = next_argument(); - my $reason = next_argument(); - return ('
' - . "Deprecated since release $release." - . "\n$reason

" - . $_); -} - -sub versionnote($$){ - # one or two parameters: \versionnote[explanation]{version} - my $type = $_[0]; - local $_ = $_[1]; - my $explanation = next_optional_argument(); - my $release = next_argument(); - my $text = "$type in version $release."; - if ($explanation) { - $text = "$type in version $release:\n$explanation."; - } - return "\n$text\n" . $_; -} - -sub do_cmd_versionadded{ - return versionnote('New', $_[0]); -} - -sub do_cmd_versionchanged{ - return versionnote('Changed', $_[0]); -} - -# -# These function handle platform dependency tracking. -# -sub do_cmd_platform{ - local($_) = @_; - my $platform = next_argument(); - $ModulePlatforms{"$THIS_MODULE"} = $platform; - $platform = "Macintosh" - if $platform eq 'Mac'; - return "\n

Availability: $platform.

\n" . $_; -} - -$IGNORE_PLATFORM_ANNOTATION = ''; -sub do_cmd_ignorePlatformAnnotation{ - local($_) = @_; - $IGNORE_PLATFORM_ANNOTATION = next_argument(); - return $_; -} - - -# index commands - -$INDEX_SUBITEM = ""; - -sub get_indexsubitem(){ - return $INDEX_SUBITEM ? " $INDEX_SUBITEM" : ''; -} - -sub do_cmd_setindexsubitem{ - local($_) = @_; - $INDEX_SUBITEM = next_argument(); - return $_; -} - -sub do_cmd_withsubitem{ - # We can't really do the right thing, because LaTeX2HTML doesn't - # do things in the right order, but we need to at least strip this stuff - # out, and leave anything that the second argument expanded out to. - # - local($_) = @_; - my $oldsubitem = $INDEX_SUBITEM; - $INDEX_SUBITEM = next_argument(); - my $stuff = next_argument(); - my $br_id = ++$globals{'max_id'}; - my $marker = "$O$br_id$C"; - $stuff =~ s/^\s+//; - return - $stuff - . "\\setindexsubitem$marker$oldsubitem$marker" - . $_; -} - -# This is the prologue macro which is required to start writing the -# mod\jobname.idx file; we can just ignore it. (Defining this suppresses -# a warning that \makemodindex is unknown.) -# -sub do_cmd_makemodindex{ return $_[0]; } - -# We're in the document subdirectory when this happens! -# -open(IDXFILE, '>index.dat') || die "\n$!\n"; -open(INTLABELS, '>intlabels.pl') || die "\n$!\n"; -print INTLABELS "%internal_labels = ();\n"; -print INTLABELS "1; # hack in case there are no entries\n\n"; - -# Using \0 for this is bad because we can't use common tools to work with the -# resulting files. Things like grep can be useful with this stuff! -# -$IDXFILE_FIELD_SEP = "\1"; - -sub write_idxfile($$){ - my($ahref, $str) = @_; - print IDXFILE $ahref, $IDXFILE_FIELD_SEP, $str, "\n"; -} - - -sub gen_link($$){ - my($node, $target) = @_; - print INTLABELS "\$internal_labels{\"$target\"} = \"/$node\";\n"; - return ""; -} - -sub add_index_entry($$){ - # add an entry to the index structures; ignore the return value - my($str, $ahref) = @_; - $str = gen_index_id($str, ''); - $index{$str} .= $ahref; - write_idxfile($ahref, $str); -} - -sub new_link_info(){ - my $name = "l2h-" . ++$globals{'max_id'}; - my $aname = ""; - my $ahref = gen_link($CURRENT_FILE, $name); - return ($name, $aname, $ahref); -} - -$IndexMacroPattern = ''; -sub define_indexing_macro(@){ - my $count = @_; - my $i = 0; - for (; $i < $count; ++$i) { - my $name = $_[$i]; - my $cmd = "idx_cmd_$name"; - die "\nNo function $cmd() defined!\n" - if (!defined &$cmd); - eval ("sub do_cmd_$name { return process_index_macros(" - . "\$_[0], '$name'); }"); - if (length($IndexMacroPattern) == 0) { - $IndexMacroPattern = "$name"; - } - else { - $IndexMacroPattern .= "|$name"; - } - } -} - -$DEBUG_INDEXING = 0; -sub process_index_macros($$){ - local($_) = @_; - my $cmdname = $_[1]; # This is what triggered us in the first place; - # we know it's real, so just process it. - my($name, $aname, $ahref) = new_link_info(); - my $cmd = "idx_cmd_$cmdname"; - print "\nIndexing: \\$cmdname" - if $DEBUG_INDEXING; - &$cmd($ahref); # modifies $_ and adds index entries - while (/^[\s\n]*\\($IndexMacroPattern)" . $_; -} - -define_indexing_macro('index'); -sub idx_cmd_index($){ - my $str = next_argument(); - add_index_entry("$str", $_[0]); -} - -define_indexing_macro('kwindex'); -sub idx_cmd_kwindex($){ - my $str = next_argument(); - add_index_entry("$str!keyword", $_[0]); - add_index_entry("keyword!$str", $_[0]); -} - -define_indexing_macro('indexii'); -sub idx_cmd_indexii($){ - my $str1 = next_argument(); - my $str2 = next_argument(); - add_index_entry("$str1!$str2", $_[0]); - add_index_entry("$str2!$str1", $_[0]); -} - -define_indexing_macro('indexiii'); -sub idx_cmd_indexiii($){ - my $str1 = next_argument(); - my $str2 = next_argument(); - my $str3 = next_argument(); - add_index_entry("$str1!$str2 $str3", $_[0]); - add_index_entry("$str2!$str3, $str1", $_[0]); - add_index_entry("$str3!$str1 $str2", $_[0]); -} - -define_indexing_macro('indexiv'); -sub idx_cmd_indexiv($){ - my $str1 = next_argument(); - my $str2 = next_argument(); - my $str3 = next_argument(); - my $str4 = next_argument(); - add_index_entry("$str1!$str2 $str3 $str4", $_[0]); - add_index_entry("$str2!$str3 $str4, $str1", $_[0]); - add_index_entry("$str3!$str4, $str1 $str2", $_[0]); - add_index_entry("$str4!$str1 $str2 $str3", $_[0]); -} - -define_indexing_macro('ttindex'); -sub idx_cmd_ttindex($){ - my $str = next_argument(); - my $entry = $str . get_indexsubitem(); - add_index_entry($entry, $_[0]); -} - -sub my_typed_index_helper($$){ - my($word, $ahref) = @_; - my $str = next_argument(); - add_index_entry("$str $word", $ahref); - add_index_entry("$word!$str", $ahref); -} - -define_indexing_macro('stindex', 'opindex', 'exindex', 'obindex'); -sub idx_cmd_stindex($){ my_typed_index_helper('statement', $_[0]); } -sub idx_cmd_opindex($){ my_typed_index_helper('operator', $_[0]); } -sub idx_cmd_exindex($){ my_typed_index_helper('exception', $_[0]); } -sub idx_cmd_obindex($){ my_typed_index_helper('object', $_[0]); } - -define_indexing_macro('bifuncindex'); -sub idx_cmd_bifuncindex($){ - my $str = next_argument(); - add_index_entry("$str() (built-in function)", - $_[0]); -} - - -sub make_mod_index_entry($$){ - my($str, $define) = @_; - my($name, $aname, $ahref) = new_link_info(); - # equivalent of add_index_entry() using $define instead of '' - $ahref =~ s/\#[-_a-zA-Z0-9]*\"/\"/ - if ($define eq 'DEF'); - $str = gen_index_id($str, $define); - $index{$str} .= $ahref; - write_idxfile($ahref, $str); - - if ($define eq 'DEF') { - # add to the module index - $str =~ /()/; - my $nstr = $1; - $Modules{$nstr} .= $ahref; - } - return "$aname$anchor_invisible_mark2"; -} - - -$THIS_MODULE = ''; -$THIS_CLASS = ''; - -sub define_module($$){ - my($word, $name) = @_; - my $section_tag = join('', @curr_sec_id); - if ($word ne "built-in" && $word ne "extension" - && $word ne "standard" && $word ne "") { - write_warnings("Bad module type '$word'" - . " for \\declaremodule (module $name)"); - $word = ""; - } - $word = "$word " if $word; - $THIS_MODULE = "$name"; - $INDEX_SUBITEM = "(in module $name)"; - print "[$name]"; - return make_mod_index_entry( - "$name (${word}module)", 'DEF'); -} - -sub my_module_index_helper($$){ - local($word, $_) = @_; - my $name = next_argument(); - return define_module($word, $name) . $_; -} - -sub do_cmd_modindex{ return my_module_index_helper('', $_[0]); } -sub do_cmd_bimodindex{ return my_module_index_helper('built-in', $_[0]); } -sub do_cmd_exmodindex{ return my_module_index_helper('extension', $_[0]); } -sub do_cmd_stmodindex{ return my_module_index_helper('standard', $_[0]); } -# local($_) = @_; -# my $name = next_argument(); -# return define_module('standard', $name) . $_; -# } - -sub ref_module_index_helper($$){ - my($word, $ahref) = @_; - my $str = next_argument(); - $word = "$word " if $word; - $str = "$str (${word}module)"; - # can't use add_index_entry() since the 2nd arg to gen_index_id() is used; - # just inline it all here - $str = gen_index_id($str, 'REF'); - $index{$str} .= $ahref; - write_idxfile($ahref, $str); -} - -# these should be adjusted a bit.... -define_indexing_macro('refmodindex', 'refbimodindex', - 'refexmodindex', 'refstmodindex'); -sub idx_cmd_refmodindex($){ - return ref_module_index_helper('', $_[0]); } -sub idx_cmd_refbimodindex($){ - return ref_module_index_helper('built-in', $_[0]); } -sub idx_cmd_refexmodindex($){ - return ref_module_index_helper('extension', $_[0]);} -sub idx_cmd_refstmodindex($){ - return ref_module_index_helper('standard', $_[0]); } - -sub do_cmd_nodename{ return do_cmd_label($_[0]); } - -sub init_myformat(){ - $anchor_invisible_mark = ' '; - $anchor_invisible_mark2 = ''; - $anchor_mark = ''; - $icons{'anchor_mark'} = ''; -} -init_myformat(); - -# Create an index entry, but include the string in the target anchor -# instead of the dummy filler. -# -sub make_str_index_entry($){ - my $str = $_[0]; - my($name, $aname, $ahref) = new_link_info(); - add_index_entry($str, $ahref); - return "$aname$str"; -} - - -%TokenToTargetMapping = (); # language:token -> link target -%DefinedGrammars = (); # language -> full grammar text -%BackpatchGrammarFiles = (); # file -> 1 (hash of files to fixup) - -sub do_cmd_token{ - local($_) = @_; - my $token = next_argument(); - my $target = $TokenToTargetMapping{"$CURRENT_GRAMMAR:$token"}; - if ($token eq $CURRENT_TOKEN || $CURRENT_GRAMMAR eq '*') { - # recursive definition or display-only productionlist - return "$token"; - } - if ($target eq '') { - $target = "<$CURRENT_GRAMMAR><$token>"; - if (! $BackpatchGrammarFiles{"$CURRENT_FILE"}) { - print "Adding '$CURRENT_FILE' to back-patch list.\n"; - } - $BackpatchGrammarFiles{"$CURRENT_FILE"} = 1; - } - return "$token" . $_; -} - -sub do_cmd_grammartoken{ - return do_cmd_token(@_); -} - -sub do_env_productionlist{ - local($_) = @_; - my $lang = next_optional_argument(); - my $filename = "grammar-$lang.txt"; - if ($lang eq '') { - $filename = 'grammar.txt'; - } - local($CURRENT_GRAMMAR) = $lang; - $DefinedGrammars{$lang} .= $_; - return ("
\n" - . "
\n" - . "\n" - . translate_commands(translate_environments($_)) - . "
\n" - . "
\n" - . (($lang eq '*') - ? '' - : ("Download entire grammar as text.\n")) - . "
"); -} - -sub do_cmd_production{ - local($_) = @_; - my $token = next_argument(); - my $defn = next_argument(); - my $lang = $CURRENT_GRAMMAR; - local($CURRENT_TOKEN) = $token; - if ($lang eq '*') { - return ("\n" - . " $token\n" - . "  ::= \n" - . " " - . translate_commands($defn) - . "" - . $_); - } - my $target; - if ($lang eq '') { - $target = "$CURRENT_FILE\#tok-$token"; - } - else { - $target = "$CURRENT_FILE\#tok-$lang-$token"; - } - $TokenToTargetMapping{"$CURRENT_GRAMMAR:$token"} = $target; - return ("\n" - . " $token\n" - . "  ::= \n" - . " " - . translate_commands($defn) - . "" - . $_); -} - -sub do_cmd_productioncont{ - local($_) = @_; - my $defn = next_argument(); - $defn =~ s/^( +)/' ' x length $1/e; - return ("\n" - . "  \n" - . "  \n" - . " " - . translate_commands($defn) - . "" - . $_); -} - -sub process_grammar_files(){ - my $lang; - my $filename; - local($_); - print "process_grammar_files()\n"; - foreach $lang (keys %DefinedGrammars) { - $filename = "grammar-$lang.txt"; - if ($lang eq '*') { - next; - } - if ($lang eq '') { - $filename = 'grammar.txt'; - } - open(GRAMMAR, ">$filename") || die "\n$!\n"; - print GRAMMAR strip_grammar_markup($DefinedGrammars{$lang}); - close(GRAMMAR); - print "Wrote grammar file $filename\n"; - } - my $PATTERN = '<([^>]*)><([^>]*)>'; - foreach $filename (keys %BackpatchGrammarFiles) { - print "\nBack-patching grammar links in $filename\n"; - my $buffer; - open(GRAMMAR, "<$filename") || die "\n$!\n"; - # read all of the file into the buffer - sysread(GRAMMAR, $buffer, 1024*1024); - close(GRAMMAR); - while ($buffer =~ /$PATTERN/) { - my($lang, $token) = ($1, $2); - my $target = $TokenToTargetMapping{"$lang:$token"}; - my $source = "<$lang><$token>"; - $buffer =~ s/$source/$target/g; - } - open(GRAMMAR, ">$filename") || die "\n$!\n"; - print GRAMMAR $buffer; - close(GRAMMAR); - } -} - -sub strip_grammar_markup($){ - local($_) = @_; - s/\\productioncont/ /g; - s/\\production(<<\d+>>)(.+)\1/\n$2 ::= /g; - s/\\token(<<\d+>>)(.+)\1/$2/g; - s/\\e([^a-zA-Z])/\\$1/g; - s/<<\d+>>//g; - s/;SPMgt;/>/g; - s/;SPMlt;/) { - if (/([a-zA-Z0-9_]+):PyObject\*:([a-zA-Z0-9_]*):(0|[-+]1|null):(.*)$/) { - my($func, $param, $count, $comment) = ($1, $2, $3, $4); - #print "\n$func($param) --> $count"; - $REFCOUNTS{"$func:$param"} = $count; - } - } -} - -sub get_refcount($$){ - my($func, $param) = @_; - load_refcounts() - unless $REFCOUNTS_LOADED; - return $REFCOUNTS{"$func:$param"}; -} - - -$TLSTART = ''; -$TLEND = ' '; - -sub cfuncline_helper($$$){ - my($type, $name, $args) = @_; - my $idx = make_str_index_entry( - "$name()" . get_indexsubitem()); - $idx =~ s/ \(.*\)//; - $idx =~ s/\(\)//; # ???? - why both of these? - $args =~ s/(\s|\*)([a-z_][a-z_0-9]*),/$1$2<\/var>,/g; - $args =~ s/(\s|\*)([a-z_][a-z_0-9]*)$/$1$2<\/var>/s; - return ('' - . "" - . "" - . '
$type\ $idx($args)
'); -} -sub do_cmd_cfuncline{ - local($_) = @_; - my $type = next_argument(); - my $name = next_argument(); - my $args = next_argument(); - my $siginfo = cfuncline_helper($type, $name, $args); - return "
$siginfo\n
" . $_; -} -sub do_env_cfuncdesc{ - local($_) = @_; - my $type = next_argument(); - my $name = next_argument(); - my $args = next_argument(); - my $siginfo = cfuncline_helper($type, $name, $args); - my $result_rc = get_refcount($name, ''); - my $rcinfo = ''; - if ($result_rc eq '+1') { - $rcinfo = 'New reference'; - } - elsif ($result_rc eq '0') { - $rcinfo = 'Borrowed reference'; - } - elsif ($result_rc eq 'null') { - $rcinfo = 'Always NULL'; - } - if ($rcinfo ne '') { - $rcinfo = ( "\n
" - . "\n Return value:" - . "\n $rcinfo." - . "\n
"); - } - return "
$siginfo\n
" - . $rcinfo - . $_ - . '
'; -} - -sub do_cmd_cmemberline{ - local($_) = @_; - my $container = next_argument(); - my $type = next_argument(); - my $name = next_argument(); - my $idx = make_str_index_entry("$name" - . " ($container member)"); - $idx =~ s/ \(.*\)//; - return "
$type $idx\n
" - . $_; -} -sub do_env_cmemberdesc{ - local($_) = @_; - my $container = next_argument(); - my $type = next_argument(); - my $name = next_argument(); - my $idx = make_str_index_entry("$name" - . " ($container member)"); - $idx =~ s/ \(.*\)//; - return "
$type $idx\n
" - . $_ - . '
'; -} - -sub do_env_csimplemacrodesc{ - local($_) = @_; - my $name = next_argument(); - my $idx = make_str_index_entry("$name"); - return "
$idx\n
" - . $_ - . '
' -} - -sub do_env_ctypedesc{ - local($_) = @_; - my $index_name = next_optional_argument(); - my $type_name = next_argument(); - $index_name = $type_name - unless $index_name; - my($name, $aname, $ahref) = new_link_info(); - add_index_entry("$index_name (C type)", $ahref); - return "
$aname$type_name\n
" - . $_ - . '
' -} - -sub do_env_cvardesc{ - local($_) = @_; - my $var_type = next_argument(); - my $var_name = next_argument(); - my $idx = make_str_index_entry("$var_name" - . get_indexsubitem()); - $idx =~ s/ \(.*\)//; - return "
$var_type $idx\n" - . '
' - . $_ - . '
'; -} - -sub convert_args($){ - local($IN_DESC_HANDLER) = 1; - local($_) = @_; - return translate_commands($_); -} - -sub funcline_helper($$$){ - my($first, $idxitem, $arglist) = @_; - return (($first ? '
' : '') - . '
' - . "\n " - . "\n
$idxitem($arglist)
\n
"); -} - -sub do_env_funcdesc{ - local($_) = @_; - my $function_name = next_argument(); - my $arg_list = convert_args(next_argument()); - my $idx = make_str_index_entry("$function_name()" - . '' - . get_indexsubitem()); - $idx =~ s/ \(.*\)//; - $idx =~ s/\(\)<\/tt>/<\/tt>/; - return funcline_helper(1, $idx, $arg_list) . $_ . '
'; -} - -sub do_env_funcdescni{ - local($_) = @_; - my $function_name = next_argument(); - my $arg_list = convert_args(next_argument()); - my $prefix = "$function_name"; - return funcline_helper(1, $prefix, $arg_list) . $_ . '
'; -} - -sub do_cmd_funcline{ - local($_) = @_; - my $function_name = next_argument(); - my $arg_list = convert_args(next_argument()); - my $prefix = "$function_name()"; - my $idx = make_str_index_entry($prefix . get_indexsubitem()); - $prefix =~ s/\(\)//; - - return funcline_helper(0, $prefix, $arg_list) . $_; -} - -sub do_cmd_funclineni{ - local($_) = @_; - my $function_name = next_argument(); - my $arg_list = convert_args(next_argument()); - my $prefix = "$function_name"; - - return funcline_helper(0, $prefix, $arg_list) . $_; -} - -# Change this flag to index the opcode entries. I don't think it's very -# useful to index them, since they're only presented to describe the dis -# module. -# -$INDEX_OPCODES = 0; - -sub do_env_opcodedesc{ - local($_) = @_; - my $opcode_name = next_argument(); - my $arg_list = next_argument(); - my $idx; - if ($INDEX_OPCODES) { - $idx = make_str_index_entry("$opcode_name" - . ' (byte code instruction)'); - $idx =~ s/ \(byte code instruction\)//; - } - else { - $idx = "$opcode_name"; - } - my $stuff = "
$idx"; - if ($arg_list) { - $stuff .= "    $arg_list"; - } - return $stuff . "\n
" . $_ . '
'; -} - -sub do_env_datadesc{ - local($_) = @_; - my $dataname = next_argument(); - my $idx = make_str_index_entry("$dataname" . get_indexsubitem()); - $idx =~ s/ \(.*\)//; - return "
$idx\n
" - . $_ - . '
'; -} - -sub do_env_datadescni{ - local($_) = @_; - my $idx = next_argument(); - if (! $STRING_INDEX_TT) { - $idx = "$idx"; - } - return "
$idx\n
" . $_ . '
'; -} - -sub do_cmd_dataline{ - local($_) = @_; - my $data_name = next_argument(); - my $idx = make_str_index_entry("$data_name" . get_indexsubitem()); - $idx =~ s/ \(.*\)//; - return "
$idx
" . $_; -} - -sub do_cmd_datalineni{ - local($_) = @_; - my $data_name = next_argument(); - return "
$data_name
" . $_; -} - -sub do_env_excdesc{ - local($_) = @_; - my $excname = next_argument(); - my $idx = make_str_index_entry("$excname"); - return ("
${TLSTART}exception$TLEND$idx" - . "\n
" - . $_ - . '
'); -} - -sub do_env_fulllineitems{ return do_env_itemize(@_); } - - -sub handle_classlike_descriptor($$){ - local($_, $what) = @_; - $THIS_CLASS = next_argument(); - my $arg_list = convert_args(next_argument()); - $idx = make_str_index_entry( - "$THIS_CLASS ($what in $THIS_MODULE)" ); - $idx =~ s/ \(.*\)//; - my $prefix = "$TLSTART$what$TLEND$idx"; - return funcline_helper(1, $prefix, $arg_list) . $_ . ''; -} - -sub do_env_classdesc{ - return handle_classlike_descriptor($_[0], "class"); -} - -sub do_env_classdescstar{ - local($_) = @_; - $THIS_CLASS = next_argument(); - $idx = make_str_index_entry( - "$THIS_CLASS (class in $THIS_MODULE)"); - $idx =~ s/ \(.*\)//; - my $prefix = "${TLSTART}class$TLEND$idx"; - # Can't use funcline_helper() since there is no args list. - return "
$prefix\n
" . $_ . '
'; -} - -sub do_env_excclassdesc{ - return handle_classlike_descriptor($_[0], "exception"); -} - - -sub do_env_methoddesc{ - local($_) = @_; - my $class_name = next_optional_argument(); - $class_name = $THIS_CLASS - unless $class_name; - my $method = next_argument(); - my $arg_list = convert_args(next_argument()); - my $extra = ''; - if ($class_name) { - $extra = " ($class_name method)"; - } - my $idx = make_str_index_entry( - "$method()$extra"); - $idx =~ s/ \(.*\)//; - $idx =~ s/\(\)//; - return funcline_helper(1, $idx, $arg_list) . $_ . ''; -} - - -sub do_cmd_methodline{ - local($_) = @_; - my $class_name = next_optional_argument(); - $class_name = $THIS_CLASS - unless $class_name; - my $method = next_argument(); - my $arg_list = convert_args(next_argument()); - my $extra = ''; - if ($class_name) { - $extra = " ($class_name method)"; - } - my $idx = make_str_index_entry( - "$method()$extra"); - $idx =~ s/ \(.*\)//; - $idx =~ s/\(\)//; - return funcline_helper(0, $idx, $arg_list) . $_; -} - - -sub do_cmd_methodlineni{ - local($_) = @_; - next_optional_argument(); - my $method = next_argument(); - my $arg_list = convert_args(next_argument()); - return funcline_helper(0, $method, $arg_list) . $_; -} - -sub do_env_methoddescni{ - local($_) = @_; - next_optional_argument(); - my $method = next_argument(); - my $arg_list = convert_args(next_argument()); - return funcline_helper(1, $method, $arg_list) . $_ . ''; -} - - -sub do_env_memberdesc{ - local($_) = @_; - my $class = next_optional_argument(); - my $member = next_argument(); - $class = $THIS_CLASS - unless $class; - my $extra = ''; - $extra = " ($class attribute)" - if ($class ne ''); - my $idx = make_str_index_entry("$member$extra"); - $idx =~ s/ \(.*\)//; - $idx =~ s/\(\)//; - return "
$idx\n
" . $_ . '
'; -} - - -sub do_cmd_memberline{ - local($_) = @_; - my $class = next_optional_argument(); - my $member = next_argument(); - $class = $THIS_CLASS - unless $class; - my $extra = ''; - $extra = " ($class attribute)" - if ($class ne ''); - my $idx = make_str_index_entry("$member$extra"); - $idx =~ s/ \(.*\)//; - $idx =~ s/\(\)//; - return "
$idx
" . $_; -} - - -sub do_env_memberdescni{ - local($_) = @_; - next_optional_argument(); - my $member = next_argument(); - return "
$member\n
" - . $_ - . '
'; -} - - -sub do_cmd_memberlineni{ - local($_) = @_; - next_optional_argument(); - my $member = next_argument(); - return "
$member
" . $_; -} - - -@col_aligns = ('', '', '', '', ''); - -%FontConversions = ('cdata' => 'tt class="cdata"', - 'character' => 'tt class="character"', - 'class' => 'tt class="class"', - 'command' => 'code', - 'constant' => 'tt class="constant"', - 'exception' => 'tt class="exception"', - 'file' => 'tt class="file"', - 'filenq' => 'tt class="file"', - 'kbd' => 'kbd', - 'member' => 'tt class="member"', - 'programopt' => 'b', - 'textrm' => '', - ); - -sub fix_font($){ - # do a little magic on a font name to get the right behavior in the first - # column of the output table - my $font = $_[0]; - if (defined $FontConversions{$font}) { - $font = $FontConversions{$font}; - } - return $font; -} - -sub figure_column_alignment($){ - my $a = $_[0]; - if (!defined $a) { - return ''; - } - my $mark = substr($a, 0, 1); - my $r = ''; - if ($mark eq 'c') - { $r = ' align="center"'; } - elsif ($mark eq 'r') - { $r = ' align="right"'; } - elsif ($mark eq 'l') - { $r = ' align="left"'; } - elsif ($mark eq 'p') - { $r = ' align="left"'; } - return $r; -} - -sub setup_column_alignments($){ - local($_) = @_; - my($s1, $s2, $s3, $s4, $s5) = split(/[|]/,$_); - my $a1 = figure_column_alignment($s1); - my $a2 = figure_column_alignment($s2); - my $a3 = figure_column_alignment($s3); - my $a4 = figure_column_alignment($s4); - my $a5 = figure_column_alignment($s5); - $col_aligns[0] = ""; - $col_aligns[1] = ""; - $col_aligns[2] = ""; - $col_aligns[3] = ""; - $col_aligns[4] = ""; - # return the aligned header start tags - return ("", "", "", "", ""); -} - -sub get_table_col1_fonts(){ - my $font = $globals{'lineifont'}; - my($sfont, $efont) = ('', ''); - if ($font) { - $sfont = "<$font>"; - $efont = ""; - $efont =~ s/ .*>/>/; - } - return ($sfont, $efont); -} - -sub do_env_tableii{ - local($_) = @_; - my $arg = next_argument(); - my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg); - my $font = fix_font(next_argument()); - my $h1 = next_argument(); - my $h2 = next_argument(); - s/[\s\n]+//; - $globals{'lineifont'} = $font; - my $a1 = $col_aligns[0]; - my $a2 = $col_aligns[1]; - s/\\lineii' - . "\n " - . "\n " - . "\n $th1$h1\ " - . "\n $th2$h2\ " - . "\n " - . "\n " - . "\n " - . $_ - . "\n " - . "\n"; -} - -sub do_env_longtableii{ - return do_env_tableii(@_); -} - -sub do_cmd_lineii{ - local($_) = @_; - my $aligns = next_optional_argument(); - my $c1 = next_argument(); - my $c2 = next_argument(); - s/[\s\n]+//; - my($sfont, $efont) = get_table_col1_fonts(); - $c2 = ' ' if ($c2 eq ''); - my($c1align, $c2align) = split('\|', $aligns); - my $padding = ''; - if ($c1align =~ /align="right"/ || $c1 eq '') { - $padding = ' '; - } - return "\n $c1align$sfont$c1$efont$padding\n" - . " $c2align$c2" - . $_; -} - -sub do_env_tableiii{ - local($_) = @_; - my $arg = next_argument(); - my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg); - my $font = fix_font(next_argument()); - my $h1 = next_argument(); - my $h2 = next_argument(); - my $h3 = next_argument(); - s/[\s\n]+//; - $globals{'lineifont'} = $font; - my $a1 = $col_aligns[0]; - my $a2 = $col_aligns[1]; - my $a3 = $col_aligns[2]; - s/\\lineiii' - . "\n " - . "\n " - . "\n $th1$h1\ " - . "\n $th2$h2\ " - . "\n $th3$h3\ " - . "\n " - . "\n " - . "\n " - . $_ - . "\n " - . "\n"; -} - -sub do_env_longtableiii{ - return do_env_tableiii(@_); -} - -sub do_cmd_lineiii{ - local($_) = @_; - my $aligns = next_optional_argument(); - my $c1 = next_argument(); - my $c2 = next_argument(); - my $c3 = next_argument(); - s/[\s\n]+//; - my($sfont, $efont) = get_table_col1_fonts(); - $c3 = ' ' if ($c3 eq ''); - my($c1align, $c2align, $c3align) = split('\|', $aligns); - my $padding = ''; - if ($c1align =~ /align="right"/ || $c1 eq '') { - $padding = ' '; - } - return "\n $c1align$sfont$c1$efont$padding\n" - . " $c2align$c2\n" - . " $c3align$c3" - . $_; -} - -sub do_env_tableiv{ - local($_) = @_; - my $arg = next_argument(); - my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg); - my $font = fix_font(next_argument()); - my $h1 = next_argument(); - my $h2 = next_argument(); - my $h3 = next_argument(); - my $h4 = next_argument(); - s/[\s\n]+//; - $globals{'lineifont'} = $font; - my $a1 = $col_aligns[0]; - my $a2 = $col_aligns[1]; - my $a3 = $col_aligns[2]; - my $a4 = $col_aligns[3]; - s/\\lineiv' - . "\n " - . "\n " - . "\n $th1$h1\ " - . "\n $th2$h2\ " - . "\n $th3$h3\ " - . "\n $th4$h4\ " - . "\n " - . "\n " - . "\n " - . $_ - . "\n " - . "\n"; -} - -sub do_env_longtableiv{ - return do_env_tableiv(@_); -} - -sub do_cmd_lineiv{ - local($_) = @_; - my $aligns = next_optional_argument(); - my $c1 = next_argument(); - my $c2 = next_argument(); - my $c3 = next_argument(); - my $c4 = next_argument(); - s/[\s\n]+//; - my($sfont, $efont) = get_table_col1_fonts(); - $c4 = ' ' if ($c4 eq ''); - my($c1align, $c2align, $c3align, $c4align) = split('\|', $aligns); - my $padding = ''; - if ($c1align =~ /align="right"/ || $c1 eq '') { - $padding = ' '; - } - return "\n $c1align$sfont$c1$efont$padding\n" - . " $c2align$c2\n" - . " $c3align$c3\n" - . " $c4align$c4" - . $_; -} - -sub do_env_tablev{ - local($_) = @_; - my $arg = next_argument(); - my($th1, $th2, $th3, $th4, $th5) = setup_column_alignments($arg); - my $font = fix_font(next_argument()); - my $h1 = next_argument(); - my $h2 = next_argument(); - my $h3 = next_argument(); - my $h4 = next_argument(); - my $h5 = next_argument(); - s/[\s\n]+//; - $globals{'lineifont'} = $font; - my $a1 = $col_aligns[0]; - my $a2 = $col_aligns[1]; - my $a3 = $col_aligns[2]; - my $a4 = $col_aligns[3]; - my $a5 = $col_aligns[4]; - s/\\linev' - . "\n " - . "\n " - . "\n $th1$h1\ " - . "\n $th2$h2\ " - . "\n $th3$h3\ " - . "\n $th4$h4\ " - . "\n $th5$h5\ " - . "\n " - . "\n " - . "\n " - . $_ - . "\n " - . "\n"; -} - -sub do_env_longtablev{ - return do_env_tablev(@_); -} - -sub do_cmd_linev{ - local($_) = @_; - my $aligns = next_optional_argument(); - my $c1 = next_argument(); - my $c2 = next_argument(); - my $c3 = next_argument(); - my $c4 = next_argument(); - my $c5 = next_argument(); - s/[\s\n]+//; - my($sfont, $efont) = get_table_col1_fonts(); - $c5 = ' ' if ($c5 eq ''); - my($c1align, $c2align, $c3align, $c4align, $c5align) = split('\|',$aligns); - my $padding = ''; - if ($c1align =~ /align="right"/ || $c1 eq '') { - $padding = ' '; - } - return "\n $c1align$sfont$c1$efont$padding\n" - . " $c2align$c2\n" - . " $c3align$c3\n" - . " $c4align$c4\n" - . " $c5align$c5" - . $_; -} - - -# These can be used to control the title page appearance; -# they need a little bit of documentation. -# -# If $TITLE_PAGE_GRAPHIC is set, it should be the name of a file in the -# $ICONSERVER directory, or include path information (other than "./"). The -# default image type will be assumed if an extension is not provided. -# -# If specified, the "title page" will contain two colums: one containing the -# title/author/etc., and the other containing the graphic. Use the other -# four variables listed here to control specific details of the layout; all -# are optional. -# -# $TITLE_PAGE_GRAPHIC = "my-company-logo"; -# $TITLE_PAGE_GRAPHIC_COLWIDTH = "30%"; -# $TITLE_PAGE_GRAPHIC_WIDTH = 150; -# $TITLE_PAGE_GRAPHIC_HEIGHT = 150; -# $TITLE_PAGE_GRAPHIC_ON_RIGHT = 0; - -sub make_my_titlepage(){ - my $the_title = ""; - if ($t_title) { - $the_title .= "\n

$t_title

"; - } - else { - write_warnings("\nThis document has no title."); - } - if ($t_author) { - if ($t_authorURL) { - my $href = translate_commands($t_authorURL); - $href = make_named_href('author', $href, - "$t_author" - . ''); - $the_title .= "\n

$href

"; - } - else { - $the_title .= ("\n

$t_author" - . '

'); - } - } - else { - write_warnings("\nThere is no author for this document."); - } - if ($t_institute) { - $the_title .= "\n

$t_institute

"; - } - if ($DEVELOPER_ADDRESS) { - $the_title .= "\n

$DEVELOPER_ADDRESS

"; - } - if ($t_affil) { - $the_title .= "\n

$t_affil

"; - } - if ($t_date) { - $the_title .= "\n

"; - if ($PACKAGE_VERSION) { - $the_title .= ('Release ' - . "$PACKAGE_VERSION$RELEASE_INFO
\n"); - } - $the_title .= "$t_date

" - } - if ($t_address) { - $the_title .= "\n

$t_address

"; - } - else { - $the_title .= "\n

"; - } - if ($t_email) { - $the_title .= "\n

$t_email

"; - } - return $the_title; -} - -sub make_my_titlegraphic(){ - my $filename = make_icon_filename($TITLE_PAGE_GRAPHIC); - my $graphic = "\n"; - return $graphic; -} - -sub do_cmd_maketitle{ - local($_) = @_; - my $the_title = "\n"; - if ($EXTERNAL_UP_LINK) { - # This generates a element in the wrong place (the - # body), but I don't see any other way to get this generated - # at all. Browsers like Mozilla, that support navigation - # links, can make use of this. - $the_title .= ("\n"); - } - $the_title .= '
'; - if ($TITLE_PAGE_GRAPHIC) { - if ($TITLE_PAGE_GRAPHIC_ON_RIGHT) { - $the_title .= ("\n" - . "\n\n" - . make_my_titlegraphic() - . "\n
" - . make_my_titlepage() - . "
"); - } - else { - $the_title .= ("\n\n" - . make_my_titlegraphic() - . "\n
" - . make_my_titlepage() - . "
"); - } - } - else { - $the_title .= ("\n
" - . make_my_titlepage() - . "\n
"); - } - $the_title .= "\n
"; - return $the_title . $_; - $the_title .= "\n"; - return $the_title . $_ ; -} - - -# -# Module synopsis support -# - -require SynopsisTable; - -sub get_chapter_id(){ - my $id = do_cmd_thechapter(''); - $id =~ s/(\d+)<\/SPAN>/$1/; - $id =~ s/\.//; - return $id; -} - -# 'chapter' => 'SynopsisTable instance' -%ModuleSynopses = (); - -sub get_synopsis_table($){ - my $chap = $_[0]; - my $key; - foreach $key (keys %ModuleSynopses) { - if ($key eq $chap) { - return $ModuleSynopses{$chap}; - } - } - my $st = SynopsisTable->new(); - $ModuleSynopses{$chap} = $st; - return $st; -} - -sub do_cmd_moduleauthor{ - local($_) = @_; - next_argument(); - next_argument(); - return $_; -} - -sub do_cmd_sectionauthor{ - local($_) = @_; - next_argument(); - next_argument(); - return $_; -} - -sub do_cmd_declaremodule{ - local($_) = @_; - my $key = next_optional_argument(); - my $type = next_argument(); - my $name = next_argument(); - my $st = get_synopsis_table(get_chapter_id()); - # - $key = $name unless $key; - $type = 'built-in' if $type eq 'builtin'; - $st->declare($name, $key, $type); - define_module($type, $name); - return anchor_label("module-$key",$CURRENT_FILE,$_) -} - -sub do_cmd_modulesynopsis{ - local($_) = @_; - my $st = get_synopsis_table(get_chapter_id()); - $st->set_synopsis($THIS_MODULE, translate_commands(next_argument())); - return $_; -} - -sub do_cmd_localmoduletable{ - local($_) = @_; - my $chap = get_chapter_id(); - my $st = get_synopsis_table($chap); - $st->set_file("$CURRENT_FILE"); - return "<$chap>\\tableofchildlinks[off]" . $_; -} - -sub process_all_localmoduletables(){ - my $key; - foreach $key (keys %ModuleSynopses) { - my $st = $ModuleSynopses{$key}; - my $file = $st->get_file(); - if ($file) { - process_localmoduletables_in_file($file); - } - else { - print "\nsynopsis table $key has no file association\n"; - } - } -} - -sub process_localmoduletables_in_file($){ - my $file = $_[0]; - open(MYFILE, "<$file"); - local($_); - sysread(MYFILE, $_, 1024*1024); - close(MYFILE); - # need to get contents of file in $_ - while (/<(\d+)>/) { - my $match = $&; - my $chap = $1; - my $st = get_synopsis_table($chap); - my $data = $st->tohtml(); - s/$match/$data/; - } - open(MYFILE,">$file"); - print MYFILE $_; - close(MYFILE); -} -sub process_python_state(){ - process_all_localmoduletables(); - process_grammar_files(); -} - - -# -# "See also:" -- references placed at the end of a \section -# - -sub do_env_seealso{ - return ("
\n " - . "

See Also:

\n" - . $_[0] - . '
'); -} - -sub do_env_seealsostar{ - return ("
\n " - . $_[0] - . '
'); -} - -sub do_cmd_seemodule{ - # Insert the right magic to jump to the module definition. This should - # work most of the time, at least for repeat builds.... - local($_) = @_; - my $key = next_optional_argument(); - my $module = next_argument(); - my $text = next_argument(); - my $period = '.'; - $key = $module - unless $key; - if ($text =~ /\.$/) { - $period = ''; - } - return ('
' - . "\n
Module " - . "$module:" - . "\n
$text$period\n
" - . $_); -} - -sub strip_html_markup($){ - my $str = $_[0]; - my $s = "$str"; - $s =~ s/<[a-zA-Z0-9]+(\s+[a-zA-Z0-9]+(\s*=\s*(\'[^\']*\'|\"[^\"]*\"|[a-zA-Z0-9]+))?)*\s*>//g; - $s =~ s/<\/[a-zA-Z0-9]+>//g; - return $s; -} - -sub handle_rfclike_reference($$$){ - local($_, $what, $format) = @_; - my $rfcnum = next_argument(); - my $title = next_argument(); - my $text = next_argument(); - my $url = get_rfc_url($rfcnum, $format); - my $icon = get_link_icon($url); - my $attrtitle = strip_html_markup($title); - return '
' - . "\n
$what $rfcnum, $title$icon" - . "\n
$text\n
" - . $_; -} - -sub do_cmd_seepep{ - return handle_rfclike_reference($_[0], "PEP", $PEP_FORMAT); -} - -sub do_cmd_seerfc{ - # XXX Would be nice to add links to the text/plain and PDF versions. - return handle_rfclike_reference($_[0], "RFC", $RFC_FORMAT); -} - -sub do_cmd_seetitle{ - local($_) = @_; - my $url = next_optional_argument(); - my $title = next_argument(); - my $text = next_argument(); - if ($url) { - my $icon = get_link_icon($url); - return '
' - . "\n
$title$icon" - . "\n
$text\n
" - . $_; - } - return '
' - . "\n
$title" - . "\n
$text\n
" - . $_; -} - -sub do_cmd_seeurl{ - local($_) = @_; - my $url = next_argument(); - my $text = next_argument(); - my $icon = get_link_icon($url); - return '
' - . "\n
$url$icon" - . "\n
$text\n
" - . $_; -} - -sub do_cmd_seetext{ - local($_) = @_; - my $content = next_argument(); - return '

' . $content . '

' . $_; -} - - -# -# Definition list support. -# - -sub do_env_definitions{ - return "
" . $_[0] . "
\n"; -} - -sub do_cmd_term{ - local($_) = @_; - my $term = next_argument(); - my($name, $aname, $ahref) = new_link_info(); - # could easily add an index entry here... - return "
$aname" . $term . "\n
" . $_; -} - - -# I don't recall exactly why this was needed, but it was very much needed. -# We'll see if anything breaks when I move the "code" line out -- some -# things broke with it in. - -#code # {} -process_commands_wrap_deferred(<<_RAW_ARG_DEFERRED_CMDS_); -declaremodule # [] # {} # {} -funcline # {} # {} -funclineni # {} # {} -memberline # [] # {} -methodline # [] # {} # {} -methodlineni # [] # {} # {} -modulesynopsis # {} -platform # {} -samp # {} -setindexsubitem # {} -withsubitem # {} # {} -_RAW_ARG_DEFERRED_CMDS_ - - -$alltt_start = '
';
-$alltt_end = '
'; - -sub do_env_alltt{ - local ($_) = @_; - local($closures,$reopens,@open_block_tags); - - # get the tag-strings for all open tags - local(@keep_open_tags) = @$open_tags_R; - ($closures,$reopens) = &preserve_open_tags() if (@$open_tags_R); - - # get the tags for text-level tags only - $open_tags_R = [ @keep_open_tags ]; - local($local_closures, $local_reopens); - ($local_closures, $local_reopens,@open_block_tags) - = &preserve_open_block_tags - if (@$open_tags_R); - - $open_tags_R = [ @open_block_tags ]; - - do { - local($open_tags_R) = [ @open_block_tags ]; - local(@save_open_tags) = (); - - local($cnt) = ++$global{'max_id'}; - $_ = join('',"$O$cnt$C\\tt$O", ++$global{'max_id'}, $C - , $_ , $O, $global{'max_id'}, "$C$O$cnt$C"); - - $_ = &translate_environments($_); - $_ = &translate_commands($_) if (/\\/); - - # preserve space-runs, using   - while (s/(\S) ( +)/$1$2;SPMnbsp;/g){}; - s/(
) /$1;SPMnbsp;/g; - - $_ = join('', $closures, $alltt_start, $local_reopens - , $_ - , &balance_tags() #, $local_closures - , $alltt_end, $reopens); - undef $open_tags_R; undef @save_open_tags; - }; - $open_tags_R = [ @keep_open_tags ]; - $_; -} - -# List of all filenames produced ny do_cmd_verbatiminput() -%VerbatimFiles = (); -@VerbatimOutputs = (); - -sub get_verbatim_output_name($){ - my $file = $_[0]; - # - # Re-write the source filename to always use a .txt extension - # so that Web servers will present it as text/plain. This is - # needed since there is no other even moderately reliable way - # to get the right Content-Type header on text files for - # servers which we can't configure (like python.org mirrors). - # - if (defined $VerbatimFiles{$file}) { - # We've seen this one before; re-use the same output file. - return $VerbatimFiles{$file}; - } - my($srcname, $srcdir, $srcext) = fileparse($file, '\..*'); - $filename = "$srcname.txt"; - # - # We need to determine if our default filename is already - # being used, and find a new one it it is. If the name is in - # used, this algorithm will first attempt to include the - # source extension as part of the name, and if that is also in - # use (if the same file is included multiple times, or if - # another source file has that as the base name), a counter is - # used instead. - # - my $found = 1; - FIND: - while ($found) { - foreach $fn (@VerbatimOutputs) { - if ($fn eq $filename) { - if ($found == 1) { - $srcext =~ s/^[.]//; # Remove '.' from extension - $filename = "$srcname-$srcext.txt"; - } - else { - $filename = "$srcname-$found.txt"; - } - ++$found; - next FIND; - } - } - $found = 0; - } - push @VerbatimOutputs, $filename; - $VerbatimFiles{$file} = $filename; - return $filename; -} - -sub do_cmd_verbatiminput{ - local($_) = @_; - my $fname = next_argument(); - my $file; - my $found = 0; - my $texpath; - # Search TEXINPUTS for the input file, the way we're supposed to: - foreach $texpath (split /$envkey/, $TEXINPUTS) { - $file = "$texpath$dd$fname"; - last if ($found = (-f $file)); - } - my $filename = ''; - my $text; - if ($found) { - open(MYFILE, "<$file") || die "\n$!\n"; - read(MYFILE, $text, 1024*1024); - close(MYFILE); - $filename = get_verbatim_output_name($file); - # Now that we have a filename, write it out. - open(MYFILE, ">$filename"); - print MYFILE $text; - close(MYFILE); - # - # These rewrites convert the raw text to something that will - # be properly visible as HTML and also will pass through the - # vagaries of conversion through LaTeX2HTML. The order in - # which the specific rewrites are performed is significant. - # - $text =~ s/\&/\&/g; - # These need to happen before the normal < and > re-writes, - # since we need to avoid LaTeX2HTML's attempt to perform - # ligature processing without regard to context (since it - # doesn't have font information). - $text =~ s/--/-&\#45;/g; - $text =~ s/<>/\>\&\#62;/g; - # Just normal re-writes... - $text =~ s//\>/g; - # These last isn't needed for the HTML, but is needed to get - # past LaTeX2HTML processing TeX macros. We use \ instead - # of / since many browsers don't support that. - $text =~ s/\\/\&\#92;/g; - } - else { - return 'Could not locate requested file $fname!\n'; - } - my $note = 'Download as text.'; - if ($file ne $filename) { - $note = ('Download as text (original file name: ' - . $fname - . ').'); - } - return ("
\n
"
-            . $text
-            . "
\n
\n" - . "$note" - . "\n
" - . $_); -} - -1; # This must be the last line diff --git a/olddoc/setup b/olddoc/setup deleted file mode 100644 index 909ce138..00000000 --- a/olddoc/setup +++ /dev/null @@ -1,4 +0,0 @@ -# tex - -TEXINPUTS=".:./texinputs:" -export TEXINPUTS diff --git a/olddoc/texinputs/boilerplate.tex b/olddoc/texinputs/boilerplate.tex deleted file mode 100644 index 56585ee7..00000000 --- a/olddoc/texinputs/boilerplate.tex +++ /dev/null @@ -1,9 +0,0 @@ -\author{Jan Decaluwe} -\authoraddress{ -Email: \email{jan@jandecaluwe.com} -} - -\date{May 1, 2006} % XXX update before release! -\release{0.5.1} % software release, not documentation -\setreleaseinfo{} % empty for final release -\setshortversion{0.5} % major.minor only for software diff --git a/olddoc/texinputs/copyright.tex b/olddoc/texinputs/copyright.tex deleted file mode 100644 index 309084aa..00000000 --- a/olddoc/texinputs/copyright.tex +++ /dev/null @@ -1,2 +0,0 @@ -Copyright \copyright{} 2003-2006 Jan Decaluwe. -All rights reserved. diff --git a/olddoc/texinputs/distutils.sty b/olddoc/texinputs/distutils.sty deleted file mode 100644 index 45e2ed11..00000000 --- a/olddoc/texinputs/distutils.sty +++ /dev/null @@ -1,33 +0,0 @@ -% -% LaTeX commands and macros needed for the two Distutils manuals, -% inst.tex and dist.tex. -% -% $Id$ -% - -% My gripe list about the Python style files: -% * I want italics in verbatim environments for variable -% text (verbatim.sty?) -% * I hate escaping underscores (url.sty fixes this) - -% '\command' is for Distutils commands which, depending on your -% perspective, are just arguments to the setup script, or sub- -% commands of the setup script, or the classes that implement -% each "command". -\newcommand{\command}[1]{\code{#1}} - -% '\option' is for Distutils options *in* the setup script. Command- -% line options *to* the setup script are marked up in the usual -% way, ie. with '\programopt' or '\longprogramopt' -\newcommand{\option}[1]{\textsf{\small{#1}}} - -% '\filevar' is for variable components of file/path names -- eg. -% when you put 'prefix' in a pathname, you mark it up with -% '\filevar' so that it still looks pathname-ish, but is -% distinguished from the literal part of the path. Fred says -% this can be accomplished just fine with '\var', but I violently -% disagree. Pistols at dawn will sort this one out. -\newcommand{\filevar}[1]{{\textsl{\filenq{#1}}}} - -% Just while the code and docs are still under development. -\newcommand{\XXX}[1]{\textbf{**#1**}} diff --git a/olddoc/texinputs/fancyhdr.sty b/olddoc/texinputs/fancyhdr.sty deleted file mode 100644 index c1026e95..00000000 --- a/olddoc/texinputs/fancyhdr.sty +++ /dev/null @@ -1,329 +0,0 @@ -% fancyhdr.sty version 1.99d -% Fancy headers and footers for LaTeX. -% Piet van Oostrum, Dept of Computer Science, University of Utrecht -% Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands -% Telephone: +31 30 2532180. Email: piet@cs.ruu.nl -% ======================================================================== -% LICENCE: This is free software. You are allowed to use and distribute -% this software in any way you like. You are also allowed to make modified -% versions of it, but you can distribute a modified version only if you -% clearly indicate that it is a modified version and the person(s) who -% modified it. This indication should be in a prominent place, e.g. in the -% top of the file. If possible a contact address, preferably by email, -% should be given for these persons. If that is feasible the modifications -% should be indicated in the source code. -% ======================================================================== -% MODIFICATION HISTORY: -% Sep 16, 1994 -% version 1.4: Correction for use with \reversemargin -% Sep 29, 1994: -% version 1.5: Added the \iftopfloat, \ifbotfloat and \iffloatpage commands -% Oct 4, 1994: -% version 1.6: Reset single spacing in headers/footers for use with -% setspace.sty or doublespace.sty -% Oct 4, 1994: -% version 1.7: changed \let\@mkboth\markboth to -% \def\@mkboth{\protect\markboth} to make it more robust -% Dec 5, 1994: -% version 1.8: corrections for amsbook/amsart: define \@chapapp and (more -% importantly) use the \chapter/sectionmark definitions from ps@headings if -% they exist (which should be true for all standard classes). -% May 31, 1995: -% version 1.9: The proposed \renewcommand{\headrulewidth}{\iffloatpage... -% construction in the doc did not work properly with the fancyplain style. -% June 1, 1995: -% version 1.91: The definition of \@mkboth wasn't restored on subsequent -% \pagestyle{fancy}'s. -% June 1, 1995: -% version 1.92: The sequence \pagestyle{fancyplain} \pagestyle{plain} -% \pagestyle{fancy} would erroneously select the plain version. -% June 1, 1995: -% version 1.93: \fancypagestyle command added. -% Dec 11, 1995: -% version 1.94: suggested by Conrad Hughes -% CJCH, Dec 11, 1995: added \footruleskip to allow control over footrule -% position (old hardcoded value of .3\normalbaselineskip is far too high -% when used with very small footer fonts). -% Jan 31, 1996: -% version 1.95: call \@normalsize in the reset code if that is defined, -% otherwise \normalsize. -% this is to solve a problem with ucthesis.cls, as this doesn't -% define \@currsize. Unfortunately for latex209 calling \normalsize doesn't -% work as this is optimized to do very little, so there \@normalsize should -% be called. Hopefully this code works for all versions of LaTeX known to -% mankind. -% April 25, 1996: -% version 1.96: initialize \headwidth to a magic (negative) value to catch -% most common cases that people change it before calling \pagestyle{fancy}. -% Note it can't be initialized when reading in this file, because -% \textwidth could be changed afterwards. This is quite probable. -% We also switch to \MakeUppercase rather than \uppercase and introduce a -% \nouppercase command for use in headers. and footers. -% May 3, 1996: -% version 1.97: Two changes: -% 1. Undo the change in version 1.8 (using the pagestyle{headings} defaults -% for the chapter and section marks. The current version of amsbook and -% amsart classes don't seem to need them anymore. Moreover the standard -% latex classes don't use \markboth if twoside isn't selected, and this is -% confusing as \leftmark doesn't work as expected. -% 2. include a call to \ps@empty in ps@@fancy. This is to solve a problem -% in the amsbook and amsart classes, that make global changes to \topskip, -% which are reset in \ps@empty. Hopefully this doesn't break other things. -% May 7, 1996: -% version 1.98: -% Added % after the line \def\nouppercase -% May 7, 1996: -% version 1.99: This is the alpha version of fancyhdr 2.0 -% Introduced the new commands \fancyhead, \fancyfoot, and \fancyhf. -% Changed \headrulewidth, \footrulewidth, \footruleskip to -% macros rather than length parameters, In this way they can be -% conditionalized and they don't consume length registers. There is no need -% to have them as length registers unless you want to do calculations with -% them, which is unlikely. Note that this may make some uses of them -% incompatible (i.e. if you have a file that uses \setlength or \xxxx=) -% May 10, 1996: -% version 1.99a: -% Added a few more % signs -% May 10, 1996: -% version 1.99b: -% Changed the syntax of \f@nfor to be resistent to catcode changes of := -% Removed the [1] from the defs of \lhead etc. because the parameter is -% consumed by the \@[xy]lhead etc. macros. -% June 24, 1997: -% version 1.99c: -% corrected \nouppercase to also include the protected form of \MakeUppercase -% \global added to manipulation of \headwidth. -% \iffootnote command added. -% Some comments added about \@fancyhead and \@fancyfoot. -% Aug 24, 1998 -% version 1.99d -% Changed the default \ps@empty to \ps@@empty in order to allow -% \fancypagestyle{empty} redefinition. - -\let\fancy@def\gdef - -\def\if@mpty#1#2#3{\def\temp@ty{#1}\ifx\@empty\temp@ty #2\else#3\fi} - -% Usage: \@forc \var{charstring}{command to be executed for each char} -% This is similar to LaTeX's \@tfor, but expands the charstring. - -\def\@forc#1#2#3{\expandafter\f@rc\expandafter#1\expandafter{#2}{#3}} -\def\f@rc#1#2#3{\def\temp@ty{#2}\ifx\@empty\temp@ty\else - \f@@rc#1#2\f@@rc{#3}\fi} -\def\f@@rc#1#2#3\f@@rc#4{\def#1{#2}#4\f@rc#1{#3}{#4}} - -% Usage: \f@nfor\name:=list\do{body} -% Like LaTeX's \@for but an empty list is treated as a list with an empty -% element - -\newcommand{\f@nfor}[3]{\edef\@fortmp{#2}% - \expandafter\@forloop#2,\@nil,\@nil\@@#1{#3}} - -% Usage: \def@ult \cs{defaults}{argument} -% sets \cs to the characters from defaults appearing in argument -% or defaults if it would be empty. All characters are lowercased. - -\newcommand\def@ult[3]{% - \edef\temp@a{\lowercase{\edef\noexpand\temp@a{#3}}}\temp@a - \def#1{}% - \@forc\tmpf@ra{#2}% - {\expandafter\if@in\tmpf@ra\temp@a{\edef#1{#1\tmpf@ra}}{}}% - \ifx\@empty#1\def#1{#2}\fi} -% -% \if@in -% -\newcommand{\if@in}[4]{% - \edef\temp@a{#2}\def\temp@b##1#1##2\temp@b{\def\temp@b{##1}}% - \expandafter\temp@b#2#1\temp@b\ifx\temp@a\temp@b #4\else #3\fi} - -\newcommand{\fancyhead}{\@ifnextchar[{\f@ncyhf h}{\f@ncyhf h[]}} -\newcommand{\fancyfoot}{\@ifnextchar[{\f@ncyhf f}{\f@ncyhf f[]}} -\newcommand{\fancyhf}{\@ifnextchar[{\f@ncyhf {}}{\f@ncyhf {}[]}} - -% The header and footer fields are stored in command sequences with -% names of the form: \f@ncy with for [eo], form [lcr] -% and from [hf]. - -\def\f@ncyhf#1[#2]#3{% - \def\temp@c{}% - \@forc\tmpf@ra{#2}% - {\expandafter\if@in\tmpf@ra{eolcrhf,EOLCRHF}% - {}{\edef\temp@c{\temp@c\tmpf@ra}}}% - \ifx\@empty\temp@c\else - \ifx\PackageError\undefined - \errmessage{Illegal char `\temp@c' in fancyhdr argument: - [#2]}\else - \PackageError{Fancyhdr}{Illegal char `\temp@c' in fancyhdr argument: - [#2]}{}\fi - \fi - \f@nfor\temp@c{#2}% - {\def@ult\f@@@eo{eo}\temp@c - \def@ult\f@@@lcr{lcr}\temp@c - \def@ult\f@@@hf{hf}{#1\temp@c}% - \@forc\f@@eo\f@@@eo - {\@forc\f@@lcr\f@@@lcr - {\@forc\f@@hf\f@@@hf - {\expandafter\fancy@def\csname - f@ncy\f@@eo\f@@lcr\f@@hf\endcsname - {#3}}}}}} - -% Fancyheadings version 1 commands. These are more or less deprecated, -% but they continue to work. - -\newcommand{\lhead}{\@ifnextchar[{\@xlhead}{\@ylhead}} -\def\@xlhead[#1]#2{\fancy@def\f@ncyelh{#1}\fancy@def\f@ncyolh{#2}} -\def\@ylhead#1{\fancy@def\f@ncyelh{#1}\fancy@def\f@ncyolh{#1}} - -\newcommand{\chead}{\@ifnextchar[{\@xchead}{\@ychead}} -\def\@xchead[#1]#2{\fancy@def\f@ncyech{#1}\fancy@def\f@ncyoch{#2}} -\def\@ychead#1{\fancy@def\f@ncyech{#1}\fancy@def\f@ncyoch{#1}} - -\newcommand{\rhead}{\@ifnextchar[{\@xrhead}{\@yrhead}} -\def\@xrhead[#1]#2{\fancy@def\f@ncyerh{#1}\fancy@def\f@ncyorh{#2}} -\def\@yrhead#1{\fancy@def\f@ncyerh{#1}\fancy@def\f@ncyorh{#1}} - -\newcommand{\lfoot}{\@ifnextchar[{\@xlfoot}{\@ylfoot}} -\def\@xlfoot[#1]#2{\fancy@def\f@ncyelf{#1}\fancy@def\f@ncyolf{#2}} -\def\@ylfoot#1{\fancy@def\f@ncyelf{#1}\fancy@def\f@ncyolf{#1}} - -\newcommand{\cfoot}{\@ifnextchar[{\@xcfoot}{\@ycfoot}} -\def\@xcfoot[#1]#2{\fancy@def\f@ncyecf{#1}\fancy@def\f@ncyocf{#2}} -\def\@ycfoot#1{\fancy@def\f@ncyecf{#1}\fancy@def\f@ncyocf{#1}} - -\newcommand{\rfoot}{\@ifnextchar[{\@xrfoot}{\@yrfoot}} -\def\@xrfoot[#1]#2{\fancy@def\f@ncyerf{#1}\fancy@def\f@ncyorf{#2}} -\def\@yrfoot#1{\fancy@def\f@ncyerf{#1}\fancy@def\f@ncyorf{#1}} - -\newdimen\headwidth -\newcommand{\headrulewidth}{0.4pt} -\newcommand{\footrulewidth}{\z@skip} -\newcommand{\footruleskip}{.3\normalbaselineskip} - -% Fancyplain stuff shouldn't be used anymore (rather -% \fancypagestyle{plain} should be used), but it must be present for -% compatibility reasons. - -\newcommand{\plainheadrulewidth}{\z@skip} -\newcommand{\plainfootrulewidth}{\z@skip} -\newif\if@fancyplain \@fancyplainfalse -\def\fancyplain#1#2{\if@fancyplain#1\else#2\fi} - -\headwidth=-123456789sp %magic constant - -% Command to reset various things in the headers: -% a.o. single spacing (taken from setspace.sty) -% and the catcode of ^^M (so that epsf files in the header work if a -% verbatim crosses a page boundary) -% It also defines a \nouppercase command that disables \uppercase and -% \Makeuppercase. It can only be used in the headers and footers. -\def\fancy@reset{\restorecr - \def\baselinestretch{1}% - \def\nouppercase##1{{\let\uppercase\relax\let\MakeUppercase\relax - \expandafter\let\csname MakeUppercase \endcsname\relax##1}}% - \ifx\undefined\@newbaseline% NFSS not present; 2.09 or 2e - \ifx\@normalsize\undefined \normalsize % for ucthesis.cls - \else \@normalsize \fi - \else% NFSS (2.09) present - \@newbaseline% - \fi} - -% Initialization of the head and foot text. - -% The default values still contain \fancyplain for compatibility. -\fancyhf{} % clear all -% lefthead empty on ``plain'' pages, \rightmark on even, \leftmark on odd pages -% evenhead empty on ``plain'' pages, \leftmark on even, \rightmark on odd pages -\fancyhead[el,or]{\fancyplain{}{\sl\rightmark}} -\fancyhead[er,ol]{\fancyplain{}{\sl\leftmark}} -\fancyfoot[c]{\rm\thepage} % page number - -% Put together a header or footer given the left, center and -% right text, fillers at left and right and a rule. -% The \lap commands put the text into an hbox of zero size, -% so overlapping text does not generate an errormessage. -% These macros have 5 parameters: -% 1. \@lodd or \@rodd % This determines at which side the header will stick -% out. -% 2. \f@ncyolh, \f@ncyelh, \f@ncyolf or \f@ncyelf. This is the left component. -% 3. \f@ncyoch, \f@ncyech, \f@ncyocf or \f@ncyecf. This is the middle comp. -% 4. \f@ncyorh, \f@ncyerh, \f@ncyorf or \f@ncyerf. This is the right component. -% 5. \@lodd or \@rodd % This determines at which side the header will stick -% out. This is the reverse of parameter nr. 1. One of them is always -% \relax and the other one is \hss (after expansion). - -\def\@fancyhead#1#2#3#4#5{#1\hbox to\headwidth{\fancy@reset\vbox{\hbox -{\rlap{\parbox[b]{\headwidth}{\raggedright#2\strut}}\hfill -\parbox[b]{\headwidth}{\centering#3\strut}\hfill -\llap{\parbox[b]{\headwidth}{\raggedleft#4\strut}}}\headrule}}#5} - -\def\@fancyfoot#1#2#3#4#5{#1\hbox to\headwidth{\fancy@reset\vbox{\footrule -\hbox{\rlap{\parbox[t]{\headwidth}{\raggedright#2\strut}}\hfill -\parbox[t]{\headwidth}{\centering#3\strut}\hfill -\llap{\parbox[t]{\headwidth}{\raggedleft#4\strut}}}}}#5} - -\def\headrule{{\if@fancyplain\let\headrulewidth\plainheadrulewidth\fi -\hrule\@height\headrulewidth\@width\headwidth \vskip-\headrulewidth}} - -\def\footrule{{\if@fancyplain\let\footrulewidth\plainfootrulewidth\fi -\vskip-\footruleskip\vskip-\footrulewidth -\hrule\@width\headwidth\@height\footrulewidth\vskip\footruleskip}} - -\def\ps@fancy{% -\@ifundefined{@chapapp}{\let\@chapapp\chaptername}{}%for amsbook -% -% Define \MakeUppercase for old LaTeXen. -% Note: we used \def rather than \let, so that \let\uppercase\relax (from -% the version 1 documentation) will still work. -% -\@ifundefined{MakeUppercase}{\def\MakeUppercase{\uppercase}}{}% -\@ifundefined{chapter}{\def\sectionmark##1{\markboth -{\MakeUppercase{\ifnum \c@secnumdepth>\z@ - \thesection\hskip 1em\relax \fi ##1}}{}}% -\def\subsectionmark##1{\markright {\ifnum \c@secnumdepth >\@ne - \thesubsection\hskip 1em\relax \fi ##1}}}% -{\def\chaptermark##1{\markboth {\MakeUppercase{\ifnum \c@secnumdepth>\m@ne - \@chapapp\ \thechapter. \ \fi ##1}}{}}% -\def\sectionmark##1{\markright{\MakeUppercase{\ifnum \c@secnumdepth >\z@ - \thesection. \ \fi ##1}}}}% -%\csname ps@headings\endcsname % use \ps@headings defaults if they exist -\ps@@fancy -\gdef\ps@fancy{\@fancyplainfalse\ps@@fancy}% -% Initialize \headwidth if the user didn't -% -\ifdim\headwidth<0sp -% -% This catches the case that \headwidth hasn't been initialized and the -% case that the user added something to \headwidth in the expectation that -% it was initialized to \textwidth. We compensate this now. This loses if -% the user intended to multiply it by a factor. But that case is more -% likely done by saying something like \headwidth=1.2\textwidth. -% The doc says you have to change \headwidth after the first call to -% \pagestyle{fancy}. This code is just to catch the most common cases were -% that requirement is violated. -% - \global\advance\headwidth123456789sp\global\advance\headwidth\textwidth -\fi} -\def\ps@fancyplain{\ps@fancy \let\ps@plain\ps@plain@fancy} -\def\ps@plain@fancy{\@fancyplaintrue\ps@@fancy} -\let\ps@@empty\ps@empty -\def\ps@@fancy{% -\ps@@empty % This is for amsbook/amsart, which do strange things with \topskip -\def\@mkboth{\protect\markboth}% -\def\@oddhead{\@fancyhead\@lodd\f@ncyolh\f@ncyoch\f@ncyorh\@rodd}% -\def\@oddfoot{\@fancyfoot\@lodd\f@ncyolf\f@ncyocf\f@ncyorf\@rodd}% -\def\@evenhead{\@fancyhead\@rodd\f@ncyelh\f@ncyech\f@ncyerh\@lodd}% -\def\@evenfoot{\@fancyfoot\@rodd\f@ncyelf\f@ncyecf\f@ncyerf\@lodd}% -} -\def\@lodd{\if@reversemargin\hss\else\relax\fi} -\def\@rodd{\if@reversemargin\relax\else\hss\fi} - -\newif\iffootnote -\let\latex@makecol\@makecol -\def\@makecol{\ifvoid\footins\footnotetrue\else\footnotefalse\fi -\let\topfloat\@toplist\let\botfloat\@botlist\latex@makecol} -\def\iftopfloat#1#2{\ifx\topfloat\empty #2\else #1\fi} -\def\ifbotfloat#1#2{\ifx\botfloat\empty #2\else #1\fi} -\def\iffloatpage#1#2{\if@fcolmade #1\else #2\fi} - -\newcommand{\fancypagestyle}[2]{% - \@namedef{ps@#1}{\let\fancy@def\def#2\relax\ps@fancy}} diff --git a/olddoc/texinputs/fncychap.sty b/olddoc/texinputs/fncychap.sty deleted file mode 100644 index b0d7b76b..00000000 --- a/olddoc/texinputs/fncychap.sty +++ /dev/null @@ -1,433 +0,0 @@ -%%% Derived from the original fncychap.sty, -%%% but changed ``TWELV'' to ``TWELVE''. - -%%% Copyright Ulf A. Lindgren -%%% Department of Applied Electronics -%%% Chalmers University of Technology -%%% S-412 96 Gothenburg, Sweden -%%% E-mail lindgren@ae.chalmers.se -%%% -%%% Note Permission is granted to modify this file under -%%% the condition that it is saved using another -%%% file and package name. -%%% -%%% Revision 1.1 -%%% -%%% Jan. 8th Modified package name base date option -%%% Jan. 22th Modified FmN and FmTi for error in book.cls -%%% \MakeUppercase{#}->{\MakeUppercase#} -%%% Apr. 6th Modified Lenny option to prevent undesired -%%% skip of line. -%%% Nov. 8th Fixed \@chapapp for AMS -%%% Feb. 11th Fixed appendix problem related to Bjarne -%%% Last modified Feb. 11th 1998 - -\NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{fncychap} - [1997/04/06 v1.11 - LaTeX package (Revised chapters)] - -%%%% DEFINITION OF Chapapp variables -\newcommand{\CNV}{\huge\bfseries} -\newcommand{\ChNameVar}[1]{\renewcommand{\CNV}{#1}} - - -%%%% DEFINITION OF TheChapter variables -\newcommand{\CNoV}{\huge\bfseries} -\newcommand{\ChNumVar}[1]{\renewcommand{\CNoV}{#1}} - -\newif\ifUCN -\UCNfalse -\newif\ifLCN -\LCNfalse -\def\ChNameLowerCase{\LCNtrue\UCNfalse} -\def\ChNameUpperCase{\UCNtrue\LCNfalse} -\def\ChNameAsIs{\UCNfalse\LCNfalse} - -%%%%% Fix for AMSBook 971008 - -\@ifundefined{@chapapp}{\let\@chapapp\chaptername}{} - - -%%%%% Fix for Bjarne and appendix 980211 - -\newif\ifinapp -\inappfalse -\renewcommand\appendix{\par - \setcounter{chapter}{0}% - \setcounter{section}{0}% - \inapptrue% - \renewcommand\@chapapp{\appendixname}% - \renewcommand\thechapter{\@Alph\c@chapter}} - -%%%%% - -\newcommand{\FmN}[1]{% -\ifUCN - {\MakeUppercase#1}\LCNfalse -\else - \ifLCN - {\MakeLowercase#1}\UCNfalse - \else #1 - \fi -\fi} - - -%%%% DEFINITION OF Title variables -\newcommand{\CTV}{\Huge\bfseries} -\newcommand{\ChTitleVar}[1]{\renewcommand{\CTV}{#1}} - -%%%% DEFINITION OF the basic rule width -\newlength{\RW} -\setlength{\RW}{1pt} -\newcommand{\ChRuleWidth}[1]{\setlength{\RW}{#1}} - -\newif\ifUCT -\UCTfalse -\newif\ifLCT -\LCTfalse -\def\ChTitleLowerCase{\LCTtrue\UCTfalse} -\def\ChTitleUpperCase{\UCTtrue\LCTfalse} -\def\ChTitleAsIs{\UCTfalse\LCTfalse} -\newcommand{\FmTi}[1]{% -\ifUCT - - {\MakeUppercase#1}\LCTfalse -\else - \ifLCT - {\MakeLowercase#1}\UCTfalse - \else #1 - \fi -\fi} - - - -\newlength{\mylen} -\newlength{\myhi} -\newlength{\px} -\newlength{\py} -\newlength{\pyy} -\newlength{\pxx} - - -\def\mghrulefill#1{\leavevmode\leaders\hrule\@height #1\hfill\kern\z@} - -\newcommand{\DOCH}{% - \CNV\FmN{\@chapapp}\space \CNoV\thechapter - \par\nobreak - \vskip 20\p@ - } -\newcommand{\DOTI}[1]{% - \CTV\FmTi{#1}\par\nobreak - \vskip 40\p@ - } -\newcommand{\DOTIS}[1]{% - \CTV\FmTi{#1}\par\nobreak - \vskip 40\p@ - } - -%%%%%% SONNY DEF - -\DeclareOption{Sonny}{% - \ChNameVar{\Large\sf} - \ChNumVar{\Huge} - \ChTitleVar{\Large\sf} - \ChRuleWidth{0.5pt} - \ChNameUpperCase - \renewcommand{\DOCH}{% - \raggedleft - \CNV\FmN{\@chapapp}\space \CNoV\thechapter - \par\nobreak - \vskip 40\p@} - \renewcommand{\DOTI}[1]{% - \CTV\raggedleft\mghrulefill{\RW}\par\nobreak - \vskip 5\p@ - \CTV\FmTi{#1}\par\nobreak - \mghrulefill{\RW}\par\nobreak - \vskip 40\p@} - \renewcommand{\DOTIS}[1]{% - \CTV\raggedleft\mghrulefill{\RW}\par\nobreak - \vskip 5\p@ - \CTV\FmTi{#1}\par\nobreak - \mghrulefill{\RW}\par\nobreak - \vskip 40\p@} -} - -%%%%%% LENNY DEF - -\DeclareOption{Lenny}{% - - \ChNameVar{\fontsize{14}{16}\usefont{OT1}{phv}{m}{n}\selectfont} - \ChNumVar{\fontsize{60}{62}\usefont{OT1}{ptm}{m}{n}\selectfont} - \ChTitleVar{\Huge\bfseries\rm} - \ChRuleWidth{1pt} - \renewcommand{\DOCH}{% - \settowidth{\px}{\CNV\FmN{\@chapapp}} - \addtolength{\px}{2pt} - \settoheight{\py}{\CNV\FmN{\@chapapp}} - \addtolength{\py}{1pt} - - \settowidth{\mylen}{\CNV\FmN{\@chapapp}\space\CNoV\thechapter} - \addtolength{\mylen}{1pt} - \settowidth{\pxx}{\CNoV\thechapter} - \addtolength{\pxx}{-1pt} - - \settoheight{\pyy}{\CNoV\thechapter} - \addtolength{\pyy}{-2pt} - \setlength{\myhi}{\pyy} - \addtolength{\myhi}{-1\py} - \par - \parbox[b]{\textwidth}{% - \rule[\py]{\RW}{\myhi}% - \hskip -\RW% - \rule[\pyy]{\px}{\RW}% - \hskip -\px% - \raggedright% - \CNV\FmN{\@chapapp}\space\CNoV\thechapter% - \hskip1pt% - \mghrulefill{\RW}% - \rule{\RW}{\pyy}\par\nobreak% - \vskip -\baselineskip% - \vskip -\pyy% - \hskip \mylen% - \mghrulefill{\RW}\par\nobreak% - \vskip \pyy}% - \vskip 20\p@} - - - \renewcommand{\DOTI}[1]{% - \raggedright - \CTV\FmTi{#1}\par\nobreak - \vskip 40\p@} - - \renewcommand{\DOTIS}[1]{% - \raggedright - \CTV\FmTi{#1}\par\nobreak - \vskip 40\p@} - } - - -%%%%%%% GLENN DEF - - -\DeclareOption{Glenn}{% - \ChNameVar{\bfseries\Large\sf} - \ChNumVar{\Huge} - \ChTitleVar{\bfseries\Large\rm} - \ChRuleWidth{1pt} - \ChNameUpperCase - \ChTitleUpperCase - \renewcommand{\DOCH}{% - \settoheight{\myhi}{\CTV\FmTi{Test}} - \setlength{\py}{\baselineskip} - \addtolength{\py}{\RW} - \addtolength{\py}{\myhi} - \setlength{\pyy}{\py} - \addtolength{\pyy}{-1\RW} - - \raggedright - \CNV\FmN{\@chapapp}\space\CNoV\thechapter - \hskip 3pt\mghrulefill{\RW}\rule[-1\pyy]{2\RW}{\py}\par\nobreak} - - \renewcommand{\DOTI}[1]{% - \addtolength{\pyy}{-4pt} - \settoheight{\myhi}{\CTV\FmTi{#1}} - \addtolength{\myhi}{\py} - \addtolength{\myhi}{-1\RW} - \vskip -1\pyy - \rule{2\RW}{\myhi}\mghrulefill{\RW}\hskip 2pt - \raggedleft\CTV\FmTi{#1}\par\nobreak - \vskip 80\p@} - - \renewcommand{\DOTIS}[1]{% - \setlength{\py}{10pt} - \setlength{\pyy}{\py} - \addtolength{\pyy}{\RW} - \setlength{\myhi}{\baselineskip} - \addtolength{\myhi}{\pyy} - \mghrulefill{\RW}\rule[-1\py]{2\RW}{\pyy}\par\nobreak -% \addtolength{}{} -\vskip -1\baselineskip - \rule{2\RW}{\myhi}\mghrulefill{\RW}\hskip 2pt - \raggedleft\CTV\FmTi{#1}\par\nobreak - \vskip 60\p@} - } - -%%%%%%% CONNY DEF - -\DeclareOption{Conny}{% - \ChNameUpperCase - \ChTitleUpperCase - \ChNameVar{\centering\Huge\rm\bfseries} - \ChNumVar{\Huge} - \ChTitleVar{\centering\Huge\rm} - \ChRuleWidth{2pt} - - \renewcommand{\DOCH}{% - \mghrulefill{3\RW}\par\nobreak - \vskip -0.5\baselineskip - \mghrulefill{\RW}\par\nobreak - \CNV\FmN{\@chapapp}\space \CNoV\thechapter - \par\nobreak - \vskip -0.5\baselineskip - } - \renewcommand{\DOTI}[1]{% - \mghrulefill{\RW}\par\nobreak - \CTV\FmTi{#1}\par\nobreak - \vskip 60\p@ - } - \renewcommand{\DOTIS}[1]{% - \mghrulefill{\RW}\par\nobreak - \CTV\FmTi{#1}\par\nobreak - \vskip 60\p@ - } - } - -%%%%%%% REJNE DEF - -\DeclareOption{Rejne}{% - - \ChNameUpperCase - \ChTitleUpperCase - \ChNameVar{\centering\Large\rm} - \ChNumVar{\Huge} - \ChTitleVar{\centering\Huge\rm} - \ChRuleWidth{1pt} - \renewcommand{\DOCH}{% - \settoheight{\py}{\CNoV\thechapter} - \addtolength{\py}{-1pt} - \CNV\FmN{\@chapapp}\par\nobreak - \vskip 20\p@ - \setlength{\myhi}{2\baselineskip} - \setlength{\px}{\myhi} - \addtolength{\px}{-1\RW} - \rule[-1\px]{\RW}{\myhi}\mghrulefill{\RW}\hskip - 10pt\raisebox{-0.5\py}{\CNoV\thechapter}\hskip -10pt\mghrulefill{\RW}\rule[-1\px]{\RW}{\myhi}\par\nobreak - \vskip -1\p@ - } - \renewcommand{\DOTI}[1]{% - \setlength{\mylen}{\textwidth} - \addtolength{\mylen}{-2\RW} - {\vrule width\RW}\parbox{\mylen}{\CTV\FmTi{#1}}{\vrule -width\RW}\par\nobreak - \vskip --1pt\rule{\RW}{2\baselineskip}\mghrulefill{\RW}\rule{\RW}{2\baselineskip} - \vskip 60\p@ - } - \renewcommand{\DOTIS}[1]{% - \setlength{\py}{\fboxrule} - \setlength{\fboxrule}{\RW} - \setlength{\mylen}{\textwidth} - \addtolength{\mylen}{-2\RW} - \fbox{\parbox{\mylen}{\vskip -2\baselineskip\CTV\FmTi{#1}\par\nobreak\vskip \baselineskip}} - \setlength{\fboxrule}{\py} - \vskip 60\p@ - } - } - - -%%%%%%% BJARNE DEF - -\DeclareOption{Bjarne}{% - \ChNameUpperCase - \ChTitleUpperCase - \ChNameVar{\raggedleft\normalsize\rm} - \ChNumVar{\raggedleft \bfseries\Large} - \ChTitleVar{\raggedleft \Large\rm} - \ChRuleWidth{1pt} - - -%% Note thechapter -> c@chapter fix appendix bug - - \newcounter{AlphaCnt} - \newcounter{AlphaDecCnt} - \newcommand{\AlphaNo}{% - \ifcase\number\theAlphaCnt - \ifnum\c@chapter=0 - ZERO\else{}\fi - \or ONE\or TWO\or THREE\or FOUR\or FIVE - \or SIX\or SEVEN\or EIGHT\or NINE\or TEN - \or ELEVEN\or TWELVE\or THIRTEEN\or FOURTEEN\or FIFTEEN - \or SIXTEEN\or SEVENTEEN\or EIGHTEEN\or NINETEEN\fi -} - - \newcommand{\AlphaDecNo}{% - \setcounter{AlphaDecCnt}{0} - \@whilenum\number\theAlphaCnt>0\do - {\addtocounter{AlphaCnt}{-10} - \addtocounter{AlphaDecCnt}{1}} - \ifnum\number\theAlphaCnt=0 - \else - \addtocounter{AlphaDecCnt}{-1} - \addtocounter{AlphaCnt}{10} - \fi - - - \ifcase\number\theAlphaDecCnt\or TEN\or TWENTY\or THIRTY\or - FORTY\or FIFTY\or SIXTY\or SEVENTY\or EIGHTY\or NINETY\fi - } - \newcommand{\TheAlphaChapter}{% - - \ifinapp - \thechapter - \else - \setcounter{AlphaCnt}{\c@chapter} - \ifnum\c@chapter<20 - \AlphaNo - \else - \AlphaDecNo\AlphaNo - \fi - \fi - } - \renewcommand{\DOCH}{% - \mghrulefill{\RW}\par\nobreak - \CNV\FmN{\@chapapp}\par\nobreak - \CNoV\TheAlphaChapter\par\nobreak - \vskip -1\baselineskip\vskip 5pt\mghrulefill{\RW}\par\nobreak - \vskip 20\p@ - } - \renewcommand{\DOTI}[1]{% - \CTV\FmTi{#1}\par\nobreak - \vskip 40\p@ - } - \renewcommand{\DOTIS}[1]{% - \CTV\FmTi{#1}\par\nobreak - \vskip 40\p@ - } -} - -\DeclareOption*{% - \PackageWarning{fancychapter}{unknown style option} - } - -\ProcessOptions* \relax - -\def\@makechapterhead#1{% - \vspace*{50\p@}% - {\parindent \z@ \raggedright \normalfont - \ifnum \c@secnumdepth >\m@ne - \DOCH - \fi - \interlinepenalty\@M - \DOTI{#1} - }} -\def\@schapter#1{\if@twocolumn - \@topnewpage[\@makeschapterhead{#1}]% - \else - \@makeschapterhead{#1}% - \@afterheading - \fi} -\def\@makeschapterhead#1{% - \vspace*{50\p@}% - {\parindent \z@ \raggedright - \normalfont - \interlinepenalty\@M - \DOTIS{#1} - \vskip 40\p@ - }} - -\endinput - - diff --git a/olddoc/texinputs/howto.cls b/olddoc/texinputs/howto.cls deleted file mode 100644 index 14e357ad..00000000 --- a/olddoc/texinputs/howto.cls +++ /dev/null @@ -1,106 +0,0 @@ -% -% howto.cls for the Python documentation -% - -\NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesClass{howto} - [1998/02/25 Document class (Python HOWTO)] - -\RequirePackage{pypaper} - -% Change the options here to get a different set of basic options, This -% is where to add things like "a4paper" or "10pt". -% -\LoadClass[\py@paper,\py@ptsize,twoside]{article} - -\setcounter{secnumdepth}{1} - -% Optional packages: -% -% If processing of these documents fails at your TeX installation, -% these may be commented out (independently) to make things work. -% These are both supplied with the current version of the teTeX -% distribution. -% -% The "fancyhdr" package makes nicer page footers reasonable to -% implement, and is used to put the chapter and section information in -% the footers. -% -\RequirePackage{fancyhdr}\typeout{Using fancier footers than usual.} - - -% Required package: -% -% This gives us all the Python-specific markup that we really want. -% This should come last. Do not change this. -% -\RequirePackage{python} - -% support for module synopsis sections: -\newcommand{\py@ModSynopsisFilename}{\jobname.syn} - - -% need to do one of these.... -\newcommand{\py@doHorizontalRule}{\rule{\textwidth}{1pt}} - - -% Change the title page to look a bit better, and fit in with the -% fncychap ``Bjarne'' style a bit better. -% -\renewcommand{\maketitle}{ - \py@doHorizontalRule - \@ifundefined{pdfinfo}{}{{ - % This \def is required to deal with multi-line authors; it - % changes \\ to ', ' (comma-space), making it pass muster for - % generating document info in the PDF file. - \def\\{, } - \pdfinfo{ - /Author (\@author) - /Title (\@title) - } - }} - \begin{flushright} - {\rm\Huge\py@HeaderFamily \@title} \par - {\em\large\py@HeaderFamily \py@release\releaseinfo} \par - \vspace{25pt} - {\Large\py@HeaderFamily \@author} \par - \vspace{25pt} - \@date \par - \py@authoraddress \par - \end{flushright} - \@thanks - \setcounter{footnote}{0} - \let\thanks\relax\let\maketitle\relax - \gdef\@thanks{}\gdef\@author{}\gdef\@title{} -} - - -\let\py@OldTableofcontents=\tableofcontents -\renewcommand{\tableofcontents}{ - \begingroup - \parskip = 0mm - \py@OldTableofcontents - \endgroup - \py@doHorizontalRule - \vspace{12pt} - \py@doing@page@targetstrue -} - -% Fix the theindex environment to add an entry to the Table of -% Contents; this is much nicer than just having to jump to the end of -% the book and flip around, especially with multiple indexes. -% -\let\py@OldTheindex=\theindex -\renewcommand{\theindex}{ - \clearpage - \py@OldTheindex - \addcontentsline{toc}{section}{\indexname} -} - -\@ifundefined{fancyhf}{ - \pagestyle{plain}}{ - \pagestyle{normal}} % start this way; change for -\pagenumbering{arabic} % ToC & chapters -\setcounter{secnumdepth}{2} - -\thispagestyle{empty} diff --git a/olddoc/texinputs/license.tex b/olddoc/texinputs/license.tex deleted file mode 100644 index 3aeb68c6..00000000 --- a/olddoc/texinputs/license.tex +++ /dev/null @@ -1,274 +0,0 @@ -\section{History of the software} - -Python was created in the early 1990s by Guido van Rossum at Stichting -Mathematisch Centrum (CWI, see \url{http://www.cwi.nl/}) in the Netherlands -as a successor of a language called ABC. Guido remains Python's -principal author, although it includes many contributions from others. - -In 1995, Guido continued his work on Python at the Corporation for -National Research Initiatives (CNRI, see \url{http://www.cnri.reston.va.us/}) -in Reston, Virginia where he released several versions of the -software. - -In May 2000, Guido and the Python core development team moved to -BeOpen.com to form the BeOpen PythonLabs team. In October of the same -year, the PythonLabs team moved to Digital Creations (now Zope -Corporation; see \url{http://www.zope.com/}). In 2001, the Python -Software Foundation (PSF, see \url{http://www.python.org/psf/}) was -formed, a non-profit organization created specifically to own -Python-related Intellectual Property. Zope Corporation is a -sponsoring member of the PSF. - -All Python releases are Open Source (see -\url{http://www.opensource.org/} for the Open Source Definition). -Historically, most, but not all, Python releases have also been -GPL-compatible; the table below summarizes the various releases. - -\begin{tablev}{c|c|c|c|c}{textrm}{Release}{Derived from}{Year}{Owner}{GPL compatible?} - \linev{0.9.0 thru 1.2}{n/a}{1991-1995}{CWI}{yes} - \linev{1.3 thru 1.5.2}{1.2}{1995-1999}{CNRI}{yes} - \linev{1.6}{1.5.2}{2000}{CNRI}{no} - \linev{2.0}{1.6}{2000}{BeOpen.com}{no} - \linev{1.6.1}{1.6}{2001}{CNRI}{no} - \linev{2.1}{2.0+1.6.1}{2001}{PSF}{no} - \linev{2.0.1}{2.0+1.6.1}{2001}{PSF}{yes} - \linev{2.1.1}{2.1+2.0.1}{2001}{PSF}{yes} - \linev{2.2}{2.1.1}{2001}{PSF}{yes} - \linev{2.1.2}{2.1.1}{2002}{PSF}{yes} - \linev{2.1.3}{2.1.2}{2002}{PSF}{yes} - \linev{2.2.1}{2.2}{2002}{PSF}{yes} -\end{tablev} - -\note{GPL-compatible doesn't mean that we're distributing -Python under the GPL. All Python licenses, unlike the GPL, let you -distribute a modified version without making your changes open source. -The GPL-compatible licenses make it possible to combine Python with -other software that is released under the GPL; the others don't.} - -Thanks to the many outside volunteers who have worked under Guido's -direction to make these releases possible. - - -\section{Terms and conditions for accessing or otherwise using Python} - -\centerline{\strong{PSF LICENSE AGREEMENT FOR PYTHON 2.3}} - -\begin{enumerate} -\item -This LICENSE AGREEMENT is between the Python Software Foundation -(``PSF''), and the Individual or Organization (``Licensee'') accessing -and otherwise using Python \version{} software in source or binary -form and its associated documentation. - -\item -Subject to the terms and conditions of this License Agreement, PSF -hereby grants Licensee a nonexclusive, royalty-free, world-wide -license to reproduce, analyze, test, perform and/or display publicly, -prepare derivative works, distribute, and otherwise use Python -\version{} alone or in any derivative version, provided, however, that -PSF's License Agreement and PSF's notice of copyright, i.e., -``Copyright \copyright{} 2001, 2002 Python Software Foundation; All -Rights Reserved'' are retained in Python \version{} alone or in any -derivative version prepared by Licensee. - -\item -In the event Licensee prepares a derivative work that is based on -or incorporates Python \version{} or any part thereof, and wants to -make the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python \version. - -\item -PSF is making Python \version{} available to Licensee on an ``AS IS'' -basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON \version{} WILL -NOT INFRINGE ANY THIRD PARTY RIGHTS. - -\item -PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -\version{} FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR -LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON -\version, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE -POSSIBILITY THEREOF. - -\item -This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -\item -Nothing in this License Agreement shall be deemed to create any -relationship of agency, partnership, or joint venture between PSF and -Licensee. This License Agreement does not grant permission to use PSF -trademarks or trade name in a trademark sense to endorse or promote -products or services of Licensee, or any third party. - -\item -By copying, installing or otherwise using Python \version, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. -\end{enumerate} - - -\centerline{\strong{BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0}} - -\centerline{\strong{BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1}} - -\begin{enumerate} -\item -This LICENSE AGREEMENT is between BeOpen.com (``BeOpen''), having an -office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the -Individual or Organization (``Licensee'') accessing and otherwise -using this software in source or binary form and its associated -documentation (``the Software''). - -\item -Subject to the terms and conditions of this BeOpen Python License -Agreement, BeOpen hereby grants Licensee a non-exclusive, -royalty-free, world-wide license to reproduce, analyze, test, perform -and/or display publicly, prepare derivative works, distribute, and -otherwise use the Software alone or in any derivative version, -provided, however, that the BeOpen Python License is retained in the -Software, alone or in any derivative version prepared by Licensee. - -\item -BeOpen is making the Software available to Licensee on an ``AS IS'' -basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -\item -BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE -SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS -AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY -DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -\item -This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -\item -This License Agreement shall be governed by and interpreted in all -respects by the law of the State of California, excluding conflict of -law provisions. Nothing in this License Agreement shall be deemed to -create any relationship of agency, partnership, or joint venture -between BeOpen and Licensee. This License Agreement does not grant -permission to use BeOpen trademarks or trade names in a trademark -sense to endorse or promote products or services of Licensee, or any -third party. As an exception, the ``BeOpen Python'' logos available -at http://www.pythonlabs.com/logos.html may be used according to the -permissions granted on that web page. - -\item -By copying, installing or otherwise using the software, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. -\end{enumerate} - - -\centerline{\strong{CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1}} - -\begin{enumerate} -\item -This LICENSE AGREEMENT is between the Corporation for National -Research Initiatives, having an office at 1895 Preston White Drive, -Reston, VA 20191 (``CNRI''), and the Individual or Organization -(``Licensee'') accessing and otherwise using Python 1.6.1 software in -source or binary form and its associated documentation. - -\item -Subject to the terms and conditions of this License Agreement, CNRI -hereby grants Licensee a nonexclusive, royalty-free, world-wide -license to reproduce, analyze, test, perform and/or display publicly, -prepare derivative works, distribute, and otherwise use Python 1.6.1 -alone or in any derivative version, provided, however, that CNRI's -License Agreement and CNRI's notice of copyright, i.e., ``Copyright -\copyright{} 1995-2001 Corporation for National Research Initiatives; -All Rights Reserved'' are retained in Python 1.6.1 alone or in any -derivative version prepared by Licensee. Alternately, in lieu of -CNRI's License Agreement, Licensee may substitute the following text -(omitting the quotes): ``Python 1.6.1 is made available subject to the -terms and conditions in CNRI's License Agreement. This Agreement -together with Python 1.6.1 may be located on the Internet using the -following unique, persistent identifier (known as a handle): -1895.22/1013. This Agreement may also be obtained from a proxy server -on the Internet using the following URL: -\url{http://hdl.handle.net/1895.22/1013}.'' - -\item -In the event Licensee prepares a derivative work that is based on -or incorporates Python 1.6.1 or any part thereof, and wants to make -the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python 1.6.1. - -\item -CNRI is making Python 1.6.1 available to Licensee on an ``AS IS'' -basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -\item -CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, -OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -\item -This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -\item -This License Agreement shall be governed by the federal -intellectual property law of the United States, including without -limitation the federal copyright law, and, to the extent such -U.S. federal law does not apply, by the law of the Commonwealth of -Virginia, excluding Virginia's conflict of law provisions. -Notwithstanding the foregoing, with regard to derivative works based -on Python 1.6.1 that incorporate non-separable material that was -previously distributed under the GNU General Public License (GPL), the -law of the Commonwealth of Virginia shall govern this License -Agreement only as to issues arising under or with respect to -Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this -License Agreement shall be deemed to create any relationship of -agency, partnership, or joint venture between CNRI and Licensee. This -License Agreement does not grant permission to use CNRI trademarks or -trade name in a trademark sense to endorse or promote products or -services of Licensee, or any third party. - -\item -By clicking on the ``ACCEPT'' button where indicated, or by copying, -installing or otherwise using Python 1.6.1, Licensee agrees to be -bound by the terms and conditions of this License Agreement. -\end{enumerate} - -\centerline{ACCEPT} - - - -\centerline{\strong{CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2}} - -Copyright \copyright{} 1991 - 1995, Stichting Mathematisch Centrum -Amsterdam, The Netherlands. All rights reserved. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Stichting Mathematisch -Centrum or CWI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE -FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/olddoc/texinputs/ltxmarkup.sty b/olddoc/texinputs/ltxmarkup.sty deleted file mode 100644 index ace08cc8..00000000 --- a/olddoc/texinputs/ltxmarkup.sty +++ /dev/null @@ -1,40 +0,0 @@ -% Created by Fred L. Drake, Jr. , as part of the -% Python Documentation Project. -% -% Define some simple markup for the LaTeX command documentation: - -\ProvidesPackage{ltxmarkup} -\RequirePackage{python} % fulllineitems environment - -% These two macros are used in constructing the last parameter to the -% envdesc and macrodesc environments. - -\newcommand{\py@ltx@optparam}[1]{{[}\var{#1}{]}} -\newcommand{\py@ltx@param}[1]{\{\var{#1}\}} - -\newenvironment{envdesc}[2]{ - \begin{fulllineitems} - \item[\code{\e begin\{{\bfseries #1}\}{% - \let\op=\py@ltx@optparam% - \let\p=\py@ltx@param% - \let\unspecified=\py@unspecified% - \let\moreargs=\py@moreargs% - #2}}] - \item[\code{\e end\{{\bfseries #1}\}}] - \index{#1 environment@\py@idxcode{#1} environment} - \index{environments!#1@\py@idxcode{#1}} -}{\end{fulllineitems}} - -\newenvironment{macrodesc}[2]{ - \begin{fulllineitems} - \item[\code{{\e\bfseries#1}{% - \let\op=\py@ltx@optparam% - \let\p=\py@ltx@param% - \let\unspecified=\py@unspecified% - \let\moreargs=\py@moreargs% - #2}}] - \index{#1@\py@idxcode{#1}} -}{\end{fulllineitems}} - -\newcommand{\env}[1]{\code{#1}} -\newcommand{\macro}[1]{\code{\e#1}} diff --git a/olddoc/texinputs/manual.cls b/olddoc/texinputs/manual.cls deleted file mode 100644 index 49693e62..00000000 --- a/olddoc/texinputs/manual.cls +++ /dev/null @@ -1,152 +0,0 @@ -% -% manual.cls for the Python documentation -% - -\NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesClass{manual} - [1998/03/03 Document class (Python manual)] - -\RequirePackage{pypaper} - -% Change the options here to get a different set of basic options, but only -% if you have to. Paper and font size should be adjusted in pypaper.sty. -% -\LoadClass[\py@paper,\py@ptsize,twoside,openright]{report} - -\setcounter{secnumdepth}{2} - -% Optional packages: -% -% If processing of these documents fails at your TeX installation, -% these may be commented out (independently) to make things work. -% These are both supplied with the current version of the teTeX -% distribution. -% -% The "fancyhdr" package makes nicer page footers reasonable to -% implement, and is used to put the chapter and section information in -% the footers. -% -\RequirePackage{fancyhdr}\typeout{Using fancier footers than usual.} - - -% Required packages: -% -% The "fncychap" package is used to get the nice chapter headers. The -% .sty file is distributed with Python, so you should not need to disable -% it. You'd also end up with a mixed page style; uglier than stock LaTeX! -% -\RequirePackage[Bjarne]{fncychap}\typeout{Using fancy chapter headings.} -% Do horizontal rules it this way to match: -\newcommand{\py@doHorizontalRule}{\mghrulefill{\RW}} -% -% -% This gives us all the Python-specific markup that we really want. -% This should come last. Do not change this. -% -\RequirePackage{python} - -% support for module synopsis sections: -\newcommand{\py@ModSynopsisFilename}{\jobname\thechapter.syn} -\let\py@OldChapter=\chapter -\renewcommand{\chapter}{ - \py@ProcessModSynopsis - \py@closeModSynopsisFile - \py@OldChapter -} - - -% Change the title page to look a bit better, and fit in with the -% fncychap ``Bjarne'' style a bit better. -% -\renewcommand{\maketitle}{% - \begin{titlepage}% - \let\footnotesize\small - \let\footnoterule\relax - \py@doHorizontalRule% - \@ifundefined{pdfinfo}{}{{ - % This \def is required to deal with multi-line authors; it - % changes \\ to ', ' (comma-space), making it pass muster for - % generating document info in the PDF file. - \def\\{, } - \pdfinfo{ - /Author (\@author) - /Title (\@title) - } - }} - \begin{flushright}% - {\rm\Huge\py@HeaderFamily \@title \par}% - {\em\LARGE\py@HeaderFamily \py@release\releaseinfo \par} - \vfill - {\LARGE\py@HeaderFamily \@author \par} - \vfill\vfill - {\large - \@date \par - \vfill - \py@authoraddress \par - }% - \end{flushright}%\par - \@thanks - \end{titlepage}% - \setcounter{footnote}{0}% - \let\thanks\relax\let\maketitle\relax - \gdef\@thanks{}\gdef\@author{}\gdef\@title{} -} - - -% Catch the end of the {abstract} environment, but here make sure the -% abstract is followed by a blank page if the 'openright' option is used. -% -\let\py@OldEndAbstract=\endabstract -\renewcommand{\endabstract}{ - \if@openright - \ifodd\value{page} - \typeout{Adding blank page after the abstract.} - \vfil\pagebreak - \fi - \fi - \py@OldEndAbstract -} - -% This wraps the \tableofcontents macro with all the magic to get the -% spacing right and have the right number of pages if the 'openright' -% option has been used. This eliminates a fair amount of crud in the -% individual document files. -% -\let\py@OldTableofcontents=\tableofcontents -\renewcommand{\tableofcontents}{% - \setcounter{page}{1}% - \pagebreak% - \pagestyle{plain}% - {% - \parskip = 0mm% - \py@OldTableofcontents% - \if@openright% - \ifodd\value{page}% - \typeout{Adding blank page after the table of contents.}% - \pagebreak\hspace{0pt}% - \fi% - \fi% - \cleardoublepage% - }% - \pagenumbering{arabic}% - \@ifundefined{fancyhf}{}{\pagestyle{normal}}% - \py@doing@page@targetstrue% -} -% This is needed to get the width of the section # area wide enough in the -% library reference. Doing it here keeps it the same for all the manuals. -% -\renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}} -\renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}} -\setcounter{tocdepth}{1} - - -% Fix the theindex environment to add an entry to the Table of -% Contents; this is much nicer than just having to jump to the end of -% the book and flip around, especially with multiple indexes. -% -\let\py@OldTheindex=\theindex -\renewcommand{\theindex}{ - \cleardoublepage - \py@OldTheindex - \addcontentsline{toc}{chapter}{\indexname} -} diff --git a/olddoc/texinputs/pypaper.sty b/olddoc/texinputs/pypaper.sty deleted file mode 100644 index 42708dca..00000000 --- a/olddoc/texinputs/pypaper.sty +++ /dev/null @@ -1,18 +0,0 @@ -% -% Change this to say a4paper instead of letterpaper if you want A4. These -% are the latex defaults. -% -\newcommand{\py@paper}{letterpaper} -\newcommand{\py@ptsize}{11pt} - -% These set up the fonts for the documents. -% -% The "times" package makes the default font the PostScript Times -% font, which makes for smaller PostScript and a font that more people -% like. -% -% The "avant" package causes the AvantGarde font to be used for -% sans-serif text, instead of the uglier Helvetica set up by the "times" -% package. -% -% \RequirePackage{times}\typeout{Using Times instead of Computer Modern.} diff --git a/olddoc/texinputs/python.ist b/olddoc/texinputs/python.ist deleted file mode 100644 index 9ffa0f95..00000000 --- a/olddoc/texinputs/python.ist +++ /dev/null @@ -1,11 +0,0 @@ -line_max 100 -headings_flag 1 -heading_prefix " \\bigletter " - -preamble "\\begin{theindex} -\\def\\bigletter#1{{\\Large\\sffamily#1}\\nopagebreak\\vspace{1mm}} - -" - -symhead_positive "{Symbols}" -numhead_positive "{Numbers}" diff --git a/olddoc/texinputs/python.sty b/olddoc/texinputs/python.sty deleted file mode 100644 index c89cedc3..00000000 --- a/olddoc/texinputs/python.sty +++ /dev/null @@ -1,1277 +0,0 @@ -% -% python.sty for the Python docummentation [works only with with Latex2e] -% - -\NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{python} - [1998/01/11 LaTeX package (Python markup)] - -\RequirePackage{longtable} - -% Uncomment these two lines to ignore the paper size and make the page -% size more like a typical published manual. -%\renewcommand{\paperheight}{9in} -%\renewcommand{\paperwidth}{8.5in} % typical squarish manual -%\renewcommand{\paperwidth}{7in} % O'Reilly ``Programmming Python'' - -% These packages can be used to add marginal annotations which indicate -% index entries and labels; useful for reviewing this messy documentation! -% -%\RequirePackage{showkeys} -%\RequirePackage{showidx} - -% for PDF output, use maximal compression & a lot of other stuff -% (test for PDF recommended by Tanmoy Bhattacharya ) -% -\newif\ifpy@doing@page@targets -\py@doing@page@targetsfalse - -\newif\ifpdf\pdffalse -\ifx\pdfoutput\undefined\else\ifcase\pdfoutput -\else - \pdftrue - \input{pdfcolor} - \let\py@LinkColor=\NavyBlue - \let\py@NormalColor=\Black - \pdfcompresslevel=9 - \pdfpagewidth=\paperwidth % page width of PDF output - \pdfpageheight=\paperheight % page height of PDF output - % - % Pad the number with '0' to 3 digits wide so no page name is a prefix - % of any other. - % - \newcommand{\py@targetno}[1]{\ifnum#1<100 0\fi\ifnum#1<10 0\fi#1} - \newcommand{\py@pageno}{\py@targetno\thepage} - % - % This definition allows the entries in the page-view of the ToC to be - % active links. Some work, some don't. - % - \let\py@OldContentsline=\contentsline - % - % Backward compatibility hack: pdfTeX 0.13 defined \pdfannotlink, - % but it changed to \pdfstartlink in 0.14. This let's us use either - % version and still get useful behavior. - % - \@ifundefined{pdfstartlink}{ - \let\pdfstartlink=\pdfannotlink - }{} - % - % Macro that takes two args: the name to link to and the content of - % the link. This takes care of the PDF magic, getting the colors - % the same for each link, and avoids having lots of garbage all over - % this style file. - \newcommand{\py@linkToName}[2]{% - \pdfstartlink attr{/Border [0 0 0]} goto name{#1}% - \py@LinkColor#2\py@NormalColor% - \pdfendlink% - } - % Compute the padded page number separately since we end up with a pair of - % \relax tokens; this gets the right string computed and works. - \renewcommand{\contentsline}[3]{% - \def\my@pageno{\py@targetno{#3}}% - \py@OldContentsline{#1}{\py@linkToName{page\my@pageno}{#2}}{#3}% - } - \AtEndDocument{ - \InputIfFileExists{\jobname.bkm}{\pdfcatalog{/PageMode /UseOutlines}}{} - } - \newcommand{\py@target}[1]{% - \ifpy@doing@page@targets% - {\pdfdest name{#1} xyz}% - \fi% - } - \let\py@OldLabel=\label - \renewcommand{\label}[1]{% - \py@OldLabel{#1}% - \py@target{label-#1}% - } - % This stuff adds a page# destination to every PDF page, where # is three - % digits wide, padded with leading zeros. This doesn't really help with - % the frontmatter, but does fine with the body. - % - % This is *heavily* based on the hyperref package. - % - \def\@begindvi{% - \unvbox \@begindvibox - \@hyperfixhead - } - \def\@hyperfixhead{% - \let\H@old@thehead\@thehead - \global\def\@foo{\py@target{page\py@pageno}}% - \expandafter\ifx\expandafter\@empty\H@old@thehead - \def\H@old@thehead{\hfil}\fi - \def\@thehead{\@foo\relax\H@old@thehead}% - } -\fi\fi - -% Increase printable page size (copied from fullpage.sty) -\topmargin 0pt -\advance \topmargin by -\headheight -\advance \topmargin by -\headsep - -% attempt to work a little better for A4 users -\textheight \paperheight -\advance\textheight by -2in - -\oddsidemargin 0pt -\evensidemargin 0pt -%\evensidemargin -.25in % for ``manual size'' documents -\marginparwidth 0.5in - -\textwidth \paperwidth -\advance\textwidth by -2in - - -% Style parameters and macros used by most documents here -\raggedbottom -\sloppy -\parindent = 0mm -\parskip = 2mm -\hbadness = 5000 % don't print trivial gripes - -\pagestyle{empty} % start this way; change for -\pagenumbering{roman} % ToC & chapters - -% Use this to set the font family for headers and other decor: -\newcommand{\py@HeaderFamily}{\sffamily} - -% Set up abstract ways to get the normal and smaller font sizes that -% work even in footnote context. -\newif\ifpy@infootnote \py@infootnotefalse -\let\py@oldmakefntext\@makefntext -\def\@makefntext#1{% - \bgroup% - \py@infootnotetrue - \py@oldmakefntext{#1}% - \egroup% -} -\def\py@defaultsize{% - \ifpy@infootnote\footnotesize\else\normalsize\fi% -} -\def\py@smallsize{% - \ifpy@infootnote\scriptsize\else\small\fi% -} - -% Redefine the 'normal' header/footer style when using "fancyhdr" package: -\@ifundefined{fancyhf}{}{ - % Use \pagestyle{normal} as the primary pagestyle for text. - \fancypagestyle{normal}{ - \fancyhf{} - \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}} - \fancyfoot[LO]{{\py@HeaderFamily\nouppercase{\rightmark}}} - \fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}} - \renewcommand{\headrulewidth}{0pt} - \renewcommand{\footrulewidth}{0.4pt} - } - % Update the plain style so we get the page number & footer line, - % but not a chapter or section title. This is to keep the first - % page of a chapter and the blank page between chapters `clean.' - \fancypagestyle{plain}{ - \fancyhf{} - \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}} - \renewcommand{\headrulewidth}{0pt} - \renewcommand{\footrulewidth}{0.4pt} - } - % Redefine \cleardoublepage so that the blank page between chapters - % gets the plain style and not the fancy style. This is described - % in the documentation for the fancyhdr package by Piet von Oostrum. - \@ifundefined{chapter}{}{ - \renewcommand{\cleardoublepage}{ - \clearpage\if@openright \ifodd\c@page\else - \hbox{} - \thispagestyle{plain} - \newpage - \if@twocolumn\hbox{}\newpage\fi\fi\fi - } - } -} - -% This sets up the {verbatim} environment to be indented and a minipage, -% and to have all the other mostly nice properties that we want for -% code samples. - -\let\py@OldVerbatim=\verbatim -\let\py@OldEndVerbatim=\endverbatim -\RequirePackage{verbatim} -\let\py@OldVerbatimInput=\verbatiminput - -% Variable used by begin code command -\newlength{\py@codewidth} - -\renewcommand{\verbatim}{% - \setlength{\parindent}{1cm}% - % Calculate the text width for the minipage: - \setlength{\py@codewidth}{\linewidth}% - \addtolength{\py@codewidth}{-\parindent}% - % - \par\indent% - \begin{minipage}[t]{\py@codewidth}% - \small% - \py@OldVerbatim% -} -\renewcommand{\endverbatim}{% - \py@OldEndVerbatim% - \end{minipage}% -} -\renewcommand{\verbatiminput}[1]{% - {\setlength{\parindent}{1cm}% - % Calculate the text width for the minipage: - \setlength{\py@codewidth}{\linewidth}% - \addtolength{\py@codewidth}{-\parindent}% - % - \small% - \begin{list}{}{\setlength{\leftmargin}{1cm}} - \item% - \py@OldVerbatimInput{#1}% - \end{list} - }% -} - -% This does a similar thing for the {alltt} environment: -\RequirePackage{alltt} -\let\py@OldAllTT=\alltt -\let\py@OldEndAllTT=\endalltt - -\renewcommand{\alltt}{% - \setlength{\parindent}{1cm}% - % Calculate the text width for the minipage: - \setlength{\py@codewidth}{\linewidth}% - \addtolength{\py@codewidth}{-\parindent}% - % - \par\indent% - \begin{minipage}[t]{\py@codewidth}% - \small% - \py@OldAllTT% -} -\renewcommand{\endalltt}{% - \py@OldEndAllTT% - \end{minipage}% -} - - -\newcommand{\py@modulebadkey}{{--just-some-junk--}} - - -%% Lots of index-entry generation support. - -% Command to wrap around stuff that refers to function / module / -% attribute names in the index. Default behavior: like \code{}. To -% just keep the index entries in the roman font, uncomment the second -% definition; it matches O'Reilly style more. -% -\newcommand{\py@idxcode}[1]{\texttt{#1}} -%\renewcommand{\py@idxcode}[1]{#1} - -% Command to generate two index entries (using subentries) -\newcommand{\indexii}[2]{\index{#1!#2}\index{#2!#1}} - -% And three entries (using only one level of subentries) -\newcommand{\indexiii}[3]{\index{#1!#2 #3}\index{#2!#3, #1}\index{#3!#1 #2}} - -% And four (again, using only one level of subentries) -\newcommand{\indexiv}[4]{ -\index{#1!#2 #3 #4} -\index{#2!#3 #4, #1} -\index{#3!#4, #1 #2} -\index{#4!#1 #2 #3} -} - -% Command to generate a reference to a function, statement, keyword, -% operator. -\newcommand{\kwindex}[1]{\indexii{keyword}{#1@{\py@idxcode{#1}}}} -\newcommand{\stindex}[1]{\indexii{statement}{#1@{\py@idxcode{#1}}}} -\newcommand{\opindex}[1]{\indexii{operator}{#1@{\py@idxcode{#1}}}} -\newcommand{\exindex}[1]{\indexii{exception}{#1@{\py@idxcode{#1}}}} -\newcommand{\obindex}[1]{\indexii{object}{#1}} -\newcommand{\bifuncindex}[1]{% - \index{#1@{\py@idxcode{#1()}} (built-in function)}} - -% Add an index entry for a module -\newcommand{\py@refmodule}[2]{\index{#1@{\py@idxcode{#1}} (#2module)}} -\newcommand{\refmodindex}[1]{\py@refmodule{#1}{}} -\newcommand{\refbimodindex}[1]{\py@refmodule{#1}{built-in }} -\newcommand{\refexmodindex}[1]{\py@refmodule{#1}{extension }} -\newcommand{\refstmodindex}[1]{\py@refmodule{#1}{standard }} - -% Refer to a module's documentation using a hyperlink of the module's -% name, at least if we're building PDF: -\ifpdf - \newcommand{\refmodule}[2][\py@modulebadkey]{% - \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% - \py@linkToName{label-module-\py@modulekey}{\module{#2}}% - } -\else - \newcommand{\refmodule}[2][\py@modulebadkey]{\module{#2}} -\fi - -% support for the module index -\newif\ifpy@UseModuleIndex -\py@UseModuleIndexfalse - -\newcommand{\makemodindex}{ - \newwrite\modindexfile - \openout\modindexfile=mod\jobname.idx - \py@UseModuleIndextrue -} - -% Add the defining entry for a module -\newcommand{\py@modindex}[2]{% - \renewcommand{\py@thismodule}{#1} - \setindexsubitem{(in module #1)}% - \index{#1@{\py@idxcode{#1}} (#2module)|textbf}% - \ifpy@UseModuleIndex% - \@ifundefined{py@modplat@\py@thismodulekey}{ - \write\modindexfile{\protect\indexentry{#1@{\texttt{#1}}}{\thepage}}% - }{\write\modindexfile{\protect\indexentry{#1@{\texttt{#1} % - \emph{(\py@platformof[\py@thismodulekey]{})}}}{\thepage}}% - } - \fi% -} - -% *** XXX *** THE NEXT FOUR MACROS ARE NOW OBSOLETE !!! *** - -% built-in & Python modules in the main distribution -\newcommand{\bimodindex}[1]{\py@modindex{#1}{built-in }% - \typeout{*** MACRO bimodindex IS OBSOLETE -- USE declaremodule INSTEAD!}} -\newcommand{\stmodindex}[1]{\py@modindex{#1}{standard }% - \typeout{*** MACRO stmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}} - -% Python & extension modules outside the main distribution -\newcommand{\modindex}[1]{\py@modindex{#1}{}% - \typeout{*** MACRO modindex IS OBSOLETE -- USE declaremodule INSTEAD!}} -\newcommand{\exmodindex}[1]{\py@modindex{#1}{extension }% - \typeout{*** MACRO exmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}} - -% Additional string for an index entry -\newif\ifpy@usingsubitem\py@usingsubitemfalse -\newcommand{\py@indexsubitem}{} -\newcommand{\setindexsubitem}[1]{\renewcommand{\py@indexsubitem}{ #1}% - \py@usingsubitemtrue} -\newcommand{\ttindex}[1]{% - \ifpy@usingsubitem - \index{#1@{\py@idxcode{#1}}\py@indexsubitem}% - \else% - \index{#1@{\py@idxcode{#1}}}% - \fi% -} -\newcommand{\withsubitem}[2]{% - \begingroup% - \def\ttindex##1{\index{##1@{\py@idxcode{##1}} #1}}% - #2% - \endgroup% -} - - -% Module synopsis processing ----------------------------------------------- -% -\newcommand{\py@thisclass}{} -\newcommand{\py@thismodule}{} -\newcommand{\py@thismodulekey}{} -\newcommand{\py@thismoduletype}{} - -\newcommand{\py@standardIndexModule}[1]{\py@modindex{#1}{standard }} -\newcommand{\py@builtinIndexModule}[1]{\py@modindex{#1}{built-in }} -\newcommand{\py@extensionIndexModule}[1]{\py@modindex{#1}{extension }} -\newcommand{\py@IndexModule}[1]{\py@modindex{#1}{}} - -\newif\ifpy@HaveModSynopsis \py@HaveModSynopsisfalse -\newif\ifpy@ModSynopsisFileIsOpen \py@ModSynopsisFileIsOpenfalse -\newif\ifpy@HaveModPlatform \py@HaveModPlatformfalse - -% \declaremodule[key]{type}{name} -\newcommand{\declaremodule}[3][\py@modulebadkey]{ - \py@openModSynopsisFile - \renewcommand{\py@thismoduletype}{#2} - \ifx\py@modulebadkey#1 - \renewcommand{\py@thismodulekey}{#3} - \else - \renewcommand{\py@thismodulekey}{#1} - \fi - \@ifundefined{py@#2IndexModule}{% - \typeout{*** MACRO declaremodule called with unknown module type: `#2'} - \py@IndexModule{#3}% - }{% - \csname py@#2IndexModule\endcsname{#3}% - } - \label{module-\py@thismodulekey} -} -\newif\ifpy@ModPlatformFileIsOpen \py@ModPlatformFileIsOpenfalse -\newcommand{\py@ModPlatformFilename}{\jobname.pla} -\newcommand{\platform}[1]{ - \ifpy@ModPlatformFileIsOpen\else - \newwrite\py@ModPlatformFile - \openout\py@ModPlatformFile=\py@ModPlatformFilename - \py@ModPlatformFileIsOpentrue - \fi -} -\InputIfFileExists{\jobname.pla}{}{} -\newcommand{\py@platformof}[2][\py@modulebadkey]{% - \ifx\py@modulebadkey#1 \def\py@key{#2}% - \else \def\py@key{#1}% - \fi% - \csname py@modplat@\py@key\endcsname% -} -\newcommand{\ignorePlatformAnnotation}[1]{} - -% \moduleauthor{name}{email} -\newcommand{\moduleauthor}[2]{} - -% \sectionauthor{name}{email} -\newcommand{\sectionauthor}[2]{} - - -\newcommand{\py@defsynopsis}{Module has no synopsis.} -\newcommand{\py@modulesynopsis}{\py@defsynopsis} -\newcommand{\modulesynopsis}[1]{ - \py@HaveModSynopsistrue - \renewcommand{\py@modulesynopsis}{#1} -} - -% define the file -\newwrite\py@ModSynopsisFile - -% hacked from \addtocontents from latex.ltx: -\long\def\py@writeModSynopsisFile#1{% - \protected@write\py@ModSynopsisFile% - {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}% - {\string#1}% -} -\newcommand{\py@closeModSynopsisFile}{ - \ifpy@ModSynopsisFileIsOpen - \closeout\py@ModSynopsisFile - \py@ModSynopsisFileIsOpenfalse - \fi -} -\newcommand{\py@openModSynopsisFile}{ - \ifpy@ModSynopsisFileIsOpen\else - \openout\py@ModSynopsisFile=\py@ModSynopsisFilename - \py@ModSynopsisFileIsOpentrue - \fi -} - -\newcommand{\py@ProcessModSynopsis}{ - \ifpy@HaveModSynopsis - \py@writeModSynopsisFile{\modulesynopsis% - {\py@thismodulekey}{\py@thismodule}% - {\py@thismoduletype}{\py@modulesynopsis}}% - \py@HaveModSynopsisfalse - \fi - \renewcommand{\py@modulesynopsis}{\py@defsynopsis} -} -\AtEndDocument{\py@ProcessModSynopsis\py@closeModSynopsisFile} - - -\long\def\py@writeModPlatformFile#1{% - \protected@write\py@ModPlatformFile% - {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}% - {\string#1}% -} - - -\newcommand{\localmoduletable}{ - \IfFileExists{\py@ModSynopsisFilename}{ - \begin{synopsistable} - \input{\py@ModSynopsisFilename} - \end{synopsistable} - }{} -} - -\ifpdf - \newcommand{\py@ModSynopsisSummary}[4]{% - \py@linkToName{label-module-#1}{\bfcode{#2}} & #4\\ - } -\else - \newcommand{\py@ModSynopsisSummary}[4]{\bfcode{#2} & #4\\} -\fi -\newenvironment{synopsistable}{ - % key, name, type, synopsis - \let\modulesynopsis=\py@ModSynopsisSummary - \begin{tabular}{ll} -}{ - \end{tabular} -} -% -% -------------------------------------------------------------------------- - - -\newcommand{\py@reset}{ - \py@usingsubitemfalse - \py@ProcessModSynopsis - \renewcommand{\py@thisclass}{} - \renewcommand{\py@thismodule}{} - \renewcommand{\py@thismodulekey}{} - \renewcommand{\py@thismoduletype}{} -} - -% Augment the sectioning commands used to get our own font family in place, -% and reset some internal data items: -\renewcommand{\section}{\py@reset% - \@startsection{section}{1}{\z@}% - {-3.5ex \@plus -1ex \@minus -.2ex}% - {2.3ex \@plus.2ex}% - {\reset@font\Large\py@HeaderFamily}} -\renewcommand{\subsection}{\@startsection{subsection}{2}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\reset@font\large\py@HeaderFamily}} -\renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\reset@font\normalsize\py@HeaderFamily}} -\renewcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}% - {3.25ex \@plus1ex \@minus.2ex}% - {-1em}% - {\reset@font\normalsize\py@HeaderFamily}} -\renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{\parindent}% - {3.25ex \@plus1ex \@minus .2ex}% - {-1em}% - {\reset@font\normalsize\py@HeaderFamily}} - - -% This gets the underscores closer to the right width; the only change -% from standard LaTeX is the width specified. - -\DeclareTextCommandDefault{\textunderscore}{% - \leavevmode \kern.06em\vbox{\hrule\@width.55em}} - -% Underscore hack (only act like subscript operator if in math mode) -% -% The following is due to Mark Wooding (the old version didn't work with -% Latex 2e. - -\DeclareRobustCommand\hackscore{% - \ifmmode_\else\textunderscore\fi% -} -\begingroup -\catcode`\_\active -\def\next{% - \AtBeginDocument{\catcode`\_\active\def_{\hackscore{}}}% -} -\expandafter\endgroup\next - - -% Now for a lot of semantically-loaded environments that do a ton of magical -% things to get the right formatting and index entries for the stuff in -% Python modules and C API. - - -% {fulllineitems} is used in one place in libregex.tex, but is really for -% internal use in this file. -% -\newcommand{\py@itemnewline}[1]{% - \@tempdima\linewidth% - \advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}% -} - -\newenvironment{fulllineitems}{ - \begin{list}{}{\labelwidth \leftmargin \labelsep 0pt - \rightmargin 0pt \topsep -\parskip \partopsep \parskip - \itemsep -\parsep - \let\makelabel=\py@itemnewline} -}{\end{list}} - -% \optional is mostly for use in the arguments parameters to the various -% {*desc} environments defined below, but may be used elsewhere. Known to -% be used in the debugger chapter. -% -% Typical usage: -% -% \begin{funcdesc}{myfunc}{reqparm\optional{, optparm}} -% ^^^ ^^^ -% No space here No space here -% -% When a function has multiple optional parameters, \optional should be -% nested, not chained. This is right: -% -% \begin{funcdesc}{myfunc}{\optional{parm1\optional{, parm2}}} -% -\let\py@badkey=\@undefined - -\newcommand{\optional}[1]{% - {\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}} - -% This can be used when a function or method accepts an varying number -% of arguments, such as by using the *args syntax in the parameter list. -\newcommand{\py@moreargs}{...} - -% This can be used when you don't want to document the parameters to a -% function or method, but simply state that it's an alias for -% something else. -\newcommand{\py@unspecified}{...} - - -\newlength{\py@argswidth} -\newcommand{\py@sigparams}[1]{% - \parbox[t]{\py@argswidth}{\py@varvars{#1}\code{)}}} -\newcommand{\py@sigline}[2]{% - \settowidth{\py@argswidth}{#1\code{(}}% - \addtolength{\py@argswidth}{-2\py@argswidth}% - \addtolength{\py@argswidth}{\textwidth}% - \item[#1\code{(}\py@sigparams{#2}]} - -% C functions ------------------------------------------------------------ -% \begin{cfuncdesc}[refcount]{type}{name}{arglist} -% Note that the [refcount] slot should only be filled in by -% tools/anno-api.py; it pulls the value from the refcounts database. -\newcommand{\cfuncline}[3]{ - \py@sigline{\code{#1 \bfcode{#2}}}{#3}% - \index{#2@{\py@idxcode{#2()}}} -} -\newenvironment{cfuncdesc}[4][\py@badkey]{ - \begin{fulllineitems} - \cfuncline{#2}{#3}{#4} - \ifx#1\@undefined\else% - \emph{Return value: \textbf{#1}.}\\ - \fi -}{\end{fulllineitems}} - -% C variables ------------------------------------------------------------ -% \begin{cvardesc}{type}{name} -\newenvironment{cvardesc}[2]{ - \begin{fulllineitems} - \item[\code{#1 \bfcode{#2}}\index{#2@{\py@idxcode{#2}}}] -}{\end{fulllineitems}} - -% C data types ----------------------------------------------------------- -% \begin{ctypedesc}[index name]{typedef name} -\newenvironment{ctypedesc}[2][\py@badkey]{ - \begin{fulllineitems} - \item[\bfcode{#2}% - \ifx#1\@undefined% - \index{#2@{\py@idxcode{#2}} (C type)} - \else% - \index{#2@{\py@idxcode{#1}} (C type)} - \fi] -}{\end{fulllineitems}} - -% C type fields ---------------------------------------------------------- -% \begin{cmemberdesc}{container type}{ctype}{membername} -\newcommand{\cmemberline}[3]{ - \item[\code{#2 \bfcode{#3}}] - \index{#3@{\py@idxcode{#3}} (#1 member)} -} -\newenvironment{cmemberdesc}[3]{ - \begin{fulllineitems} - \cmemberline{#1}{#2}{#3} -}{\end{fulllineitems}} - -% Funky macros ----------------------------------------------------------- -% \begin{csimplemacrodesc}{name} -% -- "simple" because it has no args; NOT for constant definitions! -\newenvironment{csimplemacrodesc}[1]{ - \begin{fulllineitems} - \item[\bfcode{#1}\index{#1@{\py@idxcode{#1}} (macro)}] -}{\end{fulllineitems}} - -% simple functions (not methods) ----------------------------------------- -% \begin{funcdesc}{name}{args} -\newcommand{\funcline}[2]{% - \funclineni{#1}{#2}% - \index{#1@{\py@idxcode{#1()}} (in module \py@thismodule)}} -\newenvironment{funcdesc}[2]{ - \begin{fulllineitems} - \funcline{#1}{#2} -}{\end{fulllineitems}} - -% similar to {funcdesc}, but doesn't add to the index -\newcommand{\funclineni}[2]{% - \py@sigline{\bfcode{#1}}{#2}} -\newenvironment{funcdescni}[2]{ - \begin{fulllineitems} - \funclineni{#1}{#2} -}{\end{fulllineitems}} - -% classes ---------------------------------------------------------------- -% \begin{classdesc}{name}{constructor args} -\newenvironment{classdesc}[2]{ - % Using \renewcommand doesn't work for this, for unknown reasons: - \global\def\py@thisclass{#1} - \begin{fulllineitems} - \py@sigline{\strong{class }\bfcode{#1}}{#2}% - \index{#1@{\py@idxcode{#1}} (class in \py@thismodule)} -}{\end{fulllineitems}} - -% \begin{classdesc*}{name} -\newenvironment{classdesc*}[1]{ - % Using \renewcommand doesn't work for this, for unknown reasons: - \global\def\py@thisclass{#1} - \begin{fulllineitems} - \item[\strong{class }\code{\bfcode{#1}}% - \index{#1@{\py@idxcode{#1}} (class in \py@thismodule)}] -}{\end{fulllineitems}} - -% \begin{excclassdesc}{name}{constructor args} -% but indexes as an exception -\newenvironment{excclassdesc}[2]{ - % Using \renewcommand doesn't work for this, for unknown reasons: - \global\def\py@thisclass{#1} - \begin{fulllineitems} - \py@sigline{\strong{exception }\bfcode{#1}}{#2}% - \index{#1@{\py@idxcode{#1}} (exception in \py@thismodule)} -}{\end{fulllineitems}} - -% There is no corresponding {excclassdesc*} environment. To describe -% a class exception without parameters, use the {excdesc} environment. - - -\let\py@classbadkey=\@undefined - -% object method ---------------------------------------------------------- -% \begin{methoddesc}[classname]{methodname}{args} -\newcommand{\methodline}[3][\@undefined]{ - \methodlineni{#2}{#3} - \ifx#1\@undefined - \index{#2@{\py@idxcode{#2()}} (\py@thisclass\ method)} - \else - \index{#2@{\py@idxcode{#2()}} (#1 method)} - \fi -} -\newenvironment{methoddesc}[3][\@undefined]{ - \begin{fulllineitems} - \ifx#1\@undefined - \methodline{#2}{#3} - \else - \def\py@thisclass{#1} - \methodline{#2}{#3} - \fi -}{\end{fulllineitems}} - -% similar to {methoddesc}, but doesn't add to the index -% (never actually uses the optional argument) -\newcommand{\methodlineni}[3][\py@classbadkey]{% - \py@sigline{\bfcode{#2}}{#3}} -\newenvironment{methoddescni}[3][\py@classbadkey]{ - \begin{fulllineitems} - \methodlineni{#2}{#3} -}{\end{fulllineitems}} - -% object data attribute -------------------------------------------------- -% \begin{memberdesc}[classname]{membername} -\newcommand{\memberline}[2][\py@classbadkey]{% - \ifx#1\@undefined - \memberlineni{#2} - \index{#2@{\py@idxcode{#2}} (\py@thisclass\ attribute)} - \else - \memberlineni{#2} - \index{#2@{\py@idxcode{#2}} (#1 attribute)} - \fi -} -\newenvironment{memberdesc}[2][\py@classbadkey]{ - \begin{fulllineitems} - \ifx#1\@undefined - \memberline{#2} - \else - \def\py@thisclass{#1} - \memberline{#2} - \fi -}{\end{fulllineitems}} - -% similar to {memberdesc}, but doesn't add to the index -% (never actually uses the optional argument) -\newcommand{\memberlineni}[2][\py@classbadkey]{\item[\bfcode{#2}]} -\newenvironment{memberdescni}[2][\py@classbadkey]{ - \begin{fulllineitems} - \memberlineni{#2} -}{\end{fulllineitems}} - -% For exceptions: -------------------------------------------------------- -% \begin{excdesc}{name} -% -- for constructor information, use excclassdesc instead -\newenvironment{excdesc}[1]{ - \begin{fulllineitems} - \item[\strong{exception }\bfcode{#1}% - \index{#1@{\py@idxcode{#1}} (exception in \py@thismodule)}] -}{\end{fulllineitems}} - -% Module data or constants: ---------------------------------------------- -% \begin{datadesc}{name} -\newcommand{\dataline}[1]{% - \datalineni{#1}\index{#1@{\py@idxcode{#1}} (data in \py@thismodule)}} -\newenvironment{datadesc}[1]{ - \begin{fulllineitems} - \dataline{#1} -}{\end{fulllineitems}} - -% similar to {datadesc}, but doesn't add to the index -\newcommand{\datalineni}[1]{\item[\bfcode{#1}]\nopagebreak} -\newenvironment{datadescni}[1]{ - \begin{fulllineitems} - \datalineni{#1} -}{\end{fulllineitems}} - -% bytecode instruction --------------------------------------------------- -% \begin{opcodedesc}{name}{var} -% -- {var} may be {} -\newenvironment{opcodedesc}[2]{ - \begin{fulllineitems} - \item[\bfcode{#1}\quad\var{#2}] -}{\end{fulllineitems}} - - -\newcommand{\nodename}[1]{\label{#1}} - -% For these commands, use \command{} to get the typography right, not -% {\command}. This works better with the texinfo translation. -\newcommand{\ABC}{{\sc abc}} -\newcommand{\UNIX}{{\sc Unix}} -\newcommand{\POSIX}{POSIX} -\newcommand{\ASCII}{{\sc ascii}} -\newcommand{\Cpp}{C\protect\raisebox{.18ex}{++}} -\newcommand{\C}{C} -\newcommand{\EOF}{{\sc eof}} -\newcommand{\NULL}{\constant{NULL}} -\newcommand{\infinity}{\ensuremath{\infty}} -\newcommand{\plusminus}{\ensuremath{\pm}} -% \menuselection{Start \sub Programs \sub Python} -\newcommand{\menuselection}[1]{{\def\sub{ \ensuremath{>} }#1}} - -% Also for consistency: spell Python "Python", not "python"! - -% code is the most difficult one... -\newcommand{\code}[1]{\textrm{\@vobeyspaces\@noligs\def\{{\char`\{}\def\}{\char`\}}\def\~{\char`\~}\def\^{\char`\^}\def\e{\char`\\}\def\${\char`\$}\def\#{\char`\#}\def\&{\char`\&}\def\%{\char`\%}% -\texttt{#1}}} - -\newcommand{\bfcode}[1]{\code{\bfseries#1}} % bold-faced code font -\newcommand{\csimplemacro}[1]{\code{#1}} -\newcommand{\kbd}[1]{\code{#1}} -\newcommand{\samp}[1]{`\code{#1}'} -\newcommand{\var}[1]{% - \ifmmode% - \hbox{\py@defaultsize\textrm{\textit{#1\/}}}% - \else% - \py@defaultsize\textrm{\textit{#1\/}}% - \fi% -} -\renewcommand{\emph}[1]{{\em #1}} -\newcommand{\dfn}[1]{\emph{#1}} -\newcommand{\strong}[1]{{\bf #1}} -% let's experiment with a new font: -\newcommand{\file}[1]{`\filenq{#1}'} -\newcommand{\filenq}[1]{{\py@smallsize\textsf{#1}}} - -% Use this def/redef approach for \url{} since hyperref defined this already, -% but only if we actually used hyperref: -\ifpdf - \newcommand{\url}[1]{{% - \noindent% - \pdfstartlink attr{/Border [0 0 0]} user{/S /URI /URI (#1)}% - \py@LinkColor% color of the link text - \py@smallsize\sf #1% - \py@NormalColor% Turn it back off; these are declarative - \pdfendlink}% and don't appear bound to the current - }% formatting "box". -\else - \newcommand{\url}[1]{\mbox{\py@smallsize\textsf{#1}}} -\fi -\newcommand{\email}[1]{{\py@smallsize\textsf{#1}}} -\newcommand{\newsgroup}[1]{{\py@smallsize\textsf{#1}}} - -\newcommand{\py@varvars}[1]{{% - {\let\unspecified=\py@unspecified% - \let\moreargs=\py@moreargs% - \var{#1}}}} - -% I'd really like to get rid of this! -\newif\iftexi\texifalse - -% This is used to get l2h to put the copyright and abstract on -% a separate HTML page. -\newif\ifhtml\htmlfalse - - -% These should be used for all references to identifiers which are -% used to refer to instances of specific language constructs. See the -% names for specific semantic assignments. -% -% For now, don't do anything really fancy with them; just use them as -% logical markup. This might change in the future. -% -\newcommand{\module}[1]{\texttt{#1}} -\newcommand{\keyword}[1]{\texttt{#1}} -\newcommand{\exception}[1]{\texttt{#1}} -\newcommand{\class}[1]{\texttt{#1}} -\newcommand{\function}[1]{\texttt{#1}} -\newcommand{\member}[1]{\texttt{#1}} -\newcommand{\method}[1]{\texttt{#1}} - -\newcommand{\pytype}[1]{#1} % built-in Python type - -\newcommand{\cfunction}[1]{\texttt{#1}} -\newcommand{\ctype}[1]{\texttt{#1}} % C struct or typedef name -\newcommand{\cdata}[1]{\texttt{#1}} % C variable, typically global - -\newcommand{\mailheader}[1]{{\py@smallsize\textsf{#1:}}} -\newcommand{\mimetype}[1]{{\py@smallsize\textsf{#1}}} -% The \! is a "negative thin space" in math mode. -\newcommand{\regexp}[1]{% - {\tiny$^{^\lceil}\!\!$% - {\py@defaultsize\code{#1}}% - $\!\rfloor\!$% - }} -\newcommand{\envvar}[1]{% - #1% - \index{#1}% - \index{environment variables!{#1}}% -} -\newcommand{\makevar}[1]{#1} % variable in a Makefile -\newcommand{\character}[1]{\samp{#1}} - -% constants defined in Python modules or C headers, not language constants: -\newcommand{\constant}[1]{\code{#1}} % manifest constant, not syntactic - -\newcommand{\manpage}[2]{{\emph{#1}(#2)}} -\newcommand{\pep}[1]{PEP #1\index{Python Enhancement Proposals!PEP #1}} -\newcommand{\rfc}[1]{RFC #1\index{RFC!RFC #1}} -\newcommand{\program}[1]{\strong{#1}} -\newcommand{\programopt}[1]{\strong{#1}} -% Note that \longprogramopt provides the '--'! -\newcommand{\longprogramopt}[1]{\strong{-{}-#1}} - -% \ulink{link text}{URL} -\ifpdf - % The \noindent here is a hack -- we're forcing pdfTeX into - % horizontal mode since \pdfstartlink requires that. - \newcommand{\ulink}[2]{\noindent{% - \pdfstartlink attr{/Border [0 0 0]} user{/S /URI /URI (#2)}% - \py@LinkColor% color of the link text - #1% - \py@NormalColor% Turn it back off; these are declarative - \pdfendlink}% and don't appear bound to the current - }% formatting "box". -\else - \newcommand{\ulink}[2]{#1} -\fi - -% cited titles: \citetitle{Title of Work} -% online: \citetitle[url-to-resource]{Title of Work} -\ifpdf - \newcommand{\citetitle}[2][\py@modulebadkey]{% - \ifx\py@modulebadkey#1\emph{#2}\else\ulink{\emph{#2}}{#1}\fi% - } -\else - \newcommand{\citetitle}[2][URL]{\emph{#2}} -\fi - - - -% This version is being checked in for the historical record; it shows -% how I've managed to get some aspects of this to work. It will not -% be used in practice, so a subsequent revision will change things -% again. This version has problems, but shows how to do something -% that proved more tedious than I'd expected, so I don't want to lose -% the example completely. -% -\newcommand{\grammartoken}[1]{\texttt{#1}} -\newenvironment{productionlist}[1][\py@badkey]{ - \def\optional##1{{\Large[}##1{\Large]}} - \def\production##1##2{\code{##1}&::=&\code{##2}\\} - \def\productioncont##1{& &\code{##1}\\} - \def\token##1{##1} - \let\grammartoken=\token - \parindent=2em - \indent - \begin{tabular}{lcl} -}{% - \end{tabular} -} - -\newcommand{\py@noticelabel@note}{Note:} -\newcommand{\py@noticelabel@warning}{Warning:} -\newenvironment{notice}[1][note]{ - \par\strong{\csname py@noticelabel@#1\endcsname} -}{} -\newcommand{\note}[1]{\strong{\py@noticelabel@note} #1} -\newcommand{\warning}[1]{\strong{\py@noticelabel@warning} #1} - -% Deprecation stuff. -% Should be extended to allow an index / list of deprecated stuff. But -% there's a lot of stuff that needs to be done to make that automatable. -% -% First parameter is the release number that deprecates the feature, the -% second is the action the should be taken by users of the feature. -% -% Example: -% \deprecated{1.5.1}{Use \method{frobnicate()} instead.} -% -\newcommand{\deprecated}[2]{% - \strong{Deprecated since release #1.} #2\par} - -% New stuff. -% This should be used to mark things which have been added to the -% development tree but that aren't in the release, but are documented. -% This allows release of documentation that already includes updated -% descriptions. Place at end of descriptor environment. -% -% Example: -% \versionadded{1.5.2} -% \versionchanged[short explanation]{2.0} -% -\newcommand{\versionadded}[2][\py@badkey]{% - \ifx#1\@undefined% - { New in version #2. }% - \else% - { New in version #2:\ #1. }% - \fi% -} -\newcommand{\versionchanged}[2][\py@badkey]{% - \ifx#1\@undefined% - { Changed in version #2. }% - \else% - { Changed in version #2:\ #1. }% - \fi% -} - - -% Tables. -% -\newenvironment{tableii}[4]{% - \begin{center}% - \def\lineii##1##2{\csname#2\endcsname{##1}&##2\\}% - \begin{tabular}{#1}\strong{#3}&\strong{#4} \\* \hline% -}{% - \end{tabular}% - \end{center}% -} - -\newenvironment{longtableii}[4]{% - \begin{center}% - \def\lineii##1##2{\csname#2\endcsname{##1}&##2\\}% - \begin{longtable}[c]{#1}\strong{#3}&\strong{#4} \\* \hline\endhead% -}{% - \end{longtable}% - \end{center}% -} - -\newenvironment{tableiii}[5]{% - \begin{center}% - \def\lineiii##1##2##3{\csname#2\endcsname{##1}&##2&##3\\}% - \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5} \\% - \hline% -}{% - \end{tabular}% - \end{center}% -} - -\newenvironment{longtableiii}[5]{% - \begin{center}% - \def\lineiii##1##2##3{\csname#2\endcsname{##1}&##2&##3\\}% - \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5} \\% - \hline\endhead% -}{% - \end{longtable}% - \end{center}% -} - -\newenvironment{tableiv}[6]{% - \begin{center}% - \def\lineiv##1##2##3##4{\csname#2\endcsname{##1}&##2&##3&##4\\}% - \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6} \\% - \hline% -}{% - \end{tabular}% - \end{center}% -} - -\newenvironment{longtableiv}[6]{% - \begin{center}% - \def\lineiv##1##2##3##4{\csname#2\endcsname{##1}&##2&##3&##4\\}% - \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}% - \\% - \hline\endhead% -}{% - \end{longtable}% - \end{center}% -} - -\newenvironment{tablev}[7]{% - \begin{center}% - \def\linev##1##2##3##4##5{\csname#2\endcsname{##1}&##2&##3&##4&##5\\}% - \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}&\strong{#7} \\% - \hline% -}{% - \end{tabular}% - \end{center}% -} - -\newenvironment{longtablev}[7]{% - \begin{center}% - \def\linev##1##2##3##4##5{\csname#2\endcsname{##1}&##2&##3&##4&##5\\}% - \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}&\strong{#7}% - \\% - \hline\endhead% -}{% - \end{longtable}% - \end{center}% -} - -% XXX Don't think we can use this yet, though it cleans up some -% tedious markup. There's no equivalent for the HTML transform yet, -% and that needs to exist. I don't know how to write it. -% -% This should really have something that makes it easier to bind a -% table's ``Notes'' column and an associated tablenotes environment, -% and generates the right magic for getting the numbers right in the -% table. -% -% So this is quite incomplete. -% -\newcounter{py@tablenotescounter} -\newenvironment{tablenotes}{% - \noindent Notes: - \par - \setcounter{py@tablenotescounter}{0} - \begin{list}{(\arabic{py@tablenotescounter})}% - {\usecounter{py@tablenotescounter}} -}{\end{list}} - - -% Cross-referencing (AMK, new impl. FLD) -% Sample usage: -% \begin{seealso} -% \seemodule{rand}{Uniform random number generator.}; % Module xref -% \seetext{\emph{Encyclopedia Britannica}}. % Ref to a book -% -% % A funky case: module name contains '_'; have to supply an optional key -% \seemodule[copyreg]{copy_reg}{Interface constructor registration for -% \module{pickle}.} -% \end{seealso} -% -% Note that the last parameter for \seemodule and \seetext should be complete -% sentences and be terminated with the proper punctuation. - -\ifpdf - \newcommand{\py@seemodule}[3][\py@modulebadkey]{% - \par% - \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% - \begin{fulllineitems} - \item[\py@linkToName{label-module-\py@modulekey}{Module \module{#2}} - (section \ref{module-\py@modulekey}):] - #3 - \end{fulllineitems} - } -\else - \newcommand{\py@seemodule}[3][\py@modulebadkey]{% - \par% - \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% - \begin{fulllineitems} - \item[Module \module{#2} (section \ref{module-\py@modulekey}):] - #3 - \end{fulllineitems} - } -\fi - -% \seetitle[url]{title}{why it's interesting} -\newcommand{\py@seetitle}[3][\py@modulebadkey]{% - \par - \begin{fulllineitems} - \item[\citetitle{#2}] - \ifx\py@modulebadkey#1\else - \item[{\small{(\url{#1})}}] - \fi - #3 - \end{fulllineitems} -} -% \seepep{number}{title}{why it's interesting} -\newcommand{\py@seepep}[3]{% - \par% - \begin{fulllineitems} - \item[\pep{#1}, ``\emph{#2}''] - #3 - \end{fulllineitems} -} -% \seerfc{number}{title}{why it's interesting} -\newcommand{\py@seerfc}[3]{% - \par% - \begin{fulllineitems} - \item[\rfc{#1}, ``\emph{#2}''] - #3 - \end{fulllineitems} -} -% \seeurl{url}{why it's interesting} -\newcommand{\py@seeurl}[2]{% - \par% - \begin{fulllineitems} - \item[\url{#1}] - #2 - \end{fulllineitems} -} - -\newenvironment{seealso*}{ - \par - \def\seetext##1{\par{##1}} - \let\seemodule=\py@seemodule - \let\seepep=\py@seepep - \let\seerfc=\py@seerfc - \let\seetitle=\py@seetitle - \let\seeurl=\py@seeurl -}{\par} -\newenvironment{seealso}{ - \par - \strong{See Also:} - \par - \def\seetext##1{\par{##1}} - \let\seemodule=\py@seemodule - \let\seepep=\py@seepep - \let\seerfc=\py@seerfc - \let\seetitle=\py@seetitle - \let\seeurl=\py@seeurl -}{\par} - -% Allow the Python release number to be specified independently of the -% \date{}. This allows the date to reflect the document's date and -% release to specify the Python release that is documented. -% -\newcommand{\py@release}{} -\newcommand{\version}{} -\newcommand{\shortversion}{} -\newcommand{\releaseinfo}{} -\newcommand{\releasename}{Release} -\newcommand{\release}[1]{% - \renewcommand{\py@release}{\releasename\space\version}% - \renewcommand{\version}{#1}} -\newcommand{\setshortversion}[1]{% - \renewcommand{\shortversion}{#1}} -\newcommand{\setreleaseinfo}[1]{% - \renewcommand{\releaseinfo}{#1}} - -% Allow specification of the author's address separately from the -% author's name. This can be used to format them differently, which -% is a good thing. -% -\newcommand{\py@authoraddress}{} -\newcommand{\authoraddress}[1]{\renewcommand{\py@authoraddress}{#1}} -\let\developersaddress=\authoraddress -\let\developer=\author -\let\developers=\author - -% This sets up the fancy chapter headings that make the documents look -% at least a little better than the usual LaTeX output. -% -\@ifundefined{ChTitleVar}{}{ - \ChNameVar{\raggedleft\normalsize\py@HeaderFamily} - \ChNumVar{\raggedleft \bfseries\Large\py@HeaderFamily} - \ChTitleVar{\raggedleft \rm\Huge\py@HeaderFamily} - % This creates chapter heads without the leading \vspace*{}: - \def\@makechapterhead#1{% - {\parindent \z@ \raggedright \normalfont - \ifnum \c@secnumdepth >\m@ne - \DOCH - \fi - \interlinepenalty\@M - \DOTI{#1} - } - } -} - - -% Definition lists; requested by AMK for HOWTO documents. Probably useful -% elsewhere as well, so keep in in the general style support. -% -\newenvironment{definitions}{% - \begin{description}% - \def\term##1{\item[##1]\mbox{}\\*[0mm]} -}{% - \end{description}% -} - -% Tell TeX about pathological hyphenation cases: -\hyphenation{Base-HTTP-Re-quest-Hand-ler} diff --git a/olddoc/texinputs/reportingbugs.tex b/olddoc/texinputs/reportingbugs.tex deleted file mode 100644 index 6db43de9..00000000 --- a/olddoc/texinputs/reportingbugs.tex +++ /dev/null @@ -1,61 +0,0 @@ -\label{reporting-bugs} - -Python is a mature programming language which has established a -reputation for stability. In order to maintain this reputation, the -developers would like to know of any deficiencies you find in Python -or its documentation. - -Before submitting a report, you will be required to log into SourceForge; -this will make it possible for the developers to contact you -for additional information if needed. It is not possible to submit a -bug report anonymously. - -All bug reports should be submitted via the Python Bug Tracker on -SourceForge (\url{http://sourceforge.net/bugs/?group_id=5470}). The -bug tracker offers a Web form which allows pertinent information to be -entered and submitted to the developers. - -The first step in filing a report is to determine whether the problem -has already been reported. The advantage in doing so, aside from -saving the developers time, is that you learn what has been done to -fix it; it may be that the problem has already been fixed for the next -release, or additional information is needed (in which case you are -welcome to provide it if you can!). To do this, search the bug -database using the search box near the bottom of the page. - -If the problem you're reporting is not already in the bug tracker, go -back to the Python Bug Tracker -(\url{http://sourceforge.net/bugs/?group_id=5470}). Select the -``Submit a Bug'' link at the top of the page to open the bug reporting -form. - -The submission form has a number of fields. The only fields that are -required are the ``Summary'' and ``Details'' fields. For the summary, -enter a \emph{very} short description of the problem; less than ten -words is good. In the Details field, describe the problem in detail, -including what you expected to happen and what did happen. Be sure to -include the version of Python you used, whether any extension modules -were involved, and what hardware and software platform you were using -(including version information as appropriate). - -The only other field that you may want to set is the ``Category'' -field, which allows you to place the bug report into a broad category -(such as ``Documentation'' or ``Library''). - -Each bug report will be assigned to a developer who will determine -what needs to be done to correct the problem. You will -receive an update each time action is taken on the bug. - - -\begin{seealso} - \seetitle[http://www-mice.cs.ucl.ac.uk/multimedia/software/documentation/ReportingBugs.html]{How - to Report Bugs Effectively}{Article which goes into some - detail about how to create a useful bug report. This - describes what kind of information is useful and why it is - useful.} - - \seetitle[http://www.mozilla.org/quality/bug-writing-guidelines.html]{Bug - Writing Guidelines}{Information about writing a good bug - report. Some of this is specific to the Mozilla project, but - describes general good practices.} -\end{seealso} diff --git a/olddoc/texinputs/tmp b/olddoc/texinputs/tmp deleted file mode 100644 index 7b6e6470..00000000 --- a/olddoc/texinputs/tmp +++ /dev/null @@ -1,171 +0,0 @@ -137,153d136 -< % Set up abstract ways to get the normal and smaller font sizes that -< % work even in footnote context. -< \newif\ifpy@infootnote \py@infootnotefalse -< \let\py@oldmakefntext\@makefntext -< \def\@makefntext#1{% -< \bgroup% -< \py@infootnotetrue -< \py@oldmakefntext{#1}% -< \egroup% -< } -< \def\py@defaultsize{% -< \ifpy@infootnote\footnotesize\else\normalsize\fi% -< } -< \def\py@smallsize{% -< \ifpy@infootnote\scriptsize\else\small\fi% -< } -< -201,208c184,187 -< \setlength{\parindent}{1cm}% -< % Calculate the text width for the minipage: -< \setlength{\py@codewidth}{\linewidth}% -< \addtolength{\py@codewidth}{-\parindent}% -< % -< \par\indent% -< \begin{minipage}[t]{\py@codewidth}% -< \small% ---- -> \begingroup% -> \small% -> \begin{list}{}{\setlength{\leftmargin}{1cm}} -> \item% -213c192,193 -< \end{minipage}% ---- -> \end{list}% -> \endgroup -216,221c196 -< {\setlength{\parindent}{1cm}% -< % Calculate the text width for the minipage: -< \setlength{\py@codewidth}{\linewidth}% -< \addtolength{\py@codewidth}{-\parindent}% -< % -< \small% ---- -> {\small% -601,610d575 -< -< \newlength{\py@argswidth} -< \newcommand{\py@sigparams}[1]{% -< \parbox[t]{\py@argswidth}{\py@varvars{#1}\code{)}}} -< \newcommand{\py@sigline}[2]{% -< \settowidth{\py@argswidth}{#1\code{(}}% -< \addtolength{\py@argswidth}{-2\py@argswidth}% -< \addtolength{\py@argswidth}{\textwidth}% -< \item[#1\code{(}\py@sigparams{#2}]} -< -615,618d579 -< \newcommand{\cfuncline}[3]{ -< \py@sigline{\code{#1 \bfcode{#2}}}{#3}% -< \index{#2@{\py@idxcode{#2()}}} -< } -621c582 -< \cfuncline{#2}{#3}{#4} ---- -> \item[\code{#2 \bfcode{#3}(\py@varvars{#4})}\index{#3@{\py@idxcode{#3()}}}] -646,656d606 -< % C type fields ---------------------------------------------------------- -< % \begin{cmemberdesc}{container type}{ctype}{membername} -< \newcommand{\cmemberline}[3]{ -< \item[\code{#2 \bfcode{#3}}] -< \index{#3@{\py@idxcode{#3}} (#1 member)} -< } -< \newenvironment{cmemberdesc}[3]{ -< \begin{fulllineitems} -< \cmemberline{#1}{#2}{#3} -< }{\end{fulllineitems}} -< -658c608 -< % \begin{csimplemacrodesc}{name} ---- -> % \begin{csimplemacro}{name} -676,677c626 -< \newcommand{\funclineni}[2]{% -< \py@sigline{\bfcode{#1}}{#2}} ---- -> \newcommand{\funclineni}[2]{\item[\code{\bfcode{#1}(\py@varvars{#2})}]} -689,690c638,639 -< \py@sigline{\strong{class }\bfcode{#1}}{#2}% -< \index{#1@{\py@idxcode{#1}} (class in \py@thismodule)} ---- -> \item[\strong{class }\code{\bfcode{#1}(\py@varvars{#2})}% -> \index{#1@{\py@idxcode{#1}} (class in \py@thismodule)}] -708,709c657,658 -< \py@sigline{\strong{exception }\bfcode{#1}}{#2}% -< \index{#1@{\py@idxcode{#1}} (exception in \py@thismodule)} ---- -> \item[\strong{exception }\code{\bfcode{#1}(\py@varvars{#2})}% -> \index{#1@{\py@idxcode{#1}} (exception in \py@thismodule)}] -741c690 -< \py@sigline{\bfcode{#2}}{#3}} ---- -> \item[\code{\bfcode{#2}(\py@varvars{#3})}]} -824d772 -< % \menuselection{Start \sub Programs \sub Python} -834d781 -< \newcommand{\csimplemacro}[1]{\code{#1}} -836a784,786 -> % This weird definition of \var{} allows it to always appear in roman -> % italics, and won't get funky in code fragments when we play around -> % with fonts. This also works directly in math mode. -839c789 -< \hbox{\py@defaultsize\textrm{\textit{#1\/}}}% ---- -> \hbox{\normalsize\textrm{\textit{#1\/}}}% -841c791 -< \py@defaultsize\textrm{\textit{#1\/}}% ---- -> \normalsize\textrm{\textit{#1\/}}% -848,849c798,799 -< \newcommand{\file}[1]{`\filenq{#1}'} -< \newcommand{\filenq}[1]{{\py@smallsize\textsf{#1}}} ---- -> \newcommand{\file}[1]{`{\textsf{#1}}'} -> \newcommand{\filenq}[1]{{\textsf{#1}}} -858c808 -< \py@smallsize\sf #1% ---- -> \small\sf #1% -863c813 -< \newcommand{\url}[1]{\mbox{\py@smallsize\textsf{#1}}} ---- -> \newcommand{\url}[1]{\mbox{\small\textsf{#1}}} -865,866c815,816 -< \newcommand{\email}[1]{{\py@smallsize\textsf{#1}}} -< \newcommand{\newsgroup}[1]{{\py@smallsize\textsf{#1}}} ---- -> \newcommand{\email}[1]{{\small\textsf{#1}}} -> \newcommand{\newsgroup}[1]{{\small\textsf{#1}}} -902,903c852,853 -< \newcommand{\mailheader}[1]{{\py@smallsize\textsf{#1:}}} -< \newcommand{\mimetype}[1]{{\py@smallsize\textsf{#1}}} ---- -> \newcommand{\mailheader}[1]{{\small\textsf{#1:}}} -> \newcommand{\mimetype}[1]{{\small\textsf{#1}}} -907c857 -< {\py@defaultsize\code{#1}}% ---- -> {\normalsize\code{#1}}% -1105,1125d1054 -< -< % XXX Don't think we can use this yet, though it cleans up some -< % tedious markup. There's no equivalent for the HTML transform yet, -< % and that needs to exist. I don't know how to write it. -< % -< % This should really have something that makes it easier to bind a -< % table's ``Notes'' column and an associated tablenotes environment, -< % and generates the right magic for getting the numbers right in the -< % table. -< % -< % So this is quite incomplete. -< % -< \newcounter{py@tablenotescounter} -< \newenvironment{tablenotes}{% -< \noindent Notes: -< \par -< \setcounter{py@tablenotescounter}{0} -< \begin{list}{(\arabic{py@tablenotescounter})}% -< {\usecounter{py@tablenotescounter}} -< }{\end{list}} -< diff --git a/olddoc/texinputs/typestruct.h b/olddoc/texinputs/typestruct.h deleted file mode 100644 index 0afe375d..00000000 --- a/olddoc/texinputs/typestruct.h +++ /dev/null @@ -1,76 +0,0 @@ -typedef struct _typeobject { - PyObject_VAR_HEAD - char *tp_name; /* For printing, in format "." */ - int tp_basicsize, tp_itemsize; /* For allocation */ - - /* Methods to implement standard operations */ - - destructor tp_dealloc; - printfunc tp_print; - getattrfunc tp_getattr; - setattrfunc tp_setattr; - cmpfunc tp_compare; - reprfunc tp_repr; - - /* Method suites for standard classes */ - - PyNumberMethods *tp_as_number; - PySequenceMethods *tp_as_sequence; - PyMappingMethods *tp_as_mapping; - - /* More standard operations (here for binary compatibility) */ - - hashfunc tp_hash; - ternaryfunc tp_call; - reprfunc tp_str; - getattrofunc tp_getattro; - setattrofunc tp_setattro; - - /* Functions to access object as input/output buffer */ - PyBufferProcs *tp_as_buffer; - - /* Flags to define presence of optional/expanded features */ - long tp_flags; - - char *tp_doc; /* Documentation string */ - - /* Assigned meaning in release 2.0 */ - /* call function for all accessible objects */ - traverseproc tp_traverse; - - /* delete references to contained objects */ - inquiry tp_clear; - - /* Assigned meaning in release 2.1 */ - /* rich comparisons */ - richcmpfunc tp_richcompare; - - /* weak reference enabler */ - long tp_weaklistoffset; - - /* Added in release 2.2 */ - /* Iterators */ - getiterfunc tp_iter; - iternextfunc tp_iternext; - - /* Attribute descriptor and subclassing stuff */ - struct PyMethodDef *tp_methods; - struct PyMemberDef *tp_members; - struct PyGetSetDef *tp_getset; - struct _typeobject *tp_base; - PyObject *tp_dict; - descrgetfunc tp_descr_get; - descrsetfunc tp_descr_set; - long tp_dictoffset; - initproc tp_init; - allocfunc tp_alloc; - newfunc tp_new; - freefunc tp_free; /* Low-level free-memory routine */ - inquiry tp_is_gc; /* For PyObject_IS_GC */ - PyObject *tp_bases; - PyObject *tp_mro; /* method resolution order */ - PyObject *tp_cache; - PyObject *tp_subclasses; - PyObject *tp_weaklist; - -} PyTypeObject; diff --git a/olddoc/tools/anno-api.py b/olddoc/tools/anno-api.py deleted file mode 100755 index b4b7f799..00000000 --- a/olddoc/tools/anno-api.py +++ /dev/null @@ -1,71 +0,0 @@ -#! /usr/bin/env python -"""Add reference count annotations to the Python/C API Reference.""" -__version__ = '$Revision$' - -import getopt -import os -import sys - -import refcounts - - -PREFIX_1 = r"\begin{cfuncdesc}{PyObject*}{" -PREFIX_2 = r"\begin{cfuncdesc}{PyVarObject*}{" - - -def main(): - rcfile = os.path.join(os.path.dirname(refcounts.__file__), os.pardir, - "api", "refcounts.dat") - outfile = "-" - opts, args = getopt.getopt(sys.argv[1:], "o:r:", ["output=", "refcounts="]) - for opt, arg in opts: - if opt in ("-o", "--output"): - outfile = arg - elif opt in ("-r", "--refcounts"): - rcfile = arg - rcdict = refcounts.load(rcfile) - if outfile == "-": - output = sys.stdout - else: - output = open(outfile, "w") - if not args: - args = ["-"] - for infile in args: - if infile == "-": - input = sys.stdin - else: - input = open(infile) - while 1: - line = input.readline() - if not line: - break - prefix = None - if line.startswith(PREFIX_1): - prefix = PREFIX_1 - elif line.startswith(PREFIX_2): - prefix = PREFIX_2 - if prefix: - s = line[len(prefix):].split('}', 1)[0] - try: - info = rcdict[s] - except KeyError: - sys.stderr.write("No refcount data for %s\n" % s) - else: - if info.result_type in ("PyObject*", "PyVarObject*"): - if info.result_refs is None: - rc = "Always \NULL{}" - else: - rc = info.result_refs and "New" or "Borrowed" - rc = rc + " reference" - line = (r"\begin{cfuncdesc}[%s]{%s}{" - % (rc, info.result_type)) \ - + line[len(prefix):] - output.write(line) - if infile != "-": - input.close() - if outfile != "-": - output.close() - - -if __name__ == "__main__": - main() diff --git a/olddoc/tools/buildindex.py b/olddoc/tools/buildindex.py deleted file mode 100755 index 08fdb7b3..00000000 --- a/olddoc/tools/buildindex.py +++ /dev/null @@ -1,377 +0,0 @@ -#! /usr/bin/env python - -__version__ = '$Revision$' - -import os.path -import re -import string -import sys - - -bang_join = "!".join -null_join = "".join - - -class Node: - __rmjunk = re.compile("<#\d+#>") - - continuation = 0 - - def __init__(self, link, str, seqno): - self.links = [link] - self.seqno = seqno - # remove <#\d+#> left in by moving the data out of LaTeX2HTML - str = self.__rmjunk.sub('', str) - # build up the text - self.text = split_entry_text(str) - self.key = split_entry_key(str) - - def __cmp__(self, other): - """Comparison operator includes sequence number, for use with - list.sort().""" - return self.cmp_entry(other) or cmp(self.seqno, other.seqno) - - def cmp_entry(self, other): - """Comparison 'operator' that ignores sequence number.""" - c = 0 - for i in range(min(len(self.key), len(other.key))): - c = (cmp_part(self.key[i], other.key[i]) - or cmp_part(self.text[i], other.text[i])) - if c: - break - return c or cmp(self.key, other.key) or cmp(self.text, other.text) - - def __repr__(self): - return "" % (bang_join(self.text), self.seqno) - - def __str__(self): - return bang_join(self.key) - - def dump(self): - return "%s\1%s###%s\n" \ - % ("\1".join(self.links), - bang_join(self.text), - self.seqno) - - -def cmp_part(s1, s2): - result = cmp(s1, s2) - if result == 0: - return 0 - l1 = s1.lower() - l2 = s2.lower() - minlen = min(len(s1), len(s2)) - if len(s1) < len(s2) and l1 == l2[:len(s1)]: - result = -1 - elif len(s2) < len(s1) and l2 == l1[:len(s2)]: - result = 1 - else: - result = cmp(l1, l2) or cmp(s1, s2) - return result - - -def split_entry(str, which): - stuff = [] - parts = str.split('!') - parts = [part.split('@') for part in parts] - for entry in parts: - if len(entry) != 1: - key = entry[which] - else: - key = entry[0] - stuff.append(key) - return stuff - - -_rmtt = re.compile(r"""(.*)(.*)
(.*)$""", - re.IGNORECASE) -_rmparens = re.compile(r"\(\)") - -def split_entry_key(str): - parts = split_entry(str, 1) - for i in range(len(parts)): - m = _rmtt.match(parts[i]) - if m: - parts[i] = null_join(m.group(1, 2, 3)) - else: - parts[i] = parts[i].lower() - # remove '()' from the key: - parts[i] = _rmparens.sub('', parts[i]) - return map(trim_ignored_letters, parts) - - -def split_entry_text(str): - if '<' in str: - m = _rmtt.match(str) - if m: - str = null_join(m.group(1, 2, 3)) - return split_entry(str, 1) - - -def load(fp): - nodes = [] - rx = re.compile("(.*)\1(.*)###(.*)$") - while 1: - line = fp.readline() - if not line: - break - m = rx.match(line) - if m: - link, str, seqno = m.group(1, 2, 3) - nodes.append(Node(link, str, seqno)) - return nodes - - -def trim_ignored_letters(s): - # ignore $ to keep environment variables with the - # leading letter from the name - if s.startswith("$"): - return s[1:].lower() - else: - return s.lower() - -def get_first_letter(s): - if s.startswith(""): - return "%" - else: - return trim_ignored_letters(s)[0] - - -def split_letters(nodes): - letter_groups = [] - if nodes: - group = [] - append = group.append - letter = get_first_letter(nodes[0].text[0]) - letter_groups.append((letter, group)) - for node in nodes: - nletter = get_first_letter(node.text[0]) - if letter != nletter: - letter = nletter - group = [] - letter_groups.append((letter, group)) - append = group.append - append(node) - return letter_groups - - -def group_symbols(groups): - entries = [] - ident_letters = string.ascii_letters + "_" - while groups[0][0] not in ident_letters: - entries += groups[0][1] - del groups[0] - if entries: - groups.insert(0, ("Symbols", entries)) - - -# need a function to separate the nodes into columns... -def split_columns(nodes, columns=1): - if columns <= 1: - return [nodes] - # This is a rough height; we may have to increase to avoid breaks before - # a subitem. - colheight = int(len(nodes) / columns) - numlong = int(len(nodes) % columns) - if numlong: - colheight = colheight + 1 - else: - numlong = columns - cols = [] - for i in range(numlong): - start = i * colheight - end = start + colheight - cols.append(nodes[start:end]) - del nodes[:end] - colheight = colheight - 1 - try: - numshort = int(len(nodes) / colheight) - except ZeroDivisionError: - cols = cols + (columns - len(cols)) * [[]] - else: - for i in range(numshort): - start = i * colheight - end = start + colheight - cols.append(nodes[start:end]) - # - # If items continue across columns, make sure they are marked - # as continuations so the user knows to look at the previous column. - # - for i in range(len(cols) - 1): - try: - prev = cols[i][-1] - next = cols[i + 1][0] - except IndexError: - return cols - else: - n = min(len(prev.key), len(next.key)) - for j in range(n): - if prev.key[j] != next.key[j]: - break - next.continuation = j + 1 - return cols - - -DL_LEVEL_INDENT = " " - -def format_column(nodes): - strings = ["
"] - append = strings.append - level = 0 - previous = [] - for node in nodes: - current = node.text - count = 0 - for i in range(min(len(current), len(previous))): - if previous[i] != current[i]: - break - count = i + 1 - if count > level: - append("
" * (count - level) + "\n") - level = count - elif level > count: - append("\n") - append(level * DL_LEVEL_INDENT) - append("
" * (level - count)) - level = count - # else: level == count - for i in range(count, len(current) - 1): - term = node.text[i] - level = level + 1 - if node.continuation > i: - extra = " (continued)" - else: - extra = "" - append("\n
%s%s\n
\n%s
" - % (term, extra, level * DL_LEVEL_INDENT)) - append("\n%s
%s%s" - % (level * DL_LEVEL_INDENT, node.links[0], node.text[-1])) - for link in node.links[1:]: - append(",\n%s %s[Link]" % (level * DL_LEVEL_INDENT, link)) - previous = current - append("\n") - append("
" * (level + 1)) - return null_join(strings) - - -def format_nodes(nodes, columns=1): - strings = [] - append = strings.append - if columns > 1: - colnos = range(columns) - colheight = int(len(nodes) / columns) - if len(nodes) % columns: - colheight = colheight + 1 - colwidth = int(100 / columns) - append('') - for col in split_columns(nodes, columns): - append('") - append("\n
\n' % colwidth) - append(format_column(col)) - append("\n
") - else: - append(format_column(nodes)) - append("\n

\n") - return null_join(strings) - - -def format_letter(letter): - if letter == '.': - lettername = ". (dot)" - elif letter == '_': - lettername = "_ (underscore)" - else: - lettername = letter.capitalize() - return "\n


\n

%s

\n\n" \ - % (letter, lettername) - - -def format_html_letters(nodes, columns, group_symbol_nodes): - letter_groups = split_letters(nodes) - if group_symbol_nodes: - group_symbols(letter_groups) - items = [] - for letter, nodes in letter_groups: - s = "%s" % (letter, letter) - items.append(s) - s = ["
\n%s
\n" % " |\n".join(items)] - for letter, nodes in letter_groups: - s.append(format_letter(letter)) - s.append(format_nodes(nodes, columns)) - return null_join(s) - -def format_html(nodes, columns): - return format_nodes(nodes, columns) - - -def collapse(nodes): - """Collapse sequences of nodes with matching keys into a single node. - Destructive.""" - if len(nodes) < 2: - return - prev = nodes[0] - i = 1 - while i < len(nodes): - node = nodes[i] - if not node.cmp_entry(prev): - prev.links.append(node.links[0]) - del nodes[i] - else: - i = i + 1 - prev = node - - -def dump(nodes, fp): - for node in nodes: - fp.write(node.dump()) - - -def process_nodes(nodes, columns, letters=0, group_symbol_nodes=0): - nodes.sort() - collapse(nodes) - if letters: - return format_html_letters(nodes, columns, group_symbol_nodes) - else: - return format_html(nodes, columns) - - -def main(): - import getopt - ifn = "-" - ofn = "-" - columns = 1 - letters = 0 - group_symbol_nodes = 1 - opts, args = getopt.getopt(sys.argv[1:], "c:lo:", - ["columns=", "dont-group-symbols", - "group-symbols", "letters", "output="]) - for opt, val in opts: - if opt in ("-o", "--output"): - ofn = val - elif opt in ("-c", "--columns"): - columns = int(val, 10) - elif opt in ("-l", "--letters"): - letters = 1 - elif opt == "--group-symbols": - group_symbol_nodes = 1 - elif opt == "--dont-group-symbols": - group_symbol_nodes = 0 - if not args: - args = [ifn] - nodes = [] - for fn in args: - nodes = nodes + load(open(fn)) - num_nodes = len(nodes) - html = process_nodes(nodes, columns, letters, group_symbol_nodes) - program = os.path.basename(sys.argv[0]) - if ofn == "-": - sys.stdout.write(html) - sys.stderr.write("\n%s: %d index nodes" % (program, num_nodes)) - else: - open(ofn, "w").write(html) - print - print "%s: %d index nodes" % (program, num_nodes) - - -if __name__ == "__main__": - main() diff --git a/olddoc/tools/checkargs.pm b/olddoc/tools/checkargs.pm deleted file mode 100644 index de52f69c..00000000 --- a/olddoc/tools/checkargs.pm +++ /dev/null @@ -1,112 +0,0 @@ -#!/uns/bin/perl - -package checkargs; -require 5.004; # uses "for my $var" -require Exporter; -@ISA = qw(Exporter); -@EXPORT = qw(check_args check_args_range check_args_at_least); -use strict; -use Carp; - -=head1 NAME - -checkargs -- Provide rudimentary argument checking for perl5 functions - -=head1 SYNOPSIS - - check_args(cArgsExpected, @_) - check_args_range(cArgsMin, cArgsMax, @_) - check_args_at_least(cArgsMin, @_) -where "@_" should be supplied literally. - -=head1 DESCRIPTION - -As the first line of user-written subroutine foo, do one of the following: - - my ($arg1, $arg2) = check_args(2, @_); - my ($arg1, @rest) = check_args_range(1, 4, @_); - my ($arg1, @rest) = check_args_at_least(1, @_); - my @args = check_args_at_least(0, @_); - -These functions may also be called for side effect (put a call to one -of the functions near the beginning of the subroutine), but using the -argument checkers to set the argument list is the recommended usage. - -The number of arguments and their definedness are checked; if the wrong -number are received, the program exits with an error message. - -=head1 AUTHOR - -Michael D. Ernst > - -=cut - -## Need to check that use of caller(1) really gives desired results. -## Need to give input chunk information. -## Is this obviated by Perl 5.003's declarations? Not entirely, I think. - -sub check_args ( $@ ) -{ - my ($num_formals, @args) = @_; - my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1); - if (@_ < 1) { croak "check_args needs at least 7 args, got ", scalar(@_), ": @_\n "; } - if ((!wantarray) && ($num_formals != 0)) - { croak "check_args called in scalar context"; } - # Can't use croak below here: it would only go out to caller, not its caller - my $num_actuals = @args; - if ($num_actuals != $num_formals) - { die "$file_arg:$line_arg: function $subname expected $num_formals argument", - (($num_formals == 1) ? "" : "s"), - ", got $num_actuals", - (($num_actuals == 0) ? "" : ": @args"), - "\n"; } - for my $index (0..$#args) - { if (!defined($args[$index])) - { die "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; } } - return @args; -} - -sub check_args_range ( $$@ ) -{ - my ($min_formals, $max_formals, @args) = @_; - my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1); - if (@_ < 2) { croak "check_args_range needs at least 8 args, got ", scalar(@_), ": @_"; } - if ((!wantarray) && ($max_formals != 0) && ($min_formals !=0) ) - { croak "check_args_range called in scalar context"; } - # Can't use croak below here: it would only go out to caller, not its caller - my $num_actuals = @args; - if (($num_actuals < $min_formals) || ($num_actuals > $max_formals)) - { die "$file_arg:$line_arg: function $subname expected $min_formals-$max_formals arguments, got $num_actuals", - ($num_actuals == 0) ? "" : ": @args", "\n"; } - for my $index (0..$#args) - { if (!defined($args[$index])) - { die "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; } } - return @args; -} - -sub check_args_at_least ( $@ ) -{ - my ($min_formals, @args) = @_; - my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1); - # Don't do this, because we want every sub to start with a call to check_args* - # if ($min_formals == 0) - # { die "Isn't it pointless to check for at least zero args to $subname?\n"; } - if (scalar(@_) < 1) - { croak "check_args_at_least needs at least 1 arg, got ", scalar(@_), ": @_"; } - if ((!wantarray) && ($min_formals != 0)) - { croak "check_args_at_least called in scalar context"; } - # Can't use croak below here: it would only go out to caller, not its caller - my $num_actuals = @args; - if ($num_actuals < $min_formals) - { die "$file_arg:$line_arg: function $subname expected at least $min_formals argument", - ($min_formals == 1) ? "" : "s", - ", got $num_actuals", - ($num_actuals == 0) ? "" : ": @args", "\n"; } - for my $index (0..$#args) - { if (!defined($args[$index])) - { warn "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; last; } } - return @args; -} - -1; # successful import -__END__ diff --git a/olddoc/tools/cklatex b/olddoc/tools/cklatex deleted file mode 100755 index 396e914c..00000000 --- a/olddoc/tools/cklatex +++ /dev/null @@ -1,26 +0,0 @@ -#! /bin/sh -# -*- ksh -*- - -# This script *helps* locate lines of normal content that end in '}'; -# this is useful since LaTeX2HTML (at least the old version that we -# use) breaks on many lines that end that way. -# -# Usage: cklatex files... | less -# -# *Read* the output looking for suspicious lines! - -grep -n "[^ ]}\$" $@ | \ - grep -v '\\begin{' | \ - grep -v '\\end{' | \ - grep -v '\\input{' | \ - grep -v '\\documentclass{' | \ - grep -v '\\title{' | \ - grep -v '\\chapter{' | \ - grep -v '\\chapter\*{' | \ - grep -v '\\section{' | \ - grep -v '\\subsection{' | \ - grep -v '\\subsubsection{' | \ - grep -v '\\sectionauthor{' | \ - grep -v '\\moduleauthor{' - -exit $? diff --git a/olddoc/tools/custlib.py b/olddoc/tools/custlib.py deleted file mode 100644 index 78989281..00000000 --- a/olddoc/tools/custlib.py +++ /dev/null @@ -1,78 +0,0 @@ -# Generate custlib.tex, which is a site-specific library document. - -# Phase I: list all the things that can be imported - -import glob -import os.path -import sys - -modules = {} - -for modname in sys.builtin_module_names: - modules[modname] = modname - -for dir in sys.path: - # Look for *.py files - filelist = glob.glob(os.path.join(dir, '*.py')) - for file in filelist: - path, file = os.path.split(file) - base, ext = os.path.splitext(file) - modules[base.lower()] = base - - # Look for shared library files - filelist = (glob.glob(os.path.join(dir, '*.so')) + - glob.glob(os.path.join(dir, '*.sl')) + - glob.glob(os.path.join(dir, '*.o')) ) - for file in filelist: - path, file = os.path.split(file) - base, ext = os.path.splitext(file) - if base[-6:] == 'module': - base = base[:-6] - modules[base.lower()] = base - -# Minor oddity: the types module is documented in libtypes2.tex -if modules.has_key('types'): - del modules['types'] - modules['types2'] = None - -# Phase II: find all documentation files (lib*.tex) -# and eliminate modules that don't have one. - -docs = {} -filelist = glob.glob('lib*.tex') -for file in filelist: - modname = file[3:-4] - docs[modname] = modname - -mlist = modules.keys() -mlist = filter(lambda x, docs=docs: docs.has_key(x), mlist) -mlist.sort() -mlist = map(lambda x, docs=docs: docs[x], mlist) - -modules = mlist - -# Phase III: write custlib.tex - -# Write the boilerplate -# XXX should be fancied up. -print """\documentstyle[twoside,11pt,myformat]{report} -\\title{Python Library Reference} -\\input{boilerplate} -\\makeindex % tell \\index to actually write the .idx file -\\begin{document} -\\pagenumbering{roman} -\\maketitle -\\input{copyright} -\\begin{abstract} -\\noindent This is a customized version of the Python Library Reference. -\\end{abstract} -\\pagebreak -{\\parskip = 0mm \\tableofcontents} -\\pagebreak\\pagenumbering{arabic}""" - -for modname in mlist: - print "\\input{lib%s}" % (modname,) - -# Write the end -print """\\input{custlib.ind} % Index -\\end{document}""" diff --git a/olddoc/tools/cvsinfo.py b/olddoc/tools/cvsinfo.py deleted file mode 100644 index 58a32c25..00000000 --- a/olddoc/tools/cvsinfo.py +++ /dev/null @@ -1,81 +0,0 @@ -"""Utility class and function to get information about the CVS repository -based on checked-out files. -""" - -import os - - -def get_repository_list(paths): - d = {} - for name in paths: - if os.path.isfile(name): - dir = os.path.dirname(name) - else: - dir = name - rootfile = os.path.join(name, "CVS", "Root") - root = open(rootfile).readline().strip() - if not d.has_key(root): - d[root] = RepositoryInfo(dir), [name] - else: - d[root][1].append(name) - return d.values() - - -class RepositoryInfo: - """Record holding information about the repository we want to talk to.""" - cvsroot_path = None - branch = None - - # type is '', ':ext', or ':pserver:' - type = "" - - def __init__(self, dir=None): - if dir is None: - dir = os.getcwd() - dir = os.path.join(dir, "CVS") - root = open(os.path.join(dir, "Root")).readline().strip() - if root.startswith(":pserver:"): - self.type = ":pserver:" - root = root[len(":pserver:"):] - elif ":" in root: - if root.startswith(":ext:"): - root = root[len(":ext:"):] - self.type = ":ext:" - self.repository = root - if ":" in root: - host, path = root.split(":", 1) - self.cvsroot_path = path - else: - self.cvsroot_path = root - fn = os.path.join(dir, "Tag") - if os.path.isfile(fn): - self.branch = open(fn).readline().strip()[1:] - - def get_cvsroot(self): - return self.type + self.repository - - _repository_dir_cache = {} - - def get_repository_file(self, path): - filename = os.path.abspath(path) - if os.path.isdir(path): - dir = path - join = 0 - else: - dir = os.path.dirname(path) - join = 1 - try: - repodir = self._repository_dir_cache[dir] - except KeyError: - repofn = os.path.join(dir, "CVS", "Repository") - repodir = open(repofn).readline().strip() - repodir = os.path.join(self.cvsroot_path, repodir) - self._repository_dir_cache[dir] = repodir - if join: - fn = os.path.join(repodir, os.path.basename(path)) - else: - fn = repodir - return fn[len(self.cvsroot_path)+1:] - - def __repr__(self): - return "" % `self.get_cvsroot()` diff --git a/olddoc/tools/findacks b/olddoc/tools/findacks deleted file mode 100755 index b54ea609..00000000 --- a/olddoc/tools/findacks +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env python -"""Script to locate email addresses in the CVS logs.""" -__version__ = '$Revision$' - -import os -import re -import sys -import UserDict - -import cvsinfo - - -class Acknowledgements(UserDict.UserDict): - def add(self, email, name, path): - d = self.data - d.setdefault(email, {})[path] = name - - -def open_cvs_log(info, paths=None): - cvsroot = info.get_cvsroot() - cmd = "cvs -q -d%s log " % cvsroot - if paths: - cmd += " ".join(paths) - return os.popen(cmd, "r") - - -email_rx = re.compile("<([a-z][-a-z0-9._]*@[-a-z0-9.]+)>", re.IGNORECASE) - -def find_acks(f, acks): - prev = '' - filename = None - MAGIC_WORDS = ('van', 'von') - while 1: - line = f.readline() - if not line: - break - if line.startswith("Working file: "): - filename = line.split(None, 2)[2].strip() - prev = line - continue - m = email_rx.search(line) - if m: - words = prev.split() + line[:m.start()].split() - L = [] - while words \ - and (words[-1][0].isupper() or words[-1] in MAGIC_WORDS): - L.insert(0, words.pop()) - name = " ".join(L) - email = m.group(1).lower() - acks.add(email, name, filename) - prev = line - - -def load_cvs_log_acks(acks, args): - repolist = cvsinfo.get_repository_list(args or [""]) - for info, paths in repolist: - print >>sys.stderr, "Repository:", info.get_cvsroot() - f = open_cvs_log(info, paths) - find_acks(f, acks) - f.close() - - -def load_tex_source_acks(acks, args): - for path in args: - path = path or os.curdir - if os.path.isfile(path): - read_acks_from_tex_file(acks, path) - else: - read_acks_from_tex_dir(acks, path) - - -def read_acks_from_tex_file(acks, path): - f = open(path) - while 1: - line = f.readline() - if not line: - break - if line.startswith(r"\sectionauthor{"): - line = line[len(r"\sectionauthor"):] - name, line = extract_tex_group(line) - email, line = extract_tex_group(line) - acks.add(email, name, path) - - -def read_acks_from_tex_dir(acks, path): - stack = [path] - while stack: - p = stack.pop() - for n in os.listdir(p): - n = os.path.join(p, n) - if os.path.isdir(n): - stack.insert(0, n) - elif os.path.normpath(n).endswith(".tex"): - read_acks_from_tex_file(acks, n) - - -def extract_tex_group(s): - c = 0 - for i in range(len(s)): - if s[i] == '{': - c += 1 - elif s[i] == '}': - c -= 1 - if c == 0: - return s[1:i], s[i+1:] - - -def print_acks(acks): - first = 1 - for email, D in acks.items(): - if first: - first = 0 - else: - print - L = D.items() - L.sort() - prefname = L[0][1] - for file, name in L[1:]: - if name != prefname: - prefname = "" - break - if prefname: - print prefname, "<%s>:" % email - else: - print email + ":" - for file, name in L: - if name == prefname: - print " " + file - else: - print " %s (as %s)" % (file, name) - - -def print_ack_names(acks): - names = [] - for email, D in acks.items(): - L = D.items() - L.sort() - prefname = L[0][1] - for file, name in L[1:]: - prefname = prefname or name - names.append(prefname or email) - def f(s1, s2): - s1 = s1.lower() - s2 = s2.lower() - return cmp((s1.split()[-1], s1), - (s2.split()[-1], s2)) - names.sort(f) - for name in names: - print name - - -def main(): - args = sys.argv[1:] - acks = Acknowledgements() - load_cvs_log_acks(acks, args) - load_tex_source_acks(acks, args) - print_ack_names(acks) - - -if __name__ == "__main__": - main() diff --git a/olddoc/tools/findcsyms b/olddoc/tools/findcsyms deleted file mode 100755 index ac9b7542..00000000 --- a/olddoc/tools/findcsyms +++ /dev/null @@ -1,136 +0,0 @@ -#! /usr/bin/env python - -import errno -import os -import re -import sys - -if __name__ == "__main__": - _base = sys.argv[0] -else: - _base = __file__ - -_script_home = os.path.abspath(os.path.dirname(_base)) - -srcdir = os.path.dirname(os.path.dirname(_script_home)) - -EXCLUDES = ["bitset.h", "cStringIO.h", "graminit.h", "grammar.h", - "longintrepr.h", "metagrammar.h", - "node.h", "opcode.h", "osdefs.h", "pgenheaders.h", - "py_curses.h", "parsetok.h", "symtable.h", "token.h"] - - -def list_headers(): - """Return a list of headers.""" - incdir = os.path.join(srcdir, "Include") - return [fn for fn in os.listdir(incdir) - if fn.endswith(".h") and fn not in EXCLUDES] - - -def matcher(pattern): - return re.compile(pattern).match - -MATCHERS = [ - matcher(r"\\begin\{cfuncdesc\}\{[^{]*\}\{(?P[^{]*)\}"), - matcher(r"\\cfuncline\{[^{]*\}\{(?P[^{]*)\}"), - matcher(r"\\begin\{ctypedesc\}(\[[^{]*\])?\{(?P[^{]*)\}"), - matcher(r"\\begin\{cvardesc\}\{[^{]*\}\{(?P[^{]*)\}"), - matcher(r"\\begin\{cmemberdesc\}\{[^{]*\}\{(?P[^{]*)\}"), - matcher(r"\\cmemberline\{[^{]*\}\{(?P[^{]*)\}"), - matcher(r"\\begin\{csimplemacrodesc\}\{(?P[^{]*)\}"), - ] - - -def list_documented_items(): - """Return a list of everything that's already documented.""" - apidir = os.path.join(srcdir, "Doc", "api") - files = [fn for fn in os.listdir(apidir) if fn.endswith(".tex")] - L = [] - for fn in files: - fullname = os.path.join(apidir, fn) - for line in open(fullname): - line = line.lstrip() - if not line.startswith("\\"): - continue - for matcher in MATCHERS: - m = matcher(line) - if m: - L.append(m.group("sym")) - break - return L - -def split_documented(all, documented): - """Split the list of all symbols into documented and undocumented - categories.""" - doc = [] - undoc = [] - for t in all: - if t[0] in documented: - doc.append(t) - else: - undoc.append(t) - return doc, undoc - -def print_list(L, title=None): - """Dump a list to stdout.""" - if title: - print title + ":" - print "-" * (len(title) + 1) - w = 0 - for sym, filename in L: - w = max(w, len(sym)) - if w % 4 == 0: - w += 4 - else: - w += (4 - (w % 4)) - for sym, filename in L: - print "%-*s%s" % (w, sym, filename) - - -_spcjoin = ' '.join - -def main(): - args = sys.argv[1:] - if args: - headers = args - documented = [] - else: - os.chdir(os.path.join(srcdir, "Include")) - headers = list_headers() - documented = list_documented_items() - - cmd = ("ctags -f - --file-scope=no --c-types=dgpstux " - "-Istaticforward -Istatichere=static " - + _spcjoin(headers)) - fp = os.popen(cmd) - L = [] - prevsym = None - while 1: - line = fp.readline() - if not line: - break - sym, filename = line.split()[:2] - if sym == prevsym: - continue - if not sym.endswith("_H"): - L.append((sym, filename)) - prevsym = sym - L.sort() - fp.close() - - try: - if documented: - documented, undocumented = split_documented(L, documented) - print_list(documented, "Documented symbols") - if undocumented: - print - print_list(undocumented, "Undocumented symbols") - else: - print_list(L) - except IOError, e: - if e.errno != errno.EPIPE: - raise - - -if __name__ == "__main__": - main() diff --git a/olddoc/tools/findmodrefs b/olddoc/tools/findmodrefs deleted file mode 100755 index 8c5f93fb..00000000 --- a/olddoc/tools/findmodrefs +++ /dev/null @@ -1,63 +0,0 @@ -#! /usr/bin/env python -# -*- Python -*- - -import fileinput -import getopt -import glob -import os -import re -import sys - - -declare_rx = re.compile( - r"\\declaremodule(?:\[[a-zA-Z0-9]*\]*)?{[a-zA-Z_0-9]+}{([a-zA-Z_0-9]+)}") - -module_rx = re.compile(r"\\module{([a-zA-Z_0-9]+)}") - -def main(): - try: - just_list = 0 - print_lineno = 0 - opts, args = getopt.getopt(sys.argv[1:], "ln", ["list", "number"]) - for opt, arg in opts: - if opt in ("-l", "--list"): - just_list = 1 - elif opt in ("-n", "--number"): - print_lineno = 1 - files = args - if not files: - files = glob.glob("*.tex") - files.sort() - modulename = None - for line in fileinput.input(files): - if line[:9] == r"\section{": - modulename = None - continue - if line[:16] == r"\modulesynopsys{": - continue - m = declare_rx.match(line) - if m: - modulename = m.group(1) - continue - if not modulename: - continue - m = module_rx.search(line) - if m: - name = m.group(1) - if name != modulename: - filename = fileinput.filename() - if just_list: - print filename - fileinput.nextfile() - modulename = None - elif print_lineno: - print "%s(%d):%s" \ - % (filename, fileinput.filelineno(), line[:-1]) - else: - print "%s:%s" % (filename, line[:-1]) - except KeyboardInterrupt: - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/olddoc/tools/findsyms b/olddoc/tools/findsyms deleted file mode 100755 index 3b0f7099..00000000 --- a/olddoc/tools/findsyms +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python - -# Released to the public domain by Skip Montanaro, 28 March 2002 - -""" -findsyms.py - try to identify undocumented symbols exported by modules - -Usage: findsyms.py librefdir - -For each lib*.tex file in the libref manual source directory, identify which -module is documented, import the module if possible, then search the LaTeX -source for the symbols global to that module. Report any that don't seem to -be documented. - -Certain exceptions are made to the list of undocumented symbols: - - * don't mention symbols in which all letters are upper case on the - assumption they are manifest constants - - * don't mention symbols that are themselves modules - - * don't mention symbols that match those exported by os, math, string, - types, or __builtin__ modules - -Finally, if a name is exported by the module but fails a getattr() lookup, -that anomaly is reported. -""" - -import __builtin__ -import getopt -import glob -import math -import os -import re -import string -import sys -import types -import warnings - -def usage(): - print >> sys.stderr, """ -usage: %s dir -where 'dir' is the Library Reference Manual source directory. -""" % os.path.basename(sys.argv[0]) - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "") - except getopt.error: - usage() - return - - if not args: - usage() - return - - libdir = args[0] - - warnings.filterwarnings("error") - - pat = re.compile(r"\\declaremodule\s*{[^}]*}\s*{([^}]*)}") - - missing = [] - filelist = glob.glob(os.path.join(libdir, "lib*.tex")) - filelist.sort() - for f in filelist: - mod = f[3:-4] - if not mod: continue - data = open(f).read() - mods = re.findall(pat, data) - if not mods: - print "No module declarations found in", f - continue - for modname in mods: - # skip special modules - if modname.startswith("__"): - continue - try: - mod = __import__(modname) - except ImportError: - missing.append(modname) - continue - except DeprecationWarning: - print "Deprecated module:", modname - continue - if hasattr(mod, "__all__"): - all = mod.__all__ - else: - all = [k for k in dir(mod) if k[0] != "_"] - mentioned = 0 - all.sort() - for name in all: - if data.find(name) == -1: - # certain names are predominantly used for testing - if name in ("main","test","_test"): - continue - # is it some sort of manifest constant? - if name.upper() == name: - continue - try: - item = getattr(mod, name) - except AttributeError: - print " ", name, "exposed, but not an attribute" - continue - # don't care about modules that might be exposed - if type(item) == types.ModuleType: - continue - # check a few modules which tend to be import *'d - isglobal = 0 - for m in (os, math, string, __builtin__, types): - if hasattr(m, name) and item == getattr(m, name): - isglobal = 1 - break - if isglobal: continue - if not mentioned: - print "Not mentioned in", modname, "docs:" - mentioned = 1 - print " ", name - if missing: - missing.sort() - print "Could not import:" - print " ", ", ".join(missing) - -if __name__ == "__main__": - try: - main() - except KeyboardInterrupt: - pass diff --git a/olddoc/tools/fix_hack b/olddoc/tools/fix_hack deleted file mode 100755 index 8dad1110..00000000 --- a/olddoc/tools/fix_hack +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -sed -e 's/{\\ptt[ ]*\\char[ ]*'"'"'137}/_/g' <"$1" > "@$1" && mv "@$1" $1 diff --git a/olddoc/tools/fix_libaux.sed b/olddoc/tools/fix_libaux.sed deleted file mode 100755 index fb33cc57..00000000 --- a/olddoc/tools/fix_libaux.sed +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sed -f -s/{\\tt \\hackscore {}\\hackscore {}/\\sectcode{__/ -s/\\hackscore {}\\hackscore {}/__/ diff --git a/olddoc/tools/fixinfo.el b/olddoc/tools/fixinfo.el deleted file mode 100644 index 267a7e3c..00000000 --- a/olddoc/tools/fixinfo.el +++ /dev/null @@ -1,15 +0,0 @@ -(defun fix-python-texinfo () - (goto-char (point-min)) - (replace-regexp "\\(@setfilename \\)\\([-a-z]*\\)$" - "\\1python-\\2.info") - (replace-string "@node Front Matter\n@chapter Abstract\n" - "@node Abstract\n@section Abstract\n") - (mark-whole-buffer) - (texinfo-master-menu 'update-all-nodes) - (save-buffer) - ) ;; fix-python-texinfo - -;; now really do it: -(find-file (car command-line-args-left)) -(fix-python-texinfo) -(kill-emacs) diff --git a/olddoc/tools/getpagecounts b/olddoc/tools/getpagecounts deleted file mode 100755 index 202c73c4..00000000 --- a/olddoc/tools/getpagecounts +++ /dev/null @@ -1,97 +0,0 @@ -#! /usr/bin/env python - -"""Generate a page count report of the PostScript version of the manuals.""" - -__version__ = '$Revision$' - -import getopt -import sys - - -class PageCounter: - def __init__(self): - self.doclist = [] - self.total = 0 - self.title_width = 0 - self.version = "" - - def add_document(self, prefix, title): - count = count_pages(prefix + ".ps") - self.doclist.append((title, prefix, count)) - self.title_width = max(self.title_width, len(title)) - self.total = self.total + count - - def dump(self): - fmt = "%%-%ds (%%s.ps, %%d pages)" % self.title_width - for item in self.doclist: - print fmt % item - print - print " Total page count: %d" % self.total - - def parse_options(self): - opts, args = getopt.getopt(sys.argv[1:], "r:", ["release="]) - assert not args - for opt, arg in opts: - if opt in ("-r", "--release"): - self.version = arg - - def run(self): - self.parse_options() - if self.version: - version = self.version[:3] - self.add_document("whatsnew" + version.replace(".", ""), - "What's New in Python " + version) - for prefix, title in [ - ("api", "Python/C API"), - ("ext", "Extending and Embedding the Python Interpreter"), - ("lib", "Python Library Reference"), - ("mac", "Macintosh Module Reference"), - ("ref", "Python Reference Manual"), - ("tut", "Python Tutorial"), - ("doc", "Documenting Python"), - ("inst", "Installing Python Modules"), - ("dist", "Distributing Python Modules"), - ]: - self.add_document(prefix, title) - print self.PREFIX - self.dump() - print self.SUFFIX - - PREFIX = """\ -This is the PostScript version of the standard Python documentation. -If you plan to print this, be aware that some of the documents are -long. It is formatted for printing on two-sided paper; if you do plan -to print this, *please* print two-sided if you have a printer capable -of it! To locate published copies of the larger manuals, or other -Python reference material, consult the Python Bookstore at: - - http://www.amk.ca/bookstore/ - -The following manuals are included in this package: -""" - SUFFIX = """\ - - -If you have any questions, comments, or suggestions regarding these -documents, please send them via email to python-docs@python.org. -""" - -def count_pages(filename): - fp = open(filename) - count = 0 - while 1: - lines = fp.readlines(1024*40) - if not lines: - break - for line in lines: - if line[:7] == "%%Page:": - count = count + 1 - fp.close() - return count - - -def main(): - PageCounter().run() - -if __name__ == "__main__": - main() diff --git a/olddoc/tools/html2texi.pl b/olddoc/tools/html2texi.pl deleted file mode 100755 index be050b16..00000000 --- a/olddoc/tools/html2texi.pl +++ /dev/null @@ -1,1750 +0,0 @@ -#! /usr/bin/env perl -# html2texi.pl -- Convert HTML documentation to Texinfo format -# Michael Ernst -# Time-stamp: <1999-01-12 21:34:27 mernst> - -# This program converts HTML documentation trees into Texinfo format. -# Given the name of a main (or contents) HTML file, it processes that file, -# and other files (transitively) referenced by it, into a Texinfo file -# (whose name is chosen from the file or directory name of the argument). -# For instance: -# html2texi.pl api/index.html -# produces file "api.texi". - -# Texinfo format can be easily converted to Info format (for browsing in -# Emacs or the standalone Info browser), to a printed manual, or to HTML. -# Thus, html2texi.pl permits conversion of HTML files to Info format, and -# secondarily enables producing printed versions of Web page hierarchies. - -# Unlike HTML, Info format is searchable. Since Info is integrated into -# Emacs, one can read documentation without starting a separate Web -# browser. Additionally, Info browsers (including Emacs) contain -# convenient features missing from Web browsers, such as easy index lookup -# and mouse-free browsing. - -# Limitations: -# html2texi.pl is currently tuned to latex2html output (and it corrects -# several latex2html bugs), but should be extensible to arbitrary HTML -# documents. It will be most useful for HTML with a hierarchical structure -# and an index, and it recognizes those features as created by latex2html -# (and possibly by some other tools). The HTML tree to be traversed must -# be on local disk, rather than being accessed via HTTP. -# This script requires the use of "checkargs.pm". To eliminate that -# dependence, replace calls to check_args* by @_ (which is always the last -# argument to those functions). -# Also see the "to do" section, below. -# Comments, suggestions, bug fixes, and enhancements are welcome. - -# Troubleshooting: -# Malformed HTML can cause this program to abort, so -# you should check your HTML files to make sure they are legal. - - -### -### Typical usage for the Python documentation: -### - -# (Actually, most of this is in a Makefile instead.) -# The resulting Info format Python documentation is currently available at -# ftp://ftp.cs.washington.edu/homes/mernst/python-info.tar.gz - -# Fix up HTML problems, eg
should be
. - -# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/api/index.html -# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/ext/index.html -# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/lib/index.html -# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/mac/index.html -# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/ref/index.html -# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/tut/index.html - -# Edit the generated .texi files: -# * change @setfilename to prefix "python-" -# * fix up any sectioning, such as for Abstract -# * make Texinfo menus -# * perhaps remove the @detailmenu ... @end detailmenu -# In Emacs, to do all this: -# (progn (goto-char (point-min)) (replace-regexp "\\(@setfilename \\)\\([-a-z]*\\)$" "\\1python-\\2.info") (replace-string "@node Front Matter\n@chapter Abstract\n" "@node Abstract\n@section Abstract\n") (progn (mark-whole-buffer) (texinfo-master-menu 'update-all-nodes)) (save-buffer)) - -# makeinfo api.texi -# makeinfo ext.texi -# makeinfo lib.texi -# makeinfo mac.texi -# makeinfo ref.texi -# makeinfo tut.texi - - -### -### Structure of the code -### - -# To be written... - - -### -### Design decisions -### - -# Source and destination languages -# -------------------------------- -# -# The goal is Info files; I create Texinfo, so I don't have to worry about -# the finer details of Info file creation. (I'm not even sure of its exact -# format.) -# -# Why not start from LaTeX rather than HTML? -# I could hack latex2html itself to produce Texinfo instead, or fix up -# partparse.py (which already translates LaTeX to Teinfo). -# Pros: -# * has high-level information such as index entries, original formatting -# Cons: -# * those programs are complicated to read and understand -# * those programs try to handle arbitrary LaTeX input, track catcodes, -# and more: I don't want to go to that effort. HTML isn't as powerful -# as LaTeX, so there are fewer subtleties. -# * the result wouldn't work for arbitrary HTML documents; it would be -# nice to eventually extend this program to HTML produced from Docbook, -# Frame, and more. - -# Parsing -# ------- -# -# I don't want to view the text as a linear stream; I'd rather parse the -# whole thing and then do pattern matching over the parsed representation (to -# find idioms such as indices, lists of child nodes, etc.). -# * Perl provides HTML::TreeBuilder, which does just what I want. -# * libwww-perl: http://www.linpro.no/lwp/ -# * TreeBuilder: HTML-Tree-0.51.tar.gz -# * Python Parsers, Formatters, and Writers don't really provide the right -# interface (and the version in Grail doesn't correspond to another -# distributed version, so I'm confused about which to be using). I could -# write something in Python that creates a parse tree, but why bother? - -# Other implementation language issues: -# * Python lacks variable declarations, reasonable scoping, and static -# checking tools. I've written some of the latter for myself that make -# my Perl programming a lot safer than my Python programming will be until -# I have a similar suite for that language. - - -########################################################################### -### To do -### - -# Section names: -# Fix the problem with multiple sections in a single file (eg, Abstract in -# Front Matter section). -# Deal with cross-references, as in /homes/fish/mernst/tmp/python-doc/html/ref/types.html:310 -# Index: -# Perhaps double-check that every tag mentioned in the index is found -# in the text. -# Python: email to python-docs@python.org, to get their feedback. -# Compare to existing lib/ Info manual -# Write the hooks into info-look; replace pyliblookup1-1.tar.gz. -# Postpass to remove extra quotation marks around typography already in -# a different font (to avoid double delimiters as in "`code'"); or -# perhaps consider using only font-based markup so that we don't get -# the extra *bold* and `code' markup in Info. - -## Perhaps don't rely on automatic means for adding up, next, prev; I have -## all that info available to me already, so it's not so much trouble to -## add it. (Right?) But it is *so* easy to use Emacs instead... - - -########################################################################### -### Strictures -### - -# man HTML::TreeBuilder -# man HTML::Parser -# man HTML::Element - -# require HTML::ParserWComment; -require HTML::Parser; -require HTML::TreeBuilder; -require HTML::Element; - -use File::Basename; - -use strict; -# use Carp; - -use checkargs; - - -########################################################################### -### Variables -### - -my @section_stack = (); # elements are chapter/section/subsec nodetitles (I think) -my $current_ref_tdf; # for the file currently being processed; - # used in error messages -my $html_directory; -my %footnotes; - -# First element should not be used. -my @sectionmarker = ("manual", "chapter", "section", "subsection", "subsubsection"); - -my %inline_markup = ("b" => "strong", - "code" => "code", - "i" => "emph", - "kbd" => "kbd", - "samp" => "samp", - "strong" => "strong", - "tt" => "code", - "var" => "var"); - -my @deferred_index_entries = (); - -my @index_titles = (); # list of (filename, type) lists -my %index_info = ("Index" => ["\@blindex", "bl"], - "Concept Index" => ["\@cindex", "cp"], - "Module Index" => ["\@mdindex", "md"]); - - -########################################################################### -### Main/contents page -### - -# Process first-level page on its own, or just a contents page? Well, I do -# want the title, author, etc., and the front matter... For now, just add -# that by hand at the end. - - -# data structure possibilities: -# * tree-like (need some kind of stack when processing (or parent pointers)) -# * list of name and depth; remember old and new depths. - -# Each element is a reference to a list of (nodetitle, depth, filename). -my @contents_list = (); - -# The problem with doing fixups on the fly is that some sections may have -# already been processed (and no longer available) by the time we notice -# others with the same name. It's probably better to fully construct the -# contents list (reading in all files of interest) upfront; that will also -# let me do a better job with cross-references, because again, all files -# will already be read in. -my %contents_hash = (); -my %contents_fixups = (); - -my @current_contents_list = (); - -# Merge @current_contents_list into @contents_list, -# and set @current_contents_list to be empty. -sub merge_contents_lists ( ) -{ check_args(0, @_); - - # Three possibilities: - # * @contents_list is empty: replace it by @current_contents_list. - # * prefixes of the two lists are identical: do nothing - # * @current_contents_list is all at lower level than $contents_list[0]; - # prefix @contents_list by @current_contents_list - - if (scalar(@current_contents_list) == 0) - { die "empty current_contents_list"; } - - # if (scalar(@contents_list) == 0) - # { @contents_list = @current_contents_list; - # @current_contents_list = (); - # return; } - - # if (($ {$contents_list[0]}[1]) < ($ {$current_contents_list[0]}[1])) - # { unshift @contents_list, @current_contents_list; - # @current_contents_list = (); - # return; } - - for (my $i=0; $i= scalar(@contents_list)) - { push @contents_list, $ref_c_tdf; - my $title = $ {$ref_c_tdf}[0]; - if (defined $contents_hash{$title}) - { $contents_fixups{$title} = 1; } - else - { $contents_hash{$title} = 1; } - next; } - my $ref_tdf = $contents_list[$i]; - my ($title, $depth, $file) = @{$ref_tdf}; - my ($c_title, $c_depth, $c_file) = @{$ref_c_tdf}; - - if (($title ne $c_title) - && ($depth < $c_depth) - && ($file ne $c_file)) - { splice @contents_list, $i, 0, $ref_c_tdf; - if (defined $contents_hash{$c_title}) - { $contents_fixups{$c_title} = 1; } - else - { $contents_hash{$c_title} = 1; } - next; } - - if (($title ne $c_title) - || ($depth != $c_depth) - || ($file ne $c_file)) - { die ("while processing $ {$current_ref_tdf}[2] at depth $ {$current_ref_tdf}[1], mismatch at index $i:", - "\n main: <<<$title>>> $depth $file", - "\n curr: <<<$c_title>>> $c_depth $c_file"); } - } - @current_contents_list = (); -} - - - -# Set @current_contents_list to a list of (title, href, sectionlevel); -# then merge that list into @contents_list. -# Maybe this function should also produce a map -# from title (or href) to sectionlevel (eg "chapter"?). -sub process_child_links ( $ ) -{ my ($he) = check_args(1, @_); - - # $he->dump(); - if (scalar(@current_contents_list) != 0) - { die "current_contents_list nonempty: @current_contents_list"; } - $he->traverse(\&increment_current_contents_list, 'ignore text'); - - # Normalize the depths; for instance, convert 1,3,5 into 0,1,2. - my %depths = (); - for my $ref_tdf (@current_contents_list) - { $depths{$ {$ref_tdf}[1]} = 1; } - my @sorted_depths = sort keys %depths; - my $current_depth = scalar(@section_stack)-1; - my $current_depth_2 = $ {$current_ref_tdf}[1]; - if ($current_depth != $current_depth_2) - { die "mismatch in current depths: $current_depth $current_depth_2; ", join(", ", @section_stack); } - for (my $i=0; $i 1) - && ($ {$current_contents_list[1]}[0] eq "Contents")) - { my $ref_first_tdf = shift @current_contents_list; - $current_contents_list[0] = $ref_first_tdf; } - - for (my $i=0; $itag eq "li") - { my @li_content = @{$he->content}; - if ($li_content[0]->tag ne "a") - { die "first element of
  • should be "; } - my ($name, $href, @content) = anchor_info($li_content[0]); - # unused $name - my $title = join("", collect_texts($li_content[0])); - $title = texi_remove_punctuation($title); - # The problem with these is that they are formatted differently in - # @menu and @node! - $title =~ s/``/\"/g; - $title =~ s/''/\"/g; - $title =~ s/ -- / /g; - push @current_contents_list, [ $title, $depth, $href ]; } - return 1; -} - -# Simple version for section titles -sub html_to_texi ( $ ) -{ my ($he) = check_args(1, @_); - if (!ref $he) - { return $he; } - - my $tag = $he->tag; - if (exists $inline_markup{$tag}) - { my $result = "\@$inline_markup{$tag}\{"; - for my $elt (@{$he->content}) - { $result .= html_to_texi($elt); } - $result .= "\}"; - return $result; } - else - { $he->dump(); - die "html_to_texi confused by <$tag>"; } -} - - - -sub print_contents_list () -{ check_args(0, @_); - print STDERR "Contents list:\n"; - for my $ref_tdf (@contents_list) - { my ($title, $depth, $file) = @{$ref_tdf}; - print STDERR "$title $depth $file\n"; } -} - - - -########################################################################### -### Index -### - -my $l2h_broken_link_name = "l2h-"; - - -# map from file to (map from anchor name to (list of index texts)) -# (The list is needed when a single LaTeX command like \envvar -# expands to multiple \index commands.) -my %file_index_entries = (); -my %this_index_entries; # map from anchor name to (list of index texts) - -my %file_index_entries_broken = (); # map from file to (list of index texts) -my @this_index_entries_broken; - -my $index_prefix = ""; -my @index_prefixes = (); - -my $this_indexing_command; - -sub print_index_info () -{ check_args(0, @_); - my ($key, $val); - for my $file (sort keys %file_index_entries) - { my %index_entries = %{$file_index_entries{$file}}; - print STDERR "file: $file\n"; - for my $aname (sort keys %index_entries) - { my @entries = @{$index_entries{$aname}}; - if (scalar(@entries) == 1) - { print STDERR " $aname : $entries[0]\n"; } - else - { print STDERR " $aname : ", join("\n " . (" " x length($aname)), @entries), "\n"; } } } - for my $file (sort keys %file_index_entries_broken) - { my @entries = @{$file_index_entries_broken{$file}}; - print STDERR "file: $file\n"; - for my $entry (@entries) - { print STDERR " $entry\n"; } - } -} - - -sub process_index_file ( $$ ) -{ my ($file, $indexing_command) = check_args(2, @_); - # print "process_index_file $file $indexing_command\n"; - - my $he = file_to_tree($html_directory . $file); - # $he->dump(); - - $this_indexing_command = $indexing_command; - $he->traverse(\&process_if_index_dl_compact, 'ignore text'); - undef $this_indexing_command; - # print "process_index_file done\n"; -} - - -sub process_if_index_dl_compact ( $$$ ) -{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument - if (!$startflag) - { return; } - - if (($he->tag() eq "dl") && (defined $he->attr('compact'))) - { process_index_dl_compact($he); - return 0; } - else - { return 1; } -} - - -# The elements of a
    list from a LaTeX2HTML index: -# * a single space: text to be ignored -# *
    elements with an optional
    element following each one -# Two types of
    elements: -# * Followed by a
    element: the
    contains a single -# string, and the
    contains a whitespace string to be ignored, a -#
    to be recursively processed (with the
    string as a -# prefix), and a whitespace string to be ignored. -# * Not followed by a
    element: contains a list of anchors -# and texts (ignore the texts, which are only whitespace and commas). -# Optionally contains a
    to be recursively processed (with -# the
    string as a prefix) -sub process_index_dl_compact ( $ ) -{ my ($h) = check_args(1, @_); - my @content = @{$h->content()}; - for (my $i = 0; $i < scalar(@content); $i++) - { my $this_he = $content[$i]; - if ($this_he->tag ne "dt") - { $this_he->dump(); - die "Expected
    tag: " . $this_he->tag; } - if (($i < scalar(@content) - 1) && ($content[$i+1]->tag eq "dd")) - { process_index_dt_and_dd($this_he, $content[$i+1]); - $i++; } - else - { process_index_lone_dt($this_he); } } } - - - -# Argument is a
    element. If it contains more than one anchor, then -# the texts of all subsequent ones are "[Link]". Example: -#
    -# -# "$PATH" -# ", " -# -# "[Link]" -# Optionally contains a
    as well. Example: -#
    -# -# "attribute" -#
    -#
    -# -# "assignment" -# ", " -# -# "[Link]" -#
    -# -# "assignment, class" - -sub process_index_lone_dt ( $ ) -{ my ($dt) = check_args(1, @_); - my @dtcontent = @{$dt->content()}; - my $acontent; - my $acontent_suffix; - for my $a (@dtcontent) - { if ($a eq ", ") - { next; } - if (!ref $a) - { $dt->dump; - die "Unexpected
    string element: $a"; } - - if ($a->tag eq "dl") - { push @index_prefixes, $index_prefix; - if (!defined $acontent_suffix) - { die "acontent_suffix not yet defined"; } - $index_prefix .= $acontent_suffix . ", "; - process_index_dl_compact($a); - $index_prefix = pop(@index_prefixes); - return; } - - if ($a->tag ne "a") - { $dt->dump; - $a->dump; - die "Expected anchor in lone
    "; } - - my ($aname, $ahref, @acontent) = anchor_info($a); - # unused $aname - if (scalar(@acontent) != 1) - { die "Expected just one content of in
    : @acontent"; } - if (ref $acontent[0]) - { $acontent[0]->dump; - die "Expected string content of in
    : $acontent[0]"; } - if (!defined($acontent)) - { $acontent = $index_prefix . $acontent[0]; - $acontent_suffix = $acontent[0]; } - elsif (($acontent[0] ne "[Link]") && ($acontent ne ($index_prefix . $acontent[0]))) - { die "Differing content: <<<$acontent>>>, <<<$acontent[0]>>>"; } - - if (!defined $ahref) - { $dt->dump; - die "no HREF in nachor in
    "; } - my ($ahref_file, $ahref_name) = split(/\#/, $ahref); - if (!defined $ahref_name) - { # Reference to entire file - $ahref_name = ""; } - - if ($ahref_name eq $l2h_broken_link_name) - { if (!exists $file_index_entries_broken{$ahref_file}) - { $file_index_entries_broken{$ahref_file} = []; } - push @{$file_index_entries_broken{$ahref_file}}, "$this_indexing_command $acontent"; - next; } - - if (!exists $file_index_entries{$ahref_file}) - { $file_index_entries{$ahref_file} = {}; } - # Don't do this! It appears to make a copy, which is not desired. - # my %index_entries = %{$file_index_entries{$ahref_file}}; - if (!exists $ {$file_index_entries{$ahref_file}}{$ahref_name}) - { $ {$file_index_entries{$ahref_file}}{$ahref_name} = []; } - # { my $oldcontent = $ {$file_index_entries{$ahref_file}}{$ahref_name}; - # if ($acontent eq $oldcontent) - # { die "Multiple identical index entries?"; } - # die "Trying to add $acontent, but already have index entry pointing at $ahref_file\#$ahref_name: ${$file_index_entries{$ahref_file}}{$ahref_name}"; } - - push @{$ {$file_index_entries{$ahref_file}}{$ahref_name}}, "$this_indexing_command $acontent"; - # print STDERR "keys: ", keys %{$file_index_entries{$ahref_file}}, "\n"; - } -} - -sub process_index_dt_and_dd ( $$ ) -{ my ($dt, $dd) = check_args(2, @_); - my $dtcontent; - { my @dtcontent = @{$dt->content()}; - if ((scalar(@dtcontent) != 1) || (ref $dtcontent[0])) - { $dd->dump; - $dt->dump; - die "Expected single string (actual size = " . scalar(@dtcontent) . ") in content of
    : @dtcontent"; } - $dtcontent = $dtcontent[0]; - $dtcontent =~ s/ +$//; } - my $ddcontent; - { my @ddcontent = @{$dd->content()}; - if (scalar(@ddcontent) != 1) - { die "Expected single
    content, got ", scalar(@ddcontent), " elements:\n", join("\n", @ddcontent), "\n "; } - $ddcontent = $ddcontent[0]; } - if ($ddcontent->tag ne "dl") - { die "Expected
    as content of
    , but saw: $ddcontent"; } - - push @index_prefixes, $index_prefix; - $index_prefix .= $dtcontent . ", "; - process_index_dl_compact($ddcontent); - $index_prefix = pop(@index_prefixes); -} - - -########################################################################### -### Ordinary sections -### - -sub process_section_file ( $$$ ) -{ my ($file, $depth, $nodetitle) = check_args(3, @_); - my $he = file_to_tree(($file =~ /^\//) ? $file : $html_directory . $file); - - # print STDERR "process_section_file: $file $depth $nodetitle\n"; - - # Equivalently: - # while ($depth >= scalar(@section_stack)) { pop(@section_stack); } - @section_stack = @section_stack[0..$depth-1]; - - # Not a great nodename fixup scheme; need a more global view - if ((defined $contents_fixups{$nodetitle}) - && (scalar(@section_stack) > 0)) - { my $up_title = $section_stack[$#section_stack]; - # hack for Python Standard Library - $up_title =~ s/^(Built-in|Standard) Module //g; - my ($up_first_word) = split(/ /, $up_title); - $nodetitle = "$up_first_word $nodetitle"; - } - - push @section_stack, $nodetitle; - # print STDERR "new section_stack: ", join(", ", @section_stack), "\n"; - - $he->traverse(\&process_if_child_links, 'ignore text'); - %footnotes = (); - # $he->dump; - $he->traverse(\&process_if_footnotes, 'ignore text'); - - # $he->dump; - - if (exists $file_index_entries{$file}) - { %this_index_entries = %{$file_index_entries{$file}}; - # print STDERR "this_index_entries:\n ", join("\n ", keys %this_index_entries), "\n"; - } - else - { # print STDERR "Warning: no index entries for file $file\n"; - %this_index_entries = (); } - - if (exists $file_index_entries_broken{$file}) - { @this_index_entries_broken = @{$file_index_entries_broken{$file}}; } - else - { # print STDERR "Warning: no index entries for file $file\n"; - @this_index_entries_broken = (); } - - - if ($he->tag() ne "html") - { die "Expected at top level"; } - my @content = @{$he->content()}; - if ((!ref $content[0]) or ($content[0]->tag ne "head")) - { $he->dump; - die " not first element of "; } - if ((!ref $content[1]) or ($content[1]->tag ne "body")) - { $he->dump; - die " not second element of "; } - - $content[1]->traverse(\&output_body); -} - -# stack of things we're inside that are preventing indexing from occurring now. -# These are "h1", "h2", "h3", "h4", "h5", "h6", "dt" (and possibly others?) -my @index_deferrers = (); - -sub push_or_pop_index_deferrers ( $$ ) -{ my ($tag, $startflag) = check_args(2, @_); - if ($startflag) - { push @index_deferrers, $tag; } - else - { my $old_deferrer = pop @index_deferrers; - if ($tag ne $old_deferrer) - { die "Expected $tag at top of index_deferrers but saw $old_deferrer; remainder = ", join(" ", @index_deferrers); } - do_deferred_index_entries(); } -} - - -sub label_add_index_entries ( $;$ ) -{ my ($label, $he) = check_args_range(1, 2, @_); - # print ((exists $this_index_entries{$label}) ? "*" : " "), " label_add_index_entries $label\n"; - # $he is the anchor element - if (exists $this_index_entries{$label}) - { push @deferred_index_entries, @{$this_index_entries{$label}}; - return; } - - if ($label eq $l2h_broken_link_name) - { # Try to find some text to use in guessing which links should point here - # I should probably only look at the previous element, or if that is - # all punctuation, the one before it; collecting all the previous texts - # is a bit of overkill. - my @anchor_texts = collect_texts($he); - my @previous_texts = collect_texts($he->parent, $he); - # 4 elements is arbitrary; ought to filter out punctuation and small words - # first, then perhaps keep fewer. Perhaps also filter out formatting so - # that we can see a larger chunk of text? (Probably not.) - # Also perhaps should do further chunking into words, in case the - # index term isn't a chunk of its own (eg, was in .... - my @candidate_texts = (@anchor_texts, (reverse(@previous_texts))[0..min(3,$#previous_texts)]); - - my $guessed = 0; - for my $text (@candidate_texts) - { # my $orig_text = $text; - if ($text =~ /^[\"\`\'().?! ]*$/) - { next; } - if (length($text) <= 2) - { next; } - # hack for Python manual; maybe defer until failure first time around? - $text =~ s/^sys\.//g; - for my $iterm (@this_index_entries_broken) - { # I could test for zero: LaTeX2HTML's failures in the Python - # documentation are only for items of the form "... (built-in...)" - if (index($iterm, $text) != -1) - { push @deferred_index_entries, $iterm; - # print STDERR "Guessing index term `$iterm' for text `$orig_text'\n"; - $guessed = 1; - } } } - if (!$guessed) - { # print STDERR "No guess in `", join("'; `", @this_index_entries_broken), "' for texts:\n `", join("'\n `", @candidate_texts), "'\n"; - } - } -} - - -# Need to add calls to this at various places. -# Perhaps add HTML::Element argument and do the check for appropriateness -# here (ie, no action if inside

    , etc.). -sub do_deferred_index_entries () -{ check_args(0, @_); - if ((scalar(@deferred_index_entries) > 0) - && (scalar(@index_deferrers) == 0)) - { print TEXI "\n", join("\n", @deferred_index_entries), "\n"; - @deferred_index_entries = (); } -} - -my $table_columns; # undefined if not in a table -my $table_first_column; # boolean - -sub output_body ( $$$ ) -{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument - - if (!ref $he) - { my $space_index = index($he, " "); - if ($space_index != -1) - { # Why does - # print TEXI texi_quote(substr($he, 0, $space_index+1)); - # give: Can't locate object method "TEXI" via package "texi_quote" - # (Because the definition texi_quote hasn't been seen yet.) - print TEXI &texi_quote(substr($he, 0, $space_index+1)); - do_deferred_index_entries(); - print TEXI &texi_quote(substr($he, $space_index+1)); } - else - { print TEXI &texi_quote($he); } - return; } - - my $tag = $he->tag(); - - # Ordinary text markup first - if (exists $inline_markup{$tag}) - { if ($startflag) - { print TEXI "\@$inline_markup{$tag}\{"; } - else - { print TEXI "\}"; } } - elsif ($tag eq "a") - { my ($name, $href, @content) = anchor_info($he); - if (!$href) - { # This anchor is only here for indexing/cross referencing purposes. - if ($startflag) - { label_add_index_entries($name, $he); } - } - elsif ($href =~ "^(ftp|http|news):") - { if ($startflag) - { # Should avoid second argument if it's identical to the URL. - print TEXI "\@uref\{$href, "; } - else - { print TEXI "\}"; } - } - elsif ($href =~ /^\#(foot[0-9]+)$/) - { # Footnote - if ($startflag) - { # Could double-check name and content, but I'm not - # currently storing that information. - print TEXI "\@footnote\{"; - $footnotes{$1}->traverse(\&output_body); - print TEXI "\}"; - return 0; } } - else - { if ($startflag) - { # cross-references are not active Info links, but no text is lost - print STDERR "Can't deal with internal HREF anchors yet:\n"; - $he->dump; } - } - } - elsif ($tag eq "br") - { print TEXI "\@\n"; } - elsif ($tag eq "body") - { } - elsif ($tag eq "center") - { if (has_single_content_string($he) - && ($ {$he->content}[0] =~ /^ *$/)) - { return 0; } - if ($startflag) - { print TEXI "\n\@center\n"; } - else - { print TEXI "\n\@end center\n"; } - } - elsif ($tag eq "div") - { my $align = $he->attr('align'); - if (defined($align) && ($align eq "center")) - { if (has_single_content_string($he) - && ($ {$he->content}[0] =~ /^ *$/)) - { return 0; } - if ($startflag) - { print TEXI "\n\@center\n"; } - else - { print TEXI "\n\@end center\n"; } } - } - elsif ($tag eq "dl") - { # Recognize "
     ... 
    " paradigm for "@example" - if (has_single_content_with_tag($he, "dd")) - { my $he_dd = $ {$he->content}[0]; - if (has_single_content_with_tag($he_dd, "pre")) - { my $he_pre = $ {$he_dd->content}[0]; - print_pre($he_pre); - return 0; } } - if ($startflag) - { # Could examine the elements, to be cleverer about formatting. - # (Also to use ftable, vtable...) - print TEXI "\n\@table \@asis\n"; } - else - { print TEXI "\n\@end table\n"; } - } - elsif ($tag eq "dt") - { push_or_pop_index_deferrers($tag, $startflag); - if ($startflag) - { print TEXI "\n\@item "; } - else - { } } - elsif ($tag eq "dd") - { if ($startflag) - { print TEXI "\n"; } - else - { } - if (scalar(@index_deferrers) != 0) - { $he->dump; - die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; } - do_deferred_index_entries(); - } - elsif ($tag =~ /^(font|big|small)$/) - { # Do nothing for now. - } - elsif ($tag =~ /^h[1-6]$/) - { # We don't need this because we never recursively enter the heading content. - # push_or_pop_index_deferrers($tag, $startflag); - my $secname = ""; - my @seclabels = (); - for my $elt (@{$he->content}) - { if (!ref $elt) - { $secname .= $elt; } - elsif ($elt->tag eq "br") - { } - elsif ($elt->tag eq "a") - { my ($name, $href, @acontent) = anchor_info($elt); - if ($href) - { $he->dump; - $elt->dump; - die "Nonsimple anchor in <$tag>"; } - if (!defined $name) - { die "No NAME for anchor in $tag"; } - push @seclabels, $name; - for my $subelt (@acontent) - { $secname .= html_to_texi($subelt); } } - else - { $secname .= html_to_texi($elt); } } - if ($secname eq "") - { die "No section name in <$tag>"; } - if (scalar(@section_stack) == 1) - { if ($section_stack[-1] ne "Top") - { die "Not top? $section_stack[-1]"; } - print TEXI "\@settitle $secname\n"; - print TEXI "\@c %**end of header\n"; - print TEXI "\n"; - print TEXI "\@node Top\n"; - print TEXI "\n"; } - else - { print TEXI "\n\@node $section_stack[-1]\n"; - print TEXI "\@$sectionmarker[scalar(@section_stack)-1] ", texi_remove_punctuation($secname), "\n"; } - for my $seclabel (@seclabels) - { label_add_index_entries($seclabel); } - # This should only happen once per file. - label_add_index_entries(""); - if (scalar(@index_deferrers) != 0) - { $he->dump; - die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; } - do_deferred_index_entries(); - return 0; - } - elsif ($tag eq "hr") - { } - elsif ($tag eq "ignore") - { # Hack for ignored elements - return 0; - } - elsif ($tag eq "li") - { if ($startflag) - { print TEXI "\n\n\@item\n"; - do_deferred_index_entries(); } } - elsif ($tag eq "ol") - { if ($startflag) - { print TEXI "\n\@enumerate \@bullet\n"; } - else - { print TEXI "\n\@end enumerate\n"; } } - elsif ($tag eq "p") - { if ($startflag) - { print TEXI "\n\n"; } - if (scalar(@index_deferrers) != 0) - { $he->dump; - die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; } - do_deferred_index_entries(); } - elsif ($tag eq "pre") - { print_pre($he); - return 0; } - elsif ($tag eq "table") - { # Could also indicate common formatting for first column, or - # determine relative widths for columns (or determine a prototype row) - if ($startflag) - { if (defined $table_columns) - { $he->dump; - die "Can't deal with table nested inside $table_columns-column table"; } - $table_columns = table_columns($he); - if ($table_columns < 2) - { $he->dump; - die "Column with $table_columns columns?"; } - elsif ($table_columns == 2) - { print TEXI "\n\@table \@asis\n"; } - else - { print TEXI "\n\@multitable \@columnfractions"; - for (my $i=0; $i<$table_columns; $i++) - { print TEXI " ", 1.0/$table_columns; } - print TEXI "\n"; } } - else - { if ($table_columns == 2) - { print TEXI "\n\@end table\n"; } - else - { print TEXI "\n\@end multitable\n"; } - undef $table_columns; } } - elsif (($tag eq "td") || ($tag eq "th")) - { if ($startflag) - { if ($table_first_column) - { print TEXI "\n\@item "; - $table_first_column = 0; } - elsif ($table_columns > 2) - { print TEXI "\n\@tab "; } } - else - { print TEXI "\n"; } } - elsif ($tag eq "tr") - { if ($startflag) - { $table_first_column = 1; } } - elsif ($tag eq "ul") - { if ($startflag) - { print TEXI "\n\@itemize \@bullet\n"; } - else - { print TEXI "\n\@end itemize\n"; } } - else - { # I used to have a newline before "output_body" here. - print STDERR "output_body: ignoring <$tag> tag\n"; - $he->dump; - return 0; } - - return 1; -} - -sub print_pre ( $ ) -{ my ($he_pre) = check_args(1, @_); - if (!has_single_content_string($he_pre)) - { die "Multiple or non-string content for
    : ", @{$he_pre->content}; }
    -  my $pre_content = $ {$he_pre->content}[0];
    -  print TEXI "\n\@example";
    -  print TEXI &texi_quote($pre_content);
    -  print TEXI "\@end example\n";
    -}
    -
    -sub table_columns ( $ )
    -{ my ($table) = check_args(1, @_);
    -  my $result = 0;
    -  for my $row (@{$table->content})
    -    { if ($row->tag ne "tr")
    -	{ $table->dump;
    -	  $row->dump;
    -	  die "Expected  as table row."; }
    -      $result = max($result, scalar(@{$row->content})); }
    -  return $result;
    -}
    -
    -
    -###########################################################################
    -### Utilities
    -###
    -
    -sub min ( $$ )
    -{ my ($x, $y) = check_args(2, @_);
    -  return ($x < $y) ? $x : $y;
    -}
    -
    -sub max ( $$ )
    -{ my ($x, $y) = check_args(2, @_);
    -  return ($x > $y) ? $x : $y;
    -}
    -
    -sub file_to_tree ( $ )
    -{ my ($file) = check_args(1, @_);
    -
    -  my $tree = new HTML::TreeBuilder;
    -  $tree->ignore_unknown(1);
    -  # $tree->warn(1);
    -  $tree->parse_file($file);
    -  cleanup_parse_tree($tree);
    -  return $tree
    -}
    -
    -
    -sub has_single_content ( $ )
    -{ my ($he) = check_args(1, @_);
    -  if (!ref $he)
    -    { # return 0;
    -      die "Non-reference argument: $he"; }
    -  my $ref_content = $he->content;
    -  if (!defined $ref_content)
    -    { return 0; }
    -  my @content = @{$ref_content};
    -  if (scalar(@content) != 1)
    -    { return 0; }
    -  return 1;
    -}
    -
    -
    -# Return true if the content of the element contains only one element itself,
    -# and that inner element has the specified tag.
    -sub has_single_content_with_tag ( $$ )
    -{ my ($he, $tag) = check_args(2, @_);
    -  if (!has_single_content($he))
    -    { return 0; }
    -  my $content = $ {$he->content}[0];
    -  if (!ref $content)
    -    { return 0; }
    -  my $content_tag = $content->tag;
    -  if (!defined $content_tag)
    -    { return 0; }
    -  return $content_tag eq $tag;
    -}
    -
    -sub has_single_content_string ( $ )
    -{ my ($he) = check_args(1, @_);
    -  if (!has_single_content($he))
    -    { return 0; }
    -  my $content = $ {$he->content}[0];
    -  if (ref $content)
    -    { return 0; }
    -  return 1;
    -}
    -
    -
    -# Return name, href, content.  First two may be undefined; third is an array.
    -# I don't see how to determine if there are more attributes.
    -sub anchor_info ( $ )
    -{ my ($he) = check_args(1, @_);
    -  if ($he->tag ne "a")
    -    { $he->dump;
    -      die "passed non-anchor to anchor_info"; }
    -  my $name = $he->attr('name');
    -  my $href = $he->attr('href');
    -  my @content = ();
    -  { my $ref_content = $he->content;
    -    if (defined $ref_content)
    -      { @content = @{$ref_content}; } }
    -  return ($name, $href, @content);
    -}
    -
    -
    -sub texi_quote ( $ )
    -{ my ($text) = check_args(1, @_);
    -  $text =~ s/([\@\{\}])/\@$1/g;
    -  $text =~ s/ -- / --- /g;
    -  return $text;
    -}
    -
    -# Eliminate bad punctuation (that confuses Makeinfo or Info) for section titles.
    -sub texi_remove_punctuation ( $ )
    -{ my ($text) = check_args(1, @_);
    -
    -  $text =~ s/^ +//g;
    -  $text =~ s/[ :]+$//g;
    -  $text =~ s/^[1-9][0-9.]* +//g;
    -  $text =~ s/,//g;
    -  # Both embedded colons and " -- " confuse makeinfo.  (Perhaps " -- "
    -  # gets converted into " - ", just as "---" would be converted into " -- ",
    -  # so the names end up differing.)
    -  # $text =~ s/:/ -- /g;
    -  $text =~ s/://g;
    -  return $text;
    -}
    -
    -
    -## Do not use this inside `traverse':  it throws off the traversal.  Use
    -## html_replace_by_ignore or html_replace_by_meta instead.
    -# Returns 1 if success, 0 if failure.
    -sub html_remove ( $;$ )
    -{ my ($he, $parent) = check_args_range(1, 2, @_);
    -  if (!defined $parent)
    -    { $parent = $he->parent; }
    -  my $ref_pcontent = $parent->content;
    -  my @pcontent = @{$ref_pcontent};
    -  for (my $i=0; $iparent(undef);
    -	  return 1; } }
    -  die "Didn't find $he in $parent";
    -}
    -
    -
    -sub html_replace ( $$;$ )
    -{ my ($orig, $new, $parent) = check_args_range(2, 3, @_);
    -  if (!defined $parent)
    -    { $parent = $orig->parent; }
    -  my $ref_pcontent = $parent->content;
    -  my @pcontent = @{$ref_pcontent};
    -  for (my $i=0; $iparent($parent);
    -	  $orig->parent(undef);
    -	  return 1; } }
    -  die "Didn't find $orig in $parent";
    -}
    -
    -sub html_replace_by_meta ( $;$ )
    -{ my ($orig, $parent) = check_args_range(1, 2, @_);
    -  my $meta = new HTML::Element "meta";
    -  if (!defined $parent)
    -    { $parent = $orig->parent; }
    -  return html_replace($orig, $meta, $parent);
    -}
    -
    -sub html_replace_by_ignore ( $;$ )
    -{ my ($orig, $parent) = check_args_range(1, 2, @_);
    -  my $ignore = new HTML::Element "ignore";
    -  if (!defined $parent)
    -    { $parent = $orig->parent; }
    -  return html_replace($orig, $ignore, $parent);
    -}
    -
    -
    -
    -###
    -### Collect text elements
    -###
    -
    -my @collected_texts;
    -my $collect_texts_stoppoint;
    -my $done_collecting;
    -
    -sub collect_texts ( $;$ )
    -{ my ($root, $stop) = check_args_range(1, 2, @_);
    -  # print STDERR "collect_texts: $root $stop\n";
    -  $collect_texts_stoppoint = $stop;
    -  $done_collecting = 0;
    -  @collected_texts = ();
    -  $root->traverse(\&collect_if_text); # process texts
    -  # print STDERR "collect_texts => ", join(";;;", @collected_texts), "\n";
    -  return @collected_texts;
    -}
    -
    -sub collect_if_text ( $$$ )
    -{ my $he = (check_args(3, @_))[0]; #  ignore depth and startflag arguments
    -  if ($done_collecting)
    -    { return 0; }
    -  if (!defined $he)
    -    { return 0; }
    -  if (!ref $he)
    -    { push @collected_texts, $he;
    -      return 0; }
    -  if ((defined $collect_texts_stoppoint) && ($he eq $collect_texts_stoppoint))
    -    { $done_collecting = 1;
    -      return 0; }
    -  return 1;
    -}
    -
    -
    -###########################################################################
    -### Clean up parse tree
    -###
    -
    -sub cleanup_parse_tree ( $ )
    -{ my ($he) = check_args(1, @_);
    -  $he->traverse(\&delete_if_navigation, 'ignore text');
    -  $he->traverse(\&delete_extra_spaces, 'ignore text');
    -  $he->traverse(\&merge_dl, 'ignore text');
    -  $he->traverse(\&reorder_dt_and_dl, 'ignore text');
    -  return $he;
    -}
    -
    -
    -## Simpler version that deletes contents but not the element itself.
    -# sub delete_if_navigation ( $$$ )
    -# { my $he = (check_args(3, @_))[0]; # ignore startflag and depth
    -#   if (($he->tag() eq "div") && ($he->attr('class') eq 'navigation'))
    -#     { $he->delete();
    -#       return 0; }
    -#   else
    -#     { return 1; }
    -# }
    -
    -sub delete_if_navigation ( $$$ )
    -{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
    -  if (!$startflag)
    -    { return; }
    -
    -  if (($he->tag() eq "div") && (defined $he->attr('class')) && ($he->attr('class') eq 'navigation'))
    -    { my $ref_pcontent = $he->parent()->content();
    -      # Don't try to modify @pcontent, which appears to be a COPY.
    -      # my @pcontent = @{$ref_pcontent};
    -      for (my $i = 0; $idelete();
    -      return 0; }
    -  else
    -    { return 1; }
    -}
    -
    -sub delete_extra_spaces ( $$$ )
    -{ my ($he, $startflag) = (check_args(3, @_))[0,1]; #  ignore depth argument
    -  if (!$startflag)
    -    { return; }
    -
    -  my $tag = $he->tag;
    -  if ($tag =~ /^(head|html|table|tr|ul)$/)
    -    { delete_child_spaces($he); }
    -  delete_trailing_spaces($he);
    -  return 1;
    -}
    -
    -
    -sub delete_child_spaces ( $ )
    -{ my ($he) = check_args(1, @_);
    -  my $ref_content = $he->content();
    -  for (my $i = 0; $icontent();
    -  if (! defined $ref_content)
    -    { return; }
    -  # Could also check for previous element = /^h[1-6]$/.
    -  for (my $i = 0; $itag =~ /^(br|dd|dl|dt|hr|p|ul)$/))
    -	    { splice(@{$ref_content}, $i, 1);
    -	      $i--; } } }
    -  if ($he->tag =~ /^(dd|dt|^h[1-6]|li|p)$/)
    -    { my $last_elt = $ {$ref_content}[$#{$ref_content}];
    -      if ((defined $last_elt) && ($last_elt =~ /^ *$/))
    -	{ pop @{$ref_content}; } }
    -}
    -
    -
    -# LaTeX2HTML sometimes creates
    -#   
    text -#
    text -# which should actually be: -#
    -#
    text -#
    text -# Since a
    gets added, this ends up looking like -#

    -#

    -#
    -# text1... -#
    -#
    -# text2... -# dt_or_dd1... -# dt_or_dd2... -# which should become -#

    -#

    -#
    -# text1... -#
    -# text2... -# dt_or_dd1... -# dt_or_dd2... - -sub reorder_dt_and_dl ( $$$ ) -{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument - if (!$startflag) - { return; } - - if ($he->tag() eq "p") - { my $ref_pcontent = $he->content(); - if (defined $ref_pcontent) - { my @pcontent = @{$ref_pcontent}; - # print "reorder_dt_and_dl found a

    \n"; $he->dump(); - if ((scalar(@pcontent) >= 1) - && (ref $pcontent[0]) && ($pcontent[0]->tag() eq "dl") - && $pcontent[0]->implicit()) - { my $ref_dlcontent = $pcontent[0]->content(); - # print "reorder_dt_and_dl found a

    and implicit

    \n"; - if (defined $ref_dlcontent) - { my @dlcontent = @{$ref_dlcontent}; - if ((scalar(@dlcontent) >= 1) - && (ref $dlcontent[0]) && ($dlcontent[0]->tag() eq "dt")) - { my $ref_dtcontent = $dlcontent[0]->content(); - # print "reorder_dt_and_dl found a

    , implicit

    , and
    \n"; - if (defined $ref_dtcontent) - { my @dtcontent = @{$ref_dtcontent}; - if ((scalar(@dtcontent) > 0) - && (ref $dtcontent[$#dtcontent]) - && ($dtcontent[$#dtcontent]->tag() eq "dl")) - { my $ref_dl2content = $dtcontent[$#dtcontent]->content(); - # print "reorder_dt_and_dl found a

    , implicit

    ,
    , and
    \n"; - if (defined $ref_dl2content) - { my @dl2content = @{$ref_dl2content}; - if ((scalar(@dl2content) > 0) - && (ref ($dl2content[0])) - && ($dl2content[0]->tag() eq "dd")) - { - # print "reorder_dt_and_dl found a

    , implicit

    ,
    ,
    , and
    \n"; - # print STDERR "CHANGING\n"; $he->dump(); - html_replace_by_ignore($dtcontent[$#dtcontent]); - splice(@{$ref_dlcontent}, 1, 0, @dl2content); - # print STDERR "CHANGED TO:\n"; $he->dump(); - return 0; # don't traverse children - } } } } } } } } } - return 1; -} - - -# If we find a paragraph that looks like -#

    -#


    -#