Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/sal/qa/rtl/strings/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 12 kB image not shown  

Quelle  test_ostring_stringliterals.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */


// activate the extra needed ctor
#define RTL_STRING_UNITTEST

#include <sal/types.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <rtl/string.h>
#include <rtl/string.hxx>
#include <rtl/strbuf.hxx>

bool rtl_string_unittest_const_literal;
bool rtl_string_unittest_const_literal_function;
static bool rtl_string_unittest_non_const_literal_function;

namespace test::ostring {

class StringLiterals: public CppUnit::TestFixture
{
private:
    void checkCtors();
    void checkConstexprCtor();
    void checkUsage();
    void checkNonConstUsage();
    void checkBuffer();
    void checkOstr();

    void testcall( const char str[] );

    static const char bad5[];
    static char bad6[];

    // Check that OStringLiteral ctor is actually constexpr:
    static constexpr rtlunittest::OStringLiteral dummy{"dummy"};

CPPUNIT_TEST_SUITE(StringLiterals);
CPPUNIT_TEST(checkCtors);
CPPUNIT_TEST(checkConstexprCtor);
CPPUNIT_TEST(checkUsage);
CPPUNIT_TEST(checkNonConstUsage);
CPPUNIT_TEST(checkBuffer);
CPPUNIT_TEST(checkOstr);
CPPUNIT_TEST_SUITE_END();
};

// reset the flag, call OString ctor with the given argument and return
// whether the string literal ctor was used
#define CONST_CTOR_USED( argument ) \
    ( \
    rtl_string_unittest_const_literal = false, \
    ( void ) rtl::OString( argument ), \
    result_tmp = rtl_string_unittest_const_literal, \
    rtl_string_unittest_const_literal = false, \
    ( void ) rtl::OStringBuffer( argument ), \
    rtl_string_unittest_const_literal && result_tmp )

void test::ostring::StringLiterals::checkCtors()
{
    bool result_tmp;
    CPPUNIT_ASSERT( CONST_CTOR_USED( "test" ));
    const char good1[] = "test";
    CPPUNIT_ASSERT( CONST_CTOR_USED( good1 ));

    CPPUNIT_ASSERT( !CONST_CTOR_USED( static_cast<const char*>("test") ));
    const char* bad1 = good1;
    CPPUNIT_ASSERT( !CONST_CTOR_USED( bad1 ));
    char bad2[] = "test";
    CPPUNIT_ASSERT( !CONST_CTOR_USED( bad2 ));
    char* bad3 = bad2;
    CPPUNIT_ASSERT( !CONST_CTOR_USED( bad3 ));
    const char* bad4[] = { "test1" };
    CPPUNIT_ASSERT( !CONST_CTOR_USED( bad4[ 0 ] ));
    testcall( good1 );
#ifndef _MSC_VER
    // this is actually not supposed to work (see discussion in stringutils.hxx),
    // but gcc and clang somehow manage, so keep it used, just in case some other problem
    // shows up somewhen in the future
    CPPUNIT_ASSERT( !CONST_CTOR_USED( bad5 )); // size is not known here
    CPPUNIT_ASSERT( !CONST_CTOR_USED( bad6 ));
#endif

// This one is technically broken, since the first element is 6 characters test\0\0,
// but there does not appear a way to detect this by compile time (runtime will assert()).
// RTL_CONSTASCII_USTRINGPARAM() has the same flaw.
    const char bad7[][ 6 ] = { "test""test2" };
//    CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 0 ] ));
    CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 1 ] ));

// Check that contents are correct and equal to the case when const char* ctor is used.
    CPPUNIT_ASSERT_EQUAL( rtl::OString( "" ), rtl::OString( static_cast<const char*>("") ) );
    CPPUNIT_ASSERT_EQUAL( rtl::OString( "ab" ), rtl::OString( static_cast<const char*>("ab") );

// Check that contents are correct and equal to the case when RTL_CONSTASCII_STRINGPARAM is used.
    CPPUNIT_ASSERT_EQUAL( rtl::OString( "" ), rtl::OString( RTL_CONSTASCII_STRINGPARAM( "" )) );
    CPPUNIT_ASSERT_EQUAL( rtl::OString( "ab" ), rtl::OString( RTL_CONSTASCII_STRINGPARAM( "ab" )) );
}

