.. include:: ../global.rst .. idio:currentmodule:: C .. _`c module types`: C Types ------- :lname:`Idio` supports the use of the fourteen :lname:`C` base types and typedefs thereof and a pointer type: .. csv-table:: :header: :lname:`Idio`, :lname:`C` :widths: auto ``C/char``, ``char`` ``C/schar``, ``signed char`` ``C/uchar``, ``unsigned char`` ``C/short``, ``short`` ``C/ushort``, ``unsigned short`` ``C/int``, ``int`` ``C/uint``, ``unsigned int`` ``C/long``, ``long`` ``C/ulong``, ``unsigned long`` ``C/longlong``, ``long long`` ``C/ulonglong``, ``unsigned long long`` ``C/float``, ``float`` ``C/double``, ``double`` ``C/longdouble``, ``long double`` ``C/pointer``, ``void *`` Equality tests of ``C/longdouble`` are, at best, untested. The ``C/pointer`` type is used to carry references to :lname:`C` allocated memory. They will usually be tagged such that the GC will free the referenced memory when it collects the value. There is a special form of ``C/pointer`` with a *C Structure Identifier* tag which allows for the implicit use of accessors and printers of that value. Most of the allocated :lname:`C` ``struct``\ s in :ref:`libc ` are so tagged. C Type Predicates ^^^^^^^^^^^^^^^^^ .. _`C/char?`: .. idio:function:: C/char? o test if `o` is a C/char :param o: object to test :return: ``#t`` if `o` is a C/char, ``#f`` otherwise .. _`C/schar?`: .. idio:function:: C/schar? o test if `o` is a C/schar :param o: object to test :return: ``#t`` if `o` is a C/schar, ``#f`` otherwise .. _`C/uchar?`: .. idio:function:: C/uchar? o test if `o` is a C/uchar :param o: object to test :return: ``#t`` if `o` is a C/uchar, ``#f`` otherwise .. _`C/short?`: .. idio:function:: C/short? o test if `o` is a C/short :param o: object to test :return: ``#t`` if `o` is a C/short, ``#f`` otherwise .. _`C/ushort?`: .. idio:function:: C/ushort? o test if `o` is a C/ushort :param o: object to test :return: ``#t`` if `o` is a C/ushort, ``#f`` otherwise .. _`C/int?`: .. idio:function:: C/int? o test if `o` is a C/int :param o: object to test :return: ``#t`` if `o` is a C/int, ``#f`` otherwise .. _`C/uint?`: .. idio:function:: C/uint? o test if `o` is a C/uint :param o: object to test :return: ``#t`` if `o` is a C/uint, ``#f`` otherwise .. _`C/long?`: .. idio:function:: C/long? o test if `o` is a C/long :param o: object to test :return: ``#t`` if `o` is a C/long, ``#f`` otherwise .. _`C/ulong?`: .. idio:function:: C/ulong? o test if `o` is a C/ulong :param o: object to test :return: ``#t`` if `o` is a C/ulong, ``#f`` otherwise .. _`C/longlong?`: .. idio:function:: C/longlong? o test if `o` is a C/longlong :param o: object to test :return: ``#t`` if `o` is a C/longlong, ``#f`` otherwise .. _`C/ulonglong?`: .. idio:function:: C/ulonglong? o test if `o` is a C/ulonglong :param o: object to test :return: ``#t`` if `o` is a C/ulonglong, ``#f`` otherwise .. _`C/float?`: .. idio:function:: C/float? o test if `o` is a C/float :param o: object to test :return: ``#t`` if `o` is a C/float, ``#f`` otherwise .. _`C/double?`: .. idio:function:: C/double? o test if `o` is a C/double :param o: object to test :return: ``#t`` if `o` is a C/double, ``#f`` otherwise .. _`C/longdouble?`: .. idio:function:: C/longdouble? o test if `o` is a C/longdouble :param o: object to test :return: ``#t`` if `o` is a C/longdouble, ``#f`` otherwise .. _`C/pointer?`: .. idio:function:: C/pointer? o test if `o` is a C/pointer :param o: object to test :return: ``#t`` if `o` is a C/pointer, ``#f`` otherwise .. _`C/type?`: .. idio:function:: C/type? o test if `o` is any C type :param o: object to test :return: ``#t`` if `o` is any C type, ``#f`` otherwise .. _`C/number?`: .. idio:function:: C/number? o test if `o` is any C numeric type :param o: object to test :return: ``#t`` if `o` is any C numeric type, ``#f`` otherwise .. _`C/integral?`: .. idio:function:: C/integral? o test if `o` is any C integral numeric type :param o: object to test :return: ``#t`` if `o` is any C integral numeric type, ``#f`` otherwise .. _`C/signed?`: .. idio:function:: C/signed? o test if `o` is any C signed numeric type :param o: object to test :return: ``#t`` if `o` is any C signed numeric type, ``#f`` otherwise .. _`C/unsigned?`: .. idio:function:: C/unsigned? o test if `o` is any C unsigned numeric type :param o: object to test :return: ``#t`` if `o` is any C unsigned numeric type, ``#f`` otherwise .. _`C/floating?`: .. idio:function:: C/floating? o test if `o` is a C floating point type :param o: object to test :return: ``#t`` if `o` is a C floating point type, ``#f`` otherwise C Type Constructors ^^^^^^^^^^^^^^^^^^^ .. _`C/integer->`: .. idio:function:: C/integer-> i [type] convert Idio integer `i` to a C integer If `i` is a fixnum then use `type` for a more specific C type. An integer bignum is converted to a ``libc/intmax_t``. :param i: Idio integer to convert :type i: fixnum or bignum :param type: C type to create, defaults to ``'int`` :type type: symbol, optional :return: C integer :rtype: according to `type` :raises: ^rt-C-conversion-error: `type` defaults to ``'int`` and can be one of: ``'char`` ``'schar`` ``'uchar`` ``'short`` ``'ushort`` ``'int`` ``'uint`` ``'long`` ``'ulong`` ``'longlong`` ``'ulonglong`` or an alias thereof, eg. ``libc/pid_t``. `i` is range-checked for `type` ``C/integer->`` is limited to a C ``intmax_t``, see :ref:`C/integer->unsigned unsigned>` .. _`C/integer->unsigned`: .. idio:function:: C/integer->unsigned i [C/unsigned type] convert Idio integer `i` to a C unsigned integer If `i` is a fixnum then use `type` for a more specific C type. An integer bignum is converted to a ``libc/uintmax_t``. :param i: Idio integer to convert :type i: bignum or fixnum :param type: C type to create, defaults to ``'uint`` :type type: symbol, optional :return: C unsigned integer :rtype: according to `type` :raises: ^rt-C-conversion-error: `type` defaults to ``'uint`` and can be one of: ``'uchar`` ``'ushort`` ``'uint`` ``'ulong`` ``'ulonglong`` or an alias thereof, eg. ``libc/size_t``. `i` is range-checked for `type` ``C/integer->unsigned`` is limited to a C ``uintmax_t`` .. _`C/number->`: .. idio:function:: C/number-> n type convert Idio number `n` to a C number using `type` for the specific C type. bignums must be a C floating type :param n: Idio number to convert :type n: fixnum or bignum :param type: C type to create :type type: symbol :return: C number :rtype: according to `type` :raises: ^rt-C-conversion-error: `type` can be one of: ``'char`` ``'schar`` ``'uchar`` ``'short`` ``'ushort`` ``'int`` ``'uint`` ``'long`` ``'ulong`` ``'longlong`` ``'ulonglong`` ``'float`` ``'double`` ``'longdouble`` or an alias thereof, eg. ``libc/size_t``. `n` is range-checked for integral `type`\ s Where `type` is: * signed, :ref:`C/integer-> >` is called, * unsigned, :ref:`C/integer->unsigned unsigned>` is called, .. warning:: If `n` is a bignum then `type` can only be a floating point type. C Type Converters ^^^^^^^^^^^^^^^^^ .. _`C/->integer`: .. idio:function:: C/->integer i convert C integer `i` to an Idio integer :param o: C integer to convert :type o: C/ integer type :return: Idio integer :rtype: integer .. _`C/->number`: .. idio:function:: C/->number i convert C number `i` to an Idio number :param o: C number to convert :type o: a C/ numeric type :return: Idio number :rtype: number supported C types are: ``C/char`` ``C/schar`` ``C/uchar`` ``C/short`` ``C/ushort`` ``C/int`` ``C/uint`` ``C/long`` ``C/ulong`` ``C/longlong`` ``C/ulonglong`` ``C/float`` ``C/double`` or an alias thereof, eg. ``libc/size_t``. the following types are NOT supported: ``C/longdouble`` C Pointer Reflection ^^^^^^^^^^^^^^^^^^^^ :lname:`C` pointers can be tagged with some C Structure Identification (CSI) information. The purpose is multi-fold where, using :ref:`libc/struct-stat ` as an example: * we can store a nominal structure name, eg. ``libc/struct-stat`` The name is descriptive only. * we can store a list of the structure members, eg. ``libc/struct-stat``'s: ``(st_dev st_ino st_nlink st_mode st_uid st_gid st_rdev st_size st_blksize st_blocks st_atim st_mtim st_ctim st_atime st_mtime st_ctime)`` .. note:: The modern :lname:`C` ``struct stat`` does not have ``st_atime`` etc. members *per se* but those are ``#define``'d to the ``time_t tv_sec`` components of the corresponding ``st_atim``'s ``struct timespec`` thus maintaining backwards compatibility. :lname:`Idio` supports accessing both forms. * we can associate a getter to manipulate the ``C/pointer`` given a member name, here, :ref:`libc/struct-stat-ref ` We can subsequently associate a setter with the getter -- albeit there is (deliberately) no setter for a ``libc/struct-stat``. * we can associate a function to print the ``C/pointer`` in a more aesthetically pleasing manner. For example, the ``struct timespec`` is stylised as a floating point number. Here, we associate :ref:`libc/struct-stat-as-string `. .. _`C/pointer-name`: .. idio:function:: C/pointer-name p Return the CSI name of C/pointer `p` :param p: C/pointer to query :type p: C/pointer :return: CSI name or ``#n`` :rtype: symbol or ``#n`` The CSI name is descriptive only. .. _`C/pointer-members`: .. idio:function:: C/pointer-members p Return the CSI members of C/pointer `p` :param p: C/pointer to query :type p: C/pointer :return: CSI members or ``#n`` :rtype: list .. include:: ../commit.rst