(root)/
glibc-2.38/
argp/
argp-fmtstream.h
       1  /* Word-wrapping and line-truncating streams.
       2     Copyright (C) 1997-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4     Written by Miles Bader <miles@gnu.ai.mit.edu>.
       5  
       6     The GNU C Library is free software; you can redistribute it and/or
       7     modify it under the terms of the GNU Lesser General Public
       8     License as published by the Free Software Foundation; either
       9     version 2.1 of the License, or (at your option) any later version.
      10  
      11     The GNU C Library is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14     Lesser General Public License for more details.
      15  
      16     You should have received a copy of the GNU Lesser General Public
      17     License along with the GNU C Library; if not, see
      18     <https://www.gnu.org/licenses/>.  */
      19  
      20  /* This package emulates glibc `line_wrap_stream' semantics for systems that
      21     don't have that.  If the system does have it, it is just a wrapper for
      22     that.  This header file is only used internally while compiling argp, and
      23     shouldn't be installed.  */
      24  
      25  #ifndef _ARGP_FMTSTREAM_H
      26  #define _ARGP_FMTSTREAM_H
      27  
      28  #include <stdio.h>
      29  #include <string.h>
      30  #include <unistd.h>
      31  
      32  #if defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)
      33  /* line_wrap_stream is available, so use that.  */
      34  #define ARGP_FMTSTREAM_USE_LINEWRAP
      35  #endif
      36  
      37  #ifdef ARGP_FMTSTREAM_USE_LINEWRAP
      38  /* Just be a simple wrapper for line_wrap_stream; the semantics are
      39     *slightly* different, as line_wrap_stream doesn't actually make a new
      40     object, it just modifies the given stream (reversibly) to do
      41     line-wrapping.  Since we control who uses this code, it doesn't matter.  */
      42  
      43  #include <linewrap.h>
      44  
      45  typedef FILE *argp_fmtstream_t;
      46  
      47  #define argp_make_fmtstream line_wrap_stream
      48  #define __argp_make_fmtstream line_wrap_stream
      49  #define argp_fmtstream_free line_unwrap_stream
      50  #define __argp_fmtstream_free line_unwrap_stream
      51  
      52  #define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
      53  #define argp_fmtstream_putc(fs,ch) putc(ch,fs)
      54  #define __argp_fmtstream_puts(fs,str) fputs(str,fs)
      55  #define argp_fmtstream_puts(fs,str) fputs(str,fs)
      56  #define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
      57  #define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
      58  #define __argp_fmtstream_printf fprintf
      59  #define argp_fmtstream_printf fprintf
      60  
      61  #define __argp_fmtstream_lmargin line_wrap_lmargin
      62  #define argp_fmtstream_lmargin line_wrap_lmargin
      63  #define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
      64  #define argp_fmtstream_set_lmargin line_wrap_set_lmargin
      65  #define __argp_fmtstream_rmargin line_wrap_rmargin
      66  #define argp_fmtstream_rmargin line_wrap_rmargin
      67  #define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
      68  #define argp_fmtstream_set_rmargin line_wrap_set_rmargin
      69  #define __argp_fmtstream_wmargin line_wrap_wmargin
      70  #define argp_fmtstream_wmargin line_wrap_wmargin
      71  #define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
      72  #define argp_fmtstream_set_wmargin line_wrap_set_wmargin
      73  #define __argp_fmtstream_point line_wrap_point
      74  #define argp_fmtstream_point line_wrap_point
      75  
      76  #else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
      77  /* Guess we have to define our own version.  */
      78  
      79  
      80  struct argp_fmtstream
      81  {
      82    FILE *stream;			/* The stream we're outputting to.  */
      83  
      84    size_t lmargin, rmargin;	/* Left and right margins.  */
      85    ssize_t wmargin;		/* Margin to wrap to, or -1 to truncate.  */
      86  
      87    /* Point in buffer to which we've processed for wrapping, but not output.  */
      88    size_t point_offs;
      89    /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin.  */
      90    ssize_t point_col;
      91  
      92    char *buf;			/* Output buffer.  */
      93    char *p;			/* Current end of text in BUF. */
      94    char *end;			/* Absolute end of BUF.  */
      95  };
      96  
      97  typedef struct argp_fmtstream *argp_fmtstream_t;
      98  
      99  __BEGIN_DECLS
     100  
     101  /* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
     102     written on it with LMARGIN spaces and limits them to RMARGIN columns
     103     total.  If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
     104     replacing the whitespace before them with a newline and WMARGIN spaces.
     105     Otherwise, chars beyond RMARGIN are simply dropped until a newline.
     106     Returns NULL if there was an error.  */
     107  extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
     108  					       size_t __lmargin,
     109  					       size_t __rmargin,
     110  					       ssize_t __wmargin);
     111  extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
     112  					     size_t __lmargin,
     113  					     size_t __rmargin,
     114  					     ssize_t __wmargin);
     115  
     116  /* Flush __FS to its stream, and free it (but don't close the stream).  */
     117  extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
     118  extern void argp_fmtstream_free (argp_fmtstream_t __fs);
     119  
     120  extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
     121  					const char *__fmt, ...)
     122       __attribute__ ((__format__ (printf, 2, 3)));
     123  extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
     124  				      const char *__fmt, ...)
     125       __attribute__ ((__format__ (printf, 2, 3)));
     126  
     127  extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
     128  extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
     129  
     130  extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
     131  extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
     132  
     133  extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
     134  				      const char *__str, size_t __len);
     135  extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
     136  				    const char *__str, size_t __len);
     137  
     138  /* Access macros for various bits of state.  */
     139  #define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
     140  #define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
     141  #define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
     142  #define __argp_fmtstream_lmargin argp_fmtstream_lmargin
     143  #define __argp_fmtstream_rmargin argp_fmtstream_rmargin
     144  #define __argp_fmtstream_wmargin argp_fmtstream_wmargin
     145  
     146  /* Set __FS's left margin to LMARGIN and return the old value.  */
     147  extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
     148  					  size_t __lmargin);
     149  extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
     150  					    size_t __lmargin);
     151  
     152  /* Set __FS's right margin to __RMARGIN and return the old value.  */
     153  extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
     154  					  size_t __rmargin);
     155  extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
     156  					    size_t __rmargin);
     157  
     158  /* Set __FS's wrap margin to __WMARGIN and return the old value.  */
     159  extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
     160  					  size_t __wmargin);
     161  extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
     162  					    size_t __wmargin);
     163  
     164  /* Return the column number of the current output point in __FS.  */
     165  extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
     166  extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
     167  
     168  /* Internal routines.  */
     169  extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
     170  extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
     171  extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
     172  extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
     173  
     174  #ifdef __OPTIMIZE__
     175  /* Inline versions of above routines.  */
     176  
     177  #if !_LIBC
     178  #define __argp_fmtstream_putc argp_fmtstream_putc
     179  #define __argp_fmtstream_puts argp_fmtstream_puts
     180  #define __argp_fmtstream_write argp_fmtstream_write
     181  #define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
     182  #define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
     183  #define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
     184  #define __argp_fmtstream_point argp_fmtstream_point
     185  #define __argp_fmtstream_update _argp_fmtstream_update
     186  #define __argp_fmtstream_ensure _argp_fmtstream_ensure
     187  #endif
     188  
     189  #ifndef ARGP_FS_EI
     190  #define ARGP_FS_EI extern inline
     191  #endif
     192  
     193  ARGP_FS_EI size_t
     194  __argp_fmtstream_write (argp_fmtstream_t __fs, const char *__str, size_t __len)
     195  {
     196    if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
     197      {
     198        memcpy (__fs->p, __str, __len);
     199        __fs->p += __len;
     200        return __len;
     201      }
     202    else
     203      return 0;
     204  }
     205  
     206  ARGP_FS_EI int
     207  __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str)
     208  {
     209    size_t __len = strlen (__str);
     210    if (__len)
     211      {
     212        size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
     213        return __wrote == __len ? 0 : -1;
     214      }
     215    else
     216      return 0;
     217  }
     218  
     219  ARGP_FS_EI int
     220  __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
     221  {
     222    if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
     223      return *__fs->p++ = __ch;
     224    else
     225      return EOF;
     226  }
     227  
     228  /* Set __FS's left margin to __LMARGIN and return the old value.  */
     229  ARGP_FS_EI size_t
     230  __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
     231  {
     232    size_t __old;
     233    if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
     234      __argp_fmtstream_update (__fs);
     235    __old = __fs->lmargin;
     236    __fs->lmargin = __lmargin;
     237    return __old;
     238  }
     239  
     240  /* Set __FS's right margin to __RMARGIN and return the old value.  */
     241  ARGP_FS_EI size_t
     242  __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
     243  {
     244    size_t __old;
     245    if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
     246      __argp_fmtstream_update (__fs);
     247    __old = __fs->rmargin;
     248    __fs->rmargin = __rmargin;
     249    return __old;
     250  }
     251  
     252  /* Set FS's wrap margin to __WMARGIN and return the old value.  */
     253  ARGP_FS_EI size_t
     254  __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
     255  {
     256    size_t __old;
     257    if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
     258      __argp_fmtstream_update (__fs);
     259    __old = __fs->wmargin;
     260    __fs->wmargin = __wmargin;
     261    return __old;
     262  }
     263  
     264  /* Return the column number of the current output point in __FS.  */
     265  ARGP_FS_EI size_t
     266  __argp_fmtstream_point (argp_fmtstream_t __fs)
     267  {
     268    if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
     269      __argp_fmtstream_update (__fs);
     270    return __fs->point_col >= 0 ? __fs->point_col : 0;
     271  }
     272  
     273  #if !_LIBC
     274  #undef __argp_fmtstream_putc
     275  #undef __argp_fmtstream_puts
     276  #undef __argp_fmtstream_write
     277  #undef __argp_fmtstream_set_lmargin
     278  #undef __argp_fmtstream_set_rmargin
     279  #undef __argp_fmtstream_set_wmargin
     280  #undef __argp_fmtstream_point
     281  #undef __argp_fmtstream_update
     282  #undef __argp_fmtstream_ensure
     283  #endif
     284  
     285  #endif /* __OPTIMIZE__ */
     286  
     287  __END_DECLS
     288  
     289  #endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
     290  
     291  #endif /* argp-fmtstream.h */