Re: [HACKERS] Repleacement for src/port/snprintf.c
On Mon, Feb 21, 2005 at 10:53:08PM -0500, Bruce Momjian wrote: Applied. Thanks a lot. The patch attached solves the tread safety problem. Please review it before applying, I am not sure I am doing the right thing On Tue, 22 Feb 2005 19:57:15 +0100, Kurt Roeckx [EMAIL PROTECTED] wrote: The configure test is a little broken. It needs to quote the $'s. I've rewritten the test a little. This one needs applying too. $'s do get scrambled. Best regards, Nicolai. *** ./src/port/snprintf.c.orig sali Şub 22 20:02:03 2005 --- ./src/port/snprintf.c sali Şub 22 21:59:48 2005 *** *** 80,96 * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from ! * causing nast effects. **/ /*static char _id[] = $PostgreSQL: pgsql/src/port/snprintf.c,v 1.6 2005/02/22 04:57:24 momjian Exp $;*/ - static char *end; - static int SnprfOverflow; int snprintf(char *str, size_t count, const char *fmt,...); int vsnprintf(char *str, size_t count, const char *fmt, va_list args); int printf(const char *format, ...); ! static void dopr(char *buffer, const char *format, va_list args); int printf(const char *fmt,...) --- 80,94 * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from ! * causing nasty effects. **/ /*static char _id[] = $PostgreSQL: pgsql/src/port/snprintf.c,v 1.6 2005/02/22 04:57:24 momjian Exp $;*/ int snprintf(char *str, size_t count, const char *fmt,...); int vsnprintf(char *str, size_t count, const char *fmt, va_list args); int printf(const char *format, ...); ! static void dopr(char *buffer, const char *format, va_list args, char *end); int printf(const char *fmt,...) *** *** 97,103 { int len; va_list args; ! static char* buffer[4096]; char* p; va_start(args, fmt); --- 95,101 { int len; va_list args; ! char* buffer[4096]; char* p; va_start(args, fmt); *** *** 125,134 int vsnprintf(char *str, size_t count, const char *fmt, va_list args) { str[0] = '\0'; end = str + count - 1; ! SnprfOverflow = 0; ! dopr(str, fmt, args); if (count 0) end[0] = '\0'; return strlen(str); --- 123,132 int vsnprintf(char *str, size_t count, const char *fmt, va_list args) { + char *end; str[0] = '\0'; end = str + count - 1; ! dopr(str, fmt, args, end); if (count 0) end[0] = '\0'; return strlen(str); *** *** 138,148 * dopr(): poor man's version of doprintf */ ! static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth); ! static void fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad); ! static void fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag); ! static void dostr(char *str, int cut); ! static void dopr_outch(int c); static char *output; --- 136,146 * dopr(): poor man's version of doprintf */ ! static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end); ! static void fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad, char *end); ! static void fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end); ! static void dostr(char *str, int cut, char *end); ! static void dopr_outch(int c, char *end); static char *output; *** *** 152,158 #define FMTCHAR 4 static void ! dopr(char *buffer, const char *format, va_list args) { int ch; long_long value; --- 150,156 #define FMTCHAR 4 static void ! dopr(char *buffer, const char *format, va_list args, char *end) { int ch; long_long value; *** *** 415,425 case '%': break; default: ! dostr(???, 0); } break; default: ! dopr_outch(ch); break; } } --- 413,423 case '%': break; default: ! dostr(???, 0, end); } break; default: ! dopr_outch(ch, end); break; } } *** *** 446,465 case FMTSTR: fmtstr(fmtparptr[i]-value, fmtparptr[i]-ljust, fmtparptr[i]-len, fmtparptr[i]-zpad, ! fmtparptr[i]-maxwidth); break; case FMTNUM: fmtnum(fmtparptr[i]-numvalue, fmtparptr[i]-base, fmtparptr[i]-dosign, fmtparptr[i]-ljust, ! fmtparptr[i]-len, fmtparptr[i]-zpad); break; case FMTFLOAT: fmtfloat(fmtparptr[i]-fvalue, fmtparptr[i]-type, fmtparptr[i]-ljust, fmtparptr[i]-len, ! fmtparptr[i]-precision, fmtparptr[i]-pointflag); break; case FMTCHAR: ! dopr_outch(fmtparptr[i]-charvalue); break; }
[HACKERS] Repleacement for src/port/snprintf.c
Hello all, I would like to submit my changes to src/port/snprintf.c to enable %n$ format placeholder replacement in snprintf() and vsnprintf(). Additionally I implemented a trivial printf(). I also attach a diff for configure.in to include snprintf.o in pgport but I am sure it is not the right thing to do. Could someone give a hint on where I need to place such a definition. Please review my patch. as Tom Lane pointed out there are 150 messages in the following files that do not print properly: src/backend/po/pt_BR.po src/backend/po/de.po src/backend/po/es.po src/backend/po/zh_CN.po src/backend/po/tr.po src/bin/pg_dump/po/zh_CN.po src/bin/pg_dump/po/tr.po src/bin/psql/po/zh_CN.po src/bin/psql/po/zh_TW.po src/bin/psql/po/tr.po src/bin/scripts/po/zh_CN.po we need to fix snprintf.c before next release Best regards, Nicolai Tufar *** ./src/port/snprintf.c.orig 2005-01-20 01:27:22.0 +0200 --- ./src/port/snprintf.c 2005-01-24 03:09:31.0 +0200 *** *** 57,62 --- 57,66 typedef unsigned long ulong_long; #endif + #ifndef NL_ARGMAX + #define NL_ARGMAX 4096 + #endif + /* **SNPRINTF, VSNPRINT -- counted versions of printf ** *** *** 85,93 --- 89,115 int snprintf(char *str, size_t count, const char *fmt,...); int vsnprintf(char *str, size_t count, const char *fmt, va_list args); + int printf(const char *format, ...); static void dopr(char *buffer, const char *format, va_list args); int + printf(const char *fmt,...) + { + int len; + va_list args; + static char*buffer[4096]; + char* p; + + va_start(args, fmt); + len = vsnprintf((char*)buffer, (size_t)4096, fmt, args); + va_end(args); + p = (char*)buffer; + for(;*p;p++) + putchar(*p); + return len; + } + + int snprintf(char *str, size_t count, const char *fmt,...) { int len; *** *** 124,129 --- 146,155 static char *output; + #define FMTSTR 1 + #define FMTNUM 2 + #define FMTFLOAT3 + #define FMTCHAR 4 static void dopr(char *buffer, const char *format, va_list args) *** *** 139,145 --- 165,200 int ljust; int len; int zpad; + int i; + const char* format_save; + const char* fmtbegin; + int fmtpos = 1; + int realpos = 0; + int position; + static struct{ + const char* fmtbegin; + const char* fmtend; + union{ + void* value; + long_long numvalue; + double fvalue; + int charvalue; + }; + int ljust; + int len; + int zpad; + int maxwidth; + int base; + int dosign; + chartype; + int precision; + int pointflag; + charfunc; + int realpos; + }fmtpar[NL_ARGMAX+1], *fmtparptr[NL_ARGMAX+1]; + + format_save = format; output = buffer; while ((ch = *format++)) { *** *** 148,161 case '%': ljust = len = zpad = maxwidth = 0; longflag = longlongflag = pointflag = 0; nextch: ch = *format++; switch (ch) { case 0: ! dostr(**end of format**, 0); ! *output = '\0'; ! return; case '-': ljust = 1; goto nextch; --- 203,217 case '%': ljust = len = zpad = maxwidth = 0; longflag = longlongflag = pointflag = 0; + fmtbegin = format - 1; + realpos = 0; + position = 0; nextch: ch = *format++; switch (ch) { case 0: ! goto performpr;
[HACKERS] Repleacement for src/port/snprintf.c
Greetings, I would like to submit my changes to src/port/snprintf.c to enable %n$ format placeholder replacement in snprintf() and vsnprintf(). Additionally I implemented a trivial printf(). I also attach a diff for configure.in to include snprintf.o in pgport but I am sure it is not the right thing to do. Could someone give a hint on where I need to place such a definition. Best regards, Nicolai Tufar *** ./src/port/snprintf.c.orig 2005-01-20 01:27:22.0 +0200 --- ./src/port/snprintf.c 2005-01-24 03:09:31.0 +0200 *** *** 57,62 --- 57,66 typedef unsigned long ulong_long; #endif + #ifndef NL_ARGMAX + #define NL_ARGMAX 4096 + #endif + /* **SNPRINTF, VSNPRINT -- counted versions of printf ** *** *** 85,93 --- 89,115 int snprintf(char *str, size_t count, const char *fmt,...); int vsnprintf(char *str, size_t count, const char *fmt, va_list args); + int printf(const char *format, ...); static void dopr(char *buffer, const char *format, va_list args); int + printf(const char *fmt,...) + { + int len; + va_list args; + static char*buffer[4096]; + char* p; + + va_start(args, fmt); + len = vsnprintf((char*)buffer, (size_t)4096, fmt, args); + va_end(args); + p = (char*)buffer; + for(;*p;p++) + putchar(*p); + return len; + } + + int snprintf(char *str, size_t count, const char *fmt,...) { int len; *** *** 124,129 --- 146,155 static char *output; + #define FMTSTR 1 + #define FMTNUM 2 + #define FMTFLOAT3 + #define FMTCHAR 4 static void dopr(char *buffer, const char *format, va_list args) *** *** 139,145 --- 165,200 int ljust; int len; int zpad; + int i; + const char* format_save; + const char* fmtbegin; + int fmtpos = 1; + int realpos = 0; + int position; + static struct{ + const char* fmtbegin; + const char* fmtend; + union{ + void* value; + long_long numvalue; + double fvalue; + int charvalue; + }; + int ljust; + int len; + int zpad; + int maxwidth; + int base; + int dosign; + chartype; + int precision; + int pointflag; + charfunc; + int realpos; + }fmtpar[NL_ARGMAX+1], *fmtparptr[NL_ARGMAX+1]; + + format_save = format; output = buffer; while ((ch = *format++)) { *** *** 148,161 case '%': ljust = len = zpad = maxwidth = 0; longflag = longlongflag = pointflag = 0; nextch: ch = *format++; switch (ch) { case 0: ! dostr(**end of format**, 0); ! *output = '\0'; ! return; case '-': ljust = 1; goto nextch; --- 203,217 case '%': ljust = len = zpad = maxwidth = 0; longflag = longlongflag = pointflag = 0; + fmtbegin = format - 1; + realpos = 0; + position = 0; nextch: ch = *format++; switch (ch) { case 0: ! goto performpr; case '-': ljust = 1; goto nextch; *** *** 174,180 --- 230,243 if (pointflag) maxwidth = maxwidth * 10 + ch - '0'; else +