# LibMPUIO LibMPUIO is a C library providing formatted and stream-oriented input/output facilities for the [LibMPU](https://git.radix-linux.su/libs/libmpu.git/) multiple precision arithmetic library. The library follows the general design of the standard C `stdio` interface, while adding native support for **LibMPU** integer, real, and complex objects. **LibMPUIO** is designed around a simple text model: - text is represented internally as UCS-2; - files, terminals, pipes, and other external text streams use UTF-8; - ordinary byte-oriented I/O remains available for raw binary data; - formatted I/O supports both standard **C** objects and **LibMPU** arbitrary precision objects. **LibMPUIO** is written in **C** and is intended for numerical programs, scientific software, command-line tools, virtual machines, calculators, and other applications using **LibMPU**. ## Features **LibMPUIO** provides a `stdio`-like API based on the opaque `mpu_FILE` object. Supported facilities include: - standard streams: - `mpu_stdin` - `mpu_stdout` - `mpu_stderr` - file operations: - `mpu_fopen()` - `mpu_fdopen()` - `mpu_freopen()` - `mpu_fclose()` - `mpu_fileno()` - character and string I/O: - `mpu_fgetc()` - `mpu_fputc()` - `mpu_fgets()` - `mpu_fputs()` - `mpu_getline()` - `mpu_getdelim()` - raw byte I/O: - `mpu_fread()` - `mpu_fwrite()` - formatted output: - `mpu_printf()` - `mpu_fprintf()` - `mpu_sprintf()` - `mpu_snprintf()` - `mpu_dprintf()` - corresponding `v*` functions - formatted input: - `mpu_scanf()` - `mpu_fscanf()` - `mpu_sscanf()` - corresponding `v*` functions - stream positioning: - `mpu_fseek()` - `mpu_fseeko()` - `mpu_ftell()` - `mpu_ftello()` - `mpu_fgetpos()` - `mpu_fsetpos()` - `mpu_rewind()` - buffering and stream status: - `mpu_fflush()` - `mpu_setvbuf()` - `mpu_setbuf()` - `mpu_setlinebuf()` - `mpu_feof()` - `mpu_ferror()` - `mpu_clearerr()` - `mpu_fpurge()` - stream locking and unlocked operations; - UCS-2 memory streams; - dynamically allocated UCS-2 memory streams; - user-defined cookie streams; - command pipes through `mpu_popen()` and `mpu_pclose()`; - 8-bit string, UCS-2 string, and UTF-8 string helper functions; - strict UTF-8 / UCS-2 conversion functions. ## Character representation **LibMPUIO uses** `__mpu_char16_t` UCS-2 code units for its internal text representation. String literals intended for **LibMPUIO** can be written using `MPU_UCS2()`: ```c mpu_printf( MPU_UCS2( "Hello, world!\n" ) ); ``` The `%s` formatted conversion operates on UCS-2 strings: ```c __mpu_char16_t text[] = MPU_UCS2( "Hello" ); mpu_printf( MPU_UCS2( "%s\n" ), text ); ``` The `%a` conversion operates on an 8-bit multibyte string encoded according to the active `LC_CTYPE` locale: ```c __mpu_char8_t text[] = "Hello"; mpu_printf( MPU_UCS2( "%a\n" ), text ); ``` For file and terminal streams **LibMPUIO** converts text between its internal UCS-2 representation and external UTF-8 representation. Raw `mpu_fread()` and `mpu_fwrite()` operations do not perform text conversion. ## LibMPU formatted numbers **LibMPUIO** extends the standard formatted I/O syntax with the `Z` modifier. For example: ```c mpu_int256_t value; mpu_printf( MPU_UCS2( "%Z256d\n" ), value ); ``` **LibMPU** integer values may be formatted using decimal, octal, hexadecimal, and binary representations. Examples: ```c mpu_printf( MPU_UCS2( "%Z256d\n" ), value ); mpu_printf( MPU_UCS2( "%Z256u\n" ), value ); mpu_printf( MPU_UCS2( "%#Z256x\n" ), value ); mpu_printf( MPU_UCS2( "%#Z256b\n" ), value ); ``` *LibMPU* real objects use real conversions such as: ```c mpu_real128_t value; mpu_printf( MPU_UCS2( "%Z128R\n" ), value ); mpu_printf( MPU_UCS2( "%.20Z128E\n" ), value ); ``` Both `%ZR` and `%ZE` may also be used when reading **LibMPU** real objects. For example: ```c mpu_real128_t r1, r2; mpu_sscanf( MPU_UCS2( "1.23456789E+10" ), MPU_UCS2( "%Z128R" ), r1 ); mpu_sscanf( MPU_UCS2( "1.23456789E+10" ), MPU_UCS2( "%Z128E" ), r2 ); ``` **LibMPU** complex objects use the `%J` conversion: ```c mpu_complex128_t value; mpu_printf( MPU_UCS2( "%Z128J\n" ), value ); ``` The optional second precision field may be used to control the minimum number of exponent digits for **LibMPU** real and complex output: ```c mpu_printf( MPU_UCS2( "%.20.4Z128R\n" ), value ); ``` ## Requirements **LibMPUIO** requires: - an ISO C11 compiler; - a POSIX-compatible operating system; - POSIX threads; - LibMPU; - a UTF-8 capable environment for normal text operation. **LibMPU** must be installed before configuring **LibMPUIO**. ## Building **LibMPUIO** uses the **GNU Autotools** build system. A normal build is: ```sh ./configure make ``` To build using several jobs: ```sh make -j$(nproc) ``` If the source tree was obtained directly from version control rather than from a release tarball, the Autotools files may first need to be generated with the project's **bootstrap** procedure. Release tarballs should already contain the generated `configure` script. ## Installation The default installation procedure is: ```sh make install ``` For packaged installations a staging directory should normally be used: ```sh make install DESTDIR="$PKG" ``` The public interface is provided by: ```text libmpuio.h ``` Applications should include it as: ```c #include ``` and link against LibMPUIO and LibMPU. ## Example ```c #include #include int main( void ) { mpu_real128_t value; setlocale( LC_ALL, "" ); __mpu_init(); mpu_sscanf( MPU_UCS2( "1.23456789E+10" ), MPU_UCS2( "%Z128R" ), value ); mpu_printf( MPU_UCS2( "value = %.20Z128R\n" ), value ); __mpu_free_context(); return( 0 ); } ``` ## Design **LibMPUIO** deliberately keeps three concepts separate: 1. raw bytes; 2. UCS-2 internal text; 3. UTF-8 external text. The library does not use the host C library's `FILE *` objects internally as its public stream abstraction. Applications operate on `mpu_FILE *` streams. **LibMPUIO** is intended to provide a consistent I/O layer for **LibMPU**-based software while retaining the familiar programming model of the standard C library. **Enjoy**.