const char test::ostring::StringLiterals::bad5[] = "test";
char test::ostring::StringLiterals::bad6[] = "test";

void test::ostring::StringLiterals::testcall( const char str[] )
{
#ifndef _MSC_VER
    bool result_tmp;
    CPPUNIT_ASSERT( !CONST_CTOR_USED( str ));
#else
    // MSVC just errors out on this for some reason, which is fine as well
    (void)str;
#endif
}

void test::ostring::StringLiterals::checkConstexprCtor()
{
    static constinit rtl::OString s(dummy);
    CPPUNIT_ASSERT_EQUAL(oslInterlockedCount(0x40000000), s.pData->refCount);
        // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), s.getLength());
    CPPUNIT_ASSERT_EQUAL(rtl::OString("dummy"), s);
    CPPUNIT_ASSERT_EQUAL(
        static_cast<void const *>(dummy.getStr()), static_cast<void const *>(s.getStr()));
}

void test::ostring::StringLiterals::checkUsage()
{
// simply check that all string literal based calls work as expected
// also check that they really use string literal overload and do not convert to OString
    rtl::OString foo( "foo" );
    rtl::OString FoO( "FoO" );
    rtl::OString foobarfoo( "foobarfoo" );
    rtl::OString foobar( "foobar" );
    rtl::OString FooBaRfoo( "FooBaRfoo" );
    rtl::OString FooBaR( "FooBaR" );
    rtl::OString bar( "bar" );

    rtl_string_unittest_const_literal = false// start checking for OString conversions
    rtl_string_unittest_non_const_literal_function = false// and check for non-const variants
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = "foo" );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( "fOo" ));
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( foobarfoo.match( "bar", 3 ));
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( foobar.match( "foo" ));
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( "bAr", 3 ));
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( "fOo" ));
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( foobar.startsWith( "foo" ));
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( foobar.endsWith( "bar" ));
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
//    rtl_string_unittest_const_literal_function = false;
//    CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( "bar" ));
//    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( bool(foo == "foo") );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( bool("foo" == foo) );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( foo != "bar" );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT( "foo" != bar );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    rtl_string_unittest_const_literal_function = false;
    CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.indexOf( "foo", 1 ) );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
//    rtl_string_unittest_const_literal_function = false;
//    CPPUNIT_ASSERT( foobarfoo.lastIndexOf( "foo" ) == 6 );
//    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
    // if this is not true, some of the calls above converted to OString
    CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
    // if this is not true, some of the calls above used non-const variants
    CPPUNIT_ASSERT( !rtl_string_unittest_non_const_literal_function );
}

void test::ostring::StringLiterals::checkNonConstUsage()
{
// check that (non-const) char[] overloads work and do not use const char[] overloads
    rtl::OString foo( "foo" );
    rtl::OString FoO( "FoO" );
    rtl::OString foobarfoo( "foobarfoo" );
    rtl::OString foobar( "foobar" );
    rtl::OString FooBaRfoo( "FooBaRfoo" );
    rtl::OString FooBaR( "FooBaR" );
    rtl::OString bar( "bar" );
    char foo_c[] = "foo";
    char bar_c[] = "bar";
    char fOo_c[] = "fOo";
    char bAr_c[] = "bAr";

    rtl_string_unittest_const_literal = false// start checking for OString conversions
    rtl_string_unittest_const_literal_function = false// and check for const variants
    CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = static_cast<const char*>(foo_c) );
    CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = foo_c );
    CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( static_cast<const char*>(fOo_c) ));
    CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( fOo_c ));
    CPPUNIT_ASSERT( foobarfoo.match( static_cast<const char*>(bar_c), 3 ));
    CPPUNIT_ASSERT( foobarfoo.match( bar_c, 3 ));
    CPPUNIT_ASSERT( foobar.match( static_cast<const char*>(foo_c) ));
    CPPUNIT_ASSERT( foobar.match( foo_c ));
    CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( static_cast<const char*>(bAr_c), 3 ));
    CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( bAr_c, 3 ));
    CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( static_cast<const char*>(fOo_c) ));
    CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( fOo_c ));
    CPPUNIT_ASSERT( foobar.startsWith( static_cast<const char*>(foo_c) ));
    CPPUNIT_ASSERT( foobar.startsWith( foo_c ));
    CPPUNIT_ASSERT( foobar.endsWith( static_cast<const char*>(bar_c) ));
    CPPUNIT_ASSERT( foobar.endsWith( bar_c ));
