Q: I have a pre-ANSI compiler, without <stdarg.h>. What can I do?
A: There's an older header, <varargs.h>, which offers about the same functionality.
Here is the vstrcat function from question 15.4, rewritten to use <varargs.h>:
#include <stdio.h>
#include <varargs.h>
#include <string.h>
extern char *malloc();
char *vstrcat(va_alist)
va_dcl /* no semicolon */
{
int len = 0;
char *retbuf;
va_list argp;
char *p;
va_start(argp);
while((p = va_arg(argp, char *)) != NULL) /* includes first */
len += strlen(p);
va_end(argp);
retbuf = malloc(len + 1); /* +1 for trailing \0 */
if(retbuf == NULL)
return NULL; /* error */
retbuf[0] = '\0';
va_start(argp); /* restart for second scan */
while((p = va_arg(argp, char *)) != NULL) /* includes first */
strcat(retbuf, p);
va_end(argp);
return retbuf;
}
(Note
that there is no semicolon after va_dcl.
Note that in this case,
no special treatment for the first argument is necessary.)
You may also have to
declare the string functions by hand
rather than using <string.h>.
If you can manage to find a system with vfprintf but without <stdarg.h>, here is a version of the error function (from question 15.5) using <varargs.h>:
#include <stdio.h>
#include <varargs.h>
void error(va_alist)
va_dcl /* no semicolon */
{
char *fmt;
va_list argp;
fprintf(stderr, "error: ");
va_start(argp);
fmt = va_arg(argp, char *);
vfprintf(stderr, fmt, argp);
va_end(argp);
fprintf(stderr, "\n");
}
(Note
that
in contrast to <stdarg.h>,
under <varargs.h> all arguments are variable,
so
the fmt argument must also be picked up via va_arg.)
References:
H&S Sec. 11.4 pp. 296-9
CT&P Sec. A.2 pp. 134-139
PCS Sec. 11 pp. 184-5, Sec. 13 p. 250