PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/proc/self/root/proc/thread-self/root/usr/share/guile/2.0/ice-9/
Upload File :
Current File : //proc/self/root/proc/thread-self/root/usr/share/guile/2.0/ice-9/format.scm
;;;; "format.scm" Common LISP text output formatter for SLIB
;;; 	Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc.
;;;
;;; This library is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU Lesser General Public
;;; License as published by the Free Software Foundation; either
;;; version 3 of the License, or (at your option) any later version.
;;; 
;;; This library is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; Lesser General Public License for more details.
;;; 
;;; You should have received a copy of the GNU Lesser General Public
;;; License along with this library; if not, write to the Free Software
;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;;;

;;; This code was orignally in the public domain.
;;;
;;; Written 1992-1994 by Dirk Lutzebaeck (lutzeb@cs.tu-berlin.de).
;;;
;;; Authors of the version from SLIB (< 1.4) were Ken Dickey and Aubrey
;;; Jaffer.
;;;
;;; Assimilated into Guile May 1999.
;;;
;;; Please don't bother the original authors with bug reports, though;
;;; send them to bug-guile@gnu.org.
;;;

(define-module (ice-9 format)
  #:autoload (ice-9 pretty-print) (pretty-print truncated-print)
  #:autoload (ice-9 i18n)         (%global-locale number->locale-string)
  #:replace (format))

(define format:version "3.0")

(define (format destination format-string . format-args)
  (if (not (string? format-string))
      (error "format: expected a string for format string" format-string))

  (let* ((port
          (cond
           ((not destination)
            ;; Use a Unicode-capable output string port.
            (with-fluids ((%default-port-encoding "UTF-8"))
              (open-output-string)))
           ((boolean? destination) (current-output-port)) ; boolean but not false
           ((output-port? destination) destination)
           ((number? destination)
            (issue-deprecation-warning
             "Passing a number to format as the port is deprecated."
             "Pass (current-error-port) instead.")
            (current-error-port))
           (else
            (error "format: bad destination `~a'" destination))))

         (output-col (or (port-column port) 0))

         (flush-output? #f))

    (define format:case-conversion #f)
    (define format:pos 0)        ; curr. format string parsing position
    (define format:arg-pos 0)    ; curr. format argument position
					; this is global for error presentation
       
    ;; format string and char output routines on port

    (define (format:out-str str)
      (if format:case-conversion
          (display (format:case-conversion str) port)
          (display str port))
      (set! output-col
            (+ output-col (string-length str))))

    (define (format:out-char ch)
      (if format:case-conversion
          (display (format:case-conversion (string ch))
                   port)
          (write-char ch port))
      (set! output-col
            (if (char=? ch #\newline)
                0
                (+ output-col 1))))
       
    ;;(define (format:out-substr str i n)  ; this allocates a new string
    ;;  (display (substring str i n) port)
    ;;  (set! output-col (+ output-col n)))

    (define (format:out-substr str i n)
      (do ((k i (+ k 1)))
          ((= k n))
        (write-char (string-ref str k) port))
      (set! output-col (+ output-col (- n i))))

    ;;(define (format:out-fill n ch)       ; this allocates a new string
    ;;  (format:out-str (make-string n ch)))

    (define (format:out-fill n ch)
      (do ((i 0 (+ i 1)))
          ((= i n))
        (write-char ch port))
      (set! output-col (+ output-col n)))

    ;; format's user error handler

    (define (format:error . args)       ; never returns!
      (let ((port (current-error-port)))
        (set! format:error format:intern-error)
        (if (not (zero? format:arg-pos))
            (set! format:arg-pos (- format:arg-pos 1)))
        (format port
                "~%FORMAT: error with call: (format ~a \"~a<===~a\" ~
                                  ~{~a ~}===>~{~a ~})~%        "
                destination
                (substring format-string 0 format:pos)
                (substring format-string format:pos
                           (string-length format-string))
                (list-head format-args format:arg-pos)
                (list-tail format-args format:arg-pos))
        (apply format port args)
        (newline port)
        (set! format:error format:error-save)
        (format:abort)))

    (define (format:intern-error . args)
      ;;if something goes wrong in format:error
      (display "FORMAT: INTERNAL ERROR IN FORMAT:ERROR!") (newline)
      (display "        destination: ") (write destination) (newline)
      (display "        format string: ") (write format-string) (newline)
      (display "        format args: ") (write format-args) (newline)
      (display "        error args:  ") (write args) (newline)
      (set! format:error format:error-save)
      (format:abort))
	      
    (define format:error-save format:error)
  
    (define format:parameter-characters
      '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\- #\+ #\v #\# #\'))

    (define (format:format-work format-string arglist) ; does the formatting work
      (letrec
          ((format-string-len (string-length format-string))
           (arg-pos 0)               ; argument position in arglist
           (arg-len (length arglist))   ; number of arguments
           (modifier #f)                ; 'colon | 'at | 'colon-at | #f
           (params '())                 ; directive parameter list
           (param-value-found #f)       ; a directive
					; parameter value
					; found
           (conditional-nest 0)         ; conditional nesting level
           (clause-pos 0)               ; last cond. clause
					; beginning char pos
           (clause-default #f)		; conditional default
					; clause string
           (clauses '())                ; conditional clause
					; string list
           (conditional-type #f)        ; reflects the
					; contional modifiers
           (conditional-arg #f)      ; argument to apply the conditional
           (iteration-nest 0)        ; iteration nesting level
           (iteration-pos 0)         ; iteration string
					; beginning char pos
           (iteration-type #f)		; reflects the
					; iteration modifiers
           (max-iterations #f)		; maximum number of
					; iterations
           (recursive-pos-save format:pos)
	       
           (next-char			; gets the next char
					; from format-string
            (lambda ()
              (let ((ch (peek-next-char)))
                (set! format:pos (+ 1 format:pos))
                ch)))
	       
           (peek-next-char
            (lambda ()
              (if (>= format:pos format-string-len)
                  (format:error "illegal format string")
                  (string-ref format-string format:pos))))
	       
           (one-positive-integer?
            (lambda (params)
              (cond
               ((null? params) #f)
               ((and (integer? (car params))
                     (>= (car params) 0)
                     (= (length params) 1)) #t)
               (else
                (format:error
                 "one positive integer parameter expected")))))
	       
           (next-arg
            (lambda ()
              (if (>= arg-pos arg-len)
                  (begin
                    (set! format:arg-pos (+ arg-len 1))
                    (format:error "missing argument(s)")))
              (add-arg-pos 1)
              (list-ref arglist (- arg-pos 1))))
	       
           (prev-arg
            (lambda ()
              (add-arg-pos -1)
              (if (negative? arg-pos)
                  (format:error "missing backward argument(s)"))
              (list-ref arglist arg-pos)))
	       
           (rest-args
            (lambda ()
              (let loop ((l arglist) (k arg-pos)) ; list-tail definition
                (if (= k 0) l (loop (cdr l) (- k 1))))))
	       
           (add-arg-pos
            (lambda (n) 
              (set! arg-pos (+ n arg-pos))
              (set! format:arg-pos arg-pos)))
	       
           (anychar-dispatch		; dispatches the format-string
            (lambda ()
              (if (>= format:pos format-string-len)
                  arg-pos               ; used for ~? continuance
                  (let ((char (next-char)))
                    (cond
                     ((char=? char #\~)
                      (set! modifier #f)
                      (set! params '())
                      (set! param-value-found #f)
                      (tilde-dispatch))
                     (else
                      (if (and (zero? conditional-nest)
                               (zero? iteration-nest))
                          (format:out-char char))
                      (anychar-dispatch)))))))
	       
           (tilde-dispatch
            (lambda ()
              (cond
               ((>= format:pos format-string-len)
                (format:out-str "~")	; tilde at end of
					; string is just
					; output
                arg-pos)                ; used for ~?
					; continuance
               ((and (or (zero? conditional-nest)
                         (memv (peek-next-char) ; find conditional
					; directives
                               (append '(#\[ #\] #\; #\: #\@ #\^)
                                       format:parameter-characters)))
                     (or (zero? iteration-nest)
                         (memv (peek-next-char) ; find iteration
					; directives
                               (append '(#\{ #\} #\: #\@ #\^)
                                       format:parameter-characters))))
                (case (char-upcase (next-char))
		      
                  ;; format directives
		      
                  ((#\A)                ; Any -- for humans
                   (set! format:read-proof
                         (memq modifier '(colon colon-at)))
                   (format:out-obj-padded (memq modifier '(at colon-at))
                                          (next-arg) #f params)
                   (anychar-dispatch))
                  ((#\S)                ; Slashified -- for parsers
                   (set! format:read-proof
                         (memq modifier '(colon colon-at)))
                   (format:out-obj-padded (memq modifier '(at colon-at))
                                          (next-arg) #t params)
                   (anychar-dispatch))
                  ((#\D)                ; Decimal
                   (format:out-num-padded modifier (next-arg) params 10)
                   (anychar-dispatch))
                  ((#\H)                ; Localized number
                   (let* ((num      (next-arg))
                          (locale   (case modifier
                                      ((colon) (next-arg))
                                      (else    %global-locale)))
                          (argc     (length params))
                          (width    (format:par params argc 0 #f "width"))
                          (decimals (format:par params argc 1 #t "decimals"))
                          (padchar  (integer->char
                                     (format:par params argc 2 format:space-ch
                                                 "padchar")))
                          (str      (number->locale-string num decimals
                                                           locale)))
                     (format:out-str (if (and width
                                              (< (string-length str) width))
                                         (string-pad str width padchar)
                                         str)))
                   (anychar-dispatch))
                  ((#\X)                ; Hexadecimal
                   (format:out-num-padded modifier (next-arg) params 16)
                   (anychar-dispatch))
                  ((#\O)                ; Octal
                   (format:out-num-padded modifier (next-arg) params 8)
                   (anychar-dispatch))
                  ((#\B)                ; Binary
                   (format:out-num-padded modifier (next-arg) params 2)
                   (anychar-dispatch))
                  ((#\R)
                   (if (null? params)
                       (format:out-obj-padded ; Roman, cardinal,
					; ordinal numerals
                        #f
                        ((case modifier
                           ((at) format:num->roman)
                           ((colon-at) format:num->old-roman)
                           ((colon) format:num->ordinal)
                           (else format:num->cardinal))
                         (next-arg))
                        #f params)
                       (format:out-num-padded ; any Radix
                        modifier (next-arg) (cdr params) (car params)))
                   (anychar-dispatch))
                  ((#\F)                ; Fixed-format floating-point
                   (format:out-fixed modifier (next-arg) params)
                   (anychar-dispatch))
                  ((#\E)                ; Exponential floating-point
                   (format:out-expon modifier (next-arg) params)
                   (anychar-dispatch))
                  ((#\G)                ; General floating-point
                   (format:out-general modifier (next-arg) params)
                   (anychar-dispatch))
                  ((#\$)                ; Dollars floating-point
                   (format:out-dollar modifier (next-arg) params)
                   (anychar-dispatch))
                  ((#\I)                ; Complex numbers
                   (let ((z (next-arg)))
                     (if (not (complex? z))
                         (format:error "argument not a complex number"))
                     (format:out-fixed modifier (real-part z) params)
                     (format:out-fixed 'at (imag-part z) params)
                     (format:out-char #\i))
                   (anychar-dispatch))
                  ((#\C)                ; Character
                   (let ((ch (if (one-positive-integer? params)
                                 (integer->char (car params))
                                 (next-arg))))
                     (if (not (char? ch))
                         (format:error "~~c expects a character"))
                     (case modifier
                       ((at)
                        (format:out-str (object->string ch)))
                       ((colon)
                        (let ((c (char->integer ch)))
                          (if (< c 0)
                              (set! c (+ c 256))) ; compensate
					; complement
					; impl.
                          (cond
                           ((< c #x20)	; assumes that control
					; chars are < #x20
                            (format:out-char #\^)
                            (format:out-char
                             (integer->char (+ c #x40))))
                           ((>= c #x7f)
                            (format:out-str "#\\")
                            (format:out-str
                             (number->string c 8)))
                           (else
                            (format:out-char ch)))))
                       (else (format:out-char ch))))
                   (anychar-dispatch))
                  ((#\P)                ; Plural
                   (if (memq modifier '(colon colon-at))
                       (prev-arg))
                   (let ((arg (next-arg)))
                     (if (not (number? arg))
                         (format:error "~~p expects a number argument"))
                     (if (= arg 1)
                         (if (memq modifier '(at colon-at))
                             (format:out-char #\y))
                         (if (memq modifier '(at colon-at))
                             (format:out-str "ies")
                             (format:out-char #\s))))
                   (anychar-dispatch))
                  ((#\~)                ; Tilde
                   (if (one-positive-integer? params)
                       (format:out-fill (car params) #\~)
                       (format:out-char #\~))
                   (anychar-dispatch))
                  ((#\%)                ; Newline
                   (if (one-positive-integer? params)
                       (format:out-fill (car params) #\newline)
                       (format:out-char #\newline))
                   (set! output-col 0)
                   (anychar-dispatch))
                  ((#\&)                ; Fresh line
                   (if (one-positive-integer? params)
                       (begin
                         (if (> (car params) 0)
                             (format:out-fill (- (car params)
                                                 (if (>
                                                      output-col
                                                      0) 0 1))
                                              #\newline))
                         (set! output-col 0))
                       (if (> output-col 0)
                           (format:out-char #\newline)))
                   (anychar-dispatch))
                  ((#\_)                ; Space character
                   (if (one-positive-integer? params)
                       (format:out-fill (car params) #\space)
                       (format:out-char #\space))
                   (anychar-dispatch))
                  ((#\/)                ; Tabulator character
                   (if (one-positive-integer? params)
                       (format:out-fill (car params) #\tab)
                       (format:out-char #\tab))
                   (anychar-dispatch))
                  ((#\|)                ; Page seperator
                   (if (one-positive-integer? params)
                       (format:out-fill (car params) #\page)
                       (format:out-char #\page))
                   (set! output-col 0)
                   (anychar-dispatch))
                  ((#\T)                ; Tabulate
                   (format:tabulate modifier params)
                   (anychar-dispatch))
                  ((#\Y)                ; Structured print
                   (let ((width (if (one-positive-integer? params)
                                    (car params)
                                    79)))
                     (case modifier
                       ((at)
                        (format:out-str
                         (call-with-output-string
                           (lambda (p)
                             (truncated-print (next-arg) p
                                              #:width width)))))
                       ((colon-at)
                        (format:out-str
                         (call-with-output-string
                           (lambda (p)
                             (truncated-print (next-arg) p
                                              #:width
                                              (max (- width
                                                      output-col)
                                                   1))))))
                       ((colon)
                        (format:error "illegal modifier in ~~?"))
                       (else
                        (pretty-print (next-arg) port
                                      #:width width)
                        (set! output-col 0))))
                   (anychar-dispatch))
                  ((#\? #\K)         ; Indirection (is "~K" in T-Scheme)
                   (cond
                    ((memq modifier '(colon colon-at))
                     (format:error "illegal modifier in ~~?"))
                    ((eq? modifier 'at)
                     (let* ((frmt (next-arg))
                            (args (rest-args)))
                       (add-arg-pos (format:format-work frmt args))))
                    (else
                     (let* ((frmt (next-arg))
                            (args (next-arg)))
                       (format:format-work frmt args))))
                   (anychar-dispatch))
                  ((#\!)                ; Flush output
                   (set! flush-output? #t)
                   (anychar-dispatch))
                  ((#\newline)		; Continuation lines
                   (if (eq? modifier 'at)
                       (format:out-char #\newline))
                   (if (< format:pos format-string-len)
                       (do ((ch (peek-next-char) (peek-next-char)))
                           ((or (not (char-whitespace? ch))
                                (= format:pos (- format-string-len 1))))
                         (if (eq? modifier 'colon)
                             (format:out-char (next-char))
                             (next-char))))
                   (anychar-dispatch))
                  ((#\*)                ; Argument jumping
                   (case modifier
                     ((colon)		; jump backwards
                      (if (one-positive-integer? params)
                          (do ((i 0 (+ i 1)))
                              ((= i (car params)))
                            (prev-arg))
                          (prev-arg)))
                     ((at)              ; jump absolute
                      (set! arg-pos (if (one-positive-integer? params)
                                        (car params) 0)))
                     ((colon-at)
                      (format:error "illegal modifier `:@' in ~~* directive"))
                     (else              ; jump forward
                      (if (one-positive-integer? params)
                          (do ((i 0 (+ i 1)))
                              ((= i (car params)))
                            (next-arg))
                          (next-arg))))
                   (anychar-dispatch))
                  ((#\()                ; Case conversion begin
                   (set! format:case-conversion
                         (case modifier
                           ((at) string-capitalize-first)
                           ((colon) string-capitalize)
                           ((colon-at) string-upcase)
                           (else string-downcase)))
                   (anychar-dispatch))
                  ((#\))                ; Case conversion end
                   (if (not format:case-conversion)
                       (format:error "missing ~~("))
                   (set! format:case-conversion #f)
                   (anychar-dispatch))
                  ((#\[)                ; Conditional begin
                   (set! conditional-nest (+ conditional-nest 1))
                   (cond
                    ((= conditional-nest 1)
                     (set! clause-pos format:pos)
                     (set! clause-default #f)
                     (set! clauses '())
                     (set! conditional-type
                           (case modifier
                             ((at) 'if-then)
                             ((colon) 'if-else-then)
                             ((colon-at) (format:error "illegal modifier in ~~["))
                             (else 'num-case)))
                     (set! conditional-arg
                           (if (one-positive-integer? params)
                               (car params)
                               (next-arg)))))
                   (anychar-dispatch))
                  ((#\;)                ; Conditional separator
                   (if (zero? conditional-nest)
                       (format:error "~~; not in ~~[~~] conditional"))
                   (if (not (null? params))
                       (format:error "no parameter allowed in ~~;"))
                   (if (= conditional-nest 1)
                       (let ((clause-str
                              (cond
                               ((eq? modifier 'colon)
                                (set! clause-default #t)
                                (substring format-string clause-pos 
                                           (- format:pos 3)))
                               ((memq modifier '(at colon-at))
                                (format:error "illegal modifier in ~~;"))
                               (else
                                (substring format-string clause-pos
                                           (- format:pos 2))))))
                         (set! clauses (append clauses (list clause-str)))
                         (set! clause-pos format:pos)))
                   (anychar-dispatch))
                  ((#\])                ; Conditional end
                   (if (zero? conditional-nest) (format:error "missing ~~["))
                   (set! conditional-nest (- conditional-nest 1))
                   (if modifier
                       (format:error "no modifier allowed in ~~]"))
                   (if (not (null? params))
                       (format:error "no parameter allowed in ~~]"))
                   (cond
                    ((zero? conditional-nest)
                     (let ((clause-str (substring format-string clause-pos
                                                  (- format:pos 2))))
                       (if clause-default
                           (set! clause-default clause-str)
                           (set! clauses (append clauses (list clause-str)))))
                     (case conditional-type
                       ((if-then)
                        (if conditional-arg
                            (format:format-work (car clauses)
                                                (list conditional-arg))))
                       ((if-else-then)
                        (add-arg-pos
                         (format:format-work (if conditional-arg
                                                 (cadr clauses)
                                                 (car clauses))
                                             (rest-args))))
                       ((num-case)
                        (if (or (not (integer? conditional-arg))
                                (< conditional-arg 0))
                            (format:error "argument not a positive integer"))
                        (if (not (and (>= conditional-arg (length clauses))
                                      (not clause-default)))
                            (add-arg-pos
                             (format:format-work
                              (if (>= conditional-arg (length clauses))
                                  clause-default
                                  (list-ref clauses conditional-arg))
                              (rest-args))))))))
                   (anychar-dispatch))
                  ((#\{)                ; Iteration begin
                   (set! iteration-nest (+ iteration-nest 1))
                   (cond
                    ((= iteration-nest 1)
                     (set! iteration-pos format:pos)
                     (set! iteration-type
                           (case modifier
                             ((at) 'rest-args)
                             ((colon) 'sublists)
                             ((colon-at) 'rest-sublists)
                             (else 'list)))
                     (set! max-iterations (if (one-positive-integer? params)
                                              (car params) #f))))
                   (anychar-dispatch))
                  ((#\})                ; Iteration end
                   (if (zero? iteration-nest) (format:error "missing ~~{"))
                   (set! iteration-nest (- iteration-nest 1))
                   (case modifier
                     ((colon)
                      (if (not max-iterations) (set! max-iterations 1)))
                     ((colon-at at) (format:error "illegal modifier")))
                   (if (not (null? params))
                       (format:error "no parameters allowed in ~~}"))
                   (if (zero? iteration-nest)
                       (let ((iteration-str
                              (substring format-string iteration-pos
                                         (- format:pos (if modifier 3 2)))))
                         (if (string=? iteration-str "")
                             (set! iteration-str (next-arg)))
                         (case iteration-type
                           ((list)
                            (let ((args (next-arg))
                                  (args-len 0))
                              (if (not (list? args))
                                  (format:error "expected a list argument"))
                              (set! args-len (length args))
                              (do ((arg-pos 0 (+ arg-pos
                                                 (format:format-work
                                                  iteration-str
                                                  (list-tail args arg-pos))))
                                   (i 0 (+ i 1)))
                                  ((or (>= arg-pos args-len)
                                       (and max-iterations
                                            (>= i max-iterations)))))))
                           ((sublists)
                            (let ((args (next-arg))
                                  (args-len 0))
                              (if (not (list? args))
                                  (format:error "expected a list argument"))
                              (set! args-len (length args))
                              (do ((arg-pos 0 (+ arg-pos 1)))
                                  ((or (>= arg-pos args-len)
                                       (and max-iterations
                                            (>= arg-pos max-iterations))))
                                (let ((sublist (list-ref args arg-pos)))
                                  (if (not (list? sublist))
                                      (format:error
                                       "expected a list of lists argument"))
                                  (format:format-work iteration-str sublist)))))
                           ((rest-args)
                            (let* ((args (rest-args))
                                   (args-len (length args))
                                   (usedup-args
                                    (do ((arg-pos 0 (+ arg-pos
                                                       (format:format-work
                                                        iteration-str
                                                        (list-tail
                                                         args arg-pos))))
                                         (i 0 (+ i 1)))
                                        ((or (>= arg-pos args-len)
                                             (and max-iterations
                                                  (>= i max-iterations)))
                                         arg-pos))))
                              (add-arg-pos usedup-args)))
                           ((rest-sublists)
                            (let* ((args (rest-args))
                                   (args-len (length args))
                                   (usedup-args
                                    (do ((arg-pos 0 (+ arg-pos 1)))
                                        ((or (>= arg-pos args-len)
                                             (and max-iterations
                                                  (>= arg-pos max-iterations)))
                                         arg-pos)
                                      (let ((sublist (list-ref args arg-pos)))
                                        (if (not (list? sublist))
                                            (format:error "expected list arguments"))
                                        (format:format-work iteration-str sublist)))))
                              (add-arg-pos usedup-args)))
                           (else (format:error "internal error in ~~}")))))
                   (anychar-dispatch))
                  ((#\^)                ; Up and out
                   (let* ((continue
                           (cond
                            ((not (null? params))
                             (not
                              (case (length params)
                                ((1) (zero? (car params)))
                                ((2) (= (list-ref params 0) (list-ref params 1)))
                                ((3) (<= (list-ref params 0)
                                         (list-ref params 1)
                                         (list-ref params 2)))
                                (else (format:error "too much parameters")))))
                            (format:case-conversion ; if conversion stop conversion
                             (set! format:case-conversion string-copy) #t)
                            ((= iteration-nest 1) #t)
                            ((= conditional-nest 1) #t)
                            ((>= arg-pos arg-len)
                             (set! format:pos format-string-len) #f)
                            (else #t))))
                     (if continue
                         (anychar-dispatch))))

                  ;; format directive modifiers and parameters

                  ((#\@)                ; `@' modifier
                   (if (memq modifier '(at colon-at))
                       (format:error "double `@' modifier"))
                   (set! modifier (if (eq? modifier 'colon) 'colon-at 'at))
                   (tilde-dispatch))
                  ((#\:)                ; `:' modifier
                   (if (memq modifier '(colon colon-at))
                       (format:error "double `:' modifier"))
                   (set! modifier (if (eq? modifier 'at) 'colon-at 'colon))
                   (tilde-dispatch))
                  ((#\')                ; Character parameter
                   (if modifier (format:error "misplaced modifier"))
                   (set! params (append params (list (char->integer (next-char)))))
                   (set! param-value-found #t)
                   (tilde-dispatch))
                  ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\- #\+) ; num. paramtr
                   (if modifier (format:error "misplaced modifier"))
                   (let ((num-str-beg (- format:pos 1))
                         (num-str-end format:pos))
                     (do ((ch (peek-next-char) (peek-next-char)))
                         ((not (char-numeric? ch)))
                       (next-char)
                       (set! num-str-end (+ 1 num-str-end)))
                     (set! params
                           (append params
                                   (list (string->number
                                          (substring format-string
                                                     num-str-beg
                                                     num-str-end))))))
                   (set! param-value-found #t)
                   (tilde-dispatch))
                  ((#\V)           ; Variable parameter from next argum.
                   (if modifier (format:error "misplaced modifier"))
                   (set! params (append params (list (next-arg))))
                   (set! param-value-found #t)
                   (tilde-dispatch))
                  ((#\#)         ; Parameter is number of remaining args
                   (if param-value-found (format:error "misplaced '#'"))
                   (if modifier (format:error "misplaced modifier"))
                   (set! params (append params (list (length (rest-args)))))
                   (set! param-value-found #t)
                   (tilde-dispatch))
                  ((#\,)                ; Parameter separators
                   (if modifier (format:error "misplaced modifier"))
                   (if (not param-value-found)
                       (set! params (append params '(#f)))) ; append empty paramtr
                   (set! param-value-found #f)
                   (tilde-dispatch))
                  ((#\Q)                ; Inquiry messages
                   (if (eq? modifier 'colon)
                       (format:out-str format:version)
                       (let ((nl (string #\newline)))
                         (format:out-str
                          (string-append
                           "SLIB Common LISP format version " format:version nl
                           "  (C) copyright 1992-1994 by Dirk Lutzebaeck" nl
                           "  please send bug reports to `lutzeb@cs.tu-berlin.de'"
                           nl))))
                   (anychar-dispatch))
                  (else                 ; Unknown tilde directive
                   (format:error "unknown control character `~c'"
                                 (string-ref format-string (- format:pos 1))))))
               (else (anychar-dispatch)))))) ; in case of conditional

        (set! format:pos 0)
        (set! format:arg-pos 0)
        (anychar-dispatch)              ; start the formatting
        (set! format:pos recursive-pos-save)
        arg-pos))                 ; return the position in the arg. list

    ;; when format:read-proof is true, format:obj->str will wrap
    ;; result strings starting with "#<" in an extra pair of double
    ;; quotes.
       
    (define format:read-proof #f)

    ;; format:obj->str returns a R4RS representation as a string of
    ;; an arbitrary scheme object.

    (define (format:obj->str obj slashify)
      (let ((res (if slashify
                     (object->string obj)
                     (call-with-output-string (lambda (p) (display obj p))))))
        (if (and format:read-proof (string-prefix? "#<" res))
            (object->string res)
            res)))

    (define format:space-ch (char->integer #\space))
    (define format:zero-ch (char->integer #\0))

    (define (format:par pars length index default name)
      (if (> length index)
          (let ((par (list-ref pars index)))
            (if par
                (if name
                    (if (< par 0)
                        (format:error 
                         "~s parameter must be a positive integer" name)
                        par)
                    par)
                default))
          default))

    (define (format:out-obj-padded pad-left obj slashify pars)
      (if (null? pars)
          (format:out-str (format:obj->str obj slashify))
          (let ((l (length pars)))
            (let ((mincol (format:par pars l 0 0 "mincol"))
                  (colinc (format:par pars l 1 1 "colinc"))
                  (minpad (format:par pars l 2 0 "minpad"))
                  (padchar (integer->char
                            (format:par pars l 3 format:space-ch #f)))
                  (objstr (format:obj->str obj slashify)))
              (if (not pad-left)
                  (format:out-str objstr))
              (do ((objstr-len (string-length objstr))
                   (i minpad (+ i colinc)))
                  ((>= (+ objstr-len i) mincol)
                   (format:out-fill i padchar)))
              (if pad-left
                  (format:out-str objstr))))))

    (define (format:out-num-padded modifier number pars radix)
      (if (not (integer? number)) (format:error "argument not an integer"))
      (let ((numstr (number->string number radix)))
        (if (and (null? pars) (not modifier))
            (format:out-str numstr)
            (let ((l (length pars))
                  (numstr-len (string-length numstr)))
              (let ((mincol (format:par pars l 0 #f "mincol"))
                    (padchar (integer->char
                              (format:par pars l 1 format:space-ch #f)))
                    (commachar (integer->char
                                (format:par pars l 2 (char->integer #\,) #f)))
                    (commawidth (format:par pars l 3 3 "commawidth")))
                (if mincol
                    (let ((numlen numstr-len)) ; calc. the output len of number
                      (if (and (memq modifier '(at colon-at)) (>= number 0))
                          (set! numlen (+ numlen 1)))
                      (if (memq modifier '(colon colon-at))
                          (set! numlen (+ (quotient (- numstr-len 
                                                       (if (< number 0) 2 1))
                                                    commawidth)
                                          numlen)))
                      (if (> mincol numlen)
                          (format:out-fill (- mincol numlen) padchar))))
                (if (and (memq modifier '(at colon-at))
                         (>= number 0))
                    (format:out-char #\+))
                (if (memq modifier '(colon colon-at)) ; insert comma character
                    (let ((start (remainder numstr-len commawidth))
                          (ns (if (< number 0) 1 0)))
                      (format:out-substr numstr 0 start)
                      (do ((i start (+ i commawidth)))
                          ((>= i numstr-len))
                        (if (> i ns)
                            (format:out-char commachar))
                        (format:out-substr numstr i (+ i commawidth))))
                    (format:out-str numstr)))))))

    (define (format:tabulate modifier pars)
      (let ((l (length pars)))
        (let ((colnum (format:par pars l 0 1 "colnum"))
              (colinc (format:par pars l 1 1 "colinc"))
              (padch (integer->char (format:par pars l 2 format:space-ch #f))))
          (case modifier
            ((colon colon-at)
             (format:error "unsupported modifier for ~~t"))
            ((at)                       ; relative tabulation
             (format:out-fill
              (if (= colinc 0)
                  colnum                ; colnum = colrel
                  (do ((c 0 (+ c colinc))
                       (col (+ output-col colnum)))
                      ((>= c col)
                       (- c output-col))))
              padch))
            (else                       ; absolute tabulation
             (format:out-fill
              (cond
               ((< output-col colnum)
                (- colnum output-col))
               ((= colinc 0)
                0)
               (else
                (do ((c colnum (+ c colinc)))
                    ((>= c output-col)
                     (- c output-col)))))
              padch))))))


    ;; roman numerals (from dorai@cs.rice.edu).

    (define format:roman-alist
      '((1000 #\M) (500 #\D) (100 #\C) (50 #\L)
        (10 #\X) (5 #\V) (1 #\I)))

    (define format:roman-boundary-values
      '(100 100 10 10 1 1 #f))

    (define (format:num->old-roman n)
      (if (and (integer? n) (>= n 1))
          (let loop ((n n)
                     (romans format:roman-alist)
                     (s '()))
            (if (null? romans) (list->string (reverse s))
                (let ((roman-val (caar romans))
                      (roman-dgt (cadar romans)))
                  (do ((q (quotient n roman-val) (- q 1))
                       (s s (cons roman-dgt s)))
                      ((= q 0)
                       (loop (remainder n roman-val)
                             (cdr romans) s))))))
          (format:error "only positive integers can be romanized")))

    (define (format:num->roman n)
      (if (and (integer? n) (> n 0))
          (let loop ((n n)
                     (romans format:roman-alist)
                     (boundaries format:roman-boundary-values)
                     (s '()))
            (if (null? romans)
                (list->string (reverse s))
                (let ((roman-val (caar romans))
                      (roman-dgt (cadar romans))
                      (bdry (car boundaries)))
                  (let loop2 ((q (quotient n roman-val))
                              (r (remainder n roman-val))
                              (s s))
                    (if (= q 0)
                        (if (and bdry (>= r (- roman-val bdry)))
                            (loop (remainder r bdry) (cdr romans)
                                  (cdr boundaries)
                                  (cons roman-dgt
                                        (append
                                         (cdr (assv bdry romans))
                                         s)))
                            (loop r (cdr romans) (cdr boundaries) s))
                        (loop2 (- q 1) r (cons roman-dgt s)))))))
          (format:error "only positive integers can be romanized")))

    ;; cardinals & ordinals (from dorai@cs.rice.edu)

    (define format:cardinal-ones-list
      '(#f "one" "two" "three" "four" "five"
           "six" "seven" "eight" "nine" "ten" "eleven" "twelve" "thirteen"
           "fourteen" "fifteen" "sixteen" "seventeen" "eighteen"
           "nineteen"))

    (define format:cardinal-tens-list
      '(#f #f "twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty"
           "ninety"))

    (define (format:num->cardinal999 n)
      ;; this procedure is inspired by the Bruno Haible's CLisp
      ;; function format-small-cardinal, which converts numbers
      ;; in the range 1 to 999, and is used for converting each
      ;; thousand-block in a larger number
      (let* ((hundreds (quotient n 100))
             (tens+ones (remainder n 100))
             (tens (quotient tens+ones 10))
             (ones (remainder tens+ones 10)))
        (append
         (if (> hundreds 0)
             (append
              (string->list
               (list-ref format:cardinal-ones-list hundreds))
              (string->list" hundred")
              (if (> tens+ones 0) '(#\space) '()))
             '())
         (if (< tens+ones 20)
             (if (> tens+ones 0)
                 (string->list
                  (list-ref format:cardinal-ones-list tens+ones))
                 '())
             (append
              (string->list
               (list-ref format:cardinal-tens-list tens))
              (if (> ones 0)
                  (cons #\-
                        (string->list
                         (list-ref format:cardinal-ones-list ones)))
                  '()))))))

    (define format:cardinal-thousand-block-list
      '("" " thousand" " million" " billion" " trillion" " quadrillion"
        " quintillion" " sextillion" " septillion" " octillion" " nonillion"
        " decillion" " undecillion" " duodecillion" " tredecillion"
        " quattuordecillion" " quindecillion" " sexdecillion" " septendecillion"
        " octodecillion" " novemdecillion" " vigintillion"))

    (define (format:num->cardinal n)
      (cond ((not (integer? n))
             (format:error
              "only integers can be converted to English cardinals"))
            ((= n 0) "zero")
            ((< n 0) (string-append "minus " (format:num->cardinal (- n))))
            (else
             (let ((power3-word-limit
                    (length format:cardinal-thousand-block-list)))
               (let loop ((n n)
                          (power3 0)
                          (s '()))
                 (if (= n 0)
                     (list->string s)
                     (let ((n-before-block (quotient n 1000))
                           (n-after-block (remainder n 1000)))
                       (loop n-before-block
                             (+ power3 1)
                             (if (> n-after-block 0)
                                 (append
                                  (if (> n-before-block 0)
                                      (string->list ", ") '())
                                  (format:num->cardinal999 n-after-block)
                                  (if (< power3 power3-word-limit)
                                      (string->list
                                       (list-ref
                                        format:cardinal-thousand-block-list
                                        power3))
                                      (append
                                       (string->list " times ten to the ")
                                       (string->list
                                        (format:num->ordinal
                                         (* power3 3)))
                                       (string->list " power")))
                                  s)
                                 s)))))))))

    (define format:ordinal-ones-list
      '(#f "first" "second" "third" "fourth" "fifth"
           "sixth" "seventh" "eighth" "ninth" "tenth" "eleventh" "twelfth"
           "thirteenth" "fourteenth" "fifteenth" "sixteenth" "seventeenth"
           "eighteenth" "nineteenth"))

    (define format:ordinal-tens-list
      '(#f #f "twentieth" "thirtieth" "fortieth" "fiftieth" "sixtieth"
           "seventieth" "eightieth" "ninetieth"))

    (define (format:num->ordinal n)
      (cond ((not (integer? n))
             (format:error
              "only integers can be converted to English ordinals"))
            ((= n 0) "zeroth")
            ((< n 0) (string-append "minus " (format:num->ordinal (- n))))
            (else
             (let ((hundreds (quotient n 100))
                   (tens+ones (remainder n 100)))
               (string-append
                (if (> hundreds 0)
                    (string-append
                     (format:num->cardinal (* hundreds 100))
                     (if (= tens+ones 0) "th" " "))
                    "")
                (if (= tens+ones 0) ""
                    (if (< tens+ones 20)
                        (list-ref format:ordinal-ones-list tens+ones)
                        (let ((tens (quotient tens+ones 10))
                              (ones (remainder tens+ones 10)))
                          (if (= ones 0)
                              (list-ref format:ordinal-tens-list tens)
                              (string-append
                               (list-ref format:cardinal-tens-list tens)
                               "-"
                               (list-ref format:ordinal-ones-list ones))))
                        )))))))

    ;; format inf and nan.

    (define (format:out-inf-nan number width digits edigits overch padch)
      ;; inf and nan are always printed exactly as "+inf.0", "-inf.0" or
      ;; "+nan.0", suitably justified in their field.  We insist on
      ;; printing this exact form so that the numbers can be read back in.
      (let* ((str (number->string number))
             (len (string-length str))
             (dot (string-index str #\.))
             (digits (+ (or digits 0)
                        (if edigits (+ edigits 2) 0))))
        (if (and width overch (< width len))
            (format:out-fill width (integer->char overch))
            (let* ((leftpad (if width
                                (max (- width (max len (+ dot 1 digits))) 0)
                                0))
                   (rightpad (if width
                                 (max (- width leftpad len) 0)
                                 0))
                   (padch (integer->char (or padch format:space-ch)))) 
              (format:out-fill leftpad padch)
              (format:out-str str)
              (format:out-fill rightpad padch)))))

    ;; format fixed flonums (~F)

    (define (format:out-fixed modifier number pars)
      (if (not (or (number? number) (string? number)))
          (format:error "argument is not a number or a number string"))

      (let ((l (length pars)))
        (let ((width (format:par pars l 0 #f "width"))
              (digits (format:par pars l 1 #f "digits"))
              (scale (format:par pars l 2 0 #f))
              (overch (format:par pars l 3 #f #f))
              (padch (format:par pars l 4 format:space-ch #f)))

          (cond
           ((and (number? number)
                 (or (inf? number) (nan? number)))
            (format:out-inf-nan number width digits #f overch padch))

           (digits
            (format:parse-float number #t scale)
            (if (<= (- format:fn-len format:fn-dot) digits)
                (format:fn-zfill #f (- digits (- format:fn-len format:fn-dot)))
                (format:fn-round digits))
            (if width
                (let ((numlen (+ format:fn-len 1)))
                  (if (or (not format:fn-pos?) (eq? modifier 'at))
                      (set! numlen (+ numlen 1)))
                  (if (and (= format:fn-dot 0) (> width (+ digits 1)))
                      (set! numlen (+ numlen 1)))
                  (if (< numlen width)
                      (format:out-fill (- width numlen) (integer->char padch)))
                  (if (and overch (> numlen width))
                      (format:out-fill width (integer->char overch))
                      (format:fn-out modifier (> width (+ digits 1)))))
                (format:fn-out modifier #t)))

           (else
            (format:parse-float number #t scale)
            (format:fn-strip)
            (if width
                (let ((numlen (+ format:fn-len 1)))
                  (if (or (not format:fn-pos?) (eq? modifier 'at))
                      (set! numlen (+ numlen 1)))
                  (if (= format:fn-dot 0)
                      (set! numlen (+ numlen 1)))
                  (if (< numlen width)
                      (format:out-fill (- width numlen) (integer->char padch)))
                  (if (> numlen width)	; adjust precision if possible
                      (let ((dot-index (- numlen
                                          (- format:fn-len format:fn-dot))))
                        (if (> dot-index width)
                            (if overch ; numstr too big for required width
                                (format:out-fill width (integer->char overch))
                                (format:fn-out modifier #t))
                            (begin
                              (format:fn-round (- width dot-index))
                              (format:fn-out modifier #t))))
                      (format:fn-out modifier #t)))
                (format:fn-out modifier #t)))))))

    ;; format exponential flonums (~E)

    (define (format:out-expon modifier number pars)
      (if (not (or (number? number) (string? number)))
          (format:error "argument is not a number"))

      (let ((l (length pars)))
        (let ((width (format:par pars l 0 #f "width"))
              (digits (format:par pars l 1 #f "digits"))
              (edigits (format:par pars l 2 #f "exponent digits"))
              (scale (format:par pars l 3 1 #f))
              (overch (format:par pars l 4 #f #f))
              (padch (format:par pars l 5 format:space-ch #f))
              (expch (format:par pars l 6 #f #f)))
	      
          (cond
           ((and (number? number)
                 (or (inf? number) (nan? number)))
            (format:out-inf-nan number width digits edigits overch padch))

           (digits                      ; fixed precision

            (let ((digits (if (> scale 0)
                              (if (< scale (+ digits 2))
                                  (+ (- digits scale) 1)
                                  0)
                              digits)))
              (format:parse-float number #f scale)
              (if (<= (- format:fn-len format:fn-dot) digits)
                  (format:fn-zfill #f (- digits (- format:fn-len format:fn-dot)))
                  (format:fn-round digits))
              (if width
                  (if (and edigits overch (> format:en-len edigits))
                      (format:out-fill width (integer->char overch))
                      (let ((numlen (+ format:fn-len 3))) ; .E+
                        (if (or (not format:fn-pos?) (eq? modifier 'at))
                            (set! numlen (+ numlen 1)))
                        (if (and (= format:fn-dot 0) (> width (+ digits 1)))
                            (set! numlen (+ numlen 1)))	
                        (set! numlen
                              (+ numlen 
                                 (if (and edigits (>= edigits format:en-len))
                                     edigits 
                                     format:en-len)))
                        (if (< numlen width)
                            (format:out-fill (- width numlen)
                                             (integer->char padch)))
                        (if (and overch (> numlen width))
                            (format:out-fill width (integer->char overch))
                            (begin
                              (format:fn-out modifier (> width (- numlen 1)))
                              (format:en-out edigits expch)))))
                  (begin
                    (format:fn-out modifier #t)
                    (format:en-out edigits expch)))))

           (else
            (format:parse-float number #f scale)
            (format:fn-strip)
            (if width
                (if (and edigits overch (> format:en-len edigits))
                    (format:out-fill width (integer->char overch))
                    (let ((numlen (+ format:fn-len 3))) ; .E+
                      (if (or (not format:fn-pos?) (eq? modifier 'at))
                          (set! numlen (+ numlen 1)))
                      (if (= format:fn-dot 0)
                          (set! numlen (+ numlen 1)))
                      (set! numlen
                            (+ numlen
                               (if (and edigits (>= edigits format:en-len))
                                   edigits 
                                   format:en-len)))
                      (if (< numlen width)
                          (format:out-fill (- width numlen)
                                           (integer->char padch)))
                      (if (> numlen width) ; adjust precision if possible
                          (let ((f (- format:fn-len format:fn-dot))) ; fract len
                            (if (> (- numlen f) width)
                                (if overch ; numstr too big for required width
                                    (format:out-fill width 
                                                     (integer->char overch))
                                    (begin
                                      (format:fn-out modifier #t)
                                      (format:en-out edigits expch)))
                                (begin
                                  (format:fn-round (+ (- f numlen) width))
                                  (format:fn-out modifier #t)
                                  (format:en-out edigits expch))))
                          (begin
                            (format:fn-out modifier #t)
                            (format:en-out edigits expch)))))
                (begin
                  (format:fn-out modifier #t)
                  (format:en-out edigits expch))))))))
       
    ;; format general flonums (~G)

    (define (format:out-general modifier number pars)
      (if (not (or (number? number) (string? number)))
          (format:error "argument is not a number or a number string"))

      (let ((l (length pars)))
        (let ((width (if (> l 0) (list-ref pars 0) #f))
              (digits (if (> l 1) (list-ref pars 1) #f))
              (edigits (if (> l 2) (list-ref pars 2) #f))
              (overch (if (> l 4) (list-ref pars 4) #f))
              (padch (if (> l 5) (list-ref pars 5) #f)))
          (cond
           ((and (number? number)
                 (or (inf? number) (nan? number)))
            ;; FIXME: this isn't right.
            (format:out-inf-nan number width digits edigits overch padch))
           (else
            (format:parse-float number #t 0)
            (format:fn-strip)
            (let* ((ee (if edigits (+ edigits 2) 4)) ; for the following algorithm
                   (ww (if width (- width ee) #f)) ; see Steele's CL book p.395
                   (n (if (= format:fn-dot 0) ; number less than (abs 1.0) ?
                          (- (format:fn-zlead))
                          format:fn-dot))
                   (d (if digits
                          digits
                          (max format:fn-len (min n 7)))) ; q = format:fn-len
                   (dd (- d n)))
              (if (<= 0 dd d)
                  (begin
                    (format:out-fixed modifier number (list ww dd #f overch padch))
                    (format:out-fill ee #\space)) ;~@T not implemented yet
                  (format:out-expon modifier number pars))))))))

    ;; format dollar flonums (~$)

    (define (format:out-dollar modifier number pars)
      (if (not (or (number? number) (string? number)))
          (format:error "argument is not a number or a number string"))

      (let ((l (length pars)))
        (let ((digits (format:par pars l 0 2 "digits"))
              (mindig (format:par pars l 1 1 "mindig"))
              (width (format:par pars l 2 0 "width"))
              (padch (format:par pars l 3 format:space-ch #f)))

          (cond
           ((and (number? number)
                 (or (inf? number) (nan? number)))
            (format:out-inf-nan number width digits #f #f padch))

           (else
            (format:parse-float number #t 0)
            (if (<= (- format:fn-len format:fn-dot) digits)
                (format:fn-zfill #f (- digits (- format:fn-len format:fn-dot)))
                (format:fn-round digits))
            (let ((numlen (+ format:fn-len 1)))
              (if (or (not format:fn-pos?) (memq modifier '(at colon-at)))
                  (set! numlen (+ numlen 1)))
              (if (and mindig (> mindig format:fn-dot))
                  (set! numlen (+ numlen (- mindig format:fn-dot))))
              (if (and (= format:fn-dot 0) (not mindig))
                  (set! numlen (+ numlen 1)))
              (if (< numlen width)
                  (case modifier
                    ((colon)
                     (if (not format:fn-pos?)
                         (format:out-char #\-))
                     (format:out-fill (- width numlen) (integer->char padch)))
                    ((at)
                     (format:out-fill (- width numlen) (integer->char padch))
                     (format:out-char (if format:fn-pos? #\+ #\-)))
                    ((colon-at)
                     (format:out-char (if format:fn-pos? #\+ #\-))
                     (format:out-fill (- width numlen) (integer->char padch)))
                    (else
                     (format:out-fill (- width numlen) (integer->char padch))
                     (if (not format:fn-pos?)
                         (format:out-char #\-))))
                  (if format:fn-pos?
                      (if (memq modifier '(at colon-at)) (format:out-char #\+))
                      (format:out-char #\-))))
            (if (and mindig (> mindig format:fn-dot))
                (format:out-fill (- mindig format:fn-dot) #\0))
            (if (and (= format:fn-dot 0) (not mindig))
                (format:out-char #\0))
            (format:out-substr format:fn-str 0 format:fn-dot)
            (format:out-char #\.)
            (format:out-substr format:fn-str format:fn-dot format:fn-len))))))

					; the flonum buffers

    (define format:fn-max 400)          ; max. number of number digits
    (define format:fn-str (make-string format:fn-max)) ; number buffer
    (define format:fn-len 0)            ; digit length of number
    (define format:fn-dot #f)           ; dot position of number
    (define format:fn-pos? #t)          ; number positive?
    (define format:en-max 10)           ; max. number of exponent digits
    (define format:en-str (make-string format:en-max)) ; exponent buffer
    (define format:en-len 0)            ; digit length of exponent
    (define format:en-pos? #t)          ; exponent positive?

    (define (format:parse-float num fixed? scale)
      (let ((num-str (if (string? num)
                         num
                         (number->string (exact->inexact num)))))
        (set! format:fn-pos? #t)
        (set! format:fn-len 0)
        (set! format:fn-dot #f)
        (set! format:en-pos? #t)
        (set! format:en-len 0)
        (do ((i 0 (+ i 1))
             (left-zeros 0)
             (mantissa? #t)
             (all-zeros? #t)
             (num-len (string-length num-str))
             (c #f))                ; current exam. character in num-str
            ((= i num-len)
             (if (not format:fn-dot)
                 (set! format:fn-dot format:fn-len))

             (if all-zeros?
                 (begin
                   (set! left-zeros 0)
                   (set! format:fn-dot 0)
                   (set! format:fn-len 1)))

             ;; now format the parsed values according to format's need

             (if fixed?

                 (begin                 ; fixed format m.nnn or .nnn
                   (if (and (> left-zeros 0) (> format:fn-dot 0))
                       (if (> format:fn-dot left-zeros) 
                           (begin       ; norm 0{0}nn.mm to nn.mm
                             (format:fn-shiftleft left-zeros)
                             (set! format:fn-dot (- format:fn-dot left-zeros))
                             (set! left-zeros 0))
                           (begin       ; normalize 0{0}.nnn to .nnn
                             (format:fn-shiftleft format:fn-dot)
                             (set! left-zeros (- left-zeros format:fn-dot))
                             (set! format:fn-dot 0))))
                   (if (or (not (= scale 0)) (> format:en-len 0))
                       (let ((shift (+ scale (format:en-int))))
                         (cond
                          (all-zeros? #t)
                          ((> (+ format:fn-dot shift) format:fn-len)
                           (format:fn-zfill
                            #f (- shift (- format:fn-len format:fn-dot)))
                           (set! format:fn-dot format:fn-len))
                          ((< (+ format:fn-dot shift) 0)
                           (format:fn-zfill #t (- (- shift) format:fn-dot))
                           (set! format:fn-dot 0))
                          (else
                           (if (> left-zeros 0)
                               (if (<= left-zeros shift) ; shift always > 0 here
                                   (format:fn-shiftleft shift) ; shift out 0s
                                   (begin
                                     (format:fn-shiftleft left-zeros)
                                     (set! format:fn-dot (- shift left-zeros))))
                               (set! format:fn-dot (+ format:fn-dot shift))))))))

                 (let ((negexp          ; expon format m.nnnEee
                        (if (> left-zeros 0)
                            (- left-zeros format:fn-dot -1)
                            (if (= format:fn-dot 0) 1 0))))
                   (if (> left-zeros 0)
                       (begin           ; normalize 0{0}.nnn to n.nn
                         (format:fn-shiftleft left-zeros)
                         (set! format:fn-dot 1))
                       (if (= format:fn-dot 0)
                           (set! format:fn-dot 1)))
                   (format:en-set (- (+ (- format:fn-dot scale) (format:en-int))
                                     negexp))
                   (cond 
                    (all-zeros?
                     (format:en-set 0)
                     (set! format:fn-dot 1))
                    ((< scale 0)        ; leading zero
                     (format:fn-zfill #t (- scale))
                     (set! format:fn-dot 0))
                    ((> scale format:fn-dot)
                     (format:fn-zfill #f (- scale format:fn-dot))
                     (set! format:fn-dot scale))
                    (else
                     (set! format:fn-dot scale)))))
             #t)

          ;; do body      
          (set! c (string-ref num-str i)) ; parse the output of number->string
          (cond                         ; which can be any valid number
           ((char-numeric? c)           ; representation of R4RS except 
            (if mantissa?               ; complex numbers
                (begin
                  (if (char=? c #\0)
                      (if all-zeros?
                          (set! left-zeros (+ left-zeros 1)))
                      (begin
                        (set! all-zeros? #f)))
                  (string-set! format:fn-str format:fn-len c)
                  (set! format:fn-len (+ format:fn-len 1)))
                (begin
                  (string-set! format:en-str format:en-len c)
                  (set! format:en-len (+ format:en-len 1)))))
           ((or (char=? c #\-) (char=? c #\+))
            (if mantissa?
                (set! format:fn-pos? (char=? c #\+))
                (set! format:en-pos? (char=? c #\+))))
           ((char=? c #\.)
            (set! format:fn-dot format:fn-len))
           ((char=? c #\e)
            (set! mantissa? #f))
           ((char=? c #\E)
            (set! mantissa? #f))
           ((char-whitespace? c) #t)
           ((char=? c #\d) #t)          ; decimal radix prefix
           ((char=? c #\#) #t)
           (else
            (format:error "illegal character `~c' in number->string" c))))))

    (define (format:en-int)         ; convert exponent string to integer
      (if (= format:en-len 0)
          0
          (do ((i 0 (+ i 1))
               (n 0))
              ((= i format:en-len) 
               (if format:en-pos?
                   n
                   (- n)))
            (set! n (+ (* n 10) (- (char->integer (string-ref format:en-str i))
                                   format:zero-ch))))))

    (define (format:en-set en)          ; set exponent string number
      (set! format:en-len 0)
      (set! format:en-pos? (>= en 0))
      (let ((en-str (number->string en)))
        (do ((i 0 (+ i 1))
             (en-len (string-length en-str))
             (c #f))
            ((= i en-len))
          (set! c (string-ref en-str i))
          (if (char-numeric? c)
              (begin
                (string-set! format:en-str format:en-len c)
                (set! format:en-len (+ format:en-len 1)))))))

    (define (format:fn-zfill left? n) ; fill current number string with 0s
      (if (> (+ n format:fn-len) format:fn-max) ; from the left or right
          (format:error "number is too long to format (enlarge format:fn-max)"))
      (set! format:fn-len (+ format:fn-len n))
      (if left?
          (do ((i format:fn-len (- i 1))) ; fill n 0s to left
              ((< i 0))
            (string-set! format:fn-str i
                         (if (< i n)
                             #\0
                             (string-ref format:fn-str (- i n)))))
          (do ((i (- format:fn-len n) (+ i 1))) ; fill n 0s to the right
              ((= i format:fn-len))
            (string-set! format:fn-str i #\0))))

    (define (format:fn-shiftleft n) ; shift left current number n positions
      (if (> n format:fn-len)
          (format:error "internal error in format:fn-shiftleft (~d,~d)"
                        n format:fn-len))
      (do ((i n (+ i 1)))
          ((= i format:fn-len)
           (set! format:fn-len (- format:fn-len n)))
        (string-set! format:fn-str (- i n) (string-ref format:fn-str i))))

    (define (format:fn-round digits)    ; round format:fn-str
      (set! digits (+ digits format:fn-dot))
      (do ((i digits (- i 1))		; "099",2 -> "10"
           (c 5))                       ; "023",2 -> "02"
          ((or (= c 0) (< i 0))         ; "999",2 -> "100"
           (if (= c 1)			; "005",2 -> "01"
               (begin			; carry overflow
                 (set! format:fn-len digits)
                 (format:fn-zfill #t 1) ; add a 1 before fn-str
                 (string-set! format:fn-str 0 #\1)
                 (set! format:fn-dot (+ format:fn-dot 1)))
               (set! format:fn-len digits)))
        (set! c (+ (- (char->integer (string-ref format:fn-str i))
                      format:zero-ch) c))
        (string-set! format:fn-str i (integer->char
                                      (if (< c 10) 
                                          (+ c format:zero-ch)
                                          (+ (- c 10) format:zero-ch))))
        (set! c (if (< c 10) 0 1))))

    (define (format:fn-out modifier add-leading-zero?)
      (if format:fn-pos?
          (if (eq? modifier 'at) 
              (format:out-char #\+))
          (format:out-char #\-))
      (if (= format:fn-dot 0)
          (if add-leading-zero?
              (format:out-char #\0))
          (format:out-substr format:fn-str 0 format:fn-dot))
      (format:out-char #\.)
      (format:out-substr format:fn-str format:fn-dot format:fn-len))

    (define (format:en-out edigits expch)
      (format:out-char (if expch (integer->char expch) #\E))
      (format:out-char (if format:en-pos? #\+ #\-))
      (if edigits 
          (if (< format:en-len edigits)
              (format:out-fill (- edigits format:en-len) #\0)))
      (format:out-substr format:en-str 0 format:en-len))

    (define (format:fn-strip)           ; strip trailing zeros but one
      (string-set! format:fn-str format:fn-len #\0)
      (do ((i format:fn-len (- i 1)))
          ((or (not (char=? (string-ref format:fn-str i) #\0))
               (<= i format:fn-dot))
           (set! format:fn-len (+ i 1)))))

    (define (format:fn-zlead)           ; count leading zeros
      (do ((i 0 (+ i 1)))
          ((or (= i format:fn-len)
               (not (char=? (string-ref format:fn-str i) #\0)))
           (if (= i format:fn-len)      ; found a real zero
               0
               i))))


;;; some global functions not found in SLIB

    (define (string-capitalize-first str) ; "hello" -> "Hello"
      (let ((cap-str (string-copy str))   ; "hELLO" -> "Hello"
            (non-first-alpha #f)          ; "*hello" -> "*Hello"
            (str-len (string-length str))) ; "hello you" -> "Hello you"
        (do ((i 0 (+ i 1)))
            ((= i str-len) cap-str)
          (let ((c (string-ref str i)))
            (if (char-alphabetic? c)
                (if non-first-alpha
                    (string-set! cap-str i (char-downcase c))
                    (begin
                      (set! non-first-alpha #t)
                      (string-set! cap-str i (char-upcase c)))))))))

    ;; Aborts the program when a formatting error occures. This is a null
    ;; argument closure to jump to the interpreters toplevel continuation.

    (define (format:abort) (error "error in format"))
    
    (let ((arg-pos (format:format-work format-string format-args))
          (arg-len (length format-args)))
      (cond
       ((> arg-pos arg-len)
        (set! format:arg-pos (+ arg-len 1))
        (display format:arg-pos)
        (format:error "~a missing argument~:p" (- arg-pos arg-len)))
       (else
        (if flush-output?
            (force-output port))
        (if destination
            #t
            (let ((str (get-output-string port)))
              (close-port port)
              str)))))))

(begin-deprecated
 (set! format
       (let ((format format))
         (case-lambda
           ((destination format-string . args)
            (if (string? destination)
                (begin
                  (issue-deprecation-warning
                   "Omitting the destination on a call to format is deprecated."
                   "Pass #f as the destination, before the format string.")
                  (apply format #f destination format-string args))
                (apply format destination format-string args)))
           ((deprecated-format-string-only)
            (issue-deprecation-warning
             "Omitting the destination port on a call to format is deprecated."
             "Pass #f as the destination port, before the format string.")
            (format #f deprecated-format-string-only))))))


;; Thanks to Shuji Narazaki
(module-set! the-root-module 'format format)