123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812 |
- @c -*-texinfo-*-
- @c This is part of the GNU Guile Reference Manual.
- @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2009,
- @c 2010, 2011, 2012 Free Software Foundation, Inc.
- @c See the file guile.texi for copying conditions.
- @node Pretty Printing
- @section Pretty Printing
- @c FIXME::martin: Review me!
- @cindex pretty printing
- The module @code{(ice-9 pretty-print)} provides the procedure
- @code{pretty-print}, which provides nicely formatted output of Scheme
- objects. This is especially useful for deeply nested or complex data
- structures, such as lists and vectors.
- The module is loaded by entering the following:
- @lisp
- (use-modules (ice-9 pretty-print))
- @end lisp
- This makes the procedure @code{pretty-print} available. As an example
- how @code{pretty-print} will format the output, see the following:
- @lisp
- (pretty-print '(define (foo) (lambda (x)
- (cond ((zero? x) #t) ((negative? x) -x) (else
- (if (= x 1) 2 (* x x x)))))))
- @print{}
- (define (foo)
- (lambda (x)
- (cond ((zero? x) #t)
- ((negative? x) -x)
- (else (if (= x 1) 2 (* x x x))))))
- @end lisp
- @deffn {Scheme Procedure} pretty-print obj [port] [keyword-options]
- Print the textual representation of the Scheme object @var{obj} to
- @var{port}. @var{port} defaults to the current output port, if not
- given.
- The further @var{keyword-options} are keywords and parameters as
- follows,
- @table @asis
- @item @nicode{#:display?} @var{flag}
- If @var{flag} is true then print using @code{display}. The default is
- @code{#f} which means use @code{write} style. @xref{Scheme Write}.
- @item @nicode{#:per-line-prefix} @var{string}
- Print the given @var{string} as a prefix on each line. The default is
- no prefix.
- @item @nicode{#:width} @var{columns}
- Print within the given @var{columns}. The default is 79.
- @item @nicode{#:max-expr-width} @var{columns}
- The maximum width of an expression. The default is 50.
- @end table
- @end deffn
- @cindex truncated printing
- Also exported by the @code{(ice-9 pretty-print)} module is
- @code{truncated-print}, a procedure to print Scheme datums, truncating
- the output to a certain number of characters. This is useful when you
- need to present an arbitrary datum to the user, but you only have one
- line in which to do so.
- @lisp
- (define exp '(a b #(c d e) f . g))
- (truncated-print exp #:width 10) (newline)
- @print{} (a b . #)
- (truncated-print exp #:width 15) (newline)
- @print{} (a b # f . g)
- (truncated-print exp #:width 18) (newline)
- @print{} (a b #(c ...) . #)
- (truncated-print exp #:width 20) (newline)
- @print{} (a b #(c d e) f . g)
- (truncated-print "The quick brown fox" #:width 20) (newline)
- @print{} "The quick brown..."
- (truncated-print (current-module) #:width 20) (newline)
- @print{} #<directory (gui...>
- @end lisp
- @code{truncated-print} will not output a trailing newline. If an expression does
- not fit in the given width, it will be truncated -- possibly
- ellipsized@footnote{On Unicode-capable ports, the ellipsis is represented by
- character `HORIZONTAL ELLIPSIS' (U+2026), otherwise it is represented by three
- dots.}, or in the worst case, displayed as @nicode{#}.
- @deffn {Scheme Procedure} truncated-print obj [port] [keyword-options]
- Print @var{obj}, truncating the output, if necessary, to make it fit
- into @var{width} characters. By default, @var{obj} will be printed using
- @code{write}, though that behavior can be overridden via the
- @var{display?} keyword argument.
- The default behavior is to print depth-first, meaning that the entire
- remaining width will be available to each sub-expression of @var{obj} --
- e.g., if @var{obj} is a vector, each member of @var{obj}. One can attempt to
- ``ration'' the available width, trying to allocate it equally to each
- sub-expression, via the @var{breadth-first?} keyword argument.
- The further @var{keyword-options} are keywords and parameters as
- follows,
- @table @asis
- @item @nicode{#:display?} @var{flag}
- If @var{flag} is true then print using @code{display}. The default is
- @code{#f} which means use @code{write} style. @pxref{Scheme Write}.
- @item @nicode{#:width} @var{columns}
- Print within the given @var{columns}. The default is 79.
- @item @nicode{#:breadth-first?} @var{flag}
- If @var{flag} is true, then allocate the available width breadth-first
- among elements of a compound data structure (list, vector, pair,
- etc.). The default is @code{#f} which means that any element is
- allowed to consume all of the available width.
- @end table
- @end deffn
- @node Formatted Output
- @section Formatted Output
- @cindex formatted output
- @c For reference, in this section escapes like ~a are given in
- @c @nicode, to give code font in TeX etc, but leave them unadorned in
- @c Info.
- @c
- @c The idea is to reduce clutter around what's shown, and avoid any
- @c possible confusion over whether the ` ' quotes are part of what
- @c should be entered. (In particular for instance of course ' is
- @c meaningful in a format string, introducing a char parameter).
- The @code{format} function is a powerful way to print numbers, strings
- and other objects together with literal text under the control of a
- format string. This function is available from
- @example
- (use-modules (ice-9 format))
- @end example
- A format string is generally more compact and easier than using just
- the standard procedures like @code{display}, @code{write} and
- @code{newline}. Parameters in the output string allow various output
- styles, and parameters can be taken from the arguments for runtime
- flexibility.
- @code{format} is similar to the Common Lisp procedure of the same
- name, but it's not identical and doesn't have quite all the features
- found in Common Lisp.
- C programmers will note the similarity between @code{format} and
- @code{printf}, though escape sequences are marked with @nicode{~}
- instead of @nicode{%}, and are more powerful.
- @sp 1
- @deffn {Scheme Procedure} format dest fmt arg @dots{}
- Write output specified by the @var{fmt} string to @var{dest}.
- @var{dest} can be an output port, @code{#t} for
- @code{current-output-port} (@pxref{Default Ports}), or @code{#f} to
- return the output as a string.
- @var{fmt} can contain literal text to be output, and @nicode{~}
- escapes. Each escape has the form
- @example
- ~ [param [, param@dots{}] [:] [@@] code
- @end example
- @nicode{code} is a character determining the escape sequence. The
- @nicode{:} and @nicode{@@} characters are optional modifiers, one or
- both of which change the way various codes operate. Optional
- parameters are accepted by some codes too. Parameters have the
- following forms,
- @table @asis
- @item @nicode{[+/-]number}
- An integer, with optional @nicode{+} or @nicode{-}.
- @item @nicode{'} (apostrophe)
- The following character in the format string, for instance @nicode{'z}
- for @nicode{z}.
- @item @nicode{v}
- The next function argument as the parameter. @nicode{v} stands for
- ``variable'', a parameter can be calculated at runtime and included in
- the arguments. Upper case @nicode{V} can be used too.
- @item @nicode{#}
- The number of arguments remaining. (See @nicode{~*} below for some
- usages.)
- @end table
- Parameters are separated by commas (@nicode{,}). A parameter can be
- left empty to keep its default value when supplying later parameters.
- @sp 1
- The following escapes are available. The code letters are not
- case-sensitive, upper and lower case are the same.
- @table @asis
- @item @nicode{~a}
- @itemx @nicode{~s}
- Object output. Parameters: @var{minwidth}, @var{padinc},
- @var{minpad}, @var{padchar}.
- @nicode{~a} outputs an argument like @code{display}, @nicode{~s}
- outputs an argument like @code{write} (@pxref{Scheme Write}).
- @example
- (format #t "~a" "foo") @print{} foo
- (format #t "~s" "foo") @print{} "foo"
- @end example
- @nicode{~:a} and @nicode{~:s} put objects that don't have an external
- representation in quotes like a string.
- @example
- (format #t "~:a" car) @print{} "#<primitive-procedure car>"
- @end example
- If the output is less than @var{minwidth} characters (default 0), it's
- padded on the right with @var{padchar} (default space). @nicode{~@@a}
- and @nicode{~@@s} put the padding on the left instead.
- @example
- (format #f "~5a" 'abc) @result{} "abc "
- (format #f "~5,,,'-@@a" 'abc) @result{} "--abc"
- @end example
- @var{minpad} is a minimum for the padding then plus a multiple of
- @var{padinc}. Ie.@: the padding is @math{@var{minpad} + @var{N} *
- @var{padinc}}, where @var{n} is the smallest integer making the total
- object plus padding greater than or equal to @var{minwidth}. The
- default @var{minpad} is 0 and the default @var{padinc} is 1 (imposing
- no minimum or multiple).
- @example
- (format #f "~5,1,4a" 'abc) @result{} "abc "
- @end example
- @item @nicode{~c}
- Character. Parameter: @var{charnum}.
- Output a character. The default is to simply output, as per
- @code{write-char} (@pxref{Venerable Port Interfaces}). @nicode{~@@c}
- prints in @code{write} style. @nicode{~:c} prints control characters
- (ASCII 0 to 31) in @nicode{^X} form.
- @example
- (format #t "~c" #\z) @print{} z
- (format #t "~@@c" #\z) @print{} #\z
- (format #t "~:c" #\newline) @print{} ^J
- @end example
- If the @var{charnum} parameter is given then an argument is not taken
- but instead the character is @code{(integer->char @var{charnum})}
- (@pxref{Characters}). This can be used for instance to output
- characters given by their ASCII code.
- @example
- (format #t "~65c") @print{} A
- @end example
- @item @nicode{~d}
- @itemx @nicode{~x}
- @itemx @nicode{~o}
- @itemx @nicode{~b}
- Integer. Parameters: @var{minwidth}, @var{padchar}, @var{commachar},
- @var{commawidth}.
- Output an integer argument as a decimal, hexadecimal, octal or binary
- integer (respectively), in a locale-independent way.
- @example
- (format #t "~d" 123) @print{} 123
- @end example
- @nicode{~@@d} etc shows a @nicode{+} sign is shown on positive
- numbers.
- @c FIXME: "+" is not shown on zero, unlike in Common Lisp. Should
- @c that be changed in the code, or is it too late and should just be
- @c documented that way?
- @example
- (format #t "~@@b" 12) @print{} +1100
- @end example
- If the output is less than the @var{minwidth} parameter (default no
- minimum), it's padded on the left with the @var{padchar} parameter
- (default space).
- @example
- (format #t "~5,'*d" 12) @print{} ***12
- (format #t "~5,'0d" 12) @print{} 00012
- (format #t "~3d" 1234) @print{} 1234
- @end example
- @nicode{~:d} adds commas (or the @var{commachar} parameter) every
- three digits (or the @var{commawidth} parameter many). However, when
- your intent is to write numbers in a way that follows typographical
- conventions, using @nicode{~h} is recommended.
- @example
- (format #t "~:d" 1234567) @print{} 1,234,567
- (format #t "~10,'*,'/,2:d" 12345) @print{} ***1/23/45
- @end example
- Hexadecimal @nicode{~x} output is in lower case, but the @nicode{~(}
- and @nicode{~)} case conversion directives described below can be used
- to get upper case.
- @example
- (format #t "~x" 65261) @print{} feed
- (format #t "~:@@(~x~)" 65261) @print{} FEED
- @end example
- @item @nicode{~r}
- Integer in words, roman numerals, or a specified radix. Parameters:
- @var{radix}, @var{minwidth}, @var{padchar}, @var{commachar},
- @var{commawidth}.
- With no parameters output is in words as a cardinal like ``ten'', or
- @nicode{~:r} prints an ordinal like ``tenth''.
- @example
- (format #t "~r" 9) @print{} nine ;; cardinal
- (format #t "~r" -9) @print{} minus nine ;; cardinal
- (format #t "~:r" 9) @print{} ninth ;; ordinal
- @end example
- And also with no parameters, @nicode{~@@r} gives roman numerals and
- @nicode{~:@@r} gives old roman numerals. In old roman numerals
- there's no ``subtraction'', so 9 is @nicode{VIIII} instead of
- @nicode{IX}. In both cases only positive numbers can be output.
- @example
- (format #t "~@@r" 89) @print{} LXXXIX ;; roman
- (format #t "~:@@r" 89) @print{} LXXXVIIII ;; old roman
- @end example
- When a parameter is given it means numeric output in the specified
- @var{radix}. The modifiers and parameters following the radix are the
- same as described for @nicode{~d} etc above.
- @example
- (format #f "~3r" 27) @result{} "1000" ;; base 3
- (format #f "~3,5r" 26) @result{} " 222" ;; base 3 width 5
- @end example
- @item @nicode{~f}
- Fixed-point float. Parameters: @var{width}, @var{decimals},
- @var{scale}, @var{overflowchar}, @var{padchar}.
- Output a number or number string in fixed-point format, ie.@: with a
- decimal point.
- @example
- (format #t "~f" 5) @print{} 5.0
- (format #t "~f" "123") @print{} 123.0
- (format #t "~f" "1e-1") @print{} 0.1
- @end example
- @nicode{~@@f} prints a @nicode{+} sign on positive numbers (including
- zero).
- @example
- (format #t "~@@f" 0) @print{} +0.0
- @end example
- If the output is less than @var{width} characters it's padded on the
- left with @var{padchar} (space by default). If the output equals or
- exceeds @var{width} then there's no padding. The default for
- @var{width} is no padding.
- @example
- (format #f "~6f" -1.5) @result{} " -1.5"
- (format #f "~6,,,,'*f" 23) @result{} "**23.0"
- (format #f "~6f" 1234567.0) @result{} "1234567.0"
- @end example
- @var{decimals} is how many digits to print after the decimal point,
- with the value rounded or padded with zeros as necessary. (The
- default is to output as many decimals as required.)
- @example
- (format #t "~1,2f" 3.125) @print{} 3.13
- (format #t "~1,2f" 1.5) @print{} 1.50
- @end example
- @var{scale} is a power of 10 applied to the value, moving the decimal
- point that many places. A positive @var{scale} increases the value
- shown, a negative decreases it.
- @example
- (format #t "~,,2f" 1234) @print{} 123400.0
- (format #t "~,,-2f" 1234) @print{} 12.34
- @end example
- If @var{overflowchar} and @var{width} are both given and if the output
- would exceed @var{width}, then that many @var{overflowchar}s are
- printed instead of the value.
- @example
- (format #t "~6,,,'xf" 12345) @print{} 12345.
- (format #t "~5,,,'xf" 12345) @print{} xxxxx
- @end example
- @item @nicode{~h}
- Localized number@footnote{The @nicode{~h} format specifier first
- appeared in Guile version 2.0.6.}. Parameters: @var{width},
- @var{decimals}, @var{padchar}.
- Like @nicode{~f}, output an exact or floating point number, but do so
- according to the current locale, or according to the given locale object
- when the @code{:} modifier is used (@pxref{Number Input and Output,
- @code{number->locale-string}}).
- @example
- (format #t "~h" 12345.5678) ; with "C" as the current locale
- @print{} 12345.5678
- (format #t "~14,,'*:h" 12345.5678
- (make-locale LC_ALL "en_US"))
- @print{} ***12,345.5678
- (format #t "~,2:h" 12345.5678
- (make-locale LC_NUMERIC "fr_FR"))
- @print{} 12 345,56
- @end example
- @item @nicode{~e}
- Exponential float. Parameters: @var{width}, @var{mantdigits},
- @var{expdigits}, @var{intdigits}, @var{overflowchar}, @var{padchar},
- @var{expchar}.
- Output a number or number string in exponential notation.
- @example
- (format #t "~e" 5000.25) @print{} 5.00025E+3
- (format #t "~e" "123.4") @print{} 1.234E+2
- (format #t "~e" "1e4") @print{} 1.0E+4
- @end example
- @nicode{~@@e} prints a @nicode{+} sign on positive numbers (including
- zero). (This is for the mantissa, a @nicode{+} or @nicode{-} sign is
- always shown on the exponent.)
- @example
- (format #t "~@@e" 5000.0) @print{} +5.0E+3
- @end example
- If the output is less than @var{width} characters it's padded on the
- left with @var{padchar} (space by default). The default for
- @var{width} is to output with no padding.
- @example
- (format #f "~10e" 1234.0) @result{} " 1.234E+3"
- (format #f "~10,,,,,'*e" 0.5) @result{} "****5.0E-1"
- @end example
- @c FIXME: Describe what happens when the number is bigger than WIDTH.
- @c There seems to be a bit of dodginess about this, or some deviation
- @c from Common Lisp.
- @var{mantdigits} is the number of digits shown in the mantissa after
- the decimal point. The value is rounded or trailing zeros are added
- as necessary. The default @var{mantdigits} is to show as much as
- needed by the value.
- @example
- (format #f "~,3e" 11111.0) @result{} "1.111E+4"
- (format #f "~,8e" 123.0) @result{} "1.23000000E+2"
- @end example
- @var{expdigits} is the minimum number of digits shown for the
- exponent, with leading zeros added if necessary. The default for
- @var{expdigits} is to show only as many digits as required. At least
- 1 digit is always shown.
- @example
- (format #f "~,,1e" 1.0e99) @result{} "1.0E+99"
- (format #f "~,,6e" 1.0e99) @result{} "1.0E+000099"
- @end example
- @var{intdigits} (default 1) is the number of digits to show before the
- decimal point in the mantissa. @var{intdigits} can be zero, in which
- case the integer part is a single @nicode{0}, or it can be negative,
- in which case leading zeros are shown after the decimal point.
- @c FIXME: When INTDIGITS is 0, Common Lisp format apparently only
- @c shows the single 0 digit if it fits in WIDTH. format.scm seems to
- @c show it always. Is it meant to?
- @example
- (format #t "~,,,3e" 12345.0) @print{} 123.45E+2
- (format #t "~,,,0e" 12345.0) @print{} 0.12345E+5
- (format #t "~,,,-3e" 12345.0) @print{} 0.00012345E+8
- @end example
- @c FIXME: MANTDIGITS with negative INTDIGITS doesn't match CL spec,
- @c believe the spec says it ought to still show mantdigits+1 sig
- @c figures, i.e. leading zeros don't count towards MANTDIGITS, but it
- @c seems to just treat MANTDIGITS as how many digits after the
- @c decimal point.
- If @var{overflowchar} is given then @var{width} is a hard limit. If
- the output would exceed @var{width} then instead that many
- @var{overflowchar}s are printed.
- @example
- (format #f "~6,,,,'xe" 100.0) @result{} "1.0E+2"
- (format #f "~3,,,,'xe" 100.0) @result{} "xxx"
- @end example
- @var{expchar} is the exponent marker character (default @nicode{E}).
- @example
- (format #t "~,,,,,,'ee" 100.0) @print{} 1.0e+2
- @end example
- @item @nicode{~g}
- General float. Parameters: @var{width}, @var{mantdigits},
- @var{expdigits}, @var{intdigits}, @var{overflowchar}, @var{padchar},
- @var{expchar}.
- Output a number or number string in either exponential format the same
- as @nicode{~e}, or fixed-point format like @nicode{~f} but aligned
- where the mantissa would have been and followed by padding where the
- exponent would have been.
- @c FIXME: The default MANTDIGITS is apparently max(needed,min(n,7))
- @c where 10^(n-1)<=abs(x)<=10^n. But the Common Lisp spec seems to
- @c ask for "needed" to be without leading or trailing zeros, whereas
- @c format.scm seems to include trailing zeros, ending up with it
- @c using fixed format for bigger values than it should.
- Fixed-point is used when the absolute value is 0.1 or more and it
- takes no more space than the mantissa in exponential format, ie.@:
- basically up to @var{mantdigits} digits.
- @example
- (format #f "~12,4,2g" 999.0) @result{} " 999.0 "
- (format #f "~12,4,2g" "100000") @result{} " 1.0000E+05"
- @end example
- The parameters are interpreted as per @nicode{~e} above. When
- fixed-point is used, the @var{decimals} parameter to @nicode{~f} is
- established from @var{mantdigits}, so as to give a total
- @math{@var{mantdigits}+1} figures.
- @item @nicode{~$}
- Monetary style fixed-point float. Parameters: @var{decimals},
- @var{intdigits}, @var{width}, @var{padchar}.
- @c For reference, fmtdoc.txi from past versions of slib showed the
- @c INTDIGITS parameter as SCALE. That looks like a typo, in the code
- @c and in the Common Lisp spec it's a minimum digits for the integer
- @c part, it isn't a power of 10 like in ~f.
- Output a number or number string in fixed-point format, ie.@: with a
- decimal point. @var{decimals} is the number of decimal places to
- show, default 2.
- @example
- (format #t "~$" 5) @print{} 5.00
- (format #t "~4$" "2.25") @print{} 2.2500
- (format #t "~4$" "1e-2") @print{} 0.0100
- @end example
- @nicode{~@@$} prints a @nicode{+} sign on positive numbers (including
- zero).
- @example
- (format #t "~@@$" 0) @print{} +0.00
- @end example
- @var{intdigits} is a minimum number of digits to show in the integer
- part of the value (default 1).
- @example
- (format #t "~,3$" 9.5) @print{} 009.50
- (format #t "~,0$" 0.125) @print{} .13
- @end example
- If the output is less than @var{width} characters (default 0), it's
- padded on the left with @var{padchar} (default space). @nicode{~:$}
- puts the padding after the sign.
- @example
- (format #f "~,,8$" -1.5) @result{} " -1.50"
- (format #f "~,,8:$" -1.5) @result{} "- 1.50"
- (format #f "~,,8,'.:@@$" 3) @result{} "+...3.00"
- @end example
- Note that floating point for dollar amounts is generally not a good
- idea, because a cent @math{0.01} cannot be represented exactly in the
- binary floating point Guile uses, which leads to slowly accumulating
- rounding errors. Keeping values as cents (or fractions of a cent) in
- integers then printing with the scale option in @nicode{~f} may be a
- better approach.
- @c For reference, fractions don't work with ~$ (or any of the float
- @c conversions) currently. If they did work then we could perhaps
- @c suggest keeping dollar amounts as rationals, which would of course
- @c give exact cents. An integer as cents is probably still a better
- @c recommendation though, since it forces one to think about where
- @c and when rounding can or should occur.
- @item @nicode{~i}
- Complex fixed-point float. Parameters: @var{width}, @var{decimals},
- @var{scale}, @var{overflowchar}, @var{padchar}.
- @c For reference, in Common Lisp ~i is an indent, but slib fmtdoc.txi
- @c described it as complex number output, so we keep that.
- Output the argument as a complex number, with both real and imaginary
- part shown (even if one or both are zero).
- The parameters and modifiers are the same as for fixed-point
- @nicode{~f} described above. The real and imaginary parts are both
- output with the same given parameters and modifiers, except that for
- the imaginary part the @nicode{@@} modifier is always enabled, so as
- to print a @nicode{+} sign between the real and imaginary parts.
- @example
- (format #t "~i" 1) @print{} 1.0+0.0i
- @end example
- @item @nicode{~p}
- Plural. No parameters.
- Output nothing if the argument is 1, or @samp{s} for any other
- value.
- @example
- (format #t "enter name~p" 1) @print{} enter name
- (format #t "enter name~p" 2) @print{} enter names
- @end example
- @nicode{~@@p} prints @samp{y} for 1 or @samp{ies} otherwise.
- @example
- (format #t "pupp~@@p" 1) @print{} puppy
- (format #t "pupp~@@p" 2) @print{} puppies
- @end example
- @nicode{~:p} re-uses the preceding argument instead of taking a new
- one, which can be convenient when printing some sort of count.
- @example
- (format #t "~d cat~:p" 9) @print{} 9 cats
- (format #t "~d pupp~:@@p" 5) @print{} 5 puppies
- @end example
- @nicode{~p} is designed for English plurals and there's no attempt to
- support other languages. @nicode{~[} conditionals (below) may be able
- to help. When using @code{gettext} to translate messages
- @code{ngettext} is probably best though
- (@pxref{Internationalization}).
- @item @nicode{~y}
- Structured printing. Parameters: @var{width}.
- @nicode{~y} outputs an argument using @code{pretty-print}
- (@pxref{Pretty Printing}). The result will be formatted to fit within
- @var{width} columns (79 by default), consuming multiple lines if
- necessary.
- @nicode{~@@y} outputs an argument using @code{truncated-print}
- (@pxref{Pretty Printing}). The resulting code will be formatted to fit
- within @var{width} columns (79 by default), on a single line. The
- output will be truncated if necessary.
- @nicode{~:@@y} is like @nicode{~@@y}, except the @var{width} parameter
- is interpreted to be the maximum column to which to output. That is to
- say, if you are at column 10, and @nicode{~60:@@y} is seen, the datum
- will be truncated to 50 columns.
- @item @nicode{~?}
- @itemx @nicode{~k}
- Sub-format. No parameters.
- Take a format string argument and a second argument which is a list of
- arguments for that string, and output the result.
- @example
- (format #t "~?" "~d ~d" '(1 2)) @print{} 1 2
- @end example
- @nicode{~@@?} takes arguments for the sub-format directly rather than
- in a list.
- @example
- (format #t "~@@? ~s" "~d ~d" 1 2 "foo") @print{} 1 2 "foo"
- @end example
- @nicode{~?} and @nicode{~k} are the same, @nicode{~k} is provided for
- T-Scheme compatibility.
- @item @nicode{~*}
- Argument jumping. Parameter: @var{N}.
- Move forward @var{N} arguments (default 1) in the argument list.
- @nicode{~:*} moves backwards. (@var{N} cannot be negative.)
- @example
- (format #f "~d ~2*~d" 1 2 3 4) @result{} "1 4"
- (format #f "~d ~:*~d" 6) @result{} "6 6"
- @end example
- @nicode{~@@*} moves to argument number @var{N}. The first argument is
- number 0 (and that's the default for @var{N}).
- @example
- (format #f "~d~d again ~@@*~d~d" 1 2) @result{} "12 again 12"
- (format #f "~d~d~d ~1@@*~d~d" 1 2 3) @result{} "123 23"
- @end example
- A @nicode{#} move to the end followed by a @nicode{:} modifier move
- back can be used for an absolute position relative to the end of the
- argument list, a reverse of what the @nicode{@@} modifier does.
- @example
- (format #t "~#*~2:*~a" 'a 'b 'c 'd) @print{} c
- @end example
- At the end of the format string the current argument position doesn't
- matter, any further arguments are ignored.
- @item @nicode{~t}
- Advance to a column position. Parameters: @var{colnum}, @var{colinc},
- @var{padchar}.
- Output @var{padchar} (space by default) to move to the given
- @var{colnum} column. The start of the line is column 0, the default
- for @var{colnum} is 1.
- @example
- (format #f "~tX") @result{} " X"
- (format #f "~3tX") @result{} " X"
- @end example
- If the current column is already past @var{colnum}, then the move is
- to there plus a multiple of @var{colinc}, ie.@: column
- @math{@var{colnum} + @var{N} * @var{colinc}} for the smallest @var{N}
- which makes that value greater than or equal to the current column.
- The default @var{colinc} is 1 (which means no further move).
- @example
- (format #f "abcd~2,5,'.tx") @result{} "abcd...x"
- @end example
- @nicode{~@@t} takes @var{colnum} as an offset from the current column.
- @var{colnum} many pad characters are output, then further padding to
- make the current column a multiple of @var{colinc}, if it isn't
- already so.
- @example
- (format #f "a~3,5'*@@tx") @result{} "a****x"
- @end example
- @nicode{~t} is implemented using @code{port-column} (@pxref{Textual
- I/O}), so it works even there has been other output before
- @code{format}.
- @item @nicode{~~}
- Tilde character. Parameter: @var{n}.
- Output a tilde character @nicode{~}, or @var{n} many if a parameter is
- given. Normally @nicode{~} introduces an escape sequence, @nicode{~~}
- is the way to output a literal tilde.
- @item @nicode{~%}
- Newline. Parameter: @var{n}.
- Output a newline character, or @var{n} many if a parameter is given.
- A newline (or a few newlines) can of course be output just by
- including them in the format string.
- @item @nicode{~&}
- Start a new line. Parameter: @var{n}.
- Output a newline if not already at the start of a line. With a
- parameter, output that many newlines, but with the first only if not
- already at the start of a line. So for instance 3 would be a newline
- if not already at the start of a line, and 2 further newlines.
- @item @nicode{~_}
- Space character. Parameter: @var{n}.
- @c For reference, in Common Lisp ~_ is a conditional newline, but
- @c slib fmtdoc.txi described it as a space, so we keep that.
- Output a space character, or @var{n} many if a parameter is given.
- With a variable parameter this is one way to insert runtime calculated
- padding (@nicode{~t} or the various field widths can do similar
- things).
- @example
- (format #f "~v_foo" 4) @result{} " foo"
- @end example
- @item @nicode{~/}
- Tab character. Parameter: @var{n}.
- Output a tab character, or @var{n} many if a parameter is given.
- @item @nicode{~|}
- Formfeed character. Parameter: @var{n}.
- Output a formfeed character, or @var{n} many if a parameter is given.
- @item @nicode{~!}
- Force output. No parameters.
- At the end of output, call @code{force-output} to flush any buffers on
- the destination (@pxref{Buffering}). @nicode{~!} can occur anywhere in
- the format string, but the force is done at the end of output.
- When output is to a string (destination @code{#f}), @nicode{~!} does
- nothing.
- @item @nicode{~newline} (ie.@: newline character)
- Continuation line. No parameters.
- Skip this newline and any following whitespace in the format string,
- ie.@: don't send it to the output. This can be used to break up a
- long format string for readability, but not print the extra
- whitespace.
- @example
- (format #f "abc~
- ~d def~
- ~d" 1 2) @result{} "abc1 def2"
- @end example
- @nicode{~:newline} skips the newline but leaves any further whitespace
- to be printed normally.
- @nicode{~@@newline} prints the newline then skips following
- whitespace.
- @item @nicode{~(} @nicode{~)}
- Case conversion. No parameters.
- Between @nicode{~(} and @nicode{~)} the case of all output is changed.
- The modifiers on @nicode{~(} control the conversion.
- @itemize @w{}
- @item
- @nicode{~(} --- lower case.
- @c
- @c FIXME: The : and @ modifiers are not yet documented because the
- @c code applies string-capitalize and string-capitalize-first to each
- @c separate format:out-str call, which has various subtly doubtful
- @c effects. And worse they're applied to individual characters,
- @c including literal characters in the format string, which has the
- @c silly effect of being always an upcase.
- @c
- @c The Common Lisp spec is apparently for the capitalization to be
- @c applied in one hit to the whole of the output between ~( and ~).
- @c (This can no doubt be implemented without accumulating all that
- @c text, just by keeping a state or the previous char to tell whether
- @c within a word.)
- @c
- @c @item
- @c @nicode{:} --- first letter of each word upper case, the rest lower
- @c case, as per the @code{string-capitalize} function (@pxref{Alphabetic
- @c Case Mapping}).
- @c @item
- @c @nicode{@@} --- first letter of just the first word upper case, the
- @c rest lower case.
- @c
- @item
- @nicode{~:@@(} --- upper case.
- @end itemize
- For example,
- @example
- (format #t "~(Hello~)") @print{} hello
- (format #t "~:@@(Hello~)") @print{} HELLO
- @end example
- In the future it's intended the modifiers @nicode{:} and @nicode{@@}
- alone will capitalize the first letters of words, as per Common Lisp
- @code{format}, but the current implementation of this is flawed and
- not recommended for use.
- Case conversions do not nest, currently. This might change in the
- future, but if it does then it will be to Common Lisp style where the
- outermost conversion has priority, overriding inner ones (making those
- fairly pointless).
- @item @nicode{~@{} @nicode{~@}}
- Iteration. Parameter: @var{maxreps} (for @nicode{~@{}).
- The format between @nicode{~@{} and @nicode{~@}} is iterated. The
- modifiers to @nicode{~@{} determine how arguments are taken. The
- default is a list argument with each iteration successively consuming
- elements from it. This is a convenient way to output a whole list.
- @example
- (format #t "~@{~d~@}" '(1 2 3)) @print{} 123
- (format #t "~@{~s=~d ~@}" '("x" 1 "y" 2)) @print{} "x"=1 "y"=2
- @end example
- @nicode{~:@{} takes a single argument which is a list of lists, each
- of those contained lists gives the arguments for the iterated format.
- @c @print{} on a new line here to avoid overflowing page width in DVI
- @example
- (format #t "~:@{~dx~d ~@}" '((1 2) (3 4) (5 6)))
- @print{} 1x2 3x4 5x6
- @end example
- @nicode{~@@@{} takes arguments directly, with each iteration
- successively consuming arguments.
- @example
- (format #t "~@@@{~d~@}" 1 2 3) @print{} 123
- (format #t "~@@@{~s=~d ~@}" "x" 1 "y" 2) @print{} "x"=1 "y"=2
- @end example
- @nicode{~:@@@{} takes list arguments, one argument for each iteration,
- using that list for the format.
- @c @print{} on a new line here to avoid overflowing page width in DVI
- @example
- (format #t "~:@@@{~dx~d ~@}" '(1 2) '(3 4) '(5 6))
- @print{} 1x2 3x4 5x6
- @end example
- Iterating stops when there are no more arguments or when the
- @var{maxreps} parameter to @nicode{~@{} is reached (default no
- maximum).
- @example
- (format #t "~2@{~d~@}" '(1 2 3 4)) @print{} 12
- @end example
- If the format between @nicode{~@{} and @nicode{~@}} is empty, then a
- format string argument is taken (before iteration argument(s)) and
- used instead. This allows a sub-format (like @nicode{~?} above) to be
- iterated.
- @example
- (format #t "~@{~@}" "~d" '(1 2 3)) @print{} 123
- @end example
- @c FIXME: What is the @nicode{:} modifier to ~} meant to do? The
- @c Common Lisp spec says it's a minimum of 1 iteration, but the
- @c format.scm code seems to merely make it have MAXREPS default to 1.
- Iterations can be nested, an inner iteration operates in the same way
- as described, but of course on the arguments the outer iteration
- provides it. This can be used to work into nested list structures.
- For example in the following the inner @nicode{~@{~d~@}x} is applied
- to @code{(1 2)} then @code{(3 4 5)} etc.
- @example
- (format #t "~@{~@{~d~@}x~@}" '((1 2) (3 4 5))) @print{} 12x345x
- @end example
- See also @nicode{~^} below for escaping from iteration.
- @item @nicode{~[} @nicode{~;} @nicode{~]}
- Conditional. Parameter: @var{selector}.
- A conditional block is delimited by @nicode{~[} and @nicode{~]}, and
- @nicode{~;} separates clauses within the block. @nicode{~[} takes an
- integer argument and that number clause is used. The first clause is
- number 0.
- @example
- (format #f "~[peach~;banana~;mango~]" 1) @result{} "banana"
- @end example
- The @var{selector} parameter can be used for the clause number,
- instead of taking an argument.
- @example
- (format #f "~2[peach~;banana~;mango~]") @result{} "mango"
- @end example
- If the clause number is out of range then nothing is output. Or the
- last clause can be @nicode{~:;} to use that for a number out of range.
- @example
- (format #f "~[banana~;mango~]" 99) @result{} ""
- (format #f "~[banana~;mango~:;fruit~]" 99) @result{} "fruit"
- @end example
- @nicode{~:[} treats the argument as a flag, and expects two clauses.
- The first is used if the argument is @code{#f} or the second
- otherwise.
- @example
- (format #f "~:[false~;not false~]" #f) @result{} "false"
- (format #f "~:[false~;not false~]" 'abc) @result{} "not false"
- (let ((n 3))
- (format #t "~d gnu~:[s are~; is~] here" n (= 1 n)))
- @print{} 3 gnus are here
- @end example
- @nicode{~@@[} also treats the argument as a flag, and expects one
- clause. If the argument is @code{#f} then no output is produced and
- the argument is consumed, otherwise the clause is used and the
- argument is not consumed, it's left for the clause. This can be used
- for instance to suppress output if @code{#f} means something not
- available.
- @example
- (format #f "~@@[temperature=~d~]" 27) @result{} "temperature=27"
- (format #f "~@@[temperature=~d~]" #f) @result{} ""
- @end example
- @item @nicode{~^}
- Escape. Parameters: @var{val1}, @var{val2}, @var{val3}.
- Stop formatting if there are no more arguments. This can be used for
- instance to have a format string adapt to a variable number of
- arguments.
- @example
- (format #t "~d~^ ~d" 1) @print{} 1
- (format #t "~d~^ ~d" 1 2) @print{} 1 2
- @end example
- Within a @nicode{~@{} @nicode{~@}} iteration, @nicode{~^} stops the
- current iteration step if there are no more arguments to that step,
- but continuing with possible further steps and the rest of the format.
- This can be used for instance to avoid a separator on the last
- iteration, or to adapt to variable length argument lists.
- @example
- (format #f "~@{~d~^/~@} go" '(1 2 3)) @result{} "1/2/3 go"
- (format #f "~:@{ ~d~^~d~@} go" '((1) (2 3))) @result{} " 1 23 go"
- @end example
- @c For reference, format.scm doesn't implement that Common Lisp ~:^
- @c modifier which stops the entire iterating of ~:{ or ~@:{.
- @c FIXME: Believe the Common Lisp spec is for ~^ within ~[ ~]
- @c conditional to terminate the whole format (or iteration step if in
- @c an iteration). But format.scm seems to terminate just the
- @c conditional form.
- @c
- @c (format #f "~[abc~^def~;ghi~] blah" 0)
- @c @result{} "abc blah" ;; looks wrong
- @c FIXME: Believe the Common Lisp spec is for ~^ within ~( ~) to end
- @c that case conversion and then also terminate the whole format (or
- @c iteration step if in an iteration). But format.scm doesn't seem
- @c to do that quite right.
- @c
- @c (format #f "~d ~^ ~d" 1) @result{} "1 "
- @c (format #f "~(~d ~^ ~d~)" 1) @result{} ERROR
- Within a @nicode{~?} sub-format, @nicode{~^} operates just on that
- sub-format. If it terminates the sub-format then the originating
- format will still continue.
- @example
- (format #t "~? items" "~d~^ ~d" '(1)) @print{} 1 items
- (format #t "~? items" "~d~^ ~d" '(1 2)) @print{} 1 2 items
- @end example
- The parameters to @nicode{~^} (which are numbers) change the condition
- used to terminate. For a single parameter, termination is when that
- value is zero (notice this makes plain @nicode{~^} equivalent to
- @nicode{~#^}). For two parameters, termination is when those two are
- equal. For three parameters, termination is when @math{@var{val1}
- @le{} @var{val2}} and @math{@var{val2} @le{} @var{val3}}.
- @c FIXME: Good examples of these?
- @item @nicode{~q}
- Inquiry message. Insert a copyright message into the output.
- @nicode{~:q} inserts the format implementation version.
- @end table
- @sp 1
- It's an error if there are not enough arguments for the escapes in the
- format string, but any excess arguments are ignored.
- Iterations @nicode{~@{} @nicode{~@}} and conditionals @nicode{~[}
- @nicode{~;} @nicode{~]} can be nested, but must be properly nested,
- meaning the inner form must be entirely within the outer form. So
- it's not possible, for instance, to try to conditionalize the endpoint
- of an iteration.
- @example
- (format #t "~@{ ~[ ... ~] ~@}" ...) ;; good
- (format #t "~@{ ~[ ... ~@} ... ~]" ...) ;; bad
- @end example
- The same applies to case conversions @nicode{~(} @nicode{~)}, they
- must properly nest with respect to iterations and conditionals (though
- currently a case conversion cannot nest within another case
- conversion).
- When a sub-format (@nicode{~?}) is used, that sub-format string must
- be self-contained. It cannot for instance give a @nicode{~@{} to
- begin an iteration form and have the @nicode{~@}} up in the
- originating format, or similar.
- @end deffn
- @sp 1
- Guile contains a @code{format} procedure even when the module
- @code{(ice-9 format)} is not loaded. The default @code{format} is
- @code{simple-format} (@pxref{Simple Output}), it doesn't support all
- escape sequences documented in this section, and will signal an error if
- you try to use one of them. The reason for two versions is that the
- full @code{format} is fairly large and requires some time to load.
- @code{simple-format} is often adequate too.
- @quotation Note
- Beware that when @code{(ice-9 format)} is loaded, it replaces the
- binding for @code{format} on the toplevel. If your module loads
- another module that loads @code{(ice-9 format)}, then your module
- will see the @code{format} function from @code{(ice-9 format)},
- even if it does not itself import @code{(ice-9 format)}.
- @emph{This is legacy behavior and may be removed in a future Guile
- version.}
- @end quotation
- @node File Tree Walk
- @section File Tree Walk
- @cindex file tree walk
- @cindex file system traversal
- @cindex directory traversal
- The functions in this section traverse a tree of files and
- directories. They come in two flavors: the first one is a high-level
- functional interface, and the second one is similar to the C @code{ftw}
- and @code{nftw} routines (@pxref{Working with Directory Trees,,, libc,
- GNU C Library Reference Manual}).
- @example
- (use-modules (ice-9 ftw))
- @end example
- @sp 1
- @deffn {Scheme Procedure} file-system-tree file-name [enter? [stat]]
- Return a tree of the form @code{(@var{file-name} @var{stat}
- @var{children} ...)} where @var{stat} is the result of @code{(@var{stat}
- @var{file-name})} and @var{children} are similar structures for each
- file contained in @var{file-name} when it designates a directory.
- The optional @var{enter?} predicate is invoked as @code{(@var{enter?}
- @var{name} @var{stat})} and should return true to allow recursion into
- directory @var{name}; the default value is a procedure that always
- returns @code{#t}. When a directory does not match @var{enter?}, it
- nonetheless appears in the resulting tree, only with zero children.
- The @var{stat} argument is optional and defaults to @code{lstat}, as for
- @code{file-system-fold} (see below.)
- The example below shows how to obtain a hierarchical listing of the
- files under the @file{module/language} directory in the Guile source
- tree, discarding their @code{stat} info:
- @example
- (use-modules (ice-9 match))
- (define remove-stat
- ;; Remove the `stat' object the `file-system-tree' provides
- ;; for each file in the tree.
- (match-lambda
- ((name stat) ; flat file
- name)
- ((name stat children ...) ; directory
- (list name (map remove-stat children)))))
- (let ((dir (string-append (assq-ref %guile-build-info 'top_srcdir)
- "/module/language")))
- (remove-stat (file-system-tree dir)))
- @result{}
- ("language"
- (("value" ("spec.go" "spec.scm"))
- ("scheme"
- ("spec.go"
- "spec.scm"
- "compile-tree-il.scm"
- "decompile-tree-il.scm"
- "decompile-tree-il.go"
- "compile-tree-il.go"))
- ("tree-il"
- ("spec.go"
- "fix-letrec.go"
- "inline.go"
- "fix-letrec.scm"
- "compile-glil.go"
- "spec.scm"
- "optimize.scm"
- "primitives.scm"
- @dots{}))
- @dots{}))
- @end example
- @end deffn
- @cindex file system combinator
- It is often desirable to process directories entries directly, rather
- than building up a tree of entries in memory, like
- @code{file-system-tree} does. The following procedure, a
- @dfn{combinator}, is designed to allow directory entries to be processed
- directly as a directory tree is traversed; in fact,
- @code{file-system-tree} is implemented in terms of it.
- @deffn {Scheme Procedure} file-system-fold enter? leaf down up skip error init file-name [stat]
- Traverse the directory at @var{file-name}, recursively, and return the
- result of the successive applications of the @var{leaf}, @var{down},
- @var{up}, and @var{skip} procedures as described below.
- Enter sub-directories only when @code{(@var{enter?} @var{path}
- @var{stat} @var{result})} returns true. When a sub-directory is
- entered, call @code{(@var{down} @var{path} @var{stat} @var{result})},
- where @var{path} is the path of the sub-directory and @var{stat} the
- result of @code{(false-if-exception (@var{stat} @var{path}))}; when it is
- left, call @code{(@var{up} @var{path} @var{stat} @var{result})}.
- For each file in a directory, call @code{(@var{leaf} @var{path}
- @var{stat} @var{result})}.
- When @var{enter?} returns @code{#f}, or when an unreadable directory is
- encountered, call @code{(@var{skip} @var{path} @var{stat}
- @var{result})}.
- When @var{file-name} names a flat file, @code{(@var{leaf} @var{path}
- @var{stat} @var{init})} is returned.
- When an @code{opendir} or @var{stat} call fails, call @code{(@var{error}
- @var{path} @var{stat} @var{errno} @var{result})}, with @var{errno} being
- the operating system error number that was raised---e.g.,
- @code{EACCES}---and @var{stat} either @code{#f} or the result of the
- @var{stat} call for that entry, when available.
- The special @file{.} and @file{..} entries are not passed to these
- procedures. The @var{path} argument to the procedures is a full file
- name---e.g., @code{"../foo/bar/gnu"}; if @var{file-name} is an absolute
- file name, then @var{path} is also an absolute file name. Files and
- directories, as identified by their device/inode number pair, are
- traversed only once.
- The optional @var{stat} argument defaults to @code{lstat}, which means
- that symbolic links are not followed; the @code{stat} procedure can be
- used instead when symbolic links are to be followed (@pxref{File System,
- stat}).
- The example below illustrates the use of @code{file-system-fold}:
- @example
- (define (total-file-size file-name)
- "Return the size in bytes of the files under FILE-NAME (similar
- to `du --apparent-size' with GNU Coreutils.)"
- (define (enter? name stat result)
- ;; Skip version control directories.
- (not (member (basename name) '(".git" ".svn" "CVS"))))
- (define (leaf name stat result)
- ;; Return RESULT plus the size of the file at NAME.
- (+ result (stat:size stat)))
- ;; Count zero bytes for directories.
- (define (down name stat result) result)
- (define (up name stat result) result)
- ;; Likewise for skipped directories.
- (define (skip name stat result) result)
- ;; Ignore unreadable files/directories but warn the user.
- (define (error name stat errno result)
- (format (current-error-port) "warning: ~a: ~a~%"
- name (strerror errno))
- result)
- (file-system-fold enter? leaf down up skip error
- 0 ; initial counter is zero bytes
- file-name))
- (total-file-size ".")
- @result{} 8217554
- (total-file-size "/dev/null")
- @result{} 0
- @end example
- @end deffn
- The alternative C-like functions are described below.
- @deffn {Scheme Procedure} scandir name [select? [entry<?]]
- Return the list of the names of files contained in directory @var{name}
- that match predicate @var{select?} (by default, all files). The
- returned list of file names is sorted according to @var{entry<?}, which
- defaults to @code{string-locale<?} such that file names are sorted in
- the locale's alphabetical order (@pxref{Text Collation}). Return
- @code{#f} when @var{name} is unreadable or is not a directory.
- This procedure is modeled after the C library function of the same name
- (@pxref{Scanning Directory Content,,, libc, GNU C Library Reference
- Manual}).
- @end deffn
- @deffn {Scheme Procedure} ftw startname proc ['hash-size n]
- Walk the file system tree descending from @var{startname}, calling
- @var{proc} for each file and directory.
- Hard links and symbolic links are followed. A file or directory is
- reported to @var{proc} only once, and skipped if seen again in another
- place. One consequence of this is that @code{ftw} is safe against
- circularly linked directory structures.
- Each @var{proc} call is @code{(@var{proc} filename statinfo flag)} and
- it should return @code{#t} to continue, or any other value to stop.
- @var{filename} is the item visited, being @var{startname} plus a
- further path and the name of the item. @var{statinfo} is the return
- from @code{stat} (@pxref{File System}) on @var{filename}. @var{flag}
- is one of the following symbols,
- @table @code
- @item regular
- @var{filename} is a file, this includes special files like devices,
- named pipes, etc.
- @item directory
- @var{filename} is a directory.
- @item invalid-stat
- An error occurred when calling @code{stat}, so nothing is known.
- @var{statinfo} is @code{#f} in this case.
- @item directory-not-readable
- @var{filename} is a directory, but one which cannot be read and hence
- won't be recursed into.
- @item symlink
- @var{filename} is a dangling symbolic link. Symbolic links are
- normally followed and their target reported, the link itself is
- reported if the target does not exist.
- @end table
- The return value from @code{ftw} is @code{#t} if it ran to completion,
- or otherwise the non-@code{#t} value from @var{proc} which caused the
- stop.
- Optional argument symbol @code{hash-size} and an integer can be given
- to set the size of the hash table used to track items already visited.
- (@pxref{Hash Table Reference})
- @c Actually, it's probably safe to escape from ftw, just need to
- @c check it.
- @c
- In the current implementation, returning non-@code{#t} from @var{proc}
- is the only valid way to terminate @code{ftw}. @var{proc} must not
- use @code{throw} or similar to escape.
- @end deffn
- @deffn {Scheme Procedure} nftw startname proc ['chdir] ['depth] ['hash-size n] ['mount] ['physical]
- Walk the file system tree starting at @var{startname}, calling
- @var{proc} for each file and directory. @code{nftw} has extra
- features over the basic @code{ftw} described above.
- Like @code{ftw}, hard links and symbolic links are followed. A file
- or directory is reported to @var{proc} only once, and skipped if seen
- again in another place. One consequence of this is that @code{nftw}
- is safe against circular linked directory structures.
- Each @var{proc} call is @code{(@var{proc} filename statinfo flag
- base level)} and it should return @code{#t} to continue, or any
- other value to stop.
- @var{filename} is the item visited, being @var{startname} plus a
- further path and the name of the item. @var{statinfo} is the return
- from @code{stat} on @var{filename} (@pxref{File System}). @var{base}
- is an integer offset into @var{filename} which is where the basename
- for this item begins. @var{level} is an integer giving the directory
- nesting level, starting from 0 for the contents of @var{startname} (or
- that item itself if it's a file). @var{flag} is one of the following
- symbols,
- @table @code
- @item regular
- @var{filename} is a file, including special files like devices, named
- pipes, etc.
- @item directory
- @var{filename} is a directory.
- @item directory-processed
- @var{filename} is a directory, and its contents have all been visited.
- This flag is given instead of @code{directory} when the @code{depth}
- option below is used.
- @item invalid-stat
- An error occurred when applying @code{stat} to @var{filename}, so
- nothing is known about it. @var{statinfo} is @code{#f} in this case.
- @item directory-not-readable
- @var{filename} is a directory, but one which cannot be read and hence
- won't be recursed into.
- @item stale-symlink
- @var{filename} is a dangling symbolic link. Links are normally
- followed and their target reported, the link itself is reported if its
- target does not exist.
- @item symlink
- When the @code{physical} option described below is used, this
- indicates @var{filename} is a symbolic link whose target exists (and
- is not being followed).
- @end table
- The following optional arguments can be given to modify the way
- @code{nftw} works. Each is passed as a symbol (and @code{hash-size}
- takes a following integer value).
- @table @asis
- @item @code{chdir}
- Change to the directory containing the item before calling @var{proc}.
- When @code{nftw} returns the original current directory is restored.
- Under this option, generally the @var{base} parameter to each
- @var{proc} call should be used to pick out the base part of the
- @var{filename}. The @var{filename} is still a path but with a changed
- directory it won't be valid (unless the @var{startname} directory was
- absolute).
- @item @code{depth}
- Visit files ``depth first'', meaning @var{proc} is called for the
- contents of each directory before it's called for the directory
- itself. Normally a directory is reported first, then its contents.
- Under this option, the @var{flag} to @var{proc} for a directory is
- @code{directory-processed} instead of @code{directory}.
- @item @code{hash-size @var{n}}
- Set the size of the hash table used to track items already visited.
- (@pxref{Hash Table Reference})
- @item @code{mount}
- Don't cross a mount point, meaning only visit items on the same
- file system as @var{startname} (ie.@: the same @code{stat:dev}).
- @item @code{physical}
- Don't follow symbolic links, instead report them to @var{proc} as
- @code{symlink}. Dangling links (those whose target doesn't exist) are
- still reported as @code{stale-symlink}.
- @end table
- The return value from @code{nftw} is @code{#t} if it ran to
- completion, or otherwise the non-@code{#t} value from @var{proc} which
- caused the stop.
- @c For reference, one reason not to escape is that the current
- @c directory is not saved and restored with dynamic-wind. Maybe
- @c changing that would be enough to allow escaping.
- @c
- In the current implementation, returning non-@code{#t} from @var{proc}
- is the only valid way to terminate @code{ftw}. @var{proc} must not
- use @code{throw} or similar to escape.
- @end deffn
- @node Queues
- @section Queues
- @cindex queues
- @tindex Queues
- @noindent
- The functions in this section are provided by
- @example
- (use-modules (ice-9 q))
- @end example
- This module implements queues holding arbitrary scheme objects and
- designed for efficient first-in / first-out operations.
- @code{make-q} creates a queue, and objects are entered and removed
- with @code{enq!} and @code{deq!}. @code{q-push!} and @code{q-pop!}
- can be used too, treating the front of the queue like a stack.
- @sp 1
- @deffn {Scheme Procedure} make-q
- Return a new queue.
- @end deffn
- @deffn {Scheme Procedure} q? obj
- Return @code{#t} if @var{obj} is a queue, or @code{#f} if not.
- Note that queues are not a distinct class of objects but are
- implemented with cons cells. For that reason certain list structures
- can get @code{#t} from @code{q?}.
- @end deffn
- @deffn {Scheme Procedure} enq! q obj
- Add @var{obj} to the rear of @var{q}, and return @var{q}.
- @end deffn
- @deffn {Scheme Procedure} deq! q
- @deffnx {Scheme Procedure} q-pop! q
- Remove and return the front element from @var{q}. If @var{q} is
- empty, a @code{q-empty} exception is thrown.
- @code{deq!} and @code{q-pop!} are the same operation, the two names
- just let an application match @code{enq!} with @code{deq!}, or
- @code{q-push!} with @code{q-pop!}.
- @end deffn
- @deffn {Scheme Procedure} q-push! q obj
- Add @var{obj} to the front of @var{q}, and return @var{q}.
- @end deffn
- @deffn {Scheme Procedure} q-length q
- Return the number of elements in @var{q}.
- @end deffn
- @deffn {Scheme Procedure} q-empty? q
- Return true if @var{q} is empty.
- @end deffn
- @deffn {Scheme Procedure} q-empty-check q
- Throw a @code{q-empty} exception if @var{q} is empty.
- @end deffn
- @deffn {Scheme Procedure} q-front q
- Return the first element of @var{q} (without removing it). If @var{q}
- is empty, a @code{q-empty} exception is thrown.
- @end deffn
- @deffn {Scheme Procedure} q-rear q
- Return the last element of @var{q} (without removing it). If @var{q}
- is empty, a @code{q-empty} exception is thrown.
- @end deffn
- @deffn {Scheme Procedure} q-remove! q obj
- Remove all occurrences of @var{obj} from @var{q}, and return @var{q}.
- @var{obj} is compared to queue elements using @code{eq?}.
- @end deffn
- @sp 1
- @cindex @code{q-empty}
- The @code{q-empty} exceptions described above are thrown just as
- @code{(throw 'q-empty)}, there's no message etc like an error throw.
- A queue is implemented as a cons cell, the @code{car} containing a
- list of queued elements, and the @code{cdr} being the last cell in
- that list (for ease of enqueuing).
- @example
- (@var{list} . @var{last-cell})
- @end example
- @noindent
- If the queue is empty, @var{list} is the empty list and
- @var{last-cell} is @code{#f}.
- An application can directly access the queue list if desired, for
- instance to search the elements or to insert at a specific point.
- @deffn {Scheme Procedure} sync-q! q
- Recompute the @var{last-cell} field in @var{q}.
- All the operations above maintain @var{last-cell} as described, so
- normally there's no need for @code{sync-q!}. But if an application
- modifies the queue @var{list} then it must either maintain
- @var{last-cell} similarly, or call @code{sync-q!} to recompute it.
- @end deffn
- @node Streams
- @section Streams
- @cindex streams
- This section documents Guile's legacy stream module. For a more
- complete and portable stream library, @pxref{SRFI-41}.
- A stream represents a sequence of values, each of which is calculated
- only when required. This allows large or even infinite sequences to
- be represented and manipulated with familiar operations like ``car'',
- ``cdr'', ``map'' or ``fold''. In such manipulations only as much as
- needed is actually held in memory at any one time. The functions in
- this section are available from
- @example
- (use-modules (ice-9 streams))
- @end example
- Streams are implemented using promises (@pxref{Delayed Evaluation}),
- which is how the underlying calculation of values is made only when
- needed, and the values then retained so the calculation is not
- repeated.
- @noindent
- Here is a simple example producing a stream of all odd numbers,
- @example
- (define odds (make-stream (lambda (state)
- (cons state (+ state 2)))
- 1))
- (stream-car odds) @result{} 1
- (stream-car (stream-cdr odds)) @result{} 3
- @end example
- @noindent
- @code{stream-map} could be used to derive a stream of odd squares,
- @example
- (define (square n) (* n n))
- (define oddsquares (stream-map square odds))
- @end example
- These are infinite sequences, so it's not possible to convert them to
- a list, but they could be printed (infinitely) with for example
- @example
- (stream-for-each (lambda (n sq)
- (format #t "~a squared is ~a\n" n sq))
- odds oddsquares)
- @print{}
- 1 squared is 1
- 3 squared is 9
- 5 squared is 25
- 7 squared is 49
- @dots{}
- @end example
- @sp 1
- @deffn {Scheme Procedure} make-stream proc initial-state
- Return a new stream, formed by calling @var{proc} successively.
- Each call is @code{(@var{proc} @var{state})}, it should return a pair,
- the @code{car} being the value for the stream, and the @code{cdr}
- being the new @var{state} for the next call. For the first call
- @var{state} is the given @var{initial-state}. At the end of the
- stream, @var{proc} should return some non-pair object.
- @end deffn
- @deffn {Scheme Procedure} stream-car stream
- Return the first element from @var{stream}. @var{stream} must not be
- empty.
- @end deffn
- @deffn {Scheme Procedure} stream-cdr stream
- Return a stream which is the second and subsequent elements of
- @var{stream}. @var{stream} must not be empty.
- @end deffn
- @deffn {Scheme Procedure} stream-null? stream
- Return true if @var{stream} is empty.
- @end deffn
- @deffn {Scheme Procedure} list->stream list
- @deffnx {Scheme Procedure} vector->stream vector
- Return a stream with the contents of @var{list} or @var{vector}.
- @var{list} or @var{vector} should not be modified subsequently, since
- it's unspecified whether changes there will be reflected in the stream
- returned.
- @end deffn
- @deffn {Scheme Procedure} port->stream port readproc
- Return a stream which is the values obtained by reading from @var{port}
- using @var{readproc}. Each read call is @code{(@var{readproc}
- @var{port})}, and it should return an EOF object (@pxref{Binary I/O}) at
- the end of input.
- For example a stream of characters from a file,
- @example
- (port->stream (open-input-file "/foo/bar.txt") read-char)
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream->list stream
- Return a list which is the entire contents of @var{stream}.
- @end deffn
- @deffn {Scheme Procedure} stream->reversed-list stream
- Return a list which is the entire contents of @var{stream}, but in
- reverse order.
- @end deffn
- @deffn {Scheme Procedure} stream->list&length stream
- Return two values (@pxref{Multiple Values}), being firstly a list
- which is the entire contents of @var{stream}, and secondly the number
- of elements in that list.
- @end deffn
- @deffn {Scheme Procedure} stream->reversed-list&length stream
- Return two values (@pxref{Multiple Values}) being firstly a list which
- is the entire contents of @var{stream}, but in reverse order, and
- secondly the number of elements in that list.
- @end deffn
- @deffn {Scheme Procedure} stream->vector stream
- Return a vector which is the entire contents of @var{stream}.
- @end deffn
- @defun stream-fold proc init stream1 stream2 @dots{}
- Apply @var{proc} successively over the elements of the given streams,
- from first to last until the end of the shortest stream is reached.
- Return the result from the last @var{proc} call.
- Each call is @code{(@var{proc} elem1 elem2 @dots{} prev)}, where each
- @var{elem} is from the corresponding @var{stream}. @var{prev} is the
- return from the previous @var{proc} call, or the given @var{init} for
- the first call.
- @end defun
- @defun stream-for-each proc stream1 stream2 @dots{}
- Call @var{proc} on the elements from the given @var{stream}s. The
- return value is unspecified.
- Each call is @code{(@var{proc} elem1 elem2 @dots{})}, where each
- @var{elem} is from the corresponding @var{stream}.
- @code{stream-for-each} stops when it reaches the end of the shortest
- @var{stream}.
- @end defun
- @defun stream-map proc stream1 stream2 @dots{}
- Return a new stream which is the results of applying @var{proc} to the
- elements of the given @var{stream}s.
- Each call is @code{(@var{proc} elem1 elem2 @dots{})}, where each
- @var{elem} is from the corresponding @var{stream}. The new stream
- ends when the end of the shortest given @var{stream} is reached.
- @end defun
- @node Buffered Input
- @section Buffered Input
- @cindex Buffered input
- @cindex Line continuation
- The following functions are provided by
- @example
- (use-modules (ice-9 buffered-input))
- @end example
- A buffered input port allows a reader function to return chunks of
- characters which are to be handed out on reading the port. A notion
- of further input for an application level logical expression is
- maintained too, and passed through to the reader.
- @deffn {Scheme Procedure} make-buffered-input-port reader
- Create an input port which returns characters obtained from the given
- @var{reader} function. @var{reader} is called (@var{reader} cont),
- and should return a string or an EOF object.
- The new port gives precisely the characters returned by @var{reader},
- nothing is added, so if any newline characters or other separators are
- desired they must come from the reader function.
- The @var{cont} parameter to @var{reader} is @code{#f} for initial
- input, or @code{#t} when continuing an expression. This is an
- application level notion, set with
- @code{set-buffered-input-continuation?!} below. If the user has
- entered a partial expression then it allows @var{reader} for instance
- to give a different prompt to show more is required.
- @end deffn
- @deffn {Scheme Procedure} make-line-buffered-input-port reader
- @cindex Line buffered input
- Create an input port which returns characters obtained from the
- specified @var{reader} function, similar to
- @code{make-buffered-input-port} above, but where @var{reader} is
- expected to be a line-oriented.
- @var{reader} is called (@var{reader} cont), and should return a string
- or an EOF object as above. Each string is a line of input without a
- newline character, the port code inserts a newline after each string.
- @end deffn
- @deffn {Scheme Procedure} set-buffered-input-continuation?! port cont
- Set the input continuation flag for a given buffered input
- @var{port}.
- An application uses this by calling with a @var{cont} flag of
- @code{#f} when beginning to read a new logical expression. For
- example with the Scheme @code{read} function (@pxref{Scheme Read}),
- @example
- (define my-port (make-buffered-input-port my-reader))
- (set-buffered-input-continuation?! my-port #f)
- (let ((obj (read my-port)))
- ...
- @end example
- @end deffn
- @c Local Variables:
- @c TeX-master: "guile.texi"
- @c End:
|