Silvio: What do you mean by „I can’t use vsnprintf(NULL, 0, fmt, args) on Pascal because it frees the arguments”? What frees what arguments?
Would it help to use “char buffer[1]; vsnprintf(buffer, sizeof(buffer), fmt, args)”? (It still ought to return the total size you need). I’m not sure that passing NULL as the buffer is legal (even when the count is zero). Also beware: I have a feeling that Visual Studio 2015 handles vsnprintf correctly for overflow (in that it always nul-terminates), but earlier versions do not. Of course, if you are going to go round again and just allocate a large enough buffer, that doesn’t matter. Von: [email protected] [mailto:[email protected]] Im Auftrag von silvioprog Gesendet: Montag, 29. Februar 2016 19:10 An: libmicrohttpd development and user mailinglist <[email protected]> Betreff: Re: [libmicrohttpd] Can I get the entire MHD log without depends on C function like sprintf()? Hello Christian, thanks for answer. :-) You are right, it seems the best solution in this case. I'll refactore the function and share it here ASAP. I still have a doubt, on Windows I can use the _vscprintf function to calculate the size of the buffer, but Linux doesn't have this function, and I can't use vsnprintf(NULL, 0, fmt, args) on Pascal because it frees the arguments, so is the 1024 a good buffer size when you can't calculate it automatically? If so, I'll start loading the buffer with size 1024 and re-set it to the _vsnprintf_s result length at the end. Hi Silvio, I understand what you are asking for, but I'm not terribly inclined to do so. For starters, this would break ABI compatibility, which is not a nice thing. Also, allocating the string buffer (like you do) on the stack may not be OK for some applications -- stacks on some OSes can be very tiny, and 1k may be too much. OTOH, truncating log messages is also bad. So the current solution offers the most flexibility. Furthermore, I don't quite see what's so weird about your solution. The code is pretty straightforward to read, and "it works". Breaking our ABI so that Delphi can safe 4 lines of code because it's not C-compatible is not a good trade-off in my mind. Still, I think sharing this here is useful, as others may have the same question in the future, and I actually think your solution is great. Happy hacking! Christian On 02/27/2016 09:14 PM, silvioprog wrote: > Hello, > > I'm using MHD in a small application written in Delphi (Pascal), and it is > working like a charm. Today I needed to get all generated log from MHD, > however it seems that it depends on functions like *sprintf(), but the > Pascal Format() function is a little bit different from C, because the > Pascal ones use other format style. And the other problem is that Delphi > and Free Pascal don't have this function on their RTL, so I did something > like: > > function vsnprintf_s(buffer: Pcchar; sizeOfBuffer: size_t; count: size_t; > format: Pcchar; argptr: va_list): cint; cdecl; > external LIB_NAME name {$IFDEF > MSWINDOWS}'_vsnprintf_s'{$ELSE}'vsnprintf_s'{$ENDIF}; > > procedure ErrorLog(ACls: Pointer; AFmt: Pcchar; AArgs: va_list); cdecl; > var > S: RawByteString; > VBuffer: array[0..1024] of AnsiChar; > begin > SetString(S, VBuffer, vsnprintf_s(VBuffer, SizeOf(VBuffer), > Length(VBuffer), > AFmt, AArgs)); > SetCodePage(S, CP_UTF8, False); > MyLogger.Append(S); > end; > > It works, but it seems a very weird solution, so can I get the entire > generated MHD log in a *char? In pure C code, something like: > > void error_log(void *cls, char *log) { > printf("%s", log); > } > > Instead of: > > void error_log(void *cls, char *fmt, va_list args) { > vprintf(fmt, args); > } > > It would be very useful to the ones that need to get the entire log without > depends on C format functions. > > Thank you! >
