GNU bug report logs - #59838
30.0.50; [PATCH] Save history in GDB session

Previous Next

Package: emacs;

Reported by: Manuel Giraud <manuel <at> ledu-giraud.fr>

Date: Mon, 5 Dec 2022 16:54:01 UTC

Severity: normal

Tags: patch

Found in version 30.0.50

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 59838 in the body.
You can then email your comments to 59838 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Mon, 05 Dec 2022 16:54:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Manuel Giraud <manuel <at> ledu-giraud.fr>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 05 Dec 2022 16:54:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.0.50; [PATCH] Save history in GDB session
Date: Mon, 05 Dec 2022 17:53:06 +0100
[Message part 1 (text/plain, inline)]
Hi,

I'm not really an expert in gdb (and comint-mode) but it seems that 'M-x
gdb' does not save its history.  Here is a patch that fix this.

[0001-lisp-progmodes-gdb-mi.el-gdb-send-Write-history.patch (text/x-patch, attachment)]
[Message part 3 (text/plain, inline)]

In GNU Emacs 30.0.50 (build 1, x86_64-unknown-openbsd7.2, cairo version
 1.17.6) of 2022-12-05 built on computer
Repository revision: 4fa37dc426184811e39ce113f6af7f5b308f116b
Repository branch: mgi/svg-trouble
Windowing system distributor 'The X.Org Foundation', version 11.0.12101004
System Description: OpenBSD computer 7.2 GENERIC.MP#859 amd64

Configured using:
 'configure --prefix=/home/manuel/emacs --bindir=/home/manuel/bin
 --with-x-toolkit=no --without-sound --without-compress-install
 CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib'

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LCMS2 LIBOTF LIBXML2 MODULES NOTIFY KQUEUE OLDXMENU PDUMPER PNG RSVG
SQLITE3 THREADS TIFF TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM ZLIB

Important settings:
  value of $LC_ALL: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Change Log

Minor modes in effect:
  gdb-many-windows: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  display-time-mode: t
  display-battery-mode: t
  server-mode: t
  shell-dirtrack-mode: t
  global-so-long-mode: t
  repeat-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  line-number-mode: t
  auto-fill-function: do-auto-fill
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/manuel/.emacs.d/elpa/ef-themes-0.10.0/theme-loaddefs hides /home/manuel/emacs/share/emacs/30.0.50/lisp/theme-loaddefs
/home/manuel/.emacs.d/elpa/transient-0.3.7/transient hides /home/manuel/emacs/share/emacs/30.0.50/lisp/transient

Features:
(shadow whitespace magit-patch ob-ditaa ob-plantuml ol-bibtex bibtex
org-clock org-colview org-crypt org-ctags org-habit org-mouse org-plot
org-protocol ox-odt rng-loc rng-uri rng-parse rng-match rng-dt rng-util
rng-pttrn nxml-parse nxml-ns nxml-enc xmltok nxml-util ox-latex
ox-icalendar org-agenda ox-html table ox-ascii ox-publish ox hsys-org
org-element org-persist xdg org-id org-refile avl-tree hsettings
hui-em-but hbut view hbdata hgnus hvar hsmail hypb locate hact set hhist
hmail htz cal-julian hbmap hmoccur hversion hload-path ob-C ob-R ob-awk
ob-calc calc-store calc-trail ob-clojure ob-css ob-dot ob-eshell eshell
esh-cmd esh-ext esh-opt esh-proc esh-io esh-arg esh-module esh-groups
esh-util ob-forth ob-fortran ob-gnuplot ob-groovy ob-haskell ob-java
ob-js ob-julia ob-latex ob-lilypond ob-lisp ob-lua ob-makefile ob-maxima
ob-ocaml ob-octave ob-org ob-perl ob-processing ob-python python ob-ruby
ob-sass ob-scheme ob-screen ob-sed ob-shell ob-sqlite ob-sql vc-annotate
vc ibuf-ext ibuffer ibuffer-loaddefs dabbrev shortdoc cl-print help-fns
radix-tree proced tabify man gdb-mi bindat gud bug-reference
magit-extras face-remap magit-bookmark magit-submodule magit-obsolete
magit-blame magit-stash magit-reflog magit-bisect magit-push magit-pull
magit-fetch magit-clone magit-remote magit-commit magit-sequence
magit-notes magit-worktree magit-tag magit-merge magit-branch
magit-reset magit-files magit-refs magit-status magit magit-repos
magit-apply magit-wip magit-log which-func imenu magit-diff smerge-mode
diff git-commit log-edit pcvs-util add-log magit-core magit-autorevert
autorevert magit-margin magit-transient magit-process with-editor
magit-mode transient magit-git magit-section magit-utils dash misearch
multi-isearch vc-svn sort gnus-cite mail-extr textsec uni-scripts
idna-mapping ucs-normalize uni-confusable textsec-check gnus-async
gnus-bcklg gnus-ml gnus-topic mm-archive url-http url-gw url-cache
url-auth qp utf-7 imap nndoc nndraft nnmh nnfolder nnml gnus-agent
gnus-srvr gnus-score score-mode nnvirtual nntp gnus-cache nnrss mm-url
w3m doc-view filenotify jka-compr image-mode exif w3m-hist w3m-fb
bookmark-w3m w3m-ems w3m-favicon w3m-image tab-line w3m-proc w3m-util
pcmpl-linux vc-hg vc-git diff-mode vc-bzr vc-dispatcher rfc2104
tramp-cache time-stamp tramp-sh network-stream nsm emacsbug pulse
gnus-dired sh-script smie treesit executable cus-start paredit edmacro
time battery exwm-randr xcb-randr exwm-config exwm exwm-input
xcb-keysyms xcb-xkb exwm-manage exwm-floating xcb-cursor xcb-render
exwm-layout exwm-workspace exwm-core xcb-ewmh xcb-icccm xcb xcb-xproto
xcb-types xcb-debug kmacro server stimmung-themes modus-operandi-theme
modus-themes ytdious osm mingus libmpdee reporter edebug debug backtrace
transmission diary-lib diary-loaddefs color calc-bin calc-ext calc
calc-loaddefs rect calc-macs w3m-load mu4e mu4e-org mu4e-main mu4e-view
mu4e-headers mu4e-compose mu4e-draft mu4e-actions smtpmail mu4e-search
mu4e-lists mu4e-bookmarks mu4e-mark mu4e-message flow-fill mule-util
hl-line mu4e-contacts mu4e-update mu4e-folders mu4e-server mu4e-context
mu4e-vars mu4e-helpers mu4e-config bookmark ido supercite regi
ebdb-message ebdb-gnus gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime
smime gnutls dig gnus-sum shr pixel-fill kinsoku url-file svg dom
gnus-group gnus-undo gnus-start gnus-dbus gnus-cloud nnimap nnmail
mail-source utf7 nnoo gnus-spec gnus-int gnus-range message sendmail
yank-media puny rfc822 mml mml-sec epa epg rfc6068 epg-config mm-decode
mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 ietf-drums
gmm-utils mailheader gnus-win gnus nnheader gnus-util mail-utils range
mm-util mail-prsvr ebdb-mua ebdb-com crm ebdb-format ebdb mailabbrev
eieio-opt cl-extra help-mode speedbar ezimage dframe eieio-base pcase
timezone org ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro
org-src ob-comint org-pcomplete org-list org-footnote org-faces
org-entities ob-emacs-lisp ob-core ob-eval org-cycle org-table ol
org-fold org-fold-core org-keys oc org-loaddefs find-func cal-menu
calendar cal-loaddefs org-version org-compat org-macs visual-basic-mode
cl web-mode derived disp-table erlang-start smart-tabs-mode skeleton
cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine
cc-vars cc-defs slime-asdf grep slime-tramp tramp tramp-loaddefs
trampver tramp-integration cus-edit cus-load wid-edit files-x
tramp-compat rx shell pcomplete parse-time iso8601 time-date ls-lisp
format-spec slime-fancy slime-indentation slime-cl-indent cl-indent
slime-trace-dialog slime-fontifying-fu slime-package-fu slime-references
slime-compiler-notes-tree advice slime-scratch slime-presentations
bridge slime-macrostep macrostep slime-mdot-fu slime-enclosing-context
slime-fuzzy slime-fancy-trace slime-fancy-inspector slime-c-p-c
slime-editing-commands slime-autodoc slime-repl slime-parse slime
compile text-property-search etags fileloop generator xref project
arc-mode archive-mode noutline outline icons pp comint ansi-osc
ansi-color ring hyperspec thingatpt slime-autoloads dired-aux dired-x
dired dired-loaddefs so-long notifications dbus xml repeat easy-mmode
rust-mode-autoloads stimmung-themes-autoloads ebdb-autoloads
magit-autoloads debbugs-autoloads git-commit-autoloads
magit-section-autoloads ef-themes-autoloads with-editor-autoloads
paredit-autoloads dash-autoloads ytdious-autoloads
transmission-autoloads transient-autoloads exwm-autoloads
hyperbole-autoloads detached-autoloads info package browse-url url
url-proxy url-privacy url-expand url-methods url-history url-cookie
generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse
auth-source cl-seq eieio eieio-core cl-macs password-cache json subr-x
map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs cl-lib rmc
iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind kqueue lcms2 dynamic-setting system-font-setting
font-render-setting cairo xinput2 x multi-tty make-network-process
emacs)

