Add sprintf support, that were were missing.

Add support for snprintf '+', 'h', and %* length settings.
This commit is contained in:
Bruce Momjian 2005-03-16 21:27:23 +00:00
parent ca66797308
commit 712f053587
3 changed files with 118 additions and 49 deletions

View File

@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2005, PostgreSQL Global Development Group * Copyright (c) 2000-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.141 2005/03/11 17:20:34 momjian Exp $ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.142 2005/03/16 21:27:23 momjian Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "command.h" #include "command.h"
@ -1574,11 +1574,13 @@ do_shell(const char *command)
shellName = DEFAULT_SHELL; shellName = DEFAULT_SHELL;
sys = pg_malloc(strlen(shellName) + 16); sys = pg_malloc(strlen(shellName) + 16);
#ifndef WIN32
sprintf(sys, sprintf(sys,
/* See EDITOR handling comment for an explaination */ /* See EDITOR handling comment for an explaination */
#ifndef WIN32
"exec %s", shellName); "exec %s", shellName);
#else #else
sprintf(sys,
/* See EDITOR handling comment for an explaination */
"%s\"%s\"%s", SYSTEMQUOTE, shellName, SYSTEMQUOTE); "%s\"%s\"%s", SYSTEMQUOTE, shellName, SYSTEMQUOTE);
#endif #endif
result = system(sys); result = system(sys);

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/port.h,v 1.72 2005/03/11 19:13:42 momjian Exp $ * $PostgreSQL: pgsql/src/include/port.h,v 1.73 2005/03/16 21:27:23 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -112,6 +112,9 @@ extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
extern int pg_snprintf(char *str, size_t count, const char *fmt,...) extern int pg_snprintf(char *str, size_t count, const char *fmt,...)
/* This extension allows gcc to check the format string */ /* This extension allows gcc to check the format string */
__attribute__((format(printf, 3, 4))); __attribute__((format(printf, 3, 4)));
extern int pg_sprintf(char *str, const char *fmt,...)
/* This extension allows gcc to check the format string */
__attribute__((format(printf, 2, 3)));
extern int pg_fprintf(FILE *stream, const char *fmt,...) extern int pg_fprintf(FILE *stream, const char *fmt,...)
/* This extension allows gcc to check the format string */ /* This extension allows gcc to check the format string */
__attribute__((format(printf, 2, 3))); __attribute__((format(printf, 2, 3)));
@ -127,11 +130,13 @@ __attribute__((format(printf, 1, 2)));
#ifdef __GNUC__ #ifdef __GNUC__
#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__) #define vsnprintf(...) pg_vsnprintf(__VA_ARGS__)
#define snprintf(...) pg_snprintf(__VA_ARGS__) #define snprintf(...) pg_snprintf(__VA_ARGS__)
#define sprintf(...) pg_sprintf(__VA_ARGS__)
#define fprintf(...) pg_fprintf(__VA_ARGS__) #define fprintf(...) pg_fprintf(__VA_ARGS__)
#define printf(...) pg_printf(__VA_ARGS__) #define printf(...) pg_printf(__VA_ARGS__)
#else #else
#define vsnprintf pg_vsnprintf #define vsnprintf pg_vsnprintf
#define snprintf pg_snprintf #define snprintf pg_snprintf
#define sprintf pg_sprintf
#define fprintf pg_fprintf #define fprintf pg_fprintf
#define printf pg_printf #define printf pg_printf
#endif #endif

View File

