[comp.sys.next] Variable Length Argument Lists for Methods--REPOST

brian@lighthouse.com (Brian Douglas Skinner) (09/24/89)

In article <1989Sep13.025245.1193@lighthouse.com>, I wrote what
follows.  However, no one seems to have responded.  We're still
looking for answers...

>We're trying to write a method that takes a variable number of
>arguments, something like:
>
>[error notify: "Error at line %i in file %s", __LINE__, __FILE__];
>
>or 
>
>[error notify: "Error: %s at line %i in file %s", "Big Bummer",
>__LINE__, __FILE__];
>
>We've settled on
>
>- error: (char *)format, ...;
>
>in our .h file (based on selectorRPC:paramTypes:... in Speaker.h), but
>we haven't stumbled onto how to write the method.
>
>On page 4-13 of the Objective-C Compiler User Reference Manual (in
>Volume 3 of the NeXT 0.9 Technical Documentation) is written
>
>- error:( char * ) format ; int aList ;
>//                        ^
>//                        might be a colon; can't tell
>
>However, this results in a compiler error.
>
>We've tried variations on the ANSI stdarg technique, and we've tried
>messing directly with pointers, to no avail.
>
>In our .m file, we can use
>
>- error: (char *)format, ...
>{
>    char *args;
>    char **scary;
>    char out[255];
>
>    scary = &format;
>    scary++;
>    args = *scary;
>
>    sprintf(out, format, args);
>    NXAlert(out, "OK", NULL, NULL);
>
>    return self;
>}
>
>without getting a compiler error, but it dumps core in sprintf.
>
>Hints and code fragments would be greatly appreciated.

Thanks,
Brian Skinner
Lighthouse Design, Ltd.
Usenet:   ...!uunet!lighthouse!brian
Internet: brian@lighthouse.com

ali@polya.Stanford.EDU (Ali T. Ozer) (09/28/89)

[I actually posted an answer from NeXT a few days ago, but I think the message
 never made it anywhere. So here it goes again; if you see this twice,
 apologies... -Ali]

In article <1989Sep23.215508.5568@lighthouse.com> Brian Douglas Skinner writes:
>We're trying to write a method that takes a variable number of
>arguments, something like:
>
>[error notify: "Error at line %i in file %s", __LINE__, __FILE__];

Use of variable length argument lists is described in the Second Edition of
Kernighan & Ritchie; you can use the same sort of mechanism to go through the 
arguments in ObjC. Say you have (very simple) method which takes a number
and that many string arguments, and prints the strings one after another.
The declaration would be:

- listItems:(int)numItems, ...;

... the code itself would be:

- listItems:(int)numItems, ...
{
  va_list ap;
  va_start (ap, numItems);	// Make ap point to the first unnamed argument
  printf ("The Items are: ");
  while (numItems--) 
    printf ("%s ", va_arg(ap, char *));  // All args should be char *
  printf ("\n");
  va_end (ap);			// Wrap it up...
}

... and a sample call could be:

  [self listItems:3, "foo", "bar", "zap"];


The above example is of course too simple; on page 156 of K&R there's a more
complicated example that implements a minimal printf. 

If you just want to have an error: method that takes a format string and bunch
of args and treats them like printf would, you can vfprintf (or vsprintf).
The man page has the necessary info...

Ali Ozer, NeXT Developer Support
Ali_Ozer@NeXT.com