Re: [Boston.pm] boost::format to sprintf, or how do I get a substitution with a substitution in it?
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?
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?
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?
. 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?
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