Copyright © 2023 by Thomas E. Dickey

Copy-Wrongs – comments on plagiarism


I began organizing information for this page in 2010, without completing it until now (August 2023). I have not run short of things to work on (and indeed, the scope of this page has grown). For instance, I have substantial work on pages for variations of the make program and the xterm meta-key. However, time passes, and I'm reminded that there is a limit to the time I have left.

Science Fairs

As a high school student, I developed projects for the school science fairs. I found competing in the high school and at the county level easy. Each year that I was in high school, I went on to the area fair. Doing that required placing first in a category in the county science fair. I did that with projects for these topics:

Although my project received an award only once (the first time), I enjoyed the area fair because I did not merely visit it, but lived there for a couple of days, because it was far away from my home.

During my first visit, I stayed at the home of Dr. Rappleye (a biology professor). A few details were interesting:

I asked if I might read that. It was probably the March 1966 issue, since the science fair was held on the weekend of April 16-18. To help with this page, I found its cover on Etsy, which looks familiar:

Cover: American Girl, March 1966

When I read the magazine, I found that it had stories (part of a contest). The first-place winner (a science fiction story) was submitted by a girl in California. But I had read that story before.

When I returned home, I went to the public library. They had a subscription to this magazine. I showed the magazine to the librarians, explaining that I was certain that I had read the story before. We searched through all of the science fiction books. It seemed the sort of thing that Frederic Brown would have written, and I was looking for that. However, when we found the story, it was by a less-known author:

“The Choice” by W. Hilton-Young
appeared in Groff Conklin's Omnibus of Science Fiction,
published in 1952.

It is very short. I found a copy here:

BEFORE WILLIAMS WENT into the future he bought a camera and a tape recording-machine and learned shorthand. That night, when all was ready, we made coffee and put out brandy and glasses against his return.
       “Good-bye,” I said. “Don’t stay too long.”
       “I won’t,” he answered.
       I watched him carefully, and he hardly flickered. He must have made a perfect landing on the very second he had taken off from. He seemed not a day older; we had expected he might spend several years away.
       “Well,” said he, “let’s have some coffee.”
       I poured it out, hardly able to contain my impatience. As I gave it to him I said again, “Well?”
       “Well, the thing is, I can’t remember.”
       “Can’t remember? Not a thing?”
       He thought for a moment and answered sadly, “Not a thing.”
       “But your notes? The camera? The recording-machine?”
       The notebook was empty, the indicator of the camera rested at “1” where we had set it, the tape was not even loaded into the recording-machine.
       “But good heavens,” I protested, “why? How did it happen? Can you remember nothing at all?”
       “I can remember only one thing.”
       “What was that?”
       “I was shown everything, and I was given the choice whether I should remember it or not after I got back.”
       “And you chose not to? But what an extraordinary thing to—”
       “Isn’t it?” he said. “One can’t help wondering why.”

The story in the magazine was almost identical (substituting “tea” for “coffee”).

I wrote a letter to the publisher, explaining what I had found. I received no reply.

That was my initial first-hand encounter with plagiarism (as well as copyright violation). It was not the last.

A plagiarist presents another's ideas and the manner in which they are expressed as their own. Copyright only deals with the way something is presented.


As a college student, I ran into different issues.

Copying answers

Going from high school to college, I was uncertain what I should study. I was interested in physics, mathematics, and engineering. That was resolved by getting a scholarship at an engineering school. The same thing happened when I started graduate studies (though by then I had discarded physics).

Still, as an engineering student, I had some flexibility. Late in my freshman year, another student told me that there would be a course offered in numerical methods later that year (Fall 1970). I signed up for the course, and found that its prerequisite was the course on differential equations which I would be taking at the same time. To catch up, I worked through the problems in the latter's syllabus.

The other students in this class were mathematics majors, all juniors and seniors. The numerical methods course used Sokolnikoff and Redheffer's Mathematics of Physics and Modern Engineering, which I still have. We did not complete the book, but concentrated on a set of related topics. In particular, there was the vibrating string problem.

The instructor would leave the room during exams, to avoid disturbing us. During one of those, I glanced up, having noticed some movement, to see a senior craning his neck to look at what I was writing. I moved my paper to block that.

Surprised, I recall thinking to myself: “he must be stupid” not related to being caught, but rather “how is he going to know if my answer is better than what he would do for himself?”

Cheating in this way is a form of plagiarism, because the cheater uses another's work to (attempt to) get a better mark.

Personal gain is (usually) presumed to be the reason for plagiarism. However, stupidity plays a recurring role along with its partner, aggression.

Sharing grades

As an undergraduate engineering student, I wrote reports, both individually and in small groups (see for example my comments on terseness). As an engineer, both approaches are needed. Students need practice to be proficient with both.

Later, as a graduate student in electrical engineering, the (required) “internship in university teaching” course consisted of grading reports written by undergraduate engineering students. During 1975, Gary Leive and I graded reports by 87 students for the junior-level “analysis, synthesis and evaluation” course. All of the marks are on a scale up to ten (10).

Only a few students produced good reports. The rest required some judgement on our part. One assignment asked the student to identify advantages and likely problem areas to investigate in using a computer to control an automobile. One student wrote only that this had nothing to do with electrical engineering. I wrote zero (0), but the instructor overruled that. Just handing in a paper guaranteed six (6) points.

I kept that in mind with a later assignment to compute and report the results from a numerical solution to the Fourier heat equation. The students were given the formula to use in their programs, and the grid-size. All they had to do was write the short program and write a short report presenting the results.

The instructor specified individual reports so that the students would get useful experience in developing their own ideas and learning how to express themselves.

Reading and analyzing 87 reports takes several hours (even with two to share the work). It is important to use the consistent grading criteria. Partway through, I noticed a report that seemed familiar. Looking back through the graded reports, I found a match (the same phrases, etc). Gary and I changed tactics, setting aside reports which appeared similar. We found three clusters of reports which were problematic (totalling ten of the students).

After some discussion, we decided to split the grade up between the contributors. If a report merited 9 points, and there were three students in the cluster, each got 3 points.

Our decision this time was not overruled. Whether they worked together or copied from one was unknown. Either way, those students were not presenting their own ideas, in their own words.

At work...

Out in the world of paid work, versus gratis, I have little to report:

Unpaid work...

Outside the scope of paid work, things are more interesting. As outlined here, early in 1994, I began developing computer programs, distributed free of charge, on the Internet.

With no money involved, one might suppose that there is nothing to dispute. But there is that matter of attribution, which leads us back to plagiarism.

I have encountered too many disputes to go into depth for each. Instead, I have limited it to the more interesting stories.


As I described in my page on the ncurses license, I first dealt with ncurses to fix colors for my adding machine, and then with handling window resizing for my directory editor.

Raymond was reluctant to make the corrections for background color, and when I followed up with a configure script (replacing a crude script which Raymond had written) and then my changes to support SIGWINCH, he dug in his heels, so to speak.

