Hi Hrvoje :)) * Hrvoje Niksic <[EMAIL PROTECTED]> dixit: > There have been several attempts to fix this: [...] > * In its own patches, Debian introduced the use of large file APIs and > `long long'. While that's perfectly fine for Debian, it is not > portable. Neither the large file API nor `long long' are > universally available, and both need thorough configure checking.
Yes, you're true, but... How about using C99 large integer types (intmax_t and family)? I know, is not universally available, but if you support obsolete systems IMHO you should do in a last resort way. I mean, use large file API or intmax_t on every system that supports it (all systems with a not-so-recent GNU C compiler), long long on the rest and long as the last resort. It's not very complicated to do so in autoshi^H^H^Hconf, and wget will support really huge files in most of systems (those with a GNU C compiler and those with long long support), and normal files on the rest. > Of those two issues, choosing and using the numeric type is the hard > one. Autoconf helps only to an extent -- even if you define your own > `large_number_t' typedef, which is either `long' or `long long', the > question remains how to print that number. If you use intmax_t, the problem is solved because C99 has a %-format for them. If you use long long and gcc, the same happens AFAIK. The problem is that you don't have an universal format for all those types... You should write a printf wrapper or a special function for printing those numbers. > 1. Concatenation of adjacent string literals is an ANSI feature and > would break pre-ANSI compilers. You're true again, but you can wrap it in a macro and use '##'. Or you can stop supporting pre-ANSI compilers. How many users will this affect (more or less). > 2. It breaks gettext. With translation support, the above code would > look like this: Yes, gettext is far from perfect :(((( The solution is to do the conditional preprocessing above directly on the code, so you have three (or more, as needed) printf lines with legal-gettext code in them: #ifdef CRAP_SYSTEM printf(_("Whatever %d\n"), num); #elif defined A_BIT_BETTER_SYSTEM printf(_("Whatever %lld\n", num); #else /* We have a good system */ printf(_("Whatever %j\n", num); #endif Yes, looks ugly, is crap, but... > The bottom line is, I really don't know how to solve this portably. IMHO, the best solution is to use a big unsigned type for sums, totals, sizes to print, etc... and use a large file API for reading and write large files. If the large file API doesn't exist, use off_t anyway. Provide a function for printing off_t's and just make sure that the type for sums is larger than off_t if possible, otherwise use off_t too (I suppose that autoconf can help you in this). Normally I use 'size_t' or 'uintmax_t' for sizes to print, sums, totals, etc... and off_t for files, because an off_t, being signed, will be shorter than the uintmax type for sure, although you can always use bignum libraries. The bignum libraries (well, pick up just the code for additions, for example) will help you with half of the problem. The other half, reading/writing large files, must be provided by the system. Just define _LARGEFILE64 (or whatever is the macro called in SuSv3 or POSIX) and use off_t and an small function for printing them (although off_t is opaque and if you want full portability you should not use it directly...). That's the better I can get, because when I wrote portable code, by portable I understand 'according to standards'. For me that means, in that order: SuSv3, POSIX, C99, C89, stop. No pre-ANSI and no brain damaged compilers. > Does anyone know how widely ported software deals with large files? No idea, sorry :((( And thanks for the work you're doing with wget, we all benefit from. Raúl Núñez de Arenas Coronado -- Linux Registered User 88736 http://www.pleyades.net & http://raul.pleyades.net/