@ -65,16 +65,14 @@
* causing nasty effects. * causing nasty effects.
**************************************************************/ **************************************************************/
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.22 2005/03/16 15:12:18 momjian Exp $";*/ /*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.23 2005/03/16 21:27:23 momjian Exp $";*/
int pg_snprintf(char *str, size_t count, const char *fmt,...);
int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
int pg_printf(const char *format,...);
static void dopr(char *buffer, const char *format, va_list args, char *end); static void dopr(char *buffer, const char *format, va_list args, char *end);
/* Prevent recursion */ /* Prevent recursion */
#undef vsnprintf #undef vsnprintf
#undef snprintf #undef snprintf
#undef sprintf
#undef fprintf #undef fprintf
#undef printf #undef printf
@ -103,19 +101,33 @@ pg_snprintf(char *str, size_t count, const char *fmt,...)
return len; return len;
} }
int
pg_sprintf(char *str, const char *fmt,...)
{
int len;
va_list args;
char buffer[4096];
va_start(args, fmt);
len = pg_vsnprintf(buffer, (size_t) 4096, fmt, args);
va_end(args);
/* limit output to string */
StrNCpy(str, buffer, (len + 1 < 4096) ? len + 1 : 4096);
return len;
}
int int
pg_fprintf(FILE *stream, const char *fmt,...) pg_fprintf(FILE *stream, const char *fmt,...)
{ {
int len; int len;
va_list args; va_list args;
char *buffer[4096]; char buffer[4096];
char *p; char *p;
va_start(args, fmt); va_start(args, fmt);
len = pg_vsnprintf((char *) buffer, (size_t) 4096, fmt, args); len = pg_vsnprintf(buffer, (size_t) 4096, fmt, args);
va_end(args); va_end(args);
p = (char *) buffer; for (p = buffer; *p; p++)
for (; *p; p++)
putc(*p, stream); putc(*p, stream);
return len; return len;
} }
@ -125,14 +137,14 @@ pg_printf(const char *fmt,...)
{ {
int len; int len;
va_list args; va_list args;
char *buffer[4096]; char buffer[4096];
char *p; char *p;
va_start(args, fmt); va_start(args, fmt);
len = pg_vsnprintf((char *) buffer, (size_t) 4096, fmt, args); len = pg_vsnprintf(buffer, (size_t) 4096, fmt, args);
va_end(args); va_end(args);
p = (char *) buffer;
for (; *p; p++) for (p = buffer; *p; p++)
putchar(*p); putchar(*p);
return len; return len;
} }
@ -141,12 +153,13 @@ pg_printf(const char *fmt,...)
* dopr(): poor man's version of doprintf * dopr(): poor man's version of doprintf
*/ */
static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, static void fmtstr(char *value, int ljust, int len, int maxwidth,
char *end, char **output); char *end, char **output);
static void fmtnum(int64 value, int base, int dosign, int ljust, int len, static void fmtnum(int64 value, int base, int dosign, int forcesign,
int zpad, char *end, char **output); int ljust, int len, int zpad, char *end, char **output);
static void fmtfloat(double value, char type, int ljust, int len, static void fmtfloat(double value, char type, int forcesign,
int precision, int pointflag, char *end, char **output); int ljust, int len, int zpad, int precision, int pointflag, char *end,
char **output);
static void dostr(char *str, int cut, char *end, char **output); static void dostr(char *str, int cut, char *end, char **output);
static void dopr_outch(int c, char *end, char **output); static void dopr_outch(int c, char *end, char **output);
@ -162,13 +175,14 @@ static void
dopr(char *buffer, const char *format, va_list args, char *end) dopr(char *buffer, const char *format, va_list args, char *end)
{ {
int ch; int ch;
int longlongflag = 0; int longlongflag;
int longflag = 0; int longflag;
int pointflag = 0; int pointflag;
int maxwidth = 0; int maxwidth;
int ljust; int ljust;
int len; int len;
int zpad; int zpad;
int forcesign;
int i; int i;
const char *format_save; const char *format_save;
const char *fmtbegin; const char *fmtbegin;
@ -193,6 +207,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
int maxwidth; int maxwidth;
int base; int base;
int dosign; int dosign;
int forcesign;
char type; char type;
int precision; int precision;
int pointflag; int pointflag;
@ -230,7 +245,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
switch (ch) switch (ch)
{ {
case '%': case '%':
ljust = len = zpad = maxwidth = 0; ljust = len = zpad = forcesign = maxwidth = 0;
longflag = longlongflag = pointflag = 0; longflag = longlongflag = pointflag = 0;
fmtbegin = format - 1; fmtbegin = format - 1;
realpos = 0; realpos = 0;
@ -244,6 +259,9 @@ dopr(char *buffer, const char *format, va_list args, char *end)
case '-': case '-':
ljust = 1; ljust = 1;
goto nextch; goto nextch;
case '+':
forcesign = 1;
goto nextch;
case '0': /* set zero padding if len not set */ case '0': /* set zero padding if len not set */
if (len == 0 && !pointflag) if (len == 0 && !pointflag)
zpad = '0'; zpad = '0';
@ -289,6 +307,9 @@ dopr(char *buffer, const char *format, va_list args, char *end)
else else
longflag = 1; longflag = 1;
goto nextch; goto nextch;
case 'h':
/* ignore */
goto nextch;
#ifdef NOT_USED #ifdef NOT_USED
/* /*
@ -318,6 +339,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].base = 10; fmtpar[fmtpos].base = 10;
fmtpar[fmtpos].dosign = 0; fmtpar[fmtpos].dosign = 0;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust; fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len; fmtpar[fmtpos].len = len;
fmtpar[fmtpos].zpad = zpad; fmtpar[fmtpos].zpad = zpad;
@ -333,6 +355,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].base = 8; fmtpar[fmtpos].base = 8;
fmtpar[fmtpos].dosign = 0; fmtpar[fmtpos].dosign = 0;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust; fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len; fmtpar[fmtpos].len = len;
fmtpar[fmtpos].zpad = zpad; fmtpar[fmtpos].zpad = zpad;
@ -348,6 +371,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].base = 10; fmtpar[fmtpos].base = 10;
fmtpar[fmtpos].dosign = 1; fmtpar[fmtpos].dosign = 1;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust; fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len; fmtpar[fmtpos].len = len;
fmtpar[fmtpos].zpad = zpad; fmtpar[fmtpos].zpad = zpad;
@ -362,6 +386,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].base = 16; fmtpar[fmtpos].base = 16;
fmtpar[fmtpos].dosign = 0; fmtpar[fmtpos].dosign = 0;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust; fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len; fmtpar[fmtpos].len = len;
fmtpar[fmtpos].zpad = zpad; fmtpar[fmtpos].zpad = zpad;
@ -376,6 +401,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].base = -16; fmtpar[fmtpos].base = -16;
fmtpar[fmtpos].dosign = 1; fmtpar[fmtpos].dosign = 1;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust; fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len; fmtpar[fmtpos].len = len;
fmtpar[fmtpos].zpad = zpad; fmtpar[fmtpos].zpad = zpad;
@ -409,9 +435,10 @@ dopr(char *buffer, const char *format, va_list args, char *end)
fmtpar[fmtpos].fmtbegin = fmtbegin; fmtpar[fmtpos].fmtbegin = fmtbegin;
fmtpar[fmtpos].fmtend = format; fmtpar[fmtpos].fmtend = format;
fmtpar[fmtpos].type = ch; fmtpar[fmtpos].type = ch;
fmtpar[fmtpos].forcesign = forcesign;
fmtpar[fmtpos].ljust = ljust; fmtpar[fmtpos].ljust = ljust;
fmtpar[fmtpos].len = len; fmtpar[fmtpos].len = len;
fmtpar[fmtpos].maxwidth = maxwidth; fmtpar[fmtpos].zpad = zpad;
fmtpar[fmtpos].precision = precision; fmtpar[fmtpos].precision = precision;
fmtpar[fmtpos].pointflag = pointflag; fmtpar[fmtpos].pointflag = pointflag;
fmtpar[fmtpos].func = FMTFLOAT; fmtpar[fmtpos].func = FMTFLOAT;
@ -504,20 +531,22 @@ performpr:
{ {
case FMTSTR: case FMTSTR:
fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust, fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust,
fmtparptr[i]->len, fmtparptr[i]->zpad, fmtparptr[i]->len, fmtparptr[i]->maxwidth,
fmtparptr[i]->maxwidth, end, &output); end, &output);
break; break;
case FMTNUM: case FMTNUM:
case FMTNUM_U: case FMTNUM_U:
fmtnum(fmtparptr[i]->numvalue, fmtparptr[i]->base, fmtnum(fmtparptr[i]->numvalue, fmtparptr[i]->base,
fmtparptr[i]->dosign, fmtparptr[i]->ljust, fmtparptr[i]->dosign, fmtparptr[i]->forcesign,
fmtparptr[i]->len, fmtparptr[i]->zpad, end, &output); fmtparptr[i]->ljust, fmtparptr[i]->len,
fmtparptr[i]->zpad, end, &output);
break; break;
case FMTFLOAT: case FMTFLOAT:
fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type, fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type,
fmtparptr[i]->ljust, fmtparptr[i]->len, fmtparptr[i]->forcesign, fmtparptr[i]->ljust,
fmtparptr[i]->precision, fmtparptr[i]->pointflag, fmtparptr[i]->len, fmtparptr[i]->zpad,
end, &output); fmtparptr[i]->precision, fmtparptr[i]->pointflag,
end, &output);
break; break;
case FMTCHAR: case FMTCHAR:
dopr_outch(fmtparptr[i]->charvalue, end, &output); dopr_outch(fmtparptr[i]->charvalue, end, &output);
@ -545,18 +574,24 @@ nochar:
} }
static void static void
fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end, fmtstr(char *value, int ljust, int len, int maxwidth, char *end,
char **output) char **output)
{ {
int padlen, int padlen,
strlen; /* amount to pad */ vallen; /* amount to pad */
if (value == 0) if (value == NULL)
value = "<NULL>"; value = "<NULL>";
for (strlen = 0; value[strlen]; ++strlen); /* strlen */ vallen = strlen(value);
if (strlen > maxwidth && maxwidth) if (vallen > maxwidth && maxwidth)
strlen = maxwidth; vallen = maxwidth;
padlen = len - strlen; if (len < 0)
{
/* this could happen with a "*" width spec */
ljust = 1;
len = -len;
}
padlen = len - vallen;
if (padlen < 0) if (padlen < 0)
padlen = 0; padlen = 0;
if (ljust) if (ljust)
@ -575,8 +610,8 @@ fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end,
} }
static void static void
fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, fmtnum(int64 value, int base, int dosign, int forcesign, int ljust,
char *end, char **output) int len, int zpad, char *end, char **output)
{ {
int signvalue = 0; int signvalue = 0;
uint64 uvalue; uint64 uvalue;
@ -597,6 +632,8 @@ fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad,
signvalue = '-'; signvalue = '-';
uvalue = -value; uvalue = -value;
} }
else if (forcesign)
signvalue = '+';
} }
if (base < 0) if (base < 0)
{ {
@ -658,19 +695,32 @@ fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad,
} }
static void static void
fmtfloat(double value, char type, int ljust, int len, int precision, fmtfloat(double value, char type, int forcesign, int ljust,
int pointflag, char *end, char **output) int len, int zpad, int precision, int pointflag, char *end,
char **output)
{ {
int signvalue = 0;
double uvalue;
char fmt[32]; char fmt[32];
char convert[512]; char convert[512];
int padlen = 0; /* amount to pad */ int padlen = 0; /* amount to pad */
uvalue = value;
/* we rely on regular C library's sprintf to do the basic conversion */ /* we rely on regular C library's sprintf to do the basic conversion */
if (pointflag) if (pointflag)
sprintf(fmt, "%%.%d%c", precision, type); sprintf(fmt, "%%.%d%c", precision, type);
else else
sprintf(fmt, "%%%c", type); sprintf(fmt, "%%%c", type);
sprintf(convert, fmt, value);
if (value < 0)
{
signvalue = '-';
uvalue = -value;
}
else if (forcesign)
signvalue = '+';
sprintf(convert, fmt, uvalue);
if (len < 0) if (len < 0)
{ {
@ -684,11 +734,27 @@ fmtfloat(double value, char type, int ljust, int len, int precision,
if (ljust) if (ljust)
padlen = -padlen; padlen = -padlen;
if (zpad && padlen > 0)
{
if (signvalue)
{
dopr_outch(signvalue, end, output);
--padlen;
signvalue = 0;
}
while (padlen > 0)
{
dopr_outch(zpad, end, output);
--padlen;
}
}
while (padlen > 0) while (padlen > 0)
{ {
dopr_outch(' ', end, output); dopr_outch(' ', end, output);
--padlen; --padlen;
} }
if (signvalue)
dopr_outch(signvalue, end, output);
dostr(convert, 0, end, output); dostr(convert, 0, end, output);
while (padlen < 0) while (padlen < 0)
{ {
@ -701,15 +767,11 @@ static void
dostr(char *str, int cut, char *end, char **output) dostr(char *str, int cut, char *end, char **output)
{ {
if (cut) if (cut)
{
while (*str && cut-- > 0) while (*str && cut-- > 0)
dopr_outch(*str++, end, output); dopr_outch(*str++, end, output);
}
else else
{
while (*str) while (*str)
dopr_outch(*str++, end, output); dopr_outch(*str++, end, output);
}
} }
static void static void