Thread: bu_log() width specifier does not align like in printf

  1. #1
    Registered User
    Join Date
    Nov 2011
    Location
    Buea, Cameroon
    Posts
    197

    bu_log() width specifier does not align like in printf

    hey guys i am currently debugging this function. I am trying to make this function's width specifier align like a printf() routine.

    here 's the code(Thanks for the help)

    v
    Code:
    oid
    bu_log(const char *fmt, ...)
    {
        va_list ap;
        struct bu_vls output = BU_VLS_INIT_ZERO;
    
        if (UNLIKELY(!fmt || strlen(fmt) == 0)) {
    	bu_vls_free(&output);
    	return;
        }
    
        va_start(ap, fmt);
    
        if (log_indent_level > 0) {
    	struct bu_vls newfmt = BU_VLS_INIT_ZERO;
    
    	log_do_indent_level(&newfmt, fmt);
    	bu_vls_vprintf(&output, bu_vls_addr(&newfmt), ap);
    	bu_vls_free(&newfmt);
        } else {
    	bu_vls_vprintf(&output, fmt, ap);
        }
    
        va_end(ap);
    
        if (BU_LIST_IS_EMPTY(&(log_hook_list.l)) || log_hooks_called) {
    	int ret = EOF;
    	size_t len;
    
    	if (UNLIKELY(log_first_time)) {
         bu_setlinebuf(stderr);
         log_first_time = 0;
    	}
    
    	len = bu_vls_strlen(&output);
    	if (UNLIKELY(len <= 0)) {
         bu_vls_free(&output);
         return;
    	}
    
    	if (LIKELY(stderr != NULL)) {
         bu_semaphore_acquire(BU_SEM_SYSCALL);
         ret = fwrite(bu_vls_addr(&output), len, 1, stderr);
         fflush(stderr);
         bu_semaphore_release(BU_SEM_SYSCALL);
    	}
    
    	if (UNLIKELY(!ret && stdout)) {
         /* if stderr fails, try stdout instead */
         bu_semaphore_acquire(BU_SEM_SYSCALL);
         ret = fwrite(bu_vls_addr(&output), len, 1, stdout);
         fflush(stdout);
         bu_semaphore_release(BU_SEM_SYSCALL);
    	}
    
    	if (UNLIKELY(ret != 1)) {
         bu_semaphore_acquire(BU_SEM_SYSCALL);
         perror("fwrite failed");
         bu_semaphore_release(BU_SEM_SYSCALL);
         bu_bomb("bu_log: write error");
    	}
    
        } else {
    	log_call_hooks(bu_vls_addr(&output));
        }
    
        bu_vls_free(&output);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Then you need to be looking at bu_vls_vprintf(), which does all the work of formatting.

    All the code here is just about deciding where to send the result.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2011
    Location
    Buea, Cameroon
    Posts
    197
    thanks for the help Salem let me check the bu_vls_vprintf() routine let me paste the code for that here..

  4. #4
    Registered User
    Join Date
    Nov 2011
    Location
    Buea, Cameroon
    Posts
    197

    bu_vls_printf file

    #include "common.h"
    Code:
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    #include <stdarg.h>
    #include <assert.h>
    
    #ifdef HAVE_STDINT_H
    #   include <stdint.h>
    #endif
    
    #include "bio.h"
    
    #include "bu.h"
    
    #include "./vls_internals.h"
    
    /* private constants */
    
    /* bit flags for fmt specifier attributes */
    /* short (char) length modifiers */
    static const int SHORTINT =  0x0001;
    static const int SHHRTINT =  0x0002;
    /* integer length modifiers */
    static const int LONG_INT =  0x0004;
    static const int LLONGINT =  0x0008;
    /* double length modifiers */
    static const int LONGDBLE =  0x0010;
    /* other integer length modifiers */
    static const int INTMAX_T =  0x0020;
    static const int PTRDIFFT =  0x0040;
    static const int SIZETINT =  0x0080;
    /* misc */
    static const int FIELDLEN =  0x0100;
    static const int PRECISION = 0x0200;
    /* groups */
    #define MISCINTMODS    (INTMAX_T | PTRDIFFT | SIZETINT)
    #define SHORTINTMODS   (SHORTINT | SHHRTINT)
    #define LONGINTMODS    (LONG_INT | LLONGINT)
    #define ALL_INTMODS    (SHORTINTMODS | LONGINTMODS | MISCINTMODS)
    #define ALL_DOUBLEMODS (LONGDBLE)
    #define ALL_LENGTHMODS (ALL_INTMODS | ALL_DOUBLEMODS)
    
    /* private functions */
    
    /* decls */
    static void reset_vflags(vflags_t *f);
    
    /* defs */
    static void
    reset_vflags(vflags_t *f)
    {
        f->fieldlen     = -1;
        f->flags        =  0;
        f->have_digit   =  0;
        f->have_dot     =  0;
        f->left_justify =  0;
        f->precision    =  0;
    }
    
    /* Note that multiple instances of a character will invalidate the
     * second or any later instance, i.e., first found wins.
     */
    int
    format_part_status(const char c)
    {
      int status = VP_VALID; /* assume valid */
    
      /* return a bit flag with: type, validity */
      switch (c) {
          /* VALID ===================================== */
          case 'd':
          case 'i':
          case 'o':
          case 'u':
          case 'x':
          case 'X':
          case 'e':
          case 'E':
          case 'f':
          case 'F':
          case 'g':
          case 'G':
          case 'a':
          case 'A':
          case 'c':
          case 's':
          case 'p':
          case 'n':
          case '%':
          case 'V': /* bu_vls extension */
       status |= VP_CONVERSION_SPEC;
       break;
    
          case 'h': /* can be doubled: 'hh' */
          case 'l': /* can be doubled: 'll' */
          case 'L':
          case 'j':
          case 'z':
          case 't':
       status |= VP_LENGTH_MOD;
       break;
    
          case '#':
          case '0':
          case '-':
          case ' ':
          case '+':
          case '\'': /* SUSv2 */
       status |= VP_FLAG;
       break;
    
          case '*':
          case ';':
       status |= VP_MISC;
       break;
    
       /* OBSOLETE ===================================== */
       /* obsolete or not recommended (considered obsolete for bu_vls): */
          case 'm': /* glibc extension for printing strerror(errno) (not same as %m$ or %*mS) */
          case 'C': /* Synonym for lc. (Not in C99, but in SUSv2. Don't use.) */
          case 'D': /* Synonym for ld. (libc4--don't use) */
          case 'O': /* Synonym for lo. (libc5--don't use) */
          case 'S': /* Synonym for ls. (Not in C99, but in SUSv2. Don't use.) */
          case 'U': /* Synonym for lu. (libc5--don't use) */
       status  = VP_OBSOLETE;
       status |= VP_CONVERSION_SPEC;
       break;
    
          case 'Z': /* alias for 'z' (libc5--don't use) */
       status  = VP_OBSOLETE;
       status |= VP_LENGTH_MOD;
       break;
    
          case 'I': /* alias for 'z' (libc5--don't use) */
       status  = VP_OBSOLETE;
       status |= VP_FLAG;
       break;
    
          default:
       /* all others are unknown--be sure to redefine the status value to VP_UNKNOWN */
       status = VP_UNKNOWN;
       break;
      }
    
      return status;
    }
    
    /* function returns 1 if input char is found, 0 otherwise */
    int
    handle_format_part(const int vp_part, vflags_t *f, const char c, const int print)
    {
        int status = 1; /* assume found */
    
        switch (vp_part) {
    	case VP_CONVERSION_SPEC:
         switch (c) {
      default:
          if (print)
       fprintf(stderr, "Unhandled conversion specifier '%c'.\n", c);
          status = 0;
          break;
         }
         break;
    	case VP_LENGTH_MOD:
         switch (c) {
      case 'j':
          f->flags |= INTMAX_T;
          break;
      case 't':
          f->flags |= PTRDIFFT;
          break;
      case 'z':
          f->flags |= SIZETINT;
          break;
      case 'l':
          /* 'l' can be doubled */
          /* clear all length modifiers AFTER we check for the
             first 'l' */
          if (f->flags & LONG_INT) {
       f->flags ^= ALL_LENGTHMODS;
       f->flags |= LLONGINT;
          } else {
       f->flags ^= ALL_LENGTHMODS;
       f->flags |= LONG_INT;
          }
          break;
      case 'h':
          /* 'h' can be doubled */
          /* clear all length modifiers AFTER we check for the
             first 'h' */
          if (f->flags & SHORTINT) {
       f->flags ^= ALL_LENGTHMODS;
       f->flags |= SHHRTINT;
          } else {
       f->flags ^= ALL_LENGTHMODS;
       f->flags |= SHORTINT;
          }
          break;
      case 'L':
          /* a length modifier for doubles */
          /* clear all length modifiers first */
          f->flags ^= ALL_LENGTHMODS;
          /* set the new flag */
          f->flags |= LONGDBLE;
          break;
      default:
          if (print)
       fprintf(stderr, "Unhandled length modifier '%c'.\n", c);
          status = 0;
          break;
         }
         break;
    	case VP_FLAG:
         switch (c) {
      default:
          if (print)
       fprintf(stderr, "Unhandled flag '%c'.\n", c);
       status = 0;
          break;
         }
         break;
    	case VP_MISC:
         switch (c) {
      default:
          if (print)
       fprintf(stderr, "Unhandled miscellaneous format character '%c'.\n", c);
          status = 0;
          break;
         }
         break;
    	default:
         if (print)
      fprintf(stderr, "Unhandled vprintf format part number '%d'.\n", vp_part);
         status = 0;
         break;
        }
    
        if (print && !status) {
    	fprintf(stderr, "Report error to BRL-CAD developers.\n");
        }
    
        return status;
    }
    
    /* function returns 1 if input char is found, 0 otherwise */
    int
    handle_obsolete_format_char(const char c, const int print)
    {
        int status = 1; /* assume found */
        switch (c) {
    	/* conversion specifiers */
    	case 'm': /* glibc extension for printing strerror(errno) (not same as %m$ or %*mS) */
         if (print) {
      fprintf(stderr, "Format specifier '%c' is not allowed.\n", c);
      fprintf(stderr, "  Use normal formatting to print 'strerror' and 'errno').\n");
         }
         break;
    	case 'C': /* (Not in C99, but in SUSv2.)  Synonym for lc.  Don't use. */
         if (print) {
           fprintf(stderr, "Format specifier '%c' is obsolete.\n", c);
           fprintf(stderr, "  Use 'lc' instead.\n");
         }
         break;
    	case 'D': /* libc4--don't use */
         if (print) {
      fprintf(stderr, "Format specifier '%c' is obsolete.\n", c);
      fprintf(stderr, "  Use 'ld' instead.\n");
         }
         break;
    	case 'O': /* libc5--don't use */
         if (print) {
      fprintf(stderr, "Format specifier '%c' is obsolete.\n", c);
      fprintf(stderr, "  Use 'lo' instead.\n");
         }
         break;
    	case 'S': /* (Not in C99, but in SUSv2.)  Synonym for lc.  Don't use. */
         if (print) {
      fprintf(stderr, "Format specifier '%c' is obsolete.\n", c);
      fprintf(stderr, "  Use 'ls' instead.\n");
         }
         break;
    	case 'U': /* libc5--don't use */
         if (print) {
      fprintf(stderr, "Format specifier '%c' is obsolete.\n", c);
      fprintf(stderr, "  Use 'lu' instead.\n");
         }
         break;
    
       /* length modifiers */
    	case 'q': /* "quad".  4.4BSD  and  Linux libc5 only.  Don't use. */
         if (print) {
      fprintf(stderr, "Format length modifier '%c' is obsolete.\n", c);
      fprintf(stderr, "  Use 'll' instead.\n");
         }
         break;
    	case 'Z': /* alias for 'z' Linux libc5 only.  Don't use. */
         if (print) {
      fprintf(stderr, "Format length modifier '%c' is obsolete.\n", c);
      fprintf(stderr, "  Use 'z' instead.\n");
         }
         break;
    
       /* flags */
    	case 'I': /* specifies use of locale's alternative output digits */
         if (print) {
      fprintf(stderr, "Format flag '%c' is not yet supported.\n", c);
         }
         break;
    
    	default:
         if (print) {
      fprintf(stderr, "ERROR: Unhandled format character '%c'.\n", c);
      fprintf(stderr, "Report error to BRL-CAD developers.\n");
         }
         status = 0;
         break;
        }
    
        return status;
    }
    
    /*
    
    The bu_vls_vprintf function aims to adhere to the following
    specifications:
    
      1.  First, follow the POSIX man page at
          "http://www.unix.com/man-page/POSIX/3/printf/" regarding the
          definition of a format specifier.
    
      2.  Then modify [1] to accommodate a compatible subset of parts
          applicable to a wide range of standard C libraries including
          GNU/Linux, Windows, FreeBSD, and others as differences are
          brought to our attention.
    
      3.  The subset [2] shall be the "valid" flags, length modifiers, and
          conversion specifiers ("parts") accepted by this function.
          Those are defined in the following local function:
    
    	format_part_status
    
      4.  Parts known to be defined outside subset [3] shall generate a
          message stating such invalidity and giving a suitable
          alternative if possible (such parts will be called "obsolete");
          otherwise, the part shall be said to be "unsupported."
    
      5.  Parts seen by this function but not defined above shall be
          deemed "unknown" and result in a suitable message.
    
      6.  Library users of this function receiving "unknown" messages
          while attempting to use valid parts according to their O/S and
          compiler need to contact the BRL-CAD developers to resolve the
          issue.  Resolution should normally result in assigning the
          "unknown" part to one of the categories described in [4].
    
    */
    
    void
    bu_vls_vprintf(struct bu_vls *vls, const char *fmt, va_list ap)
    {
        const char *sp; /* start pointer */
        const char *ep; /* end pointer */
        int len;
    
        /* flag variables are reset for each fmt specifier */
        vflags_t f;
    
        char buf[BUFSIZ] = {0};
        int c;
    
        struct bu_vls fbuf = BU_VLS_INIT_ZERO; /* % format buffer */
        const char *fbufp  = NULL;
    
        if (UNLIKELY(!vls || !fmt || fmt[0] == '\0')) {
    	/* nothing to print to or from */
    	return;
        }
    
        BU_CK_VLS(vls);
    
        bu_vls_extend(vls, (unsigned int)_VLS_ALLOC_STEP);
    
        sp = fmt;
        while (*sp) {
    	/* Initial state:  just printing chars */
    	fmt = sp;
    	while (*sp != '%' && *sp)
         sp++;
    
    	if (sp != fmt)
         bu_vls_strncat(vls, fmt, (size_t)(sp - fmt));
    
    	if (*sp == '\0')
         break;
    
    	/* Saw a percent sign, now need to find end of fmt specifier */
    	/* All flags get reset for this fmt specifier */
    	reset_vflags(&f);
    
    	ep = sp;
    	while ((c = *(++ep))) {
    
         if (c == ' '
      || c == '#'
      || c == '+'
      || c == '.'
      || c == '\''
      || isdigit(c)) {
      /* need to set flags for some of these */
      if (c == '.') {
          f.have_dot = 1;
      } else if (isdigit(c)) {
          /* set flag for later error checks */
          f.have_digit = 1;
      }
      continue;
         } else if (c == '-') {
      /* the first occurrence before a dot is the
       left-justify flag, but the occurrence AFTER a dot is
       taken to be zero precision */
      if (f.have_dot) {
        f.precision  = 0;
        f.have_digit = 0;
      } else if (f.have_digit) {
          /* FIXME: ERROR condition?: invalid format string
             (e.g., '%7.8-f') */
          /* seems as if the fprintf man page is indefinite here,
             looks like the '-' is passed through and
             appears in output */
          ;
      } else {
          f.left_justify = 1;
      }
         } else if (c == '*') {
      /* the first occurrence is the field width, but the
         second occurrence is the precision specifier */
      if (!f.have_dot) {
          f.fieldlen = va_arg(ap, int);
          f.flags |= FIELDLEN;
      }
      else {
          f.precision = va_arg(ap, int);
          f.flags |= PRECISION;
      }
      /* all length modifiers below here */
         } else if (format_part_status(c) == (VP_VALID | VP_LENGTH_MOD)) {
      handle_format_part(VP_LENGTH_MOD, &f, c, VP_PRINT);
         } else {
      /* Anything else must be the end of the fmt specifier
         (i.e., the conversion specifier)*/
      break;
         }
    	}
    
    	/* libc left-justifies if there's a '-' char, even if the
      * value is already negative, so no need to check current value
      * of left_justify.
      */
    	if (f.fieldlen < 0) {
         f.fieldlen = -f.fieldlen;
         f.left_justify = 1;
    	}
    
    	/* Copy off this entire format string specifier */
    	len = ep - sp + 1;
    
    	/* intentionally avoid bu_strlcpy here since the source field
      * may be legitimately truncated.
      */
    	bu_vls_strncpy(&fbuf, sp, (size_t)len);
    	fbufp = bu_vls_addr(&fbuf);
    
    #ifndef HAVE_C99_FORMAT_SPECIFIERS
    	/* if the format string uses the %z or %t width specifier, we need to
      * replace it with something more palatable to this busted compiler.
      */
    
    	if ((f.flags & SIZETINT) || (f.flags & PTRDIFFT)) {
         char *fp = fbufp;
         while (*fp) {
      if (*fp == '%') {
          /* found the next format specifier */
          while (*fp) {
       fp++;
       /* possible characters that can precede the field
        * length character (before the type).
        */
       if (isdigit(*fp)
           || *fp == '$'
           || *fp == '#'
           || *fp == '+'
           || *fp == '.'
           || *fp == '-'
           || *fp == ' '
           || *fp == '*') {
           continue;
       }
       if (*fp == 'z' || *fp == 't') {
           /* assume MSVC replacing instances of %z or %t with
            * %I (capital i) until we encounter anything
            * different.
            */
           *fp = 'I';
       }
    
       break;
          }
          if (*fp == '\0') {
       break;
          }
      }
      fp++;
         }
    	}
    #endif
    
    	/* use type specifier to grab parameter appropriately from arg
        list, and print it correctly */
    	switch (c) {
         case 's':
      {
          /* variables used to determine final effects of
             field length and precision (different for
             strings versus numbers) */
          int minfldwid = -1;
          int maxstrlen = -1;
    
          char *str = va_arg(ap, char *);
    
          /* for strings only */
          /* field length is a minimum size and precision is
             max length of string to be printed */
          if (f.flags & FIELDLEN) {
       minfldwid = f.fieldlen;
          }
          if (f.flags & PRECISION) {
       maxstrlen = f.precision;
          }
          if (str) {
       int stringlen = (int)strlen(str);
       struct bu_vls tmpstr = BU_VLS_INIT_ZERO;
    
       /* use a copy of the string */
       bu_vls_strcpy(&tmpstr, str);
    
       /* handle a non-empty string */
       /* strings may be truncated */
       if (maxstrlen >= 0) {
           if (maxstrlen < stringlen) {
        /* have to truncate */
        bu_vls_trunc(&tmpstr, maxstrlen);
        stringlen = maxstrlen;
           } else {
        maxstrlen = stringlen;
           }
       }
       minfldwid = minfldwid < maxstrlen ? maxstrlen : minfldwid;
    
       if (stringlen < minfldwid) {
           /* padding spaces needed */
           /* start a temp string to deal with padding */
           struct bu_vls padded = BU_VLS_INIT_ZERO;
           int i;
    
           if (f.left_justify) {
        /* string goes before padding spaces */
        bu_vls_vlscat(&padded, &tmpstr);
           }
           /* now put in padding spaces in all cases */
           for (i = 0; i < minfldwid - stringlen; ++i) {
        bu_vls_putc(&padded, ' ');
           }
           if (!f.left_justify) {
        /* string follows the padding spaces */
        bu_vls_vlscat(&padded, &tmpstr);
           }
           /* now we can send the padded string to the tmp string */
           /* have to truncate it to zero length first */
           bu_vls_trunc(&tmpstr, 0);
           bu_vls_vlscat(&tmpstr, &padded);
    
           bu_vls_free(&padded);
       }
       /* now take string as is */
       bu_vls_vlscat(vls, &tmpstr);
    
       bu_vls_free(&tmpstr);
          } else {
       /* handle an empty string */
       /* FIXME: should we trunc to precision if > fieldlen? */
       if (f.flags & FIELDLEN) {
           bu_vls_strncat(vls, "(null)", (size_t)f.fieldlen);
       } else {
           bu_vls_strcat(vls, "(null)");
       }
          }
      }
      break;
         case 'V':
      {
          struct bu_vls *vp;
    
          vp = va_arg(ap, struct bu_vls *);
          if (vp) {
       BU_CK_VLS(vp);
       if (f.flags & FIELDLEN) {
           int stringlen = bu_vls_strlen(vp);
    
           if (stringlen >= f.fieldlen)
        bu_vls_strncat(vls, bu_vls_addr(vp), (size_t)f.fieldlen);
           else {
        struct bu_vls padded = BU_VLS_INIT_ZERO;
        int i;
    
        if (f.left_justify)
            bu_vls_vlscat(&padded, vp);
        for (i = 0; i < f.fieldlen - stringlen; ++i)
            bu_vls_putc(&padded, ' ');
        if (!f.left_justify)
            bu_vls_vlscat(&padded, vp);
        bu_vls_vlscat(vls, &padded);
           }
       } else {
           bu_vls_vlscat(vls, vp);
       }
          } else {
       if (f.flags & FIELDLEN)
           bu_vls_strncat(vls, "(null)", (size_t)f.fieldlen);
       else
           bu_vls_strcat(vls, "(null)");
          }
      }
      break;
         case 'e':
         case 'E':
         case 'f':
         case 'g':
         case 'G':
         case 'F':
      /* All floating point ==> "double" */
      {
          double d = va_arg(ap, double);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, d);
          else
       snprintf(buf, BUFSIZ, fbufp, d);
      }
      bu_vls_strcat(vls, buf);
      break;
         case 'o':
         case 'u':
         case 'x':
         case 'X':
      if (f.flags & LONG_INT) {
          /* Unsigned long int */
          unsigned long l = va_arg(ap, unsigned long);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, l);
          else
       snprintf(buf, BUFSIZ, fbufp, l);
      } else if (f.flags & LLONGINT) {
          /* Unsigned long long int */
          unsigned long long ll = va_arg(ap, unsigned long long);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, ll);
          else
       snprintf(buf, BUFSIZ, fbufp, ll);
      } else if (f.flags & SHORTINT || f.flags & SHHRTINT) {
          /* unsigned short int */
          unsigned short int sh = (unsigned short int)va_arg(ap, int);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, sh);
          else
       snprintf(buf, BUFSIZ, fbufp, sh);
      } else if (f.flags & INTMAX_T) {
          intmax_t im = va_arg(ap, intmax_t);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, im);
          else
       snprintf(buf, BUFSIZ, fbufp, im);
      } else if (f.flags & PTRDIFFT) {
          ptrdiff_t pd = va_arg(ap, ptrdiff_t);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, pd);
          else
       snprintf(buf, BUFSIZ, fbufp, pd);
      } else if (f.flags & SIZETINT) {
          size_t st = va_arg(ap, size_t);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, st);
          else
       snprintf(buf, BUFSIZ, fbufp, st);
      } else {
          /* Regular unsigned int */
          unsigned int j = (unsigned int)va_arg(ap, unsigned int);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, j);
          else
       snprintf(buf, BUFSIZ, fbufp, j);
      }
      bu_vls_strcat(vls, buf);
      break;
         case 'd':
         case 'i':
      if (f.flags & LONG_INT) {
          /* Long int */
          long l = va_arg(ap, long);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, l);
          else
       snprintf(buf, BUFSIZ, fbufp, l);
      } else if (f.flags & LLONGINT) {
          /* Long long int */
          long long ll = va_arg(ap, long long);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, ll);
          else
       snprintf(buf, BUFSIZ, fbufp, ll);
      } else if (f.flags & SHORTINT || f.flags & SHHRTINT) {
          /* short int */
          short int sh = (short int)va_arg(ap, int);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, sh);
          else
       snprintf(buf, BUFSIZ, fbufp, sh);
      } else if (f.flags & INTMAX_T) {
          intmax_t im = va_arg(ap, intmax_t);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, im);
          else
       snprintf(buf, BUFSIZ, fbufp, im);
      } else if (f.flags & PTRDIFFT) {
          ptrdiff_t pd = va_arg(ap, ptrdiff_t);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, pd);
          else
       snprintf(buf, BUFSIZ, fbufp, pd);
      } else if (f.flags & SIZETINT) {
          size_t st = va_arg(ap, size_t);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, st);
          else
       snprintf(buf, BUFSIZ, fbufp, st);
      } else {
          /* Regular int */
          int j = va_arg(ap, int);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, j);
          else
       snprintf(buf, BUFSIZ, fbufp, j);
      }
      bu_vls_strcat(vls, buf);
      break;
         case 'n':
         case 'p':
      /* all pointer == "void *" */
      {
          void *vp = (void *)va_arg(ap, void *);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, vp);
          else
       snprintf(buf, BUFSIZ, fbufp, vp);
      }
      bu_vls_strcat(vls, buf);
      break;
         case '%':
      bu_vls_putc(vls, '%');
      break;
         case 'c':
      {
          char ch = (char)va_arg(ap, int);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, ch);
          else
       snprintf(buf, BUFSIZ, fbufp, ch);
      }
      bu_vls_strcat(vls, buf);
      break;
         default:
      if (format_part_status(c) & VP_UNKNOWN) {
          fprintf(stderr, "ERROR: Unknown format character '%c'.\n", c);
      } else if (format_part_status(c) & VP_OBSOLETE) {
          handle_obsolete_format_char(c, VP_PRINT);
      } else {
          fprintf(stderr, "Unknown format character '%c'.\n", c);
          fprintf(stderr, "  Status flags: %x.\n", format_part_status(c));
          bu_bomb("ERROR: Shouldn't get here.\n");
      }
      /* try to get some kind of output, assume it's an int */
      {
          int d = va_arg(ap, int);
          if (f.flags & FIELDLEN)
       snprintf(buf, BUFSIZ, fbufp, f.fieldlen, d);
          else
       snprintf(buf, BUFSIZ, fbufp, d);
      }
      bu_vls_strcat(vls, buf);
      break;
    	}
    	sp = ep + 1;
        }
    
        va_end(ap);
    
        bu_vls_free(&fbuf);
    }

  5. #5
    Registered User
    Join Date
    Nov 2011
    Location
    Buea, Cameroon
    Posts
    197
    this code is quite huge but the latter part of the code has the bu_vls_printf() routine.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Without a specific test case which is troubling you, I've no interest in wading through 1000 lines of code just to guess at what your issue might be.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Nov 2011
    Location
    Buea, Cameroon
    Posts
    197
    ok yeah its an opensource project and its one of the bugs reported by other developers and users in the bug file so i'm jst trying to figure out where exactly the problem might be occuring..Thats the thing. so any head up on how to narrow down the problem quickly?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Yes, you post something like

    I call it with
    bu_log("%05d",123);

    I expect to see
    00123

    what I actually see is
    banana
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Nov 2011
    Location
    Buea, Cameroon
    Posts
    197
    ok thanks salem working on a test like that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. printf field width
    By mashour06 in forum C Programming
    Replies: 1
    Last Post: 02-28-2012, 09:36 AM
  2. printf format specifier padding
    By Blasz in forum C Programming
    Replies: 3
    Last Post: 07-08-2010, 11:26 PM
  3. Setting width in printf with a #define macro?
    By noobiept in forum C Programming
    Replies: 6
    Last Post: 06-25-2010, 07:25 AM
  4. multiply sections of printf format specifier?
    By space_ferret in forum C Programming
    Replies: 14
    Last Post: 03-27-2009, 10:54 AM
  5. How to get text to align left when using width(X)
    By Darksbane in forum C++ Programming
    Replies: 4
    Last Post: 11-29-2001, 09:25 AM