1998-05-07 07:44:09 -04:00
|
|
|
/* Provide a version _doprnt in terms of fprintf.
|
|
|
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
1999-01-06 15:44:41 -05:00
|
|
|
Contributed by Kaveh Ghazi (ghazi@caip.rutgers.edu) 3/29/98
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
|
|
|
1998-05-07 07:44:09 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "system.h"
|
|
|
|
#undef _doprnt
|
|
|
|
|
|
|
|
#ifdef TEST /* Make sure to use the internal one. */
|
|
|
|
#define _doprnt my_doprnt
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define COPY_VA_INT \
|
|
|
|
do { \
|
|
|
|
const int value = abs (va_arg (ap, int)); \
|
|
|
|
char buf[32]; \
|
|
|
|
ptr++; /* Go past the asterisk. */ \
|
|
|
|
*sptr = '\0'; /* NULL terminate sptr. */ \
|
|
|
|
sprintf(buf, "%d", value); \
|
|
|
|
strcat(sptr, buf); \
|
|
|
|
while (*sptr) sptr++; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define PRINT_CHAR(CHAR) \
|
|
|
|
do { \
|
|
|
|
putc(CHAR, stream); \
|
|
|
|
ptr++; \
|
|
|
|
total_printed++; \
|
|
|
|
continue; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define PRINT_TYPE(TYPE) \
|
|
|
|
do { \
|
|
|
|
int result; \
|
|
|
|
TYPE value = va_arg (ap, TYPE); \
|
|
|
|
*sptr++ = *ptr++; /* Copy the type specifier. */ \
|
|
|
|
*sptr = '\0'; /* NULL terminate sptr. */ \
|
|
|
|
result = fprintf(stream, specifier, value); \
|
|
|
|
if (result == -1) \
|
|
|
|
return -1; \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
total_printed += result; \
|
|
|
|
continue; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
int
|
|
|
|
_doprnt (format, ap, stream)
|
|
|
|
const char * format;
|
|
|
|
va_list ap;
|
|
|
|
FILE * stream;
|
|
|
|
{
|
|
|
|
const char * ptr = format;
|
|
|
|
char specifier[128];
|
|
|
|
int total_printed = 0;
|
|
|
|
|
|
|
|
while (*ptr != '\0')
|
|
|
|
{
|
|
|
|
if (*ptr != '%') /* While we have regular characters, print them. */
|
|
|
|
PRINT_CHAR(*ptr);
|
|
|
|
else /* We got a format specifier! */
|
|
|
|
{
|
|
|
|
char * sptr = specifier;
|
|
|
|
int wide_width = 0, short_width = 0;
|
|
|
|
|
|
|
|
*sptr++ = *ptr++; /* Copy the % and move forward. */
|
|
|
|
|
|
|
|
while (strchr ("-+ #0", *ptr)) /* Move past flags. */
|
|
|
|
*sptr++ = *ptr++;
|
|
|
|
|
|
|
|
if (*ptr == '*')
|
|
|
|
COPY_VA_INT;
|
|
|
|
else
|
|
|
|
while (isdigit(*ptr)) /* Handle explicit numeric value. */
|
|
|
|
*sptr++ = *ptr++;
|
|
|
|
|
|
|
|
if (*ptr == '.')
|
|
|
|
{
|
|
|
|
*sptr++ = *ptr++; /* Copy and go past the period. */
|
|
|
|
if (*ptr == '*')
|
|
|
|
COPY_VA_INT;
|
|
|
|
else
|
|
|
|
while (isdigit(*ptr)) /* Handle explicit numeric value. */
|
|
|
|
*sptr++ = *ptr++;
|
|
|
|
}
|
|
|
|
while (strchr ("hlL", *ptr))
|
|
|
|
{
|
|
|
|
switch (*ptr)
|
|
|
|
{
|
|
|
|
case 'h':
|
|
|
|
short_width = 1;
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
wide_width++;
|
|
|
|
break;
|
|
|
|
case 'L':
|
|
|
|
wide_width = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
*sptr++ = *ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (*ptr)
|
|
|
|
{
|
|
|
|
case 'd':
|
|
|
|
case 'i':
|
|
|
|
case 'o':
|
|
|
|
case 'u':
|
|
|
|
case 'x':
|
|
|
|
case 'X':
|
|
|
|
case 'c':
|
|
|
|
{
|
|
|
|
/* Short values are promoted to int, so just copy it
|
|
|
|
as an int and trust the C library printf to cast it
|
|
|
|
to the right width. */
|
|
|
|
if (short_width)
|
|
|
|
PRINT_TYPE(int);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (wide_width)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
PRINT_TYPE(int);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
PRINT_TYPE(long);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
default:
|
|
|
|
#if defined(__GNUC__) || defined(HAVE_LONG_LONG)
|
|
|
|
PRINT_TYPE(long long);
|
|
|
|
#else
|
|
|
|
PRINT_TYPE(long); /* Fake it and hope for the best. */
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
} /* End of switch (wide_width) */
|
|
|
|
} /* End of else statement */
|
|
|
|
} /* End of integer case */
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
case 'g':
|
|
|
|
case 'G':
|
|
|
|
{
|
|
|
|
if (wide_width == 0)
|
|
|
|
PRINT_TYPE(double);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#if defined(__GNUC__) || defined(HAVE_LONG_DOUBLE)
|
|
|
|
PRINT_TYPE(long double);
|
|
|
|
#else
|
|
|
|
PRINT_TYPE(double); /* Fake it and hope for the best. */
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
PRINT_TYPE(char *);
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
PRINT_TYPE(void *);
|
|
|
|
break;
|
|
|
|
case '%':
|
|
|
|
PRINT_CHAR('%');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
} /* End of switch (*ptr) */
|
|
|
|
} /* End of else statement */
|
|
|
|
}
|
|
|
|
|
|
|
|
return total_printed;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef TEST
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#ifndef M_PI
|
|
|
|
#define M_PI (3.1415926535897932385)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define RESULT(x) do \
|
|
|
|
{ \
|
|
|
|
int i = (x); \
|
|
|
|
printf ("printed %d characters\n", i); \
|
|
|
|
fflush(stdin); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
static int checkit PVPROTO ((const char * format, ...)) ATTRIBUTE_PRINTF_1;
|
|
|
|
|
|
|
|
static int
|
|
|
|
checkit VPROTO ((const char* format, ...))
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
int result;
|
|
|
|
|
gansidecl.h: Prepend a "G" to the macro wrapping this file (to distinguish it from the macro...
* gansidecl.h: Prepend a "G" to the macro wrapping this file
(to distinguish it from the macro wrapping ansidecl.h.)
Include libiberty's ansidecl.h. Remove all redundant definitions.
Define the PROTO() style macros in terms of the PARAMS() ones.
* calls.c (emit_library_call): Switch on ANSI_PROTOTYPES, not
__STDC__, when deciding whether to use ANSI variable args.
(emit_library_call_value): Likewise.
* cccp.c (error): Likewise.
(warning): Likewise.
(error_with_line): Likewise.
(warning_with_line): Likewise.
(pedwarn): Likewise.
(pedwarn_with_line): Likewise.
(pedwarn_with_file_and_line): Likewise.
(fatal): Likewise.
* cexp.y (error): Likewise.
(pedwarn): Likewise.
(warning): Likewise.
* collect2.c (fatal_perror): Likewise.
(fatal): Likewise.
(error): Likewise.
* combine.c (gen_rtx_combine): Likewise.
* cpperror.c (cpp_message): Likewise.
(cpp_fatal): Likewise.
* cpplib.c (cpp_error): Likewise.
(cpp_warning): Likewise.
(cpp_pedwarn): Likewise.
(cpp_error_with_line): Likewise.
(cpp_warning_with_line): Likewise.
(cpp_pedwarn_with_line): Likewise.
(cpp_pedwarn_with_file_and_line): Likewise.
* cpplib.h: Don't define PARAMS() macro.
* demangle.h: Likewise.
* doprint.c (checkit): Switch on ANSI_PROTOTYPES, not __STDC__,
when deciding whether to use ANSI variable args.
* emit-rtl.c (gen_rtx): Likewise.
(gen_rtvec): Likewise.
* final.c (asm_fprintf): Likewise.
* fix-header.c (cpp_message): Likewise.
(fatal): Likewise.
(cpp_fatal): Likewise.
* gcc.c (concat): Likewise.
(fatal): Likewise.
(error): Likewise.
* genattr.c (fatal): Likewise.
* genattrtab.c (attr_rtx): Likewise.
(attr_printf): Likewise.
(fatal): Likewise.
* gencodes.c (fatal): Likewise.
* genconfig.c (fatal): Likewise.
* genemit.c (fatal): Likewise.
* genextract.c (fatal): Likewise.
* genflags.c (fatal): Likewise.
* genopinit.c (fatal): Likewise.
* genoutput.c (fatal): Likewise.
(error): Likewise.
* genpeep.c (fatal): Likewise.
* genrecog.c (fatal): Likewise.
* halfpic.h: Switch on ANSI_PROTOTYPES, not __STDC__, when
deciding whether to declare `tree_node' and `rtx_def'.
* hash.h: Don't define stuff we get from gansidecl.h.
* mips-tfile.c: Likewise. Define __proto() in terms of PARAMS().
(fatal): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding
whether to use ANSI variable args.
(error): Likewise.
* prefix.c (concat): Likewise.
* scan.h: Likewise.
* system.h: Likewise.
* toplev.c (error_with_file_and_line): Likewise.
(error_with_decl): Likewise.
(error_for_asm): Likewise.
(error): Likewise.
(fatal): Likewise.
(warning_with_file_and_line): Likewise.
(warning_with_decl): Likewise.
(warning_for_asm): Likewise.
(warning): Likewise.
(pedwarn): Likewise.
(pedwarn_with_decl): Likewise.
(pedwarn_with_file_and_line): Likewise.
(sorry): Likewise.
(really_sorry): Likewise.
* toplev.h: Switch on ANSI_PROTOTYPES, not __STDC__, when deciding
whether to declare `tree_node' and `rtx_def'.
* tree.c (build): Switch on ANSI_PROTOTYPES, not __STDC__, when
deciding whether to use ANSI variable args.
(build_nt): Likewise.
(build_parse_node): Likewise.
From-SVN: r23577
1998-11-08 10:10:24 -05:00
|
|
|
#ifndef ANSI_PROTOTYPES
|
1998-05-07 07:44:09 -04:00
|
|
|
char *format;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
VA_START (args, format);
|
|
|
|
|
gansidecl.h: Prepend a "G" to the macro wrapping this file (to distinguish it from the macro...
* gansidecl.h: Prepend a "G" to the macro wrapping this file
(to distinguish it from the macro wrapping ansidecl.h.)
Include libiberty's ansidecl.h. Remove all redundant definitions.
Define the PROTO() style macros in terms of the PARAMS() ones.
* calls.c (emit_library_call): Switch on ANSI_PROTOTYPES, not
__STDC__, when deciding whether to use ANSI variable args.
(emit_library_call_value): Likewise.
* cccp.c (error): Likewise.
(warning): Likewise.
(error_with_line): Likewise.
(warning_with_line): Likewise.
(pedwarn): Likewise.
(pedwarn_with_line): Likewise.
(pedwarn_with_file_and_line): Likewise.
(fatal): Likewise.
* cexp.y (error): Likewise.
(pedwarn): Likewise.
(warning): Likewise.
* collect2.c (fatal_perror): Likewise.
(fatal): Likewise.
(error): Likewise.
* combine.c (gen_rtx_combine): Likewise.
* cpperror.c (cpp_message): Likewise.
(cpp_fatal): Likewise.
* cpplib.c (cpp_error): Likewise.
(cpp_warning): Likewise.
(cpp_pedwarn): Likewise.
(cpp_error_with_line): Likewise.
(cpp_warning_with_line): Likewise.
(cpp_pedwarn_with_line): Likewise.
(cpp_pedwarn_with_file_and_line): Likewise.
* cpplib.h: Don't define PARAMS() macro.
* demangle.h: Likewise.
* doprint.c (checkit): Switch on ANSI_PROTOTYPES, not __STDC__,
when deciding whether to use ANSI variable args.
* emit-rtl.c (gen_rtx): Likewise.
(gen_rtvec): Likewise.
* final.c (asm_fprintf): Likewise.
* fix-header.c (cpp_message): Likewise.
(fatal): Likewise.
(cpp_fatal): Likewise.
* gcc.c (concat): Likewise.
(fatal): Likewise.
(error): Likewise.
* genattr.c (fatal): Likewise.
* genattrtab.c (attr_rtx): Likewise.
(attr_printf): Likewise.
(fatal): Likewise.
* gencodes.c (fatal): Likewise.
* genconfig.c (fatal): Likewise.
* genemit.c (fatal): Likewise.
* genextract.c (fatal): Likewise.
* genflags.c (fatal): Likewise.
* genopinit.c (fatal): Likewise.
* genoutput.c (fatal): Likewise.
(error): Likewise.
* genpeep.c (fatal): Likewise.
* genrecog.c (fatal): Likewise.
* halfpic.h: Switch on ANSI_PROTOTYPES, not __STDC__, when
deciding whether to declare `tree_node' and `rtx_def'.
* hash.h: Don't define stuff we get from gansidecl.h.
* mips-tfile.c: Likewise. Define __proto() in terms of PARAMS().
(fatal): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding
whether to use ANSI variable args.
(error): Likewise.
* prefix.c (concat): Likewise.
* scan.h: Likewise.
* system.h: Likewise.
* toplev.c (error_with_file_and_line): Likewise.
(error_with_decl): Likewise.
(error_for_asm): Likewise.
(error): Likewise.
(fatal): Likewise.
(warning_with_file_and_line): Likewise.
(warning_with_decl): Likewise.
(warning_for_asm): Likewise.
(warning): Likewise.
(pedwarn): Likewise.
(pedwarn_with_decl): Likewise.
(pedwarn_with_file_and_line): Likewise.
(sorry): Likewise.
(really_sorry): Likewise.
* toplev.h: Switch on ANSI_PROTOTYPES, not __STDC__, when deciding
whether to declare `tree_node' and `rtx_def'.
* tree.c (build): Switch on ANSI_PROTOTYPES, not __STDC__, when
deciding whether to use ANSI variable args.
(build_nt): Likewise.
(build_parse_node): Likewise.
From-SVN: r23577
1998-11-08 10:10:24 -05:00
|
|
|
#ifndef ANSI_PROTOTYPES
|
1998-05-07 07:44:09 -04:00
|
|
|
format = va_arg (args, char *);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
result = _doprnt (format, args, stdout);
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main ()
|
|
|
|
{
|
|
|
|
RESULT(checkit ("<%d>\n", 0x12345678));
|
|
|
|
RESULT(printf ("<%d>\n", 0x12345678));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%200d>\n", 5));
|
|
|
|
RESULT(printf ("<%200d>\n", 5));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%.300d>\n", 6));
|
|
|
|
RESULT(printf ("<%.300d>\n", 6));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%100.150d>\n", 7));
|
|
|
|
RESULT(printf ("<%100.150d>\n", 7));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%s>\n",
|
|
|
|
"jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
|
|
|
|
777777777777777777333333333333366666666666622222222222777777777777733333"));
|
|
|
|
RESULT(printf ("<%s>\n",
|
|
|
|
"jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
|
|
|
|
777777777777777777333333333333366666666666622222222222777777777777733333"));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%f><%0+#f>%s%d%s>\n",
|
|
|
|
1.0, 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"));
|
|
|
|
RESULT(printf ("<%f><%0+#f>%s%d%s>\n",
|
|
|
|
1.0, 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%4f><%.4f><%%><%4.4f>\n", M_PI, M_PI, M_PI));
|
|
|
|
RESULT(printf ("<%4f><%.4f><%%><%4.4f>\n", M_PI, M_PI, M_PI));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%*f><%.*f><%%><%*.*f>\n", 3, M_PI, 3, M_PI, 3, 3, M_PI));
|
|
|
|
RESULT(printf ("<%*f><%.*f><%%><%*.*f>\n", 3, M_PI, 3, M_PI, 3, 3, M_PI));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%d><%i><%o><%u><%x><%X><%c>\n",
|
|
|
|
75, 75, 75, 75, 75, 75, 75));
|
|
|
|
RESULT(printf ("<%d><%i><%o><%u><%x><%X><%c>\n",
|
|
|
|
75, 75, 75, 75, 75, 75, 75));
|
|
|
|
|
|
|
|
RESULT(checkit ("<%d><%i><%o><%u><%x><%X><%c>\n",
|
|
|
|
75, 75, 75, 75, 75, 75, 75));
|
|
|
|
RESULT(printf ("<%d><%i><%o><%u><%x><%X><%c>\n",
|
|
|
|
75, 75, 75, 75, 75, 75, 75));
|
|
|
|
|
|
|
|
RESULT(checkit ("Testing (hd) short: <%d><%ld><%hd><%hd><%d>\n", 123, (long)234, 345, 123456789, 456));
|
|
|
|
RESULT(printf ("Testing (hd) short: <%d><%ld><%hd><%hd><%d>\n", 123, (long)234, 345, 123456789, 456));
|
|
|
|
|
|
|
|
#if defined(__GNUC__) || defined (HAVE_LONG_LONG)
|
|
|
|
RESULT(checkit ("Testing (lld) long long: <%d><%lld><%d>\n", 123, 234234234234234234LL, 345));
|
|
|
|
RESULT(printf ("Testing (lld) long long: <%d><%lld><%d>\n", 123, 234234234234234234LL, 345));
|
|
|
|
RESULT(checkit ("Testing (Ld) long long: <%d><%Ld><%d>\n", 123, 234234234234234234LL, 345));
|
|
|
|
RESULT(printf ("Testing (Ld) long long: <%d><%Ld><%d>\n", 123, 234234234234234234LL, 345));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__GNUC__) || defined (HAVE_LONG_DOUBLE)
|
|
|
|
RESULT(checkit ("Testing (Lf) long double: <%.20f><%.20Lf><%0+#.20f>\n",
|
|
|
|
1.23456, 1.234567890123456789L, 1.23456));
|
|
|
|
RESULT(printf ("Testing (Lf) long double: <%.20f><%.20Lf><%0+#.20f>\n",
|
|
|
|
1.23456, 1.234567890123456789L, 1.23456));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* TEST */
|