From: SourceForge.net <no...@so...> - 2008-08-13 14:27:53
|
Patches item #2016112, was opened at 2008-07-11 10:59 Message generated for change (Comment added) made by earnie You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=302435&aid=2016112&group_id=2435 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: runtime Group: None Status: Open Resolution: None Priority: 5 Private: No Submitted By: Keith Marshall (keithmarshall) Assigned to: Keith Marshall (keithmarshall) Summary: Make ALL *printf() functions deliver consistent output Initial Comment: This submission supersedes or augments: https://sourceforge.net/tracker/index.php?func=detail&aid=1983559&group_id=2435&atid=302435 https://sourceforge.net/tracker/index.php?func=detail&aid=1985560&group_id=2435&atid=302435 I've created an alternative implementation for the printf() format interpreter, to replace the current mingw_snprintf.c; this is accompanied by API wrappers for ALL of the *printf() functions, so delivering consistent output from the entire family, whether writing to streams or to process memory (strings). I've attached both source, and a prebuilt library, libprintf.a, which may be linked ahead of libmingwex.a, to access this alternative implementation. The source tarball includes a rudimentary test suite; please feel free to add additional test cases, and report any bugs you might uncover. In writing this, I've attempted to maintain consistency with MSVCRT output, except where C99/POSIX mandate differently; I have also included, as does mingw_snprintf.c, support for BOTH the Microsoft and the C99/POSIX format conversion specifiers. I've retained the Microsoft convention of at least three exponent digits in floating point conversions, but I've also provided an environment variable hook, such that users may set PRINTF_EXPONENT_DIGITS=2, if they prefer the C99/POSIX style; (I've also coded in support for _get_output_format(), if -D__MSVCRT_VERSION__=0x800, or greater, is added to the CFLAGS, when building this library code, and subsequently linking with a newer MSVCRT version). At present, I have not prepared a final patch, for integration into libmingwex.a; before that can happen, agreement is required on the following: As currently written, integration of these replacement functions into libmingwex.a will deny users access to the similarly named MSVCRT functions, for all but _snprintf() and _vsnprintf(), (for which the paradigm of mingw_snprintf.c will continue to apply). Possibly, this isn't a great loss, since I've taken care to maintain close consistency with MSVCRT behaviour, except in the reporting of infinities and NaNs; however, no doubt there are some who will perceive this as a major issue. To circumvent this, I can see two possible approaches:-- 1) Do not integrate into libmingwex.a, but offer this as a free standing libprintf.a (say), which users could explicitly link to gain the new behaviour, or omit to retain the current status quo. 2) Provide an alternative mechanism for accessing the MSVCRT functions; (I am uncertain how to implement this, but Danny has suggested that it should be possible). ---------------------------------------------------------------------- >Comment By: Earnie Boyd (earnie) Date: 2008-08-13 10:27 Message: Logged In: YES user_id=15438 Originator: NO >> Comment By: Keith Marshall (keithmarshall) > Date: 2008-08-12 22:48 > > Message: > Logged In: YES > user_id=823908 > Originator: YES > > I've now committed all of my replacement C sources, with names analogous > to: > > __mingw_printf() /* for the replacement function */ > __msvcrt_printf() /* for guaranteed reference to the MSVCRT function > */ > I prefer these to > If we subsequently decide to make these: > > __mingw_ansi_printf() /* for the replacement function */ > __mingw_msvcrt_printf() /* for the MSVCRT function */ > these. Let's go with the former for now and if we find issues we can modify then. > then it will not be too onerous to change. However, while I'm not opposed > to such a change, I do not want to proceed without consensus on the effect > on e.g. __mingw_snprintf(), which for consistency, should then be > deprecated in favour of __mingw_ansi_snprintf(); (I'd hoped Danny might > have an opinion to express on this point). > I agree and would like to hear from Danny as well. > The final step, to complete this implementation, requires some > modifications to stdio.h. Attached includes.diff.gz illustrates how I > propose to achieve this; (on the basis that _mingw.h is our equivalent of > glibc's features.h, I've added some __MINGW_FEATURES__ activation logic to > that too). > Comments on the file in previous post. > Ok to commit, (with an appropriate ChangeLog, of course)? > File Added: includes.diff.gz > Not yet, but close. ---------------------------------------------------------------------- Comment By: Earnie Boyd (earnie) Date: 2008-08-13 10:23 Message: Logged In: YES user_id=15438 Originator: NO The include file comments: 1) The aesthetic tabbing is off for the __MINGW_LC*__ definitions. 2) Should the *_VERSION macros be toward the top of the file? I think I would rather see that but will not push the issue. 3) The code changes look good to me. ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-08-12 18:48 Message: Logged In: YES user_id=823908 Originator: YES I've now committed all of my replacement C sources, with names analogous to: __mingw_printf() /* for the replacement function */ __msvcrt_printf() /* for guaranteed reference to the MSVCRT function */ If we subsequently decide to make these: __mingw_ansi_printf() /* for the replacement function */ __mingw_msvcrt_printf() /* for the MSVCRT function */ then it will not be too onerous to change. However, while I'm not opposed to such a change, I do not want to proceed without consensus on the effect on e.g. __mingw_snprintf(), which for consistency, should then be deprecated in favour of __mingw_ansi_snprintf(); (I'd hoped Danny might have an opinion to express on this point). The final step, to complete this implementation, requires some modifications to stdio.h. Attached includes.diff.gz illustrates how I propose to achieve this; (on the basis that _mingw.h is our equivalent of glibc's features.h, I've added some __MINGW_FEATURES__ activation logic to that too). Ok to commit, (with an appropriate ChangeLog, of course)? File Added: includes.diff.gz ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-30 10:11 Message: Logged In: YES user_id=823908 Originator: YES Thanks Earnie, > I do think there would be more confusion over > __mingw_msvcrt_printf() than there would be namespace > clashes with just __msvcrt_printf(). But if you go with > __mingw_msvcrt_printf() then we must use > __mingw_ansi_printf() in my opinion > to help the confusion factor. So far, I've committed to CVS as just __msvcrt_printf(), and friends; obviously, it's easiest for me to just leave it like that. However, I'd really appreciate other opinions on this; on current vote of 2-to-1, I'm not going to change it, but my own vote isn't 100% decisive. I agree that, if it is to be changed, then the alternative must be __mingw_ansi_printf(), and friends; for consistency that would also mandate deprecation of the existing __mingw_snprintf() and __mingw_vsnprintf(), (both of which I've now implemented using the new pformat() interpreter), in favour of __mingw_ansi_snprintf() and __mingw_ansi_vsnprintf(). > While I have no real opinion over __MINGW_FEATURES__ vs > __MINGW_ALTERNATIVES__ I think your idea here is good; it > may not be the right time though. Is it possible for the > added features here are for a different patch? I'd expect the details to evolve over a number of (unrelated) patches. However, the basic infrastructure needs to be set up now, so stdio.h can establish appropriate defines for the alternative printf() implementations. Until we establish some consensus on the way forward, for all of the above, I'll have to put this patch on hold. ---------------------------------------------------------------------- Comment By: Earnie Boyd (earnie) Date: 2008-07-30 09:20 Message: Logged In: YES user_id=15438 Originator: NO >> Comment By: Keith Marshall (keithmarshall) > Date: 2008-07-30 11:27 > > Message: > Logged In: YES > user_id=823908 > Originator: YES > > Ok Aaron, > > Your concern about leaking implementation specific symbols which we > define, outside of a MinGW specific namespace, is valid. My reservation > about this is that `__mingw_msvcrt_printf()' vs. `__mingw_printf()' might > convey an impression that the former is a more advanced implementation than > the latter; (maybe it is, if you consider Microsoft's predilection for > standards violation to be more advanced than a conforming implementation). > But, maybe we should address this from the opposite direction? > `__mingw_msvcrt_printf()' vs. `__mingw_ansi_printf()' say? Or maybe I'm > just being unnecessarily pernickety? > I don't think it is unnecessary. I do think there would be more confusion over __mingw_msvcrt_printf() than there would be namespace clashes with just __msvcrt_printf(). But if you go with __mingw_msvcrt_printf() then we must use __mingw_ansi_printf() in my opinion to help the confusion factor. > Regarding __MINGW_ALTERNATIVES__, I like the concept, but I'd like to > suggest __MINGW_FEATURES__ as an alternative name; I'm thinking that one > alternative compilation unit could support two or more independent > features, such as > http://mingw.cvs.sourceforge.net/mingw/catgets/repl/setlocale.c?view=annotate > for example, (which, in its associated header, aims to define > MINGW_LC_MESSAGES and MINGW_LC_ENVVARS as two independently supportable > features in user code; I'm not sure how well it achieves it). > > If we define __MINGW_FEATURES__ as a bitmap, with manifests for the > individual features, e.g. > > #define __MINGW_ANSI_STDIO__ 0x0000000000000001ULL > ... > #define __MINGW_LC_MESSAGES__ 0x0000000000000010ULL > #define __MINGW_LC_ENVVARS__ 0x0000000000000040ULL > ... > > then the user can specify an appropriate > `-D__MINGW_FEATURES__=<value_for_features_I_want>', (possibly as a specs > file inclusion), and we can use tests of the form > > #if __MINGW_FEATURES__ & __MINGW_ANSI_STDIO__ > ... > #endif > > to set up the preprocessor environment as appropriate. While I have no real opinion over __MINGW_FEATURES__ vs __MINGW_ALTERNATIVES__ I think your idea here is good; it may not be the right time though. Is it possible for the added features here are for a different patch? ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-30 07:27 Message: Logged In: YES user_id=823908 Originator: YES Ok Aaron, Your concern about leaking implementation specific symbols which we define, outside of a MinGW specific namespace, is valid. My reservation about this is that `__mingw_msvcrt_printf()' vs. `__mingw_printf()' might convey an impression that the former is a more advanced implementation than the latter; (maybe it is, if you consider Microsoft's predilection for standards violation to be more advanced than a conforming implementation). But, maybe we should address this from the opposite direction? `__mingw_msvcrt_printf()' vs. `__mingw_ansi_printf()' say? Or maybe I'm just being unnecessarily pernickety? Regarding __MINGW_ALTERNATIVES__, I like the concept, but I'd like to suggest __MINGW_FEATURES__ as an alternative name; I'm thinking that one alternative compilation unit could support two or more independent features, such as http://mingw.cvs.sourceforge.net/mingw/catgets/repl/setlocale.c?view=annotate for example, (which, in its associated header, aims to define MINGW_LC_MESSAGES and MINGW_LC_ENVVARS as two independently supportable features in user code; I'm not sure how well it achieves it). If we define __MINGW_FEATURES__ as a bitmap, with manifests for the individual features, e.g. #define __MINGW_ANSI_STDIO__ 0x0000000000000001ULL ... #define __MINGW_LC_MESSAGES__ 0x0000000000000010ULL #define __MINGW_LC_ENVVARS__ 0x0000000000000040ULL ... then the user can specify an appropriate `-D__MINGW_FEATURES__=<value_for_features_I_want>', (possibly as a specs file inclusion), and we can use tests of the form #if __MINGW_FEATURES__ & __MINGW_ANSI_STDIO__ ... #endif to set up the preprocessor environment as appropriate. ---------------------------------------------------------------------- Comment By: Aaron W. LaFramboise (aaronwl) Date: 2008-07-29 10:41 Message: Logged In: YES user_id=1040098 Originator: NO Keith, 1) OK, your plan is OK with me; I will save more -p discussion for later. 2) On symbol naming, the reason I think __mingw_msvcrt_ is better than __msvcrt_ is because mingw.org is the on providing the symbols. Its conceivable that some other project with "implementor's privilege" such as STLport or even MSVC itself might also use __msvcrt_ for something, which could mess us up really bad down the road. For safety, I think it would be best if we kept all of the reserved symbols named by mingw.org within __mingw_. 3) On 'overriding malloc', what I really meant was 'hook.' With the alternate symbols, you can do something like: void *malloc(size_t n) { track_malloc_usage_some_sort_of_way(); return __mingw_msvcrt_malloc(n); } With a little more infrastructure, this can be improved to: void *malloc(size_t n) { track_malloc_usage_some_sort_of_way(); return _MINGW_ORIGINAL(malloc)(n); } where _MINGW_ORIGINAL knows what "mode" we're in and prepends the appropriate prefix, wheither __msvcrt_mingw_ or __mingw_ or whatever. 4) On selecting impls with -limpl versus -DIMPL, I agree that the latter of using the preprocessor is better. With the former, adjusting the default or adding blanket modes requires modifying upstream GCC specs, whereas with the preprocessor, it can all be contained within mingwrt headers some sort of way. ---------------------------------------------------------------------- Comment By: Earnie Boyd (earnie) Date: 2008-07-29 10:23 Message: Logged In: YES user_id=15438 Originator: NO > FWIW, this is the agreed strategy incumbent in option #1. My original > reason for favouring option #2, is that the __mingw_printf() symbol isn't > available, if linking without -lprintf, whereas, with option #2 it would > always be available as a MinGW alternative; however, with option #2, > printf() would then always refer to the MinGW alternative implementation, > and users would be forced to call __msvcrt_printf(), if they wanted the > warts-and-all MSVCRT version. AIUI, it is this limitation which concerned > Earnie and Danny. > Yes, that would be correct. > So, maybe the most appropriate solution lies somewhere between #1 and #2; > fold everything into libmingwex.a, but dispense with the > __attribute__((alias())) business in the MinGW alternative implementations, > thus providing only the __mingw_ prefixed symbol names within libmingwex.a. > This would make all three symbols always available, with printf() > defaulting to __msvcrt_printf(), and we could then fall back to > preprocessor defines, or maybe __inline__ function redirects, in stdio.h > say, to achieve the alternative mappings, on demand. IMO, this will be a > cleaner solution than relying on an additional optionally linked library. > I like this solution. ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-29 09:38 Message: Logged In: YES user_id=823908 Originator: YES Earnie, I believe #3 and #5 are identically equivalent in effect; #5 is simply more selective WRT which symbols it creates aliases for. Aaron, As I've implemented it so far, I have the following symbolic names for printf():-- printf(); __msvcrt_printf(); __mingw_printf(); Within libmsvcrt.a, and its version specific siblings, printf() and __msvcrt_printf() are mutual aliases, provided by completely independent stubs, referring to the MSVCRT exported "printf". (I've chosen __msvcrt_ as the prefix, in preference to __mingw_msvcrt_, as it is unequivocal in its reference to an MSVCRT entity; I think __mingw_msvcrt_ may be potentially confusing. Nonetheless, I've implemented it in a manner which allows it to be readily changed, if consensus so dictates). Within the yet-to-be-completed libprintf.a, printf() and __mingw_printf() will also be mutual aliases, but this time created by GCC's __attribute__((alias())) facility, and therefore *not* independent; this will furnish the MinGW alternative implementation for printf(). Now, if the user specifies -lprintf, then he will have access to all three symbols, with printf() referring to the __mingw_printf(), while __msvcrt_printf() provides back door access to the original MSVCRT implementation. If the user does *not* link with -lprintf, he will lose the __mingw_printf() feature, and both printf() and __msvcrt_printf() will refer to the original MSVCRT implementation. FWIW, this is the agreed strategy incumbent in option #1. My original reason for favouring option #2, is that the __mingw_printf() symbol isn't available, if linking without -lprintf, whereas, with option #2 it would always be available as a MinGW alternative; however, with option #2, printf() would then always refer to the MinGW alternative implementation, and users would be forced to call __msvcrt_printf(), if they wanted the warts-and-all MSVCRT version. AIUI, it is this limitation which concerned Earnie and Danny. So, maybe the most appropriate solution lies somewhere between #1 and #2; fold everything into libmingwex.a, but dispense with the __attribute__((alias())) business in the MinGW alternative implementations, thus providing only the __mingw_ prefixed symbol names within libmingwex.a. This would make all three symbols always available, with printf() defaulting to __msvcrt_printf(), and we could then fall back to preprocessor defines, or maybe __inline__ function redirects, in stdio.h say, to achieve the alternative mappings, on demand. IMO, this will be a cleaner solution than relying on an additional optionally linked library. ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-29 08:32 Message: Logged In: YES user_id=823908 Originator: YES Aaron wrote: > I'd like to make an argument in favor of #3 over #5. Hmm. I've already committed the foundation for a solution based on #5. However, this isn't cast in stone; we can change it later, if we consider #3 to be more appropriate. > Doubling the number of symbols here doesn't really seem to be that bad. Maybe not in terms of ultimate file size, but IMO, it does hint of sloppy software engineering. I'm afraid that I just don't subscribe to the philosophy that because the cost of storage media is relatively low, it is ok to fill it up with bloated, poorly engineered software. > Linking 'hello world' with ld with the two different libraries > shows no statistically significant difference. For a trivial hello world, I would not expect it to. Doubling the size of the symbol table increases the average number of probes required, to locate any one symbol, by exactly one. If there are relatively few symbols to locate, that additional probe is unlikely to have much effect. Those additional probes will accumulate, for more complex applications, which require the resolution of relatively more symbols. > So the only practical improvement of #5 over #3 is saving about > half a megabyte of disk space on the developer's machine. Six megabytes, actually; (there are twelve variants of libmsvcrt.a, all of which must be similarly equipped with the additional symbols). That may not seem like much, but it hurts if you are using a dial up connection for download. > The real reason I'd prefer to use -p is that I think we might > want to use this same facility for things other than *printf(). In which case, we can add it selectively, as required. If dlltool behaved as documented, (or at least as I read the documentation, for I found it rather confusing), for EXPORTS declarations of the form `alias = symbol', then we probably would not be having this discussion. The solution I've implemented reproduces the effect of your -p option, but selectively, in the way that aliased declarations *should* work, IMO. > Additionally, this is a feature that users will find useful. Maybe, but you'll need to explain more, to convince me. > For instance, it gives us a simple solution to the otherwise > annoyingly-difficult problem of "how to override malloc()." I don't follow you here. Sure, we can override malloc() where we call it directly, by linking an alternative implementation ahead of the default runtime, but does that prevent other routines, within the runtime DLL itself say, from using the original version? Am I missing something? ---------------------------------------------------------------------- Comment By: Aaron W. LaFramboise (aaronwl) Date: 2008-07-29 08:22 Message: Logged In: YES user_id=1040098 Originator: NO Earnie, what I'm thinking is -p __mingw_msvcrt_ to dlltool for this library. For strcpy, for instance, we'd end up with both printf and __mingw_msvcrt__printf that refer to the 'strcpy' export of msvcrt.dll. Keith would name these printfs something like __mingw_printf, then we use a selector mechanism, such as the __MINGW_ALTERNATES__ mechanism you mentioned, to decide which one actually gets linkage against 'printf'. It's this selector mechanism that I have some further ideas about, such as the ability to select various "modes" that make blanket decisions across all parts of the runtime. Anyway, I don't want to do anything that would make it harder for Keith to get this finished immediately. I'm OK with whatever reasonable thing he decides. It's just preference is to use dlltool -p because I think it will make life better down the road. ---------------------------------------------------------------------- Comment By: Earnie Boyd (earnie) Date: 2008-07-29 08:04 Message: Logged In: YES user_id=15438 Originator: NO I'm confused a bit, would #3 leave the MSVCRT functions as the default? Yes, I'm OK with it. No, then I object since we started by striving to use only MSVCRT and that is what users mostly expect. There should be easy options for the user that always wants to user the new functions to do so; such as defining __MINGW_ALTERNATES__ or some other appropriately named macro. ---------------------------------------------------------------------- Comment By: Aaron W. LaFramboise (aaronwl) Date: 2008-07-28 13:59 Message: Logged In: YES user_id=1040098 Originator: NO I'd like to make an argument in favor of #3 over #5. Doubling the number of symbols here doesn't really seem to be that bad. Regarding file size on developer's machine: 492kb versus 1029kb (1mb) Regarding download size, gzipped: 25kb versus 44kb Linking 'hello world' with ld with the two different libraries shows no statistically significant difference. without -p (seconds): n=30, mean 0.1586, stddev 0.0133 with -p (seconds): n=30, mean 0.1578, stddev 0.0137 So the only practical improvement of #5 over #3 is saving about half a megabyte of disk space on the developer's machine. The real reason I'd prefer to use -p is that I think we might want to use this same facility for things other than *printf(). Additionally, this is a feature that users will find useful. For instance, it gives us a simple solution to the otherwise annoyingly-difficult problem of "how to override malloc()." I will solicit discussion on the "modes" plan RSN once I'm finished with the critical GCC-related stuff on my plate right now. Having these extra symbols is something I think might be essential for what I have in mind. ---------------------------------------------------------------------- Comment By: Earnie Boyd (earnie) Date: 2008-07-25 13:56 Message: Logged In: YES user_id=15438 Originator: NO This proposal sounds feasible. i.e: go for it. ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-25 11:07 Message: Logged In: YES user_id=823908 Originator: YES Earnie, Danny, Thanks. The problem with doing (1) alone is that there is no way to use both the replacement implementation, and the original MSVCRT implementation side by side, in a single application. Ok, maybe other than for evaluation, there is no compelling reason to want to do that, but some may want the capability. (5) actually isn't too difficult to do, (read, I've already figured out an implementation), so while (2)+(5) may not be the preferred option, (1)+(5) may be advantageous. Neither of you commented on the msvcr80.dll compatibility issue. I'd like to avoid providing two variants of libprintf.a, yet I'd still like to support the msvcr80.dll _[gs]et_output_format() behaviour. Option (8) makes that possible, without compromising backwards msvcrt.dll compatibility, and is also easy to implement. You both seem to prefer option (1) to option (2); therefore, I'd like to propose proceeding on the basis of options (1)+(5)+(8). With that combination, (using printf() as an example, and assuming __msvcrt_ as the alias prefix for libmsvcr*.a), we would have:-- Without libprintf.a: printf() aliased to __msvcrt_printf() /* from msvcr*.dll */ /* __mingw_printf() unavailable */ With libprintf.a linked ahead of libmsvcr*.a: printf() aliased to __mingw_printf() /* from libprintf.a */ __msvcrt_printf() /* back door to original MSVCRT printf() */ With libprintf.a linked after libmsvcr*.a: /* probable printf() linking contention here * need rethink, if we wish to support */ printf() aliased to __msvcrt_printf() /* from msvcr*.dll */ printf() aliased to __mingw_printf() /* from libprintf.a */ In any of these cases _get_output_format() would be added and always return zero, (default behaviour), for msvcr*.dll prior to msvcr80.dll; for msvcr80.dll and later, it would link to the actual DLL implementation, (via the dllimport stub), so a single libprintf.a would suffice, and deliver expected behaviour, with all supported MSVCRT versions. ---------------------------------------------------------------------- Comment By: Danny Smith (dannysmith) Date: 2008-07-24 23:27 Message: Logged In: YES user_id=11494 Originator: NO I vote for (1) What earnie said. Danny ---------------------------------------------------------------------- Comment By: Earnie Boyd (earnie) Date: 2008-07-24 15:02 Message: Logged In: YES user_id=15438 Originator: NO s/who always which it to be used/who always wish it to be used ---------------------------------------------------------------------- Comment By: Earnie Boyd (earnie) Date: 2008-07-24 13:42 Message: Logged In: YES user_id=15438 Originator: NO I am thinking I favor option 1. It is the more minimal and should provide the greatest benefit for everyone. Additionally instruction can be given for modifying the GCC specs file to add this library by default before the msvcrt library for those who always which it to be used. ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-24 08:59 Message: Logged In: YES user_id=823908 Originator: YES Ok, I've done some further follow up on the deployment options, but can we PLEASE have some follow up opinions from others, concerning the best way forward? To summarise:-- 1) The simplest option, (for me), is to just offer a freestanding libprintf.a; however, that isn't the most elegant, and therefore isn't my favourite. 2) Almost equally as simple, would be to add these replacement functions to libmingwex.a, and ignore the consequences of denying users access to the MSVCRT equivalents; probably not a good idea, as someone is sure to be upset. 3) Proceed as (2), but also adopt Aaron's suggestion, and use "dlltool -p __mingw_msvcrt ...", (or some alternative prefix, maybe just __msvcrt), as the dlltool invocation for building the libmsvcr*.a import libraries. That certainly provides an alternative name for linking to each of the replaced functions, but it is non-selective, creating similar aliases for every symbol in the exports list; IMO, a helluva price to pay, when only six such aliases are required, among 720 or so symbols overall. (It's a shame that dlltool doesn't seem to DTRT for exports declared as "symbol = alias", which would be to create alias stubs similar to those created by the -p option, but selectively). 4) Proceed as (2), and use "objcopy --redefine-syms" to modify the symbol names in the import stubs in libmsvcr*.a, for just those functions which are affected. The downside of this is that the original symbol names would no longer be present in the import libraries. 5) Proceed in a similar manner to (4), but instead of modifying the symbol names in place, use ar to pull the respective member stubs out of the import libraries, rename in the extracted object module, mangle the object file name, and add the modified object to the import library. This is more difficult, but quite achievable, and would effectively simulate the "dlltool -p ..." behaviour, but more selectively. In addition to the above, I'd also like opinions on supporting _[gs]et_output_format(). As I've written the code, it will call _get_output_format(), if it is compiled with -D__MSVCRT_VERSION__=<<value >= 0x0800>>. IMO, it is worth supporting this feature, but it presents a problem for building libmingwex.a, since _get_output_format() isn't present in the default msvcrt.dll, or in any prior to msvcr80.dll. So, we can: 6) Forget about supporting _[gs]et_output_format(), and just provide for least common denominator support of msvcrt.dll; easy, but least desirable, IMO. 7) Build for msvcr80+.dll support, and forget about supporting any earlier version; we would probably be lynched, if we were to go for that, especially since these later versions aren't formally provided as OS components. 8) Build as for (7), and add a minimal "return zero" stub for _get_output_format() into libmsvcr[7t]*.a; this again is simple enough to do, and is my preferred solution. 9) Build as for (7), and retrofit our own implementation for _[gs]et_output_format() into libmsvcr[7t]*.a; this may not be so easily accomplished, as there may be thread safety issues. ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-22 11:35 Message: Logged In: YES user_id=823908 Originator: YES Thanks, Jacky. That's good to know. Now we just need a decision on how best to deploy... ---------------------------------------------------------------------- Comment By: Jacky Lai (crazyjacky) Date: 2008-07-22 08:37 Message: Logged In: YES user_id=2105531 Originator: NO With the two patches it should pass the gnulib testsuite ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-20 19:46 Message: Logged In: YES user_id=823908 Originator: YES Library rebuilt, to incorporate latest patch. File Added: pformat-0.0-20080721-1-lib.tar.gz ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-20 19:42 Message: Logged In: YES user_id=823908 Originator: YES Thanks again, Jacky. Fortunately, I wasn't distracted by these wild geese for too long; unfortunately, the attached patch was delayed by a hard disk crash, requiring a full system reinstall, and backup restore. > %a field width not correct:... Actually nothing to do with the %a field width; this was a difficult to identify problem with %d formatting, rather easily fixed once I eventually did identify it. (Specifically, if %d was given an explicit field width, but no precision, and the output value was zero, a single zero digit would be emitted, but not counted as contributing to the field width; this showed up in your test case, because the zero exponent of the %a output was handed off to the %d interpreter, requiring right side padding to complete the $a field, in precisely the circumstances which exposed the %d bug). > %g not left-adjusted:... Once again, nothing to do with left alignment, which your test case didn't request. This one was a side effect of the previous patch, to discard trailing zeros; the precision was reduced to achieve this, and a compensating increment was applied to the field width padding, without first checking if any padding was appropriate; (precision reduced by three, to remove three trailing zeros, three added to field width of minus one, which should have signified no padding, became two padding spaces). Both are addressed by the attached patch, which is incremental to the previous one. File Added: pformat-0.0-20080721-1-src.diff.gz ---------------------------------------------------------------------- Comment By: Jacky Lai (crazyjacky) Date: 2008-07-16 10:04 Message: Logged In: YES user_id=2105531 Originator: NO 3 more test cases which fails: %a field width not correct: snprintf(result, sizeof(result), "%-10a %d", 1.75, 33, 44, 55); result="0x1.cp+0 33", expected="0x1.cp+0 33"/"0x3.8p-1 33"/"0x7p-2 33"/"0xep-3 33" %g not left-adjusted: snprintf(result, sizeof(result), "%.5g %d", 999.996, 33, 44, 55); result=" 1000 33", expected="1000 33" snprintf(result, sizeof(result), "%.5Lg %d", 999.996L, 33, 44, 55); result=" 1000 33", expected="1000 33" ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-15 19:07 Message: Logged In: YES user_id=823908 Originator: YES Further to the previous comment, I've replaced the attached prebuilt library with the patched version. File Added: pformat-0.0-20080715-1-lib.tar.gz ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-15 19:03 Message: Logged In: YES user_id=823908 Originator: YES Jacky, Thanks for testing, and pointing out these bugs; I've attached a patch, which I believe addresses them. Thanks also for pointing to the gnulib test suite. I don't want to refer to that myself, because gnulib is GPL/LGPL, and we don't want a licence dependency on either of those, in core MinGW libraries. (FWIW, I've rewritten this entire printf implementation with no more than the C99 and POSIX standards, and the current MinGW snprintf implementation as reference sources). However, I have no issue with you using the gnulib test suite to evaluate, and report back here. Aaron, Thanks for the pointer on the -p option for dlltool. It does appear to offer a mechanism for providing linkage to original MSVCRT functions by alternative names, when we've usurped their standard names to deliver better open standards conformance, but is there any way to make it selective wrt individual function stubs within the import library? libmsvcrt.a will approximately double in size if we add alternative name stubs for every exported symbol. Regarding your concerns about maybe needing to offer multiple different flavours of MinGW runtimes, that seems to me to be something of a policy discussion. Perhaps you would like to broach the subject on the developers' list? File Added: pformat-0.0-20080715-1-src.diff.gz ---------------------------------------------------------------------- Comment By: Jacky Lai (crazyjacky) Date: 2008-07-13 01:37 Message: Logged In: YES user_id=2105531 Originator: NO I ran the test cases from gnulib and found some bugs: %g/%e/%f - leading zeros are not written when 0 is specified %g - trailing zeros are not dropped when # not specified %a has more problems: 1. Outputted field width not correct my_snprintf (result, sizeof(result), "%010La %d", 1.75L, 33, 44, 55); result="0x00000ep-3 33", expected="0x0000ep-3 33" 2. Some conversion not correct, for example my_snprintf(result, sizeof(result), "%.1La %d", 1.999L, 33, 44, 55); result="0x0.0p+0 33", expected="0x1.0p+1 33"/"0x2.0p+0 33"/"0x4.0p-1 33"/"0x8.0p-2 33" my_snprintf(result, sizeof(result), "%.0a %d", 1.5, 33, 44, 55); result="0x2p-1 33", expected="0x2p+0 33"/"0x3p-1 33"/"0x6p-2 33"/"0xcp-3 33" my_snprintf(result, sizeof(result), "%.0a %d", 1.51, 33, 44, 55); result="0x2p-1 33", expected="0x2p+0 33"/"0x3p-1 33"/"0x6p-2 33"/"0xcp-3 33" my_snprintf(result, sizeof (result), "%.1a %d", 1.999, 33, 44, 55); test-snprintf-posix.h:283: result="0x2.0p-1 33", expected="0x1.0p+1 33"/"0x2.0p+0 33"/"0x4.0p-1 33"/"0x8.0p-2 33" P.S. The test case from gnulib can be found at http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=tree;f=tests;h=fa8fcec357aac576cfedfb9aec38179cf48008c6;hb=HEAD (nan.h, test-snprintf-posix.h, test-snprintf-posix.c, and require minor modification) ---------------------------------------------------------------------- Comment By: Aaron W. LaFramboise (aaronwl) Date: 2008-07-11 11:48 Message: Logged In: YES user_id=1040098 Originator: NO Regarding #2, I added the -p option to dlltool for this purpose. I would suggest something careful like __mingw_msvcrt_ as the aliased prefix. An idea I've been thinking about lately (regarding some of my own improvement) is high-level switches of some sort to switch between different MinGW 'modes.' The main motivation is the substantial differences between people who want MinGW to be 1) a good minimalistic subset of POSIX for porting 2) a good native Win32 compiler, or 3) a thin wrapper around a Microsoft runtime. Just as an observation, some important MinGW users in the GCC community have expressed some alarm that MinGW is drifting away from #3. This can be done either with -D options or -m options; the latter are more powerful, but harder to work with since we need to change GCC to work with them. ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-07-11 11:00 Message: Logged In: YES user_id=823908 Originator: YES File Added: pformat-0.0-lib.tar.gz ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=302435&aid=2016112&group_id=2435 |