Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is really more a C pattern than a C++ pattern, isn't it?

Frustrated by C's limitations relative to Golang, last year I sketched out an approach to using X-macros to define VNC protocol message types as structs with automatically-generated serialization and deserialization code. So for example you would define the VNC KeyEvent message as follows:

    #define KeyEvent_fields(field, padding)               \
      field(u8, down_flag)                                \
      padding(u8)                                         \
      padding(u8)                                         \
      field(u32, keysym)

    MESSAGE_TYPE(KeyEvent)
And that would generate a KeyEvent typedef (to an anonymous struct type) and two functions named read_KeyEvent_big_endian and write_KeyEvent_big_endian. (It wouldn't be difficult to add debug_print_KeyEvent.) Since KeyEvent is a typedef, you can use it as a field type in other, larger structs just like u8 and u32.

Note that here there are two Xes, and they are passed as parameters to the KeyEvent_fields macro rather than being globally defined and undefined over time. To me this feels cleaner than the traditional way.

The usage above is in http://canonical.org/~kragen/sw/dev3/binmsg_cpp.c, MESSAGE_TYPE and its ilk are in http://canonical.org/~kragen/sw/dev3/binmsg_cpp.h, and an alternative approach using Python instead of the C preprocessor to generate the required C is in http://canonical.org/~kragen/sw/dev3/binmsg.py.



> This is really more a C pattern than a C++ pattern, isn't it?

You're right, although it feels a bit safer in C++ with the extra type safety. And that in my mind makes it more powerful in C++.


What I love are macros that take parameters that are the names of other macros to call, and parameters that are fragments of code without balanced brackets to insert.

The term of art for that and the X pattern kind of approach is "macrology".

An infamous example is Microsoft's original C preprocessor macros for generating COM components for C code.

MFC infamously used a similar approach for its COM/OLE bindings to C++ too. You could include the same interface definition .h files in either C or C++ code with the proper meta-macros defined to declare the same interfaces in either C or C++ code (which was kind of the whole point of COM).

That was long before the (in contrast) much more elegant ATL (ActiveX Template Library) implemented with C++ templates.

Microsoft isn't the only offender -- Sun did it to!

Check out the "arctochain.c" code in the original NeWS server by Vaughan Pratt and James Gosling for a great example of macros that take the names of other macros and code fragments containing gotos, to make a state machine with a twisty maze of hopping gotos, plus some manual exception handling gotology like "goto this_curve_is_trash;" and "goto straight;" thrown in for fun:

https://donhopkins.com/home/NeWS/SUN/src/server/graphics/arc...

  /*-
      Convert a conic arc to a curve

      arctochain.c, Tue Jun 11 14:23:17 1985

      "Elegance and truth are inversely related." -- Becker's Razor

          Vaughan Pratt
          Sun Microsystems

          This code is a version of the conix package that has been
          heavily massaged by James Gosling.
   */
More NeWS macrology:

https://news.ycombinator.com/item?id=15680904

>[...] Two pieces of work were done at SUN which provide other key components of the solution to the imaging problems. One is Vaughan Pratt's Conix [53], a package for quickly manipulating curve bounded regions, and the other is Craig Taylor's Pixscene [63], a package for performing graphics operations in overlapped layers of bitmaps. [...]

>[...] Pixscene is based on a shape algebra package. The ability, provided by Conix, to do algebra very rapidly on curves should make non-rectangular windows perform well. [...]

>[53] Pratt, V., Techniques for Conic Splines, Computer Graphics 19(3), pp.151159 (1985).

>[63] Taylor, C. and Pratt, V., A Technique for Representing Layered Images. SUN Microsystems Inc., 2550 Garcia Avenue, Mountain View, CA94043.

Techniques for Conic Splines:

https://dl.acm.org/doi/pdf/10.1145/325334.325225

>The main loop of the NeWS PostScript interpreter itself is the realization of Duff's dire warning "Actually, I have another revolting way to use switches to implement interrupt driven state machines but it's too horrid to go into."

https://news.ycombinator.com/item?id=4360306

https://www.lysator.liu.se/c/duffs-device.html

https://donhopkins.com/home/code/NeWS/SUN/src/server/nucleus...

The blocking PostScript parser also has some charming macrology, by the same guy who brought you Java, written in the morning of New Years Eve 1984:

https://donhopkins.com/home/code/NeWS/SUN/src/server/nucleus...

  #define case4(tag) case tag: case tag+1: case tag+2: case tag+3
  #define case16(tag) case4(tag):case4(tag+4):case4(tag+8):case4(tag+12)
  #define case32(tag) case16(tag):case16(tag+16)


These are awesome! I didn't realize NeWS had been released in source form, or that Pratt had worked on it. Does it build today?

`goto straight;` sounds appalling. Can't escape heteronormativity even in NeWS!


> Does it build today In this form it won't, since that is missing the Sun PixRect library. And you also need the "operators.h" file (which is in another directory...) and the "acceptconnect" function.

On comp.windows.news Usenet group and on the NeWS book is reported that a portable codebase (called REF) exists, and Sun ported it on Ultrix (on thr VAXstation) and System V. I read it included a version of PixRect called "Generic PixRect", which should be more portable.

BitSavers put on the net a tape dump of X/NeWS 2.0, and there are some differences: a different graphics library called SHAPES replacing CScript (and it needs the Ace preprocessor to build the device dependent portion of the library), a different memory allocator, support for X11 protocol, support for Folio F3 fonts, and other things.

Fortunately I found a copy of PixRect in the leaked sources of SunOS 4.1.4 , but it's not enough, since that device dependent routines must be rewritten.

I'm slowly porting NeWS 1.1 to NetBSD (since that wscons is easier to work with) as a proof of concept. I managed to execute code and grt my screen turn blue, but the current obstacle is decoding binary fonts: the OG routines fail completely on 64 bit machines, since that the original format assumes 32 bit machine words and big endian order. More work will be needed.


Alas, it's quite dependent on old compilers and libraries, and only really useful for "educational and research purposes".

With all due respect, in that code, "goto straight;" is only for boring degenerate conics, as it should be.

There's a funny commented out line with a call to an undefined function that I love:

    /*- clearasil(buf0+1, bitlen);  /* clean out 0011/1100 pimples */




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: