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_();
}