summaryrefslogtreecommitdiff
path: root/README.md
blob: ca52d74cf6677302af508741a61e9e00f46b93b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# 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<bits>`
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 `%Z<bits>R` and `%Z<bits>E` 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 <libmpuio.h>
```

and link against LibMPUIO and LibMPU.


## Example

```c
#include <locale.h>
#include <libmpuio.h>

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**.