Skip to content

About

A modern restoration and port of the historic, object-oriented C++ application framework originally released in 1991.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ET++ 2.2 Restoration

A modern restoration and port of the historic, object-oriented C++ application framework originally released in 1991.


📖 About ET++

ET++ is a pioneering, window-system-independent application framework developed in the late 1980s and early 1990s at UBILAB (Union Bank of Switzerland Informatics Laboratory) by André Weinand, Erich Gamma, and Rudolf Marty.

While today the library is mostly known as the system mentioned as an example of an application framework in "Design Patterns: Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson, and Vlissides, my interest in the library comes from the details of its implementation, such as its elegant reflection system which in turn enabled serialization and persistent storage of objects, and neat features built into the development environment such as the object inspector and class browser. In fact, just having the development environment built into the development version of your application is a neat feature.

Following the release of 2.2, development continued, eventually resulting in MET++, a multimedia-focused evolution of ET++, which is, as far as I can tell, lost to the Internet. MET++ was supposedly based on version 3.0, but the history here becomes hard to follow.

One prominent public application of the ET++ framework was the SNiFF+ IDE, a powerful C++ IDE for software development and browsing. SNiFF+ was used by Taligent (the Apple/IBM/HP joint venture) during the development of their CommonPoint application frameworks, providing a tangible technical thread from ET++ to one of the most ambitious object-oriented platform efforts of the mid-1990s. In the end, Taligent failed and was ultimately folded into IBM products. Today, Taligent is mentioned as one of two sources of inspiration for Google's Project Fuchsia (the other being Apple's Project Pink). SNiFF+ survived into the early 2000s and was distributed with SuSE Linux in shareware form supporting C/C++, and sold by Wind River with support for other languages.


🛠️ The Restoration & Modernization

The goal of this project is to restore the legacy ET++ 2.2 codebase (October 1991) so that it builds and runs on modern systems. For now, NetBSD and Linux are supported.

The original code was written in C++ 2.0, which was quite a different language from modern C++ (or C++98, for that matter). The code was written on SunOS 4.x, which is now ancient history, so it relied on the tools, conventions, and OS of that time.

One additional peculiar thing about the code is that it used braces, tabs, and newlines very sparingly. This made the code extremely hard to read and editing error-prone. I have converted any single statement following a conditional or loop into code blocks and added newlines and indentation matching the logical structure of the code. As a consequence, while the overall design of the library is unchanged, almost no line of the original code was left untouched.

The work was done in a few iterations: starting with resolving build system issues, moving to incompatibilities in the C++ language, adjusting code to modern system interfaces, and finally fixing bugs that arose from assumptions in the original code about pointer size and byte order.

Most of the work was done on NetBSD 10.1, so BSD make was used. As NetBSD is a closer cousin of SunOS, this also made the initial work easier since some system interfaces absent from Linux were present in NetBSD.

During restoration AI was used occasionally to provide hints and for investigation of old APIs and system interfaces, but the vast majority of the work was manual. Scripts man_to_pdf.sh and man_to_md.sh are product of interrogating LLM.

All bugs I've found were fixed, though I didn't use library much. Some of those were probably introduced during the restoration while it's possible that I did some drive by fixes of old bugs.

List of changes, in the approximate order they were made:

  • Build System and File Layout
    • The original src/makefile was renamed to the now more common Makefile.
    • The configuration system from the original file was extracted to Makefile.conf, and common rules repeated across Makefiles were extracted to Makefile.inc and Makefile.head.
    • The original code used makedepend from the X Consortium (present in the utils/makedepend directory); this was replaced with the version of makedepend present in NetBSD pkgsrc. This was later changed to BSD mkdep as makedepend is not readily available on Linux.
    • The dependency generator was instructed to write to files named Makedepend instead of Makefiles to avoid churn in version control. The Makefiles were adjusted accordingly.
    • File extensions were changed from .C and .h to .cpp and .hpp for C++. For C files, .c and .h were kept as-is. This required editing all #include directives.
    • The Makefiles were modified for out-of-tree builds.
  • C++ Language Issues
    • C++ 2.0 did not support multiple inheritance. The later addition of multiple inheritance changed the syntax of the language to require the name of the base class to be stated when passing parameters to base class constructors. This, in turn, broke the MetaDef and MetaImpl macros in Class.hpp used to provide reflection features in the library. With those macros adjusted for modern C++, all constructor implementations and calls to MetaImpl for each class had to be fixed.
    • cfront 1.2 allowed naming conditional blocks on the #endif line, like #endif Class.cpp, so this had to be commented out in all header files.
    • The original code included some conditional code for ancient versions of GCC, which had to be commented out so as not to interfere with modern GCC.
    • C++ 2.0 did not have a bool type, so TRUE/FALSE macros were used. These were replaced with the modern bool type and true/false throughout the code.
    • Modern C++ requires that string constants be passed around as const char* rather than char*, so those had to be added throughout the code.
    • Uses of the old style of naming parameters in function implementations were removed.
    • Deprecated register declarations were removed.
    • Some bugs appeared in the transition from 32-bit to 64-bit systems. Most of these were caused by the use of a literal zero for null pointers and were visible only on NetBSD systems due to different handling of parameters for variadic functions. These were fixed by replacing the literal zero with nullptr.
    • One artifact from cfront days encountered was the ability to assign to this and check whether this was valid within methods.
  • X System
    • Surprisingly, only one fix was needed to make the X11R5 code run on X11R7. The old code had support for storing approximated colors on pre-TrueColor displays, which is not allowed with modern X servers by default.
    • The only place where special handling of big-endian data was required was in rendering images that were precompiled on SunOS on SPARC.
  • Operating System
    • Legacy pseudo-terminal (PTTY) logic was updated from the ancient BSD sgtty (gtty/stty) to the standard POSIX termios.
    • For Linux and NetBSD, the custom SunOS dynamic loading of a.out shared format implementation was replaced with standard ELF loader <dlfcn.h> library calls (dlopen, dlsym).
    • Replaced deprecated global errno usage with strerror.
    • Removed session logging code that tried to write to utmp and wtmp. On modern systems, this would require running applications as root.
  • Misc
    • Updated the fonts Makefile to compile fonts to the PCF format used by modern X11 instead of SNF.
    • Produced documentation in PDF and Markdown formats from the original set of man pages (still present).

