2012-07-02 23:29:39 +08:00
|
|
|
/* Parse a printf-style format string.
|
|
|
|
|
2018-01-01 12:43:02 +08:00
|
|
|
Copyright (C) 1986-2018 Free Software Foundation, Inc.
|
2012-07-02 23:29:39 +08:00
|
|
|
|
|
|
|
This file is part of GDB.
|
|
|
|
|
|
|
|
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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
2017-11-23 00:37:05 +08:00
|
|
|
#ifndef COMMON_FORMAT_H
|
|
|
|
#define COMMON_FORMAT_H
|
|
|
|
|
2018-05-18 01:05:59 +08:00
|
|
|
#include "common/gdb_string_view.h"
|
|
|
|
|
2012-07-02 23:29:39 +08:00
|
|
|
#if defined(__MINGW32__) && !defined(PRINTF_HAS_LONG_LONG)
|
|
|
|
# define USE_PRINTF_I64 1
|
|
|
|
# define PRINTF_HAS_LONG_LONG
|
|
|
|
#else
|
|
|
|
# define USE_PRINTF_I64 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* The argclass represents the general type of data that goes with a
|
|
|
|
format directive; int_arg for %d, long_arg for %l, and so forth.
|
|
|
|
Note that these primarily distinguish types by size and need for
|
|
|
|
special handling, so for instance %u and %x are (at present) also
|
|
|
|
classed as int_arg. */
|
|
|
|
|
|
|
|
enum argclass
|
|
|
|
{
|
|
|
|
literal_piece,
|
|
|
|
int_arg, long_arg, long_long_arg, ptr_arg,
|
|
|
|
string_arg, wide_string_arg, wide_char_arg,
|
Target FP printing: Simplify and fix ui_printf
This patch adds support for handling format strings to both
floatformat_to_string and decimal_to_string, and then uses
those routines to implement ui_printf formatted printing.
There is already a subroutine printf_decfloat that ui_printf uses to
handle decimal FP. This is renamed to printf_floating and updated
to handle both binary and decimal FP. This includes the following
set of changes:
- printf_decfloat currently parses the format string again to determine
the intended target format. This seems superfluous since the common
parsing code in parse_format_string already did this, but then did
not pass the result on to its users. Fixed by splitting the decfloat_arg
argument class into three distinct classes, and passing them through.
- Now we can rename printf_decfloat to printf_floating and also call it
for the argument classes representing binary FP types.
- The code will now use the argclass to detect the type the value should
be printed at, and converts the input value to this type if necessary.
To remain compatible with current behavior, for binary FP the code
instead tries to re-interpret the input value as a FP type of the
same size if that exists. (Maybe this behavior is more confusing
than useful -- but this can be changed later if we want to ...)
- Finally, we can use floatformat_to_string / decimal_to_string passing
the format string to perform the formatted output using the desired
target FP type.
Note that we no longer generate different code depending on whether or not
the host supports "long double" -- this check is obsolete anyway since C++11
mandates "long double", and in any case a %lg format string is intended to
refer to the *target* long double type, not the host version.
Note also that formatted printing of DFP numbers may not work correctly,
since it attempts to use the host printf to do so (and makes unwarranted
assumptions about the host ABI while doing so!). This is no change to
the current behavior -- I simply moved the code from printf_decfloat to
the decimal_to_string routine in dfp.c. If we want to fix it in the
future, that is a more appropriate place anyway.
ChangeLog:
2017-10-24 Ulrich Weigand <uweigand@de.ibm.com>
* common/format.h (enum argclass): Replace decfloat_arg by
dec32float_arg, dec64float_arg, and dec128float_arg.
* common/format.c (parse_format_string): Update to return
new decimal float argument classes.
* printcmd.c (printf_decfloat): Rename to ...
(printf_floating): ... this. Add argclass argument, and use it
instead of parsing the format string again. Add support for
binary floating-point values, using floatformat_to_string.
Convert value to the target format if it doesn't already match.
(ui_printf): Call printf_floating instead of printf_decfloat,
also for double_arg / long_double_arg. Pass argclass.
* dfp.c (decimal_to_string): Add format string argument.
* dfp.h (decimal_to_string): Likewise.
* doublest.c (floatformat_to_string): Add format string argument.
* doublest.h (floatformat_to_string): Likewise.
2017-10-25 00:00:50 +08:00
|
|
|
double_arg, long_double_arg,
|
|
|
|
dec32float_arg, dec64float_arg, dec128float_arg
|
2012-07-02 23:29:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* A format piece is a section of the format string that may include a
|
|
|
|
single print directive somewhere in it, and the associated class
|
|
|
|
for the argument. */
|
|
|
|
|
|
|
|
struct format_piece
|
|
|
|
{
|
2017-11-23 11:17:28 +08:00
|
|
|
format_piece (const char *str, enum argclass argc)
|
|
|
|
: string (str),
|
|
|
|
argclass (argc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-05-18 01:05:59 +08:00
|
|
|
bool operator== (const format_piece &other) const
|
|
|
|
{
|
|
|
|
return (this->argclass == other.argclass
|
|
|
|
&& gdb::string_view (this->string) == other.string);
|
|
|
|
}
|
|
|
|
|
2017-11-23 11:17:28 +08:00
|
|
|
const char *string;
|
2012-07-02 23:29:39 +08:00
|
|
|
enum argclass argclass;
|
|
|
|
};
|
|
|
|
|
2017-11-23 11:17:28 +08:00
|
|
|
class format_pieces
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
format_pieces (const char **arg);
|
|
|
|
~format_pieces () = default;
|
|
|
|
|
|
|
|
DISABLE_COPY_AND_ASSIGN (format_pieces);
|
2012-07-02 23:29:39 +08:00
|
|
|
|
2017-11-23 11:17:28 +08:00
|
|
|
typedef std::vector<format_piece>::iterator iterator;
|
2012-07-02 23:29:39 +08:00
|
|
|
|
2017-11-23 11:17:28 +08:00
|
|
|
iterator begin ()
|
|
|
|
{
|
|
|
|
return m_pieces.begin ();
|
|
|
|
}
|
2012-07-02 23:29:39 +08:00
|
|
|
|
2017-11-23 11:17:28 +08:00
|
|
|
iterator end ()
|
|
|
|
{
|
|
|
|
return m_pieces.end ();
|
|
|
|
}
|
2012-07-02 23:29:39 +08:00
|
|
|
|
2017-11-23 11:17:28 +08:00
|
|
|
private:
|
|
|
|
|
|
|
|
std::vector<format_piece> m_pieces;
|
|
|
|
gdb::unique_xmalloc_ptr<char> m_storage;
|
|
|
|
};
|
2017-11-23 00:37:05 +08:00
|
|
|
|
|
|
|
#endif /* COMMON_FORMAT_H */
|