Git Product home page Git Product logo

format's People

Contributors

awulkiew avatar belcourt avatar beman avatar bkentel avatar brycelelbach avatar dabrahams avatar danieljames avatar douggregor avatar eldiener avatar flamefire avatar glenfe avatar grafikrobot avatar hkaiser avatar imikejackson avatar jeking3 avatar jewillco avatar jhunold avatar joachim-faulhaber avatar joaquintides avatar jzmaddock avatar lanurmi avatar mclow avatar pdimov avatar sdarwin avatar soukouki avatar stbergmann avatar steveire avatar straszheim avatar swatanabe avatar vprus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

format's Issues

Direct use of `Allocator::allocate` is deprecated in C++17

#ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
void *vd_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
Ch *new_ptr = static_cast<Ch *>(vd_ptr);
#else
Ch *new_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
#endif

Should use allocator_traits when at least C++11 is detected instead; the above code produces a deprecation warning in some compiler configurations.

There might be some other code that should be updated as well, but this was the only one that I noticed a warning being flagged on (when compiling with VS2017 in C++17 mode).

Wdeprecated-copy warnings from group.hpp.

In file included from src/config/printer.cpp:19:
In file included from ./include/bitcoin/system/config/printer.hpp:25:
In file included from /home/runner/work/libbitcoin-system/libbitcoin-system/prefixenv/include/boost/format.hpp:48:
/home/runner/work/libbitcoin-system/libbitcoin-system/prefixenv/include/boost/format/group.hpp:59:12: warning: definition of implicit copy constructor for 'group1<boost::io::detail::group0>' is deprecated because it has a user-declared copy assignment operator [-Wdeprecated-copy]
   group1& operator=(const group1&);
           ^
/home/runner/work/libbitcoin-system/libbitcoin-system/prefixenv/include/boost/format/group.hpp:472:18: note: in implicit copy constructor for 'boost::io::detail::group1<boost::io::detail::group0>' first required here
group() { return detail::group1< detail::group0 > ( detail::group0() ); }
                 ^
  CXX      src/config/libbitcoin_system_la-script.lo
1 warning generated.

https://github.com/evoskuil/libbitcoin-system/runs/6664512291?check_suite_focus=true#step:6:2861

Origin: https://www.boost.org/doc/libs/1_79_0/boost/format/group.hpp

This warning repeats heavily in all of versions of boost, and there are no other warnings in our clang builds, which incorporate many boost libraries. There is no apparent workaround apart from global warning suppression.

Support thousands separator

I know the docs say

the ' printf option (format with thousands grouping characters)) has no effect in format.

and the code says

case '\'':
break; // no effect yet. (painful to implement)

but it would be really neat if this could be supported in the future.

I assume the issue is that Boost::format is essentially trying to achieve all (or at least the majority) of its formatting using standard stream flags and there is none for thousands separators?

From https://stackoverflow.com/questions/17530408/print-integer-with-thousands-and-millions-separator it seems that what would be necessary is to use a imbue in combination with a locale.
Has this been considered yet?

EDIT: This approach seems to at least break when using Boost::multiprecision numbers with the stream at which case the thousands separator is ignored again.

Redundant condition

else if(way == ::std::ios_base::beg)

Line 127 is -
else if(way == ::std::ios_base::beg)

It is followed on line 129 -
else if(way != ::std::ios_base::beg)

Which, of course is always true given the previous test. This "impossible-redundant-condition" was spotted by a source analyser I used.

Allow to compile with "-Werror=suggest-override"

Newer versions of clang / gcc support a suggest-override warning: If you have a file format_error.cpp

#include <boost/format.hpp>

the compilation with e.g. Apple clang version 13.0.0 (clang-1300.0.29.3)

clang++ -std=c++11 -c -Werror=suggest-override format_error.cpp

will produce