Memory information:
((conses 16 1325793 307023)
 (symbols 48 70022 13)
 (strings 32 342856 14419)
 (string-bytes 1 10944812)
 (vectors 16 219440)
 (vector-slots 8 3492670 116033)
 (floats 8 859 791)
 (intervals 56 37544 5279)
 (buffers 992 62))

-- 
Manuel Giraud

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Mon, 05 Dec 2022 17:20:02 GMT) Full text and rfc822 format available.

Message #8 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Manuel Giraud <manuel <at> ledu-giraud.fr>
Cc: 59838 <at> debbugs.gnu.org
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Mon, 05 Dec 2022 19:19:00 +0200
> From: Manuel Giraud <manuel <at> ledu-giraud.fr>
> Date: Mon, 05 Dec 2022 17:53:06 +0100
> 
> I'm not really an expert in gdb (and comint-mode) but it seems that 'M-x
> gdb' does not save its history.  Here is a patch that fix this.

GDB has its own history feature, activated by the GDB command "set history
save on".  If the GDB history file is detected when "M-x gdb" starts, it
will read the history and fill comint-input-ring with what it finds there.
See the function 'gdb' in gdb-mi.el.

So I think this is already covered, or what did I miss?

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Mon, 05 Dec 2022 17:54:02 GMT) Full text and rfc822 format available.

Message #11 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 59838 <at> debbugs.gnu.org
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Mon, 05 Dec 2022 18:53:33 +0100
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Manuel Giraud <manuel <at> ledu-giraud.fr>
>> Date: Mon, 05 Dec 2022 17:53:06 +0100
>> 
>> I'm not really an expert in gdb (and comint-mode) but it seems that 'M-x
>> gdb' does not save its history.  Here is a patch that fix this.
>
> GDB has its own history feature, activated by the GDB command "set history
> save on".  If the GDB history file is detected when "M-x gdb" starts, it
> will read the history and fill comint-input-ring with what it finds there.
> See the function 'gdb' in gdb-mi.el.
>
> So I think this is already covered, or what did I miss?

I already have this in my ~/.gdbinit:
--8<---------------cut here---------------start------------->8---
set history save on
set history size 1024
add-auto-load-safe-path /home/manuel/emacs-repo/src/.gdbinit
--8<---------------cut here---------------end--------------->8---

When debugging emacs from 'M-x gdb', gdb does create a file
"/home/manuel/emacs-repo/src/.gdb_history" but it always stays empty
even when I "quit" from the *gud-emacs* buffer.
-- 
Manuel Giraud




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Mon, 05 Dec 2022 19:37:02 GMT) Full text and rfc822 format available.

Message #14 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Manuel Giraud <manuel <at> ledu-giraud.fr>
Cc: 59838 <at> debbugs.gnu.org
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Mon, 05 Dec 2022 21:35:25 +0200
> From: Manuel Giraud <manuel <at> ledu-giraud.fr>
> Cc: 59838 <at> debbugs.gnu.org
> Date: Mon, 05 Dec 2022 18:53:33 +0100
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> >> From: Manuel Giraud <manuel <at> ledu-giraud.fr>
> >> Date: Mon, 05 Dec 2022 17:53:06 +0100
> >> 
> >> I'm not really an expert in gdb (and comint-mode) but it seems that 'M-x
> >> gdb' does not save its history.  Here is a patch that fix this.
> >
> > GDB has its own history feature, activated by the GDB command "set history
> > save on".  If the GDB history file is detected when "M-x gdb" starts, it
> > will read the history and fill comint-input-ring with what it finds there.
> > See the function 'gdb' in gdb-mi.el.
> >
> > So I think this is already covered, or what did I miss?
> 
> I already have this in my ~/.gdbinit:
> --8<---------------cut here---------------start------------->8---
> set history save on
> set history size 1024
> add-auto-load-safe-path /home/manuel/emacs-repo/src/.gdbinit
> --8<---------------cut here---------------end--------------->8---
> 
> When debugging emacs from 'M-x gdb', gdb does create a file
> "/home/manuel/emacs-repo/src/.gdb_history" but it always stays empty
> even when I "quit" from the *gud-emacs* buffer.

I guess this is because GDB's history works via Readline, and Readline is
not used when Emacs is the front end.

Then I think your patch is correct, thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Tue, 06 Dec 2022 10:31:01 GMT) Full text and rfc822 format available.

Message #17 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 59838 <at> debbugs.gnu.org, Manuel Giraud <manuel <at> ledu-giraud.fr>
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Tue, 06 Dec 2022 11:30:01 +0100
Eli Zaretskii <eliz <at> gnu.org> writes:

[...]

> I guess this is because GDB's history works via Readline, and Readline is
> not used when Emacs is the front end.

Ok.

> Then I think your patch is correct, thanks.

But as I said, I'm not an expert with comint-mode stuff.  I put
'(comint-write-input-ring)' at the end of gdb-send because it seems to
make sense but I don't know for sure.
-- 
Manuel Giraud




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Tue, 06 Dec 2022 12:28:02 GMT) Full text and rfc822 format available.

Message #20 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Manuel Giraud <manuel <at> ledu-giraud.fr>
Cc: 59838 <at> debbugs.gnu.org, manuel <at> ledu-giraud.fr
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Tue, 06 Dec 2022 14:27:15 +0200
> From: Manuel Giraud <manuel <at> ledu-giraud.fr>
> Cc: Manuel Giraud <manuel <at> ledu-giraud.fr>,  59838 <at> debbugs.gnu.org
> Date: Tue, 06 Dec 2022 11:30:01 +0100
> 
> > Then I think your patch is correct, thanks.
> 
> But as I said, I'm not an expert with comint-mode stuff.  I put
> '(comint-write-input-ring)' at the end of gdb-send because it seems to
> make sense but I don't know for sure.

I think the call should be where the gud buffer is killed or we exit the
debugger, not after each string we send to the debugger.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Tue, 06 Dec 2022 16:24:02 GMT) Full text and rfc822 format available.

Message #23 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 59838 <at> debbugs.gnu.org
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Tue, 06 Dec 2022 17:23:01 +0100
Eli Zaretskii <eliz <at> gnu.org> writes:

[...]

>> But as I said, I'm not an expert with comint-mode stuff.  I put
>> '(comint-write-input-ring)' at the end of gdb-send because it seems to
>> make sense but I don't know for sure.
>
> I think the call should be where the gud buffer is killed or we exit the
> debugger, not after each string we send to the debugger.

Alright, I'll try to find this place ;-)
-- 
Manuel Giraud




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Thu, 08 Dec 2022 10:29:02 GMT) Full text and rfc822 format available.

Message #26 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 59838 <at> debbugs.gnu.org
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Thu, 08 Dec 2022 11:28:43 +0100
[Message part 1 (text/plain, inline)]
Hi,

I think I have found the right place.  I've tested it with "M-x gdb"
doing an explicit "quit" or using `C-d'.  I've also tested with "M-x
gud-gdb".  Now I think we'll need a patch to gitignore the .gbd_history
files into the emacs directory.

[0001-Fix-GDB-save-history-bug-59838.patch (text/x-patch, attachment)]
[Message part 3 (text/plain, inline)]
-- 
Manuel Giraud

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#59838; Package emacs. (Fri, 09 Dec 2022 09:03:01 GMT) Full text and rfc822 format available.

Message #29 received at 59838 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 59838 <at> debbugs.gnu.org
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Fri, 09 Dec 2022 10:02:40 +0100
[Message part 1 (text/plain, inline)]
Hi,

I think I have found the right place.  I've tested it with "M-x gdb"
doing an explicit "quit" or using `C-d'.  I've also tested with "M-x
gud-gdb".  Now I think we'll need a patch to gitignore the .gbd_history
files into the emacs directory.
[0001-Fix-GDB-save-history-bug-59838.patch (text/x-patch, attachment)]
[Message part 3 (text/plain, inline)]
-- 
Manuel Giraud

Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Sat, 10 Dec 2022 13:41:02 GMT) Full text and rfc822 format available.

Notification sent to Manuel Giraud <manuel <at> ledu-giraud.fr>:
bug acknowledged by developer. (Sat, 10 Dec 2022 13:41:02 GMT) Full text and rfc822 format available.

Message #34 received at 59838-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Manuel Giraud <manuel <at> ledu-giraud.fr>
Cc: 59838-done <at> debbugs.gnu.org
Subject: Re: bug#59838: 30.0.50; [PATCH] Save history in GDB session
Date: Sat, 10 Dec 2022 15:40:32 +0200
> From: Manuel Giraud <manuel <at> ledu-giraud.fr>
> Cc: 59838 <at> debbugs.gnu.org
> Date: Fri, 09 Dec 2022 10:02:40 +0100
> 
> I think I have found the right place.  I've tested it with "M-x gdb"
> doing an explicit "quit" or using `C-d'.  I've also tested with "M-x
> gud-gdb".

Thanks, installed on the master branch.

> Now I think we'll need a patch to gitignore the .gbd_history files
> into the emacs directory.

Yes, I think it's a good idea.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 08 Jan 2023 12:24:06 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 102 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.