]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/build/cross-build/fgetwln_fallback.c
Update to bmake-20200902
[FreeBSD/FreeBSD.git] / tools / build / cross-build / fgetwln_fallback.c
1 /*
2  * Copyright 2012 Guillem Jover <guillem@hadrons.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
18  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <wchar.h>
32
33 #include "local-link.h"
34
35 struct filewbuf {
36         FILE *fp;
37         wchar_t *wbuf;
38         size_t len;
39 };
40
41 #define FILEWBUF_INIT_LEN       128
42 #define FILEWBUF_POOL_ITEMS     32
43
44 static struct filewbuf fb_pool[FILEWBUF_POOL_ITEMS];
45 static int fb_pool_cur;
46
47 wchar_t *
48 fgetwln(FILE *stream, size_t *lenp)
49 {
50         struct filewbuf *fb;
51         wint_t wc;
52         size_t wused = 0;
53
54         /* Try to diminish the possibility of several fgetwln() calls being
55          * used on different streams, by using a pool of buffers per file. */
56         fb = &fb_pool[fb_pool_cur];
57         if (fb->fp != stream && fb->fp != NULL) {
58                 fb_pool_cur++;
59                 fb_pool_cur %= FILEWBUF_POOL_ITEMS;
60                 fb = &fb_pool[fb_pool_cur];
61         }
62         fb->fp = stream;
63
64         while ((wc = fgetwc(stream)) != WEOF) {
65                 if (!fb->len || wused >= fb->len) {
66                         wchar_t *wp;
67
68                         if (fb->len)
69                                 fb->len *= 2;
70                         else
71                                 fb->len = FILEWBUF_INIT_LEN;
72
73                         wp = reallocarray(fb->wbuf, fb->len, sizeof(wchar_t));
74                         if (wp == NULL) {
75                                 wused = 0;
76                                 break;
77                         }
78                         fb->wbuf = wp;
79                 }
80
81                 fb->wbuf[wused++] = wc;
82
83                 if (wc == L'\n')
84                         break;
85         }
86
87         *lenp = wused;
88         return wused ? fb->wbuf : NULL;
89 }
90
91 libbsd_link_warning(fgetwln,
92                     "This function cannot be safely ported, use fgetwc(3) "
93                     "instead, as it is supported by C99 and POSIX.1-2001.")