Back to index

tetex-bin  3.0
varargs.c
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Copyright (c) 2001-2002,2003 Free Software Foundation, Inc.              *
00003  *                                                                          *
00004  * Permission is hereby granted, free of charge, to any person obtaining a  *
00005  * copy of this software and associated documentation files (the            *
00006  * "Software"), to deal in the Software without restriction, including      *
00007  * without limitation the rights to use, copy, modify, merge, publish,      *
00008  * distribute, distribute with modifications, sublicense, and/or sell       *
00009  * copies of the Software, and to permit persons to whom the Software is    *
00010  * furnished to do so, subject to the following conditions:                 *
00011  *                                                                          *
00012  * The above copyright notice and this permission notice shall be included  *
00013  * in all copies or substantial portions of the Software.                   *
00014  *                                                                          *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00016  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00017  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00018  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00020  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00021  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00022  *                                                                          *
00023  * Except as contained in this notice, the name(s) of the above copyright   *
00024  * holders shall not be used in advertising or otherwise to promote the     *
00025  * sale, use or other dealings in this Software without prior written       *
00026  * authorization.                                                           *
00027  ****************************************************************************/
00028 
00029 /****************************************************************************
00030  *  Author: Thomas E. Dickey 2001                                           *
00031  ****************************************************************************/
00032 
00033 #include <curses.priv.h>
00034 
00035 #include <ctype.h>
00036 
00037 MODULE_ID("$Id: varargs.c,v 1.4 2003/05/24 21:10:28 tom Exp $")
00038 
00039 #ifdef TRACE
00040 
00041 #define MAX_PARMS 10
00042 
00043 typedef enum {
00044     atUnknown = 0, atInteger, atFloat, atPoint, atString
00045 } ARGTYPE;
00046 
00047 #define VA_INT(type) ival = va_arg(ap, type)
00048 #define VA_FLT(type) fval = va_arg(ap, type)
00049 #define VA_PTR(type) pval = (char *)va_arg(ap, type)
00050 #define VA_STR(type) sval = va_arg(ap, type)
00051 
00052 /*
00053  * Returns a string that represents the parameter list of a printf-style call.
00054  */
00055 NCURSES_EXPORT(char *)
00056 _nc_varargs(const char *fmt, va_list ap)
00057 {
00058     static char dummy[] = "";
00059     static char *result_buf;
00060     static size_t result_len;
00061 
00062     char buffer[BUFSIZ];
00063     const char *param;
00064     int n;
00065 
00066     if (fmt == 0 || *fmt == '\0')
00067        return dummy;
00068     if (result_len == 0)
00069        result_buf = typeMalloc(char, result_len = BUFSIZ);
00070     if (result_buf == 0)
00071        return dummy;
00072     *result_buf = '\0';
00073 
00074     while (*fmt != '\0') {
00075        if (*fmt == '%') {
00076            char *pval = 0;  /* avoid const-cast */
00077            const char *sval = "";
00078            double fval = 0.0;
00079            int done = FALSE;
00080            int ival = 0;
00081            int type = 0;
00082            ARGTYPE parm[MAX_PARMS];
00083            int parms = 0;
00084            ARGTYPE used = atUnknown;
00085 
00086            while (*++fmt != '\0' && !done) {
00087 
00088               if (*fmt == '*') {
00089                   VA_INT(int);
00090                   if (parms < MAX_PARMS)
00091                      parm[parms++] = atInteger;
00092               } else if (isalpha(UChar(*fmt))) {
00093                   done = TRUE;
00094                   switch (*fmt) {
00095                   case 'Z': /* FALLTHRU */
00096                   case 'h': /* FALLTHRU */
00097                   case 'l': /* FALLTHRU */
00098                      done = FALSE;
00099                      type = *fmt;
00100                      break;
00101                   case 'i': /* FALLTHRU */
00102                   case 'd': /* FALLTHRU */
00103                   case 'u': /* FALLTHRU */
00104                   case 'x': /* FALLTHRU */
00105                   case 'X': /* FALLTHRU */
00106                      if (type == 'l')
00107                          VA_INT(long);
00108                      else if (type == 'Z')
00109                          VA_INT(size_t);
00110                      else
00111                          VA_INT(int);
00112                      used = atInteger;
00113                      break;
00114                   case 'f': /* FALLTHRU */
00115                   case 'e': /* FALLTHRU */
00116                   case 'E': /* FALLTHRU */
00117                   case 'g': /* FALLTHRU */
00118                   case 'G': /* FALLTHRU */
00119                      VA_FLT(double);
00120                      used = atFloat;
00121                      break;
00122                   case 'c':
00123                      VA_INT(int);
00124                      used = atInteger;
00125                      break;
00126                   case 's':
00127                      VA_STR(const char *);
00128                      used = atString;
00129                      break;
00130                   case 'p':
00131                      VA_PTR(void *);
00132                      used = atPoint;
00133                      break;
00134                   case 'n':
00135                      VA_PTR(int *);
00136                      used = atPoint;
00137                      break;
00138                   default:
00139                      break;
00140                   }
00141               } else if (*fmt == '%') {
00142                   done = TRUE;
00143               }
00144               if (used != atUnknown && parms < MAX_PARMS) {
00145                   parm[parms++] = used;
00146                   for (n = 0; n < parms; ++n) {
00147                      used = parm[n];
00148                      param = buffer;
00149                      switch (used) {
00150                      case atInteger:
00151                          sprintf(buffer, "%d", ival);
00152                          break;
00153                      case atFloat:
00154                          sprintf(buffer, "%f", fval);
00155                          break;
00156                      case atPoint:
00157                          sprintf(buffer, "%p", pval);
00158                          break;
00159                      case atString:
00160                          param = _nc_visbuf2(1, sval);
00161                          break;
00162                      default:
00163                          strcpy(buffer, "?");
00164                          break;
00165                      }
00166                      result_len += strlen(param) + 2;
00167                      result_buf = typeRealloc(char, result_len, result_buf);
00168                      sprintf(result_buf + strlen(result_buf), ", %s", param);
00169                   }
00170               }
00171               used = atUnknown;
00172            }
00173        } else {
00174            fmt++;
00175        }
00176     }
00177 
00178     return (result_buf);
00179 }
00180 #else
00181 empty_module(_nc_varargs)
00182 #endif