In file included from format_error.cpp:1:
In file included from /usr/local/include/boost/format.hpp:44:
/usr/local/include/boost/format/exceptions.hpp:33:33: error: 'what' overrides a member function but is not marked 'override' [-Werror,-Wsuggest-override]
            virtual const char *what() const throw() {
                                ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/exception:104:25: note: overridden virtual function is here
    virtual const char* what() const _NOEXCEPT;
                        ^

Add a release note for 1.86.0 about the C++11 language level requirement

boost::format has a number of dependencies, some of which have moved to only supporting C++11:

  1. boost::optional
  2. boost::smart_ptr

Therefore boost::format must join them in only supporting C++11 or later.

We can reduce the complexity of CI builds a bit, dropping older compilers and the 98 and 03 language level builds.

Encoding error in generated page

In this page the output is broken because the source code file uses ISO-8859-1 but is assumed to be UTF-8 when copying to the web page. Github guesses the correct encoding so it displays properly

The server must be fixed to read the file in the correct encoding, or just convert all files to UTF-8. I think the latter is the best solution

image

Parse Microsoft extension argument size modifiers (I, I32, I64)

This is a request from Dan Konigsbach on Boost Trac which I am moving to github issues.

Microsoft's printf implementation includes non-ANSI extensions to the valid length modifier prefixes: I, I32, and I64. boost::format currently does not recognize them.

It would ease migration to boost::format if parse_printf_directive() in format/parsing.hpp would parse and ignore them, just as it currently does with h and l.

(Note: I'd be willing to code the proposed enhancement, if that's appropriate.)

Thanks!!!! Dan K.

Reference: https://msdn.microsoft.com/en-us/library/56e442dc.aspx

Note that even though we could add parsing for these options, they would be summarily ignored by the current implementation because no conversion is done based on argument size. These modifiers are parsed and ignored because the type passed in defines the argument size.

Enhancement: format (u)int8 types correctly to number, if formatted with %d, &i, %u

If I try to format a (u)int8 number, Boost.Format considers this as (unsigned) char, even if I use %d, %i or %u.

This is a known and rather old issue.

The workaround is to cast the number to (u)int32, before formatting.

Nevertheless the current behavior leads to very subtle bugs, because the developer has to check the type of the number to be printed very carefully.

Plain printf handles (u)int8 numbers in combination with %d, %i or %u correctly.

Boost version: 1.68 (32bit)
Compiler: MSVC 15.8

basic_format = operator does not swap locale

Tracking down a locale related bug in my source code, I found that the = operator of basic_format doesn't swap its locale, though the copy constructor does copy it. I find it confusing and hard to use this way, if i want to use a basic_format as a member and change it according to different needs.

template< class Ch, class Tr, class Alloc> // just don't copy the buf_ member
basic_format<Ch, Tr, Alloc>:: basic_format(const basic_format& x)
: items_(x.items_), bound_(x.bound_), style_(x.style_),
cur_arg_(x.cur_arg_), num_args_(x.num_args_), dumped_(x.dumped_),
prefix_(x.prefix_), exceptions_(x.exceptions_), loc_(x.loc_)
{
}
template< class Ch, class Tr, class Alloc> // just don't copy the buf_ member
basic_format<Ch, Tr, Alloc>& basic_format<Ch, Tr, Alloc>::
operator= (const basic_format& x) {
if(this == &x)
return *this;
(basic_format<Ch, Tr, Alloc>(x)).swap(*this);
return *this;
}
template< class Ch, class Tr, class Alloc>
void basic_format<Ch, Tr, Alloc>::
swap (basic_format & x) {
std::swap(exceptions_, x.exceptions_);
std::swap(style_, x.style_);
std::swap(cur_arg_, x.cur_arg_);
std::swap(num_args_, x.num_args_);
std::swap(dumped_, x.dumped_);
items_.swap(x.items_);
prefix_.swap(x.prefix_);
bound_.swap(x.bound_);
}

Modular Boost C++ Libraries Request

We are in the process of making B2 build changes to all of the B2 build files
to support "modular" consumption of the Boost Libraries by users. See this list
post for some details: https://lists.boost.org/Archives/boost/2024/01/255704.php

The process requires making a variety of changes to make each Boost library
independent of the super-project structure. But the changes do not remove the
super-project structure or the comprehensive Boost release. The changes make
solely make it possible, optionally, for users, like package manages, to easily
consume libraries individually.

Generally the changes include:

  • Adding a libroot/build.jam.
  • Porting any functionality from libroot/jamfile to libroot/build.jam.
  • Moving boost-install declaration from libroot/build/jamfile is applicable.
  • Adjusting other B2 build files in the library, like test/jamfile, as needed.
  • Possible changes to C++ source files to remove includes relative to the
    super-project boostroot location.

Some examples of such changes:

We are asking how you would like us to handle the changes. We would prefer if
you allow the owners of the Boost.org GitHub project to make changes to B2
build files, as needed, to accomplish the changes. But understand
that you may want to manage the proposed changes yourself.

We previously sent emails to all known maintainers to fill out a form with their
preference. We are contacting you in this issue as we have not gotten a response
to that email. You can see the ongoing responses for that form and the responses
to these issues here https://github.com/users/grafikrobot/projects/1/views/6

We are now asking if you can reply directly to this issue to indicate your
preference of handling the changes. Please supply a response to this question
and close the issue (so that we can verify you are a maintainer).

How would you like the build changes to be processed?

  1. Pull request, reviewed and merged by a BOOSTORG OWNER.
  2. Pull request, reviewed and merged by YOU.
  3. Other. (please specify details in the reply)

Also please indicate any special instructions you want us to consider. Or other
information you want us to be aware of.

Thanks you, René

Parse additional ISO C99 format string specifiers

Argument Types

Per the Boost.Format documentation, argument types are ignored, however there are some newer ones that appeared in ISO C99 which should be parsed at least so that an exception is not thrown:

Currently, using 'hh', 'h', 'l', 'll', and 'L' parse properly, however using 'j' or 'z', cause a boost::io::bad_format_string.

The argument type specifier 't' from C++11 cannot be honored by boost::format because 'T' and 't' are used in boost::format for tabulations.

boost format operator % won't accept dereference of volatile

Originally reported by Paul Rose in Boost Trac.

struct A{
    A() : a(9) {} int a;
}; A a; A volatile *pva = &a;

std::cout << boost::format("%d") % pva->a << std::endl;

This worked in 1_54 but fails in 1_56 with error:
    format/feed_args.hpp:135:47: error: invalid conversion from 'volatile void*' to 'const void*'

Can work around this with cast:
    std::cout << boost::format("%d") % (int)pva->a << std::endl;
but should not have to. The appearance to the user is pass by value.

Running linux with g++ 4.6.2 and 4.8.2

Originally reported in Boost 1.56.0.
Confirmed in Boost 1.59.0 with clang-3.8 on linux.
Confirmed in Boost 1.61.0 with VS2008.
Confirmed in Boost 1.63.0 with gcc-5.2.

Misspelled config macro

format.hpp refers to a macro BOOST_NO_LOCALE_ISIDIGIT, which probably should be BOOST_NO_LOCALE_ISDIGIT

"sign=space & pad_0s_until_width & alignment=right/internal/center" do not work together ("sign=space" is ignored)

#include<string>
#include<iostream>
#include<iomanip>
#include<boost/format.hpp>

class Rational {
public:
    Rational(int n, unsigned int d) : n_(n), d_(d) {}
    Rational(int n, int d);    // convert denominator to unsigned
    friend std::ostream& operator<<(std::ostream&, const Rational&);
private:
    int n_;               // numerator
    unsigned int d_;      // denominator
};

Rational::Rational(int n, int d) : n_(n)
{
    if (d < 0) { n_ = -n_; d = -d; } // make the denominator always non-negative.
    d_ = static_cast<unsigned int>(d);
}

std::ostream& operator<<(std::ostream& os, const Rational& r) {
    using namespace std;
    streamsize w = os.width(0); // width has to be zeroed before saving state.

    boost::io::basic_oaltstringstream<char> oss;
    oss.copyfmt(os);
    oss << r.n_ << "/" << noshowpos << r.d_;

    os.write(oss.begin(), oss.size());
    return os;
}

int main(int argc, char* argv[])
{
    using namespace std;
    using boost::format;
    using boost::io::group;
    using boost::io::str;

    std::printf("[%8s][%8s]\n", "format", "printf");

    std::printf("\nright:\n");//'+'/' ', right
    std::cerr << boost::format("[%+8d]") % 12; std::printf("[%+8d]\n", 12);
    std::cerr << boost::format("[% 8d]") % 12; std::printf("[% 8d]\n", 12);
    std::cerr << boost::format("[%+08d]") % 12; std::printf("[%+08d]\n", 12);
    std::cerr << boost::format("[% 08d]") % 12; std::printf("[% 08d] !!!\n", 12);

    std::printf("\ninternal:\n");//'+'/' ', internal('_')
    std::cerr << boost::format("[%_+8d]\n") % 12;
    std::cerr << boost::format("[%_ 8d]\n") % 12;
    std::cerr << boost::format("[%_+08d]\n") % 12;
    std::cerr << boost::format("[%_ 08d] !!!\n") % 12;

    std::printf("\ncenter:\n");//'+'/' ', center('=')
    std::cerr << boost::format("[%=+8d]\n") % 12;
    std::cerr << boost::format("[%= 8d]\n") % 12;
    std::cerr << boost::format("[%=+08d]\n") % 12;
    std::cerr << boost::format("[%= 08d] !!!\n") % 12;

    std::printf("\nleft:\n");//'+'/' ', left('-')
    std::cerr << boost::format("[%-+8d]") % 12; std::printf("[%-+8d]\n", 12);
    std::cerr << boost::format("[%- 8d]") % 12; std::printf("[%- 8d]\n", 12);
    std::cerr << boost::format("[%-+08d]") % 12; std::printf("[%-+08d]\n", 12);
    std::cerr << boost::format("[%- 08d]") % 12; std::printf("[%- 08d]\n", 12);

    Rational  r(16, 9);
    std::printf("\nright:\n");
    cerr << format("[%+8d]\n") % r;
    cerr << format("[% 8d]\n") % r;
    cerr << format("[%+08d]\n") % r;
    cerr << format("[% 08d] !!!\n") % r;

    std::printf("\ninternal:\n");
    cerr << format("[%_+8d]\n") % r;
    cerr << format("[%_ 8d]\n") % r;
    cerr << format("[%_+08d]\n") % r;
    cerr << format("[%_ 08d] !!!\n") % r;

    std::printf("\ncenter:\n");
    cerr << format("[%=+8d]\n") % r;
    cerr << format("[%= 8d]\n") % r;
    cerr << format("[%=+08d]\n") % r;
    cerr << format("[%= 08d] !!!\n") % r;

    std::printf("\nleft:\n");
    cerr << format("[%-+8d]\n") % r;
    cerr << format("[%- 8d]\n") % r;
    cerr << format("[%-+08d]\n") % r;
    cerr << format("[%- 08d]\n") % r;
}

output (boost.format on the left, std::printf on the right, the differences is marked with !!!):

[  format][  printf]

right:
[     +12][     +12]
[      12][      12]
[+0000012][+0000012]
[00000012][ 0000012] !!!

internal:
[+     12]
[      12]
[+0000012]
[00000012] !!!

center:
[   +12  ]
[    12  ]
[+0000012]
[00000012] !!!

left:
[+12     ][+12     ]
[ 12     ][ 12     ]
[+12     ][+12     ]
[ 12     ][ 12     ]

right:
[   +16/9]
[    16/9]
[000+16/9]
[000016/9] !!!

internal:
[   +16/9]
[    16/9]
[000+16/9]
[000016/9] !!!

center:
[  +16/9 ]
[   16/9 ]
[000+16/9]
[000016/9] !!!

left:
[+16/9   ]
[ 16/9   ]
[+16/9   ]
[ 16/9   ]

ISO C99 Standards Support

I am working on identifying where boost::format and sprintf differ in behavior. I wrote a matrix test comparing standard sprintf to boost::format for purposes of ensuring that boost::format handles all of the format strings that sprintf does, and we're currently at about 41% pass rate. This matrix doesn't test every possible combination of format modifiers yet - just one of each was enough. Results are very early, and I will be working on improving this.

Here's some sample output from the test:

       Format String | RSLT | "printf"                              | "boost::format"                       | error info
---------------------+------+---------------------------------------+---------------------------------------+--------------------------------------------------
              % 1.5c | FAIL | "X"                                   | " "                                   | mismatch
             % 1.20c | FAIL | "X"                                   | " "                                   | mismatch
                % 2c | FAIL | " X"                                  | "  "                                  | mismatch
               % 2.c | FAIL | " X"                                  | "  "                                  | mismatch
...
                 %5u |      | "4294954950"                          | "4294954950"                          |
                %5.u |      | "4294954950"                          | "4294954950"                          |
               %5.2u |      | "4294954950"                          | "4294954950"                          |
               %5.5u |      | "4294954950"                          | "4294954950"                          |
              %5.20u | FAIL | "00000000004294954950"                | "4294954950"                          | mismatch
...
              %020Lf |      | "6543211234567.891602"                | "6543211234567.891602"                |
             %020.Lf |      | "00000006543211234568"                | "00000006543211234568"                |
            %020.2Lf |      | "00006543211234567.89"                | "00006543211234567.89"                |
            %020.5Lf |      | "06543211234567.89160"                | "06543211234567.89160"                |
           %020.20Lf |      | "6543211234567.89160156250000000000"  | "6543211234567.89160156250000000000"  |
                  %F | EXCP | "1234567.875000"                      | ""                                    | boost::bad_format_string: format-string is ill-formed
...
              %020LG |      | "0000000006.54321E+12"                | "0000000006.54321E+12"                |
             %020.LG | FAIL | "0000000000000007E+12"                | "0000000006.54321E+12"                | mismatch
            %020.2LG |      | "00000000000006.5E+12"                | "00000000000006.5E+12"                |
            %020.5LG |      | "00000000006.5432E+12"                | "00000000006.5432E+12"                |
           %020.20LG |      | "6543211234567.8916016"               | "6543211234567.8916016"               |

Failed Tests: 6707
Total Tests: 11401
Pass Rate: 41.2%

Add a test tool that will allow comparison between releases to identify regressions

In general, Boost.Format is a stable and long-lived component and used by many consumers. Changes to the behavior of Boost.Format could cause widespread issues. A mechanism is needed that will allow comparison of one edition of Boost.Format to another to ensure there haven't been any regressions.

Proposal

Create a matrix tester that will attempt to generate every possible format syntax string expression, and test against a variety of inputs appropriate to that type, and output the results to a text file which will be considered the results file. The results file format is:

# glibc.version = n
{format specification}<tab>OK |ERR<tab>string result or exception message
...

The tool will also allow for results to be generated against the platform's snprintf call, so that boost::format and snprintf on the same inputs and format specifications can be compared.

Support std::variant

Hello. I have a problem with using std::variant with boost::format.
Visual Studio 2019 - 16.7.3
boost - 1.74

Sample code:

`
#include < iostream>
#include < variant>
#include <boost/variant.hpp>
#include <boost/format.hpp>

typedef std::variant<uint16_t, std::string> MemCaptureIdType;
//typedef boost::variant<uint16_t, std::string> MemCaptureIdType;

std::ostream& operator<<(std::ostream& os, const MemCaptureIdType& type)
{
return os;
}

int main()
{
auto tmp1 = MemCaptureIdType(0);

auto tmp = boost::format("%1%") % tmp1;

return 0;

}
`

But it works when I use boost::variant.
I think we need to support std::variant.

Failures when build boost with MSVC+ /permissive-

Boost test ‘test_json_parser’ in libs\property_tree\test failed with error C2589 C2760 when build with /permissive- in windows, this is source issue looks involved by bc53dbb#diff-67bfd7972eb56b5161d31780dbaa62a2

The source includes windows.h which defines the macro 'min' and 'max'. It need define ‘NOMINMAX’ before include ‘windows.h‘.

Environment: windows server 2016 + Visual studio 2017 update2 + Boost( master branch with latest revision ‘b30e350’)

Failures like:
test_json_parser.cpp
Info: Boost.Config is older than your compiler version - probably nothing bad will happen - but you may wish to look for an update Boost version. Define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE to suppress this message.
.\boost/format/feed_args.hpp(205): warning C4003: not enough actual parameters for macro 'max'
.\boost/format/feed_args.hpp(250): warning C4003: not enough actual parameters for macro 'max'
.\boost/format/feed_args.hpp(205): error C2589: '(': illegal token on right side of '::'
.\boost/format/feed_args.hpp(205): error C2760: syntax error: unexpected token '(', expected ')'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.