home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / lang / cplus / 18899 < prev    next >
Encoding:
Text File  |  1993-01-10  |  5.0 KB  |  158 lines

  1. 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
  2. From: ecm@casbah.acns.nwu.edu (Edward Malthouse)
  3. Newsgroups: comp.lang.c++
  4. Subject: varargs
  5. Message-ID: <1993Jan10.193617.5871@news.acns.nwu.edu>
  6. Date: 10 Jan 93 19:36:17 GMT
  7. Sender: usenet@news.acns.nwu.edu (Usenet on news.acns)
  8. Organization: Northwestern University, Evanston Illinois.
  9. Lines: 146
  10. Nntp-Posting-Host: unseen1.acns.nwu.edu
  11.  
  12.  
  13. I am trying to write a function error which will will be declared as follows:
  14. error(va_list)
  15.  
  16. The usage will be
  17. error(char *format, arg_list)
  18. so that it writes to stderr the arguments that comprise the arg_list under the
  19. control of the string pointed to by format.  The string pointed to 
  20. by format is to have the same form as that used by the printf
  21. family of functions.  After the message is printed, error calls the
  22. cleanup function and then exits with an error status of 1.  The
  23. cleanup function must be provided by the user and should be declared as
  24. void cleanup(void); The purpose of cleanup is to return any global resourses 
  25. allocated at runtime and close any global files that may be open.
  26.  
  27. I've used varargs for other applications but am having a few problems with
  28. this one.  I've tried three different approaches, but none work
  29. satisfactorily.  The approaches are as follows:
  30.  
  31. void error(va_alist)
  32. va_dcl
  33. {
  34.     va_list ap;
  35.     char *format;
  36.  
  37.     va_start(ap);
  38.     format = va_arg(ap, char*);
  39.     fprintf(stderr,format,ap);    
  40. /*    fprintf(stderr,format,&ap);    */
  41.     va_end(ap);
  42.     cleanup();
  43.     exit(1);
  44. } /* error */
  45.  
  46. I get a core dump with the first one when fprintf tries to pop anything off 
  47. of ap (or &ap).
  48.  
  49. void error(va_alist)
  50. va_dcl
  51. {
  52.     va_list ap;
  53.     char *t, *u;
  54.     char *format;
  55.     short argcnt;       /* counts number of %*'s in the format string */
  56.     char *argptr;
  57.     char buffer[100];
  58.  
  59.     va_start(ap);
  60.     format = va_arg(ap, char*);
  61.     for(t=format; *t; t++)
  62.         if(*t == '%') /* print a % */
  63.             if(*(t+1) == '%') fputc(*t++,stderr);
  64.             else{
  65.                 /* cut format argument */
  66.                 u = buffer;
  67.                 do
  68.                     *u++ = *t++;
  69.                 while(isdigit(*t) || *t=='.');
  70.                 *u = *t;
  71.                 *(u+1) = '\0';
  72.                 argptr = va_arg(ap, void*);
  73.                 fprintf(stderr,buffer,*argptr);
  74. /*                fprintf(stderr,buffer,argptr);  */
  75.             } /* else */
  76.         else fputc(*t,stderr);
  77.  
  78.     va_end(ap);
  79.     cleanup();
  80.     exit(1);
  81. } /* error */
  82.  
  83. The second one will not compile when I send *argptr.  When argptr is sent it
  84. core dumps.
  85.  
  86. void error(va_alist)
  87. va_dcl
  88. {
  89.     va_list ap;
  90.     char *t, *u;        /* loop vars */
  91.     char *format;       /* will point to format str from usr */
  92.     short argcnt;       /* counts number of %*'s in the format string */
  93.     char *tmps, tmpc;
  94.     double tmpd;
  95.     int tmpi;
  96.     char buffer[100];
  97.  
  98.     va_start(ap);
  99.     format = va_arg(ap, char*);
  100.     for(t=format; *t; t++)
  101.         if(*t == '%') /* print a % */
  102.             if(*(t+1) == '%') fputc(*t++,stderr);
  103.             else{
  104.                 /* cut out format arg */
  105.                 u = buffer;
  106.                 do
  107.                     *u++ = *t++;
  108.                 while(isdigit(*t) || *t=='.');
  109.                 *u = *t;
  110.                 *(u+1) = '\0';
  111.  
  112.                 switch(*u){
  113.                 case 'c':  tmpc = va_arg(ap, char);
  114.                     fprintf(stderr,buffer,tmpc);                break;
  115.                 case 'd':
  116.                 case 'i':
  117.                 case 'o':
  118.                 case 'x':  tmpi = va_arg(ap, int);
  119.                     fprintf(stderr,buffer,tmpi);                break;
  120.                 case 'e':
  121.                 case 'f':
  122.                 case 'g':  tmpd = va_arg(ap, double);
  123.                     fprintf(stderr,buffer,tmpd);                break;
  124.                 case 's':  tmps = va_arg(ap, char*);
  125.                     fprintf(stderr,buffer,tmps);                break;
  126.                 default:  fprintf(stderr,"\nunrecognized option (%c)\n",*u);
  127.                     continue;
  128.                 } /* switch */
  129.             } /* else */
  130.         else fputc(*t,stderr);
  131.  
  132.     va_end(ap);
  133.     cleanup();
  134.     exit(1);
  135. } /* error */
  136.  
  137. This version works but I am concerned about portability problems when it
  138. comes to all the different flavors of int's (int, short, long, unsigned,
  139. etc.), doubles, floats, etc.  I have not included any code to handle the
  140. backslash codes or formats with *'s in them (e.g., printf("%*d\n",10,i)) yet.
  141.  
  142. My questions are as follows:
  143.  
  144. -  Method 1 seems like the best way.  Is there any way of getting this to
  145.    work?
  146.  
  147. -  How does printf etc. get around the "multiple flavors of int's" problem,
  148.    i.e., printf does not know if a %d is associated with a short, int, long,
  149.    unsigned long int, etc.  How does it know what type to specify when it
  150.    calls va_arg?
  151.  
  152. Thank you in advance for your help.  Please mail any responses and I will
  153. summarize if there is interest.
  154.  
  155. Ed Malthouse
  156. Department of Statistics
  157. Northwestern University
  158.