diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-03-30 20:34:21 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-03-30 20:34:21 +0000 |
commit | 144c447139eb6739d67c01a446bf00826316f624 (patch) | |
tree | 41746a15608e2c1f504b17a4fa94b96f0251c4b5 /nuttx/lib/stdio | |
parent | 16eaa06941bbeb6c8fb1131bf631dfc6cb77452b (diff) | |
download | px4-nuttx-144c447139eb6739d67c01a446bf00826316f624.tar.gz px4-nuttx-144c447139eb6739d67c01a446bf00826316f624.tar.bz2 px4-nuttx-144c447139eb6739d67c01a446bf00826316f624.zip |
Move stdio.h functions in lib/ to lib/stdio
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3440 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/lib/stdio')
49 files changed, 8862 insertions, 0 deletions
diff --git a/nuttx/lib/stdio/Make.defs b/nuttx/lib/stdio/Make.defs new file mode 100644 index 000000000..9478369f3 --- /dev/null +++ b/nuttx/lib/stdio/Make.defs @@ -0,0 +1,56 @@ +############################################################################ +# lib/stdio/Make.defs +# +# Copyright (C) 2011 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt <spudmonkey@racsa.co.cr> +# +# 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 NuttX 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 COPYRIGHT HOLDERS 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 +# COPYRIGHT OWNER 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. +# +############################################################################ + +STDIO_SRCS = lib_fileno.c lib_printf.c lib_rawprintf.c lib_lowprintf.c \ + lib_sprintf.c lib_snprintf.c lib_libsprintf.c lib_vsprintf.c \ + lib_vsnprintf.c lib_libvsprintf.c lib_meminstream.c \ + lib_memoutstream.c lib_lowinstream.c lib_lowoutstream.c \ + lib_zeroinstream.c lib_nullinstream.c lib_nulloutstream.c \ + lib_sscanf.c + +ifneq ($(CONFIG_NFILE_DESCRIPTORS),0) +STDIO_SRCS += lib_rawinstream.c lib_rawoutstream.c +ifneq ($(CONFIG_NFILE_STREAMS),0) +STDIO_SRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c \ + lib_ftell.c lib_fsetpos.c lib_fgetpos.c lib_fgetc.c lib_fgets.c \ + lib_gets.c lib_fwrite.c lib_libfwrite.c lib_fflush.c \ + lib_libflushall.c lib_libfflush.c lib_rdflush.c lib_wrflush.c \ + lib_fputc.c lib_puts.c lib_fputs.c lib_ungetc.c lib_vprintf.c \ + lib_fprintf.c lib_vfprintf.c lib_stdinstream.c lib_stdoutstream.c +endif +endif +ifeq ($(CONFIG_LIBC_FLOATINGPOINT),y) +STDIO_SRCS += lib_dtoa.c +endif diff --git a/nuttx/lib/stdio/lib_dtoa.c b/nuttx/lib/stdio/lib_dtoa.c new file mode 100755 index 000000000..942ed2033 --- /dev/null +++ b/nuttx/lib/stdio/lib_dtoa.c @@ -0,0 +1,1536 @@ +/**************************************************************************** + * lib/stdio/lib_dtoa.c + * + * This file was ported to NuttX by Yolande Cates. + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef Unsigned_Shifts +# define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; +#else +# define Sign_Extend(a,b) /* no-op */ +#endif + +#ifdef CONFIG_ENDIAN_BIG +# define word0(x) ((uint32_t *)&x)[0] +# define word1(x) ((uint32_t *)&x)[1] +#else +# define word0(x) ((uint32_t *)&x)[1] +# define word1(x) ((uint32_t *)&x)[0] +#endif + +#ifdef CONFIG_ENDIAN_BIG +# define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ + ((unsigned short *)a)[1] = (unsigned short)c, a++) +#else +# define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ + ((unsigned short *)a)[0] = (unsigned short)c, a++) +#endif + +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define IEEE_Arith +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ + +#define Kmax 15 + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ + y->wds*sizeof(long) + 2*sizeof(int)) + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct Bigint +{ + struct Bigint *next; + int k, maxwds, sign, wds; + unsigned long x[1]; +}; + +typedef struct Bigint Bigint; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static Bigint *freelist[Kmax + 1]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static Bigint *Balloc(int k) +{ + int x; + Bigint *rv; + + if ((rv = freelist[k])) + { + freelist[k] = rv->next; + } + else + { + x = 1 << k; + rv = (Bigint *) malloc(sizeof(Bigint) + (x - 1) * sizeof(long)); + rv->k = k; + rv->maxwds = x; + } + rv->sign = rv->wds = 0; + return rv; +} + +static void Bfree(Bigint * v) +{ + if (v) + { + v->next = freelist[v->k]; + freelist[v->k] = v; + } +} + +/* multiply by m and add a */ + +static Bigint *multadd(Bigint * b, int m, int a) +{ + int i, wds; + unsigned long *x, y; +#ifdef Pack_32 + unsigned long xi, z; +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + do + { +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + a; + z = (xi >> 16) * m + (y >> 16); + a = (int)(z >> 16); + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + a; + a = (int)(y >> 16); + *x++ = y & 0xffff; +#endif + } + while (++i < wds); + if (a) + { + if (wds >= b->maxwds) + { + b1 = Balloc(b->k + 1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = a; + b->wds = wds; + } + return b; +} + +static int hi0bits(unsigned long x) +{ + int k = 0; + + if (!(x & 0xffff0000)) + { + k = 16; + x <<= 16; + } + + if (!(x & 0xff000000)) + { + k += 8; + x <<= 8; + } + + if (!(x & 0xf0000000)) + { + k += 4; + x <<= 4; + } + + if (!(x & 0xc0000000)) + { + k += 2; + x <<= 2; + } + + if (!(x & 0x80000000)) + { + k++; + if (!(x & 0x40000000)) + { + return 32; + } + } + return k; +} + +static int lo0bits(unsigned long *y) +{ + int k; + unsigned long x = *y; + + if (x & 7) + { + if (x & 1) + { + return 0; + } + if (x & 2) + { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + + k = 0; + if (!(x & 0xffff)) + { + k = 16; + x >>= 16; + } + + if (!(x & 0xff)) + { + k += 8; + x >>= 8; + } + + if (!(x & 0xf)) + { + k += 4; + x >>= 4; + } + + if (!(x & 0x3)) + { + k += 2; + x >>= 2; + } + + if (!(x & 1)) + { + k++; + x >>= 1; + if (!x & 1) + { + return 32; + } + } + *y = x; + return k; +} + +static Bigint *i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} + +static Bigint *mult(Bigint * a, Bigint * b) +{ + Bigint *c; + int k, wa, wb, wc; + unsigned long carry, y, z; + unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0; +#ifdef Pack_32 + uint32_t z2; +#endif + + if (a->wds < b->wds) + { + c = a; + a = b; + b = c; + } + + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + { + k++; + } + c = Balloc(k); + for (x = c->x, xa = x + wc; x < xa; x++) + { + *x = 0; + } + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef Pack_32 + for (; xb < xbe; xb++, xc0++) + { + if ((y = *xb & 0xffff)) + { + x = xa; + xc = xc0; + carry = 0; + do + { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while (x < xae); + *xc = carry; + } + if ((y = *xb >> 16)) + { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do + { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while (x < xae); + *xc = z2; + } + } +#else + for (; xb < xbe; xc0++) + { + if ((y = *xb++)) + { + x = xa; + xc = xc0; + carry = 0; + do + { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while (x < xae); + *xc = carry; + } + } +#endif + for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc); + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint *pow5mult(Bigint * b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) + b = multadd(b, p05[i - 1], 0); + + if (!(k >>= 2)) + { + return b; + } + + if (!(p5 = p5s)) + { + /* first time */ + p5 = p5s = i2b(625); + p5->next = 0; + } + + for (;;) + { + if (k & 1) + { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + { + break; + } + + if (!(p51 = p5->next)) + { + p51 = p5->next = mult(p5, p5); + p51->next = 0; + } + p5 = p51; + } + return b; +} + +static Bigint *lshift(Bigint * b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + unsigned long *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for (i = b->maxwds; n1 > i; i <<= 1) + { + k1++; + } + b1 = Balloc(k1); + x1 = b1->x; + for (i = 0; i < n; i++) + { + *x1++ = 0; + } + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) + { + k1 = 32 - k; + z = 0; + do + { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while (x < xe); + if ((*x1 = z)) + { + ++n1; + } + } +#else + if (k &= 0xf) + { + k1 = 16 - k; + z = 0; + do + { + *x1++ = ((*x << k) & 0xffff) | z; + z = *x++ >> k1; + } + while (x < xe); + if ((*x1 = z)) + { + ++n1; + } + } +#endif + else + do + { + *x1++ = *x++; + } + while (x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int cmp(Bigint * a, Bigint * b) +{ + unsigned long *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef CONFIG_DEBUG_LIB + if (i > 1 && !a->x[i - 1]) + { + ldbg("cmp called with a->x[a->wds-1] == 0\n"); + } + if (j > 1 && !b->x[j - 1]) + { + ldbg("cmp called with b->x[b->wds-1] == 0\n"); + } +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for (;;) + { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +static Bigint *diff(Bigint * a, Bigint * b) +{ + Bigint *c; + int i, wa, wb; + long borrow, y; /* We need signed shifts here. */ + unsigned long *xa, *xae, *xb, *xbe, *xc; +#ifdef Pack_32 + int32_t z; +#endif + + i = cmp(a, b); + if (!i) + { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) + { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef Pack_32 + do + { + y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } + while (xb < xbe); + while (xa < xae) + { + y = (*xa & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } +#else + do + { + y = *xa++ - *xb++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } + while (xb < xbe); + while (xa < xae) + { + y = *xa++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } +#endif + while (!*--xc) + wa--; + c->wds = wa; + return c; +} + +static Bigint *d2b(double d, int *e, int *bits) +{ + Bigint *b; + int de, i, k; + unsigned long *x, y, z; + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = word0(d) & Frac_mask; + word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */ + if ((de = (int)(word0(d) >> Exp_shift))) + z |= Exp_msk1; +#ifdef Pack_32 + if ((y = word1(d))) + { + if ((k = lo0bits(&y))) + { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = b->wds = (x[1] = z) ? 2 : 1; + } + else + { +#ifdef CONFIG_DEBUG_LIB + if (!z) + { + ldbg("Zero passed to d2b\n"); + } +#endif + k = lo0bits(&z); + x[0] = z; + i = b->wds = 1; + k += 32; + } +#else + if ((y = word1(d))) + { + if ((k = lo0bits(&y))) + if (k >= 16) + { + x[0] = y | ((z << (32 - k)) & 0xffff); + x[1] = z >> (k - 16) & 0xffff; + x[2] = z >> k; + i = 2; + } + else + { + x[0] = y & 0xffff; + x[1] = (y >> 16) | ((z << (16 - k)) & 0xffff); + x[2] = z >> k & 0xffff; + x[3] = z >> (k + 16); + i = 3; + } + else + { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else + { +#ifdef CONFIG_DEBUG_LIB + if (!z) + { + ldbg("Zero passed to d2b\n"); + } +#endif + k = lo0bits(&z); + if (k >= 16) + { + x[0] = z; + i = 0; + } + else + { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while (!x[i]) + --i; + b->wds = i + 1; +#endif + if (de) + { + *e = de - Bias - (P - 1) + k; + *bits = P - k; + } + else + { + *e = de - Bias - (P - 1) + 1 + k; +#ifdef Pack_32 + *bits = 32 * i - hi0bits(x[i - 1]); +#else + *bits = (i + 2) * 16 - hi0bits(x[i]); +#endif + } + return b; +} + +static const double tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +}; + +#ifdef IEEE_Arith +static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; + +# define n_bigtens 5 +#else +static const double bigtens[] = { 1e16, 1e32 }; +static const double tinytens[] = { 1e-16, 1e-32 }; + +# define n_bigtens 2 +#endif + +static int quorem(Bigint * b, Bigint * S) +{ + int n; + long borrow, y; + unsigned long carry, q, ys; + unsigned long *bx, *bxe, *sx, *sxe; +#ifdef Pack_32 + int32_t z; + uint32_t si, zs; +#endif + + n = S->wds; +#ifdef CONFIG_DEBUG_LIB + if (b->wds > n) + { + ldbg("oversize b in quorem\n"); + } +#endif + if (b->wds < n) + { + return 0; + } + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef CONFIG_DEBUG_LIB + if (q > 9) + { + ldbg("oversized quotient in quorem\n"); + } +#endif + if (q) + { + borrow = 0; + carry = 0; + do + { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while (sx <= sxe); + if (!*bxe) + { + bx = b->x; + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) + { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do + { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while (sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) + { + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the int32_t + * calculation. + */ + +char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) +{ + /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; + * trailing zeros are suppressed from the returned string. If not null, *rve + * is set to point to the end of the return value. If d is +-Infinity or + * NaN, then *decpt is set to 9999. + * + * mode: 0 ==> shortest string that yields d when read in and rounded to + * nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with + * IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives + * 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives + * a return value similar to that of ecvt, except that trailing zeros are + * suppressed. 3 ==> through ndigits past the decimal point. This gives a + * return value similar to that from fcvt, except that trailing zeros are + * suppressed, and ndigits can be negative. 4-9 should give the same return + * values as 2-3, i.e., 4 <= mode <= 9 ==> same return as mode 2 + (mode & + * 1). These modes are mainly for debugging; often they run slower but + * sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right digit + * generation. 6-9 ==> don't try fast floating-point estimate (if + * applicable). + * + * Values of mode other than 0-9 are treated as mode 0. + * + * Sufficient space is allocated to the return value to hold the suppressed + * trailing zeros. */ + + int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, + j, j_1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case = 0, try_quick; + long L; + int denorm; + unsigned long x; + Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S; + double d2, ds, eps; + char *s, *s0; + static Bigint *result; + static int result_k; + + if (result) + { + result->k = result_k; + result->maxwds = 1 << result_k; + Bfree(result); + result = 0; + } + + if (word0(d) & Sign_bit) + { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) +# ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; + s = +#ifdef IEEE_Arith + !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : +#endif + "NaN"; + if (rve) + *rve = +#ifdef IEEE_Arith + s[3] ? s + 8 : +#endif + s + 3; + return s; + } +#endif + if (!d) + { + *decpt = 1; + s = "0"; + if (rve) + *rve = s + 1; + return s; + } + + b = d2b(d, &be, &bbits); + if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) + { + d2 = d; + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 log10(x) = log(x) / log(10) ~=~ + * log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) log10(d) = + * (i-Bias)*log(2)/log(10) + log10(d2) This suggests computing an + * approximation k to log10(d) by k = (i - Bias)*0.301029995663981 + ( + * (d2-1.5)*0.289529654602168 + 0.176091259055681 ); We want k to be too + * large rather than too small. The error in the first-order Taylor + * series approximation is in our favor, so we just round up the constant + * enough to compensate for any error in the multiplication of (i - Bias) + * by 0.301029995663981; since |i - Bias| <= 1077, and 1077 * 0.30103 * + * 2^-52 ~=~ 7.2e-14, adding 1e-13 to the constant term more than + * suffices. Hence we adjust the constant term to 0.1760912590558. (We + * could get a more accurate k by invoking log10, but this is probably + * not worthwhile.) */ + + i -= Bias; + denorm = 0; + } + else + { + /* d is denormalized */ + + i = bbits + be + (Bias + (P - 1) - 1); + x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) + : word1(d) << (32 - i); + d2 = x; + word0(d2) -= 31 * Exp_msk1; /* adjust exponent */ + i -= (Bias + (P - 1) - 1) + 1; + denorm = 1; + } + ds = (d2 - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) + { + if (d < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) + { + b2 = 0; + s2 = j; + } + else + { + b2 = -j; + s2 = 0; + } + if (k >= 0) + { + b5 = 0; + s5 = k; + s2 += k; + } + else + { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) + { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch (mode) + { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + j = sizeof(unsigned long); + for (result_k = 0; (signed)(sizeof(Bigint) - sizeof(unsigned long) + j) <= i; + j <<= 1) + result_k++; + result = Balloc(result_k); + s = s0 = (char *)result; + + if (ilim >= 0 && ilim <= Quick_max && try_quick) + { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = d; + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) + { + ds = tens[k & 0xf]; + j = k >> 4; + if (j & Bletch) + { + /* prevent overflows */ + j &= Bletch - 1; + d /= bigtens[n_bigtens - 1]; + ieps++; + } + for (; j; j >>= 1, i++) + if (j & 1) + { + ieps++; + ds *= bigtens[i]; + } + d /= ds; + } + else if ((j_1 = -k)) + { + d *= tens[j_1 & 0xf]; + for (j = j_1 >> 4; j; j >>= 1, i++) + if (j & 1) + { + ieps++; + d *= bigtens[i]; + } + } + if (k_check && d < 1. && ilim > 0) + { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + d *= 10.; + ieps++; + } + eps = ieps * d + 7.; + word0(eps) -= (P - 1) * Exp_msk1; + if (ilim == 0) + { + S = mhi = 0; + d -= 5.; + if (d > eps) + goto one_digit; + if (d < -eps) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) + { + /* Use Steele & White method of only generating digits needed. */ + eps = 0.5 / tens[ilim - 1] - eps; + for (i = 0;;) + { + L = (int)d; + d -= L; + *s++ = '0' + (int)L; + if (d < eps) + goto ret1; + if (1. - d < eps) + goto bump_up; + if (++i >= ilim) + break; + eps *= 10.; + d *= 10.; + } + } + else + { +#endif + /* Generate ilim digits, then fix them up. */ + eps *= tens[ilim - 1]; + for (i = 1;; i++, d *= 10.) + { + L = (int)d; + d -= L; + *s++ = '0' + (int)L; + if (i == ilim) + { + if (d > 0.5 + eps) + goto bump_up; + else if (d < 0.5 - eps) + { + while (*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + d = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) + { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) + { + S = mhi = 0; + if (ilim < 0 || d <= 5 * ds) + goto no_digits; + goto one_digit; + } + for (i = 1;; i++) + { + L = (int)(d / ds); + d -= L * ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (d < 0) + { + L--; + d += ds; + } +#endif + *s++ = '0' + (int)L; + if (i == ilim) + { + d += d; + if (d > ds || (d == ds && (L & 1))) + { + bump_up: + while (*--s == '9') + if (s == s0) + { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + if (!(d *= 10.)) + break; + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) + { + if (mode < 2) + { + i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits; + } + else + { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else + { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) + { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) + { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) + { + if (leftright) + { + if (m5 > 0) + { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5)) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + if (mode < 2) + { + if (!word1(d) && !(word0(d) & Bndry_mask) && word0(d) & Exp_mask) + { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + else + spec_case = 0; + } + + /* + * Arrange for convenient computation of quotients: shift left if + * necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once and for all + * and pass them and a shift to quorem, so it can do shifts and ors + * to compute the numerator for q. + */ +#ifdef Pack_32 + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0x1f)) + i = 32 - i; +#else + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0xf)) + i = 16 - i; +#endif + if (i > 4) + { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) + { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) + { + if (cmp(b, S) < 0) + { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) + { + if (ilim < 0 || cmp(b, S = multadd(S, 5, 0)) <= 0) + { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) + { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case that d is a normalized power of + * 2. */ + + mlo = mhi; + if (spec_case) + { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for (i = 1;; i++) + { + dig = quorem(b, S) + '0'; + /* Do we yet have the shortest decimal string that will round to d? */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j_1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j_1 == 0 && !mode && !(word1(d) & 1)) + { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && !mode +#ifndef ROUND_BIASED + && (!(word1(d) & 1)) +#endif + )) + { + if ((j_1 > 0)) + { + b = lshift(b, 1); + j_1 = cmp(b, S); + if ((j_1 > 0 || (j_1 == 0 && (dig & 1))) && dig++ == '9') + goto round_9_up; + } + *s++ = dig; + goto ret; + } + if (j_1 > 0) + { + if (dig == '9') + { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else + { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for (i = 1;; i++) + { + *s++ = dig = quorem(b, S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || (j == 0 && (dig & 1))) + { + roundoff: + while (*--s == '9') + if (s == s0) + { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else + { + while (*--s == '0'); + s++; + } +ret: + Bfree(S); + if (mhi) + { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } +ret1: + Bfree(b); + if (s == s0) + { /* don't return empty string */ + *s++ = '0'; + k = 0; + } + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; +} diff --git a/nuttx/lib/stdio/lib_fclose.c b/nuttx/lib/stdio/lib_fclose.c new file mode 100644 index 000000000..4a9ded90b --- /dev/null +++ b/nuttx/lib/stdio/lib_fclose.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * lib/stdio/lib_fclose.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +int fclose(FAR FILE *stream) +{ + int ret = OK; + if (stream) + { + if (stream->fs_filedes > 0) + { + ret = close(stream->fs_filedes); + } + +#if CONFIG_STDIO_BUFFER_SIZE > 0 + /* Destroy the semaphore */ + + sem_destroy(&stream->fs_sem); + + /* release the buffer */ + + if (stream->fs_bufstart) + { + free(stream->fs_bufstart); + } + + /* Clear the whole structure */ + + memset(stream, 0, sizeof(FILE)); +#else +#if CONFIG_NUNGET_CHARS > 0 + /* Reset the number of ungetc characters */ + + stream->fs_nungotten = 0; +#endif + /* Reset the flags */ + + stream->fs_oflags = 0; +#endif + /* Setting the fs_filedescriptor to -1 makes the stream available for reuse */ + + stream->fs_filedes = -1; + } + + return ret; +} + diff --git a/nuttx/lib/stdio/lib_fflush.c b/nuttx/lib/stdio/lib_fflush.c new file mode 100644 index 000000000..c77ab686a --- /dev/null +++ b/nuttx/lib/stdio/lib_fflush.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * lib/stdio/lib_fflush.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdbool.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> + +#include <nuttx/fs.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fflush + * + * Description: + * The function fflush() forces a write of all user-space buffered data for + * the given output or update stream via the stream's underlying write + * function. The open status of the stream is unaffected. + * + * If the stream argument is NULL, fflush() flushes all open output streams. + * + * Return: + * OK on success EOF on failure (with errno set appropriately) + * + ****************************************************************************/ + +int fflush(FAR FILE *stream) +{ + /* Is the stream argument NULL? */ + + if (!stream) + { + /* Yes... then this is a request to flush all streams */ + + return lib_flushall(sched_getstreams()); + } + else if (lib_fflush(stream, true) != 0) + { + /* An error occurred during the flush AND/OR we were unable to flush all + * of the buffered write data. Return EOF on failure. + */ + + return EOF; + } + return OK; +} + diff --git a/nuttx/lib/stdio/lib_fgetc.c b/nuttx/lib/stdio/lib_fgetc.c new file mode 100644 index 000000000..58a199724 --- /dev/null +++ b/nuttx/lib/stdio/lib_fgetc.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * lib/stdio/lib_fgetc.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/************************************************************************** + * Global Constant Data + **************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/************************************************************************** + * Private Constant Data + **************************************************************************/ + +/**************************************************************************** + * Private Variables + **************************************************************************/ + +/**************************************************************************** + * Global Functions + **************************************************************************/ + +/**************************************************************************** + * fgetc + **************************************************************************/ + +int fgetc(FAR FILE *stream) +{ + unsigned char c; + if (lib_fread(&c, 1, stream) > 0) + { + return c; + } + else + { + return EOF; + } +} diff --git a/nuttx/lib/stdio/lib_fgetpos.c b/nuttx/lib/stdio/lib_fgetpos.c new file mode 100644 index 000000000..a641db481 --- /dev/null +++ b/nuttx/lib/stdio/lib_fgetpos.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * lib/stdio/lib_fgetpos.c + * + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fgetpos + * + * Description: + * fgetpos() function is an alternate interfaces equivalent to ftell(). + * It gets the current value of the file offset and store it in the location + * referenced by pos. On some non-UNIX systems an fpos_t object may be a + * complex object and fsetpos may be the only way to portably reposition a + * stream. + * + * Returned Value: + * Zero on succes; -1 on failure with errno set appropriately. + * + ****************************************************************************/ + +int fgetpos(FAR FILE *stream, FAR fpos_t *pos) +{ + long position; + +#if CONFIG_DEBUG + if (!stream || !pos) + { + errno = EINVAL; + return ERROR; + } +#endif + + position = ftell(stream); + if (position == -1) + { + return ERROR; + } + + *pos = (fpos_t)position; + return OK; +} diff --git a/nuttx/lib/stdio/lib_fgets.c b/nuttx/lib/stdio/lib_fgets.c new file mode 100644 index 000000000..3f72f0000 --- /dev/null +++ b/nuttx/lib/stdio/lib_fgets.c @@ -0,0 +1,340 @@ +/**************************************************************************** + * lib/stdio/lib_fgets.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdbool.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <debug.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/* In some systems, the underlying serial logic may + * automatically echo characters back to the console. We + * will assume that that is not the case here + */ + +#define CONFIG_FGETS_ECHO 1 + +/* Some environments may return CR as end-of-line, others LF, and + * others both. The logic here assumes either but not both. + */ + +#undef CONFIG_EOL_IS_CR +#undef CONFIG_EOL_IS_LF +#undef CONFIG_EOL_IS_BOTH_CRLF +#define CONFIG_EOL_IS_EITHER_CRLF 1 + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* <esc>[K is the VT100 command erases to the end of the line. */ + +static const char g_erasetoeol[] = "\033[K"; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _lib_rawgetc + ****************************************************************************/ + +static inline int _lib_rawgetc(int fd) +{ + char buffer; + if (read(fd, &buffer, 1) < 1) + { + /* Return EOF if the end of file (0) or error (-1) occurs */ + + return EOF; + } + return (int)buffer; +} + +/**************************************************************************** + * Name: _lib_consoleputc + ****************************************************************************/ + +#ifdef CONFIG_FGETS_ECHO +static inline void _lib_consoleputc(int ch) +{ + char buffer = ch; + (void)write(1, &buffer, 1); +} +#endif + +/**************************************************************************** + * Name: _lib_consoleputs + ****************************************************************************/ + +#ifdef CONFIG_FGETS_ECHO +static inline void _lib_consoleputs(FAR const char *str) +{ + (void)write(1, str, strlen(str)); +} +#endif + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fgets + * + * Description: + * fgets() reads in at most one less than 'buflen' characters + * from stream and stores them into the buffer pointed to + * by 'buf'. Reading stops after an EOF or a newline. If a + * newline is read, it is stored into the buffer. A null + * terminator is stored after the last character in the + * buffer. + * + * Assumptions: + * If the stream corresponds to stdin (fd=0) this version + * will assume that we are reading characters from a + * VT100 console and that stdout (fd=1) is also available. + * This will not work well if fd=0 corresponds to a raw + * byte steam. + * + **************************************************************************/ + +char *fgets(FAR char *buf, int buflen, FILE *stream) +{ +#ifdef CONFIG_FGETS_ECHO + bool console; +#endif + int escape = 0; + int nch = 0; + + /* Sanity checks */ + + if (!stream || !buf || buflen < 1 || stream->fs_filedes < 0) + { + return NULL; + } + + if (buflen < 2) + { + *buf = '\0'; + return buf; + } + + /* Check if the stream is stdin */ + +#ifdef CONFIG_FGETS_ECHO + console = (stream->fs_filedes == 0); + + /* <esc>[K is the VT100 command that erases to the end of the line. */ + + if (console) + { + _lib_consoleputs(g_erasetoeol); + } +#endif + + /* Read characters until we have a full line. On each + * the loop we must be assured that there are two free bytes + * in the line buffer: One for the next character and one for + * the null terminator. + */ + + for(;;) + { + /* Get the next character */ + + int ch = _lib_rawgetc(stream->fs_filedes); + + /* Are we processing a VT100 escape sequence */ + + if (escape) + { + /* Yes, is it an <esc>[, 3 byte sequence */ + + if (ch != 0x5b || escape == 2) + { + /* We are finished with the escape sequence */ + + escape = 0; + ch = 'a'; + } + else + { + /* The next character is the end of a 3-byte sequence. + * NOTE: Some of the <esc>[ sequences are longer than + * 3-bytes, but I have not encountered any in normal use + * yet and, so, have not provided the decoding logic. + */ + + escape = 2; + } + } + + /* Check for backspace */ + + else if (ch == 0x08) + { + /* Eliminate that last character in the buffer. */ + + if (nch > 0) + { + nch--; + +#ifdef CONFIG_FGETS_ECHO + if (console) + { + /* Echo the backspace character on the console */ + + _lib_consoleputc(ch); + _lib_consoleputs(g_erasetoeol); + } +#endif + } + } + + /* Check for the beginning of a VT100 escape sequence */ + + else if (console && ch == 0x1b) + { + /* The next character is escaped */ + + escape = 1; + } + + /* Check for end-of-line. This is tricky only in that some + * environments may return CR as end-of-line, others LF, and + * others both. + */ + +#if defined(CONFIG_EOL_IS_LF) || defined(CONFIG_EOL_IS_BOTH_CRLF) + else if (ch == '\n') +#elif defined(CONFIG_EOL_IS_CR) + else if (ch == '\r') +#elif CONFIG_EOL_IS_EITHER_CRLF + else if (ch == '\n' || ch == '\r') +#endif + { + /* The newline is stored in the buffer along + * with the null terminator. + */ + + buf[nch++] = '\n'; + buf[nch] = '\0'; + +#ifdef CONFIG_FGETS_ECHO + if (console) + { + /* Echo the newline to the console */ + + _lib_consoleputc('\n'); + } +#endif + return buf; + } + + /* Check for end-of-file */ + + else if (ch == EOF) + { + /* End of file with no data? */ + + if (!nch) + { + /* Yes.. return NULL as the end of file mark */ + + return NULL; + } + else + { + /* Terminate the line */ + + buf[nch] = '\0'; + return buf; + } + } + + /* Otherwise, check if the character is printable and, + * if so, put the character in the line buffer + */ + + else if (isprint(ch)) + { + buf[nch++] = ch; + +#ifdef CONFIG_FGETS_ECHO + if (console) + { + /* Echo the character to the console */ + + _lib_consoleputc(ch); + } +#endif + /* Check if there is room for another character + * and the line's null terminator. If not then + * we have to end the line now. + */ + + if (nch + 1 >= buflen) + { + buf[nch] = '\0'; + return buf; + } + } + } + +} + diff --git a/nuttx/lib/stdio/lib_fileno.c b/nuttx/lib/stdio/lib_fileno.c new file mode 100644 index 000000000..2fe3d9c99 --- /dev/null +++ b/nuttx/lib/stdio/lib_fileno.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * lib/stdio/lib_fileno.c + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <errno.h> + +#include <nuttx/fs.h> + +#if CONFIG_NFILE_STREAMS > 0 + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +int fileno(FAR FILE *stream) +{ + int ret = -1; + if (stream) + { + ret = stream->fs_filedes; + } + + if (ret < 0) + { + errno = EBADF; + return ERROR; + } + return ret; +} +#endif /* CONFIG_NFILE_STREAMS */ + diff --git a/nuttx/lib/stdio/lib_fopen.c b/nuttx/lib/stdio/lib_fopen.c new file mode 100644 index 000000000..07437161c --- /dev/null +++ b/nuttx/lib/stdio/lib_fopen.c @@ -0,0 +1,284 @@ +/**************************************************************************** + * lib/stdio/lib_fopen.c + * + * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_mode2oflags + ****************************************************************************/ + +static int lib_mode2oflags(FAR const char *mode) +{ + int oflags = 0; + if (mode) + { + while(*mode) + { + switch (*mode) + { + /* Open for read access */ + + case 'r' : + if (*(mode + 1) == '+') + { + /* Open for read/write access */ + oflags |= O_RDWR; + mode++; + } + else + { + /* Open for read access */ + oflags |= O_RDOK; + } + break; + + /* Open for write access? */ + + case 'w' : + if (*(mode + 1) == '+') + { + /* Open for write read/access, truncating any existing file */ + oflags |= O_RDWR|O_CREAT|O_TRUNC; + mode++; + } + else + { + /* Open for write access, truncating any existing file */ + oflags |= O_WROK|O_CREAT|O_TRUNC; + } + break; + + /* Open for write/append access? */ + + case 'a' : + if (*(mode + 1) == '+') + { + /* Read from the beginning of the file; write to the end */ + oflags |= O_RDWR|O_CREAT; + mode++; + } + else + { + /* Write to the end of the file */ + oflags |= O_WROK|O_CREAT; + } + break; + + /* Open for binary access? */ + + case 'b' : + default: + break; + } + mode++; + } + } + return oflags; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_fdopen + ****************************************************************************/ + +FAR struct file_struct *lib_fdopen(int fd, FAR const char *mode, + FAR struct filelist *flist, + FAR struct streamlist *slist) +{ + FAR struct inode *inode; + FAR FILE *stream; + int oflags = lib_mode2oflags(mode); + int err = OK; + int i; + + /* Check input parameters */ + + if (fd < 0 || !flist || !slist) + { + err = EBADF; + goto errout; + } + + /* Get the inode associated with the file descriptor. This should + * normally be the case if fd >= 0. But not in the case where the + * called attempts to explictly stdin with fdopen(0) but stdin has + * been closed. + */ + + inode = flist->fl_files[fd].f_inode; + if (!inode) + { + err = ENOENT; + goto errout; + } + + /* Make sure that the inode supports the requested access. In + * the case of fdopen, we are not actually creating the file -- in + * particular w and w+ do not truncate the file and any files have + * already been created. + */ + + if (inode_checkflags(inode, oflags) != OK) + { + err = EACCES; + goto errout; + } + + /* Find an unallocated FILE structure */ + + stream_semtake(slist); + for (i = 0 ; i < CONFIG_NFILE_STREAMS; i++) + { + stream = &slist->sl_streams[i]; + if (stream->fs_filedes < 0) + { + /* Zero the structure */ +#if CONFIG_STDIO_BUFFER_SIZE > 0 + memset(stream, 0, sizeof(FILE)); +#elif CONFIG_NUNGET_CHARS > 0 + stream->fs_nungotten = 0; +#endif + +#if CONFIG_STDIO_BUFFER_SIZE > 0 + /* Initialize the semaphore the manages access to the buffer */ + + (void)sem_init(&stream->fs_sem, 0, 1); + + /* Allocate the IO buffer */ + + stream->fs_bufstart = malloc(CONFIG_STDIO_BUFFER_SIZE); + if (!stream) + { + err = ENOMEM; + goto errout_with_sem; + } + + /* Set up pointers */ + + stream->fs_bufend = &stream->fs_bufstart[CONFIG_STDIO_BUFFER_SIZE]; + stream->fs_bufpos = stream->fs_bufstart; + stream->fs_bufpos = stream->fs_bufstart; + stream->fs_bufread = stream->fs_bufstart; +#endif + /* Save the file description and open flags. Setting the + * file descriptor locks this stream. + */ + + stream->fs_filedes = fd; + stream->fs_oflags = oflags; + + stream_semgive(slist); + return stream; + } + } + +#if CONFIG_STDIO_BUFFER_SIZE > 0 +errout_with_sem: +#endif + stream_semgive(slist); + +errout: + *get_errno_ptr() = err; + return NULL; +} + +/**************************************************************************** + * Name: fdopen + ****************************************************************************/ + +FAR FILE *fdopen(int fd, FAR const char *mode) +{ + FAR struct filelist *flist = sched_getfiles(); + FAR struct streamlist *slist = sched_getstreams(); + return lib_fdopen(fd, mode, flist, slist); +} + +/**************************************************************************** + * Name: fopen + ****************************************************************************/ + +FAR FILE *fopen(FAR const char *path, FAR const char *mode) +{ + FAR FILE *ret = NULL;; + int oflags; + int fd; + + /* Open the file */ + + oflags = lib_mode2oflags(mode); + fd = open(path, oflags, 0666); + + /* If the open was successful, then fdopen() the fil using the file + * desciptor returned by open. If open failed, then just return the + * NULL stream -- open() has already set the errno. + */ + + if (fd >= 0) + { + FAR struct filelist *flist = sched_getfiles(); + FAR struct streamlist *slist = sched_getstreams(); + + ret = lib_fdopen(fd, mode, flist, slist); + if (!ret) + { + /* Don't forget to close the file descriptor if any other + * failures are reported by fdopen(). + */ + + (void)close(fd); + } + } + return ret; +} diff --git a/nuttx/lib/stdio/lib_fprintf.c b/nuttx/lib/stdio/lib_fprintf.c new file mode 100644 index 000000000..4ebb3d7d2 --- /dev/null +++ b/nuttx/lib/stdio/lib_fprintf.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * lib/stdio/lib_fprintf.c + * + * Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fprintf + ****************************************************************************/ + +int fprintf(FAR FILE *stream, FAR const char *fmt, ...) +{ + va_list ap; + int n; + + /* vfprintf into the stream */ + + va_start(ap, fmt); + n = vfprintf(stream, fmt, ap); + va_end(ap); + return n; +} diff --git a/nuttx/lib/stdio/lib_fputc.c b/nuttx/lib/stdio/lib_fputc.c new file mode 100644 index 000000000..f5eeecea7 --- /dev/null +++ b/nuttx/lib/stdio/lib_fputc.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * lib/stdio/lib_fputc.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fputc + ****************************************************************************/ + +int fputc(int c, FAR FILE *stream) +{ + unsigned char buf = (unsigned char)c; + if (lib_fwrite(&buf, 1, stream) > 0) + { + return c; + } + else + { + return EOF; + } +} diff --git a/nuttx/lib/stdio/lib_fputs.c b/nuttx/lib/stdio/lib_fputs.c new file mode 100644 index 000000000..870c5c42e --- /dev/null +++ b/nuttx/lib/stdio/lib_fputs.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * lib/stdio/lib_fputs.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fputs + ****************************************************************************/ + +/* fputs() writes the string s to stream, without its + * trailing '\0'. + */ + +int fputs(FAR const char *s, FAR FILE *stream) +{ + int ntowrite; + int nwritten; + int nput = EOF; + + /* Make sure that a string was provided. */ + + if (!s) + { + *get_errno_ptr() = EINVAL; + } + else + { + /* Get the length of the string. */ + + ntowrite = strlen(s); + if (ntowrite == 0) + { + nput = 0; + } + else + { + /* Write the string */ + + nwritten = lib_fwrite(s, ntowrite, stream); + if (nwritten > 0) + { + nput = nwritten; + } + } + } + return nput; +} diff --git a/nuttx/lib/stdio/lib_fread.c b/nuttx/lib/stdio/lib_fread.c new file mode 100644 index 000000000..cc652fab7 --- /dev/null +++ b/nuttx/lib/stdio/lib_fread.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * lib/stdio/lib_fread.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fread + ****************************************************************************/ + +size_t fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream) +{ + size_t full_size = n_items * (size_t)size; + ssize_t bytes_read; + size_t items_read = 0; + + /* Write the data into the stream buffer */ + + bytes_read = lib_fread(ptr, full_size, stream); + if (bytes_read > 0) + { + /* Return the number of full items read */ + + items_read = bytes_read / size; + } + return items_read; +} + + diff --git a/nuttx/lib/stdio/lib_fseek.c b/nuttx/lib/stdio/lib_fseek.c new file mode 100644 index 000000000..e56645ab6 --- /dev/null +++ b/nuttx/lib/stdio/lib_fseek.c @@ -0,0 +1,138 @@ +/**************************************************************************** + * lib/stdio/lib_fseek.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fseek + * + * Description: + * The fseek() function sets the file position indicator for the stream + * pointed to by stream. The new position, measured in bytes, is obtained + * by adding offset bytes to the position specified by whence. If whence is + * set to SEEK_SET, SEEK_CUR, or SEEK_END, the offset is relative to the + * start of the file, the current position indicator, or end-of-file, + * respectively. A successful call to the fseek() function clears the + * end-of-file indicator for the stream and undoes any effects of the ungetc(3) + * function on the same stream. + * + * Returned Value: + * Zero on succes; -1 on failure with errno set appropriately. + * + ****************************************************************************/ + +int fseek(FAR FILE *stream, long int offset, int whence) +{ + #if CONFIG_STDIO_BUFFER_SIZE > 0 + /* Flush any valid read/write data in the buffer (also verifies stream) */ + + if (lib_rdflush(stream) < 0 || lib_wrflush(stream) < 0) + { + return ERROR; + } +#else + /* Verify that we were provided with a stream */ + + if (!stream) + { + errno = EBADF; + return ERROR; + } +#endif + + /* On success or failure, discard any characters saved by ungetc() */ + +#if CONFIG_NUNGET_CHARS > 0 + stream->fs_nungotten = 0; +#endif + + /* Perform the fseek on the underlying file descriptor */ + + return lseek(stream->fs_filedes, offset, whence) == (off_t)-1 ? ERROR : OK; +} + + diff --git a/nuttx/lib/stdio/lib_fsetpos.c b/nuttx/lib/stdio/lib_fsetpos.c new file mode 100644 index 000000000..637c627b5 --- /dev/null +++ b/nuttx/lib/stdio/lib_fsetpos.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * lib/stdio/lib_fsetpos.c + * + * Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fsetpos + * + * Description: + * fsetpos() function is an alternate interfaces equivalent to fseek() + * (with whence set to SEEK_SET). It sets the current value of the file + * offset to value in the location referenced by pos. On some non-UNIX + * systems an fpos_t object may be a complex object and fsetpos may be the + * only way to portably reposition a stream. + * + * Returned Value: + * Zero on succes; -1 on failure with errno set appropriately. + * + ****************************************************************************/ + +int fsetpos(FAR FILE *stream, FAR fpos_t *pos) +{ +#if CONFIG_DEBUG + if (!stream || !pos) + { + errno = EINVAL; + return ERROR; + } +#endif + + return fseek(stream, (FAR off_t)*pos, SEEK_SET); +} diff --git a/nuttx/lib/stdio/lib_ftell.c b/nuttx/lib/stdio/lib_ftell.c new file mode 100644 index 000000000..b0b0a78e5 --- /dev/null +++ b/nuttx/lib/stdio/lib_ftell.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * lib/stdio/lib_ftell.c + * + * Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ftell + * + * Description: + * ftell() returns the current value of the file position indicator for the + * stream pointed to by stream. + * + * Returned Value: + * Zero on succes; -1 on failure with errno set appropriately. + * + ****************************************************************************/ + +long ftell(FAR FILE *stream) +{ + off_t position; + + /* Verify that we were provided with a stream */ + + if (!stream) + { + errno = EBADF; + return ERROR; + } + + /* Perform the lseek to the current position. This will not move the + * file pointer, but will return its current setting + */ + + position = lseek(stream->fs_filedes, 0, SEEK_CUR); + if (position != (off_t)-1) + { + return (long)position; + } + else + { + return ERROR; + } +} + + diff --git a/nuttx/lib/stdio/lib_fwrite.c b/nuttx/lib/stdio/lib_fwrite.c new file mode 100644 index 000000000..1b7be2ce5 --- /dev/null +++ b/nuttx/lib/stdio/lib_fwrite.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * lib/stdio/lib_fwrite.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fwrite + ****************************************************************************/ + +size_t fwrite(FAR const void *ptr, size_t size, size_t n_items, FAR FILE *stream) +{ + size_t full_size = n_items * (size_t)size; + ssize_t bytes_written; + size_t items_written = 0; + + /* Write the data into the stream buffer */ + + bytes_written = lib_fwrite(ptr, full_size, stream); + if (bytes_written > 0) + { + /* Return the number of full items written */ + + items_written = bytes_written / size; + } + return items_written; +} diff --git a/nuttx/lib/stdio/lib_gets.c b/nuttx/lib/stdio/lib_gets.c new file mode 100644 index 000000000..33ae48aaa --- /dev/null +++ b/nuttx/lib/stdio/lib_gets.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * lib/stdio/lib_gets.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <limits.h> +#include <string.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gets + * + * Description: + * gets() reads a line from stdin into the buffer pointed + * to by s until either a terminating newline or EOF, + * which it replaces with '\0'. No check for buffer + * overrun is performed + * + * This API should not be used because it is inherently + * unsafe. Consider using fgets which is safer and + * slightly more efficient. + * + **************************************************************************/ + +FAR char *gets(FAR char *s) +{ + /* gets is ALMOST the same as fgets using stdin and no + * lenght limit (hence, the unsafeness of gets). So let + * fgets do most of the work. + */ + + FAR char *ret = fgets(s, INT_MAX, stdin); + if (ret) + { + /* Another subtle difference from fgets is that gets + * replaces end-of-line markers with null terminators. + * We will do that as a second step (with some loss + * in performance). + */ + + int len = strlen(ret); + if (len > 0 && ret[len-1] == '\n') + { + ret[len-1] = '\0'; + } + } + return ret; +} + diff --git a/nuttx/lib/stdio/lib_libfflush.c b/nuttx/lib/stdio/lib_libfflush.c new file mode 100644 index 000000000..68a1bc39f --- /dev/null +++ b/nuttx/lib/stdio/lib_libfflush.c @@ -0,0 +1,196 @@ +/**************************************************************************** + * lib/stdio/lib_libfflush.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdbool.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include <nuttx/fs.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_fflush + * + * Description: + * The function lib_fflush() forces a write of all user-space buffered data for + * the given output or update stream via the stream's underlying write + * function. The open status of the stream is unaffected. + * + * Parmeters: + * stream - the stream to flush + * bforce - flush must be complete. + * + * Return: + * ERROR on failure, otherwise the number of bytes remaining in the buffer. + * If bforce is set, then only the values ERROR and 0 will be returned. + * + ****************************************************************************/ + +ssize_t lib_fflush(FAR FILE *stream, bool bforce) +{ +#if CONFIG_STDIO_BUFFER_SIZE > 0 + FAR const unsigned char *src; + ssize_t bytes_written; + size_t nbuffer; + + /* Return EBADF if the file is not opened for writing */ + + if (stream->fs_filedes < 0 || (stream->fs_oflags & O_WROK) == 0) + { + *get_errno_ptr() = EBADF; + return ERROR; + } + + /* Make sure that we have exclusive access to the stream */ + + lib_take_semaphore(stream); + + /* Make sure tht the buffer holds valid data */ + + if (stream->fs_bufpos != stream->fs_bufstart) + { + /* Make sure that the buffer holds buffered write data. We do not + * support concurrent read/write buffer usage. + */ + + if (stream->fs_bufread != stream->fs_bufstart) + { + /* The buffer holds read data... just return zero */ + + return 0; + } + + /* How many bytes of write data are used in the buffer now */ + + nbuffer = stream->fs_bufpos - stream->fs_bufstart; + + /* Try to write that amount */ + + src = stream->fs_bufstart; + do + { + /* Perform the write */ + + bytes_written = write(stream->fs_filedes, src, nbuffer); + if (bytes_written < 0) + { + lib_give_semaphore(stream); + return ERROR; + } + + /* Handle partial writes. fflush() must either return with + * an error condition or with the data successfully flushed + * from the buffer. + */ + + src += bytes_written; + nbuffer -= bytes_written; + } + while (bforce && nbuffer > 0); + + /* Reset the buffer position to the beginning of the buffer */ + + stream->fs_bufpos = stream->fs_bufstart; + + /* For the case of an incomplete write, nbuffer will be non-zero + * It will hold the number of bytes that were not written. + * Move the data down in the buffer to handle this (rare) case + */ + + while (nbuffer) + { + *stream->fs_bufpos++ = *src++; + --nbuffer; + } + } + + /* Restore normal access to the stream and return the number of bytes + * remaining in the buffer. + */ + + lib_give_semaphore(stream); + return stream->fs_bufpos - stream->fs_bufstart; +#else + /* Return no bytes remaining in the buffer */ + + return 0; +#endif +} + diff --git a/nuttx/lib/stdio/lib_libflushall.c b/nuttx/lib/stdio/lib_libflushall.c new file mode 100644 index 000000000..de2853df8 --- /dev/null +++ b/nuttx/lib/stdio/lib_libflushall.c @@ -0,0 +1,136 @@ +/**************************************************************************** + * lib/stdio/lib_libflushall.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdbool.h> +#include <fcntl.h> +#include <errno.h> + +#include <nuttx/fs.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_flushall + * + * Description: + * Called either (1) by the OS when a task exits, or (2) from fflush() + * when a NULL stream argument is provided. + * + ****************************************************************************/ + +int lib_flushall(FAR struct streamlist *list) +{ + int lasterrno = OK; + int ret = OK; + + /* Make sure that there are streams associated with this thread */ + + if (list) + { + int i; + + /* Process each stream in the thread's stream list */ + + stream_semtake(list); + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + FILE *stream = &list->sl_streams[i]; + + /* If the stream is open (i.e., assigned a non-negative file + * descriptor) and opened for writing, then flush all of the pending + * write data in the stream. + */ + + if (stream->fs_filedes >= 0 && (stream->fs_oflags & O_WROK) != 0) + { + /* Flush the writable FILE */ + + if (lib_fflush(stream, true) != 0) + { + /* An error occurred during the flush AND/OR we were unable + * to flush all of the buffered write data. Return EOF on failure. + */ + + lasterrno = *get_errno_ptr(); + ret = ERROR; + } + } + } + stream_semgive(list); + } + + /* If any flush failed, return that last failed flush */ + + *get_errno_ptr() = lasterrno; + return ret; +} diff --git a/nuttx/lib/stdio/lib_libfread.c b/nuttx/lib/stdio/lib_libfread.c new file mode 100644 index 000000000..abeb34deb --- /dev/null +++ b/nuttx/lib/stdio/lib_libfread.c @@ -0,0 +1,271 @@ +/**************************************************************************** + * lib/stdio/lib_libfread.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> /* for CONFIG_STDIO_BUFFER_SIZE */ + +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_fread + ****************************************************************************/ + +ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream) +{ + unsigned char *dest = (unsigned char*)ptr; + ssize_t bytes_read; + + /* Make sure that reading from this stream is allowed */ + + if (!stream || (stream->fs_oflags & O_RDOK) == 0) + { + *get_errno_ptr() = EBADF; + bytes_read = -1; + } + else + { + /* The stream must be stable until we complete the read */ + + lib_take_semaphore(stream); + +#if CONFIG_NUNGET_CHARS > 0 + /* First, re-read any previously ungotten characters */ + + while ((stream->fs_nungotten > 0) && (count > 0)) + { + /* Decrement the count of ungotten bytes to get an index */ + + stream->fs_nungotten--; + + /* Return the last ungotten byte */ + + *dest++ = stream->fs_ungotten[stream->fs_nungotten]; + + /* That's one less byte that we have to read */ + + count--; + } +#endif + +#if CONFIG_STDIO_BUFFER_SIZE > 0 + /* If the buffer is currently being used for write access, then + * flush all of the buffered write data. We do not support concurrent + * buffered read/write access. + */ + + if (lib_wrflush(stream) != 0) + { + return ERROR; + } + + /* Now get any other needed chars from the buffer or the file. */ + + while (count > 0) + { + /* Is there readable data in the buffer? */ + + while ((count > 0) && (stream->fs_bufpos < stream->fs_bufread)) + { + /* Yes, copy a byte into the user buffer */ + + *dest++ = *stream->fs_bufpos++; + count--; + } + + /* The buffer is empty OR we have already supplied the number of + * bytes requested in the read. Check if we need to read + * more from the file. + */ + + if (count > 0) + { + size_t buffer_available; + + /* We need to read more data into the buffer from the file */ + + /* Mark the buffer empty */ + + stream->fs_bufpos = stream->fs_bufread = stream->fs_bufstart; + + /* How much space is available in the buffer? */ + + buffer_available = stream->fs_bufend - stream->fs_bufread; + + /* Will the number of bytes that we need to read fit into + * the buffer space that is available? If the read size is + * larger than the buffer, then read some of the data + * directly into the user's buffer. + */ + + if (count > buffer_available) + { + bytes_read = read(stream->fs_filedes, dest, count); + if (bytes_read < 0) + { + /* An error occurred on the read */ + + goto err_out; + } + else if (bytes_read == 0) + { + /* We are at the end of the file */ + + goto short_read; + } + else + { + /* Some bytes were read. Adjust the dest pointer */ + + dest += bytes_read; + + /* Were all of the requested bytes read? */ + + if (bytes_read < count) + { + /* No. We must be at the end of file. */ + + goto short_read; + } + else + { + /* Yes. We are done. */ + + count = 0; + } + } + } + else + { + /* The number of bytes required to satisfy the read + * is less than or equal to the size of the buffer + * space that we have left. Read as much as we can + * into the buffer. + */ + + bytes_read = read(stream->fs_filedes, stream->fs_bufread, buffer_available); + if (bytes_read < 0) + { + /* An error occurred on the read */ + + goto err_out; + } + else if (bytes_read == 0) + { + /* We are at the end of the file */ + + goto short_read; + } + else + { + /* Some bytes were read */ + + stream->fs_bufread += bytes_read; + } + } + } + } +#else + /* Now get any other needed chars from the file. */ + + while (count > 0) + { + bytes_read = read(stream->fs_filedes, dest, count); + if (bytes_read < 0) + { + goto err_out; + } + else if (bytes_read == 0) + { + break; + } + else + { + dest += bytes_read; + count -= bytes_read; + } + } +#endif +#if CONFIG_STDIO_BUFFER_SIZE > 0 + short_read: +#endif + bytes_read = dest - (unsigned char*)ptr; + err_out: + lib_give_semaphore(stream); + } + return bytes_read; +} + diff --git a/nuttx/lib/stdio/lib_libfwrite.c b/nuttx/lib/stdio/lib_libfwrite.c new file mode 100644 index 000000000..3b7253cdd --- /dev/null +++ b/nuttx/lib/stdio/lib_libfwrite.c @@ -0,0 +1,179 @@ +/**************************************************************************** + * lib/stdio/lib_libfwrite.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> /* for CONFIG_STDIO_BUFFER_SIZE */ + +#include <sys/types.h> +#include <stdbool.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_fwrite + ****************************************************************************/ + +ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream) +#if CONFIG_STDIO_BUFFER_SIZE > 0 +{ + FAR const unsigned char *start = ptr; + FAR const unsigned char *src = ptr; + ssize_t ret = ERROR; + unsigned char *dest; + + /* Make sure that writing to this stream is allowed */ + + if (!stream || (stream->fs_oflags & O_WROK) == 0) + { + *get_errno_ptr() = EBADF; + goto errout; + } + + /* Get exclusive access to the stream */ + + lib_take_semaphore(stream); + + /* If the buffer is currently being used for read access, then + * discard all of the read-ahead data. We do not support concurrent + * buffered read/write access. + */ + + if (lib_rdflush(stream) < 0) + { + goto errout_with_semaphore; + } + + /* Loop until all of the bytes have been buffered */ + + while (count > 0) + { + /* Determine the number of bytes left in the buffer */ + + size_t gulp_size = stream->fs_bufend - stream->fs_bufpos; + + /* Will the user data fit into the amount of buffer space + * that we have left? + */ + + if (gulp_size > count) + { + /* Yes, clip the gulp to the size of the user data */ + + gulp_size = count; + } + + /* Adjust the number of bytes remaining to be transferred + * on the next pass through the loop (might be zero). + */ + + count -= gulp_size; + + /* Transfer the data into the buffer */ + + for (dest = stream->fs_bufpos; gulp_size > 0; gulp_size--) + { + *dest++ = *src++; + } + stream->fs_bufpos = dest; + + /* Is the buffer full? */ + + if (dest >= stream->fs_bufend) + { + /* Flush the buffered data to the IO stream */ + + int bytes_buffered = lib_fflush(stream, false); + if (bytes_buffered < 0) + { + goto errout_with_semaphore; + } + } + } + + /* Return the number of bytes written */ + + ret = src - start; + +errout_with_semaphore: + lib_give_semaphore(stream); + +errout: + return ret; +} +#else +{ + return write(stream->fs_filedes, ptr, count); +} +#endif /* CONFIG_STDIO_BUFFER_SIZE */ + diff --git a/nuttx/lib/stdio/lib_libsprintf.c b/nuttx/lib/stdio/lib_libsprintf.c new file mode 100644 index 000000000..04d547754 --- /dev/null +++ b/nuttx/lib/stdio/lib_libsprintf.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * lib/stdio/lib_libsprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_sprintf + ****************************************************************************/ + +int lib_sprintf(FAR struct lib_outstream_s *obj, const char *fmt, ...) +{ + va_list ap; + int n; + + /* Let lib_vsprintf do the real work */ + + va_start(ap, fmt); + n = lib_vsprintf(obj, fmt, ap); + va_end(ap); + return n; +} diff --git a/nuttx/lib/stdio/lib_libvsprintf.c b/nuttx/lib/stdio/lib_libvsprintf.c new file mode 100644 index 000000000..b3b9e41e6 --- /dev/null +++ b/nuttx/lib/stdio/lib_libvsprintf.c @@ -0,0 +1,1485 @@ +/**************************************************************************** + * lib/stdio/lib_libvsprintf.c + * + * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/compiler.h> + +#include <stdint.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor oDefinitions + ****************************************************************************/ + +enum +{ + FMT_RJUST = 0, /* Default */ + FMT_LJUST, + FMT_RJUST0, + FMT_CENTER +}; + +#define FLAG_SHOWPLUS 0x01 +#define FLAG_ALTFORM 0x02 +#define FLAG_HASDOT 0x04 +#define FLAG_HASASTERISKWIDTH 0x08 +#define FLAG_HASASTERISKTRUNC 0x10 +#define FLAG_LONGPRECISION 0x20 +#define FLAG_LONGLONGPRECISION 0x40 +#define FLAG_NEGATE 0x80 + +#define SET_SHOWPLUS(f) do (f) |= FLAG_SHOWPLUS; while (0) +#define SET_ALTFORM(f) do (f) |= FLAG_ALTFORM; while (0) +#define SET_HASDOT(f) do (f) |= FLAG_HASDOT; while (0) +#define SET_HASASTERISKWIDTH(f) do (f) |= FLAG_HASASTERISKWIDTH; while (0) +#define SET_HASASTERISKTRUNC(f) do (f) |= FLAG_HASASTERISKTRUNC; while (0) +#define SET_LONGPRECISION(f) do (f) |= FLAG_LONGPRECISION; while (0) +#define SET_LONGLONGPRECISION(f) do (f) |= FLAG_LONGLONGPRECISION; while (0) +#define SET_NEGATE(f) do (f) |= FLAG_NEGATE; while (0) + +#define CLR_SHOWPLUS(f) do (f) &= ~FLAG_SHOWPLUS; while (0) +#define CLR_ALTFORM(f) do (f) &= ~FLAG_ALTFORM; while (0) +#define CLR_HASDOT(f) do (f) &= ~FLAG_HASDOT; while (0) +#define CLR_HASASTERISKWIDTH(f) do (f) &= ~FLAG_HASASTERISKWIDTH; while (0) +#define CLR_HASASTERISKTRUNC(f) do (f) &= ~FLAG_HASASTERISKTRUNC; while (0) +#define CLR_LONGPRECISION(f) do (f) &= ~FLAG_LONGPRECISION; while (0) +#define CLR_LONGLONGPRECISION(f) do (f) &= ~FLAG_LONGLONGPRECISION; while (0) +#define CLR_NEGATE(f) do (f) &= ~FLAG_NEGATE; while (0) +#define CLR_SIGNED(f) do (f) &= ~(FLAG_SHOWPLUS|FLAG_NEGATE); while (0) + +#define IS_SHOWPLUS(f) (((f) & FLAG_SHOWPLUS) != 0) +#define IS_ALTFORM(f) (((f) & FLAG_ALTFORM) != 0) +#define IS_HASDOT(f) (((f) & FLAG_HASDOT) != 0) +#define IS_HASASTERISKWIDTH(f) (((f) & FLAG_HASASTERISKWIDTH) != 0) +#define IS_HASASTERISKTRUNC(f) (((f) & FLAG_HASASTERISKTRUNC) != 0) +#define IS_LONGPRECISION(f) (((f) & FLAG_LONGPRECISION) != 0) +#define IS_LONGLONGPRECISION(f) (((f) & FLAG_LONGLONGPRECISION) != 0) +#define IS_NEGATE(f) (((f) & FLAG_NEGATE) != 0) +#define IS_SIGNED(f) (((f) & (FLAG_SHOWPLUS|FLAG_NEGATE)) != 0) + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Pointer to ASCII conversion */ + +#ifdef CONFIG_PTR_IS_NOT_INT +static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, FAR void *p); +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static int getsizesize(uint8_t fmt, uint8_t flags, FAR void *p) +#endif /* CONFIG_NOPRINTF_FIELDWIDTH */ +#endif /* CONFIG_PTR_IS_NOT_INT */ + +/* Unsigned int to ASCII conversion */ + +static void utodec(FAR struct lib_outstream_s *obj, unsigned int n); +static void utohex(FAR struct lib_outstream_s *obj, unsigned int n, uint8_t a); +static void utooct(FAR struct lib_outstream_s *obj, unsigned int n); +static void utobin(FAR struct lib_outstream_s *obj, unsigned int n); +static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, unsigned int lln); + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void fixup(uint8_t fmt, FAR uint8_t *flags, int *n); +static int getusize(uint8_t fmt, uint8_t flags, unsigned int lln); +#endif + +/* Unsigned long int to ASCII conversion */ + +#ifdef CONFIG_LONG_IS_NOT_INT +static void lutodec(FAR struct lib_outstream_s *obj, unsigned long ln); +static void lutohex(FAR struct lib_outstream_s *obj, unsigned long ln, uint8_t a); +static void lutooct(FAR struct lib_outstream_s *obj, unsigned long ln); +static void lutobin(FAR struct lib_outstream_s *obj, unsigned long ln); +static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, unsigned long ln); +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void lfixup(uint8_t fmt, FAR uint8_t *flags, long *ln); +static int getlusize(uint8_t fmt, FAR uint8_t flags, unsigned long ln); +#endif +#endif + +/* Unsigned long long int to ASCII conversions */ + +#ifdef CONFIG_HAVE_LONG_LONG +static void llutodec(FAR struct lib_outstream_s *obj, unsigned long long lln); +static void llutohex(FAR struct lib_outstream_s *obj, unsigned long long lln, uint8_t a); +static void llutooct(FAR struct lib_outstream_s *obj, unsigned long long lln); +static void llutobin(FAR struct lib_outstream_s *obj, unsigned long long lln); +static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, unsigned long long lln); +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void llfixup(uint8_t fmt, FAR uint8_t *flags, FAR long long *lln); +static int getllusize(uint8_t fmt, FAR uint8_t flags, FAR unsigned long long lln); +#endif +#endif + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, int fieldwidth, int numwidth); +static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, int fieldwidth, int numwidth); +#endif + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +static const char g_nullstring[] = "(null)"; + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Include floating point functions */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# include "lib_libdtoa.c" +#endif + +/**************************************************************************** + * Name: ptohex + ****************************************************************************/ + +#ifdef CONFIG_PTR_IS_NOT_INT +static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, FAR void *p) +{ + union + { + uint32_t dw; + FAR void *p; + } u; + uint8_t bits; + + /* Check for alternate form */ + + if (IS_ALTFORM(flags)) + { + /* Prefix the number with "0x" */ + + obj->put(obj, '0'); + obj->put(obj, 'x'); + } + + u.dw = 0; + u.p = p; + + for (bits = 8*sizeof(void *); bits > 0; bits -= 4) + { + uint8_t nibble = (uint8_t)((u.dw >> (bits - 4)) & 0xf); + if (nibble < 10) + { + obj->put(obj, nibble + '0'); + } + else + { + obj->put(obj, nibble + 'a' - 10); + } + } +} + +/**************************************************************************** + * Name: getpsize + ****************************************************************************/ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static int getpsize(uint8_t flags, FAR void *p) +{ + struct lib_outstream_s nulloutstream; + lib_nulloutstream(&nulloutstream); + + ptohex(&nulloutstream, flags, p); + return nulloutstream.nput; +} + +#endif /* CONFIG_NOPRINTF_FIELDWIDTH */ +#endif /* CONFIG_PTR_IS_NOT_INT */ + +/**************************************************************************** + * Name: utodec + ****************************************************************************/ + +static void utodec(FAR struct lib_outstream_s *obj, unsigned int n) +{ + unsigned int remainder = n % 10; + unsigned int dividend = n / 10; + + if (dividend) + { + utodec(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: utohex + ****************************************************************************/ + +static void utohex(FAR struct lib_outstream_s *obj, unsigned int n, uint8_t a) +{ + bool nonzero = false; + uint8_t bits; + + for (bits = 8*sizeof(unsigned int); bits > 0; bits -= 4) + { + uint8_t nibble = (uint8_t)((n >> (bits - 4)) & 0xf); + if (nibble || nonzero) + { + nonzero = true; + + if (nibble < 10) + { + obj->put(obj, nibble + '0'); + } + else + { + obj->put(obj, nibble + a - 10); + } + } + } + + if (!nonzero) + { + obj->put(obj, '0'); + } +} + +/**************************************************************************** + * Name: utooct + ****************************************************************************/ + +static void utooct(FAR struct lib_outstream_s *obj, unsigned int n) +{ + unsigned int remainder = n & 0x7; + unsigned int dividend = n >> 3; + + if (dividend) + { + utooct(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: utobin + ****************************************************************************/ + +static void utobin(FAR struct lib_outstream_s *obj, unsigned int n) +{ + unsigned int remainder = n & 1; + unsigned int dividend = n >> 1; + + if (dividend) + { + utobin(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: utoascii + ****************************************************************************/ + +static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned int n) +{ + /* Perform the integer conversion according to the format specifier */ + + switch (fmt) + { + case 'd': + case 'i': + /* Signed base 10 */ + { +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + if ((int)n < 0) + { + obj->put(obj, '-'); + n = (unsigned int)(-(int)n); + } + else if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } +#endif + /* Convert the unsigned value to a string. */ + + utodec(obj, n); + } + break; + + case 'u': + /* Unigned base 10 */ + { +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } +#endif + /* Convert the unsigned value to a string. */ + + utodec(obj, n); + } + break; + +#ifndef CONFIG_PTR_IS_NOT_INT + case 'p': +#endif + case 'x': + case 'X': + /* Hexadecimal */ + { + /* Check for alternate form */ + + if (IS_ALTFORM(flags)) + { + /* Prefix the number with "0x" */ + + obj->put(obj, '0'); + obj->put(obj, 'x'); + } + + /* Convert the unsigned value to a string. */ + + if (fmt == 'X') + { + utohex(obj, n, 'A'); + } + else + { + utohex(obj, n, 'a'); + } + } + break; + + case 'o': + /* Octal */ + { + /* Check for alternate form */ + + if (IS_ALTFORM(flags)) + { + /* Prefix the number with '0' */ + + obj->put(obj, '0'); + } + + /* Convert the unsigned value to a string. */ + + utooct(obj, n); + } + break; + + case 'b': + /* Binary */ + { + /* Convert the unsigned value to a string. */ + + utobin(obj, n); + } + break; + +#ifdef CONFIG_PTR_IS_NOT_INT + case 'p': +#endif + default: + break; + } +} + +/**************************************************************************** + * Name: fixup + ****************************************************************************/ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void fixup(uint8_t fmt, FAR uint8_t *flags, FAR int *n) +{ + /* Perform the integer conversion according to the format specifier */ + + switch (fmt) + { + case 'd': + case 'i': + /* Signed base 10 */ + + if (*n < 0) + { + SET_NEGATE(*flags); + CLR_SHOWPLUS(*flags); + *n = -*n; + } + break; + + case 'u': + /* Unsigned base 10 */ + break; + + case 'p': + case 'x': + case 'X': + /* Hexadecimal */ + case 'o': + /* Octal */ + case 'b': + /* Binary */ + CLR_SIGNED(*flags); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: getusize + ****************************************************************************/ + +static int getusize(uint8_t fmt, uint8_t flags, unsigned int n) +{ + struct lib_outstream_s nulloutstream; + lib_nulloutstream(&nulloutstream); + + utoascii(&nulloutstream, fmt, flags, n); + return nulloutstream.nput; +} +#endif /* CONFIG_NOPRINTF_FIELDWIDTH */ + +#ifdef CONFIG_LONG_IS_NOT_INT +/**************************************************************************** + * Name: lutodec + ****************************************************************************/ + +static void lutodec(FAR struct lib_outstream_s *obj, unsigned long n) +{ + unsigned int remainder = n % 10; + unsigned long dividend = n / 10; + + if (dividend) + { + lutodec(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: lutohex + ****************************************************************************/ + +static void lutohex(FAR struct lib_outstream_s *obj, unsigned long n, uint8_t a) +{ + bool nonzero = false; + uint8_t bits; + + for (bits = 8*sizeof(unsigned long); bits > 0; bits -= 4) + { + uint8_t nibble = (uint8_t)((n >> (bits - 4)) & 0xf); + if (nibble || nonzero) + { + nonzero = true; + + if (nibble < 10) + { + obj->put(obj, nibble + '0'); + } + else + { + obj->put(obj, nibble + a - 10); + } + } + } + + if (!nonzero) + { + obj->put(obj, '0'); + } +} + +/**************************************************************************** + * Name: lutooct + ****************************************************************************/ + +static void lutooct(FAR struct lib_outstream_s *obj, unsigned long n) +{ + unsigned int remainder = n & 0x7; + unsigned long dividend = n >> 3; + + if (dividend) + { + lutooct(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: lutobin + ****************************************************************************/ + +static void lutobin(FAR struct lib_outstream_s *obj, unsigned long n) +{ + unsigned int remainder = n & 1; + unsigned long dividend = n >> 1; + + if (dividend) + { + lutobin(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: lutoascii + ****************************************************************************/ + +static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned long ln) +{ + /* Perform the integer conversion according to the format specifier */ + + switch (fmt) + { + case 'd': + case 'i': + /* Signed base 10 */ + { +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + if ((long)ln < 0) + { + obj->put(obj, '-'); + ln = (unsigned long)(-(long)ln); + } + else if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } +#endif + /* Convert the unsigned value to a string. */ + + lutodec(obj, ln); + } + break; + + case 'u': + /* Unigned base 10 */ + { +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } +#endif + /* Convert the unsigned value to a string. */ + + lutodec(obj, ln); + } + break; + + case 'x': + case 'X': + /* Hexadecimal */ + { + /* Check for alternate form */ + + if (IS_ALTFORM(flags)) + { + /* Prefix the number with "0x" */ + + obj->put(obj, '0'); + obj->put(obj, 'x'); + } + + /* Convert the unsigned value to a string. */ + + if (fmt == 'X') + { + lutohex(obj, ln, 'A'); + } + else + { + lutohex(obj, ln, 'a'); + } + } + break; + + case 'o': + /* Octal */ + { + /* Check for alternate form */ + + if (IS_ALTFORM(flags)) + { + /* Prefix the number with '0' */ + + obj->put(obj, '0'); + } + + /* Convert the unsigned value to a string. */ + + lutooct(obj, ln); + } + break; + + case 'b': + /* Binary */ + { + /* Convert the unsigned value to a string. */ + + lutobin(obj, ln); + } + break; + + case 'p': + default: + break; + } +} + +/**************************************************************************** + * Name: lfixup + ****************************************************************************/ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void lfixup(uint8_t fmt, FAR uint8_t *flags, FAR long *ln) +{ + /* Perform the integer conversion according to the format specifier */ + + switch (fmt) + { + case 'd': + case 'i': + /* Signed base 10 */ + + if (*ln < 0) + { + SET_NEGATE(*flags); + CLR_SHOWPLUS(*flags); + *ln = -*ln; + } + break; + + case 'u': + /* Unsigned base 10 */ + break; + + case 'p': + case 'x': + case 'X': + /* Hexadecimal */ + case 'o': + /* Octal */ + case 'b': + /* Binary */ + CLR_SIGNED(*flags); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: getlusize + ****************************************************************************/ + +static int getlusize(uint8_t fmt, uint8_t flags, unsigned long ln) +{ + struct lib_outstream_s nulloutstream; + lib_nulloutstream(&nulloutstream); + + lutoascii(&nulloutstream, fmt, flags, ln); + return nulloutstream.nput; +} + +#endif /* CONFIG_NOPRINTF_FIELDWIDTH */ +#endif /* CONFIG_LONG_IS_NOT_INT */ + +#ifdef CONFIG_HAVE_LONG_LONG +/**************************************************************************** + * Name: llutodec + ****************************************************************************/ + +static void llutodec(FAR struct lib_outstream_s *obj, unsigned long long n) +{ + unsigned int remainder = n % 10; + unsigned long long dividend = n / 10; + + if (dividend) + { + llutodec(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: llutohex + ****************************************************************************/ + +static void llutohex(FAR struct lib_outstream_s *obj, unsigned long long n, uint8_t a) +{ + bool nonzero = false; + uint8_t bits; + + for (bits = 8*sizeof(unsigned long long); bits > 0; bits -= 4) + { + uint8_t nibble = (uint8_t)((n >> (bits - 4)) & 0xf); + if (nibble || nonzero) + { + nonzero = true; + + if (nibble < 10) + { + obj->put(obj, (nibble + '0')); + } + else + { + obj->put(obj, (nibble + a - 10)); + } + } + } + + if (!nonzero) + { + obj->put(obj, '0'); + } +} + +/**************************************************************************** + * Name: llutooct + ****************************************************************************/ + +static void llutooct(FAR struct lib_outstream_s *obj, unsigned long long n) +{ + unsigned int remainder = n & 0x7; + unsigned long long dividend = n >> 3; + + if (dividend) + { + llutooct(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: llutobin + ****************************************************************************/ + +static void llutobin(FAR struct lib_outstream_s *obj, unsigned long long n) +{ + unsigned int remainder = n & 1; + unsigned long long dividend = n >> 1; + + if (dividend) + { + llutobin(obj, dividend); + } + + obj->put(obj, (remainder + (unsigned int)'0')); +} + +/**************************************************************************** + * Name: llutoascii + ****************************************************************************/ + +static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned long long lln) +{ + /* Perform the integer conversion according to the format specifier */ + + switch (fmt) + { + case 'd': + case 'i': + /* Signed base 10 */ + { +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + if ((long long)lln < 0) + { + obj->put(obj, '-'); + lln = (unsigned long long)(-(long long)lln); + } + else if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } +#endif + /* Convert the unsigned value to a string. */ + + llutodec(obj, (unsigned long long)lln); + } + break; + + case 'u': + /* Unigned base 10 */ + { +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } +#endif + /* Convert the unsigned value to a string. */ + + llutodec(obj, (unsigned long long)lln); + } + break; + + case 'x': + case 'X': + /* Hexadecimal */ + { + /* Check for alternate form */ + + if (IS_ALTFORM(flags)) + { + /* Prefix the number with "0x" */ + + obj->put(obj, '0'); + obj->put(obj, 'x'); + } + + /* Convert the unsigned value to a string. */ + + if (fmt == 'X') + { + llutohex(obj, (unsigned long long)lln, 'A'); + } + else + { + llutohex(obj, (unsigned long long)lln, 'a'); + } + } + break; + + case 'o': + /* Octal */ + { + /* Check for alternate form */ + + if (IS_ALTFORM(flags)) + { + /* Prefix the number with '0' */ + + obj->put(obj, '0'); + } + + /* Convert the unsigned value to a string. */ + + llutooct(obj, (unsigned long long)lln); + } + break; + + case 'b': + /* Binary */ + { + /* Convert the unsigned value to a string. */ + + llutobin(obj, (unsigned long long)lln); + } + break; + + case 'p': + default: + break; + } +} + +/**************************************************************************** + * Name: llfixup + ****************************************************************************/ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void llfixup(uint8_t fmt, FAR uint8_t *flags, FAR long long *lln) +{ + /* Perform the integer conversion according to the format specifier */ + + switch (fmt) + { + case 'd': + case 'i': + /* Signed base 10 */ + + if (*lln < 0) + { + SET_NEGATE(*flags); + CLR_SHOWPLUS(*flags); + *lln = -*lln; + } + break; + + case 'u': + /* Unsigned base 10 */ + break; + + case 'p': + case 'x': + case 'X': + /* Hexadecimal */ + case 'o': + /* Octal */ + case 'b': + /* Binary */ + CLR_SIGNED(*flags); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: getllusize + ****************************************************************************/ + +static int getllusize(uint8_t fmt, uint8_t flags, unsigned long long lln) +{ + struct lib_outstream_s nulloutstream; + lib_nulloutstream(&nulloutstream); + + + llutoascii(&nulloutstream, fmt, flags, lln); + return nulloutstream.nput; +} + +#endif /* CONFIG_NOPRINTF_FIELDWIDTH */ +#endif /* CONFIG_HAVE_LONG_LONG */ + +/**************************************************************************** + * Name: prejustify + ****************************************************************************/ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, int fieldwidth, int numwidth) +{ + int i; + + switch (fmt) + { + default: + case FMT_RJUST: + if (IS_SIGNED(flags)) + { + numwidth++; + } + + for (i = fieldwidth - numwidth; i > 0; i--) + { + obj->put(obj, ' '); + } + + if (IS_NEGATE(flags)) + { + obj->put(obj, '-'); + } + else if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } + break; + + case FMT_RJUST0: + if (IS_NEGATE(flags)) + { + obj->put(obj, '-'); + numwidth++; + } + else if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + numwidth++; + } + + for (i = fieldwidth - numwidth; i > 0; i--) + { + obj->put(obj, '0'); + } + break; + + case FMT_LJUST: + if (IS_NEGATE(flags)) + { + obj->put(obj, '-'); + } + else if (IS_SHOWPLUS(flags)) + { + obj->put(obj, '+'); + } + break; + } +} +#endif + +/**************************************************************************** + * Name: postjustify + ****************************************************************************/ + +#ifndef CONFIG_NOPRINTF_FIELDWIDTH +static void postjustify(FAR struct lib_outstream_s *obj, uint8_t fmt, + uint8_t flags, int fieldwidth, int numwidth) +{ + int i; + + /* Apply field justification to the integer value. */ + + switch (fmt) + { + default: + case FMT_RJUST: + case FMT_RJUST0: + break; + + case FMT_LJUST: + if (IS_SIGNED(flags)) + { + numwidth++; + } + + for (i = fieldwidth - numwidth; i > 0; i--) + { + obj->put(obj, ' '); + } + break; + } +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * lib/stdio/lib_vsprintf + ****************************************************************************/ + +int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap) +{ + char *ptmp; +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + int width; + int trunc; + uint8_t fmt; +#endif + uint8_t flags; + + for (; *src; src++) + { + /* Just copy regular characters */ + + if (*src != '%') + { + obj->put(obj, *src); + continue; + } + + /* We have found a format specifier. Move past it. */ + + src++; + + /* Assume defaults */ + + flags = 0; +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + fmt = FMT_RJUST; + width = 0; + trunc = 0; +#endif + + /* Process each format qualifier. */ + + for (; *src; src++) + { + /* Break out of the loop when the format is known. */ + + if (strchr("diuxXpobeEfgGlLsc%", *src)) + { + break; + } + + /* Check for left justification. */ + + else if (*src == '-') + { +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + fmt = FMT_LJUST; +#endif + } + + /* Check for leading zero fill right justification. */ + + else if (*src == '0') + { +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + fmt = FMT_RJUST0; +#endif + } +#if 0 + /* Center justification. */ + + else if (*src == '~') + { +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + fmt = FMT_CENTER; +#endif + } +#endif + + else if (*src == '*') + { +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + int value = va_arg(ap, int); + if (IS_HASDOT(flags)) + { + trunc = value; + SET_HASASTERISKTRUNC(flags); + } + else + { + width = value; + SET_HASASTERISKWIDTH(flags); + } +#endif + } + + /* Check for field width */ + + else if (*src >= '1' && *src <= '9') + { +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + for (src++; (*src >= '0' && *src <= '9'); src++); +#else + /* Accumulate the field width integer. */ + + int n = ((int)(*src)) - (int)'0'; + for (src++; (*src >= '0' && *src <= '9'); src++) + { + n = 10*n + (((int)(*src)) - (int)'0'); + } + + if (IS_HASDOT(flags)) + { + trunc = n; + } + else + { + width = n; + } +#endif + /* Back up to the last digit. */ + + src--; + } + + /* Check for a decimal point. */ + + else if (*src == '.') + { +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + SET_HASDOT(flags); +#endif + } + + /* Check for leading plus sign. */ + + else if (*src == '+') + { + SET_SHOWPLUS(flags); + } + + /* Check for alternate form. */ + + else if (*src == '#') + { + SET_ALTFORM(flags); + } + } + + /* "%%" means that a literal '%' was intended (instead of a format + * specification). + */ + + if (*src == '%') + { + obj->put(obj, '%'); + continue; + } + + /* Check for the string format. */ + + if (*src == 's') + { + /* Just concatenate the string into the output */ + + ptmp = va_arg(ap, char *); + if (!ptmp) + { + ptmp = (char*)g_nullstring; + } + + while(*ptmp) + { + obj->put(obj, *ptmp); + ptmp++; + } + continue; + } + + /* Check for the character output */ + + else if (*src == 'c') + { + /* Just copy the character into the output. */ + + int n = va_arg(ap, int); + obj->put(obj, n); + continue; + } + + /* Check for the long long prefix. */ + + if (*src == 'L') + { + SET_LONGLONGPRECISION(flags); + ++src; + } + else if (*src == 'l') + { + SET_LONGPRECISION(flags); + if (*++src == 'l') + { + SET_LONGLONGPRECISION(flags); + ++src; + } + } + + /* Handle integer conversions */ + + if (strchr("diuxXpob", *src)) + { +#ifdef CONFIG_HAVE_LONG_LONG + if (IS_LONGLONGPRECISION(flags) && *src != 'p') + { + long long lln; +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + int lluwidth; +#endif + /* Extract the long long value. */ + + lln = va_arg(ap, long long); + +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + /* Output the number */ + + llutoascii(obj, *src, flags, (unsigned long long)lln); +#else + /* Resolve sign-ness and format issues */ + + llfixup(*src, &flags, &lln); + + /* Get the width of the output */ + + lluwidth = getllusize(*src, flags, lln); + + /* Perform left field justification actions */ + + prejustify(obj, fmt, flags, width, lluwidth); + + /* Output the number */ + + llutoascii(obj, *src, flags, (unsigned long long)lln); + + /* Perform right field justification actions */ + + postjustify(obj, fmt, flags, width, lluwidth); +#endif + } + else +#endif /* CONFIG_HAVE_LONG_LONG */ +#ifdef CONFIG_LONG_IS_NOT_INT + if (IS_LONGPRECISION(flags) && *src != 'p') + { + long ln; +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + int luwidth; +#endif + /* Extract the long value. */ + + ln = va_arg(ap, long); + +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + /* Output the number */ + + lutoascii(obj, *src, flags, (unsigned long)ln); +#else + /* Resolve sign-ness and format issues */ + + lfixup(*src, &flags, &ln); + + /* Get the width of the output */ + + luwidth = getlusize(*src, flags, ln); + + /* Perform left field justification actions */ + + prejustify(obj, fmt, flags, width, luwidth); + + /* Output the number */ + + lutoascii(obj, *src, flags, (unsigned long)ln); + + /* Perform right field justification actions */ + + postjustify(obj, fmt, flags, width, luwidth); +#endif + } + else +#endif /* CONFIG_LONG_IS_NOT_INT */ +#ifdef CONFIG_PTR_IS_NOT_INT + if (*src == 'p') + { + void *p; +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + int pwidth; +#endif + /* Extract the integer value. */ + + p = va_arg(ap, void *); + +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + /* Output the pointer value */ + + ptohex(obj, flags, p); +#else + /* Resolve sign-ness and format issues */ + + lfixup(*src, &flags, &ln); + + /* Get the width of the output */ + + luwidth = getpsize(*src, flags, p); + + /* Perform left field justification actions */ + + prejustify(obj, fmt, flags, width, pwidth); + + /* Output the pointer value */ + + ptohex(obj, flags, p); + + /* Perform right field justification actions */ + + postjustify(obj, fmt, flags, width, pwidth); +#endif + } + else +#endif + { + int n; +#ifndef CONFIG_NOPRINTF_FIELDWIDTH + int uwidth; +#endif + /* Extract the long long value. */ + + n = va_arg(ap, int); + +#ifdef CONFIG_NOPRINTF_FIELDWIDTH + /* Output the number */ + + utoascii(obj, *src, flags, (unsigned int)n); +#else + /* Resolve sign-ness and format issues */ + + fixup(*src, &flags, &n); + + /* Get the width of the output */ + + uwidth = getusize(*src, flags, n); + + /* Perform left field justification actions */ + + prejustify(obj, fmt, flags, width, uwidth); + + /* Output the number */ + + utoascii(obj, *src, flags, (unsigned int)n); + + /* Perform right field justification actions */ + + postjustify(obj, fmt, flags, width, uwidth); +#endif + } + } + + /* Handle floating point conversions */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT + else if (strchr("eEfgG", *src)) + { + double dblval = va_arg(ap, double); + lib_dtoa(obj, *src, trunc, flags, dblval); + } +#endif + } + + return obj->nput; +} + diff --git a/nuttx/lib/stdio/lib_lowinstream.c b/nuttx/lib/stdio/lib_lowinstream.c new file mode 100644 index 000000000..85f916acb --- /dev/null +++ b/nuttx/lib/stdio/lib_lowinstream.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * lib/stdio/lib_lowinstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#ifdef CONFIG_ARCH_LOWGETC + +#include <stdio.h> +#include <errno.h> +#include <nuttx/arch.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lowinstream_getc + ****************************************************************************/ + +static int lowinstream_getc(FAR struct lib_outstream_s *this) +{ + if (this && up_getc(ch) != EOF) + { + this->nget++; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_lowinstream + * + * Description: + * Initializes a stream for use with low-level, architecture-specific I/O. + * + * Input parameters: + * lowoutstream - User allocated, uninitialized instance of struct + * lib_lowoutstream_s to be initialized. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_lowinstream(FAR struct lib_outstream_s *stream) +{ + stream->get = lowinstream_getc; + stream->nget = 0; +} + +#endif /* CONFIG_ARCH_LOWGETC */ diff --git a/nuttx/lib/stdio/lib_lowoutstream.c b/nuttx/lib/stdio/lib_lowoutstream.c new file mode 100644 index 000000000..2ab7c9f67 --- /dev/null +++ b/nuttx/lib/stdio/lib_lowoutstream.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * lib/stdio/lib_lowoutstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#ifdef CONFIG_ARCH_LOWPUTC + +#include <stdio.h> +#include <errno.h> +#include <nuttx/arch.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lowoutstream_putc + ****************************************************************************/ + +static void lowoutstream_putc(FAR struct lib_outstream_s *this, int ch) +{ + if (this && up_putc(ch) != EOF) + { + this->nput++; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_lowoutstream + * + * Description: + * Initializes a stream for use with low-level, architecture-specific I/O. + * + * Input parameters: + * lowoutstream - User allocated, uninitialized instance of struct + * lib_lowoutstream_s to be initialized. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_lowoutstream(FAR struct lib_outstream_s *stream) +{ + stream->put = lowoutstream_putc; + stream->nput = 0; +} + +#endif /* CONFIG_ARCH_LOWPUTC */ diff --git a/nuttx/lib/stdio/lib_lowprintf.c b/nuttx/lib/stdio/lib_lowprintf.c new file mode 100644 index 000000000..576402d61 --- /dev/null +++ b/nuttx/lib/stdio/lib_lowprintf.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * lib/stdio/lib_lowprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <stdio.h> +#include <debug.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_lowvprintf + ****************************************************************************/ + +#ifdef CONFIG_ARCH_LOWPUTC + +int lib_lowvprintf(const char *fmt, va_list ap) +{ + struct lib_outstream_s stream; + + /* Wrap the stdout in a stream object and let lib_vsprintf + * do the work. + */ + + lib_lowoutstream((FAR struct lib_outstream_s *)&stream); + return lib_vsprintf((FAR struct lib_outstream_s *)&stream, fmt, ap); +} + +/**************************************************************************** + * Name: lib_lowprintf + ****************************************************************************/ + +int lib_lowprintf(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret= lib_lowvprintf(fmt, ap); + va_end(ap); + return ret; +} + +#endif /* CONFIG_ARCH_LOWPUTC */ diff --git a/nuttx/lib/stdio/lib_meminstream.c b/nuttx/lib/stdio/lib_meminstream.c new file mode 100644 index 000000000..6e1db7c2c --- /dev/null +++ b/nuttx/lib/stdio/lib_meminstream.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * lib/stdio/lib_meminstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: meminstream_getc + ****************************************************************************/ + +static int meminstream_getc(FAR struct lib_instream_s *this) +{ + FAR struct lib_meminstream_s *mthis = (FAR struct lib_meminstream_s *)this; + int ret; + + if (this && this->nget < mthis->buflen - 1) + { + ret = mthis->buffer[this->nget]; + this->nget++; + } + else + { + ret = EOF; + } + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_meminstream + * + * Description: + * Initializes a stream for use with a fixed-size memory buffer. + * + * Input parameters: + * meminstream - User allocated, uninitialized instance of struct + * lib_meminstream_s to be initialized. + * bufstart - Address of the beginning of the fixed-size memory buffer + * buflen - Size of the fixed-sized memory buffer in bytes + * + * Returned Value: + * None (meminstream initialized). + * + ****************************************************************************/ + +void lib_meminstream(FAR struct lib_meminstream_s *meminstream, + FAR const char *bufstart, int buflen) +{ + meminstream->public.get = meminstream_getc; + meminstream->public.nget = 0; /* Will be buffer index */ + meminstream->buffer = bufstart; /* Start of buffer */ + meminstream->buflen = buflen; /* Length of the buffer */ +} + + diff --git a/nuttx/lib/stdio/lib_memoutstream.c b/nuttx/lib/stdio/lib_memoutstream.c new file mode 100644 index 000000000..1cf2a8f29 --- /dev/null +++ b/nuttx/lib/stdio/lib_memoutstream.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * lib/stdio/lib_memoutstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: memoutstream_putc + ****************************************************************************/ + +static void memoutstream_putc(FAR struct lib_outstream_s *this, int ch) +{ + FAR struct lib_memoutstream_s *mthis = (FAR struct lib_memoutstream_s *)this; + if (this && this->nput < mthis->buflen - 1) + { + mthis->buffer[this->nput] = ch; + this->nput++; + mthis->buffer[this->nput] = '\0'; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_memoutstream + * + * Description: + * Initializes a stream for use with a fixed-size memory buffer. + * + * Input parameters: + * memoutstream - User allocated, uninitialized instance of struct + * lib_memoutstream_s to be initialized. + * bufstart - Address of the beginning of the fixed-size memory buffer + * buflen - Size of the fixed-sized memory buffer in bytes + * + * Returned Value: + * None (memoutstream initialized). + * + ****************************************************************************/ + +void lib_memoutstream(FAR struct lib_memoutstream_s *memoutstream, + FAR char *bufstart, int buflen) +{ + memoutstream->public.put = memoutstream_putc; + memoutstream->public.nput = 0; /* Will be buffer index */ + memoutstream->buffer = bufstart; /* Start of buffer */ + memoutstream->buflen = buflen - 1; /* Save space for null terminator */ +} + + diff --git a/nuttx/lib/stdio/lib_nullinstream.c b/nuttx/lib/stdio/lib_nullinstream.c new file mode 100644 index 000000000..271cba396 --- /dev/null +++ b/nuttx/lib/stdio/lib_nullinstream.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * lib/stdio/lib_nullinstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <errno.h> +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int nullinstream_getc(FAR struct lib_instream_s *this) +{ + return EOF; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_nullinstream + * + * Description: + * Initializes a NULL stream. The initialized stream will will return only + * EOF. + * + * Input parameters: + * nullinstream - User allocated, uninitialized instance of struct + * lib_instream_s to be initialized. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_nullinstream(FAR struct lib_instream_s *nullinstream) +{ + nullinstream->get = nullinstream_getc; + nullinstream->nget = 0; +} + diff --git a/nuttx/lib/stdio/lib_nulloutstream.c b/nuttx/lib/stdio/lib_nulloutstream.c new file mode 100644 index 000000000..85b7daa9e --- /dev/null +++ b/nuttx/lib/stdio/lib_nulloutstream.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * lib/stdio/lib_nulloutstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <errno.h> +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void nulloutstream_putc(FAR struct lib_outstream_s *this, int ch) +{ + this->nput++; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_nulloutstream + * + * Description: + * Initializes a NULL streams. The initialized stream will write all data + * to the bit-bucket. + * + * Input parameters: + * nulloutstream - User allocated, uninitialized instance of struct + * lib_outstream_s to be initialized. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_nulloutstream(FAR struct lib_outstream_s *nulloutstream) +{ + nulloutstream->put = nulloutstream_putc; + nulloutstream->nput = 0; +} + diff --git a/nuttx/lib/stdio/lib_printf.c b/nuttx/lib/stdio/lib_printf.c new file mode 100644 index 000000000..d24355f40 --- /dev/null +++ b/nuttx/lib/stdio/lib_printf.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * lib/stdio/lib_printf.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/************************************************************************** + * Global Constant Data + **************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/************************************************************************** + * Private Constant Data + **************************************************************************/ + +/**************************************************************************** + * Private Variables + **************************************************************************/ + +/**************************************************************************** + * Global Functions + **************************************************************************/ + +/**************************************************************************** + * Name: printf + **************************************************************************/ + +int printf(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); +#if CONFIG_NFILE_STREAMS > 0 + ret = vfprintf(stdout, fmt, ap); +#elif CONFIG_NFILE_DESCRIPTORS > 0 + ret = lib_rawvprintf(fmt, ap); +#elif defined(CONFIG_ARCH_LOWPUTC) + ret = lib_lowvprintf(fmt, ap); +#else +# ifdef CONFIG_CPP_HAVE_WARNING +# warning "printf has no data sink" +# endif + ret = 0; +#endif + va_end(ap); + + return ret; +} + diff --git a/nuttx/lib/stdio/lib_puts.c b/nuttx/lib/stdio/lib_puts.c new file mode 100644 index 000000000..5e651c4de --- /dev/null +++ b/nuttx/lib/stdio/lib_puts.c @@ -0,0 +1,115 @@ +/**************************************************************************** + * lib/stdio/lib_puts.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: puts + * + * Description: + * puts() writes the string s and a trailing newline to + * stdout. + ****************************************************************************/ + +int puts(FAR const char *s) +{ + int nwritten; + int nput = EOF; + + /* Write the string (the next two steps must be atomic) */ + + lib_take_semaphore(stdout); + + /* Write the string without its trailing '\0' */ + + nwritten = fputs(s, stdout); + if (nwritten > 0) + { + /* Followed by a newline */ + char newline = '\n'; + if (lib_fwrite(&newline, 1, stdout) > 0) + { + nput = nwritten + 1; + } + } + lib_give_semaphore(stdout); + return nput; +} + diff --git a/nuttx/lib/stdio/lib_rawinstream.c b/nuttx/lib/stdio/lib_rawinstream.c new file mode 100644 index 000000000..b54305ce6 --- /dev/null +++ b/nuttx/lib/stdio/lib_rawinstream.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * lib/stdio/lib_rawinstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <unistd.h> +#include <errno.h> +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rawinstream_getc + ****************************************************************************/ + +static int rawinstream_getc(FAR struct lib_instream_s *this) +{ + FAR struct lib_rawinstream_s *rthis = (FAR struct lib_rawinstream_s *)this; + char ch; + + if (this && rthis->fd >= 0) + { + int nwritten; + do + { + nwritten = read(rthis->fd, &ch, 1); + if (nwritten == 1) + { + this->nget++; + return ch; + } + } + while (nwritten < 0 && errno == EINTR); + } + + return EOF; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_rawinstream + * + * Description: + * Initializes a stream for use with a file descriptor. + * + * Input parameters: + * rawinstream - User allocated, uninitialized instance of struct + * lib_rawinstream_s to be initialized. + * fd - User provided file/socket descriptor (must have been opened + * for the correct access). + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_rawinstream(FAR struct lib_rawinstream_s *rawinstream, int fd) +{ + rawinstream->public.get = rawinstream_getc; + rawinstream->public.nget = 0; + rawinstream->fd = fd; +} + diff --git a/nuttx/lib/stdio/lib_rawoutstream.c b/nuttx/lib/stdio/lib_rawoutstream.c new file mode 100644 index 000000000..bf9a68206 --- /dev/null +++ b/nuttx/lib/stdio/lib_rawoutstream.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * lib/stdio/lib_rawoutstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <unistd.h> +#include <errno.h> +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rawoutstream_putc + ****************************************************************************/ + +static void rawoutstream_putc(FAR struct lib_outstream_s *this, int ch) +{ + FAR struct lib_rawoutstream_s *rthis = (FAR struct lib_rawoutstream_s *)this; + char buffer = ch; + if (this && rthis->fd >= 0) + { + int nwritten; + do + { + nwritten = write(rthis->fd, &buffer, 1); + if (nwritten == 1) + { + this->nput++; + } + } + while (nwritten < 0 && *get_errno_ptr() == EINTR); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_rawoutstream + * + * Description: + * Initializes a stream for use with a file descriptor. + * + * Input parameters: + * rawoutstream - User allocated, uninitialized instance of struct + * lib_rawoutstream_s to be initialized. + * fd - User provided file/socket descriptor (must have been opened + * for write access). + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_rawoutstream(FAR struct lib_rawoutstream_s *rawoutstream, int fd) +{ + rawoutstream->public.put = rawoutstream_putc; + rawoutstream->public.nput = 0; + rawoutstream->fd = fd; +} + diff --git a/nuttx/lib/stdio/lib_rawprintf.c b/nuttx/lib/stdio/lib_rawprintf.c new file mode 100644 index 000000000..915fd833b --- /dev/null +++ b/nuttx/lib/stdio/lib_rawprintf.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * lib/stdio/lib_rawprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <debug.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_rawvprintf + ****************************************************************************/ + +int lib_rawvprintf(const char *fmt, va_list ap) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + + struct lib_rawoutstream_s rawoutstream; + + /* Wrap the stdout in a stream object and let lib_vsprintf + * do the work. + */ + + lib_rawoutstream(&rawoutstream, 1); + return lib_vsprintf(&rawoutstream.public, fmt, ap); + +#elif defined(CONFIG_ARCH_LOWPUTC) + + struct lib_outstream_s stream; + + /* Wrap the low-level output in a stream object and let lib_vsprintf + * do the work. + */ + + lib_lowoutstream((FAR struct lib_outstream_s *)&stream); + return lib_vsprintf((FAR struct lib_outstream_s *)&stream, fmt, ap); + +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: lib_rawprintf + ****************************************************************************/ + +int lib_rawprintf(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret= lib_rawvprintf(fmt, ap); + va_end(ap); + return ret; +} diff --git a/nuttx/lib/stdio/lib_rdflush.c b/nuttx/lib/stdio/lib_rdflush.c new file mode 100644 index 000000000..592cc4183 --- /dev/null +++ b/nuttx/lib/stdio/lib_rdflush.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * lib/stdio/lib_rdflush.c + * + * Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_rdflush + * + * Description: + * Flush read data from the I/O buffer and adjust the file pointer to + * account for the unread data + * + ****************************************************************************/ + +#if CONFIG_STDIO_BUFFER_SIZE > 0 +int lib_rdflush(FAR FILE *stream) +{ + if (!stream) + { + *get_errno_ptr() = EBADF; + return ERROR; + } + + /* Get exclusive access to the stream */ + + lib_take_semaphore(stream); + + /* If the buffer is currently being used for read access, then discard all + * of the read-ahead data. We do not support concurrent buffered read/write + * access. + */ + + if (stream->fs_bufread != stream->fs_bufstart) + { + /* Now adjust the stream pointer to account for the read-ahead data that + * was not actually read by the user. + */ + +#if CONFIG_NUNGET_CHARS > 0 + off_t rdoffset = stream->fs_bufread - stream->fs_bufpos + stream->fs_nungotten; +#else + off_t rdoffset = stream->fs_bufread - stream->fs_bufpos; +#endif + /* Mark the buffer as empty (do this before calling fseek() because fseek() + * also calls this function). + */ + + stream->fs_bufpos = stream->fs_bufread = stream->fs_bufstart; +#if CONFIG_NUNGET_CHARS > 0 + stream->fs_nungotten = 0; +#endif + /* Then seek to the position corresponding to the last data read by the user */ + + if (fseek(stream, -rdoffset, SEEK_CUR) < 0) + { + lib_give_semaphore(stream); + return ERROR; + } + } + + lib_give_semaphore(stream); + return OK; +} +#endif /* CONFIG_STDIO_BUFFER_SIZE */ + diff --git a/nuttx/lib/stdio/lib_snprintf.c b/nuttx/lib/stdio/lib_snprintf.c new file mode 100644 index 000000000..a4dcd399b --- /dev/null +++ b/nuttx/lib/stdio/lib_snprintf.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * lib/stdio/lib_snprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * sprintf + ****************************************************************************/ + +int snprintf(FAR char *buf, size_t size, const char *format, ...) +{ + struct lib_memoutstream_s memoutstream; + va_list ap; + int n; + + /* Initialize a memory stream to write to the buffer */ + + lib_memoutstream((FAR struct lib_memoutstream_s *)&memoutstream, buf, size); + + /* Then let lib_vsprintf do the real work */ + + va_start(ap, format); + n = lib_vsprintf((FAR struct lib_outstream_s *)&memoutstream.public, format, ap); + va_end(ap); + return n; +} diff --git a/nuttx/lib/stdio/lib_sprintf.c b/nuttx/lib/stdio/lib_sprintf.c new file mode 100644 index 000000000..6de019cc5 --- /dev/null +++ b/nuttx/lib/stdio/lib_sprintf.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * lib/stdio/lib_sprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * sprintf + ****************************************************************************/ + +int sprintf (FAR char *buf, const char *fmt, ...) +{ + struct lib_memoutstream_s memoutstream; + va_list ap; + int n; + + /* Initialize a memory stream to write to the buffer */ + + lib_memoutstream((FAR struct lib_memoutstream_s *)&memoutstream, buf, LIB_BUFLEN_UNKNOWN); + + /* Then let lib_vsprintf do the real work */ + + va_start(ap, fmt); + n = lib_vsprintf((FAR struct lib_outstream_s *)&memoutstream.public, fmt, ap); + va_end(ap); + return n; +} diff --git a/nuttx/lib/stdio/lib_sscanf.c b/nuttx/lib/stdio/lib_sscanf.c new file mode 100644 index 000000000..9f2a411a4 --- /dev/null +++ b/nuttx/lib/stdio/lib_sscanf.c @@ -0,0 +1,353 @@ +/**************************************************************************** + * lib/stdio/lib_sscanf.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/compiler.h> +#include <sys/types.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <debug.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#define MAXLN 128 + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +int vsscanf(char *buf, const char *s, va_list ap); + +/************************************************************************** + * Global Constant Data + **************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/************************************************************************** + * Private Constant Data + **************************************************************************/ + +static const char spaces[] = " \t\n\r\f\v"; + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Function: sscanf + * + * Description: + * ANSI standard sscanf implementation. + * + ****************************************************************************/ + +int sscanf(const char *buf, const char *fmt, ...) +{ + va_list ap; + int count; + + va_start(ap, fmt); + count = vsscanf((char*)buf, fmt, ap); + va_end(ap); + return count; + +} /* end sscanf */ + +/**************************************************************************** + * Function: vsscanf + * + * Description: + * ANSI standard vsscanf implementation. + * + ****************************************************************************/ +int vsscanf(char *buf, const char *s, va_list ap) +{ + int count; + int noassign; + int width; + int base = 10; + int lflag; + char *tv; + const char *tc; + char tmp[MAXLN]; + + lvdbg("vsscanf: buf=\"%s\" fmt=\"%s\"\n", buf, s); + + count = noassign = width = lflag = 0; + while (*s && *buf) + { + /* Skip over white space */ + + while (isspace(*s)) + s++; + + /* Check for a conversion specifier */ + + if (*s == '%') + { + lvdbg("vsscanf: Specifier found\n"); + + /* Check for qualifiers on the conversion specifier */ + s++; + for (; *s; s++) + { + lvdbg("vsscanf: Processing %c\n", *s); + + if (strchr("dibouxcsefg%", *s)) + break; + if (*s == '*') + noassign = 1; + else if (*s == 'l' || *s == 'L') + lflag = 1; + else if (*s >= '1' && *s <= '9') { + for (tc = s; isdigit(*s); s++); + strncpy(tmp, tc, s - tc); + tmp[s - tc] = '\0'; + width = atoi(tmp); + /* atob(&width, tmp, 10); */ + s--; + } + } + + /* Process %s: String conversion */ + + if (*s == 's') + { + lvdbg("vsscanf: Performing string conversion\n"); + + while (isspace(*buf)) + buf++; + if (!width) + { + width = strcspn(buf, spaces); + } + if (!noassign) + { + tv = va_arg(ap, char*); + strncpy(tv, buf, width); + tv[width] = '\0'; + } + buf += width; + } + + /* Process %c: Character conversion */ + + else if (*s == 'c') + { + lvdbg("vsscanf: Performing character conversion\n"); + + if (!width) + width = 1; + if (!noassign) + { + tv = va_arg(ap, char*); + strncpy(tv, buf, width); + tv[width] = '\0'; + } + buf += width; + } + + /* Process %d, %o, %b, %x, %u: Various integer conversions */ + + else if (strchr("dobxu", *s)) + { + lvdbg("vsscanf: Performing integer conversion\n"); + + /* Skip over any white space before the integer string */ + + while (isspace(*buf)) + buf++; + + /* The base of the integer conversion depends on the specific + * conversion specification. + */ + + if (*s == 'd' || *s == 'u') + base = 10; + else if (*s == 'x') + base = 16; + else if (*s == 'o') + base = 8; + else if (*s == 'b') + base = 2; + + /* Copy the integer string into a temporary working buffer. */ + + if (!width) + { + if (isspace(*(s + 1)) || *(s + 1) == 0) + { + width = strcspn(buf, spaces); + } + else + { + width = strchr(buf, *(s + 1)) - buf; + } + } + strncpy(tmp, buf, width); + tmp[width] = '\0'; + + lvdbg("vsscanf: tmp[]=\"%s\"\n", tmp); + + /* Perform the integer conversion */ + + buf += width; + if (!noassign) + { + int *pint = va_arg(ap, int*); +#ifdef SDCC + char *endptr; + int tmpint = strtol(tmp, &endptr, base); +#else + int tmpint = strtol(tmp, NULL, base); +#endif + lvdbg("vsscanf: Return %d to 0x%p\n", tmpint, pint); + *pint = tmpint; + } + } + + /* Process %f: Floating point conversion */ + + else if (*s == 'f') + { +#ifndef CONFIG_LIBC_FLOATINGPOINT + /* No floating point conversions */ + + void *pv = va_arg(ap, void*); + + lvdbg("vsscanf: Return 0.0 to %p\n", pv); + *((double_t*)pv) = 0.0; +#else + lvdbg("vsscanf: Performing floating point conversion\n"); + + /* Skip over any white space before the real string */ + + while (isspace(*buf)) + { + buf++; + } + + /* Copy the real string into a temporary working buffer. */ + + if (!width) + { + if (isspace(*(s + 1)) || *(s + 1) == 0) + { + width = strcspn(buf, spaces); + } + else + { + width = strchr(buf, *(s + 1)) - buf; + } + } + strncpy(tmp, buf, width); + tmp[width] = '\0'; + buf += width; + + lvdbg("vsscanf: tmp[]=\"%s\"\n", tmp); + + /* Perform the floating point conversion */ + + if (!noassign) + { + /* strtod always returns a double */ +#ifdef SDCC + char *endptr; + double_t dvalue = strtod(tmp,&endptr); +#else + double_t dvalue = strtod(tmp, NULL); +#endif + void *pv = va_arg(ap, void*); + + lvdbg("vsscanf: Return %f to %p\n", dvalue, pv); + + /* But we have to check whether we need to return a + * float or a double. + */ + +#ifdef CONFIG_HAVE_DOUBLE + if (lflag) + { + *((double_t*)pv) = dvalue; + } + else +#endif + { + *((float*)pv) = (float)dvalue; + } + } +#endif + } + + if (!noassign) + { + count++; + } + width = noassign = lflag = 0; + s++; + } + + /* Its is not a conversion specifier */ + + else + { + while (isspace(*buf)) + buf++; + if (*s != *buf) + break; + else + s++, buf++; + } + } + return count; +} diff --git a/nuttx/lib/stdio/lib_stdinstream.c b/nuttx/lib/stdio/lib_stdinstream.c new file mode 100644 index 000000000..d89b6b63a --- /dev/null +++ b/nuttx/lib/stdio/lib_stdinstream.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * lib/stdio/lib_stdinstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stdinstream_getc + ****************************************************************************/ + +static int stdinstream_getc(FAR struct lib_instream_s *this) +{ + FAR struct lib_stdinstream_s *sthis = (FAR struct lib_stdinstream_s *)this; + if (this) + { + int ret = getc(sthis->stream); + if (ret != EOF) + { + this->nget++; + } + return ret; + } + return EOF; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_stdinstream + * + * Description: + * Initializes a stream for use with a FILE instance. + * + * Input parameters: + * stdinstream - User allocated, uninitialized instance of struct + * lib_stdinstream_s to be initialized. + * stream - User provided stream instance (must have been opened for + * read access). + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_stdinstream(FAR struct lib_stdinstream_s *stdinstream, + FAR FILE *stream) +{ + stdinstream->public.get = stdinstream_getc; + stdinstream->public.nget = 0; + stdinstream->stream = stream; +} + + diff --git a/nuttx/lib/stdio/lib_stdoutstream.c b/nuttx/lib/stdio/lib_stdoutstream.c new file mode 100644 index 000000000..272a93309 --- /dev/null +++ b/nuttx/lib/stdio/lib_stdoutstream.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * lib/stdio/lib_stdoutstream.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stdoutstream_putc + ****************************************************************************/ + +static void stdoutstream_putc(FAR struct lib_outstream_s *this, int ch) +{ + FAR struct lib_stdoutstream_s *sthis = (FAR struct lib_stdoutstream_s *)this; + if (this) + { + if (putc(ch, sthis->stream) != EOF) + { + this->nput++; + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_stdoutstream + * + * Description: + * Initializes a stream for use with a FILE instance. + * + * Input parameters: + * stdoutstream - User allocated, uninitialized instance of struct + * lib_stdoutstream_s to be initialized. + * stream - User provided stream instance (must have been opened for + * write access). + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_stdoutstream(FAR struct lib_stdoutstream_s *stdoutstream, + FAR FILE *stream) +{ + stdoutstream->public.put = stdoutstream_putc; + stdoutstream->public.nput = 0; + stdoutstream->stream = stream; +} + + diff --git a/nuttx/lib/stdio/lib_ungetc.c b/nuttx/lib/stdio/lib_ungetc.c new file mode 100644 index 000000000..9ad72b394 --- /dev/null +++ b/nuttx/lib/stdio/lib_ungetc.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * lib/stdio/lib_ungetc.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <nuttx/fs.h> +#include "lib_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/************************************************************************** + * Global Constant Data + **************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/************************************************************************** + * Private Constant Data + **************************************************************************/ + +/**************************************************************************** + * Private Variables + **************************************************************************/ + +/**************************************************************************** + * Public Functions + **************************************************************************/ + +/**************************************************************************** + * Name: ungetc + **************************************************************************/ + +int ungetc(int c, FAR FILE *stream) +{ +#if CONFIG_NUNGET_CHARS > 0 + int nungotten; +#endif + + /* Stream must be open for read access */ + + if ((stream && stream->fs_filedes < 0) || + ((stream->fs_oflags & O_RDOK) == 0)) + { + errno = EBADF; + return EOF; + } + +#if CONFIG_NUNGET_CHARS > 0 + nungotten = stream->fs_nungotten; + if (stream->fs_nungotten < CONFIG_NUNGET_CHARS) + { + stream->fs_ungotten[nungotten] = c; + stream->fs_nungotten = nungotten + 1; + return c; + } + else +#endif + { + errno = ENOMEM; + return EOF; + } +} + diff --git a/nuttx/lib/stdio/lib_vfprintf.c b/nuttx/lib/stdio/lib_vfprintf.c new file mode 100644 index 000000000..25c3954c0 --- /dev/null +++ b/nuttx/lib/stdio/lib_vfprintf.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * lib/stdio/lib_vfprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <semaphore.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int vfprintf(FAR FILE *stream, FAR const char *fmt, va_list ap) +{ + struct lib_stdoutstream_s stdoutstream; + int n = ERROR; + + if (stream) + { + /* Wrap the stream in a stream object and let lib_vsprintf + * do the work. + */ + + lib_stdoutstream(&stdoutstream, stream); + + /* Hold the stream semaphore throughout the lib_vsprintf + * call so that this thread can get its entire message out + * before being pre-empted by the next thread. + */ + + lib_take_semaphore(stream); + n = lib_vsprintf(&stdoutstream.public, fmt, ap); + lib_give_semaphore(stream); + } + return n; +} diff --git a/nuttx/lib/stdio/lib_vprintf.c b/nuttx/lib/stdio/lib_vprintf.c new file mode 100644 index 000000000..a2e31fa05 --- /dev/null +++ b/nuttx/lib/stdio/lib_vprintf.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * lib/stdio/lib_vprintf.c + * + * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Compilation Switches + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Function Prototypes + ****************************************************************************/ + +/************************************************************************** + * Global Constant Data + **************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/************************************************************************** + * Private Constant Data + **************************************************************************/ + +/**************************************************************************** + * Private Variables + **************************************************************************/ + +/**************************************************************************** + * Public Functions + **************************************************************************/ + +/**************************************************************************** + * Name: vprintf + **************************************************************************/ + +int vprintf(FAR const char *fmt, va_list ap) +{ + /* vfprintf into stdout */ + + return vfprintf(stdout, fmt, ap); +} + diff --git a/nuttx/lib/stdio/lib_vsnprintf.c b/nuttx/lib/stdio/lib_vsnprintf.c new file mode 100644 index 000000000..da885977c --- /dev/null +++ b/nuttx/lib/stdio/lib_vsnprintf.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * lib/stdio/lib_vsnprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdio.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vsnprintf + ****************************************************************************/ + +int vsnprintf(FAR char *buf, size_t size, const char *format, va_list ap) +{ + struct lib_memoutstream_s memoutstream; + int n; + + /* Initialize a memory stream to write to the buffer */ + + lib_memoutstream((FAR struct lib_memoutstream_s *)&memoutstream, buf, size); + + /* Then let lib_vsprintf do the real work */ + + n = lib_vsprintf((FAR struct lib_outstream_s *)&memoutstream.public, format, ap); + return n; +} diff --git a/nuttx/lib/stdio/lib_vsprintf.c b/nuttx/lib/stdio/lib_vsprintf.c new file mode 100644 index 000000000..72a829a79 --- /dev/null +++ b/nuttx/lib/stdio/lib_vsprintf.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * lib/stdio/lib_vsprintf.c + * + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vsprintf + ****************************************************************************/ + +int vsprintf(FAR char *dest, const char *src, va_list ap) +{ + struct lib_memoutstream_s memoutstream; + + /* Wrap the destination buffer in a stream object and let + * lib/stdio/lib_vsprintf do the work. + */ + + lib_memoutstream((FAR struct lib_memoutstream_s *)&memoutstream, dest, LIB_BUFLEN_UNKNOWN); + return lib_vsprintf((FAR struct lib_outstream_s *)&memoutstream.public, src, ap); +} diff --git a/nuttx/lib/stdio/lib_wrflush.c b/nuttx/lib/stdio/lib_wrflush.c new file mode 100644 index 000000000..c16109515 --- /dev/null +++ b/nuttx/lib/stdio/lib_wrflush.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * lib/stdio/lib_wrflush.c + * + * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdbool.h> +#include <fcntl.h> +#include <errno.h> + +#include "lib_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_wrflush + * + * Description: + * This is simply a version of fflush that does not report an error if + * the file is not open for writing. + * + ****************************************************************************/ + +int lib_wrflush(FAR FILE *stream) +{ + /* Verify that we were passed a valid (i.e., non-NULL) stream */ + +#if CONFIG_STDIO_BUFFER_SIZE > 0 + if (stream) + { + /* Verify that the stream is opened for writing... lib_fflush will + * return an error if it is called for a stream that is not opened for + * writing. + */ + + if ((stream->fs_oflags & O_WROK) == 0 || + lib_fflush(stream, true) == 0) + { + /* Return success if there is no buffered write data -- i.e., that + * the stream is not opened for writing or, if it is, that all of + * the buffered write data was successfully flushed. + */ + + return OK; + } + } + return ERROR; +#else + return stream ? OK : ERROR; +#endif +} diff --git a/nuttx/lib/stdio/lib_zeroinstream.c b/nuttx/lib/stdio/lib_zeroinstream.c new file mode 100644 index 000000000..27655b547 --- /dev/null +++ b/nuttx/lib/stdio/lib_zeroinstream.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * lib/stdio/lib_zeroinstream.c + * + * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <errno.h> +#include "lib_internal.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int zeroinstream_getc(FAR struct lib_instream_s *this) +{ + this->nget++; + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lib_zeroinstream + * + * Description: + * Initializes a NULL stream. The initialized stream will return an + * infinitely long stream of zeroes. + * + * Input parameters: + * zeroinstream - User allocated, uninitialized instance of struct + * lib_instream_s to be initialized. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void lib_zeroinstream(FAR struct lib_instream_s *zeroinstream) +{ + zeroinstream->get = zeroinstream_getc; + zeroinstream->nget = 0; +} + |