123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688 |
- % -*- Mode: TeX -*-
- % Pretty Printer Concepts
- % Printer
- % Printer Variables
- \def\writekeys#1{\vtop{\hbox{array base case circle escape gensym}
- \hbox{length level lines miser-width pprint-dispatch}
- \hbox{pretty radix readably right-margin #1}}}
- \def\writekeydescriptions#1{\param{array}---a \term{generalized boolean}.
- \param{base}---a \term{radix}.
- \param{case}---a \term{symbol} of \term{type} \f{(member :upcase :downcase :capitalize)}.
- \param{circle}---a \term{generalized boolean}.
- \param{escape}---a \term{generalized boolean}.
- \param{gensym}---a \term{generalized boolean}.
- \param{length}---a non-negative \term{integer}, or \nil.
- \param{level}---a non-negative \term{integer}, or \nil.
- \param{lines}---a non-negative \term{integer}, or \nil.
- \param{miser-width}---a non-negative \term{integer}, or \nil.
- \param{pprint-dispatch}---a \term{pprint dispatch table}.
- \param{pretty}---a \term{generalized boolean}.
- \param{radix}---a \term{generalized boolean}.
- \param{readably}---a \term{generalized boolean}.
- \param{right-margin}---a non-negative \term{integer}, or \nil.
- #1}
- %-------------------- Printer --------------------
- %%% ========== COPY-PPRINT-DISPATCH
- \begincom{copy-pprint-dispatch}\ftype{Function}
- %KMP: I'd like to change the name of this function to COPY-PPRINT-DISPATCH-TABLE.
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefunWithValues copy-pprint-dispatch {{\opt} table} {new-table}
- \label Arguments and Values::
- \param{table}---a \term{pprint dispatch table}, or \nil.
- \param{new-table}---a \term{fresh} \term{pprint dispatch table}.
- \label Description::
- Creates and returns a copy of the specified \param{table},
- or of \thevalueof{*print-pprint-dispatch*} if no \param{table} is specified,
- or of the initial \term{value} of \varref{*print-pprint-dispatch*} if \nil\ is specified.
- \label Examples:\None.
- \label Side Effects:\None.
- %% Sandra thinks this is excessive.
- %Creates a \term{pprint dispatch table}.
- \label Affected By:\None.
- \label Exceptional Situations::
- Should signal an error \oftype{type-error} if \param{table}
- is not a \term{pprint dispatch table}.
- \label See Also:\None.
- \label Notes:\None.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== FORMATTER
- \begincom{formatter}\ftype{Macro}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefmacWithValues formatter {control-string} {function}
- \label Arguments and Values::
- \param{control-string}---a \term{format string}; \noeval.
- \param{function}---a \term{function}.
- \label Description::
- Returns a \term{function} which has behavior equivalent to:
- \code
- #'(lambda (*standard-output* &rest arguments)
- (apply #'format t \i{control-string} arguments)
- \i{arguments-tail})
- \endcode
- where \i{arguments-tail} is either the tail of \i{arguments}
- which has as its \term{car} the argument that would be processed next
- if there were more format directives in the \param{control-string},
- or else \nil\ if no more \i{arguments} follow the most recently
- processed argument.
- \label Examples::
- %This doesn't look like valid syntax to me. --sjl 16 mar 92
- %\code
- %((formatter "~&~A~A") *standard-output* 'a 'b 'c)
- %\OUT AB
- %\EV (C)
- \code
- (funcall (formatter "~&~A~A") *standard-output* 'a 'b 'c)
- \OUT AB
- \EV (C)
- (format t (formatter "~&~A~A") 'a 'b 'c)
- \OUT AB
- \EV NIL
- \endcode
- \label Side Effects:\None.
- %% Sandra thinks this is excessive.
- %Might create a \term{closure} at run time.
- \label Affected By:\None.
- \label Exceptional Situations::
- Might signal an error (at macro expansion time or at run time) if the argument
- is not a valid \term{format string}.
- \label See Also::
- \funref{format}
- \label Notes:\None.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PPRINT-DISPATCH
- \begincom{pprint-dispatch}\ftype{Function}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefunWithValues pprint-dispatch {object {\opt} table} {function, found-p}
- \label Arguments and Values::
- \param{object}---an \term{object}.
- %!!! pprint dispatch table designator?? -kmp 16-Oct-91
- \param{table}---a \term{pprint dispatch table}, or \nil.
- \Default{\thevalueof{*print-pprint-dispatch*}}
- % It wasn't obvious if this should be a "function" or "function designator".
- % I asked x3j13 with issue PPRINT-DISPATCH-RETURN-VALUE, but rather than vote
- % on it, they just told me to use my discretion. Which is basically the same
- % as if they had approved the issue. "function designator" it is. -kmp 11-Feb-92
- \param{function}---a \term{function designator}.
- \param{found-p}---a \term{generalized boolean}.
- \label Description::
- Retrieves the highest priority function in \param{table} that is
- associated with a \term{type specifier} that matches \param{object}.
- The function is chosen by finding all of the \term{type specifiers} in \param{table}
- that match the \param{object} and
- selecting the highest priority function associated with any of these
- \term{type specifiers}. If there is more than one highest priority function,
- an arbitrary choice is made. If no \term{type specifiers} match the
- \param{object}, a function is returned that prints \param{object}
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- %with \varref{*print-pretty*} bound to \nil.
- using \funref{print-object}.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- The \term{secondary value}, \param{found-p}, is \term{true} if a matching
- \term{type specifier} was found in \param{table}, or \term{false} otherwise.
- If \param{table} is \nil,
- retrieval is done in the
- %initial value of \varref{*print-pprint-dispatch*}.
- \term{initial pprint dispatch table}.
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By::
- The state of the \param{table}.
- \label Exceptional Situations::
- Should signal an error \oftype{type-error} if \term{table} is neither a
- \term{pprint-dispatch-table} nor \nil.
- \label See Also:\None.
- \label Notes::
- \code
- (let ((*print-pretty* t))
- (write object :stream s))
- \EQ (funcall (pprint-dispatch object) s object)
- \endcode
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PPRINT-EXIT-IF-LIST-EXHAUSTED
- \begincom{pprint-exit-if-list-exhausted}\ftype{Local Macro}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefmacWithValues pprint-exit-if-list-exhausted {\noargs} {\nil}
- \label Arguments and Values:\None.
- \label Description::
- Tests whether or not the \param{list} passed to
- the \term{lexically current logical block}
- has been exhausted; \seesection\DynamicControlofOutput.
- If this \param{list} has been
- reduced to \nil, \funref{pprint-exit-if-list-exhausted} terminates the execution
- of the \term{lexically current logical block} except for the printing
- of the suffix. Otherwise \funref{pprint-exit-if-list-exhausted} returns \nil.
- \issue{LEXICAL-CONSTRUCT-GLOBAL-DEFINITION:UNDEFINED}
- Whether or not \macref{pprint-exit-if-list-exhausted} is \term{fbound} in the
- \term{global environment} is \term{implementation-dependent};
- however, the restrictions on redefinition and \term{shadowing} of
- \macref{pprint-exit-if-list-exhausted} are the same as for \term{symbols} in \thepackage{common-lisp}
- which are \term{fbound} in the \term{global environment}.
- The consequences of attempting to use \macref{pprint-exit-if-list-exhausted} outside
- of \macref{pprint-logical-block} are undefined.
- \endissue{LEXICAL-CONSTRUCT-GLOBAL-DEFINITION:UNDEFINED}
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- An error is signaled (at macro expansion time or at run time) if
- \funref{pprint-exit-if-list-exhausted} is used anywhere other than
- %syntactically nested
- lexically within a call on \macref{pprint-logical-block}.
- % It is undefined what happens if \funref{pprint-if-list-exhausted} is executed outside
- % of the dynamic extent of this \funref{pprint-logical-block}.
- Also, the consequences of executing \funref{pprint-if-list-exhausted} outside
- of the dynamic extent of the \macref{pprint-logical-block} which lexically
- contains it are undefined.
- \label See Also::
- \macref{pprint-logical-block}, \funref{pprint-pop}.
- \label Notes:\None.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PPRINT-FILL
- %%% ========== PPRINT-LINEAR
- %%% ========== PPRINT-TABULAR
- \begincom{pprint-fill, pprint-linear, pprint-tabular}\ftype{Function}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefunWithValues pprint-fill {stream object {\opt} colon-p at-sign-p} {\nil}
- \DefunWithValues pprint-linear {stream object {\opt} colon-p at-sign-p} {\nil}
- \DefunWithValues pprint-tabular {stream object {\opt} colon-p at-sign-p tabsize} {\nil}
- \label Arguments and Values::
- \param{stream}---an \term{output} \term{stream designator}.
- \param{object}---an \term{object}.
- \param{colon-p}---a \term{generalized boolean}.
- \Default{\term{true}}
- \param{at-sign-p}---a \term{generalized boolean}.
- \Default{\term{implementation-dependent}}
- \param{tabsize}---a non-negative \term{integer}.
- \Default{\f{16}}
- \label Description::
- The functions \funref{pprint-fill}, \funref{pprint-linear}, and
- \funref{pprint-tabular} specify particular ways of \term{pretty printing}
- a \term{list} to \param{stream}.
- Each function prints parentheses around the output if and only
- if \param{colon-p} is \term{true}.
- Each function ignores its \param{at-sign-p} argument.
- (Both arguments are included even though only one is needed
- so that these functions can be used via \formatOp{/.../}
- and as \funref{set-pprint-dispatch} functions, as well as directly.)
- Each function handles abbreviation and the detection of circularity
- and sharing correctly, and uses \funref{write} to print \param{object}
- when it is a \term{non-list}.
- % KMP: The pretty printer proposal as adopted was ambiguous
- % in the preceding sentence. I tried to resolve the ambiguity
- % by changing the argument name and doing some rewording.
- % Dick Waters should double-check this interpretation.
- % Waters: Is ok.
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- If \param{object} is a \term{list} and
- if \thevalueof{*print-pretty*} is \term{false},
- each of these functions prints \param{object}
- using a minimum of \term{whitespace},
- as described in \secref\PrintingListsAndConses.
- Otherwise (if \param{object} is a \term{list} and
- if \thevalueof{*print-pretty*} is \term{true}):
- \beginlist
- \itemitem{\bull}
- \Thefunction{pprint-linear} prints a \term{list} either all on one line,
- or with each \term{element} on a separate line.
- \itemitem{\bull}
- \Thefunction{pprint-fill} prints a \term{list} with as many \term{elements}
- as possible on each line.
- \itemitem{\bull}
- \Thefunction{pprint-tabular} is the same as \funref{pprint-fill}
- except that it prints the \term{elements} so that they line up in columns.
- The \param{tabsize} specifies the column spacing in \term{ems},
- % KMP: Is this (1) the minimum intercolumn spacing, or
- % (2) the total spacing from the left edge of one column
- % to the left edge of the next?
- % Waters: (2)
- which is the total spacing from the leading edge of one column to
- the leading edge of the next.
- \endlist
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- \label Examples::
- Evaluating the following with a line length of \f{25} produces the output shown.
-
- \code
- (progn (princ "Roads ")
- (pprint-tabular *standard-output* '(elm main maple center) nil nil 8))
- Roads ELM MAIN
- MAPLE CENTER
- \endcode
- \label Side Effects::
- Performs output to the indicated \term{stream}.
- \label Affected By::
- The cursor position on the indicated \term{stream}, if it can be determined.
- \label Exceptional Situations:\None.
- \label See Also:\None.
- \label Notes::
- \Thefunction{pprint-tabular} could be defined as follows:
- \code
- (defun pprint-tabular (s list &optional (colon-p t) at-sign-p (tabsize nil))
- (declare (ignore at-sign-p))
- (when (null tabsize) (setq tabsize 16))
- (pprint-logical-block (s list :prefix (if colon-p "(" "")
- :suffix (if colon-p ")" ""))
- (pprint-exit-if-list-exhausted)
- (loop (write (pprint-pop) :stream s)
- (pprint-exit-if-list-exhausted)
- (write-char #\\Space s)
- (pprint-tab :section-relative 0 tabsize s)
- (pprint-newline :fill s))))
- \endcode
- Note that it would have been inconvenient to specify this function
- using \funref{format}, because of the need to pass its \param{tabsize} argument
- through to a \formatdirective{:T} nested within an iteration over a list.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PPRINT-INDENT
- \begincom{pprint-indent}\ftype{Function}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefunWithValues pprint-indent {relative-to n {\opt} stream} {\nil}
- \label Arguments and Values::
- \param{relative-to}---either \kwd{block} or \kwd{current}.
- \param{n}---a \term{real}.
- \param{stream}---an \term{output} \term{stream designator}.
- \Default{\term{standard output}}
- \label Description::
- \funref{pprint-indent} specifies the indentation to use in a logical block on \term{stream}.
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- If \param{stream} is a \term{pretty printing stream}
- and \thevalueof{*print-pretty*} is \term{true},
- \funref{pprint-indent} sets the indentation in the innermost
- dynamically enclosing logical block;
- otherwise, \funref{pprint-indent} has no effect.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- \param{N} specifies the indentation in
- \term{ems}. If \param{relative-to} is \kwd{block}, the indentation is set
- to the horizontal position of the first character in the \term{dynamically current logical block} plus \param{n}
- \term{ems}. If \param{relative-to} is \kwd{current}, the indentation is set
- to the current output position plus \param{n} \term{ems}. (For robustness
- in the face of variable-width fonts, it is advisable to use \kwd{current}
- with an \param{n} of zero whenever possible.)
- \param{N} can be negative;
- however, the total indentation cannot be moved
- left of the beginning of the line
- or left of the end of the rightmost per-line prefix---an attempt to move beyond
- one of these limits is treated
- % KMP: How?
- % (1) Is an error signaled,
- % or (2) or do we just min out at 0?
- % Waters: (2).
- the same as an attempt to move to that limit.
- Changes in indentation caused by \param{pprint-indent}
- do not take effect until after the next line break. In addition, in
- miser mode all calls to \funref{pprint-indent} are ignored, forcing the lines
- corresponding to the logical block to line up under the first character in
- the block.
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- An error is signaled if \param{relative-to} is any \term{object} other
- than \kwd{block} or \kwd{current}.
- \label See Also::
- {\secref\TildeI}
- \label Notes:\None.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PPRINT-LOGICAL-BLOCK
- \begincom{pprint-logical-block}\ftype{Macro}
- \issue{DECLS-AND-DOC}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefmacWithValuesNewline pprint-logical-block
- {\vtop{\hbox{\paren{stream-symbol object
- {\key} prefix per-line-prefix suffix}}
- \hbox{\starparam{declaration} \starparam{form}}}}
- {\nil}
- \label Arguments and Values::
- \param{stream-symbol}---a \term{stream variable designator}.
- \param{object}---an \term{object}; \eval.
- \kwd{prefix}---a \term{string}; \eval.
- \HairyDefault.
- \kwd{per-line-prefix}---a \term{string}; \eval.
- \HairyDefault.
- \kwd{suffix}---a \term{string}; \eval.
- \Default{the \term{null} \term{string}}
- \param{declaration}---a \misc{declare} \term{expression}; \noeval.
- \param{forms}---an \term{implicit progn}.
- \label Description::
- Causes printing to be grouped into a logical block.
- The logical block is printed to the \term{stream} that is the \term{value}
- of the \term{variable} denoted by \param{stream-symbol}.
- During the execution of the \term{forms},
- that \term{variable} is \term{bound} to a \term{pretty printing stream}
- that supports decisions about the arrangement of output
- and then forwards the output to the destination stream.
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- % If, during that context, \varref{*print-pretty*} becomes bound to \nil,
- % the stream ceases to behave as a \term{pretty printing stream}.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- All the standard printing functions
- (\eg \funref{write},
- \funref{princ},
- and \funref{terpri})
- can be used to print output to the \term{pretty printing stream}.
- All and only the output sent to this \term{pretty printing stream}
- is treated as being in the logical block.
-
- The \param{prefix} specifies a prefix to be printed before the beginning of
- the logical block.
- The \param{per-line-prefix} specifies a prefix that is printed before the block
- and at the beginning of each new line in the block.
- The \kwd{prefix} and \kwd{pre-line-prefix} \term{arguments} are mutually exclusive.
- If neither \kwd{prefix} nor \kwd{per-line-prefix} is specified,
- a \param{prefix} of the \term{null} \term{string} is assumed.
- The \param{suffix} specifies a suffix that is printed just after the logical block.
- The \param{object} is
- %interpreted as
- normally
- a \term{list} that the body \param{forms} are responsible for printing.
- If \param{object} is not a \term{list},
- it is printed using \funref{write}.
- (This makes it easier to write printing functions that are robust
- in the face of malformed arguments.)
- If \varref{*print-circle*}
- %%There's no such var. -kmp 14-Jan-91
- %(and possibly \varref{*print-shared*})
- is \term{non-nil} and \param{object} is a circular (or shared) reference to a \term{cons},
- then an appropriate ``\f{\#\i{n}\#}'' marker is printed. (This
- makes it easy to write printing functions that provide full support
- for circularity and sharing abbreviation.) If \varref{*print-level*} is not
- \nil\ and the logical block is at a dynamic nesting depth of greater
- than \varref{*print-level*} in logical blocks, ``\f{\#}'' is printed.
- (This makes easy to write printing functions that provide full support for depth
- abbreviation.)
-
- If either of the three conditions above occurs, the indicated output is
- printed on \param{stream-symbol} and the body \param{forms} are skipped
- along with the printing of the \kwd{prefix} and \kwd{suffix}.
- (If the body \param{forms} are not to be responsible for printing a list,
- then the first two tests above can be turned off by supplying \nil\ for
- the \param{object} argument.)
-
- In addition to the \param{object} argument of \macref{pprint-logical-block},
- the arguments of the standard printing functions (such as \funref{write},
- \funref{print}, \funref{prin1}, and \funref{pprint}, as well as the arguments
- of the standard \term{format directives} such as \formatOp{A}, \formatOp{S},
- (and \formatOp{W}) are all checked (when necessary) for circularity and sharing.
- However, such checking is not applied to the arguments of the
- functions \funref{write-line}, \funref{write-string}, and \funref{write-char}
- or to the literal text output by \funref{format}. A consequence of this is
- that you must use one of the latter functions if you want to print some
- literal text in the output that is not supposed to be checked for circularity
- or sharing.
- % (See the examples below.)
- The body \param{forms} of a \macref{pprint-logical-block} \term{form}
- must not perform any side-effects on the surrounding environment; for
- example, no \term{variables} must be assigned which have not been
- \term{bound} within its scope.
- % (See notes below for rationale.)
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- \Themacro{pprint-logical-block} may be used regardless of \thevalueof{*print-pretty*}.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By::
- \varref{*print-circle*}, \varref{*print-level*}.
- \label Exceptional Situations::
- An error \oftype{type-error} is signaled if any of the \kwd{suffix},
- \kwd{prefix}, or \kwd{per-line-prefix} is supplied but does not evaluate
- to a \term{string}.
- An error is signaled if \kwd{prefix} and \kwd{pre-line-prefix} are both used.
- \macref{pprint-logical-block} and the \term{pretty printing stream} it creates
- have \term{dynamic extent}. The consequences are undefined if, outside
- of this extent, output is attempted to the \term{pretty printing stream} it creates.
- It is also unspecified what happens if, within this extent, any output is
- sent directly to the underlying destination stream.
- \label See Also::
- \macref{pprint-pop},
- \macref{pprint-exit-if-list-exhausted},
- {\secref\TildeLessThanLogicalBlock}
- \label Notes::
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- One reason for using \themacro{pprint-logical-block} when \thevalueof{*print-pretty*}
- is \nil\ would be to allow it to perform checking for \term{dotted lists},
- as well as (in conjunction with \macref{pprint-pop})
- checking for \varref{*print-level*} or \varref{*print-length*} being exceeded.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- Detection of circularity and sharing is supported by the \term{pretty printer}
- by in essence performing requested output twice. On the first pass,
- circularities and sharing are detected and the actual outputting of characters
- is suppressed. On the second pass, the appropriate ``\f{\#\param{n}=}''
- and ``\f{\#\param{n}\#}'' markers are inserted and characters are output.
- This is why the restriction on side-effects is necessary.
- Obeying this restriction is facilitated by using \macref{pprint-pop},
- instead of an ordinary \macref{pop} when traversing a list being printed by
- the body \param{forms} of the \macref{pprint-logical-block} \term{form}.)
- \endissue{PRETTY-PRINT-INTERFACE}
- \endissue{DECLS-AND-DOC}
- \endcom
- %%% ========== PPRINT-NEWLINE
- \begincom{pprint-newline}\ftype{Function}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefunWithValues pprint-newline {kind {\opt} stream} {\nil}
- \label Arguments and Values::
- \param{kind}---one of \kwd{linear}, \kwd{fill}, \kwd{miser}, or \kwd{mandatory}.
- \param{stream}---a \term{stream designator}.
- \Default{\term{standard output}}
- \label Description::
- %% This follows from being a stream designator. -kmp 27-Aug-93
- % \param{Stream} defaults to \term{standard output}.
- % If it is \nil, \term{standard output} is used instead.
- % If it is \t, \term{terminal I/O} is used instead.
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- If \param{stream} is a \term{pretty printing stream}
- and \thevalueof{*print-pretty*} is \term{true},
- a line break is inserted in the output
- when the appropriate condition below is satisfied;
- otherwise, \funref{pprint-newline} has no effect.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- \param{Kind} specifies the style of conditional newline.
- This \term{parameter} is treated as follows:
- \beginlist
- \item{\kwd{linear}}
- This specifies a
- ``linear-style'' \term{conditional newline}.\idxtext{linear-style conditional newline}
- A line break is inserted
- if and only if the immediately containing \term{section}
- cannot be printed on one line.
- The effect of this is that line breaks are
- either inserted at every linear-style conditional newline in a logical block
- or at none of them.
- \item{\kwd{miser}}
- This specifies a
- ``miser-style'' \term{conditional newline}.\idxtext{miser-style conditional newline}
- A line break is inserted
- if and only if the immediately containing \term{section}
- cannot be printed on one line
- and miser style is in effect in the immediately containing logical block.
- The effect of this is that miser-style conditional newlines
- act like linear-style conditional newlines,
- but only when miser style is in effect.
- Miser style is in effect for a logical block if and only if
- the starting position of the logical block
- is less than or equal to
- \varref{*print-miser-width*} \term{ems} from the right margin.
- \item{\kwd{fill}}
- This specifies a
- ``fill-style'' \term{conditional newline}.\idxtext{fill-style conditional newline}
- A line break is inserted if and only if
- either (a) the following \term{section} cannot be printed
- on the end of the current line,
- (b) the preceding \term{section} was not printed on a single line,
- or (c) the immediately containing \term{section} cannot
- be printed on one line and miser style is in effect
- in the immediately containing logical block.
- If a logical block is broken up into a number of subsections
- by fill-style conditional newlines,
- the basic effect is that the logical block
- is printed with as many subsections as possible on each line.
- However, if miser style is in effect,
- fill-style conditional newlines act like linear-style conditional newlines.
- \item{\kwd{mandatory}}
- This specifies a
- ``mandatory-style'' \term{conditional newline}.\idxtext{mandatory-style conditional newline}
- A line break is always inserted.
- This implies that none of the containing \term{sections}
- can be printed on a single line and
- will therefore trigger the insertion of line breaks
- at linear-style conditional newlines in these \term{sections}.
- \endlist
- When a line break is inserted by any type of conditional newline,
- any blanks that immediately precede the conditional newline are omitted
- from the output and indentation is introduced at the beginning of the next line.
- By default, the indentation causes the following line to begin
- in the same horizontal position
- as the first character in the immediately containing logical block.
- (The indentation can be changed via \funref{pprint-indent}.)
- There are a variety of ways unconditional newlines can be introduced into
- the output (\ie via \funref{terpri} or by printing a string containing a newline
- character). As with mandatory conditional newlines, this prevents any of
- the containing \term{sections} from being printed on one line. In general, when
- an unconditional newline is encountered, it is printed out without
- suppression of the preceding blanks and without any indentation following
- it. However, if a per-line prefix has been specified (see
- \macref{pprint-logical-block}), this prefix will always be printed no matter
- how a newline originates.
- \label Examples::
- \Seesection\PrettyPrinterExamples.
- \label Side Effects::
- Output to \param{stream}.
- \label Affected By::
- \varref{*print-pretty*}, \varref{*print-miser*}.
- The presence of containing logical blocks.
- The placement of newlines and conditional newlines.
- \label Exceptional Situations::
- An error \oftype{type-error} is signaled if \param{kind}
- is not one of \kwd{linear}, \kwd{fill}, \kwd{miser}, or \kwd{mandatory}.
- \label See Also::
- {\secref\TildeUnderscore},
- {\secref\PrettyPrinterExamples}
- \label Notes:\None.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PPRINT-POP
- \begincom{pprint-pop}\ftype{Local Macro}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefmacWithValues pprint-pop {\noargs} {object}
- \label Arguments and Values::
- \param{object}---an \term{element} of the \term{list}
- being printed in the \term{lexically current logical block},
- or \nil.
- \label Description::
- Pops one \term{element} from the \term{list} being printed
- in the \term{lexically current logical block}, obeying \varref{*print-length*}
- and \varref{*print-circle*} as described below.
- Each time \macref{pprint-pop} is called, it pops the next value off the
- \term{list} passed to the \term{lexically current logical block} and returns it.
- However, before doing this, it performs three tests:
- \beginlist
- \item{\bull}
- If the remaining `list' is not a \term{list},
- ``\f{. }''\idxterm{dot} is printed followed by the remaining `list.'
- (This makes it easier to write printing functions that
- are robust in the face of malformed arguments.)
- \item{\bull}
- If \varref{*print-length*} is \term{non-nil},
- and \macref{pprint-pop} has already been called \varref{*print-length*} times
- within the immediately containing logical block,
- ``\f{...}''\idxtext{Dot Dot Dot}\idxcode{...} is printed.
- (This makes it easy to write printing functions that properly handle
- \varref{*print-length*}.)
- \item{\bull}
- If \varref{*print-circle*} is
- \term{non-nil}, and the remaining list is a circular (or shared) reference,
- then ``\f{. }'' is printed followed by an appropriate
- ``\f{\#\i{n}\#}''\idxtext{Sharpsign Sharpsign (reader macro)} marker.
- (This catches instances of \term{cdr} circularity and sharing in lists.)
- \endlist
- If either of the three conditions above occurs, the indicated output is
- printed on the \term{pretty printing stream} created by the immediately containing
- \macref{pprint-logical-block} and the execution of the immediately containing
- \macref{pprint-logical-block} is terminated except for the printing of the suffix.
- %KMP: I find this next paragraph fairly undecipherable.
- If \macref{pprint-logical-block} is given a `list' argument of \nil---because
- it is not processing a list---\macref{pprint-pop} can still be used to obtain
- support for \varref{*print-length*}.
- In this situation, the first and third tests above are disabled and
- \macref{pprint-pop} always returns \nil.
- \Seesection\PrettyPrinterExamples---specifically, the \funref{pprint-vector} example.
- \issue{LEXICAL-CONSTRUCT-GLOBAL-DEFINITION:UNDEFINED}
- Whether or not \macref{pprint-pop} is \term{fbound} in the
- \term{global environment} is \term{implementation-dependent};
- however, the restrictions on redefinition and \term{shadowing} of
- \macref{pprint-pop} are the same as for \term{symbols} in \thepackage{common-lisp}
- which are \term{fbound} in the \term{global environment}.
- The consequences of attempting to use \macref{pprint-pop} outside
- of \macref{pprint-logical-block} are undefined.
- \endissue{LEXICAL-CONSTRUCT-GLOBAL-DEFINITION:UNDEFINED}
- \label Examples:\None.
- \label Side Effects::
- Might cause output
- %This next info supplied by Waters. -kmp 16-Oct-91
- to the \term{pretty printing stream} associated with the lexically current logical block.
- \label Affected By::
- \varref{*print-length*}, \varref{*print-circle*}.
- \label Exceptional Situations::
- An error is signaled (either at macro expansion time or at run time)
- if a usage of \macref{pprint-pop} occurs where there is no lexically
- containing \macref{pprint-logical-block} \term{form}.
- The consequences are undefined if \macref{pprint-pop} is executed outside
- of the \term{dynamic extent} of this \macref{pprint-logical-block}.
- \label See Also::
- \macref{pprint-exit-if-list-exhausted}, \macref{pprint-logical-block}.
- \label Notes::
- It is frequently a good idea to call \macref{pprint-exit-if-list-exhausted}
- before calling \macref{pprint-pop}.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PPRINT-TAB
- \begincom{pprint-tab}\ftype{Function}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefunWithValues pprint-tab {kind colnum colinc {\opt} stream} {\nil}
- \label Arguments and Values::
- \param{kind}---one of \kwd{line}, \kwd{section}, \kwd{line-relative},
- or \kwd{section-relative}.
- \param{colnum}---a non-negative \term{integer}.
- \param{colinc}---a non-negative \term{integer}.
- \param{stream}---an \term{output} \term{stream designator}.
- \label Description::
- Specifies tabbing to \param{stream} as performed by the standard \formatdirective{T}.
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- If \param{stream} is a \term{pretty printing stream} and
- \thevalueof{*print-pretty*} is \term{true},
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- tabbing is performed;
- otherwise, \funref{pprint-tab} has no effect.
- The arguments \param{colnum} and \param{colinc} correspond to the two
- \param{parameters} to \formatOp{T} and are in terms of \term{ems}.
- The \param{kind} argument specifies the style of tabbing. It must be one of
- \kwd{line} (tab as by \formatOp{T}),
- \kwd{section} (tab as by \formatOp{:T},
- but measuring horizontal positions relative to
- the start of the dynamically enclosing section),
- \kwd{line-relative} (tab as by \formatOp{@T}), or
- \kwd{section-relative} (tab as by \formatOp{:@T},
- but measuring horizontal positions relative to
- the start of the dynamically enclosing section).
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- An error is signaled if \param{kind} is not one of \kwd{line},
- \kwd{section}, \kwd{line-relative}, or \kwd{section-relative}.
- \label See Also::
- \macref{pprint-logical-block}
- \label Notes:\None.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PRINT-OBJECT
- \begincom{print-object}\ftype{Standard Generic Function}
-
- \label Syntax::
-
- \DefgenWithValues print-object {object stream} {object}
-
- \label Method Signatures::
-
- \Defmeth {print-object} {\paren{\param{object} standard-object} \param{stream}}
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- \Defmeth {print-object} {\paren{\param{object} structure-object} \param{stream}}
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- \label Arguments and Values::
-
- \param{object}---an \term{object}.
-
- \param{stream}---a \term{stream}.
- %% KMP: It should not be necessary to say this.
- % it cannot be the \term{symbols} \t\ or \nil.
-
- \label Description::
-
- \TheGF{print-object} writes the printed representation of \param{object}
- to \param{stream}.
- \Thefunction{print-object} is called by the \term{Lisp printer};
- it should not be called by the user.
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- Each implementation is required to provide a \term{method} on
- \theclass{standard-object} and on \theclass{structure-object}.
- In addition, each \term{implementation} must provide
- \term{methods} on enough other \term{classes}
- so as to ensure that there is always an applicable \term{method}.
- Implementations are free to add \term{methods} for other \term{classes}.
- Users may write \term{methods} for \funref{print-object} for their own
- \term{classes} if they do not wish to inherit an
- \term{implementation-dependent} \term{method}.
- The \term{method} on \theclass{structure-object} prints the object in the
- default \f{\#S} notation; \seesection\PrintingStructures.
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- %\term{Methods} on \funref{print-object} must
- %obey the print control special variables.
- %The specific details are the following:
- \term{Methods} on \funref{print-object} are responsible for implementing
- their part of the semantics of the \term{printer control variables}, as follows:
-
- \beginlist
-
- \issue{DATA-IO:ADD-SUPPORT}
- \item{\varref{*print-readably*}}
- All methods for \funref{print-object} must obey \varref{*print-readably*}.
- This includes both user-defined methods and \term{implementation-defined} methods.
- Readable printing of \term{structures} and \term{standard objects}
- is controlled by their \funref{print-object} method,
- not by their \funref{make-load-form} \term{method}.
- \term{Similarity} for these \term{objects} is application dependent
- and hence is defined to be whatever these \term{methods} do;
- \seesection\Similarity.
-
- \endissue{DATA-IO:ADD-SUPPORT}
- \item{\varref{*print-escape*}}
- Each \term{method} must implement \varref{*print-escape*}.
-
- \item{\varref{*print-pretty*}}
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- % The \varref{*print-pretty*} control variable can be ignored
- % by most \term{methods} other than the one for \term{lists}.
- The \term{method} may wish to perform specialized line breaking
- or other output conditional on \thevalueof{*print-pretty*}.
- For further information,
- see (for example) the \term{macro} \macref{pprint-fill}.
- See also \secref\PPrintDispatchTables\ and \secref\PrettyPrinterExamples.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
-
- \item{\varref{*print-length*}}
- \term{Methods} that produce output of indefinite length must obey
- \varref{*print-length*}.
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- %, but most \term{methods} other than the one for
- %\term{lists} can ignore it.
- For further information,
- see (for example) the \term{macros} \macref{pprint-logical-block}
- and \macref{pprint-pop}.
- See also \secref\PPrintDispatchTables\ and \secref\PrettyPrinterExamples.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- \item{\varref{*print-level*}}
- The printer takes care of \varref{*print-level*} automatically,
- provided that each \term{method} handles exactly one level of structure and
- calls \funref{write} (or an equivalent \term{function}) recursively if
- there are more structural levels. The printer's decision of whether an
- \term{object} has components (and therefore should not be printed when the
- printing depth is not less than \varref{*print-level*}) is
- \term{implementation-dependent}. In some implementations its
- \funref{print-object} \term{method} is not called;
- in others the \term{method} is called,
- and the determination that the \term{object} has components is based on what
- it tries to write to the \param{stream}.
-
- \item{\varref{*print-circle*}}
- \issue{PRINT-CIRCLE-STRUCTURE:USER-FUNCTIONS-WORK}
- When \thevalueof{*print-circle*} is \term{true},
- a user-defined
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- %print function
- \funref{print-object} \term{method}
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- can print \term{objects} to the supplied \term{stream}
- using \funref{write},
- \funref{prin1},
- \funref{princ},
- or \funref{format}
- and expect circularities to be detected
- and printed using the \f{\#\i{n}\#} syntax.
- If a user-defined
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- %print function
- \funref{print-object} \term{method}
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- prints to a \term{stream} other than the one
- that was supplied, then circularity detection starts over for that
- \term{stream}. See \varref{*print-circle*}.
- \endissue{PRINT-CIRCLE-STRUCTURE:USER-FUNCTIONS-WORK}
- \item{\varref{*print-base*},
- \varref{*print-radix*},
- \varref{*print-case*},
- \varref{*print-gensym*},
- and \varref{*print-array*}}
- These \term{printer control variables} apply to specific types of \term{objects}
- and are handled by the \term{methods} for those \term{objects}.
- \endlist
-
- If these rules are not obeyed, the results are undefined.
-
- %!!! What is the motivation for this?
- In general, the printer and the \funref{print-object} methods should not
- rebind the print control variables as they operate recursively through the
- structure, but this is \term{implementation-dependent}.
-
- In some implementations the \param{stream} argument passed to a
- \funref{print-object} \term{method} is not the original \term{stream},
- but is an intermediate \term{stream} that implements part of the printer.
- \term{methods} should therefore not depend on the identity of this \term{stream}.
-
- %All of the existing printing functions (\funref{write},
- %\funref{prin1}, \funref{print}, \funref{princ}, \funref{pprint},
- %\funref{write-to-string}, \funref{prin1-to-string},
- %\funref{princ-to-string}, the \formatOp{S} and \formatOp{A}
- %format operations, and the \formatOp{B}, \formatOp{D},
- %\formatOp{E}, \formatOp{F}, \formatOp{G}, \formatOp{\$},
- %\formatOp{O}, \formatOp{R}, and \formatOp{X}
- %format operations when they encounter a non-numeric
- %value) are required to be changed to go through the \funref{print-object}
- %generic function. Each implementation is required to
- %replace its former implementation of printing with one or more
- %\funref{print-object} methods.
- %% Flushed per X3J13. -kmp 05-Oct-93
- % Exactly which \term{classes} have \term{methods} for \funref{print-object}
- % is not specified; it would be valid for an implementation to have one
- % default \term{method} that is inherited by all system-defined \term{classes}.
-
- %% Per X3J13. -kmp 05-Oct-93
- \label Examples:\None.
-
- \label Affected By:\None.
-
- \label Exceptional Situations:\None.
-
- \label See Also::
-
- \funref{pprint-fill},
- \macref{pprint-logical-block},
- \macref{pprint-pop},
- \funref{write},
- \varref{*print-readably*},
- \varref{*print-escape*},
- \varref{*print-pretty*},
- \varref{*print-length*},
- {\secref\DefaultPrintObjMeths},
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- {\secref\PrintingStructures},
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- {\secref\PPrintDispatchTables},
- {\secref\PrettyPrinterExamples}
- \label Notes:\None.
-
- \endcom
- %%% ========== PRINT-UNREADABLE-OBJECT
- \begincom{print-unreadable-object}\ftype{Macro}
- \issue{DATA-IO:ADD-SUPPORT}
- \label Syntax::
- \DefmacWithValues print-unreadable-object
- {\paren{object stream {\key} type identity} \starparam{form}}
- {\nil}
- \label Arguments and Values::
- \param{object}---an \term{object}; \eval.
- \param{stream}---%
- %% Changed per Barrett #8 (first public review) -kmp 14-May-93
- % the \term{name} of a \term{lexical variable} or \term{dynamic variable},
- % the \term{value} of which is a \term{stream};
- % used both unevaluated and evaluated.
- a \term{stream designator}; \eval.
- \param{type}---a \term{generalized boolean}; \eval.
- \param{identity}---a \term{generalized boolean}; \eval.
- \param{forms}---an \term{implicit progn}.
- %!!! it is evaluated. also used unevaluated to determine if any forms were present. hmmm...
- \label Description::
- Outputs a printed representation of \param{object} on \param{stream},
- beginning with ``\f{\#<}'' and ending with ``\f{>}''.
- Everything output to \param{stream} by the body \param{forms}
- is enclosed in the the angle brackets.
- If \param{type} is \term{true}, the output from \param{forms}
- is preceded by a brief description of the \param{object}'s
- \term{type} and a space character.
- If \param{identity} is \term{true},
- the output from \param{forms} is followed by a space character
- and a representation of the \param{object}'s identity,
- typically a storage address.
-
- If either \param{type} or \param{identity} is not supplied,
- its value is \term{false}. It is valid to omit the body \param{forms}.
- If \param{type} and \param{identity} are both true and there are no
- body \param{forms}, only one space character separates the type
- and the identity.
-
- \label Examples::
-
- ;; Note that in this example, the precise form of the output
- ;; is \term{implementation-dependent}.
- \code
- (defmethod print-object ((obj airplane) stream)
- (print-unreadable-object (obj stream :type t :identity t)
- (princ (tail-number obj) stream)))
- (prin1-to-string my-airplane)
- \EV "#<Airplane NW0773 36000123135>"
- \OV "#<FAA:AIRPLANE NW0773 17>"
- \endcode
- \label Affected By:\None.
- \label Exceptional Situations::
- If \varref{*print-readably*} is \term{true}, \funref{print-unreadable-object}
- signals an error \oftype{print-not-readable} without printing anything.
-
- \label See Also:\None.
- \label Notes:\None.
- \endissue{DATA-IO:ADD-SUPPORT}
- \endcom
- %%% ========== SET-PPRINT-DISPATCH
- \begincom{set-pprint-dispatch}\ftype{Function}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Syntax::
- \DefunWithValues set-pprint-dispatch {type-specifier function {\opt} priority table} {\nil}
- \label Arguments and Values::
- \param{type-specifier}---a \term{type specifier}.
- % %This is now a valid type specifier! -kmp 30-Apr-91
- % or a list of the form
- % \f{(cons \param{type-specifier} \param{type-specifier})}
- % or {\tt (cons \param{type-specifier})}.
- % \editornote{KMP: Can the type-specifier in a cons specifier also be a
- % usage of CONS? Why don't we extend the CONS type specifier
- % rather than make this special case?}
- \param{function}---a \term{function}, a \term{function name}, or \nil.
- \param{priority}---a \term{real}.
- \Default{\f{0}}
- \param{table}---a \term{pprint dispatch table}.
- \Default{\thevalueof{*print-pprint-dispatch*}}
- \label Description::
- Installs an entry into the \term{pprint dispatch table} which is \param{table}.
- \param{Type-specifier}
- %% already said above. -kmp
- %must be a valid \term{type specifier} and
- is the \term{key}
- of the entry. The first action of \funref{set-pprint-dispatch} is to remove any
- pre-existing entry associated with \param{type-specifier}. This guarantees that
- there will never be two entries associated with the same \term{type specifier}
- in a given \term{pprint dispatch table}. Equality of \term{type specifiers} is
- tested by \funref{equal}.
- Two values are associated with each \term{type specifier} in a
- \term{pprint dispatch table}: a \param{function} and a \param{priority}.
- The \param{function} must accept two arguments: the \term{stream} to which output
- is sent and the \term{object} to be printed. The \param{function} should
- \term{pretty print} the \term{object} to the \param{stream}. The \param{function}
- can assume that object satisfies the \term{type} given by \term{type-specifier}.
- The \param{function} must obey \varref{*print-readably*}.
- %(see issue DATA-IO)
- Any values returned by the \param{function} are ignored.
- \param{Priority} is a priority to resolve conflicts
- when an object matches more than one entry.
- It is permissible for \param{function} to be \nil. In this situation,
- there will be no \param{type-specifier} entry in \param{table} after
- \funref{set-pprint-dispatch} returns.
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- An error is signaled if \param{priority} is not a \term{real}.
- \label See Also:\None.
- \label Notes::
- Since \term{pprint dispatch tables} are often used to control the pretty
- printing of Lisp code, it is common for the \param{type-specifier} to be
- an \term{expression} of the form
- \code
- (cons \param{car-type} \param{cdr-type})
- \endcode
- This signifies that the corresponding object must be a cons cell
- whose \term{car} matches the \term{type specifier} \param{car-type}
- and whose \term{cdr} matches the \term{type specifier} \param{cdr-type}.
- The \param{cdr-type} can be omitted in which case it defaults to \misc{t}.
- %% I don't think this note had any content. -kmp 13-Jan-91
- % ----------------------------------------------------------------------
- %
- % Implementation note: The restriction above is very useful to users
- % without actually limiting what Common Lisp implementors can do. It is
- % possible for implementors to set up any kind of pretty printing they
- % desire using the range of priorities available to them.
- %
- % ----------------------------------------------------------------------
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== PRIN1
- %%% ========== PRINC
- %%% ========== PRINT
- %%% ========== PPRINT
- %%% ========== WRITE
- \begincom{write, prin1, print, pprint, princ}\ftype{Function}
- %% 22.3.1 2
- \label Syntax::
- %% 22.3.1 5
- \DefunWithValuesNewline write
- {\param{object} {\key} \writekeys{stream}}
- {object}
- \DefunWithValues prin1 {object {\opt} output-stream} {object}
- \DefunWithValues princ {object {\opt} output-stream} {object}
- \DefunWithValues print {object {\opt} output-stream} {object}
- \DefunWithValues pprint {object {\opt} output-stream} {\novalues}
- %% 22.3.1 1
- %% 22.3.1 3
- \label Arguments and Values::
- \param{object}---an \term{object}.
- \param{output-stream}---an \term{output} \term{stream designator}.
- \Default{\term{standard output}}
- \writekeydescriptions{\param{stream}---an \term{output} \term{stream designator}.
- \Default{\term{standard output}}}
- \label Description::
- \funref{write}, \funref{prin1}, \funref{princ}, \funref{print}, and \funref{pprint}
- write the printed representation of \param{object} to \param{output-stream}.
- %!!! Does WRITE actually bind all the vars?? -kmp 8-May-91
- \funref{write} is the general entry point to the \term{Lisp printer}.
- For each explicitly supplied \term{keyword parameter} named in \thenextfigure,
- the corresponding \term{printer control variable} is dynamically bound to its \term{value}
- while printing goes on;
- for each \term{keyword parameter} in \thenextfigure\ that is not explicitly supplied,
- the value of the corresponding \term{printer control variable} is the same as it was
- at the time \funref{write} was invoked.
- Once the appropriate \term{bindings} are \term{established},
- the \term{object} is output by the \term{Lisp printer}.
- \tablefigtwo{Argument correspondences for the WRITE function.}{Parameter}{Corresponding Dynamic Variable}{
- \param{array} & \varref{*print-array*} \cr
- \param{base} & \varref{*print-base*} \cr
- \param{case} & \varref{*print-case*} \cr
- \param{circle} & \varref{*print-circle*} \cr
- \param{escape} & \varref{*print-escape*} \cr
- \param{gensym} & \varref{*print-gensym*} \cr
- \param{length} & \varref{*print-length*} \cr
- \param{level} & \varref{*print-level*} \cr
- \param{lines} & \varref{*print-lines*} \cr
- \param{miser-width} & \varref{*print-miser-width*} \cr
- \param{pprint-dispatch} & \varref{*print-pprint-dispatch*} \cr
- \param{pretty} & \varref{*print-pretty*} \cr
- \param{radix} & \varref{*print-radix*} \cr
- \param{readably} & \varref{*print-readably*} \cr
- \param{right-margin} & \varref{*print-right-margin*} \cr
- }
- \issue{PRETTY-PRINT-INTERFACE}
- \funref{prin1}, \funref{princ}, \funref{print}, and \funref{pprint} implicitly
- \term{bind} certain print parameters to particular values. The remaining parameter
- values are taken from
- \varref{*print-array*},
- \varref{*print-base*},
- \varref{*print-case*},
- \varref{*print-circle*},
- \varref{*print-escape*},
- \varref{*print-gensym*},
- \varref{*print-length*},
- \varref{*print-level*},
- \varref{*print-lines*},
- \varref{*print-miser-width*},
- \varref{*print-pprint-dispatch*},
- \varref{*print-pretty*},
- \varref{*print-radix*},
- and \varref{*print-right-margin*}.
- \endissue{PRETTY-PRINT-INTERFACE}
- \funref{prin1} produces output suitable for input to \funref{read}.
- It binds \varref{*print-escape*} to \term{true}.
- %% 2.5.2 3
- %% 2.5.3 2
- % I don't think this belongs here. --sjl 16 Mar 92
- %\funref{prin1} prints any \term{string}
- %or \term{bit vector}, not just a simple one, but \funref{read} will
- %always construct a \term{simple string} or \term{simple bit vector}
- %when it reads the appropriate syntax.
- %% 22.3.1 8
- \funref{princ} is just like \funref{prin1} except that the
- output has no \term{escape} \term{characters}.
- It binds \varref{*print-escape*} to \term{false}
- \issue{PRINC-READABLY:X3J13-DEC-91}
- and \varref{*print-readably*} to \term{false}.
- \endissue{PRINC-READABLY:X3J13-DEC-91}
- % I don't think this belongs here. --sjl 16 Mar 92
- %A \term{symbol} is printed as the characters of its \term{name};
- %a \term{string} is printed without surrounding \term{double-quotes};
- %and there might be differences for other \term{types} as well.
- The general rule is that output from \funref{princ} is intended to look
- good to people, while output from \funref{prin1} is intended to
- be acceptable to \funref{read}.
- % I don't think this belongs here. --sjl 16 Mar 92
- %\issue{PRINC-CHARACTER}
- %For \term{characters},
- %
- %\code
- % (princ character output-stream) \EQ (write-char character output-stream)
- %\endcode
- %\endissue{PRINC-CHARACTER}
- %% 22.3.1 6
- \funref{print} is just like \funref{prin1}
- except that the printed representation
- of \param{object} is preceded by a newline
- and followed by a space.
- %% 22.3.1 7
- \funref{pprint} is just like \funref{print} except that the trailing
- space is omitted and
- \param{object} is printed with the \varref{*print-pretty*} flag \term{non-nil}
- to produce pretty output.
- \param{Output-stream} specifies the \term{stream} to which
- output is to be sent.
- \label Affected By::
- \varref{*standard-output*},
- \varref{*terminal-io*},
- \varref{*print-escape*},
- \varref{*print-radix*},
- \varref{*print-base*},
- \varref{*print-circle*},
- \varref{*print-pretty*},
- \varref{*print-level*},
- \varref{*print-length*},
- \varref{*print-case*},
- \varref{*print-gensym*},
- \varref{*print-array*},
- \varref{*read-default-float-format*}.
- \label Exceptional Situations:\None.
- \label See Also::
- \funref{readtable-case},
- {\secref\FORMATPrinterOps}
- \label Notes::
- \Thefunctions{prin1} and \funref{print} do not bind \varref{*print-readably*}.
- \code
- (prin1 object output-stream)
- \EQ (write object :stream output-stream :escape t)
- \endcode
- \issue{PRINC-READABLY:X3J13-DEC-91}
- \code
- (princ object output-stream)
- \EQ (write object stream output-stream :escape nil :readably nil)
- \endcode
- \endissue{PRINC-READABLY:X3J13-DEC-91}
- \code
- (print object output-stream)
- \EQ (progn (terpri output-stream)
- (write object :stream output-stream
- :escape t)
- (write-char #\\space output-stream))
- \endcode
- \code
- (pprint object output-stream)
- \EQ (write object :stream output-stream :escape t :pretty t)
- \endcode
- \endcom
- %%% ========== PRIN1-TO-STRING
- %%% ========== PRINC-TO-STRING
- %%% ========== WRITE-TO-STRING
- \begincom{write-to-string, prin1-to-string, princ-to-string}\ftype{Function}
- \label Syntax::
- \DefunWithValuesNewline write-to-string
- {object {\key} \writekeys{}}
- {string}
- \DefunWithValues prin1-to-string {object} {string}
- \DefunWithValues princ-to-string {object} {string}
- \label Arguments and Values::
- \param{object}---an \term{object}.
- \writekeydescriptions{}
- \param{string}---a \term{string}.
- \label Description::
- \funref{write-to-string}, \funref{prin1-to-string}, and \funref{princ-to-string}
- are used to create a \term{string} consisting of the printed representation
- of \param{object}.
- %% 22.3.1 11
- \param{Object} is effectively printed as if by \funref{write},
- \funref{prin1}, or \funref{princ}, respectively,
- and the \term{characters} that would be output are made
- into a \term{string}.
- \funref{write-to-string} is the general output function.
- It has the ability to specify all the parameters applicable
- to the printing of \param{object}.
- \funref{prin1-to-string} acts like \funref{write-to-string} with
- \f{:escape t}, that is, escape characters are written where appropriate.
- \funref{princ-to-string} acts like \funref{write-to-string} with
- \issue{PRINC-READABLY:X3J13-DEC-91}
- \f{:escape nil :readably nil}.
- \endissue{PRINC-READABLY:X3J13-DEC-91}
- Thus no \term{escape} \term{characters} are written.
- All other keywords that would be specified to \funref{write-to-string}
- are default values when \funref{prin1-to-string}
- or \funref{princ-to-string} is invoked.
- The meanings and defaults for the keyword arguments to \funref{write-to-string}
- are the same as those for \funref{write}.
- \label Examples::
- \code
- (prin1-to-string "abc") \EV "\\"abc\\""
- (princ-to-string "abc") \EV "abc"
- \endcode
- \label Side Effects:\None.
- \label Affected By::
- \varref{*print-escape*},
- \varref{*print-radix*},
- \varref{*print-base*},
- \varref{*print-circle*},
- \varref{*print-pretty*},
- \varref{*print-level*},
- \varref{*print-length*},
- \varref{*print-case*},
- \varref{*print-gensym*},
- \varref{*print-array*},
- \varref{*read-default-float-format*}.
- \label Exceptional Situations:\None.%!!! Not likely.
- \label See Also::
- \funref{write}
- \label Notes::
- \code
- (write-to-string \param{object} \star{\curly{\param{key} \param{argument}}})
- \EQ (with-output-to-string (#1=#:string-stream)
- (write object :stream #1# \star{\curly{\param{key} \param{argument}}}))
- (princ-to-string \param{object})
- \EQ (with-output-to-string (string-stream)
- (princ \param{object} string-stream))
- (prin1-to-string \param{object})
- \EQ (with-output-to-string (string-stream)
- (prin1 \param{object} string-stream))
- \endcode
- \endcom
- %-------------------- Printer Variables --------------------
- %%% ========== *PRINT-ARRAY*
- \begincom{*print-array*}\ftype{Variable}
- \label Value Type::
- a \term{generalized boolean}.
- \label Initial Value::
- \term{implementation-dependent}.
- \label Description::
- %% 22.1.6 55
- Controls the format in which \term{arrays} are printed.
- If it is \term{false}, the contents of \term{arrays} other than \term{strings}
- are never printed. Instead, \term{arrays} are printed in a concise form using
- \f{\#<} that gives enough information for the user to be able to identify the
- \term{array}, but does not include the entire \term{array} contents.
- If it is \term{true}, non-\term{string} \term{arrays} are printed using
- \f{\#(...)}, \f{\#*}, or \f{\#nA} syntax.
- \label Examples:\None.
- \label Affected By::
- The \term{implementation}.
- \label See Also::
- {\secref\SharpsignLeftParen},
- {\secref\SharpsignLeftAngle}
- \label Notes:\None.
- \endcom
- %%% ========== *PRINT-BASE*
- %%% ========== *PRINT-RADIX*
- \begincom{*print-base*, *print-radix*}\ftype{Variable}
- \label Value Type::
- \varref{*print-base*}---a \term{radix}.
- \varref{*print-radix*}---a \term{generalized boolean}.
- \label Initial Value::
- The initial \term{value} of \varref{*print-base*} is \f{10}.
- %%It's implied. -kmp 12-Jan-91
- % (decimal radix).
- The initial \term{value} of \varref{*print-radix*} is \term{false}.
- \label Description::
- \varref{*print-base*} and \varref{*print-radix*} control the printing
- of \term{rationals}.
- \Thevalueof{*print-base*} is called the \newterm{current output base}.
- %% 22.1.6 44
- \Thevalueof{*print-base*} is the \term{radix} in which the printer
- will print \term{rationals}. For radices above \f{10}, letters of
- the alphabet are used to represent digits above \f{9}.
- %% 22.1.6 46
- If \thevalueof{*print-radix*} is \term{true},
- the printer will print a radix specifier to indicate the \term{radix}
- in which it is printing a \term{rational} number. The radix specifier
- is always printed using lowercase letters. If \varref{*print-base*}
- is \f{2}, \f{8}, or \f{16}, then the radix specifier used is \f{\#b},
- \f{\#o}, or \f{\#x}, respectively. For \term{integers}, base ten is
- indicated by a trailing decimal point instead of a leading radix
- specifier; for \term{ratios}, \f{\#10r} is used.
-
- \label Examples::
- \code
- (let ((*print-base* 24.) (*print-radix* t))
- (print 23.))
- \OUT #24rN
- \EV 23
- (setq *print-base* 10) \EV 10
- (setq *print-radix* nil) \EV NIL
- (dotimes (i 35)
- (let ((*print-base* (+ i 2))) ;print the decimal number 40
- (write 40) ;in each base from 2 to 36
- (if (zerop (mod i 10)) (terpri) (format t " "))))
- \OUT 101000
- \OUT 1111 220 130 104 55 50 44 40 37 34
- \OUT 31 2C 2A 28 26 24 22 20 1J 1I
- \OUT 1H 1G 1F 1E 1D 1C 1B 1A 19 18
- \OUT 17 16 15 14
- \EV NIL
- (dolist (pb '(2 3 8 10 16))
- (let ((*print-radix* t) ;print the integer 10 and
- (*print-base* pb)) ;the ratio 1/10 in bases 2,
- (format t "~&~S ~S~%" 10 1/10))) ;3, 8, 10, 16
- \OUT #b1010 #b1/1010
- \OUT #3r101 #3r1/101
- \OUT #o12 #o1/12
- \OUT 10. #10r1/10
- \OUT #xA #x1/A
- \EV NIL
- \endcode
- \label Affected By::
- Might be \term{bound} by \funref{format}, and \funref{write}, \funref{write-to-string}.
- \label See Also::
- \funref{format},
- \funref{write},
- \funref{write-to-string}
- \label Notes:\None.
- \endcom
- %%% ========== *PRINT-CASE*
- \begincom{*print-case*}\ftype{Variable}
- \label Value Type::
- One of the \term{symbols} \kwd{upcase}, \kwd{downcase}, or \kwd{capitalize}.
- \label Initial Value::
- The \term{symbol} \kwd{upcase}.
- \label Description::
- %% 22.1.6 47
- \Thevalueof{*print-case*} controls the case (upper, lower, or mixed) in
- which to print any uppercase characters in the names of \term{symbols}
- when vertical-bar syntax is not used.
- \issue{PRINT-CASE-PRINT-ESCAPE-INTERACTION:VERTICAL-BAR-RULE-NO-UPCASE}
- \issue{JUN90-TRIVIAL-ISSUES:3}
- \varref{*print-case*} has an effect at all times when \thevalueof{*print-escape*}
- is \term{false}. \varref{*print-case*} also has an effect when
- \thevalueof{*print-escape*} is \term{true} unless inside an escape context
- (\ie unless between \term{vertical-bars} or after a \term{slash}).
- \issue{PRINT-CASE-BEHAVIOR:CLARIFY}
- % Under no circumstance is
- % any character that is lowercase in the internal representation ever presented
- % as uppercase due to \varref{*print-case*}.
- \endissue{PRINT-CASE-BEHAVIOR:CLARIFY}
- \endissue{JUN90-TRIVIAL-ISSUES:3}
- \endissue{PRINT-CASE-PRINT-ESCAPE-INTERACTION:VERTICAL-BAR-RULE-NO-UPCASE}
- \label Examples::
- \code
- (defun test-print-case ()
- (dolist (*print-case* '(:upcase :downcase :capitalize))
- (format t "~&~S ~S~%" 'this-and-that '|And-something-elSE|)))
- \EV TEST-PC
- ;; Although the choice of which characters to escape is specified by
- ;; *PRINT-CASE*, the choice of how to escape those characters
- ;; (i.e., whether single escapes or multiple escapes are used)
- ;; is implementation-dependent. The examples here show two of the
- ;; many valid ways in which escaping might appear.
- (test-print-case) ;Implementation A
- \OUT THIS-AND-THAT |And-something-elSE|
- \OUT this-and-that a\\n\\d-\\s\\o\\m\\e\\t\\h\\i\\n\\g-\\e\\lse
- \OUT This-And-That A\\n\\d-\\s\\o\\m\\e\\t\\h\\i\\n\\g-\\e\\lse
- \EV NIL
- (test-print-case) ;Implementation B
- \OUT THIS-AND-THAT |And-something-elSE|
- \OUT this-and-that a|nd-something-el|se
- \OUT This-And-That A|nd-something-el|se
- \EV NIL
- \endcode
- \label Affected By:\None.
- \label See Also::
- \funref{write}
- \label Notes::
- %!!! Does issue READ-CASE-SENSITIVITY affect any of this?
- \funref{read} normally converts lowercase characters appearing
- in \term{symbols} to corresponding uppercase characters,
- so that internally print names normally contain only uppercase characters.
- %% 22.1.6 48
- If \varref{*print-escape*} is \term{true},
- lowercase characters in the \term{name} of a \term{symbol}
- are always printed in lowercase, and
- are preceded by a single escape character
- or enclosed by multiple escape characters;
- uppercase characters in the \term{name} of a \term{symbol}
- are printed in upper case, in lower case, or in mixed case
- so as to capitalize words, according to the value of
- \varref{*print-case*}. The convention for what constitutes
- a ``word'' is the same as for \funref{string-capitalize}.
- \endcom
- %%% ========== *PRINT-CIRCLE*
- \begincom{*print-circle*}\ftype{Variable}
- \issue{PRINT-CIRCLE-SHARED:RESPECT-PRINT-CIRCLE}
- \label Value Type::
- a \term{generalized boolean}.
- \label Initial Value::
- \term{false}.
- \label Description::
- %% 22.1.6 42
- Controls the attempt to detect circularity and sharing in an \term{object}
- being printed.
- If \term{false},
- the printing process merely proceeds by recursive descent without attempting
- to detect circularity and sharing.
- %% 22.1.6 43
- If \term{true},
- the printer will endeavor to detect cycles and sharing
- in the structure to be printed,
- and to use \f{\#\i{n}=} and \f{\#\i{n}\#}
- syntax to indicate the circularities or shared components.
- \issue{PRINT-CIRCLE-STRUCTURE:USER-FUNCTIONS-WORK}
- If \term{true}, a user-defined
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- %print function
- \funref{print-object} \term{method}
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- can print
- \term{objects} to the supplied \term{stream} using \funref{write}, \funref{prin1},
- \funref{princ}, or \funref{format} and expect circularities and sharing
- to be detected and printed using the \f{\#\i{n}\#} syntax.
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- %This applies to \term{methods} on \funref{print-object} in addition to
- %\kwd{print-function} options.
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- If a user-defined
- \issue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- %print function
- \funref{print-object} \term{method}
- \endissue{DEFSTRUCT-PRINT-FUNCTION-AGAIN:X3J13-MAR-93}
- prints to a \term{stream} other than the one
- that was supplied, then circularity detection starts over for that \term{stream}.
- \endissue{PRINT-CIRCLE-STRUCTURE:USER-FUNCTIONS-WORK}
- Note that implementations should not use \f{\#\i{n}\#} notation
- when the \term{Lisp reader} would automatically assure sharing without it
- (\eg as happens with \term{interned} \term{symbols}).
- \label Examples::
- \code
- (let ((a (list 1 2 3)))
- (setf (cdddr a) a)
- (let ((*print-circle* t))
- (write a)
- :done))
- \OUT #1=(1 2 3 . #1#)
- \EV :DONE
- \endcode
- \label Affected By:\None.
- \label See Also::
- \funref{write}
- \label Notes::
- An attempt to print a circular structure with \varref{*print-circle*}
- set to \nil\ may lead to looping behavior and failure to terminate.
- \endissue{PRINT-CIRCLE-SHARED:RESPECT-PRINT-CIRCLE}
- \endcom
- %%% ========== *PRINT-ESCAPE*
- \begincom{*print-escape*}\ftype{Variable}
- \label Value Type::
- a \term{generalized boolean}.
- \label Initial Value::
- %% 22.1.6 38
- \term{true}.
- \label Description::
- %% 22.1.6 35
- If \term{false},
- escape characters and \term{package prefixes} are not output
- when an expression is printed.
-
- %% 22.1.6 36
- If \term{true}, an attempt is made to print an \term{expression}
- in such a way that it can be read again to produce an \funref{equal} \term{expression}.
- (This is only a guideline; not a requirement. See \varref{*print-readably*}.)
- For more specific details of how \thevalueof{*print-escape*}
- affects the printing of certain \term{types},
- \seesection\DefaultPrintObjMeths.
- \label Examples::
- \code
- (let ((*print-escape* t)) (write #\\a))
- \OUT #\\a
- \EV #\\a
- (let ((*print-escape* nil)) (write #\\a))
- \OUT a
- \EV #\\a
- \endcode
- \label Affected By::
- \funref{princ}, \funref{prin1}, \funref{format}
- \label See Also::
- \funref{write}, \funref{readtable-case}
- \label Notes::
- \funref{princ} effectively binds \varref{*print-escape*} to \term{false}.
- \funref{prin1} effectively binds \varref{*print-escape*} to \term{true}.
-
- \endcom
- %%% ========== *PRINT-GENSYM*
- \begincom{*print-gensym*}\ftype{Variable}
- \label Value Type::
- a \term{generalized boolean}.
- \label Initial Value::
- \term{true}.
- \label Description::
- %% 22.1.6 49
- Controls whether the prefix ``\f{\#:}'' is printed before
- \term{apparently uninterned} \term{symbols}.
- The prefix is printed before such \term{symbols}
- if and only if \thevalueof{*print-gensym*} is \term{true}.
- \label Examples::
- \code
- (let ((*print-gensym* nil))
- (print (gensym)))
- \OUT G6040
- \EV #:G6040
- \endcode
- \label Affected By:\None.
- \label See Also::
- \funref{write}, \varref{*print-escape*}
- \label Notes:\None.
- \endcom
- %%% ========== *PRINT-LEVEL*
- %%% ========== *PRINT-LENGTH*
- \begincom{*print-level*, *print-length*}\ftype{Variable}
- \label Value Type::
- a non-negative \term{integer}, or \nil.
- \label Initial Value::
- \nil.
- \label Description::
- %% 22.1.6 50
- \varref{*print-level*} controls how many levels deep a nested \term{object} will print.
- If it is \term{false}, then no control is exercised.
- Otherwise, it is an \term{integer} indicating the maximum level to be printed.
- An \term{object} to be printed is at level \f{0};
- its components (as of a \term{list} or \term{vector}) are at level \f{1};
- and so on.
- If an \term{object} to be recursively printed has components
- and is at a level equal to or greater than \thevalueof{*print-level*},
- then the \term{object} is printed as ``\f{\#}''.
- %% 22.1.6 51
- \varref{*print-length*} controls how many elements at a given level are printed.
- If it is \term{false}, there is no limit to the number of components printed.
- Otherwise, it is an \term{integer} indicating the maximum number of \term{elements}
- of an \term{object} to be printed. If exceeded, the printer will print
- ``\f{...}'' in place of the other \term{elements}. In the case of a \term{dotted list},
- if the \term{list} contains exactly as many \term{elements} as \thevalueof{*print-length*},
- the terminating \term{atom} is printed rather than printing ``\f{...}''
- %% 22.1.6 52
- \varref{*print-level*} and \varref{*print-length*} affect the printing
- of an any \term{object} printed with a list-like syntax. They do not affect
- the printing of \term{symbols}, \term{strings}, and \term{bit vectors}.
- \label Examples::
- %% 22.1.6 54
- \medbreak
- \code
- (setq a '(1 (2 (3 (4 (5 (6))))))) \EV (1 (2 (3 (4 (5 (6))))))
- (dotimes (i 8)
- (let ((*print-level* i))
- (format t "~&~D -- ~S~%" i a)))
- \OUT 0 -- #
- \OUT 1 -- (1 #)
- \OUT 2 -- (1 (2 #))
- \OUT 3 -- (1 (2 (3 #)))
- \OUT 4 -- (1 (2 (3 (4 #))))
- \OUT 5 -- (1 (2 (3 (4 (5 #)))))
- \OUT 6 -- (1 (2 (3 (4 (5 (6))))))
- \OUT 7 -- (1 (2 (3 (4 (5 (6))))))
- \EV NIL
- \medbreak
- (setq a '(1 2 3 4 5 6)) \EV (1 2 3 4 5 6)
- (dotimes (i 7)
- (let ((*print-length* i))
- (format t "~&~D -- ~S~%" i a)))
- \OUT 0 -- (...)
- \OUT 1 -- (1 ...)
- \OUT 2 -- (1 2 ...)
- \OUT 3 -- (1 2 3 ...)
- \OUT 4 -- (1 2 3 4 ...)
- \OUT 5 -- (1 2 3 4 5 6)
- \OUT 6 -- (1 2 3 4 5 6)
- \EV NIL
- \medbreak
- (dolist (level-length '((0 1) (1 1) (1 2) (1 3) (1 4)
- (2 1) (2 2) (2 3) (3 2) (3 3) (3 4)))
- (let ((*print-level* (first level-length))
- (*print-length* (second level-length)))
- (format t "~&~D ~D -- ~S~%"
- *print-level* *print-length*
- '(if (member x y) (+ (car x) 3) '(foo . #(a b c d "Baz"))))))
- \OUT 0 1 -- #
- \OUT 1 1 -- (IF ...)
- \OUT 1 2 -- (IF # ...)
- \OUT 1 3 -- (IF # # ...)
- \OUT 1 4 -- (IF # # #)
- \OUT 2 1 -- (IF ...)
- \OUT 2 2 -- (IF (MEMBER X ...) ...)
- \OUT 2 3 -- (IF (MEMBER X Y) (+ # 3) ...)
- \OUT 3 2 -- (IF (MEMBER X ...) ...)
- \OUT 3 3 -- (IF (MEMBER X Y) (+ (CAR X) 3) ...)
- \OUT 3 4 -- (IF (MEMBER X Y) (+ (CAR X) 3) '(FOO . #(A B C D ...)))
- \EV NIL
- \endcode
- \label Affected By:\None.
- \label See Also::
- \funref{write}
- \label Notes:\None.
- % KMP:
- % There has been some debate about how strictly these abbreviation guidelines
- % should be applied.
- %
- % (write '(1 2 3) :length 1) prints (1 ...) or (1 2 3)?
- % (write '(1 2 3) :length 2) prints (1 2 ...) or (1 2 3)?
- %
- % Barmar:
- % While I've always secretly wished that these limits were defined such
- % that they would be ignored when the length of the thing being replaced
- % with "..." or "#" is less than or equal to the replacement text, I
- % don't seriously believe there's really a need for implementation
- % flexibility. This is a fairly straightforward piece of the language.
- %
- % Dick:
- % As the original author of GPRINT, I am probably partly responsible for
- % the behavior you see. I deliberately tried to do better than the
- % default length and depth processing did. I was however copying what
- % the standard Lispm software did at the time.
- % Nevertheless, I agree with the point of view that there is no reason
- % to make this complicated. Let's just have a simple abbreviation
- % algorithm and hold everybody to it. It is not worth being more
- % creative than that.
- \endcom
- %%% ========== *PRINT-LINES*
- \begincom{*print-lines*}\ftype{Variable}
- \label Value Type::
- a non-negative \term{integer}, or \nil.
- \label Initial Value::
- \nil.
- \label Description::
- When \thevalueof{*print-lines*} is other than \nil,
- it is a limit on the number of output lines produced when something is pretty
- printed. If an attempt is made to go beyond that many lines,
- ``\f{..}''\idxtext{Dot Dot}\idxcode{..}
- is printed at the end of the last line followed by all of the
- suffixes (closing delimiters) that are pending to be printed.
- \label Examples::
- \code
- (let ((*print-right-margin* 25) (*print-lines* 3))
- (pprint '(progn (setq a 1 b 2 c 3 d 4))))
- \OUT (PROGN (SETQ A 1
- \OUT B 2
- \OUT C 3 ..))
- \EV \novalues
- \endcode
- \label See Also:\None.
- \label Notes::
- The ``\f{..}'' notation is intentionally different than
- the ``\f{...}'' notation used for level abbreviation, so that the two
- different situations can be visually distinguished.
- This notation is used to increase the likelihood that the \term{Lisp reader}
- will signal an error if an attempt is later made to read the abbreviated output.
- Note however that if the truncation occurs in a \term{string},
- as in \f{"This string has been trunc.."}, the problem situation cannot be
- detected later and no such error will be signaled.
- \endcom
- %%% ========== *PRINT-MISER-WIDTH*
- \begincom{*print-miser-width*}\ftype{Variable}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Value Type::
- a non-negative \term{integer}, or \nil.
- \label Initial Value::
- \term{implementation-dependent}
- \label Description::
- If it is not \nil, the \term{pretty printer} switches to a compact
- style of output (called miser style) whenever the width available for
- printing a substructure is less than or equal to this many \term{ems}.
- \label Examples:\None.
- \label See Also:\None.
- \label Notes:\None.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== *PRINT-PPRINT-DISPATCH*
- \begincom{*print-pprint-dispatch*}\ftype{Variable}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Value Type::
- a \term{pprint dispatch table}.
- \label Initial Value::
- \term{implementation-dependent}, but the initial entries all use a
- special class of priorities that have the property that they are less
- than every priority that can be specified using \funref{set-pprint-dispatch},
- so that the initial contents of any entry can be overridden.
- \label Description::
- The \term{pprint dispatch table} which currently controls the \term{pretty printer}.
- \label Examples:\None.
- \label See Also::
- \varref{*print-pretty*},
- {\secref\PPrintDispatchTables}
- \label Notes::
- The intent is that the initial \term{value} of this \term{variable} should
- cause `traditional' \term{pretty printing} of \term{code}.
- % Added on advice of Dick Waters:
- In general, however, you can put a value in \varref{*print-pprint-dispatch*}
- that makes pretty-printed output look exactly like non-pretty-printed output.
- \issue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- % Setting \varref{*print-pretty*} to \term{true} means having \varref{*print-pprint-dispatch*}
- % control printing---nothing more, and nothing less.
- Setting \varref{*print-pretty*} to \term{true}
- just causes the functions contained in the \term{current pprint dispatch table}
- to have priority over normal \funref{print-object} methods;
- it has no magic way of enforcing that those functions actually produce pretty
- output. For details, \seesection\PPrintDispatchTables.
- \endissue{GENERALIZE-PRETTY-PRINTER:UNIFY}
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %%% ========== *PRINT-PRETTY*
- \begincom{*print-pretty*}\ftype{Variable}
- \label Value Type::
- a \term{generalized boolean}.
- \label Initial Value::
- %% 22.1.6 41
- \term{implementation-dependent}.
- \label Description::
- Controls whether the \term{Lisp printer} calls the \term{pretty printer}.
- %% 22.1.6 39
- If it is \term{false},
- the \term{pretty printer} is not used and
- \issue{PRINTER-WHITESPACE:JUST-ONE-SPACE}
- a minimum
- %only a small amount
- \endissue{PRINTER-WHITESPACE:JUST-ONE-SPACE}
- of \term{whitespace}\meaning{1}
- is output when printing an expression.
- %% 22.1.6 40
- If it is \term{true},
- the \term{pretty printer} is used, and the \term{Lisp printer} will endeavor
- to insert extra \term{whitespace}\meaning{1} where appropriate to make \term{expressions}
- more readable.
- \varref{*print-pretty*} has an effect even when \thevalueof{*print-escape*}
- is \term{false}.
- \label Examples::
- \issue{FORMAT-PRETTY-PRINT:YES}
- \code
- (setq *print-pretty* 'nil) \EV NIL
- (progn (write '(let ((a 1) (b 2) (c 3)) (+ a b c))) nil)
- \OUT (LET ((A 1) (B 2) (C 3)) (+ A B C))
- \EV NIL
- (let ((*print-pretty* t))
- (progn (write '(let ((a 1) (b 2) (c 3)) (+ a b c))) nil))
- \OUT (LET ((A 1)
- \OUT (B 2)
- \OUT (C 3))
- \OUT (+ A B C))
- \EV NIL
- ;; Note that the first two expressions printed by this next form
- ;; differ from the second two only in whether escape characters are printed.
- ;; In all four cases, extra whitespace is inserted by the pretty printer.
- (flet ((test (x)
- (let ((*print-pretty* t))
- (print x)
- (format t "~%~S " x)
- (terpri) (princ x) (princ " ")
- (format t "~%~A " x))))
- (test '#'(lambda () (list "a" #\b 'c #'d))))
- \OUT #'(LAMBDA ()
- \OUT (LIST "a" #\b 'C #'D))
- \OUT #'(LAMBDA ()
- \OUT (LIST "a" #\b 'C #'D))
- \OUT #'(LAMBDA ()
- \OUT (LIST a b 'C #'D))
- \OUT #'(LAMBDA ()
- \OUT (LIST a b 'C #'D))
- \EV NIL
- \endcode
- \endissue{FORMAT-PRETTY-PRINT:YES}
- \label Affected By:\None.
- \label See Also::
- \funref{write}
- \label Notes:\None.
- \endcom
- %%% ========== *PRINT-READABLY*
- \begincom{*print-readably*}\ftype{Variable}
- \issue{DATA-IO:ADD-SUPPORT}
- \label Value Type::
- a \term{generalized boolean}.
- \label Initial Value::
- %% 22.1.6 38
- \term{false}.
- \label Description::
- %% 22.1.6 36
- If \varref{*print-readably*} is \term{true},
- some special rules for printing \term{objects} go into effect.
- Specifically, printing any \term{object} $O\sub 1$ produces a printed
- representation that, when seen by the \term{Lisp reader}
- %% This additional restriction added in response to Loosemore #14, first public review
- while the \term{standard readtable} is in effect,
- will produce
- an \term{object} $O\sub 2$ that is \term{similar} to $O\sub 1$.
- The printed representation produced might or might not be the same as
- the printed representation produced when \varref{*print-readably*} is \term{false}.
- % If printing a readable printed representation of an \term{object} is not possible,
- If printing an \term{object} \term{readably} is not possible,
- an error \oftype{print-not-readable} is signaled rather than
- using a syntax (\eg the ``\f{\#<}'' syntax) that would not be readable by
- the same \term{implementation}.
- If the \term{value} of some other \term{printer control variable} is such
- that these requirements would be violated, the \term{value} of that other
- \term{variable} is ignored.
- \issue{PRINT-READABLY-BEHAVIOR:CLARIFY}
- %%!!! Glag. I can't believe we voted this in.
- %% I want (and *print-readably* *print-escape*) implies ...!
- %% Grumbling mail sent to X3J13.
- %% -kmp 22-Aug-93
- Specifically, if \varref{*print-readably*} is \term{true},
- printing proceeds as if
- \varref{*print-escape*},
- \varref{*print-array*},
- and \varref{*print-gensym*} were also \term{true},
- and as if
- \varref{*print-length*},
- \varref{*print-level*},
- and \varref{*print-lines*} were \term{false}.
- \endissue{PRINT-READABLY-BEHAVIOR:CLARIFY}
- If \varref{*print-readably*} is \term{false},
- the normal rules for printing and the normal interpretations
- of other \term{printer control variables} are in effect.
- Individual \term{methods} for \funref{print-object}, including user-defined
- \term{methods}, are responsible for implementing these requirements.
- If \varref{*read-eval*} is \term{false} and \varref{*print-readably*} is \term{true},
- any such method that would output a reference to the ``\f{\#.}'' \term{reader macro}
- will either output something else or will signal an error (as described above).
- \label Examples::
- \code
- (let ((x (list "a" '\\a (gensym) '((a (b (c))) d e f g)))
- (*print-escape* nil)
- (*print-gensym* nil)
- (*print-level* 3)
- (*print-length* 3))
- (write x)
- (let ((*print-readably* t))
- (terpri)
- (write x)
- :done))
- \OUT (a a G4581 ((A #) D E ...))
- \OUT ("a" |a| #:G4581 ((A (B (C))) D E F G))
- \EV :DONE
- ;; This is setup code is shared between the examples
- ;; of three hypothetical implementations which follow.
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32005763>
- (setf (gethash table 1) 'one) \EV ONE
- (setf (gethash table 2) 'two) \EV TWO
- ;; Implementation A
- (let ((*print-readably* t)) (print table))
- Error: Can't print #<HASH-TABLE EQL 0/120 32005763> readably.
- ;; Implementation B
- ;; No standardized #S notation for hash tables is defined,
- ;; but there might be an implementation-defined notation.
- (let ((*print-readably* t)) (print table))
- \OUT #S(HASH-TABLE :TEST EQL :SIZE 120 :CONTENTS (1 ONE 2 TWO))
- \EV #<HASH-TABLE EQL 0/120 32005763>
- ;; Implementation C
- ;; Note that #. notation can only be used if *READ-EVAL* is true.
- ;; If *READ-EVAL* were false, this same implementation might have to
- ;; signal an error unless it had yet another printing strategy to fall
- ;; back on.
- (let ((*print-readably* t)) (print table))
- \OUT #.(LET ((HASH-TABLE (MAKE-HASH-TABLE)))
- \OUT (SETF (GETHASH 1 HASH-TABLE) ONE)
- \OUT (SETF (GETHASH 2 HASH-TABLE) TWO)
- \OUT HASH-TABLE)
- \EV #<HASH-TABLE EQL 0/120 32005763>
- \endcode
- \label Affected By:\None.
- \label See Also::
- \funref{write}, \macref{print-unreadable-object}
- \label Notes::
- The rules for ``\term{similarity}'' imply that
- \f{\#A} or \f{\#(} % )
- syntax cannot be used for \term{arrays} of \term{element type}
- other than \typeref{t}.
- An implementation will have to use another syntax
- or signal an error \oftype{print-not-readable}.
- \issue{PRINT-READABLY-BEHAVIOR:CLARIFY}
- % The printing of interned \term{symbols}, of \term{strings},
- % and of \term{bit vectors} is not affected by \varref{*print-readably*}.
- \endissue{PRINT-READABLY-BEHAVIOR:CLARIFY}
- \endissue{DATA-IO:ADD-SUPPORT}
- \endcom
- %%% ========== *PRINT-RIGHT-MARGIN*
- \begincom{*print-right-margin*}\ftype{Variable}
- \issue{PRETTY-PRINT-INTERFACE}
- \label Value Type::
- a non-negative \term{integer}, or \nil.
- \label Initial Value::
- \nil.
- \label Description::
- If it is \term{non-nil}, it specifies the right margin (as \term{integer}
- number of \term{ems}) to use when the \term{pretty printer} is making
- layout decisions.
- If it is \nil, the right margin is taken to be the maximum line length
- such that output can be displayed without wraparound or truncation.
- If this cannot be determined, an \term{implementation-dependent} value is used.
- \label Examples:\None.
- \label See Also:\None.
- \label Notes::
- This measure is in units of \term{ems} in order to be compatible with
- \term{implementation-defined} variable-width fonts while still not
- requiring the language to provide support for fonts.
- \endissue{PRETTY-PRINT-INTERFACE}
- \endcom
- %-------------------- Printer Errors --------------------
- %%% ========== PRINT-NOT-READABLE
- \begincom{print-not-readable}\ftype{Condition Type}
- \issue{DATA-IO:ADD-SUPPORT}
- \label Class Precedence List::
- \typeref{print-not-readable},
- \typeref{error},
- \typeref{serious-condition},
- \typeref{condition},
- \typeref{t}
- \label Description::
- \Thetype{print-not-readable} consists of error conditions that occur during
- output while \varref{*print-readably*} is \term{true}, as a result of attempting
- to write a printed representation with the \term{Lisp printer}
- that would not be correctly read back with the \term{Lisp reader}.
- The object which could not be printed is initialized by
- \theinitkeyarg{object} to \funref{make-condition}, and is \term{accessed} by
- \thefunction{print-not-readable-object}.
- \endissue{DATA-IO:ADD-SUPPORT}
- \label See Also::
- \funref{print-not-readable-object}
- \endcom%{print-not-readable}\ftype{Condition Type}
- %%% ========== PRINT-NOT-READABLE-OBJECT
- \begincom{print-not-readable-object}\ftype{Function}
- \issue{DATA-IO:ADD-SUPPORT}
- \label Syntax::
- \DefunWithValues print-not-readable-object {condition} {object}
- \label Arguments and Values::
- \param{condition}---a \term{condition} \oftype{print-not-readable}.
- \param{object}---an \term{object}.
- \label Description::
- Returns the \term{object} that could not be printed readably
- in the situation represented by \param{condition}.
- \label Examples:\None.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \typeref{print-not-readable},
- {\secref\Conditions}
- \label Notes:\None.
- %% Should not be needed.
- %It is an error to use \macref{setf} with \funref{print-not-readable-object}.
- \endissue{DATA-IO:ADD-SUPPORT}
- \endcom
- %%% ========== FORMAT
- \begincom{format}\ftype{Function}
- \label Syntax::
- \DefunWithValues {format} {destination control-string {\rest} args} {result}
- \label Arguments and Values::
- \param{destination}---\nil,
- \t,
- a \term{stream},
- or a \term{string} with a \term{fill pointer}.
- \issue{FORMAT-STRING-ARGUMENTS:SPECIFY}
- \param{control-string}---a \term{format control}.
- \endissue{FORMAT-STRING-ARGUMENTS:SPECIFY}
- \param{args}---\term{format arguments} for \param{control-string}.
- \param{result}---if \param{destination} is \term{non-nil}, then \nil;
- otherwise, a \term{string}.
- \label Description::
- %% 22.3.2 6
- \funref{format} produces formatted output by outputting the characters
- of \param{control-string} and observing that a \term{tilde}
- introduces a directive. The character after the tilde, possibly preceded
- by prefix parameters and modifiers, specifies what kind of formatting
- is desired. Most directives use one or more elements of \param{args} to
- create their output.
- If \param{destination} is a \term{string}, a \term{stream}, or \t,
- then the \param{result} is \nil. Otherwise, the \param{result} is
- a \term{string} containing the `output.'
- %% 22.3.1 21
- \funref{format} is useful for producing nicely formatted text, producing
- good-looking messages, and so on. \funref{format} can generate and return
- a \term{string} or output to \param{destination}.
- For details on how the \param{control-string} is interpreted,
- \seesection\FormattedOutput.
- \label Examples:\None.
- \label Affected By::
- \varref{*standard-output*},
- \varref{*print-escape*},
- \varref{*print-radix*},
- \varref{*print-base*},
- \varref{*print-circle*},
- \varref{*print-pretty*},
- \varref{*print-level*},
- \varref{*print-length*},
- \varref{*print-case*},
- \varref{*print-gensym*},
- \varref{*print-array*}.
- \label Exceptional Situations::
- \issue{STRING-OUTPUT-STREAM-BASHING:UNDEFINED}
- If \param{destination} is a \term{string} with a \term{fill pointer},
- the consequences are undefined if destructive modifications are performed
- directly on the \term{string} during the \term{dynamic extent} of the call.
- \endissue{STRING-OUTPUT-STREAM-BASHING:UNDEFINED}
- \label See Also::
- \funref{write},
- {\secref\ImplementationDefinedScripts}
- \label Notes:\None.
- \endcom
|