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


Groups > comp.lang.c > #94453

Re: When parameters to printf are in memory

From James Harris <james.harris.1@gmail.com>
Newsgroups comp.lang.c
Subject Re: When parameters to printf are in memory
Date 2016-10-04 20:31 +0100
Organization A noiseless patient Spider
Message-ID <nt101m$qn2$1@dont-email.me> (permalink)
References (5 earlier) <nsjvj1$4c2$1@dont-email.me> <nsk1e9$ai1$1@dont-email.me> <nsk3ic$kh3$1@dont-email.me> <nsmcbv$2cc$1@dont-email.me> <449b9df4-6dda-8898-f9a3-2aa389d36eb3@verizon.net>

Show all headers | View raw


On 04/10/2016 19:25, James R. Kuyper wrote:
> On 09/30/2016 02:53 PM, James Harris wrote:
>> On 29/09/2016 23:11, BartC wrote:
> ...
>>> If the format string is:
>>>
>>>    "(%2d-%2d-%4d)"
>>>
>>> and you start at the first "(", should it stop on (but not including)
>>> the first "-", or at the second "%"? And how to make it do that.
>>
>> Why not:
>>
>> - copy the literal "(" into the output
>> - copy "%2d" into a 'format buffer' and terminate it
>> - call snprintf using that buffer
>>
>> and then repeat the process for the rest of the string?
>>
>>> There might be some hairy methods of doing this: copying the format
>>> string, detecting the start of a format (first "%"), skipping to the
>>> start of the next "%", temporarily putting a null there, calling
>>> snprintf on the first bit, then restoring the second "%" and repeating
>>> with the next bit. With special handling for "%%" and for the last
>>> format.
>>
>> If I omit the size checking for now, how about something like this:
>>
>>    for (;;) { /* Each pair of non-format, format */
>>
>>      /* Copy normal characters straight to the output buffer */
>>      while (*src != '%' && *src != '\0') {
>>        *dest++ = *src++;
>>      }
>>      if (*src == '\0') {
>>        break;
>>      }
>>
>>      /* Copy the format string (starting with %) to a format buffer */
>>      format = format_buffer;
>>      *format++ = *src++;
>>      if (*src == '%') { /* If the source has %% */
>>        *dest++ = '%';
>>      }
>>      else { /* A single percent sign, i.e. starting a format spec */
>>        for (;;) { /* Until a terminating character */
>>          ch = *src++;
>>          if (ch == '\0') ....error....;
>>          *format++ = ch;
>>          if (ch ....is one of the terminating characters....) break;
>>        }
>>        *format = '\0';
>>
>>        /* Format an argument */
>>        bytes = sprintf(dest, format, ....current arg ++....);
>
> "current arg ++" is a syntax error unless either "current" or "arg" is a
> macro of some kind. I'm not sure what, precisely, it's supposed to mean.
> I wouldn't think you want to increment the argument itself. I can
> imagine that you might want to increment a pointer to the current
> argument, but it's the value of that argument that you need to pass to
> sprintf().
> I'm not sure I understand all of the "...." in your call to sprintf() -
> ordinarily, I'd interpret that as shorthand indicating that your
> sprintf() call has other arguments that you're not bothering to specify,
> in addition to the ones you've shown explicitly.

Yes, that was the idea. The code was meant only to outline the suggested 
approach. I recognise that the code would need to use the right member 
of the union.

> However, if I
> understand your code properly, the format string contains only a single
> format specifier extracted from the src string. Unless that format
> specifier contains a field width or precision specification of "*"
> (which your code does not seem designed to handle), then, as I
> understand it, your sprintf() call should have exactly three arguments.
>
> In the context of your original message, my best guess is that you meant
> something like the following:
>
>    union any {
>        int i;
>        long l;
>        long long ll;
>        double d;
>        long double ld;
>        // etc.
>    };
>    struct {
>        char *text;
>        union any parms[];
>    } *p = malloc(sizeof *p + 5*sizeof *p->parms);
>    // Error handling if p is null
>
>    p->text = "array[%d][%ld][%lld] = %f - %lf\n";
>    p->parms[0].i = 1;
>    p->parms[1].l = 2L;
>    p->parms[2].ll = 3LL;
>    p->parms[3].d = 4.0;
>    p->parms[4].ld = 5.0L;
>
>    union any *current_arg = p->parms;

Exactly.

>
>    ...
>
>    bytes = sprintf(dest, format, *current_arg++);

I hadn't bottomed out the third argument part. I was thinking it would 
be similar to the va_arg mechanism of having to supply the type. But 
that's all.

As you went on to say (snipped) I can see I would have to supply the 
type by referring to the correct member of the union, and that would 
require recognition of the type code used in the format string. Easy for 
single character type codes but awkward when size modifiers are involved.

I will maybe come back to this in C. For the time being I have written 
the app that this mechanism was to support in <heresy>Python</heresy>! 
It has each object know how to render an instance of itself as text. And 
that conversion gets invoked automatically if the format string has %s. 
It will do for now.


-- 
James Harris

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


Thread

When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-29 16:20 +0100
  Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-29 16:43 +0100
    Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-29 20:30 +0100
    Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-29 21:23 +0100
    Re: When parameters to printf are in memory BartC <bc@freeuk.com> - 2016-09-29 22:03 +0100
      Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-29 22:35 +0100
        Re: When parameters to printf are in memory BartC <bc@freeuk.com> - 2016-09-29 23:11 +0100
          Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-30 19:53 +0100
            Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-30 20:53 +0100
              Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-01 09:08 +0100
                Re: When parameters to printf are in memory BartC <bc@freeuk.com> - 2016-10-01 11:15 +0100
                Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-04 08:32 +0100
                Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-01 11:15 +0100
                Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-04 08:28 +0100
                Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-04 09:49 +0100
                Re: When parameters to printf are in memory BartC <bc@freeuk.com> - 2016-10-04 11:43 +0100
                Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-04 13:42 +0100
                Re: When parameters to printf are in memory BartC <bc@freeuk.com> - 2016-10-04 14:03 +0100
                Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-04 14:16 +0100
                Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-04 20:01 +0100
                Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-04 20:24 +0100
                Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-04 20:40 +0100
                Re: When parameters to printf are in memory Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-04 22:51 +0100
            Re: When parameters to printf are in memory "James R. Kuyper" <jameskuyper@verizon.net> - 2016-10-04 14:25 -0400
              Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-04 20:31 +0100
  Re: When parameters to printf are in memory BartC <bc@freeuk.com> - 2016-09-29 17:03 +0100
    Re: When parameters to printf are in memory gazelle@shell.xmission.com (Kenny McCormack) - 2016-09-30 12:20 +0000
      Re: When parameters to printf are in memory Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-30 05:55 -0700
      Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-30 20:06 +0100
        Re: When parameters to printf are in memory gazelle@shell.xmission.com (Kenny McCormack) - 2016-09-30 22:01 +0000
          Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-01 09:15 +0100
        Re: When parameters to printf are in memory Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-30 23:18 -0700
          Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-01 09:32 +0100
  Re: When parameters to printf are in memory jacobnavia <jacob@jacob.remcomp.fr> - 2016-09-29 18:35 +0200
    Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-29 19:55 +0100
      Re: When parameters to printf are in memory jacobnavia <jacob@jacob.remcomp.fr> - 2016-09-29 21:22 +0200
  Re: When parameters to printf are in memory Barry Schwarz <schwarzb@dqel.com> - 2016-09-29 11:20 -0700
    Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-09-29 20:08 +0100
  Re: When parameters to printf are in memory Lőrinczy Zsigmond <nospam@for.me> - 2016-10-02 20:15 +0200
    Re: When parameters to printf are in memory Lőrinczy Zsigmond <nospam@for.me> - 2016-10-02 20:19 +0200
      Re: When parameters to printf are in memory gazelle@shell.xmission.com (Kenny McCormack) - 2016-10-02 18:29 +0000
        Re: When parameters to printf are in memory Lőrinczy Zsigmond <nospam@for.me> - 2016-10-03 07:04 +0200
          Re: When parameters to printf are in memory James Harris <james.harris.1@gmail.com> - 2016-10-04 08:36 +0100
    Re: When parameters to printf are in memory jacobnavia <jacob@jacob.remcomp.fr> - 2016-10-02 21:27 +0200

csiph-web