argp-fmtstream.h
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:10k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

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