home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!charon.amdahl.com!pacbell.com!att-out!rutgers!usc!zaphod.mps.ohio-state.edu!news.acns.nwu.edu!casbah.acns.nwu.edu!ecm
- From: ecm@casbah.acns.nwu.edu (Edward Malthouse)
- Newsgroups: comp.lang.c++
- Subject: varargs
- Message-ID: <1993Jan10.193617.5871@news.acns.nwu.edu>
- Date: 10 Jan 93 19:36:17 GMT
- Sender: usenet@news.acns.nwu.edu (Usenet on news.acns)
- Organization: Northwestern University, Evanston Illinois.
- Lines: 146
- Nntp-Posting-Host: unseen1.acns.nwu.edu
-
-
- I am trying to write a function error which will will be declared as follows:
- error(va_list)
-
- The usage will be
- error(char *format, arg_list)
- so that it writes to stderr the arguments that comprise the arg_list under the
- control of the string pointed to by format. The string pointed to
- by format is to have the same form as that used by the printf
- family of functions. After the message is printed, error calls the
- cleanup function and then exits with an error status of 1. The
- cleanup function must be provided by the user and should be declared as
- void cleanup(void); The purpose of cleanup is to return any global resourses
- allocated at runtime and close any global files that may be open.
-
- I've used varargs for other applications but am having a few problems with
- this one. I've tried three different approaches, but none work
- satisfactorily. The approaches are as follows:
-
- void error(va_alist)
- va_dcl
- {
- va_list ap;
- char *format;
-
- va_start(ap);
- format = va_arg(ap, char*);
- fprintf(stderr,format,ap);
- /* fprintf(stderr,format,&ap); */
- va_end(ap);
- cleanup();
- exit(1);
- } /* error */
-
- I get a core dump with the first one when fprintf tries to pop anything off
- of ap (or &ap).
-
- void error(va_alist)
- va_dcl
- {
- va_list ap;
- char *t, *u;
- char *format;
- short argcnt; /* counts number of %*'s in the format string */
- char *argptr;
- char buffer[100];
-
- va_start(ap);
- format = va_arg(ap, char*);
- for(t=format; *t; t++)
- if(*t == '%') /* print a % */
- if(*(t+1) == '%') fputc(*t++,stderr);
- else{
- /* cut format argument */
- u = buffer;
- do
- *u++ = *t++;
- while(isdigit(*t) || *t=='.');
- *u = *t;
- *(u+1) = '\0';
- argptr = va_arg(ap, void*);
- fprintf(stderr,buffer,*argptr);
- /* fprintf(stderr,buffer,argptr); */
- } /* else */
- else fputc(*t,stderr);
-
- va_end(ap);
- cleanup();
- exit(1);
- } /* error */
-
- The second one will not compile when I send *argptr. When argptr is sent it
- core dumps.
-
- void error(va_alist)
- va_dcl
- {
- va_list ap;
- char *t, *u; /* loop vars */
- char *format; /* will point to format str from usr */
- short argcnt; /* counts number of %*'s in the format string */
- char *tmps, tmpc;
- double tmpd;
- int tmpi;
- char buffer[100];
-
- va_start(ap);
- format = va_arg(ap, char*);
- for(t=format; *t; t++)
- if(*t == '%') /* print a % */
- if(*(t+1) == '%') fputc(*t++,stderr);
- else{
- /* cut out format arg */
- u = buffer;
- do
- *u++ = *t++;
- while(isdigit(*t) || *t=='.');
- *u = *t;
- *(u+1) = '\0';
-
- switch(*u){
- case 'c': tmpc = va_arg(ap, char);
- fprintf(stderr,buffer,tmpc); break;
- case 'd':
- case 'i':
- case 'o':
- case 'x': tmpi = va_arg(ap, int);
- fprintf(stderr,buffer,tmpi); break;
- case 'e':
- case 'f':
- case 'g': tmpd = va_arg(ap, double);
- fprintf(stderr,buffer,tmpd); break;
- case 's': tmps = va_arg(ap, char*);
- fprintf(stderr,buffer,tmps); break;
- default: fprintf(stderr,"\nunrecognized option (%c)\n",*u);
- continue;
- } /* switch */
- } /* else */
- else fputc(*t,stderr);
-
- va_end(ap);
- cleanup();
- exit(1);
- } /* error */
-
- This version works but I am concerned about portability problems when it
- comes to all the different flavors of int's (int, short, long, unsigned,
- etc.), doubles, floats, etc. I have not included any code to handle the
- backslash codes or formats with *'s in them (e.g., printf("%*d\n",10,i)) yet.
-
- My questions are as follows:
-
- - Method 1 seems like the best way. Is there any way of getting this to
- work?
-
- - How does printf etc. get around the "multiple flavors of int's" problem,
- i.e., printf does not know if a %d is associated with a short, int, long,
- unsigned long int, etc. How does it know what type to specify when it
- calls va_arg?
-
- Thank you in advance for your help. Please mail any responses and I will
- summarize if there is interest.
-
- Ed Malthouse
- Department of Statistics
- Northwestern University
-