Raymond's first mention of the imitation of wresize implied that he was not looking at my original, but the manual page was written in Raymond's style, easily recognizable as his own work. Given that, whether the imitation was a collaboration or not was a moot point (and dealt with, in due course).

However, that raised an issue which I had not previously encountered: the use of misattribution to discredit other developers, e.g., by stating that some other (inaccessible) person did the original work rather than the one who is being attacked. It is less straightforward than simple plagiarism, but serves the same purpose if aggression is the basis. Since then, I have seen this technique employed frequently.

Given the issue with manual pages, and this episode, I considered creating a webpage devoted to Raymond, since it appeared to me that half of his website contained dubious material. However, on closer examination I could only demonstrate problems in 19% of the site, and put that thought aside.


This came shortly after the ncurses dispute, and has a similar story: a developer decided to emphasize his rejection of my proposed changes. To do this, he went beyond the dispute, plagiarizing something that I had developed (see discussion).

tparm, initial

The ncurses tparm function has some issues:

Reflecting on that, it improved ncurses but diverged from X/Open Curses which simply blessed the AT&T implementation from around 1985. That used a fixed-length parameter list:

char *tparm(char *, long, long, long, long, long, long, long, long, long);

To the extent that we discussed this in 1995, the consensus was that surely the standards people would keep up with the C language standard. Of course that did not happen.

Several years later, I helped review and update X/Open Curses,

Date: Tue, 5 Feb 2008 16:13:20 +0000
From: Geoff Clare <>
Subject: tparm (was: Bug in CursesI5d2)

> From: Thomas Dickey
> On Thu, 24 Jan 2008, Geoff Clare wrote:
> > Problem:
> >
> > In this revision, the first parameter of tigetflag(), tigetnum() and
> > tigetstr() has changed to be const.  For consistency, the first
> > parameter of tparm() should get the same change.
> >
> > (In the preliminary draft the const was there, together with a change
> > from nine longs to an ellipsis; there were objections to the ellipsis,
> > resulting in the change back to nine longs, but I don't think there
> > was any objection to the const.)
> It's worth pointing out that the technical reason for the 9 longs is that
> some terminfo capabilities require those parameters to be strings rather
> than long/integer values.  (The reason for making that point of course is
> a concern that some platform may have a pointer that does not fit in a
> long).

I have been thinking about how best to address this issue of string

As a minimum we should add some app usage text for tparm() explaining
that capabilities with string-valued parameters can only be used
in programming environments where converting a char * pointer to long
and back does not alter the value of the pointer.

I spot the following capabilities that have string parameters:

   pkey_key    (pfkey)
   pkey_local  (pfloc)
   pkey_plab   (pfxl)
   pkey_xmit   (pfx)
   plab_norm   (pln)

Are there any more?

If these are seldom used we could consider marking them obsolescent.

On the other hand, if they are widely used, and are felt to be
important enough, we should perhaps consider a more radical fix.
As previously discussed, we can't just change tparm() to have an
ellipsis in the prototype, as that would break existing conforming
apps.  What we could do instead is mark tparm() as obsolescent and
introduce a replacement function called, say, tiparm().  That way
existing apps would continue to work on XCurses Issue 5
implementations, and there would be a gradual migration path
from using tparm() to tiparm().

Geoff Clare <>
The Open Group, Thames Tower, Station Road, Reading, RG1 1LX, England

adding the ncurses variation (actually a new entrypoint to the same code) as tiparm in January 2010:

        + add tiparm(), based on review of X/Open Curses Issue 7.

possibly reminded by a mention of X/Open Curses, Issue 7, as I noted recently:

The only new feature in issue 7 was tiparm, which was in ncurses a week after this answer. – Thomas Dickey

In the meantime, my implementation in ncurses was plagiarized twice:

In contrast to OpenQM, when I noticed that Cristiano De Michele had copied from xterm in developing multi-gnome-terminal in 2002, he apologized and added a comment giving credit for the changes:

 * Cristiano De Michele <>
 * April 2002:
 * enhacements and bug fixings
 * for making zvt compliant with vttest
 * Some code (see vt_clear_line_portion())
 * here has been taken from xterm, the popular terminal
 * emulator developed and maintained by
 * Thomas Dickey <>
 * */


See my note in the xterm FAQ for XITERM. Judging by the release notes, the unattributed copying was from by someone at IBM (another apparent blunder). This issue did not get much attention from Sun: the program (according to comments by Alan Coopersmith in the October 2002 and November 2003 threads) was used as the default “xterm” for some time.

The first newsgroup thread is more interesting to me for a different reason. It is where I first encountered Jörg Schilling. In writing this page, I checked to see whether his plagiarism of ncurses (see xtermcap) was perhaps motivated by some prior encounter. But I found no evidence of that. Our first encounter came in 2002, after his copying from ncurses. That is ironic given his attitude about Solaris versus every other system.

XtInherit fixes

The issues with tparm overlap and bracket an occasion on which I was accused of plagiarism.

To recap, briefly:

Harold's message to David Dawes put the latter into an awkward position, because Harold's tone was hostile, and according to David, private discussion had been worse:

Date: Sun, 26 Oct 2003 16:42:51 -0500
From: David Dawes <dawes@XFree86.Org>
To: devel@XFree86.Org
Subject: Re: Cygwin/XFree86 - Staying or leaving [Was: Re:
        Cygwin/XFree86 Bugs?]

On Sun, Oct 26, 2003 at 12:37:29PM -0500, Harold L Hunt II wrote:
>Michel Dänzer wrote:
>>>Well, you know, XFree86's disregard for offers to help made by
>>>developers that have been with the project for over two years are
>>>certainly part of the problem.
>> Err, this is about bug triage, which you can do just as well as
>> everybody else.
>No, this is about my submitting Cygwin-specific bugs that can't actually
>be assigned to me for committing them, even though I am the "expert" on
>Cygwin/XFree86.  This thread started to point out the hypocrisy of the
>situation and to see what the official response to this was.

When I discussed this with you privately a while ago all I got were
disrespectful and insulting responses.  Now there is more of the same.
As a volunteer myself, I don't have to take this type of attitude from
you or from anyone else.  And I won't.

David Dawes
Founder/committer/developer                     The XFree86 Project
Devel mailing list

I stepped in to point out that Harold's perception of the time involved was not shared, and got Harold's vulgar response.

Harold and I had never met, though he knew who I was, as seen in mid-2002:

Remember, we Cygwin/XFree86 folks are but mere packagers of XFree86 for
Cygwin; none of us work on xterm.  If you have problems with xterm, you
can take them up with the XFree86 project or with Thomas Dickey, the
primary developer of XFree86's xterm:

Harold knew who David Dawes was, having responded to messages forwarded by Alan Hourihane on the cygwin-xfree mailing list about XFree86 releases, e.g., early in 2003:

From  Tue Jan 14 15:14:00 2003
From: (Alan Hourihane)
Date: Tue, 14 Jan 2003 15:14:00 -0000
Subject: 4.3.0 status update
Message-ID: <>

This is what David Dawes wrote about the forthcoming 4.3.0 release.

