read_type
Overview
Module with functions to read types from a text with a scanner.
Important
|
Check the err value of the scanner if a function returns false. |
Functions
basic
read_bool_c
#define read_bool_c_( Sca, Bool ) \
read_bool_c( (Sca), (Bool), "" )
bool read_bool_c( cScanner sca[static 1],
bool val[static 1],
char const fmt[static 1] );
Reads a bool value from a text with a scanner. The function supports the following formats:
l |
lower-case representation |
true or false |
U |
upper-case representation |
TRUE or FALSE |
Cc |
camel-case representation |
True or False |
* |
all cases |
The function will use \'*' as default format.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
bool expReturn;
bool expVal;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// default
t_( "true", "", true, true ),
t_( "False", "", true, false ),
t_( "FALSE", "", true, false ),
t_( "Yes", "", false, false ),
// *
t_( "true", "", true, true ),
t_( "False", "", true, false ),
t_( "FALSE", "", true, false ),
t_( "NO", "", false, false ),
// l
t_( "true", "l", true, true ),
t_( "false", "l", true, false ),
t_( "True", "l", false, false ),
// U
t_( "TRUE", "U", true, true ),
t_( "FALSE", "U", true, false ),
t_( "false", "U", false, false ),
// Cc
t_( "True", "Cc", true, true ),
t_( "False", "Cc", true, false ),
t_( "TRUE", "Cc", false, false )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
bool val = false;
bool res = read_bool_c( sca, &val, t.fmt ) == t.expReturn;
res &= val == t.expVal;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
read_byte_c
#define read_byte_c_( Sca, Byte ) \
read_byte_c( (Sca), (Byte), "" )
bool read_byte_c( cScanner sca[static 1],
cByte byte[static 1],
char const fmt[static 1] );
Reads a byte value from a text with a scanner.
read_char_c
#define read_char_c_( Sca, Char ) \
read_char_c( (Sca), (Char), "" )
bool read_char_c( cScanner sca[static 1],
char c[static 1],
char const fmt[static 1] );
Reads a char value from a text with a scanner.
read_range_c
#define read_range_c_( Sca, Rng ) \
read_range_c( (Sca), (Rng), "" )
bool read_range_c( cScanner sca[static 1],
cRange rng[static 1],
char const fmt[static 1] );
Reads a range from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
cRange exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
t_( "[-213,-78]", closed_range_c_( -213, -78 ) ),
t_( "[0..1984)", closed_open_range_c_( 0, 1984 ) ),
t_( "(-56;56]", open_closed_range_c_( -56, 56 ) ),
t_( "(64..256)", open_range_c_( 64, 256 ) )
);
for_each_c_( test const*, t, tests )
{
cScanner* sca = &cstr_scanner_c_( t->str );
cRange dst;
bool res = read_range_c( sca, &dst, "" );
res &= eq_range_c( dst, t->exp );
tap_descf_c( res, "test %s", t->str );
}
return finish_tap_c_();
}
read_rune_c
#define read_rune_c_( Sca, Rune ) \
read_rune_c( (Sca), (Rune), "" )
bool read_rune_c( cScanner sca[static 1],
cRune rune[static 1],
char const fmt[static 1] );
Reads a rune value from a text with a scanner. The function supports the following formats:
s |
just the rune |
♘ |
n |
unicode number |
U+2658 |
u8 |
the UTF-8 hex values |
e29998 |
html |
decimal HTML-code |
|
htmlx |
hex HTML-code |
|
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
#include "clingo/io/print.h"
#define pln_( ... ) pjotln_c_( xyz, 1024, __VA_ARGS__ )
TEMP_SLICE_C_(
test,
{
char const* inp;
char const* fmt;
char const* exp;
char const* unscanned;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// "" / "s"
t_( "abc", "", "a", "bc" ),
t_( "🪓♘", "", "🪓", "♘" ),
// "n"
t_( "U+005A,", "n", "Z", "," ),
t_( "U+2658,", "n", "♘", "," ),
t_( "U+1FA93,", "n", "🪓", "," ),
// "u8"
t_( "5aaf", "u8", "Z", "af" ),
t_( "e2999800", "u8", "♘", "00" ),
t_( "f09faa9312", "u8", "🪓", "12" ),
// "html"
t_( "Zfoo", "html", "Z", "foo" ),
t_( "♘bar", "html", "♘", "bar" ),
t_( "🪓tar", "html", "🪓" , "tar" ),
// "htmlx"
t_( "Zbla", "htmlx", "Z", "bla" ),
t_( "♘blo", "htmlx", "♘", "blo" ),
t_( "🪓blub", "htmlx", "🪓", "blub" )
);
for_each_c_( test const*, t, tests )
{
cScanner* sca = &cstr_scanner_c_( t->inp );
cRune r = null_rune_c();
bool res = read_rune_c( sca, &r, t->fmt );
res &= rune_is_c( r, t->exp );
res &= unscanned_is_c( sca, t->unscanned );
tap_descf_c( res, "test '%s' + '%s' -> '%s'", t->inp, t->fmt, t->exp );
}
return finish_tap_c_();
}
float
read_double_c
#define read_double_c_( Sca, Double ) \
read_double_c( (Sca), (Double), "" )
bool read_double_c( cScanner sca[static 1],
double d[static 1],
char const fmt[static 1] );
Reads a double value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
#include "clingo/lang/locale.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
double exp;
double diff;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
set_locale_c( LC_ALL, "C" );
testSlice tests = slice_c_( test,
t_( "129038.213", "", 129038.213, 0.00001 )
);
for_each_c_( test const*, t, tests )
{
cScanner* sca = &cstr_scanner_c_( t->str );
double d = 0.0;
bool res = true;
res &= read_double_c( sca, &d, t->fmt );
res &= eq_double_c( d, t->exp, t->diff );
tap_descf_c( res, "%s + \"%s\" -> %f", t->str, t->fmt, d );
}
return finish_tap_c_();
}
read_float_c
#define read_float_c_( Sca, Float ) \
read_float_c( (Sca), (Float), "" )
bool read_float_c( cScanner sca[static 1],
float f[static 1],
char const format[static 1] );
Reads a float value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
#include "clingo/lang/locale.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
float exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
set_locale_c( LC_ALL, "C" );
testSlice tests = slice_c_( test,
t_( "9038.213", "", 9038.213f )
);
for_each_c_( test const*, t, tests )
{
cScanner* sca = &cstr_scanner_c_( t->str );
float f = 0.0f;
bool res = true;
res &= read_float_c( sca, &f, t->fmt );
res &= eq_float_c_( f, t->exp );
tap_descf_c( res, "%s + \"%s\" -> %f", t->str, t->fmt, f );
}
return finish_tap_c_();
}
signed
The format for all signed integers is:
d |
decimal value |
x |
lower- and upper-case hexadecimal value |
X |
lower- and upper-case hexadecimal value |
o |
octal-value |
read_int16_c
#define read_int16_c_( Sca, Int16 ) \
read_int16_c( (Sca), (Int16), "" )
bool read_int16_c( cScanner sca[static 1],
int16_t i16[static 1],
char const fmt[static 1] );
// > C_ReadError
Reads a int16_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
int16_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "18", "", 18 ),
t_( "30df", "x", 12511 ),
t_( "-4E3", "X", -1251 ),
t_( "7561", "o", 3953 ),
// boundaries
t_( "-32768", "", -32768 ),
t_( "32767", "", 32767 ),
t_( "32768", "", 3276 ),
// ignore other data at the end
t_( "345wxyz", "", 345 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
int16_t val;
bool res = read_int16_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
read_int32_c
#define read_int32_c_( Sca, Int32 ) \
read_int32_c( (Sca), (Int32), "" )
bool read_int32_c( cScanner sca[static 1],
int32_t i32[static 1],
char const fmt[static 1] );
Reads a int32_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
int32_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "18", "", 18 ),
t_( "30df", "x", 12511 ),
t_( "-4E3", "X", -1251 ),
t_( "7561", "o", 3953 ),
// boundaries
t_( "-2147483648", "", -2147483648 ),
t_( "2147483647", "", 2147483647 ),
t_( "-2147483649", "", -214748364 ),
// ignore other data at the end
t_( "345wxyz", "", 345 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
int32_t val;
bool res = read_int32_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
read_int64_c
#define read_int64_c_( Sca, Int64 ) \
read_int64_c( (Sca), (Int64), "" )
bool read_int64_c( cScanner sca[static 1],
int64_t i64[static 1],
char const fmt[static 1] );
Reads a int64_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
int64_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "42", "", 42 ),
t_( "aBcD", "x", 43981 ),
t_( "-4a3F", "X", -19007 ),
t_( "7561", "o", 3953 ),
// boundaries
t_( "-9223372036854775808", "", int64_c_( -9223372036854775807 - 1 ) ),
t_( "9223372036854775807", "", int64_c_( 9223372036854775807 ) ),
t_( "9223372036854775808", "", int64_c_( 922337203685477580 ) ),
// ignore other data at the end
t_( "777 oth", "", 777 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
int64_t val;
bool res = read_int64_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
read_int8_c
#define read_int8_c_( Sca, Int8 ) \
read_int8_c( (Sca), (Int8), "" )
bool read_int8_c( cScanner sca[static 1],
int8_t i8[static 1],
char const fmt[static 1] );
Reads a int8_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
int8_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "22", "", 22 ),
t_( "1c", "x", 28 ),
t_( "0", "X", 0 ),
t_( "-70", "o", -56 ),
// boundaries
t_( "-128", "", -128 ),
t_( "127", "", 127 ),
t_( "-2345", "", -23 ),
t_( "128", "", 12 ),
// with leading zeros
t_( "-0046", "", -46 ),
// ignore other data at the end
t_( "32-blocks", "", 32 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
int8_t val;
bool res = read_int8_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
unsigned
The format for all unsigned integers is:
d |
decimal value |
x |
lower- and upper-case hexadecimal value |
X |
lower- and upper-case hexadecimal value |
o |
octal-value |
read_uint16_c
#define read_uint16_c_( Sca, Uint16 ) \
read_uint16_c( (Sca), (Uint16), "" )
bool read_uint16_c( cScanner sca[static 1],
uint16_t u16[static 1],
char const fmt[static 1] );
Reads a uint16_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
uint16_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "1834", "", 1834 ),
t_( "30df", "x", 12511 ),
t_( "4E3", "X", 1251 ),
t_( "7561", "o", 3953 ),
// boundaries
t_( "0", "", 0 ),
t_( "65535", "", 65535 ),
t_( "65536", "", 6553 ),
// ignore other data at the end
t_( "8761hgfa", "", 8761 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
uint16_t val;
bool res = read_uint16_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
read_uint32_c
#define read_uint32_c_( Sca, Uint32 ) \
read_uint32_c( (Sca), (Uint32), "" )
bool read_uint32_c( cScanner sca[static 1],
uint32_t u32[static 1],
char const fmt[static 1] );
Reads a uint32_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
uint32_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "18", "", 18 ),
t_( "30df", "x", 12511 ),
t_( "4E3", "X", 1251 ),
t_( "7561", "o", 3953 ),
// boundaries
t_( "0", "", 0 ),
t_( "4294967295", "", 4294967295 ),
t_( "4294967296", "", 429496729 ),
// ignore other data at the end
t_( "345junk", "", 345 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
uint32_t val;
bool res = read_uint32_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
read_uint64_c
#define read_uint64_c_( Sca, Uint64 ) \
read_uint64_c( (Sca), (Uint64), "" )
bool read_uint64_c( cScanner sca[static 1],
uint64_t u64[static 1],
char const fmt[static 1] );
Reads a uint64_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
uint64_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "18", "", 18 ),
t_( "30df", "x", 12511 ),
t_( "4E3", "X", 1251 ),
t_( "7561", "o", 3953 ),
// boundaries
t_( "0", "", 0 ),
t_( "18446744073709551615", "", 18446744073709551615ULL ),
t_( "18446744073709551616", "", 1844674407370955161ULL ),
// ignore other data at the end
t_( "1170343number", "", 1170343 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
uint64_t val;
bool res = read_uint64_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
read_uint8_c
#define read_uint8_c_( Sca, Uint8 ) \
read_uint8_c( (Sca), (Uint8), "" )
bool read_uint8_c( cScanner sca[static 1],
uint8_t u8[static 1],
char const fmt[static 1] );
Reads a uint8_t value from a text with a scanner.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
uint8_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// general
t_( "18", "", 18 ),
t_( "1c", "x", 28 ),
t_( "F0", "X", 240 ),
t_( "70", "o", 56 ),
// boundaries
t_( "0", "", 0 ),
t_( "255", "", 255 ),
t_( "2345", "", 234 ),
t_( "256", "", 25 ),
// with leading zeros
t_( "0046", "", 46 ),
// ignore other data at the end
t_( "34test", "", 34 )
);
for ( int64_t i = 0; i < tests.s; ++i )
{
test t = tests.v[i];
cScanner* sca = &cstr_scanner_c_( t.str );
uint8_t val;
bool res = read_uint8_c( sca, &val, t.fmt );
res &= val == t.exp;
tap_descf_c( res, "test at index %"PRIi64, i );
}
return finish_tap_c_();
}
slice
read_chars_c
#define read_chars_c_( Sca, Chars ) \
read_chars_c( (Sca), (Chars), "" )
bool read_chars_c( cScanner sca[static 1],
cChars chars[static 1],
char const fmt[static 1] );
Reads the scanner and tracks the read chars in the chars value. The fmt C-string can have the same commands and specifier like the read_c function.
#include "clingo/io/read_type.h"
#include "clingo/lang/expect.h"
TEMP_SLICE_C_(
test,
{
char const* str;
char const* fmt;
char const* expChars;
char const* expUnscanned;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
testSlice tests = slice_c_( test,
// any
t_( "'key': 'value'", "{>:}", "'key'", ": 'value'" ),
// func
t_( "123456", "{/?d}", "1", "23456" ),
t_( "123456", "{/*d}", "123456", "" ),
// range
t_( "I am müller", "{[*0000-007F}", "I am m", "üller" ),
t_( "I am müller", "{[+0-7f}", "I am m", "üller" ),
t_( "I am müller", "{[+ z}", "I am m", "üller" )
);
for_each_c_( test const*, t, tests )
{
cScanner* sca = &cstr_scanner_c_( t->str );
cChars chars = (cChars)empty_c_();
bool res = read_chars_c( sca, &chars, t->fmt );
res &= chars_is_c( chars, t->expChars );
res &= unscanned_is_c( sca, t->expUnscanned );
tap_descf_c( res, "%s on %s", t->fmt, t->str );
}
return finish_tap_c_();
}