[comp.lang.c] macro-parameters and curses

rblieva@cs.vu.nl (Roemer b Lievaart) (09/08/87)

Often in this group it has been pointed out, that macro-parameters should
only be used ONCE in a macro-definition. I guess we all know why now.
So I was very surprised to find the following defintions in the
<curses.h> include file:

#define	mvwaddch(win,y,x,ch)	VOID(wmove(win,y,x)==ERR?ERR:waddch(win,ch))
#define	mvwgetch(win,y,x)	VOID(wmove(win,y,x)==ERR?ERR:wgetch(win))
		... etc ... (and LOTS more like that)
#define flushok(win,bf)	 (bf ? (win->_flags |= _FLUSH):(win->_flags &= ~_FLUSH))
#define	getyx(win,y,x)	 y = win->_cury, x = win->_curx
#define	winch(win)	 (win->_y[win->_cury][win->_curx])

Also notice the lack of parenthesis, especially in the last three.
(I don't think one must parenthesise (????) the first two, should one?)

I could think of dozens of situations where the innocent ;-) programmer
is tearing his hear out, wondering whatever he is doing wrong.

But that's not all.

Also, I had very much problems with curses, clearing screens and printing
in standout-mode when I didn't want it to. After lots of searching,
(first in my own program, ofcourse, only much later in the curses-sources,)
I found out that in the function newwin, flags where set, but not
initialised. So the win->_flags were almost completely random.
Consequences: the program sometimes treated tiny little windows
as full screens, thought they were subwindows, that it should print
in standoutmode, etc. etc.

While examining the routine, I also noticed this very clever freeing
in the same routine:

/usr/src/lib/libcurses/newwin.c :
[ ...  ]
:  * 1/26/81 (Berkeley) %W
[ .... ]
: 	if ((win->_lastch = calloc(nl, sizeof (short))) == NULL) {
: 		cfree(win);
: 		cfree(win->_y);
: 		cfree(win->_firstch);
: 	}

Now:

- I don't know why cfree is used, here it's just defined as:

  : /* @(#)calloc.c	4.1 (Berkeley) 12/21/80 */
  [ ... ]
  : cfree(p, num, size) char *p;
  : unsigned num, size;
  : {
  : 	free(p);
  : }

  Now that's clever, calling cfree with only ONE parameter!
  I guess cfree (not at all documented here!!!) is to be used iff
  you allocated something with calloc. Our documentation, however,
  only mentions free for both malloc and calloc.

- win, however, was created by malloc, not calloc.

- Ofcourse the order of free-ing is COMPLETELY BOGUS! (It will probably
  work on most systems, but it may very well not!!)

- Notice, that it doesn't return NULL, as it does by SOME other errors.
  It just continues on, using win, win->_y and the rest, like they
  still "existed"!!!


Now I am aware, we work on a hopelessly old BSD4.1-system, but I am
really surprised noone had ever so much problems with it like I had,
that there wasn't a fix for this.

It's NOT FUNNY when your program dumps core because of bugs in the systems
library!!!!! (Except when you hate the person who gets them, ofcourse.)


			-- Roemer  (pron.: Rumor)

PS: Our curses dousn't support the "bell()" function (or anything similar),
either.