(linenum→info "unix/slp.c:2238")

glibc/2.7/argp/argp-fmtstream.h

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