github.com/afumu/libc@v0.0.6/musl/src/stdio/fgetwc.c (about)

     1  #include "stdio_impl.h"
     2  #include "locale_impl.h"
     3  #include <wchar.h>
     4  #include <errno.h>
     5  
     6  static wint_t __fgetwc_unlocked_internal(FILE *f)
     7  {
     8  	wchar_t wc;
     9  	int c;
    10  	size_t l;
    11  
    12  	/* Convert character from buffer if possible */
    13  	if (f->rpos != f->rend) {
    14  		l = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos);
    15  		if (l+1 >= 1) {
    16  			f->rpos += l + !l; /* l==0 means 1 byte, null */
    17  			return wc;
    18  		}
    19  	}
    20  
    21  	/* Convert character byte-by-byte */
    22  	mbstate_t st = { 0 };
    23  	unsigned char b;
    24  	int first = 1;
    25  	do {
    26  		b = c = getc_unlocked(f);
    27  		if (c < 0) {
    28  			if (!first) {
    29  				f->flags |= F_ERR;
    30  				errno = EILSEQ;
    31  			}
    32  			return WEOF;
    33  		}
    34  		l = mbrtowc(&wc, (void *)&b, 1, &st);
    35  		if (l == -1) {
    36  			if (!first) {
    37  				f->flags |= F_ERR;
    38  				ungetc(b, f);
    39  			}
    40  			return WEOF;
    41  		}
    42  		first = 0;
    43  	} while (l == -2);
    44  
    45  	return wc;
    46  }
    47  
    48  wint_t __fgetwc_unlocked(FILE *f)
    49  {
    50  	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
    51  	if (f->mode <= 0) fwide(f, 1);
    52  	*ploc = f->locale;
    53  	wchar_t wc = __fgetwc_unlocked_internal(f);
    54  	*ploc = loc;
    55  	return wc;
    56  }
    57  
    58  wint_t fgetwc(FILE *f)
    59  {
    60  	wint_t c;
    61  	FLOCK(f);
    62  	c = __fgetwc_unlocked(f);
    63  	FUNLOCK(f);
    64  	return c;
    65  }
    66  
    67  weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
    68  weak_alias(__fgetwc_unlocked, getwc_unlocked);