Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add fgetwc, getwc, ungetwc wchar api implementation #11408

Merged
merged 3 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions include/wchar.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,15 @@ extern "C"
wint_t btowc(int);
int fwprintf(FILE *, FAR const wchar_t *, ...);
int fwscanf(FILE *, FAR const wchar_t *, ...);
wint_t fgetwc(FILE *);
wint_t fgetwc(FAR FILE *);
wint_t fgetwc_unlocked(FAR FILE *f);
FAR wchar_t *fgetws(wchar_t *, int, FILE *);
wint_t fputwc(wchar_t, FILE *);
wint_t fputwc_unlocked(wchar_t, FAR FILE *);
int fputws(FAR const wchar_t *, FILE *);
int fputws_unlocked(FAR const wchar_t *, FAR FILE *);
int fwide(FILE *, int);
wint_t getwc(FILE *);
wint_t getwc(FAR FILE *);
wint_t getwchar(void);
int mbsinit(FAR const mbstate_t *);
size_t mbrlen(FAR const char *, size_t, FAR mbstate_t *);
Expand All @@ -165,7 +166,8 @@ wint_t putwchar(wchar_t);
wint_t putwchar_unlocked(wchar_t);
int swprintf(FAR wchar_t *, size_t, FAR const wchar_t *, ...);
int swscanf(FAR const wchar_t *, FAR const wchar_t *, ...);
wint_t ungetwc(wint_t, FILE *);
wint_t ungetwc(wint_t, FAR FILE *);
wint_t ungetwc_unlocked(wint_t, FAR FILE *);
int vfwprintf(FILE *, FAR const wchar_t *, va_list);
int vfwscanf(FILE *, FAR const wchar_t *, va_list);
int vwprintf(FAR const wchar_t *, va_list);
Expand Down
5 changes: 5 additions & 0 deletions libs/libc/libc.csv
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
"fgetc","stdio.h","defined(CONFIG_FILE_STREAM)","int","FAR FILE *"
"fgetpos","stdio.h","defined(CONFIG_FILE_STREAM)","int","FAR FILE *","FAR fpos_t *"
"fgets","stdio.h","defined(CONFIG_FILE_STREAM)","FAR char *","FAR char *","int","FAR FILE *"
"fgetwc","wchar.h","defined(CONFIG_FILE_STREAM)","wint_t","FAR FILE *"
"fgetwc_unlocked","wchar.h","defined(CONFIG_FILE_STREAM)","wint_t","FAR FILE *"
"fileno","stdio.h","","int","FAR FILE *"
"flockfile","stdio.h","!defined(CONFIG_FILE_STREAM)","void","FAR FILE *"
"fnmatch","fnmatch.h","","int","FAR const char *","FAR const char *","int"
Expand Down Expand Up @@ -107,6 +109,7 @@
"gets","stdio.h","defined(CONFIG_FILE_STREAM)","FAR char *","FAR char *"
"gettext","libintl.h","defined(CONFIG_LIBC_LOCALE_GETTEXT)","FAR char *","FAR const char *"
"gettimeofday","sys/time.h","","int","FAR struct timeval *","FAR struct timezone *"
"getwc","wchar.h","defined(CONFIG_FILE_STREAM)","wint_t","FAR FILE *"
"gmtime","time.h","","FAR struct tm *","FAR const time_t *"
"gmtime_r","time.h","","FAR struct tm *","FAR const time_t *","FAR struct tm *"
"htonl","arpa/inet.h","","uint32_t","uint32_t"
Expand Down Expand Up @@ -329,6 +332,8 @@
"ub16sqr","fixedmath.h","!defined(CONFIG_HAVE_LONG_LONG)","ub16_t","ub16_t"
"uname","sys/utsname.h","","int","FAR struct utsname *"
"ungetc","stdio.h","defined(CONFIG_FILE_STREAM)","int","int","FAR FILE *"
"ungetwc","wchar.h","defined(CONFIG_FILE_STREAM)","wint_t","wint_t","FAR FILE *"
"ungetwc_unlocked","wchar.h","defined(CONFIG_FILE_STREAM)","wint_t","wint_t","FAR FILE *"
"usleep","unistd.h","","int","useconds_t"
"vasprintf","stdio.h","","int","FAR char **","FAR const IPTR char *","va_list"
"versionsort","dirent.h","","int","FAR const struct dirent **","FAR const struct dirent **"
Expand Down
5 changes: 4 additions & 1 deletion libs/libc/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ if(CONFIG_FILE_STREAM)
lib_putwc.c
lib_fputws.c
lib_fopencookie.c
lib_fmemopen.c)
lib_fmemopen.c
lib_fgetwc.c
lib_getwc.c
lib_ungetwc.c)
endif()

target_sources(c PRIVATE ${SRCS})
3 changes: 2 additions & 1 deletion libs/libc/stdio/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ CSRCS += lib_feof.c lib_ferror.c lib_rewind.c lib_clearerr.c
CSRCS += lib_scanf.c lib_vscanf.c lib_fscanf.c lib_vfscanf.c lib_tmpfile.c
CSRCS += lib_setbuf.c lib_setvbuf.c lib_libfilelock.c lib_libgetstreams.c
CSRCS += lib_setbuffer.c lib_fputwc.c lib_putwc.c lib_fputws.c
CSRCS += lib_fopencookie.c lib_fmemopen.c lib_open_memstream.c
CSRCS += lib_fopencookie.c lib_fmemopen.c lib_open_memstream.c lib_fgetwc.c
CSRCS += lib_getwc.c lib_ungetwc.c
endif

# Add the stdio directory to the build
Expand Down
121 changes: 121 additions & 0 deletions libs/libc/stdio/lib_fgetwc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/****************************************************************************
* libs/libc/stdio/lib_fgetwc.c
*
* Copyright © 2005-2014 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <wchar.h>
#include <errno.h>
#include <string.h>

#ifdef CONFIG_FILE_STREAM

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: fgetwc_unlocked
*
* Description:
* Get wide character from stream without lock the stream
*
* Input Parameters:
* f - Pointer to a FILE object that identifies an input stream, during
* the read operaiton, the stream will not be locked
*
* Returned Value:
* Return the character read is returned,
* Return WEOF is the sequence of bytes that read cannot be interpreted as
* a valid wide characted, and sets the errno to EILSEQ
*
****************************************************************************/

wint_t fgetwc_unlocked(FAR FILE *f)
{
mbstate_t st;
wchar_t wc;
int c;
char b;
size_t l = -2;

memset(&st, 0, sizeof(mbstate_t));

/* Convert character byte-by-byte */

while (l == -2)
{
b = c = getc_unlocked(f);
if (c < 0)
{
if (!mbsinit(&st))
{
set_errno(EILSEQ);
}

f->fs_flags |= __FS_FLAG_EOF;
return WEOF;
}

l = mbrtowc(&wc, &b, 1, &st);
if (l == -1)
{
f->fs_flags |= __FS_FLAG_EOF;
return WEOF;
}
}

return wc;
}

/****************************************************************************
* Name: fgetwc
*
* Description:
* Get wide character from stream
*
* Input Parameters:
* f - Pointer to a FILE object that identifies an input stream, the stream
* will be locked during the read operation
*
* Returned Value:
* Return the character read is returned,
* Return WEOF is the sequence of bytes that read cannot be interpreted as
* a valid wide characted, and sets the errno to EILSEQ
*
****************************************************************************/

wint_t fgetwc(FAR FILE *f)
{
wint_t c;
flockfile(f);
c = fgetwc_unlocked(f);
funlockfile(f);
return c;
}

#endif /* CONFIG_FILE_STREAM */
60 changes: 60 additions & 0 deletions libs/libc/stdio/lib_getwc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/****************************************************************************
* libs/libc/stdio/lib_getwc.c
*
* Copyright © 2005-2014 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <wchar.h>

#ifdef CONFIG_FILE_STREAM

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: getwc
*
* Description:
* Get wide character from stream
*
* Input Parameters:
* f - Pointer to a FILE object that identifies an input stream
*
* Returned Value:
* Return the character read is returned,
* Return WEOF is the sequence of bytes that read cannot be interpreted as
* a valid wide characted, and sets the errno to EILSEQ
*
****************************************************************************/

wint_t getwc(FAR FILE *f)
{
return fgetwc(f);
}

#endif /* CONFIG_FILE_STREAM */
125 changes: 125 additions & 0 deletions libs/libc/stdio/lib_ungetwc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/****************************************************************************
* libs/libc/stdio/lib_ungetwc.c
*
* Copyright © 2005-2014 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <wchar.h>
#include <limits.h>
#include <ctype.h>
#include <fcntl.h>
#include <string.h>

#ifdef CONFIG_FILE_STREAM

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: ungetwc_unlocked
*
* Description:
* Put a wide character back to the stream without lock the stream
*
* Input Parameters:
* wc - the wide character to be put back
* f - the file stream to put the wide character back to
*
* Returned Value:
* Return the wide character that put back to the stream on success,
* return WEOF on failed, and keep the given stream remains unchanged.
*
****************************************************************************/

wint_t ungetwc_unlocked(wint_t wc, FAR FILE *f)
{
char mbc[MB_LEN_MAX];
int l = 1;

/* Stream must be open for read access */

if ((f->fs_oflags & O_RDOK) == 0)
{
return WEOF;
}

/* Try conversion early so we can fail without locking if invalid */

if ((l = wctomb(mbc, wc)) < 0)
{
return WEOF;
}

#if CONFIG_NUNGET_CHARS > 0
if (f->fs_nungotten + l <= CONFIG_NUNGET_CHARS)
{
memcpy(f->fs_ungotten + f->fs_nungotten, mbc, l);
f->fs_nungotten += l;
return wc;
}
else
#endif
{
return WEOF;
}
}

/****************************************************************************
* Name: ungetwc
*
* Description:
* Put a wide character back to the stream
*
* Input Parameters:
* wc - the wide character that need to put back to the stream
* f - pointer to a FILE object that identifies an input stream
*
* Returned Value:
* Return the wide character that put back to the stream on success,
* return WEOF on failed, and keep the given stream remains unchanged.
*
****************************************************************************/

wint_t ungetwc(wint_t wc, FAR FILE *f)
{
wint_t ret;

/* Verify that a non-NULL stream was provided and wc is not WEOF */

if (!f || wc == WEOF)
{
return WEOF;
}

flockfile(f);
ret = ungetwc_unlocked(wc, f);
funlockfile(f);
return ret;
}

#endif /* CONFIG_FILE_STREAM */
Loading