Re: [Boston.pm] boost::format to sprintf, or how do I get a substitution with a substitution in it?

2015-04-04 Thread Gyepi SAM
On Fri, Apr 03, 2015 at 09:48:22PM -0500, Greg London wrote:
 Cool!  15 years of perl and I never used /e
 
 I got the regexp to convert the first file
 and discovered that sprintf is way more inconvenient
 than I remember. It doesn't return the string,
 it returns pass/fail. And it operates on char* ?
 
 This may have been why I used boost::format.
 
 Anyone know of a c++ self contained function that takes
 a format string and returns the result string
 rather than using char*'s and returning the value in
 a char*?

I ran into this problem with C code some time ago.

sprintf and friends do not return the string because that would require
them to allocate the memory for the string, which raises difficult
questions of ownership and memory management.

Instead, you are expected to pre-allocate the memory and pass it in as
a char * argument so sprintf can write to it.

But how do you know how big to make the string? The basic idea is to
call snprintf with a zero length value and it will tell you how big the
string should be so you can make a second call with the correct length.
It works, but is annoying. I suspect most programmers write utility code
to abstract this stuff away.

Here's the code I wrote back then to solve the problem, it's extracted from
my util library so there are references to other util or application
functions but they are pretty obvious. Note that you are expected to
deallocate the string after use.

char *
xvstrfmt (const char *fmt, va_list args)
{
  int size = 0;

  char *str = NULL;

  int n;

  for (;;) {

n = vsnprintf (str, size, fmt, args);

if (n == -1) {
  fatal_sys (vsnprintf);
}
else if (n  size) {
  return str;
}
else {
  size = n + 1;
  str = xrealloc (str, size);
}
  }

  return NULL;
}

char *
xstrfmt (const char *fmt, ...)
{
  va_list args;

  char *str;

  va_start (args, fmt);
  str = xvstrfmt (fmt, args);
  va_end (args);

  return str;
}

-Gyepi

___
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm


Re: [Boston.pm] boost::format to sprintf, or how do I get a substitution with a substitution in it?

2015-04-04 Thread Mike Small
Greg London em...@greglondon.com writes:

 Cool!  15 years of perl and I never used /e

 I got the regexp to convert the first file
 and discovered that sprintf is way more inconvenient
 than I remember. It doesn't return the string,
 it returns pass/fail. And it operates on char* ?

 This may have been why I used boost::format.

 Anyone know of a c++ self contained function that takes
 a format string and returns the result string
 rather than using char*'s and returning the value in
 a char*?

The boost::format documentation and the following stack overflow thread
refer to a library by James Kanze and John Dibling that pre-dates
Boost::Format, but I can't find it with a quick look. Kanze is not
enthusiastic about it in his comment, so perhaps he retracted it, but
maybe you can track it down:

http://stackoverflow.com/questions/16696165/any-library-that-does-printf-on-a-c-stream

Aside from the above problem with sprintf, I'd be worried about type
errors. e.g. boost::format's %s I'm guessing could take a corresponding
std::string arg as is, but if you convert that directly you'll blow away
your stack, sprintf expecting a char* not a std::string when it sees
%s. You could make sure to put .c_str() after, but what other implicit
type conversions might be lurking that won't be done by sprintf?

What about converting to std::ostringstream instead?

-- 
Mike Small
sma...@panix.com

___
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm


[Boston.pm] boost::format to sprintf, or how do I get a substitution with a substitution in it?

2015-04-03 Thread Greg London
I've got a rather largish pile of c++ code that makes a lot of calls to
boost::format. I'm having trouble compiling the code on my FPGA platform
(can't figure out how to install boost::format into the tool flow). So, I
thought maybe I'd try to do a perl script to convert all the files to use
sprintf.

So I need to convert
(format(blah %s de %d bleh) % expression1 % expression2 ).str()

to
sprintf(blah %s de %d bleh, expression1 , expression2 )

A single format() call might span multiple lines,
so I figured I'd slurp all the text in at once
and do a search and replace. There might be more
than one occurrence per file, so I'd add the /g modifier.

s/format\((.*?)\)(.*?)\.str\(\)/something/g

The problem is I need $1 and $2 to put into sprintf
but I before I do that, I also need to take the '%'
operators in $2 and replace them with ',' and THEN
put it back in.

Things started to get hairy, and I was wondering
if I'm overlooking a solution that would make this
a lot easier.






___
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm


Re: [Boston.pm] boost::format to sprintf, or how do I get a substitution with a substitution in it?

2015-04-03 Thread Bill Ricker
 . It doesn't return the string,
 it returns pass/fail. And it operates on char* ?

 This may have been why I used boost::format.

 Anyone know of a c++ self contained function that takes
 a format string and returns the result string
 rather than using char*'s and returning the value in
 a char*?

There may be a variant ? Check top and bottom of the man 3.

___
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm


Re: [Boston.pm] boost::format to sprintf, or how do I get a substitution with a substitution in it?

2015-04-03 Thread Uri Guttman

On 04/03/2015 08:59 PM, Greg London wrote:

s/format\((.*?)\)(.*?)\.str\(\)/something/g

The problem is I need $1 and $2 to put into sprintf
but I before I do that, I also need to take the '%'
operators in $2 and replace them with ',' and THEN
put it back in.

Things started to get hairy, and I was wondering
if I'm overlooking a solution that would make this
a lot easier.


the /e modifier is your friend. just put the logic to transform the $2 
into the replacement section and s/// will use the value of the 
expression for its replacement. if the code gets too long for the 
replacement part, call out to a sub instead. for a working example with 
the sub, look at Template::Simple which uses s///e to replace template 
markup with recursed calls to the same sub.


uri


___
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm