read

Overview

Module that allows to read text with additional arguments.

Type and Definitions

definitions

cREAD_ERROR_

#define cREAD_ERROR_

Defines the c_ReadError values and the corresponding messages.

c_ReadError

enum c_WriteError {
   c_NotAbleToReadValue = 1,
   c_ToLargeReadFormat = 2,
   c_InvalidReadFormat = 3,
};
type enum c_ReadError c_ReadError;

Enum type to represent errors that can happen in a read function.

c_read_va_arg

typedef int64_t ( *c_read_va_arg )( cScanner sca[static 1],
                                    void* val,
                                    cChars type,
                                    char const fmt[static 1] );

c_read_va_arg is the signature of a function to read a with type specified value into val with the format fmt. The default implementation of the function is read_format_arg_c.

Functions

overall

read_format_arg_c

int64_t read_format_arg_c( cScanner sca[static 1],
                           void* val,
                           cChars type,
                           char const fmt[static 1] );

Interprets val as pointer as type and reads the formated(fmt) text into it.

read_c

#define read_c_( Sca, ... )                                                    \
   read_c( (Sca), read_format_arg_c, nargs_c_( __VA_ARGS__ ), __VA_ARGS__ )
int64_t read_c( cScanner sca[static 1],
                c_read_va_arg read_arg,
                int n,
                ... );

Reads data from a scanner and can store them according to parameter specifier into the variables given by the additional arguments. A specifier has the following format:

{[!]type[:fmt]}

The optional "!"" at the beginning means that no variable is given by the additional arguments for this value. The optional "fmt" value can have a size of 32 chars. The values ^ and } are special characters, use ^^ and ^} to pass this characters in the "fmt" value to the corresponding read function.

The requried type value shows witch sub read function will be used. The default read_arg value read_format_arg_c uses the following mapping:

Table 1. type

bool

read_bool_c

b

read_byte_c

c

read_char_c

i8

read_int8_c

i16

read_int16_c

i32

read_int32_c

i64

read_int64_c

r

read_rune_c

rng

read_range_c

u8

read_uint8_c

u16

read_uint16_c

u32

read_uint32_c

u64

read_uint64_c

Additional to the the specifiers can a format string also contain commands. A command has the following format:

{[type]op(func/range/set)}

The values ^ and } are special characters, use ^^ and ^} to pass this characters to the set or range value.

If no "type" value is set expects the function a set of runes. The command will use, dependent on "op", the following functions with the set:

Table 2. set operations

>

move_to_any_rune_c

=

move_if_any_rune_c

1 occurrence

?

move_if_any_rune_c

optional (0 or 1 occurrence)

+

move_while_any_rune_c

1 or more repetitions

*

move_while_any_rune_c

0 or more repetitions

If "type" is / expects the function one of the following letters:

Table 3. func values

a

isalpha

c

iscntrl

d

isdigit

g

isgraph

l

islower

o

isprint

p

ispunct

s

isspace

u

isupper

w

isalnum

x

isxdigit

The command will use, dependent on "op", the following functions with the func:

Table 4. func operations

>

move_to_char_match_c

=

move_if_char_match_c

1 occurrence

?

move_if_char_match_c

optional (0 or 1 occurrence)

+

move_while_char_match_c

1 or more repetitions

*

move_while_char_match_c

0 or more repetitions

If "type" is [ expects the function a rune range value. A rune range value can have two representations:

unicode number range:
"0020-007e"
"20-7E"
just min and max rune:
" ~"
"az"

The command will use, dependent on "op", the following functions with the range:

Table 5. range operations

>

move_to_in_range_c

=

move_if_in_range_c

1 occurrence

?

move_if_in_range_c

optional (0 or 1 occurrence)

+

move_while_in_range_c

1 or more repetitions

*

move_while_in_range_c

0 or more repetitions

Example
#include "clingo/io/read.h"
#include "clingo/lang/expect.h"

int main( void )
{
   init_tap_c_();

   {
      cScanner* sca = &cstr_scanner_c_( "a lower  123:456 true a1   " );
      int16_t i16 = 0;
      bool b = false;
      int32_t hex = 0;
      expect_c_( read_c_( sca, "a {/+l}{/>d}{i16}:{!i64} {bool} {i32:x}{/*s}",
                                &i16, &b, &hex ) );
      expect_c_( i16 == 123 );
      expect_c_( b );
      expect_c_( hex == 0xa1 );
      expect_c_( sca->space == 0 );
   }

   {
      cScanner* sca = &cstr_scanner_c_( "a lower  123:456 true a1" );
      int16_t i16 = 0;
      bool b = false;
      int32_t hex = 0;
      expect_c_( read_c_( sca, "a {/+l}{/>d}{i16}:{!i64} {bool} {i32:x}",
                               &i16, &b, &hex ) );
      expect_c_( i16 == 123 );
      expect_c_( b );
      expect_c_( hex == 0xa1 );
      expect_c_( sca->space == 0 );
   }

   {
      cScanner* sca = &cstr_scanner_c_( "a lower  123:456 true a1   " );
      int16_t i16 = 0;
      bool b = false;
      expect_c_( read_c_( sca, "a {/+l}{/>d}{i16}", &i16,
                               ":{!i64} {bool} {!i32:x}{/*s}", &b ) );
      expect_c_( i16 == 123 );
      expect_c_( b );
      expect_c_( sca->space == 0 );
   }

   {
      cScanner* sca = &cstr_scanner_c_( "a lower  123:456 true a1   " );
      expect_c_( read_c_( sca, "a ", "{/+l}{/>d}{>:}:{/>s}",
                               " {/+l} {/+x}{/*s}" ) );
      expect_c_( sca->space == 0 );
   }

   {
      cScanner* sca = &cstr_scanner_c_( "a lower  123:456 true a1   " );
      expect_c_( read_c_( sca, "a {/+l}{/>d}{>:}:{/>s} {/+l} {/+x}{/*s}" ) );
      expect_c_( sca->space == 0 );
   }

   return finish_tap_c_();
}

error

read_error_msg_c

char const* read_error_msg_c( cScanner sca[static 1] );

Returns the corresponding message for a C_ReadError.