📂 Repository Structure

  • src/ - The core ET++ library source code.
    • MALLOC/ - Custom debugging memory manager.
    • XSERVER/, NEWS, SUNWINDOW & SUNSERVER - display server interfaces.
    • POSTSCRIPT/, PIC & PICT - printer interfaces.
    • LINUX/, NETBSD/ & SUNOS - Platform-specific system backends.
    • PROGENV/ - Built-in runtime programming environment (Inspector, Class/Method Browsers).
    • IO/ - Custom stream library implementation (istream, ostream, streambuf, filebuf) modeled after AT&T cfront 1.2 streams, which were later standardized into the C++ Standard Library.
  • applications/ - Rich collection of example applications showing the power of the framework.
    • calculator/ - Scientific and programmers calculator.
    • desktop/ - A graphical desktop environment.
    • draw/ - A vector graphics editor.
    • filebrowser/ & filebrowserII/ - Directory tree and file viewers.
    • miniedit/ - A rich text editor.
    • typescript/ - A terminal/shell wrapper window.
    • hello/ - The classic minimal ET++ application.
  • doc/ - Documentation assets.
    • doc/markdown/ - Class-by-class and method-by-method manual pages in Markdown format.
    • doc/reference_manual.pdf - High-quality PDF Reference Manual.
    • doc/screenshots/ - Screenshots showing ET++ applications running on modern X11.
  • fonts/ & xfonts/ - Font BDF sources and utilities for X11 PCF font generation.

Of the display servers, the code for NEWS, SUNWINDOW, and SUNSERVER is not modernized, as they are not viable on modern systems. For printer interfaces, only the source for POSTSCRIPT is modernized. I may modernize PIC (the driver for troff using pic). PICT contains the source for the Macintosh PICT format, so it will be left as-is.


🚀 Building & Running

Prerequisites

To build and run ET++, you need:

  • A modern C++ compiler (g++ / gcc)
  • BSD make (bmake on Linux, make on NetBSD)
  • X11 development headers (on Debian/Ubuntu: libx11-dev and libxcb-dev)
  • Font utilities (on Debian/Ubuntu: xfonts-utils / bdftopcf and mkfontdir to compile BDF fonts)

Compilation

  1. Generate Dependencies:

    bmake depend
  2. Build the Library and Applications:

    bmake
  3. (Optional) Compile and Register Fonts: If you want to compile and load the custom ET++ bitmap fonts into your X server:

    bmake fonts

    This will make applications appear a bit nicer.

Running the Demo Applications

The library comes with 22 demo applications. The compiled executable files are placed in the build/applications/ directory. You can run them directly in your X11 session:

# Run the Hello World demo
./build/applications/hello/hello

# Run the FilebrowserII
./build/applications/filebrowserII/filebrowser

# Run the Calculator
./build/applications/calculator/calculator

# Run the Vector Draw app
./build/applications/draw/draw

# Run the Graphical Desktop environment
./build/applications/desktop/desktop

FilebrowserII has a GUI button for invoking the built-in development environment. To start other applications with the development environment, use the following command-line flags -EE or -Ee:

./build/applications/calculator/calculator -EE

🖼️ Screenshots

Here is the FilebrowserII demo running on a modern system:

Application Screenshot
ET++ FileBrowser Demo ET++ FileBrowser Demo
Source Browser Source Browser
Structure Browser Structure Browser
Object Inspector Object Inspector
Class Browser Class Browser

📚 Documentation

Detailed documentation for classes, methods, global variables, and macros is available in:

  • Markdown Docs: Explore the detailed reference pages under doc/markdown/.
  • Reference Manual: View the comprehensive PDF guide at doc/reference_manual.pdf.

⚖️ License & Copyright

ET++ 2.2 is subject to the terms of the original license. See the LICENCE and copyright files in the repository root for details.

Copyright © 1990, 1991 Union Bank of Switzerland (UBILAB). All rights reserved.

About

A modern restoration and port of the historic, object-oriented C++ application framework originally released in 1991.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages