Add new fgetwln() function

Man page taken from FreeBSD.
This commit is contained in:
Guillem Jover 2012-11-23 21:19:45 +01:00
parent ee0489eb2b
commit a97ce513e0
6 changed files with 209 additions and 0 deletions

View File

@ -38,6 +38,8 @@
#include <sys/types.h>
__BEGIN_DECLS
wchar_t *fgetwln(FILE *stream, size_t *len);
size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size);
size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size);
__END_DECLS

View File

@ -24,6 +24,7 @@ dist_man_MANS = \
dehumanize_number.3 \
expand_number.3 \
fgetln.3 \
fgetwln.3 \
flopen.3 \
fmtcheck.3 \
fparseln.3 \

117
man/fgetwln.3 Normal file
View File

@ -0,0 +1,117 @@
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
.Dd July 16, 2004
.Dt FGETWLN 3
.Os
.Sh NAME
.Nm fgetwln
.Nd get a line of wide characters from a stream
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.Lb libbsd
.Sh SYNOPSIS
.In stdio.h
.In bsd/wchar.h
.Ft wchar_t *
.Fn fgetwln "FILE * restrict stream" "size_t * restrict len"
.Sh DESCRIPTION
The
.Fn fgetwln
function
returns a pointer to the next line from the stream referenced by
.Fa stream .
This line is
.Em not
a standard wide character string as it does not end with a terminating
null wide character.
The length of the line, including the final newline,
is stored in the memory location to which
.Fa len
points.
(Note, however, that if the line is the last
in a file that does not end in a newline,
the returned text will not contain a newline.)
.Sh RETURN VALUES
Upon successful completion a pointer is returned;
this pointer becomes invalid after the next
.Tn I/O
operation on
.Fa stream
(whether successful or not)
or as soon as the stream is closed.
Otherwise,
.Dv NULL
is returned.
The
.Fn fgetwln
function
does not distinguish between end-of-file and error; the routines
.Xr feof 3
and
.Xr ferror 3
must be used
to determine which occurred.
If an error occurs, the global variable
.Va errno
is set to indicate the error.
The end-of-file condition is remembered, even on a terminal, and all
subsequent attempts to read will return
.Dv NULL
until the condition is
cleared with
.Xr clearerr 3 .
.Pp
The text to which the returned pointer points may be modified,
provided that no changes are made beyond the returned size.
These changes are lost as soon as the pointer becomes invalid.
.Sh ERRORS
.Bl -tag -width Er
.It Bq Er EBADF
The argument
.Fa stream
is not a stream open for reading.
.El
.Pp
The
.Fn fgetwln
function
may also fail and set
.Va errno
for any of the errors specified for the routines
.Xr mbrtowc 3 ,
.Xr realloc 3 ,
or
.Xr read 2 .
.Sh SEE ALSO
.Xr ferror 3 ,
.Xr fgetln 3 ,
.Xr fgetws 3 ,
.Xr fopen 3

View File

@ -43,6 +43,7 @@ libbsd_la_SOURCES = \
err.c \
expand_number.c \
fgetln.c \
fgetwln.c \
flopen.c \
fmtcheck.c \
fparseln.c \

87
src/fgetwln.c Normal file
View File

@ -0,0 +1,87 @@
/*
* Copyright © 2012 Guillem Jover <guillem@hadrons.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
struct filewbuf {
FILE *fp;
wchar_t *wbuf;
size_t len;
};
#define FILEWBUF_INIT_LEN 128
#define FILEWBUF_POOL_ITEMS 32
static struct filewbuf fb_pool[FILEWBUF_POOL_ITEMS];
static int fb_pool_cur;
wchar_t *
fgetwln(FILE *stream, size_t *lenp)
{
struct filewbuf *fb;
wint_t wc;
size_t wused = 0;
/* Try to diminish the possibility of several fgetwln() calls being
* used on different streams, by using a pool of buffers per file. */
fb = &fb_pool[fb_pool_cur];
if (fb->fp != stream && fb->fp != NULL) {
fb_pool_cur++;
fb_pool_cur %= FILEWBUF_POOL_ITEMS;
fb = &fb_pool[fb_pool_cur];
}
fb->fp = stream;
while ((wc = fgetwc(stream)) != WEOF) {
if (!fb->len || wused > fb->len) {
wchar_t *wp;
if (fb->len)
fb->len *= 2;
else
fb->len = FILEWBUF_INIT_LEN;
wp = realloc(fb->wbuf, fb->len * sizeof(wchar_t));
if (wp == NULL) {
wused = 0;
break;
}
fb->wbuf = wp;
}
fb->wbuf[wused++] = wc;
if (wc == L'\n')
break;
}
*lenp = wused;
return wused ? fb->wbuf : NULL;
}

View File

@ -96,6 +96,7 @@ LIBBSD_0.4 {
} LIBBSD_0.3;
LIBBSD_0.5 {
fgetwln;
fparseln;
strnstr;