Xref: utzoo comp.lang.c:21542 comp.windows.x:13154 Path: utzoo!attcan!uunet!seismo!ukma!rex!ames!think!bloom-beacon!hstbme.mit.edu!scs From: scs@hstbme.mit.edu (Steve Summit) Newsgroups: comp.lang.c,comp.windows.x Subject: Re: varargs and X Keywords: varargs, X Windows, stdarg Message-ID: <14108@bloom-beacon.MIT.EDU> Date: 7 Sep 89 03:39:17 GMT References: <19199@gatech.edu> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: scs@adam.pika.mit.edu (Steve Summit) Lines: 72 In article <19199@gatech.edu> ken@gatech.edu (Ken Seefried III) writes: >I'm trying to build a general purpose error notification routine >for an X11/Motif application that I am writing. I need to use >varargs to get the error messages to the routine (printf() style). I assume you want to call this routine with things like WidgetError(parentwidget, "funny name \"%s\"", name); If you are using (old) varargs, I believe that your function's argument list must contain only the va_alist. You would have to pull the widget ID out manually, as you do the printf format: WidgetError(va_alist) va_dcl { va_list vaargs; Widget parent; char *fmt; char buffer[1024]; va_start(vaargs); parent = va_arg(args, Widget); fmt = va_arg(args, char *); vsprintf(buffer, fmt, vaargs); va_end(vaargs); (Note that I have also removed a space from "Widget Error", changed va_list in the formal parameters list to va_alist, changed vsscanf to vsprintf, and added a "call" to va_end.) The key is that the second argument to va_arg can be any type descriptor. (Actually, many implementations are buggy and break if it's a char, but as long as sizeof(Widget) >= sizeof(int) it should work.) It would be worth your while to implement this in terms of the new ANSI instead of the old . stdarg dispenses with va_alist and va_dcl, and allows (nay, requires) you to have fixed arguments before the variable ones. The stdarg implementation would look like this: WidgetError(parent, fmt, ...) Widget parent; char *fmt; { va_list vaargs; char buffer[1024]; va_start(vaargs, fmt); vsprintf(buffer, fmt, vaargs); va_end(vaargs); Note that, under stdarg, va_start takes the name of the last fixed parameter as its second argument. If you don't have an ANSI compiler, you can leave out the ", ..." in the formals list, and va_start will (can) still work. If you don't have , I can supply one that should work on "conventional," stack-based machines. (I'd append it here, since it's short, but the machine it's on is down.) I don't know much about X, but it would be appropriate to provide an Xwindowvprintf(window, fmt, ...) so that you could printf things into windows without using the vsprintf/buffer dodge. (Any fixed-size buffer will always be too big or too small.) Of course, implementing Xwindowvprintf would be another story. (From the looks of your example, you're "printing" not to a window but to an XmString or a "dialog," so a vprintf analogue would be appropriate for those objects as well.) Steve Summit