Harold, Alex, and others. Can you take the time to really test the
current CVS and get patches in now.



----- Forwarded message from David Dawes <dawes@XFree86.Org> -----

Here's a quick status update regarding the 4.3.0 release.

More on background:

Someone (on SlashDot) construed Harold's response as implying that I was abusing a critically ill person. Seeing that, I studied the cygwin-xfree mailing archives for clues which would support that. I found none (no unexplained absences, no requests for reasonable accommodation, etc). Rather than taking Harold's remarks literally, I concluded that Harold simply responded in an abusive manner, using whatever came to mind. We met again on that basis.

In December, I noticed a problem with the cygwin/X files, which were no longer in a build-ready form, and started discussing the problem with David Dawes:

Date: Fri, 19 Dec 2003 06:13:36 -0500 (EST)
From: Thomas Dickey <>
To: David Dawes <dawes@XFree86.Org>
Subject: Re: cygwin/X

On Thu, 18 Dec 2003, David Dawes wrote:

> On Sat, Dec 13, 2003 at 04:47:28PM -0500, Thomas Dickey wrote:
> >I just noticed yesterday that the current fontconfig & related packages on
> >cygwin/X are broken, e.g., that fontconfig itself contains only documentation -
> >no useful code.  The package is dated 28 October.  Were you aware of that?
> No, I wasn't aware of that.  I haven't looked at the cygwin stuff in a while.

The current set of packages that xterm would use for dependencies is
broken, since they rely on dll's that aren't in the release (this applies
to both my own compile as well as the downloaded xterm).  I noticed this
since I was doing some test-compiles.  By downloading from

I was able to get a workable set of dll's.  From reading various things
on the net, I can see this is a known issue for several months (since
July, actually).  I don't _use_ cygwin/X much, but since some of the
contributed fixes were incorrect, have been reviewing it periodically.

Thomas E. Dickey

We discussed this further, and thinking that it would only take a day or two to repair the damage, decided to go ahead and fix it, providing a binary distribution for the Cygwin configuration.

I made some fixes (otherwise the X server would not build).

commit d45adc9641c7d37e61eb327eb9e46f72235f9809
Author: dickey <dickey>
Date:   Mon Dec 22 01:34:20 2003 +0000

    build-fixes (undeclared variable from region-changes)

But I noticed an additional problem:

Date: Sun, 21 Dec 2003 15:15:34 -0500 (EST)
From: Thomas Dickey <>
To: David Dawes <dawes@XFree86.Org>
Subject: Re: cygwin/X

On Sat, 20 Dec 2003, David Dawes wrote:

Some applications (such as xman) do not run.  It's something that Harold
has discussed on email recently:

I'm reading to see whether they actually made it work - since cygwin.rules
says Xt is shared.

Thomas E. Dickey

There was a fix, and I noticed that Harold had committed another developer's change without mentioning how the code got there. In my commit for XFree86, I used the same checkin-comment, so that Harold would be encouraged to discuss this with me:

commit f7b000a8192aaa5aeb2939272965fca808fa4c9f
Author: dickey <dickey>
Date:   Mon Dec 22 21:10:25 2003 +0000

    fixes for _XtInherit on cygwin.

Finally, summarizing both changes, I updated the XFree86 changelog:

commit 8d785559b2edbc020768f3ebfad8392de27233c2
Author: dickey <dickey>
Date:   Mon Dec 22 21:33:53 2003 +0000

    fixes for cygwin (_XtInherit).

As expected, Harold noticed this and immediately posted his comment.

Here is the source code change (using Adam Jackson's Git repository derived from XFree86 CVS):

diff --git a/lib/Xt/Initialize.c b/lib/Xt/Initialize.c
index fa4379987eedce524c2fd02f3c6e68aa19661d42..9ad6522f6633a1af1890c802858b9f336c16cb12 100644
--- a/lib/Xt/Initialize.c
+++ b/lib/Xt/Initialize.c
-/* $XFree86: xc/lib/Xt/Initialize.c,v 3.20 2002/04/10 16:20:07 tsi Exp $ */
+/* $XFree86: xc/lib/Xt/Initialize.c,v 3.21 2003/04/21 16:34:27 herrb Exp $ */
@@ -184,6 +184,66 @@ void _XtInherit()
 #define _XtInherit __XtInherit
+#if defined(__CYGWIN__)
+ * The Symbol _XtInherit is used in two different manners.
+ * First it could be used as a generic function and second
+ * as an absolute address reference, which will be used to
+ * check the initialisation process of several other libraries.
+ * Because of this the symbol must be accessable by all
+ * client dll's and applications.  In unix environments
+ * this is no problem, because the used shared libraries
+ * format (elf) supports this immediatly.  Under Windows
+ * this isn't true, because a functions address in a dll
+ * is different from the same function in another dll or
+ * applications, because the used Portable Executable
+ * File adds a code stub to each client to provide the
+ * exported symbol name.  This stub uses an indirect
+ * pointer to get the original symbol address, which is
+ * then jumped to, like in this example: 
+ *
+ * --- client ---                                     --- dll ----
+ *  ... 
+ *  call foo 
+ * 
+ * foo: jmp (*_imp_foo)               ---->           foo: .... 
+ *      nop
+ *      nop       
+ * 
+ * _imp_foo: .long <index of foo in dll export table, is
+ *                 set to the real address by the runtime linker>
+ * 
+ * Now it is clear why the clients symbol foo isn't the same
+ * as in the dll and we can think about how to deal which
+ * this two above mentioned requirements, to export this
+ * symbol to all clients and to allow calling this symbol
+ * as a function.  The solution I've used exports the
+ * symbol _XtInherit as data symbol, because global data
+ * symbols are exported to all clients.  But how to deal
+ * with the second requirement, that this symbol should
+ * be used as function.  The Trick is to build a little
+ * code stub in the data section in the exact manner as
+ * above explained.  This is done with the assembler code 
+ * below.
+ * 
+ * Ralf Habacker
+ *
+ * References: 
+ * msdn
+ * cygwin-xfree:
+ */
+asm (".data\n\
+ .globl __XtInherit        \n\
+ __XtInherit:      jmp *_y \n\
+  _y: .long ___XtInherit   \n\
+    .text                 \n"); 
+#define _XtInherit __XtInherit
 void _XtInherit()
diff --git a/lib/Xt/Vendor.c b/lib/Xt/Vendor.c
index c1167c6ac8cb7a7b95ef6bb6e002d81494cd9fa0..aa2e7a6d88c0f0f5fa7db29bf7dde39a7740d814 100644
--- a/lib/Xt/Vendor.c
+++ b/lib/Xt/Vendor.c
-/* $XFree86: xc/lib/Xt/Vendor.c,v 1.6 2001/12/14 19:56:32 dawes Exp $ */
+/* $XFree86: xc/lib/Xt/Vendor.c,v 1.7 2002/05/31 18:45:46 dawes Exp $ */
 /* Make sure all wm properties can make it out of the resource manager */
@@ -64,9 +64,11 @@ SOFTWARE.
-#ifdef __UNIXOS2__
+#if defined(__UNIXOS2__) || defined(__CYGWIN__)
 /* to fix the EditRes problem because of wrong linker semantics */
 extern WidgetClass vendorShellWidgetClass;
+#if defined(__UNIXOS2__)
 unsigned long _DLL_InitTerm(unsigned long mod,unsigned long flag)
         switch (flag) {
@@ -82,6 +84,23 @@ unsigned long _DLL_InitTerm(unsigned long mod,unsigned long flag)
+#if defined(__CYGWIN__)
+int __stdcall
+DllMain(unsigned long mod_handle, unsigned long flag, void *routine)
+  switch (flag)
+    {
+    case 1: /* DLL_PROCESS_ATTACH - process attach */
+      vendorShellWidgetClass = (WidgetClass)(&vendorShellClassRec);
+      break;
+    case 0: /* DLL_PROCESS_DETACH - process detach */
+      break;
+    }
+  return 1;
 externaldef(vendorshellclassrec) VendorShellClassRec vendorShellClassRec = {
     /* superclass         */    (WidgetClass) &wmShellClassRec,

Here is my change-log update:

diff --git a/programs/Xserver/hw/xfree86/CHANGELOG b/programs/Xserver/hw/xfree86/CHANGELOG
index 8ee5309a41595d15107602f1b3ba157231e55bcd..4c003aec7dd7bdeb763ebc5e792ddfe9183d5c9d 100644
--- a/programs/Xserver/hw/xfree86/CHANGELOG
+++ b/programs/Xserver/hw/xfree86/CHANGELOG
@@ -1,4 +1,5 @@
 XFree86 (xx December 2003)
+ 699. Fixes to build/run on cygwin (Thomas Dickey).
  698. Warning fixes for gcc 3.3.2 (Marc La France).
  697. Fix file descriptor leaks in xdm (Marc La France).
  696. Fix memory leaks in libFS (Marc La France).
@@ -18399,7 +18400,7 @@ XFree86 3.0a (28 April 1994)
 XFree86 3.0 (26 April 1994)
-$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3045 2003/12/22 14:59:04 pascal Exp $
+$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3046 2003/12/22 17:48:05 tsi Exp $

In the ensuing discussion, Harold began with accusations and demands. However, due to our previous encounter, I had no obligation to Harold.

Because he could only rephrase and amplify his initial message, we were at an impasse, until Eric Anholt politely suggested a resolution. Alan Hourihane offered to make the change (see his message and my followup).

but got the facts awry when updating the changelog. I repaired that.

commit 4eb9e1292a7cb11b5bde28469fb9ac97b7006cc9
Author: dickey <dickey>
Date:   Tue Dec 23 22:21:51 2003 +0000

    no comment

commit 22de7f7cb0402ff94059f16757838e9ce053b122
Author: alanh <alanh>
Date:   Tue Dec 23 20:51:08 2003 +0000

    correction to cygwin fixes

giving this result:

 699. Fixes to build/run on cygwin (Thomas Dickey).  This includes a workaround
      for _XtInherit by Ralf Habacker, needed to run applications such as xman.

If Habacker had wanted the Cygwin/X project to be mentioned in the changelog, he was the only person who could make that request. He did not contribute to this discussion.

A few of Harold's admirers added heat to the discussion, but no light. None of them had read the change which is appreciably longer than twenty lines (Harold's estimate). In the forty-five line comment,

No one who had actually read the change would have any doubt where it came from. Others (who did not read it) could be persuaded by deft vitriol that I had plagiarized the work.

During the discussion, I pointed out to Harold (off-list) a deficiency in his approach, i.e., to take a close look at who was supporting him. I had in mind three individuals, each with different character defects:

None of those was a contributor to either XFree86 or Cygwin/X, aside from being a vocal supporter of Harold.

Back to the theme: plagiarism is something that affects an individual. Cygwin/X was not an individual, nor did it have ideas. The appropriate remedy for organizations is to copyright their work, either collectively or individually and complain about infringement on that basis.

Later, Harold graduated, and was briefly employed by one company and bounced off to another, creating a Wikipedia page to let everyone know where he went. It was deleted a few years later, but can be inspected on the Internet Archive.

The freedesktop repository from which I obtained Habacker's workaround (rather than directly from Cygwin/X's ephemeral repository) is (see Cygwin/X contributor's guide) retained in an unused branch in Git:

commit 74a94933d160fc9b82c5f5e1c895cb52689f3e41
Author: Alexander Gottwald <>
Date:   Thu Dec 11 19:37:33 2003 +0000

    Import changes from xoncygwin

The branch in Git which is used is actually a residue of the bulk copying by Egbert Eich and Kaleb Keithley from the XFree86 CVS, as seen in these commits:

commit 77d281253982e2ebe27430f38b993927d879a005
Author: Egbert Eich <>
Date:   Thu Feb 26 13:35:34 2004 +0000

    readding XFree86's cvs IDs

commit 0efb2e616125953a3773b9b6c9a530ad30ce9bc8
Author: Egbert Eich <>
Date:   Thu Feb 26 09:22:45 2004 +0000

    Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004

commit 036e955dfcc31d3b6c081f84e4f0b85969ccdd12
Author: Egbert Eich <>
Date:   Thu Jan 29 08:08:07 2004 +0000

    Importing vendor version xf86-012804-2330 on Thu Jan 29 00:06:33 PST 2004

commit f81d7ef72c9b4f13e33efa812bed9446657ed003
Author: Kaleb Keithley <>
Date:   Tue Nov 25 19:28:16 2003 +0000

    XFree86 Bring the tree up to date for the Cygwin folks

The XFree86 changelog itself is nowhere to be found. All of the attribution to the XFree86 developers was discarded in 2006:

author          Erik Andren <>           2006-11-04 19:29:49 +0200
committer       Daniel Stone <>             2006-11-08 15:29:15 +0200
commit          96f78e3886791b723ccd9ba40bea701603537b0c (patch)
tree            4f641e8d4c490f93650a67d5087bf7ab3de19148 /hw/xfree86/doc/changelogs/CHANGELOG
parent          5a40448f2d0ac2c86c617bebe3fb649174bf0d7f (diff)

remove XFree86 changelogs (bug #7262)
Without being able to tie these to specific commits, the text changelog is
useless, as well as being huge.

tparm, revisited

The most recent version of X/Open Curses (Issue 7) was published October 28, 2009. I happen to have a final copy from July of that year, because I participated in the review. It describes tiparm in detail (well beyond the information which I provided):

Application Usage: tiparm and tparm

I had pointed out that the mixture of long and char* used by tparm was not really portable, and Geoff Clare proposed tiparm as a replacement. The X/Open Curses specifically says that the terminal capabilities which correspond to strings should not be used with tparm, and that tiparm should be used instead. The document's editor exceeded my expectations.

The problem comes about from other developers, e.g., those developing NetBSD's implementation of curses and terminfo. Some copy from ncurses, noting in the commits that they are implementing "SYSV curses".

Others document some things, but not others. I noticed this commit:

commit ba3282ab6d8d163de7b290a7f7c20749642e5e0b
Author: roy <>
Date:   Mon Oct 3 12:31:51 2011 +0000

    Correctly use ti_ instead of t_ for our extensions as per the man page.
    Replace vtparm with tiparm.
    tiparm is also non standard, but has been proposed at least.

and reading the corresponding manual page (terminfo.3) see neither a note that it was actually approved and published (three years earlier), or copied from ncurses. One of those possibilities should be documented.

Either way, there are pitfalls in maintaining these functions. In April 2023 (another ten years forward), I made security-relevant changes to tparm and tiparm in ncurses.

NetBSD terminfo is subject to the same problems, because it was based on the design from ncurses. Part of that is because the developer did not clearly understand the design from the outset, and therefore did not see the places where it might be improved.


The dispute between Cygwin/X and XFree86 in 2003 involved a one-line entry in a changelog regarding the addition of 80 lines (more than half comments or whitespace) to a library with forty-four thousand lines of code and comments.

Our roles were reversed in mid-2010 when developers copied more than two thousand lines of changes from work which I had done on luit, deleting the changelog which detailed the changes, and dismissing my work as janitorial cleanups. That was more than a little unfriendly, but something that I should have kept in mind when dealing with developers, as you might understand by reading the mailing list archives a year before.

Up until that point, I was uncertain how I should mark my copyright on luit, because I had not calculated the percentage of change, etc. Typically I start copyright notices when I have changed twenty percent of a file. Some others use much lower thresholds, and then there are others who abuse copyright notices in other ways.

Keeping all of that in mind, I spent my time more productively by developing a new version of luit which would have no dependencies upon sources. I copyrighted that, of course.

I started my page on change-logs at this point (September 2009), although it would have been topical earlier, e.g., in 2003:


After the encounters with Jörg Schilling in 2002 and 2003, there were others of note. For instance, in the 2004-2005 comp.os.solaris thread which led me document issues with Solaris Systems Programming, Schilling played a minor role. Some of it was pointless (for instance his praise of Bill Joy, whom he despised on other occasions as “Sun's first employee”), because of his pro-German bias. But for the most part, it consisted of attacks on Linux developers, e.g., those involved with cdrecord. Schilling was not the only person of interest. See for example:

in one case giving poor advice, and in another blaming me for work done by others.

But seriously, I looked up “self-deprecating” thinking at first that Schilling had meant to say “self-discrediting” before recalling his bias.

In 2011, Yuri Pankov asked me for my response to Schilling's comments about the ncurses terminal database:

Date: Wed, 20 Jul 2011 16:31:51 +0400
From: Yuri Pankov <>
To: Thomas Dickey <>
Cc: Gordon Ross <>
Subject: Re: [illumos-Developer] A question about license for terminfo.src
        (Was: Re: webrev for 294, 1149)

On Wed, Jul 20, 2011 at 04:05:39AM -0400, Thomas Dickey wrote:
> On Tue, 19 Jul 2011, Gordon Ross wrote:
> > Thanks, Thomas.
> >
> > Yuri, perhaps you could find a suitable MIT copyright from some version of
> > this and put it in our THIRDPARTYLICENSE file or whatever?  (The file in
> > each source directory where we put the copyright and license text.)
> >
> > Thomas, can you point us to a suitable MIT copyright for this?
> There's lots of copies of the ncurses license in the source code...

Thanks Thomas,

and sorry for bothering you. One more question though, could you please
comment on the Joerg Schilling's reply about termcap/terminfo sources:

Is it something we should care about?


Schilling was commenting about termcap only (he had neither interest or expertise in terminfo). I had been mechanically generating termcap from the ncurses terminfo source for several years after completing the work that Eric Raymond had begun in 1995. While Schilling said there were hundreds of errors, there actually were only a few problems in the translation. I fixed those later that week (July 23, 2011):

        + improve generation of termcap using tic/infocmp -C option, e.g.,
          to correspond with 4.2BSD (prompted by discussion with Yuri Pankov
          regarding Schilling's test program):
          + translate %02 and %03 to %2 and %3 respectively.
          + suppress string capabilities which use %s, not supported by tgoto
          + use \040 rather than \s
          + expand null characters as \200 rather than \0

That done, I was not finished. It occurred to me that there were different termcap implementations, and that they might not behave identically. I developed an application tctest and documented the different implementations which I knew about. I included Schilling's termcap variation, which turned out to be the least robust. There is a patch shown in my webpage on the topic which addresses this.

But there is more. Schilling's comment concludes with

To verify my statements:

-       get recent schily tools

-       compile

-       run the program "termcap" (a termcap compiler) with:

        termcap if=filename > newcap

filename is the name of a file to parse and to compile
newcap is the output file that contains comments with
hints to repaired bugs and to unrepairable bugs.

I investigated that, finding that it offered me no insight into termcap syntax. However, half of the program was copied from ncurses, as I noted here:

However, I did not incorporate any aspect of Schilling's test-program into
tctest.  It was not useful.

On the other hand, Schilling used ncurses in his test program.  It consists of
two files (cap.c and caplist.c).
Schilling copied the latter from ncurses 5.2 source code: include/Caps:

going on, to describe the copying.

Seeing that, I added Schilling to my plan for this page. There are other interesting stories to tell; I have only documented a few:

Here are some potential topics for which I have notes:


Some developers do not bother with change-logs. Bram Mooleanaar's release notes for vim did not detail the changes, only telling what the entire program did. Since he first started using use source-archives late in 1999, this made it difficult to determine what was done, and who actually did the work. Reading the vim mailing lists and the comp.editors newsgroup helped.

That said, I cited Bram several times on my ncurses and xterm change-logs, for ideas and requests for features. He made one small change to xterm in 2004, making its usage message write to the standard output rather than to the standard error. That was not reciprocated (there are exactly two mentions of xterm with my name in the documentation, none in the commit logs, versus 51 cites in those two change-logs). Nor did we ever discuss vile (vi-like-emacs).

Some of our discussion did not lead directly to a fix or feature change in ncurses or xterm. On one occasion, Bram asked for more documentation:

Date: Fri, 11 Oct 2019 11:02:15 +0200
From: Bram Moolenaar <>
Subject: Re: Prefixing a key when Meta is pressed

Thomas -

> > With patch 8.1.2135 I added the basics of the implementation.  It is not
> > enabled by default  That can be done with:
> >
> >     let &t_ti = "\<Esc>[>4;2m"
> >     let &t_te = "\<Esc>[>4;m"
> >     silent !echo
> >
> > The "silent !echo" is not needed when doing this on startup.
> > I can now map <C-Space> and a few other things works.
> > However, mapping <C-H> does the opposite: it maps the Backspace key and
> > not Ctrl-H.  That's a Vim problem.
> yes... the reason why I decided to make a table was to make it more
> apparent how the special keys would be handled.  Basically xterm's
> passing back the key event data (after some filtering/transforming
> which a table and the generating script would make more apparent).

I would like to see that table.

One thing I noticed was using CTRL-A (thus CTRL-Shift-a) result in
getting the CTRL and SHIFT modifiers and an upper case A.  That is a bit
strange, since the SHIFT is already included in the letter A.

> > I also added support in libvterm, so that I can do some debugging.
> > That's a bit tricky, since modifyOtherKeys has to be enabled in the Vim
> > instance, where the debugger runs, the Vim instance running in the
> > debugger, and the Vim instance running in a terminal in the debugged
> > Vim.  Yeah, that's confusing :-).
> mostly I use debug-logs (finding it simpler to study a log than
> single-step with gdb).

I do that sometimes, but it requires adding a lot of log statements (and
remembering to remove them again).

- Bram

Permission is granted to read this message out aloud on Kings Cross Road,
London, under the condition that the orator is properly dressed.

 /// Bram Moolenaar -- --   \\\
///        sponsor Vim, vote for features -- \\\
\\\  an exciting new programming language --        ///
 \\\            help me help AIDS victims --    ///

On this occasion, I wrote another webpage XTerm – “Other” Modified Keys about the origin of the features in xterm for passing modifier information of keys to an application. The page gives the table that Bram wanted to see, along with the script which I wrote to generate the tables.

Because Bram was in the process of getting libvterm to work with vim, he had course been exposed to Paul Evans' version of the facts. They are slightly skewed off. Referring to his webpage entitled “Fix Terminals – Please” I see several issues:

The variant presented as an innovation could be expressed as a single line of code. To make it clearer in xterm, I implemented that as a short function (shorter than the comment which Ralf Habacker wrote):

 * Function-key code 27 happens to not be used in the vt220-style encoding.
 * xterm uses this to represent modified non-function-keys such as control/+ in
 * the Sun/PC keyboard layout.  See the modifyOtherKeys resource in the manpage
 * for more information.
static Bool
modifyOtherKey(ANSI *reply, int input_char, unsigned modify_parm, int format_keys)
    Bool result = False;
    if (input_char >= 0) {
        reply->a_type = ANSI_CSI;
        if (format_keys) {
            reply->a_final = 'u';
        } else {
            reply->a_final = '~';
        result = True;
    return result;

A few days later, Bram continued that email thread, commenting

Date: Sat, 02 Nov 2019 18:13:40 +0100
From: Bram Moolenaar <>
To: Thomas Dickey <>
Subject: Re: Prefixing a key when Meta is pressed

Thomas -
> > >
> > > Looks useful.  The background images are a bit distracting.
> ...
> here's something more complete:
> I have some work to do on the manpage and ctlseqs files to (try to)
> clarify some points.

Thanks, interesting history.  I didn't realize that Paul Evans was
already working on this stuff in 2008.  Also confirms that he has a bit
of a strange look on things, adding another key encoding, arguing it's
"much nicer".  And then forgetting to document how it works...  I
haven't verified it, but in the code it looks like his implementation
doesn't use Alt and uses the Esc prefix instead (which then causes the
timing problem).

- Bram

Not everyone conceded that I had documented the feature better than Evans. For example, in tmux #2669, Nicolas commented:

Nobody has really documented the keys well. xterm has a page on their variant
here and the alternative
form is documented here

However, Bram and I occasionally discussed this area as well as others for ncurses and xterm. He started a new discussion in October 2022:

Date: Mon, 17 Oct 2022 17:11:49 +0100
From: Bram Moolenaar <>
To: Thomas Dickey <>
Subject: Kitty keyboard protocol

Thomas -

A few Vim users asked about supporting the kitty keyboard protocol.
It's like an advanced version of modifyOtherKeys.

Have you been contacted about it?  I wonder what your opinion is.

I thought it would be OK to enable with the TI and TE codes, like we do
for modifyOtherKeys.  But they suggested (or insisted) to first send a
request for whether the protocol is supported, and if the reply
indicates so only then enable it.  I told them that this is inconvenient
and rather enable it based on the termresponse value.  Or that they
implement modifyOtherKeys, since that is already more widely supported.
But that's where the discussion stopped.

One reason for the kitty protocol that was mentioned is supporting the
Cmd key on Mac.  I suppose xterm isn't used (much) on Mac, but perhaps
that keyboard can also be used on other systems.

There are few terminals and apps that support this kitty protocol, and
considering their attitute about using it I won't expect it will spread
quickly.  Wezterm is another one, first time I heard about it.

There was also mention that it was so great that the Esc key produces an
escape sequence, thus avoiding the need to have a timeout when a Esc is
received.  Somehow they didn't bring up 8-bit encoding (I also didn't
want to give away that obvious solution).  They appear to have a bit of
a one sided "my solution is the only good solution" view.

- Bram

My Go, this amn keyboar oesn't have a .

 /// Bram Moolenaar -- --   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- ///
 \\\            help me help AIDS victims --    ///

Calling it “like an advanced version of modifyOtherKeys” was stretching the point.

Date: Tue, 18 Oct 2022 12:02:03 +0100
From: Bram Moolenaar <>
To: Thomas Dickey <>
Subject: Re: Kitty keyboard protocol

Thomas -

Thanks for replying.

> > A few Vim users asked about supporting the kitty keyboard protocol.
> > It's like an advanced version of modifyOtherKeys.
> >
> > Have you been contacted about it?  I wonder what your opinion is.
> no.
> Looks like just a different way of encoding the same information.
> (add a few more modifiers, for the 12-fingered hackers...)
> Like modifyOtherKeys, with the same pitfall: the key-symbols that can
> be used depend on the keyboard configuration.

Yes, it has some small advantages that probably help few people.  It's
an interesting idea to send the Esc key as an escape sequence to avoid
ambiguity.  But as I explained to them, we have to deal with it anyway
because of how most terminals work.  And kitty only does it after
enabling, which may take a little while.

>From your reply I gather you have no plans to support the kitty
protocol, right?

agreeing with his conclusion

> >From your reply I gather you have no plans to support the kitty
> protocol, right?

right (it's not a priority - perhaps some user will offer a patch,
though it seems that most of those involved with stuff like this
aren't inclined to be constructive).

and we moved on to more productive issues of keyboard encoding.

Bram dropped the focus on kitty, widening it to keyboard protocols:

Date: Mon, 21 Nov 2022 00:04:00 +0000
From: Bram Moolenaar <>
To: Thomas Dickey <>
Subject: Re: Keyboard protocols

Thomas -

I recently made the libvterm copy that's in Vim work better, it now
produces the same codes with modifyOtherKeys level 2 as xterm, at least
for the keys I tried it with.  Makes it easier for me to debug the key
codes (I run gdb that starts Vim in a terminal window that's using
libvterm inside a running Vim).

> xterm does support the CSI u flavor, as I pointed out in

Vim understands both, and they contain the same information.  Thus it
doesn't really matter if the keys are encoded one way or the other.

Soon I'll add the kitty keyboard protocol, so I can try that out too.
I don't expect it to be complicated.  And we'll see how Paul Evans
reacts to that...

- Bram

>From "know your smileys":
 :-*    A big kiss!

 /// Bram Moolenaar -- --   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- ///
 \\\            help me help AIDS victims --    ///

His mention of Paul Evans was because Kovid's page on the topic borrows heavily from Paul Evans' page, amplifying all of its problems without providing any benefit.

color stack

In responding to one of Bram Moolenaar's questions about keyboard protocols, I noticed an unrelated problem on Kovid's website:

Date: Fri, 25 Nov 2022 04:20:17 -0500
From: Thomas Dickey <>
To: Bram Moolenaar <>
Cc: Thomas Dickey <>
Subject: Re: Keyboard protocols

On Thu, Nov 24, 2022 at 10:29:06AM -0500, Thomas Dickey wrote:
> On Thu, Nov 24, 2022 at 02:12:38PM +0000, Bram Moolenaar wrote:
> >
> > Thomas -
> >
> > > > Anyway, for making Shift-Escape work I guess it needs to be added below
> > > > the "case XK_Return":
> > > >
> > > >                 case XK_Return:
> > > >                 case XK_Escape:
> > > >                 case XK_Tab:
> > > >                     result = (modify_parm != 0);
> > > >                     break;
> > >
> > > ok - added this to input.c and updated to match.
> >
> >
> > Thanks.  I assume the next version will have Shift-Esc working then.
> > Would that be version 377 ?
> yes ("soon", because I have fixes for a couple of bugs)
> I'm working on the newer query controls now, and will add in a few items
> from my backlog, but intend releasing 377 today or tomorrow.

...still on track for that (in testing this morning, found another hole in
one of my fixes).  Yesterday, I added two new sets of controls, to retrieve
the state information for the modified-keys feature and for the group of
"allowXXX" features.  The latter are (intentionally) set only via resource
or menu-action (and that only when SendEvents is off).

The "allowXXX" feature is best done using names, so that pointed me to
implementing it with OSC.  Since several programs have their own quirks
with OSC's, I did a quick check for conflicting codes, and came across

which is untrue.  On investigating, I see that Kovid implemented a push/pop
for the current colors in 2018 using DCS, and then changed it to OSC in 2021,
at the time that he made this webpage, with the comment about xterm.

I added the sgr-stack feature also in 2018, which pushes/pops colors, but
intentionally limited that to the current colors, since it pushes/pops only
the attributes specified.

That's not useful for managing the 256-color palettes, and (you've probably
also seen) some users prefer one version of Solarized on the command line,
and a vim theme in the editor.  I resolved that in 2020 with another control,
for managing the color palettes.  In that, the current colors (which Kovid
refers to as the dynamic colors) came along for consistency.

Since he doesn't document things systematically, I only noticed this during
this week.  The keyboard protocol page has similar issues, but at the moment,
I don't see a need to address either on my webpages.

> > The changes to also support the kitty keyboard protocol are mostly done.
> > Now awaiting users to complain about any problems.  I also made some
> > improvements for how modifyOtherKeys is used and updated the help.

Thomas E. Dickey <>

Bram was not very interested in pursuing this (since his interest in color schemes was solely for vim). However, since the page stated

In July 2020, after several years, XTerm copied this protocol extension,
without acknowledgement, and using incompatible escape codes (XTPUSHCOLORS,
XTPOPCOLORS, XTREPORTCOLORS).  And they decided to save not just the dynamic
colors but the entire ANSI color table.  In the interests of promoting
interoperability, kitty added support for XTerm’s escape codes as well, and
changed this extension to also save/restore the entire ANSI color table.

I added it to my plan for this page.

Readers knowledgeable about the technical area may find it bizarre, but those familiar with Kovid Goyal likely will have a different reaction.

In short, Kovid accused me of plagiarism. The facts do not support the accusation.

Stacks in programs predate my use of them, as well as likely preceding Kovid's existence. I have designed and implemented more than one control sequence for xterm which uses a stack:

Occasionally someone suggests (I am one of those) that the alternate screen feature of xterm could be done better as a stack. There are pros and cons about that, which would be a distraction from this topic.

In the instance of the color-stack, the motivation went back several years, before Kovid began developing kitty in October 2016.

Kovid referred to these features in XTerm Control Sequences. I gave them names, which is simpler than typing the escape sequence, and encoded them using CSI because that fits with the convention used by other controls:

Kovid ignored these related features (from SGR-stack):

Kovid probably ignored the SGR-stack features because they are more complicated than the color-stack features. If he had examined them, he would have undoubtedly added another paragraph accusing me of plagiarism for the special case where it saves and restores the foreground and background color.

The SGR-stack feature was initiated by Dan Thompson in three emails starting June 9, 2018:

Date: Sat, 9 Jun 2018 17:28:27 +0000
From: Dan Thompson <>
To: Thomas Dickey <>
Subject: xterm: SGR control sequences: method to do push/pop?

I've got a question about Control Sequences, specifically regarding Select Graphics Rendition (SGR).

I've been writing code that emits text that contains SGR control sequences to colorize it. However, I've found that my text is not easily composable--that is, I may have a format string like "The name is: %s, the position is: %s", and then I want to sprintf some inserts into that. Then that whole string I may want to insert into another, and so forth. The problem is that to have SGR sequences in that one has to have sort of a global awareness of content and associated coloring for that to work out.

What I'd *like* to do is have some sort of push/pop mechanism for the SGR settings, so that I could have strings like:

    <fgBlack>   : CSI 3 0 m
    <fgGreen>   : CSI 3 2 m
    <fgYellow>  : CSI 3 3 m
    <fgMagenta> : CSI 3 5 m
    <fgWhite>   : CSI 3 7 m
    <bgBlack>   : CSI 4 0 m
    <bgYellow>  : CSI 4 3 m
    <bgWhite>   : CSI 4 7 m
    <pushSgr>   : CSI ??? m
    <popSgr>    : CSI ??? m

    name = "Dan <pushSgr><fgBlack><bgWhite>Thompson<popSgr>"
    position = "<pushSgr><fgMagenta><bgYellow>Developer at Large<popSgr>"
    line1 = "<pushSgr><bgBlack><fgWhite>The name is: %s, the position is: %s<popSgr>"

And then be able to do printf(line1, name, position), and have it all work out.

Without a push/pop mechanism, composing strings like that cannot be done that way at all, unless you do your own custom rendering pass to handle the pushes and pops.

He followed up with a patch on June 14, and an update on June 22. Just saving and restoring all of the video attributes was not interesting to me, so I modified it to allow for selecting the attributes to be saved by parameters. If this had come after the color-stack feature, I probably would have used consistent parameters for the two features. But because of my changes, it is possible to save and restore the foreground and background colors without the other attributes, like this (using the same convention as Kovid's page):

<ESC>[#30;31{        # push foreground and background colors
<ESC>[#30;31}        # pop foreground and background colors

Thompson's patch made the feature SGR 66 and 67, which (ignoring subparameters) did not fit in with my improvement. I used curly braces for the final characters to make the feature easier to read. Thompson did not like the curly braces because he found it inconvenient in C#, although the Microsoft documentation shows it would be simple. At the time, that documentation was not readily available, so I added aliases for the feature:

For reference, here are sample scripts which I wrote to test and demonstrate the three stack-related features of xterm:

and here is an illustration of solarized and other themes using the color-stacks feature:

Example of color-stack (

Unresolved issues

Not all of these issues are in the past.


This is still (after more than twenty-five years) an issue as new developers come to invent this method of detracting from others' work. After all, there is no point (for some) in improving one's resume unless they can do this by taking it away from someone else.

You can see this issue by the way changes are documented – or not. Several examples are mentioned in my page on bracketed-paste.

Continuing the previous section, Kovid is among several developers who practice this methodology. e.g., this change referring to the xterm title-stack feature:

commit 3067103b188c55d594918d1525d397cb523f8fea
Author: Kovid Goyal <>
Date:   Wed Aug 29 09:56:52 2018 +0530

    Implement window title stack

    Used by new versions of vim

This was one of several attempts by Kovid to make kitty imitate xterm well enough that Bram would be forced to do the remaining work to accommodate kitty as a slight variation on xterm. Bram was neither convinced, nor treated well by Kovid in their encounters, e.g., this:

After 9.0.1080, &tgc doesn't work in kitty #11729

As one might guess, I have also encountered Kovid. At one point, Kovid claimed to acknowledge my work:

commit 952aa7ad4ada9ec46fe023ac7cbedfc2b3ab518c
Author: Kovid Goyal <>
Date:   Tue May 23 20:27:51 2017 +0530

    A tribute to Thomas E. Dickey

but later (silently) removed that

commit f87d62571bcf58f0b72c0181d340eccebded026e
Author: Kovid Goyal <>
Date:   Fri Feb 23 09:13:20 2018 +0530

    Add links to relevant parts of the README in the major features list

shortly after this discussion on bug-ncurses:

   From:  Kovid Goyal <>
Subject:  Request for new terminfo capability (DECCARA extended)
   Date:  Wed, 7 Feb 2018 08:23:48 +0530

As the developer of a library supporting many types of terminals, I will not spend time writing specialized code to support one. Kovid's interactions with other developers generally are exploitative. When thwarted, he responds.

Kovid came back, having arranged with someone else to act as his agent:

   From:  Igor Urazov
Subject:  Request for inclusion of new xterm-kitty terminfo
   Date:  Thu, 6 Sep 2018 16:13:16 +0300

Notwithstanding his comments about the FAQ, Kovid had only read the parts that he was interested in. This one is a good starting point:

Why not just use TERM set to “xterm”?

Change Logs

By sheer coincidence, I found that revisiting mawk after seven years has some relevance to this page's discussion of change-logs.

Mawk's README has some rather hostile remarks pointed at me:

In my absence, there have been other developers that produced mawk 1.3.4-xxx.
I started from 1.3.3 and there is no code from the 1.3.4 developers in
this mawk, because their work either did not address my concerns or
inadequately addressed my concerns or, in some cases,
was wrong.  I did look at the
bug reports and fixed those that applied to 1.3.3

While I was aware that the comment about Mike's concerns was misleading (and addressed that in 2016), I did not notice that the disclaimer that “there is no code from the 1.3.4 developers” was also untruthful. I discovered that in July 2023 while analyzing this bug report:

        + use da_string more consistently in dumps.
        + improve scanner to some type-checks of arrays versus scalars by
          deferring this into the runtime execution (report by Rajeev V Pillai).

Rajaeev gave an example in email, and mentioned some variations. I made some modifications, e.g., replacing an environment variable with a literal string to make it suitable for regression testing.

# Subject: Re: mawk 20230525: var-type confusion
# On Sun, Jun 04, 2023 at 07:27:26AM +0000, Rajeev V. Pillai wrote:
function xdelete(a,     i) {
        for (i = 1; i <= length(a); i++) {
                printf "deleting %d:%d %s\n", i, length(a), a[i]
                delete a[i]
        #for (i in a)
        #       delete a[i]
        print split("/usr/sbin:/sbin:/usr/bin:/bin:/usr/games", a, /:/)
        print length(a)

I tested Rajeev's example with gawk, original-awk, mawk 1.3.3, 1.3.4, and, finding that it failed with both 1.3.3 and 1.3.4 (so the problem was not a regression due to my changes). The failure occurred at the parsing stage:

mawk: raj_array.awk: line 5: illegal reference to local variable a
mawk: raj_array.awk: line 6: illegal reference to local variable a
mawk: raj_array.awk: line 14: type error in arg(1) in call to xdelete
mawk: raj_array.awk: line 15: illegal reference to array a

However, since it worked for, I next examined the output from mawk's assembly-language dump.

As expected, there were some differences, though the numeric-offsets between the two dumps make it hard to read. Part of that was due to my formatting change to add a column of dots (separating the offsets from the mnemonics). To help eliminate that nuisance, I made a copy of, and edited da.c to make this cosmetic change.

At that point, I noticed that Mike's version of that file had a function function named visible_string, while mine had the same function (except for that line) but named da_string. Curious about that, I checked my source archive and found that I had written that function in 2009 as part of my fixes to allow RS to contain an embedded null. It certainly was not in mawk 1.3.3 (disagreeing with the disclaimer in the README file).

That gave me something to think about. In the meantime, I was curious how Mike had solved the problem of the ambiguous forward reference to the length function. I proceeded by applying changes from 1.3.4 to this copy of, to reduce the total difference to review. In that process, I found additional borrowing from my work. Reviewing the result, there were four commits in which I noticed the borrowing, and noted it in the check-in message. Now these are fairly small, but undeniable borrowing from my work which Mike said he did not do.

There also was the comment header, which says

Mawk is distributed without warranty under the terms of
the GNU General Public License, version 3, 2007.

If you import elements of this code into another product,
you agree to not name that product mawk.

Actually that is contradictory, but I get the point. Mike was again addressing me.

If it were not for that README file, Mike would get better treatment. However, I have my own policy regarding that, dating back to 2009. In this case, I adapted Mike's changes.

Continuing, I pinpointed the relevant code, and could see how to adapt the idea. Considering the situation, I decided to acknowledge the idea on this page, explaining why a direct borrowing from Mike's version was unsuitable. If Mike wants to discuss this with me, he will have to be polite and accurate.

The license is based on copyright, which essentially limits it to prohibiting literal borrowing. It is not a patent, which would protect the algorithm. I used the algorithm, and eliminated literal borrowing.

I preferred not making the bug-fix, but without that, mawk was not able to get to the test-cases which I added to validate the new feature.

While developing the test-cases, I found another case of ambiguous length which Mike's change did not handle, and spent some time working on a solution for that.

In the meantime, I had targeted completing this page in August 2023 for various reasons. Therefore, I put aside the work on mawk, expecting to resume on mawk after some maintenance on xterm.