Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #26461

Re: Problem with printf-like logging framework and inline hexdumps.

From Kaz Kylheku <kaz@kylheku.com>
Newsgroups comp.lang.c
Subject Re: Problem with printf-like logging framework and inline hexdumps.
Date 2012-09-17 06:39 +0000
Organization Aioe.org NNTP Server
Message-ID <20120916231327.103@kylheku.com> (permalink)
References (2 earlier) <k2tk9f$1k4$1@speranza.aioe.org> <0.0d6e7c2b5d0bb3a4be5a.20120913235432BST.87sjalh6tz.fsf@bsb.me.uk> <k2vm54$ugp$1@speranza.aioe.org> <0.c3d5c8305e29bcc05411.20120914220219BST.87obl8fhd0.fsf@bsb.me.uk> <0.8f649757be2c6e10d580.20120914224958BST.87ipbgff5l.fsf@bsb.me.uk>

Show all headers | View raw


On 2012-09-14, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
><snip>
>> There may be no correct va_start/va_copy/va_end pattern that works.  If
>> so, that's a great shame, but it was presumably unavoidable.  I can't
>> believe this old trick was ruled un-portable without it having to be so
>> ruled.  I'll give it some more thought...
>
> I have thunk and I think there is no suitable pattern of
> va_start/va_copy/va_end calls that will work.
>
> This means that the only way to add your own formats (portably) is to
> keep a synchronised copy of the va_list: you duplicate it at the start,
> and you duplicate the current state when you call vprintf to process one
> or more of its formats.  When vprintf returns, you must scan the format
> and execute the same va_args calls the vprintf will have used.
>
> That makes it much more fiddly because of all the types that might be
> involved.  And to do this requires actually parsing the format
> specifiers which is not trivial.

It's a piece of cake. And anyway, you don't have to support everything
in printf. If you require yourself to do a complete, perfect job,
that's a good way to get out of getting anything done.

I've used this in projects past, just for quick and dirty debugging,
not part of any permanent framework. 

It's not a complete solution but it could be massaged into one.

For instance, note how it assumes that only one argument is consumed
by printf, and it just eats a void *.  This worked on the target platforms
I was working on, where I was using mostly %d and %s arguments.

It also doesn't handle variable widths and precisions (* character).

These things would not be very hard to add.  You need to add some
sophistication to the parser, which has to produce some info in a bunch of
local variables: number of stars which occured (to consume that many ints)
and the type of the argument  (requiring a switch statement to various
va_arg calls).

int hexprintf(const char *fmt, ...)
{
   int ch, count = 0;
   va_list vl;

   va_start (vl, fmt);

   for (ch = *fmt++; ch != 0; ch = *fmt++) {
      switch (ch) {
      case '%': /* printf conversion */
         {
            /* regular printf conversion */
            char conv[64] = "%";
            const char *end = fmt;
            va_list vl_copy;

            va_copy (vl_copy, vl);

            end += strspn(end, "#0-+ "); /* skip flags */
            end += strspn(end, "0123456789*"); /* skip precision */
            if (*end == '.') /* skip precision */
               end += 1 + strspn(end + 1, "0123456789*");

            /* skip length */
            if (strncmp(end, "hh", 2) == 0)
               end += 2;
            else if (strncmp(end, "ll", 2) == 0)
               end += 2;
            else if (strspn(end, "hlLqjzt") > 0)
               end += 1;

            if (*end == '@') {
               /* our hex conversion */
               const unsigned char *data = va_arg (vl, unsigned char *);
               int i, size = va_arg (vl, int);
              
               for (i = 0; i < size; i++) {
                  count += printf("%02x", (unsigned int) data[i]);
                  if (i < size - 1) {
                     putchar(' ');
                     count++;
                  }
               }
            } else {
               /* copy and call printf */
               memcpy(conv + 1, fmt, end - fmt + 1);
               count += vprintf(conv, vl_copy);
               va_end (vl_copy);
               va_arg (vl, void *);
            }
            fmt = end + 1;
         }
         break;
      default:
         putchar(ch);
         count++;
         break;
      }
   }

   va_end (vl);
   return count;
}

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Problem with printf-like logging framework and inline hexdumps. Jef Driesen <jefdriesen@hotmail.com.invalid> - 2012-09-13 18:11 +0200
  Re: Problem with printf-like logging framework and inline hexdumps. "Heinrich Wolf" <invalid@invalid.invalid> - 2012-09-13 18:55 +0200
    Re: Problem with printf-like logging framework and inline hexdumps. Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-09-20 17:19 +0000
  Re: Problem with printf-like logging framework and inline hexdumps. Barry Schwarz <schwarzb@dqel.com> - 2012-09-13 11:26 -0700
    Re: Problem with printf-like logging framework and inline hexdumps. Jef Driesen <jefdriesen@hotmail.com.invalid> - 2012-09-14 00:06 +0200
  Re: Problem with printf-like logging framework and inline hexdumps. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-09-13 21:24 +0100
    Re: Problem with printf-like logging framework and inline hexdumps. Jef Driesen <jefdriesen@hotmail.com.invalid> - 2012-09-13 23:47 +0200
      Re: Problem with printf-like logging framework and inline hexdumps. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-09-13 23:54 +0100
        Re: Problem with printf-like logging framework and inline hexdumps. Jef Driesen <jefdriesen@hotmail.com.invalid> - 2012-09-14 18:31 +0200
          Re: Problem with printf-like logging framework and inline hexdumps. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-09-14 22:02 +0100
            Re: Problem with printf-like logging framework and inline hexdumps. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-09-14 22:49 +0100
              Re: Problem with printf-like logging framework and inline hexdumps. Jef Driesen <jefdriesen@hotmail.com.invalid> - 2012-09-17 07:09 +0200
              Re: Problem with printf-like logging framework and inline hexdumps. Kaz Kylheku <kaz@kylheku.com> - 2012-09-17 06:39 +0000
                Re: Problem with printf-like logging framework and inline hexdumps. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-09-17 13:30 +0100
      Re: Problem with printf-like logging framework and inline hexdumps. Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-09-14 03:29 -0700
        Re: Problem with printf-like logging framework and inline hexdumps. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-09-14 12:01 +0100
  Re: Problem with printf-like logging framework and inline hexdumps. Jef Driesen <jefdriesen@hotmail.com.invalid> - 2012-09-14 22:50 +0200

csiph-web