cRune
Overview
Module with functions and types to work with cRune values.
Types and Definitions
cRune
struct cRune
{
union
{
uint32_t ctrl;
cByte b[4];
char c[4];
};
};
typedef struct cRune cRune;
A cRune is a type that can hold a single Unicode code point. The Unicode code point is encoded in UTF-8 inside a cRune.
c_check_rune
typedef bool ( *c_check_rune )( cRune r )
c_check_rune is the signature of a function to check a rune value.
Functions
utf8
is_utf8_head_c
bool is_utf8_head_c( char c );
Returns true if c is a valid first byte of a UTF-8 encoded code point, otherwise false.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
char const* cs1 = "®"; // size 2
expect_c_( is_utf8_head_c( cs1[0] ) );
expect_c_( !is_utf8_head_c( cs1[1] ) );
char const* cs2 = "€"; // size 3
expect_c_( is_utf8_head_c( cs2[0] ) );
expect_c_( !is_utf8_head_c( cs2[1] ) );
expect_c_( !is_utf8_head_c( cs2[2] ) );
char const* cs3 = "𝄞"; // size 4
expect_c_( is_utf8_head_c( cs3[0] ) );
expect_c_( !is_utf8_head_c( cs3[1] ) );
expect_c_( !is_utf8_head_c( cs3[2] ) );
expect_c_( !is_utf8_head_c( cs3[3] ) );
return finish_tap_c_();
}
is_utf8_tail_c
bool is_utf8_tail_c( char c );
Returns true if c is a valid byte in the tail of a UTF-8 encoded code point, otherwise false.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
char const* cs1 = "®"; // size 2
expect_c_( !is_utf8_tail_c( cs1[0] ) );
expect_c_( is_utf8_tail_c( cs1[1] ) );
char const* cs2 = "€"; // size 3
expect_c_( !is_utf8_tail_c( cs2[0] ) );
expect_c_( is_utf8_tail_c( cs2[1] ) );
expect_c_( is_utf8_tail_c( cs2[2] ) );
char const* cs3 = "𝄞"; // size 4
expect_c_( !is_utf8_tail_c( cs3[0] ) );
expect_c_( is_utf8_tail_c( cs3[1] ) );
expect_c_( is_utf8_tail_c( cs3[2] ) );
expect_c_( is_utf8_tail_c( cs3[3] ) );
return finish_tap_c_();
}
utf8_length_c
int8_t utf8_length_c( char c );
Returns number of bytes of the UTF-8 encoded code point. An invalid c value leads to the result 0.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
char const* cs1 = "y";
expect_c_( utf8_length_c( cs1[0] ) == 1 );
char const* cs2 = "®";
expect_c_( utf8_length_c( cs2[0] ) == 2 );
char const* cs3 = "€";
expect_c_( utf8_length_c( cs3[0] ) == 3 );
char const* cs4 = "𝄞";
expect_c_( utf8_length_c( cs4[0] ) == 4 );
expect_c_( utf8_length_c( char_c_( 0xff ) ) == 0 );
return finish_tap_c_();
}
utf16
is_high_utf16_surrogate_c
bool is_high_utf16_surrogate_c( uint16_t val );
Returns true if the value represents a UTF-16 high surrogate value.
is_low_utf16_surrogate_c
bool is_low_utf16_surrogate_c( uint16_t val );
Returns true if the value represents a UTF-16 low surrogate value.
utf16_to_utf32_c
uint32_t utf16_to_utf32_c( uint16_t high, uint16_t low );
Converts a UTF-16 surrogate pair to an UTF-32 value.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
uint16_t h;
uint16_t l;
uint32_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( 0xd834, 0xdd1e, 0x1d11e ),
t_( 0xd83d, 0xde03, 0x1f603 ),
t_( 0x2605, 0x0, 0x2605 )
);
for_each_c_( test const*, t, tests )
{
uint32_t val = utf16_to_utf32_c( t->h, t->l );
expect_c_( val == t->exp );
}
return finish_tap_c_();
}
utf32_to_utf16_c
uint16_t utf32_to_utf16_c( uint32_t val, uint16_t low[static 1] );
Converts a UTF-32 in to a UTF-16 surrogate pair. The function returns the high surrogate and writes the low surrogate into low.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
uint32_t inp;
uint16_t val;
uint16_t low;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( 0x1d11e, 0xd834, 0xdd1e ),
t_( 0x1f603, 0xd83d, 0xde03 ),
t_( 0x2605, 0x2605, 0x0 )
);
for_each_c_( test const*, t, tests )
{
uint16_t low = 0;
uint16_t high = utf32_to_utf16_c( t->inp, &low );
expect_c_( t->val == high );
expect_c_( t->low == low );
}
return finish_tap_c_();
}
init
build_rune_c_
#define build_rune_c_( A, B, C, D )
Creates a cRune with the byte values A, B, C and D.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cRune dollar = build_rune_c_( 0x24, 0, 0, 0 );
expect_c_( rune_is_c( dollar, "$" ) );
expect_c_( not rune_is_c( dollar, "€" ) );
cRune euro = build_rune_c_( 0xe2, 0x82, 0xac, 0 );
expect_c_( rune_is_c( euro, "€" ) );
expect_c_( not rune_is_c( euro, "$" ) );
return finish_tap_c_();
}
make_rune_c
cRune make_rune_c( cChars chars );
Creates a cRune from the UTF-8 encoded code point at the front.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cChars euroChars = c_c( "€" );
cRune euro = make_rune_c( euroChars );
expect_c_( rune_is_c( euro, "€" ) );
cRune invalidEuro = make_rune_c( left_c_( cChars, euroChars ,2 ) );
expect_c_( not rune_is_valid_c( invalidEuro ) );
return finish_tap_c_();
}
null_rune_c
cRune null_rune_c();
Creates a invalid cRune.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cRune r = null_rune_c();
expect_c_( not rune_is_valid_c( r ) );
return finish_tap_c_();
}
rune_c
cRune rune_c( char const cstr[static 1] );
Creates a cRune from the UTF-8 encoded code point at the front.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cRune x = rune_c( "x" );
expect_c_( rune_is_c( x, "x" ) );
cRune y = rune_c( "yz" );
expect_c_( rune_is_c( y, "y" ) );
cRune snowman = rune_c( "☃ needs an ☂" );
expect_c_( rune_is_c( snowman, "☃" ) );
return finish_tap_c_();
}
utf16_rune_c
cRune utf16_rune_c( uint16_t val );
Creates a cRune from a UTF-16 encoded code point.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
#define expect_( Rune, Exp ) \
expect_c_( \
rune_is_c( (Rune), (Exp) ) \
)
int main( void )
{
init_tap_c_();
expect_( utf16_rune_c( 0x56 ), "V" );
expect_( utf16_rune_c( 0xe9 ), "é" );
expect_( utf16_rune_c( 0x2602 ), "☂" );
return finish_tap_c_();
}
utf32_rune_c
cRune utf32_rune_c( uint32_t val );
Creates a rune from a UTF-32 encoded code point.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
#define expect_( Rune, Exp ) \
expect_c_( \
rune_is_c( (Rune), (Exp) ) \
)
int main( void )
{
init_tap_c_();
expect_( utf32_rune_c( 0x56 ), "V" ); // 56
expect_( utf32_rune_c( 0xe9 ), "é" ); // c3 a9
expect_( utf32_rune_c( 0x0f3c ), "༼" ); // e0 bc bc
expect_( utf32_rune_c( 0x0103ab ), "𐎫" ); // f0 90 8e ab
return finish_tap_c_();
}
overall
cmp_rune_c
int cmp_rune_c( cRune a, cRune b );
Compares the cRune values and returns the three possible results:
- <0
-
means that a is less compared to b
- 0
-
means that a and b are equal
- >0
-
means that a is greater compared to b
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
// ascii
cRune x = rune_c( "x" );
cRune y = rune_c( "y" );
cRune z = rune_c( "z" );
expect_eq_c_( cmp_rune_c( x, x ) );
expect_eq_c_( cmp_rune_c( y, y ) );
expect_eq_c_( cmp_rune_c( z, z ) );
expect_lt_c_( cmp_rune_c( x, y ) );
expect_lt_c_( cmp_rune_c( x, z ) );
expect_lt_c_( cmp_rune_c( y, z ) );
expect_gt_c_( cmp_rune_c( y, x ) );
expect_gt_c_( cmp_rune_c( z, x ) );
expect_gt_c_( cmp_rune_c( z, y ) );
// unicode
cRune umbrella = rune_c( "☂" ); // U+2602
expect_eq_c_( cmp_rune_c( umbrella, utf16_rune_c( 0x2602 ) ) );
cRune snowman = rune_c( "☃" ); // U+2603
expect_eq_c_( cmp_rune_c( snowman, utf16_rune_c( 0x2603 ) ) );
expect_lt_c_( cmp_rune_c( umbrella, snowman ) );
expect_gt_c_( cmp_rune_c( snowman, umbrella ) );
return finish_tap_c_();
}
eq_rune_c
bool eq_rune_c( cRune a, cRune b );
Checks if a and b are equal.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cRune x = rune_c( "x" );
cRune snowman = rune_c( "☃" ); // U+2603
expect_c_( eq_rune_c( x, x ) );
expect_c_( eq_rune_c( snowman, snowman ) );
expect_c_( !eq_rune_c( x, snowman ) );
return finish_tap_c_();
}
rune_code_c
uint32_t rune_code_c( cRune r );
Converts a rune into a UTF-32 encoded code point.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
char const* input;
uint32_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( "A", 0x41 ),
t_( "ö", 0xf6 ),
t_( "Ж", 0x0416 ),
t_( "€", 0x20ac ),
t_( "𝄞", 0x1d11e ),
t_( "α", 0x03b1 ),
t_( "😎", 0x01f60e )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cRune r = rune_c( t.input );
uint32_t res = rune_code_c( r );
tap_descf_c( res == t.exp, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
rune_is_c
bool rune_is_c( cRune r, char const cstr[static 1] );
Checks if r and the first UTF-8 encoded code point in the C string are equal.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cRune umbrella = rune_c( "☂" );
expect_c_( rune_is_c( umbrella, "☂" ) );
expect_c_( !rune_is_c( umbrella, "y" ) );
return finish_tap_c_();
}
rune_is_valid_c
bool rune_is_valid_c( cRune r );
Checks if r contains a valid byte sequence.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cRune valid = rune_c( "a" );
expect_c_( rune_is_valid_c( valid ) );
cRune invalid = { .ctrl=0xffffffff };
expect_c_( not rune_is_valid_c( invalid ) );
// € = e2 82 ac
cRune euro = build_rune_c_( 0xe2, 0x82, 0, 0 );
expect_c_( not rune_is_valid_c( euro ) );
return finish_tap_c_();
}
rune_size_c
int8_t rune_size_c( cRune r );
Returns how much bytes are used to store the UTF-8 encoded code point.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
char const* input;
int8_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( "☂", 3 ),
t_( "y", 1 ),
t_( "®", 2 ),
t_( "€", 3 ),
t_( "𝄞", 4 ),
t_( "yes", 1 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cRune r = rune_c( t.input );
int8_t res = rune_size_c( r );
tap_descf_c( res == t.exp, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
access
ceil_to_rune_c
char const* ceil_to_rune_c( cChars chars, int64_t index );
Returns a pointer to the first char of a UTF-8 encoded code point at the byte index. If the char at index is a UTF-8 tail goes the function forward to the next UTF-8 head.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
// rune/size -> ®/2 =/1 ☂/3
cChars chars = c_c( "®=☂" );
expect_c_( ceil_to_rune_c( chars, 1 ) == ptr_for_c_( chars, 2 ) );
expect_c_( ceil_to_rune_c( chars, 2 ) == ptr_for_c_( chars, 2 ) );
expect_c_( ceil_to_rune_c( chars, 3 ) == ptr_for_c_( chars, 3 ) );
expect_c_( ceil_to_rune_c( chars, 4 ) == ptr_for_c_( chars, -1 ) );
return finish_tap_c_();
}
first_rune_c
char const* first_rune_c( cChars chars );
Returns a pointer to the first rune in chars.
floor_to_rune_c
char const* floor_to_rune_c( cChars chars, int64_t index );
Returns a pointer to the first char of a UTF-8 encoded code point at the byte index. If the char at index is a UTF-8 tail goes the function back to the beginning of the UTF8- encoded code point.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
// rune/size -> ®/2 =/1 ☂/3
cChars chars = c_c( "®=☂" );
expect_c_( floor_to_rune_c( chars, 1 ) == ptr_for_c_( chars, 0 ) );
expect_c_( floor_to_rune_c( chars, 2 ) == ptr_for_c_( chars, 2 ) );
expect_c_( floor_to_rune_c( chars, 3 ) == ptr_for_c_( chars, 3 ) );
expect_c_( floor_to_rune_c( chars, 4 ) == ptr_for_c_( chars, 3 ) );
return finish_tap_c_();
}
last_rune_c
char const* last_rune_c( cChars chars );
Returns a pointer to the last rune in chars.
nth_rune_c
char const* nth_rune_c( cChars chars, int64_t n );
Returns a pointer to the nth UTF-8 encoded code point in the chars. The n value can be nagtive to access the chars backwards. If n is out of range returns the function NULL.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
#define expect_( Rune, Exp ) \
expect_c_( \
rune_is_c( rune_c( Rune ), (Exp) ) \
)
int main( void )
{
init_tap_c_();
cChars chars = c_c( "abcd€f®!" );
expect_( nth_rune_c( chars, 0 ), "a" );
expect_( nth_rune_c( chars, 4 ), "€" );
expect_( nth_rune_c( chars, 5 ), "f" );
expect_( nth_rune_c( chars, 6 ), "®" );
expect_( nth_rune_c( chars, 7 ), "!" );
expect_c_( nth_rune_c( chars, 8 ) == NULL );
expect_( nth_rune_c( chars, -1 ), "!" );
expect_( nth_rune_c( chars, -2 ), "®" );
expect_( nth_rune_c( chars, -3 ), "f" );
expect_( nth_rune_c( chars, -4 ), "€" );
expect_( nth_rune_c( chars, -8 ), "a" );
expect_c_( nth_rune_c( chars, -9 ) == NULL );
return finish_tap_c_();
}
iterate
iterate_runes_c_
#define iterate_runes_c_( Itr, Rune, Chars )
Macro function to define a for statement to iterate over all runes in chars.
#include "clingo/io/cRecorder.h"
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cRecorder* ascii = &recorder_c_( 128 );
cRecorder* unicode = &recorder_c_( 128 );
cChars chars = c_c( "® yes this is a 𝄞 and €!" );
cRune r;
iterate_runes_c_( itr, r, chars )
{
cRecorder* rec = rune_size_c( r) == 1 ? ascii : unicode;
record_rune_c( rec, r );
}
expect_c_( recorded_is_c( ascii, " yes this is a and !" ));
println_recorded_c( ascii );
expect_c_( recorded_is_c( unicode, "®𝄞€" ));
return finish_tap_c_();
}
next_rune_c
char const* next_rune_c( cChars chars, char const* itr, cRune r[static 1] )
Navigates a to the next UTF-8 encoded code point in a C string. The returned iterator is invalid if no next value exist.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cChars chars = c_c( "® yes this is a 𝄞 and €!" );
cRune r;
char const* itr;
itr = next_rune_c( chars, NULL, &r );
expect_c_( rune_is_c( r, "®" ) );
itr = next_rune_c( chars, itr, &r );
expect_c_( rune_is_c( r, " " ) );
expect_eq_c_( strcmp( " yes this is a 𝄞 and €!", itr ) );
itr = next_rune_c( chars, itr, &r );
expect_c_( rune_is_c( r, "y" ) );
expect_eq_c_( strcmp( "yes this is a 𝄞 and €!", itr ) );
return finish_tap_c_();
}
char slice
count_runes_c
int64_t count_runes_c( cChars chars );
Counts the number of runes of the chars. Returns -1 for chars with incomplete runes.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
// ®=2 / 𝄞=4 / €=3
cChars chars1 = c_c( "® yes this is a 𝄞 and €!" );
expect_c_( chars1.s == 30 );
expect_c_( count_runes_c( chars1 ) == 24 );
cChars chars2 = c_c( "abcdefgh" );
expect_c_( chars2.s == 8 );
expect_c_( count_runes_c( chars2 ) == 8 );
cChars empty = (cChars)empty_c_();
expect_c_( count_runes_c( empty ) == 0 );
cChars euroSign = (cChars){ 7, "euro:€" }; // wrong size
expect_c_( count_runes_c( euroSign ) == -1 );
euroSign.s = 8;
expect_c_( count_runes_c( euroSign ) == 6 );
return finish_tap_c_();
}
fill_rune_slice_c
cVarRuneSlice fill_rune_slice_c( cVarRuneSlice dst, cChars src );
Fills dst with the complete runes in src.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
cChars src = c_c( "My € makes 𝄞®!" );
{
cVarRuneSlice dst = structs_c_( 20, cRune );
cVarRuneSlice res = fill_rune_slice_c( dst, src );
expect_c_( res.s == 14 );
expect_c_( rune_is_c( res.v[ 0 ], "M" ) );
expect_c_( rune_is_c( res.v[ 1 ], "y" ) );
expect_c_( rune_is_c( res.v[ 2 ], " " ) );
expect_c_( rune_is_c( res.v[ 3 ], "€" ) );
expect_c_( rune_is_c( res.v[ 4 ], " " ) );
expect_c_( rune_is_c( res.v[ 5 ], "m" ) );
expect_c_( rune_is_c( res.v[ 6 ], "a" ) );
expect_c_( rune_is_c( res.v[ 7 ], "k" ) );
expect_c_( rune_is_c( res.v[ 8 ], "e" ) );
expect_c_( rune_is_c( res.v[ 9 ], "s" ) );
expect_c_( rune_is_c( res.v[ 10 ], " " ) );
expect_c_( rune_is_c( res.v[ 11 ], "𝄞" ) );
expect_c_( rune_is_c( res.v[ 12 ], "®" ) );
expect_c_( rune_is_c( res.v[ 13 ], "!" ) );
}
{
cVarRuneSlice dst = structs_c_( 10, cRune );
cVarRuneSlice res = fill_rune_slice_c( dst, src );
expect_c_( res.s == 10 );
expect_c_( rune_is_c( res.v[ 0 ], "M" ) );
expect_c_( rune_is_c( res.v[ 1 ], "y" ) );
expect_c_( rune_is_c( res.v[ 2 ], " " ) );
expect_c_( rune_is_c( res.v[ 3 ], "€" ) );
expect_c_( rune_is_c( res.v[ 4 ], " " ) );
expect_c_( rune_is_c( res.v[ 5 ], "m" ) );
expect_c_( rune_is_c( res.v[ 6 ], "a" ) );
expect_c_( rune_is_c( res.v[ 7 ], "k" ) );
expect_c_( rune_is_c( res.v[ 8 ], "e" ) );
expect_c_( rune_is_c( res.v[ 9 ], "s" ) );
}
return finish_tap_c_();
}
find_any_rune_c
#define find_any_rune_c_( Chars, Cstr ) \
find_any_rune_c( (Chars), c_c( Cstr ) )
char const* find_any_rune_c( cChars chars, cChars set );
Returns a pointer to the first char that matches any of the runes in the set and NULL if non of the runes exist in the chars.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
#define expect_rune_( Res, Exp ) \
expect_c_( eq_rune_c( rune_c( Res ), rune_c( Exp ) ) );
int main( void )
{
init_tap_c_();
cChars base = c_c( "with 𐤠 and 𐤹, from the Lydian set" );
cChars chars = base;
cChars set = c_c( "𐤹,𐤠L" );
char const* ptr = NULL;
int64_t idx = -1;
ptr = find_any_rune_c( chars, set ); // --------------------------------- '𐤠'
idx = index_of_c_( base, ptr );
expect_rune_( ptr, "𐤠" );
expect_c_( idx == 5 );
chars = mid_runes_c( base, 6 );
ptr = find_any_rune_c( chars, set ); // --------------------------------- '𐤹'
idx = index_of_c_( base, ptr );
expect_rune_( ptr, "𐤹" );
expect_c_( idx == 14 );
chars = mid_runes_c( base, 12 );
ptr = find_any_rune_c( chars, set ); // --------------------------------- ','
idx = index_of_c_( base, ptr );
expect_rune_( ptr, "," );
expect_c_( idx == 18 );
chars = mid_runes_c( base, 13 );
ptr = find_any_rune_c( chars, set ); // --------------------------------- 'L'
idx = index_of_c_( base, ptr );
expect_rune_( ptr, "L" );
expect_c_( idx == 29 );
chars = mid_runes_c( base, 24 );
return finish_tap_c_();
}
find_rune_c
#define find_rune_c_( Chars, Cstr ) \
find_rune_c( (Chars), rune_c( Cstr ) )
char const* find_rune_c( cChars chars, cRune r );
Returns a pointer to the first char of a UTF-8 encoded code point in a chars that equals r.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
int main( void )
{
init_tap_c_();
// ®=2 / 𝄞=4 / €=3
cChars chars = c_c( "® yes 𝄞 and €!" );
char const* res = find_rune_c( chars, rune_c( "𝄞" ) );
expect_c_( index_of_c_( chars, res ) == 7 );
expect_c_( rune_is_c( rune_c( res ), "𝄞" ) );
res = find_rune_c_( chars, "€" );
expect_c_( index_of_c_( chars, res ) == 16 );
expect_c_( rune_is_c( rune_c( res ), "€" ) );
res = find_rune_c_( chars, "x" );
expect_c_( index_of_c_( chars, res ) == -1 );
expect_c_( res == NULL );
chars.s = 17; // ends in the middle of '€'
res = find_rune_c_( chars, "€" );
expect_c_( index_of_c_( chars, res ) == -1 );
expect_c_( res == NULL );
return finish_tap_c_();
}
left_runes_c
cChars left_runes_c( cChars chars, int64_t maxLen );
Returns the leftmost runes in a chars. If maxLen is greater or equal the number of runes in the chars returns the function the whole chars.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
char const* input;
int64_t maxLen;
char const* exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( "ананас", 6, "ананас" ),
t_( "ананас", 4, "анан" ),
t_( "ананас", 0, "" )
);
for_each_c_( test const*, t, tests )
{
cChars chars = c_c( t->input );
cChars left = left_runes_c( chars, t->maxLen );
bool res = chars_is_c( left, t->exp );
tap_descf_c( res, "test '%s' -> '%s'", t->input, t->exp );
}
return finish_tap_c_();
}
mid_runes_c
cChars mid_runes_c( cChars chars, int64_t index );
Returns chars starting(including) at a given rune index. If index does not point into the chars returns the function an empty slice.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
char const* input;
int64_t index;
char const* exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( "ананас", 0, "ананас" ),
t_( "ананас", 4, "ас" ),
t_( "ананас", 6, "" )
);
for_each_c_( test const*, t, tests )
{
cChars chars = c_c( t->input );
cChars mid = mid_runes_c( chars, t->index );
bool res = chars_is_c( mid, t->exp );
tap_descf_c( res, "test '%s' -> '%s'", t->input, t->exp );
}
return finish_tap_c_();
}
right_runes_c
cChars right_runes_c( cChars chars, int64_t maxLen );
Returns the rightmost runes in chars. If maxLen is greater or equal the number of runes in the chars returns the function the whole chars.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
char const* input;
int64_t maxLen;
char const* exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( "ананас", 6, "ананас" ),
t_( "ананас", 4, "анас" ),
t_( "ананас", 0, "" )
);
for_each_c_( test const*, t, tests )
{
cChars chars = c_c( t->input );
cChars right = right_runes_c( chars, t->maxLen );
bool res = chars_is_c( right, t->exp );
tap_descf_c( res, "test '%s' -> '%s'", t->input, t->exp );
}
return finish_tap_c_();
}
sub_runes_c
cChars sub_runes_c( cChars chars, int64_t begIdx, int64_t endIdx );
The returned chars includes the rune at begIdx(begin index) as first value and the rune at endIdx-1 as last value. If begIdx or endIdx are not valid rune indices returns the function a empty slice.
#include "clingo/lang/expect.h"
#include "clingo/type/cRune.h"
TEMP_SLICE_C_(
test,
{
char const* input;
int64_t begIdx;
int64_t endIdx;
char const* exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( "ананас", 0, 3, "ана" ),
t_( "ананас", 2, 6, "анас" ),
t_( "ананас", 3, 4, "н" ),
t_( "ананас", 6, 2, "" ),
t_( "ананас", 0, 7, "" )
);
for_each_c_( test const*, t, tests )
{
cChars chars = c_c( t->input );
cChars sub = sub_runes_c( chars, t->begIdx, t->endIdx );
bool res = chars_is_c( sub, t->exp );
tap_descf_c( res, "test '%s' -> '%s'", t->input, t->exp );
}
return finish_tap_c_();
}