Needed: A (Portable) way of setting up the arg stack

Ian Stewartson gis at datlog.co.uk
Sat Jun 10 05:14:39 AEST 1989


In article <11830 at bloom-beacon.MIT.EDU> scs at adam.pika.mit.edu (Steve Summit) writes:
>specific problem, not an operating system specific problem.)  A
>routine such as va_call MUST be written in assembly language; it
>is one of the handful of functions I know of that cannot possibly
>be written in C.

It seemed to me that the printf and scanf (and in particular the vprintf
family) have a similar problem looked at in a mirror.  They effectively do
what you want in reverse.  I noticed that all the printf family use the
function _doprnt (possibly not on all systems, but certainly the few that
I have access to).  Therefore va_call could be implemented in the similar
manner.  Taking Steve's example code, I hacked it to produce a macro
va_access to get the top of the argument stack excluding the count and then
modified pf.c to produce the following code:

#include <stdio.h>
#include "varargs2.h"

#define va_access(stack)	&stack[1]

main()
{
    va_stack(stack, 10);

    va_stack_init(stack);

    va_push(stack, 12, int);
    va_push(stack, 3.14, double);
    va_push(stack, "Hello, world!", char *);

    _doprnt ("%d %f %s\n", va_access(stack), stdout);
    printf ("%d %f %s\n", 12, 3.14, "Hello, world!");
}

Which generates the strings:

12 3.140000 Hello, world!
12 3.140000 Hello, world!

(The last printf to check the results).

The declaration of _doprnt is of the form

    int		_doprnt (format, args, iop)
    char	*format;
    va_list	args;
    FILE	*iop;

and the arguments are accessed within _doprnt using

    width = va_arg(args, int);

There being no va_start and va_end in the function.

Now I realised that _doprnt is a special case on Unix systems and may not
exist on other systems MS-DOS (which uses _output in MSC5 with iop as the
first parameter) or MPE (HP's proprietary 3000 system) which has an odd
stack frame format which includes a count of the number of arguments and
flags to indicate if an argument is on the stack.  However, from what I
remember of the version of C we were using on MPE, the printf family
shared common code and varargs definitely existed.  So it may be possible
to generate portable code, especially if varargs exists on the intended
system.

I tested the code on our Vax (Sys Vr2) and MS-DOS systems.

On a personnel note:  Thanks Steve, your include file and usage saved me
time I would have wasted using a different method.

Regards,

Ian Stewartson
Data Logic Ltd, Queens House, Greenhill Way, Harrow, Middlesex, HA1 1YR, UK.
(Phone) +44 1 863 0383 (Telex) 888103 (Fax) +44 1 861 2010
(Network) gis at datlog.co.uk or ukc!datlog!gis



More information about the Comp.unix.wizards mailing list