blob: f880a9e959491b77ff4d6a873a809a60be7502c7 (
plain) (
blame)
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
|
#include <stdio.h>
#include <string.h>
#include "macros.h"
#include "mbio.h"
#include "mbstring.h"
#include "rune.h"
/* Width in bytes of U+FFFD REPLACEMENT CHARACTER */
constexpr int ERR_WIDTH = 3;
int
u8fgetr(rune *ch, FILE *stream)
{
int c, n = 0;
char8_t buf[U8_LEN_MAX];
if ((c = fgetc(stream)) == EOF)
goto eof;
n = u8byte1(c) ? 0 : u8byte2(c) ? 1 : u8byte3(c) ? 2 : u8byte4(c) ? 3 : -1;
if (n == -1)
goto err;
buf[0] = (char8_t)c;
for (int i = 0; i < n; i++) {
/* If fgetc() returns EOF we must have malformed UTF-8 unless the EOF
was the result of a reading error. */
if ((c = fgetc(stream)) == EOF || !u8bytec(c)) {
if (ferror(stream))
goto eof;
goto err;
}
buf[i + 1] = c;
}
return u8tor(ch, buf);
eof:
*ch = MBEOF;
return 0;
err:
*ch = RUNE_ERROR;
return ERR_WIDTH;
}
|