//    CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( (const char*)bar_c ));
//    CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( bar_c ));
    CPPUNIT_ASSERT( bool(foo == static_cast<const char*>(foo_c)) );
    CPPUNIT_ASSERT( bool(foo == foo_c) );
    CPPUNIT_ASSERT( bool(static_cast<const char*>(foo_c) == foo) );
    CPPUNIT_ASSERT( bool(foo_c == foo) );
    CPPUNIT_ASSERT( foo != static_cast<const char*>(bar_c) );
    CPPUNIT_ASSERT( foo != bar_c );
    CPPUNIT_ASSERT( static_cast<const char*>(foo_c) != bar );
    CPPUNIT_ASSERT( foo_c != bar );
    CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.indexOf( static_cast<const char*>(foo_c), 1 ) );
    CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.indexOf( foo_c, 1 ) );
//    CPPUNIT_ASSERT( foobarfoo.lastIndexOf( (const char*)foo_c ) == 6 );
//    CPPUNIT_ASSERT( foobarfoo.lastIndexOf( foo_c ) == 6 );
    // if this is not true, some of the calls above used const variants
    CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
    CPPUNIT_ASSERT( !rtl_string_unittest_const_literal_function );
}

void test::ostring::StringLiterals::checkBuffer()
{
    rtl::OStringBuffer buf;
    rtl_string_unittest_const_literal_function = false;
    buf.append( "foo" );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    CPPUNIT_ASSERT_EQUAL( rtl::OString( "foo" ), buf.toString());
    rtl_string_unittest_const_literal_function = false;
    buf.append( "bar" );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    CPPUNIT_ASSERT_EQUAL( rtl::OString( "foobar" ), buf.toString());
    rtl_string_unittest_const_literal_function = false;
    buf.insert( 3, "baz" );
    CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
    CPPUNIT_ASSERT_EQUAL( rtl::OString( "foobazbar" ), buf.toString());

    rtl::OString foobazbard( "foobazbard" );
    rtl::OString foodbazbard( "foodbazbard" );
    rtl_string_unittest_const_literal = false// start checking for OString conversions
    rtl_string_unittest_const_literal_function = false// and check for const variants
    char d[] = "d";
    CPPUNIT_ASSERT_EQUAL( foobazbard, buf.append( d ).toString());
    CPPUNIT_ASSERT_EQUAL( foodbazbard, buf.insert( 3, d ).toString() );
    CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
    CPPUNIT_ASSERT( !rtl_string_unittest_const_literal_function );
}

void test::ostring::StringLiterals::checkOstr() {
    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), ""_ostr.getLength());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), "foobar"_ostr.getLength());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(7), "foo\0bar"_ostr.getLength());
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), u8"\U00010000"_ostr.getLength());
    CPPUNIT_ASSERT_EQUAL(""_ostr, rtl::OString(""_tstr));
    CPPUNIT_ASSERT_EQUAL("foobar"_ostr, rtl::OString("foobar"_tstr));
    CPPUNIT_ASSERT_EQUAL("foo\0bar"_ostr, rtl::OString("foo\0bar"_tstr));
}

#undef CONST_CTOR_USED

// namespace

CPPUNIT_TEST_SUITE_REGISTRATION(test::ostring::StringLiterals);

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=86 H=100 G=93

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.