[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] Can I get the entire MHD log without depends on C fu

From: Martin Bonner
Subject: Re: [libmicrohttpd] Can I get the entire MHD log without depends on C function like sprintf()?
Date: Tue, 1 Mar 2016 07:57:29 +0000

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: libmicrohttpd-bounces+address@hidden [mailto:libmicrohttpd-bounces+address@hidden Im Auftrag von silvioprog
Gesendet: Montag, 29. Februar 2016 19:10
An: libmicrohttpd development and user mailinglist <address@hidden>
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!


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!

reply via email to

[Prev in Thread] Current Thread [Next in Thread]